Progress on the MainPod circuit (#159)
* feat: add SignedPodVerify test * unify circuits style * more clear sizes * get operation_verify test working * be consistent with names
This commit is contained in:
parent
9afc43675d
commit
b93187c9bb
11 changed files with 411 additions and 175 deletions
|
|
@ -5,6 +5,7 @@ use std::{fmt, hash as h, iter, iter::zip};
|
|||
use anyhow::{anyhow, Result};
|
||||
use plonky2::field::types::Field;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::{
|
||||
hash_fields, AnchoredKey, Hash, NativePredicate, Params, PodId, Statement, StatementArg,
|
||||
|
|
@ -12,7 +13,6 @@ use super::{
|
|||
};
|
||||
use crate::backends::plonky2::basetypes::HASH_SIZE;
|
||||
use crate::util::hashmap_insert_no_dupe;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
// BEGIN Custom 1b
|
||||
|
||||
|
|
@ -49,9 +49,9 @@ impl fmt::Display for HashOrWildcard {
|
|||
}
|
||||
|
||||
impl ToFields for HashOrWildcard {
|
||||
fn to_fields(&self, _params: &Params) -> Vec<F> {
|
||||
fn to_fields(&self, params: &Params) -> Vec<F> {
|
||||
match self {
|
||||
HashOrWildcard::Hash(h) => h.to_fields(_params),
|
||||
HashOrWildcard::Hash(h) => h.to_fields(params),
|
||||
HashOrWildcard::Wildcard(w) => (0..HASH_SIZE - 1)
|
||||
.chain(iter::once(*w))
|
||||
.map(|x| F::from_canonical_u64(x as u64))
|
||||
|
|
@ -91,7 +91,7 @@ impl StatementTmplArg {
|
|||
}
|
||||
|
||||
impl ToFields for StatementTmplArg {
|
||||
fn to_fields(&self, _params: &Params) -> Vec<F> {
|
||||
fn to_fields(&self, params: &Params) -> Vec<F> {
|
||||
// None => (0, ...)
|
||||
// Literal(value) => (1, [value], 0, 0, 0, 0)
|
||||
// Key(hash_or_wildcard1, hash_or_wildcard2)
|
||||
|
|
@ -107,15 +107,15 @@ impl ToFields for StatementTmplArg {
|
|||
}
|
||||
StatementTmplArg::Literal(v) => {
|
||||
let fields: Vec<F> = iter::once(F::from_canonical_u64(1))
|
||||
.chain(v.to_fields(_params))
|
||||
.chain(v.to_fields(params))
|
||||
.chain(iter::repeat_with(|| F::from_canonical_u64(0)).take(HASH_SIZE))
|
||||
.collect();
|
||||
fields
|
||||
}
|
||||
StatementTmplArg::Key(hw1, hw2) => {
|
||||
let fields: Vec<F> = iter::once(F::from_canonical_u64(2))
|
||||
.chain(hw1.to_fields(_params))
|
||||
.chain(hw2.to_fields(_params))
|
||||
.chain(hw1.to_fields(params))
|
||||
.chain(hw2.to_fields(params))
|
||||
.collect();
|
||||
fields
|
||||
}
|
||||
|
|
@ -165,7 +165,7 @@ impl StatementTmpl {
|
|||
Err(anyhow!(
|
||||
"Cannot check self-referencing statement templates."
|
||||
))
|
||||
} else if self.pred() != &s.code() {
|
||||
} else if self.pred() != &s.predicate() {
|
||||
Err(anyhow!("Type mismatch between {:?} and {}.", self, s))
|
||||
} else {
|
||||
zip(self.args(), s.args())
|
||||
|
|
@ -318,8 +318,8 @@ impl ToFields for CustomPredicateBatch {
|
|||
}
|
||||
|
||||
impl CustomPredicateBatch {
|
||||
pub fn hash(&self, _params: &Params) -> Hash {
|
||||
let input = self.to_fields(_params);
|
||||
pub fn hash(&self, params: &Params) -> Hash {
|
||||
let input = self.to_fields(params);
|
||||
|
||||
hash_fields(&input)
|
||||
}
|
||||
|
|
@ -399,7 +399,7 @@ impl From<NativePredicate> for Predicate {
|
|||
}
|
||||
|
||||
impl ToFields for Predicate {
|
||||
fn to_fields(&self, _params: &Params) -> Vec<F> {
|
||||
fn to_fields(&self, params: &Params) -> Vec<F> {
|
||||
// serialize:
|
||||
// NativePredicate(id) as (0, id, 0, 0, 0, 0) -- id: usize
|
||||
// BatchSelf(i) as (1, i, 0, 0, 0, 0) -- i: usize
|
||||
|
|
@ -410,13 +410,13 @@ impl ToFields for Predicate {
|
|||
// in every case: pad to (hash_size + 2) field elements
|
||||
let mut fields: Vec<F> = match self {
|
||||
Self::Native(p) => iter::once(F::from_canonical_u64(1))
|
||||
.chain(p.to_fields(_params))
|
||||
.chain(p.to_fields(params))
|
||||
.collect(),
|
||||
Self::BatchSelf(i) => iter::once(F::from_canonical_u64(2))
|
||||
.chain(iter::once(F::from_canonical_usize(*i)))
|
||||
.collect(),
|
||||
Self::Custom(CustomPredicateRef(pb, i)) => iter::once(F::from_canonical_u64(3))
|
||||
.chain(pb.hash(_params).0)
|
||||
.chain(pb.hash(params).0)
|
||||
.chain(iter::once(F::from_canonical_usize(*i)))
|
||||
.collect(),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -93,6 +93,8 @@ pub struct Params {
|
|||
// in a custom predicate
|
||||
pub max_custom_predicate_arity: usize,
|
||||
pub max_custom_batch_size: usize,
|
||||
// maximum depth for merkle tree gates
|
||||
pub max_depth_mt_gate: usize,
|
||||
}
|
||||
|
||||
impl Default for Params {
|
||||
|
|
@ -107,6 +109,7 @@ impl Default for Params {
|
|||
max_operation_args: 5,
|
||||
max_custom_predicate_arity: 5,
|
||||
max_custom_batch_size: 5,
|
||||
max_depth_mt_gate: 32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -116,15 +119,27 @@ impl Params {
|
|||
self.max_statements - self.max_public_statements
|
||||
}
|
||||
|
||||
pub fn statement_tmpl_arg_size() -> usize {
|
||||
pub const fn statement_tmpl_arg_size() -> usize {
|
||||
2 * HASH_SIZE + 1
|
||||
}
|
||||
|
||||
pub fn predicate_size() -> usize {
|
||||
pub const fn predicate_size() -> usize {
|
||||
HASH_SIZE + 2
|
||||
}
|
||||
|
||||
pub fn statement_tmpl_size(&self) -> usize {
|
||||
pub const fn operation_type_size() -> usize {
|
||||
HASH_SIZE + 2
|
||||
}
|
||||
|
||||
pub fn statement_size(&self) -> usize {
|
||||
Self::predicate_size() + STATEMENT_ARG_F_LEN * self.max_statement_args
|
||||
}
|
||||
|
||||
pub fn operation_size(&self) -> usize {
|
||||
Self::operation_type_size() + OPERATION_ARG_F_LEN * self.max_operation_args
|
||||
}
|
||||
|
||||
pub const fn statement_tmpl_size(&self) -> usize {
|
||||
Self::predicate_size() + self.max_statement_args * Self::statement_tmpl_arg_size()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
use anyhow::{anyhow, Result};
|
||||
use log::error;
|
||||
use plonky2::field::types::Field;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use std::iter;
|
||||
|
||||
use super::{CustomPredicateRef, NativePredicate, Statement, StatementArg};
|
||||
use super::{CustomPredicateRef, NativePredicate, Statement, StatementArg, ToFields, F};
|
||||
use crate::middleware::{AnchoredKey, Params, Predicate, Value, SELF};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
|
|
@ -12,6 +14,22 @@ pub enum OperationType {
|
|||
Custom(CustomPredicateRef),
|
||||
}
|
||||
|
||||
impl ToFields for OperationType {
|
||||
fn to_fields(&self, params: &Params) -> Vec<F> {
|
||||
let mut fields: Vec<F> = match self {
|
||||
Self::Native(p) => iter::once(F::from_canonical_u64(1))
|
||||
.chain(p.to_fields(params))
|
||||
.collect(),
|
||||
Self::Custom(CustomPredicateRef(pb, i)) => iter::once(F::from_canonical_u64(3))
|
||||
.chain(pb.hash(params).0)
|
||||
.chain(iter::once(F::from_canonical_usize(*i)))
|
||||
.collect(),
|
||||
};
|
||||
fields.resize_with(Params::operation_type_size(), || F::from_canonical_u64(0));
|
||||
fields
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum NativeOperation {
|
||||
None = 0,
|
||||
|
|
@ -31,6 +49,12 @@ pub enum NativeOperation {
|
|||
MaxOf = 15,
|
||||
}
|
||||
|
||||
impl ToFields for NativeOperation {
|
||||
fn to_fields(&self, _params: &Params) -> Vec<F> {
|
||||
vec![F::from_canonical_u64(*self as u64)]
|
||||
}
|
||||
}
|
||||
|
||||
impl OperationType {
|
||||
/// Gives the type of predicate that the operation will output, if known.
|
||||
/// CopyStatement may output any predicate (it will match the statement copied),
|
||||
|
|
@ -91,7 +115,7 @@ pub enum Operation {
|
|||
}
|
||||
|
||||
impl Operation {
|
||||
pub fn predicate(&self) -> OperationType {
|
||||
pub fn op_type(&self) -> OperationType {
|
||||
type OT = OperationType;
|
||||
use NativeOperation::*;
|
||||
match self {
|
||||
|
|
@ -178,7 +202,7 @@ impl Operation {
|
|||
/// The outer Result is error handling
|
||||
pub fn output_statement(&self) -> Result<Option<Statement>> {
|
||||
use Statement::*;
|
||||
let pred: Option<Predicate> = self.predicate().output_predicate();
|
||||
let pred: Option<Predicate> = self.op_type().output_predicate();
|
||||
|
||||
let st_args: Option<Vec<StatementArg>> = match self {
|
||||
Self::None => Some(vec![]),
|
||||
|
|
@ -401,10 +425,16 @@ impl Operation {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToFields for Operation {
|
||||
fn to_fields(&self, params: &Params) -> Vec<F> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Operation {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
writeln!(f, "middleware::Operation:")?;
|
||||
writeln!(f, " {:?} ", self.predicate())?;
|
||||
writeln!(f, " {:?} ", self.op_type())?;
|
||||
for arg in self.args().iter() {
|
||||
writeln!(f, " {}", arg)?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,14 @@ use serde::{Deserialize, Serialize};
|
|||
use std::{fmt, iter};
|
||||
use strum_macros::FromRepr;
|
||||
|
||||
use super::{AnchoredKey, CustomPredicateRef, Params, Predicate, ToFields, Value, F, VALUE_SIZE};
|
||||
use super::{
|
||||
AnchoredKey, CustomPredicateRef, Params, Predicate, ToFields, Value, F, HASH_SIZE, VALUE_SIZE,
|
||||
};
|
||||
|
||||
pub const KEY_SIGNER: &str = "_signer";
|
||||
pub const KEY_TYPE: &str = "_type";
|
||||
pub const STATEMENT_ARG_F_LEN: usize = 8;
|
||||
pub const OPERATION_ARG_F_LEN: usize = 1;
|
||||
|
||||
#[derive(Clone, Copy, Debug, FromRepr, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
|
||||
pub enum NativePredicate {
|
||||
|
|
@ -53,7 +56,7 @@ impl Statement {
|
|||
pub fn is_none(&self) -> bool {
|
||||
self == &Self::None
|
||||
}
|
||||
pub fn code(&self) -> Predicate {
|
||||
pub fn predicate(&self) -> Predicate {
|
||||
use Predicate::*;
|
||||
match self {
|
||||
Self::None => Native(NativePredicate::None),
|
||||
|
|
@ -184,16 +187,17 @@ impl Statement {
|
|||
}
|
||||
|
||||
impl ToFields for Statement {
|
||||
fn to_fields(&self, _params: &Params) -> Vec<F> {
|
||||
let mut fields = self.code().to_fields(_params);
|
||||
fields.extend(self.args().iter().flat_map(|arg| arg.to_fields(_params)));
|
||||
fn to_fields(&self, params: &Params) -> Vec<F> {
|
||||
let mut fields = self.predicate().to_fields(params);
|
||||
fields.extend(self.args().iter().flat_map(|arg| arg.to_fields(params)));
|
||||
fields.resize_with(params.statement_size(), || F::ZERO);
|
||||
fields
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Statement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{:?} ", self.code())?;
|
||||
write!(f, "{:?} ", self.predicate())?;
|
||||
for (i, arg) in self.args().iter().enumerate() {
|
||||
if i != 0 {
|
||||
write!(f, " ")?;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue