No Pod IDs (#394)
- middleware:
- Add `Statement::Intro`
- Add `SignedBy` native predicate and operation. The signature is auxiliary data to the operation
- Rename `PodSigner` to `Signer` with a new API (just for signing `RawValue`)
- Removed `NewEntry` operation. Use `ContainsFromEntries` instead
- Remove `KEY_SIGNER` and `KEY_TYPE` which are no longer used
- Merge `RecursivePod` and `Pod` traits
- Change the `Pod::deserialize_data` method to use `Self` instead of `Box<dyn Pod>`
- Extend `Pod` trait with these methods:
- `is_main`: when the pod is Main, in a (recursive) verification its vk will be checked to exist in the vd_set but not if it's intro pod
- `is_mock`: skip some verifications in the recursive mock MainPod verification
- `verifier_data_hash`
- `pod_id` renamed to `statements_hash`
- AnchoredKeys are now a pair of dictionary root and key
- Entry statements are now defined as Contains with literal arguments
- Operations that take Entries now use Contains statements with literal arguments
- frontend:
- Rename `SignedPod` to `SignedDict` (which now contains the dict, public key and signature, and can still `verify(self)`ed)
- The `SignedDict` keeps the method `get_statement` for convenience but now it returns a `Contains` statement that proves the existence of the key in the dict
- The `MainPodBuilder` automatically inserts a `Contains` statement when an operation is added that uses an entry as argument that was not yet "opened".
- Removed the `literal` methods from the `MainPodBuilder` that were loading literals to anchored keys: that was no longer needed after we introduced literal arguments
- backend
- Only verify inclusion of the verifying key into the vd_set if the pod is MainPod. A pod is not MainPod if the first statement is Intro.
- Reject intro pods that have non-intro statements
- Empty pod now returns an intro statement
- Don't insert a type statement automatically in MainPod and MockMainPod. We get rid of the type entry.
- Implement `SignedBy` operation, which uses the muxed table to store signature verifications
- Rename `PodId` to `statements_hash` or `sts_hash` for short. Now this is only used as a hash of the statements for the circuits public inputs.
- Refactor normalization of `self` statements:
- Before: replace values that contain `SELF` by the given pod_id
- After: place the verifying key hash into the Intro predicates
This commit is contained in:
parent
122f9c3cac
commit
0e2f7b756e
39 changed files with 2127 additions and 3064 deletions
|
|
@ -5,28 +5,15 @@ use hex::ToHex;
|
|||
use crate::{
|
||||
frontend::{PodRequest, Result},
|
||||
lang::parse,
|
||||
middleware::{CustomPredicateBatch, Params, PodType, Value, KEY_SIGNER, KEY_TYPE},
|
||||
middleware::{CustomPredicateBatch, Params},
|
||||
};
|
||||
|
||||
macro_rules! render {
|
||||
($tmpl: expr, $($arg:tt)*) => {{
|
||||
format!(
|
||||
$tmpl,
|
||||
KEY_TYPE = Value::from(KEY_TYPE),
|
||||
KEY_SIGNER = Value::from(KEY_SIGNER),
|
||||
$($arg)*
|
||||
)
|
||||
}};
|
||||
}
|
||||
|
||||
/// Instantiates an ETHDos batch
|
||||
pub fn eth_dos_batch(params: &Params) -> Result<Arc<CustomPredicateBatch>> {
|
||||
let input = render!(
|
||||
r#"
|
||||
eth_friend(src, dst, private: attestation_pod) = AND(
|
||||
Equal(?attestation_pod[{KEY_TYPE}], {pod_type})
|
||||
Equal(?attestation_pod[{KEY_SIGNER}], ?src)
|
||||
Equal(?attestation_pod["attestation"], ?dst)
|
||||
let input = r#"
|
||||
eth_friend(src, dst, private: attestation) = AND(
|
||||
SignedBy(?attestation, ?src)
|
||||
Contains(?attestation, "attestation", ?dst)
|
||||
)
|
||||
|
||||
eth_dos_base(src, dst, distance) = AND(
|
||||
|
|
@ -44,10 +31,8 @@ pub fn eth_dos_batch(params: &Params) -> Result<Arc<CustomPredicateBatch>> {
|
|||
eth_dos_base(?src, ?dst, ?distance)
|
||||
eth_dos_ind(?src, ?dst, ?distance)
|
||||
)
|
||||
"#,
|
||||
pod_type = Value::from(PodType::Signed),
|
||||
);
|
||||
let batch = parse(&input, params, &[]).expect("lang parse").custom_batch;
|
||||
"#;
|
||||
let batch = parse(input, params, &[]).expect("lang parse").custom_batch;
|
||||
println!("a.0. {}", batch.predicates[0]);
|
||||
println!("a.1. {}", batch.predicates[1]);
|
||||
println!("a.2. {}", batch.predicates[2]);
|
||||
|
|
|
|||
|
|
@ -8,26 +8,26 @@ use num::BigUint;
|
|||
pub static MOCK_VD_SET: LazyLock<VDSet> = LazyLock::new(|| VDSet::new(6, &[]).unwrap());
|
||||
|
||||
use crate::{
|
||||
backends::plonky2::{primitives::ec::schnorr::SecretKey, signedpod::Signer},
|
||||
backends::plonky2::{primitives::ec::schnorr::SecretKey, signer::Signer},
|
||||
frontend::{
|
||||
MainPod, MainPodBuilder, Operation, PodRequest, Result, SignedPod, SignedPodBuilder,
|
||||
MainPod, MainPodBuilder, Operation, PodRequest, Result, SignedDict, SignedDictBuilder,
|
||||
},
|
||||
lang::parse,
|
||||
middleware::{
|
||||
containers::Set, hash_values, CustomPredicateRef, Params, PodSigner, PodType, Predicate,
|
||||
Statement, StatementArg, TypedValue, VDSet, Value, KEY_SIGNER, KEY_TYPE,
|
||||
self, containers::Set, hash_values, CustomPredicateRef, Params, Predicate, PublicKey,
|
||||
Signer as _, Statement, StatementArg, TypedValue, VDSet, Value,
|
||||
},
|
||||
};
|
||||
|
||||
// ZuKYC
|
||||
|
||||
pub fn zu_kyc_sign_pod_builders(params: &Params) -> (SignedPodBuilder, SignedPodBuilder) {
|
||||
let mut gov_id = SignedPodBuilder::new(params);
|
||||
pub fn zu_kyc_sign_dict_builders(params: &Params) -> (SignedDictBuilder, SignedDictBuilder) {
|
||||
let mut gov_id = SignedDictBuilder::new(params);
|
||||
gov_id.insert("idNumber", "4242424242");
|
||||
gov_id.insert("dateOfBirth", 1169909384);
|
||||
gov_id.insert("socialSecurityNumber", "G2121210");
|
||||
|
||||
let mut pay_stub = SignedPodBuilder::new(params);
|
||||
let mut pay_stub = SignedDictBuilder::new(params);
|
||||
pay_stub.insert("socialSecurityNumber", "G2121210");
|
||||
pay_stub.insert("startDate", 1706367566);
|
||||
|
||||
|
|
@ -41,8 +41,8 @@ pub const ZU_KYC_SANCTION_LIST: &[&str] = &["A343434340"];
|
|||
pub fn zu_kyc_pod_builder(
|
||||
params: &Params,
|
||||
vd_set: &VDSet,
|
||||
gov_id: &SignedPod,
|
||||
pay_stub: &SignedPod,
|
||||
gov_id: &SignedDict,
|
||||
pay_stub: &SignedDict,
|
||||
) -> Result<MainPodBuilder> {
|
||||
let now_minus_18y = ZU_KYC_NOW_MINUS_18Y;
|
||||
let now_minus_1y = ZU_KYC_NOW_MINUS_1Y;
|
||||
|
|
@ -54,8 +54,9 @@ pub fn zu_kyc_pod_builder(
|
|||
Value::from(Set::new(params.max_depth_mt_containers, sanctions_values).unwrap());
|
||||
|
||||
let mut kyc = MainPodBuilder::new(params, vd_set);
|
||||
kyc.add_signed_pod(gov_id);
|
||||
kyc.add_signed_pod(pay_stub);
|
||||
kyc.pub_op(Operation::dict_signed_by(gov_id))?;
|
||||
kyc.pub_op(Operation::dict_signed_by(pay_stub))?;
|
||||
|
||||
kyc.pub_op(Operation::set_not_contains(
|
||||
sanction_set,
|
||||
(gov_id, "idNumber"),
|
||||
|
|
@ -66,14 +67,6 @@ pub fn zu_kyc_pod_builder(
|
|||
(pay_stub, "socialSecurityNumber"),
|
||||
))?;
|
||||
kyc.pub_op(Operation::eq((pay_stub, "startDate"), now_minus_1y))?;
|
||||
kyc.pub_op(Operation::eq(
|
||||
(gov_id, "_signer"),
|
||||
gov_id.get("_signer").unwrap(),
|
||||
))?;
|
||||
kyc.pub_op(Operation::eq(
|
||||
(pay_stub, "_signer"),
|
||||
pay_stub.get("_signer").unwrap(),
|
||||
))?;
|
||||
|
||||
Ok(kyc)
|
||||
}
|
||||
|
|
@ -93,8 +86,8 @@ pub fn zu_kyc_pod_request(gov_signer: &Value, pay_signer: &Value) -> Result<PodR
|
|||
Lt(?gov["dateOfBirth"], {ZU_KYC_NOW_MINUS_18Y})
|
||||
Equal(?pay["startDate"], {ZU_KYC_NOW_MINUS_1Y})
|
||||
Equal(?gov["socialSecurityNumber"], ?pay["socialSecurityNumber"])
|
||||
Equal(?gov["_signer"], {gov_signer})
|
||||
Equal(?pay["_signer"], {pay_signer})
|
||||
SignedBy(?gov, {gov_signer})
|
||||
SignedBy(?pay, {pay_signer})
|
||||
// TODO: Ownership check and watermarking
|
||||
// Depends partly on https://github.com/0xPARC/pod2/issues/351
|
||||
)
|
||||
|
|
@ -106,8 +99,12 @@ pub fn zu_kyc_pod_request(gov_signer: &Value, pay_signer: &Value) -> Result<PodR
|
|||
|
||||
// ETHDoS
|
||||
|
||||
pub fn attest_eth_friend(params: &Params, src: &impl PodSigner, dst: Value) -> SignedPod {
|
||||
let mut attestation = SignedPodBuilder::new(params);
|
||||
pub fn attest_eth_friend(
|
||||
params: &Params,
|
||||
src: &impl middleware::Signer,
|
||||
dst: PublicKey,
|
||||
) -> SignedDict {
|
||||
let mut attestation = SignedDictBuilder::new(params);
|
||||
attestation.insert("attestation", dst);
|
||||
attestation.sign(src).unwrap()
|
||||
}
|
||||
|
|
@ -115,16 +112,15 @@ pub fn attest_eth_friend(params: &Params, src: &impl PodSigner, dst: Value) -> S
|
|||
pub struct EthDosHelper {
|
||||
params: Params,
|
||||
vd_set: VDSet,
|
||||
mock: bool,
|
||||
eth_friend: CustomPredicateRef,
|
||||
eth_dos_base: CustomPredicateRef,
|
||||
eth_dos_ind: CustomPredicateRef,
|
||||
eth_dos: CustomPredicateRef,
|
||||
src: Value,
|
||||
src: PublicKey,
|
||||
}
|
||||
|
||||
impl EthDosHelper {
|
||||
pub fn new(params: &Params, vd_set: &VDSet, mock: bool, src: Value) -> Result<Self> {
|
||||
pub fn new(params: &Params, vd_set: &VDSet, src: PublicKey) -> Result<Self> {
|
||||
let eth_dos_batch = eth_dos_batch(params)?;
|
||||
let eth_friend = eth_dos_batch.predicate_ref_by_name("eth_friend").unwrap();
|
||||
let eth_dos_base = eth_dos_batch.predicate_ref_by_name("eth_dos_base").unwrap();
|
||||
|
|
@ -133,7 +129,6 @@ impl EthDosHelper {
|
|||
Ok(Self {
|
||||
params: params.clone(),
|
||||
vd_set: vd_set.clone(),
|
||||
mock,
|
||||
eth_friend,
|
||||
eth_dos_base,
|
||||
eth_dos_ind,
|
||||
|
|
@ -142,16 +137,13 @@ impl EthDosHelper {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn dist_1(&self, src_attestation: &SignedPod) -> Result<MainPodBuilder> {
|
||||
assert_eq!(
|
||||
&self.src,
|
||||
src_attestation.get(KEY_SIGNER).expect("get KEY_SIGNER")
|
||||
);
|
||||
pub fn dist_1(&self, src_attestation: &SignedDict) -> Result<MainPodBuilder> {
|
||||
assert_eq!(self.src, src_attestation.public_key);
|
||||
|
||||
let mut pod = MainPodBuilder::new(&self.params, &self.vd_set);
|
||||
pod.add_signed_pod(src_attestation);
|
||||
pod.pub_op(Operation::dict_signed_by(src_attestation))?;
|
||||
|
||||
let src_eq_src = pod.priv_op(Operation::eq(self.src.clone(), self.src.clone()))?;
|
||||
let src_eq_src = pod.priv_op(Operation::eq(self.src, self.src))?;
|
||||
let distance_eq_zero = pod.priv_op(Operation::eq(0, 0))?;
|
||||
let eth_dos_src_to_src_base = pod.priv_op(Operation::custom(
|
||||
self.eth_dos_base.clone(),
|
||||
|
|
@ -171,20 +163,10 @@ impl EthDosHelper {
|
|||
pub fn dist_n_plus_1(
|
||||
&self,
|
||||
eth_dos_src_to_int_pod: &MainPod,
|
||||
int_attestation: &SignedPod, // int signs dst
|
||||
int_attestation: &SignedDict, // int signs dst
|
||||
) -> Result<MainPodBuilder> {
|
||||
assert_eq!(
|
||||
Value::from(if self.mock {
|
||||
PodType::MockMain
|
||||
} else {
|
||||
PodType::Main
|
||||
}),
|
||||
eth_dos_src_to_int_pod.get(KEY_TYPE).expect("get KEY_TYPE")
|
||||
);
|
||||
|
||||
let mut pod = MainPodBuilder::new(&self.params, &self.vd_set);
|
||||
pod.add_signed_pod(int_attestation);
|
||||
pod.add_recursive_pod(eth_dos_src_to_int_pod.clone());
|
||||
pod.add_pod(eth_dos_src_to_int_pod.clone());
|
||||
|
||||
let eth_dos_int_to_dst = eth_dos_src_to_int_pod
|
||||
.pod
|
||||
|
|
@ -200,10 +182,7 @@ impl EthDosHelper {
|
|||
_ => panic!("expected StatementArg::Literal"),
|
||||
})
|
||||
};
|
||||
assert_eq!(
|
||||
&int,
|
||||
int_attestation.get(KEY_SIGNER).expect("get KEY_SIGNER")
|
||||
);
|
||||
assert_eq!(int, Value::from(int_attestation.public_key));
|
||||
|
||||
let n_i64 = if let TypedValue::Int(x) = n.typed() {
|
||||
*x
|
||||
|
|
@ -221,25 +200,15 @@ impl EthDosHelper {
|
|||
&self,
|
||||
pod: &mut MainPodBuilder,
|
||||
eth_dos_int_to_dst: Statement,
|
||||
int_attestation: &SignedPod,
|
||||
int_attestation: &SignedDict,
|
||||
n: i64,
|
||||
) -> Result<()> {
|
||||
assert_eq!(
|
||||
&Value::from(PodType::Signed),
|
||||
int_attestation.get(KEY_TYPE).expect("get KEY_TYPE")
|
||||
);
|
||||
|
||||
// eth_friend statement
|
||||
let attestation_is_signed_pod = int_attestation.get_statement(KEY_TYPE).unwrap();
|
||||
let attestation_signed_by_int = int_attestation.get_statement(KEY_SIGNER).unwrap();
|
||||
let attestation_signed_by_int = pod.priv_op(Operation::dict_signed_by(int_attestation))?;
|
||||
let int_attests_to_dst = int_attestation.get_statement("attestation").unwrap();
|
||||
let ethfriends_int_dst = pod.priv_op(Operation::custom(
|
||||
self.eth_friend.clone(),
|
||||
[
|
||||
attestation_is_signed_pod,
|
||||
attestation_signed_by_int,
|
||||
int_attests_to_dst,
|
||||
],
|
||||
[attestation_signed_by_int, int_attests_to_dst],
|
||||
))?;
|
||||
|
||||
// distance = n + 1
|
||||
|
|
@ -259,17 +228,17 @@ impl EthDosHelper {
|
|||
|
||||
// GreatBoy
|
||||
|
||||
pub fn good_boy_sign_pod_builder(params: &Params, user: &Value, age: i64) -> SignedPodBuilder {
|
||||
let mut good_boy = SignedPodBuilder::new(params);
|
||||
good_boy.insert("user", user.clone());
|
||||
pub fn good_boy_sign_pod_builder(params: &Params, user: &PublicKey, age: i64) -> SignedDictBuilder {
|
||||
let mut good_boy = SignedDictBuilder::new(params);
|
||||
good_boy.insert("user", *user);
|
||||
good_boy.insert("age", age);
|
||||
|
||||
good_boy
|
||||
}
|
||||
|
||||
pub fn friend_sign_pod_builder(params: &Params, friend: &Value) -> SignedPodBuilder {
|
||||
let mut friend_pod = SignedPodBuilder::new(params);
|
||||
friend_pod.insert("friend", friend.clone());
|
||||
pub fn friend_sign_pod_builder(params: &Params, friend: &PublicKey) -> SignedDictBuilder {
|
||||
let mut friend_pod = SignedDictBuilder::new(params);
|
||||
friend_pod.insert("friend", *friend);
|
||||
|
||||
friend_pod
|
||||
}
|
||||
|
|
@ -277,10 +246,10 @@ pub fn friend_sign_pod_builder(params: &Params, friend: &Value) -> SignedPodBuil
|
|||
pub fn great_boy_pod_builder(
|
||||
params: &Params,
|
||||
vd_set: &VDSet,
|
||||
good_boy_pods: [&SignedPod; 4],
|
||||
friend_pods: [&SignedPod; 2],
|
||||
good_boy_signed_dicts: [&SignedDict; 4],
|
||||
friend_signed_dicts: [&SignedDict; 2],
|
||||
good_boy_issuers: &Value,
|
||||
receiver: &Value,
|
||||
receiver: &PublicKey,
|
||||
) -> Result<MainPodBuilder> {
|
||||
// Attestment chain (issuer -> good boy -> great boy):
|
||||
// issuer 0 -> good_boy_pods[0] => good boy 0
|
||||
|
|
@ -291,51 +260,41 @@ pub fn great_boy_pod_builder(
|
|||
// good boy 1 -> friend_pods[1] => receiver
|
||||
|
||||
let mut great_boy = MainPodBuilder::new(params, vd_set);
|
||||
for good_boy_pod in good_boy_pods {
|
||||
great_boy.add_signed_pod(good_boy_pod);
|
||||
for good_boy_signed_dict in good_boy_signed_dicts {
|
||||
great_boy.pub_op(Operation::dict_signed_by(good_boy_signed_dict))?;
|
||||
}
|
||||
for friend_pod in friend_pods {
|
||||
great_boy.add_signed_pod(friend_pod);
|
||||
for friend_signed_dict in friend_signed_dicts {
|
||||
great_boy.pub_op(Operation::dict_signed_by(friend_signed_dict))?;
|
||||
}
|
||||
|
||||
for good_boy_idx in 0..2 {
|
||||
// Type check
|
||||
great_boy.pub_op(Operation::eq(
|
||||
(friend_pods[good_boy_idx], KEY_TYPE),
|
||||
PodType::Signed as i64,
|
||||
))?;
|
||||
for issuer_idx in 0..2 {
|
||||
// Type check
|
||||
great_boy.pub_op(Operation::eq(
|
||||
(good_boy_pods[good_boy_idx * 2 + issuer_idx], KEY_TYPE),
|
||||
PodType::Signed as i64,
|
||||
))?;
|
||||
// Each good boy POD comes from a valid issuer
|
||||
great_boy.pub_op(Operation::set_contains(
|
||||
good_boy_issuers,
|
||||
(good_boy_pods[good_boy_idx * 2 + issuer_idx], KEY_SIGNER),
|
||||
good_boy_signed_dicts[good_boy_idx * 2 + issuer_idx].public_key,
|
||||
))?;
|
||||
// Each good boy has 2 good boy pods
|
||||
great_boy.pub_op(Operation::eq(
|
||||
(good_boy_pods[good_boy_idx * 2 + issuer_idx], "user"),
|
||||
(friend_pods[good_boy_idx], KEY_SIGNER),
|
||||
(good_boy_signed_dicts[good_boy_idx * 2 + issuer_idx], "user"),
|
||||
friend_signed_dicts[good_boy_idx].public_key,
|
||||
))?;
|
||||
}
|
||||
// The good boy PODs from each good boy have different issuers
|
||||
great_boy.pub_op(Operation::ne(
|
||||
(good_boy_pods[good_boy_idx * 2], KEY_SIGNER),
|
||||
(good_boy_pods[good_boy_idx * 2 + 1], KEY_SIGNER),
|
||||
good_boy_signed_dicts[good_boy_idx * 2].public_key,
|
||||
good_boy_signed_dicts[good_boy_idx * 2 + 1].public_key,
|
||||
))?;
|
||||
// Each good boy is receivers' friend
|
||||
great_boy.pub_op(Operation::eq(
|
||||
(friend_pods[good_boy_idx], "friend"),
|
||||
receiver.clone(),
|
||||
(friend_signed_dicts[good_boy_idx], "friend"),
|
||||
*receiver,
|
||||
))?;
|
||||
}
|
||||
// The two good boys are different
|
||||
great_boy.pub_op(Operation::ne(
|
||||
(friend_pods[0], KEY_SIGNER),
|
||||
(friend_pods[1], KEY_SIGNER),
|
||||
friend_signed_dicts[0].public_key,
|
||||
friend_signed_dicts[1].public_key,
|
||||
))?;
|
||||
|
||||
Ok(great_boy)
|
||||
|
|
@ -343,11 +302,11 @@ pub fn great_boy_pod_builder(
|
|||
|
||||
pub fn great_boy_pod_full_flow() -> Result<MainPodBuilder> {
|
||||
let params = Params {
|
||||
max_input_signed_pods: 6,
|
||||
max_input_recursive_pods: 0,
|
||||
max_signed_by: 6,
|
||||
max_input_pods: 0,
|
||||
max_statements: 100,
|
||||
max_public_statements: 50,
|
||||
num_public_statements_id: 50,
|
||||
num_public_statements_hash: 50,
|
||||
..Default::default()
|
||||
};
|
||||
let vd_set = &*MOCK_VD_SET;
|
||||
|
|
@ -413,13 +372,13 @@ pub fn great_boy_pod_full_flow() -> Result<MainPodBuilder> {
|
|||
|
||||
pub const TICKET_OWNER_SECRET_KEY: SecretKey = SecretKey(BigUint::ZERO);
|
||||
|
||||
pub fn tickets_sign_pod_builder(params: &Params) -> SignedPodBuilder {
|
||||
pub fn tickets_sign_pod_builder(params: &Params) -> SignedDictBuilder {
|
||||
// Create a signed pod with all atomic types (string, int, bool)
|
||||
let mut builder = SignedPodBuilder::new(params);
|
||||
let mut builder = SignedDictBuilder::new(params);
|
||||
builder.insert("eventId", 123);
|
||||
builder.insert("productId", 456);
|
||||
// Removed temporarily to make the example fit in 8 entries.
|
||||
//builder.insert("attendeeName", "John Doe");
|
||||
// builder.insert("attendeeName", "John Doe");
|
||||
builder.insert("attendeeEmail", "john.doe@example.com");
|
||||
builder.insert("attendeePublicKey", TICKET_OWNER_SECRET_KEY.public_key());
|
||||
builder.insert("isConsumed", true);
|
||||
|
|
@ -430,7 +389,7 @@ pub fn tickets_sign_pod_builder(params: &Params) -> SignedPodBuilder {
|
|||
pub fn tickets_pod_builder(
|
||||
params: &Params,
|
||||
vd_set: &VDSet,
|
||||
signed_pod: &SignedPod,
|
||||
signed_dict: &SignedDict,
|
||||
expected_event_id: i64,
|
||||
expect_consumed: bool,
|
||||
blacklisted_emails: &Set,
|
||||
|
|
@ -438,28 +397,28 @@ pub fn tickets_pod_builder(
|
|||
let blacklisted_email_set_value = Value::from(TypedValue::Set(blacklisted_emails.clone()));
|
||||
// Create a main pod referencing this signed pod with some statements
|
||||
let mut builder = MainPodBuilder::new(params, vd_set);
|
||||
builder.add_signed_pod(signed_pod);
|
||||
builder.pub_op(Operation::eq((signed_pod, "eventId"), expected_event_id))?;
|
||||
builder.pub_op(Operation::eq((signed_pod, "isConsumed"), expect_consumed))?;
|
||||
builder.pub_op(Operation::eq((signed_pod, "isRevoked"), false))?;
|
||||
builder.pub_op(Operation::dict_signed_by(signed_dict))?;
|
||||
builder.pub_op(Operation::eq((signed_dict, "eventId"), expected_event_id))?;
|
||||
builder.pub_op(Operation::eq((signed_dict, "isConsumed"), expect_consumed))?;
|
||||
builder.pub_op(Operation::eq((signed_dict, "isRevoked"), false))?;
|
||||
builder.pub_op(Operation::dict_not_contains(
|
||||
blacklisted_email_set_value,
|
||||
(signed_pod, "attendeeEmail"),
|
||||
(signed_dict, "attendeeEmail"),
|
||||
))?;
|
||||
|
||||
// This isn't the most fool-proof way to prove ownership (it requires
|
||||
// verifier to check pod ID on an anchored key to confirm statement wasn't
|
||||
// copied), but it's the simplest.
|
||||
let st_sk = builder.priv_literal(TICKET_OWNER_SECRET_KEY)?;
|
||||
let sk = TICKET_OWNER_SECRET_KEY;
|
||||
builder.pub_op(Operation::public_key_of(
|
||||
(signed_pod, "attendeePublicKey"),
|
||||
st_sk.clone(),
|
||||
(signed_dict, "attendeePublicKey"),
|
||||
sk.clone(),
|
||||
))?;
|
||||
|
||||
// Nullifier calculation is public, but based on the private sk.
|
||||
let external_nullifier = "external nullifier";
|
||||
let nullifier = hash_values(&[TICKET_OWNER_SECRET_KEY.into(), external_nullifier.into()]);
|
||||
builder.pub_op(Operation::hash_of(nullifier, st_sk, external_nullifier))?;
|
||||
builder.pub_op(Operation::hash_of(nullifier, sk, external_nullifier))?;
|
||||
|
||||
Ok(builder)
|
||||
}
|
||||
|
|
@ -467,11 +426,11 @@ pub fn tickets_pod_builder(
|
|||
pub fn tickets_pod_full_flow(params: &Params, vd_set: &VDSet) -> Result<MainPodBuilder> {
|
||||
let builder = tickets_sign_pod_builder(params);
|
||||
|
||||
let signed_pod = builder.sign(&Signer(SecretKey(1u32.into()))).unwrap();
|
||||
let signed_dict = builder.sign(&Signer(SecretKey(1u32.into()))).unwrap();
|
||||
tickets_pod_builder(
|
||||
params,
|
||||
vd_set,
|
||||
&signed_pod,
|
||||
&signed_dict,
|
||||
123,
|
||||
true,
|
||||
&Set::new(params.max_depth_mt_containers, HashSet::new())?,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue