driven/binary/
checksum.rs1pub type Blake3Checksum = [u8; 16];
7
8pub fn compute_blake3(data: &[u8]) -> Blake3Checksum {
10 let hash = blake3::hash(data);
11 let mut checksum = [0u8; 16];
12 checksum.copy_from_slice(&hash.as_bytes()[..16]);
13 checksum
14}
15
16pub fn verify_blake3(data: &[u8], expected: &Blake3Checksum) -> bool {
18 let computed = compute_blake3(data);
19 computed == *expected
20}
21
22pub fn full_blake3(data: &[u8]) -> [u8; 32] {
24 *blake3::hash(data).as_bytes()
25}
26
27pub fn keyed_blake3(key: &[u8; 32], data: &[u8]) -> [u8; 32] {
29 *blake3::keyed_hash(key, data).as_bytes()
30}
31
32#[derive(Debug)]
34pub struct Blake3Hasher {
35 hasher: blake3::Hasher,
36}
37
38impl Blake3Hasher {
39 pub fn new() -> Self {
41 Self {
42 hasher: blake3::Hasher::new(),
43 }
44 }
45
46 pub fn new_keyed(key: &[u8; 32]) -> Self {
48 Self {
49 hasher: blake3::Hasher::new_keyed(key),
50 }
51 }
52
53 pub fn update(&mut self, data: &[u8]) {
55 self.hasher.update(data);
56 }
57
58 pub fn finalize(self) -> Blake3Checksum {
60 let hash = self.hasher.finalize();
61 let mut checksum = [0u8; 16];
62 checksum.copy_from_slice(&hash.as_bytes()[..16]);
63 checksum
64 }
65
66 pub fn finalize_full(self) -> [u8; 32] {
68 *self.hasher.finalize().as_bytes()
69 }
70}
71
72impl Default for Blake3Hasher {
73 fn default() -> Self {
74 Self::new()
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 #[test]
83 fn test_compute_verify() {
84 let data = b"Hello, World!";
85 let checksum = compute_blake3(data);
86
87 assert!(verify_blake3(data, &checksum));
88 assert!(!verify_blake3(b"Different data", &checksum));
89 }
90
91 #[test]
92 fn test_incremental() {
93 let data = b"Hello, World!";
94
95 let direct = compute_blake3(data);
96
97 let mut hasher = Blake3Hasher::new();
98 hasher.update(b"Hello, ");
99 hasher.update(b"World!");
100 let incremental = hasher.finalize();
101
102 assert_eq!(direct, incremental);
103 }
104
105 #[test]
106 fn test_full_hash() {
107 let data = b"test";
108 let hash = full_blake3(data);
109 assert_eq!(hash.len(), 32);
110 }
111
112 #[test]
113 fn test_keyed_hash() {
114 let key = [0u8; 32];
115 let data = b"test";
116
117 let hash1 = keyed_blake3(&key, data);
118 let hash2 = keyed_blake3(&key, data);
119
120 assert_eq!(hash1, hash2);
121 }
122}