Refactor frontend/middleware types (#194)
* unify fe/be NativeOp and NativePred * remove Origin in favour of PodId * Combine string and hash in Key * use middleware::AnchoredKey in frontend * merge frontend/middleware types * refactor custom predicates * clean up a bit * fix middleware custom tests * clean up * clean up 2 * add acronyms in typos list
This commit is contained in:
parent
9e860ef262
commit
c232c8dae5
33 changed files with 1985 additions and 2800 deletions
|
|
@ -23,7 +23,7 @@ use crate::{
|
|||
primitives::merkletree::MerkleClaimAndProofTarget,
|
||||
},
|
||||
middleware::{
|
||||
NativeOperation, NativePredicate, Params, Predicate, StatementArg, ToFields, Value,
|
||||
NativeOperation, NativePredicate, Params, Predicate, RawValue, StatementArg, ToFields,
|
||||
EMPTY_VALUE, F, HASH_SIZE, OPERATION_ARG_F_LEN, OPERATION_AUX_F_LEN, STATEMENT_ARG_F_LEN,
|
||||
VALUE_SIZE,
|
||||
},
|
||||
|
|
@ -294,7 +294,7 @@ pub trait CircuitBuilderPod<F: RichField + Extendable<D>, const D: usize> {
|
|||
fn add_virtual_operation(&mut self, params: &Params) -> OperationTarget;
|
||||
fn select_value(&mut self, b: BoolTarget, x: ValueTarget, y: ValueTarget) -> ValueTarget;
|
||||
fn select_bool(&mut self, b: BoolTarget, x: BoolTarget, y: BoolTarget) -> BoolTarget;
|
||||
fn constant_value(&mut self, v: Value) -> ValueTarget;
|
||||
fn constant_value(&mut self, v: RawValue) -> ValueTarget;
|
||||
fn is_equal_slice(&mut self, xs: &[Target], ys: &[Target]) -> BoolTarget;
|
||||
|
||||
// Convenience methods for checking values.
|
||||
|
|
@ -365,7 +365,7 @@ impl CircuitBuilderPod<F, D> for CircuitBuilder<F, D> {
|
|||
BoolTarget::new_unsafe(self.select(b, x.target, y.target))
|
||||
}
|
||||
|
||||
fn constant_value(&mut self, v: Value) -> ValueTarget {
|
||||
fn constant_value(&mut self, v: RawValue) -> ValueTarget {
|
||||
ValueTarget {
|
||||
elements: std::array::from_fn(|i| {
|
||||
self.constant(F::from_noncanonical_u64(v.0[i].to_noncanonical_u64()))
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use plonky2::{
|
|||
|
||||
use crate::{
|
||||
backends::plonky2::{
|
||||
basetypes::{Value, D, EMPTY_HASH, F, VALUE_SIZE},
|
||||
basetypes::D,
|
||||
circuits::{
|
||||
common::{
|
||||
CircuitBuilderPod, Flattenable, MerkleClaimTarget, OperationTarget,
|
||||
|
|
@ -24,8 +24,8 @@ use crate::{
|
|||
signedpod::SignedPod,
|
||||
},
|
||||
middleware::{
|
||||
hash_str, AnchoredKey, NativeOperation, NativePredicate, Params, PodType, Statement,
|
||||
StatementArg, ToFields, KEY_TYPE, SELF,
|
||||
AnchoredKey, NativeOperation, NativePredicate, Params, PodType, Statement, StatementArg,
|
||||
ToFields, Value, F, KEY_TYPE, SELF, VALUE_SIZE,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -304,7 +304,7 @@ impl OperationVerifyGadget {
|
|||
let st_code_ok = st.has_native_type(builder, &self.params, NativePredicate::ValueOf);
|
||||
|
||||
let expected_arg_prefix = builder.constants(
|
||||
&StatementArg::Key(AnchoredKey(SELF, EMPTY_HASH)).to_fields(&self.params)[..VALUE_SIZE],
|
||||
&StatementArg::Key(AnchoredKey::from((SELF, ""))).to_fields(&self.params)[..VALUE_SIZE],
|
||||
);
|
||||
let arg_prefix_ok =
|
||||
builder.is_equal_slice(&st.args[0].elements[..VALUE_SIZE], &expected_arg_prefix);
|
||||
|
|
@ -422,11 +422,13 @@ impl MainPodVerifyGadget {
|
|||
let type_statement = &pub_statements[0];
|
||||
// TODO: Store this hash in a global static with lazy init so that we don't have to
|
||||
// compute it every time.
|
||||
let key_type = hash_str(KEY_TYPE);
|
||||
let expected_type_statement = StatementTarget::from_flattened(
|
||||
&builder.constants(
|
||||
&Statement::ValueOf(AnchoredKey(SELF, key_type), Value::from(PodType::MockMain))
|
||||
.to_fields(params),
|
||||
&Statement::ValueOf(
|
||||
AnchoredKey::from((SELF, KEY_TYPE)),
|
||||
Value::from(PodType::MockMain),
|
||||
)
|
||||
.to_fields(params),
|
||||
),
|
||||
);
|
||||
builder.connect_flattenable(type_statement, &expected_type_statement);
|
||||
|
|
@ -541,7 +543,7 @@ mod tests {
|
|||
mainpod::{OperationArg, OperationAux},
|
||||
},
|
||||
},
|
||||
middleware::{OperationType, PodId},
|
||||
middleware::{OperationType, PodId, RawValue},
|
||||
};
|
||||
|
||||
fn operation_verify(
|
||||
|
|
@ -573,7 +575,7 @@ mod tests {
|
|||
.map(|pf| pf.into())
|
||||
.collect();
|
||||
|
||||
let operation_verify = OperationVerifyGadget {
|
||||
OperationVerifyGadget {
|
||||
params: params.clone(),
|
||||
}
|
||||
.eval(
|
||||
|
|
@ -634,10 +636,10 @@ mod tests {
|
|||
|
||||
// NewEntry
|
||||
let st1: mainpod::Statement =
|
||||
Statement::ValueOf(AnchoredKey(SELF, "hello".into()), 55.into()).into();
|
||||
Statement::ValueOf(AnchoredKey::from((SELF, "hello")), Value::from(55)).into();
|
||||
let st2: mainpod::Statement = Statement::ValueOf(
|
||||
AnchoredKey(PodId(Value::from(75).into()), "hello".into()),
|
||||
55.into(),
|
||||
AnchoredKey::from((PodId(RawValue::from(75).into()), "hello")),
|
||||
Value::from(55),
|
||||
)
|
||||
.into();
|
||||
let prev_statements = vec![st2];
|
||||
|
|
@ -665,13 +667,13 @@ mod tests {
|
|||
|
||||
// Eq
|
||||
let st2: mainpod::Statement = Statement::ValueOf(
|
||||
AnchoredKey(PodId(Value::from(75).into()), "world".into()),
|
||||
55.into(),
|
||||
AnchoredKey::from((PodId(RawValue::from(75).into()), "world")),
|
||||
Value::from(55),
|
||||
)
|
||||
.into();
|
||||
let st: mainpod::Statement = Statement::Equal(
|
||||
AnchoredKey(SELF, "hello".into()),
|
||||
AnchoredKey(PodId(Value::from(75).into()), "world".into()),
|
||||
AnchoredKey::from((SELF, "hello")),
|
||||
AnchoredKey::from((PodId(RawValue::from(75).into()), "world")),
|
||||
)
|
||||
.into();
|
||||
let op = mainpod::Operation(
|
||||
|
|
@ -684,13 +686,13 @@ mod tests {
|
|||
|
||||
// Lt
|
||||
let st2: mainpod::Statement = Statement::ValueOf(
|
||||
AnchoredKey(PodId(Value::from(88).into()), "hello".into()),
|
||||
56.into(),
|
||||
AnchoredKey::from((PodId(RawValue::from(88).into()), "hello")),
|
||||
Value::from(56),
|
||||
)
|
||||
.into();
|
||||
let st: mainpod::Statement = Statement::Lt(
|
||||
AnchoredKey(SELF, "hello".into()),
|
||||
AnchoredKey(PodId(Value::from(88).into()), "hello".into()),
|
||||
AnchoredKey::from((SELF, "hello")),
|
||||
AnchoredKey::from((PodId(RawValue::from(88).into()), "hello")),
|
||||
)
|
||||
.into();
|
||||
let op = mainpod::Operation(
|
||||
|
|
@ -711,16 +713,16 @@ mod tests {
|
|||
.collect();
|
||||
let mt = MerkleTree::new(params.max_depth_mt_gadget, &kvs)?;
|
||||
|
||||
let root = mt.root().into();
|
||||
let root_ak = AnchoredKey(PodId(Value::from(88).into()), "merkle root".into());
|
||||
let root = Value::from(mt.root());
|
||||
let root_ak = AnchoredKey::from((PodId(RawValue::from(88).into()), "merkle root"));
|
||||
|
||||
let key = 5.into();
|
||||
let key_ak = AnchoredKey(PodId(Value::from(88).into()), "key".into());
|
||||
let key_ak = AnchoredKey::from((PodId(RawValue::from(88).into()), "key"));
|
||||
|
||||
let no_key_pf = mt.prove_nonexistence(&key)?;
|
||||
|
||||
let root_st: mainpod::Statement = Statement::ValueOf(root_ak, root).into();
|
||||
let key_st: mainpod::Statement = Statement::ValueOf(key_ak, key).into();
|
||||
let root_st: mainpod::Statement = Statement::ValueOf(root_ak.clone(), root.clone()).into();
|
||||
let key_st: mainpod::Statement = Statement::ValueOf(key_ak.clone(), key.into()).into();
|
||||
let st: mainpod::Statement = Statement::NotContains(root_ak, key_ak).into();
|
||||
let op = mainpod::Operation(
|
||||
OperationType::Native(NativeOperation::NotContainsFromEntries),
|
||||
|
|
@ -729,7 +731,11 @@ mod tests {
|
|||
);
|
||||
|
||||
let merkle_proofs = vec![mainpod::MerkleClaimAndProof::try_from_middleware(
|
||||
¶ms, &root, &key, None, &no_key_pf,
|
||||
¶ms,
|
||||
&root.raw(),
|
||||
&key,
|
||||
None,
|
||||
&no_key_pf,
|
||||
)?];
|
||||
let prev_statements = vec![root_st, key_st];
|
||||
operation_verify(st, op, prev_statements, merkle_proofs.clone())?;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use plonky2::{
|
|||
|
||||
use crate::{
|
||||
backends::plonky2::{
|
||||
basetypes::{Value, D, EMPTY_VALUE, F},
|
||||
basetypes::D,
|
||||
circuits::common::{CircuitBuilderPod, StatementArgTarget, StatementTarget, ValueTarget},
|
||||
primitives::{
|
||||
merkletree::{MerkleProof, MerkleProofExistenceGadget, MerkleProofExistenceTarget},
|
||||
|
|
@ -22,7 +22,8 @@ use crate::{
|
|||
signedpod::SignedPod,
|
||||
},
|
||||
middleware::{
|
||||
hash_str, NativePredicate, Params, PodType, Predicate, ToFields, KEY_SIGNER, KEY_TYPE, SELF,
|
||||
hash_str, Key, NativePredicate, Params, PodType, Predicate, RawValue, ToFields, Value,
|
||||
EMPTY_VALUE, F, KEY_SIGNER, KEY_TYPE, SELF,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -48,7 +49,7 @@ impl SignedPodVerifyGadget {
|
|||
let type_mt_proof = &mt_proofs[0];
|
||||
let key_type = builder.constant_value(hash_str(KEY_TYPE).into());
|
||||
builder.connect_values(type_mt_proof.key, key_type);
|
||||
let value_type = builder.constant_value(Value::from(PodType::Signed));
|
||||
let value_type = builder.constant_value(Value::from(PodType::Signed).raw());
|
||||
builder.connect_values(type_mt_proof.value, value_type);
|
||||
|
||||
// 3.a. Verify signature
|
||||
|
|
@ -56,7 +57,7 @@ impl SignedPodVerifyGadget {
|
|||
|
||||
// 3.b. Verify signer (ie. signature.pk == merkletree.signer_leaf)
|
||||
let signer_mt_proof = &mt_proofs[1];
|
||||
let key_signer = builder.constant_value(hash_str(KEY_SIGNER).into());
|
||||
let key_signer = builder.constant_value(Key::from(KEY_SIGNER).raw());
|
||||
builder.connect_values(signer_mt_proof.key, key_signer);
|
||||
builder.connect_values(signer_mt_proof.value, signature.pk);
|
||||
|
||||
|
|
@ -122,21 +123,28 @@ impl SignedPodVerifyTarget {
|
|||
// - empty leaves (if needed)
|
||||
|
||||
// add proof verification of KEY_TYPE & KEY_SIGNER leaves
|
||||
let key_type_key = Value::from(hash_str(KEY_TYPE));
|
||||
let key_signer_key = Value::from(hash_str(KEY_SIGNER));
|
||||
let key_signer_value = [key_type_key, key_signer_key]
|
||||
let key_type_key = Key::from(KEY_TYPE);
|
||||
let key_signer_key = Key::from(KEY_SIGNER);
|
||||
let key_signer_value = [&key_type_key, &key_signer_key]
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, k)| {
|
||||
let (v, proof) = pod.dict.prove(k)?;
|
||||
self.mt_proofs[i].set_targets(pw, true, pod.dict.commitment(), proof, *k, v)?;
|
||||
self.mt_proofs[i].set_targets(
|
||||
pw,
|
||||
true,
|
||||
pod.dict.commitment(),
|
||||
proof,
|
||||
k.raw(),
|
||||
v.raw(),
|
||||
)?;
|
||||
Ok(v)
|
||||
})
|
||||
.collect::<Result<Vec<Value>>>()?[1];
|
||||
.collect::<Result<Vec<&Value>>>()?[1];
|
||||
|
||||
// add the verification of the rest of leaves
|
||||
let mut curr = 2; // since we already added key_type and key_signer
|
||||
for (k, v) in pod.dict.iter().sorted_by_key(|kv| kv.0) {
|
||||
for (k, v) in pod.dict.kvs().iter().sorted_by_key(|kv| kv.0.hash()) {
|
||||
if *k == key_type_key || *k == key_signer_key {
|
||||
// skip the key_type & key_signer leaves, since they have
|
||||
// already been checked
|
||||
|
|
@ -144,9 +152,16 @@ impl SignedPodVerifyTarget {
|
|||
}
|
||||
|
||||
let (obtained_v, proof) = pod.dict.prove(k)?;
|
||||
assert_eq!(obtained_v, *v); // sanity check
|
||||
assert_eq!(obtained_v, v); // sanity check
|
||||
|
||||
self.mt_proofs[curr].set_targets(pw, true, pod.dict.commitment(), proof, *k, *v)?;
|
||||
self.mt_proofs[curr].set_targets(
|
||||
pw,
|
||||
true,
|
||||
pod.dict.commitment(),
|
||||
proof,
|
||||
k.raw(),
|
||||
v.raw(),
|
||||
)?;
|
||||
curr += 1;
|
||||
}
|
||||
// sanity check
|
||||
|
|
@ -170,9 +185,9 @@ impl SignedPodVerifyTarget {
|
|||
}
|
||||
|
||||
// get the signer pk
|
||||
let pk = PublicKey(key_signer_value);
|
||||
let pk = PublicKey(key_signer_value.raw());
|
||||
// the msg signed is the pod.id
|
||||
let msg = Value::from(pod.id.0);
|
||||
let msg = RawValue::from(pod.id.0);
|
||||
|
||||
// set signature targets values
|
||||
self.signature
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue