Add verifier-datas tree (set) & in-circuit verification (#274)
* containers: add method to create new {Dict,Set,Array} with custom max_depth
* add vds_tree computation, update tree circuit interface
* add VDTree struct, add DEFAULT_VD_TREE, integrate it with MainPod,EmptyPod,frontend,etc.
* adapt frontend/serialization tests to new containers field (max_depth)
* adapt interfaces to allow using custom vd_tree in frontend & backend constructors
* rename VDTree to VDSet (and derivate namings too)
* containers 'new' always with param 'max_depth', use params.max_depth_mt_containers instead of the global constant MAX_DEPTH
* adapt after rebasing the branch to main latest changes
* apply review suggestions from @ed255
* use emptypod vd_mt_proofs (using vd_set as circuit input), merge the two existing set_targets methods of MainPodVerifyTarget
* document VDSet & vds_root
This commit is contained in:
parent
6258e52e1a
commit
273d803ebd
17 changed files with 486 additions and 259 deletions
|
|
@ -294,7 +294,7 @@ mod tests {
|
|||
backends::plonky2::mock::mainpod::MockProver,
|
||||
examples::custom::{eth_dos_batch, eth_friend_batch},
|
||||
frontend::MainPodBuilder,
|
||||
middleware::{self, containers::Set, CustomPredicateRef, Params, PodType},
|
||||
middleware::{self, containers::Set, CustomPredicateRef, Params, PodType, DEFAULT_VD_SET},
|
||||
op,
|
||||
};
|
||||
|
||||
|
|
@ -328,6 +328,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_desugared_gt_custom_pred() -> Result<()> {
|
||||
let params = Params::default();
|
||||
let vd_set = &*DEFAULT_VD_SET;
|
||||
let mut builder = CustomPredicateBatchBuilder::new(params.clone(), "gt_custom_pred".into());
|
||||
|
||||
let gt_stb = StatementTmplBuilder::new(NativePredicate::Gt)
|
||||
|
|
@ -344,7 +345,7 @@ mod tests {
|
|||
let batch_clone = batch.clone();
|
||||
let gt_custom_pred = CustomPredicateRef::new(batch, 0);
|
||||
|
||||
let mut mp_builder = MainPodBuilder::new(¶ms);
|
||||
let mut mp_builder = MainPodBuilder::new(¶ms, &vd_set);
|
||||
|
||||
// 2 > 1
|
||||
let s1 = mp_builder.literal(true, Value::from(2))?;
|
||||
|
|
@ -376,6 +377,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_desugared_set_contains_custom_pred() -> Result<()> {
|
||||
let params = Params::default();
|
||||
let vd_set = &*DEFAULT_VD_SET;
|
||||
let mut builder =
|
||||
CustomPredicateBatchBuilder::new(params.clone(), "set_contains_custom_pred".into());
|
||||
|
||||
|
|
@ -392,10 +394,13 @@ mod tests {
|
|||
let batch = builder.finish();
|
||||
let batch_clone = batch.clone();
|
||||
|
||||
let mut mp_builder = MainPodBuilder::new(¶ms);
|
||||
let mut mp_builder = MainPodBuilder::new(¶ms, &vd_set);
|
||||
|
||||
let set_values: HashSet<Value> = [1, 2, 3].iter().map(|i| Value::from(*i)).collect();
|
||||
let s1 = mp_builder.literal(true, Value::from(Set::new(set_values)?))?;
|
||||
let s1 = mp_builder.literal(
|
||||
true,
|
||||
Value::from(Set::new(params.max_depth_mt_containers, set_values)?),
|
||||
)?;
|
||||
let s2 = mp_builder.literal(true, Value::from(1))?;
|
||||
|
||||
let set_contains = mp_builder.pub_op(op!(set_contains, s1, s2))?;
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ use serialization::{SerializedMainPod, SerializedSignedPod};
|
|||
use crate::middleware::{
|
||||
self, check_st_tmpl, hash_str, hash_values, AnchoredKey, Hash, Key, MainPodInputs,
|
||||
NativeOperation, NativePredicate, OperationAux, OperationType, Params, PodId, PodProver,
|
||||
PodSigner, Predicate, Statement, StatementArg, Value, WildcardValue, EMPTY_HASH, KEY_TYPE,
|
||||
SELF,
|
||||
PodSigner, Predicate, Statement, StatementArg, VDSet, Value, WildcardValue, KEY_TYPE, SELF,
|
||||
};
|
||||
|
||||
mod custom;
|
||||
|
|
@ -117,6 +116,7 @@ impl SignedPod {
|
|||
#[derive(Debug)]
|
||||
pub struct MainPodBuilder {
|
||||
pub params: Params,
|
||||
pub vd_set: VDSet,
|
||||
pub input_signed_pods: Vec<SignedPod>,
|
||||
pub input_main_pods: Vec<MainPod>,
|
||||
pub statements: Vec<Statement>,
|
||||
|
|
@ -151,9 +151,10 @@ impl fmt::Display for MainPodBuilder {
|
|||
}
|
||||
|
||||
impl MainPodBuilder {
|
||||
pub fn new(params: &Params) -> Self {
|
||||
pub fn new(params: &Params, vd_set: &VDSet) -> Self {
|
||||
Self {
|
||||
params: params.clone(),
|
||||
vd_set: vd_set.clone(),
|
||||
input_signed_pods: Vec::new(),
|
||||
input_main_pods: Vec::new(),
|
||||
statements: Vec::new(),
|
||||
|
|
@ -548,6 +549,7 @@ impl MainPodBuilder {
|
|||
};
|
||||
|
||||
let (statements, operations, public_statements) = compiler.compile(inputs, params)?;
|
||||
|
||||
let inputs = MainPodInputs {
|
||||
signed_pods: &self
|
||||
.input_signed_pods
|
||||
|
|
@ -562,9 +564,9 @@ impl MainPodBuilder {
|
|||
statements: &statements,
|
||||
operations: &operations,
|
||||
public_statements: &public_statements,
|
||||
vds_root: EMPTY_HASH, // TODO https://github.com/0xPARC/pod2/issues/249
|
||||
vds_set: self.vd_set.clone(),
|
||||
};
|
||||
let pod = prover.prove(&self.params, inputs)?;
|
||||
let pod = prover.prove(&self.params, &self.vd_set, inputs)?;
|
||||
|
||||
// Gather public statements, making sure to inject the type
|
||||
// information specified by the backend.
|
||||
|
|
@ -838,7 +840,7 @@ pub mod tests {
|
|||
eth_dos_pod_builder, eth_friend_signed_pod_builder, great_boy_pod_full_flow,
|
||||
tickets_pod_full_flow, zu_kyc_pod_builder, zu_kyc_sign_pod_builders,
|
||||
},
|
||||
middleware::{containers::Dictionary, Value},
|
||||
middleware::{containers::Dictionary, Value, DEFAULT_VD_SET},
|
||||
};
|
||||
|
||||
// Check that frontend public statements agree with those
|
||||
|
|
@ -873,6 +875,7 @@ pub mod tests {
|
|||
#[test]
|
||||
fn test_front_zu_kyc() -> Result<()> {
|
||||
let params = Params::default();
|
||||
let vd_set = &*DEFAULT_VD_SET;
|
||||
let (gov_id, pay_stub, sanction_list) = zu_kyc_sign_pod_builders(¶ms);
|
||||
|
||||
println!("{}", gov_id);
|
||||
|
|
@ -899,7 +902,7 @@ pub mod tests {
|
|||
check_kvs(&sanction_list)?;
|
||||
println!("{}", sanction_list);
|
||||
|
||||
let kyc_builder = zu_kyc_pod_builder(¶ms, &gov_id, &pay_stub, &sanction_list)?;
|
||||
let kyc_builder = zu_kyc_pod_builder(¶ms, &vd_set, &gov_id, &pay_stub, &sanction_list)?;
|
||||
println!("{}", kyc_builder);
|
||||
|
||||
// prove kyc with MockProver and print it
|
||||
|
|
@ -926,6 +929,7 @@ pub mod tests {
|
|||
max_custom_predicate_wildcards: 12,
|
||||
..Default::default()
|
||||
};
|
||||
let vd_set = &*DEFAULT_VD_SET;
|
||||
|
||||
let mut alice = MockSigner { pk: "Alice".into() };
|
||||
let bob = MockSigner { pk: "Bob".into() };
|
||||
|
|
@ -945,6 +949,7 @@ pub mod tests {
|
|||
let mut prover = MockProver {};
|
||||
let alice_bob_ethdos = eth_dos_pod_builder(
|
||||
¶ms,
|
||||
&vd_set,
|
||||
true,
|
||||
&alice_attestation,
|
||||
&charlie_attestation,
|
||||
|
|
@ -978,13 +983,15 @@ pub mod tests {
|
|||
#[should_panic]
|
||||
fn test_equal() {
|
||||
let params = Params::default();
|
||||
let vd_set = &*DEFAULT_VD_SET;
|
||||
|
||||
let mut signed_builder = SignedPodBuilder::new(¶ms);
|
||||
signed_builder.insert("a", 1);
|
||||
signed_builder.insert("b", 1);
|
||||
let mut signer = MockSigner { pk: "key".into() };
|
||||
let signed_pod = signed_builder.sign(&mut signer).unwrap();
|
||||
|
||||
let mut builder = MainPodBuilder::new(¶ms);
|
||||
let mut builder = MainPodBuilder::new(¶ms, &vd_set);
|
||||
builder.add_signed_pod(&signed_pod);
|
||||
|
||||
//let op_val1 = Operation{
|
||||
|
|
@ -1028,6 +1035,7 @@ pub mod tests {
|
|||
#[should_panic]
|
||||
fn test_false_st() {
|
||||
let params = Params::default();
|
||||
let vd_set = &*DEFAULT_VD_SET;
|
||||
let mut builder = SignedPodBuilder::new(¶ms);
|
||||
|
||||
builder.insert("num", 2);
|
||||
|
|
@ -1039,7 +1047,7 @@ pub mod tests {
|
|||
|
||||
println!("{}", pod);
|
||||
|
||||
let mut builder = MainPodBuilder::new(¶ms);
|
||||
let mut builder = MainPodBuilder::new(¶ms, &vd_set);
|
||||
builder.add_signed_pod(&pod);
|
||||
builder.pub_op(op!(gt, (&pod, "num"), 5)).unwrap();
|
||||
|
||||
|
|
@ -1053,6 +1061,7 @@ pub mod tests {
|
|||
#[test]
|
||||
fn test_dictionaries() -> Result<()> {
|
||||
let params = Params::default();
|
||||
let vd_set = &*DEFAULT_VD_SET;
|
||||
let mut builder = SignedPodBuilder::new(¶ms);
|
||||
|
||||
let mut my_dict_kvs: HashMap<Key, Value> = HashMap::new();
|
||||
|
|
@ -1061,7 +1070,7 @@ pub mod tests {
|
|||
my_dict_kvs.insert(Key::from("c"), Value::from(3));
|
||||
// let my_dict_as_mt = MerkleTree::new(5, &my_dict_kvs).unwrap();
|
||||
// let dict = Dictionary { mt: my_dict_as_mt };
|
||||
let dict = Dictionary::new(my_dict_kvs)?;
|
||||
let dict = Dictionary::new(params.max_depth_mt_containers, my_dict_kvs)?;
|
||||
let dict_root = Value::from(dict.clone());
|
||||
builder.insert("dict", dict_root);
|
||||
|
||||
|
|
@ -1070,7 +1079,7 @@ pub mod tests {
|
|||
};
|
||||
let pod = builder.sign(&mut signer).unwrap();
|
||||
|
||||
let mut builder = MainPodBuilder::new(¶ms);
|
||||
let mut builder = MainPodBuilder::new(¶ms, &vd_set);
|
||||
builder.add_signed_pod(&pod);
|
||||
let st0 = pod.get_statement("dict").unwrap();
|
||||
let st1 = builder.op(true, op!(new_entry, ("key", "a"))).unwrap();
|
||||
|
|
@ -1106,7 +1115,8 @@ pub mod tests {
|
|||
env_logger::init();
|
||||
|
||||
let params = Params::default();
|
||||
let mut builder = MainPodBuilder::new(¶ms);
|
||||
let vd_set = &*DEFAULT_VD_SET;
|
||||
let mut builder = MainPodBuilder::new(¶ms, &vd_set);
|
||||
let st = Statement::ValueOf(AnchoredKey::from((SELF, "a")), Value::from(3));
|
||||
let op_new_entry = Operation(
|
||||
OperationType::Native(NativeOperation::NewEntry),
|
||||
|
|
@ -1124,8 +1134,7 @@ pub mod tests {
|
|||
|
||||
// try to insert a statement that doesn't follow from the operation
|
||||
// right now the mock prover catches this when it calls compile()
|
||||
let params = Params::default();
|
||||
let mut builder = MainPodBuilder::new(¶ms);
|
||||
let mut builder = MainPodBuilder::new(¶ms, &vd_set);
|
||||
let self_a = AnchoredKey::from((SELF, "a"));
|
||||
let self_b = AnchoredKey::from((SELF, "b"));
|
||||
let value_of_a = Statement::ValueOf(self_a.clone(), Value::from(3));
|
||||
|
|
|
|||
|
|
@ -112,24 +112,25 @@ mod tests {
|
|||
middleware::{
|
||||
self,
|
||||
containers::{Array, Dictionary, Set},
|
||||
Params, TypedValue,
|
||||
Params, TypedValue, DEFAULT_VD_SET,
|
||||
},
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test_value_serialization() {
|
||||
let params = &Params::default();
|
||||
// Pairs of values and their expected serialized representations
|
||||
let values = vec![
|
||||
(TypedValue::String("hello".to_string()), "\"hello\""),
|
||||
(TypedValue::Int(42), "{\"Int\":\"42\"}"),
|
||||
(TypedValue::Bool(true), "true"),
|
||||
(
|
||||
TypedValue::Array(Array::new(vec!["foo".into(), false.into()]).unwrap()),
|
||||
"[\"foo\",false]",
|
||||
TypedValue::Array(Array::new(params.max_depth_mt_containers, vec!["foo".into(), false.into()]).unwrap()),
|
||||
"{\"max_depth\":32,\"array\":[\"foo\",false]}",
|
||||
),
|
||||
(
|
||||
TypedValue::Dictionary(
|
||||
Dictionary::new(HashMap::from([
|
||||
Dictionary::new(params.max_depth_mt_containers, HashMap::from([
|
||||
// The set of valid keys is equal to the set of valid JSON keys
|
||||
("foo".into(), 123.into()),
|
||||
// Empty strings are valid JSON keys
|
||||
|
|
@ -145,11 +146,11 @@ mod tests {
|
|||
]))
|
||||
.unwrap(),
|
||||
),
|
||||
"{\"Dictionary\":{\"\":\"baz\",\"\\u0000\":\"\",\" hi\":false,\"!@£$%^&&*()\":\"\",\"foo\":{\"Int\":\"123\"},\"🥳\":\"party time!\"}}",
|
||||
"{\"Dictionary\":{\"max_depth\":32,\"kvs\":{\"\":\"baz\",\"\\u0000\":\"\",\" hi\":false,\"!@£$%^&&*()\":\"\",\"foo\":{\"Int\":\"123\"},\"🥳\":\"party time!\"}}}",
|
||||
),
|
||||
(
|
||||
TypedValue::Set(Set::new(HashSet::from(["foo".into(), "bar".into()])).unwrap()),
|
||||
"{\"Set\":[\"bar\",\"foo\"]}",
|
||||
TypedValue::Set(Set::new(params.max_depth_mt_containers, HashSet::from(["foo".into(), "bar".into()])).unwrap()),
|
||||
"{\"Set\":{\"max_depth\":32,\"set\":[\"bar\",\"foo\"]}}",
|
||||
),
|
||||
];
|
||||
|
||||
|
|
@ -168,30 +169,45 @@ mod tests {
|
|||
}
|
||||
|
||||
fn signed_pod_builder() -> SignedPodBuilder {
|
||||
let mut builder = SignedPodBuilder::new(&Params::default());
|
||||
let params = &Params::default();
|
||||
let mut builder = SignedPodBuilder::new(params);
|
||||
builder.insert("name", "test");
|
||||
builder.insert("age", 30);
|
||||
builder.insert("very_large_int", 1152921504606846976);
|
||||
builder.insert(
|
||||
"a_dict_containing_one_key",
|
||||
Dictionary::new(HashMap::from([
|
||||
("foo".into(), 123.into()),
|
||||
(
|
||||
"an_array_containing_three_ints".into(),
|
||||
Array::new(vec![1.into(), 2.into(), 3.into()])
|
||||
Dictionary::new(
|
||||
params.max_depth_mt_containers,
|
||||
HashMap::from([
|
||||
("foo".into(), 123.into()),
|
||||
(
|
||||
"an_array_containing_three_ints".into(),
|
||||
Array::new(
|
||||
params.max_depth_mt_containers,
|
||||
vec![1.into(), 2.into(), 3.into()],
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
),
|
||||
(
|
||||
"a_set_containing_two_strings".into(),
|
||||
Set::new(HashSet::from([
|
||||
Array::new(vec!["foo".into(), "bar".into()]).unwrap().into(),
|
||||
"baz".into(),
|
||||
]))
|
||||
.unwrap()
|
||||
.into(),
|
||||
),
|
||||
]))
|
||||
),
|
||||
(
|
||||
"a_set_containing_two_strings".into(),
|
||||
Set::new(
|
||||
params.max_depth_mt_containers,
|
||||
HashSet::from([
|
||||
Array::new(
|
||||
params.max_depth_mt_containers,
|
||||
vec!["foo".into(), "bar".into()],
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
"baz".into(),
|
||||
]),
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
),
|
||||
]),
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
builder
|
||||
|
|
@ -235,6 +251,7 @@ mod tests {
|
|||
|
||||
fn build_mock_zukyc_pod() -> Result<MainPod> {
|
||||
let params = middleware::Params::default();
|
||||
let vd_set = &*DEFAULT_VD_SET;
|
||||
|
||||
let (gov_id_builder, pay_stub_builder, sanction_list_builder) =
|
||||
zu_kyc_sign_pod_builders(¶ms);
|
||||
|
|
@ -250,8 +267,14 @@ mod tests {
|
|||
pk: "ZooOFAC".into(),
|
||||
};
|
||||
let sanction_list_pod = sanction_list_builder.sign(&mut signer).unwrap();
|
||||
let kyc_builder =
|
||||
zu_kyc_pod_builder(¶ms, &gov_id_pod, &pay_stub_pod, &sanction_list_pod).unwrap();
|
||||
let kyc_builder = zu_kyc_pod_builder(
|
||||
¶ms,
|
||||
&vd_set,
|
||||
&gov_id_pod,
|
||||
&pay_stub_pod,
|
||||
&sanction_list_pod,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut prover = MockProver {};
|
||||
let kyc_pod = kyc_builder.prove(&mut prover, ¶ms).unwrap();
|
||||
|
|
@ -265,6 +288,7 @@ mod tests {
|
|||
max_input_recursive_pods: 1,
|
||||
..Default::default()
|
||||
};
|
||||
let vd_set = &*DEFAULT_VD_SET;
|
||||
|
||||
let (gov_id_builder, pay_stub_builder, sanction_list_builder) =
|
||||
zu_kyc_sign_pod_builders(¶ms);
|
||||
|
|
@ -274,8 +298,13 @@ mod tests {
|
|||
let pay_stub_pod = pay_stub_builder.sign(&mut signer)?;
|
||||
let mut signer = Signer(SecretKey(3u32.into()));
|
||||
let sanction_list_pod = sanction_list_builder.sign(&mut signer)?;
|
||||
let kyc_builder =
|
||||
zu_kyc_pod_builder(¶ms, &gov_id_pod, &pay_stub_pod, &sanction_list_pod)?;
|
||||
let kyc_builder = zu_kyc_pod_builder(
|
||||
¶ms,
|
||||
&vd_set,
|
||||
&gov_id_pod,
|
||||
&pay_stub_pod,
|
||||
&sanction_list_pod,
|
||||
)?;
|
||||
|
||||
let mut prover = Prover {};
|
||||
let kyc_pod = kyc_builder.prove(&mut prover, ¶ms)?;
|
||||
|
|
@ -324,6 +353,7 @@ mod tests {
|
|||
max_custom_predicate_wildcards: 12,
|
||||
..Default::default()
|
||||
};
|
||||
let vd_set = &*DEFAULT_VD_SET;
|
||||
|
||||
let mut alice = MockSigner { pk: "Alice".into() };
|
||||
let bob = MockSigner { pk: "Bob".into() };
|
||||
|
|
@ -341,6 +371,7 @@ mod tests {
|
|||
let mut prover = MockProver {};
|
||||
let alice_bob_ethdos = eth_dos_pod_builder(
|
||||
¶ms,
|
||||
&vd_set,
|
||||
true,
|
||||
&alice_attestation,
|
||||
&charlie_attestation,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue