Add serialization support for PLONK verifying keys.

This commit is contained in:
Sean Bowe 2021-01-12 08:28:35 -07:00 committed by therealyingtong
parent a0d7998785
commit ba591c3b39
2 changed files with 70 additions and 3 deletions

View File

@ -6,7 +6,9 @@
//! [plonk]: https://eprint.iacr.org/2019/953
use crate::arithmetic::CurveAffine;
use crate::poly::{Coeff, EvaluationDomain, ExtendedLagrangeCoeff, LagrangeCoeff, Polynomial};
use crate::poly::{
commitment::Params, Coeff, EvaluationDomain, ExtendedLagrangeCoeff, LagrangeCoeff, Polynomial,
};
use crate::transcript::ChallengeScalar;
mod circuit;
@ -23,6 +25,8 @@ pub use keygen::*;
pub use prover::*;
pub use verifier::*;
use std::io;
/// This is a verifying key which allows for the verification of proofs for a
/// particular circuit.
#[derive(Debug)]
@ -33,6 +37,45 @@ pub struct VerifyingKey<C: CurveAffine> {
cs: ConstraintSystem<C::Scalar>,
}
impl<C: CurveAffine> VerifyingKey<C> {
/// Writes a verifying key to a buffer.
pub fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
for commitment in &self.fixed_commitments {
writer.write_all(&commitment.to_bytes())?;
}
for permutation in &self.permutations {
permutation.write(writer)?;
}
Ok(())
}
/// Reads a verification key from a buffer.
pub fn read<R: io::Read, ConcreteCircuit: Circuit<C::Scalar>>(
reader: &mut R,
params: &Params<C>,
) -> io::Result<Self> {
let (domain, cs, _) = keygen::create_domain::<C, ConcreteCircuit>(params);
let mut fixed_commitments = Vec::with_capacity(cs.num_fixed_columns);
for _ in 0..cs.num_fixed_columns {
fixed_commitments.push(C::read(reader)?);
}
let mut permutations = Vec::with_capacity(cs.permutations.len());
for argument in &cs.permutations {
permutations.push(permutation::VerifyingKey::read(reader, argument)?);
}
Ok(VerifyingKey {
domain,
fixed_commitments,
permutations,
cs,
})
}
}
/// This is a proving key which allows for the creation of proofs for a
/// particular circuit.
#[derive(Debug)]
@ -487,8 +530,11 @@ fn test_proving() {
let msm = guard.clone().use_challenges();
assert!(msm.clone().eval());
let mut transcript = DummyHashRead::init(&proof[..], Fq::one());
let guard =
verify_proof(&params, pk.get_vk(), msm, pubinput_slice, &mut transcript).unwrap();
let mut vk_buffer = vec![];
pk.get_vk().write(&mut vk_buffer).unwrap();
let vk = VerifyingKey::<EqAffine>::read::<_, MyCircuit<Fp>>(&mut &vk_buffer[..], &params)
.unwrap();
let guard = verify_proof(&params, &vk, msm, pubinput_slice, &mut transcript).unwrap();
{
let msm = guard.clone().use_challenges();
assert!(msm.eval());

View File

@ -10,6 +10,8 @@ pub(crate) mod keygen;
mod prover;
mod verifier;
use std::io;
/// A permutation argument.
#[derive(Debug, Clone)]
pub(crate) struct Argument {
@ -49,6 +51,25 @@ pub(crate) struct VerifyingKey<C: CurveAffine> {
commitments: Vec<C>,
}
impl<C: CurveAffine> VerifyingKey<C> {
pub(crate) fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
for commitment in &self.commitments {
commitment.write(writer)?;
}
Ok(())
}
pub(crate) fn read<R: io::Read>(reader: &mut R, argument: &Argument) -> io::Result<Self> {
let mut commitments = Vec::with_capacity(argument.columns.len());
for _ in 0..argument.columns.len() {
commitments.push(C::read(reader)?);
}
Ok(VerifyingKey { commitments })
}
}
/// The proving key for a single permutation argument.
#[derive(Debug)]
pub(crate) struct ProvingKey<C: CurveAffine> {