rock_n_rollup/plugins/
hasher.rs1use blake2::digest::{Update, VariableOutput};
2use blake2::Blake2bVar;
3
4use crate::core::Runtime;
5
6#[derive(PartialEq, Eq, Debug)]
7pub struct Blake2b512([u8; 64]);
8
9#[derive(PartialEq, Eq, Debug)]
10pub struct Blake2b256([u8; 32]);
11
12pub trait Hasher {
13 fn hash(&mut self, data: &[u8]) -> Blake2b256;
15
16 fn hash_512(&mut self, data: &[u8]) -> Blake2b512;
18}
19
20impl ToString for Blake2b512 {
21 fn to_string(&self) -> String {
22 self.0
23 .iter()
24 .fold(String::default(), |acc, u8| format!("{}{:02x}", acc, u8))
25 }
26}
27
28impl ToString for Blake2b256 {
29 fn to_string(&self) -> String {
30 self.0
31 .iter()
32 .fold(String::default(), |acc, u8| format!("{}{:02x}", acc, u8))
33 }
34}
35
36impl AsRef<[u8]> for Blake2b512 {
37 fn as_ref(&self) -> &[u8] {
38 &self.0
39 }
40}
41
42impl AsRef<[u8]> for Blake2b256 {
43 fn as_ref(&self) -> &[u8] {
44 &self.0
45 }
46}
47
48impl<R> Hasher for R
49where
50 R: Runtime,
51{
52 fn hash(&mut self, data: &[u8]) -> Blake2b256 {
53 let mut hasher = Blake2bVar::new(32).unwrap();
54 hasher.update(data.as_ref());
55 let mut buf = [0u8; 32];
56 hasher.finalize_variable(&mut buf).unwrap();
57 Blake2b256(buf)
58 }
59
60 fn hash_512(&mut self, data: &[u8]) -> Blake2b512 {
61 let mut hasher = Blake2bVar::new(64).unwrap();
62 hasher.update(data.as_ref());
63 let mut buf = [0u8; 64];
64 hasher.finalize_variable(&mut buf).unwrap();
65 Blake2b512(buf)
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::Hasher;
72 use crate::core::MockRuntime;
73
74 #[test]
75 fn test_hash_512() {
76 let mut runtime = MockRuntime::default();
77 let data = "hello world".as_bytes().to_vec();
78 let hash = runtime.hash_512(&data);
79 let hash = hash.to_string();
80 assert_eq!(hash, "021ced8799296ceca557832ab941a50b4a11f83478cf141f51f933f653ab9fbcc05a037cddbed06e309bf334942c4e58cdf1a46e237911ccd7fcf9787cbc7fd0");
81 }
82
83 #[test]
84 fn equal_hash_256() {
85 let data1: Vec<u8> = vec![0x01, 0x02, 0x03, 0x04];
86 let data2: Vec<u8> = vec![0x01, 0x02, 0x03, 0x04];
87 let mut runtime = MockRuntime::default();
88 let hash1 = runtime.hash(&data1);
89 let hash2 = runtime.hash(&data2);
90
91 assert_eq!(hash1, hash2);
92 }
93
94 #[test]
95 fn not_equal_hash_256() {
96 let data1: Vec<u8> = vec![0x01, 0x02, 0x03, 0x04];
97 let data2: Vec<u8> = vec![0x01, 0x02, 0x03, 0x04, 0x05];
98 let mut runtime = MockRuntime::default();
99 let hash1 = runtime.hash(&data1);
100 let hash2 = runtime.hash(&data2);
101
102 assert_ne!(hash1, hash2);
103 }
104
105 #[test]
106 fn equal_hash_512() {
107 let data1: Vec<u8> = vec![0x01, 0x02, 0x03, 0x04];
108 let data2: Vec<u8> = vec![0x01, 0x02, 0x03, 0x04];
109 let mut runtime = MockRuntime::default();
110 let hash1 = runtime.hash_512(&data1);
111 let hash2 = runtime.hash_512(&data2);
112
113 assert_eq!(hash1, hash2);
114 }
115
116 #[test]
117 fn not_equal_hash_512() {
118 let data1: Vec<u8> = vec![0x01, 0x02, 0x03, 0x04];
119 let data2: Vec<u8> = vec![0x01, 0x02, 0x03, 0x04, 0x05];
120 let mut runtime = MockRuntime::default();
121 let hash1 = runtime.hash_512(&data1);
122 let hash2 = runtime.hash_512(&data2);
123
124 assert_ne!(hash1, hash2);
125 }
126}