1use crate::classic::crypto_generichash::{
43 GenericHashState, crypto_generichash, crypto_generichash_final, crypto_generichash_init,
44 crypto_generichash_update,
45};
46use crate::constants::{CRYPTO_GENERICHASH_BYTES, CRYPTO_GENERICHASH_KEYBYTES};
47use crate::error::Error;
48pub use crate::types::*;
49
50pub type Hash = StackByteArray<CRYPTO_GENERICHASH_BYTES>;
52pub type Key = StackByteArray<CRYPTO_GENERICHASH_KEYBYTES>;
54
55#[cfg(any(feature = "nightly", all(doc, not(doctest))))]
56#[cfg_attr(all(feature = "nightly", doc), doc(cfg(feature = "nightly")))]
57pub mod protected {
58 use super::*;
77 pub use crate::protected::*;
78
79 pub type Key = HeapByteArray<CRYPTO_GENERICHASH_KEYBYTES>;
82 pub type Hash = HeapByteArray<CRYPTO_GENERICHASH_BYTES>;
85}
86
87pub struct GenericHash<const KEY_LENGTH: usize, const OUTPUT_LENGTH: usize> {
90 state: GenericHashState,
91}
92
93impl<const KEY_LENGTH: usize, const OUTPUT_LENGTH: usize> GenericHash<KEY_LENGTH, OUTPUT_LENGTH> {
94 pub fn new<Key: ByteArray<KEY_LENGTH>>(key: Option<&Key>) -> Result<Self, Error> {
96 Ok(Self {
97 state: crypto_generichash_init(key.map(|k| k.as_slice()), OUTPUT_LENGTH)?,
98 })
99 }
100
101 pub fn update<Input: Bytes + ?Sized>(&mut self, input: &Input) {
103 crypto_generichash_update(&mut self.state, input.as_slice())
104 }
105
106 pub fn finalize<Output: NewByteArray<OUTPUT_LENGTH>>(self) -> Result<Output, Error> {
108 let mut output = Output::new_byte_array();
109
110 crypto_generichash_final(self.state, output.as_mut_slice())?;
111
112 Ok(output)
113 }
114
115 pub fn finalize_to_vec(self) -> Result<Vec<u8>, Error> {
118 self.finalize()
119 }
120
121 pub fn hash<
141 Input: Bytes + ?Sized,
142 Key: ByteArray<KEY_LENGTH>,
143 Output: NewByteArray<OUTPUT_LENGTH>,
144 >(
145 input: &Input,
146 key: Option<&Key>,
147 ) -> Result<Output, Error> {
148 let mut output = Output::new_byte_array();
149 crypto_generichash(
150 output.as_mut_slice(),
151 input.as_slice(),
152 key.map(|k| k.as_slice()),
153 )?;
154 Ok(output)
155 }
156
157 pub fn hash_to_vec<Input: Bytes, Key: ByteArray<KEY_LENGTH>>(
159 input: &Input,
160 key: Option<&Key>,
161 ) -> Result<Vec<u8>, Error> {
162 Self::hash(input, key)
163 }
164}
165
166impl GenericHash<CRYPTO_GENERICHASH_KEYBYTES, CRYPTO_GENERICHASH_BYTES> {
167 pub fn new_with_defaults<Key: ByteArray<CRYPTO_GENERICHASH_KEYBYTES>>(
170 key: Option<&Key>,
171 ) -> Result<Self, Error> {
172 Ok(Self {
173 state: crypto_generichash_init(key.map(|k| k.as_slice()), CRYPTO_GENERICHASH_BYTES)?,
174 })
175 }
176
177 pub fn hash_with_defaults<
180 Input: Bytes + ?Sized,
181 Key: ByteArray<CRYPTO_GENERICHASH_KEYBYTES>,
182 Output: NewByteArray<CRYPTO_GENERICHASH_BYTES>,
183 >(
184 input: &Input,
185 key: Option<&Key>,
186 ) -> Result<Output, Error> {
187 Self::hash(input, key)
188 }
189
190 pub fn hash_with_defaults_to_vec<
193 Input: Bytes + ?Sized,
194 Key: ByteArray<CRYPTO_GENERICHASH_KEYBYTES>,
195 >(
196 input: &Input,
197 key: Option<&Key>,
198 ) -> Result<Vec<u8>, Error> {
199 Self::hash(input, key)
200 }
201}
202
203#[cfg(test)]
204mod tests {
205 use super::*;
206
207 #[test]
208 fn test_generichash() {
209 use base64::Engine as _;
210 use base64::engine::general_purpose;
211
212 let mut hasher = GenericHash::new_with_defaults::<Key>(None).expect("new hash failed");
213 hasher.update(b"hello");
214
215 let output: Vec<u8> = hasher.finalize().expect("finalize failed");
216
217 assert_eq!(
218 general_purpose::STANDARD.encode(output),
219 "Mk3PAn3UowqTLEQfNlol6GsXPe+kuOWJSCU0cbgbcs8="
220 );
221
222 let mut hasher = GenericHash::new_with_defaults::<Key>(None).expect("new hash failed");
223 hasher.update(b"hello");
224
225 let output = hasher.finalize_to_vec().expect("finalize failed");
226
227 assert_eq!(
228 general_purpose::STANDARD.encode(output),
229 "Mk3PAn3UowqTLEQfNlol6GsXPe+kuOWJSCU0cbgbcs8="
230 );
231 }
232
233 #[test]
234 fn test_generichash_onetime() {
235 use base64::Engine as _;
236 use base64::engine::general_purpose;
237
238 let output: Hash =
239 GenericHash::hash(b"hello", Some(b"a very secret key")).expect("hash failed");
240
241 assert_eq!(
242 general_purpose::STANDARD.encode(&output),
243 "AECDe+XJsB6nOkbCsbS/OPXdzpcRm3AolW/Bg1LFY9A="
244 );
245
246 let output: Vec<u8> =
247 GenericHash::hash_with_defaults::<_, Key, _>(b"hello", None).expect("hash failed");
248
249 assert_eq!(
250 general_purpose::STANDARD.encode(output),
251 "Mk3PAn3UowqTLEQfNlol6GsXPe+kuOWJSCU0cbgbcs8="
252 );
253
254 let output =
255 GenericHash::hash_with_defaults_to_vec::<_, Key>(b"hello", None).expect("hash failed");
256
257 assert_eq!(
258 general_purpose::STANDARD.encode(output),
259 "Mk3PAn3UowqTLEQfNlol6GsXPe+kuOWJSCU0cbgbcs8="
260 );
261 }
262 #[test]
263 fn test_generichash_onetime_empty() {
264 use base64::Engine as _;
265 use base64::engine::general_purpose;
266
267 let output =
268 GenericHash::hash_with_defaults_to_vec::<_, Key>(&[], None).expect("hash failed");
269
270 assert_eq!(
271 general_purpose::STANDARD.encode(output),
272 "DldRwCblQ7Loqy6wYJnaodHl30d3j3eH+qtFzfEv46g="
273 );
274 }
275
276 #[test]
277 fn test_vectors() {
278 let test_vec = |input, key, hash| {
279 let input = hex::decode(input).expect("decode input");
280 let key = hex::decode(key).expect("decode key");
281 let expected_hash = hex::decode(hash).expect("decode hash");
282
283 let hash: Vec<u8> =
284 GenericHash::<64, 64>::hash(&input, Some(&key)).expect("hash failed");
285
286 assert_eq!(expected_hash, hash);
287 };
288
289 test_vec("", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", "10ebb67700b1868efb4417987acf4690ae9d972fb7a590c2f02871799aaa4786b5e996e8f0f4eb981fc214b005f42d2ff4233499391653df7aefcbc13fc51568");
290 test_vec("00", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", "961f6dd1e4dd30f63901690c512e78e4b45e4742ed197c3c5e45c549fd25f2e4187b0bc9fe30492b16b0d0bc4ef9b0f34c7003fac09a5ef1532e69430234cebd");
291 test_vec("0001", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", "da2cfbe2d8409a0f38026113884f84b50156371ae304c4430173d08a99d9fb1b983164a3770706d537f49e0c916d9f32b95cc37a95b99d857436f0232c88a965");
292 test_vec("000102", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", "33d0825dddf7ada99b0e7e307104ad07ca9cfd9692214f1561356315e784f3e5a17e364ae9dbb14cb2036df932b77f4b292761365fb328de7afdc6d8998f5fc1");
293 test_vec("00010203", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", "beaa5a3d08f3807143cf621d95cd690514d0b49efff9c91d24b59241ec0eefa5f60196d407048bba8d2146828ebcb0488d8842fd56bb4f6df8e19c4b4daab8ac");
294 test_vec("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfc", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", "a6213743568e3b3158b9184301f3690847554c68457cb40fc9a4b8cfd8d4a118c301a07737aeda0f929c68913c5f51c80394f53bff1c3e83b2e40ca97eba9e15");
295 test_vec("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfd", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", "d444bfa2362a96df213d070e33fa841f51334e4e76866b8139e8af3bb3398be2dfaddcbc56b9146de9f68118dc5829e74b0c28d7711907b121f9161cb92b69a9");
296 test_vec("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfe", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", "142709d62e28fcccd0af97fad0f8465b971e82201dc51070faa0372aa43e92484be1c1e73ba10906d5d1853db6a4106e0a7bf9800d373d6dee2d46d62ef2a461");
297 }
298}