allow SELF in st_tmpl (#240)
* allow SELF in st_tmpl * add some tests * Update src/backends/plonky2/circuits/mainpod.rs Co-authored-by: Ahmad Afuni <root@ahmadafuni.com> --------- Co-authored-by: Ahmad Afuni <root@ahmadafuni.com>
This commit is contained in:
parent
b4a4c72328
commit
82481e88d7
9 changed files with 178 additions and 87 deletions
25
.github/workflows/build.yml
vendored
Normal file
25
.github/workflows/build.yml
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
name: Rust Build with features
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: [ main ]
|
||||||
|
types: [ready_for_review, opened, synchronize, reopened]
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
if: github.event.pull_request.draft == false
|
||||||
|
name: Rust tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Set up Rust
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
- name: Build default
|
||||||
|
run: cargo build
|
||||||
|
- name: Build metrics
|
||||||
|
run: cargo build --features metrics
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{array, sync::Arc};
|
use std::{array, iter, sync::Arc};
|
||||||
|
|
||||||
use itertools::{zip_eq, Itertools};
|
use itertools::{zip_eq, Itertools};
|
||||||
use plonky2::{
|
use plonky2::{
|
||||||
|
|
@ -767,12 +767,18 @@ impl CustomOperationVerifyGadget {
|
||||||
// optimization: ak_id_wc_index and wc_index use the same signals, so we only need to do one
|
// optimization: ak_id_wc_index and wc_index use the same signals, so we only need to do one
|
||||||
// random access to resolve both of them
|
// random access to resolve both of them
|
||||||
assert_eq!(ak_id_wc_index, wc_index);
|
assert_eq!(ak_id_wc_index, wc_index);
|
||||||
|
// optimization: the wildcard indices have an offset of +1. This allows us to set a fixed
|
||||||
|
// SELF in args[0] to resolve SelfOrWildcard::SELF encoded as a wildcard at index 0.
|
||||||
|
let value_self = ValueTarget::from_slice(&builder.constants(&SELF.0 .0));
|
||||||
|
let args = iter::once(value_self)
|
||||||
|
.chain(args.iter().cloned())
|
||||||
|
.collect_vec();
|
||||||
// If the index is not used, use a 0 instead to still pass the range constraints from
|
// If the index is not used, use a 0 instead to still pass the range constraints from
|
||||||
// vec_ref
|
// vec_ref
|
||||||
let first_index = ak_id_wc_index;
|
let first_index = ak_id_wc_index;
|
||||||
let is_first_index_valid = builder.or(is_ak, is_wc_literal);
|
let is_first_index_valid = builder.or(is_ak, is_wc_literal);
|
||||||
let first_index = builder.select(is_first_index_valid, first_index, zero);
|
let first_index = builder.select(is_first_index_valid, first_index, zero);
|
||||||
let resolved_ak_id = builder.vec_ref(&self.params, args, first_index);
|
let resolved_ak_id = builder.vec_ref(&self.params, &args, first_index);
|
||||||
let resolved_wc = resolved_ak_id;
|
let resolved_wc = resolved_ak_id;
|
||||||
|
|
||||||
// If the index is not used, use a 0 instead to still pass the range constraints from
|
// If the index is not used, use a 0 instead to still pass the range constraints from
|
||||||
|
|
@ -780,7 +786,7 @@ impl CustomOperationVerifyGadget {
|
||||||
let second_index = ak_key_wc_index;
|
let second_index = ak_key_wc_index;
|
||||||
let is_second_index_valid = builder.and(is_ak, is_ak_key_wc);
|
let is_second_index_valid = builder.and(is_ak, is_ak_key_wc);
|
||||||
let second_index = builder.select(is_second_index_valid, second_index, zero);
|
let second_index = builder.select(is_second_index_valid, second_index, zero);
|
||||||
let resolved_ak_key = builder.vec_ref(&self.params, args, second_index);
|
let resolved_ak_key = builder.vec_ref(&self.params, &args, second_index);
|
||||||
|
|
||||||
let ak_key = ak_key_lit; // is_ak_key_lit
|
let ak_key = ak_key_lit; // is_ak_key_lit
|
||||||
let ak_key =
|
let ak_key =
|
||||||
|
|
@ -1278,7 +1284,7 @@ mod tests {
|
||||||
frontend::{self, key, literal, CustomPredicateBatchBuilder, StatementTmplBuilder},
|
frontend::{self, key, literal, CustomPredicateBatchBuilder, StatementTmplBuilder},
|
||||||
middleware::{
|
middleware::{
|
||||||
hash_str, hash_values, Hash, Key, KeyOrWildcard, OperationType, PodId, Predicate,
|
hash_str, hash_values, Hash, Key, KeyOrWildcard, OperationType, PodId, Predicate,
|
||||||
RawValue, StatementTmpl, StatementTmplArg, Wildcard, WildcardValue,
|
RawValue, SelfOrWildcard, StatementTmpl, StatementTmplArg, Wildcard, WildcardValue,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -2222,7 +2228,7 @@ mod tests {
|
||||||
|
|
||||||
// case: AnchoredKey(id_wildcard, key_literal)
|
// case: AnchoredKey(id_wildcard, key_literal)
|
||||||
let st_tmpl_arg = StatementTmplArg::AnchoredKey(
|
let st_tmpl_arg = StatementTmplArg::AnchoredKey(
|
||||||
Wildcard::new("a".to_string(), 1),
|
SelfOrWildcard::Wildcard(Wildcard::new("a".to_string(), 1)),
|
||||||
KeyOrWildcard::Key(Key::from("foo")),
|
KeyOrWildcard::Key(Key::from("foo")),
|
||||||
);
|
);
|
||||||
let args = vec![Value::from(1), Value::from(pod_id.0), Value::from(3)];
|
let args = vec![Value::from(1), Value::from(pod_id.0), Value::from(3)];
|
||||||
|
|
@ -2231,13 +2237,31 @@ mod tests {
|
||||||
|
|
||||||
// case: AnchoredKey(id_wildcard, key_wildcard)
|
// case: AnchoredKey(id_wildcard, key_wildcard)
|
||||||
let st_tmpl_arg = StatementTmplArg::AnchoredKey(
|
let st_tmpl_arg = StatementTmplArg::AnchoredKey(
|
||||||
Wildcard::new("a".to_string(), 1),
|
SelfOrWildcard::Wildcard(Wildcard::new("a".to_string(), 1)),
|
||||||
KeyOrWildcard::Wildcard(Wildcard::new("b".to_string(), 2)),
|
KeyOrWildcard::Wildcard(Wildcard::new("b".to_string(), 2)),
|
||||||
);
|
);
|
||||||
let args = vec![Value::from(1), Value::from(pod_id.0), Value::from("key")];
|
let args = vec![Value::from(1), Value::from(pod_id.0), Value::from("key")];
|
||||||
let expected_st_arg = StatementArg::Key(AnchoredKey::new(pod_id, Key::from("key")));
|
let expected_st_arg = StatementArg::Key(AnchoredKey::new(pod_id, Key::from("key")));
|
||||||
helper_statement_arg_from_template(¶ms, st_tmpl_arg, args, expected_st_arg)?;
|
helper_statement_arg_from_template(¶ms, st_tmpl_arg, args, expected_st_arg)?;
|
||||||
|
|
||||||
|
// case: AnchoredKey(SELF, key_literal)
|
||||||
|
let st_tmpl_arg = StatementTmplArg::AnchoredKey(
|
||||||
|
SelfOrWildcard::SELF,
|
||||||
|
KeyOrWildcard::Key(Key::from("foo")),
|
||||||
|
);
|
||||||
|
let args = vec![Value::from(1), Value::from(pod_id.0), Value::from(3)];
|
||||||
|
let expected_st_arg = StatementArg::Key(AnchoredKey::new(SELF, Key::from("foo")));
|
||||||
|
helper_statement_arg_from_template(¶ms, st_tmpl_arg, args, expected_st_arg)?;
|
||||||
|
|
||||||
|
// case: AnchoredKey(SELF, key_wildcard)
|
||||||
|
let st_tmpl_arg = StatementTmplArg::AnchoredKey(
|
||||||
|
SelfOrWildcard::SELF,
|
||||||
|
KeyOrWildcard::Wildcard(Wildcard::new("b".to_string(), 2)),
|
||||||
|
);
|
||||||
|
let args = vec![Value::from(1), Value::from(pod_id.0), Value::from("key")];
|
||||||
|
let expected_st_arg = StatementArg::Key(AnchoredKey::new(SELF, Key::from("key")));
|
||||||
|
helper_statement_arg_from_template(¶ms, st_tmpl_arg, args, expected_st_arg)?;
|
||||||
|
|
||||||
// case: WildcardLiteral(wildcard)
|
// case: WildcardLiteral(wildcard)
|
||||||
let st_tmpl_arg = StatementTmplArg::WildcardLiteral(Wildcard::new("a".to_string(), 1));
|
let st_tmpl_arg = StatementTmplArg::WildcardLiteral(Wildcard::new("a".to_string(), 1));
|
||||||
let args = vec![Value::from(1), Value::from("key"), Value::from(3)];
|
let args = vec![Value::from(1), Value::from("key"), Value::from(3)];
|
||||||
|
|
@ -2294,7 +2318,7 @@ mod tests {
|
||||||
pred: Predicate::Native(NativePredicate::ValueOf),
|
pred: Predicate::Native(NativePredicate::ValueOf),
|
||||||
args: vec![
|
args: vec![
|
||||||
StatementTmplArg::AnchoredKey(
|
StatementTmplArg::AnchoredKey(
|
||||||
Wildcard::new("a".to_string(), 1),
|
SelfOrWildcard::Wildcard(Wildcard::new("a".to_string(), 1)),
|
||||||
KeyOrWildcard::Key(Key::from("key")),
|
KeyOrWildcard::Key(Key::from("key")),
|
||||||
),
|
),
|
||||||
StatementTmplArg::Literal(Value::from("value")),
|
StatementTmplArg::Literal(Value::from("value")),
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ pub mod measure_macros {
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! measure_gates_begin {
|
macro_rules! measure_gates_begin {
|
||||||
($builder:expr, $name:expr) => {{
|
($builder:expr, $name:expr) => {{
|
||||||
use $crate::backends::plonky2::circuits::utils::METRICS;
|
use $crate::backends::plonky2::circuits::metrics::METRICS;
|
||||||
let mut metrics = METRICS.lock().unwrap();
|
let mut metrics = METRICS.lock().unwrap();
|
||||||
metrics.begin($builder, $name)
|
metrics.begin($builder, $name)
|
||||||
}};
|
}};
|
||||||
|
|
@ -76,7 +76,7 @@ pub mod measure_macros {
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! measure_gates_end {
|
macro_rules! measure_gates_end {
|
||||||
($builder:expr, $measure:expr) => {{
|
($builder:expr, $measure:expr) => {{
|
||||||
use $crate::backends::plonky2::circuits::utils::METRICS;
|
use $crate::backends::plonky2::circuits::metrics::METRICS;
|
||||||
let mut metrics = METRICS.lock().unwrap();
|
let mut metrics = METRICS.lock().unwrap();
|
||||||
metrics.end($builder, $measure);
|
metrics.end($builder, $measure);
|
||||||
}};
|
}};
|
||||||
|
|
@ -85,7 +85,7 @@ pub mod measure_macros {
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! measure_gates_print {
|
macro_rules! measure_gates_print {
|
||||||
() => {{
|
() => {{
|
||||||
use $crate::backends::plonky2::circuits::utils::METRICS;
|
use $crate::backends::plonky2::circuits::metrics::METRICS;
|
||||||
let metrics = METRICS.lock().unwrap();
|
let metrics = METRICS.lock().unwrap();
|
||||||
metrics.print();
|
metrics.print();
|
||||||
}};
|
}};
|
||||||
|
|
|
||||||
|
|
@ -737,11 +737,11 @@ pub mod tests {
|
||||||
max_statements: 26,
|
max_statements: 26,
|
||||||
max_public_statements: 5,
|
max_public_statements: 5,
|
||||||
max_signed_pod_values: 8,
|
max_signed_pod_values: 8,
|
||||||
max_statement_args: 6,
|
max_statement_args: 3,
|
||||||
max_operation_args: 4,
|
max_operation_args: 4,
|
||||||
max_custom_predicate_arity: 4,
|
max_custom_predicate_arity: 4,
|
||||||
max_custom_batch_size: 3,
|
max_custom_batch_size: 3,
|
||||||
max_custom_predicate_wildcards: 12,
|
max_custom_predicate_wildcards: 6,
|
||||||
max_custom_predicate_verifications: 8,
|
max_custom_predicate_verifications: 8,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ pub fn eth_friend_batch(params: &Params, mock: bool) -> Result<Arc<CustomPredica
|
||||||
let _eth_friend = builder.predicate_and(
|
let _eth_friend = builder.predicate_and(
|
||||||
"eth_friend",
|
"eth_friend",
|
||||||
// arguments:
|
// arguments:
|
||||||
&["src_ori", "src_key", "dst_ori", "dst_key"],
|
&["src_key", "dst_key"],
|
||||||
// private arguments:
|
// private arguments:
|
||||||
&["attestation_pod"],
|
&["attestation_pod"],
|
||||||
// statement templates:
|
// statement templates:
|
||||||
|
|
@ -33,11 +33,11 @@ pub fn eth_friend_batch(params: &Params, mock: bool) -> Result<Arc<CustomPredica
|
||||||
// the attestation pod is signed by (src_or, src_key)
|
// the attestation pod is signed by (src_or, src_key)
|
||||||
STB::new(NP::Equal)
|
STB::new(NP::Equal)
|
||||||
.arg(("attestation_pod", key(KEY_SIGNER)))
|
.arg(("attestation_pod", key(KEY_SIGNER)))
|
||||||
.arg(("src_ori", "src_key")),
|
.arg(("SELF", "src_key")),
|
||||||
// that same attestation pod has an "attestation"
|
// that same attestation pod has an "attestation"
|
||||||
STB::new(NP::Equal)
|
STB::new(NP::Equal)
|
||||||
.arg(("attestation_pod", key("attestation")))
|
.arg(("attestation_pod", key("attestation")))
|
||||||
.arg(("dst_ori", "dst_key")),
|
.arg(("SELF", "dst_key")),
|
||||||
],
|
],
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|
@ -59,11 +59,8 @@ pub fn eth_dos_batch(params: &Params, mock: bool) -> Result<Arc<CustomPredicateB
|
||||||
"eth_dos_distance_base",
|
"eth_dos_distance_base",
|
||||||
&[
|
&[
|
||||||
// arguments:
|
// arguments:
|
||||||
"src_ori",
|
|
||||||
"src_key",
|
"src_key",
|
||||||
"dst_ori",
|
|
||||||
"dst_key",
|
"dst_key",
|
||||||
"distance_ori",
|
|
||||||
"distance_key",
|
"distance_key",
|
||||||
],
|
],
|
||||||
&[ // private arguments:
|
&[ // private arguments:
|
||||||
|
|
@ -71,10 +68,10 @@ pub fn eth_dos_batch(params: &Params, mock: bool) -> Result<Arc<CustomPredicateB
|
||||||
&[
|
&[
|
||||||
// statement templates:
|
// statement templates:
|
||||||
STB::new(NP::Equal)
|
STB::new(NP::Equal)
|
||||||
.arg(("src_ori", "src_key"))
|
.arg(("SELF", "src_key"))
|
||||||
.arg(("dst_ori", "dst_key")),
|
.arg(("SELF", "dst_key")),
|
||||||
STB::new(NP::ValueOf)
|
STB::new(NP::ValueOf)
|
||||||
.arg(("distance_ori", "distance_key"))
|
.arg(("SELF", "distance_key"))
|
||||||
.arg(literal(0)),
|
.arg(literal(0)),
|
||||||
],
|
],
|
||||||
)?;
|
)?;
|
||||||
|
|
@ -89,45 +86,32 @@ pub fn eth_dos_batch(params: &Params, mock: bool) -> Result<Arc<CustomPredicateB
|
||||||
"eth_dos_distance_ind",
|
"eth_dos_distance_ind",
|
||||||
&[
|
&[
|
||||||
// arguments:
|
// arguments:
|
||||||
"src_ori",
|
|
||||||
"src_key",
|
"src_key",
|
||||||
"dst_ori",
|
|
||||||
"dst_key",
|
"dst_key",
|
||||||
"distance_ori",
|
|
||||||
"distance_key",
|
"distance_key",
|
||||||
],
|
],
|
||||||
&[
|
&[
|
||||||
// private arguments:
|
// private arguments:
|
||||||
"one_ori",
|
|
||||||
"one_key",
|
"one_key",
|
||||||
"shorter_distance_ori",
|
|
||||||
"shorter_distance_key",
|
"shorter_distance_key",
|
||||||
"intermed_ori",
|
|
||||||
"intermed_key",
|
"intermed_key",
|
||||||
],
|
],
|
||||||
&[
|
&[
|
||||||
// statement templates:
|
// statement templates:
|
||||||
STB::new(eth_dos_distance)
|
STB::new(eth_dos_distance)
|
||||||
.arg("src_ori")
|
|
||||||
.arg("src_key")
|
.arg("src_key")
|
||||||
.arg("intermed_ori")
|
|
||||||
.arg("intermed_key")
|
.arg("intermed_key")
|
||||||
.arg("shorter_distance_ori")
|
|
||||||
.arg("shorter_distance_key"),
|
.arg("shorter_distance_key"),
|
||||||
// distance == shorter_distance + 1
|
// distance == shorter_distance + 1
|
||||||
STB::new(NP::ValueOf)
|
STB::new(NP::ValueOf)
|
||||||
.arg(("one_ori", "one_key"))
|
.arg(("SELF", "one_key"))
|
||||||
.arg(literal(1)),
|
.arg(literal(1)),
|
||||||
STB::new(NP::SumOf)
|
STB::new(NP::SumOf)
|
||||||
.arg(("distance_ori", "distance_key"))
|
.arg(("SELF", "distance_key"))
|
||||||
.arg(("shorter_distance_ori", "shorter_distance_key"))
|
.arg(("SELF", "shorter_distance_key"))
|
||||||
.arg(("one_ori", "one_key")),
|
.arg(("SELF", "one_key")),
|
||||||
// intermed is a friend of dst
|
// intermed is a friend of dst
|
||||||
STB::new(eth_friend)
|
STB::new(eth_friend).arg("intermed_key").arg("dst_key"),
|
||||||
.arg("intermed_ori")
|
|
||||||
.arg("intermed_key")
|
|
||||||
.arg("dst_ori")
|
|
||||||
.arg("dst_key"),
|
|
||||||
],
|
],
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|
@ -138,29 +122,16 @@ pub fn eth_dos_batch(params: &Params, mock: bool) -> Result<Arc<CustomPredicateB
|
||||||
|
|
||||||
let _eth_dos_distance = builder.predicate_or(
|
let _eth_dos_distance = builder.predicate_or(
|
||||||
"eth_dos_distance",
|
"eth_dos_distance",
|
||||||
&[
|
&["src_key", "dst_key", "distance_key"],
|
||||||
"src_ori",
|
|
||||||
"src_key",
|
|
||||||
"dst_ori",
|
|
||||||
"dst_key",
|
|
||||||
"distance_ori",
|
|
||||||
"distance_key",
|
|
||||||
],
|
|
||||||
&[],
|
&[],
|
||||||
&[
|
&[
|
||||||
STB::new(eth_dos_distance_base)
|
STB::new(eth_dos_distance_base)
|
||||||
.arg("src_ori")
|
|
||||||
.arg("src_key")
|
.arg("src_key")
|
||||||
.arg("dst_ori")
|
|
||||||
.arg("dst_key")
|
.arg("dst_key")
|
||||||
.arg("distance_ori")
|
|
||||||
.arg("distance_key"),
|
.arg("distance_key"),
|
||||||
STB::new(eth_dos_distance_ind)
|
STB::new(eth_dos_distance_ind)
|
||||||
.arg("src_ori")
|
|
||||||
.arg("src_key")
|
.arg("src_key")
|
||||||
.arg("dst_ori")
|
|
||||||
.arg("dst_key")
|
.arg("dst_key")
|
||||||
.arg("distance_ori")
|
|
||||||
.arg("distance_key"),
|
.arg("distance_key"),
|
||||||
],
|
],
|
||||||
)?;
|
)?;
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ pub fn eth_dos_pod_builder(
|
||||||
let zero = alice_bob_ethdos.priv_literal(0)?;
|
let zero = alice_bob_ethdos.priv_literal(0)?;
|
||||||
let alice_equals_alice = alice_bob_ethdos.priv_op(op!(
|
let alice_equals_alice = alice_bob_ethdos.priv_op(op!(
|
||||||
eq,
|
eq,
|
||||||
(alice_attestation, KEY_SIGNER),
|
alice_pubkey_copy.clone(),
|
||||||
alice_pubkey_copy.clone()
|
alice_pubkey_copy.clone()
|
||||||
))?;
|
))?;
|
||||||
let ethdos_alice_alice_is_zero_base = alice_bob_ethdos.priv_op(op!(
|
let ethdos_alice_alice_is_zero_base = alice_bob_ethdos.priv_op(op!(
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ use crate::{
|
||||||
frontend::{AnchoredKey, Error, Result, Statement, StatementArg},
|
frontend::{AnchoredKey, Error, Result, Statement, StatementArg},
|
||||||
middleware::{
|
middleware::{
|
||||||
self, hash_str, CustomPredicate, CustomPredicateBatch, Key, KeyOrWildcard, NativePredicate,
|
self, hash_str, CustomPredicate, CustomPredicateBatch, Key, KeyOrWildcard, NativePredicate,
|
||||||
Params, PodId, Predicate, StatementTmpl, StatementTmplArg, ToFields, Value, Wildcard,
|
Params, PodId, Predicate, SelfOrWildcard, StatementTmpl, StatementTmplArg, ToFields, Value,
|
||||||
|
Wildcard,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -18,6 +19,12 @@ pub enum KeyOrWildcardStr {
|
||||||
Wildcard(String),
|
Wildcard(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub enum SelfOrWildcardStr {
|
||||||
|
SELF,
|
||||||
|
Wildcard(String),
|
||||||
|
}
|
||||||
|
|
||||||
/// helper to build a literal KeyOrWildcardStr::Key from the given str
|
/// helper to build a literal KeyOrWildcardStr::Key from the given str
|
||||||
pub fn key(s: &str) -> KeyOrWildcardStr {
|
pub fn key(s: &str) -> KeyOrWildcardStr {
|
||||||
KeyOrWildcardStr::Key(s.to_string())
|
KeyOrWildcardStr::Key(s.to_string())
|
||||||
|
|
@ -27,11 +34,21 @@ pub fn key(s: &str) -> KeyOrWildcardStr {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum BuilderArg {
|
pub enum BuilderArg {
|
||||||
Literal(Value),
|
Literal(Value),
|
||||||
/// Key: (origin, key), where origin is a Wildcard and key can be both Key or Wildcard
|
/// Key: (origin, key), where origin is SELF or Wildcard and key is Key or Wildcard
|
||||||
Key(String, KeyOrWildcardStr),
|
Key(SelfOrWildcardStr, KeyOrWildcardStr),
|
||||||
WildcardLiteral(String),
|
WildcardLiteral(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<&str> for SelfOrWildcardStr {
|
||||||
|
fn from(origin: &str) -> Self {
|
||||||
|
if origin == "SELF" {
|
||||||
|
SelfOrWildcardStr::SELF
|
||||||
|
} else {
|
||||||
|
SelfOrWildcardStr::Wildcard(origin.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// When defining a `BuilderArg`, it can be done from 3 different inputs:
|
/// When defining a `BuilderArg`, it can be done from 3 different inputs:
|
||||||
/// i. (&str, literal): this is to set a POD and a field, ie. (POD, literal("field"))
|
/// i. (&str, literal): this is to set a POD and a field, ie. (POD, literal("field"))
|
||||||
/// ii. (&str, &str): this is to define a origin-key wildcard pair, ie. (src_origin, src_dest)
|
/// ii. (&str, &str): this is to define a origin-key wildcard pair, ie. (src_origin, src_dest)
|
||||||
|
|
@ -40,11 +57,6 @@ pub enum BuilderArg {
|
||||||
/// case i.
|
/// case i.
|
||||||
impl From<(&str, KeyOrWildcardStr)> for BuilderArg {
|
impl From<(&str, KeyOrWildcardStr)> for BuilderArg {
|
||||||
fn from((origin, lit): (&str, KeyOrWildcardStr)) -> Self {
|
fn from((origin, lit): (&str, KeyOrWildcardStr)) -> Self {
|
||||||
// ensure that `lit` is of HashOrWildcardStr::Hash type
|
|
||||||
match lit {
|
|
||||||
KeyOrWildcardStr::Key(_) => (),
|
|
||||||
_ => panic!("not supported"),
|
|
||||||
};
|
|
||||||
Self::Key(origin.into(), lit)
|
Self::Key(origin.into(), lit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -197,7 +209,7 @@ impl CustomPredicateBatchBuilder {
|
||||||
.map(|a| match a {
|
.map(|a| match a {
|
||||||
BuilderArg::Literal(v) => StatementTmplArg::Literal(v.clone()),
|
BuilderArg::Literal(v) => StatementTmplArg::Literal(v.clone()),
|
||||||
BuilderArg::Key(pod_id, key) => StatementTmplArg::AnchoredKey(
|
BuilderArg::Key(pod_id, key) => StatementTmplArg::AnchoredKey(
|
||||||
resolve_wildcard(args, priv_args, pod_id),
|
resolve_self_or_wildcard(args, priv_args, pod_id),
|
||||||
resolve_key_or_wildcard(args, priv_args, key),
|
resolve_key_or_wildcard(args, priv_args, key),
|
||||||
),
|
),
|
||||||
BuilderArg::WildcardLiteral(v) => {
|
BuilderArg::WildcardLiteral(v) => {
|
||||||
|
|
@ -227,6 +239,19 @@ impl CustomPredicateBatchBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn resolve_self_or_wildcard(
|
||||||
|
args: &[&str],
|
||||||
|
priv_args: &[&str],
|
||||||
|
v: &SelfOrWildcardStr,
|
||||||
|
) -> SelfOrWildcard {
|
||||||
|
match v {
|
||||||
|
SelfOrWildcardStr::SELF => SelfOrWildcard::SELF,
|
||||||
|
SelfOrWildcardStr::Wildcard(s) => {
|
||||||
|
SelfOrWildcard::Wildcard(resolve_wildcard(args, priv_args, s))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_key_or_wildcard(
|
fn resolve_key_or_wildcard(
|
||||||
args: &[&str],
|
args: &[&str],
|
||||||
priv_args: &[&str],
|
priv_args: &[&str],
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ impl fmt::Display for Wildcard {
|
||||||
|
|
||||||
impl ToFields for Wildcard {
|
impl ToFields for Wildcard {
|
||||||
fn to_fields(&self, _params: &Params) -> Vec<F> {
|
fn to_fields(&self, _params: &Params) -> Vec<F> {
|
||||||
vec![F::from_canonical_u64(self.index as u64)]
|
vec![F::from_canonical_u64(self.index as u64 + 1)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,11 +52,11 @@ impl fmt::Display for KeyOrWildcard {
|
||||||
impl ToFields for KeyOrWildcard {
|
impl ToFields for KeyOrWildcard {
|
||||||
// Encoding:
|
// Encoding:
|
||||||
// - Key(k) => [[k]]
|
// - Key(k) => [[k]]
|
||||||
// - Wildcard(index) => [[index], 0, 0, 0]
|
// - Wildcard(index) => [[index + 1], 0, 0, 0]
|
||||||
fn to_fields(&self, params: &Params) -> Vec<F> {
|
fn to_fields(&self, params: &Params) -> Vec<F> {
|
||||||
match self {
|
match self {
|
||||||
KeyOrWildcard::Key(k) => k.hash().to_fields(params),
|
KeyOrWildcard::Key(k) => k.hash().to_fields(params),
|
||||||
KeyOrWildcard::Wildcard(wc) => iter::once(F::from_canonical_u64(wc.index as u64))
|
KeyOrWildcard::Wildcard(wc) => iter::once(F::from_canonical_u64(wc.index as u64 + 1))
|
||||||
.chain(iter::repeat(F::ZERO))
|
.chain(iter::repeat(F::ZERO))
|
||||||
.take(HASH_SIZE)
|
.take(HASH_SIZE)
|
||||||
.collect(),
|
.collect(),
|
||||||
|
|
@ -64,13 +64,41 @@ impl ToFields for KeyOrWildcard {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||||
|
#[serde(tag = "type", content = "value")]
|
||||||
|
pub enum SelfOrWildcard {
|
||||||
|
SELF,
|
||||||
|
Wildcard(Wildcard),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for SelfOrWildcard {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::SELF => write!(f, "SELF"),
|
||||||
|
Self::Wildcard(wc) => write!(f, "{}", wc),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToFields for SelfOrWildcard {
|
||||||
|
// Encoding:
|
||||||
|
// - Self => [0]
|
||||||
|
// - Wildcard(index) => [index+1]
|
||||||
|
fn to_fields(&self, _params: &Params) -> Vec<F> {
|
||||||
|
match self {
|
||||||
|
SelfOrWildcard::SELF => vec![F::ZERO],
|
||||||
|
SelfOrWildcard::Wildcard(wc) => vec![F::from_canonical_u64(wc.index as u64 + 1)],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||||
#[serde(tag = "type", content = "value")]
|
#[serde(tag = "type", content = "value")]
|
||||||
pub enum StatementTmplArg {
|
pub enum StatementTmplArg {
|
||||||
None,
|
None,
|
||||||
Literal(Value),
|
Literal(Value),
|
||||||
// AnchoredKey
|
// AnchoredKey
|
||||||
AnchoredKey(Wildcard, KeyOrWildcard),
|
AnchoredKey(SelfOrWildcard, KeyOrWildcard),
|
||||||
// TODO: This naming is a bit confusing: a WildcardLiteral that contains a Wildcard...
|
// TODO: This naming is a bit confusing: a WildcardLiteral that contains a Wildcard...
|
||||||
// Could we merge WildcardValue and Value and allow wildcard value apart from pod_id and key?
|
// Could we merge WildcardValue and Value and allow wildcard value apart from pod_id and key?
|
||||||
WildcardLiteral(Wildcard),
|
WildcardLiteral(Wildcard),
|
||||||
|
|
@ -438,6 +466,9 @@ mod tests {
|
||||||
fn kow_wc(i: usize) -> KOW {
|
fn kow_wc(i: usize) -> KOW {
|
||||||
KOW::Wildcard(wc(i))
|
KOW::Wildcard(wc(i))
|
||||||
}
|
}
|
||||||
|
fn sow_wc(i: usize) -> SOW {
|
||||||
|
SOW::Wildcard(wc(i))
|
||||||
|
}
|
||||||
fn wc(i: usize) -> Wildcard {
|
fn wc(i: usize) -> Wildcard {
|
||||||
Wildcard {
|
Wildcard {
|
||||||
name: format!("{}", i),
|
name: format!("{}", i),
|
||||||
|
|
@ -447,6 +478,7 @@ mod tests {
|
||||||
|
|
||||||
type STA = StatementTmplArg;
|
type STA = StatementTmplArg;
|
||||||
type KOW = KeyOrWildcard;
|
type KOW = KeyOrWildcard;
|
||||||
|
type SOW = SelfOrWildcard;
|
||||||
type P = Predicate;
|
type P = Predicate;
|
||||||
type NP = NativePredicate;
|
type NP = NativePredicate;
|
||||||
|
|
||||||
|
|
@ -468,14 +500,17 @@ mod tests {
|
||||||
vec![
|
vec![
|
||||||
st(
|
st(
|
||||||
P::Native(NP::ValueOf),
|
P::Native(NP::ValueOf),
|
||||||
vec![STA::AnchoredKey(wc(4), kow_wc(5)), STA::Literal(2.into())],
|
vec![
|
||||||
|
STA::AnchoredKey(sow_wc(4), kow_wc(5)),
|
||||||
|
STA::Literal(2.into()),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
st(
|
st(
|
||||||
P::Native(NP::ProductOf),
|
P::Native(NP::ProductOf),
|
||||||
vec![
|
vec![
|
||||||
STA::AnchoredKey(wc(0), kow_wc(1)),
|
STA::AnchoredKey(sow_wc(0), kow_wc(1)),
|
||||||
STA::AnchoredKey(wc(4), kow_wc(5)),
|
STA::AnchoredKey(sow_wc(4), kow_wc(5)),
|
||||||
STA::AnchoredKey(wc(2), kow_wc(3)),
|
STA::AnchoredKey(sow_wc(2), kow_wc(3)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
@ -523,22 +558,22 @@ mod tests {
|
||||||
st(
|
st(
|
||||||
P::Native(NP::ValueOf),
|
P::Native(NP::ValueOf),
|
||||||
vec![
|
vec![
|
||||||
STA::AnchoredKey(wc(4), KeyOrWildcard::Key("type".into())),
|
STA::AnchoredKey(sow_wc(4), KeyOrWildcard::Key("type".into())),
|
||||||
STA::Literal(PodType::Signed.into()),
|
STA::Literal(PodType::Signed.into()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
st(
|
st(
|
||||||
P::Native(NP::Equal),
|
P::Native(NP::Equal),
|
||||||
vec![
|
vec![
|
||||||
STA::AnchoredKey(wc(4), KeyOrWildcard::Key("signer".into())),
|
STA::AnchoredKey(sow_wc(4), KeyOrWildcard::Key("signer".into())),
|
||||||
STA::AnchoredKey(wc(0), kow_wc(1)),
|
STA::AnchoredKey(sow_wc(0), kow_wc(1)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
st(
|
st(
|
||||||
P::Native(NP::Equal),
|
P::Native(NP::Equal),
|
||||||
vec![
|
vec![
|
||||||
STA::AnchoredKey(wc(4), KeyOrWildcard::Key("attestation".into())),
|
STA::AnchoredKey(sow_wc(4), KeyOrWildcard::Key("attestation".into())),
|
||||||
STA::AnchoredKey(wc(2), kow_wc(3)),
|
STA::AnchoredKey(sow_wc(2), kow_wc(3)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
@ -556,13 +591,16 @@ mod tests {
|
||||||
st(
|
st(
|
||||||
P::Native(NP::Equal),
|
P::Native(NP::Equal),
|
||||||
vec![
|
vec![
|
||||||
STA::AnchoredKey(wc(0), kow_wc(1)),
|
STA::AnchoredKey(sow_wc(0), kow_wc(1)),
|
||||||
STA::AnchoredKey(wc(2), kow_wc(3)),
|
STA::AnchoredKey(sow_wc(2), kow_wc(3)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
st(
|
st(
|
||||||
P::Native(NP::ValueOf),
|
P::Native(NP::ValueOf),
|
||||||
vec![STA::AnchoredKey(wc(4), kow_wc(5)), STA::Literal(0.into())],
|
vec![
|
||||||
|
STA::AnchoredKey(sow_wc(4), kow_wc(5)),
|
||||||
|
STA::Literal(0.into()),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
6,
|
6,
|
||||||
|
|
@ -586,14 +624,17 @@ mod tests {
|
||||||
),
|
),
|
||||||
st(
|
st(
|
||||||
P::Native(NP::ValueOf),
|
P::Native(NP::ValueOf),
|
||||||
vec![STA::AnchoredKey(wc(6), kow_wc(7)), STA::Literal(1.into())],
|
vec![
|
||||||
|
STA::AnchoredKey(sow_wc(6), kow_wc(7)),
|
||||||
|
STA::Literal(1.into()),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
st(
|
st(
|
||||||
P::Native(NP::SumOf),
|
P::Native(NP::SumOf),
|
||||||
vec![
|
vec![
|
||||||
STA::AnchoredKey(wc(4), kow_wc(5)),
|
STA::AnchoredKey(sow_wc(4), kow_wc(5)),
|
||||||
STA::AnchoredKey(wc(8), kow_wc(9)),
|
STA::AnchoredKey(sow_wc(8), kow_wc(9)),
|
||||||
STA::AnchoredKey(wc(6), kow_wc(7)),
|
STA::AnchoredKey(sow_wc(6), kow_wc(7)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
st(
|
st(
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ use crate::{
|
||||||
backends::plonky2::primitives::merkletree::MerkleProof,
|
backends::plonky2::primitives::merkletree::MerkleProof,
|
||||||
middleware::{
|
middleware::{
|
||||||
custom::KeyOrWildcard, AnchoredKey, CustomPredicate, CustomPredicateRef, Error,
|
custom::KeyOrWildcard, AnchoredKey, CustomPredicate, CustomPredicateRef, Error,
|
||||||
NativePredicate, Params, Predicate, Result, Statement, StatementArg, StatementTmplArg,
|
NativePredicate, Params, Predicate, Result, SelfOrWildcard, Statement, StatementArg,
|
||||||
ToFields, Wildcard, WildcardValue, F, SELF,
|
StatementTmplArg, ToFields, Wildcard, WildcardValue, F, SELF,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -363,10 +363,15 @@ pub fn check_st_tmpl(
|
||||||
(StatementTmplArg::None, StatementArg::None) => true,
|
(StatementTmplArg::None, StatementArg::None) => true,
|
||||||
(StatementTmplArg::Literal(lhs), StatementArg::Literal(rhs)) if lhs == rhs => true,
|
(StatementTmplArg::Literal(lhs), StatementArg::Literal(rhs)) if lhs == rhs => true,
|
||||||
(
|
(
|
||||||
StatementTmplArg::AnchoredKey(pod_id_wc, key_or_wc),
|
StatementTmplArg::AnchoredKey(self_or_wc, key_or_wc),
|
||||||
StatementArg::Key(AnchoredKey { pod_id, key }),
|
StatementArg::Key(AnchoredKey { pod_id, key }),
|
||||||
) => {
|
) => {
|
||||||
let pod_id_ok = check_or_set(WildcardValue::PodId(*pod_id), pod_id_wc, wildcard_map);
|
let pod_id_ok = match self_or_wc {
|
||||||
|
SelfOrWildcard::SELF => SELF == *pod_id,
|
||||||
|
SelfOrWildcard::Wildcard(pod_id_wc) => {
|
||||||
|
check_or_set(WildcardValue::PodId(*pod_id), pod_id_wc, wildcard_map)
|
||||||
|
}
|
||||||
|
};
|
||||||
let key_ok = match key_or_wc {
|
let key_ok = match key_or_wc {
|
||||||
KeyOrWildcard::Key(tmpl_key) => tmpl_key == key,
|
KeyOrWildcard::Key(tmpl_key) => tmpl_key == key,
|
||||||
KeyOrWildcard::Wildcard(key_wc) => {
|
KeyOrWildcard::Wildcard(key_wc) => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue