diff --git a/miden-crypto/src/merkle/sparse_path.rs b/miden-crypto/src/merkle/sparse_path.rs index 59dd828..f045646 100644 --- a/miden-crypto/src/merkle/sparse_path.rs +++ b/miden-crypto/src/merkle/sparse_path.rs @@ -47,9 +47,27 @@ impl SparseMerklePath { I: IntoIterator, { let iterator = iterator.into_iter(); - // `iterator.len() as u8` will truncate, but not below `SMT_MAX_DEPTH`, which - // `from_iter_with_depth` checks for. - Self::from_iter_with_depth(iterator.len() as u8, iterator) + let tree_depth = iterator.len() as u8; + + if tree_depth > SMT_MAX_DEPTH { + return Err(MerkleError::DepthTooBig(tree_depth as u64)); + } + + let mut empty_nodes_mask: u64 = 0; + let mut nodes: Vec = Default::default(); + + for (depth, node) in iter::zip(path_depth_iter(tree_depth), iterator) { + let &equivalent_empty_node = EmptySubtreeRoots::entry(tree_depth, depth.get()); + let is_empty = node == equivalent_empty_node; + let node = if is_empty { None } else { Some(node) }; + + match node { + Some(node) => nodes.push(node), + None => empty_nodes_mask |= Self::bitmask_for_depth(depth), + } + } + + Ok(SparseMerklePath { nodes, empty_nodes_mask }) } /// Returns the total depth of this path, i.e., the number of nodes this path represents. @@ -114,41 +132,6 @@ impl SparseMerklePath { // PRIVATE HELPERS // ============================================================================================ - /// Constructs a sparse Merkle path from a manually specified tree depth, and an iterator over - /// Merkle nodes from deepest to shallowest. - /// - /// Knowing the size is necessary to calculate the depth of the tree, which is needed to detect - /// which nodes are empty nodes. - /// - /// Warning: this method does not check if the iterator contained more elements. - /// - /// # Errors - /// Returns [MerkleError::DepthTooBig] if `tree_depth` is greater than [SMT_MAX_DEPTH]. - fn from_iter_with_depth( - tree_depth: u8, - iter: impl IntoIterator, - ) -> Result { - if tree_depth > SMT_MAX_DEPTH { - return Err(MerkleError::DepthTooBig(tree_depth as u64)); - } - - let mut empty_nodes_mask: u64 = 0; - let mut nodes: Vec = Default::default(); - - for (depth, node) in iter::zip(path_depth_iter(tree_depth), iter) { - let &equivalent_empty_node = EmptySubtreeRoots::entry(tree_depth, depth.get()); - let is_empty = node == equivalent_empty_node; - let node = if is_empty { None } else { Some(node) }; - - match node { - Some(node) => nodes.push(node), - None => empty_nodes_mask |= Self::bitmask_for_depth(depth), - } - } - - Ok(SparseMerklePath { nodes, empty_nodes_mask }) - } - const fn bitmask_for_depth(node_depth: NonZero) -> u64 { // - 1 because paths do not include the root. 1 << (node_depth.get() - 1)