Skip to content

Commit

Permalink
update Nova VerifierParams serializers to avoid serializing the R1CS …
Browse files Browse the repository at this point in the history
…to save big part of the old serialized size
  • Loading branch information
arnaucube committed Oct 4, 2024
1 parent 99fdf04 commit 3402391
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 35 deletions.
27 changes: 8 additions & 19 deletions folding-schemes/src/folding/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,44 +28,33 @@ pub mod tests {
#[test]
fn test_serialize_ivc() {
let poseidon_config = poseidon_canonical_config::<Fr>();
let f_circuit = CubicFCircuit::<Fr>::new(()).unwrap();
type FC = CubicFCircuit<Fr>;
let f_circuit = FC::new(()).unwrap();

// test Nova
type N = Nova<G1, GVar1, G2, GVar2, CubicFCircuit<Fr>, Pedersen<G1>, Pedersen<G2>, false>;
type N = Nova<G1, GVar1, G2, GVar2, FC, Pedersen<G1>, Pedersen<G2>, false>;
let prep_param = NovaPreprocessorParam::new(poseidon_config.clone(), f_circuit);
test_serialize_ivc_opt::<G1, G2, CubicFCircuit<Fr>, N>(
"nova".to_string(),
prep_param.clone(),
)
.unwrap();
test_serialize_ivc_opt::<G1, G2, FC, N>("nova".to_string(), prep_param.clone()).unwrap();

// test HyperNova
type HN = HyperNova<
G1,
GVar1,
G2,
GVar2,
CubicFCircuit<Fr>,
FC,
Pedersen<G1>,
Pedersen<G2>,
1, // mu
1, // nu
false,
>;
test_serialize_ivc_opt::<G1, G2, CubicFCircuit<Fr>, HN>(
"hypernova".to_string(),
prep_param,
)
.unwrap();
test_serialize_ivc_opt::<G1, G2, FC, HN>("hypernova".to_string(), prep_param).unwrap();

// test ProtoGalaxy
type P = ProtoGalaxy<G1, GVar1, G2, GVar2, CubicFCircuit<Fr>, Pedersen<G1>, Pedersen<G2>>;
type P = ProtoGalaxy<G1, GVar1, G2, GVar2, FC, Pedersen<G1>, Pedersen<G2>>;
let prep_param = (poseidon_config, f_circuit);
test_serialize_ivc_opt::<G1, G2, CubicFCircuit<Fr>, P>(
"protogalaxy".to_string(),
prep_param,
)
.unwrap();
test_serialize_ivc_opt::<G1, G2, FC, P>("protogalaxy".to_string(), prep_param).unwrap();
}

fn test_serialize_ivc_opt<
Expand Down
10 changes: 7 additions & 3 deletions folding-schemes/src/folding/nova/decider_eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ impl<C1, GC1, C2, GC2, FC, CS1, CS2, S, FS> DeciderTrait<C1, C2, FC, FS>
for Decider<C1, GC1, C2, GC2, FC, CS1, CS2, S, FS>
where
C1: CurveGroup,
C2: CurveGroup,
GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>,
C2: CurveGroup,
GC2: CurveVar<C2, CF2<C2>> + ToConstraintFieldGadget<CF2<C2>>,
FC: FCircuit<C1::ScalarField>,
// CS1 is a KZG commitment, where challenge is C1::Fr elem
Expand Down Expand Up @@ -495,8 +495,12 @@ pub mod tests {
Projective2,
KZG<'static, Bn254>,
Pedersen<Projective2>,
>::deserialize_compressed(
&mut nova_vp_serialized.as_slice()
false,
>::deserialize_with_mode::<GVar, GVar2, CubicFCircuit<Fr>, _>(
&mut nova_vp_serialized.as_slice(),
ark_serialize::Compress::Yes,
ark_serialize::Validate::Yes,
(), // fcircuit_params
)
.unwrap();

Expand Down
63 changes: 50 additions & 13 deletions folding-schemes/src/folding/nova/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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<C1, C2, CS1, CS2, const H: bool> CanonicalDeserialize for VerifierParams<C1, C2, CS1, CS2, H>
impl<C1, C2, CS1, CS2, const H: bool> VerifierParams<C1, C2, CS1, CS2, H>
where
C1: CurveGroup,
C2: CurveGroup,
C1: CurveGroup<BaseField = C2::ScalarField, ScalarField = C2::BaseField>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
<C1 as CurveGroup>::BaseField: PrimeField,
<C2 as CurveGroup>::BaseField: PrimeField,
<C1 as Group>::ScalarField: Absorb,
<C2 as Group>::ScalarField: Absorb,
C1: CurveGroup<BaseField = C2::ScalarField, ScalarField = C2::BaseField>,
{
fn deserialize_with_mode<R: std::io::prelude::Read>(
pub fn deserialize_with_mode<GC1, GC2, FC, R: std::io::prelude::Read>(
mut reader: R,
compress: ark_serialize::Compress,
validate: ark_serialize::Validate,
) -> Result<Self, ark_serialize::SerializationError> {
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<Self, SerializationError>
where
GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>,
GC2: CurveVar<C2, CF2<C2>> + ToConstraintFieldGadget<CF2<C2>>,
FC: FCircuit<C1::ScalarField>,
for<'a> &'a GC1: GroupOpsBounds<'a, C1, GC1>,
for<'a> &'a GC2: GroupOpsBounds<'a, C2, GC2>,
{
let poseidon_config = poseidon_canonical_config::<C1::ScalarField>();

// 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::<C1::ScalarField>::new_ref();
let augmented_F_circuit =
AugmentedFCircuit::<C1, C2, GC2, FC>::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::<C1::ScalarField>(&cs);

// CycleFold circuit R1CS
let cs2 = ConstraintSystem::<C1::BaseField>::new_ref();
let cf_circuit = NovaCycleFoldCircuit::<C1, GC1>::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::<C1::BaseField>(&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::<C1::ScalarField>(),
poseidon_config,
r1cs,
cf_r1cs,
cs_vp,
Expand Down Expand Up @@ -959,6 +995,7 @@ where
cs2.finalize();
let cs2 = cs2.into_inner().ok_or(Error::NoInnerConstraintSystem)?;
let cf_r1cs = extract_r1cs::<C1::BaseField>(&cs2);

Ok(Self {
_gc1: PhantomData,
_c2: PhantomData,
Expand Down

0 comments on commit 3402391

Please sign in to comment.