chore(backend): implement more circuit op logic (#173)

* Add backend MerkleProof type

* Add eval_not_contains

* Remove print statement

* Handle some edge cases

* Add test

* Add missing ?

* Optimisation and stylistic changes

* Code review
This commit is contained in:
Ahmad Afuni 2025-04-08 02:15:46 +10:00 committed by GitHub
parent adad695ba5
commit 6528914366
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 502 additions and 48 deletions

View file

@ -23,13 +23,21 @@ pub struct MerkleTree {
impl MerkleTree {
/// builds a new `MerkleTree` where the leaves contain the given key-values
pub fn new(max_depth: usize, kvs: &HashMap<Value, Value>) -> Result<Self> {
let mut root = Node::Intermediate(Intermediate::empty());
// Construct leaves.
let mut leaves: Vec<_> = kvs
.iter()
.map(|(k, v)| Leaf::new(max_depth, *k, *v))
.collect::<Result<_>>()?;
for (k, v) in kvs.iter() {
let leaf = Leaf::new(max_depth, *k, *v)?;
// Start with a leaf or conclude with an empty node as root.
let mut root = leaves.pop().map(|l| Node::Leaf(l)).unwrap_or(Node::None);
// Iterate over remaining leaves (if any) and add them.
for leaf in leaves.into_iter() {
root.add_leaf(0, max_depth, leaf)?;
}
// Fill in hashes.
let _ = root.compute_hash();
Ok(Self { max_depth, root })
}

View file

@ -35,8 +35,9 @@ pub struct MerkleProofGadget {
pub max_depth: usize,
}
pub struct MerkleProofTarget {
max_depth: usize,
#[derive(Clone)]
pub struct MerkleClaimAndProofTarget {
pub(crate) max_depth: usize,
// `enabled` determines if the merkleproof verification is enabled
pub(crate) enabled: BoolTarget,
pub(crate) root: HashOutTarget,
@ -51,7 +52,7 @@ pub struct MerkleProofTarget {
impl MerkleProofGadget {
/// creates the targets and defines the logic of the circuit
pub fn eval(&self, builder: &mut CircuitBuilder<F, D>) -> Result<MerkleProofTarget> {
pub fn eval(&self, builder: &mut CircuitBuilder<F, D>) -> Result<MerkleClaimAndProofTarget> {
let enabled = builder.add_virtual_bool_target_safe();
let root = builder.add_virtual_hash();
let key = builder.add_virtual_value();
@ -133,7 +134,7 @@ impl MerkleProofGadget {
builder.connect(computed_root[j], expected_root[j]);
}
Ok(MerkleProofTarget {
Ok(MerkleClaimAndProofTarget {
max_depth: self.max_depth,
enabled,
existence,
@ -148,7 +149,7 @@ impl MerkleProofGadget {
}
}
impl MerkleProofTarget {
impl MerkleClaimAndProofTarget {
/// assigns the given values to the targets
pub fn set_targets(
&self,