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 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 #[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 pub type Blake2b256 = Blake2bHasher<32>;
80
81 pub type Blake2b512 = Blake2bHasher<64>;
83}
84
85#[cfg(feature = "blake2s")]
86pub mod blake2s {
87 derive_hasher_blake!(blake2s_simd, Blake2sHasher);
88
89 pub type Blake2s128 = Blake2sHasher<16>;
91
92 pub type Blake2s256 = Blake2sHasher<32>;
94}
95
96#[cfg(feature = "blake3")]
97pub mod blake3 {
98 #[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 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 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 #[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 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 pub type Strobe256 = StrobeHasher<32>;
292
293 pub type Strobe512 = StrobeHasher<64>;
295}