1pub mod proof;
4
5pub use proof::Proof;
6
7use core::marker::PhantomData;
8
9use digest::{consts::U32, Digest, FixedOutputReset};
10
11use crate::crypto::Sha256;
12use crate::prelude::*;
13
14pub use crate::crypto::sha256::HASH_SIZE;
16
17pub type Hash = [u8; HASH_SIZE];
19
20pub fn simple_hash_from_byte_vectors<H>(byte_vecs: &[impl AsRef<[u8]>]) -> Hash
24where
25 H: MerkleHash + Default,
26{
27 let mut hasher = H::default();
28 hasher.hash_byte_vectors(byte_vecs)
29}
30
31pub trait MerkleHash {
33 fn empty_hash(&mut self) -> Hash;
37
38 fn leaf_hash(&mut self, bytes: &[u8]) -> Hash;
42
43 fn inner_hash(&mut self, left: Hash, right: Hash) -> Hash;
47
48 fn hash_byte_vectors(&mut self, byte_vecs: &[impl AsRef<[u8]>]) -> Hash {
52 let length = byte_vecs.len();
53 match length {
54 0 => self.empty_hash(),
55 1 => self.leaf_hash(byte_vecs[0].as_ref()),
56 _ => {
57 let split = length.next_power_of_two() / 2;
58 let left = self.hash_byte_vectors(&byte_vecs[..split]);
59 let right = self.hash_byte_vectors(&byte_vecs[split..]);
60 self.inner_hash(left, right)
61 },
62 }
63 }
64}
65
66fn copy_to_hash(output: impl AsRef<[u8]>) -> Hash {
68 let mut hash_bytes = [0u8; HASH_SIZE];
69 hash_bytes.copy_from_slice(output.as_ref());
70 hash_bytes
71}
72
73impl<H> MerkleHash for H
74where
75 H: Digest<OutputSize = U32> + FixedOutputReset,
76{
77 fn empty_hash(&mut self) -> Hash {
78 let digest = self.finalize_reset();
80 copy_to_hash(digest)
81 }
82
83 fn leaf_hash(&mut self, bytes: &[u8]) -> Hash {
84 Digest::update(self, [0x00]);
86 Digest::update(self, bytes);
87
88 let digest = self.finalize_reset();
90
91 copy_to_hash(digest)
92 }
93
94 fn inner_hash(&mut self, left: Hash, right: Hash) -> Hash {
95 Digest::update(self, [0x01]);
97 Digest::update(self, left);
98 Digest::update(self, right);
99
100 let digest = self.finalize_reset();
102
103 copy_to_hash(digest)
104 }
105}
106
107pub struct NonIncremental<H>(PhantomData<H>);
110
111impl<H> Default for NonIncremental<H> {
112 fn default() -> Self {
113 Self(Default::default())
114 }
115}
116
117impl<H: Sha256> MerkleHash for NonIncremental<H> {
118 fn empty_hash(&mut self) -> Hash {
119 let digest = H::digest([]);
120 copy_to_hash(digest)
121 }
122
123 fn leaf_hash(&mut self, bytes: &[u8]) -> Hash {
124 let mut buf = Vec::with_capacity(1 + bytes.len());
126 buf.push(0);
127 buf.extend_from_slice(bytes);
128 let digest = H::digest(buf);
129 copy_to_hash(digest)
130 }
131
132 fn inner_hash(&mut self, left: Hash, right: Hash) -> Hash {
133 let mut buf = [0u8; 1 + HASH_SIZE * 2];
135 buf[0] = 1;
136 buf[1..HASH_SIZE + 1].copy_from_slice(&left);
137 buf[HASH_SIZE + 1..].copy_from_slice(&right);
138 let digest = H::digest(buf);
139 copy_to_hash(digest)
140 }
141}
142
143#[cfg(all(test, feature = "rust-crypto"))]
144mod tests {
145 use sha2::Sha256;
146 use subtle_encoding::hex;
147
148 use super::*; #[test]
151 fn test_rfc6962_empty_tree() {
152 let empty_tree_root_hex =
153 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
154 let empty_tree_root = &hex::decode(empty_tree_root_hex).unwrap();
155 let empty_tree: Vec<Vec<u8>> = vec![];
156
157 let root = simple_hash_from_byte_vectors::<Sha256>(&empty_tree);
158 assert_eq!(empty_tree_root, &root);
159 }
160
161 #[test]
162 fn test_rfc6962_empty_leaf() {
163 let empty_leaf_root_hex =
164 "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d";
165 let empty_leaf_root = &hex::decode(empty_leaf_root_hex).unwrap();
166 let one_empty_leaf: Vec<Vec<u8>> = vec![vec![]; 1];
167
168 let root = simple_hash_from_byte_vectors::<Sha256>(&one_empty_leaf);
169 assert_eq!(empty_leaf_root, &root);
170 }
171
172 #[test]
173 fn test_rfc6962_leaf() {
174 let leaf_root_hex = "395aa064aa4c29f7010acfe3f25db9485bbd4b91897b6ad7ad547639252b4d56";
175 let leaf_string = "L123456";
176
177 let leaf_root = &hex::decode(leaf_root_hex).unwrap();
178 let leaf_tree: Vec<Vec<u8>> = vec![leaf_string.as_bytes().to_vec(); 1];
179
180 let root = simple_hash_from_byte_vectors::<Sha256>(&leaf_tree);
181 assert_eq!(leaf_root, &root);
182 }
183
184 #[test]
185 fn test_rfc6962_tree_of_2() {
186 let node_hash_hex = "dc9a0536ff2e196d5a628a5bf377ab247bbddf83342be39699461c1e766e6646";
187 let left = b"N123".to_vec();
188 let right = b"N456".to_vec();
189
190 let node_hash = &hex::decode(node_hash_hex).unwrap();
191 let hash = simple_hash_from_byte_vectors::<Sha256>(&[left, right]);
192 assert_eq!(node_hash, &hash);
193 }
194
195 mod non_incremental {
196 use super::*;
197
198 #[test]
199 fn test_rfc6962_tree_of_2() {
200 let node_hash_hex = "dc9a0536ff2e196d5a628a5bf377ab247bbddf83342be39699461c1e766e6646";
201 let left = b"N123".to_vec();
202 let right = b"N456".to_vec();
203
204 let node_hash = &hex::decode(node_hash_hex).unwrap();
205 let hash = simple_hash_from_byte_vectors::<NonIncremental<Sha256>>(&[left, right]);
206 assert_eq!(node_hash, &hash);
207 }
208 }
209}