1use crate::{
2 error::Error,
3 hasher::{
4 Digest,
5 StatefulHasher,
6 },
7};
8
9use core::convert::TryFrom;
10
11macro_rules! derive_digest {
12 ($name:ident) => {
13 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
15 pub struct $name<const S: usize>([u8; S]);
16
17 impl<const S: usize> Default for $name<S> {
18 fn default() -> Self { [0u8; S].into() }
19 }
20
21 impl<const S: usize> AsRef<[u8]> for $name<S> {
22 fn as_ref(&self) -> &[u8] { &self.0 }
23 }
24
25 impl<const S: usize> AsMut<[u8]> for $name<S> {
26 fn as_mut(&mut self) -> &mut [u8] { &mut self.0 }
27 }
28
29 impl<const S: usize> From<[u8; S]> for $name<S> {
30 fn from(array: [u8; S]) -> Self { Self(array) }
31 }
32
33 impl<const S: usize> From<$name<S>> for [u8; S] {
34 fn from(digest: $name<S>) -> Self { digest.0 }
35 }
36
37 impl<const S: usize> TryFrom<&[u8]> for $name<S> {
42 type Error = Error;
43
44 fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
45 Self::wrap(slice)
46 }
47 }
48
49 impl<const S: usize> Digest<S> for $name<S> {}
50 };
51}
52
53macro_rules! derive_write {
54 ($name:ident) => {
55 #[cfg(feature = "std")]
56 impl<const S: usize> std::io::Write for $name<S> {
57 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
58 self.update(buf);
59 Ok(buf.len())
60 }
61
62 fn flush(&mut self) -> std::io::Result<()> { Ok(()) }
63 }
64 };
65}
66
67#[cfg(any(feature = "blake2b", feature = "blake2s"))]
68macro_rules! derive_hasher_blake {
69 ($module:ident, $name:ident, $digest:ident) => {
70 derive_digest!($digest);
71
72 #[derive(Debug)]
74 pub struct $name<const S: usize> {
75 state: $module::State,
76 }
77
78 impl<const S: usize> Default for $name<S> {
79 fn default() -> Self {
80 let mut params = $module::Params::new();
81 params.hash_length(S);
82 Self { state: params.to_state() }
83 }
84 }
85
86 impl<const S: usize> StatefulHasher<S> for $name<S> {
87 type Digest = $digest<S>;
88
89 fn update(&mut self, input: &[u8]) { self.state.update(input); }
90
91 fn finalize(&self) -> Self::Digest {
92 let digest = self.state.finalize();
93 let mut array = [0; S];
94 array.clone_from_slice(digest.as_bytes());
95 array.into()
96 }
97
98 fn reset(&mut self) {
99 let Self { state, .. } = Self::default();
100 self.state = state;
101 }
102 }
103 derive_write!($name);
104 };
105}
106
107#[cfg(feature = "blake2b")]
108pub mod blake2b {
109 use super::*;
110
111 derive_hasher_blake!(blake2b_simd, Blake2bHasher, Blake2bDigest);
112
113 pub type Blake2b256 = Blake2bHasher<32>;
115
116 pub type Blake2b512 = Blake2bHasher<64>;
118}
119
120#[cfg(feature = "blake2s")]
121pub mod blake2s {
122 use super::*;
123
124 derive_hasher_blake!(blake2s_simd, Blake2sHasher, Blake2sDigest);
125
126 pub type Blake2s128 = Blake2sHasher<16>;
128
129 pub type Blake2s256 = Blake2sHasher<32>;
131}
132
133#[cfg(feature = "blake3")]
134pub mod blake3 {
135 use super::*;
136
137 derive_digest!(Blake3Digest);
138
139 #[derive(Debug)]
141 pub struct Blake3Hasher<const S: usize> {
142 hasher: ::blake3::Hasher,
143 }
144
145 impl<const S: usize> Default for Blake3Hasher<S> {
146 fn default() -> Self {
147 let hasher = ::blake3::Hasher::new();
148
149 Self { hasher }
150 }
151 }
152
153 impl<const S: usize> StatefulHasher<S> for Blake3Hasher<S> {
154 type Digest = Blake3Digest<S>;
155
156 fn update(&mut self, input: &[u8]) { self.hasher.update(input); }
157
158 fn finalize(&self) -> Self::Digest {
159 let digest = self.hasher.finalize(); let mut array = [0; S];
161 array.clone_from_slice(digest.as_bytes());
162 array.into()
163 }
164
165 fn reset(&mut self) { self.hasher.reset(); }
166 }
167
168 derive_write!(Blake3Hasher);
169
170 pub type Blake3_256 = Blake3Hasher<32>;
172}
173
174#[cfg(feature = "digest")]
175macro_rules! derive_hasher_sha {
176 ($module:ty, $name:ident, $size:expr, $digest:ident) => {
177 #[derive(Debug, Default)]
179 pub struct $name {
180 state: $module,
181 }
182
183 impl $crate::hasher::StatefulHasher<$size> for $name {
184 type Digest = $digest<$size>;
185
186 fn update(&mut self, input: &[u8]) {
187 use digest::Digest;
188 self.state.update(input)
189 }
190
191 fn finalize(&self) -> Self::Digest {
192 use digest::Digest;
193 let digest = self.state.clone().finalize();
194 let mut array = [0; $size];
195 array.copy_from_slice(digest.as_slice());
196 array.into()
197 }
198
199 fn reset(&mut self) {
200 use digest::Digest;
201 self.state.reset();
202 }
203 }
204
205 #[cfg(feature = "std")]
206 impl std::io::Write for $name {
207 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
208 self.update(buf);
209 Ok(buf.len())
210 }
211
212 fn flush(&mut self) -> std::io::Result<()> { Ok(()) }
213 }
214 };
215}
216
217#[cfg(feature = "sha1")]
218pub mod sha1 {
219 use super::*;
220
221 derive_digest!(Sha1Digest);
222 derive_hasher_sha!(::sha1::Sha1, Sha1, 20, Sha1Digest);
223}
224
225#[cfg(feature = "sha2")]
226pub mod sha2 {
227 use super::*;
228
229 derive_digest!(Sha2Digest);
230 derive_hasher_sha!(sha_2::Sha256, Sha2_256, 32, Sha2Digest);
231 derive_hasher_sha!(sha_2::Sha512, Sha2_512, 64, Sha2Digest);
232}
233
234#[cfg(feature = "sha3")]
235pub mod sha3 {
236 use super::*;
237
238 derive_digest!(Sha3Digest);
239 derive_hasher_sha!(sha_3::Sha3_224, Sha3_224, 28, Sha3Digest);
240 derive_hasher_sha!(sha_3::Sha3_256, Sha3_256, 32, Sha3Digest);
241 derive_hasher_sha!(sha_3::Sha3_384, Sha3_384, 48, Sha3Digest);
242 derive_hasher_sha!(sha_3::Sha3_512, Sha3_512, 64, Sha3Digest);
243
244 derive_digest!(KeccakDigest);
245 derive_hasher_sha!(sha_3::Keccak224, Keccak224, 28, KeccakDigest);
246 derive_hasher_sha!(sha_3::Keccak256, Keccak256, 32, KeccakDigest);
247 derive_hasher_sha!(sha_3::Keccak384, Keccak384, 48, KeccakDigest);
248 derive_hasher_sha!(sha_3::Keccak512, Keccak512, 64, KeccakDigest);
249}
250
251pub mod identity {
252 use super::*;
253 use crate::error::Error;
254
255 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
257 pub struct IdentityDigest<const S: usize>(usize, [u8; S]);
258
259 impl<const S: usize> Default for IdentityDigest<S> {
260 fn default() -> Self { Self(0, [0u8; S]) }
261 }
262
263 impl<const S: usize> AsRef<[u8]> for IdentityDigest<S> {
264 fn as_ref(&self) -> &[u8] { &self.1[..self.0 as usize] }
265 }
266
267 impl<const S: usize> AsMut<[u8]> for IdentityDigest<S> {
268 fn as_mut(&mut self) -> &mut [u8] { &mut self.1[..self.0 as usize] }
269 }
270
271 impl<const S: usize> From<[u8; S]> for IdentityDigest<S> {
272 fn from(array: [u8; S]) -> Self { Self(array.len(), array) }
273 }
274
275 impl<const S: usize> From<IdentityDigest<S>> for [u8; S] {
276 fn from(digest: IdentityDigest<S>) -> Self { digest.1 }
277 }
278
279 impl<const S: usize> Digest<S> for IdentityDigest<S> {
280 const SIZE: usize = S;
281
282 fn wrap(digest: &[u8]) -> Result<Self, Error> {
285 if digest.len() > S {
286 return Err(Error::InvalidSize(digest.len() as _));
287 }
288 let mut array = [0; S];
289 let len = digest.len().min(array.len());
290 array[..len].copy_from_slice(&digest[..len]);
291 Ok(Self(len, array))
292 }
293
294 #[cfg(feature = "std")]
297 fn from_reader<R>(mut r: R) -> Result<Self, Error>
298 where R: std::io::Read {
299 use unsigned_varint::io::read_u64;
300
301 let size = read_u64(&mut r)?;
302 if size > S as u64 || size > u8::MAX as u64 {
303 return Err(Error::InvalidSize(size));
304 }
305 let mut digest = [0; S];
306 r.read_exact(&mut digest[..size as usize])?;
307 Ok(Self(size as usize, digest))
308 }
309 }
310
311 #[derive(Debug)]
317 pub struct IdentityHasher<const S: usize> {
318 bytes: [u8; S],
319 i: usize,
320 }
321
322 impl<const S: usize> Default for IdentityHasher<S> {
323 fn default() -> Self { Self { i: 0, bytes: [0u8; S] } }
324 }
325
326 impl<const S: usize> StatefulHasher<S> for IdentityHasher<S> {
327 type Digest = IdentityDigest<S>;
328
329 fn update(&mut self, input: &[u8]) {
330 let start = self.i.min(self.bytes.len());
331 let end = (self.i + input.len()).min(self.bytes.len());
332 self.bytes[start..end].copy_from_slice(input);
333 self.i = end;
334 }
335
336 fn finalize(&self) -> Self::Digest {
337 IdentityDigest(self.i, self.bytes.clone())
338 }
339
340 fn reset(&mut self) {
341 self.bytes = [0; S];
342 self.i = 0;
343 }
344 }
345
346 derive_write!(IdentityHasher);
347
348 pub type Identity256 = IdentityHasher<32>;
354}
355
356pub mod unknown {
357 use super::*;
358 derive_digest!(UnknownDigest);
359}
360
361#[cfg(feature = "strobe")]
362pub mod strobe {
363 use super::*;
364 use strobe_rs::{
365 SecParam,
366 Strobe,
367 };
368
369 derive_digest!(StrobeDigest);
370
371 pub struct StrobeHasher<const S: usize> {
373 strobe: Strobe,
374 initialized: bool,
375 }
376
377 impl<const S: usize> Default for StrobeHasher<S> {
378 fn default() -> Self {
379 Self {
380 strobe: Strobe::new(b"StrobeHash", SecParam::B128),
381 initialized: false,
382 }
383 }
384 }
385
386 impl<const S: usize> StatefulHasher<S> for StrobeHasher<S> {
387 type Digest = StrobeDigest<S>;
388
389 fn update(&mut self, input: &[u8]) {
390 self.strobe.ad(input, self.initialized);
391 self.initialized = true;
392 }
393
394 fn finalize(&self) -> Self::Digest {
395 let mut hash = [0; S];
396 self.strobe.clone().prf(&mut hash, false);
397 Self::Digest::from(hash)
398 }
399
400 fn reset(&mut self) {
401 let Self { strobe, .. } = Self::default();
402 self.strobe = strobe;
403 self.initialized = false;
404 }
405 }
406
407 derive_write!(StrobeHasher);
408
409 pub type Strobe256 = StrobeHasher<32>;
411
412 pub type Strobe512 = StrobeHasher<64>;
414}