1use crate::classic::crypto_generichash::{
44 GenericHashState, crypto_generichash, crypto_generichash_final, crypto_generichash_init,
45 crypto_generichash_update,
46};
47use crate::constants::{CRYPTO_GENERICHASH_BYTES, CRYPTO_GENERICHASH_KEYBYTES};
48use crate::error::Error;
49pub use crate::types::*;
50
51pub type Hash = StackByteArray<CRYPTO_GENERICHASH_BYTES>;
53pub type Key = StackByteArray<CRYPTO_GENERICHASH_KEYBYTES>;
55
56#[cfg(any(all(feature = "protected", any(unix, windows)), all(doc, not(doctest))))]
57#[cfg_attr(all(feature = "nightly", doc), doc(cfg(feature = "protected")))]
58pub mod protected {
59 use super::*;
76 pub use crate::protected::*;
77
78 pub type Key = HeapByteArray<CRYPTO_GENERICHASH_KEYBYTES>;
81 pub type Hash = HeapByteArray<CRYPTO_GENERICHASH_BYTES>;
84}
85
86pub struct GenericHash<const KEY_LENGTH: usize, const OUTPUT_LENGTH: usize> {
89 state: GenericHashState,
90}
91
92impl<const KEY_LENGTH: usize, const OUTPUT_LENGTH: usize> GenericHash<KEY_LENGTH, OUTPUT_LENGTH> {
93 pub fn new<Key: ByteArray<KEY_LENGTH>>(key: Option<&Key>) -> Result<Self, Error> {
100 Ok(Self {
101 state: crypto_generichash_init(key.map(|k| k.as_slice()), OUTPUT_LENGTH)?,
102 })
103 }
104
105 pub fn update<Input: Bytes + ?Sized>(&mut self, input: &Input) {
107 crypto_generichash_update(&mut self.state, input.as_slice())
108 }
109
110 pub fn finalize<Output: NewByteArray<OUTPUT_LENGTH>>(self) -> Result<Output, Error> {
117 let mut output = Output::new_byte_array();
118
119 crypto_generichash_final(self.state, output.as_mut_slice())?;
120
121 Ok(output)
122 }
123
124 pub fn finalize_to_vec(self) -> Result<Vec<u8>, Error> {
132 self.finalize()
133 }
134
135 pub fn hash<
161 Input: Bytes + ?Sized,
162 Key: ByteArray<KEY_LENGTH>,
163 Output: NewByteArray<OUTPUT_LENGTH>,
164 >(
165 input: &Input,
166 key: Option<&Key>,
167 ) -> Result<Output, Error> {
168 let mut output = Output::new_byte_array();
169 crypto_generichash(
170 output.as_mut_slice(),
171 input.as_slice(),
172 key.map(|k| k.as_slice()),
173 )?;
174 Ok(output)
175 }
176
177 pub fn hash_to_vec<Input: Bytes, Key: ByteArray<KEY_LENGTH>>(
183 input: &Input,
184 key: Option<&Key>,
185 ) -> Result<Vec<u8>, Error> {
186 Self::hash(input, key)
187 }
188}
189
190impl GenericHash<CRYPTO_GENERICHASH_KEYBYTES, CRYPTO_GENERICHASH_BYTES> {
191 pub fn new_with_defaults<Key: ByteArray<CRYPTO_GENERICHASH_KEYBYTES>>(
200 key: Option<&Key>,
201 ) -> Result<Self, Error> {
202 Ok(Self {
203 state: crypto_generichash_init(key.map(|k| k.as_slice()), CRYPTO_GENERICHASH_BYTES)?,
204 })
205 }
206
207 pub fn hash_with_defaults<
216 Input: Bytes + ?Sized,
217 Key: ByteArray<CRYPTO_GENERICHASH_KEYBYTES>,
218 Output: NewByteArray<CRYPTO_GENERICHASH_BYTES>,
219 >(
220 input: &Input,
221 key: Option<&Key>,
222 ) -> Result<Output, Error> {
223 Self::hash(input, key)
224 }
225
226 pub fn hash_with_defaults_to_vec<
235 Input: Bytes + ?Sized,
236 Key: ByteArray<CRYPTO_GENERICHASH_KEYBYTES>,
237 >(
238 input: &Input,
239 key: Option<&Key>,
240 ) -> Result<Vec<u8>, Error> {
241 Self::hash(input, key)
242 }
243}
244
245#[cfg(test)]
246mod tests {
247 use super::*;
248
249 #[test]
250 fn test_generichash() {
251 use base64::Engine as _;
252 use base64::engine::general_purpose;
253
254 let mut hasher = GenericHash::new_with_defaults::<Key>(None).expect("new hash failed");
255 hasher.update(b"hello");
256
257 let output: Vec<u8> = hasher.finalize().expect("finalize failed");
258
259 assert_eq!(
260 general_purpose::STANDARD.encode(output),
261 "Mk3PAn3UowqTLEQfNlol6GsXPe+kuOWJSCU0cbgbcs8="
262 );
263
264 let mut hasher = GenericHash::new_with_defaults::<Key>(None).expect("new hash failed");
265 hasher.update(b"hello");
266
267 let output = hasher.finalize_to_vec().expect("finalize failed");
268
269 assert_eq!(
270 general_purpose::STANDARD.encode(output),
271 "Mk3PAn3UowqTLEQfNlol6GsXPe+kuOWJSCU0cbgbcs8="
272 );
273 }
274
275 #[test]
276 fn test_generichash_onetime() {
277 use base64::Engine as _;
278 use base64::engine::general_purpose;
279
280 let output: Hash =
281 GenericHash::hash(b"hello", Some(b"a very secret key")).expect("hash failed");
282
283 assert_eq!(
284 general_purpose::STANDARD.encode(&output),
285 "AECDe+XJsB6nOkbCsbS/OPXdzpcRm3AolW/Bg1LFY9A="
286 );
287
288 let output: Vec<u8> =
289 GenericHash::hash_with_defaults::<_, Key, _>(b"hello", None).expect("hash failed");
290
291 assert_eq!(
292 general_purpose::STANDARD.encode(output),
293 "Mk3PAn3UowqTLEQfNlol6GsXPe+kuOWJSCU0cbgbcs8="
294 );
295
296 let output =
297 GenericHash::hash_with_defaults_to_vec::<_, Key>(b"hello", None).expect("hash failed");
298
299 assert_eq!(
300 general_purpose::STANDARD.encode(output),
301 "Mk3PAn3UowqTLEQfNlol6GsXPe+kuOWJSCU0cbgbcs8="
302 );
303 }
304 #[test]
305 fn test_generichash_onetime_empty() {
306 use base64::Engine as _;
307 use base64::engine::general_purpose;
308
309 let output =
310 GenericHash::hash_with_defaults_to_vec::<_, Key>(&[], None).expect("hash failed");
311
312 assert_eq!(
313 general_purpose::STANDARD.encode(output),
314 "DldRwCblQ7Loqy6wYJnaodHl30d3j3eH+qtFzfEv46g="
315 );
316 }
317
318 #[test]
319 fn test_vectors() {
320 let test_vec = |input, key, hash| {
321 let input = hex::decode(input).expect("decode input");
322 let key = hex::decode(key).expect("decode key");
323 let expected_hash = hex::decode(hash).expect("decode hash");
324
325 let hash: Vec<u8> =
326 GenericHash::<64, 64>::hash(&input, Some(&key)).expect("hash failed");
327
328 assert_eq!(expected_hash, hash);
329 };
330
331 test_vec("", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", "10ebb67700b1868efb4417987acf4690ae9d972fb7a590c2f02871799aaa4786b5e996e8f0f4eb981fc214b005f42d2ff4233499391653df7aefcbc13fc51568");
332 test_vec("00", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", "961f6dd1e4dd30f63901690c512e78e4b45e4742ed197c3c5e45c549fd25f2e4187b0bc9fe30492b16b0d0bc4ef9b0f34c7003fac09a5ef1532e69430234cebd");
333 test_vec("0001", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", "da2cfbe2d8409a0f38026113884f84b50156371ae304c4430173d08a99d9fb1b983164a3770706d537f49e0c916d9f32b95cc37a95b99d857436f0232c88a965");
334 test_vec("000102", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", "33d0825dddf7ada99b0e7e307104ad07ca9cfd9692214f1561356315e784f3e5a17e364ae9dbb14cb2036df932b77f4b292761365fb328de7afdc6d8998f5fc1");
335 test_vec("00010203", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", "beaa5a3d08f3807143cf621d95cd690514d0b49efff9c91d24b59241ec0eefa5f60196d407048bba8d2146828ebcb0488d8842fd56bb4f6df8e19c4b4daab8ac");
336 test_vec("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfc", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", "a6213743568e3b3158b9184301f3690847554c68457cb40fc9a4b8cfd8d4a118c301a07737aeda0f929c68913c5f51c80394f53bff1c3e83b2e40ca97eba9e15");
337 test_vec("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfd", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", "d444bfa2362a96df213d070e33fa841f51334e4e76866b8139e8af3bb3398be2dfaddcbc56b9146de9f68118dc5829e74b0c28d7711907b121f9161cb92b69a9");
338 test_vec("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfe", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", "142709d62e28fcccd0af97fad0f8465b971e82201dc51070faa0372aa43e92484be1c1e73ba10906d5d1853db6a4106e0a7bf9800d373d6dee2d46d62ef2a461");
339 }
340}