multihash_codetable/
hasher_impl.rs1#[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 #[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 pub type Blake2b256 = Blake2bHasher<32>;
81
82 pub type Blake2b512 = Blake2bHasher<64>;
84}
85
86#[cfg(feature = "blake2s")]
87pub mod blake2s {
88 derive_hasher_blake!(blake2s_simd, Blake2sHasher);
89
90 pub type Blake2s128 = Blake2sHasher<16>;
92
93 pub type Blake2s256 = Blake2sHasher<32>;
95}
96
97#[cfg(feature = "blake3")]
98pub mod blake3 {
99 #[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 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 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 #[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 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 pub type Strobe256 = StrobeHasher<32>;
294
295 pub type Strobe512 = StrobeHasher<64>;
297}