1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
//! # xkcp-rs
//!
//! Safe wrappers to the [eXtended Keccak Code Package (XKCP)](https://github.com/XKCP/XKCP) library.

#![doc(html_root_url = "https://danipopes.github.io/xkcp-rs")]
#![warn(
    missing_debug_implementations,
    missing_docs,
    rust_2018_idioms,
    unreachable_pub,
    rustdoc::all
)]
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]

pub extern crate xkcp_sys as ffi;

mod error;
mod keccak;

pub use error::{Error, Result};
pub use keccak::KeccakHash;

/// Function to evaluate the sponge function Keccak\[r, c] in a single call.
#[inline]
pub fn keccak_sponge(
    rate: u32,
    capacity: u32,
    suffix: u8,
    input: &[u8],
    output: &mut [u8],
) -> Result<()> {
    Error::from_int(unsafe {
        ffi::KeccakWidth1600_Sponge(
            rate,
            capacity,
            input.as_ptr(),
            input.len(),
            suffix,
            output.as_mut_ptr(),
            output.len(),
        )
    })
}

/// Implementation of the SHAKE128 extendable output function (XOF) \[FIPS 202].
#[inline]
pub fn shake128(input: &[u8], output: &mut [u8]) -> Result<()> {
    keccak_sponge(1344, 256, 0x1F, input, output)
}

/// Implementation of the SHAKE256 extendable output function (XOF) \[FIPS 202].
#[inline]
pub fn shake256(input: &[u8], output: &mut [u8]) -> Result<()> {
    keccak_sponge(1088, 512, 0x1F, input, output)
}

/// Implementation of SHA3-224 \[FIPS 202].
#[inline]
#[cfg_attr(debug_assertions, track_caller)]
pub fn sha3_224(input: &[u8], output: &mut [u8; 28]) {
    let result = keccak_sponge(1152, 448, 0x06, input, output);
    debug_assert_eq!(result, Ok(()));
}

/// Implementation of SHA3-256 \[FIPS 202].
#[inline]
#[cfg_attr(debug_assertions, track_caller)]
pub fn sha3_256(input: &[u8], output: &mut [u8; 32]) {
    let result = keccak_sponge(1088, 512, 0x06, input, output);
    debug_assert_eq!(result, Ok(()));
}

/// Implementation of SHA3-384 \[FIPS 202].
#[inline]
#[cfg_attr(debug_assertions, track_caller)]
pub fn sha3_384(input: &[u8], output: &mut [u8; 48]) {
    let result = keccak_sponge(832, 768, 0x06, input, output);
    debug_assert_eq!(result, Ok(()));
}

/// Implementation of SHA3-512 \[FIPS 202].
#[inline]
#[cfg_attr(debug_assertions, track_caller)]
pub fn sha3_512(input: &[u8], output: &mut [u8; 64]) {
    let result = keccak_sponge(576, 1024, 0x06, input, output);
    debug_assert_eq!(result, Ok(()));
}

/// Implementation of Keccak-224.
#[inline]
#[cfg_attr(debug_assertions, track_caller)]
pub fn keccak224(input: &[u8], output: &mut [u8; 28]) {
    let result = keccak_sponge(1152, 448, 0x01, input, output);
    debug_assert_eq!(result, Ok(()));
}

/// Implementation of Keccak-256.
#[inline]
#[cfg_attr(debug_assertions, track_caller)]
pub fn keccak256(input: &[u8], output: &mut [u8; 32]) {
    let result = keccak_sponge(1088, 512, 0x01, input, output);
    debug_assert_eq!(result, Ok(()));
}

/// Implementation of Keccak-384.
#[inline]
#[cfg_attr(debug_assertions, track_caller)]
pub fn keccak384(input: &[u8], output: &mut [u8; 48]) {
    let result = keccak_sponge(832, 768, 0x01, input, output);
    debug_assert_eq!(result, Ok(()));
}

/// Implementation of Keccak-512.
#[inline]
#[cfg_attr(debug_assertions, track_caller)]
pub fn keccak512(input: &[u8], output: &mut [u8; 64]) {
    let result = keccak_sponge(576, 1024, 0x01, input, output);
    debug_assert_eq!(result, Ok(()));
}