sp_multihash/
hasher_impl.rs

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    /// Multihash digest.
14    #[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    /// Convert slice to `Digest`.
38    ///
39    /// It errors when the length of the slice does not match the size of the
40    /// `Digest`.
41    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    /// Multihash hasher.
73    #[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  /// 256 bit blake2b hasher.
114  pub type Blake2b256 = Blake2bHasher<32>;
115
116  /// 512 bit blake2b hasher.
117  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  /// 256 bit blake2b hasher.
127  pub type Blake2s128 = Blake2sHasher<16>;
128
129  /// 512 bit blake2b hasher.
130  pub type Blake2s256 = Blake2sHasher<32>;
131}
132
133#[cfg(feature = "blake3")]
134pub mod blake3 {
135  use super::*;
136
137  derive_digest!(Blake3Digest);
138
139  /// Multihash hasher.
140  #[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(); //default is 32 bytes anyway
160      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  /// blake3-256 hasher.
171  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    /// Multihash hasher.
178    #[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  /// Multihash digest.
256  #[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    // A custom implementation is needed as an identity hash value might be
283    // shorter than the allocated Digest.
284    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    // A custom implementation is needed as an identity hash also stores the
295    // actual size of the given digest.
296    #[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  /// Identity hasher with a maximum size.
312  ///
313  /// # Panics
314  ///
315  /// Panics if the input is bigger than the maximum size.
316  #[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  /// 32 byte Identity hasher (constrained to 32 bytes).
349  ///
350  /// # Panics
351  ///
352  /// Panics if the input is bigger than 32 bytes.
353  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  /// Strobe hasher.
372  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  /// 256 bit strobe hasher.
410  pub type Strobe256 = StrobeHasher<32>;
411
412  /// 512 bit strobe hasher.
413  pub type Strobe512 = StrobeHasher<64>;
414}