arnaucube
arnaucube/miden-cryptoPublic Self-hosted repository
miden-crypto/src/merkle/mmr/accumulator.rs
src/merkle/mmr/accumulator.rsRaw
 1use super::{super::Vec, MmrProof, Rpo256, Word};
 2
 3#[derive(Debug, Clone, PartialEq)]
 4pub struct MmrPeaks {
 5    /// The number of leaves is used to differentiate accumulators that have the same number of
 6    /// peaks. This happens because the number of peaks goes up-and-down as the structure is used
 7    /// causing existing trees to be merged and new ones to be created. As an example, every time
 8    /// the MMR has a power-of-two number of leaves there is a single peak.
 9    ///
10    /// Every tree in the MMR forest has a distinct power-of-two size, this means only the right
11    /// most tree can have an odd number of elements (1). Additionally this means that the bits in
12    /// `num_leaves` conveniently encode the size of each individual tree.
13    ///
14    /// Examples:
15    ///
16    ///    Example 1: With 5 leaves, the binary 0b101. The number of set bits is equal the number
17    ///    of peaks, in this case there are 2 peaks. The 0-indexed least-significant position of
18    ///    the bit determines the number of elements of a tree, so the rightmost tree has 2**0
19    ///    elements and the left most has 2**2.
20    ///
21    ///    Example 2: With 12 leaves, the binary is 0b1100, this case also has 2 peaks, the
22    ///    leftmost tree has 2**3=8 elements, and the right most has 2**2=4 elements.
23    pub num_leaves: usize,
24
25    /// All the peaks of every tree in the MMR forest. The peaks are always ordered by number of
26    /// leaves, starting from the peak with most children, to the one with least.
27    ///
28    /// Invariant: The length of `peaks` must be equal to the number of true bits in `num_leaves`.
29    pub peaks: Vec<Word>,
30}
31
32impl MmrPeaks {
33    /// Hashes the peaks sequentially, compacting it to a single digest
34    pub fn hash_peaks(&self) -> Word {
35        Rpo256::hash_elements(&self.peaks.as_slice().concat()).into()
36    }
37
38    pub fn verify(&self, value: Word, opening: MmrProof) -> bool {
39        let root = &self.peaks[opening.peak_index()];
40        opening
41            .merkle_path
42            .verify(opening.relative_pos() as u64, value, root)
43    }
44}