1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use crypto::sha3::Sha3;
use crypto::digest::Digest;
pub trait Hashable {
fn update_context(&self, context: &mut Sha3);
}
impl <T: AsRef<[u8]>> Hashable for T {
fn update_context(&self, context: &mut Sha3) {
context.input(self.as_ref());
}
}
pub trait HashUtils<U: AsRef<[u8]>> {
fn hash_empty(self) -> U;
fn hash_leaf<T>(self, bytes: &T) -> U where T: Hashable;
fn hash_nodes<T>(self, left: &T, right: &T) -> U where T: Hashable;
}
impl<H: From<[u8; 32]> + AsRef<[u8]>> HashUtils<H> for Sha3 {
fn hash_empty(mut self) -> H {
let mut r: [u8; 32] = [0u8; 32];
self.reset();
self.input(&[]);
self.result(&mut r);
r.into()
}
fn hash_leaf<T>(mut self, bytes: &T) -> H where T: Hashable {
let mut r: [u8; 32] = [0u8; 32];
self.reset();
bytes.update_context(&mut self);
self.result(&mut r);
r.into()
}
fn hash_nodes<T>(mut self, left: &T, right: &T) -> H where T: Hashable {
let mut r: [u8; 32] = [0u8; 32];
self.reset();
left.update_context(&mut self);
right.update_context(&mut self);
self.result(&mut r);
r.into()
}
}