implement the specified sparse merkletree (#82)
* wip * prototype custom predicates 1b * feat: implement custom pred recursion * files reorg, add github CI for rustfmt checks * start sparsemerkletree. impl add_leaf method, initial Leaf & Intermediate types with methods * mt: add hash computation of all the nodes in the tree, add method to print the tree to visualize it as a graphviz * mt: add (till the leaf) method which is used by get,contains,prove methods * mt: add verify (of inclusion) method * mt: update 'down' method to reuse siblings, update get,contains,prove methods (the three use 'down' under the hood) * Add nonexistence proofs and iterator * Add iterator test * migrate usage of old merkletree to the new merkletree impl in POD2 code --------- Co-authored-by: Eduard S. <eduardsanou@posteo.net> Co-authored-by: Ahmad <root@ahmadafuni.com>
This commit is contained in:
parent
2e9719a1ca
commit
c101d94530
9 changed files with 649 additions and 198 deletions
|
|
@ -6,6 +6,7 @@ use plonky2::plonk::config::Hasher;
|
|||
use std::collections::HashMap;
|
||||
|
||||
use super::{Hash, Value, EMPTY};
|
||||
use crate::constants::MAX_DEPTH;
|
||||
use crate::primitives::merkletree::{MerkleProof, MerkleTree};
|
||||
|
||||
/// Dictionary: the user original keys and values are hashed to be used in the leaf.
|
||||
|
|
@ -18,11 +19,11 @@ pub struct Dictionary {
|
|||
}
|
||||
|
||||
impl Dictionary {
|
||||
pub fn new(kvs: &HashMap<Hash, Value>) -> Self {
|
||||
pub fn new(kvs: &HashMap<Hash, Value>) -> Result<Self> {
|
||||
let kvs: HashMap<Value, Value> = kvs.into_iter().map(|(&k, &v)| (Value(k.0), v)).collect();
|
||||
Self {
|
||||
mt: MerkleTree::new(&kvs),
|
||||
}
|
||||
Ok(Self {
|
||||
mt: MerkleTree::new(MAX_DEPTH, &kvs)?,
|
||||
})
|
||||
}
|
||||
pub fn commitment(&self) -> Hash {
|
||||
self.mt.root()
|
||||
|
|
@ -30,25 +31,25 @@ impl Dictionary {
|
|||
pub fn get(&self, key: &Value) -> Result<Value> {
|
||||
self.mt.get(key)
|
||||
}
|
||||
pub fn prove(&self, key: &Value) -> Result<MerkleProof> {
|
||||
pub fn prove(&self, key: &Value) -> Result<(Value, MerkleProof)> {
|
||||
self.mt.prove(key)
|
||||
}
|
||||
pub fn prove_nonexistence(&self, key: &Value) -> Result<MerkleProof> {
|
||||
self.mt.prove_nonexistence(key)
|
||||
}
|
||||
pub fn verify(root: Hash, proof: &MerkleProof, key: &Value, value: &Value) -> Result<()> {
|
||||
MerkleTree::verify(root, proof, key, value)
|
||||
MerkleTree::verify(MAX_DEPTH, root, proof, key, value)
|
||||
}
|
||||
pub fn verify_nonexistence(root: Hash, proof: &MerkleProof, key: &Value) -> Result<()> {
|
||||
MerkleTree::verify_nonexistence(root, proof, key)
|
||||
MerkleTree::verify_nonexistence(MAX_DEPTH, root, proof, key)
|
||||
}
|
||||
pub fn iter(&self) -> std::collections::hash_map::Iter<Value, Value> {
|
||||
pub fn iter(&self) -> crate::primitives::merkletree::Iter {
|
||||
self.mt.iter()
|
||||
}
|
||||
}
|
||||
impl<'a> IntoIterator for &'a Dictionary {
|
||||
type Item = (&'a Value, &'a Value);
|
||||
type IntoIter = std::collections::hash_map::Iter<'a, Value, Value>;
|
||||
type IntoIter = crate::primitives::merkletree::Iter<'a>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.mt.iter()
|
||||
|
|
@ -71,7 +72,7 @@ pub struct Set {
|
|||
}
|
||||
|
||||
impl Set {
|
||||
pub fn new(set: &Vec<Value>) -> Self {
|
||||
pub fn new(set: &Vec<Value>) -> Result<Self> {
|
||||
let kvs: HashMap<Value, Value> = set
|
||||
.into_iter()
|
||||
.map(|e| {
|
||||
|
|
@ -79,29 +80,30 @@ impl Set {
|
|||
(Value(h), EMPTY)
|
||||
})
|
||||
.collect();
|
||||
Self {
|
||||
mt: MerkleTree::new(&kvs),
|
||||
}
|
||||
Ok(Self {
|
||||
mt: MerkleTree::new(MAX_DEPTH, &kvs)?,
|
||||
})
|
||||
}
|
||||
pub fn commitment(&self) -> Hash {
|
||||
self.mt.root()
|
||||
}
|
||||
pub fn contains(&self, value: &Value) -> bool {
|
||||
pub fn contains(&self, value: &Value) -> Result<bool> {
|
||||
self.mt.contains(value)
|
||||
}
|
||||
pub fn prove(&self, value: &Value) -> Result<MerkleProof> {
|
||||
self.mt.prove(value)
|
||||
let (_, proof) = self.mt.prove(value)?;
|
||||
Ok(proof)
|
||||
}
|
||||
pub fn prove_nonexistence(&self, value: &Value) -> Result<MerkleProof> {
|
||||
self.mt.prove_nonexistence(value)
|
||||
}
|
||||
pub fn verify(root: Hash, proof: &MerkleProof, value: &Value) -> Result<()> {
|
||||
MerkleTree::verify(root, proof, value, &EMPTY)
|
||||
MerkleTree::verify(MAX_DEPTH, root, proof, value, &EMPTY)
|
||||
}
|
||||
pub fn verify_nonexistence(root: Hash, proof: &MerkleProof, value: &Value) -> Result<()> {
|
||||
MerkleTree::verify_nonexistence(root, proof, value)
|
||||
MerkleTree::verify_nonexistence(MAX_DEPTH, root, proof, value)
|
||||
}
|
||||
pub fn iter(&self) -> std::collections::hash_map::Iter<Value, Value> {
|
||||
pub fn iter(&self) -> crate::primitives::merkletree::Iter {
|
||||
self.mt.iter()
|
||||
}
|
||||
}
|
||||
|
|
@ -123,16 +125,16 @@ pub struct Array {
|
|||
}
|
||||
|
||||
impl Array {
|
||||
pub fn new(array: &Vec<Value>) -> Self {
|
||||
pub fn new(array: &Vec<Value>) -> Result<Self> {
|
||||
let kvs: HashMap<Value, Value> = array
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(i, &e)| (Value::from(i as i64), e))
|
||||
.collect();
|
||||
|
||||
Self {
|
||||
mt: MerkleTree::new(&kvs),
|
||||
}
|
||||
Ok(Self {
|
||||
mt: MerkleTree::new(MAX_DEPTH, &kvs)?,
|
||||
})
|
||||
}
|
||||
pub fn commitment(&self) -> Hash {
|
||||
self.mt.root()
|
||||
|
|
@ -140,13 +142,13 @@ impl Array {
|
|||
pub fn get(&self, i: usize) -> Result<Value> {
|
||||
self.mt.get(&Value::from(i as i64))
|
||||
}
|
||||
pub fn prove(&self, i: usize) -> Result<MerkleProof> {
|
||||
pub fn prove(&self, i: usize) -> Result<(Value, MerkleProof)> {
|
||||
self.mt.prove(&Value::from(i as i64))
|
||||
}
|
||||
pub fn verify(root: Hash, proof: &MerkleProof, i: usize, value: &Value) -> Result<()> {
|
||||
MerkleTree::verify(root, proof, &Value::from(i as i64), value)
|
||||
MerkleTree::verify(MAX_DEPTH, root, proof, &Value::from(i as i64), value)
|
||||
}
|
||||
pub fn iter(&self) -> std::collections::hash_map::Iter<Value, Value> {
|
||||
pub fn iter(&self) -> crate::primitives::merkletree::Iter {
|
||||
self.mt.iter()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,15 @@ pub type Entry = (String, Value);
|
|||
#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq)]
|
||||
pub struct Value(pub [F; 4]);
|
||||
|
||||
impl Value {
|
||||
pub fn to_bytes(self) -> Vec<u8> {
|
||||
self.0
|
||||
.iter()
|
||||
.flat_map(|e| e.to_canonical_u64().to_le_bytes())
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for Value {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
for (lhs, rhs) in self.0.iter().zip(other.0.iter()).rev() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue