nmt_rs/
tendermint_hash.rs

1use sha2::{Digest, Sha256};
2
3use crate::simple_merkle::tree::MerkleHash;
4
5const LEAF_PREFIX: &[u8] = &[0];
6const INNER_PREFIX: &[u8] = &[1];
7
8fn leaf_hash(bytes: &[u8]) -> [u8; 32] {
9    //hash([LEAF_PREFIX, bytes].concat().as_slice())
10    let mut hasher = Sha256::new();
11    hasher.update(LEAF_PREFIX);
12    hasher.update(bytes);
13    hasher.finalize().into()
14}
15
16fn inner_hash(left: &[u8], right: &[u8]) -> [u8; 32] {
17    let mut hasher = Sha256::new();
18    hasher.update(INNER_PREFIX);
19    hasher.update(left);
20    hasher.update(right);
21    hasher.finalize().into()
22}
23
24/// A sha256 hasher, compatible with [Tendermint merkle hash](https://github.com/informalsystems/tendermint-rs/blob/979456c9f33463944f97f7ea3900640e59f7ea6d/tendermint/src/merkle.rs)
25pub struct TmSha2Hasher;
26
27impl Default for TmSha2Hasher {
28    fn default() -> Self {
29        Self::new()
30    }
31}
32
33impl TmSha2Hasher {
34    /// Create a new instance of the hasher
35    pub fn new() -> Self {
36        TmSha2Hasher
37    }
38}
39
40impl MerkleHash for TmSha2Hasher {
41    type Output = [u8; 32];
42
43    const EMPTY_ROOT: Self::Output = [
44        227, 176, 196, 66, 152, 252, 28, 20, 154, 251, 244, 200, 153, 111, 185, 36, 39, 174, 65,
45        228, 100, 155, 147, 76, 164, 149, 153, 27, 120, 82, 184, 85,
46    ];
47
48    fn hash_leaf(&self, data: &[u8]) -> Self::Output {
49        leaf_hash(data)
50    }
51    fn hash_nodes(&self, left: &Self::Output, right: &Self::Output) -> Self::Output {
52        inner_hash(left, right)
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59    use crate::{MemDb, MerkleTree};
60    use tendermint::merkle::simple_hash_from_byte_vectors;
61    #[test]
62    fn test_tm_hash_matches_upstream() {
63        let leaves: Vec<&[u8]> = vec![b"leaf_1", b"leaf_2", b"leaf_3", b"leaf_4"];
64        let hasher = TmSha2Hasher {};
65        let mut tree: MerkleTree<MemDb<[u8; 32]>, TmSha2Hasher> = MerkleTree::with_hasher(hasher);
66        leaves.iter().for_each(|leaf| {
67            tree.push_raw_leaf(leaf);
68        });
69        let hash_from_byte_slices = simple_hash_from_byte_vectors::<Sha256>(leaves.as_slice());
70        assert_eq!(tree.root().as_ref(), &hash_from_byte_slices);
71    }
72}