Skip to main content

zlicenser_protocol/crypto/
hash.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
4pub struct Hash([u8; 32]);
5
6impl Hash {
7    pub fn as_bytes(&self) -> &[u8; 32] {
8        &self.0
9    }
10
11    pub fn from_bytes(b: [u8; 32]) -> Self {
12        Self(b)
13    }
14}
15
16pub fn hash(input: &[u8]) -> Hash {
17    Hash(*blake3::hash(input).as_bytes())
18}
19
20pub fn keyed_hash(key: &[u8; 32], input: &[u8]) -> Hash {
21    Hash(*blake3::keyed_hash(key, input).as_bytes())
22}
23
24#[cfg(test)]
25mod tests {
26    use super::*;
27
28    // BLAKE3 reference test vectors, input filled with counter bytes 0x00, 0x01, ...
29    // Source: https://github.com/BLAKE3-team/BLAKE3/blob/master/test_vectors/test_vectors.json
30
31    #[test]
32    fn blake3_empty() {
33        let h = hash(&[]);
34        assert_eq!(
35            h.as_bytes(),
36            &[
37                0xaf, 0x13, 0x49, 0xb9, 0xf5, 0xf9, 0xa1, 0xa6, 0xa0, 0x40, 0x4d, 0xea, 0x36, 0xdc,
38                0xc9, 0x49, 0x9b, 0xcb, 0x25, 0xc9, 0xad, 0xc1, 0x12, 0xb7, 0xcc, 0x9a, 0x93, 0xca,
39                0xe4, 0x1f, 0x32, 0x62
40            ]
41        );
42    }
43
44    #[test]
45    fn blake3_one_zero_byte() {
46        let h = hash(&[0x00]);
47        assert_eq!(
48            h.as_bytes(),
49            &[
50                0x2d, 0x3a, 0xde, 0xdf, 0xf1, 0x1b, 0x61, 0xf1, 0x4c, 0x88, 0x6e, 0x35, 0xaf, 0xa0,
51                0x36, 0x73, 0x6d, 0xcd, 0x87, 0xa7, 0x4d, 0x27, 0xb5, 0xc1, 0x51, 0x02, 0x25, 0xd0,
52                0xf5, 0x92, 0xe2, 0x13
53            ]
54        );
55    }
56
57    #[test]
58    fn blake3_single_byte_0x61() {
59        // RFC-style sanity: "a" = 0x61
60        let expected = blake3::hash(b"a");
61        let h = hash(b"a");
62        assert_eq!(h.as_bytes(), expected.as_bytes());
63    }
64
65    #[test]
66    fn blake3_deterministic() {
67        assert_eq!(hash(b"hello"), hash(b"hello"));
68        assert_ne!(hash(b"hello"), hash(b"world"));
69    }
70
71    #[test]
72    fn keyed_hash_differs_from_unkeyed() {
73        let key = [0xaau8; 32];
74        let h = keyed_hash(&key, b"test");
75        let u = hash(b"test");
76        assert_ne!(h.as_bytes(), u.as_bytes());
77    }
78
79    #[test]
80    fn keyed_hash_key_sensitive() {
81        let k1 = [0x01u8; 32];
82        let k2 = [0x02u8; 32];
83        assert_ne!(keyed_hash(&k1, b"data"), keyed_hash(&k2, b"data"));
84    }
85}