Skip to main content

audit_trail/hashers/
blake3.rs

1//! BLAKE3 [`Hasher`] backed by the [`blake3`] crate. Requires the `blake3`
2//! feature.
3
4use crate::hash::{Digest, HASH_LEN, Hasher};
5
6/// BLAKE3 [`Hasher`].
7///
8/// Faster than SHA-256 on most modern hardware and produces a 32-byte
9/// output that drops in wherever [`crate::Sha256Hasher`] would. Useful
10/// when throughput matters more than the FIPS pedigree of SHA-256.
11///
12/// # Example
13///
14/// ```
15/// use audit_trail::{Blake3Hasher, Digest, Hasher};
16///
17/// let mut hasher = Blake3Hasher::new();
18/// hasher.update(b"audit-trail");
19/// let mut out = Digest::ZERO;
20/// hasher.finalize(&mut out);
21/// assert_ne!(out, Digest::ZERO);
22/// ```
23#[derive(Clone, Default)]
24pub struct Blake3Hasher(blake3::Hasher);
25
26impl Blake3Hasher {
27    /// Construct a fresh [`Blake3Hasher`].
28    #[inline]
29    pub fn new() -> Self {
30        Self(blake3::Hasher::new())
31    }
32}
33
34impl core::fmt::Debug for Blake3Hasher {
35    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
36        f.debug_struct("Blake3Hasher").finish_non_exhaustive()
37    }
38}
39
40impl Hasher for Blake3Hasher {
41    #[inline]
42    fn reset(&mut self) {
43        let _ = self.0.reset();
44    }
45
46    #[inline]
47    fn update(&mut self, bytes: &[u8]) {
48        let _ = self.0.update(bytes);
49    }
50
51    #[inline]
52    fn finalize(&mut self, out: &mut Digest) {
53        let hash = self.0.finalize();
54        let bytes: [u8; HASH_LEN] = *hash.as_bytes();
55        *out = Digest::from_bytes(bytes);
56    }
57}