arnaucube
arnaucube/miden-cryptoPublic Self-hosted repository
miden-crypto/src/merkle/partial_mt/tests.rs
src/merkle/partial_mt/tests.rsRaw
  1use crate::hash::rpo::RpoDigest;
  2
  3use super::{
  4    super::{int_to_digest, int_to_node, NodeIndex},
  5    PartialMerkleTree, Rpo256,
  6};
  7
  8// TEST DATA
  9// ================================================================================================
 10
 11const NODE22: NodeIndex = NodeIndex::new_unchecked(2, 2);
 12
 13const NODE32: NodeIndex = NodeIndex::new_unchecked(3, 2);
 14const NODE33: NodeIndex = NodeIndex::new_unchecked(3, 3);
 15
 16// TESTS
 17// ================================================================================================
 18
 19// with_paths CONSTRUCTOR TESTS
 20// ------------------------------------------------------------------------------------------------
 21
 22#[test]
 23fn get_root() {
 24    let leaf0 = int_to_digest(0);
 25    let leaf1 = int_to_digest(1);
 26    let leaf2 = int_to_digest(2);
 27    let leaf3 = int_to_digest(3);
 28
 29    let parent0 = calculate_parent_hash(leaf0, 0, leaf1);
 30    let parent1 = calculate_parent_hash(leaf2, 2, leaf3);
 31
 32    let root_exp = calculate_parent_hash(parent0, 0, parent1);
 33
 34    let set =
 35        super::PartialMerkleTree::with_paths([(0, leaf0, vec![*leaf1, *parent1].into())]).unwrap();
 36
 37    assert_eq!(set.root(), root_exp);
 38}
 39
 40#[test]
 41fn add_and_get_paths() {
 42    let value32 = int_to_digest(32);
 43    let value33 = int_to_digest(33);
 44    let value20 = int_to_digest(20);
 45    let value22 = int_to_digest(22);
 46    let value23 = int_to_digest(23);
 47
 48    let value21 = Rpo256::merge(&[value32, value33]);
 49    let value10 = Rpo256::merge(&[value20, value21]);
 50    let value11 = Rpo256::merge(&[value22, value23]);
 51
 52    let path_33 = vec![*value32, *value20, *value11];
 53
 54    let path_22 = vec![*value23, *value10];
 55
 56    let pmt = PartialMerkleTree::with_paths([
 57        (3, value33, path_33.clone().into()),
 58        (2, value22, path_22.clone().into()),
 59    ])
 60    .unwrap();
 61    let stored_path_33 = pmt.get_path(NODE33).unwrap();
 62    let stored_path_22 = pmt.get_path(NODE22).unwrap();
 63
 64    assert_eq!(path_33, *stored_path_33);
 65    assert_eq!(path_22, *stored_path_22);
 66}
 67
 68#[test]
 69fn get_node() {
 70    let path_6 = vec![int_to_node(7), int_to_node(45), int_to_node(123)];
 71    let hash_6 = int_to_digest(6);
 72    let index = NodeIndex::make(3, 6);
 73    let pmt = PartialMerkleTree::with_paths([(index.value(), hash_6, path_6.into())]).unwrap();
 74
 75    assert_eq!(int_to_digest(6u64), pmt.get_node(index).unwrap());
 76}
 77
 78#[test]
 79fn update_leaf() {
 80    let value32 = int_to_digest(32);
 81    let value33 = int_to_digest(33);
 82    let value20 = int_to_digest(20);
 83    let value22 = int_to_digest(22);
 84    let value23 = int_to_digest(23);
 85
 86    let value21 = Rpo256::merge(&[value32, value33]);
 87    let value10 = Rpo256::merge(&[value20, value21]);
 88    let value11 = Rpo256::merge(&[value22, value23]);
 89
 90    let path_33 = vec![*value32, *value20, *value11];
 91
 92    let path_22 = vec![*value23, *value10];
 93
 94    let mut pmt =
 95        PartialMerkleTree::with_paths([(3, value33, path_33.into()), (2, value22, path_22.into())])
 96            .unwrap();
 97
 98    let new_value32 = int_to_digest(132);
 99    let new_value21 = Rpo256::merge(&[new_value32, value33]);
100    let new_value10 = Rpo256::merge(&[value20, new_value21]);
101    let expected_root = Rpo256::merge(&[new_value10, value11]);
102
103    let old_leaf = pmt.update_leaf(NODE32, new_value32).unwrap();
104
105    assert_eq!(value32, old_leaf);
106
107    let new_root = pmt.root();
108
109    assert_eq!(new_root, expected_root);
110}
111
112#[test]
113fn check_leaf_depth() {
114    let value32 = int_to_digest(32);
115    let value33 = int_to_digest(33);
116    let value20 = int_to_digest(20);
117    let value22 = int_to_digest(22);
118    let value23 = int_to_digest(23);
119
120    let value11 = Rpo256::merge(&[value22, value23]);
121
122    let path_33 = vec![*value32, *value20, *value11];
123
124    let pmt = PartialMerkleTree::with_paths([(3, value33, path_33.into())]).unwrap();
125
126    assert_eq!(pmt.get_leaf_depth(0).unwrap(), 2);
127    assert_eq!(pmt.get_leaf_depth(1).unwrap(), 2);
128    assert_eq!(pmt.get_leaf_depth(2).unwrap(), 3);
129    assert_eq!(pmt.get_leaf_depth(3).unwrap(), 3);
130    assert_eq!(pmt.get_leaf_depth(4).unwrap(), 1);
131    assert_eq!(pmt.get_leaf_depth(5).unwrap(), 1);
132    assert_eq!(pmt.get_leaf_depth(6).unwrap(), 1);
133    assert_eq!(pmt.get_leaf_depth(7).unwrap(), 1);
134}
135
136// TODO: add test for add_path function and check correctness of leaf determination (requires
137// inner_nodes iter)
138
139// HELPER FUNCTIONS
140// --------------------------------------------------------------------------------------------
141
142/// Calculates the hash of the parent node by two sibling ones
143/// - node — current node
144/// - node_pos — position of the current node
145/// - sibling — neighboring vertex in the tree
146fn calculate_parent_hash(node: RpoDigest, node_pos: u64, sibling: RpoDigest) -> RpoDigest {
147    let parity = node_pos & 1;
148    if parity == 0 {
149        Rpo256::merge(&[node, sibling])
150    } else {
151        Rpo256::merge(&[sibling, node])
152    }
153}