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> core2::io::Write for $name<S> {
10 fn write(&mut self, buf: &[u8]) -> core2::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) -> core2::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 derive_write!($name);
65 };
66}
67
68#[cfg(feature = "blake2b")]
69pub mod blake2b {
70 derive_hasher_blake!(blake2b_simd, Blake2bHasher);
71
72 pub type Blake2b256 = Blake2bHasher<32>;
74
75 pub type Blake2b512 = Blake2bHasher<64>;
77}
78
79#[cfg(feature = "blake2s")]
80pub mod blake2s {
81 derive_hasher_blake!(blake2s_simd, Blake2sHasher);
82
83 pub type Blake2s128 = Blake2sHasher<16>;
85
86 pub type Blake2s256 = Blake2sHasher<32>;
88}
89
90#[cfg(feature = "blake3")]
91pub mod blake3 {
92 #[derive(Debug)]
94 pub struct Blake3Hasher<const S: usize> {
95 hasher: ::blake3::Hasher,
96 digest: [u8; S],
97 }
98
99 impl<const S: usize> Blake3Hasher<S> {
100 pub fn finalize_xof_fill(&mut self, digest_out: &mut [u8]) {
102 let mut digest = self.hasher.finalize_xof();
103 digest.fill(digest_out)
104 }
105 }
106
107 impl<const S: usize> Default for Blake3Hasher<S> {
108 fn default() -> Self {
109 let hasher = ::blake3::Hasher::new();
110
111 Self {
112 hasher,
113 digest: [0; S],
114 }
115 }
116 }
117
118 impl<const S: usize> multihash_derive::Hasher for Blake3Hasher<S> {
119 fn update(&mut self, input: &[u8]) {
120 self.hasher.update(input);
121 }
122
123 fn finalize(&mut self) -> &[u8] {
124 let mut output = self.hasher.finalize_xof();
125 output.fill(&mut self.digest);
126 &self.digest
127 }
128
129 fn reset(&mut self) {
130 self.hasher.reset();
131 }
132 }
133
134 derive_write!(Blake3Hasher);
135
136 pub type Blake3_256 = Blake3Hasher<32>;
138}
139
140#[cfg(any(
141 feature = "sha1",
142 feature = "sha2",
143 feature = "sha3",
144 feature = "ripemd"
145))]
146macro_rules! derive_rustcrypto_hasher {
147 ($module:ty, $name:ident, $size:expr) => {
148 #[derive(Debug)]
150 pub struct $name {
151 state: $module,
152 digest: [u8; $size],
153 }
154
155 impl Default for $name {
156 fn default() -> Self {
157 $name {
158 state: Default::default(),
159 digest: [0; $size],
160 }
161 }
162 }
163
164 impl ::multihash_derive::Hasher for $name {
165 fn update(&mut self, input: &[u8]) {
166 use digest::Digest;
167 self.state.update(input)
168 }
169
170 fn finalize(&mut self) -> &[u8] {
171 use digest::Digest;
172 let digest = self.state.clone().finalize();
173 let digest_bytes = digest.as_slice();
174 let digest_out = &mut self.digest[..digest_bytes.len().max($size)];
175 digest_out.copy_from_slice(digest_bytes);
176 digest_out
177 }
178
179 fn reset(&mut self) {
180 use digest::Digest;
181 self.state.reset();
182 }
183 }
184
185 impl core2::io::Write for $name {
186 fn write(&mut self, buf: &[u8]) -> core2::io::Result<usize> {
187 use multihash_derive::Hasher as _;
188
189 self.update(buf);
190 Ok(buf.len())
191 }
192
193 fn flush(&mut self) -> core2::io::Result<()> {
194 Ok(())
195 }
196 }
197 };
198}
199
200#[cfg(feature = "sha1")]
201pub mod sha1 {
202 derive_rustcrypto_hasher!(::sha1::Sha1, Sha1, 20);
203}
204
205#[cfg(feature = "sha2")]
206pub mod sha2 {
207 derive_rustcrypto_hasher!(::sha2::Sha256, Sha2_256, 32);
208 derive_rustcrypto_hasher!(::sha2::Sha512, Sha2_512, 64);
209}
210
211#[cfg(feature = "sha3")]
212pub mod sha3 {
213 derive_rustcrypto_hasher!(::sha3::Sha3_224, Sha3_224, 28);
214 derive_rustcrypto_hasher!(::sha3::Sha3_256, Sha3_256, 32);
215 derive_rustcrypto_hasher!(::sha3::Sha3_384, Sha3_384, 48);
216 derive_rustcrypto_hasher!(::sha3::Sha3_512, Sha3_512, 64);
217
218 derive_rustcrypto_hasher!(::sha3::Keccak224, Keccak224, 28);
219 derive_rustcrypto_hasher!(::sha3::Keccak256, Keccak256, 32);
220 derive_rustcrypto_hasher!(::sha3::Keccak384, Keccak384, 48);
221 derive_rustcrypto_hasher!(::sha3::Keccak512, Keccak512, 64);
222}
223
224#[cfg(feature = "ripemd")]
225pub mod ripemd {
226 derive_rustcrypto_hasher!(::ripemd::Ripemd160, Ripemd160, 20);
227 derive_rustcrypto_hasher!(::ripemd::Ripemd256, Ripemd256, 32);
228 derive_rustcrypto_hasher!(::ripemd::Ripemd320, Ripemd320, 40);
229}
230
231#[cfg(feature = "strobe")]
232pub mod strobe {
233 use strobe_rs::{SecParam, Strobe};
234
235 pub struct StrobeHasher<const S: usize> {
237 strobe: Strobe,
238 initialized: bool,
239 digest: [u8; S],
240 }
241
242 impl<const S: usize> Default for StrobeHasher<S> {
243 fn default() -> Self {
244 Self {
245 strobe: Strobe::new(b"StrobeHash", SecParam::B128),
246 initialized: false,
247 digest: [0; S],
248 }
249 }
250 }
251
252 impl<const S: usize> multihash_derive::Hasher for StrobeHasher<S> {
253 fn update(&mut self, input: &[u8]) {
254 self.strobe.ad(input, self.initialized);
255 self.initialized = true;
256 }
257
258 fn finalize(&mut self) -> &[u8] {
259 self.strobe.clone().prf(&mut self.digest, false);
260 &self.digest
261 }
262
263 fn reset(&mut self) {
264 let Self { strobe, .. } = Self::default();
265 self.strobe = strobe;
266 self.initialized = false;
267 }
268 }
269
270 derive_write!(StrobeHasher);
271
272 pub type Strobe256 = StrobeHasher<32>;
274
275 pub type Strobe512 = StrobeHasher<64>;
277}