Skip to main content

multihash_codetable/
hasher_impl.rs

1#[cfg(any(
2    feature = "strobe",
3    feature = "blake2b",
4    feature = "blake2s",
5    feature = "blake3"
6))]
7macro_rules! derive_write {
8    ($name:ident) => {
9        #[cfg(feature = "std")]
10        impl<const S: usize> std::io::Write for $name<S> {
11            fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
12                use multihash_derive::Hasher as _;
13
14                self.update(buf);
15                Ok(buf.len())
16            }
17
18            fn flush(&mut self) -> std::io::Result<()> {
19                Ok(())
20            }
21        }
22    };
23}
24
25#[cfg(any(feature = "blake2b", feature = "blake2s"))]
26macro_rules! derive_hasher_blake {
27    ($module:ident, $name:ident) => {
28        /// Multihash hasher.
29        #[derive(Debug)]
30        pub struct $name<const S: usize> {
31            state: $module::State,
32            digest: [u8; S],
33        }
34
35        impl<const S: usize> Default for $name<S> {
36            fn default() -> Self {
37                let mut params = $module::Params::new();
38                params.hash_length(S);
39                Self {
40                    state: params.to_state(),
41                    digest: [0; S],
42                }
43            }
44        }
45
46        impl<const S: usize> multihash_derive::Hasher for $name<S> {
47            fn update(&mut self, input: &[u8]) {
48                self.state.update(input);
49            }
50
51            fn finalize(&mut self) -> &[u8] {
52                let digest = self.state.finalize();
53                let digest_bytes = digest.as_bytes();
54                let digest_out = &mut self.digest[..digest_bytes.len().max(S)];
55                digest_out.copy_from_slice(digest_bytes);
56                digest_out
57            }
58
59            fn reset(&mut self) {
60                let Self { state, .. } = Self::default();
61                self.state = state;
62            }
63        }
64
65        impl<const S: usize> ::digest::Update for $name<S> {
66            fn update(&mut self, data: &[u8]) {
67                ::multihash_derive::Hasher::update(self, data)
68            }
69        }
70
71        derive_write!($name);
72    };
73}
74
75#[cfg(feature = "blake2b")]
76pub mod blake2b {
77    derive_hasher_blake!(blake2b_simd, Blake2bHasher);
78
79    /// 256 bit blake2b hasher.
80    pub type Blake2b256 = Blake2bHasher<32>;
81
82    /// 512 bit blake2b hasher.
83    pub type Blake2b512 = Blake2bHasher<64>;
84}
85
86#[cfg(feature = "blake2s")]
87pub mod blake2s {
88    derive_hasher_blake!(blake2s_simd, Blake2sHasher);
89
90    /// 256 bit blake2s hasher.
91    pub type Blake2s128 = Blake2sHasher<16>;
92
93    /// 512 bit blake2s hasher.
94    pub type Blake2s256 = Blake2sHasher<32>;
95}
96
97#[cfg(feature = "blake3")]
98pub mod blake3 {
99    /// Multihash hasher.
100    #[derive(Debug)]
101    pub struct Blake3Hasher<const S: usize> {
102        hasher: ::blake3::Hasher,
103        digest: [u8; S],
104    }
105
106    impl<const S: usize> Blake3Hasher<S> {
107        /// using blake3's XOF function, fills the given slice with hash output
108        pub fn finalize_xof_fill(&mut self, digest_out: &mut [u8]) {
109            let mut digest = self.hasher.finalize_xof();
110            digest.fill(digest_out)
111        }
112    }
113
114    impl<const S: usize> Default for Blake3Hasher<S> {
115        fn default() -> Self {
116            let hasher = ::blake3::Hasher::new();
117
118            Self {
119                hasher,
120                digest: [0; S],
121            }
122        }
123    }
124
125    impl<const S: usize> multihash_derive::Hasher for Blake3Hasher<S> {
126        fn update(&mut self, input: &[u8]) {
127            self.hasher.update(input);
128        }
129
130        fn finalize(&mut self) -> &[u8] {
131            let mut output = self.hasher.finalize_xof();
132            output.fill(&mut self.digest);
133            &self.digest
134        }
135
136        fn reset(&mut self) {
137            self.hasher.reset();
138        }
139    }
140
141    impl<const S: usize> ::digest::Update for Blake3Hasher<S> {
142        fn update(&mut self, data: &[u8]) {
143            ::multihash_derive::Hasher::update(self, data)
144        }
145    }
146
147    derive_write!(Blake3Hasher);
148
149    /// blake3-256 hasher.
150    pub type Blake3_256 = Blake3Hasher<32>;
151}
152
153#[cfg(any(
154    feature = "sha1",
155    feature = "sha2",
156    feature = "sha3",
157    feature = "ripemd"
158))]
159macro_rules! derive_rustcrypto_hasher {
160    ($module:ty, $name:ident, $size:expr) => {
161        /// Multihash hasher.
162        #[derive(Debug)]
163        pub struct $name {
164            state: $module,
165            digest: [u8; $size],
166        }
167
168        impl Default for $name {
169            fn default() -> Self {
170                $name {
171                    state: Default::default(),
172                    digest: [0; $size],
173                }
174            }
175        }
176
177        impl ::multihash_derive::Hasher for $name {
178            fn update(&mut self, input: &[u8]) {
179                use digest::Digest;
180                self.state.update(input)
181            }
182
183            fn finalize(&mut self) -> &[u8] {
184                use digest::Digest;
185                let digest = self.state.clone().finalize();
186                let digest_bytes = digest.as_slice();
187                let digest_out = &mut self.digest[..digest_bytes.len().max($size)];
188                digest_out.copy_from_slice(digest_bytes);
189                digest_out
190            }
191
192            fn reset(&mut self) {
193                use digest::Digest;
194                self.state.reset();
195            }
196        }
197
198        #[cfg(feature = "std")]
199        impl std::io::Write for $name {
200            fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
201                use multihash_derive::Hasher as _;
202
203                self.update(buf);
204                Ok(buf.len())
205            }
206
207            fn flush(&mut self) -> std::io::Result<()> {
208                Ok(())
209            }
210        }
211
212        impl ::digest::Update for $name {
213            fn update(&mut self, data: &[u8]) {
214                ::multihash_derive::Hasher::update(self, data)
215            }
216        }
217    };
218}
219
220#[cfg(feature = "sha1")]
221pub mod sha1 {
222    derive_rustcrypto_hasher!(::sha1::Sha1, Sha1, 20);
223}
224
225#[cfg(feature = "sha2")]
226pub mod sha2 {
227    derive_rustcrypto_hasher!(::sha2::Sha256, Sha2_256, 32);
228    derive_rustcrypto_hasher!(::sha2::Sha512, Sha2_512, 64);
229}
230
231#[cfg(feature = "sha3")]
232pub mod sha3 {
233    derive_rustcrypto_hasher!(::sha3::Sha3_224, Sha3_224, 28);
234    derive_rustcrypto_hasher!(::sha3::Sha3_256, Sha3_256, 32);
235    derive_rustcrypto_hasher!(::sha3::Sha3_384, Sha3_384, 48);
236    derive_rustcrypto_hasher!(::sha3::Sha3_512, Sha3_512, 64);
237
238    derive_rustcrypto_hasher!(::sha3::Keccak224, Keccak224, 28);
239    derive_rustcrypto_hasher!(::sha3::Keccak256, Keccak256, 32);
240    derive_rustcrypto_hasher!(::sha3::Keccak384, Keccak384, 48);
241    derive_rustcrypto_hasher!(::sha3::Keccak512, Keccak512, 64);
242}
243
244#[cfg(feature = "ripemd")]
245pub mod ripemd {
246    derive_rustcrypto_hasher!(::ripemd::Ripemd160, Ripemd160, 20);
247    derive_rustcrypto_hasher!(::ripemd::Ripemd256, Ripemd256, 32);
248    derive_rustcrypto_hasher!(::ripemd::Ripemd320, Ripemd320, 40);
249}
250
251#[cfg(feature = "strobe")]
252pub mod strobe {
253    use strobe_rs::{SecParam, Strobe};
254
255    /// Strobe hasher.
256    pub struct StrobeHasher<const S: usize> {
257        strobe: Strobe,
258        initialized: bool,
259        digest: [u8; S],
260    }
261
262    impl<const S: usize> Default for StrobeHasher<S> {
263        fn default() -> Self {
264            Self {
265                strobe: Strobe::new(b"StrobeHash", SecParam::B128),
266                initialized: false,
267                digest: [0; S],
268            }
269        }
270    }
271
272    impl<const S: usize> multihash_derive::Hasher for StrobeHasher<S> {
273        fn update(&mut self, input: &[u8]) {
274            self.strobe.ad(input, self.initialized);
275            self.initialized = true;
276        }
277
278        fn finalize(&mut self) -> &[u8] {
279            self.strobe.clone().prf(&mut self.digest, false);
280            &self.digest
281        }
282
283        fn reset(&mut self) {
284            let Self { strobe, .. } = Self::default();
285            self.strobe = strobe;
286            self.initialized = false;
287        }
288    }
289
290    derive_write!(StrobeHasher);
291
292    /// 256 bit strobe hasher.
293    pub type Strobe256 = StrobeHasher<32>;
294
295    /// 512 bit strobe hasher.
296    pub type Strobe512 = StrobeHasher<64>;
297}