1use crate::proofs::proof_path;
7use crate::{MerkleDimension, MerkleShape};
8use decanter::prelude::{hasher, Hashable, H256};
9
10pub fn add_hash(a: &H256, b: &H256) -> H256 {
12 let c = [a.as_ref(), b.as_ref()].concat();
13 let combined = ring::digest::digest(&ring::digest::SHA256, &c);
14 hasher(combined).into()
15}
16pub fn combine_hash_str<T: ToString>(a: &T, b: &T) -> String {
18 format!("{}{}", a.to_string(), b.to_string())
19}
20pub fn create_merkle_tree<T>(data: &[T]) -> (Box<dyn MerkleShape>, Vec<H256>)
22where
23 T: Hashable,
24{
25 let mut length = data.len();
26 let mut nodes = Vec::new();
27 let mut last_level = Vec::new();
28 for i in data {
29 let h: H256 = i.hash();
30 last_level.push(h);
31 nodes.push(h);
32 }
33 let mut depth = 1;
34 while length > 1 {
35 if length % 2 != 0 {
36 last_level.push(data[length - 1].hash());
37 nodes.push(data[length - 1].hash());
38 length += 1;
39 }
40 let mut temp = Vec::new();
41 for i in 0..length / 2 {
42 let h: H256 = add_hash(&last_level[2 * i], &last_level[2 * i + 1]);
43 temp.push(h);
44 nodes.push(h);
45 }
46 last_level = temp.clone();
47 length /= 2;
48 depth += 1;
49 }
50 let dim = MerkleDimension::new(depth, data.len(), nodes.len());
51 (Box::new(dim), nodes)
52}
53
54pub fn merkle_hash(data: impl AsRef<[u8]>) -> H256 {
56 let tmp: H256 = hasher(data).into();
57 hasher(&tmp).into()
58}
59
60pub fn is_merkle_valid(
63 root: &H256,
64 datum: &H256,
65 proof: &[H256],
66 index: usize,
67 leaf_size: usize,
68) -> bool {
69 let mut h: H256 = *datum;
70 let proof_index = proof_path(index, leaf_size);
71 for i in 0..proof.len() {
72 if proof_index[i] % 2 == 0 {
73 h = add_hash(&proof[i], &h);
74 } else {
75 h = add_hash(&h, &proof[i]);
76 }
77 }
78 *root == h
79}