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> 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        /// 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        derive_write!($name);
65    };
66}
67
68#[cfg(feature = "blake2b")]
69pub mod blake2b {
70    derive_hasher_blake!(blake2b_simd, Blake2bHasher);
71
72    /// 256 bit blake2b hasher.
73    pub type Blake2b256 = Blake2bHasher<32>;
74
75    /// 512 bit blake2b hasher.
76    pub type Blake2b512 = Blake2bHasher<64>;
77}
78
79#[cfg(feature = "blake2s")]
80pub mod blake2s {
81    derive_hasher_blake!(blake2s_simd, Blake2sHasher);
82
83    /// 256 bit blake2s hasher.
84    pub type Blake2s128 = Blake2sHasher<16>;
85
86    /// 512 bit blake2s hasher.
87    pub type Blake2s256 = Blake2sHasher<32>;
88}
89
90#[cfg(feature = "blake3")]
91pub mod blake3 {
92    /// Multihash hasher.
93    #[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        /// using blake3's XOF function, fills the given slice with hash output
101        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    /// blake3-256 hasher.
137    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        /// Multihash hasher.
149        #[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    /// Strobe hasher.
236    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    /// 256 bit strobe hasher.
273    pub type Strobe256 = StrobeHasher<32>;
274
275    /// 512 bit strobe hasher.
276    pub type Strobe512 = StrobeHasher<64>;
277}