encryption/hash/
blake2.rs1use blake2::{Blake2b512, Blake2s256, Digest};
8
9use crate::contract::{Hasher, Identified};
10use crate::error::Result;
11
12#[derive(Debug, Default, Clone, Copy)]
14pub struct Blake2b512Hasher;
15
16impl Blake2b512Hasher {
17 pub const IDENTIFIER: &'static str = "blake2b-512";
18
19 pub fn new() -> Self {
20 Self
21 }
22}
23
24impl Identified for Blake2b512Hasher {
25 fn identifier(&self) -> &str {
26 Self::IDENTIFIER
27 }
28}
29
30impl Hasher for Blake2b512Hasher {
31 fn digest(&self, data: &[u8]) -> Result<Vec<u8>> {
32 Ok(Blake2b512::digest(data).to_vec())
33 }
34}
35
36#[derive(Debug, Default, Clone, Copy)]
38pub struct Blake2s256Hasher;
39
40impl Blake2s256Hasher {
41 pub const IDENTIFIER: &'static str = "blake2s-256";
42
43 pub fn new() -> Self {
44 Self
45 }
46}
47
48impl Identified for Blake2s256Hasher {
49 fn identifier(&self) -> &str {
50 Self::IDENTIFIER
51 }
52}
53
54impl Hasher for Blake2s256Hasher {
55 fn digest(&self, data: &[u8]) -> Result<Vec<u8>> {
56 Ok(Blake2s256::digest(data).to_vec())
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
66 fn matches_rfc7693_appendix_vectors() {
67 assert_eq!(
68 Blake2b512Hasher::new().digest_hex(b"abc").unwrap(),
69 "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d1\
70 7d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923"
71 );
72 assert_eq!(
73 Blake2s256Hasher::new().digest_hex(b"abc").unwrap(),
74 "508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982"
75 );
76 assert_eq!(Blake2b512Hasher::new().digest(b"abc").unwrap().len(), 64);
77 assert_eq!(Blake2s256Hasher::new().digest(b"abc").unwrap().len(), 32);
78 }
79
80 #[test]
82 fn digest_hex_is_lowercase_hex() {
83 let hex = Blake2b512Hasher::new().digest_hex(b"abc").unwrap();
84 assert_eq!(hex.len(), 128);
85 assert!(
86 hex.bytes()
87 .all(|b| b.is_ascii_hexdigit() && !b.is_ascii_uppercase())
88 );
89
90 let hex = Blake2s256Hasher::new().digest_hex(b"abc").unwrap();
91 assert_eq!(hex.len(), 64);
92 assert!(
93 hex.bytes()
94 .all(|b| b.is_ascii_hexdigit() && !b.is_ascii_uppercase())
95 );
96 }
97
98 #[test]
100 fn distinct_inputs_distinct_digests() {
101 let hasher = Blake2b512Hasher::new();
102 assert_ne!(
103 hasher.digest(b"abc").unwrap(),
104 hasher.digest(b"abd").unwrap()
105 );
106
107 let hasher = Blake2s256Hasher::new();
108 assert_ne!(
109 hasher.digest(b"abc").unwrap(),
110 hasher.digest(b"abd").unwrap()
111 );
112 }
113}