diff --git a/plonk/Cargo.toml b/plonk/Cargo.toml index 365e2a585..55bd423ee 100644 --- a/plonk/Cargo.toml +++ b/plonk/Cargo.toml @@ -49,6 +49,7 @@ ark-ed-on-bn254 = "0.4.0" criterion = { version = "0.5", features = ["async", "async_tokio"] } hex = "^0.4.3" lazy_static = "1.4" +serde_json = "1.0" tokio = "1.33" # Benchmarks diff --git a/plonk/src/proof_system/proof_linking.rs b/plonk/src/proof_system/proof_linking.rs index 3fb7aaa65..2f5e45005 100644 --- a/plonk/src/proof_system/proof_linking.rs +++ b/plonk/src/proof_system/proof_linking.rs @@ -8,6 +8,7 @@ use ark_ec::{ }; use ark_ff::{Field, One, Zero}; use ark_poly::{univariate::DensePolynomial, DenseUVPolynomial}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use jf_primitives::{ pcs::{ prelude::{Commitment, UnivariateKzgPCS, UnivariateKzgProof}, @@ -19,6 +20,7 @@ use mpc_relation::{ gadgets::ecc::SWToTEConParam, proof_linking::{GroupLayout, PROOF_LINK_WIRE_IDX}, }; +use serde::{Deserialize, Serialize}; use crate::{errors::PlonkError, transcript::PlonkTranscript}; @@ -28,7 +30,7 @@ use super::{ }; /// A proof that two circuits are linked on a given domain -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq, Eq, CanonicalSerialize, CanonicalDeserialize)] pub struct LinkingProof { /// The commitment to the linking quotient polynomial pub quotient_commitment: Commitment, @@ -36,6 +38,28 @@ pub struct LinkingProof { pub opening_proof: UnivariateKzgProof, } +impl Serialize for LinkingProof { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut bytes = Vec::new(); + self.serialize_compressed(&mut bytes).map_err(serde::ser::Error::custom)?; + + serializer.serialize_bytes(&bytes) + } +} + +impl<'de, E: Pairing> Deserialize<'de> for LinkingProof { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let bytes = >::deserialize(deserializer)?; + Self::deserialize_compressed(bytes.as_slice()).map_err(serde::de::Error::custom) + } +} + // ---------- // | Prover | // ---------- @@ -407,8 +431,10 @@ pub mod test_helpers { #[cfg(test)] mod test { use ark_bn254::{Bn254, Fr as FrBn254}; + use ark_ec::pairing::Pairing; use ark_std::UniformRand; use itertools::Itertools; + use jf_primitives::pcs::prelude::UnivariateKzgProof; use mpc_relation::{ proof_linking::{GroupLayout, LinkableCircuit}, PlonkCircuit, @@ -424,9 +450,12 @@ mod test { transcript::SolidityTranscript, }; - use super::test_helpers::{ - gen_commit_keys, gen_proving_keys, gen_test_circuit1, gen_test_circuit2, CircuitSelector, - GROUP_NAME, + use super::{ + test_helpers::{ + gen_commit_keys, gen_proving_keys, gen_test_circuit1, gen_test_circuit2, + CircuitSelector, GROUP_NAME, + }, + LinkingProof, }; // ----------- @@ -493,6 +522,22 @@ mod test { // | Test Cases | // -------------- + /// Tests serialization and deserialization of a linking proof + #[test] + fn test_serde() { + let mut rng = thread_rng(); + let commitment = ::G1Affine::rand(&mut rng).into(); + let opening = UnivariateKzgProof { proof: ::G1Affine::rand(&mut rng) }; + + let proof = + LinkingProof:: { quotient_commitment: commitment, opening_proof: opening }; + + let bytes = serde_json::to_vec(&proof).unwrap(); + let recovered = serde_json::from_slice(&bytes).unwrap(); + + assert_eq!(proof, recovered); + } + /// Tests a linking proof between two circuits that correctly use the same /// values in the linking domain #[test]