smtree/traits.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
6//! This module provides a generic set of traits
7//! for customizing nodes in the sparse Merkle tree.
8//!
9//! For examples on how to use these traits,
10//! see the implementations of the [example](../example/index.html) module.
11
12use crate::pad_secret::Secret;
13use crate::{error::DecodingError, index::TreeIndex};
14
15/// Trait for merging two child nodes to extract the parent node in the SMT.
16pub trait Mergeable {
17 /// A function to merge two child nodes as the parent node in the SMT.
18 fn merge(lch: &Self, rch: &Self) -> Self;
19}
20
21/// Trait for generating a padding node in the SMT.
22pub trait Paddable {
23 /// When the tree node of the input index doesn't exist,
24 /// we need to construct a padding node at that position.
25 fn padding(idx: &TreeIndex, secret: &Secret) -> Self;
26}
27
28/// Trait for getting the type name of tree nodes in the SMT.
29pub trait TypeName {
30 /// A function returning the type name of tree nodes in the SMT for logging purpose.
31 fn get_name() -> String {
32 "Name".to_owned()
33 }
34}
35
36/// Trait for generating a random value.
37pub trait Rand {
38 /// A function returning a random value of the corresponding type.
39 fn randomize(&mut self) {}
40}
41
42/// Trait for extracting a node with necessary information in Merkle proofs from a tree node.
43pub trait ProofExtractable {
44 /// The type of a node with necessary information in Merkle proofs.
45 type ProofNode;
46
47 /// Extracting a proof node from a tree node.
48 fn get_proof_node(&self) -> Self::ProofNode;
49}
50
51/// Trait for prove and verify padding nodes at random sampling.
52pub trait PaddingProvable {
53 /// The data type of the proof for a padding node.
54 type PaddingProof;
55
56 /// Generate the proof for padding node at given tree index.
57 fn prove_padding_node(&self, idx: &TreeIndex, secret: &Secret) -> Self::PaddingProof;
58
59 /// Verify the proof for a padding node at given tree index with associated node data in the Merkle proof.
60 ///
61 /// Note that ```node``` is the node data in the Merkle proof,
62 /// ```proof``` is the proof of the padding node,
63 /// ```idx``` is the tree index.
64 fn verify_padding_node(
65 node: &<Self as ProofExtractable>::ProofNode,
66 proof: &Self::PaddingProof,
67 idx: &TreeIndex,
68 ) -> bool
69 where
70 Self: ProofExtractable;
71}
72
73/// Trait for encoding.
74pub trait Serializable {
75 /// Encode the input object.
76 fn serialize(&self) -> Vec<u8>
77 where
78 Self: std::marker::Sized;
79
80 /// Decode some of the input bytes starting from the ```begin``` position as a ```Self``` object,
81 /// possibly with some bytes at the end left.
82 ///
83 /// Note that ```bytes``` is the input bytes to be decoded,
84 /// and ```begin``` is the beginning position of ```bytes```.
85 /// At the end of the execution,
86 /// ```begin``` should point to the first byte not decoded.
87 fn deserialize_as_a_unit(bytes: &[u8], begin: &mut usize) -> Result<Self, DecodingError>
88 where
89 Self: std::marker::Sized;
90
91 /// Decode the input bytes as a ```Self``` object, using up all bytes.
92 ///
93 /// The default implementation of this method is to first call ```deserialize_as_a_unit``` with ```begin = 0```.
94 /// If any error message is returned, return the error message directly.
95 /// If ```begin != bytes.len()```, which means there are bytes not used for decoding,
96 /// return [DecodingError::TooManyEncodedBytes](../error/enum.DecodingError.html#variant.TooManyEncodedBytes).
97 /// Otherwise, return the object of decoding result.
98 fn deserialize(bytes: &[u8]) -> Result<Self, DecodingError>
99 where
100 Self: std::marker::Sized,
101 {
102 let mut begin = 0usize;
103 let res = Self::deserialize_as_a_unit(bytes, &mut begin);
104 if let Err(e) = res {
105 return Err(e);
106 }
107 // Check if all input bytes are used for decoding.
108 if begin != bytes.len() {
109 println!("{}, {}", begin, bytes.len());
110 return Err(DecodingError::TooManyEncodedBytes);
111 }
112 res
113 }
114}
115
116/// Trait for generating and verifying inclusion proofs.
117pub trait InclusionProvable {
118 /// The data type of a node with necessary information in Merkle proofs.
119 type ProofNodeType;
120 /// The data type of the Merkle tree.
121 type TreeStruct;
122
123 /// Generate an inclusion proof for the input list of indexes.
124 fn generate_inclusion_proof(tree: &Self::TreeStruct, list: &[TreeIndex]) -> Option<Self>
125 where
126 Self: std::marker::Sized;
127
128 /// Verify the inclusion proof according to the leave nodes and the root.
129 fn verify_inclusion_proof(
130 &self,
131 leaves: &[Self::ProofNodeType],
132 root: &Self::ProofNodeType,
133 ) -> bool;
134}
135
136/// Trait for random sampling and verifying sampling proofs.
137pub trait RandomSampleable {
138 /// The data type of a node with necessary information in Merkle proofs.
139 type ProofNodeType;
140 /// The data type of the Merkle tree.
141 type TreeStruct;
142
143 /// Random sampling.
144 /// Returns the random sampling proof of the input index.
145 ///
146 /// If the input index is a real leaf node in the Merkle tree, return the inclusion proof of the leaf node.
147 ///
148 /// Otherwise, find the closest real leaf nodes left to and right to the input index respectively.
149 /// Return the inclusion proof of the closest nodes if exist,
150 /// together with proofs of necessary padding nodes showing that the leaf nodes are the closest.
151 fn random_sampling(tree: &Self::TreeStruct, idx: &TreeIndex, secret: &Secret) -> Self;
152
153 /// Verify the random sampling proof.
154 fn verify_random_sampling_proof(&self, root: &Self::ProofNodeType) -> bool;
155}