1use crate::hash::Id32;
11
12#[derive(Debug, Clone)]
17pub struct MerkleTree {
18 nodes: Vec<Id32>,
20 leaf_count: usize,
22 padded_leaf_count: usize,
24}
25
26impl MerkleTree {
27 #[must_use]
32 pub fn from_leaves(leaves: &[Id32]) -> Self {
33 assert!(
34 !leaves.is_empty(),
35 "cannot build Merkle tree from empty leaves"
36 );
37
38 let leaf_count = leaves.len();
39 let padded = leaf_count.next_power_of_two();
40 let total_nodes = 2 * padded; let mut nodes = vec![Id32::ZERO; total_nodes];
43
44 for (i, leaf) in leaves.iter().enumerate() {
46 nodes[padded + i] = *leaf;
47 }
48 for i in (1..padded).rev() {
52 let left = nodes[2 * i];
53 let right = nodes[2 * i + 1];
54 nodes[i] = hash_pair(left, right);
55 }
56
57 Self {
58 nodes,
59 leaf_count,
60 padded_leaf_count: padded,
61 }
62 }
63
64 #[must_use]
66 pub fn root(&self) -> Id32 {
67 self.nodes[1]
68 }
69
70 #[must_use]
72 pub fn leaf_count(&self) -> usize {
73 self.leaf_count
74 }
75
76 #[must_use]
78 pub fn depth(&self) -> usize {
79 self.padded_leaf_count.trailing_zeros() as usize
80 }
81
82 #[must_use]
86 pub fn layer(&self, depth: usize) -> &[Id32] {
87 let layer_size = 1usize << depth;
88 let start = layer_size; if start + layer_size > self.nodes.len() {
90 return &[];
91 }
92 &self.nodes[start..start + layer_size]
93 }
94
95 #[must_use]
100 pub fn piece_layer(&self, blocks_per_piece: usize) -> &[Id32] {
101 assert!(
102 blocks_per_piece.is_power_of_two(),
103 "blocks_per_piece must be a power of 2"
104 );
105 let levels_up = blocks_per_piece.trailing_zeros() as usize;
106 let tree_depth = self.depth();
107 if levels_up > tree_depth {
108 return self.layer(0);
110 }
111 self.layer(tree_depth - levels_up)
112 }
113
114 #[must_use]
116 pub fn leaves(&self) -> &[Id32] {
117 let start = self.padded_leaf_count;
118 &self.nodes[start..start + self.leaf_count]
119 }
120
121 #[must_use]
126 pub fn root_from_hashes(hashes: &[Id32]) -> Id32 {
127 if hashes.is_empty() {
128 return Id32::ZERO;
129 }
130 Self::from_leaves(hashes).root()
131 }
132
133 #[must_use]
139 pub fn proof_path(&self, leaf_index: usize) -> Vec<Id32> {
140 assert!(
141 leaf_index < self.padded_leaf_count,
142 "leaf index out of range"
143 );
144 let mut path = Vec::with_capacity(self.depth());
145 let mut idx = self.padded_leaf_count + leaf_index;
146
147 while idx > 1 {
148 let sibling = idx ^ 1;
150 path.push(self.nodes[sibling]);
151 idx /= 2; }
153
154 path
155 }
156
157 #[must_use]
161 pub fn verify_proof(root: Id32, leaf: Id32, leaf_index: usize, proof: &[Id32]) -> bool {
162 let mut hash = leaf;
163 let mut idx = leaf_index;
164
165 for sibling in proof {
166 hash = if idx.is_multiple_of(2) {
167 hash_pair(hash, *sibling)
169 } else {
170 hash_pair(*sibling, hash)
172 };
173 idx /= 2;
174 }
175
176 hash == root
177 }
178}
179
180fn hash_pair(left: Id32, right: Id32) -> Id32 {
182 crate::sha256(&[left.0, right.0].concat())
183}
184
185#[cfg(test)]
186mod tests {
187 use super::*;
188
189 fn leaf(byte: u8) -> Id32 {
190 crate::sha256(&[byte])
191 }
192
193 #[test]
194 fn single_leaf() {
195 let l = leaf(0x01);
196 let tree = MerkleTree::from_leaves(&[l]);
197 assert_eq!(tree.leaf_count(), 1);
199 assert_eq!(tree.depth(), 0);
200 assert_eq!(tree.root(), l);
201 }
202
203 #[test]
204 fn two_leaves() {
205 let l0 = leaf(0x01);
206 let l1 = leaf(0x02);
207 let tree = MerkleTree::from_leaves(&[l0, l1]);
208 assert_eq!(tree.leaf_count(), 2);
209 assert_eq!(tree.depth(), 1);
210 assert_eq!(tree.root(), hash_pair(l0, l1));
211 assert_eq!(tree.leaves(), &[l0, l1]);
212 }
213
214 #[test]
215 fn three_leaves_padded() {
216 let l0 = leaf(0x01);
217 let l1 = leaf(0x02);
218 let l2 = leaf(0x03);
219 let tree = MerkleTree::from_leaves(&[l0, l1, l2]);
220 assert_eq!(tree.leaf_count(), 3);
221 assert_eq!(tree.depth(), 2); let left = hash_pair(l0, l1);
224 let right = hash_pair(l2, Id32::ZERO);
225 assert_eq!(tree.root(), hash_pair(left, right));
226 }
227
228 #[test]
229 fn layer_extraction() {
230 let leaves: Vec<Id32> = (0..4).map(leaf).collect();
231 let tree = MerkleTree::from_leaves(&leaves);
232 assert_eq!(tree.depth(), 2);
233
234 assert_eq!(tree.layer(0).len(), 1);
236 assert_eq!(tree.layer(0)[0], tree.root());
237
238 assert_eq!(tree.layer(1).len(), 2);
240
241 assert_eq!(tree.layer(2).len(), 4);
243 assert_eq!(tree.layer(2)[0], leaves[0]);
244 assert_eq!(tree.layer(2)[3], leaves[3]);
245 }
246
247 #[test]
248 fn piece_layer_extraction() {
249 let leaves: Vec<Id32> = (0..8).map(leaf).collect();
251 let tree = MerkleTree::from_leaves(&leaves);
252 assert_eq!(tree.depth(), 3);
253
254 let pieces = tree.piece_layer(2); assert_eq!(pieces.len(), 4);
256 assert_eq!(pieces[0], hash_pair(leaves[0], leaves[1]));
258 assert_eq!(pieces[1], hash_pair(leaves[2], leaves[3]));
259 }
260
261 #[test]
262 fn root_from_piece_layer_round_trip() {
263 let leaves: Vec<Id32> = (0..8).map(leaf).collect();
264 let tree = MerkleTree::from_leaves(&leaves);
265 let pieces = tree.piece_layer(2);
266 let rebuilt_root = MerkleTree::root_from_hashes(pieces);
268 assert_eq!(rebuilt_root, tree.root());
269 }
270
271 #[test]
272 fn proof_path_generation() {
273 let leaves: Vec<Id32> = (0..4).map(leaf).collect();
274 let tree = MerkleTree::from_leaves(&leaves);
275
276 let proof = tree.proof_path(0);
277 assert_eq!(proof.len(), 2); assert_eq!(proof[0], leaves[1]);
280 assert_eq!(proof[1], hash_pair(leaves[2], leaves[3]));
281 }
282
283 #[test]
284 fn proof_verification_success() {
285 let leaves: Vec<Id32> = (0..4).map(leaf).collect();
286 let tree = MerkleTree::from_leaves(&leaves);
287
288 for (i, &leaf_hash) in leaves.iter().enumerate() {
289 let proof = tree.proof_path(i);
290 assert!(
291 MerkleTree::verify_proof(tree.root(), leaf_hash, i, &proof),
292 "proof failed for leaf {i}"
293 );
294 }
295 }
296
297 #[test]
298 fn proof_verification_failure() {
299 let leaves: Vec<Id32> = (0..4).map(leaf).collect();
300 let tree = MerkleTree::from_leaves(&leaves);
301
302 let proof = tree.proof_path(0);
303 let wrong_leaf = leaf(0xFF);
304 assert!(!MerkleTree::verify_proof(
305 tree.root(),
306 wrong_leaf,
307 0,
308 &proof
309 ));
310 }
311}