fix: use raw values for container keys and values (#312)

* Get rid of additional key/value hashing in container types

* Add test
This commit is contained in:
Ahmad Afuni 2025-06-25 22:41:52 +10:00 committed by GitHub
parent e1775d8578
commit 115c3c1152
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 42 additions and 32 deletions

View file

@ -732,11 +732,11 @@ pub mod tests {
}, },
examples::{attest_eth_friend, zu_kyc_pod_builder, zu_kyc_sign_pod_builders, EthDosHelper}, examples::{attest_eth_friend, zu_kyc_pod_builder, zu_kyc_sign_pod_builders, EthDosHelper},
frontend::{ frontend::{
literal, CustomPredicateBatchBuilder, MainPodBuilder, StatementTmplBuilder as STB, self, literal, CustomPredicateBatchBuilder, MainPodBuilder, StatementTmplBuilder as STB,
{self}, },
middleware::{
self, containers::Set, CustomPredicateRef, NativePredicate as NP, Value, DEFAULT_VD_SET,
}, },
middleware,
middleware::{CustomPredicateRef, NativePredicate as NP, Value, DEFAULT_VD_SET},
op, op,
}; };
@ -948,4 +948,25 @@ pub mod tests {
Ok(pod.verify()?) Ok(pod.verify()?)
} }
#[test]
fn test_set_contains() -> frontend::Result<()> {
let params = Params::default();
let mut builder = MainPodBuilder::new(&params, &*DEFAULT_VD_SET);
let set = [1, 2, 3].into_iter().map(|n| n.into()).collect();
let st = builder
.pub_op(op!(
new_entry,
"entry",
Set::new(params.max_merkle_proofs_containers, set).unwrap()
))
.unwrap();
builder.pub_op(op!(set_contains, st, 1))?;
let mut prover = Prover {};
let proof = builder.prove(&mut prover, &params).unwrap();
let pod = (proof.pod as Box<dyn Any>).downcast::<MainPod>().unwrap();
Ok(pod.verify()?)
}
} }

View file

