encryption/hash/
blake3.rs1use crate::contract::{Hasher, Identified};
10use crate::error::Result;
11
12#[derive(Debug, Default, Clone, Copy)]
14pub struct Blake3Hasher;
15
16impl Blake3Hasher {
17 pub const IDENTIFIER: &'static str = "blake3";
18
19 pub fn new() -> Self {
20 Self
21 }
22}
23
24impl Identified for Blake3Hasher {
25 fn identifier(&self) -> &str {
26 Self::IDENTIFIER
27 }
28}
29
30impl Hasher for Blake3Hasher {
31 fn digest(&self, data: &[u8]) -> Result<Vec<u8>> {
32 Ok(blake3::hash(data).as_bytes().to_vec())
33 }
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39
40 #[test]
45 fn matches_official_test_vectors() {
46 let hasher = Blake3Hasher::new();
47 assert_eq!(
48 hasher.digest_hex(b"").unwrap(),
49 "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262"
50 );
51 assert_eq!(
52 hasher.digest_hex(&[0x00]).unwrap(),
53 "2d3adedff11b61f14c886e35afa036736dcd87a74d27b5c1510225d0f592e213"
54 );
55 assert_eq!(hasher.digest(b"").unwrap().len(), 32);
56 }
57
58 #[test]
60 fn digest_hex_is_lowercase_hex() {
61 let hex = Blake3Hasher::new().digest_hex(b"abc").unwrap();
62 assert_eq!(hex.len(), 64);
63 assert!(
64 hex.bytes()
65 .all(|b| b.is_ascii_hexdigit() && !b.is_ascii_uppercase())
66 );
67 }
68
69 #[test]
71 fn distinct_inputs_distinct_digests() {
72 let hasher = Blake3Hasher::new();
73 assert_ne!(
74 hasher.digest(b"abc").unwrap(),
75 hasher.digest(b"abd").unwrap()
76 );
77 }
78}