use sp_core::H256;
use sp_io::hashing::sha2_256;
pub fn verify_merkle_branch(
leaf: H256,
branch: &[H256],
index: usize,
depth: usize,
root: H256,
) -> bool {
if branch.len() != depth {
return false
}
root == compute_merkle_root(leaf, branch, index)
}
fn compute_merkle_root(leaf: H256, proof: &[H256], index: usize) -> H256 {
let mut value: [u8; 32] = leaf.into();
for (i, node) in proof.iter().enumerate() {
let mut data = [0u8; 64];
if generalized_index_bit(index, i) {
data[0..32].copy_from_slice(node.as_bytes());
data[32..64].copy_from_slice(&value);
value = sha2_256(&data);
} else {
data[0..32].copy_from_slice(&value);
data[32..64].copy_from_slice(node.as_bytes());
value = sha2_256(&data);
}
}
value.into()
}
fn generalized_index_bit(index: usize, position: usize) -> bool {
index & (1 << position) > 0
}
pub const fn subtree_index(generalized_index: usize) -> usize {
generalized_index % (1 << generalized_index_length(generalized_index))
}
pub const fn generalized_index_length(generalized_index: usize) -> usize {
match generalized_index.checked_ilog2() {
Some(v) => v as usize,
None => panic!("checked statically; qed"),
}
}