@ -9,7 +9,7 @@ use serde::{Deserialize, Deserializer, Serialize};
use super::serialization::{ordered_map, ordered_set}; use super::serialization::{ordered_map, ordered_set};
#[cfg(feature = "backend_plonky2")] #[cfg(feature = "backend_plonky2")]
use crate::backends::plonky2::primitives::merkletree::{MerkleProof, MerkleTree}; use crate::backends::plonky2::primitives::merkletree::{MerkleProof, MerkleTree};
use crate::middleware::{hash_value, Error, Hash, Key, RawValue, Result, Value}; use crate::middleware::{Error, Hash, Key, RawValue, Result, Value};
/// Dictionary: the user original keys and values are hashed to be used in the leaf. /// Dictionary: the user original keys and values are hashed to be used in the leaf.
/// leaf.key=hash(original_key) /// leaf.key=hash(original_key)
@ -28,10 +28,8 @@ impl Dictionary {
/// max_depth determines the depth of the underlying MerkleTree, allowing to /// max_depth determines the depth of the underlying MerkleTree, allowing to
/// store 2^max_depth elements in the Dictionary /// store 2^max_depth elements in the Dictionary
pub fn new(max_depth: usize, kvs: HashMap<Key, Value>) -> Result<Self> { pub fn new(max_depth: usize, kvs: HashMap<Key, Value>) -> Result<Self> {
let kvs_raw: HashMap<RawValue, RawValue> = kvs let kvs_raw: HashMap<RawValue, RawValue> =
.iter() kvs.iter().map(|(k, v)| (k.raw(), v.raw())).collect();
.map(|(k, v)| (RawValue(k.hash().0), v.raw()))
.collect();
Ok(Self { Ok(Self {
mt: MerkleTree::new(max_depth, &kvs_raw)?, mt: MerkleTree::new(max_depth, &kvs_raw)?,
max_depth, max_depth,
@ -47,12 +45,12 @@ impl Dictionary {
.ok_or_else(|| Error::custom(format!("key \"{}\" not found", key.name()))) .ok_or_else(|| Error::custom(format!("key \"{}\" not found", key.name())))
} }
pub fn prove(&self, key: &Key) -> Result<(&Value, MerkleProof)> { pub fn prove(&self, key: &Key) -> Result<(&Value, MerkleProof)> {
let (_, mtp) = self.mt.prove(&RawValue(key.hash().0))?; let (_, mtp) = self.mt.prove(&key.raw())?;
let value = self.kvs.get(key).expect("key exists"); let value = self.kvs.get(key).expect("key exists");
Ok((value, mtp)) Ok((value, mtp))
} }
pub fn prove_nonexistence(&self, key: &Key) -> Result<MerkleProof> { pub fn prove_nonexistence(&self, key: &Key) -> Result<MerkleProof> {
Ok(self.mt.prove_nonexistence(&RawValue(key.hash().0))?) Ok(self.mt.prove_nonexistence(&key.raw())?)
} }
pub fn verify( pub fn verify(
max_depth: usize, max_depth: usize,
@ -61,7 +59,7 @@ impl Dictionary {
key: &Key, key: &Key,
value: &Value, value: &Value,
) -> Result<()> { ) -> Result<()> {
let key = RawValue(key.hash().0); let key = key.raw();
Ok(MerkleTree::verify( Ok(MerkleTree::verify(
max_depth, max_depth,
root, root,
@ -76,7 +74,7 @@ impl Dictionary {
proof: &MerkleProof, proof: &MerkleProof,
key: &Key, key: &Key,
) -> Result<()> { ) -> Result<()> {
let key = RawValue(key.hash().0); let key = key.raw();
Ok(MerkleTree::verify_nonexistence( Ok(MerkleTree::verify_nonexistence(
max_depth, root, proof, &key, max_depth, root, proof, &key,
)?) )?)
@ -130,8 +128,8 @@ impl Set {
let kvs_raw: HashMap<RawValue, RawValue> = set let kvs_raw: HashMap<RawValue, RawValue> = set
.iter() .iter()
.map(|e| { .map(|e| {
let h = hash_value(&e.raw()); let rv = e.raw();
(RawValue::from(h), RawValue::from(h)) (rv, rv)
}) })
.collect(); .collect();
Ok(Self { Ok(Self {
@ -147,23 +145,17 @@ impl Set {
self.set.contains(value) self.set.contains(value)
} }
pub fn prove(&self, value: &Value) -> Result<MerkleProof> { pub fn prove(&self, value: &Value) -> Result<MerkleProof> {
let h = hash_value(&value.raw()); let rv = value.raw();
let (_, proof) = self.mt.prove(&RawValue::from(h))?; let (_, proof) = self.mt.prove(&rv)?;
Ok(proof) Ok(proof)
} }
pub fn prove_nonexistence(&self, value: &Value) -> Result<MerkleProof> { pub fn prove_nonexistence(&self, value: &Value) -> Result<MerkleProof> {
let h = hash_value(&value.raw()); let rv = value.raw();
Ok(self.mt.prove_nonexistence(&RawValue::from(h))?) Ok(self.mt.prove_nonexistence(&rv)?)
} }
pub fn verify(max_depth: usize, root: Hash, proof: &MerkleProof, value: &Value) -> Result<()> { pub fn verify(max_depth: usize, root: Hash, proof: &MerkleProof, value: &Value) -> Result<()> {
let h = hash_value(&value.raw()); let rv = value.raw();
Ok(MerkleTree::verify( Ok(MerkleTree::verify(max_depth, root, proof, &rv, &rv)?)
max_depth,
root,
proof,
&RawValue::from(h),
&RawValue::from(h),
)?)
} }
pub fn verify_nonexistence( pub fn verify_nonexistence(
max_depth: usize, max_depth: usize,
@ -171,12 +163,9 @@ impl Set {
proof: &MerkleProof, proof: &MerkleProof,
value: &Value, value: &Value,
) -> Result<()> { ) -> Result<()> {
let h = hash_value(&value.raw()); let rv = value.raw();
Ok(MerkleTree::verify_nonexistence( Ok(MerkleTree::verify_nonexistence(
max_depth, max_depth, root, proof, &rv,
root,
proof,
&RawValue::from(h),
)?) )?)
} }
pub fn set(&self) -> &HashSet<Value> { pub fn set(&self) -> &HashSet<Value> {