arnaucube
arnaucube/miden-cryptoPublic Self-hosted repository
miden-crypto/src/merkle/path.rs
src/merkle/path.rsRaw
 1use super::{vec, NodeIndex, Rpo256, Vec, Word};
 2use core::ops::{Deref, DerefMut};
 3
 4// MERKLE PATH
 5// ================================================================================================
 6
 7/// A merkle path container, composed of a sequence of nodes of a Merkle tree.
 8#[derive(Clone, Debug, Default, PartialEq, Eq)]
 9pub struct MerklePath {
10    nodes: Vec<Word>,
11}
12
13impl MerklePath {
14    // CONSTRUCTORS
15    // --------------------------------------------------------------------------------------------
16
17    /// Creates a new Merkle path from a list of nodes.
18    pub fn new(nodes: Vec<Word>) -> Self {
19        Self { nodes }
20    }
21
22    // PROVIDERS
23    // --------------------------------------------------------------------------------------------
24
25    /// Computes the merkle root for this opening.
26    pub fn compute_root(&self, index_value: u64, node: Word) -> Word {
27        let mut index = NodeIndex::new(self.depth(), index_value);
28        self.nodes.iter().copied().fold(node, |node, sibling| {
29            // compute the node and move to the next iteration.
30            let input = index.build_node(node.into(), sibling.into());
31            index.move_up();
32            Rpo256::merge(&input).into()
33        })
34    }
35
36    /// Returns the depth in which this Merkle path proof is valid.
37    pub fn depth(&self) -> u8 {
38        self.nodes.len() as u8
39    }
40
41    /// Verifies the Merkle opening proof towards the provided root.
42    ///
43    /// Returns `true` if `node` exists at `index` in a Merkle tree with `root`.
44    pub fn verify(&self, index: u64, node: Word, root: &Word) -> bool {
45        root == &self.compute_root(index, node)
46    }
47}
48
49impl From<Vec<Word>> for MerklePath {
50    fn from(path: Vec<Word>) -> Self {
51        Self::new(path)
52    }
53}
54
55impl Deref for MerklePath {
56    // we use `Vec` here instead of slice so we can call vector mutation methods directly from the
57    // merkle path (example: `Vec::remove`).
58    type Target = Vec<Word>;
59
60    fn deref(&self) -> &Self::Target {
61        &self.nodes
62    }
63}
64
65impl DerefMut for MerklePath {
66    fn deref_mut(&mut self) -> &mut Self::Target {
67        &mut self.nodes
68    }
69}
70
71impl FromIterator<Word> for MerklePath {
72    fn from_iter<T: IntoIterator<Item = Word>>(iter: T) -> Self {
73        Self::new(iter.into_iter().collect())
74    }
75}
76
77impl IntoIterator for MerklePath {
78    type Item = Word;
79    type IntoIter = vec::IntoIter<Word>;
80
81    fn into_iter(self) -> Self::IntoIter {
82        self.nodes.into_iter()
83    }
84}