light_concurrent_merkle_tree/
hash.rs

1use light_bounded_vec::BoundedVec;
2use light_hasher::Hasher;
3
4use crate::errors::ConcurrentMerkleTreeError;
5
6/// Returns the hash of the parent node based on the provided `node` (with its
7/// `node_index`) and `sibling` (with its `sibling_index`).
8pub fn compute_parent_node<H>(
9    node: &[u8; 32],
10    sibling: &[u8; 32],
11    node_index: usize,
12    level: usize,
13) -> Result<[u8; 32], ConcurrentMerkleTreeError>
14where
15    H: Hasher,
16{
17    let is_left = (node_index >> level) & 1 == 0;
18    let hash = if is_left {
19        H::hashv(&[node, sibling])?
20    } else {
21        H::hashv(&[sibling, node])?
22    };
23    Ok(hash)
24}
25
26/// Computes the root for the given `leaf` (with index `i`) and `proof`. It
27/// doesn't perform the validation of the provided `proof`.
28pub fn compute_root<H>(
29    leaf: &[u8; 32],
30    leaf_index: usize,
31    proof: &BoundedVec<[u8; 32]>,
32) -> Result<[u8; 32], ConcurrentMerkleTreeError>
33where
34    H: Hasher,
35{
36    let mut node = *leaf;
37    for (level, sibling) in proof.iter().enumerate() {
38        node = compute_parent_node::<H>(&node, sibling, leaf_index, level)?;
39    }
40    Ok(node)
41}