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