ore_rs/primitives/
hash.rs1use crate::primitives::{AesBlock, Hash, HashKey};
2use aes::cipher::{generic_array::GenericArray, BlockEncrypt, KeyInit};
3use aes::Aes128;
4use zeroize::ZeroizeOnDrop;
5
6#[derive(ZeroizeOnDrop)]
7pub struct Aes128Z2Hash {
8 cipher: Aes128,
9}
10
11impl Hash for Aes128Z2Hash {
12 fn new(key: &HashKey) -> Self {
13 let key_array = GenericArray::from_slice(key);
14 let cipher = Aes128::new(key_array);
15 Self { cipher }
16 }
17
18 fn hash(&self, data: &[u8]) -> u8 {
19 assert_eq!(data.len(), 16);
26 let mut output = [0u8; 16];
28 output.clone_from_slice(data);
29 let block = GenericArray::from_mut_slice(&mut output);
30 self.cipher.encrypt_block(block);
31 output[0] & 1u8
32 }
33
34 fn hash_all(&self, data: &mut [AesBlock]) -> Vec<u8> {
36 self.cipher.encrypt_blocks(data);
37
38 let mut vec = Vec::with_capacity(data.len());
39 for &mut block in data {
40 vec.push(block[0] & 1u8);
42 }
43
44 vec
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51 use hex_literal::hex;
52
53 fn init_hash() -> Aes128Z2Hash {
54 let key: [u8; 16] = hex!("00010203 04050607 08090a0b 0c0d0e0f");
55 let key_array = GenericArray::from_slice(&key);
56 Hash::new(key_array)
57 }
58
59 #[test]
60 fn hash_test_1() {
61 let hash = init_hash();
62 let input: [u8; 16] = hex!("00010203 04050607 08090a0b 0c0d0eaa");
63
64 assert_eq!(1u8, hash.hash(&input));
65 }
66
67 #[test]
68 fn hash_test_2() {
69 let hash = init_hash();
70 let input: [u8; 16] = hex!("00010203 04050607 08090a0b 0c0d0e0f");
71
72 assert_eq!(0u8, hash.hash(&input));
73 }
74
75 #[test]
76 #[should_panic(expected = "assertion failed")]
77 fn hash_test_input_too_small() {
78 let hash = init_hash();
79 let input: [u8; 8] = hex!("00010203 04050607");
80
81 assert_eq!(0u8, hash.hash(&input));
82 }
83
84 #[test]
85 #[should_panic(expected = "assertion failed")]
86 fn hash_test_input_too_large() {
87 let hash = init_hash();
88 let input: [u8; 24] = hex!("00010203 04050607 ffffffff bbbbbbbb cccccccc abababab");
89
90 hash.hash(&input);
91 }
92}