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}