Serialization of Signed and Main Pods (#128)
This commit is contained in:
parent
fee70af12b
commit
9afc43675d
16 changed files with 817 additions and 189 deletions
|
|
@ -4,18 +4,19 @@ use std::{fmt, hash as h, iter, iter::zip};
|
|||
|
||||
use anyhow::{anyhow, Result};
|
||||
use plonky2::field::types::Field;
|
||||
|
||||
use crate::backends::plonky2::basetypes::HASH_SIZE;
|
||||
use crate::util::hashmap_insert_no_dupe;
|
||||
use schemars::JsonSchema;
|
||||
|
||||
use super::{
|
||||
hash_fields, AnchoredKey, Hash, NativePredicate, Params, PodId, Statement, StatementArg,
|
||||
ToFields, Value, F,
|
||||
};
|
||||
use crate::backends::plonky2::basetypes::HASH_SIZE;
|
||||
use crate::util::hashmap_insert_no_dupe;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
// BEGIN Custom 1b
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, h::Hash)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, h::Hash, Serialize, Deserialize, JsonSchema)]
|
||||
pub enum HashOrWildcard {
|
||||
Hash(Hash),
|
||||
Wildcard(usize),
|
||||
|
|
@ -59,7 +60,7 @@ impl ToFields for HashOrWildcard {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, h::Hash)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, h::Hash, Serialize, Deserialize, JsonSchema)]
|
||||
pub enum StatementTmplArg {
|
||||
None,
|
||||
Literal(Value),
|
||||
|
|
@ -145,7 +146,7 @@ impl fmt::Display for StatementTmplArg {
|
|||
// END
|
||||
|
||||
/// Statement Template for a Custom Predicate
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct StatementTmpl(pub Predicate, pub Vec<StatementTmplArg>);
|
||||
|
||||
impl StatementTmpl {
|
||||
|
|
@ -199,7 +200,7 @@ impl ToFields for StatementTmpl {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
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.
|
||||
|
|
@ -287,7 +288,7 @@ impl fmt::Display for CustomPredicate {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct CustomPredicateBatch {
|
||||
pub name: String,
|
||||
pub predicates: Vec<CustomPredicate>,
|
||||
|
|
@ -324,7 +325,7 @@ impl CustomPredicateBatch {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct CustomPredicateRef(pub Arc<CustomPredicateBatch>, pub usize);
|
||||
|
||||
impl CustomPredicateRef {
|
||||
|
|
@ -383,7 +384,8 @@ impl CustomPredicateRef {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(tag = "type", content = "value")]
|
||||
pub enum Predicate {
|
||||
Native(NativePredicate),
|
||||
BatchSelf(usize),
|
||||
|
|
|
|||
|
|
@ -5,14 +5,17 @@ mod basetypes;
|
|||
pub mod containers;
|
||||
mod custom;
|
||||
mod operation;
|
||||
pub mod serialization;
|
||||
mod statement;
|
||||
pub use basetypes::*;
|
||||
pub use custom::*;
|
||||
pub use operation::*;
|
||||
use schemars::JsonSchema;
|
||||
pub use statement::*;
|
||||
|
||||
use anyhow::Result;
|
||||
use dyn_clone::DynClone;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::any::Any;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
|
|
@ -32,7 +35,7 @@ impl fmt::Display for PodId {
|
|||
}
|
||||
|
||||
/// AnchoredKey is a tuple containing (OriginId: PodId, key: Hash)
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct AnchoredKey(pub PodId, pub Hash);
|
||||
|
||||
impl AnchoredKey {
|
||||
|
|
@ -54,7 +57,7 @@ impl fmt::Display for AnchoredKey {
|
|||
/// An entry consists of a key-value pair.
|
||||
pub type Entry = (String, Value);
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct PodId(pub Hash);
|
||||
|
||||
impl ToFields for PodId {
|
||||
|
|
@ -77,7 +80,7 @@ impl From<PodType> for Value {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Params {
|
||||
pub max_input_signed_pods: usize,
|
||||
pub max_input_main_pods: usize,
|
||||
|
|
@ -166,6 +169,15 @@ pub trait Pod: fmt::Debug + DynClone {
|
|||
}
|
||||
// Used for downcasting
|
||||
fn into_any(self: Box<Self>) -> Box<dyn Any>;
|
||||
// Front-end Pods keep references to middleware Pods. Most of 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
|
||||
// cannot be reconstructed. As such, we need to serialize it whenever
|
||||
// we serialize a front-end Pod. Since the front-end does not understand
|
||||
// the implementation details of the middleware, this method allows the
|
||||
// middleware to provide some serialized data that can be used to
|
||||
// reconstruct the proof.
|
||||
fn serialized_proof(&self) -> String;
|
||||
}
|
||||
|
||||
// impl Clone for Box<dyn SignedPod>
|
||||
|
|
@ -193,6 +205,9 @@ impl Pod for NonePod {
|
|||
fn into_any(self: Box<Self>) -> Box<dyn Any> {
|
||||
self
|
||||
}
|
||||
fn serialized_proof(&self) -> String {
|
||||
"".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
use std::fmt;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use log::error;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
use super::{CustomPredicateRef, NativePredicate, Statement, StatementArg};
|
||||
use crate::middleware::{AnchoredKey, Params, Predicate, Value, SELF};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum OperationType {
|
||||
Native(NativeOperation),
|
||||
Custom(CustomPredicateRef),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum NativeOperation {
|
||||
None = 0,
|
||||
NewEntry = 1,
|
||||
|
|
@ -91,7 +91,7 @@ pub enum Operation {
|
|||
}
|
||||
|
||||
impl Operation {
|
||||
pub fn code(&self) -> OperationType {
|
||||
pub fn predicate(&self) -> OperationType {
|
||||
type OT = OperationType;
|
||||
use NativeOperation::*;
|
||||
match self {
|
||||
|
|
@ -178,7 +178,7 @@ impl Operation {
|
|||
/// The outer Result is error handling
|
||||
pub fn output_statement(&self) -> Result<Option<Statement>> {
|
||||
use Statement::*;
|
||||
let pred: Option<Predicate> = self.code().output_predicate();
|
||||
let pred: Option<Predicate> = self.predicate().output_predicate();
|
||||
|
||||
let st_args: Option<Vec<StatementArg>> = match self {
|
||||
Self::None => Some(vec![]),
|
||||
|
|
@ -404,7 +404,7 @@ impl Operation {
|
|||
impl fmt::Display for Operation {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
writeln!(f, "middleware::Operation:")?;
|
||||
writeln!(f, " {:?} ", self.code())?;
|
||||
writeln!(f, " {:?} ", self.predicate())?;
|
||||
for arg in self.args().iter() {
|
||||
writeln!(f, " {}", arg)?;
|
||||
}
|
||||
|
|
|
|||
69
src/middleware/serialization.rs
Normal file
69
src/middleware/serialization.rs
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
use plonky2::field::types::Field;
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::{F, HASH_SIZE, VALUE_SIZE};
|
||||
|
||||
fn serialize_field_tuple<S, const N: usize>(
|
||||
value: &[F; N],
|
||||
serializer: S,
|
||||
) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_str(&format!(
|
||||
"{:016x}{:016x}{:016x}{:016x}",
|
||||
value[0].0, value[1].0, value[2].0, value[3].0
|
||||
))
|
||||
}
|
||||
|
||||
fn deserialize_field_tuple<'de, D, const N: usize>(deserializer: D) -> Result<[F; N], D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let hex_str = String::deserialize(deserializer)?;
|
||||
|
||||
if !hex_str.chars().count() == 64 || !hex_str.chars().all(|c| c.is_ascii_hexdigit()) {
|
||||
return Err(serde::de::Error::custom(
|
||||
"Invalid hex string format - expected 64 hexadecimal characters",
|
||||
));
|
||||
}
|
||||
|
||||
let mut v = [F::ZERO; N];
|
||||
for i in 0..N {
|
||||
let start = i * 16;
|
||||
let end = start + 16;
|
||||
let hex_part = &hex_str[start..end];
|
||||
v[i] = F::from_canonical_u64(
|
||||
u64::from_str_radix(hex_part, 16).map_err(serde::de::Error::custom)?,
|
||||
);
|
||||
}
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
pub fn serialize_hash_tuple<S>(value: &[F; HASH_SIZE], serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serialize_field_tuple::<S, HASH_SIZE>(value, serializer)
|
||||
}
|
||||
|
||||
pub fn deserialize_hash_tuple<'de, D>(deserializer: D) -> Result<[F; HASH_SIZE], D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
deserialize_field_tuple::<D, HASH_SIZE>(deserializer)
|
||||
}
|
||||
|
||||
pub fn serialize_value_tuple<S>(value: &[F; VALUE_SIZE], serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serialize_field_tuple::<S, VALUE_SIZE>(value, serializer)
|
||||
}
|
||||
|
||||
pub fn deserialize_value_tuple<'de, D>(deserializer: D) -> Result<[F; VALUE_SIZE], D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
deserialize_field_tuple::<D, VALUE_SIZE>(deserializer)
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
use anyhow::{anyhow, Result};
|
||||
use plonky2::field::types::Field;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{fmt, iter};
|
||||
use strum_macros::FromRepr;
|
||||
|
||||
|
|
@ -9,7 +11,7 @@ pub const KEY_SIGNER: &str = "_signer";
|
|||
pub const KEY_TYPE: &str = "_type";
|
||||
pub const STATEMENT_ARG_F_LEN: usize = 8;
|
||||
|
||||
#[derive(Clone, Copy, Debug, FromRepr, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Copy, Debug, FromRepr, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
|
||||
pub enum NativePredicate {
|
||||
None = 0,
|
||||
ValueOf = 1,
|
||||
|
|
@ -203,7 +205,7 @@ impl fmt::Display for Statement {
|
|||
}
|
||||
|
||||
/// Statement argument type. Useful for statement decompositions.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum StatementArg {
|
||||
None,
|
||||
Literal(Value),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue