merkle_heapless/
traits.rs

1use crate::prefixed::Prefixed;
2use crate::Error;
3use core::fmt::Debug;
4use core::hash::Hash;
5
6impl<const ARITY: usize, H: HashT> PartialEq for Prefixed<ARITY, H> {
7    fn eq(&self, other: &Self) -> bool {
8        self.hashes == other.hashes
9    }
10}
11
12/// trait for a hash pluggable to Merkle tree at compile time
13pub trait HashT {
14    /// output returned by hash implementor
15    type Output: Hash + Default + Copy + PartialEq + Debug  + From<u8>;
16    /// hash implementation
17    fn hash(input: &[u8]) -> Self::Output;
18    /// default implementation for concatenating and hashing hash values contained in the nodes
19    /// used by proof items for hashing with prefix
20    fn concat_then_hash(hashes: &[Self::Output]) -> Self::Output {
21        unsafe {
22            Self::hash(core::slice::from_raw_parts(
23                hashes.as_ref().as_ptr() as *const u8,
24                core::mem::size_of_val(hashes),
25            ))
26        }
27    }
28}
29/// trait that an item contained in a proof implements.
30/// [ProofBuilder] implementor relies on it
31pub trait ProofItemT<const ARITY: usize, H: HashT>: Clone + Default + Debug {
32    /// consructor
33    fn create(offset: usize, prefixed: Prefixed<ARITY, H>) -> Self;
34    /// hash the hashed input with its siblings
35    fn hash_with_siblings(self, word_hash: H::Output) -> Option<H::Output>;
36}
37/// trait for building a proof
38/// a proof is normally supposed to implement both [ProofBuilder] and [ProofValidator]
39/// [StaticTreeTrait.generate_proof]
40pub trait ProofBuilder<const ARITY: usize, H: HashT>: Default {
41    /// type of the item this proof contains
42    type Item: ProofItemT<ARITY, H>;
43    /// create a proof instance and assign its root
44    fn from_root(root: H::Output) -> Self;
45    /// add a new item to proof
46    fn push(&mut self, offset: usize, prefixed: Prefixed<ARITY, H>);
47}
48
49/// trait for verifying a proof generated by a [ProofBuilder] implementor
50pub trait ProofValidator {
51    /// verify the proof at given index
52    fn validate(self, input: &[u8]) -> bool;
53}
54/// trait for a basic Merkle Tree functionality
55pub trait StaticTreeTrait<const ARITY: usize, H: HashT, PB: ProofBuilder<ARITY, H>> {
56    /// generate a proof for a leaf at index
57    fn generate_proof(&self, index: usize) -> PB;
58    /// replace a leaf at index with a new value
59    fn replace(&mut self, index: usize, input: &[u8]);
60    /// replace a hashed leaf at index with a new hashed value
61    fn replace_leaf(&mut self, index: usize, leaf: H::Output);
62    /// return a root
63    fn root(&self) -> H::Output;
64    /// return a slice of leaves
65    fn leaves(&self) -> &[Prefixed<ARITY, H>];
66    /// a size (not necessarily a number of currently present leaves) of the leaf layer
67    fn base_layer_size(&self) -> usize;
68    /// returns tree's arity (determined at compile time)
69    fn arity(&self) -> usize {
70        ARITY
71    }
72    /// returns tree's height (determined at compile time)
73    fn height(&self) -> usize;
74}
75/// trait for append-only Merkle tree semantics
76pub trait AppendOnly {
77    /// appends a new leaf into the tree unless it's full
78    fn try_append(&mut self, input: &[u8]) -> Result<(), Error>;
79    /// number of leaves currently stored in the tree
80    fn num_of_leaves(&self) -> usize;
81}
82
83/// trait for Merkle tree supporting leaf removal
84pub trait CanRemove {
85    /// removes a leaf at index
86    fn remove(&mut self, index: usize);
87    /// number of leaves currently stored in the trsee
88    fn num_of_leaves(&self) -> usize;
89}