refactor: refactor crypto APIs to use RpoDigest instead of Word
jump to
@@ -409,7 +409,7 @@ |(index, value)| {
// The MerkleTree automatically updates its internal root, the Store maintains // the old root and adds the new one. Here we update the root to have a fair // comparison - store_root = store.set_node(root, index, value).unwrap().root; + store_root = store.set_node(root, index, value.into()).unwrap().root; black_box(store_root) }, BatchSize::SmallInput,@@ -455,7 +455,7 @@ |(index, value)| {
// The MerkleTree automatically updates its internal root, the Store maintains // the old root and adds the new one. Here we update the root to have a fair // comparison - store_root = store.set_node(root, index, value).unwrap().root; + store_root = store.set_node(root, index, value.into()).unwrap().root; black_box(store_root) }, BatchSize::SmallInput,
@@ -2,7 +2,10 @@ use super::{
Felt, FieldElement, Hasher, Rpo256, RpoDigest, StarkField, ALPHA, INV_ALPHA, ONE, STATE_WIDTH, ZERO, }; -use crate::utils::collections::{BTreeSet, Vec}; +use crate::{ + utils::collections::{BTreeSet, Vec}, + Word, +}; use core::convert::TryInto; use proptest::prelude::*; use rand_utils::rand_value;@@ -232,7 +235,7 @@ Rpo256::hash(&vec);
} } -const EXPECTED: [[Felt; 4]; 19] = [ +const EXPECTED: [Word; 19] = [ [ Felt::new(1502364727743950833), Felt::new(5880949717274681448),
@@ -1,10 +1,5 @@
-use super::{ - Felt, InnerNodeInfo, MerkleError, MerklePath, NodeIndex, Rpo256, RpoDigest, Vec, Word, -}; -use crate::{ - utils::{string::String, uninit_vector, word_to_hex}, - FieldElement, -}; +use super::{InnerNodeInfo, MerkleError, MerklePath, NodeIndex, Rpo256, RpoDigest, Vec, Word}; +use crate::utils::{string::String, uninit_vector, word_to_hex}; use core::{fmt, slice}; use winter_math::log2;@@ -14,7 +9,7 @@
/// A fully-balanced binary Merkle tree (i.e., a tree where the number of leaves is a power of two). #[derive(Debug, Clone, PartialEq, Eq)] pub struct MerkleTree { - nodes: Vec<Word>, + nodes: Vec<RpoDigest>, } impl MerkleTree {@@ -34,10 +29,12 @@ }
// create un-initialized vector to hold all tree nodes let mut nodes = unsafe { uninit_vector(2 * n) }; - nodes[0] = [Felt::ZERO; 4]; + nodes[0] = RpoDigest::default(); // copy leaves into the second part of the nodes vector - nodes[n..].copy_from_slice(&leaves); + nodes[n..].iter_mut().zip(leaves).for_each(|(node, leaf)| { + *node = RpoDigest::from(leaf); + }); // re-interpret nodes as an array of two nodes fused together // Safety: `nodes` will never move here as it is not bound to an external lifetime (i.e.@@ -47,7 +44,7 @@ let pairs = unsafe { slice::from_raw_parts(ptr, n) };
// calculate all internal tree nodes for i in (1..n).rev() { - nodes[i] = Rpo256::merge(&pairs[i]).into(); + nodes[i] = Rpo256::merge(&pairs[i]); } Ok(Self { nodes })@@ -57,7 +54,7 @@ // PUBLIC ACCESSORS
// -------------------------------------------------------------------------------------------- /// Returns the root of this Merkle tree. - pub fn root(&self) -> Word { + pub fn root(&self) -> RpoDigest { self.nodes[1] }@@ -74,7 +71,7 @@ /// # Errors
/// Returns an error if: /// * The specified depth is greater than the depth of the tree. /// * The specified index is not valid for the specified depth. - pub fn get_node(&self, index: NodeIndex) -> Result<Word, MerkleError> { + pub fn get_node(&self, index: NodeIndex) -> Result<RpoDigest, MerkleError> { if index.is_root() { return Err(MerkleError::DepthTooSmall(index.depth())); } else if index.depth() > self.depth() {@@ -120,7 +117,7 @@
/// Returns an iterator over the leaves of this [MerkleTree]. pub fn leaves(&self) -> impl Iterator<Item = (u64, &Word)> { let leaves_start = self.nodes.len() / 2; - self.nodes.iter().skip(leaves_start).enumerate().map(|(i, v)| (i as u64, v)) + self.nodes.iter().skip(leaves_start).enumerate().map(|(i, v)| (i as u64, &**v)) } /// Returns n iterator over every inner node of this [MerkleTree].@@ -159,13 +156,13 @@ let pairs: &'a [[RpoDigest; 2]] = unsafe { slice::from_raw_parts(ptr, n) };
// update the current node let pos = index.to_scalar_index() as usize; - self.nodes[pos] = value; + self.nodes[pos] = value.into(); // traverse to the root, updating each node with the merged values of its parents for _ in 0..index.depth() { index.move_up(); let pos = index.to_scalar_index() as usize; - let value = Rpo256::merge(&pairs[pos]).into(); + let value = Rpo256::merge(&pairs[pos]); self.nodes[pos] = value; }@@ -180,7 +177,7 @@ /// An iterator over every inner node of the [MerkleTree].
/// /// Use this to extract the data of the tree, there is no guarantee on the order of the elements. pub struct InnerNodeIterator<'a> { - nodes: &'a Vec<Word>, + nodes: &'a Vec<RpoDigest>, index: usize, }@@ -258,21 +255,25 @@
#[cfg(test)] mod tests { use super::*; - use crate::merkle::{int_to_node, InnerNodeInfo}; + use crate::{ + merkle::{int_to_leaf, InnerNodeInfo}, + Felt, Word, WORD_SIZE, + }; use core::mem::size_of; use proptest::prelude::*; - const LEAVES4: [Word; 4] = [int_to_node(1), int_to_node(2), int_to_node(3), int_to_node(4)]; + const LEAVES4: [Word; WORD_SIZE] = + [int_to_leaf(1), int_to_leaf(2), int_to_leaf(3), int_to_leaf(4)]; const LEAVES8: [Word; 8] = [ - int_to_node(1), - int_to_node(2), - int_to_node(3), - int_to_node(4), - int_to_node(5), - int_to_node(6), - int_to_node(7), - int_to_node(8), + int_to_leaf(1), + int_to_leaf(2), + int_to_leaf(3), + int_to_leaf(4), + int_to_leaf(5), + int_to_leaf(6), + int_to_leaf(7), + int_to_leaf(8), ]; #[test]@@ -282,7 +283,7 @@ assert_eq!(8, tree.nodes.len());
// leaves were copied correctly for (a, b) in tree.nodes.iter().skip(4).zip(LEAVES4.iter()) { - assert_eq!(a, b); + assert_eq!(*a, RpoDigest::from(*b)); } let (root, node2, node3) = compute_internal_nodes();@@ -299,10 +300,10 @@ fn get_leaf() {
let tree = super::MerkleTree::new(LEAVES4.to_vec()).unwrap(); // check depth 2 - assert_eq!(LEAVES4[0], tree.get_node(NodeIndex::make(2, 0)).unwrap()); - assert_eq!(LEAVES4[1], tree.get_node(NodeIndex::make(2, 1)).unwrap()); - assert_eq!(LEAVES4[2], tree.get_node(NodeIndex::make(2, 2)).unwrap()); - assert_eq!(LEAVES4[3], tree.get_node(NodeIndex::make(2, 3)).unwrap()); + assert_eq!(RpoDigest::from(LEAVES4[0]), tree.get_node(NodeIndex::make(2, 0)).unwrap()); + assert_eq!(RpoDigest::from(LEAVES4[1]), tree.get_node(NodeIndex::make(2, 1)).unwrap()); + assert_eq!(RpoDigest::from(LEAVES4[2]), tree.get_node(NodeIndex::make(2, 2)).unwrap()); + assert_eq!(RpoDigest::from(LEAVES4[3]), tree.get_node(NodeIndex::make(2, 3)).unwrap()); // check depth 1 let (_, node2, node3) = compute_internal_nodes();@@ -318,10 +319,22 @@
let (_, node2, node3) = compute_internal_nodes(); // check depth 2 - assert_eq!(vec![LEAVES4[1], node3], *tree.get_path(NodeIndex::make(2, 0)).unwrap()); - assert_eq!(vec![LEAVES4[0], node3], *tree.get_path(NodeIndex::make(2, 1)).unwrap()); - assert_eq!(vec![LEAVES4[3], node2], *tree.get_path(NodeIndex::make(2, 2)).unwrap()); - assert_eq!(vec![LEAVES4[2], node2], *tree.get_path(NodeIndex::make(2, 3)).unwrap()); + assert_eq!( + vec![RpoDigest::from(LEAVES4[1]), node3], + *tree.get_path(NodeIndex::make(2, 0)).unwrap() + ); + assert_eq!( + vec![RpoDigest::from(LEAVES4[0]), node3], + *tree.get_path(NodeIndex::make(2, 1)).unwrap() + ); + assert_eq!( + vec![RpoDigest::from(LEAVES4[3]), node2], + *tree.get_path(NodeIndex::make(2, 2)).unwrap() + ); + assert_eq!( + vec![RpoDigest::from(LEAVES4[2]), node2], + *tree.get_path(NodeIndex::make(2, 3)).unwrap() + ); // check depth 1 assert_eq!(vec![node3], *tree.get_path(NodeIndex::make(1, 0)).unwrap());@@ -334,7 +347,7 @@ let mut tree = super::MerkleTree::new(LEAVES8.to_vec()).unwrap();
// update one leaf let value = 3; - let new_node = int_to_node(9); + let new_node = int_to_leaf(9); let mut expected_leaves = LEAVES8.to_vec(); expected_leaves[value as usize] = new_node; let expected_tree = super::MerkleTree::new(expected_leaves.clone()).unwrap();@@ -344,7 +357,7 @@ assert_eq!(expected_tree.nodes, tree.nodes);
// update another leaf let value = 6; - let new_node = int_to_node(10); + let new_node = int_to_leaf(10); expected_leaves[value as usize] = new_node; let expected_tree = super::MerkleTree::new(expected_leaves.clone()).unwrap();@@ -417,11 +430,13 @@
// HELPER FUNCTIONS // -------------------------------------------------------------------------------------------- - fn compute_internal_nodes() -> (Word, Word, Word) { - let node2 = Rpo256::hash_elements(&[LEAVES4[0], LEAVES4[1]].concat()); - let node3 = Rpo256::hash_elements(&[LEAVES4[2], LEAVES4[3]].concat()); + fn compute_internal_nodes() -> (RpoDigest, RpoDigest, RpoDigest) { + let node2 = + Rpo256::hash_elements(&[Word::from(LEAVES4[0]), Word::from(LEAVES4[1])].concat()); + let node3 = + Rpo256::hash_elements(&[Word::from(LEAVES4[2]), Word::from(LEAVES4[3])].concat()); let root = Rpo256::merge(&[node2, node3]); - (root.into(), node2.into(), node3.into()) + (root, node2, node3) } }
@@ -1,4 +1,7 @@
-use super::{super::Vec, super::ZERO, Felt, MmrProof, Rpo256, Word}; +use super::{ + super::{RpoDigest, Vec, ZERO}, + Felt, MmrProof, Rpo256, Word, +}; #[derive(Debug, Clone, PartialEq)] pub struct MmrPeaks {@@ -25,7 +28,7 @@ /// All the peaks of every tree in the MMR forest. The peaks are always ordered by number of
/// leaves, starting from the peak with most children, to the one with least. /// /// Invariant: The length of `peaks` must be equal to the number of true bits in `num_leaves`. - pub peaks: Vec<Word>, + pub peaks: Vec<RpoDigest>, } impl MmrPeaks {@@ -38,7 +41,7 @@ pub fn hash_peaks(&self) -> Word {
Rpo256::hash_elements(&self.flatten_and_pad_peaks()).into() } - pub fn verify(&self, value: Word, opening: MmrProof) -> bool { + pub fn verify(&self, value: RpoDigest, opening: MmrProof) -> bool { let root = &self.peaks[opening.peak_index()]; opening.merkle_path.verify(opening.relative_pos() as u64, value, root) }@@ -72,7 +75,15 @@ num_peaks * 4
}; let mut elements = Vec::with_capacity(len); - elements.extend_from_slice(&self.peaks.as_slice().concat()); + elements.extend_from_slice( + &self + .peaks + .as_slice() + .iter() + .map(|digest| digest.into()) + .collect::<Vec<Word>>() + .concat(), + ); elements.resize(len, ZERO); elements }
@@ -10,10 +10,10 @@ //! least number of leaves. The structure preserves the invariant that each tree has different
//! depths, i.e. as part of adding adding a new element to the forest the trees with same depth are //! merged, creating a new tree with depth d+1, this process is continued until the property is //! restabilished. -use super::bit::TrueBitPositionIterator; use super::{ - super::{InnerNodeInfo, MerklePath, Vec}, - MmrPeaks, MmrProof, Rpo256, Word, + super::{InnerNodeInfo, MerklePath, RpoDigest, Vec}, + bit::TrueBitPositionIterator, + MmrPeaks, MmrProof, Rpo256, }; use core::fmt::{Display, Formatter};@@ -38,7 +38,7 @@ /// The trees are in postorder sequential representation. This representation allows for all
/// the elements of every tree in the forest to be stored in the same sequential buffer. It /// also means new elements can be added to the forest, and merging of trees is very cheap with /// no need to copy elements. - pub(super) nodes: Vec<Word>, + pub(super) nodes: Vec<RpoDigest>, } #[derive(Debug, PartialEq, Eq, Copy, Clone)]@@ -129,7 +129,7 @@ ///
/// Note: The leaf position is the 0-indexed number corresponding to the order the leaves were /// added, this corresponds to the MMR size _prior_ to adding the element. So the 1st element /// has position 0, the second position 1, and so on. - pub fn get(&self, pos: usize) -> Result<Word, MmrError> { + pub fn get(&self, pos: usize) -> Result<RpoDigest, MmrError> { // find the target tree responsible for the MMR position let tree_bit = leaf_to_corresponding_tree(pos, self.forest).ok_or(MmrError::InvalidPosition(pos))?;@@ -153,7 +153,7 @@ Ok(value)
} /// Adds a new element to the MMR. - pub fn add(&mut self, el: Word) { + pub fn add(&mut self, el: RpoDigest) { // Note: every node is also a tree of size 1, adding an element to the forest creates a new // rooted-tree of size 1. This may temporarily break the invariant that every tree in the // forest has different sizes, the loop below will eagerly merge trees of same size and@@ -164,7 +164,7 @@ let mut left_offset = self.nodes.len().saturating_sub(2);
let mut right = el; let mut left_tree = 1; while self.forest & left_tree != 0 { - right = *Rpo256::merge(&[self.nodes[left_offset].into(), right.into()]); + right = Rpo256::merge(&[self.nodes[left_offset], right]); self.nodes.push(right); left_offset = left_offset.saturating_sub(nodes_in_forest(left_tree));@@ -176,7 +176,7 @@ }
/// Returns an accumulator representing the current state of the MMR. pub fn accumulator(&self) -> MmrPeaks { - let peaks: Vec<Word> = TrueBitPositionIterator::new(self.forest) + let peaks: Vec<RpoDigest> = TrueBitPositionIterator::new(self.forest) .rev() .map(|bit| nodes_in_forest(1 << bit)) .scan(0, |offset, el| {@@ -212,7 +212,7 @@ tree_bit: u32,
relative_pos: usize, index_offset: usize, mut index: usize, - ) -> (Word, Vec<Word>) { + ) -> (RpoDigest, Vec<RpoDigest>) { // collect the Merkle path let mut tree_depth = tree_bit as usize; let mut path = Vec::with_capacity(tree_depth + 1);@@ -247,7 +247,7 @@ }
impl<T> From<T> for Mmr where - T: IntoIterator<Item = Word>, + T: IntoIterator<Item = RpoDigest>, { fn from(values: T) -> Self { let mut mmr = Mmr::new();
@@ -1,10 +1,14 @@
-use super::bit::TrueBitPositionIterator; -use super::full::{high_bitmask, leaf_to_corresponding_tree, nodes_in_forest}; use super::{ - super::{InnerNodeInfo, Vec, WORD_SIZE, ZERO}, - Mmr, MmrPeaks, Rpo256, Word, + super::{InnerNodeInfo, Vec, WORD_SIZE}, + bit::TrueBitPositionIterator, + full::{high_bitmask, leaf_to_corresponding_tree, nodes_in_forest}, + Mmr, MmrPeaks, Rpo256, }; -use crate::merkle::{int_to_node, MerklePath}; +use crate::{ + hash::rpo::RpoDigest, + merkle::{int_to_node, MerklePath}, + Felt, Word, +}; #[test] fn test_position_equal_or_higher_than_leafs_is_never_contained() {@@ -99,7 +103,7 @@ assert_eq!(nodes_in_forest(1usize << bit), size);
} } -const LEAVES: [Word; 7] = [ +const LEAVES: [RpoDigest; 7] = [ int_to_node(0), int_to_node(1), int_to_node(2),@@ -114,14 +118,38 @@ fn test_mmr_simple() {
let mut postorder = Vec::new(); postorder.push(LEAVES[0]); postorder.push(LEAVES[1]); - postorder.push(*Rpo256::hash_elements(&[LEAVES[0], LEAVES[1]].concat())); + postorder.push(Rpo256::hash_elements( + &[LEAVES[0], LEAVES[1]] + .iter() + .map(|digest| digest.into()) + .collect::<Vec<[Felt; WORD_SIZE]>>() + .concat(), + )); postorder.push(LEAVES[2]); postorder.push(LEAVES[3]); - postorder.push(*Rpo256::hash_elements(&[LEAVES[2], LEAVES[3]].concat())); - postorder.push(*Rpo256::hash_elements(&[postorder[2], postorder[5]].concat())); + postorder.push(Rpo256::hash_elements( + &[LEAVES[2], LEAVES[3]] + .iter() + .map(|digest| digest.into()) + .collect::<Vec<[Felt; WORD_SIZE]>>() + .concat(), + )); + postorder.push(Rpo256::hash_elements( + &[postorder[2], postorder[5]] + .iter() + .map(|digest| digest.into()) + .collect::<Vec<[Felt; WORD_SIZE]>>() + .concat(), + )); postorder.push(LEAVES[4]); postorder.push(LEAVES[5]); - postorder.push(*Rpo256::hash_elements(&[LEAVES[4], LEAVES[5]].concat())); + postorder.push(Rpo256::hash_elements( + &[LEAVES[4], LEAVES[5]] + .iter() + .map(|digest| digest.into()) + .collect::<Vec<[Felt; WORD_SIZE]>>() + .concat(), + )); postorder.push(LEAVES[6]); let mut mmr = Mmr::new();@@ -195,8 +223,20 @@
#[test] fn test_mmr_open() { let mmr: Mmr = LEAVES.into(); - let h01: Word = Rpo256::hash_elements(&LEAVES[0..2].concat()).into(); - let h23: Word = Rpo256::hash_elements(&LEAVES[2..4].concat()).into(); + let h01: RpoDigest = Rpo256::hash_elements( + &LEAVES[0..2] + .iter() + .map(|digest| digest.into()) + .collect::<Vec<[Felt; WORD_SIZE]>>() + .concat(), + ); + let h23: RpoDigest = Rpo256::hash_elements( + &LEAVES[2..4] + .iter() + .map(|digest| digest.into()) + .collect::<Vec<[Felt; WORD_SIZE]>>() + .concat(), + ); // node at pos 7 is the root assert!(mmr.open(7).is_err(), "Element 7 is not in the tree, result should be None");@@ -214,7 +254,7 @@ mmr.accumulator().verify(LEAVES[6], opening),
"MmrProof should be valid for the current accumulator." ); - // nodes 4,5 are detph 1 + // nodes 4,5 are depth 1 let root_to_path = MerklePath::new(vec![LEAVES[4]]); let opening = mmr .open(5)@@ -361,10 +401,34 @@ fn test_mmr_inner_nodes() {
let mmr: Mmr = LEAVES.into(); let nodes: Vec<InnerNodeInfo> = mmr.inner_nodes().collect(); - let h01 = *Rpo256::hash_elements(&[LEAVES[0], LEAVES[1]].concat()); - let h23 = *Rpo256::hash_elements(&[LEAVES[2], LEAVES[3]].concat()); - let h0123 = *Rpo256::hash_elements(&[h01, h23].concat()); - let h45 = *Rpo256::hash_elements(&[LEAVES[4], LEAVES[5]].concat()); + let h01 = Rpo256::hash_elements( + &[LEAVES[0], LEAVES[1]] + .iter() + .map(|digest| digest.into()) + .collect::<Vec<[Felt; WORD_SIZE]>>() + .concat(), + ); + let h23 = Rpo256::hash_elements( + &[LEAVES[2], LEAVES[3]] + .iter() + .map(|digest| digest.into()) + .collect::<Vec<[Felt; WORD_SIZE]>>() + .concat(), + ); + let h0123 = Rpo256::hash_elements( + &[h01, h23] + .iter() + .map(|digest| digest.into()) + .collect::<Vec<[Felt; WORD_SIZE]>>() + .concat(), + ); + let h45 = Rpo256::hash_elements( + &[LEAVES[4], LEAVES[5]] + .iter() + .map(|digest| digest.into()) + .collect::<Vec<[Felt; WORD_SIZE]>>() + .concat(), + ); let postorder = vec![ InnerNodeInfo { value: h01,@@ -396,17 +460,45 @@ fn test_mmr_hash_peaks() {
let mmr: Mmr = LEAVES.into(); let peaks = mmr.accumulator(); - let first_peak = *Rpo256::merge(&[ - Rpo256::hash_elements(&[LEAVES[0], LEAVES[1]].concat()), - Rpo256::hash_elements(&[LEAVES[2], LEAVES[3]].concat()), + let first_peak = Rpo256::merge(&[ + Rpo256::hash_elements( + &[LEAVES[0], LEAVES[1]] + .iter() + .map(|digest| digest.into()) + .collect::<Vec<Word>>() + .concat(), + ), + Rpo256::hash_elements( + &[LEAVES[2], LEAVES[3]] + .iter() + .map(|digest| digest.into()) + .collect::<Vec<Word>>() + .concat(), + ), ]); - let second_peak = *Rpo256::hash_elements(&[LEAVES[4], LEAVES[5]].concat()); + let second_peak = Rpo256::hash_elements( + &[LEAVES[4], LEAVES[5]] + .iter() + .map(|digest| digest.into()) + .collect::<Vec<[Felt; WORD_SIZE]>>() + .concat(), + ); let third_peak = LEAVES[6]; // minimum length is 16 let mut expected_peaks = [first_peak, second_peak, third_peak].to_vec(); - expected_peaks.resize(16, [ZERO; WORD_SIZE]); - assert_eq!(peaks.hash_peaks(), *Rpo256::hash_elements(&expected_peaks.as_slice().concat())); + expected_peaks.resize(16, RpoDigest::default()); + assert_eq!( + peaks.hash_peaks(), + *Rpo256::hash_elements( + &expected_peaks + .as_slice() + .iter() + .map(|digest| digest.into()) + .collect::<Vec<Word>>() + .concat() + ) + ); } #[test]@@ -422,10 +514,17 @@ };
// minimum length is 16 let mut expected_peaks = peaks.clone(); - expected_peaks.resize(16, [ZERO; WORD_SIZE]); + expected_peaks.resize(16, RpoDigest::default()); assert_eq!( accumulator.hash_peaks(), - *Rpo256::hash_elements(&expected_peaks.as_slice().concat()) + *Rpo256::hash_elements( + &expected_peaks + .as_slice() + .iter() + .map(|digest| digest.into()) + .collect::<Vec<Word>>() + .concat() + ) ); } }@@ -441,10 +540,17 @@ };
// odd length bigger than 16 is padded to the next even nubmer let mut expected_peaks = peaks.clone(); - expected_peaks.resize(18, [ZERO; WORD_SIZE]); + expected_peaks.resize(18, RpoDigest::default()); assert_eq!( accumulator.hash_peaks(), - *Rpo256::hash_elements(&expected_peaks.as_slice().concat()) + *Rpo256::hash_elements( + &expected_peaks + .as_slice() + .iter() + .map(|digest| digest.into()) + .collect::<Vec<Word>>() + .concat() + ) ); }
@@ -10,7 +10,6 @@ // ================================================================================================
mod empty_roots; pub use empty_roots::EmptySubtreeRoots; -use empty_roots::EMPTY_WORD; mod index; pub use index::NodeIndex;@@ -44,7 +43,7 @@ // ================================================================================================
#[derive(Clone, Debug, PartialEq, Eq)] pub enum MerkleError { - ConflictingRoots(Vec<Word>), + ConflictingRoots(Vec<RpoDigest>), DepthTooSmall(u8), DepthTooBig(u64), DuplicateValuesForIndex(u64),@@ -54,9 +53,9 @@ InvalidDepth { expected: u8, provided: u8 },
InvalidPath(MerklePath), InvalidNumEntries(usize, usize), NodeNotInSet(NodeIndex), - NodeNotInStore(Word, NodeIndex), + NodeNotInStore(RpoDigest, NodeIndex), NumLeavesNotPowerOfTwo(usize), - RootNotInStore(Word), + RootNotInStore(RpoDigest), } impl fmt::Display for MerkleError {@@ -95,6 +94,11 @@ // HELPER FUNCTIONS
// ================================================================================================ #[cfg(test)] -const fn int_to_node(value: u64) -> Word { +const fn int_to_node(value: u64) -> RpoDigest { + RpoDigest::new([Felt::new(value), ZERO, ZERO, ZERO]) +} + +#[cfg(test)] +const fn int_to_leaf(value: u64) -> Word { [Felt::new(value), ZERO, ZERO, ZERO] }
@@ -1,9 +1,9 @@
-use super::Word; +use crate::hash::rpo::RpoDigest; /// Representation of a node with two children used for iterating over containers. #[derive(Debug, Clone, PartialEq, Eq)] pub struct InnerNodeInfo { - pub value: Word, - pub left: Word, - pub right: Word, + pub value: RpoDigest, + pub left: RpoDigest, + pub right: RpoDigest, }
@@ -1,4 +1,4 @@
-use super::{vec, InnerNodeInfo, MerkleError, NodeIndex, Rpo256, Vec, Word}; +use super::{vec, InnerNodeInfo, MerkleError, NodeIndex, Rpo256, RpoDigest, Vec}; use core::ops::{Deref, DerefMut}; // MERKLE PATH@@ -7,7 +7,7 @@
/// A merkle path container, composed of a sequence of nodes of a Merkle tree. #[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct MerklePath { - nodes: Vec<Word>, + nodes: Vec<RpoDigest>, } impl MerklePath {@@ -15,7 +15,7 @@ // CONSTRUCTORS
// -------------------------------------------------------------------------------------------- /// Creates a new Merkle path from a list of nodes. - pub fn new(nodes: Vec<Word>) -> Self { + pub fn new(nodes: Vec<RpoDigest>) -> Self { Self { nodes } }@@ -28,13 +28,13 @@ self.nodes.len() as u8
} /// Computes the merkle root for this opening. - pub fn compute_root(&self, index: u64, node: Word) -> Result<Word, MerkleError> { + pub fn compute_root(&self, index: u64, node: RpoDigest) -> Result<RpoDigest, MerkleError> { let mut index = NodeIndex::new(self.depth(), index)?; let root = self.nodes.iter().copied().fold(node, |node, sibling| { // compute the node and move to the next iteration. - let input = index.build_node(node.into(), sibling.into()); + let input = index.build_node(node, sibling); index.move_up(); - Rpo256::merge(&input).into() + Rpo256::merge(&input) }); Ok(root) }@@ -42,7 +42,7 @@
/// Verifies the Merkle opening proof towards the provided root. /// /// Returns `true` if `node` exists at `index` in a Merkle tree with `root`. - pub fn verify(&self, index: u64, node: Word, root: &Word) -> bool { + pub fn verify(&self, index: u64, node: RpoDigest, root: &RpoDigest) -> bool { match self.compute_root(index, node) { Ok(computed_root) => root == &computed_root, Err(_) => false,@@ -55,7 +55,11 @@ /// The iteration order is unspecified.
/// /// # Errors /// Returns an error if the specified index is not valid for this path. - pub fn inner_nodes(&self, index: u64, node: Word) -> Result<InnerNodeIterator, MerkleError> { + pub fn inner_nodes( + &self, + index: u64, + node: RpoDigest, + ) -> Result<InnerNodeIterator, MerkleError> { Ok(InnerNodeIterator { nodes: &self.nodes, index: NodeIndex::new(self.depth(), index)?,@@ -64,8 +68,8 @@ })
} } -impl From<Vec<Word>> for MerklePath { - fn from(path: Vec<Word>) -> Self { +impl From<Vec<RpoDigest>> for MerklePath { + fn from(path: Vec<RpoDigest>) -> Self { Self::new(path) } }@@ -73,7 +77,7 @@
impl Deref for MerklePath { // we use `Vec` here instead of slice so we can call vector mutation methods directly from the // merkle path (example: `Vec::remove`). - type Target = Vec<Word>; + type Target = Vec<RpoDigest>; fn deref(&self) -> &Self::Target { &self.nodes@@ -89,15 +93,15 @@
// ITERATORS // ================================================================================================ -impl FromIterator<Word> for MerklePath { - fn from_iter<T: IntoIterator<Item = Word>>(iter: T) -> Self { +impl FromIterator<RpoDigest> for MerklePath { + fn from_iter<T: IntoIterator<Item = RpoDigest>>(iter: T) -> Self { Self::new(iter.into_iter().collect()) } } impl IntoIterator for MerklePath { - type Item = Word; - type IntoIter = vec::IntoIter<Word>; + type Item = RpoDigest; + type IntoIter = vec::IntoIter<RpoDigest>; fn into_iter(self) -> Self::IntoIter { self.nodes.into_iter()@@ -106,9 +110,9 @@ }
/// An iterator over internal nodes of a [MerklePath]. pub struct InnerNodeIterator<'a> { - nodes: &'a Vec<Word>, + nodes: &'a Vec<RpoDigest>, index: NodeIndex, - value: Word, + value: RpoDigest, } impl<'a> Iterator for InnerNodeIterator<'a> {@@ -123,7 +127,7 @@ } else {
(self.value, self.nodes[sibling_pos]) }; - self.value = Rpo256::merge(&[left.into(), right.into()]).into(); + self.value = Rpo256::merge(&[left, right]); self.index.move_up(); Some(InnerNodeInfo {@@ -144,7 +148,7 @@ /// A container for a [Word] value and its [MerklePath] opening.
#[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct ValuePath { /// The node value opening for `path`. - pub value: Word, + pub value: RpoDigest, /// The path from `value` to `root` (exclusive). pub path: MerklePath, }@@ -156,7 +160,7 @@ /// root. For more information, check [MerklePath::verify].
#[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct RootPath { /// The node value opening for `path`. - pub root: Word, + pub root: RpoDigest, /// The path from `value` to `root` (exclusive). pub path: MerklePath, }
@@ -1,4 +1,5 @@
-use super::{BTreeMap, MerkleError, MerklePath, NodeIndex, Rpo256, ValuePath, Vec, Word, ZERO}; +use super::{BTreeMap, MerkleError, MerklePath, NodeIndex, Rpo256, ValuePath, Vec}; +use crate::{hash::rpo::RpoDigest, Word}; // MERKLE PATH SET // ================================================================================================@@ -6,7 +7,7 @@
/// A set of Merkle paths. #[derive(Debug, Clone, PartialEq, Eq)] pub struct MerklePathSet { - root: Word, + root: RpoDigest, total_depth: u8, paths: BTreeMap<u64, MerklePath>, }@@ -17,7 +18,7 @@ // --------------------------------------------------------------------------------------------
/// Returns an empty MerklePathSet. pub fn new(depth: u8) -> Self { - let root = [ZERO; 4]; + let root = RpoDigest::default(); let paths = BTreeMap::new(); Self {@@ -32,7 +33,7 @@ ///
/// Analogous to `[Self::add_path]`. pub fn with_paths<I>(self, paths: I) -> Result<Self, MerkleError> where - I: IntoIterator<Item = (u64, Word, MerklePath)>, + I: IntoIterator<Item = (u64, RpoDigest, MerklePath)>, { paths.into_iter().try_fold(self, |mut set, (index, value, path)| { set.add_path(index, value, path)?;@@ -44,7 +45,7 @@ // PUBLIC ACCESSORS
// -------------------------------------------------------------------------------------------- /// Returns the root to which all paths in this set resolve. - pub const fn root(&self) -> Word { + pub const fn root(&self) -> RpoDigest { self.root }@@ -61,7 +62,7 @@ /// # Errors
/// Returns an error if: /// * The specified index is not valid for the depth of structure. /// * Requested node does not exist in the set. - pub fn get_node(&self, index: NodeIndex) -> Result<Word, MerkleError> { + pub fn get_node(&self, index: NodeIndex) -> Result<RpoDigest, MerkleError> { if index.depth() != self.total_depth { return Err(MerkleError::InvalidDepth { expected: self.total_depth,@@ -84,7 +85,7 @@ /// * The specified index is not valid for the depth of the structure.
/// * Leaf with the requested path does not exist in the set. pub fn get_leaf(&self, index: u64) -> Result<Word, MerkleError> { let index = NodeIndex::new(self.depth(), index)?; - self.get_node(index) + Ok(self.get_node(index)?.into()) } /// Returns a Merkle path to the node at the specified index. The node itself is@@ -150,7 +151,7 @@ /// different root).
pub fn add_path( &mut self, index_value: u64, - value: Word, + value: RpoDigest, mut path: MerklePath, ) -> Result<(), MerkleError> { let mut index = NodeIndex::new(path.len() as u8, index_value)?;@@ -166,15 +167,15 @@ let parity = index_value & 1;
path.insert(parity as usize, value); // traverse to the root, updating the nodes - let root: Word = Rpo256::merge(&[path[0].into(), path[1].into()]).into(); + let root: RpoDigest = Rpo256::merge(&[path[0], path[1]]); let root = path.iter().skip(2).copied().fold(root, |root, hash| { index.move_up(); - Rpo256::merge(&index.build_node(root.into(), hash.into())).into() + Rpo256::merge(&index.build_node(root, hash)) }); // if the path set is empty (the root is all ZEROs), set the root to the root of the added // path; otherwise, the root of the added path must be identical to the current root - if self.root == [ZERO; 4] { + if self.root == RpoDigest::default() { self.root = root; } else if self.root != root { return Err(MerkleError::ConflictingRoots([self.root, root].to_vec()));@@ -191,7 +192,11 @@ ///
/// # Errors /// Returns an error if: /// * Requested node does not exist in the set. - pub fn update_leaf(&mut self, base_index_value: u64, value: Word) -> Result<(), MerkleError> { + pub fn update_leaf( + &mut self, + base_index_value: u64, + value: RpoDigest, + ) -> Result<(), MerkleError> { let mut index = NodeIndex::new(self.depth(), base_index_value)?; let parity = index.value() & 1; let path_key = index.value() - parity;@@ -203,24 +208,24 @@
// Fill old_hashes vector ----------------------------------------------------------------- let mut current_index = index; let mut old_hashes = Vec::with_capacity(path.len().saturating_sub(2)); - let mut root: Word = Rpo256::merge(&[path[0].into(), path[1].into()]).into(); + let mut root: RpoDigest = Rpo256::merge(&[path[0], path[1]]); for hash in path.iter().skip(2).copied() { old_hashes.push(root); current_index.move_up(); - let input = current_index.build_node(hash.into(), root.into()); - root = Rpo256::merge(&input).into(); + let input = current_index.build_node(hash, root); + root = Rpo256::merge(&input); } // Fill new_hashes vector ----------------------------------------------------------------- path[index.is_value_odd() as usize] = value; let mut new_hashes = Vec::with_capacity(path.len().saturating_sub(2)); - let mut new_root: Word = Rpo256::merge(&[path[0].into(), path[1].into()]).into(); + let mut new_root: RpoDigest = Rpo256::merge(&[path[0], path[1]]); for path_hash in path.iter().skip(2).copied() { new_hashes.push(new_root); index.move_up(); - let input = current_index.build_node(path_hash.into(), new_root.into()); - new_root = Rpo256::merge(&input).into(); + let input = current_index.build_node(path_hash, new_root); + new_root = Rpo256::merge(&input); } self.root = new_root;@@ -345,13 +350,13 @@ let f = int_to_node(6);
let g = int_to_node(7); let h = int_to_node(8); - let i = Rpo256::merge(&[a.into(), b.into()]); - let j = Rpo256::merge(&[c.into(), d.into()]); - let k = Rpo256::merge(&[e.into(), f.into()]); - let l = Rpo256::merge(&[g.into(), h.into()]); + let i = Rpo256::merge(&[a, b]); + let j = Rpo256::merge(&[c, d]); + let k = Rpo256::merge(&[e, f]); + let l = Rpo256::merge(&[g, h]); - let m = Rpo256::merge(&[i.into(), j.into()]); - let n = Rpo256::merge(&[k.into(), l.into()]); + let m = Rpo256::merge(&[i, j]); + let n = Rpo256::merge(&[k, l]); let root = Rpo256::merge(&[m.into(), n.into()]);@@ -359,31 +364,31 @@ let mut set = MerklePathSet::new(3);
let value = b; let index = 1; - let path = MerklePath::new([a.into(), j.into(), n.into()].to_vec()); + let path = MerklePath::new([a, j, n].to_vec()); set.add_path(index, value, path.clone()).unwrap(); - assert_eq!(value, set.get_leaf(index).unwrap()); - assert_eq!(Word::from(root), set.root()); + assert_eq!(*value, set.get_leaf(index).unwrap()); + assert_eq!(RpoDigest::from(root), set.root()); let value = e; let index = 4; let path = MerklePath::new([f.into(), l.into(), m.into()].to_vec()); set.add_path(index, value, path.clone()).unwrap(); - assert_eq!(value, set.get_leaf(index).unwrap()); - assert_eq!(Word::from(root), set.root()); + assert_eq!(*value, set.get_leaf(index).unwrap()); + assert_eq!(RpoDigest::from(root), set.root()); let value = a; let index = 0; let path = MerklePath::new([b.into(), j.into(), n.into()].to_vec()); set.add_path(index, value, path.clone()).unwrap(); - assert_eq!(value, set.get_leaf(index).unwrap()); - assert_eq!(Word::from(root), set.root()); + assert_eq!(*value, set.get_leaf(index).unwrap()); + assert_eq!(RpoDigest::from(root), set.root()); let value = h; let index = 7; let path = MerklePath::new([g.into(), k.into(), m.into()].to_vec()); set.add_path(index, value, path.clone()).unwrap(); - assert_eq!(value, set.get_leaf(index).unwrap()); - assert_eq!(Word::from(root), set.root()); + assert_eq!(*value, set.get_leaf(index).unwrap()); + assert_eq!(RpoDigest::from(root), set.root()); } // HELPER FUNCTIONS@@ -397,11 +402,11 @@ /// Calculates the hash of the parent node by two sibling ones
/// - node — current node /// - node_pos — position of the current node /// - sibling — neighboring vertex in the tree - fn calculate_parent_hash(node: Word, node_pos: u64, sibling: Word) -> Word { + fn calculate_parent_hash(node: RpoDigest, node_pos: u64, sibling: RpoDigest) -> RpoDigest { if is_even(node_pos) { - Rpo256::merge(&[node.into(), sibling.into()]).into() + Rpo256::merge(&[node, sibling]) } else { - Rpo256::merge(&[sibling.into(), node.into()]).into() + Rpo256::merge(&[sibling, node]) } } }
@@ -1,6 +1,6 @@
use super::{ - BTreeMap, BTreeSet, EmptySubtreeRoots, InnerNodeInfo, MerkleError, MerklePath, NodeIndex, - Rpo256, RpoDigest, Vec, Word, EMPTY_WORD, + empty_roots::EMPTY_WORD, BTreeMap, BTreeSet, EmptySubtreeRoots, InnerNodeInfo, MerkleError, + MerklePath, NodeIndex, Rpo256, RpoDigest, Vec, Word, }; #[cfg(test)]@@ -15,7 +15,7 @@ /// The root of the tree is recomputed on each new leaf update.
#[derive(Debug, Clone, PartialEq, Eq)] pub struct SimpleSmt { depth: u8, - root: Word, + root: RpoDigest, leaves: BTreeMap<u64, Word>, branches: BTreeMap<NodeIndex, BranchNode>, empty_hashes: Vec<RpoDigest>,@@ -49,7 +49,7 @@ return Err(MerkleError::DepthTooBig(depth as u64));
} let empty_hashes = EmptySubtreeRoots::empty_hashes(depth).to_vec(); - let root = empty_hashes[0].into(); + let root = empty_hashes[0]; Ok(Self { root,@@ -107,7 +107,7 @@ // PUBLIC ACCESSORS
// -------------------------------------------------------------------------------------------- /// Returns the root of this Merkle tree. - pub const fn root(&self) -> Word { + pub const fn root(&self) -> RpoDigest { self.root }@@ -121,7 +121,7 @@ ///
/// # Errors /// Returns an error if the specified index has depth set to 0 or the depth is greater than /// the depth of this Merkle tree. - pub fn get_node(&self, index: NodeIndex) -> Result<Word, MerkleError> { + pub fn get_node(&self, index: NodeIndex) -> Result<RpoDigest, MerkleError> { if index.is_root() { Err(MerkleError::DepthTooSmall(index.depth())) } else if index.depth() > self.depth() {@@ -129,11 +129,12 @@ Err(MerkleError::DepthTooBig(index.depth() as u64))
} else if index.depth() == self.depth() { // the lookup in empty_hashes could fail only if empty_hashes were not built correctly // by the constructor as we check the depth of the lookup above. - Ok(self - .get_leaf_node(index.value()) - .unwrap_or_else(|| self.empty_hashes[index.depth() as usize].into())) + Ok(RpoDigest::from( + self.get_leaf_node(index.value()) + .unwrap_or_else(|| *self.empty_hashes[index.depth() as usize]), + )) } else { - Ok(self.get_branch_node(&index).parent().into()) + Ok(self.get_branch_node(&index).parent()) } }@@ -143,7 +144,7 @@ /// # Errors
/// Returns an error if the index is greater than the maximum tree capacity, that is 2^{depth}. pub fn get_leaf(&self, index: u64) -> Result<Word, MerkleError> { let index = NodeIndex::new(self.depth, index)?; - self.get_node(index) + Ok(self.get_node(index)?.into()) } /// Returns a Merkle path from the node at the specified index to the root.@@ -166,9 +167,9 @@ let is_right = index.is_value_odd();
index.move_up(); let BranchNode { left, right } = self.get_branch_node(&index); let value = if is_right { left } else { right }; - path.push(*value); + path.push(value); } - Ok(path.into()) + Ok(MerklePath::new(path)) } /// Return a Merkle path from the leaf at the specified index to the root.@@ -193,9 +194,9 @@
/// Returns an iterator over the inner nodes of this Merkle tree. pub fn inner_nodes(&self) -> impl Iterator<Item = InnerNodeInfo> + '_ { self.branches.values().map(|e| InnerNodeInfo { - value: e.parent().into(), - left: e.left.into(), - right: e.right.into(), + value: e.parent(), + left: e.left, + right: e.right, }) }@@ -226,7 +227,7 @@ let (left, right) = if is_right { (left, value) } else { (value, right) };
self.insert_branch_node(index, left, right); value = Rpo256::merge(&[left, right]); } - self.root = value.into(); + self.root = value; Ok(old_value) }
@@ -1,6 +1,10 @@
use super::{ - super::{int_to_node, InnerNodeInfo, MerkleError, MerkleTree, RpoDigest, SimpleSmt}, - NodeIndex, Rpo256, Vec, Word, EMPTY_WORD, + super::{InnerNodeInfo, MerkleError, MerkleTree, RpoDigest, SimpleSmt}, + NodeIndex, Rpo256, Vec, +}; +use crate::{ + merkle::{empty_roots::EMPTY_WORD, int_to_leaf}, + Word, }; // TEST DATA@@ -9,20 +13,20 @@
const KEYS4: [u64; 4] = [0, 1, 2, 3]; const KEYS8: [u64; 8] = [0, 1, 2, 3, 4, 5, 6, 7]; -const VALUES4: [Word; 4] = [int_to_node(1), int_to_node(2), int_to_node(3), int_to_node(4)]; +const VALUES4: [Word; 4] = [int_to_leaf(1), int_to_leaf(2), int_to_leaf(3), int_to_leaf(4)]; const VALUES8: [Word; 8] = [ - int_to_node(1), - int_to_node(2), - int_to_node(3), - int_to_node(4), - int_to_node(5), - int_to_node(6), - int_to_node(7), - int_to_node(8), + int_to_leaf(1), + int_to_leaf(2), + int_to_leaf(3), + int_to_leaf(4), + int_to_leaf(5), + int_to_leaf(6), + int_to_leaf(7), + int_to_leaf(8), ]; -const ZERO_VALUES8: [Word; 8] = [int_to_node(0); 8]; +const ZERO_VALUES8: [Word; 8] = [int_to_leaf(0); 8]; // TESTS // ================================================================================================@@ -32,7 +36,7 @@ fn build_empty_tree() {
// tree of depth 3 let smt = SimpleSmt::new(3).unwrap(); let mt = MerkleTree::new(ZERO_VALUES8.to_vec()).unwrap(); - assert_eq!(mt.root(), smt.root()); + assert_eq!(mt.root(), smt.root().into()); } #[test]@@ -42,11 +46,11 @@ let mut values = ZERO_VALUES8.to_vec();
// insert single value let key = 6; - let new_node = int_to_node(7); + let new_node = int_to_leaf(7); values[key as usize] = new_node; let old_value = smt.update_leaf(key, new_node).expect("Failed to update leaf"); let mt2 = MerkleTree::new(values.clone()).unwrap(); - assert_eq!(mt2.root(), smt.root()); + assert_eq!(mt2.root(), smt.root().into()); assert_eq!( mt2.get_path(NodeIndex::make(3, 6)).unwrap(), smt.get_path(NodeIndex::make(3, 6)).unwrap()@@ -55,11 +59,11 @@ assert_eq!(old_value, EMPTY_WORD);
// insert second value at distinct leaf branch let key = 2; - let new_node = int_to_node(3); + let new_node = int_to_leaf(3); values[key as usize] = new_node; let old_value = smt.update_leaf(key, new_node).expect("Failed to update leaf"); let mt3 = MerkleTree::new(values).unwrap(); - assert_eq!(mt3.root(), smt.root()); + assert_eq!(mt3.root(), smt.root().into()); assert_eq!( mt3.get_path(NodeIndex::make(3, 2)).unwrap(), smt.get_path(NodeIndex::make(3, 2)).unwrap()@@ -78,16 +82,16 @@ assert_eq!(node2, tree.get_node(NodeIndex::make(1, 0)).unwrap());
assert_eq!(node3, tree.get_node(NodeIndex::make(1, 1)).unwrap()); // check get_node() - assert_eq!(VALUES4[0], tree.get_node(NodeIndex::make(2, 0)).unwrap()); - assert_eq!(VALUES4[1], tree.get_node(NodeIndex::make(2, 1)).unwrap()); - assert_eq!(VALUES4[2], tree.get_node(NodeIndex::make(2, 2)).unwrap()); - assert_eq!(VALUES4[3], tree.get_node(NodeIndex::make(2, 3)).unwrap()); + assert_eq!(VALUES4[0], *tree.get_node(NodeIndex::make(2, 0)).unwrap()); + assert_eq!(VALUES4[1], *tree.get_node(NodeIndex::make(2, 1)).unwrap()); + assert_eq!(VALUES4[2], *tree.get_node(NodeIndex::make(2, 2)).unwrap()); + assert_eq!(VALUES4[3], *tree.get_node(NodeIndex::make(2, 3)).unwrap()); // check get_path(): depth 2 - assert_eq!(vec![VALUES4[1], node3], *tree.get_path(NodeIndex::make(2, 0)).unwrap()); - assert_eq!(vec![VALUES4[0], node3], *tree.get_path(NodeIndex::make(2, 1)).unwrap()); - assert_eq!(vec![VALUES4[3], node2], *tree.get_path(NodeIndex::make(2, 2)).unwrap()); - assert_eq!(vec![VALUES4[2], node2], *tree.get_path(NodeIndex::make(2, 3)).unwrap()); + assert_eq!(vec![VALUES4[1].into(), node3], *tree.get_path(NodeIndex::make(2, 0)).unwrap()); + assert_eq!(vec![VALUES4[0].into(), node3], *tree.get_path(NodeIndex::make(2, 1)).unwrap()); + assert_eq!(vec![VALUES4[3].into(), node2], *tree.get_path(NodeIndex::make(2, 2)).unwrap()); + assert_eq!(vec![VALUES4[2].into(), node2], *tree.get_path(NodeIndex::make(2, 3)).unwrap()); // check get_path(): depth 1 assert_eq!(vec![node3], *tree.get_path(NodeIndex::make(1, 0)).unwrap());@@ -99,10 +103,10 @@ fn test_inner_node_iterator() -> Result<(), MerkleError> {
let tree = SimpleSmt::with_leaves(2, KEYS4.into_iter().zip(VALUES4.into_iter())).unwrap(); // check depth 2 - assert_eq!(VALUES4[0], tree.get_node(NodeIndex::make(2, 0)).unwrap()); - assert_eq!(VALUES4[1], tree.get_node(NodeIndex::make(2, 1)).unwrap()); - assert_eq!(VALUES4[2], tree.get_node(NodeIndex::make(2, 2)).unwrap()); - assert_eq!(VALUES4[3], tree.get_node(NodeIndex::make(2, 3)).unwrap()); + assert_eq!(VALUES4[0], *tree.get_node(NodeIndex::make(2, 0)).unwrap()); + assert_eq!(VALUES4[1], *tree.get_node(NodeIndex::make(2, 1)).unwrap()); + assert_eq!(VALUES4[2], *tree.get_node(NodeIndex::make(2, 2)).unwrap()); + assert_eq!(VALUES4[3], *tree.get_node(NodeIndex::make(2, 3)).unwrap()); // get parent nodes let root = tree.root();@@ -142,7 +146,7 @@ let mut tree = SimpleSmt::with_leaves(3, KEYS8.into_iter().zip(VALUES8.into_iter())).unwrap();
// update one value let key = 3; - let new_node = int_to_node(9); + let new_node = int_to_leaf(9); let mut expected_values = VALUES8.to_vec(); expected_values[key] = new_node; let expected_tree = MerkleTree::new(expected_values.clone()).unwrap();@@ -153,7 +157,7 @@ assert_eq!(old_leaf, VALUES8[key]);
// update another value let key = 6; - let new_node = int_to_node(10); + let new_node = int_to_leaf(10); expected_values[key] = new_node; let expected_tree = MerkleTree::new(expected_values.clone()).unwrap();@@ -172,34 +176,34 @@ // e f g h
// / \ / \ / \ / \ // a b 0 0 c 0 0 d - let z = Word::from(RpoDigest::default()); + let z = EMPTY_WORD; let a = Word::from(Rpo256::merge(&[z.into(); 2])); let b = Word::from(Rpo256::merge(&[a.into(); 2])); let c = Word::from(Rpo256::merge(&[b.into(); 2])); let d = Word::from(Rpo256::merge(&[c.into(); 2])); - let e = Word::from(Rpo256::merge(&[a.into(), b.into()])); - let f = Word::from(Rpo256::merge(&[z.into(), z.into()])); - let g = Word::from(Rpo256::merge(&[c.into(), z.into()])); - let h = Word::from(Rpo256::merge(&[z.into(), d.into()])); + let e = RpoDigest::from(Rpo256::merge(&[a.into(), b.into()])); + let f = RpoDigest::from(Rpo256::merge(&[z.into(), z.into()])); + let g = RpoDigest::from(Rpo256::merge(&[c.into(), z.into()])); + let h = RpoDigest::from(Rpo256::merge(&[z.into(), d.into()])); - let i = Word::from(Rpo256::merge(&[e.into(), f.into()])); - let j = Word::from(Rpo256::merge(&[g.into(), h.into()])); + let i = RpoDigest::from(Rpo256::merge(&[e.into(), f.into()])); + let j = RpoDigest::from(Rpo256::merge(&[g.into(), h.into()])); - let k = Word::from(Rpo256::merge(&[i.into(), j.into()])); + let k = RpoDigest::from(Rpo256::merge(&[i.into(), j.into()])); let depth = 3; let entries = vec![(0, a), (1, b), (4, c), (7, d)]; let tree = SimpleSmt::with_leaves(depth, entries).unwrap(); - assert_eq!(tree.root(), Word::from(k)); + assert_eq!(tree.root(), RpoDigest::from(k)); - let cases: Vec<(u8, u64, Vec<Word>)> = vec![ - (3, 0, vec![b, f, j]), - (3, 1, vec![a, f, j]), - (3, 4, vec![z, h, i]), - (3, 7, vec![z, g, i]), + let cases: Vec<(u8, u64, Vec<RpoDigest>)> = vec![ + (3, 0, vec![b.into(), f, j]), + (3, 1, vec![a.into(), f, j]), + (3, 4, vec![z.into(), h, i]), + (3, 7, vec![z.into(), g, i]), (2, 0, vec![f, j]), (2, 1, vec![e, j]), (2, 2, vec![h, i]),@@ -217,26 +221,26 @@ }
#[test] fn fail_on_duplicates() { - let entries = [(1_u64, int_to_node(1)), (5, int_to_node(2)), (1_u64, int_to_node(3))]; + let entries = [(1_u64, int_to_leaf(1)), (5, int_to_leaf(2)), (1_u64, int_to_leaf(3))]; let smt = SimpleSmt::with_leaves(64, entries); assert!(smt.is_err()); - let entries = [(1_u64, int_to_node(0)), (5, int_to_node(2)), (1_u64, int_to_node(0))]; + let entries = [(1_u64, int_to_leaf(0)), (5, int_to_leaf(2)), (1_u64, int_to_leaf(0))]; let smt = SimpleSmt::with_leaves(64, entries); assert!(smt.is_err()); - let entries = [(1_u64, int_to_node(0)), (5, int_to_node(2)), (1_u64, int_to_node(1))]; + let entries = [(1_u64, int_to_leaf(0)), (5, int_to_leaf(2)), (1_u64, int_to_leaf(1))]; let smt = SimpleSmt::with_leaves(64, entries); assert!(smt.is_err()); - let entries = [(1_u64, int_to_node(1)), (5, int_to_node(2)), (1_u64, int_to_node(0))]; + let entries = [(1_u64, int_to_leaf(1)), (5, int_to_leaf(2)), (1_u64, int_to_leaf(0))]; let smt = SimpleSmt::with_leaves(64, entries); assert!(smt.is_err()); } #[test] fn with_no_duplicates_empty_node() { - let entries = [(1_u64, int_to_node(0)), (5, int_to_node(2))]; + let entries = [(1_u64, int_to_leaf(0)), (5, int_to_leaf(2))]; let smt = SimpleSmt::with_leaves(64, entries); assert!(smt.is_ok()); }@@ -244,9 +248,21 @@
// HELPER FUNCTIONS // -------------------------------------------------------------------------------------------- -fn compute_internal_nodes() -> (Word, Word, Word) { - let node2 = Rpo256::hash_elements(&[VALUES4[0], VALUES4[1]].concat()); - let node3 = Rpo256::hash_elements(&[VALUES4[2], VALUES4[3]].concat()); +fn compute_internal_nodes() -> (RpoDigest, RpoDigest, RpoDigest) { + let node2 = Rpo256::hash_elements( + &[VALUES4[0], VALUES4[1]] + .iter() + .map(|digest| *digest) + .collect::<Vec<Word>>() + .concat(), + ); + let node3 = Rpo256::hash_elements( + &[VALUES4[2], VALUES4[3]] + .iter() + .map(|digest| *digest) + .collect::<Vec<Word>>() + .concat(), + ); let root = Rpo256::merge(&[node2, node3]); (root.into(), node2.into(), node3.into())
@@ -1,6 +1,6 @@
use super::{ mmr::Mmr, BTreeMap, EmptySubtreeRoots, InnerNodeInfo, MerkleError, MerklePath, MerklePathSet, - MerkleTree, NodeIndex, RootPath, Rpo256, RpoDigest, SimpleSmt, TieredSmt, ValuePath, Vec, Word, + MerkleTree, NodeIndex, RootPath, Rpo256, RpoDigest, SimpleSmt, TieredSmt, ValuePath, Vec, }; use crate::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable}; use core::borrow::Borrow;@@ -130,21 +130,20 @@ ///
/// This method can return the following errors: /// - `RootNotInStore` if the `root` is not present in the store. /// - `NodeNotInStore` if a node needed to traverse from `root` to `index` is not present in the store. - pub fn get_node(&self, root: Word, index: NodeIndex) -> Result<Word, MerkleError> { - let mut hash: RpoDigest = root.into(); + pub fn get_node(&self, root: RpoDigest, index: NodeIndex) -> Result<RpoDigest, MerkleError> { + let mut hash = root; // corner case: check the root is in the store when called with index `NodeIndex::root()` - self.nodes.get(&hash).ok_or(MerkleError::RootNotInStore(hash.into()))?; + self.nodes.get(&hash).ok_or(MerkleError::RootNotInStore(hash))?; for i in (0..index.depth()).rev() { - let node = - self.nodes.get(&hash).ok_or(MerkleError::NodeNotInStore(hash.into(), index))?; + let node = self.nodes.get(&hash).ok_or(MerkleError::NodeNotInStore(hash, index))?; let bit = (index.value() >> i) & 1; hash = if bit == 0 { node.left } else { node.right } } - Ok(hash.into()) + Ok(hash) } /// Returns the node at the specified `index` and its opening to the `root`.@@ -155,23 +154,22 @@ /// # Errors
/// This method can return the following errors: /// - `RootNotInStore` if the `root` is not present in the store. /// - `NodeNotInStore` if a node needed to traverse from `root` to `index` is not present in the store. - pub fn get_path(&self, root: Word, index: NodeIndex) -> Result<ValuePath, MerkleError> { - let mut hash: RpoDigest = root.into(); + pub fn get_path(&self, root: RpoDigest, index: NodeIndex) -> Result<ValuePath, MerkleError> { + let mut hash = root; let mut path = Vec::with_capacity(index.depth().into()); // corner case: check the root is in the store when called with index `NodeIndex::root()` - self.nodes.get(&hash).ok_or(MerkleError::RootNotInStore(hash.into()))?; + self.nodes.get(&hash).ok_or(MerkleError::RootNotInStore(hash))?; for i in (0..index.depth()).rev() { - let node = - self.nodes.get(&hash).ok_or(MerkleError::NodeNotInStore(hash.into(), index))?; + let node = self.nodes.get(&hash).ok_or(MerkleError::NodeNotInStore(hash, index))?; let bit = (index.value() >> i) & 1; hash = if bit == 0 { - path.push(node.right.into()); + path.push(node.right); node.left } else { - path.push(node.left.into()); + path.push(node.left); node.right } }@@ -180,7 +178,7 @@ // the path is computed from root to leaf, so it must be reversed
path.reverse(); Ok(ValuePath { - value: hash.into(), + value: hash, path: MerklePath::new(path), }) }@@ -202,7 +200,7 @@ /// - The provided `index` is not valid for a depth equivalent to `tree_depth`. For more
/// information, check [NodeIndex::new]. pub fn get_leaf_depth( &self, - root: Word, + root: RpoDigest, tree_depth: u8, index: u64, ) -> Result<u8, MerkleError> {@@ -221,9 +219,9 @@ }
// check if the root exists, providing the proper error report if it doesn't let empty = EmptySubtreeRoots::empty_hashes(tree_depth); - let mut hash: RpoDigest = root.into(); + let mut hash = root; if !self.nodes.contains_key(&hash) { - return Err(MerkleError::RootNotInStore(hash.into())); + return Err(MerkleError::RootNotInStore(hash)); } // we traverse from root to leaf, so the path is reversed@@ -266,11 +264,11 @@ /// The roots for which no descendants exist in this Merkle store are ignored.
pub fn subset<I, R>(&self, roots: I) -> MerkleStore where I: Iterator<Item = R>, - R: Borrow<Word>, + R: Borrow<RpoDigest>, { let mut store = MerkleStore::new(); for root in roots { - let root = RpoDigest::from(*root.borrow()); + let root = *root.borrow(); store.clone_tree_from(root, self); } store@@ -279,9 +277,9 @@
/// Iterator over the inner nodes of the [MerkleStore]. pub fn inner_nodes(&self) -> impl Iterator<Item = InnerNodeInfo> + '_ { self.nodes.iter().map(|(r, n)| InnerNodeInfo { - value: r.into(), - left: n.left.into(), - right: n.right.into(), + value: *r, + left: n.left, + right: n.right, }) }@@ -294,9 +292,9 @@ where
I: Iterator<Item = InnerNodeInfo>, { for node in iter { - let value: RpoDigest = node.value.into(); - let left: RpoDigest = node.left.into(); - let right: RpoDigest = node.right.into(); + let value: RpoDigest = node.value; + let left: RpoDigest = node.left; + let right: RpoDigest = node.right; debug_assert_eq!(Rpo256::merge(&[left, right]), value); self.nodes.insert(value, Node { left, right });@@ -313,13 +311,13 @@ /// include all the nodes into the store.
pub fn add_merkle_path( &mut self, index: u64, - node: Word, + node: RpoDigest, path: MerklePath, - ) -> Result<Word, MerkleError> { - let root = path.inner_nodes(index, node)?.fold(Word::default(), |_, node| { - let value: RpoDigest = node.value.into(); - let left: RpoDigest = node.left.into(); - let right: RpoDigest = node.right.into(); + ) -> Result<RpoDigest, MerkleError> { + let root = path.inner_nodes(index, node)?.fold(RpoDigest::default(), |_, node| { + let value: RpoDigest = node.value; + let left: RpoDigest = node.left; + let right: RpoDigest = node.right; debug_assert_eq!(Rpo256::merge(&[left, right]), value); self.nodes.insert(value, Node { left, right });@@ -337,7 +335,7 @@ ///
/// For further reference, check [MerkleStore::add_merkle_path]. pub fn add_merkle_paths<I>(&mut self, paths: I) -> Result<(), MerkleError> where - I: IntoIterator<Item = (u64, Word, MerklePath)>, + I: IntoIterator<Item = (u64, RpoDigest, MerklePath)>, { for (index_value, node, path) in paths.into_iter() { self.add_merkle_path(index_value, node, path)?;@@ -348,7 +346,10 @@
/// Appends the provided [MerklePathSet] into the store. /// /// For further reference, check [MerkleStore::add_merkle_path]. - pub fn add_merkle_path_set(&mut self, path_set: &MerklePathSet) -> Result<Word, MerkleError> { + pub fn add_merkle_path_set( + &mut self, + path_set: &MerklePathSet, + ) -> Result<RpoDigest, MerkleError> { let root = path_set.root(); for (index, path) in path_set.to_paths() { self.add_merkle_path(index, path.value, path.path)?;@@ -365,9 +366,9 @@ /// - `RootNotInStore` if the `root` is not present in the store.
/// - `NodeNotInStore` if a node needed to traverse from `root` to `index` is not present in the store. pub fn set_node( &mut self, - mut root: Word, + mut root: RpoDigest, index: NodeIndex, - value: Word, + value: RpoDigest, ) -> Result<RootPath, MerkleError> { let node = value; let ValuePath { value, path } = self.get_path(root, index)?;@@ -383,14 +384,21 @@
/// Merges two elements and adds the resulting node into the store. /// /// Merges arbitrary values. They may be leafs, nodes, or a mixture of both. - pub fn merge_roots(&mut self, root1: Word, root2: Word) -> Result<Word, MerkleError> { - let left: RpoDigest = root1.into(); - let right: RpoDigest = root2.into(); - - let parent = Rpo256::merge(&[left, right]); - self.nodes.insert(parent, Node { left, right }); + pub fn merge_roots( + &mut self, + left_root: RpoDigest, + right_root: RpoDigest, + ) -> Result<RpoDigest, MerkleError> { + let parent = Rpo256::merge(&[left_root, right_root]); + self.nodes.insert( + parent, + Node { + left: left_root, + right: right_root, + }, + ); - Ok(parent.into()) + Ok(parent) } // HELPER METHODS@@ -404,7 +412,7 @@ // process the node only if it is in the source
if let Some(node) = source.nodes.get(&root) { // if the node has already been inserted, no need to process it further as all of its // descendants should be already cloned from the source store - if matches!(self.nodes.insert(root, *node), None) { + if self.nodes.insert(root, *node).is_none() { self.clone_tree_from(node.left, source); self.clone_tree_from(node.right, source); }
@@ -1,10 +1,10 @@
use super::{ - super::EMPTY_WORD, Deserializable, EmptySubtreeRoots, MerkleError, MerklePath, MerkleStore, - NodeIndex, RpoDigest, Serializable, + Deserializable, EmptySubtreeRoots, MerkleError, MerklePath, MerkleStore, NodeIndex, RpoDigest, + Serializable, }; use crate::{ hash::rpo::Rpo256, - merkle::{int_to_node, MerklePathSet, MerkleTree, SimpleSmt}, + merkle::{int_to_leaf, int_to_node, MerklePathSet, MerkleTree, SimpleSmt}, Felt, Word, WORD_SIZE, };@@ -15,17 +15,17 @@ // TEST DATA
// ================================================================================================ const KEYS4: [u64; 4] = [0, 1, 2, 3]; -const VALUES4: [Word; 4] = [int_to_node(1), int_to_node(2), int_to_node(3), int_to_node(4)]; +const VALUES4: [Word; 4] = [int_to_leaf(1), int_to_leaf(2), int_to_leaf(3), int_to_leaf(4)]; const VALUES8: [Word; 8] = [ - int_to_node(1), - int_to_node(2), - int_to_node(3), - int_to_node(4), - int_to_node(5), - int_to_node(6), - int_to_node(7), - int_to_node(8), + int_to_leaf(1), + int_to_leaf(2), + int_to_leaf(3), + int_to_leaf(4), + int_to_leaf(5), + int_to_leaf(6), + int_to_leaf(7), + int_to_leaf(8), ]; // TESTS@@ -36,13 +36,13 @@ fn test_root_not_in_store() -> Result<(), MerkleError> {
let mtree = MerkleTree::new(VALUES4.to_vec())?; let store = MerkleStore::from(&mtree); assert_eq!( - store.get_node(VALUES4[0], NodeIndex::make(mtree.depth(), 0)), - Err(MerkleError::RootNotInStore(VALUES4[0])), + store.get_node(VALUES4[0].into(), NodeIndex::make(mtree.depth(), 0)), + Err(MerkleError::RootNotInStore(VALUES4[0].into())), "Leaf 0 is not a root" ); assert_eq!( - store.get_path(VALUES4[0], NodeIndex::make(mtree.depth(), 0)), - Err(MerkleError::RootNotInStore(VALUES4[0])), + store.get_path(VALUES4[0].into(), NodeIndex::make(mtree.depth(), 0)), + Err(MerkleError::RootNotInStore(VALUES4[0].into())), "Leaf 0 is not a root" );@@ -58,22 +58,22 @@ // STORE LEAVES ARE CORRECT -------------------------------------------------------------------
// checks the leaves in the store corresponds to the expected values assert_eq!( store.get_node(mtree.root(), NodeIndex::make(mtree.depth(), 0)), - Ok(VALUES4[0]), + Ok(VALUES4[0].into()), "node 0 must be in the tree" ); assert_eq!( store.get_node(mtree.root(), NodeIndex::make(mtree.depth(), 1)), - Ok(VALUES4[1]), + Ok(VALUES4[1].into()), "node 1 must be in the tree" ); assert_eq!( store.get_node(mtree.root(), NodeIndex::make(mtree.depth(), 2)), - Ok(VALUES4[2]), + Ok(VALUES4[2].into()), "node 2 must be in the tree" ); assert_eq!( store.get_node(mtree.root(), NodeIndex::make(mtree.depth(), 3)), - Ok(VALUES4[3]), + Ok(VALUES4[3].into()), "node 3 must be in the tree" );@@ -104,7 +104,7 @@ // STORE MERKLE PATH MATCHS ==============================================================
// assert the merkle path returned by the store is the same as the one in the tree let result = store.get_path(mtree.root(), NodeIndex::make(mtree.depth(), 0)).unwrap(); assert_eq!( - VALUES4[0], result.value, + VALUES4[0], *result.value, "Value for merkle path at index 0 must match leaf value" ); assert_eq!(@@ -115,7 +115,7 @@ );
let result = store.get_path(mtree.root(), NodeIndex::make(mtree.depth(), 1)).unwrap(); assert_eq!( - VALUES4[1], result.value, + VALUES4[1], *result.value, "Value for merkle path at index 0 must match leaf value" ); assert_eq!(@@ -126,7 +126,7 @@ );
let result = store.get_path(mtree.root(), NodeIndex::make(mtree.depth(), 2)).unwrap(); assert_eq!( - VALUES4[2], result.value, + VALUES4[2], *result.value, "Value for merkle path at index 0 must match leaf value" ); assert_eq!(@@ -137,7 +137,7 @@ );
let result = store.get_path(mtree.root(), NodeIndex::make(mtree.depth(), 3)).unwrap(); assert_eq!( - VALUES4[3], result.value, + VALUES4[3], *result.value, "Value for merkle path at index 0 must match leaf value" ); assert_eq!(@@ -152,7 +152,7 @@
#[test] fn test_empty_roots() { let store = MerkleStore::default(); - let mut root = RpoDigest::new(EMPTY_WORD); + let mut root = RpoDigest::default(); for depth in 0..255 { root = Rpo256::merge(&[root; 2]);@@ -176,13 +176,17 @@
let index = NodeIndex::make(depth, 0); let store_path = store.get_path(smt.root(), index)?; let smt_path = smt.get_path(index)?; - assert_eq!(store_path.value, EMPTY_WORD, "the leaf of an empty tree is always ZERO"); + assert_eq!( + store_path.value, + RpoDigest::default(), + "the leaf of an empty tree is always ZERO" + ); assert_eq!( store_path.path, smt_path, "the returned merkle path does not match the computed values" ); assert_eq!( - store_path.path.compute_root(depth.into(), EMPTY_WORD).unwrap(), + store_path.path.compute_root(depth.into(), RpoDigest::default()).unwrap(), smt.root(), "computed root from the path must match the empty tree root" );@@ -201,16 +205,16 @@
#[test] fn test_add_sparse_merkle_tree_one_level() -> Result<(), MerkleError> { let keys2: [u64; 2] = [0, 1]; - let leaves2: [Word; 2] = [int_to_node(1), int_to_node(2)]; + let leaves2: [Word; 2] = [int_to_leaf(1), int_to_leaf(2)]; let smt = SimpleSmt::with_leaves(1, keys2.into_iter().zip(leaves2.into_iter())).unwrap(); let store = MerkleStore::from(&smt); let idx = NodeIndex::make(1, 0); - assert_eq!(smt.get_node(idx).unwrap(), leaves2[0]); - assert_eq!(store.get_node(smt.root(), idx).unwrap(), smt.get_node(idx).unwrap()); + assert_eq!(smt.get_node(idx).unwrap(), leaves2[0].into()); + assert_eq!(store.get_node(smt.root().into(), idx).unwrap(), smt.get_node(idx).unwrap()); let idx = NodeIndex::make(1, 1); - assert_eq!(smt.get_node(idx).unwrap(), leaves2[1]); + assert_eq!(smt.get_node(idx).unwrap(), leaves2[1].into()); assert_eq!(store.get_node(smt.root(), idx).unwrap(), smt.get_node(idx).unwrap()); Ok(())@@ -227,28 +231,28 @@
// STORE LEAVES ARE CORRECT ============================================================== // checks the leaves in the store corresponds to the expected values assert_eq!( - store.get_node(smt.root(), NodeIndex::make(smt.depth(), 0)), - Ok(VALUES4[0]), + store.get_node(smt.root().into(), NodeIndex::make(smt.depth(), 0)), + Ok(VALUES4[0].into()), "node 0 must be in the tree" ); assert_eq!( - store.get_node(smt.root(), NodeIndex::make(smt.depth(), 1)), - Ok(VALUES4[1]), + store.get_node(smt.root().into(), NodeIndex::make(smt.depth(), 1)), + Ok(VALUES4[1].into()), "node 1 must be in the tree" ); assert_eq!( - store.get_node(smt.root(), NodeIndex::make(smt.depth(), 2)), - Ok(VALUES4[2]), + store.get_node(smt.root().into(), NodeIndex::make(smt.depth(), 2)), + Ok(VALUES4[2].into()), "node 2 must be in the tree" ); assert_eq!( - store.get_node(smt.root(), NodeIndex::make(smt.depth(), 3)), - Ok(VALUES4[3]), + store.get_node(smt.root().into(), NodeIndex::make(smt.depth(), 3)), + Ok(VALUES4[3].into()), "node 3 must be in the tree" ); assert_eq!( - store.get_node(smt.root(), NodeIndex::make(smt.depth(), 4)), - Ok(EMPTY_WORD), + store.get_node(smt.root().into(), NodeIndex::make(smt.depth(), 4)), + Ok(RpoDigest::default()), "unmodified node 4 must be ZERO" );@@ -284,7 +288,7 @@ // STORE MERKLE PATH MATCHS ==============================================================
// assert the merkle path returned by the store is the same as the one in the tree let result = store.get_path(smt.root(), NodeIndex::make(smt.depth(), 0)).unwrap(); assert_eq!( - VALUES4[0], result.value, + VALUES4[0], *result.value, "Value for merkle path at index 0 must match leaf value" ); assert_eq!(@@ -295,7 +299,7 @@ );
let result = store.get_path(smt.root(), NodeIndex::make(smt.depth(), 1)).unwrap(); assert_eq!( - VALUES4[1], result.value, + VALUES4[1], *result.value, "Value for merkle path at index 1 must match leaf value" ); assert_eq!(@@ -306,7 +310,7 @@ );
let result = store.get_path(smt.root(), NodeIndex::make(smt.depth(), 2)).unwrap(); assert_eq!( - VALUES4[2], result.value, + VALUES4[2], *result.value, "Value for merkle path at index 2 must match leaf value" ); assert_eq!(@@ -317,7 +321,7 @@ );
let result = store.get_path(smt.root(), NodeIndex::make(smt.depth(), 3)).unwrap(); assert_eq!( - VALUES4[3], result.value, + VALUES4[3], *result.value, "Value for merkle path at index 3 must match leaf value" ); assert_eq!(@@ -328,7 +332,8 @@ );
let result = store.get_path(smt.root(), NodeIndex::make(smt.depth(), 4)).unwrap(); assert_eq!( - EMPTY_WORD, result.value, + RpoDigest::default(), + result.value, "Value for merkle path at index 4 must match leaf value" ); assert_eq!(@@ -357,10 +362,10 @@ let i3 = 3;
let p3 = mtree.get_path(NodeIndex::make(2, i3)).unwrap(); let paths = [ - (i0, VALUES4[i0 as usize], p0), - (i1, VALUES4[i1 as usize], p1), - (i2, VALUES4[i2 as usize], p2), - (i3, VALUES4[i3 as usize], p3), + (i0, VALUES4[i0 as usize].into(), p0), + (i1, VALUES4[i1 as usize].into(), p1), + (i2, VALUES4[i2 as usize].into(), p2), + (i3, VALUES4[i3 as usize].into(), p3), ]; let mut store = MerkleStore::default();@@ -373,22 +378,22 @@ // STORE LEAVES ARE CORRECT ==============================================================
// checks the leaves in the store corresponds to the expected values assert_eq!( store.get_node(set.root(), NodeIndex::make(set.depth(), 0)), - Ok(VALUES4[0]), + Ok(VALUES4[0].into()), "node 0 must be in the set" ); assert_eq!( store.get_node(set.root(), NodeIndex::make(set.depth(), 1)), - Ok(VALUES4[1]), + Ok(VALUES4[1].into()), "node 1 must be in the set" ); assert_eq!( store.get_node(set.root(), NodeIndex::make(set.depth(), 2)), - Ok(VALUES4[2]), + Ok(VALUES4[2].into()), "node 2 must be in the set" ); assert_eq!( store.get_node(set.root(), NodeIndex::make(set.depth(), 3)), - Ok(VALUES4[3]), + Ok(VALUES4[3].into()), "node 3 must be in the set" );@@ -419,7 +424,7 @@ // STORE MERKLE PATH MATCHS ==============================================================
// assert the merkle path returned by the store is the same as the one in the set let result = store.get_path(set.root(), NodeIndex::make(set.depth(), 0)).unwrap(); assert_eq!( - VALUES4[0], result.value, + VALUES4[0], *result.value, "Value for merkle path at index 0 must match leaf value" ); assert_eq!(@@ -430,7 +435,7 @@ );
let result = store.get_path(set.root(), NodeIndex::make(set.depth(), 1)).unwrap(); assert_eq!( - VALUES4[1], result.value, + VALUES4[1], *result.value, "Value for merkle path at index 0 must match leaf value" ); assert_eq!(@@ -441,7 +446,7 @@ );
let result = store.get_path(set.root(), NodeIndex::make(set.depth(), 2)).unwrap(); assert_eq!( - VALUES4[2], result.value, + VALUES4[2], *result.value, "Value for merkle path at index 0 must match leaf value" ); assert_eq!(@@ -452,7 +457,7 @@ );
let result = store.get_path(set.root(), NodeIndex::make(set.depth(), 3)).unwrap(); assert_eq!( - VALUES4[3], result.value, + VALUES4[3], *result.value, "Value for merkle path at index 0 must match leaf value" ); assert_eq!(@@ -477,7 +482,7 @@ let mut root = Rpo256::merge(&[a.into(), b.into()]);
for depth in (1..=63).rev() { root = Rpo256::merge(&[root, empty[depth]]); } - let root = Word::from(root); + let root = RpoDigest::from(root); // For this example, the depth of the Merkle tree is 1, as we have only two leaves. Here we // attempt to fetch a node on the maximum depth, and it should fail because the root shouldn't@@ -556,20 +561,20 @@ }
let d = 2; let paths = [ - (0, VALUES4[0], mtree.get_path(NodeIndex::make(d, 0)).unwrap()), - (1, VALUES4[1], mtree.get_path(NodeIndex::make(d, 1)).unwrap()), - (2, VALUES4[2], mtree.get_path(NodeIndex::make(d, 2)).unwrap()), - (3, VALUES4[3], mtree.get_path(NodeIndex::make(d, 3)).unwrap()), + (0, VALUES4[0].into(), mtree.get_path(NodeIndex::make(d, 0)).unwrap()), + (1, VALUES4[1].into(), mtree.get_path(NodeIndex::make(d, 1)).unwrap()), + (2, VALUES4[2].into(), mtree.get_path(NodeIndex::make(d, 2)).unwrap()), + (3, VALUES4[3].into(), mtree.get_path(NodeIndex::make(d, 3)).unwrap()), ]; let mut store1 = MerkleStore::default(); store1.add_merkle_paths(paths.clone())?; let mut store2 = MerkleStore::default(); - store2.add_merkle_path(0, VALUES4[0], mtree.get_path(NodeIndex::make(d, 0))?)?; - store2.add_merkle_path(1, VALUES4[1], mtree.get_path(NodeIndex::make(d, 1))?)?; - store2.add_merkle_path(2, VALUES4[2], mtree.get_path(NodeIndex::make(d, 2))?)?; - store2.add_merkle_path(3, VALUES4[3], mtree.get_path(NodeIndex::make(d, 3))?)?; + store2.add_merkle_path(0, VALUES4[0].into(), mtree.get_path(NodeIndex::make(d, 0))?)?; + store2.add_merkle_path(1, VALUES4[1].into(), mtree.get_path(NodeIndex::make(d, 1))?)?; + store2.add_merkle_path(2, VALUES4[2].into(), mtree.get_path(NodeIndex::make(d, 2))?)?; + store2.add_merkle_path(3, VALUES4[3].into(), mtree.get_path(NodeIndex::make(d, 3))?)?; let set = MerklePathSet::new(d).with_paths(paths).unwrap(); for key in [0, 1, 2, 3] {@@ -590,11 +595,11 @@ fn node_path_should_be_truncated_by_midtier_insert() {
let key = 0b11010010_11001100_11001100_11001100_11001100_11001100_11001100_11001100_u64; let mut store = MerkleStore::new(); - let root: Word = EmptySubtreeRoots::empty_hashes(64)[0].into(); + let root: RpoDigest = EmptySubtreeRoots::empty_hashes(64)[0]; // insert first node - works as expected let depth = 64; - let node = [Felt::new(key); WORD_SIZE]; + let node = RpoDigest::from([Felt::new(key); WORD_SIZE]); let index = NodeIndex::new(depth, key).unwrap(); let root = store.set_node(root, index, node).unwrap().root; let result = store.get_node(root, index).unwrap();@@ -607,7 +612,7 @@ // flip the first bit of the key and insert the second node on a different depth
let key = key ^ (1 << 63); let key = key >> 8; let depth = 56; - let node = [Felt::new(key); WORD_SIZE]; + let node = RpoDigest::from([Felt::new(key); WORD_SIZE]); let index = NodeIndex::new(depth, key).unwrap(); let root = store.set_node(root, index, node).unwrap().root; let result = store.get_node(root, index).unwrap();@@ -626,13 +631,13 @@
#[test] fn get_leaf_depth_works_depth_64() { let mut store = MerkleStore::new(); - let mut root: Word = EmptySubtreeRoots::empty_hashes(64)[0].into(); + let mut root: RpoDigest = EmptySubtreeRoots::empty_hashes(64)[0]; let key = u64::MAX; // this will create a rainbow tree and test all opening to depth 64 for d in 0..64 { let k = key & (u64::MAX >> d); - let node = [Felt::new(k); WORD_SIZE]; + let node = RpoDigest::from([Felt::new(k); WORD_SIZE]); let index = NodeIndex::new(64, k).unwrap(); // assert the leaf doesn't exist before the insert. the returned depth should always@@ -649,14 +654,14 @@
#[test] fn get_leaf_depth_works_with_incremental_depth() { let mut store = MerkleStore::new(); - let mut root: Word = EmptySubtreeRoots::empty_hashes(64)[0].into(); + let mut root: RpoDigest = EmptySubtreeRoots::empty_hashes(64)[0]; // insert some path to the left of the root and assert it let key = 0b01001011_10110110_00001101_01110100_00111011_10101101_00000100_01000001_u64; assert_eq!(0, store.get_leaf_depth(root, 64, key).unwrap()); let depth = 64; let index = NodeIndex::new(depth, key).unwrap(); - let node = [Felt::new(key); WORD_SIZE]; + let node = RpoDigest::from([Felt::new(key); WORD_SIZE]); root = store.set_node(root, index, node).unwrap().root; assert_eq!(depth, store.get_leaf_depth(root, 64, key).unwrap());@@ -665,7 +670,7 @@ let key = 0b11001011_10110110_00000000_00000000_00000000_00000000_00000000_00000000_u64;
assert_eq!(1, store.get_leaf_depth(root, 64, key).unwrap()); let depth = 16; let index = NodeIndex::new(depth, key >> (64 - depth)).unwrap(); - let node = [Felt::new(key); WORD_SIZE]; + let node = RpoDigest::from([Felt::new(key); WORD_SIZE]); root = store.set_node(root, index, node).unwrap().root; assert_eq!(depth, store.get_leaf_depth(root, 64, key).unwrap());@@ -673,7 +678,7 @@ // attempt the sibling of the previous leaf
let key = 0b11001011_10110111_00000000_00000000_00000000_00000000_00000000_00000000_u64; assert_eq!(16, store.get_leaf_depth(root, 64, key).unwrap()); let index = NodeIndex::new(depth, key >> (64 - depth)).unwrap(); - let node = [Felt::new(key); WORD_SIZE]; + let node = RpoDigest::from([Felt::new(key); WORD_SIZE]); root = store.set_node(root, index, node).unwrap().root; assert_eq!(depth, store.get_leaf_depth(root, 64, key).unwrap());@@ -682,7 +687,7 @@ let key = 0b11001011_10110100_00000000_00000000_00000000_00000000_00000000_00000000_u64;
assert_eq!(15, store.get_leaf_depth(root, 64, key).unwrap()); let depth = 17; let index = NodeIndex::new(depth, key >> (64 - depth)).unwrap(); - let node = [Felt::new(key); WORD_SIZE]; + let node = RpoDigest::from([Felt::new(key); WORD_SIZE]); root = store.set_node(root, index, node).unwrap().root; assert_eq!(depth, store.get_leaf_depth(root, 64, key).unwrap()); }@@ -690,7 +695,7 @@
#[test] fn get_leaf_depth_works_with_depth_8() { let mut store = MerkleStore::new(); - let mut root: Word = EmptySubtreeRoots::empty_hashes(8)[0].into(); + let mut root: RpoDigest = EmptySubtreeRoots::empty_hashes(8)[0]; // insert some random, 8 depth keys. `a` diverges from the first bit let a = 0b01101001_u64;@@ -700,7 +705,7 @@ let d = 0b11110110_u64;
for k in [a, b, c, d] { let index = NodeIndex::new(8, k).unwrap(); - let node = [Felt::new(k); WORD_SIZE]; + let node = RpoDigest::from([Felt::new(k); WORD_SIZE]); root = store.set_node(root, index, node).unwrap().root; }@@ -780,7 +785,7 @@ fn check_mstore_subtree(store: &MerkleStore, subtree: &MerkleTree) {
for (i, value) in subtree.leaves() { let index = NodeIndex::new(subtree.depth(), i).unwrap(); let path1 = store.get_path(subtree.root(), index).unwrap(); - assert_eq!(&path1.value, value); + assert_eq!(*path1.value, *value); let path2 = subtree.get_path(index).unwrap(); assert_eq!(path1.path, path2);
@@ -1,6 +1,6 @@
use super::{ - BTreeMap, BTreeSet, EmptySubtreeRoots, Felt, InnerNodeInfo, MerkleError, MerklePath, NodeIndex, - Rpo256, RpoDigest, StarkField, Vec, Word, EMPTY_WORD, ZERO, + empty_roots::EMPTY_WORD, BTreeMap, BTreeSet, EmptySubtreeRoots, Felt, InnerNodeInfo, + MerkleError, MerklePath, NodeIndex, Rpo256, RpoDigest, StarkField, Vec, Word, ZERO, }; use core::cmp;@@ -123,7 +123,7 @@
let mut path = Vec::with_capacity(index.depth() as usize); for _ in 0..index.depth() { let node = self.get_node_unchecked(&index.sibling()); - path.push(node.into()); + path.push(node); index.move_up(); }@@ -200,9 +200,9 @@ pub fn inner_nodes(&self) -> impl Iterator<Item = InnerNodeInfo> + '_ {
self.nodes.iter().filter_map(|(index, node)| { if is_inner_node(index) { Some(InnerNodeInfo { - value: node.into(), - left: self.get_node_unchecked(&index.left_child()).into(), - right: self.get_node_unchecked(&index.right_child()).into(), + value: *node, + left: self.get_node_unchecked(&index.left_child()), + right: self.get_node_unchecked(&index.right_child()), }) } else { None@@ -456,7 +456,7 @@ pub fn hash(&self) -> RpoDigest {
let mut elements = Vec::with_capacity(self.values.len() * 2); for (key, val) in self.values.iter() { key.iter().for_each(|&v| elements.push(Felt::new(v))); - elements.extend_from_slice(val); + elements.extend_from_slice(val.as_slice()); } // TODO: hash in domain Rpo256::hash_elements(&elements)
@@ -66,11 +66,19 @@ // --- build Merkle store with equivalent data ----------------------------
let mut tree_root = get_init_root(); let index_a = NodeIndex::make(32, raw_a >> 32); let leaf_node_a = build_leaf_node(key_a, val_a, 32); - tree_root = store.set_node(tree_root, index_a, leaf_node_a.into()).unwrap().root; + tree_root = store + .set_node(tree_root.into(), index_a, leaf_node_a.into()) + .unwrap() + .root + .into(); let index_b = NodeIndex::make(32, raw_b >> 32); let leaf_node_b = build_leaf_node(key_b, val_b, 32); - tree_root = store.set_node(tree_root, index_b, leaf_node_b.into()).unwrap().root; + tree_root = store + .set_node(tree_root.into(), index_b, leaf_node_b.into()) + .unwrap() + .root + .into(); // --- verify that data is consistent between store and tree --------------@@ -78,12 +86,12 @@ assert_eq!(smt.root(), tree_root.into());
assert_eq!(smt.get_value(key_a), val_a); assert_eq!(smt.get_node(index_a).unwrap(), leaf_node_a); - let expected_path = store.get_path(tree_root, index_a).unwrap().path; + let expected_path = store.get_path(tree_root.into(), index_a).unwrap().path; assert_eq!(smt.get_path(index_a).unwrap(), expected_path); assert_eq!(smt.get_value(key_b), val_b); assert_eq!(smt.get_node(index_b).unwrap(), leaf_node_b); - let expected_path = store.get_path(tree_root, index_b).unwrap().path; + let expected_path = store.get_path(tree_root.into(), index_b).unwrap().path; assert_eq!(smt.get_path(index_b).unwrap(), expected_path); // make sure inner nodes match - the store contains more entries because it keeps track of@@ -122,11 +130,19 @@ // --- build Merkle store with equivalent data ----------------------------
let mut tree_root = get_init_root(); let index_a = NodeIndex::make(48, raw_a >> 16); let leaf_node_a = build_leaf_node(key_a, val_a, 48); - tree_root = store.set_node(tree_root, index_a, leaf_node_a.into()).unwrap().root; + tree_root = store + .set_node(tree_root.into(), index_a, leaf_node_a.into()) + .unwrap() + .root + .into(); let index_b = NodeIndex::make(48, raw_b >> 16); let leaf_node_b = build_leaf_node(key_b, val_b, 48); - tree_root = store.set_node(tree_root, index_b, leaf_node_b.into()).unwrap().root; + tree_root = store + .set_node(tree_root.into(), index_b, leaf_node_b.into()) + .unwrap() + .root + .into(); // --- verify that data is consistent between store and tree --------------@@ -134,12 +150,12 @@ assert_eq!(smt.root(), tree_root.into());
assert_eq!(smt.get_value(key_a), val_a); assert_eq!(smt.get_node(index_a).unwrap(), leaf_node_a); - let expected_path = store.get_path(tree_root, index_a).unwrap().path; + let expected_path = store.get_path(tree_root.into(), index_a).unwrap().path; assert_eq!(smt.get_path(index_a).unwrap(), expected_path); assert_eq!(smt.get_value(key_b), val_b); assert_eq!(smt.get_node(index_b).unwrap(), leaf_node_b); - let expected_path = store.get_path(tree_root, index_b).unwrap().path; + let expected_path = store.get_path(tree_root.into(), index_b).unwrap().path; assert_eq!(smt.get_path(index_b).unwrap(), expected_path); // make sure inner nodes match - the store contains more entries because it keeps track of@@ -181,15 +197,27 @@ // --- build Merkle store with equivalent data ----------------------------
let mut tree_root = get_init_root(); let index_a = NodeIndex::make(32, raw_a >> 32); let leaf_node_a = build_leaf_node(key_a, val_a, 32); - tree_root = store.set_node(tree_root, index_a, leaf_node_a.into()).unwrap().root; + tree_root = store + .set_node(tree_root.into(), index_a, leaf_node_a.into()) + .unwrap() + .root + .into(); let index_b = NodeIndex::make(32, raw_b >> 32); let leaf_node_b = build_leaf_node(key_b, val_b, 32); - tree_root = store.set_node(tree_root, index_b, leaf_node_b.into()).unwrap().root; + tree_root = store + .set_node(tree_root.into(), index_b, leaf_node_b.into()) + .unwrap() + .root + .into(); let index_c = NodeIndex::make(32, raw_c >> 32); let leaf_node_c = build_leaf_node(key_c, val_c, 32); - tree_root = store.set_node(tree_root, index_c, leaf_node_c.into()).unwrap().root; + tree_root = store + .set_node(tree_root.into(), index_c, leaf_node_c.into()) + .unwrap() + .root + .into(); // --- verify that data is consistent between store and tree --------------@@ -197,17 +225,17 @@ assert_eq!(smt.root(), tree_root.into());
assert_eq!(smt.get_value(key_a), val_a); assert_eq!(smt.get_node(index_a).unwrap(), leaf_node_a); - let expected_path = store.get_path(tree_root, index_a).unwrap().path; + let expected_path = store.get_path(tree_root.into(), index_a).unwrap().path; assert_eq!(smt.get_path(index_a).unwrap(), expected_path); assert_eq!(smt.get_value(key_b), val_b); assert_eq!(smt.get_node(index_b).unwrap(), leaf_node_b); - let expected_path = store.get_path(tree_root, index_b).unwrap().path; + let expected_path = store.get_path(tree_root.into(), index_b).unwrap().path; assert_eq!(smt.get_path(index_b).unwrap(), expected_path); assert_eq!(smt.get_value(key_c), val_c); assert_eq!(smt.get_node(index_c).unwrap(), leaf_node_c); - let expected_path = store.get_path(tree_root, index_c).unwrap().path; + let expected_path = store.get_path(tree_root.into(), index_c).unwrap().path; assert_eq!(smt.get_path(index_c).unwrap(), expected_path); // make sure inner nodes match - the store contains more entries because it keeps track of@@ -236,13 +264,13 @@ // --- verify consistency -------------------------------------------------
let mut tree_root = get_init_root(); let index = NodeIndex::make(16, raw >> 48); let leaf_node = build_leaf_node(key, value_b, 16); - tree_root = store.set_node(tree_root, index, leaf_node.into()).unwrap().root; + tree_root = store.set_node(tree_root.into(), index, leaf_node.into()).unwrap().root.into(); assert_eq!(smt.root(), tree_root.into()); assert_eq!(smt.get_value(key), value_b); assert_eq!(smt.get_node(index).unwrap(), leaf_node); - let expected_path = store.get_path(tree_root, index).unwrap().path; + let expected_path = store.get_path(tree_root.into(), index).unwrap().path; assert_eq!(smt.get_path(index).unwrap(), expected_path); // make sure inner nodes match - the store contains more entries because it keeps track of@@ -281,7 +309,7 @@ // to build bottom leaf we sort by key starting with the least significant element, thus
// key_b is smaller than key_a. let leaf_node = build_bottom_leaf_node(&[key_b, key_a], &[val_b, val_a]); let mut tree_root = get_init_root(); - tree_root = store.set_node(tree_root, index, leaf_node.into()).unwrap().root; + tree_root = store.set_node(tree_root.into(), index, leaf_node.into()).unwrap().root.into(); // --- verify that data is consistent between store and tree --------------@@ -291,7 +319,7 @@ assert_eq!(smt.get_value(key_a), val_a);
assert_eq!(smt.get_value(key_b), val_b); assert_eq!(smt.get_node(index).unwrap(), leaf_node); - let expected_path = store.get_path(tree_root, index).unwrap().path; + let expected_path = store.get_path(tree_root.into(), index).unwrap().path; assert_eq!(smt.get_path(index).unwrap(), expected_path); // make sure inner nodes match - the store contains more entries because it keeps track of@@ -329,11 +357,19 @@ // --- build Merkle store with equivalent data ----------------------------
let mut tree_root = get_init_root(); let index_a = NodeIndex::make(64, raw_a); let leaf_node_a = build_bottom_leaf_node(&[key_a], &[val_a]); - tree_root = store.set_node(tree_root, index_a, leaf_node_a.into()).unwrap().root; + tree_root = store + .set_node(tree_root.into(), index_a, leaf_node_a.into()) + .unwrap() + .root + .into(); let index_b = NodeIndex::make(64, raw_b); let leaf_node_b = build_bottom_leaf_node(&[key_b], &[val_b]); - tree_root = store.set_node(tree_root, index_b, leaf_node_b.into()).unwrap().root; + tree_root = store + .set_node(tree_root.into(), index_b, leaf_node_b.into()) + .unwrap() + .root + .into(); // --- verify that data is consistent between store and tree --------------@@ -341,12 +377,12 @@ assert_eq!(smt.root(), tree_root.into());
assert_eq!(smt.get_value(key_a), val_a); assert_eq!(smt.get_node(index_a).unwrap(), leaf_node_a); - let expected_path = store.get_path(tree_root, index_a).unwrap().path; + let expected_path = store.get_path(tree_root.into(), index_a).unwrap().path; assert_eq!(smt.get_path(index_a).unwrap(), expected_path); assert_eq!(smt.get_value(key_b), val_b); assert_eq!(smt.get_node(index_b).unwrap(), leaf_node_b); - let expected_path = store.get_path(tree_root, index_b).unwrap().path; + let expected_path = store.get_path(tree_root.into(), index_b).unwrap().path; assert_eq!(smt.get_path(index_b).unwrap(), expected_path); // make sure inner nodes match - the store contains more entries because it keeps track of@@ -423,7 +459,7 @@ for (key, val) in keys.iter().zip(values.iter()) {
let mut key = Word::from(key); key[3] = ZERO; elements.extend_from_slice(&key); - elements.extend_from_slice(val); + elements.extend_from_slice(val.as_slice()); } Rpo256::hash_elements(&elements)