merkle_cbt_lean/
lib.rs

1//! This crate is a `no_std` compatible tool to generate Merkle trees and
2//! and calculate root values in constrained RAM environments.
3//! Merkle tree elements are addressable from generalized "external" memory
4//! which could be anything from regular address space to address space
5//! on remote storage with arbitrary access rules, or even serial input pipes.
6//!
7//! The crate is based on CBMT implementation of the crate
8//! [`merkle-cbt`](https://docs.rs/merkle-cbt/latest/merkle_cbt/index.html).
9//! The root calculation outcomes are matching those of the `merkle-cbt` crate.
10//!
11//! Calculation sequence differs, and lemmas have different sorting.
12//! `MerkleProof` constructions of the two crates **are not** interchangeable.
13//!
14//! In this crate, all lemmas of the proof are sorted strictly left-to-right.
15//! It is also assumed that the proof was generated strictly by this algorithm:
16//! if the proof is not optimized, i.e., there are lemmas that could be merged
17//! without supplying valuer of leaves to be checked, this process will fail.
18//!
19//! In this crate, the root calculation is done with depth graph traverse, as
20//! opposed to width graph traverse in `merkle-cbt`. This approach substantially
21//! decreases memory requirements (other than lemmas and leaves storage space,
22//! it stores only one hash per tree layer to total ~log(n),
23//! opposed to storing whole layer in width traverse algorithms, ~n),
24//! at the cost of more time needed for the calculation
25//! (roughly O(n^2) versus O(n)).
26//!
27//! # Key definitions
28//!
29//! [`Leaf`] is generalized Merkle tree node, it has a corresponding value, an
30//! array of pre-known length N. Trait `Leaf` describes how such arrays could be
31//! read and (for `proof-gen` feature) written in memory.
32//!
33//! [`Hasher`] describes how the values of Merkle tree nodes are calculated and
34//! merged.
35//!
36//! [`MerkleProof`] contains leaves and lemmas, and root value could be
37//! calculated for it.
38//!
39//! # Example
40//! ```
41//! use external_memory_tools::ExternalMemory;
42//! use merkle_cbt_lean::{Hasher, Leaf, MerkleProof};
43//!
44//! const LEN: usize = 32;
45//!
46//! #[derive(Debug)]
47//! struct Blake3Hasher;
48//!
49//! impl Hasher<LEN> for Blake3Hasher {
50//!     fn make(bytes: &[u8]) -> [u8; LEN] {
51//!         blake3::hash(bytes).into()
52//!     }
53//!     fn merge(left: &[u8; LEN], right: &[u8; LEN]) -> [u8; LEN] {
54//!         blake3::hash(&[left.as_slice(), right.as_slice()].concat()).into()
55//!     }
56//! }
57//!
58//! #[derive(Copy, Clone, Debug)]
59//! struct Blake3Leaf([u8; LEN]);
60//!
61//! impl<E: ExternalMemory> Leaf<LEN, E> for Blake3Leaf {
62//!     fn read(&self, _ext_memory: &mut E) -> Result<[u8; LEN], E::ExternalMemoryError> {
63//!         Ok(self.0)
64//!     }
65//!     fn write(value: [u8; LEN], _ext_memory: &mut E) -> Result<Self, E::ExternalMemoryError> {
66//!         Ok(Self(value))
67//!     }
68//! }
69//!
70//! // All leaf values, deterministically sorted.
71//! let all_values = vec![[0; LEN], [1; LEN], [2; LEN], [3; LEN], [4; LEN], [5; LEN]];
72//!
73//! // Values that remain as leaves in the proof structure, other leaves will be
74//! // reduced to lemmas.
75//! // Remaining leaves will be available during the proof de-serialization.
76//! // It is assumed that the remaining leaf values are deterministically sorted
77//! // during serialization and de-serialization.
78//! let remaining_as_leaves = &[[0; LEN], [3; LEN], [1; LEN]];
79//!
80//! // Calculate `MerkleProof` for known complete set of values and known subset
81//! // of remaining values:
82//! let merkle_proof: MerkleProof<LEN, Blake3Leaf, (), Blake3Hasher> =
83//!     MerkleProof::for_leaves_subset(all_values, remaining_as_leaves, &mut ()).unwrap();
84//!
85//! // Serialize `MerkleProof` for data transferring:
86//!
87//! // Indices for remaining leaves:
88//! let indices = merkle_proof.indices();
89//!
90//! // Lemmas:
91//! let lemmas = merkle_proof.lemmas;
92//!
93//! // De-serialize `MerkleProof`:
94//! let mut merkle_proof_restored: MerkleProof<LEN, Blake3Leaf, (), Blake3Hasher> =
95//!     MerkleProof::new_with_external_indices(
96//!         remaining_as_leaves.to_vec(),
97//!         indices,
98//!         lemmas,
99//!     ).unwrap();
100//!
101//! // Calculate root:
102//! let root_restored = merkle_proof_restored.calculate_root(&mut ()).unwrap();
103//! ```
104//!
105//! # Features
106//!
107//! Crate supports `no_std` in `default-features = false` mode.
108//!
109//! With feature `proof-gen` (`no-std` compatible) [`MerkleProof`] could be
110//! generated for a subset of leaves. `proof-gen` is not needed to reconstruct
111//! `MerkleProof` from serialization, nor to calculate root for existing
112//! `MerkleProof`.
113#![no_std]
114#![deny(unused_crate_dependencies)]
115
116#[cfg(any(feature = "std", test))]
117#[macro_use]
118extern crate std;
119
120#[cfg(all(not(feature = "std"), not(test)))]
121#[macro_use]
122extern crate alloc;
123
124#[cfg(all(not(feature = "std"), not(test)))]
125extern crate core;
126
127#[cfg(feature = "std")]
128use std::error::Error;
129#[cfg(any(feature = "std", test))]
130use std::{
131    fmt::{Debug, Display, Formatter, Result as FmtResult},
132    marker::PhantomData,
133    string::String,
134    vec::Vec,
135};
136
137#[cfg(all(not(feature = "std"), not(test)))]
138use alloc::{string::String, vec::Vec};
139#[cfg(all(not(feature = "std"), not(test)))]
140use core::{
141    fmt::{Debug, Display, Formatter, Result as FmtResult},
142    marker::PhantomData,
143};
144
145use external_memory_tools::ExternalMemory;
146
147/// Describes how Merkle tree leaves are generated and merged.
148///
149/// Leaves are always sized, generic parameter N is leaf size.
150pub trait Hasher<const N: usize> {
151    fn make(bytes: &[u8]) -> [u8; N];
152    fn merge(left: &[u8; N], right: &[u8; N]) -> [u8; N];
153}
154
155/// Describes how Merkle tree leaves are accessed from memory.
156///
157/// Need to write the leaf into memory exists only when generating proof, is
158/// unlocked with feature `proof-gen`.
159pub trait Leaf<const N: usize, E: ExternalMemory>: Clone + Copy + Debug + Sized {
160    fn read(&self, ext_memory: &mut E) -> Result<[u8; N], E::ExternalMemoryError>;
161
162    #[cfg(any(feature = "proof-gen", test))]
163    fn write(data: [u8; N], ext_memory: &mut E) -> Result<Self, E::ExternalMemoryError>;
164}
165
166/// Index of the first leaf.
167fn first_leaf_index(total_leaves: usize) -> usize {
168    total_leaves - 1
169}
170
171/// Number of layers for a given nodes set.
172fn number_of_layers<const N: usize>(nodes: &[Node<N>]) -> Option<usize> {
173    nodes.last().map(|a| a.index.layer() as usize + 1usize)
174}
175
176/// Check set of hashes for duplicates.
177#[cfg(any(feature = "proof-gen", test))]
178fn has_duplicates<const N: usize, E: ExternalMemory>(
179    values: &[[u8; N]],
180) -> Result<bool, ErrorMT<E>> {
181    if values.is_empty() {
182        Err(ErrorMT::NoValuesInput)
183    } else {
184        Ok((1..values.len()).any(|i| values[i..].contains(&values[i - 1])))
185    }
186}
187
188/// Combination of lemmas and leaves, sufficient to calculate Merkle tree root.
189#[derive(Debug)]
190pub struct MerkleProof<const N: usize, L, E, H>
191where
192    L: Leaf<N, E>,
193    E: ExternalMemory,
194    H: Hasher<N>,
195{
196    /// Nodes existing as leaves
197    pub leaves: Vec<Node<N>>,
198
199    /// Nodes existing as lemmas
200    pub lemmas: Vec<L>,
201
202    /// Buffer, number of elements equals to the number of layers in
203    /// `MerkleProof`
204    buffer: Vec<Option<[u8; N]>>,
205
206    /// Path to previously processed element
207    previous_path: Option<Vec<Index>>,
208
209    /// Position of the leftmost leaf in the leaves iterator
210    leftmost_leaf_position: usize,
211    ext_memory: PhantomData<E>,
212    hasher_type: PhantomData<H>,
213}
214
215impl<const N: usize, L, E, H> MerkleProof<N, L, E, H>
216where
217    L: Leaf<N, E>,
218    E: ExternalMemory,
219    H: Hasher<N>,
220{
221    /// Make new `MerkleProof` from existing set of leaves and lemmas.
222    pub fn new(leaves: Vec<Node<N>>, lemmas: Vec<L>) -> Result<Self, ErrorMT<E>> {
223        let number_of_layers = number_of_layers::<N>(&leaves).ok_or(ErrorMT::NoLeavesInput)?;
224
225        // Input should be deduplicated
226        for i in 0..leaves.len() - 1 {
227            for j in i + 1..leaves.len() {
228                if leaves[j].value == leaves[i].value {
229                    return Err(ErrorMT::DuplicateLeafValues);
230                }
231            }
232        }
233
234        let mut buffer = Vec::with_capacity(number_of_layers);
235        for _i in 0..number_of_layers {
236            buffer.push(None);
237        }
238
239        let last_layer = number_of_layers - 1;
240        let last_layer_leftmost_node = 2u32.pow(last_layer as u32) - 1;
241        let leftmost_leaf_position = leaves
242            .iter()
243            .position(|leaf| leaf.index.0 >= last_layer_leftmost_node)
244            .expect("last layer always contains at least a single leaf");
245
246        Ok(Self {
247            leaves,
248            lemmas,
249            buffer,
250            previous_path: None,
251            leftmost_leaf_position,
252            ext_memory: PhantomData,
253            hasher_type: PhantomData,
254        })
255    }
256
257    /// Make new `MerkleProof` from leaves values, corresponding leaves `u32`
258    /// indices, and lemmas.
259    ///
260    /// Method is suitable for de-serialization in cases when values used to
261    /// generate leaves inside the proof are calculated from scratch.
262    pub fn new_with_external_indices(
263        leaves_values: Vec<[u8; N]>,
264        indices: Vec<u32>,
265        lemmas: Vec<L>,
266    ) -> Result<Self, ErrorMT<E>> {
267        if leaves_values.len() != indices.len() {
268            return Err(ErrorMT::IndicesValuesLengthMismatch);
269        }
270        let mut leaves: Vec<Node<N>> = Vec::new();
271        for i in 0..leaves_values.len() {
272            let leaf = Node::new(Index(indices[i]), leaves_values[i]);
273            leaves.push(leaf);
274        }
275        Self::new(leaves, lemmas)
276    }
277
278    /// Calculate `MerkleProof` for a complete set of leaf values
279    /// and a subset of leaf values that would not be reduced into lemmas.
280    ///
281    /// It is assumed here that the leaf values are deterministically sorted.
282    /// No additional sorting is done here.
283    #[cfg(any(feature = "proof-gen", test))]
284    pub fn for_leaves_subset(
285        all_values: Vec<[u8; N]>,
286        remaining_as_leaves: &[[u8; N]],
287        ext_memory: &mut E,
288    ) -> Result<Self, ErrorMT<E>> {
289        if has_duplicates::<N, E>(&all_values)? {
290            return Err(ErrorMT::DuplicateLeafValues);
291        }
292        if has_duplicates::<N, E>(remaining_as_leaves)? {
293            return Err(ErrorMT::DuplicateRemainingValues);
294        }
295
296        let first_leaf_index = first_leaf_index(all_values.len());
297
298        let mut remaining_indices_in_whole_set: Vec<usize> = Vec::new();
299
300        // find indices corresponding to remaining leaf values in complete set
301        for remaining_value in remaining_as_leaves.iter() {
302            let index_in_whole_set = all_values
303                .iter()
304                .position(|value| value == remaining_value)
305                .ok_or(ErrorMT::UnknownRemainingLeaf)?;
306            remaining_indices_in_whole_set.push(index_in_whole_set);
307        }
308
309        let mut leaves: Vec<Node<N>> = Vec::new();
310        let mut lemma_collector: Vec<Node<N>> = Vec::new();
311
312        // Split nodes into remaining set and lemma collector
313        for (index_in_whole_set, value) in all_values.into_iter().enumerate() {
314            let index = Index((index_in_whole_set + first_leaf_index) as u32);
315            let node = Node::new(index, value);
316
317            if remaining_indices_in_whole_set.contains(&index_in_whole_set) {
318                leaves.push(node);
319            } else {
320                lemma_collector.push(node);
321            }
322        }
323
324        let lemmas = match number_of_layers::<N>(&lemma_collector) {
325            Some(number_of_layers) => {
326                // Merge all nodes that could be merged in lemma collector
327                for layer in (0..number_of_layers).rev() {
328                    let mut lemmas_modified = false;
329                    let mut removal_set: Vec<Index> = Vec::new();
330                    let mut added_lemmas: Vec<Node<N>> = Vec::new();
331                    for (n, node) in lemma_collector.iter().enumerate() {
332                        if node.index.layer() == layer as u32 {
333                            if let Some(node_sibling_index) = node.index.sibling() {
334                                if let Some(i) =
335                                    lemma_collector.iter().position(|node_in_collector| {
336                                        node_in_collector.index == node_sibling_index
337                                    })
338                                {
339                                    if node.index.is_left() {
340                                        removal_set.push(node.index);
341                                        removal_set.push(node_sibling_index);
342                                        let left_node = &lemma_collector[n];
343                                        let right_node = &lemma_collector[i];
344                                        let parent_index = left_node.index.parent().expect(
345                                            "if there is a sibling, there must be a parent",
346                                        );
347                                        let parent_value =
348                                            H::merge(&left_node.value, &right_node.value);
349                                        added_lemmas.push(Node::new(parent_index, parent_value));
350                                        lemmas_modified = true;
351                                    }
352                                }
353                            }
354                        }
355                    }
356                    lemma_collector.retain(|x| !removal_set.contains(&x.index));
357                    lemma_collector.append(&mut added_lemmas);
358                    if !lemmas_modified {
359                        break;
360                    }
361                }
362
363                // Sort lemmas left-to-right
364                lemma_collector
365                    .sort_by(|a, b| a.index.path_top_down().cmp(&b.index.path_top_down()));
366                let mut lemmas: Vec<L> = Vec::new();
367                for node in lemma_collector.into_iter() {
368                    let lemma_to_add =
369                        L::write(node.value, ext_memory).map_err(ErrorMT::ExternalMemory)?;
370                    lemmas.push(lemma_to_add)
371                }
372                lemmas
373            }
374            None => Vec::new(),
375        };
376
377        Self::new(leaves, lemmas)
378    }
379
380    /// Provide ordered set of `u32` indices for all leaves in `MerkleProof`.
381    pub fn indices(&self) -> Vec<u32> {
382        let mut out: Vec<u32> = Vec::new();
383        for leaf in self.leaves.iter() {
384            out.push(leaf.index.0);
385        }
386        out
387    }
388
389    /// Provide ordered set of lemma values from `MerkleProof`.
390    pub fn lemma_values(&self, ext_memory: &mut E) -> Result<Vec<[u8; N]>, ErrorMT<E>> {
391        let mut out: Vec<[u8; N]> = Vec::new();
392        for lemma in self.lemmas.iter() {
393            out.push(lemma.read(ext_memory).map_err(ErrorMT::ExternalMemory)?);
394        }
395        Ok(out)
396    }
397
398    /// Merge next sibling nodes, one of the iterative steps in calculating the
399    /// root.
400    pub fn update(&mut self, ext_memory: &mut E) -> Result<(), ErrorMT<E>> {
401        let leftmost_leaf = self.leftmost_leaf();
402        let leftmost_leaf_index = leftmost_leaf.index;
403        let leftmost_leaf_value = leftmost_leaf.value;
404
405        let path_top_down = leftmost_leaf_index.path_top_down();
406        let first_layer_below_bifurcation = self.first_layer_below_bifurcation(&path_top_down)?;
407
408        let mut new_buffer_calc: Option<[u8; N]> = None;
409
410        // First traverse path up until layer below bifurcation
411        // and merge all leaves on the left
412        for (i, buffer_element) in self.buffer.iter_mut().enumerate().rev() {
413            if i == first_layer_below_bifurcation {
414                break;
415            }
416            if let Some(buffer_element_content) = buffer_element {
417                if let Some(new_buffer_calc_content) = new_buffer_calc {
418                    new_buffer_calc =
419                        Some(H::merge(buffer_element_content, &new_buffer_calc_content));
420                    *buffer_element = None;
421                } else {
422                    new_buffer_calc = Some(H::merge(
423                        buffer_element_content,
424                        &self
425                            .lemmas
426                            .remove(0)
427                            .read(ext_memory)
428                            .map_err(ErrorMT::ExternalMemory)?,
429                    ));
430                    *buffer_element = None;
431                }
432            } else if let Some(new_buffer_calc_content) = new_buffer_calc {
433                new_buffer_calc = Some(H::merge(
434                    &new_buffer_calc_content,
435                    &self
436                        .lemmas
437                        .remove(0)
438                        .read(ext_memory)
439                        .map_err(ErrorMT::ExternalMemory)?,
440                ));
441            }
442        }
443
444        if let Some(new_buffer_calc_content) = new_buffer_calc {
445            self.buffer[first_layer_below_bifurcation] = Some(new_buffer_calc_content);
446        }
447
448        // Second, traverse path down and fill buffer with lemmas on the right
449        for (layer, index) in path_top_down.iter().enumerate() {
450            if layer < first_layer_below_bifurcation {
451                continue;
452            }
453            if !index.is_left() {
454                self.buffer[layer + 1] = Some(
455                    self.lemmas
456                        .remove(0)
457                        .read(ext_memory)
458                        .map_err(ErrorMT::ExternalMemory)?,
459                );
460            }
461        }
462
463        // Finally, traverse buffer up merging all nodes that could be merged,
464        // starting from next leftmost leaf
465        let mut new_buffer_calc = leftmost_leaf_value;
466        for (i, buffer_element) in self.buffer.iter_mut().enumerate().rev() {
467            if leftmost_leaf_index.layer() >= i as u32 {
468                if let Some(buffer_element_content) = buffer_element {
469                    new_buffer_calc = H::merge(buffer_element_content, &new_buffer_calc);
470                    *buffer_element = None;
471                } else {
472                    *buffer_element = Some(new_buffer_calc);
473                    break;
474                }
475            }
476        }
477        self.previous_path = Some(path_top_down);
478        Ok(())
479    }
480
481    /// Take the leftmost leaf for processing and accordingly shift the leftmost
482    /// leaf position.
483    pub fn leftmost_leaf(&mut self) -> &Node<N> {
484        let leftmost_leaf = &self.leaves[self.leftmost_leaf_position];
485        self.leftmost_leaf_position += 1;
486        if self.leftmost_leaf_position == self.leaves.len() {
487            self.leftmost_leaf_position = 0;
488        }
489        leftmost_leaf
490    }
491
492    /// Index of the first layer under the node at which the previous known path
493    /// of `MerkleProof` deviates from the provided path.
494    pub fn first_layer_below_bifurcation(&self, path: &[Index]) -> Result<usize, ErrorMT<E>> {
495        match &self.previous_path {
496            Some(known_previous_path) => {
497                for (i, path_element) in path.iter().enumerate() {
498                    match known_previous_path.get(i) {
499                        Some(previous_path_element) => {
500                            if previous_path_element != path_element {
501                                return Ok(i + 1);
502                            }
503                        }
504                        None => return Err(ErrorMT::PrevPathShorter),
505                    }
506                }
507                Err(ErrorMT::PrevPathIdentical)
508            }
509            None => Ok(0usize),
510        }
511    }
512
513    /// Calculate root for `MerkleProof` through iterative updates.
514    pub fn calculate_root(&mut self, ext_memory: &mut E) -> Result<[u8; N], ErrorMT<E>> {
515        let mut found_root: Option<[u8; N]> = None;
516
517        // This guarantees that all leaves are consumed.
518        for _i in 0..self.leaves.len() {
519            self.update(ext_memory)?;
520        }
521
522        // Last vertical traverse after all leaves are consumed
523        // to process rightmost lemmas
524        let mut new_buffer_calc: Option<[u8; N]> = None;
525        for (i, buffer_element) in self.buffer.iter_mut().enumerate().rev() {
526            if i == 0 {
527                if new_buffer_calc.is_some() {
528                    found_root = new_buffer_calc
529                }
530                break;
531            }
532            if let Some(buffer_element_content) = buffer_element {
533                if let Some(new_buffer_calc_content) = new_buffer_calc {
534                    new_buffer_calc =
535                        Some(H::merge(buffer_element_content, &new_buffer_calc_content));
536                    *buffer_element = None;
537                } else {
538                    new_buffer_calc = Some(H::merge(
539                        buffer_element_content,
540                        &self
541                            .lemmas
542                            .remove(0)
543                            .read(ext_memory)
544                            .map_err(ErrorMT::ExternalMemory)?,
545                    ));
546                    *buffer_element = None;
547                }
548            } else if let Some(new_buffer_calc_content) = new_buffer_calc {
549                new_buffer_calc = Some(H::merge(
550                    &new_buffer_calc_content,
551                    &self
552                        .lemmas
553                        .remove(0)
554                        .read(ext_memory)
555                        .map_err(ErrorMT::ExternalMemory)?,
556                ));
557            }
558        }
559        if self.buffer[0].is_some() {
560            found_root = self.buffer[0];
561        }
562        match found_root {
563            Some(root) => {
564                if !self.lemmas.is_empty() {
565                    return Err(ErrorMT::LemmasNotEmpty);
566                }
567                Ok(root)
568            }
569            None => Err(ErrorMT::RootUnavailable),
570        }
571    }
572}
573
574/// Errors in Merkle tree construction and processing.
575#[derive(Debug, Eq, PartialEq)]
576pub enum ErrorMT<E: ExternalMemory> {
577    DuplicateLeafValues,
578    DuplicateRemainingValues,
579    ExternalMemory(E::ExternalMemoryError),
580    IndicesValuesLengthMismatch,
581    LemmasNotEmpty,
582    NoLeavesInput,
583    NoValuesInput,
584    PrevPathShorter,
585    PrevPathIdentical,
586    RootUnavailable,
587    UnknownRemainingLeaf,
588}
589
590impl<E: ExternalMemory> ErrorMT<E> {
591    fn error_text(&self) -> String {
592        match &self {
593            ErrorMT::DuplicateLeafValues => String::from("Error constructing Merkle proof. There are duplicates in complete set of leaf values."),
594            ErrorMT::DuplicateRemainingValues => String::from("Error constructing Merkle proof. There are duplicates in provided set of remaining leaf values."),
595            ErrorMT::ExternalMemory(external_memory_error) => format!("External memory error. {external_memory_error}"),
596            ErrorMT::IndicesValuesLengthMismatch => String::from("Error de-serializing the Merkle proof. Number of indices for leaves does not match the number of leaves."),
597            ErrorMT::LemmasNotEmpty => String::from("Error calculating Merkle root. Some lemmas from the proof remained unused."),
598            ErrorMT::NoLeavesInput => String::from("Error constructing Merkle proof. No leaves provided."),
599            ErrorMT::NoValuesInput => String::from("Error constructing Merkle proof. Provided set of leaf values is empty."),
600            ErrorMT::PrevPathShorter => String::from("Unable to find bifurcation point. Path to previously processed node is shorter. This is a bug, please report it."),
601            ErrorMT::PrevPathIdentical => String::from("Unable to find bifurcation point. Path to previously processed node is exactly same. This is a bug, please report it."),
602            ErrorMT::RootUnavailable => String::from("Provided data is insufficient to calculate Merkle root."),
603            ErrorMT::UnknownRemainingLeaf => String::from("Error constructing Merkle proof. Provided set of remaining leaf values contains a value that is not found in the complete set."),
604        }
605    }
606}
607
608impl<E: ExternalMemory> Display for ErrorMT<E> {
609    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
610        write!(f, "{}", self.error_text())
611    }
612}
613
614#[cfg(feature = "std")]
615impl<E: ExternalMemory> Error for ErrorMT<E> {
616    fn source(&self) -> Option<&(dyn Error + 'static)> {
617        None
618    }
619}
620
621/// Node, a combination of index and hash value.
622#[derive(Clone, Copy, Debug)]
623pub struct Node<const N: usize> {
624    pub index: Index,
625    pub value: [u8; N],
626}
627
628impl<const N: usize> Node<N> {
629    pub fn new(index: Index, value: [u8; N]) -> Self {
630        Self { index, value }
631    }
632}
633
634/// Node index.
635///
636/// All nodes in the Merkle tree structure are indexed as schematically shown
637/// below:
638/// ```text
639///             (0, or root)            layer 0
640///          /               \
641///        (1)               (2)        layer 1
642///      /     \           /     \
643///    (3)     (4)       (5)     (6)    layer 2
644///   /  \     /  \     /  \
645/// (7)  (8) (9) (10) (11) (12)         layer 3
646/// ```
647///
648/// Indexation persists even though in Merkle proof structure some leaves may
649/// already be reduced to the lemmas. In the scheme below, square brackets
650/// denote data available through lemmas, angle brackets denote data available
651/// as actual leaves:
652/// ```text
653///             (0, or root)
654///          /               \
655///        (1)               (2)
656///      /     \           /     \
657///    (3)     [4]       (5)     <6>
658///   /  \              /  \
659/// <7>  [8]          <11> <12>
660/// ```
661#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
662pub struct Index(pub u32);
663
664impl Index {
665    /// Layer corresponding to the index.
666    pub fn layer(&self) -> u32 {
667        (self.0 + 1).ilog2()
668    }
669
670    /// Set of indices leading from the root to the node with a given index.
671    pub fn path_top_down(&self) -> Vec<Index> {
672        let mut out: Vec<Index> = Vec::with_capacity(self.layer() as usize);
673        let mut current_index = *self;
674        while let Some(current_parent) = current_index.parent() {
675            out.push(current_index);
676            current_index = current_parent;
677        }
678        out.reverse();
679        out
680    }
681
682    /// Index of the node with which the given node would be merged to calculate
683    /// their parent node.
684    pub fn sibling(&self) -> Option<Self> {
685        if self.0 == 0 {
686            None
687        } else {
688            Some(Index(((self.0 + 1) ^ 1) - 1))
689        }
690    }
691
692    /// Index of the parent node for the given node.
693    pub fn parent(&self) -> Option<Self> {
694        if self.0 == 0 {
695            None
696        } else {
697            Some(Index((self.0 - 1) / 2))
698        }
699    }
700
701    /// Is the node left? (This affects how it is merged.)
702    pub fn is_left(&self) -> bool {
703        self.0 % 2 == 1
704    }
705}
706
707#[cfg(test)]
708mod tests {
709    use merkle_cbt::{merkle_tree::Merge, CBMT};
710    use std::vec;
711
712    use super::*;
713
714    struct MergeHashes;
715
716    impl Merge for MergeHashes {
717        type Item = [u8; 32];
718        fn merge(left: &Self::Item, right: &Self::Item) -> Self::Item {
719            blake3::hash(&[*left, *right].concat()).into()
720        }
721    }
722
723    const LEN: usize = 32;
724
725    #[derive(Debug)]
726    struct Blake3Hasher;
727
728    impl Hasher<LEN> for Blake3Hasher {
729        fn make(bytes: &[u8]) -> [u8; LEN] {
730            blake3::hash(bytes).into()
731        }
732        fn merge(left: &[u8; LEN], right: &[u8; LEN]) -> [u8; LEN] {
733            blake3::hash(&[left.as_slice(), right.as_slice()].concat()).into()
734        }
735    }
736
737    #[derive(Copy, Clone, Debug)]
738    struct Blake3Leaf([u8; LEN]);
739
740    impl<E: ExternalMemory> Leaf<LEN, E> for Blake3Leaf {
741        fn read(&self, _ext_memory: &mut E) -> Result<[u8; LEN], E::ExternalMemoryError> {
742            Ok(self.0)
743        }
744        fn write(value: [u8; LEN], _ext_memory: &mut E) -> Result<Self, E::ExternalMemoryError> {
745            Ok(Self(value))
746        }
747    }
748
749    #[test]
750    fn find_node_layer() {
751        assert_eq!(Index(0).layer(), 0);
752        assert_eq!(Index(1).layer(), 1);
753        assert_eq!(Index(2).layer(), 1);
754        assert_eq!(Index(4).layer(), 2);
755        assert_eq!(Index(12).layer(), 3);
756    }
757
758    #[test]
759    fn node_is_left() {
760        assert!(Index(1).is_left());
761        assert!(!Index(2).is_left());
762        assert!(!Index(4).is_left());
763        assert!(Index(11).is_left());
764    }
765
766    #[test]
767    fn correct_path() {
768        assert_eq!(Index(1).path_top_down(), vec![Index(1)]);
769        assert_eq!(Index(2).path_top_down(), vec![Index(2)]);
770        assert_eq!(Index(0).path_top_down(), vec![]);
771        assert_eq!(
772            Index(12).path_top_down(),
773            vec![Index(2), Index(5), Index(12)]
774        );
775        assert_eq!(
776            Index(13).path_top_down(),
777            vec![Index(2), Index(6), Index(13)]
778        );
779    }
780
781    #[test]
782    fn leftmost_node() {
783        let mut merkle_proof_mock = MerkleProof::<LEN, Blake3Leaf, (), Blake3Hasher>::new(
784            vec![
785                Node::<LEN>::new(Index(3), [1; LEN]),
786                Node::<LEN>::new(Index(9), [4; LEN]),
787                Node::<LEN>::new(Index(12), [7; LEN]),
788            ],
789            vec![],
790        )
791        .unwrap();
792        assert_eq!(merkle_proof_mock.leftmost_leaf().index.0, 9);
793
794        let mut merkle_proof_mock = MerkleProof::<LEN, Blake3Leaf, (), Blake3Hasher>::new(
795            vec![
796                Node::<LEN>::new(Index(1), [1; LEN]),
797                Node::<LEN>::new(Index(5), [6; LEN]),
798                Node::<LEN>::new(Index(13), [3; LEN]),
799            ],
800            vec![],
801        )
802        .unwrap();
803        assert_eq!(merkle_proof_mock.leftmost_leaf().index.0, 13);
804
805        let mut merkle_proof_mock = MerkleProof::<LEN, Blake3Leaf, (), Blake3Hasher>::new(
806            vec![
807                Node::<LEN>::new(Index(1), [4; LEN]),
808                Node::<LEN>::new(Index(12), [8; LEN]),
809                Node::<LEN>::new(Index(6), [3; LEN]),
810            ],
811            vec![],
812        )
813        .unwrap();
814        assert_eq!(merkle_proof_mock.leftmost_leaf().index.0, 12);
815    }
816
817    #[test]
818    fn two_leaf_tree() {
819        let mut merkle_proof = MerkleProof::<LEN, Blake3Leaf, (), Blake3Hasher>::new(
820            vec![
821                Node::<LEN>::new(Index(1), [0; LEN]),
822                Node::<LEN>::new(Index(2), [1; LEN]),
823            ],
824            vec![],
825        )
826        .unwrap();
827        let root = merkle_proof.calculate_root(&mut ()).unwrap();
828
829        let leaves = &[[0; 32], [1; 32]];
830        let root_merkle_cbt = CBMT::<[u8; 32], MergeHashes>::build_merkle_root(leaves);
831        assert_eq!(root, root_merkle_cbt);
832    }
833
834    fn test_set(total_leaves: usize) -> Vec<[u8; LEN]> {
835        let mut testbed: Vec<[u8; LEN]> = Vec::new();
836        for i in 0..total_leaves {
837            testbed.push(blake3::hash(&i.to_le_bytes()).into());
838        }
839        testbed
840    }
841
842    fn set_test(total_leaves: usize) {
843        let test_set = test_set(total_leaves);
844        let mut merkle_proof = MerkleProof::<LEN, Blake3Leaf, (), Blake3Hasher>::new(
845            test_set
846                .iter()
847                .enumerate()
848                .map(|(i, array)| {
849                    Node::<LEN>::new(Index((i + first_leaf_index(total_leaves)) as u32), *array)
850                })
851                .collect(),
852            vec![],
853        )
854        .unwrap();
855        let root = merkle_proof.calculate_root(&mut ()).unwrap();
856
857        let root_merkle_cbt = CBMT::<[u8; 32], MergeHashes>::build_merkle_root(&test_set);
858        assert_eq!(root, root_merkle_cbt);
859    }
860
861    #[test]
862    fn set_tree_1() {
863        set_test(3)
864    }
865
866    #[test]
867    fn set_tree_2() {
868        set_test(4)
869    }
870
871    #[test]
872    fn set_tree_3() {
873        set_test(15)
874    }
875
876    #[test]
877    fn set_tree_4() {
878        set_test(16)
879    }
880
881    #[test]
882    fn set_tree_5() {
883        set_test(17)
884    }
885
886    #[test]
887    fn set_tree_6() {
888        set_test(10000)
889    }
890
891    #[test]
892    fn proof_test_1() {
893        let all_values = vec![[0; 32], [1; 32]];
894        let remaining_as_leaves = &[[0; 32]];
895        let root_merkle_cbt = CBMT::<[u8; 32], MergeHashes>::build_merkle_root(&all_values);
896        let mut merkle_proof: MerkleProof<LEN, Blake3Leaf, (), Blake3Hasher> =
897            MerkleProof::for_leaves_subset(all_values, remaining_as_leaves, &mut ()).unwrap();
898        let root: [u8; 32] = merkle_proof.calculate_root(&mut ()).unwrap();
899        assert_eq!(root, root_merkle_cbt);
900    }
901
902    #[test]
903    fn proof_test_2() {
904        let all_values = vec![[0; 32], [1; 32], [2; 32], [3; 32], [4; 32]];
905        let remaining_as_leaves = &[[0; 32], [2; 32]];
906        let root_merkle_cbt = CBMT::<[u8; 32], MergeHashes>::build_merkle_root(&all_values);
907        let mut merkle_proof: MerkleProof<LEN, Blake3Leaf, (), Blake3Hasher> =
908            MerkleProof::for_leaves_subset(all_values, remaining_as_leaves, &mut ()).unwrap();
909        let root: [u8; 32] = merkle_proof.calculate_root(&mut ()).unwrap();
910        assert_eq!(root, root_merkle_cbt);
911    }
912
913    #[test]
914    fn proof_test_3() {
915        let all_values = vec![
916            [0; 32], [1; 32], [2; 32], [3; 32], [4; 32], [5; 32], [6; 32],
917        ];
918        let remaining_as_leaves = &[[0; 32], [6; 32]];
919        let root_merkle_cbt = CBMT::<[u8; 32], MergeHashes>::build_merkle_root(&all_values);
920        let mut merkle_proof: MerkleProof<LEN, Blake3Leaf, (), Blake3Hasher> =
921            MerkleProof::for_leaves_subset(all_values, remaining_as_leaves, &mut ()).unwrap();
922        let root: [u8; 32] = merkle_proof.calculate_root(&mut ()).unwrap();
923        assert_eq!(root, root_merkle_cbt);
924    }
925
926    #[test]
927    fn proof_test_4() {
928        let total_leaves = 1000;
929        let test_set = test_set(total_leaves);
930        let test_subset = [test_set[1], test_set[12], test_set[118]];
931        let root_merkle_cbt = CBMT::<[u8; 32], MergeHashes>::build_merkle_root(&test_set);
932
933        let mut merkle_proof: MerkleProof<LEN, Blake3Leaf, (), Blake3Hasher> =
934            MerkleProof::for_leaves_subset(test_set, test_subset.as_slice(), &mut ()).unwrap();
935        let root: [u8; 32] = merkle_proof.calculate_root(&mut ()).unwrap();
936
937        assert_eq!(root, root_merkle_cbt);
938    }
939
940    #[test]
941    fn proof_test_5() {
942        let all_values = vec![[0; 32], [1; 32], [2; 32], [3; 32], [4; 32], [5; 32]];
943        let remaining_as_leaves = &[[0; 32], [1; 32], [2; 32], [3; 32], [4; 32], [5; 32]];
944        let root_merkle_cbt = CBMT::<[u8; 32], MergeHashes>::build_merkle_root(&all_values);
945        let mut merkle_proof: MerkleProof<LEN, Blake3Leaf, (), Blake3Hasher> =
946            MerkleProof::for_leaves_subset(all_values, remaining_as_leaves, &mut ()).unwrap();
947        let root: [u8; 32] = merkle_proof.calculate_root(&mut ()).unwrap();
948        assert_eq!(root, root_merkle_cbt);
949    }
950
951    #[test]
952    fn error_gen_1() {
953        let all_values = vec![
954            [0; 32], [1; 32], [2; 32], [3; 32], [4; 32], [5; 32], [0; 32],
955        ];
956        let remaining_as_leaves = &[[0; 32], [3; 32]];
957        assert_eq!(
958            MerkleProof::<LEN, Blake3Leaf, (), Blake3Hasher>::for_leaves_subset(
959                all_values,
960                remaining_as_leaves,
961                &mut ()
962            )
963            .unwrap_err(),
964            ErrorMT::DuplicateLeafValues
965        );
966    }
967
968    #[test]
969    fn error_gen_2() {
970        let all_values = vec![[0; 32], [1; 32], [2; 32], [3; 32]];
971        let remaining_as_leaves = &[[1; 32], [1; 32]];
972        assert_eq!(
973            MerkleProof::<LEN, Blake3Leaf, (), Blake3Hasher>::for_leaves_subset(
974                all_values,
975                remaining_as_leaves,
976                &mut ()
977            )
978            .unwrap_err(),
979            ErrorMT::DuplicateRemainingValues
980        );
981    }
982
983    #[test]
984    fn error_gen_3() {
985        let all_values = vec![[0; 32], [1; 32], [2; 32], [3; 32], [4; 32], [5; 32]];
986        let remaining_as_leaves = &[[0; 32], [6; 32]];
987        assert_eq!(
988            MerkleProof::<LEN, Blake3Leaf, (), Blake3Hasher>::for_leaves_subset(
989                all_values,
990                remaining_as_leaves,
991                &mut ()
992            )
993            .unwrap_err(),
994            ErrorMT::UnknownRemainingLeaf
995        );
996    }
997
998    #[test]
999    fn error_gen_4() {
1000        assert_eq!(
1001            MerkleProof::<LEN, Blake3Leaf, (), Blake3Hasher>::new(vec![], vec![]).unwrap_err(),
1002            ErrorMT::NoLeavesInput
1003        );
1004    }
1005
1006    #[test]
1007    fn error_gen_5() {
1008        assert_eq!(
1009            MerkleProof::<LEN, Blake3Leaf, (), Blake3Hasher>::for_leaves_subset(
1010                vec![],
1011                &[],
1012                &mut ()
1013            )
1014            .unwrap_err(),
1015            ErrorMT::NoValuesInput
1016        );
1017    }
1018}