Skip to main content

crypto/sha3/
sha3_512.rs

1use super::keccak::Keccak;
2use crate::{Hash, Hasher};
3
4const SHA3_512_RATE: usize = 72;
5const SHA3_512_DOMAIN_SEPARATOR: u8 = 0x06;
6
7#[derive(Clone)]
8#[cfg_attr(feature = "zeroize", derive(zeroize::Zeroize, zeroize::ZeroizeOnDrop))]
9pub struct Sha3_512 {
10    keccak: Keccak<24>,
11}
12
13impl Sha3_512 {
14    #[inline]
15    pub fn new() -> Self {
16        return Sha3_512 {
17            keccak: Keccak::new(SHA3_512_RATE, SHA3_512_DOMAIN_SEPARATOR),
18        };
19    }
20
21    #[inline]
22    pub fn write(&mut self, data: &[u8]) {
23        self.keccak.absorb(data);
24    }
25
26    #[inline]
27    pub fn sum(mut self) -> [u8; 64] {
28        let mut output = [0u8; 64];
29        self.keccak.squeeze(&mut output);
30        return output;
31    }
32}
33
34impl Hasher for Sha3_512 {
35    const BLOCK_SIZE: usize = SHA3_512_RATE;
36    const OUTPUT_SIZE: usize = 64;
37
38    #[inline]
39    fn new() -> Self {
40        return Sha3_512::new();
41    }
42
43    #[inline]
44    fn update(&mut self, data: &[u8]) {
45        self.write(data);
46    }
47
48    #[inline]
49    fn sum(mut self) -> Hash {
50        let mut hash = Hash::with_length(Self::OUTPUT_SIZE);
51        self.keccak.squeeze(hash.as_mut());
52        return hash;
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::Sha3_512;
59    use crate::Hasher;
60
61    fn vectors_sha3_512() -> Vec<(Vec<u8>, &'static str)> {
62        vec![
63            (
64                b"".to_vec(),
65                "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26",
66            ),
67            (
68                b"abc".to_vec(),
69                "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0",
70            ),
71            (
72                b"hello world".to_vec(),
73                "840006653e9ac9e95117a15c915caab81662918e925de9e004f774ff82d7079a40d4d27b1b372657c61d46d470304c88c788b3a4527ad074d1dccbee5dbaa99a",
74            ),
75            (
76                b"The quick brown fox jumps over the lazy dog".to_vec(),
77                "01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450",
78            ),
79            (
80                b"The quick brown fox jumps over the lazy dog.".to_vec(),
81                "18f4f4bd419603f95538837003d9d254c26c23765565162247483f65c50303597bc9ce4d289f21d1c2f1f458828e33dc442100331b35e7eb031b5d38ba6460f8",
82            ),
83            (
84                vec![b'a'; 1_000_000],
85                "3c3a876da14034ab60627c077bb98f7e120a2a5370212dffb3385a18d4f38859ed311d0a9d5141ce9cc5c66ee689b266a8aa18ace8282a0e0db596c90b0a7b87",
86            ),
87        ]
88    }
89
90    #[test]
91    fn known_vectors_single_update() {
92        for (input, expected) in vectors_sha3_512() {
93            assert_eq!(hex::encode(Sha3_512::hash(&input)), expected);
94        }
95    }
96
97    #[test]
98    fn known_vectors_incremental() {
99        for (input, expected) in vectors_sha3_512() {
100            let mut sha3_512 = Sha3_512::new();
101            for chunk in input.chunks(11) {
102                sha3_512.write(chunk);
103            }
104            assert_eq!(hex::encode(sha3_512.sum()), expected);
105        }
106    }
107
108    #[test]
109    fn hasher_trait_impl() {
110        for (input, expected) in vectors_sha3_512() {
111            let digest = <Sha3_512 as Hasher>::hash(&input);
112            assert_eq!(hex::encode(digest.as_ref()), expected);
113        }
114    }
115}