Add clippy (#191)
* Organize imports Use rustfmt to organize imports. Resolve #162 * remove unused imports * Fix clippy complaints * add clippy github action * remove comment for @arnaucube
This commit is contained in:
parent
24ff82dd3d
commit
0759d6e165
27 changed files with 217 additions and 339 deletions
21
.github/workflows/clippy.yml
vendored
Normal file
21
.github/workflows/clippy.yml
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
name: Clippy Check
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: [ main ]
|
||||||
|
types: [ready_for_review, opened, synchronize, reopened]
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
rustfmt:
|
||||||
|
if: github.event.pull_request.draft == false
|
||||||
|
name: Rust formatting
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||||
|
with:
|
||||||
|
components: clippy
|
||||||
|
- name: Check lints with clippy
|
||||||
|
run: cargo clippy
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "nightly"
|
channel = "nightly-2025-01-20"
|
||||||
components = ["clippy", "rustfmt"]
|
components = ["clippy", "rustfmt"]
|
||||||
|
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
//! This module allows to count operations involved in tests, isolating by test.
|
|
||||||
//!
|
|
||||||
//! Example of usage:
|
|
||||||
//! ```rust
|
|
||||||
//! #[test]
|
|
||||||
//! fn test_example() {
|
|
||||||
//! // [...]
|
|
||||||
//! println!("{}", counter::counter_get());
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
use std::{cell::RefCell, fmt, thread_local};
|
|
||||||
|
|
||||||
thread_local! {
|
|
||||||
static COUNTER: RefCell<Counter> = RefCell::new(Counter::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub(crate) struct Counter {
|
|
||||||
hash: usize,
|
|
||||||
tree_insert: usize,
|
|
||||||
tree_proof_gen: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Counter {
|
|
||||||
const fn new() -> Self {
|
|
||||||
Counter {
|
|
||||||
hash: 0,
|
|
||||||
tree_insert: 0,
|
|
||||||
tree_proof_gen: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Counter {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
let counter = counter_get();
|
|
||||||
write!(f, "Counter:\n")?;
|
|
||||||
write!(f, " hashes: {},\n", counter.hash)?;
|
|
||||||
write!(f, " tree_inserts: {},\n", counter.tree_insert)?;
|
|
||||||
write!(f, " tree_proof_gens: {}\n", counter.tree_proof_gen)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn count_hash() {
|
|
||||||
#[cfg(test)]
|
|
||||||
COUNTER.with(|c| c.borrow_mut().hash += 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn count_tree_insert() {
|
|
||||||
#[cfg(test)]
|
|
||||||
COUNTER.with(|c| c.borrow_mut().tree_insert += 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn count_tree_proof_gen() {
|
|
||||||
#[cfg(test)]
|
|
||||||
COUNTER.with(|c| c.borrow_mut().tree_proof_gen += 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn counter_get() -> Counter {
|
|
||||||
COUNTER.with(|c| c.borrow().clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn counter_reset() {
|
|
||||||
COUNTER.with(|c| {
|
|
||||||
c.borrow_mut().hash = 0;
|
|
||||||
c.borrow_mut().tree_insert = 0;
|
|
||||||
c.borrow_mut().tree_proof_gen = 0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,2 @@
|
||||||
pub(crate) mod counter;
|
|
||||||
|
|
||||||
#[cfg(feature = "backend_plonky2")]
|
#[cfg(feature = "backend_plonky2")]
|
||||||
pub mod plonky2;
|
pub mod plonky2;
|
||||||
|
|
|
||||||
|
|
@ -23,15 +23,12 @@ use plonky2::{
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::middleware::{
|
||||||
backends::counter,
|
|
||||||
middleware::{
|
|
||||||
serialization::{
|
serialization::{
|
||||||
deserialize_hash_tuple, deserialize_value_tuple, serialize_hash_tuple,
|
deserialize_hash_tuple, deserialize_value_tuple, serialize_hash_tuple,
|
||||||
serialize_value_tuple,
|
serialize_value_tuple,
|
||||||
},
|
},
|
||||||
Params, ToFields,
|
Params, ToFields,
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// F is the native field we use everywhere. Currently it's Goldilocks from plonky2
|
/// F is the native field we use everywhere. Currently it's Goldilocks from plonky2
|
||||||
|
|
@ -83,10 +80,10 @@ impl Ord for Value {
|
||||||
fn cmp(&self, other: &Self) -> Ordering {
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
for (lhs, rhs) in self.0.iter().zip(other.0.iter()).rev() {
|
for (lhs, rhs) in self.0.iter().zip(other.0.iter()).rev() {
|
||||||
let (lhs, rhs) = (lhs.to_canonical_u64(), rhs.to_canonical_u64());
|
let (lhs, rhs) = (lhs.to_canonical_u64(), rhs.to_canonical_u64());
|
||||||
if lhs < rhs {
|
match lhs.cmp(&rhs) {
|
||||||
return Ordering::Less;
|
Ordering::Less => return Ordering::Less,
|
||||||
} else if lhs > rhs {
|
Ordering::Greater => return Ordering::Greater,
|
||||||
return Ordering::Greater;
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ordering::Equal
|
Ordering::Equal
|
||||||
|
|
@ -159,10 +156,7 @@ pub fn hash_value(input: &Value) -> Hash {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash_fields(input: &[F]) -> Hash {
|
pub fn hash_fields(input: &[F]) -> Hash {
|
||||||
// Note: the counter counts when this method is called, but different input
|
Hash(PoseidonHash::hash_no_pad(input).elements)
|
||||||
// sizes will have different costs in-circuit.
|
|
||||||
counter::count_hash();
|
|
||||||
Hash(PoseidonHash::hash_no_pad(&input).elements)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Value> for Hash {
|
impl From<Value> for Hash {
|
||||||
|
|
|
||||||
|
|
@ -79,11 +79,7 @@ impl StatementArgTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(first: ValueTarget, second: ValueTarget) -> Self {
|
fn new(first: ValueTarget, second: ValueTarget) -> Self {
|
||||||
let elements: Vec<_> = first
|
let elements: Vec<_> = first.elements.into_iter().chain(second.elements).collect();
|
||||||
.elements
|
|
||||||
.into_iter()
|
|
||||||
.chain(second.elements.into_iter())
|
|
||||||
.collect();
|
|
||||||
StatementArgTarget {
|
StatementArgTarget {
|
||||||
elements: elements.try_into().expect("size STATEMENT_ARG_F_LEN"),
|
elements: elements.try_into().expect("size STATEMENT_ARG_F_LEN"),
|
||||||
}
|
}
|
||||||
|
|
@ -91,12 +87,12 @@ impl StatementArgTarget {
|
||||||
|
|
||||||
pub fn none(builder: &mut CircuitBuilder<F, D>) -> Self {
|
pub fn none(builder: &mut CircuitBuilder<F, D>) -> Self {
|
||||||
let empty = builder.constant_value(EMPTY_VALUE);
|
let empty = builder.constant_value(EMPTY_VALUE);
|
||||||
Self::new(empty.clone(), empty)
|
Self::new(empty, empty)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn literal(builder: &mut CircuitBuilder<F, D>, value: &ValueTarget) -> Self {
|
pub fn literal(builder: &mut CircuitBuilder<F, D>, value: &ValueTarget) -> Self {
|
||||||
let empty = builder.constant_value(EMPTY_VALUE);
|
let empty = builder.constant_value(EMPTY_VALUE);
|
||||||
Self::new(value.clone(), empty)
|
Self::new(*value, empty)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn anchored_key(
|
pub fn anchored_key(
|
||||||
|
|
@ -104,7 +100,7 @@ impl StatementArgTarget {
|
||||||
pod_id: &ValueTarget,
|
pod_id: &ValueTarget,
|
||||||
key: &ValueTarget,
|
key: &ValueTarget,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new(pod_id.clone(), key.clone())
|
Self::new(*pod_id, *key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -250,7 +246,7 @@ impl Flattenable for MerkleClaimTarget {
|
||||||
fn from_flattened(vs: &[Target]) -> Self {
|
fn from_flattened(vs: &[Target]) -> Self {
|
||||||
Self {
|
Self {
|
||||||
enabled: BoolTarget::new_unsafe(vs[0]),
|
enabled: BoolTarget::new_unsafe(vs[0]),
|
||||||
root: HashOutTarget::from_vec((&vs[1..1 + NUM_HASH_OUT_ELTS]).to_vec()),
|
root: HashOutTarget::from_vec(vs[1..1 + NUM_HASH_OUT_ELTS].to_vec()),
|
||||||
key: ValueTarget::from_slice(
|
key: ValueTarget::from_slice(
|
||||||
&vs[1 + NUM_HASH_OUT_ELTS..1 + NUM_HASH_OUT_ELTS + VALUE_SIZE],
|
&vs[1 + NUM_HASH_OUT_ELTS..1 + NUM_HASH_OUT_ELTS + VALUE_SIZE],
|
||||||
),
|
),
|
||||||
|
|
@ -439,7 +435,7 @@ impl CircuitBuilderPod<F, D> for CircuitBuilder<F, D> {
|
||||||
let matrix_row_ref = |builder: &mut CircuitBuilder<F, D>, m: &[Vec<Target>], i| {
|
let matrix_row_ref = |builder: &mut CircuitBuilder<F, D>, m: &[Vec<Target>], i| {
|
||||||
let num_rows = m.len();
|
let num_rows = m.len();
|
||||||
let num_columns = m
|
let num_columns = m
|
||||||
.get(0)
|
.first()
|
||||||
.map(|row| {
|
.map(|row| {
|
||||||
let row_len = row.len();
|
let row_len = row.len();
|
||||||
assert!(m.iter().all(|row| row.len() == row_len));
|
assert!(m.iter().all(|row| row.len() == row_len));
|
||||||
|
|
|
||||||
|
|
@ -45,14 +45,14 @@ impl OperationVerifyGadget {
|
||||||
op: &OperationTarget,
|
op: &OperationTarget,
|
||||||
prev_statements: &[StatementTarget],
|
prev_statements: &[StatementTarget],
|
||||||
merkle_claims: &[MerkleClaimTarget],
|
merkle_claims: &[MerkleClaimTarget],
|
||||||
) -> Result<OperationVerifyTarget> {
|
) -> Result<()> {
|
||||||
let _true = builder._true();
|
let _true = builder._true();
|
||||||
let _false = builder._false();
|
let _false = builder._false();
|
||||||
|
|
||||||
// Verify that the operation `op` correctly generates the statement `st`. The operation
|
// Verify that the operation `op` correctly generates the statement `st`. The operation
|
||||||
// can reference any of the `prev_statements`.
|
// can reference any of the `prev_statements`.
|
||||||
// TODO: Clean this up.
|
// TODO: Clean this up.
|
||||||
let resolved_op_args = if prev_statements.len() == 0 {
|
let resolved_op_args = if prev_statements.is_empty() {
|
||||||
vec![]
|
vec![]
|
||||||
} else {
|
} else {
|
||||||
op.args
|
op.args
|
||||||
|
|
@ -66,7 +66,7 @@ impl OperationVerifyGadget {
|
||||||
// of the provided Merkle proofs (if any). These proofs have already
|
// of the provided Merkle proofs (if any). These proofs have already
|
||||||
// been verified, so we need only look up the claim.
|
// been verified, so we need only look up the claim.
|
||||||
let resolved_merkle_claim =
|
let resolved_merkle_claim =
|
||||||
(merkle_claims.len() > 0).then(|| builder.vec_ref(merkle_claims, op.aux[0]));
|
(!merkle_claims.is_empty()).then(|| builder.vec_ref(merkle_claims, op.aux[0]));
|
||||||
|
|
||||||
// The verification may require aux data which needs to be stored in the
|
// The verification may require aux data which needs to be stored in the
|
||||||
// `OperationVerifyTarget` so that we can set during witness generation.
|
// `OperationVerifyTarget` so that we can set during witness generation.
|
||||||
|
|
@ -76,13 +76,13 @@ impl OperationVerifyGadget {
|
||||||
// as 'eval' restricted to the op of type X, where the
|
// as 'eval' restricted to the op of type X, where the
|
||||||
// returned target is `false` if the input targets lie outside
|
// returned target is `false` if the input targets lie outside
|
||||||
// of the domain.
|
// of the domain.
|
||||||
let op_checks = vec![
|
let op_checks = [
|
||||||
vec![
|
vec![
|
||||||
self.eval_none(builder, st, op),
|
self.eval_none(builder, st, op),
|
||||||
self.eval_new_entry(builder, st, op, prev_statements),
|
self.eval_new_entry(builder, st, op, prev_statements),
|
||||||
],
|
],
|
||||||
// Skip these if there are no resolved op args
|
// Skip these if there are no resolved op args
|
||||||
if resolved_op_args.len() == 0 {
|
if resolved_op_args.is_empty() {
|
||||||
vec![]
|
vec![]
|
||||||
} else {
|
} else {
|
||||||
vec![
|
vec![
|
||||||
|
|
@ -110,7 +110,7 @@ impl OperationVerifyGadget {
|
||||||
|
|
||||||
builder.connect(ok.target, _true.target);
|
builder.connect(ok.target, _true.target);
|
||||||
|
|
||||||
Ok(OperationVerifyTarget {})
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_not_contains_from_entries(
|
fn eval_not_contains_from_entries(
|
||||||
|
|
@ -311,9 +311,8 @@ impl OperationVerifyGadget {
|
||||||
|
|
||||||
let dupe_check = {
|
let dupe_check = {
|
||||||
let individual_checks = prev_statements
|
let individual_checks = prev_statements
|
||||||
.into_iter()
|
.iter()
|
||||||
.enumerate()
|
.map(|ps| {
|
||||||
.map(|(i, ps)| {
|
|
||||||
let same_predicate = builder.is_equal_slice(&st.predicate, &ps.predicate);
|
let same_predicate = builder.is_equal_slice(&st.predicate, &ps.predicate);
|
||||||
let same_anchored_key =
|
let same_anchored_key =
|
||||||
builder.is_equal_slice(&st.args[0].elements, &ps.args[0].elements);
|
builder.is_equal_slice(&st.args[0].elements, &ps.args[0].elements);
|
||||||
|
|
@ -344,21 +343,6 @@ impl OperationVerifyGadget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OperationVerifyTarget {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
struct OperationVerifyInput {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OperationVerifyTarget {
|
|
||||||
fn set_targets(&self, pw: &mut PartialWitness<F>, input: &OperationVerifyInput) -> Result<()> {
|
|
||||||
// TODO
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct MainPodVerifyGadget {
|
struct MainPodVerifyGadget {
|
||||||
params: Params,
|
params: Params,
|
||||||
}
|
}
|
||||||
|
|
@ -425,12 +409,11 @@ impl MainPodVerifyGadget {
|
||||||
// 2. Calculate the Pod Id from the public statements
|
// 2. Calculate the Pod Id from the public statements
|
||||||
let pub_statements_flattened = pub_statements
|
let pub_statements_flattened = pub_statements
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| {
|
.flat_map(|s| {
|
||||||
s.predicate
|
s.predicate
|
||||||
.iter()
|
.iter()
|
||||||
.chain(s.args.iter().flat_map(|a| &a.elements))
|
.chain(s.args.iter().flat_map(|a| &a.elements))
|
||||||
})
|
})
|
||||||
.flatten()
|
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
let id = builder.hash_n_to_hash_no_pad::<PoseidonHash>(pub_statements_flattened);
|
let id = builder.hash_n_to_hash_no_pad::<PoseidonHash>(pub_statements_flattened);
|
||||||
|
|
@ -451,14 +434,12 @@ impl MainPodVerifyGadget {
|
||||||
// 3. check that all `input_statements` of type `ValueOf` with origin=SELF have unique keys
|
// 3. check that all `input_statements` of type `ValueOf` with origin=SELF have unique keys
|
||||||
// (no duplicates). We do this in the verification of NewEntry operation.
|
// (no duplicates). We do this in the verification of NewEntry operation.
|
||||||
// 5. Verify input statements
|
// 5. Verify input statements
|
||||||
let mut op_verifications = Vec::new();
|
|
||||||
for (i, (st, op)) in input_statements.iter().zip(operations.iter()).enumerate() {
|
for (i, (st, op)) in input_statements.iter().zip(operations.iter()).enumerate() {
|
||||||
let prev_statements = &statements[..input_statements_offset + i];
|
let prev_statements = &statements[..input_statements_offset + i];
|
||||||
let op_verification = OperationVerifyGadget {
|
OperationVerifyGadget {
|
||||||
params: params.clone(),
|
params: params.clone(),
|
||||||
}
|
}
|
||||||
.eval(builder, st, op, prev_statements, &merkle_claims)?;
|
.eval(builder, st, op, prev_statements, &merkle_claims)?;
|
||||||
op_verifications.push(op_verification);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(MainPodVerifyTarget {
|
Ok(MainPodVerifyTarget {
|
||||||
|
|
@ -468,7 +449,6 @@ impl MainPodVerifyGadget {
|
||||||
statements: input_statements.to_vec(),
|
statements: input_statements.to_vec(),
|
||||||
operations,
|
operations,
|
||||||
merkle_proofs,
|
merkle_proofs,
|
||||||
op_verifications,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -481,7 +461,6 @@ pub struct MainPodVerifyTarget {
|
||||||
statements: Vec<StatementTarget>,
|
statements: Vec<StatementTarget>,
|
||||||
operations: Vec<OperationTarget>,
|
operations: Vec<OperationTarget>,
|
||||||
merkle_proofs: Vec<MerkleClaimAndProofTarget>,
|
merkle_proofs: Vec<MerkleClaimAndProofTarget>,
|
||||||
op_verifications: Vec<OperationVerifyTarget>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MainPodVerifyInput {
|
pub struct MainPodVerifyInput {
|
||||||
|
|
@ -624,8 +603,6 @@ mod tests {
|
||||||
merkle_proof.value,
|
merkle_proof.value,
|
||||||
)?
|
)?
|
||||||
}
|
}
|
||||||
let input = OperationVerifyInput {};
|
|
||||||
operation_verify.set_targets(&mut pw, &input)?;
|
|
||||||
|
|
||||||
// generate & verify proof
|
// generate & verify proof
|
||||||
let data = builder.build::<C>();
|
let data = builder.build::<C>();
|
||||||
|
|
|
||||||
|
|
@ -108,10 +108,7 @@ impl SignedPodVerifyTarget {
|
||||||
.chain(iter::repeat_with(|| StatementArgTarget::none(builder)))
|
.chain(iter::repeat_with(|| StatementArgTarget::none(builder)))
|
||||||
.take(self.params.max_statement_args)
|
.take(self.params.max_statement_args)
|
||||||
.collect();
|
.collect();
|
||||||
let statement = StatementTarget {
|
let statement = StatementTarget { predicate, args };
|
||||||
predicate: predicate.clone(),
|
|
||||||
args,
|
|
||||||
};
|
|
||||||
statements.push(statement);
|
statements.push(statement);
|
||||||
}
|
}
|
||||||
statements
|
statements
|
||||||
|
|
@ -131,7 +128,7 @@ impl SignedPodVerifyTarget {
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, k)| {
|
.map(|(i, k)| {
|
||||||
let (v, proof) = pod.dict.prove(&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, v)?;
|
||||||
Ok(v)
|
Ok(v)
|
||||||
})
|
})
|
||||||
|
|
@ -146,7 +143,7 @@ impl SignedPodVerifyTarget {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (obtained_v, proof) = pod.dict.prove(&k)?;
|
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, *v)?;
|
||||||
|
|
@ -217,7 +214,7 @@ pub mod tests {
|
||||||
pod.insert("idNumber", "4242424242");
|
pod.insert("idNumber", "4242424242");
|
||||||
pod.insert("dateOfBirth", 1169909384);
|
pod.insert("dateOfBirth", 1169909384);
|
||||||
pod.insert("socialSecurityNumber", "G2121210");
|
pod.insert("socialSecurityNumber", "G2121210");
|
||||||
let sk = SecretKey::new();
|
let sk = SecretKey::new_rand();
|
||||||
let mut signer = Signer(sk);
|
let mut signer = Signer(sk);
|
||||||
let pod = pod.sign(&mut signer).unwrap();
|
let pod = pod.sign(&mut signer).unwrap();
|
||||||
let signed_pod = pod.pod.into_any().downcast::<SignedPod>().unwrap();
|
let signed_pod = pod.pod.into_any().downcast::<SignedPod>().unwrap();
|
||||||
|
|
|
||||||
|
|
@ -39,14 +39,15 @@ impl PodProver for Prover {
|
||||||
.signed_pods
|
.signed_pods
|
||||||
.iter()
|
.iter()
|
||||||
.map(|p| {
|
.map(|p| {
|
||||||
let p: Box<dyn middleware::Pod> = (*p).clone();
|
let p = p
|
||||||
*p.into_any()
|
.as_any()
|
||||||
.downcast::<SignedPod>()
|
.downcast_ref::<SignedPod>()
|
||||||
.expect("type SignedPod")
|
.expect("type SignedPod");
|
||||||
|
p.clone()
|
||||||
})
|
})
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
|
|
||||||
let merkle_proofs = MockMainPod::extract_merkle_proofs(params, &inputs.operations)?;
|
let merkle_proofs = MockMainPod::extract_merkle_proofs(params, inputs.operations)?;
|
||||||
|
|
||||||
// TODO: Move these methods from the mock main pod to a common place
|
// TODO: Move these methods from the mock main pod to a common place
|
||||||
let statements = MockMainPod::layout_statements(params, &inputs);
|
let statements = MockMainPod::layout_statements(params, &inputs);
|
||||||
|
|
@ -151,6 +152,9 @@ impl Pod for MainPod {
|
||||||
fn into_any(self: Box<Self>) -> Box<dyn Any> {
|
fn into_any(self: Box<Self>) -> Box<dyn Any> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
fn serialized_proof(&self) -> String {
|
fn serialized_proof(&self) -> String {
|
||||||
todo!()
|
todo!()
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ use std::{any::Any, fmt};
|
||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use base64::prelude::*;
|
use base64::prelude::*;
|
||||||
use itertools::Itertools;
|
|
||||||
use plonky2::{hash::poseidon::PoseidonHash, plonk::config::Hasher};
|
use plonky2::{hash::poseidon::PoseidonHash, plonk::config::Hasher};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|
@ -92,7 +91,7 @@ fn fmt_statement_index(
|
||||||
op: Option<&Operation>,
|
op: Option<&Operation>,
|
||||||
index: usize,
|
index: usize,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
if !(!f.alternate() && st.is_none()) {
|
if f.alternate() || !st.is_none() {
|
||||||
write!(f, " {:03}. ", index)?;
|
write!(f, " {:03}. ", index)?;
|
||||||
if f.alternate() {
|
if f.alternate() {
|
||||||
write!(f, "{:#}", &st)?;
|
write!(f, "{:#}", &st)?;
|
||||||
|
|
@ -127,9 +126,6 @@ pub fn fill_pad<T: Clone>(v: &mut Vec<T>, pad_value: T, len: usize) {
|
||||||
/// - private Statements
|
/// - private Statements
|
||||||
/// - public Statements
|
/// - public Statements
|
||||||
impl MockMainPod {
|
impl MockMainPod {
|
||||||
fn offset_input_signed_pods(&self) -> usize {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
fn offset_input_main_pods(&self) -> usize {
|
fn offset_input_main_pods(&self) -> usize {
|
||||||
self.params.max_input_signed_pods * self.params.max_signed_pod_values
|
self.params.max_input_signed_pods * self.params.max_signed_pod_values
|
||||||
}
|
}
|
||||||
|
|
@ -143,9 +139,6 @@ impl MockMainPod {
|
||||||
fn pad_statement(params: &Params, s: &mut Statement) {
|
fn pad_statement(params: &Params, s: &mut Statement) {
|
||||||
fill_pad(&mut s.1, StatementArg::None, params.max_statement_args)
|
fill_pad(&mut s.1, StatementArg::None, params.max_statement_args)
|
||||||
}
|
}
|
||||||
fn pad_operation(params: &Params, op: &mut Operation) {
|
|
||||||
fill_pad(&mut op.1, OperationArg::None, params.max_operation_args)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the statements from the given MainPodInputs, padding to the
|
/// Returns the statements from the given MainPodInputs, padding to the
|
||||||
/// respective max lengths defined at the given Params.
|
/// respective max lengths defined at the given Params.
|
||||||
|
|
@ -153,10 +146,11 @@ impl MockMainPod {
|
||||||
let mut statements = Vec::new();
|
let mut statements = Vec::new();
|
||||||
|
|
||||||
// Input signed pods region
|
// Input signed pods region
|
||||||
let none_sig_pod: Box<dyn Pod> = Box::new(NonePod {});
|
let none_sig_pod_box: Box<dyn Pod> = Box::new(NonePod {});
|
||||||
|
let none_sig_pod = none_sig_pod_box.as_ref();
|
||||||
assert!(inputs.signed_pods.len() <= params.max_input_signed_pods);
|
assert!(inputs.signed_pods.len() <= params.max_input_signed_pods);
|
||||||
for i in 0..params.max_input_signed_pods {
|
for i in 0..params.max_input_signed_pods {
|
||||||
let pod = inputs.signed_pods.get(i).copied().unwrap_or(&none_sig_pod);
|
let pod = inputs.signed_pods.get(i).unwrap_or(&none_sig_pod);
|
||||||
let sts = pod.pub_statements();
|
let sts = pod.pub_statements();
|
||||||
assert!(sts.len() <= params.max_signed_pod_values);
|
assert!(sts.len() <= params.max_signed_pod_values);
|
||||||
for j in 0..params.max_signed_pod_values {
|
for j in 0..params.max_signed_pod_values {
|
||||||
|
|
@ -171,10 +165,11 @@ impl MockMainPod {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input main pods region
|
// Input main pods region
|
||||||
let none_main_pod: Box<dyn Pod> = Box::new(NonePod {});
|
let none_main_pod_box: Box<dyn Pod> = Box::new(NonePod {});
|
||||||
|
let none_main_pod = none_main_pod_box.as_ref();
|
||||||
assert!(inputs.main_pods.len() <= params.max_input_main_pods);
|
assert!(inputs.main_pods.len() <= params.max_input_main_pods);
|
||||||
for i in 0..params.max_input_main_pods {
|
for i in 0..params.max_input_main_pods {
|
||||||
let pod = inputs.main_pods.get(i).copied().unwrap_or(&none_main_pod);
|
let pod = inputs.main_pods.get(i).copied().unwrap_or(none_main_pod);
|
||||||
let sts = pod.pub_statements();
|
let sts = pod.pub_statements();
|
||||||
assert!(sts.len() <= params.max_public_statements);
|
assert!(sts.len() <= params.max_public_statements);
|
||||||
for j in 0..params.max_public_statements {
|
for j in 0..params.max_public_statements {
|
||||||
|
|
@ -256,11 +251,11 @@ impl MockMainPod {
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>>>()?;
|
.collect::<Result<Vec<_>>>()?;
|
||||||
if merkle_proofs.len() > params.max_merkle_proofs {
|
if merkle_proofs.len() > params.max_merkle_proofs {
|
||||||
return Err(anyhow!(
|
Err(anyhow!(
|
||||||
"The number of required Merkle proofs ({}) exceeds the maximum number ({}).",
|
"The number of required Merkle proofs ({}) exceeds the maximum number ({}).",
|
||||||
merkle_proofs.len(),
|
merkle_proofs.len(),
|
||||||
params.max_merkle_proofs
|
params.max_merkle_proofs
|
||||||
));
|
))
|
||||||
} else {
|
} else {
|
||||||
fill_pad(
|
fill_pad(
|
||||||
&mut merkle_proofs,
|
&mut merkle_proofs,
|
||||||
|
|
@ -388,7 +383,7 @@ impl MockMainPod {
|
||||||
// value=PodType::MockMainPod`
|
// value=PodType::MockMainPod`
|
||||||
let statements = Self::layout_statements(params, &inputs);
|
let statements = Self::layout_statements(params, &inputs);
|
||||||
// Extract Merkle proofs and pad.
|
// Extract Merkle proofs and pad.
|
||||||
let merkle_proofs = Self::extract_merkle_proofs(params, &inputs.operations)?;
|
let merkle_proofs = Self::extract_merkle_proofs(params, inputs.operations)?;
|
||||||
|
|
||||||
let operations = Self::process_private_statements_operations(
|
let operations = Self::process_private_statements_operations(
|
||||||
params,
|
params,
|
||||||
|
|
@ -399,22 +394,6 @@ impl MockMainPod {
|
||||||
let operations =
|
let operations =
|
||||||
Self::process_public_statements_operations(params, &statements, operations)?;
|
Self::process_public_statements_operations(params, &statements, operations)?;
|
||||||
|
|
||||||
let input_signed_pods = inputs
|
|
||||||
.signed_pods
|
|
||||||
.iter()
|
|
||||||
.map(|p| (*p).clone())
|
|
||||||
.collect_vec();
|
|
||||||
let input_main_pods = inputs.main_pods.iter().map(|p| (*p).clone()).collect_vec();
|
|
||||||
let input_statements = inputs
|
|
||||||
.statements
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.map(|s| {
|
|
||||||
let mut s = s.into();
|
|
||||||
Self::pad_statement(params, &mut s);
|
|
||||||
s
|
|
||||||
})
|
|
||||||
.collect_vec();
|
|
||||||
let public_statements =
|
let public_statements =
|
||||||
statements[statements.len() - params.max_public_statements..].to_vec();
|
statements[statements.len() - params.max_public_statements..].to_vec();
|
||||||
|
|
||||||
|
|
@ -434,26 +413,6 @@ impl MockMainPod {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn statement_none(params: &Params) -> Statement {
|
|
||||||
let mut args = Vec::with_capacity(params.max_statement_args);
|
|
||||||
Self::pad_statement_args(params, &mut args);
|
|
||||||
Statement(Predicate::Native(NativePredicate::None), args)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn operation_none(params: &Params) -> Operation {
|
|
||||||
let mut op = Operation(
|
|
||||||
OperationType::Native(NativeOperation::None),
|
|
||||||
vec![],
|
|
||||||
OperationAux::None,
|
|
||||||
);
|
|
||||||
fill_pad(&mut op.1, OperationArg::None, params.max_operation_args);
|
|
||||||
op
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pad_statement_args(params: &Params, args: &mut Vec<StatementArg>) {
|
|
||||||
fill_pad(args, StatementArg::None, params.max_statement_args)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pad_operation_args(params: &Params, args: &mut Vec<OperationArg>) {
|
fn pad_operation_args(params: &Params, args: &mut Vec<OperationArg>) {
|
||||||
fill_pad(args, OperationArg::None, params.max_operation_args)
|
fill_pad(args, OperationArg::None, params.max_operation_args)
|
||||||
}
|
}
|
||||||
|
|
@ -487,10 +446,7 @@ impl Pod for MockMainPod {
|
||||||
let ids_match = self.id == PodId(hash_statements(&self.public_statements, &self.params));
|
let ids_match = self.id == PodId(hash_statements(&self.public_statements, &self.params));
|
||||||
// find a ValueOf statement from the public statements with key=KEY_TYPE and check that the
|
// find a ValueOf statement from the public statements with key=KEY_TYPE and check that the
|
||||||
// value is PodType::MockMainPod
|
// value is PodType::MockMainPod
|
||||||
let has_type_statement = self
|
let has_type_statement = self.public_statements.iter().any(|s| {
|
||||||
.public_statements
|
|
||||||
.iter()
|
|
||||||
.find(|s| {
|
|
||||||
s.0 == Predicate::Native(NativePredicate::ValueOf)
|
s.0 == Predicate::Native(NativePredicate::ValueOf)
|
||||||
&& !s.1.is_empty()
|
&& !s.1.is_empty()
|
||||||
&& if let StatementArg::Key(AnchoredKey(pod_id, key_hash)) = s.1[0] {
|
&& if let StatementArg::Key(AnchoredKey(pod_id, key_hash)) = s.1[0] {
|
||||||
|
|
@ -498,8 +454,7 @@ impl Pod for MockMainPod {
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
.is_some();
|
|
||||||
// 3. check that all `input_statements` of type `ValueOf` with origin=SELF have unique keys
|
// 3. check that all `input_statements` of type `ValueOf` with origin=SELF have unique keys
|
||||||
// (no duplicates)
|
// (no duplicates)
|
||||||
// TODO: Instead of doing this, do a uniqueness check when verifying the output of a
|
// TODO: Instead of doing this, do a uniqueness check when verifying the output of a
|
||||||
|
|
@ -597,6 +552,9 @@ impl Pod for MockMainPod {
|
||||||
fn into_any(self: Box<Self>) -> Box<dyn Any> {
|
fn into_any(self: Box<Self>) -> Box<dyn Any> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
fn serialized_proof(&self) -> String {
|
fn serialized_proof(&self) -> String {
|
||||||
BASE64_STANDARD.encode(serde_json::to_string(self).unwrap())
|
BASE64_STANDARD.encode(serde_json::to_string(self).unwrap())
|
||||||
|
|
|
||||||
|
|
@ -94,8 +94,8 @@ impl MerkleClaimAndProof {
|
||||||
let (other_key, other_value) = mid_mp.other_leaf.unwrap_or((EMPTY_VALUE, EMPTY_VALUE));
|
let (other_key, other_value) = mid_mp.other_leaf.unwrap_or((EMPTY_VALUE, EMPTY_VALUE));
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
root: root.clone().into(),
|
root: (*root).into(),
|
||||||
key: key.clone(),
|
key: *key,
|
||||||
value: value.cloned().unwrap_or(EMPTY_VALUE),
|
value: value.cloned().unwrap_or(EMPTY_VALUE),
|
||||||
existence: mid_mp.existence,
|
existence: mid_mp.existence,
|
||||||
siblings: mid_mp
|
siblings: mid_mp
|
||||||
|
|
@ -197,7 +197,7 @@ impl fmt::Display for Operation {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{:?} ", self.0)?;
|
write!(f, "{:?} ", self.0)?;
|
||||||
for (i, arg) in self.1.iter().enumerate() {
|
for (i, arg) in self.1.iter().enumerate() {
|
||||||
if !(!f.alternate() && arg.is_none()) {
|
if f.alternate() || !arg.is_none() {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
write!(f, " ")?;
|
write!(f, " ")?;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ impl fmt::Display for Statement {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{:?} ", self.0)?;
|
write!(f, "{:?} ", self.0)?;
|
||||||
for (i, arg) in self.1.iter().enumerate() {
|
for (i, arg) in self.1.iter().enumerate() {
|
||||||
if !(!f.alternate() && arg.is_none()) {
|
if f.alternate() || !arg.is_none() {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
write!(f, " ")?;
|
write!(f, " ")?;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,9 @@ impl Pod for MockSignedPod {
|
||||||
fn into_any(self: Box<Self>) -> Box<dyn Any> {
|
fn into_any(self: Box<Self>) -> Box<dyn Any> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
fn serialized_proof(&self) -> String {
|
fn serialized_proof(&self) -> String {
|
||||||
self.signature.to_string()
|
self.signature.to_string()
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,7 @@ use plonky2::field::types::Field;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub use super::merkletree_circuit::*;
|
pub use super::merkletree_circuit::*;
|
||||||
use crate::backends::{
|
use crate::backends::plonky2::basetypes::{hash_fields, Hash, Value, EMPTY_HASH, F};
|
||||||
counter,
|
|
||||||
plonky2::basetypes::{hash_fields, Hash, Value, EMPTY_HASH, F},
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Implements the MerkleTree specified at
|
/// Implements the MerkleTree specified at
|
||||||
/// https://0xparc.github.io/pod2/merkletree.html
|
/// https://0xparc.github.io/pod2/merkletree.html
|
||||||
|
|
@ -30,7 +27,7 @@ impl MerkleTree {
|
||||||
.collect::<Result<_>>()?;
|
.collect::<Result<_>>()?;
|
||||||
|
|
||||||
// Start with a leaf or conclude with an empty node as root.
|
// Start with a leaf or conclude with an empty node as root.
|
||||||
let mut root = leaves.pop().map(|l| Node::Leaf(l)).unwrap_or(Node::None);
|
let mut root = leaves.pop().map(Node::Leaf).unwrap_or(Node::None);
|
||||||
|
|
||||||
// Iterate over remaining leaves (if any) and add them.
|
// Iterate over remaining leaves (if any) and add them.
|
||||||
for leaf in leaves.into_iter() {
|
for leaf in leaves.into_iter() {
|
||||||
|
|
@ -81,8 +78,6 @@ impl MerkleTree {
|
||||||
/// the tree. It returns the `value` of the leaf at the given `key`, and the
|
/// the tree. It returns the `value` of the leaf at the given `key`, and the
|
||||||
/// `MerkleProof`.
|
/// `MerkleProof`.
|
||||||
pub fn prove(&self, key: &Value) -> Result<(Value, MerkleProof)> {
|
pub fn prove(&self, key: &Value) -> Result<(Value, MerkleProof)> {
|
||||||
counter::count_tree_proof_gen();
|
|
||||||
|
|
||||||
let path = keypath(self.max_depth, *key)?;
|
let path = keypath(self.max_depth, *key)?;
|
||||||
|
|
||||||
let mut siblings: Vec<Hash> = Vec::new();
|
let mut siblings: Vec<Hash> = Vec::new();
|
||||||
|
|
@ -108,8 +103,6 @@ impl MerkleTree {
|
||||||
/// the key-value pair in the leaf reached as a result of
|
/// the key-value pair in the leaf reached as a result of
|
||||||
/// resolving `key` as well as a `MerkleProof`.
|
/// resolving `key` as well as a `MerkleProof`.
|
||||||
pub fn prove_nonexistence(&self, key: &Value) -> Result<MerkleProof> {
|
pub fn prove_nonexistence(&self, key: &Value) -> Result<MerkleProof> {
|
||||||
counter::count_tree_proof_gen();
|
|
||||||
|
|
||||||
let path = keypath(self.max_depth, *key)?;
|
let path = keypath(self.max_depth, *key)?;
|
||||||
|
|
||||||
let mut siblings: Vec<Hash> = Vec::new();
|
let mut siblings: Vec<Hash> = Vec::new();
|
||||||
|
|
@ -373,8 +366,6 @@ impl Node {
|
||||||
|
|
||||||
// adds the leaf at the tree from the current node (self), without computing any hash
|
// adds the leaf at the tree from the current node (self), without computing any hash
|
||||||
pub(crate) fn add_leaf(&mut self, lvl: usize, max_depth: usize, leaf: Leaf) -> Result<()> {
|
pub(crate) fn add_leaf(&mut self, lvl: usize, max_depth: usize, leaf: Leaf) -> Result<()> {
|
||||||
counter::count_tree_insert();
|
|
||||||
|
|
||||||
if lvl >= max_depth {
|
if lvl >= max_depth {
|
||||||
return Err(anyhow!("max depth reached"));
|
return Err(anyhow!("max depth reached"));
|
||||||
}
|
}
|
||||||
|
|
@ -610,11 +601,8 @@ pub mod tests {
|
||||||
let (v, proof) = tree.prove(&Value::from(13))?;
|
let (v, proof) = tree.prove(&Value::from(13))?;
|
||||||
assert_eq!(v, Value::from(1013));
|
assert_eq!(v, Value::from(1013));
|
||||||
println!("{}", proof);
|
println!("{}", proof);
|
||||||
println!("after proof generation, {}", counter::counter_get());
|
|
||||||
|
|
||||||
counter::counter_reset();
|
|
||||||
MerkleTree::verify(32, tree.root(), &proof, &key, &value)?;
|
MerkleTree::verify(32, tree.root(), &proof, &key, &value)?;
|
||||||
println!("after verify, {}", counter::counter_get());
|
|
||||||
|
|
||||||
// Exclusion checks
|
// Exclusion checks
|
||||||
let key = Value::from(12);
|
let key = Value::from(12);
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,7 @@ impl MerkleProofGadget {
|
||||||
|
|
||||||
impl MerkleClaimAndProofTarget {
|
impl MerkleClaimAndProofTarget {
|
||||||
/// assigns the given values to the targets
|
/// assigns the given values to the targets
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn set_targets(
|
pub fn set_targets(
|
||||||
&self,
|
&self,
|
||||||
pw: &mut PartialWitness<F>,
|
pw: &mut PartialWitness<F>,
|
||||||
|
|
@ -293,9 +294,9 @@ impl MerkleProofExistenceTarget {
|
||||||
fn compute_root_from_leaf(
|
fn compute_root_from_leaf(
|
||||||
max_depth: usize,
|
max_depth: usize,
|
||||||
builder: &mut CircuitBuilder<F, D>,
|
builder: &mut CircuitBuilder<F, D>,
|
||||||
path: &Vec<BoolTarget>,
|
path: &[BoolTarget],
|
||||||
leaf_hash: &HashOutTarget,
|
leaf_hash: &HashOutTarget,
|
||||||
siblings: &Vec<HashOutTarget>,
|
siblings: &[HashOutTarget],
|
||||||
) -> Result<HashOutTarget> {
|
) -> Result<HashOutTarget> {
|
||||||
assert_eq!(siblings.len(), max_depth);
|
assert_eq!(siblings.len(), max_depth);
|
||||||
// Convenience constants
|
// Convenience constants
|
||||||
|
|
@ -322,7 +323,7 @@ fn compute_root_from_leaf(
|
||||||
.rev()
|
.rev()
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let mut h = leaf_hash.clone();
|
let mut h = *leaf_hash;
|
||||||
for (i, (sibling, selector)) in std::iter::zip(siblings, &sibling_selectors)
|
for (i, (sibling, selector)) in std::iter::zip(siblings, &sibling_selectors)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.rev()
|
.rev()
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ pub struct Signature(pub(crate) Proof);
|
||||||
|
|
||||||
/// Implements the key generation and the computation of proof-based signatures.
|
/// Implements the key generation and the computation of proof-based signatures.
|
||||||
impl SecretKey {
|
impl SecretKey {
|
||||||
pub fn new() -> Self {
|
pub fn new_rand() -> Self {
|
||||||
// note: the `F::rand()` internally uses `rand::rngs::OsRng`
|
// note: the `F::rand()` internally uses `rand::rngs::OsRng`
|
||||||
Self(Value(std::array::from_fn(|_| F::rand())))
|
Self(Value(std::array::from_fn(|_| F::rand())))
|
||||||
}
|
}
|
||||||
|
|
@ -189,9 +189,9 @@ impl SignatureInternalCircuit {
|
||||||
msg: Value,
|
msg: Value,
|
||||||
s: Value,
|
s: Value,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
pw.set_target_arr(&self.sk_targ, &sk.0 .0.to_vec())?;
|
pw.set_target_arr(&self.sk_targ, sk.0 .0.as_ref())?;
|
||||||
pw.set_hash_target(self.pk_targ, HashOut::<F>::from_vec(pk.0 .0.to_vec()))?;
|
pw.set_hash_target(self.pk_targ, HashOut::<F>::from_vec(pk.0 .0.to_vec()))?;
|
||||||
pw.set_target_arr(&self.msg_targ, &msg.0.to_vec())?;
|
pw.set_target_arr(&self.msg_targ, msg.0.as_ref())?;
|
||||||
pw.set_hash_target(self.s_targ, HashOut::<F>::from_vec(s.0.to_vec()))?;
|
pw.set_hash_target(self.s_targ, HashOut::<F>::from_vec(s.0.to_vec()))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -205,7 +205,7 @@ pub mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_signature() -> Result<()> {
|
fn test_signature() -> Result<()> {
|
||||||
let sk = SecretKey::new();
|
let sk = SecretKey::new_rand();
|
||||||
let pk = sk.public_key();
|
let pk = sk.public_key();
|
||||||
|
|
||||||
let msg = Value::from(42);
|
let msg = Value::from(42);
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,7 @@ pub mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_signature_gadget() -> Result<()> {
|
fn test_signature_gadget() -> Result<()> {
|
||||||
// generate a valid signature
|
// generate a valid signature
|
||||||
let sk = SecretKey::new();
|
let sk = SecretKey::new_rand();
|
||||||
let pk = sk.public_key();
|
let pk = sk.public_key();
|
||||||
let msg = Value::from(42);
|
let msg = Value::from(42);
|
||||||
let sig = sk.sign(msg)?;
|
let sig = sk.sign(msg)?;
|
||||||
|
|
@ -206,7 +206,7 @@ pub mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_signature_gadget_disabled() -> Result<()> {
|
fn test_signature_gadget_disabled() -> Result<()> {
|
||||||
// generate a valid signature
|
// generate a valid signature
|
||||||
let sk = SecretKey::new();
|
let sk = SecretKey::new_rand();
|
||||||
let pk = sk.public_key();
|
let pk = sk.public_key();
|
||||||
let msg = Value::from(42);
|
let msg = Value::from(42);
|
||||||
let sig = sk.sign(msg)?;
|
let sig = sk.sign(msg)?;
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,9 @@ impl Pod for SignedPod {
|
||||||
fn into_any(self: Box<Self>) -> Box<dyn Any> {
|
fn into_any(self: Box<Self>) -> Box<dyn Any> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
fn serialized_proof(&self) -> String {
|
fn serialized_proof(&self) -> String {
|
||||||
let mut buffer = Vec::new();
|
let mut buffer = Vec::new();
|
||||||
|
|
@ -134,7 +137,7 @@ pub mod tests {
|
||||||
pod.insert("socialSecurityNumber", "G2121210");
|
pod.insert("socialSecurityNumber", "G2121210");
|
||||||
|
|
||||||
// TODO: Use a deterministic secret key to get deterministic tests
|
// TODO: Use a deterministic secret key to get deterministic tests
|
||||||
let sk = SecretKey::new();
|
let sk = SecretKey::new_rand();
|
||||||
let mut signer = Signer(sk);
|
let mut signer = Signer(sk);
|
||||||
let pod = pod.sign(&mut signer).unwrap();
|
let pod = pod.sign(&mut signer).unwrap();
|
||||||
let pod = pod.pod.into_any().downcast::<SignedPod>().unwrap();
|
let pod = pod.pod.into_any().downcast::<SignedPod>().unwrap();
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,8 @@ pub struct Set(Vec<Value>, #[serde(skip)] MiddlewareSet);
|
||||||
|
|
||||||
impl Set {
|
impl Set {
|
||||||
pub fn new(values: Vec<Value>) -> Result<Self> {
|
pub fn new(values: Vec<Value>) -> Result<Self> {
|
||||||
let set = MiddlewareSet::new(
|
let set =
|
||||||
&values
|
MiddlewareSet::new(&values.iter().map(MiddlewareValue::from).collect::<Vec<_>>())?;
|
||||||
.iter()
|
|
||||||
.map(|v| MiddlewareValue::from(v))
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
)?;
|
|
||||||
Ok(Self(values, set))
|
Ok(Self(values, set))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,12 +87,8 @@ pub struct Array(Vec<Value>, #[serde(skip)] MiddlewareArray);
|
||||||
|
|
||||||
impl Array {
|
impl Array {
|
||||||
pub fn new(values: Vec<Value>) -> Result<Self> {
|
pub fn new(values: Vec<Value>) -> Result<Self> {
|
||||||
let array = MiddlewareArray::new(
|
let array =
|
||||||
&values
|
MiddlewareArray::new(&values.iter().map(MiddlewareValue::from).collect::<Vec<_>>())?;
|
||||||
.iter()
|
|
||||||
.map(|v| MiddlewareValue::from(v))
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
)?;
|
|
||||||
Ok(Self(values, array))
|
Ok(Self(values, array))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -252,10 +252,9 @@ impl From<CustomPredicateBatch> for middleware::CustomPredicateBatch {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||||
|
/// NOTE: fields are not public (outside of crate) to enforce the struct instantiation through
|
||||||
|
/// the `::and/or` methods, which performs checks on the values.
|
||||||
pub struct CustomPredicate {
|
pub struct CustomPredicate {
|
||||||
/// NOTE: fields are not public (outside of crate) to enforce the struct instantiation through
|
|
||||||
/// the `::and/or` methods, which performs checks on the values.
|
|
||||||
|
|
||||||
/// true for "and", false for "or"
|
/// true for "and", false for "or"
|
||||||
pub(crate) conjunction: bool,
|
pub(crate) conjunction: bool,
|
||||||
pub(crate) statements: Vec<StatementTmpl>,
|
pub(crate) statements: Vec<StatementTmpl>,
|
||||||
|
|
@ -550,7 +549,7 @@ fn resolve_wildcard(args: &[&str], priv_args: &[&str], v: &KeyOrWildcardStr) ->
|
||||||
args.iter()
|
args.iter()
|
||||||
.chain(priv_args.iter())
|
.chain(priv_args.iter())
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find_map(|(i, name)| (&s == name).then_some(IndexedWildcard::new(s.clone(), i)))
|
.find_map(|(i, name)| (s == name).then_some(IndexedWildcard::new(s.clone(), i)))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -425,12 +425,9 @@ impl MainPodBuilder {
|
||||||
use NativeOperation::*;
|
use NativeOperation::*;
|
||||||
let Operation(op_type, ref mut args, _) = &mut op;
|
let Operation(op_type, ref mut args, _) = &mut op;
|
||||||
// TODO: argument type checking
|
// TODO: argument type checking
|
||||||
let pred = op_type
|
let pred = op_type.output_predicate().map(Ok).unwrap_or_else(|| {
|
||||||
.output_predicate()
|
|
||||||
.map(|p| Ok(p))
|
|
||||||
.unwrap_or_else(|| {
|
|
||||||
// We are dealing with a copy here.
|
// We are dealing with a copy here.
|
||||||
match (&args).get(0) {
|
match (args).first() {
|
||||||
Some(OperationArg::Statement(s)) if args.len() == 1 => Ok(s.predicate.clone()),
|
Some(OperationArg::Statement(s)) if args.len() == 1 => Ok(s.predicate.clone()),
|
||||||
_ => Err(anyhow!("Invalid arguments to copy operation: {:?}", args)),
|
_ => Err(anyhow!("Invalid arguments to copy operation: {:?}", args)),
|
||||||
}
|
}
|
||||||
|
|
@ -644,7 +641,6 @@ impl MainPodBuilder {
|
||||||
};
|
};
|
||||||
st_args
|
st_args
|
||||||
}
|
}
|
||||||
RenameContainedBy => todo!(),
|
|
||||||
_ => {
|
_ => {
|
||||||
return Err(anyhow!("Invalid arguments to operation"));
|
return Err(anyhow!("Invalid arguments to operation"));
|
||||||
}
|
}
|
||||||
|
|
@ -680,7 +676,7 @@ impl MainPodBuilder {
|
||||||
.map(|chunk| {
|
.map(|chunk| {
|
||||||
Ok(StatementArg::Key(AnchoredKey::new(
|
Ok(StatementArg::Key(AnchoredKey::new(
|
||||||
Origin::new(PodId(match chunk[0] {
|
Origin::new(PodId(match chunk[0] {
|
||||||
Value::Raw(v) => v.try_into()?,
|
Value::Raw(v) => v.into(),
|
||||||
_ => return Err(anyhow!("Invalid POD class value.")),
|
_ => return Err(anyhow!("Invalid POD class value.")),
|
||||||
})),
|
})),
|
||||||
self.key_table
|
self.key_table
|
||||||
|
|
@ -752,8 +748,16 @@ impl MainPodBuilder {
|
||||||
|
|
||||||
let (statements, operations, public_statements) = compiler.compile(inputs, params)?;
|
let (statements, operations, public_statements) = compiler.compile(inputs, params)?;
|
||||||
let inputs = MainPodInputs {
|
let inputs = MainPodInputs {
|
||||||
signed_pods: &self.input_signed_pods.iter().map(|p| &p.pod).collect_vec(),
|
signed_pods: &self
|
||||||
main_pods: &self.input_main_pods.iter().map(|p| &p.pod).collect_vec(),
|
.input_signed_pods
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.pod.as_ref())
|
||||||
|
.collect_vec(),
|
||||||
|
main_pods: &self
|
||||||
|
.input_main_pods
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.pod.as_ref())
|
||||||
|
.collect_vec(),
|
||||||
statements: &statements,
|
statements: &statements,
|
||||||
operations: &operations,
|
operations: &operations,
|
||||||
public_statements: &public_statements,
|
public_statements: &public_statements,
|
||||||
|
|
@ -948,15 +952,14 @@ impl MainPodCompiler {
|
||||||
(Some(StatementArg::Key(ak1)), Some(StatementArg::Key(ak2))) => (ak1, ak2),
|
(Some(StatementArg::Key(ak1)), Some(StatementArg::Key(ak2))) => (ak1, ak2),
|
||||||
_ => Err(anyhow!("Ill-formed statement: {}", st))?,
|
_ => Err(anyhow!("Ill-formed statement: {}", st))?,
|
||||||
};
|
};
|
||||||
let middle_st =
|
let middle_st = middleware::Statement::Contains(ak1.into(), ak2.into(), empty_ak);
|
||||||
middleware::Statement::Contains(ak1.into(), ak2.into(), empty_ak.clone());
|
|
||||||
let middle_op = middleware::Operation::ContainsFromEntries(
|
let middle_op = middleware::Operation::ContainsFromEntries(
|
||||||
match &op.1[0] {
|
match &op.1[0] {
|
||||||
OperationArg::Statement(s) => self.compile_st(&s)?,
|
OperationArg::Statement(s) => self.compile_st(s)?,
|
||||||
_ => Err(anyhow!("Statement compile failed in manual compile"))?,
|
_ => Err(anyhow!("Statement compile failed in manual compile"))?,
|
||||||
},
|
},
|
||||||
match &op.1[1] {
|
match &op.1[1] {
|
||||||
OperationArg::Statement(s) => self.compile_st(&s)?,
|
OperationArg::Statement(s) => self.compile_st(s)?,
|
||||||
_ => Err(anyhow!("Statement compile failed in manual compile"))?,
|
_ => Err(anyhow!("Statement compile failed in manual compile"))?,
|
||||||
},
|
},
|
||||||
empty_st,
|
empty_st,
|
||||||
|
|
@ -1000,7 +1003,6 @@ impl MainPodCompiler {
|
||||||
Err(StatementConversionError::MCR(_)) => {
|
Err(StatementConversionError::MCR(_)) => {
|
||||||
let empty_st = self
|
let empty_st = self
|
||||||
.get_literal(EMPTY_VALUE)
|
.get_literal(EMPTY_VALUE)
|
||||||
.clone()
|
|
||||||
.ok_or(anyhow!("Literal value not found for empty literal."))?;
|
.ok_or(anyhow!("Literal value not found for empty literal."))?;
|
||||||
let empty_ak = match empty_st {
|
let empty_ak = match empty_st {
|
||||||
middleware::Statement::ValueOf(ak, _) => ak,
|
middleware::Statement::ValueOf(ak, _) => ak,
|
||||||
|
|
@ -1010,8 +1012,7 @@ impl MainPodCompiler {
|
||||||
(Some(StatementArg::Key(ak1)), Some(StatementArg::Key(ak2))) => (ak1, ak2),
|
(Some(StatementArg::Key(ak1)), Some(StatementArg::Key(ak2))) => (ak1, ak2),
|
||||||
_ => Err(anyhow!("Ill-formed statement: {}", st))?,
|
_ => Err(anyhow!("Ill-formed statement: {}", st))?,
|
||||||
};
|
};
|
||||||
let middle_st =
|
let middle_st = middleware::Statement::Contains(ak1.into(), ak2.into(), *empty_ak);
|
||||||
middleware::Statement::Contains(ak1.into(), ak2.into(), empty_ak.clone());
|
|
||||||
Ok(middle_st)
|
Ok(middle_st)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1023,9 +1024,9 @@ impl MainPodCompiler {
|
||||||
// TODO: Take Merkle proof into account.
|
// TODO: Take Merkle proof into account.
|
||||||
let mop_args =
|
let mop_args =
|
||||||
op.1.iter()
|
op.1.iter()
|
||||||
.flat_map(|arg| self.compile_op_arg(arg).map(|s| Ok(s.try_into()?)))
|
.flat_map(|arg| self.compile_op_arg(arg))
|
||||||
.collect::<Result<Vec<middleware::Statement>>>()?;
|
.collect_vec();
|
||||||
middleware::Operation::op(mop_code.into(), &mop_args, &op.2)
|
middleware::Operation::op(mop_code, &mop_args, &op.2)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_st_op(&mut self, st: &Statement, op: &Operation, params: &Params) -> Result<()> {
|
fn compile_st_op(&mut self, st: &Statement, op: &Operation, params: &Params) -> Result<()> {
|
||||||
|
|
@ -1095,55 +1096,55 @@ pub mod build_utils {
|
||||||
macro_rules! op {
|
macro_rules! op {
|
||||||
(new_entry, ($key:expr, $value:expr)) => { $crate::frontend::Operation(
|
(new_entry, ($key:expr, $value:expr)) => { $crate::frontend::Operation(
|
||||||
$crate::frontend::OperationType::Native($crate::frontend::NativeOperation::NewEntry),
|
$crate::frontend::OperationType::Native($crate::frontend::NativeOperation::NewEntry),
|
||||||
$crate::op_args!(($key, $value)), crate::middleware::OperationAux::None) };
|
$crate::op_args!(($key, $value)), $crate::middleware::OperationAux::None) };
|
||||||
(eq, $($arg:expr),+) => { $crate::frontend::Operation(
|
(eq, $($arg:expr),+) => { $crate::frontend::Operation(
|
||||||
$crate::frontend::OperationType::Native($crate::frontend::NativeOperation::EqualFromEntries),
|
$crate::frontend::OperationType::Native($crate::frontend::NativeOperation::EqualFromEntries),
|
||||||
$crate::op_args!($($arg),*), crate::middleware::OperationAux::None) };
|
$crate::op_args!($($arg),*), $crate::middleware::OperationAux::None) };
|
||||||
(ne, $($arg:expr),+) => { $crate::frontend::Operation(
|
(ne, $($arg:expr),+) => { $crate::frontend::Operation(
|
||||||
$crate::frontend::OperationType::Native($crate::frontend::NativeOperation::NotEqualFromEntries),
|
$crate::frontend::OperationType::Native($crate::frontend::NativeOperation::NotEqualFromEntries),
|
||||||
$crate::op_args!($($arg),*), crate::middleware::OperationAux::None) };
|
$crate::op_args!($($arg),*), $crate::middleware::OperationAux::None) };
|
||||||
(gt, $($arg:expr),+) => { crate::frontend::Operation(
|
(gt, $($arg:expr),+) => { $crate::frontend::Operation(
|
||||||
crate::frontend::OperationType::Native(crate::frontend::NativeOperation::GtFromEntries),
|
$crate::frontend::OperationType::Native($crate::frontend::NativeOperation::GtFromEntries),
|
||||||
crate::op_args!($($arg),*), crate::middleware::OperationAux::None) };
|
$crate::op_args!($($arg),*), $crate::middleware::OperationAux::None) };
|
||||||
(lt, $($arg:expr),+) => { crate::frontend::Operation(
|
(lt, $($arg:expr),+) => { $crate::frontend::Operation(
|
||||||
crate::frontend::OperationType::Native(crate::frontend::NativeOperation::LtFromEntries),
|
$crate::frontend::OperationType::Native($crate::frontend::NativeOperation::LtFromEntries),
|
||||||
crate::op_args!($($arg),*), crate::middleware::OperationAux::None) };
|
$crate::op_args!($($arg),*), $crate::middleware::OperationAux::None) };
|
||||||
(transitive_eq, $($arg:expr),+) => { crate::frontend::Operation(
|
(transitive_eq, $($arg:expr),+) => { $crate::frontend::Operation(
|
||||||
crate::frontend::OperationType::Native(crate::frontend::NativeOperation::TransitiveEqualFromStatements),
|
$crate::frontend::OperationType::Native($crate::frontend::NativeOperation::TransitiveEqualFromStatements),
|
||||||
crate::op_args!($($arg),*), crate::middleware::OperationAux::None) };
|
$crate::op_args!($($arg),*), $crate::middleware::OperationAux::None) };
|
||||||
(gt_to_ne, $($arg:expr),+) => { crate::frontend::Operation(
|
(gt_to_ne, $($arg:expr),+) => { $crate::frontend::Operation(
|
||||||
crate::frontend::OperationType::Native(crate::frontend::NativeOperation::GtToNotEqual),
|
$crate::frontend::OperationType::Native($crate::frontend::NativeOperation::GtToNotEqual),
|
||||||
crate::op_args!($($arg),*), crate::middleware::OperationAux::None) };
|
$crate::op_args!($($arg),*), $crate::middleware::OperationAux::None) };
|
||||||
(lt_to_ne, $($arg:expr),+) => { crate::frontend::Operation(
|
(lt_to_ne, $($arg:expr),+) => { $crate::frontend::Operation(
|
||||||
crate::frontend::OperationType::Native(crate::frontend::NativeOperation::LtToNotEqual),
|
$crate::frontend::OperationType::Native($crate::frontend::NativeOperation::LtToNotEqual),
|
||||||
crate::op_args!($($arg),*), crate::middleware::OperationAux::None) };
|
$crate::op_args!($($arg),*), $crate::middleware::OperationAux::None) };
|
||||||
(sum_of, $($arg:expr),+) => { crate::frontend::Operation(
|
(sum_of, $($arg:expr),+) => { $crate::frontend::Operation(
|
||||||
crate::frontend::OperationType::Native(crate::frontend::NativeOperation::SumOf),
|
$crate::frontend::OperationType::Native($crate::frontend::NativeOperation::SumOf),
|
||||||
crate::op_args!($($arg),*), crate::middleware::OperationAux::None) };
|
$crate::op_args!($($arg),*), $crate::middleware::OperationAux::None) };
|
||||||
(product_of, $($arg:expr),+) => { crate::frontend::Operation(
|
(product_of, $($arg:expr),+) => { $crate::frontend::Operation(
|
||||||
crate::frontend::OperationType::Native(crate::frontend::NativeOperation::ProductOf),
|
$crate::frontend::OperationType::Native($crate::frontend::NativeOperation::ProductOf),
|
||||||
crate::op_args!($($arg),*), crate::middleware::OperationAux::None) };
|
$crate::op_args!($($arg),*), $crate::middleware::OperationAux::None) };
|
||||||
(max_of, $($arg:expr),+) => { crate::frontend::Operation(
|
(max_of, $($arg:expr),+) => { $crate::frontend::Operation(
|
||||||
crate::frontend::OperationType::Native(crate::frontend::NativeOperation::MaxOf),
|
$crate::frontend::OperationType::Native($crate::frontend::NativeOperation::MaxOf),
|
||||||
crate::op_args!($($arg),*), crate::middleware::OperationAux::None) };
|
$crate::op_args!($($arg),*), $crate::middleware::OperationAux::None) };
|
||||||
(custom, $op:expr, $($arg:expr),+) => { $crate::frontend::Operation(
|
(custom, $op:expr, $($arg:expr),+) => { $crate::frontend::Operation(
|
||||||
$crate::frontend::OperationType::Custom($op),
|
$crate::frontend::OperationType::Custom($op),
|
||||||
$crate::op_args!($($arg),*), crate::middleware::OperationAux::None) };
|
$crate::op_args!($($arg),*), $crate::middleware::OperationAux::None) };
|
||||||
(dict_contains, $dict:expr, $key:expr, $value:expr, $aux:expr) => { crate::frontend::Operation(
|
(dict_contains, $dict:expr, $key:expr, $value:expr, $aux:expr) => { $crate::frontend::Operation(
|
||||||
crate::frontend::OperationType::Native(crate::frontend::NativeOperation::DictContainsFromEntries),
|
$crate::frontend::OperationType::Native($crate::frontend::NativeOperation::DictContainsFromEntries),
|
||||||
crate::op_args!($dict, $key, $value), crate::middleware::OperationAux::MerkleProof($aux)) };
|
$crate::op_args!($dict, $key, $value), $crate::middleware::OperationAux::MerkleProof($aux)) };
|
||||||
(dict_not_contains, $dict:expr, $key:expr, $aux:expr) => { crate::frontend::Operation(
|
(dict_not_contains, $dict:expr, $key:expr, $aux:expr) => { $crate::frontend::Operation(
|
||||||
crate::frontend::OperationType::Native(crate::frontend::NativeOperation::DictNotContainsFromEntries),
|
$crate::frontend::OperationType::Native($crate::frontend::NativeOperation::DictNotContainsFromEntries),
|
||||||
crate::op_args!($dict, $key), crate::middleware::OperationAux::MerkleProof($aux)) };
|
$crate::op_args!($dict, $key), $crate::middleware::OperationAux::MerkleProof($aux)) };
|
||||||
(set_contains, $set:expr, $value:expr, $aux:expr) => { crate::frontend::Operation(
|
(set_contains, $set:expr, $value:expr, $aux:expr) => { $crate::frontend::Operation(
|
||||||
crate::frontend::OperationType::Native(crate::frontend::NativeOperation::SetContainsFromEntries),
|
$crate::frontend::OperationType::Native($crate::frontend::NativeOperation::SetContainsFromEntries),
|
||||||
crate::op_args!($set, $value), crate::middleware::OperationAux::MerkleProof($aux)) };
|
$crate::op_args!($set, $value), $crate::middleware::OperationAux::MerkleProof($aux)) };
|
||||||
(set_not_contains, $set:expr, $value:expr, $aux:expr) => { crate::frontend::Operation(
|
(set_not_contains, $set:expr, $value:expr, $aux:expr) => { $crate::frontend::Operation(
|
||||||
crate::frontend::OperationType::Native(crate::frontend::NativeOperation::SetNotContainsFromEntries),
|
$crate::frontend::OperationType::Native($crate::frontend::NativeOperation::SetNotContainsFromEntries),
|
||||||
crate::op_args!($set, $value), crate::middleware::OperationAux::MerkleProof($aux)) };
|
$crate::op_args!($set, $value), $crate::middleware::OperationAux::MerkleProof($aux)) };
|
||||||
(array_contains, $array:expr, $value:expr, $aux:expr) => { crate::frontend::Operation(
|
(array_contains, $array:expr, $value:expr, $aux:expr) => { $crate::frontend::Operation(
|
||||||
crate::frontend::OperationType::Native(crate::frontend::NativeOperation::ArrayContainsFromEntries),
|
$crate::frontend::OperationType::Native($crate::frontend::NativeOperation::ArrayContainsFromEntries),
|
||||||
crate::op_args!($array, $value), crate::middleware::OperationAux::MerkleProof($aux)) };
|
$crate::op_args!($array, $value), $crate::middleware::OperationAux::MerkleProof($aux)) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ impl TryFrom<Statement> for middleware::Statement {
|
||||||
(NP::DictNotContains, (Some(SA::Key(ak1)), Some(SA::Key(ak2)), None)) => {
|
(NP::DictNotContains, (Some(SA::Key(ak1)), Some(SA::Key(ak2)), None)) => {
|
||||||
MS::NotContains(ak1.into(), ak2.into())
|
MS::NotContains(ak1.into(), ak2.into())
|
||||||
}
|
}
|
||||||
(NP::SetContains, (Some(SA::Key(ak1)), Some(SA::Key(ak2)), None)) => {
|
(NP::SetContains, (Some(SA::Key(_)), Some(SA::Key(_)), None)) => {
|
||||||
return Err(StatementConversionError::MCR(ManualConversionRequired()));
|
return Err(StatementConversionError::MCR(ManualConversionRequired()));
|
||||||
}
|
}
|
||||||
(NP::SetNotContains, (Some(SA::Key(ak1)), Some(SA::Key(ak2)), None)) => {
|
(NP::SetNotContains, (Some(SA::Key(ak1)), Some(SA::Key(ak2)), None)) => {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![allow(clippy::get_first)]
|
||||||
|
|
||||||
pub mod backends;
|
pub mod backends;
|
||||||
pub mod constants;
|
pub mod constants;
|
||||||
pub mod frontend;
|
pub mod frontend;
|
||||||
|
|
|
||||||
|
|
@ -201,10 +201,9 @@ impl ToFields for StatementTmpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||||
|
/// NOTE: fields are not public (outside of crate) to enforce the struct instantiation through
|
||||||
|
/// the `::and/or` methods, which performs checks on the values.
|
||||||
pub struct CustomPredicate {
|
pub struct CustomPredicate {
|
||||||
/// NOTE: fields are not public (outside of crate) to enforce the struct instantiation through
|
|
||||||
/// the `::and/or` methods, which performs checks on the values.
|
|
||||||
|
|
||||||
/// true for "and", false for "or"
|
/// true for "and", false for "or"
|
||||||
pub(crate) conjunction: bool,
|
pub(crate) conjunction: bool,
|
||||||
pub(crate) statements: Vec<StatementTmpl>,
|
pub(crate) statements: Vec<StatementTmpl>,
|
||||||
|
|
|
||||||
|
|
@ -197,6 +197,7 @@ pub trait Pod: fmt::Debug + DynClone {
|
||||||
}
|
}
|
||||||
// Used for downcasting
|
// Used for downcasting
|
||||||
fn into_any(self: Box<Self>) -> Box<dyn Any>;
|
fn into_any(self: Box<Self>) -> Box<dyn Any>;
|
||||||
|
fn as_any(&self) -> &dyn Any;
|
||||||
// Front-end Pods keep references to middleware Pods. Most of the
|
// Front-end Pods keep references to middleware Pods. Most of the
|
||||||
// middleware data can be derived directly from front-end data, but the
|
// middleware data can be derived directly from front-end data, but the
|
||||||
// "proof" data is only created at the point of proving/signing, and
|
// "proof" data is only created at the point of proving/signing, and
|
||||||
|
|
@ -233,6 +234,9 @@ impl Pod for NonePod {
|
||||||
fn into_any(self: Box<Self>) -> Box<dyn Any> {
|
fn into_any(self: Box<Self>) -> Box<dyn Any> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
fn serialized_proof(&self) -> String {
|
fn serialized_proof(&self) -> String {
|
||||||
"".to_string()
|
"".to_string()
|
||||||
}
|
}
|
||||||
|
|
@ -240,8 +244,8 @@ impl Pod for NonePod {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MainPodInputs<'a> {
|
pub struct MainPodInputs<'a> {
|
||||||
pub signed_pods: &'a [&'a Box<dyn Pod>],
|
pub signed_pods: &'a [&'a dyn Pod],
|
||||||
pub main_pods: &'a [&'a Box<dyn Pod>],
|
pub main_pods: &'a [&'a dyn Pod],
|
||||||
pub statements: &'a [Statement],
|
pub statements: &'a [Statement],
|
||||||
pub operations: &'a [Operation],
|
pub operations: &'a [Operation],
|
||||||
/// Statements that need to be made public (they can come from input pods or input
|
/// Statements that need to be made public (they can come from input pods or input
|
||||||
|
|
|
||||||
|
|
@ -180,8 +180,8 @@ impl Operation {
|
||||||
Self::TransitiveEqualFromStatements(s1, s2) => vec![s1, s2],
|
Self::TransitiveEqualFromStatements(s1, s2) => vec![s1, s2],
|
||||||
Self::GtToNotEqual(s) => vec![s],
|
Self::GtToNotEqual(s) => vec![s],
|
||||||
Self::LtToNotEqual(s) => vec![s],
|
Self::LtToNotEqual(s) => vec![s],
|
||||||
Self::ContainsFromEntries(s1, s2, s3, pf) => vec![s1, s2, s3],
|
Self::ContainsFromEntries(s1, s2, s3, _pf) => vec![s1, s2, s3],
|
||||||
Self::NotContainsFromEntries(s1, s2, pf) => vec![s1, s2],
|
Self::NotContainsFromEntries(s1, s2, _pf) => vec![s1, s2],
|
||||||
Self::SumOf(s1, s2, s3) => vec![s1, s2, s3],
|
Self::SumOf(s1, s2, s3) => vec![s1, s2, s3],
|
||||||
Self::ProductOf(s1, s2, s3) => vec![s1, s2, s3],
|
Self::ProductOf(s1, s2, s3) => vec![s1, s2, s3],
|
||||||
Self::MaxOf(s1, s2, s3) => vec![s1, s2, s3],
|
Self::MaxOf(s1, s2, s3) => vec![s1, s2, s3],
|
||||||
|
|
@ -303,7 +303,7 @@ impl Operation {
|
||||||
}
|
}
|
||||||
Self::TransitiveEqualFromStatements(Equal(ak1, ak2), Equal(ak3, ak4)) => {
|
Self::TransitiveEqualFromStatements(Equal(ak1, ak2), Equal(ak3, ak4)) => {
|
||||||
if ak2 == ak3 {
|
if ak2 == ak3 {
|
||||||
Some(vec![StatementArg::Key(*ak1), StatementArg::Key(*ak3)])
|
Some(vec![StatementArg::Key(*ak1), StatementArg::Key(*ak4)])
|
||||||
} else {
|
} else {
|
||||||
return Err(anyhow!("Invalid operation"));
|
return Err(anyhow!("Invalid operation"));
|
||||||
}
|
}
|
||||||
|
|
@ -324,7 +324,7 @@ impl Operation {
|
||||||
return Err(anyhow!("Invalid operation"));
|
return Err(anyhow!("Invalid operation"));
|
||||||
}
|
}
|
||||||
Self::ContainsFromEntries(ValueOf(ak1, v1), ValueOf(ak2, v2), ValueOf(ak3, v3), pf)
|
Self::ContainsFromEntries(ValueOf(ak1, v1), ValueOf(ak2, v2), ValueOf(ak3, v3), pf)
|
||||||
if MerkleTree::verify(pf.siblings.len(), (*v1).into(), &pf, v2, v3)? == () =>
|
if MerkleTree::verify(pf.siblings.len(), (*v1).into(), pf, v2, v3).is_ok() =>
|
||||||
{
|
{
|
||||||
Some(vec![
|
Some(vec![
|
||||||
StatementArg::Key(*ak1),
|
StatementArg::Key(*ak1),
|
||||||
|
|
@ -336,8 +336,8 @@ impl Operation {
|
||||||
return Err(anyhow!("Invalid operation"));
|
return Err(anyhow!("Invalid operation"));
|
||||||
}
|
}
|
||||||
Self::NotContainsFromEntries(ValueOf(ak1, v1), ValueOf(ak2, v2), pf)
|
Self::NotContainsFromEntries(ValueOf(ak1, v1), ValueOf(ak2, v2), pf)
|
||||||
if MerkleTree::verify_nonexistence(pf.siblings.len(), (*v1).into(), &pf, v2)?
|
if MerkleTree::verify_nonexistence(pf.siblings.len(), (*v1).into(), pf, v2)
|
||||||
== () =>
|
.is_ok() =>
|
||||||
{
|
{
|
||||||
Some(vec![StatementArg::Key(*ak1), StatementArg::Key(*ak2)])
|
Some(vec![StatementArg::Key(*ak1), StatementArg::Key(*ak2)])
|
||||||
}
|
}
|
||||||
|
|
@ -349,7 +349,11 @@ impl Operation {
|
||||||
let v2: i64 = (*v2).try_into()?;
|
let v2: i64 = (*v2).try_into()?;
|
||||||
let v3: i64 = (*v3).try_into()?;
|
let v3: i64 = (*v3).try_into()?;
|
||||||
if v1 == v2 + v3 {
|
if v1 == v2 + v3 {
|
||||||
Some(vec![StatementArg::Key(*ak1), StatementArg::Key(*ak2)])
|
Some(vec![
|
||||||
|
StatementArg::Key(*ak1),
|
||||||
|
StatementArg::Key(*ak2),
|
||||||
|
StatementArg::Key(*ak3),
|
||||||
|
])
|
||||||
} else {
|
} else {
|
||||||
return Err(anyhow!("Invalid operation"));
|
return Err(anyhow!("Invalid operation"));
|
||||||
}
|
}
|
||||||
|
|
@ -362,7 +366,11 @@ impl Operation {
|
||||||
let v2: i64 = (*v2).try_into()?;
|
let v2: i64 = (*v2).try_into()?;
|
||||||
let v3: i64 = (*v3).try_into()?;
|
let v3: i64 = (*v3).try_into()?;
|
||||||
if v1 == v2 * v3 {
|
if v1 == v2 * v3 {
|
||||||
Some(vec![StatementArg::Key(*ak1), StatementArg::Key(*ak2)])
|
Some(vec![
|
||||||
|
StatementArg::Key(*ak1),
|
||||||
|
StatementArg::Key(*ak2),
|
||||||
|
StatementArg::Key(*ak3),
|
||||||
|
])
|
||||||
} else {
|
} else {
|
||||||
return Err(anyhow!("Invalid operation"));
|
return Err(anyhow!("Invalid operation"));
|
||||||
}
|
}
|
||||||
|
|
@ -375,7 +383,11 @@ impl Operation {
|
||||||
let v2: i64 = (*v2).try_into()?;
|
let v2: i64 = (*v2).try_into()?;
|
||||||
let v3: i64 = (*v3).try_into()?;
|
let v3: i64 = (*v3).try_into()?;
|
||||||
if v1 == std::cmp::max(v2, v3) {
|
if v1 == std::cmp::max(v2, v3) {
|
||||||
Some(vec![StatementArg::Key(*ak1), StatementArg::Key(*ak2)])
|
Some(vec![
|
||||||
|
StatementArg::Key(*ak1),
|
||||||
|
StatementArg::Key(*ak2),
|
||||||
|
StatementArg::Key(*ak3),
|
||||||
|
])
|
||||||
} else {
|
} else {
|
||||||
return Err(anyhow!("Invalid operation"));
|
return Err(anyhow!("Invalid operation"));
|
||||||
}
|
}
|
||||||
|
|
@ -484,7 +496,7 @@ impl Operation {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToFields for Operation {
|
impl ToFields for Operation {
|
||||||
fn to_fields(&self, params: &Params) -> Vec<F> {
|
fn to_fields(&self, _params: &Params) -> Vec<F> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,11 +29,11 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut v = [F::ZERO; N];
|
let mut v = [F::ZERO; N];
|
||||||
for i in 0..N {
|
for (i, v_i) in v.iter_mut().enumerate() {
|
||||||
let start = i * 16;
|
let start = i * 16;
|
||||||
let end = start + 16;
|
let end = start + 16;
|
||||||
let hex_part = &hex_str[start..end];
|
let hex_part = &hex_str[start..end];
|
||||||
v[i] = F::from_canonical_u64(
|
*v_i = F::from_canonical_u64(
|
||||||
u64::from_str_radix(hex_part, 16).map_err(serde::de::Error::custom)?,
|
u64::from_str_radix(hex_part, 16).map_err(serde::de::Error::custom)?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue