arnaucube
arnaucube/miden-cryptoPublic Self-hosted repository
miden-crypto/src/merkle/path.rs
src/merkle/path.rsRaw
  1use super::{vec, InnerNodeInfo, MerkleError, NodeIndex, Rpo256, RpoDigest, Vec};
  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<RpoDigest>,
 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<RpoDigest>) -> Self {
 19        Self { nodes }
 20    }
 21
 22    // PROVIDERS
 23    // --------------------------------------------------------------------------------------------
 24
 25    /// Returns the depth in which this Merkle path proof is valid.
 26    pub fn depth(&self) -> u8 {
 27        self.nodes.len() as u8
 28    }
 29
 30    /// Computes the merkle root for this opening.
 31    pub fn compute_root(&self, index: u64, node: RpoDigest) -> Result<RpoDigest, MerkleError> {
 32        let mut index = NodeIndex::new(self.depth(), index)?;
 33        let root = self.nodes.iter().copied().fold(node, |node, sibling| {
 34            // compute the node and move to the next iteration.
 35            let input = index.build_node(node, sibling);
 36            index.move_up();
 37            Rpo256::merge(&input)
 38        });
 39        Ok(root)
 40    }
 41
 42    /// Verifies the Merkle opening proof towards the provided root.
 43    ///
 44    /// Returns `true` if `node` exists at `index` in a Merkle tree with `root`.
 45    pub fn verify(&self, index: u64, node: RpoDigest, root: &RpoDigest) -> bool {
 46        match self.compute_root(index, node) {
 47            Ok(computed_root) => root == &computed_root,
 48            Err(_) => false,
 49        }
 50    }
 51
 52    /// Returns an iterator over every inner node of this [MerklePath].
 53    ///
 54    /// The iteration order is unspecified.
 55    ///
 56    /// # Errors
 57    /// Returns an error if the specified index is not valid for this path.
 58    pub fn inner_nodes(
 59        &self,
 60        index: u64,
 61        node: RpoDigest,
 62    ) -> Result<InnerNodeIterator, MerkleError> {
 63        Ok(InnerNodeIterator {
 64            nodes: &self.nodes,
 65            index: NodeIndex::new(self.depth(), index)?,
 66            value: node,
 67        })
 68    }
 69}
 70
 71impl From<MerklePath> for Vec<RpoDigest> {
 72    fn from(path: MerklePath) -> Self {
 73        path.nodes
 74    }
 75}
 76
 77impl From<Vec<RpoDigest>> for MerklePath {
 78    fn from(path: Vec<RpoDigest>) -> Self {
 79        Self::new(path)
 80    }
 81}
 82
 83impl Deref for MerklePath {
 84    // we use `Vec` here instead of slice so we can call vector mutation methods directly from the
 85    // merkle path (example: `Vec::remove`).
 86    type Target = Vec<RpoDigest>;
 87
 88    fn deref(&self) -> &Self::Target {
 89        &self.nodes
 90    }
 91}
 92
 93impl DerefMut for MerklePath {
 94    fn deref_mut(&mut self) -> &mut Self::Target {
 95        &mut self.nodes
 96    }
 97}
 98
 99// ITERATORS
100// ================================================================================================
101
102impl FromIterator<RpoDigest> for MerklePath {
103    fn from_iter<T: IntoIterator<Item = RpoDigest>>(iter: T) -> Self {
104        Self::new(iter.into_iter().collect())
105    }
106}
107
108impl IntoIterator for MerklePath {
109    type Item = RpoDigest;
110    type IntoIter = vec::IntoIter<RpoDigest>;
111
112    fn into_iter(self) -> Self::IntoIter {
113        self.nodes.into_iter()
114    }
115}
116
117/// An iterator over internal nodes of a [MerklePath].
118pub struct InnerNodeIterator<'a> {
119    nodes: &'a Vec<RpoDigest>,
120    index: NodeIndex,
121    value: RpoDigest,
122}
123
124impl<'a> Iterator for InnerNodeIterator<'a> {
125    type Item = InnerNodeInfo;
126
127    fn next(&mut self) -> Option<Self::Item> {
128        if !self.index.is_root() {
129            let sibling_pos = self.nodes.len() - self.index.depth() as usize;
130            let (left, right) = if self.index.is_value_odd() {
131                (self.nodes[sibling_pos], self.value)
132            } else {
133                (self.value, self.nodes[sibling_pos])
134            };
135
136            self.value = Rpo256::merge(&[left, right]);
137            self.index.move_up();
138
139            Some(InnerNodeInfo {
140                value: self.value,
141                left,
142                right,
143            })
144        } else {
145            None
146        }
147    }
148}
149
150// MERKLE PATH CONTAINERS
151// ================================================================================================
152
153/// A container for a [Word] value and its [MerklePath] opening.
154#[derive(Clone, Debug, Default, PartialEq, Eq)]
155pub struct ValuePath {
156    /// The node value opening for `path`.
157    pub value: RpoDigest,
158    /// The path from `value` to `root` (exclusive).
159    pub path: MerklePath,
160}
161
162/// A container for a [MerklePath] and its [Word] root.
163///
164/// This structure does not provide any guarantees regarding the correctness of the path to the
165/// root. For more information, check [MerklePath::verify].
166#[derive(Clone, Debug, Default, PartialEq, Eq)]
167pub struct RootPath {
168    /// The node value opening for `path`.
169    pub root: RpoDigest,
170    /// The path from `value` to `root` (exclusive).
171    pub path: MerklePath,
172}
173
174// TESTS
175// ================================================================================================
176
177#[cfg(test)]
178mod tests {
179    use crate::merkle::{int_to_node, MerklePath};
180
181    #[test]
182    fn test_inner_nodes() {
183        let nodes = vec![int_to_node(1), int_to_node(2), int_to_node(3), int_to_node(4)];
184        let merkle_path = MerklePath::new(nodes);
185
186        let index = 6;
187        let node = int_to_node(5);
188        let root = merkle_path.compute_root(index, node).unwrap();
189
190        let inner_root = merkle_path.inner_nodes(index, node).unwrap().last().unwrap().value;
191
192        assert_eq!(root, inner_root);
193    }
194}