use super::{vec, NodeIndex, Rpo256, Vec, Word}; use core::ops::{Deref, DerefMut}; // MERKLE PATH // ================================================================================================ /// 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, } impl MerklePath { // CONSTRUCTORS // -------------------------------------------------------------------------------------------- /// Creates a new Merkle path from a list of nodes. pub fn new(nodes: Vec) -> Self { Self { nodes } } // PROVIDERS // -------------------------------------------------------------------------------------------- /// Computes the merkle root for this opening. pub fn compute_root(&self, index_value: u64, node: Word) -> Word { let mut index = NodeIndex::new(self.depth(), index_value); 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()); index.move_up(); Rpo256::merge(&input).into() }) } /// Returns the depth in which this Merkle path proof is valid. pub fn depth(&self) -> u8 { self.nodes.len() as u8 } /// 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 { root == &self.compute_root(index, node) } } impl From> for MerklePath { fn from(path: Vec) -> Self { Self::new(path) } } 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; fn deref(&self) -> &Self::Target { &self.nodes } } impl DerefMut for MerklePath { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.nodes } } impl FromIterator for MerklePath { fn from_iter>(iter: T) -> Self { Self::new(iter.into_iter().collect()) } } impl IntoIterator for MerklePath { type Item = Word; type IntoIter = vec::IntoIter; fn into_iter(self) -> Self::IntoIter { self.nodes.into_iter() } } // MERKLE PATH CONTAINERS // ================================================================================================ /// 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, /// The path from `value` to `root` (exclusive). pub path: MerklePath, } /// A container for a [MerklePath] and its [Word] root. /// /// This structure does not provide any guarantees regarding the correctness of the path to the /// 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, /// The path from `value` to `root` (exclusive). pub path: MerklePath, }