From 34023913bff10efd3588eeb5c2bffb83e14828cc Mon Sep 17 00:00:00 2001 From: arnaucube Date: Tue, 1 Oct 2024 16:56:48 +0200 Subject: [PATCH] update Nova VerifierParams serializers to avoid serializing the R1CS to save big part of the old serialized size --- folding-schemes/src/folding/mod.rs | 27 +++----- .../src/folding/nova/decider_eth.rs | 10 ++- folding-schemes/src/folding/nova/mod.rs | 63 +++++++++++++++---- 3 files changed, 65 insertions(+), 35 deletions(-) diff --git a/folding-schemes/src/folding/mod.rs b/folding-schemes/src/folding/mod.rs index 91855b53..e66a3994 100644 --- a/folding-schemes/src/folding/mod.rs +++ b/folding-schemes/src/folding/mod.rs @@ -28,16 +28,13 @@ pub mod tests { #[test] fn test_serialize_ivc() { let poseidon_config = poseidon_canonical_config::(); - let f_circuit = CubicFCircuit::::new(()).unwrap(); + type FC = CubicFCircuit; + let f_circuit = FC::new(()).unwrap(); // test Nova - type N = Nova, Pedersen, Pedersen, false>; + type N = Nova, Pedersen, false>; let prep_param = NovaPreprocessorParam::new(poseidon_config.clone(), f_circuit); - test_serialize_ivc_opt::, N>( - "nova".to_string(), - prep_param.clone(), - ) - .unwrap(); + test_serialize_ivc_opt::("nova".to_string(), prep_param.clone()).unwrap(); // test HyperNova type HN = HyperNova< @@ -45,27 +42,19 @@ pub mod tests { GVar1, G2, GVar2, - CubicFCircuit, + FC, Pedersen, Pedersen, 1, // mu 1, // nu false, >; - test_serialize_ivc_opt::, HN>( - "hypernova".to_string(), - prep_param, - ) - .unwrap(); + test_serialize_ivc_opt::("hypernova".to_string(), prep_param).unwrap(); // test ProtoGalaxy - type P = ProtoGalaxy, Pedersen, Pedersen>; + type P = ProtoGalaxy, Pedersen>; let prep_param = (poseidon_config, f_circuit); - test_serialize_ivc_opt::, P>( - "protogalaxy".to_string(), - prep_param, - ) - .unwrap(); + test_serialize_ivc_opt::("protogalaxy".to_string(), prep_param).unwrap(); } fn test_serialize_ivc_opt< diff --git a/folding-schemes/src/folding/nova/decider_eth.rs b/folding-schemes/src/folding/nova/decider_eth.rs index 8ef02519..b6f9938e 100644 --- a/folding-schemes/src/folding/nova/decider_eth.rs +++ b/folding-schemes/src/folding/nova/decider_eth.rs @@ -75,8 +75,8 @@ impl DeciderTrait for Decider where C1: CurveGroup, - C2: CurveGroup, GC1: CurveVar> + ToConstraintFieldGadget>, + C2: CurveGroup, GC2: CurveVar> + ToConstraintFieldGadget>, FC: FCircuit, // CS1 is a KZG commitment, where challenge is C1::Fr elem @@ -495,8 +495,12 @@ pub mod tests { Projective2, KZG<'static, Bn254>, Pedersen, - >::deserialize_compressed( - &mut nova_vp_serialized.as_slice() + false, + >::deserialize_with_mode::, _>( + &mut nova_vp_serialized.as_slice(), + ark_serialize::Compress::Yes, + ark_serialize::Validate::Yes, + (), // fcircuit_params ) .unwrap(); diff --git a/folding-schemes/src/folding/nova/mod.rs b/folding-schemes/src/folding/nova/mod.rs index 2b2ac284..d1500c2c 100644 --- a/folding-schemes/src/folding/nova/mod.rs +++ b/folding-schemes/src/folding/nova/mod.rs @@ -8,7 +8,7 @@ use ark_ec::{CurveGroup, Group}; use ark_ff::{BigInteger, PrimeField}; use ark_r1cs_std::{groups::GroupOpsBounds, prelude::CurveVar, ToConstraintFieldGadget}; use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystem}; -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Valid}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError, Valid}; use ark_std::fmt::Debug; use ark_std::rand::RngCore; use ark_std::{One, UniformRand, Zero}; @@ -370,37 +370,73 @@ where mut writer: W, compress: ark_serialize::Compress, ) -> Result<(), ark_serialize::SerializationError> { - self.r1cs.serialize_with_mode(&mut writer, compress)?; - self.cf_r1cs.serialize_with_mode(&mut writer, compress)?; + self.cs_vp.serialize_with_mode(&mut writer, compress)?; self.cs_vp.serialize_with_mode(&mut writer, compress)?; self.cf_cs_vp.serialize_with_mode(&mut writer, compress) } fn serialized_size(&self, compress: ark_serialize::Compress) -> usize { - self.r1cs.serialized_size(compress) - + self.cf_r1cs.serialized_size(compress) - + self.cs_vp.serialized_size(compress) - + self.cf_cs_vp.serialized_size(compress) + self.cs_vp.serialized_size(compress) + self.cf_cs_vp.serialized_size(compress) } } -impl CanonicalDeserialize for VerifierParams +impl VerifierParams where C1: CurveGroup, C2: CurveGroup, + C1: CurveGroup, CS1: CommitmentScheme, CS2: CommitmentScheme, + ::BaseField: PrimeField, + ::BaseField: PrimeField, + ::ScalarField: Absorb, + ::ScalarField: Absorb, + C1: CurveGroup, { - fn deserialize_with_mode( + pub fn deserialize_with_mode( mut reader: R, compress: ark_serialize::Compress, validate: ark_serialize::Validate, - ) -> Result { - let r1cs = R1CS::deserialize_with_mode(&mut reader, compress, validate)?; - let cf_r1cs = R1CS::deserialize_with_mode(&mut reader, compress, validate)?; + fcircuit_params: FC::Params, + ) -> Result + where + GC1: CurveVar> + ToConstraintFieldGadget>, + GC2: CurveVar> + ToConstraintFieldGadget>, + FC: FCircuit, + for<'a> &'a GC1: GroupOpsBounds<'a, C1, GC1>, + for<'a> &'a GC2: GroupOpsBounds<'a, C2, GC2>, + { + let poseidon_config = poseidon_canonical_config::(); + + // generate the r1cs & cf_r1cs needed for the VerifierParams. In this way we avoid needing + // to serialize them, saving significant space in the VerifierParams serialized size. + + // main circuit R1CS: + let f_circuit = FC::new(fcircuit_params).or(Err(SerializationError::InvalidData))?; + let cs = ConstraintSystem::::new_ref(); + let augmented_F_circuit = + AugmentedFCircuit::::empty(&poseidon_config, f_circuit.clone()); + augmented_F_circuit + .generate_constraints(cs.clone()) + .or(Err(SerializationError::InvalidData))?; + cs.finalize(); + let cs = cs.into_inner().ok_or(SerializationError::InvalidData)?; + let r1cs = extract_r1cs::(&cs); + + // CycleFold circuit R1CS + let cs2 = ConstraintSystem::::new_ref(); + let cf_circuit = NovaCycleFoldCircuit::::empty(); + cf_circuit + .generate_constraints(cs2.clone()) + .or(Err(SerializationError::InvalidData))?; + cs2.finalize(); + let cs2 = cs2.into_inner().ok_or(SerializationError::InvalidData)?; + let cf_r1cs = extract_r1cs::(&cs2); + let cs_vp = CS1::VerifierParams::deserialize_with_mode(&mut reader, compress, validate)?; let cf_cs_vp = CS2::VerifierParams::deserialize_with_mode(&mut reader, compress, validate)?; + Ok(VerifierParams { - poseidon_config: poseidon_canonical_config::(), + poseidon_config, r1cs, cf_r1cs, cs_vp, @@ -959,6 +995,7 @@ where cs2.finalize(); let cs2 = cs2.into_inner().ok_or(Error::NoInnerConstraintSystem)?; let cf_r1cs = extract_r1cs::(&cs2); + Ok(Self { _gc1: PhantomData, _c2: PhantomData,