winter_crypto/merkle/
mod.rs

1// Copyright (c) Facebook, Inc. and its affiliates.
2//
3// This source code is licensed under the MIT license found in the
4// LICENSE file in the root directory of this source tree.
5
6use alloc::{
7    collections::{BTreeMap, BTreeSet},
8    vec::Vec,
9};
10use core::slice;
11
12mod proofs;
13pub use proofs::BatchMerkleProof;
14
15use crate::{Hasher, MerkleTreeError, VectorCommitment};
16
17#[cfg(feature = "concurrent")]
18pub mod concurrent;
19
20#[cfg(test)]
21mod tests;
22
23// TYPES AND INTERFACES
24// ================================================================================================
25
26/// A fully-balanced Merkle tree.
27///
28/// In this implementation, a Merkle tree consists of two types of nodes: leaves and internal nodes
29/// (one of which is a tree root). All nodes must be instances of the digest specified by the
30/// [Hasher] used to build the tree.
31///
32/// ```text
33///       *        <- tree root
34///     /   \
35///    /     \
36///   *       *    <- internal nodes
37///  / \     / \
38/// o   o   o   o  <- leaves
39/// |   |   |   |
40/// #   #   #   #  <- values
41/// ```
42///
43/// A tree can be built from a slice of leaves using [MerkleTree::new()] function. Thus, the user
44/// is responsible for performing the first level of hashing (i.e., hashing values into leaf
45/// nodes). The number of leaves must always be a power of two so that the tree is fully balanced,
46/// and a tree must contain at least two leaves.
47///
48/// The depth of a tree is zero-based. Thus, a tree with two leaves has depth 1, a tree with four
49/// leaves has depth 2 etc.
50///
51/// When the crate is compiled with `concurrent` feature enabled, tree construction will be
52/// performed in multiple threads (usually, as many threads as there are logical cores on the
53/// machine). The number of threads can be configured via `RAYON_NUM_THREADS` environment variable.
54///
55/// To generate an inclusion proof for a given leaf, [MerkleTree::prove()] method can be used.
56/// You can also use [MerkleTree::prove_batch()] method to generate inclusion proofs for multiple
57/// leaves. The advantage of the batch method is that redundant internal nodes are removed from
58/// the batch proof, thereby compressing it (we use a variation of the
59/// [Octopus](https://eprint.iacr.org/2017/933) algorithm).
60///
61/// To verify proofs, [MerkleTree::verify()] and [MerkleTree::verify_batch()] functions can be
62/// used respectively.
63///
64/// # Examples
65/// ```
66/// # use winter_crypto::{MerkleTree, Hasher, hashers::Blake3_256};
67/// # use math::fields::f128::BaseElement;
68/// type Blake3 = Blake3_256<BaseElement>;
69///
70/// // build a tree
71/// let leaves = [
72///     Blake3::hash(&[1u8]),
73///     Blake3::hash(&[2u8]),
74///     Blake3::hash(&[3u8]),
75///     Blake3::hash(&[4u8]),
76/// ];
77/// let tree = MerkleTree::<Blake3>::new(leaves.to_vec()).unwrap();
78/// assert_eq!(2, tree.depth());
79/// assert_eq!(leaves, tree.leaves());
80///
81/// // generate a proof
82/// let (leaf, proof) = tree.prove(2).unwrap();
83/// assert_eq!(2, proof.len());
84/// assert_eq!(leaves[2], leaf);
85///
86/// // verify proof
87/// assert!(MerkleTree::<Blake3>::verify(*tree.root(), 2, leaf, &proof).is_ok());
88/// assert!(MerkleTree::<Blake3>::verify(*tree.root(), 1, leaf, &proof).is_err());
89/// ```
90#[derive(Debug)]
91pub struct MerkleTree<H: Hasher> {
92    nodes: Vec<H::Digest>,
93    leaves: Vec<H::Digest>,
94}
95
96/// Merkle tree opening consisting of a leaf value and a Merkle path leading from this leaf
97/// up to the root (excluding the root itself).
98pub type MerkleTreeOpening<H> = (<H as Hasher>::Digest, Vec<<H as Hasher>::Digest>);
99
100// MERKLE TREE IMPLEMENTATION
101// ================================================================================================
102
103impl<H: Hasher> MerkleTree<H> {
104    // CONSTRUCTORS
105    // --------------------------------------------------------------------------------------------
106
107    /// Returns new Merkle tree built from the provide leaves using hash function specified by the
108    /// `H` generic parameter.
109    ///
110    /// When `concurrent` feature is enabled, the tree is built using multiple threads.
111    ///
112    /// # Errors
113    /// Returns an error if:
114    /// * Fewer than two leaves were provided.
115    /// * Number of leaves is not a power of two.
116    pub fn new(leaves: Vec<H::Digest>) -> Result<Self, MerkleTreeError> {
117        if leaves.len() < 2 {
118            return Err(MerkleTreeError::TooFewLeaves(2, leaves.len()));
119        }
120        if !leaves.len().is_power_of_two() {
121            return Err(MerkleTreeError::NumberOfLeavesNotPowerOfTwo(leaves.len()));
122        }
123
124        #[cfg(not(feature = "concurrent"))]
125        let nodes = build_merkle_nodes::<H>(&leaves);
126
127        #[cfg(feature = "concurrent")]
128        let nodes = if leaves.len() <= concurrent::MIN_CONCURRENT_LEAVES {
129            build_merkle_nodes::<H>(&leaves)
130        } else {
131            concurrent::build_merkle_nodes::<H>(&leaves)
132        };
133
134        Ok(MerkleTree { nodes, leaves })
135    }
136
137    /// Forms a MerkleTree from a list of nodes and leaves.
138    ///
139    /// Nodes are supplied as a vector where the root is stored at position 1.
140    ///
141    /// # Errors
142    /// Returns an error if:
143    /// * Fewer than two leaves were provided.
144    /// * Number of leaves is not a power of two.
145    ///
146    /// # Panics
147    /// Panics if nodes doesn't have the same length as leaves.
148    pub fn from_raw_parts(
149        nodes: Vec<H::Digest>,
150        leaves: Vec<H::Digest>,
151    ) -> Result<Self, MerkleTreeError> {
152        if leaves.len() < 2 {
153            return Err(MerkleTreeError::TooFewLeaves(2, leaves.len()));
154        }
155        if !leaves.len().is_power_of_two() {
156            return Err(MerkleTreeError::NumberOfLeavesNotPowerOfTwo(leaves.len()));
157        }
158        assert_eq!(nodes.len(), leaves.len());
159        Ok(MerkleTree { nodes, leaves })
160    }
161
162    // PUBLIC ACCESSORS
163    // --------------------------------------------------------------------------------------------
164
165    /// Returns the root of the tree.
166    pub fn root(&self) -> &H::Digest {
167        &self.nodes[1]
168    }
169
170    /// Returns depth of the tree.
171    ///
172    /// The depth of a tree is zero-based. Thus, a tree with two leaves has depth 1, a tree with
173    /// four leaves has depth 2 etc.
174    pub fn depth(&self) -> usize {
175        self.leaves.len().ilog2() as usize
176    }
177
178    /// Returns leaf nodes of the tree.
179    pub fn leaves(&self) -> &[H::Digest] {
180        &self.leaves
181    }
182
183    // PROVING METHODS
184    // --------------------------------------------------------------------------------------------
185
186    /// Returns a Merkle proof to a leaf at the specified `index`.
187    ///
188    /// The leaf itself will be the first element of the returned tuple.
189    ///
190    /// # Errors
191    /// Returns an error if the specified index is greater than or equal to the number of leaves
192    /// in the tree.
193    pub fn prove(&self, index: usize) -> Result<MerkleTreeOpening<H>, MerkleTreeError> {
194        if index >= self.leaves.len() {
195            return Err(MerkleTreeError::LeafIndexOutOfBounds(self.leaves.len(), index));
196        }
197        let leaf = self.leaves[index];
198        let mut proof = vec![self.leaves[index ^ 1]];
199
200        let mut index = (index + self.nodes.len()) >> 1;
201        while index > 1 {
202            proof.push(self.nodes[index ^ 1]);
203            index >>= 1;
204        }
205
206        Ok((leaf, proof))
207    }
208
209    /// Computes Merkle proofs for the provided indexes, compresses the proofs into a single batch
210    /// and returns the batch proof alongside the leaves at the provided indexes.
211    ///
212    /// # Errors
213    /// Returns an error if:
214    /// * No indexes were provided (i.e., `indexes` is an empty slice).
215    /// * Any of the provided indexes are greater than or equal to the number of leaves in the tree.
216    /// * List of indexes contains duplicates.
217    pub fn prove_batch(
218        &self,
219        indexes: &[usize],
220    ) -> Result<(Vec<H::Digest>, BatchMerkleProof<H>), MerkleTreeError> {
221        if indexes.is_empty() {
222            return Err(MerkleTreeError::TooFewLeafIndexes);
223        }
224
225        let index_map = map_indexes(indexes, self.depth())?;
226        let indexes = normalize_indexes(indexes);
227        let mut leaves = vec![H::Digest::default(); index_map.len()];
228        let mut nodes: Vec<Vec<H::Digest>> = Vec::with_capacity(indexes.len());
229
230        // populate the proof with leaf node values
231        let n = self.leaves.len();
232        let mut next_indexes: Vec<usize> = Vec::new();
233        for index in indexes {
234            let missing: Vec<H::Digest> = (index..index + 2)
235                .flat_map(|i| {
236                    let v = self.leaves[i];
237                    if let Some(idx) = index_map.get(&i) {
238                        leaves[*idx] = v;
239                        None
240                    } else {
241                        Some(v)
242                    }
243                })
244                .collect();
245            nodes.push(missing);
246
247            next_indexes.push((index + n) >> 1);
248        }
249
250        // add required internal nodes to the proof, skipping redundancies
251        for _ in 1..self.depth() {
252            let indexes = next_indexes.clone();
253            next_indexes.truncate(0);
254
255            let mut i = 0;
256            while i < indexes.len() {
257                let sibling_index = indexes[i] ^ 1;
258                if i + 1 < indexes.len() && indexes[i + 1] == sibling_index {
259                    i += 1;
260                } else {
261                    nodes[i].push(self.nodes[sibling_index]);
262                }
263
264                // add parent index to the set of next indexes
265                next_indexes.push(sibling_index >> 1);
266
267                i += 1;
268            }
269        }
270
271        Ok((leaves, BatchMerkleProof { depth: self.depth() as u8, nodes }))
272    }
273
274    // VERIFICATION METHODS
275    // --------------------------------------------------------------------------------------------
276
277    /// Checks whether the `proof` for the given `leaf` at the specified `index` is valid.
278    ///
279    /// # Errors
280    /// Returns an error if the specified `proof` (which is a Merkle path) does not resolve to the
281    /// specified `root`.
282    pub fn verify(
283        root: H::Digest,
284        index: usize,
285        leaf: H::Digest,
286        proof: &[H::Digest],
287    ) -> Result<(), MerkleTreeError> {
288        let r = index & 1;
289        let mut v = if r == 0 {
290            H::merge(&[leaf, proof[0]])
291        } else {
292            H::merge(&[proof[0], leaf])
293        };
294
295        let mut index = (index + 2usize.pow((proof.len()) as u32)) >> 1;
296        for &p in proof.iter().skip(1) {
297            v = if index & 1 == 0 {
298                H::merge(&[v, p])
299            } else {
300                H::merge(&[p, v])
301            };
302            index >>= 1;
303        }
304
305        if v != root {
306            return Err(MerkleTreeError::InvalidProof);
307        }
308        Ok(())
309    }
310
311    /// Checks whether the batch `proof` contains Merkle proofs resolving to `root` for
312    /// the provided `leaves` at the specified `indexes`.
313    ///
314    /// # Errors
315    /// Returns an error if:
316    /// * No indexes were provided (i.e., `indexes` is an empty slice).
317    /// * Any of the specified `indexes` is greater than or equal to the number of leaves in the
318    ///   tree from which the batch proof was generated.
319    /// * List of indexes contains duplicates.
320    /// * Any of the proofs in the batch proof does not resolve to the specified `root`.
321    pub fn verify_batch(
322        root: &H::Digest,
323        indexes: &[usize],
324        leaves: &[H::Digest],
325        proof: &BatchMerkleProof<H>,
326    ) -> Result<(), MerkleTreeError> {
327        if *root != proof.get_root(indexes, leaves)? {
328            return Err(MerkleTreeError::InvalidProof);
329        }
330        Ok(())
331    }
332}
333
334// HELPER FUNCTIONS
335// ================================================================================================
336
337/// Returns the internal nodes of a Merkle tree defined by the specified leaves.
338///
339/// The internal nodes are turned as a vector where the root is stored at position 1, its children
340/// are stored at positions 2, 3, their children are stored at positions 4, 5, 6, 7 etc.
341///
342/// This function is exposed primarily for benchmarking purposes. It is not intended to be used
343/// directly by the end users of the crate.
344pub fn build_merkle_nodes<H: Hasher>(leaves: &[H::Digest]) -> Vec<H::Digest> {
345    let n = leaves.len() / 2;
346
347    // create un-initialized array to hold all intermediate nodes
348    let mut nodes = unsafe { utils::uninit_vector::<H::Digest>(2 * n) };
349    nodes[0] = H::Digest::default();
350
351    // re-interpret leaves as an array of two leaves fused together
352    let two_leaves = unsafe { slice::from_raw_parts(leaves.as_ptr() as *const [H::Digest; 2], n) };
353
354    // build first row of internal nodes (parents of leaves)
355    for (i, j) in (0..n).zip(n..nodes.len()) {
356        nodes[j] = H::merge(&two_leaves[i]);
357    }
358
359    // re-interpret nodes as an array of two nodes fused together
360    let two_nodes = unsafe { slice::from_raw_parts(nodes.as_ptr() as *const [H::Digest; 2], n) };
361
362    // calculate all other tree nodes
363    for i in (1..n).rev() {
364        nodes[i] = H::merge(&two_nodes[i]);
365    }
366
367    nodes
368}
369
370fn map_indexes(
371    indexes: &[usize],
372    tree_depth: usize,
373) -> Result<BTreeMap<usize, usize>, MerkleTreeError> {
374    let num_leaves = 2usize.pow(tree_depth as u32);
375    let mut map = BTreeMap::new();
376    for (i, index) in indexes.iter().cloned().enumerate() {
377        map.insert(index, i);
378        if index >= num_leaves {
379            return Err(MerkleTreeError::LeafIndexOutOfBounds(num_leaves, index));
380        }
381    }
382
383    if indexes.len() != map.len() {
384        return Err(MerkleTreeError::DuplicateLeafIndex);
385    }
386
387    Ok(map)
388}
389
390fn normalize_indexes(indexes: &[usize]) -> Vec<usize> {
391    let mut set = BTreeSet::new();
392    for &index in indexes {
393        set.insert(index - (index & 1));
394    }
395    set.into_iter().collect()
396}
397
398// VECTOR COMMITMENT IMPLEMENTATION
399// ================================================================================================
400
401impl<H: Hasher> VectorCommitment<H> for MerkleTree<H> {
402    type Options = ();
403
404    type Proof = Vec<H::Digest>;
405
406    type MultiProof = BatchMerkleProof<H>;
407
408    type Error = MerkleTreeError;
409
410    fn with_options(items: Vec<H::Digest>, _options: Self::Options) -> Result<Self, Self::Error> {
411        MerkleTree::new(items)
412    }
413
414    fn commitment(&self) -> H::Digest {
415        *self.root()
416    }
417
418    fn domain_len(&self) -> usize {
419        1 << self.depth()
420    }
421
422    fn get_proof_domain_len(proof: &Self::Proof) -> usize {
423        1 << proof.len()
424    }
425
426    fn get_multiproof_domain_len(proof: &Self::MultiProof) -> usize {
427        1 << proof.depth
428    }
429
430    fn open(&self, index: usize) -> Result<(H::Digest, Self::Proof), Self::Error> {
431        self.prove(index)
432    }
433
434    fn open_many(
435        &self,
436        indexes: &[usize],
437    ) -> Result<(Vec<H::Digest>, Self::MultiProof), Self::Error> {
438        self.prove_batch(indexes)
439    }
440
441    fn verify(
442        commitment: H::Digest,
443        index: usize,
444        item: H::Digest,
445        proof: &Self::Proof,
446    ) -> Result<(), Self::Error> {
447        MerkleTree::<H>::verify(commitment, index, item, proof)
448    }
449
450    fn verify_many(
451        commitment: H::Digest,
452        indexes: &[usize],
453        items: &[H::Digest],
454        proof: &Self::MultiProof,
455    ) -> Result<(), Self::Error> {
456        MerkleTree::<H>::verify_batch(&commitment, indexes, items, proof)
457    }
458}