lib_q_stark_shake256/
lib.rs1#![no_std]
22
23extern crate alloc;
24
25use digest::{
26 ExtendableOutput,
27 Update,
28 XofReader,
29};
30use lib_q_sha3::Shake256;
31use lib_q_stark_symmetric::CryptographicHasher;
32
33const STREAM_BUFFER_SIZE: usize = 4096;
36
37#[derive(Clone, Copy, Debug)]
42pub struct Shake256Hash;
43
44impl CryptographicHasher<u8, [u8; 32]> for Shake256Hash {
45 fn hash_iter<I>(&self, input: I) -> [u8; 32]
46 where
47 I: IntoIterator<Item = u8>,
48 {
49 let mut hasher = Shake256::default();
50 let mut buffer = [0u8; STREAM_BUFFER_SIZE];
51 let mut buffer_pos = 0;
52 let mut has_data = false;
53
54 for byte in input {
56 has_data = true;
57 buffer[buffer_pos] = byte;
58 buffer_pos += 1;
59
60 if buffer_pos >= STREAM_BUFFER_SIZE {
62 hasher.update(&buffer);
63 buffer_pos = 0;
64 }
65 }
66
67 if has_data && buffer_pos > 0 {
69 hasher.update(&buffer[..buffer_pos]);
70 }
71
72 let mut reader = hasher.finalize_xof();
73 let mut output = [0u8; 32];
74 reader.read(&mut output);
75 output
76 }
77
78 fn hash_iter_slices<'a, I>(&self, input: I) -> [u8; 32]
79 where
80 I: IntoIterator<Item = &'a [u8]>,
81 u8: 'a,
82 {
83 let mut hasher = Shake256::default();
84 for chunk in input {
85 hasher.update(chunk);
86 }
87
88 let mut reader = hasher.finalize_xof();
89 let mut output = [0u8; 32];
90 reader.read(&mut output);
91 output
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use alloc::vec::Vec;
98
99 use super::*;
100
101 #[test]
102 fn test_shake256_hash() {
103 let hasher = Shake256Hash;
104 let input = b"test input";
105 let output = hasher.hash_slice(input);
106
107 assert_eq!(output.len(), 32);
109
110 let output2 = hasher.hash_slice(input);
112 assert_eq!(output, output2);
113 }
114
115 #[test]
116 fn test_shake256_hash_iter() {
117 let hasher = Shake256Hash;
118 let input: Vec<u8> = (0..100).collect();
119 let output = hasher.hash_iter(input.iter().copied());
120
121 assert_eq!(output.len(), 32);
122 }
123}