Proof serialization (#93)

Using `serde_cbor` for now. It's probably far from optimal, as we have many `Vec`s which I assume it will prefix with their lengths, but it's a nice and easy method for now.
This commit is contained in:
Daniel Lubarov 2021-07-15 07:35:12 -07:00 committed by GitHub
parent 83a1430038
commit 77ce69dc15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 45 additions and 12 deletions

View File

@ -21,6 +21,8 @@ rand_chacha = "0.2.2"
rayon = "1.5.0"
unroll = "0.1.5"
anyhow = "1.0.40"
serde = { version = "1.0", features = ["derive"] }
serde_cbor = "0.11.1"
[profile.release]
opt-level = 3

View File

@ -1,4 +1,5 @@
use env_logger::Env;
use log::info;
use plonky2::circuit_builder::CircuitBuilder;
use plonky2::circuit_data::CircuitConfig;
use plonky2::field::crandall_field::CrandallField;
@ -25,10 +26,10 @@ fn bench_prove<F: Field + Extendable<D>, const D: usize>() {
rate_bits: 3,
num_challenges: 3,
fri_config: FriConfig {
proof_of_work_bits: 1,
proof_of_work_bits: 10,
rate_bits: 3,
reduction_arity_bits: vec![2, 2, 2, 2, 2],
num_query_rounds: 1,
num_query_rounds: 35,
},
};
@ -46,7 +47,10 @@ fn bench_prove<F: Field + Extendable<D>, const D: usize>() {
builder.add(zero, zero);
builder.add_extension(zero_ext, zero_ext);
let prover = builder.build_prover();
let circuit = builder.build();
let inputs = PartialWitness::new();
prover.prove(inputs);
let proof = circuit.prove(inputs);
let proof_bytes = serde_cbor::to_vec(&proof).unwrap();
info!("Proof length: {} bytes", proof_bytes.len());
circuit.verify(proof).unwrap();
}

View File

@ -38,7 +38,7 @@ impl Default for CircuitConfig {
num_challenges: 3,
fri_config: FriConfig {
proof_of_work_bits: 1,
rate_bits: 1,
rate_bits: 3,
reduction_arity_bits: vec![1, 1, 1, 1],
num_query_rounds: 1,
},

View File

@ -5,6 +5,7 @@ use std::iter::{Product, Sum};
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use num::Integer;
use serde::{Deserialize, Serialize};
use crate::field::extension_field::quadratic::QuadraticCrandallField;
use crate::field::extension_field::quartic::QuarticCrandallField;
@ -106,7 +107,7 @@ const CAUCHY_MDS_8: [[CrandallField; 8]; 8] = [
/// = 2**64 - 9 * 2**28 + 1
/// = 2**28 * (2**36 - 9) + 1
/// ```
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Serialize, Deserialize)]
pub struct CrandallField(pub u64);
impl PartialEq for CrandallField {

View File

@ -4,12 +4,13 @@ use std::iter::{Product, Sum};
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use rand::Rng;
use serde::{Deserialize, Serialize};
use crate::field::crandall_field::CrandallField;
use crate::field::extension_field::{FieldExtension, Frobenius, OEF};
use crate::field::field::Field;
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub struct QuadraticCrandallField([CrandallField; 2]);
impl OEF<2> for QuadraticCrandallField {

View File

@ -4,13 +4,14 @@ use std::iter::{Product, Sum};
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use rand::Rng;
use serde::{Deserialize, Serialize};
use crate::field::crandall_field::CrandallField;
use crate::field::extension_field::{FieldExtension, Frobenius, OEF};
use crate::field::field::Field;
/// A quartic extension of `CrandallField`.
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub struct QuarticCrandallField(pub(crate) [CrandallField; 4]);
impl OEF<4> for QuarticCrandallField {

View File

@ -6,6 +6,8 @@ use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssi
use num::Integer;
use rand::Rng;
use serde::de::DeserializeOwned;
use serde::Serialize;
use crate::field::extension_field::Frobenius;
use crate::util::bits_u64;
@ -31,6 +33,8 @@ pub trait Field:
+ Display
+ Send
+ Sync
+ Serialize
+ DeserializeOwned
{
type PrimeField: Field;

View File

@ -1,4 +1,5 @@
use anyhow::{ensure, Result};
use serde::{Deserialize, Serialize};
use crate::circuit_builder::CircuitBuilder;
use crate::field::extension_field::Extendable;
@ -10,7 +11,8 @@ use crate::proof::{Hash, HashTarget};
use crate::target::Target;
use crate::wire::Wire;
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(bound = "")]
pub struct MerkleProof<F: Field> {
/// The Merkle digest of each sibling subtree, staying from the bottommost layer.
pub siblings: Vec<Hash<F>>,

View File

@ -1,5 +1,6 @@
use anyhow::Result;
use rayon::prelude::*;
use serde::{Deserialize, Serialize};
use crate::circuit_data::CommonCircuitData;
use crate::field::extension_field::Extendable;
@ -245,6 +246,8 @@ impl<F: Field> ListPolynomialCommitment<F> {
}
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(bound = "")]
pub struct OpeningProof<F: Field + Extendable<D>, const D: usize> {
fri_proof: FriProof<F, D>,
// TODO: Get the degree from `CommonCircuitData` instead.

View File

@ -3,6 +3,7 @@ use std::iter::Sum;
use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign};
use anyhow::{ensure, Result};
use serde::{Deserialize, Serialize};
use crate::field::extension_field::Extendable;
use crate::field::fft::{fft, fft_with_options, ifft};
@ -76,7 +77,8 @@ impl<F: Field> From<Vec<F>> for PolynomialValues<F> {
}
/// A polynomial in coefficient form.
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(bound = "")]
pub struct PolynomialCoeffs<F: Field> {
pub(crate) coeffs: Vec<F>,
}

View File

@ -1,5 +1,7 @@
use std::convert::TryInto;
use serde::{Deserialize, Serialize};
use crate::circuit_data::CommonCircuitData;
use crate::field::extension_field::target::ExtensionTarget;
use crate::field::extension_field::Extendable;
@ -12,7 +14,8 @@ use crate::polynomial::polynomial::PolynomialCoeffs;
use crate::target::Target;
/// Represents a ~256 bit hash output.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(bound = "")]
pub struct Hash<F: Field> {
pub(crate) elements: [F; 4],
}
@ -61,6 +64,8 @@ impl HashTarget {
}
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(bound = "")]
pub struct Proof<F: Field + Extendable<D>, const D: usize> {
/// Merkle root of LDEs of wire values.
pub wires_root: Hash<F>,
@ -83,6 +88,8 @@ pub struct ProofTarget<const D: usize> {
}
/// Evaluations and Merkle proof produced by the prover in a FRI query step.
#[derive(Serialize, Deserialize, Debug)]
#[serde(bound = "")]
pub struct FriQueryStep<F: Field + Extendable<D>, const D: usize> {
pub evals: Vec<F::Extension>,
pub merkle_proof: MerkleProof<F>,
@ -95,6 +102,8 @@ pub struct FriQueryStepTarget<const D: usize> {
/// Evaluations and Merkle proofs of the original set of polynomials,
/// before they are combined into a composition polynomial.
#[derive(Serialize, Deserialize, Debug)]
#[serde(bound = "")]
pub struct FriInitialTreeProof<F: Field> {
pub evals_proofs: Vec<(Vec<F>, MerkleProof<F>)>,
}
@ -118,6 +127,8 @@ impl FriInitialTreeProofTarget {
}
/// Proof for a FRI query round.
#[derive(Serialize, Deserialize, Debug)]
#[serde(bound = "")]
pub struct FriQueryRound<F: Field + Extendable<D>, const D: usize> {
pub initial_trees_proof: FriInitialTreeProof<F>,
pub steps: Vec<FriQueryStep<F, D>>,
@ -128,6 +139,8 @@ pub struct FriQueryRoundTarget<const D: usize> {
pub steps: Vec<FriQueryStepTarget<D>>,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(bound = "")]
pub struct FriProof<F: Field + Extendable<D>, const D: usize> {
/// A Merkle root for each reduced polynomial in the commit phase.
pub commit_phase_merkle_roots: Vec<Hash<F>>,
@ -146,7 +159,7 @@ pub struct FriProofTarget<const D: usize> {
pub pow_witness: Target,
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Serialize, Deserialize)]
/// The purported values of each polynomial at a single point.
pub struct OpeningSet<F: Field + Extendable<D>, const D: usize> {
pub constants: Vec<F::Extension>,