tiny_multihash/
hasher_impl.rs

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