No Pod IDs (#394)
- middleware:
- Add `Statement::Intro`
- Add `SignedBy` native predicate and operation. The signature is auxiliary data to the operation
- Rename `PodSigner` to `Signer` with a new API (just for signing `RawValue`)
- Removed `NewEntry` operation. Use `ContainsFromEntries` instead
- Remove `KEY_SIGNER` and `KEY_TYPE` which are no longer used
- Merge `RecursivePod` and `Pod` traits
- Change the `Pod::deserialize_data` method to use `Self` instead of `Box<dyn Pod>`
- Extend `Pod` trait with these methods:
- `is_main`: when the pod is Main, in a (recursive) verification its vk will be checked to exist in the vd_set but not if it's intro pod
- `is_mock`: skip some verifications in the recursive mock MainPod verification
- `verifier_data_hash`
- `pod_id` renamed to `statements_hash`
- AnchoredKeys are now a pair of dictionary root and key
- Entry statements are now defined as Contains with literal arguments
- Operations that take Entries now use Contains statements with literal arguments
- frontend:
- Rename `SignedPod` to `SignedDict` (which now contains the dict, public key and signature, and can still `verify(self)`ed)
- The `SignedDict` keeps the method `get_statement` for convenience but now it returns a `Contains` statement that proves the existence of the key in the dict
- The `MainPodBuilder` automatically inserts a `Contains` statement when an operation is added that uses an entry as argument that was not yet "opened".
- Removed the `literal` methods from the `MainPodBuilder` that were loading literals to anchored keys: that was no longer needed after we introduced literal arguments
- backend
- Only verify inclusion of the verifying key into the vd_set if the pod is MainPod. A pod is not MainPod if the first statement is Intro.
- Reject intro pods that have non-intro statements
- Empty pod now returns an intro statement
- Don't insert a type statement automatically in MainPod and MockMainPod. We get rid of the type entry.
- Implement `SignedBy` operation, which uses the muxed table to store signature verifications
- Rename `PodId` to `statements_hash` or `sts_hash` for short. Now this is only used as a hash of the statements for the circuits public inputs.
- Refactor normalization of `self` statements:
- Before: replace values that contain `SELF` by the given pod_id
- After: place the verifying key hash into the Intro predicates
This commit is contained in:
parent
122f9c3cac
commit
0e2f7b756e
39 changed files with 2127 additions and 3064 deletions
|
|
@ -6,6 +6,7 @@ use std::sync::Arc;
|
|||
use hex::ToHex;
|
||||
use itertools::Itertools;
|
||||
use strum_macros::FromRepr;
|
||||
|
||||
mod basetypes;
|
||||
use std::{cmp::PartialEq, hash};
|
||||
|
||||
|
|
@ -19,7 +20,7 @@ mod operation;
|
|||
mod pod_deserialization;
|
||||
pub mod serialization;
|
||||
mod statement;
|
||||
use std::{any::Any, collections::HashMap, fmt};
|
||||
use std::{any::Any, fmt};
|
||||
|
||||
pub use basetypes::*;
|
||||
pub use custom::*;
|
||||
|
|
@ -30,13 +31,10 @@ pub use pod_deserialization::*;
|
|||
use serialization::*;
|
||||
pub use statement::*;
|
||||
|
||||
use crate::backends::plonky2::primitives::{
|
||||
ec::{curve::Point as PublicKey, schnorr::SecretKey},
|
||||
merkletree::{MerkleProof, MerkleTreeStateTransitionProof},
|
||||
use crate::backends::plonky2::primitives::merkletree::{
|
||||
MerkleProof, MerkleTreeStateTransitionProof,
|
||||
};
|
||||
|
||||
pub const SELF: PodId = PodId(SELF_ID_HASH);
|
||||
|
||||
// TODO: Move all value-related types to to `value.rs`
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
|
||||
// TODO #[schemars(transform = serialization::transform_value_schema)]
|
||||
|
|
@ -64,7 +62,6 @@ pub enum TypedValue {
|
|||
PublicKey(PublicKey),
|
||||
// Schnorr secret key variant (scalar)
|
||||
SecretKey(SecretKey),
|
||||
PodId(PodId),
|
||||
// UNTAGGED TYPES:
|
||||
#[serde(untagged)]
|
||||
Set(Set),
|
||||
|
|
@ -120,12 +117,6 @@ impl From<SecretKey> for TypedValue {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<PodId> for TypedValue {
|
||||
fn from(id: PodId) -> Self {
|
||||
TypedValue::PodId(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Set> for TypedValue {
|
||||
fn from(s: Set) -> Self {
|
||||
TypedValue::Set(s)
|
||||
|
|
@ -150,12 +141,6 @@ impl From<RawValue> for TypedValue {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<PodType> for TypedValue {
|
||||
fn from(t: PodType) -> Self {
|
||||
TypedValue::from(t as i64)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&TypedValue> for i64 {
|
||||
type Error = Error;
|
||||
fn try_from(v: &TypedValue) -> std::result::Result<Self, Self::Error> {
|
||||
|
|
@ -167,30 +152,23 @@ impl TryFrom<&TypedValue> for i64 {
|
|||
}
|
||||
}
|
||||
|
||||
impl TryFrom<TypedValue> for Key {
|
||||
impl TryFrom<&TypedValue> for String {
|
||||
type Error = Error;
|
||||
fn try_from(tv: TypedValue) -> Result<Self> {
|
||||
fn try_from(tv: &TypedValue) -> Result<Self> {
|
||||
match tv {
|
||||
TypedValue::String(s) => Ok(Key::new(s)),
|
||||
TypedValue::String(s) => Ok(s.clone()),
|
||||
_ => Err(Error::custom(format!(
|
||||
"Value {} cannot be converted to a key.",
|
||||
"Value {} cannot be converted to a string.",
|
||||
tv
|
||||
))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&TypedValue> for PodId {
|
||||
impl TryFrom<&TypedValue> for Key {
|
||||
type Error = Error;
|
||||
fn try_from(v: &TypedValue) -> Result<Self> {
|
||||
match v {
|
||||
TypedValue::PodId(id) => Ok(*id),
|
||||
TypedValue::Raw(v) => Ok(PodId(Hash(v.0))),
|
||||
_ => Err(Error::custom(format!(
|
||||
"Value {} cannot be converted to a PodId.",
|
||||
v
|
||||
))),
|
||||
}
|
||||
fn try_from(tv: &TypedValue) -> Result<Self> {
|
||||
Ok(Key::new(String::try_from(tv)?))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -262,13 +240,6 @@ impl fmt::Display for TypedValue {
|
|||
}
|
||||
TypedValue::PublicKey(p) => write!(f, "PublicKey({})", p),
|
||||
TypedValue::SecretKey(p) => write!(f, "SecretKey({})", p),
|
||||
TypedValue::PodId(p) => {
|
||||
if *p == SELF {
|
||||
write!(f, "SELF")
|
||||
} else {
|
||||
write!(f, "0x{}", p.0.encode_hex::<String>())
|
||||
}
|
||||
}
|
||||
TypedValue::Raw(r) => {
|
||||
write!(f, "Raw(0x{})", r.encode_hex::<String>())
|
||||
}
|
||||
|
|
@ -288,7 +259,6 @@ impl From<&TypedValue> for RawValue {
|
|||
TypedValue::Raw(v) => *v,
|
||||
TypedValue::PublicKey(p) => RawValue::from(hash_fields(&p.as_fields())),
|
||||
TypedValue::SecretKey(sk) => RawValue::from(hash_fields(&sk.to_limbs())),
|
||||
TypedValue::PodId(id) => RawValue::from(id.0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -342,13 +312,13 @@ impl JsonSchema for TypedValue {
|
|||
..Default::default()
|
||||
};
|
||||
|
||||
let pod_id_schema = schemars::schema::SchemaObject {
|
||||
let root_schema = schemars::schema::SchemaObject {
|
||||
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Object))),
|
||||
object: Some(Box::new(schemars::schema::ObjectValidation {
|
||||
properties: [("PodId".to_string(), gen.subschema_for::<PodId>())]
|
||||
properties: [("Root".to_string(), gen.subschema_for::<Hash>())]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
required: ["PodId".to_string()].into_iter().collect(),
|
||||
required: ["Root".to_string()].into_iter().collect(),
|
||||
..Default::default()
|
||||
})),
|
||||
..Default::default()
|
||||
|
|
@ -390,7 +360,7 @@ impl JsonSchema for TypedValue {
|
|||
Schema::Object(SchemaObject {
|
||||
subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
|
||||
any_of: Some(vec![
|
||||
Schema::Object(pod_id_schema),
|
||||
Schema::Object(root_schema),
|
||||
Schema::Object(int_schema),
|
||||
Schema::Object(raw_schema),
|
||||
Schema::Object(public_key_schema),
|
||||
|
|
@ -498,7 +468,7 @@ impl Value {
|
|||
key, self
|
||||
)))?,
|
||||
},
|
||||
TypedValue::Dictionary(d) => d.prove(&key.typed().clone().try_into()?),
|
||||
TypedValue::Dictionary(d) => d.prove(&key.typed().try_into()?),
|
||||
TypedValue::Set(s) => Ok((key, s.prove(key)?)),
|
||||
_ => Err(Error::custom(format!(
|
||||
"Invalid container value {}",
|
||||
|
|
@ -512,7 +482,7 @@ impl Value {
|
|||
TypedValue::Array(_) => Err(Error::custom(
|
||||
"Arrays do not support `NotContains` operation.".to_string(),
|
||||
)),
|
||||
TypedValue::Dictionary(d) => d.prove_nonexistence(&key.typed().clone().try_into()?),
|
||||
TypedValue::Dictionary(d) => d.prove_nonexistence(&key.typed().try_into()?),
|
||||
TypedValue::Set(s) => s.prove_nonexistence(key),
|
||||
_ => Err(Error::custom(format!(
|
||||
"Invalid container value {}",
|
||||
|
|
@ -529,7 +499,7 @@ impl Value {
|
|||
) -> Result<MerkleTreeStateTransitionProof> {
|
||||
let container = self.typed().clone();
|
||||
match container {
|
||||
TypedValue::Dictionary(mut d) => d.insert(&key.typed().clone().try_into()?, value),
|
||||
TypedValue::Dictionary(mut d) => d.insert(&key.typed().try_into()?, value),
|
||||
TypedValue::Set(mut s) => s.insert(value),
|
||||
_ => Err(Error::custom(format!(
|
||||
"Invalid container value {}",
|
||||
|
|
@ -553,7 +523,7 @@ impl Value {
|
|||
key, self
|
||||
)))?,
|
||||
},
|
||||
TypedValue::Dictionary(mut d) => d.update(&key.typed().clone().try_into()?, value),
|
||||
TypedValue::Dictionary(mut d) => d.update(&key.typed().try_into()?, value),
|
||||
_ => Err(Error::custom(format!(
|
||||
"Invalid container value {} for update op",
|
||||
self.typed()
|
||||
|
|
@ -565,7 +535,7 @@ impl Value {
|
|||
pub(crate) fn prove_deletion(&self, key: &Value) -> Result<MerkleTreeStateTransitionProof> {
|
||||
let container = self.typed().clone();
|
||||
match container {
|
||||
TypedValue::Dictionary(mut d) => d.delete(&key.typed().clone().try_into()?),
|
||||
TypedValue::Dictionary(mut d) => d.delete(&key.typed().try_into()?),
|
||||
TypedValue::Set(mut s) => s.delete(key),
|
||||
_ => Err(Error::custom(format!(
|
||||
"Invalid container value {}",
|
||||
|
|
@ -585,26 +555,6 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for PodId {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
if *self == SELF {
|
||||
write!(f, "self")
|
||||
} else if self.0 == EMPTY_HASH {
|
||||
write!(f, "null")
|
||||
} else if f.alternate() {
|
||||
write!(f, "{:#}", self.0)
|
||||
} else {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Value> for Hash {
|
||||
fn from(v: &Value) -> Self {
|
||||
Self(v.raw.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq)]
|
||||
pub struct Key {
|
||||
name: String,
|
||||
|
|
@ -708,32 +658,32 @@ impl JsonSchema for Key {
|
|||
#[derive(Clone, Debug, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AnchoredKey {
|
||||
pub pod_id: PodId,
|
||||
pub root: Hash,
|
||||
pub key: Key,
|
||||
}
|
||||
|
||||
impl AnchoredKey {
|
||||
pub fn new(pod_id: PodId, key: Key) -> Self {
|
||||
Self { pod_id, key }
|
||||
pub fn new(root: Hash, key: Key) -> Self {
|
||||
Self { root, key }
|
||||
}
|
||||
}
|
||||
|
||||
impl hash::Hash for AnchoredKey {
|
||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||||
self.pod_id.hash(state);
|
||||
self.root.hash(state);
|
||||
self.key.hash.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for AnchoredKey {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.pod_id == other.pod_id && self.key.hash == other.key.hash
|
||||
self.root == other.root && self.key.hash == other.key.hash
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for AnchoredKey {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.pod_id.fmt(f)?;
|
||||
self.root.fmt(f)?;
|
||||
write!(f, "[")?;
|
||||
self.key.fmt(f)?;
|
||||
write!(f, "]")?;
|
||||
|
|
@ -741,31 +691,30 @@ impl fmt::Display for AnchoredKey {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> From<(PodId, T)> for AnchoredKey
|
||||
impl<T> From<(Hash, T)> for AnchoredKey
|
||||
where
|
||||
T: Into<Key>,
|
||||
{
|
||||
fn from((pod_id, t): (PodId, T)) -> Self {
|
||||
Self::new(pod_id, t.into())
|
||||
fn from((root, t): (Hash, T)) -> Self {
|
||||
Self::new(root, t.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct PodId(pub Hash);
|
||||
|
||||
impl ToFields for PodId {
|
||||
fn to_fields(&self, params: &Params) -> Vec<F> {
|
||||
self.0.to_fields(params)
|
||||
impl<T> From<(&Dictionary, T)> for AnchoredKey
|
||||
where
|
||||
T: Into<Key>,
|
||||
{
|
||||
fn from((dict, t): (&Dictionary, T)) -> Self {
|
||||
Self::new(dict.commitment(), t.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, FromRepr, Serialize, Deserialize, JsonSchema)]
|
||||
pub enum PodType {
|
||||
Signed = 1,
|
||||
Main = 2,
|
||||
Empty = 3,
|
||||
MockMain = 102,
|
||||
MockEmpty = 103,
|
||||
Main = 1,
|
||||
Empty = 2,
|
||||
MockMain = 101,
|
||||
MockEmpty = 102,
|
||||
}
|
||||
|
||||
impl fmt::Display for PodType {
|
||||
|
|
@ -773,7 +722,6 @@ impl fmt::Display for PodType {
|
|||
match self {
|
||||
PodType::MockMain => write!(f, "MockMain"),
|
||||
PodType::MockEmpty => write!(f, "MockEmpty"),
|
||||
PodType::Signed => write!(f, "Signed"),
|
||||
PodType::Main => write!(f, "Main"),
|
||||
PodType::Empty => write!(f, "Empty"),
|
||||
}
|
||||
|
|
@ -784,11 +732,9 @@ impl fmt::Display for PodType {
|
|||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Hash)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Params {
|
||||
pub max_input_signed_pods: usize,
|
||||
pub max_input_recursive_pods: usize,
|
||||
pub max_input_pods: usize,
|
||||
pub max_input_pods_public_statements: usize,
|
||||
pub max_statements: usize,
|
||||
pub max_signed_pod_values: usize,
|
||||
pub max_public_statements: usize,
|
||||
pub max_operation_args: usize,
|
||||
// max number of custom predicates batches that a MainPod can use
|
||||
|
|
@ -809,13 +755,15 @@ pub struct Params {
|
|||
pub max_depth_mt_vds: usize,
|
||||
// maximum number of public key derivations used for PublicKeyOf operation
|
||||
pub max_public_key_of: usize,
|
||||
// maximum number of signature verifications used for SignedBy operation
|
||||
pub max_signed_by: usize,
|
||||
//
|
||||
// The following parameters define how a pod id is calculated. They need to be the same among
|
||||
// different circuits to be compatible in their verification.
|
||||
//
|
||||
// Number of public statements to hash to calculate the id. Must be equal or greater than
|
||||
// `max_public_statements`.
|
||||
pub num_public_statements_id: usize,
|
||||
// Number of public statements to hash to calculate the public inputs. Must be equal or
|
||||
// greater than `max_public_statements`.
|
||||
pub num_public_statements_hash: usize,
|
||||
pub max_statement_args: usize,
|
||||
//
|
||||
// The following parameters define how a custom predicate batch id is calculated.
|
||||
|
|
@ -829,13 +777,11 @@ pub struct Params {
|
|||
impl Default for Params {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
max_input_signed_pods: 3,
|
||||
max_input_recursive_pods: 2,
|
||||
max_input_pods: 2,
|
||||
max_input_pods_public_statements: 10,
|
||||
max_statements: 20,
|
||||
max_signed_pod_values: 8,
|
||||
max_statements: 40,
|
||||
max_public_statements: 10,
|
||||
num_public_statements_id: 16,
|
||||
num_public_statements_hash: 16,
|
||||
max_statement_args: 5,
|
||||
max_operation_args: 5,
|
||||
max_custom_predicate_batches: 2,
|
||||
|
|
@ -843,11 +789,12 @@ impl Default for Params {
|
|||
max_custom_predicate_arity: 5,
|
||||
max_custom_predicate_wildcards: 10,
|
||||
max_custom_batch_size: 5, // TODO: Move down to 4?
|
||||
max_merkle_proofs_containers: 5,
|
||||
max_merkle_proofs_containers: 16,
|
||||
max_merkle_tree_state_transition_proofs_containers: 5,
|
||||
max_depth_mt_containers: 32,
|
||||
max_depth_mt_vds: 6, // up to 64 (2^6) different pod circuits
|
||||
max_public_key_of: 2,
|
||||
max_signed_by: 3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -888,15 +835,13 @@ impl Params {
|
|||
/// Total size of the statement table including None, input statements from signed pods and
|
||||
/// input recursive pods and new statements (public & private)
|
||||
pub fn statement_table_size(&self) -> usize {
|
||||
1 + self.max_input_signed_pods * self.max_signed_pod_values
|
||||
+ self.max_input_recursive_pods * self.max_input_pods_public_statements
|
||||
+ self.max_statements
|
||||
1 + self.max_input_pods * self.max_input_pods_public_statements + self.max_statements
|
||||
}
|
||||
|
||||
/// Parameters that define how the id is calculated
|
||||
pub fn id_params(&self) -> Vec<usize> {
|
||||
vec![
|
||||
self.num_public_statements_id,
|
||||
self.num_public_statements_hash,
|
||||
self.max_statement_args,
|
||||
self.max_custom_predicate_arity,
|
||||
self.max_custom_batch_size,
|
||||
|
|
@ -920,23 +865,19 @@ impl Params {
|
|||
}
|
||||
}
|
||||
|
||||
/// Replace references to SELF by `self_id`.
|
||||
pub fn normalize_statement(statement: &Statement, self_id: PodId) -> Statement {
|
||||
let predicate = statement.predicate();
|
||||
let args = statement
|
||||
.args()
|
||||
.iter()
|
||||
.map(|sa| match &sa {
|
||||
StatementArg::Key(AnchoredKey { pod_id, key }) if *pod_id == SELF => {
|
||||
StatementArg::Key(AnchoredKey::new(self_id, key.clone()))
|
||||
}
|
||||
StatementArg::Literal(value) if value.raw.0 == SELF.0 .0 => {
|
||||
StatementArg::Literal(self_id.into())
|
||||
}
|
||||
_ => sa.clone(),
|
||||
})
|
||||
.collect();
|
||||
Statement::from_args(predicate, args).expect("statement was valid before normalization")
|
||||
/// Replace EMPTY_HASH in IntroPredicateRef by verifier_data_hash
|
||||
pub fn normalize_statement(statement: &Statement, verifier_data_hash: Hash) -> Statement {
|
||||
match statement {
|
||||
Statement::Intro(ir, args) if ir.verifier_data_hash == EMPTY_HASH => Statement::Intro(
|
||||
IntroPredicateRef {
|
||||
name: ir.name.clone(),
|
||||
args_len: ir.args_len,
|
||||
verifier_data_hash,
|
||||
},
|
||||
args.clone(),
|
||||
),
|
||||
s => s.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub trait EqualsAny {
|
||||
|
|
@ -953,10 +894,27 @@ impl<T: Any + Eq> EqualsAny for T {
|
|||
}
|
||||
}
|
||||
|
||||
/// Trait for pods that are generated with a plonky2 circuit and that can be verified by a
|
||||
/// recursive MainPod circuit (with the exception of mock types). A Pod implementing this trait
|
||||
/// does not necesarilly come from recursion: for example an introduction Pod in general is not
|
||||
/// recursive.
|
||||
pub trait Pod: fmt::Debug + DynClone + Sync + Send + Any + EqualsAny {
|
||||
fn params(&self) -> &Params;
|
||||
fn verify(&self) -> Result<(), BackendError>;
|
||||
fn id(&self) -> PodId;
|
||||
/// Overwrite this method to return true in a mock pod to skip plonky2 verification
|
||||
fn is_mock(&self) -> bool {
|
||||
false
|
||||
}
|
||||
/// Overwrite this method to return true in a MainPod to generate verifier key inclusion proof
|
||||
/// into the vd set
|
||||
fn is_main(&self) -> bool {
|
||||
false
|
||||
}
|
||||
/// Hash of the public statements. This can be used to identify a Pod. Different pods can
|
||||
/// have the same `statements_hash` if they expose the same public statements even if they
|
||||
/// arrive to them through different private inputs.
|
||||
fn statements_hash(&self) -> Hash;
|
||||
// TODO: String instead of &str
|
||||
/// Return a uuid of the pod type and its name. The name is only used as metadata.
|
||||
fn pod_type(&self) -> (usize, &'static str);
|
||||
/// Statements as internally generated, where self-referencing arguments use SELF in the
|
||||
|
|
@ -965,29 +923,39 @@ pub trait Pod: fmt::Debug + DynClone + Sync + Send + Any + EqualsAny {
|
|||
/// Normalized statements, where self-referencing arguments use the pod id instead of SELF in
|
||||
/// the anchored key.
|
||||
fn pub_statements(&self) -> Vec<Statement> {
|
||||
let verifier_data_hash = self.verifier_data_hash();
|
||||
self.pub_self_statements()
|
||||
.into_iter()
|
||||
.map(|statement| normalize_statement(&statement, self.id()))
|
||||
.map(|statement| normalize_statement(&statement, verifier_data_hash))
|
||||
.collect()
|
||||
}
|
||||
/// Return this Pods data serialized into a json value. This serialization can skip `params,
|
||||
/// id, vds_root`
|
||||
fn serialize_data(&self) -> serde_json::Value;
|
||||
|
||||
/// Extract key-values from ValueOf public statements
|
||||
fn kvs(&self) -> HashMap<AnchoredKey, Value> {
|
||||
self.pub_statements()
|
||||
.into_iter()
|
||||
.filter_map(|st| match st {
|
||||
Statement::Equal(ValueRef::Key(ak), ValueRef::Literal(v)) => Some((ak, v)),
|
||||
_ => None,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
/// Returns the deserialized Pod.
|
||||
fn deserialize_data(
|
||||
params: Params,
|
||||
data: serde_json::Value,
|
||||
vd_set: VDSet,
|
||||
id: Hash,
|
||||
) -> Result<Self, BackendError>
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
fn equals(&self, other: &dyn Pod) -> bool {
|
||||
self.equals_any(other as &dyn Any)
|
||||
}
|
||||
|
||||
fn verifier_data(&self) -> VerifierOnlyCircuitData;
|
||||
fn verifier_data_hash(&self) -> Hash {
|
||||
Hash(hash_verifier_data(&self.verifier_data()).elements)
|
||||
}
|
||||
/// Return a hash of the CommonCircuitData that uniquely identifies the circuit
|
||||
/// configuration and list of custom gates.
|
||||
fn common_hash(&self) -> String;
|
||||
fn proof(&self) -> Proof;
|
||||
fn vd_set(&self) -> &VDSet;
|
||||
}
|
||||
impl PartialEq for Box<dyn Pod> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
|
|
@ -1000,66 +968,24 @@ impl Eq for Box<dyn Pod> {}
|
|||
// impl Clone for Box<dyn Pod>
|
||||
dyn_clone::clone_trait_object!(Pod);
|
||||
|
||||
/// Trait for pods that are generated with a plonky2 circuit and that can be verified by a
|
||||
/// recursive MainPod circuit. A Pod implementing this trait does not necesarilly come from
|
||||
/// recursion: for example an introduction Pod in general is not recursive.
|
||||
pub trait RecursivePod: Pod {
|
||||
fn verifier_data(&self) -> VerifierOnlyCircuitData;
|
||||
/// Return a hash of the CommonCircuitData that uniquely identifies the circuit
|
||||
/// configuration and list of custom gates.
|
||||
fn common_hash(&self) -> String;
|
||||
fn proof(&self) -> Proof;
|
||||
fn vd_set(&self) -> &VDSet;
|
||||
|
||||
/// Returns the deserialized RecursivePod.
|
||||
fn deserialize_data(
|
||||
params: Params,
|
||||
data: serde_json::Value,
|
||||
vd_set: VDSet,
|
||||
id: PodId,
|
||||
) -> Result<Box<dyn RecursivePod>, BackendError>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
impl PartialEq for Box<dyn RecursivePod> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.equals(&**other)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Box<dyn RecursivePod> {}
|
||||
|
||||
// impl Clone for Box<dyn RecursivePod>
|
||||
dyn_clone::clone_trait_object!(RecursivePod);
|
||||
|
||||
pub trait PodSigner {
|
||||
fn sign(
|
||||
&self,
|
||||
params: &Params,
|
||||
kvs: &HashMap<Key, Value>,
|
||||
) -> Result<Box<dyn Pod>, BackendError>;
|
||||
pub trait Signer {
|
||||
fn sign(&self, msg: RawValue) -> Signature;
|
||||
fn public_key(&self) -> PublicKey;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MainPodInputs<'a> {
|
||||
pub signed_pods: &'a [&'a dyn Pod],
|
||||
pub recursive_pods: &'a [&'a dyn RecursivePod],
|
||||
pub pods: &'a [&'a dyn Pod],
|
||||
pub statements: &'a [Statement],
|
||||
pub operations: &'a [Operation],
|
||||
/// Statements that need to be made public (they can come from input pods or input
|
||||
/// statements)
|
||||
pub public_statements: &'a [Statement],
|
||||
// TODO: REMOVE THIS
|
||||
pub vd_set: VDSet,
|
||||
}
|
||||
|
||||
pub trait PodProver {
|
||||
fn prove(
|
||||
&self,
|
||||
params: &Params,
|
||||
vd_set: &VDSet,
|
||||
inputs: MainPodInputs,
|
||||
) -> Result<Box<dyn RecursivePod>, BackendError>;
|
||||
pub trait MainPodProver {
|
||||
fn prove(&self, params: &Params, inputs: MainPodInputs) -> Result<Box<dyn Pod>, BackendError>;
|
||||
}
|
||||
|
||||
pub trait ToFields {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue