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