snarkvm_console_algorithms/keccak/
hash.rs1use super::*;
17use snarkvm_utilities::{bits_from_bytes_le, bytes_from_bits_le};
18
19impl<const TYPE: u8, const VARIANT: usize> Hash for Keccak<TYPE, VARIANT> {
20 type Input = bool;
21 type Output = Vec<bool>;
22
23 #[inline]
25 fn hash(&self, input: &[Self::Input]) -> Result<Self::Output> {
26 let result = match (TYPE, VARIANT) {
27 (0, 224) => bits_from_bytes_le(&keccak_224_native(&bytes_from_bits_le(input))).collect(),
28 (0, 256) => bits_from_bytes_le(&keccak_256_native(&bytes_from_bits_le(input))).collect(),
29 (0, 384) => bits_from_bytes_le(&keccak_384_native(&bytes_from_bits_le(input))).collect(),
30 (0, 512) => bits_from_bytes_le(&keccak_512_native(&bytes_from_bits_le(input))).collect(),
31 (1, 224) => bits_from_bytes_le(&sha3_224_native(&bytes_from_bits_le(input))).collect(),
32 (1, 256) => bits_from_bytes_le(&sha3_256_native(&bytes_from_bits_le(input))).collect(),
33 (1, 384) => bits_from_bytes_le(&sha3_384_native(&bytes_from_bits_le(input))).collect(),
34 (1, 512) => bits_from_bytes_le(&sha3_512_native(&bytes_from_bits_le(input))).collect(),
35 _ => unreachable!("Invalid Keccak type and variant"),
36 };
37 Ok(result)
38 }
39}
40
41fn keccak_224_native(preimage: &[u8]) -> [u8; 28] {
43 let mut keccak = TinyKeccak::v224();
44 keccak.update(preimage);
45
46 let mut hash = [0u8; 28];
47 keccak.finalize(&mut hash);
48 hash
49}
50
51fn keccak_256_native(preimage: &[u8]) -> [u8; 32] {
53 let mut keccak = TinyKeccak::v256();
54 keccak.update(preimage);
55
56 let mut hash = [0u8; 32];
57 keccak.finalize(&mut hash);
58 hash
59}
60
61fn keccak_384_native(preimage: &[u8]) -> [u8; 48] {
63 let mut keccak = TinyKeccak::v384();
64 keccak.update(preimage);
65
66 let mut hash = [0u8; 48];
67 keccak.finalize(&mut hash);
68 hash
69}
70
71fn keccak_512_native(preimage: &[u8]) -> [u8; 64] {
73 let mut keccak = TinyKeccak::v512();
74 keccak.update(preimage);
75
76 let mut hash = [0u8; 64];
77 keccak.finalize(&mut hash);
78 hash
79}
80
81fn sha3_224_native(preimage: &[u8]) -> [u8; 28] {
83 let mut keccak = TinySha3::v224();
84 keccak.update(preimage);
85
86 let mut hash = [0u8; 28];
87 keccak.finalize(&mut hash);
88 hash
89}
90
91fn sha3_256_native(preimage: &[u8]) -> [u8; 32] {
93 let mut keccak = TinySha3::v256();
94 keccak.update(preimage);
95
96 let mut hash = [0u8; 32];
97 keccak.finalize(&mut hash);
98 hash
99}
100
101fn sha3_384_native(preimage: &[u8]) -> [u8; 48] {
103 let mut keccak = TinySha3::v384();
104 keccak.update(preimage);
105
106 let mut hash = [0u8; 48];
107 keccak.finalize(&mut hash);
108 hash
109}
110
111fn sha3_512_native(preimage: &[u8]) -> [u8; 64] {
113 let mut keccak = TinySha3::v512();
114 keccak.update(preimage);
115
116 let mut hash = [0u8; 64];
117 keccak.finalize(&mut hash);
118 hash
119}
120
121#[cfg(test)]
122mod tests {
123 use super::*;
124 use crate::Rng;
125 use snarkvm_utilities::{bits_from_bytes_le, bytes_from_bits_le};
126
127 macro_rules! check_equivalence {
128 ($console:expr, $native:expr) => {
129 let rng = &mut TestRng::default();
130
131 let mut input_sizes = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16, 32, 64, 128, 256, 512, 1024];
132 input_sizes.extend((0..100).map(|_| rng.gen_range(1..1024)));
133
134 for num_inputs in input_sizes {
135 println!("Checking equivalence for {num_inputs} inputs");
136
137 let input = (0..num_inputs).map(|_| Uniform::rand(rng)).collect::<Vec<bool>>();
139
140 let expected = $native(&bytes_from_bits_le(&input));
142 let expected = bits_from_bytes_le(&expected).collect::<Vec<_>>();
143
144 let candidate = $console.hash(&input).unwrap();
146 assert_eq!(expected, candidate);
147 }
148 };
149 }
150
151 #[test]
152 fn test_keccak_224_equivalence() {
153 check_equivalence!(Keccak224::default(), keccak_224_native);
154 }
155
156 #[test]
157 fn test_keccak_256_equivalence() {
158 check_equivalence!(Keccak256::default(), keccak_256_native);
159 }
160
161 #[test]
162 fn test_keccak_384_equivalence() {
163 check_equivalence!(Keccak384::default(), keccak_384_native);
164 }
165
166 #[test]
167 fn test_keccak_512_equivalence() {
168 check_equivalence!(Keccak512::default(), keccak_512_native);
169 }
170
171 #[test]
172 fn test_sha3_224_equivalence() {
173 check_equivalence!(Sha3_224::default(), sha3_224_native);
174 }
175
176 #[test]
177 fn test_sha3_256_equivalence() {
178 check_equivalence!(Sha3_256::default(), sha3_256_native);
179 }
180
181 #[test]
182 fn test_sha3_384_equivalence() {
183 check_equivalence!(Sha3_384::default(), sha3_384_native);
184 }
185
186 #[test]
187 fn test_sha3_512_equivalence() {
188 check_equivalence!(Sha3_512::default(), sha3_512_native);
189 }
190}