Merkleproof verify circuit (#143)
* merkletree: add keypath circuit * merkletree-circuit: implement proof of existence verification in-circuit * parametrize max_depth at the tree circuit * Constrain selectors in-circuit * implement merketree nonexistence proof circuit, and add edgecase tests * add non-existence proofs documentation in the mdbook, mv EMPTY->EMPTY_VALUE & NULL->EMPTY_HASH, dependency clean and public exposure methods * review comments, some extra polishing and add a test that expects wrong proofs to fail * Add circuit to check only merkleproofs-of-existence With this, the merkletree_circuit module offers two different circuits: - `MerkleProofCircuit`: allows to verify both proofs of existence and proofs non-existence with the same circuit. - `MerkleProofExistenceCircuit`: allows to verify proofs of existence only. In this way, if only proofs of existence are needed, `MerkleProofExistenceCircuit` should be used, which requires less amount of constraints than `MerkleProofCircuit`. * Code review --------- Co-authored-by: Ahmad <root@ahmadafuni.com>
This commit is contained in:
parent
abce0af675
commit
b1689c5b37
9 changed files with 683 additions and 26 deletions
|
|
@ -35,6 +35,6 @@
|
|||
/// then the Value, Hash and F types would come from the plonky3 backend.
|
||||
#[cfg(feature = "backend_plonky2")]
|
||||
pub use crate::backends::plonky2::basetypes::{
|
||||
hash_fields, hash_str, hash_value, Hash, Value, EMPTY, F, HASH_SIZE, NULL, SELF_ID_HASH,
|
||||
VALUE_SIZE,
|
||||
hash_fields, hash_str, hash_value, Hash, Value, EMPTY_HASH, EMPTY_VALUE, F, HASH_SIZE,
|
||||
SELF_ID_HASH, VALUE_SIZE,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use crate::constants::MAX_DEPTH;
|
|||
#[cfg(feature = "backend_plonky2")]
|
||||
use crate::backends::plonky2::primitives::merkletree::{Iter as TreeIter, MerkleProof, MerkleTree};
|
||||
|
||||
use super::basetypes::{hash_value, Hash, Value, EMPTY};
|
||||
use super::basetypes::{hash_value, Hash, Value, EMPTY_VALUE};
|
||||
|
||||
/// Dictionary: the user original keys and values are hashed to be used in the leaf.
|
||||
/// leaf.key=hash(original_key)
|
||||
|
|
@ -78,7 +78,7 @@ impl Set {
|
|||
.iter()
|
||||
.map(|e| {
|
||||
let h = hash_value(e);
|
||||
(Value::from(h), EMPTY)
|
||||
(Value::from(h), EMPTY_VALUE)
|
||||
})
|
||||
.collect();
|
||||
Ok(Self {
|
||||
|
|
@ -99,7 +99,7 @@ impl Set {
|
|||
self.mt.prove_nonexistence(value)
|
||||
}
|
||||
pub fn verify(root: Hash, proof: &MerkleProof, value: &Value) -> Result<()> {
|
||||
MerkleTree::verify(MAX_DEPTH, root, proof, value, &EMPTY)
|
||||
MerkleTree::verify(MAX_DEPTH, root, proof, value, &EMPTY_VALUE)
|
||||
}
|
||||
pub fn verify_nonexistence(root: Hash, proof: &MerkleProof, value: &Value) -> Result<()> {
|
||||
MerkleTree::verify_nonexistence(MAX_DEPTH, root, proof, value)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ impl fmt::Display for PodId {
|
|||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
if *self == SELF {
|
||||
write!(f, "self")
|
||||
} else if self.0 == NULL {
|
||||
} else if self.0 == EMPTY_HASH {
|
||||
write!(f, "null")
|
||||
} else {
|
||||
write!(f, "{}", self.0)
|
||||
|
|
@ -185,7 +185,7 @@ impl Pod for NonePod {
|
|||
true
|
||||
}
|
||||
fn id(&self) -> PodId {
|
||||
PodId(NULL)
|
||||
PodId(EMPTY_HASH)
|
||||
}
|
||||
fn pub_statements(&self) -> Vec<Statement> {
|
||||
Vec::new()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue