Skip to main content

sha3/
lib.rs

1//! SHA-3 Hash Functions
2//!
3//! This crate provides portable, pure Rust implementations of the SHA-3 hashing
4//! functions standardized in [FIPS 202].
5//!
6//! # Limitations
7//!
8//! This software is intended as a learning exercise and not for production use.
9//!
10//! Performance has thus far not been a priority. This implementation is likely
11//! orders of magnitude slower than optimized ones.
12//!
13//! We currently only expose functions to hash a complete byte slice `&[u8]`.
14//! Individual bits or multiple inputs that update the hash are currently not
15//! supported.
16//!
17//! We currently do not implement the SHAKE extendable-output functions
18//! described in [FIPS 202].
19//!
20//! # Example Usage
21//! ```
22//! # use sha3::sha3_256;
23//! #
24//! let message = b"your input bytes";
25//! let hash: [u8; 32] = sha3_256(message);
26//! let expected = "414d4b6d11a92aaeeebe35f9374942f563848d345631bf5537407252dca6b378";
27//! assert_eq!(expected, hex::encode(hash))
28//! ```
29//!
30//! [FIPS 202]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
31
32mod keccak;
33
34use crate::keccak::keccak;
35
36// TODO: remove code duplication. Use a macro?
37
38/// SHA-3 Hash with 224 bits (28 bytes) output.
39pub fn sha3_224(message: &[u8]) -> [u8; 28] {
40    let mut output = [0; 28];
41    const CAPACITY: usize = 224 * 2;
42    const RATE: usize = 1600 - CAPACITY;
43    keccak(RATE, CAPACITY, message, &mut output);
44    output
45}
46
47/// SHA-3 Hash with 256 bits (32 bytes) output.
48pub fn sha3_256(message: &[u8]) -> [u8; 32] {
49    let mut output = [0; 32];
50    const CAPACITY: usize = 256 * 2;
51    const RATE: usize = 1600 - CAPACITY;
52    keccak(RATE, CAPACITY, message, &mut output);
53    output
54}
55
56/// SHA-3 Hash with 384 bits (48 bytes) output.
57pub fn sha3_384(message: &[u8]) -> [u8; 48] {
58    let mut output = [0; 48];
59    const CAPACITY: usize = 384 * 2;
60    const RATE: usize = 1600 - CAPACITY;
61    keccak(RATE, CAPACITY, message, &mut output);
62    output
63}
64
65/// SHA-3 Hash with 512 bits (64 bytes) output.
66pub fn sha3_512(message: &[u8]) -> [u8; 64] {
67    let mut output = [0; 64];
68    const CAPACITY: usize = 512 * 2;
69    const RATE: usize = 1600 - CAPACITY;
70    keccak(RATE, CAPACITY, message, &mut output);
71    output
72}
73
74#[cfg(test)]
75mod tests {
76
77    use crate::sha3_256;
78
79    #[test]
80    fn can_hash() {
81        let input = b"some input string";
82        sha3_256(&input[..]);
83    }
84
85    #[cfg(not(miri))]
86    #[test]
87    fn compare_to_libcrux() {
88        // Go beyond one block
89        for i in 0..300 {
90            let input = vec![0; i];
91            let my_hash = sha3_256(&input[..]);
92            let other_hash = libcrux_sha3::sha256(&input);
93            assert_eq!(my_hash, other_hash.as_slice(), "len {i} hash differs");
94        }
95    }
96}