Browse Source

Enable hiding commitments in nova and hypernova (#129)

* feat: enable hiding commitments in nova and hypernova

* fix: set blinding values for witness vector

* fix: remove cloning of the cyclefold running instance

* fix: do not re-use blinding values between prove steps

* fix: specify whether the witness should use blinding values using a
const generic

* feat: create a `dummy` method for nova witnesses as well

* chore: clippy - removed unused imports
main
Pierre 4 months ago
committed by GitHub
parent
commit
21ff3cf1ab
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
21 changed files with 349 additions and 198 deletions
  1. +2
    -1
      examples/circom_full_flow.rs
  2. +1
    -0
      examples/external_inputs.rs
  3. +2
    -1
      examples/full_flow.rs
  4. +1
    -0
      examples/multi_inputs.rs
  5. +1
    -0
      examples/sha256.rs
  6. +9
    -7
      folding-schemes/src/folding/circuits/cyclefold.rs
  7. +1
    -1
      folding-schemes/src/folding/hypernova/cccs.rs
  8. +12
    -6
      folding-schemes/src/folding/hypernova/circuits.rs
  9. +7
    -3
      folding-schemes/src/folding/hypernova/lcccs.rs
  10. +98
    -42
      folding-schemes/src/folding/hypernova/mod.rs
  11. +10
    -10
      folding-schemes/src/folding/hypernova/nimfs.rs
  12. +2
    -2
      folding-schemes/src/folding/hypernova/utils.rs
  13. +14
    -10
      folding-schemes/src/folding/nova/decider_eth.rs
  14. +15
    -15
      folding-schemes/src/folding/nova/decider_eth_circuit.rs
  15. +131
    -65
      folding-schemes/src/folding/nova/mod.rs
  16. +20
    -17
      folding-schemes/src/folding/nova/nifs.rs
  17. +10
    -8
      folding-schemes/src/folding/nova/serialize.rs
  18. +2
    -2
      folding-schemes/src/folding/nova/traits.rs
  19. +2
    -0
      folding-schemes/src/lib.rs
  20. +3
    -3
      folding-schemes/src/utils/mod.rs
  21. +6
    -5
      solidity-verifiers/src/verifiers/nova_cyclefold.rs

+ 2
- 1
examples/circom_full_flow.rs

@ -64,7 +64,8 @@ fn main() {
let f_circuit_params = (r1cs_path, wasm_path, 1, 2); let f_circuit_params = (r1cs_path, wasm_path, 1, 2);
let f_circuit = CircomFCircuit::<Fr>::new(f_circuit_params).unwrap(); let f_circuit = CircomFCircuit::<Fr>::new(f_circuit_params).unwrap();
pub type N = Nova<G1, GVar, G2, GVar2, CircomFCircuit<Fr>, KZG<'static, Bn254>, Pedersen<G2>>;
pub type N =
Nova<G1, GVar, G2, GVar2, CircomFCircuit<Fr>, KZG<'static, Bn254>, Pedersen<G2>, false>;
pub type D = DeciderEth< pub type D = DeciderEth<
G1, G1,
GVar, GVar,

+ 1
- 0
examples/external_inputs.rs

@ -181,6 +181,7 @@ fn main() {
ExternalInputsCircuit<Fr>, ExternalInputsCircuit<Fr>,
KZG<'static, Bn254>, KZG<'static, Bn254>,
Pedersen<Projective2>, Pedersen<Projective2>,
false,
>; >;
let mut rng = rand::rngs::OsRng; let mut rng = rand::rngs::OsRng;

+ 2
- 1
examples/full_flow.rs

@ -81,7 +81,8 @@ fn main() {
let f_circuit = CubicFCircuit::<Fr>::new(()).unwrap(); let f_circuit = CubicFCircuit::<Fr>::new(()).unwrap();
pub type N = Nova<G1, GVar, G2, GVar2, CubicFCircuit<Fr>, KZG<'static, Bn254>, Pedersen<G2>>;
pub type N =
Nova<G1, GVar, G2, GVar2, CubicFCircuit<Fr>, KZG<'static, Bn254>, Pedersen<G2>, false>;
pub type D = DeciderEth< pub type D = DeciderEth<
G1, G1,
GVar, GVar,

+ 1
- 0
examples/multi_inputs.rs

@ -137,6 +137,7 @@ fn main() {
MultiInputsFCircuit<Fr>, MultiInputsFCircuit<Fr>,
KZG<'static, Bn254>, KZG<'static, Bn254>,
Pedersen<Projective2>, Pedersen<Projective2>,
false,
>; >;
println!("Prepare Nova ProverParams & VerifierParams"); println!("Prepare Nova ProverParams & VerifierParams");

+ 1
- 0
examples/sha256.rs

@ -119,6 +119,7 @@ fn main() {
Sha256FCircuit<Fr>, Sha256FCircuit<Fr>,
KZG<'static, Bn254>, KZG<'static, Bn254>,
Pedersen<Projective2>, Pedersen<Projective2>,
false,
>; >;
let poseidon_config = poseidon_canonical_config::<Fr>(); let poseidon_config = poseidon_canonical_config::<Fr>();

+ 9
- 7
folding-schemes/src/folding/circuits/cyclefold.rs

@ -16,6 +16,7 @@ use ark_relations::r1cs::{
ConstraintSynthesizer, ConstraintSystem, ConstraintSystemRef, Namespace, SynthesisError, ConstraintSynthesizer, ConstraintSystem, ConstraintSystemRef, Namespace, SynthesisError,
}; };
use ark_std::fmt::Debug; use ark_std::fmt::Debug;
use ark_std::rand::RngCore;
use ark_std::Zero; use ark_std::Zero;
use core::{borrow::Borrow, marker::PhantomData}; use core::{borrow::Borrow, marker::PhantomData};
@ -382,7 +383,7 @@ where
/// scheme struct because it is used both by Nova & HyperNova's CycleFold. /// scheme struct because it is used both by Nova & HyperNova's CycleFold.
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn fold_cyclefold_circuit<C1, GC1, C2, GC2, FC, CS1, CS2>(
pub fn fold_cyclefold_circuit<C1, GC1, C2, GC2, FC, CS1, CS2, const H: bool>(
_n_points: usize, _n_points: usize,
transcript: &mut impl Transcript<C1::ScalarField>, transcript: &mut impl Transcript<C1::ScalarField>,
cf_r1cs: R1CS<C2::ScalarField>, cf_r1cs: R1CS<C2::ScalarField>,
@ -392,6 +393,7 @@ pub fn fold_cyclefold_circuit(
cf_U_i: CommittedInstance<C2>, // running instance cf_U_i: CommittedInstance<C2>, // running instance
cf_u_i_x: Vec<C2::ScalarField>, cf_u_i_x: Vec<C2::ScalarField>,
cf_circuit: CycleFoldCircuit<C1, GC1>, cf_circuit: CycleFoldCircuit<C1, GC1>,
mut rng: impl RngCore,
) -> Result< ) -> Result<
( (
Witness<C2>, Witness<C2>,
@ -409,8 +411,8 @@ where
C2: CurveGroup, C2: CurveGroup,
GC2: CurveVar<C2, CF2<C2>> + ToConstraintFieldGadget<CF2<C2>>, GC2: CurveVar<C2, CF2<C2>> + ToConstraintFieldGadget<CF2<C2>>,
FC: FCircuit<C1::ScalarField>, FC: FCircuit<C1::ScalarField>,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
<C1 as CurveGroup>::BaseField: PrimeField, <C1 as CurveGroup>::BaseField: PrimeField,
<C2 as CurveGroup>::BaseField: PrimeField, <C2 as CurveGroup>::BaseField: PrimeField,
<C1 as Group>::ScalarField: Absorb, <C1 as Group>::ScalarField: Absorb,
@ -432,11 +434,11 @@ where
assert_eq!(cf_x_i.len(), cf_io_len(_n_points)); assert_eq!(cf_x_i.len(), cf_io_len(_n_points));
// fold cyclefold instances // fold cyclefold instances
let cf_w_i = Witness::<C2>::new(cf_w_i.clone(), cf_r1cs.A.n_rows);
let cf_u_i: CommittedInstance<C2> = cf_w_i.commit::<CS2>(&cf_cs_params, cf_x_i.clone())?;
let cf_w_i = Witness::<C2>::new::<H>(cf_w_i.clone(), cf_r1cs.A.n_rows, &mut rng);
let cf_u_i: CommittedInstance<C2> = cf_w_i.commit::<CS2, H>(&cf_cs_params, cf_x_i.clone())?;
// compute T* and cmT* for CycleFoldCircuit // compute T* and cmT* for CycleFoldCircuit
let (cf_T, cf_cmT) = NIFS::<C2, CS2>::compute_cyclefold_cmT(
let (cf_T, cf_cmT) = NIFS::<C2, CS2, H>::compute_cyclefold_cmT(
&cf_cs_params, &cf_cs_params,
&cf_r1cs, &cf_r1cs,
&cf_w_i, &cf_w_i,
@ -455,7 +457,7 @@ where
let cf_r_Fq = C1::BaseField::from_bigint(BigInteger::from_bits_le(&cf_r_bits)) let cf_r_Fq = C1::BaseField::from_bigint(BigInteger::from_bits_le(&cf_r_bits))
.expect("cf_r_bits out of bounds"); .expect("cf_r_bits out of bounds");
let (cf_W_i1, cf_U_i1) = NIFS::<C2, CS2>::fold_instances(
let (cf_W_i1, cf_U_i1) = NIFS::<C2, CS2, H>::fold_instances(
cf_r_Fq, &cf_W_i, &cf_U_i, &cf_w_i, &cf_u_i, &cf_T, cf_cmT, cf_r_Fq, &cf_W_i, &cf_U_i, &cf_w_i, &cf_u_i, &cf_T, cf_cmT,
)?; )?;
Ok((cf_w_i, cf_u_i, cf_W_i1, cf_U_i1, cf_cmT, cf_r_Fq)) Ok((cf_w_i, cf_u_i, cf_W_i1, cf_U_i1, cf_cmT, cf_r_Fq))

+ 1
- 1
folding-schemes/src/folding/hypernova/cccs.rs

@ -26,7 +26,7 @@ pub struct CCCS {
} }
impl<F: PrimeField> CCS<F> { impl<F: PrimeField> CCS<F> {
pub fn to_cccs<R: Rng, C: CurveGroup, CS: CommitmentScheme<C>>(
pub fn to_cccs<R: Rng, C: CurveGroup, CS: CommitmentScheme<C, H>, const H: bool>(
&self, &self,
rng: &mut R, rng: &mut R,
cs_params: &CS::ProverParams, cs_params: &CS::ProverParams,

+ 12
- 6
folding-schemes/src/folding/hypernova/circuits.rs

@ -949,7 +949,7 @@ mod tests {
let mut lcccs_instances = Vec::new(); let mut lcccs_instances = Vec::new();
for z_i in z_lcccs.iter() { for z_i in z_lcccs.iter() {
let (inst, _) = ccs let (inst, _) = ccs
.to_lcccs::<_, _, Pedersen<Projective>>(&mut rng, &pedersen_params, z_i)
.to_lcccs::<_, _, Pedersen<Projective, true>, true>(&mut rng, &pedersen_params, z_i)
.unwrap(); .unwrap();
lcccs_instances.push(inst); lcccs_instances.push(inst);
} }
@ -957,7 +957,7 @@ mod tests {
let mut cccs_instances = Vec::new(); let mut cccs_instances = Vec::new();
for z_i in z_cccs.iter() { for z_i in z_cccs.iter() {
let (inst, _) = ccs let (inst, _) = ccs
.to_cccs::<_, _, Pedersen<Projective>>(&mut rng, &pedersen_params, z_i)
.to_cccs::<_, _, Pedersen<Projective>, false>(&mut rng, &pedersen_params, z_i)
.unwrap(); .unwrap();
cccs_instances.push(inst); cccs_instances.push(inst);
} }
@ -1045,7 +1045,11 @@ mod tests {
let mut w_lcccs = Vec::new(); let mut w_lcccs = Vec::new();
for z_i in z_lcccs.iter() { for z_i in z_lcccs.iter() {
let (running_instance, w) = ccs let (running_instance, w) = ccs
.to_lcccs::<_, _, Pedersen<Projective>>(&mut rng, &pedersen_params, z_i)
.to_lcccs::<_, _, Pedersen<Projective, false>, false>(
&mut rng,
&pedersen_params,
z_i,
)
.unwrap(); .unwrap();
lcccs_instances.push(running_instance); lcccs_instances.push(running_instance);
w_lcccs.push(w); w_lcccs.push(w);
@ -1055,7 +1059,7 @@ mod tests {
let mut w_cccs = Vec::new(); let mut w_cccs = Vec::new();
for z_i in z_cccs.iter() { for z_i in z_cccs.iter() {
let (new_instance, w) = ccs let (new_instance, w) = ccs
.to_cccs::<_, _, Pedersen<Projective>>(&mut rng, &pedersen_params, z_i)
.to_cccs::<_, _, Pedersen<Projective>, false>(&mut rng, &pedersen_params, z_i)
.unwrap(); .unwrap();
cccs_instances.push(new_instance); cccs_instances.push(new_instance);
w_cccs.push(w); w_cccs.push(w);
@ -1139,7 +1143,7 @@ mod tests {
let z_0 = vec![Fr::from(3_u32)]; let z_0 = vec![Fr::from(3_u32)];
let z_i = vec![Fr::from(3_u32)]; let z_i = vec![Fr::from(3_u32)];
let (lcccs, _) = ccs let (lcccs, _) = ccs
.to_lcccs::<_, _, Pedersen<Projective>>(&mut rng, &pedersen_params, &z1)
.to_lcccs::<_, _, Pedersen<Projective, true>, true>(&mut rng, &pedersen_params, &z1)
.unwrap(); .unwrap();
let h = lcccs let h = lcccs
.clone() .clone()
@ -1378,6 +1382,7 @@ mod tests {
CubicFCircuit<Fr>, CubicFCircuit<Fr>,
Pedersen<Projective>, Pedersen<Projective>,
Pedersen<Projective2>, Pedersen<Projective2>,
false,
>( >(
mu + nu, mu + nu,
&mut transcript_p, &mut transcript_p,
@ -1388,6 +1393,7 @@ mod tests {
cf_U_i.clone(), // CycleFold running instance cf_U_i.clone(), // CycleFold running instance
cf_u_i_x, // CycleFold incoming instance cf_u_i_x, // CycleFold incoming instance
cf_circuit, cf_circuit,
&mut rng,
) )
.unwrap(); .unwrap();
@ -1439,7 +1445,7 @@ mod tests {
// compute committed instances, w_{i+1}, u_{i+1}, which will be used as w_i, u_i, so we // compute committed instances, w_{i+1}, u_{i+1}, which will be used as w_i, u_i, so we
// assign them directly to w_i, u_i. // assign them directly to w_i, u_i.
(u_i, w_i) = ccs (u_i, w_i) = ccs
.to_cccs::<_, _, Pedersen<Projective>>(&mut rng, &pedersen_params, &r1cs_z)
.to_cccs::<_, _, Pedersen<Projective>, false>(&mut rng, &pedersen_params, &r1cs_z)
.unwrap(); .unwrap();
u_i.check_relation(&ccs, &w_i).unwrap(); u_i.check_relation(&ccs, &w_i).unwrap();

+ 7
- 3
folding-schemes/src/folding/hypernova/lcccs.rs

@ -30,7 +30,7 @@ pub struct LCCCS {
} }
impl<F: PrimeField> CCS<F> { impl<F: PrimeField> CCS<F> {
pub fn to_lcccs<R: Rng, C: CurveGroup, CS: CommitmentScheme<C>>(
pub fn to_lcccs<R: Rng, C: CurveGroup, CS: CommitmentScheme<C, H>, const H: bool>(
&self, &self,
rng: &mut R, rng: &mut R,
cs_params: &CS::ProverParams, cs_params: &CS::ProverParams,
@ -221,7 +221,11 @@ pub mod tests {
Pedersen::<Projective>::setup(&mut rng, ccs.n - ccs.l - 1).unwrap(); Pedersen::<Projective>::setup(&mut rng, ccs.n - ccs.l - 1).unwrap();
let (lcccs, _) = ccs let (lcccs, _) = ccs
.to_lcccs::<_, Projective, Pedersen<Projective>>(&mut rng, &pedersen_params, &z)
.to_lcccs::<_, Projective, Pedersen<Projective, false>, false>(
&mut rng,
&pedersen_params,
&z,
)
.unwrap(); .unwrap();
// with our test vector coming from R1CS, v should have length 3 // with our test vector coming from R1CS, v should have length 3
assert_eq!(lcccs.v.len(), 3); assert_eq!(lcccs.v.len(), 3);
@ -255,7 +259,7 @@ pub mod tests {
Pedersen::<Projective>::setup(&mut rng, ccs.n - ccs.l - 1).unwrap(); Pedersen::<Projective>::setup(&mut rng, ccs.n - ccs.l - 1).unwrap();
// Compute v_j with the right z // Compute v_j with the right z
let (lcccs, _) = ccs let (lcccs, _) = ccs
.to_lcccs::<_, Projective, Pedersen<Projective>>(&mut rng, &pedersen_params, &z)
.to_lcccs::<_, Projective, Pedersen<Projective>, false>(&mut rng, &pedersen_params, &z)
.unwrap(); .unwrap();
// with our test vector coming from R1CS, v should have length 3 // with our test vector coming from R1CS, v should have length 3
assert_eq!(lcccs.v.len(), 3); assert_eq!(lcccs.v.len(), 3);

+ 98
- 42
folding-schemes/src/folding/hypernova/mod.rs

@ -61,12 +61,12 @@ impl Witness {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ProverParams<C1, C2, CS1, CS2>
pub struct ProverParams<C1, C2, CS1, CS2, const H: bool>
where where
C1: CurveGroup, C1: CurveGroup,
C2: CurveGroup, C2: CurveGroup,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
{ {
pub poseidon_config: PoseidonConfig<C1::ScalarField>, pub poseidon_config: PoseidonConfig<C1::ScalarField>,
pub cs_params: CS1::ProverParams, pub cs_params: CS1::ProverParams,
@ -81,8 +81,9 @@ where
pub struct VerifierParams< pub struct VerifierParams<
C1: CurveGroup, C1: CurveGroup,
C2: CurveGroup, C2: CurveGroup,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
const H: bool,
> { > {
pub poseidon_config: PoseidonConfig<C1::ScalarField>, pub poseidon_config: PoseidonConfig<C1::ScalarField>,
pub ccs: CCS<C1::ScalarField>, pub ccs: CCS<C1::ScalarField>,
@ -91,16 +92,16 @@ pub struct VerifierParams<
pub cf_cs_vp: CS2::VerifierParams, pub cf_cs_vp: CS2::VerifierParams,
} }
impl<C1, C2, CS1, CS2> VerifierParams<C1, C2, CS1, CS2>
impl<C1, C2, CS1, CS2, const H: bool> VerifierParams<C1, C2, CS1, CS2, H>
where where
C1: CurveGroup, C1: CurveGroup,
C2: CurveGroup, C2: CurveGroup,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
{ {
/// returns the hash of the public parameters of HyperNova /// returns the hash of the public parameters of HyperNova
pub fn pp_hash(&self) -> Result<C1::ScalarField, Error> { pub fn pp_hash(&self) -> Result<C1::ScalarField, Error> {
pp_hash::<C1, C2, CS1, CS2>(
pp_hash::<C1, C2, CS1, CS2, H>(
&self.ccs, &self.ccs,
&self.cf_r1cs, &self.cf_r1cs,
&self.cs_vp, &self.cs_vp,
@ -114,15 +115,15 @@ where
/// [HyperNova](https://eprint.iacr.org/2023/573.pdf) and /// [HyperNova](https://eprint.iacr.org/2023/573.pdf) and
/// [CycleFold](https://eprint.iacr.org/2023/1192.pdf), following the FoldingScheme trait /// [CycleFold](https://eprint.iacr.org/2023/1192.pdf), following the FoldingScheme trait
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct HyperNova<C1, GC1, C2, GC2, FC, CS1, CS2>
pub struct HyperNova<C1, GC1, C2, GC2, FC, CS1, CS2, const H: bool>
where where
C1: CurveGroup, C1: CurveGroup,
GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>, GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>,
C2: CurveGroup, C2: CurveGroup,
GC2: CurveVar<C2, CF2<C2>>, GC2: CurveVar<C2, CF2<C2>>,
FC: FCircuit<C1::ScalarField>, FC: FCircuit<C1::ScalarField>,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
{ {
_gc1: PhantomData<GC1>, _gc1: PhantomData<GC1>,
_c2: PhantomData<C2>, _c2: PhantomData<C2>,
@ -159,16 +160,16 @@ where
pub cf_U_i: CommittedInstance<C2>, pub cf_U_i: CommittedInstance<C2>,
} }
impl<C1, GC1, C2, GC2, FC, CS1, CS2> MultiFolding<C1, C2, FC>
for HyperNova<C1, GC1, C2, GC2, FC, CS1, CS2>
impl<C1, GC1, C2, GC2, FC, CS1, CS2, const H: bool> MultiFolding<C1, C2, FC>
for HyperNova<C1, GC1, C2, GC2, FC, CS1, CS2, H>
where where
C1: CurveGroup, C1: CurveGroup,
GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>, GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>,
C2: CurveGroup, C2: CurveGroup,
GC2: CurveVar<C2, CF2<C2>> + ToConstraintFieldGadget<CF2<C2>>, GC2: CurveVar<C2, CF2<C2>> + ToConstraintFieldGadget<CF2<C2>>,
FC: FCircuit<C1::ScalarField>, FC: FCircuit<C1::ScalarField>,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
<C1 as CurveGroup>::BaseField: PrimeField, <C1 as CurveGroup>::BaseField: PrimeField,
<C2 as CurveGroup>::BaseField: PrimeField, <C2 as CurveGroup>::BaseField: PrimeField,
<C1 as Group>::ScalarField: Absorb, <C1 as Group>::ScalarField: Absorb,
@ -195,7 +196,7 @@ where
// assign them directly to w_i, u_i. // assign them directly to w_i, u_i.
let (U_i, W_i) = self let (U_i, W_i) = self
.ccs .ccs
.to_lcccs::<_, _, CS1>(&mut rng, &self.cs_params, &r1cs_z)?;
.to_lcccs::<_, _, CS1, H>(&mut rng, &self.cs_params, &r1cs_z)?;
#[cfg(test)] #[cfg(test)]
U_i.check_relation(&self.ccs, &W_i)?; U_i.check_relation(&self.ccs, &W_i)?;
@ -217,7 +218,7 @@ where
// assign them directly to w_i, u_i. // assign them directly to w_i, u_i.
let (u_i, w_i) = self let (u_i, w_i) = self
.ccs .ccs
.to_cccs::<_, _, CS1>(&mut rng, &self.cs_params, &r1cs_z)?;
.to_cccs::<_, _, CS1, H>(&mut rng, &self.cs_params, &r1cs_z)?;
#[cfg(test)] #[cfg(test)]
u_i.check_relation(&self.ccs, &w_i)?; u_i.check_relation(&self.ccs, &w_i)?;
@ -226,15 +227,15 @@ where
} }
} }
impl<C1, GC1, C2, GC2, FC, CS1, CS2> HyperNova<C1, GC1, C2, GC2, FC, CS1, CS2>
impl<C1, GC1, C2, GC2, FC, CS1, CS2, const H: bool> HyperNova<C1, GC1, C2, GC2, FC, CS1, CS2, H>
where where
C1: CurveGroup, C1: CurveGroup,
GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>, GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>,
C2: CurveGroup, C2: CurveGroup,
GC2: CurveVar<C2, CF2<C2>> + ToConstraintFieldGadget<CF2<C2>>, GC2: CurveVar<C2, CF2<C2>> + ToConstraintFieldGadget<CF2<C2>>,
FC: FCircuit<C1::ScalarField>, FC: FCircuit<C1::ScalarField>,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
<C1 as CurveGroup>::BaseField: PrimeField, <C1 as CurveGroup>::BaseField: PrimeField,
<C2 as CurveGroup>::BaseField: PrimeField, <C2 as CurveGroup>::BaseField: PrimeField,
<C1 as Group>::ScalarField: Absorb, <C1 as Group>::ScalarField: Absorb,
@ -333,16 +334,16 @@ where
} }
} }
impl<C1, GC1, C2, GC2, FC, CS1, CS2> FoldingScheme<C1, C2, FC>
for HyperNova<C1, GC1, C2, GC2, FC, CS1, CS2>
impl<C1, GC1, C2, GC2, FC, CS1, CS2, const H: bool> FoldingScheme<C1, C2, FC>
for HyperNova<C1, GC1, C2, GC2, FC, CS1, CS2, H>
where where
C1: CurveGroup, C1: CurveGroup,
GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>, GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>,
C2: CurveGroup, C2: CurveGroup,
GC2: CurveVar<C2, CF2<C2>> + ToConstraintFieldGadget<CF2<C2>>, GC2: CurveVar<C2, CF2<C2>> + ToConstraintFieldGadget<CF2<C2>>,
FC: FCircuit<C1::ScalarField>, FC: FCircuit<C1::ScalarField>,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
<C1 as CurveGroup>::BaseField: PrimeField, <C1 as CurveGroup>::BaseField: PrimeField,
<C2 as CurveGroup>::BaseField: PrimeField, <C2 as CurveGroup>::BaseField: PrimeField,
<C1 as Group>::ScalarField: Absorb, <C1 as Group>::ScalarField: Absorb,
@ -354,9 +355,9 @@ where
/// Reuse Nova's PreprocessorParam, together with two usize values, which are mu & nu /// Reuse Nova's PreprocessorParam, together with two usize values, which are mu & nu
/// respectively, which indicate the amount of LCCCS & CCCS instances to be folded at each /// respectively, which indicate the amount of LCCCS & CCCS instances to be folded at each
/// folding step. /// folding step.
type PreprocessorParam = (PreprocessorParam<C1, C2, FC, CS1, CS2>, usize, usize);
type ProverParam = ProverParams<C1, C2, CS1, CS2>;
type VerifierParam = VerifierParams<C1, C2, CS1, CS2>;
type PreprocessorParam = (PreprocessorParam<C1, C2, FC, CS1, CS2, H>, usize, usize);
type ProverParam = ProverParams<C1, C2, CS1, CS2, H>;
type VerifierParam = VerifierParams<C1, C2, CS1, CS2, H>;
type RunningInstance = (LCCCS<C1>, Witness<C1::ScalarField>); type RunningInstance = (LCCCS<C1>, Witness<C1::ScalarField>);
type IncomingInstance = (CCCS<C1>, Witness<C1::ScalarField>); type IncomingInstance = (CCCS<C1>, Witness<C1::ScalarField>);
type MultiCommittedInstanceWithWitness = type MultiCommittedInstanceWithWitness =
@ -403,7 +404,7 @@ where
(cf_cs_pp, cf_cs_vp) = CS2::setup(&mut rng, cf_r1cs.A.n_cols - cf_r1cs.l - 1)?; (cf_cs_pp, cf_cs_vp) = CS2::setup(&mut rng, cf_r1cs.A.n_cols - cf_r1cs.l - 1)?;
} }
let pp = ProverParams::<C1, C2, CS1, CS2> {
let pp = ProverParams::<C1, C2, CS1, CS2, H> {
poseidon_config: prep_param.poseidon_config.clone(), poseidon_config: prep_param.poseidon_config.clone(),
cs_params: cs_pp.clone(), cs_params: cs_pp.clone(),
cf_cs_params: cf_cs_pp.clone(), cf_cs_params: cf_cs_pp.clone(),
@ -411,7 +412,7 @@ where
mu: *mu, mu: *mu,
nu: *nu, nu: *nu,
}; };
let vp = VerifierParams::<C1, C2, CS1, CS2> {
let vp = VerifierParams::<C1, C2, CS1, CS2, H> {
poseidon_config: prep_param.poseidon_config.clone(), poseidon_config: prep_param.poseidon_config.clone(),
ccs, ccs,
cf_r1cs, cf_r1cs,
@ -505,6 +506,22 @@ where
external_inputs: Vec<C1::ScalarField>, external_inputs: Vec<C1::ScalarField>,
other_instances: Option<Self::MultiCommittedInstanceWithWitness>, other_instances: Option<Self::MultiCommittedInstanceWithWitness>,
) -> Result<(), Error> { ) -> Result<(), Error> {
// ensure that commitments are blinding if user has specified so.
if H {
let blinding_commitments = if self.i == C1::ScalarField::zero() {
vec![self.w_i.r_w]
} else {
vec![self.w_i.r_w, self.W_i.r_w]
};
if blinding_commitments.contains(&C1::ScalarField::zero()) {
return Err(Error::IncorrectBlinding(
H,
format!("{:?}", blinding_commitments),
));
}
}
// `sponge` is for digest computation. // `sponge` is for digest computation.
let sponge = PoseidonSponge::<C1::ScalarField>::new(&self.poseidon_config); let sponge = PoseidonSponge::<C1::ScalarField>::new(&self.poseidon_config);
@ -572,10 +589,11 @@ where
// u_{i+1}.x[1] = H(cf_U_{i+1}) // u_{i+1}.x[1] = H(cf_U_{i+1})
let cf_u_i1_x: C1::ScalarField; let cf_u_i1_x: C1::ScalarField;
let (U_i1, W_i1);
let (U_i1, mut W_i1);
if self.i == C1::ScalarField::zero() { if self.i == C1::ScalarField::zero() {
W_i1 = Witness::<C1::ScalarField>::dummy(&self.ccs); W_i1 = Witness::<C1::ScalarField>::dummy(&self.ccs);
W_i1.r_w = self.W_i.r_w;
U_i1 = LCCCS::dummy(self.ccs.l, self.ccs.t, self.ccs.s); U_i1 = LCCCS::dummy(self.ccs.l, self.ccs.t, self.ccs.s);
let u_i1_x = U_i1.hash( let u_i1_x = U_i1.hash(
@ -697,7 +715,7 @@ where
}; };
let (_cf_w_i, cf_u_i, cf_W_i1, cf_U_i1, cf_cmT, _) = let (_cf_w_i, cf_u_i, cf_W_i1, cf_U_i1, cf_cmT, _) =
fold_cyclefold_circuit::<C1, GC1, C2, GC2, FC, CS1, CS2>(
fold_cyclefold_circuit::<C1, GC1, C2, GC2, FC, CS1, CS2, H>(
self.mu + self.nu, self.mu + self.nu,
&mut transcript_p, &mut transcript_p,
self.cf_r1cs.clone(), self.cf_r1cs.clone(),
@ -707,6 +725,7 @@ where
self.cf_U_i.clone(), // CycleFold running instance self.cf_U_i.clone(), // CycleFold running instance
cf_u_i_x, cf_u_i_x,
cf_circuit, cf_circuit,
&mut rng,
)?; )?;
cf_u_i1_x = cf_U_i1.hash_cyclefold(&sponge, self.pp_hash); cf_u_i1_x = cf_U_i1.hash_cyclefold(&sponge, self.pp_hash);
@ -762,7 +781,7 @@ where
// assign them directly to w_i, u_i. // assign them directly to w_i, u_i.
let (u_i, w_i) = self let (u_i, w_i) = self
.ccs .ccs
.to_cccs::<_, C1, CS1>(&mut rng, &self.cs_params, &r1cs_z)?;
.to_cccs::<_, C1, CS1, H>(&mut rng, &self.cs_params, &r1cs_z)?;
self.u_i = u_i.clone(); self.u_i = u_i.clone();
self.w_i = w_i.clone(); self.w_i = w_i.clone();
@ -861,6 +880,7 @@ mod tests {
use crate::commitment::kzg::KZG; use crate::commitment::kzg::KZG;
use ark_bn254::{constraints::GVar, Bn254, Fr, G1Projective as Projective}; use ark_bn254::{constraints::GVar, Bn254, Fr, G1Projective as Projective};
use ark_grumpkin::{constraints::GVar as GVar2, Projective as Projective2}; use ark_grumpkin::{constraints::GVar as GVar2, Projective as Projective2};
use ark_std::UniformRand;
use super::*; use super::*;
use crate::commitment::pedersen::Pedersen; use crate::commitment::pedersen::Pedersen;
@ -874,35 +894,71 @@ mod tests {
let F_circuit = CubicFCircuit::<Fr>::new(()).unwrap(); let F_circuit = CubicFCircuit::<Fr>::new(()).unwrap();
// run the test using Pedersen commitments on both sides of the curve cycle // run the test using Pedersen commitments on both sides of the curve cycle
test_ivc_opt::<Pedersen<Projective>, Pedersen<Projective2>>(
test_ivc_opt::<Pedersen<Projective>, Pedersen<Projective2>, false>(
poseidon_config.clone(), poseidon_config.clone(),
F_circuit, F_circuit,
); );
test_ivc_opt::<Pedersen<Projective, true>, Pedersen<Projective2, true>, true>(
poseidon_config.clone(),
F_circuit,
);
// run the test using KZG for the commitments on the main curve, and Pedersen for the // run the test using KZG for the commitments on the main curve, and Pedersen for the
// commitments on the secondary curve // commitments on the secondary curve
test_ivc_opt::<KZG<Bn254>, Pedersen<Projective2>>(poseidon_config, F_circuit);
test_ivc_opt::<KZG<Bn254>, Pedersen<Projective2>, false>(poseidon_config, F_circuit);
} }
// test_ivc allowing to choose the CommitmentSchemes // test_ivc allowing to choose the CommitmentSchemes
fn test_ivc_opt<CS1: CommitmentScheme<Projective>, CS2: CommitmentScheme<Projective2>>(
fn test_ivc_opt<
CS1: CommitmentScheme<Projective, H>,
CS2: CommitmentScheme<Projective2, H>,
const H: bool,
>(
poseidon_config: PoseidonConfig<Fr>, poseidon_config: PoseidonConfig<Fr>,
F_circuit: CubicFCircuit<Fr>, F_circuit: CubicFCircuit<Fr>,
) { ) {
let mut rng = ark_std::test_rng(); let mut rng = ark_std::test_rng();
type HN<CS1, CS2> =
HyperNova<Projective, GVar, Projective2, GVar2, CubicFCircuit<Fr>, CS1, CS2>;
let (mu, nu) = (2, 3); let (mu, nu) = (2, 3);
let prep_param = let prep_param =
PreprocessorParam::<Projective, Projective2, CubicFCircuit<Fr>, CS1, CS2>::new(
PreprocessorParam::<Projective, Projective2, CubicFCircuit<Fr>, CS1, CS2, H>::new(
poseidon_config.clone(), poseidon_config.clone(),
F_circuit, F_circuit,
); );
let hypernova_params = HN::preprocess(&mut rng, &(prep_param, mu, nu)).unwrap();
let hypernova_params = HyperNova::<
Projective,
GVar,
Projective2,
GVar2,
CubicFCircuit<Fr>,
CS1,
CS2,
H,
>::preprocess(&mut rng, &(prep_param, mu, nu))
.unwrap();
let z_0 = vec![Fr::from(3_u32)]; let z_0 = vec![Fr::from(3_u32)];
let mut hypernova = HN::init(&hypernova_params, F_circuit, z_0.clone()).unwrap();
let mut hypernova = HyperNova::<
Projective,
GVar,
Projective2,
GVar2,
CubicFCircuit<Fr>,
CS1,
CS2,
H,
>::init(&hypernova_params, F_circuit, z_0.clone())
.unwrap();
let (w_i_blinding, W_i_blinding) = if H {
(Fr::rand(&mut rng), Fr::rand(&mut rng))
} else {
(Fr::zero(), Fr::zero())
};
hypernova.w_i.r_w = w_i_blinding;
hypernova.W_i.r_w = W_i_blinding;
let num_steps: usize = 3; let num_steps: usize = 3;
for _ in 0..num_steps { for _ in 0..num_steps {
@ -932,7 +988,7 @@ mod tests {
assert_eq!(Fr::from(num_steps as u32), hypernova.i); assert_eq!(Fr::from(num_steps as u32), hypernova.i);
let (running_instance, incoming_instance, cyclefold_instance) = hypernova.instances(); let (running_instance, incoming_instance, cyclefold_instance) = hypernova.instances();
HN::verify(
HyperNova::<Projective, GVar, Projective2, GVar2, CubicFCircuit<Fr>, CS1, CS2, H>::verify(
hypernova_params.1, // verifier_params hypernova_params.1, // verifier_params
z_0, z_0,
hypernova.z_i, hypernova.z_i,

+ 10
- 10
folding-schemes/src/folding/hypernova/nimfs.rs

@ -441,10 +441,10 @@ pub mod tests {
Pedersen::<Projective>::setup(&mut rng, ccs.n - ccs.l - 1).unwrap(); Pedersen::<Projective>::setup(&mut rng, ccs.n - ccs.l - 1).unwrap();
let (lcccs, w1) = ccs let (lcccs, w1) = ccs
.to_lcccs::<_, Projective, Pedersen<Projective>>(&mut rng, &pedersen_params, &z1)
.to_lcccs::<_, Projective, Pedersen<Projective>, false>(&mut rng, &pedersen_params, &z1)
.unwrap(); .unwrap();
let (cccs, w2) = ccs let (cccs, w2) = ccs
.to_cccs::<_, Projective, Pedersen<Projective>>(&mut rng, &pedersen_params, &z2)
.to_cccs::<_, Projective, Pedersen<Projective>, false>(&mut rng, &pedersen_params, &z2)
.unwrap(); .unwrap();
lcccs.check_relation(&ccs, &w1).unwrap(); lcccs.check_relation(&ccs, &w1).unwrap();
@ -484,11 +484,11 @@ pub mod tests {
// Create the LCCCS instance out of z_1 // Create the LCCCS instance out of z_1
let (running_instance, w1) = ccs let (running_instance, w1) = ccs
.to_lcccs::<_, _, Pedersen<Projective>>(&mut rng, &pedersen_params, &z_1)
.to_lcccs::<_, _, Pedersen<Projective>, false>(&mut rng, &pedersen_params, &z_1)
.unwrap(); .unwrap();
// Create the CCCS instance out of z_2 // Create the CCCS instance out of z_2
let (new_instance, w2) = ccs let (new_instance, w2) = ccs
.to_cccs::<_, _, Pedersen<Projective>>(&mut rng, &pedersen_params, &z_2)
.to_cccs::<_, _, Pedersen<Projective>, false>(&mut rng, &pedersen_params, &z_2)
.unwrap(); .unwrap();
// Prover's transcript // Prover's transcript
@ -540,7 +540,7 @@ pub mod tests {
// LCCCS witness // LCCCS witness
let z_1 = get_test_z(2); let z_1 = get_test_z(2);
let (mut running_instance, mut w1) = ccs let (mut running_instance, mut w1) = ccs
.to_lcccs::<_, _, Pedersen<Projective>>(&mut rng, &pedersen_params, &z_1)
.to_lcccs::<_, _, Pedersen<Projective>, false>(&mut rng, &pedersen_params, &z_1)
.unwrap(); .unwrap();
let poseidon_config = poseidon_canonical_config::<Fr>(); let poseidon_config = poseidon_canonical_config::<Fr>();
@ -557,7 +557,7 @@ pub mod tests {
let z_2 = get_test_z(i); let z_2 = get_test_z(i);
let (new_instance, w2) = ccs let (new_instance, w2) = ccs
.to_cccs::<_, _, Pedersen<Projective>>(&mut rng, &pedersen_params, &z_2)
.to_cccs::<_, _, Pedersen<Projective>, false>(&mut rng, &pedersen_params, &z_2)
.unwrap(); .unwrap();
// run the prover side of the multifolding // run the prover side of the multifolding
@ -621,7 +621,7 @@ pub mod tests {
let mut w_lcccs = Vec::new(); let mut w_lcccs = Vec::new();
for z_i in z_lcccs.iter() { for z_i in z_lcccs.iter() {
let (running_instance, w) = ccs let (running_instance, w) = ccs
.to_lcccs::<_, _, Pedersen<Projective>>(&mut rng, &pedersen_params, z_i)
.to_lcccs::<_, _, Pedersen<Projective>, false>(&mut rng, &pedersen_params, z_i)
.unwrap(); .unwrap();
lcccs_instances.push(running_instance); lcccs_instances.push(running_instance);
w_lcccs.push(w); w_lcccs.push(w);
@ -631,7 +631,7 @@ pub mod tests {
let mut w_cccs = Vec::new(); let mut w_cccs = Vec::new();
for z_i in z_cccs.iter() { for z_i in z_cccs.iter() {
let (new_instance, w) = ccs let (new_instance, w) = ccs
.to_cccs::<_, _, Pedersen<Projective>>(&mut rng, &pedersen_params, z_i)
.to_cccs::<_, _, Pedersen<Projective>, false>(&mut rng, &pedersen_params, z_i)
.unwrap(); .unwrap();
cccs_instances.push(new_instance); cccs_instances.push(new_instance);
w_cccs.push(w); w_cccs.push(w);
@ -717,7 +717,7 @@ pub mod tests {
let mut w_lcccs = Vec::new(); let mut w_lcccs = Vec::new();
for z_i in z_lcccs.iter() { for z_i in z_lcccs.iter() {
let (running_instance, w) = ccs let (running_instance, w) = ccs
.to_lcccs::<_, _, Pedersen<Projective>>(&mut rng, &pedersen_params, z_i)
.to_lcccs::<_, _, Pedersen<Projective>, false>(&mut rng, &pedersen_params, z_i)
.unwrap(); .unwrap();
lcccs_instances.push(running_instance); lcccs_instances.push(running_instance);
w_lcccs.push(w); w_lcccs.push(w);
@ -727,7 +727,7 @@ pub mod tests {
let mut w_cccs = Vec::new(); let mut w_cccs = Vec::new();
for z_i in z_cccs.iter() { for z_i in z_cccs.iter() {
let (new_instance, w) = ccs let (new_instance, w) = ccs
.to_cccs::<_, _, Pedersen<Projective>>(&mut rng, &pedersen_params, z_i)
.to_cccs::<_, _, Pedersen<Projective>, false>(&mut rng, &pedersen_params, z_i)
.unwrap(); .unwrap();
cccs_instances.push(new_instance); cccs_instances.push(new_instance);
w_cccs.push(w); w_cccs.push(w);

+ 2
- 2
folding-schemes/src/folding/hypernova/utils.rs

@ -242,7 +242,7 @@ pub mod tests {
let (pedersen_params, _) = let (pedersen_params, _) =
Pedersen::<Projective>::setup(&mut rng, ccs.n - ccs.l - 1).unwrap(); Pedersen::<Projective>::setup(&mut rng, ccs.n - ccs.l - 1).unwrap();
let (lcccs_instance, _) = ccs let (lcccs_instance, _) = ccs
.to_lcccs::<_, _, Pedersen<Projective>>(&mut rng, &pedersen_params, &z1)
.to_lcccs::<_, _, Pedersen<Projective>, false>(&mut rng, &pedersen_params, &z1)
.unwrap(); .unwrap();
let sigmas_thetas = let sigmas_thetas =
@ -292,7 +292,7 @@ pub mod tests {
let (pedersen_params, _) = let (pedersen_params, _) =
Pedersen::<Projective>::setup(&mut rng, ccs.n - ccs.l - 1).unwrap(); Pedersen::<Projective>::setup(&mut rng, ccs.n - ccs.l - 1).unwrap();
let (lcccs_instance, _) = ccs let (lcccs_instance, _) = ccs
.to_lcccs::<_, _, Pedersen<Projective>>(&mut rng, &pedersen_params, &z1)
.to_lcccs::<_, _, Pedersen<Projective>, false>(&mut rng, &pedersen_params, &z1)
.unwrap(); .unwrap();
// Compute g(x) with that r_x // Compute g(x) with that r_x

+ 14
- 10
folding-schemes/src/folding/nova/decider_eth.rs

@ -81,10 +81,10 @@ where
for<'b> &'b GC1: GroupOpsBounds<'b, C1, GC1>, for<'b> &'b GC1: GroupOpsBounds<'b, C1, GC1>,
for<'b> &'b GC2: GroupOpsBounds<'b, C2, GC2>, for<'b> &'b GC2: GroupOpsBounds<'b, C2, GC2>,
// constrain FS into Nova, since this is a Decider specifically for Nova // constrain FS into Nova, since this is a Decider specifically for Nova
Nova<C1, GC1, C2, GC2, FC, CS1, CS2>: From<FS>,
crate::folding::nova::ProverParams<C1, C2, CS1, CS2>:
Nova<C1, GC1, C2, GC2, FC, CS1, CS2, false>: From<FS>,
crate::folding::nova::ProverParams<C1, C2, CS1, CS2, false>:
From<<FS as FoldingScheme<C1, C2, FC>>::ProverParam>, From<<FS as FoldingScheme<C1, C2, FC>>::ProverParam>,
crate::folding::nova::VerifierParams<C1, C2, CS1, CS2>:
crate::folding::nova::VerifierParams<C1, C2, CS1, CS2, false>:
From<<FS as FoldingScheme<C1, C2, FC>>::VerifierParam>, From<<FS as FoldingScheme<C1, C2, FC>>::VerifierParam>,
{ {
type PreprocessorParam = (FS::ProverParam, FS::VerifierParam); type PreprocessorParam = (FS::ProverParam, FS::VerifierParam);
@ -108,14 +108,17 @@ where
// get the FoldingScheme prover & verifier params from Nova // get the FoldingScheme prover & verifier params from Nova
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
let nova_pp:
<Nova<C1, GC1, C2, GC2, FC, CS1, CS2> as FoldingScheme<C1, C2, FC>>::ProverParam =
prep_param.0.clone().into()
;
let nova_pp: <Nova<C1, GC1, C2, GC2, FC, CS1, CS2, false> as FoldingScheme<
C1,
C2,
FC,
>>::ProverParam = prep_param.0.clone().into();
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
let nova_vp:
<Nova<C1, GC1, C2, GC2, FC, CS1, CS2> as FoldingScheme<C1, C2, FC>>::VerifierParam =
prep_param.1.clone().into();
let nova_vp: <Nova<C1, GC1, C2, GC2, FC, CS1, CS2, false> as FoldingScheme<
C1,
C2,
FC,
>>::VerifierParam = prep_param.1.clone().into();
let pp_hash = nova_vp.pp_hash()?; let pp_hash = nova_vp.pp_hash()?;
let pp = (g16_pk, nova_pp.cs_pp); let pp = (g16_pk, nova_pp.cs_pp);
@ -338,6 +341,7 @@ pub mod tests {
CubicFCircuit<Fr>, CubicFCircuit<Fr>,
KZG<'static, Bn254>, KZG<'static, Bn254>,
Pedersen<Projective2>, Pedersen<Projective2>,
false,
>; >;
type D = Decider< type D = Decider<
Projective, Projective,

+ 15
- 15
folding-schemes/src/folding/nova/decider_eth_circuit.rs

@ -193,14 +193,14 @@ where
/// Circuit that implements the in-circuit checks needed for the onchain (Ethereum's EVM) /// Circuit that implements the in-circuit checks needed for the onchain (Ethereum's EVM)
/// verification. /// verification.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct DeciderEthCircuit<C1, GC1, C2, GC2, CS1, CS2>
pub struct DeciderEthCircuit<C1, GC1, C2, GC2, CS1, CS2, const H: bool = false>
where where
C1: CurveGroup, C1: CurveGroup,
GC1: CurveVar<C1, CF2<C1>>, GC1: CurveVar<C1, CF2<C1>>,
C2: CurveGroup, C2: CurveGroup,
GC2: CurveVar<C2, CF2<C2>>, GC2: CurveVar<C2, CF2<C2>>,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
{ {
_c1: PhantomData<C1>, _c1: PhantomData<C1>,
_gc1: PhantomData<GC1>, _gc1: PhantomData<GC1>,
@ -246,25 +246,25 @@ where
pub eval_W: Option<C1::ScalarField>, pub eval_W: Option<C1::ScalarField>,
pub eval_E: Option<C1::ScalarField>, pub eval_E: Option<C1::ScalarField>,
} }
impl<C1, GC1, C2, GC2, CS1, CS2> DeciderEthCircuit<C1, GC1, C2, GC2, CS1, CS2>
impl<C1, GC1, C2, GC2, CS1, CS2, const H: bool> DeciderEthCircuit<C1, GC1, C2, GC2, CS1, CS2, H>
where where
C1: CurveGroup, C1: CurveGroup,
C2: CurveGroup, C2: CurveGroup,
GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>, GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>,
GC2: CurveVar<C2, CF2<C2>> + ToConstraintFieldGadget<CF2<C2>>, GC2: CurveVar<C2, CF2<C2>> + ToConstraintFieldGadget<CF2<C2>>,
CS1: CommitmentScheme<C1>,
CS1: CommitmentScheme<C1, H>,
// enforce that the CS2 is Pedersen commitment scheme, since we're at Ethereum's EVM decider // enforce that the CS2 is Pedersen commitment scheme, since we're at Ethereum's EVM decider
CS2: CommitmentScheme<C2, ProverParams = PedersenParams<C2>>,
CS2: CommitmentScheme<C2, H, ProverParams = PedersenParams<C2>>,
<C1 as Group>::ScalarField: Absorb, <C1 as Group>::ScalarField: Absorb,
<C1 as CurveGroup>::BaseField: PrimeField, <C1 as CurveGroup>::BaseField: PrimeField,
{ {
pub fn from_nova<FC: FCircuit<C1::ScalarField>>( pub fn from_nova<FC: FCircuit<C1::ScalarField>>(
nova: Nova<C1, GC1, C2, GC2, FC, CS1, CS2>,
nova: Nova<C1, GC1, C2, GC2, FC, CS1, CS2, H>,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
let mut transcript = PoseidonSponge::<C1::ScalarField>::new(&nova.poseidon_config); let mut transcript = PoseidonSponge::<C1::ScalarField>::new(&nova.poseidon_config);
// compute the U_{i+1}, W_{i+1} // compute the U_{i+1}, W_{i+1}
let (T, cmT) = NIFS::<C1, CS1>::compute_cmT(
let (T, cmT) = NIFS::<C1, CS1, H>::compute_cmT(
&nova.cs_pp, &nova.cs_pp,
&nova.r1cs.clone(), &nova.r1cs.clone(),
&nova.w_i.clone(), &nova.w_i.clone(),
@ -281,7 +281,7 @@ where
); );
let r_Fr = C1::ScalarField::from_bigint(BigInteger::from_bits_le(&r_bits)) let r_Fr = C1::ScalarField::from_bigint(BigInteger::from_bits_le(&r_bits))
.ok_or(Error::OutOfBounds)?; .ok_or(Error::OutOfBounds)?;
let (W_i1, U_i1) = NIFS::<C1, CS1>::fold_instances(
let (W_i1, U_i1) = NIFS::<C1, CS1, H>::fold_instances(
r_Fr, &nova.W_i, &nova.U_i, &nova.w_i, &nova.u_i, &T, cmT, r_Fr, &nova.W_i, &nova.U_i, &nova.w_i, &nova.u_i, &T, cmT,
)?; )?;
@ -376,8 +376,8 @@ where
})?; })?;
let u_dummy_native = CommittedInstance::<C1>::dummy(2); let u_dummy_native = CommittedInstance::<C1>::dummy(2);
let w_dummy_native = Witness::<C1>::new(
vec![C1::ScalarField::zero(); self.r1cs.A.n_cols - 3 /* (3=2+1, since u_i.x.len=2) */],
let w_dummy_native = Witness::<C1>::dummy(
self.r1cs.A.n_cols - 3, /* (3=2+1, since u_i.x.len=2) */
self.E_len, self.E_len,
); );
@ -453,10 +453,8 @@ where
use ark_r1cs_std::ToBitsGadget; use ark_r1cs_std::ToBitsGadget;
let cf_u_dummy_native = CommittedInstance::<C2>::dummy(cf_io_len(NOVA_CF_N_POINTS)); let cf_u_dummy_native = CommittedInstance::<C2>::dummy(cf_io_len(NOVA_CF_N_POINTS));
let w_dummy_native = Witness::<C2>::new(
vec![C2::ScalarField::zero(); self.cf_r1cs.A.n_cols - 1 - self.cf_r1cs.l],
self.cf_E_len,
);
let w_dummy_native =
Witness::<C2>::dummy(self.cf_r1cs.A.n_cols - 1 - self.cf_r1cs.l, self.cf_E_len);
let cf_U_i = CycleFoldCommittedInstanceVar::<C2, GC2>::new_witness(cs.clone(), || { let cf_U_i = CycleFoldCommittedInstanceVar::<C2, GC2>::new_witness(cs.clone(), || {
Ok(self.cf_U_i.unwrap_or_else(|| cf_u_dummy_native.clone())) Ok(self.cf_U_i.unwrap_or_else(|| cf_u_dummy_native.clone()))
})?; })?;
@ -788,6 +786,7 @@ pub mod tests {
CubicFCircuit<Fr>, CubicFCircuit<Fr>,
Pedersen<Projective>, Pedersen<Projective>,
Pedersen<Projective2>, Pedersen<Projective2>,
false,
>; >;
let prep_param = PreprocessorParam::< let prep_param = PreprocessorParam::<
@ -796,6 +795,7 @@ pub mod tests {
CubicFCircuit<Fr>, CubicFCircuit<Fr>,
Pedersen<Projective>, Pedersen<Projective>,
Pedersen<Projective2>, Pedersen<Projective2>,
false,
>::new(poseidon_config, F_circuit); >::new(poseidon_config, F_circuit);
let nova_params = N::preprocess(&mut rng, &prep_param).unwrap(); let nova_params = N::preprocess(&mut rng, &prep_param).unwrap();

+ 131
- 65
folding-schemes/src/folding/nova/mod.rs

@ -11,7 +11,7 @@ use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystem};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use ark_std::fmt::Debug; use ark_std::fmt::Debug;
use ark_std::rand::RngCore; use ark_std::rand::RngCore;
use ark_std::{One, Zero};
use ark_std::{One, UniformRand, Zero};
use core::marker::PhantomData; use core::marker::PhantomData;
use crate::commitment::CommitmentScheme; use crate::commitment::CommitmentScheme;
@ -166,17 +166,37 @@ impl Witness
where where
<C as Group>::ScalarField: Absorb, <C as Group>::ScalarField: Absorb,
{ {
pub fn new(w: Vec<C::ScalarField>, e_len: usize) -> Self {
// note: at the current version, we don't use the blinding factors and we set them to 0
// always.
pub fn new<const H: bool>(w: Vec<C::ScalarField>, e_len: usize, mut rng: impl RngCore) -> Self {
let (rW, rE) = if H {
(
C::ScalarField::rand(&mut rng),
C::ScalarField::rand(&mut rng),
)
} else {
(C::ScalarField::zero(), C::ScalarField::zero())
};
Self {
E: vec![C::ScalarField::zero(); e_len],
rE,
W: w,
rW,
}
}
pub fn dummy(w_len: usize, e_len: usize) -> Self {
let (rW, rE) = (C::ScalarField::zero(), C::ScalarField::zero());
let w = vec![C::ScalarField::zero(); w_len];
Self { Self {
E: vec![C::ScalarField::zero(); e_len], E: vec![C::ScalarField::zero(); e_len],
rE: C::ScalarField::zero(),
rE,
W: w, W: w,
rW: C::ScalarField::zero(),
rW,
} }
} }
pub fn commit<CS: CommitmentScheme<C>>(
pub fn commit<CS: CommitmentScheme<C, HC>, const HC: bool>(
&self, &self,
params: &CS::ProverParams, params: &CS::ProverParams,
x: Vec<C::ScalarField>, x: Vec<C::ScalarField>,
@ -196,13 +216,13 @@ where
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct PreprocessorParam<C1, C2, FC, CS1, CS2>
pub struct PreprocessorParam<C1, C2, FC, CS1, CS2, const H: bool>
where where
C1: CurveGroup, C1: CurveGroup,
C2: CurveGroup, C2: CurveGroup,
FC: FCircuit<C1::ScalarField>, FC: FCircuit<C1::ScalarField>,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
{ {
pub poseidon_config: PoseidonConfig<C1::ScalarField>, pub poseidon_config: PoseidonConfig<C1::ScalarField>,
pub F: FC, pub F: FC,
@ -213,13 +233,13 @@ where
pub cf_cs_vp: Option<CS2::VerifierParams>, pub cf_cs_vp: Option<CS2::VerifierParams>,
} }
impl<C1, C2, FC, CS1, CS2> PreprocessorParam<C1, C2, FC, CS1, CS2>
impl<C1, C2, FC, CS1, CS2, const H: bool> PreprocessorParam<C1, C2, FC, CS1, CS2, H>
where where
C1: CurveGroup, C1: CurveGroup,
C2: CurveGroup, C2: CurveGroup,
FC: FCircuit<C1::ScalarField>, FC: FCircuit<C1::ScalarField>,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
{ {
pub fn new(poseidon_config: PoseidonConfig<C1::ScalarField>, F: FC) -> Self { pub fn new(poseidon_config: PoseidonConfig<C1::ScalarField>, F: FC) -> Self {
Self { Self {
@ -234,12 +254,12 @@ where
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ProverParams<C1, C2, CS1, CS2>
pub struct ProverParams<C1, C2, CS1, CS2, const H: bool>
where where
C1: CurveGroup, C1: CurveGroup,
C2: CurveGroup, C2: CurveGroup,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
{ {
pub poseidon_config: PoseidonConfig<C1::ScalarField>, pub poseidon_config: PoseidonConfig<C1::ScalarField>,
pub cs_pp: CS1::ProverParams, pub cs_pp: CS1::ProverParams,
@ -247,12 +267,12 @@ where
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct VerifierParams<C1, C2, CS1, CS2>
pub struct VerifierParams<C1, C2, CS1, CS2, const H: bool>
where where
C1: CurveGroup, C1: CurveGroup,
C2: CurveGroup, C2: CurveGroup,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
{ {
pub poseidon_config: PoseidonConfig<C1::ScalarField>, pub poseidon_config: PoseidonConfig<C1::ScalarField>,
pub r1cs: R1CS<C1::ScalarField>, pub r1cs: R1CS<C1::ScalarField>,
@ -261,16 +281,16 @@ where
pub cf_cs_vp: CS2::VerifierParams, pub cf_cs_vp: CS2::VerifierParams,
} }
impl<C1, C2, CS1, CS2> VerifierParams<C1, C2, CS1, CS2>
impl<C1, C2, CS1, CS2, const H: bool> VerifierParams<C1, C2, CS1, CS2, H>
where where
C1: CurveGroup, C1: CurveGroup,
C2: CurveGroup, C2: CurveGroup,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
{ {
/// returns the hash of the public parameters of Nova /// returns the hash of the public parameters of Nova
pub fn pp_hash(&self) -> Result<C1::ScalarField, Error> { pub fn pp_hash(&self) -> Result<C1::ScalarField, Error> {
pp_hash::<C1, C2, CS1, CS2>(
pp_hash::<C1, C2, CS1, CS2, H>(
&self.r1cs, &self.r1cs,
&self.cf_r1cs, &self.cf_r1cs,
&self.cs_vp, &self.cs_vp,
@ -282,16 +302,17 @@ where
/// Implements Nova+CycleFold's IVC, described in [Nova](https://eprint.iacr.org/2021/370.pdf) and /// Implements Nova+CycleFold's IVC, described in [Nova](https://eprint.iacr.org/2021/370.pdf) and
/// [CycleFold](https://eprint.iacr.org/2023/1192.pdf), following the FoldingScheme trait /// [CycleFold](https://eprint.iacr.org/2023/1192.pdf), following the FoldingScheme trait
/// The `H` const generic specifies whether the homorphic commitment scheme is blinding
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Nova<C1, GC1, C2, GC2, FC, CS1, CS2>
pub struct Nova<C1, GC1, C2, GC2, FC, CS1, CS2, const H: bool = false>
where where
C1: CurveGroup, C1: CurveGroup,
GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>, GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>,
C2: CurveGroup, C2: CurveGroup,
GC2: CurveVar<C2, CF2<C2>>, GC2: CurveVar<C2, CF2<C2>>,
FC: FCircuit<C1::ScalarField>, FC: FCircuit<C1::ScalarField>,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
{ {
_gc1: PhantomData<GC1>, _gc1: PhantomData<GC1>,
_c2: PhantomData<C2>, _c2: PhantomData<C2>,
@ -325,16 +346,16 @@ where
pub cf_U_i: CommittedInstance<C2>, pub cf_U_i: CommittedInstance<C2>,
} }
impl<C1, GC1, C2, GC2, FC, CS1, CS2> FoldingScheme<C1, C2, FC>
for Nova<C1, GC1, C2, GC2, FC, CS1, CS2>
impl<C1, GC1, C2, GC2, FC, CS1, CS2, const H: bool> FoldingScheme<C1, C2, FC>
for Nova<C1, GC1, C2, GC2, FC, CS1, CS2, H>
where where
C1: CurveGroup, C1: CurveGroup,
GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>, GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>,
C2: CurveGroup, C2: CurveGroup,
GC2: CurveVar<C2, CF2<C2>> + ToConstraintFieldGadget<CF2<C2>>, GC2: CurveVar<C2, CF2<C2>> + ToConstraintFieldGadget<CF2<C2>>,
FC: FCircuit<C1::ScalarField>, FC: FCircuit<C1::ScalarField>,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
<C1 as CurveGroup>::BaseField: PrimeField, <C1 as CurveGroup>::BaseField: PrimeField,
<C2 as CurveGroup>::BaseField: PrimeField, <C2 as CurveGroup>::BaseField: PrimeField,
<C1 as Group>::ScalarField: Absorb, <C1 as Group>::ScalarField: Absorb,
@ -343,9 +364,9 @@ where
for<'a> &'a GC1: GroupOpsBounds<'a, C1, GC1>, for<'a> &'a GC1: GroupOpsBounds<'a, C1, GC1>,
for<'a> &'a GC2: GroupOpsBounds<'a, C2, GC2>, for<'a> &'a GC2: GroupOpsBounds<'a, C2, GC2>,
{ {
type PreprocessorParam = PreprocessorParam<C1, C2, FC, CS1, CS2>;
type ProverParam = ProverParams<C1, C2, CS1, CS2>;
type VerifierParam = VerifierParams<C1, C2, CS1, CS2>;
type PreprocessorParam = PreprocessorParam<C1, C2, FC, CS1, CS2, H>;
type ProverParam = ProverParams<C1, C2, CS1, CS2, H>;
type VerifierParam = VerifierParams<C1, C2, CS1, CS2, H>;
type RunningInstance = (CommittedInstance<C1>, Witness<C1>); type RunningInstance = (CommittedInstance<C1>, Witness<C1>);
type IncomingInstance = (CommittedInstance<C1>, Witness<C1>); type IncomingInstance = (CommittedInstance<C1>, Witness<C1>);
type MultiCommittedInstanceWithWitness = (); type MultiCommittedInstanceWithWitness = ();
@ -377,12 +398,12 @@ where
(cf_cs_pp, cf_cs_vp) = CS2::setup(&mut rng, cf_r1cs.A.n_rows)?; (cf_cs_pp, cf_cs_vp) = CS2::setup(&mut rng, cf_r1cs.A.n_rows)?;
} }
let prover_params = ProverParams::<C1, C2, CS1, CS2> {
let prover_params = ProverParams::<C1, C2, CS1, CS2, H> {
poseidon_config: prep_param.poseidon_config.clone(), poseidon_config: prep_param.poseidon_config.clone(),
cs_pp: cs_pp.clone(), cs_pp: cs_pp.clone(),
cf_cs_pp: cf_cs_pp.clone(), cf_cs_pp: cf_cs_pp.clone(),
}; };
let verifier_params = VerifierParams::<C1, C2, CS1, CS2> {
let verifier_params = VerifierParams::<C1, C2, CS1, CS2, H> {
poseidon_config: prep_param.poseidon_config.clone(), poseidon_config: prep_param.poseidon_config.clone(),
r1cs, r1cs,
cf_r1cs, cf_r1cs,
@ -455,11 +476,26 @@ where
/// Implements IVC.P of Nova+CycleFold /// Implements IVC.P of Nova+CycleFold
fn prove_step( fn prove_step(
&mut self, &mut self,
_rng: impl RngCore,
mut rng: impl RngCore,
external_inputs: Vec<C1::ScalarField>, external_inputs: Vec<C1::ScalarField>,
// Nova does not support multi-instances folding // Nova does not support multi-instances folding
_other_instances: Option<Self::MultiCommittedInstanceWithWitness>, _other_instances: Option<Self::MultiCommittedInstanceWithWitness>,
) -> Result<(), Error> { ) -> Result<(), Error> {
// ensure that commitments are blinding if user has specified so.
if H && self.i >= C1::ScalarField::one() {
let blinding_commitments = if self.i == C1::ScalarField::one() {
// blinding values of the running instances are zero at the first iteration
vec![self.w_i.rW, self.w_i.rE]
} else {
vec![self.w_i.rW, self.w_i.rE, self.W_i.rW, self.W_i.rE]
};
if blinding_commitments.contains(&C1::ScalarField::zero()) {
return Err(Error::IncorrectBlinding(
H,
format!("{:?}", blinding_commitments),
));
}
}
// `sponge` is for digest computation. // `sponge` is for digest computation.
let sponge = PoseidonSponge::<C1::ScalarField>::new(&self.poseidon_config); let sponge = PoseidonSponge::<C1::ScalarField>::new(&self.poseidon_config);
// `transcript` is for challenge generation. // `transcript` is for challenge generation.
@ -517,9 +553,10 @@ where
.ok_or(Error::OutOfBounds)?; .ok_or(Error::OutOfBounds)?;
// fold Nova instances // fold Nova instances
let (W_i1, U_i1): (Witness<C1>, CommittedInstance<C1>) = NIFS::<C1, CS1>::fold_instances(
r_Fr, &self.W_i, &self.U_i, &self.w_i, &self.u_i, &T, cmT,
)?;
let (W_i1, U_i1): (Witness<C1>, CommittedInstance<C1>) =
NIFS::<C1, CS1, H>::fold_instances(
r_Fr, &self.W_i, &self.U_i, &self.w_i, &self.u_i, &T, cmT,
)?;
// folded instance output (public input, x) // folded instance output (public input, x)
// u_{i+1}.x[0] = H(i+1, z_0, z_{i+1}, U_{i+1}) // u_{i+1}.x[0] = H(i+1, z_0, z_{i+1}, U_{i+1})
@ -561,7 +598,7 @@ where
}; };
#[cfg(test)] #[cfg(test)]
NIFS::<C1, CS1>::verify_folded_instance(r_Fr, &self.U_i, &self.u_i, &U_i1, &cmT)?;
NIFS::<C1, CS1, H>::verify_folded_instance(r_Fr, &self.U_i, &self.u_i, &U_i1, &cmT)?;
} else { } else {
// CycleFold part: // CycleFold part:
// get the vector used as public inputs 'x' in the CycleFold circuit // get the vector used as public inputs 'x' in the CycleFold circuit
@ -604,6 +641,7 @@ where
self.cf_U_i.clone(), // CycleFold running instance self.cf_U_i.clone(), // CycleFold running instance
cfW_u_i_x, cfW_u_i_x,
cfW_circuit, cfW_circuit,
&mut rng,
)?; )?;
// fold [the output from folding self.cf_U_i + cfW_U] + cfE_U = folded_running_with_cfW + cfE // fold [the output from folding self.cf_U_i + cfW_U] + cfE_U = folded_running_with_cfW + cfE
let (_cfE_w_i, cfE_u_i, cf_W_i1, cf_U_i1, cf_cmT, _) = self.fold_cyclefold_circuit( let (_cfE_w_i, cfE_u_i, cf_W_i1, cf_U_i1, cf_cmT, _) = self.fold_cyclefold_circuit(
@ -612,6 +650,7 @@ where
cfW_U_i1.clone(), cfW_U_i1.clone(),
cfE_u_i_x, cfE_u_i_x,
cfE_circuit, cfE_circuit,
&mut rng,
)?; )?;
cf_u_i1_x = cf_U_i1.hash_cyclefold(&sponge, self.pp_hash); cf_u_i1_x = cf_U_i1.hash_cyclefold(&sponge, self.pp_hash);
@ -674,8 +713,8 @@ where
// set values for next iteration // set values for next iteration
self.i += C1::ScalarField::one(); self.i += C1::ScalarField::one();
self.z_i = z_i1; self.z_i = z_i1;
self.w_i = Witness::<C1>::new(w_i1, self.r1cs.A.n_rows);
self.u_i = self.w_i.commit::<CS1>(&self.cs_pp, x_i1)?;
self.w_i = Witness::<C1>::new::<H>(w_i1, self.r1cs.A.n_rows, &mut rng);
self.u_i = self.w_i.commit::<CS1, H>(&self.cs_pp, x_i1)?;
self.W_i = W_i1; self.W_i = W_i1;
self.U_i = U_i1; self.U_i = U_i1;
@ -767,15 +806,15 @@ where
} }
} }
impl<C1, GC1, C2, GC2, FC, CS1, CS2> Nova<C1, GC1, C2, GC2, FC, CS1, CS2>
impl<C1, GC1, C2, GC2, FC, CS1, CS2, const H: bool> Nova<C1, GC1, C2, GC2, FC, CS1, CS2, H>
where where
C1: CurveGroup, C1: CurveGroup,
GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>, GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>,
C2: CurveGroup, C2: CurveGroup,
GC2: CurveVar<C2, CF2<C2>>, GC2: CurveVar<C2, CF2<C2>>,
FC: FCircuit<C1::ScalarField>, FC: FCircuit<C1::ScalarField>,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
<C2 as CurveGroup>::BaseField: PrimeField, <C2 as CurveGroup>::BaseField: PrimeField,
<C1 as Group>::ScalarField: Absorb, <C1 as Group>::ScalarField: Absorb,
<C2 as Group>::ScalarField: Absorb, <C2 as Group>::ScalarField: Absorb,
@ -783,7 +822,7 @@ where
{ {
// computes T and cmT for the AugmentedFCircuit // computes T and cmT for the AugmentedFCircuit
fn compute_cmT(&self) -> Result<(Vec<C1::ScalarField>, C1), Error> { fn compute_cmT(&self) -> Result<(Vec<C1::ScalarField>, C1), Error> {
NIFS::<C1, CS1>::compute_cmT(
NIFS::<C1, CS1, H>::compute_cmT(
&self.cs_pp, &self.cs_pp,
&self.r1cs, &self.r1cs,
&self.w_i, &self.w_i,
@ -794,15 +833,15 @@ where
} }
} }
impl<C1, GC1, C2, GC2, FC, CS1, CS2> Nova<C1, GC1, C2, GC2, FC, CS1, CS2>
impl<C1, GC1, C2, GC2, FC, CS1, CS2, const H: bool> Nova<C1, GC1, C2, GC2, FC, CS1, CS2, H>
where where
C1: CurveGroup, C1: CurveGroup,
GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>, GC1: CurveVar<C1, CF2<C1>> + ToConstraintFieldGadget<CF2<C1>>,
C2: CurveGroup, C2: CurveGroup,
GC2: CurveVar<C2, CF2<C2>> + ToConstraintFieldGadget<CF2<C2>>, GC2: CurveVar<C2, CF2<C2>> + ToConstraintFieldGadget<CF2<C2>>,
FC: FCircuit<C1::ScalarField>, FC: FCircuit<C1::ScalarField>,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
<C1 as CurveGroup>::BaseField: PrimeField, <C1 as CurveGroup>::BaseField: PrimeField,
<C2 as CurveGroup>::BaseField: PrimeField, <C2 as CurveGroup>::BaseField: PrimeField,
<C1 as Group>::ScalarField: Absorb, <C1 as Group>::ScalarField: Absorb,
@ -820,6 +859,7 @@ where
cf_U_i: CommittedInstance<C2>, // running instance cf_U_i: CommittedInstance<C2>, // running instance
cf_u_i_x: Vec<C2::ScalarField>, cf_u_i_x: Vec<C2::ScalarField>,
cf_circuit: CycleFoldCircuit<C1, GC1>, cf_circuit: CycleFoldCircuit<C1, GC1>,
rng: &mut impl RngCore,
) -> Result< ) -> Result<
( (
Witness<C2>, Witness<C2>,
@ -831,7 +871,7 @@ where
), ),
Error, Error,
> { > {
fold_cyclefold_circuit::<C1, GC1, C2, GC2, FC, CS1, CS2>(
fold_cyclefold_circuit::<C1, GC1, C2, GC2, FC, CS1, CS2, H>(
NOVA_CF_N_POINTS, NOVA_CF_N_POINTS,
transcript, transcript,
self.cf_r1cs.clone(), self.cf_r1cs.clone(),
@ -841,6 +881,7 @@ where
cf_U_i, cf_U_i,
cf_u_i_x, cf_u_i_x,
cf_circuit, cf_circuit,
rng,
) )
} }
} }
@ -929,35 +970,60 @@ pub mod tests {
let F_circuit = CubicFCircuit::<Fr>::new(()).unwrap(); let F_circuit = CubicFCircuit::<Fr>::new(()).unwrap();
// run the test using Pedersen commitments on both sides of the curve cycle // run the test using Pedersen commitments on both sides of the curve cycle
test_ivc_opt::<Pedersen<Projective>, Pedersen<Projective2>>(
test_ivc_opt::<Pedersen<Projective>, Pedersen<Projective2>, false>(
poseidon_config.clone(), poseidon_config.clone(),
F_circuit, F_circuit,
); );
test_ivc_opt::<Pedersen<Projective, true>, Pedersen<Projective2, true>, true>(
poseidon_config.clone(),
F_circuit,
);
// run the test using KZG for the commitments on the main curve, and Pedersen for the // run the test using KZG for the commitments on the main curve, and Pedersen for the
// commitments on the secondary curve // commitments on the secondary curve
test_ivc_opt::<KZG<Bn254>, Pedersen<Projective2>>(poseidon_config, F_circuit);
test_ivc_opt::<KZG<Bn254>, Pedersen<Projective2>, false>(poseidon_config, F_circuit);
} }
// test_ivc allowing to choose the CommitmentSchemes // test_ivc allowing to choose the CommitmentSchemes
fn test_ivc_opt<CS1: CommitmentScheme<Projective>, CS2: CommitmentScheme<Projective2>>(
fn test_ivc_opt<
CS1: CommitmentScheme<Projective, H>,
CS2: CommitmentScheme<Projective2, H>,
const H: bool,
>(
poseidon_config: PoseidonConfig<Fr>, poseidon_config: PoseidonConfig<Fr>,
F_circuit: CubicFCircuit<Fr>, F_circuit: CubicFCircuit<Fr>,
) { ) {
let mut rng = ark_std::test_rng(); let mut rng = ark_std::test_rng();
type N<CS1, CS2> = Nova<Projective, GVar, Projective2, GVar2, CubicFCircuit<Fr>, CS1, CS2>;
let prep_param = PreprocessorParam::<Projective, Projective2, CubicFCircuit<Fr>, CS1, CS2> {
poseidon_config,
F: F_circuit,
cs_pp: None,
cs_vp: None,
cf_cs_pp: None,
cf_cs_vp: None,
};
let nova_params = N::preprocess(&mut rng, &prep_param).unwrap();
let prep_param =
PreprocessorParam::<Projective, Projective2, CubicFCircuit<Fr>, CS1, CS2, H> {
poseidon_config,
F: F_circuit,
cs_pp: None,
cs_vp: None,
cf_cs_pp: None,
cf_cs_vp: None,
};
let nova_params = Nova::<
Projective,
GVar,
Projective2,
GVar2,
CubicFCircuit<Fr>,
CS1,
CS2,
H,
>::preprocess(&mut rng, &prep_param)
.unwrap();
let z_0 = vec![Fr::from(3_u32)]; let z_0 = vec![Fr::from(3_u32)];
let mut nova = N::init(&nova_params, F_circuit, z_0.clone()).unwrap();
let mut nova =
Nova::<Projective, GVar, Projective2, GVar2, CubicFCircuit<Fr>, CS1, CS2, H>::init(
&nova_params,
F_circuit,
z_0.clone(),
)
.unwrap();
let num_steps: usize = 3; let num_steps: usize = 3;
for _ in 0..num_steps { for _ in 0..num_steps {
@ -966,7 +1032,7 @@ pub mod tests {
assert_eq!(Fr::from(num_steps as u32), nova.i); assert_eq!(Fr::from(num_steps as u32), nova.i);
let (running_instance, incoming_instance, cyclefold_instance) = nova.instances(); let (running_instance, incoming_instance, cyclefold_instance) = nova.instances();
N::<CS1, CS2>::verify(
Nova::<Projective, GVar, Projective2, GVar2, CubicFCircuit<Fr>, CS1, CS2, H>::verify(
nova_params.1, // Nova's verifier params nova_params.1, // Nova's verifier params
z_0, z_0,
nova.z_i, nova.z_i,

+ 20
- 17
folding-schemes/src/folding/nova/nifs.rs

@ -12,12 +12,13 @@ use crate::Error;
/// Implements the Non-Interactive Folding Scheme described in section 4 of /// Implements the Non-Interactive Folding Scheme described in section 4 of
/// [Nova](https://eprint.iacr.org/2021/370.pdf) /// [Nova](https://eprint.iacr.org/2021/370.pdf)
pub struct NIFS<C: CurveGroup, CS: CommitmentScheme<C>> {
/// `H` specifies whether the NIFS will use a blinding factor
pub struct NIFS<C: CurveGroup, CS: CommitmentScheme<C, H>, const H: bool = false> {
_c: PhantomData<C>, _c: PhantomData<C>,
_cp: PhantomData<CS>, _cp: PhantomData<CS>,
} }
impl<C: CurveGroup, CS: CommitmentScheme<C>> NIFS<C, CS>
impl<C: CurveGroup, CS: CommitmentScheme<C, H>, const H: bool> NIFS<C, CS, H>
where where
<C as Group>::ScalarField: Absorb, <C as Group>::ScalarField: Absorb,
{ {
@ -141,10 +142,10 @@ where
) -> Result<(Witness<C>, CommittedInstance<C>), Error> { ) -> Result<(Witness<C>, CommittedInstance<C>), Error> {
// fold witness // fold witness
// use r_T=0 since we don't need hiding property for cm(T) // use r_T=0 since we don't need hiding property for cm(T)
let w3 = NIFS::<C, CS>::fold_witness(r, w1, w2, T, C::ScalarField::zero())?;
let w3 = NIFS::<C, CS, H>::fold_witness(r, w1, w2, T, C::ScalarField::zero())?;
// fold committed instances // fold committed instances
let ci3 = NIFS::<C, CS>::fold_committed_instance(r, ci1, ci2, &cmT);
let ci3 = NIFS::<C, CS, H>::fold_committed_instance(r, ci1, ci2, &cmT);
Ok((w3, ci3)) Ok((w3, ci3))
} }
@ -158,7 +159,7 @@ where
ci2: &CommittedInstance<C>, ci2: &CommittedInstance<C>,
cmT: &C, cmT: &C,
) -> CommittedInstance<C> { ) -> CommittedInstance<C> {
NIFS::<C, CS>::fold_committed_instance(r, ci1, ci2, cmT)
NIFS::<C, CS, H>::fold_committed_instance(r, ci1, ci2, cmT)
} }
/// Verify committed folded instance (ci) relations. Notice that this method does not open the /// Verify committed folded instance (ci) relations. Notice that this method does not open the
@ -206,7 +207,7 @@ pub mod tests {
}; };
use ark_ff::{BigInteger, PrimeField}; use ark_ff::{BigInteger, PrimeField};
use ark_pallas::{Fr, Projective}; use ark_pallas::{Fr, Projective};
use ark_std::{ops::Mul, UniformRand};
use ark_std::{ops::Mul, test_rng, UniformRand};
use crate::arith::r1cs::tests::{get_test_r1cs, get_test_z}; use crate::arith::r1cs::tests::{get_test_r1cs, get_test_z};
use crate::commitment::pedersen::{Params as PedersenParams, Pedersen}; use crate::commitment::pedersen::{Params as PedersenParams, Pedersen};
@ -241,18 +242,18 @@ pub mod tests {
let (w1, x1) = r1cs.split_z(&z1); let (w1, x1) = r1cs.split_z(&z1);
let (w2, x2) = r1cs.split_z(&z2); let (w2, x2) = r1cs.split_z(&z2);
let w1 = Witness::<C>::new(w1.clone(), r1cs.A.n_rows);
let w2 = Witness::<C>::new(w2.clone(), r1cs.A.n_rows);
let w1 = Witness::<C>::new::<false>(w1.clone(), r1cs.A.n_rows, test_rng());
let w2 = Witness::<C>::new::<false>(w2.clone(), r1cs.A.n_rows, test_rng());
let mut rng = ark_std::test_rng(); let mut rng = ark_std::test_rng();
let (pedersen_params, _) = Pedersen::<C>::setup(&mut rng, r1cs.A.n_cols).unwrap(); let (pedersen_params, _) = Pedersen::<C>::setup(&mut rng, r1cs.A.n_cols).unwrap();
// compute committed instances // compute committed instances
let ci1 = w1 let ci1 = w1
.commit::<Pedersen<C>>(&pedersen_params, x1.clone())
.commit::<Pedersen<C>, false>(&pedersen_params, x1.clone())
.unwrap(); .unwrap();
let ci2 = w2 let ci2 = w2
.commit::<Pedersen<C>>(&pedersen_params, x2.clone())
.commit::<Pedersen<C>, false>(&pedersen_params, x2.clone())
.unwrap(); .unwrap();
// NIFS.P // NIFS.P
@ -304,9 +305,9 @@ pub mod tests {
let (pedersen_params, _) = Pedersen::<Projective>::setup(&mut rng, r1cs.A.n_cols).unwrap(); let (pedersen_params, _) = Pedersen::<Projective>::setup(&mut rng, r1cs.A.n_cols).unwrap();
// dummy instance, witness and public inputs zeroes // dummy instance, witness and public inputs zeroes
let w_dummy = Witness::<Projective>::new(vec![Fr::zero(); w1.len()], r1cs.A.n_rows);
let w_dummy = Witness::<Projective>::dummy(w1.len(), r1cs.A.n_rows);
let mut u_dummy = w_dummy let mut u_dummy = w_dummy
.commit::<Pedersen<Projective>>(&pedersen_params, vec![Fr::zero(); x1.len()])
.commit::<Pedersen<Projective>, false>(&pedersen_params, vec![Fr::zero(); x1.len()])
.unwrap(); .unwrap();
u_dummy.u = Fr::zero(); u_dummy.u = Fr::zero();
@ -353,7 +354,7 @@ pub mod tests {
// check that folded commitments from folded instance (ci) are equal to folding the // check that folded commitments from folded instance (ci) are equal to folding the
// use folded rE, rW to commit w3 // use folded rE, rW to commit w3
let ci3_expected = w3 let ci3_expected = w3
.commit::<Pedersen<Projective>>(&pedersen_params, ci3.x.clone())
.commit::<Pedersen<Projective>, false>(&pedersen_params, ci3.x.clone())
.unwrap(); .unwrap();
assert_eq!(ci3_expected.cmE, ci3.cmE); assert_eq!(ci3_expected.cmE, ci3.cmE);
assert_eq!(ci3_expected.cmW, ci3.cmW); assert_eq!(ci3_expected.cmW, ci3.cmW);
@ -417,9 +418,10 @@ pub mod tests {
let (pedersen_params, _) = Pedersen::<Projective>::setup(&mut rng, r1cs.A.n_cols).unwrap(); let (pedersen_params, _) = Pedersen::<Projective>::setup(&mut rng, r1cs.A.n_cols).unwrap();
// prepare the running instance // prepare the running instance
let mut running_instance_w = Witness::<Projective>::new(w.clone(), r1cs.A.n_rows);
let mut running_instance_w =
Witness::<Projective>::new::<false>(w.clone(), r1cs.A.n_rows, test_rng());
let mut running_committed_instance = running_instance_w let mut running_committed_instance = running_instance_w
.commit::<Pedersen<Projective>>(&pedersen_params, x)
.commit::<Pedersen<Projective>, false>(&pedersen_params, x)
.unwrap(); .unwrap();
r1cs.check_relaxed_instance_relation(&running_instance_w, &running_committed_instance) r1cs.check_relaxed_instance_relation(&running_instance_w, &running_committed_instance)
@ -430,9 +432,10 @@ pub mod tests {
// prepare the incoming instance // prepare the incoming instance
let incoming_instance_z = get_test_z(i + 4); let incoming_instance_z = get_test_z(i + 4);
let (w, x) = r1cs.split_z(&incoming_instance_z); let (w, x) = r1cs.split_z(&incoming_instance_z);
let incoming_instance_w = Witness::<Projective>::new(w.clone(), r1cs.A.n_rows);
let incoming_instance_w =
Witness::<Projective>::new::<false>(w.clone(), r1cs.A.n_rows, test_rng());
let incoming_committed_instance = incoming_instance_w let incoming_committed_instance = incoming_instance_w
.commit::<Pedersen<Projective>>(&pedersen_params, x)
.commit::<Pedersen<Projective>, false>(&pedersen_params, x)
.unwrap(); .unwrap();
r1cs.check_relaxed_instance_relation( r1cs.check_relaxed_instance_relation(
&incoming_instance_w, &incoming_instance_w,

+ 10
- 8
folding-schemes/src/folding/nova/serialize.rs

@ -21,13 +21,14 @@ use crate::{
frontend::FCircuit, frontend::FCircuit,
}; };
impl<C1, GC1, C2, GC2, FC, CS1, CS2> CanonicalSerialize for Nova<C1, GC1, C2, GC2, FC, CS1, CS2>
impl<C1, GC1, C2, GC2, FC, CS1, CS2, const H: bool> CanonicalSerialize
for Nova<C1, GC1, C2, GC2, FC, CS1, CS2, H>
where where
C1: CurveGroup, C1: CurveGroup,
C2: CurveGroup, C2: CurveGroup,
FC: FCircuit<C1::ScalarField>, FC: FCircuit<C1::ScalarField>,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
<C1 as CurveGroup>::BaseField: PrimeField, <C1 as CurveGroup>::BaseField: PrimeField,
<C2 as CurveGroup>::BaseField: PrimeField, <C2 as CurveGroup>::BaseField: PrimeField,
<C1 as Group>::ScalarField: Absorb, <C1 as Group>::ScalarField: Absorb,
@ -94,13 +95,13 @@ where
// Note that we can't derive or implement `CanonicalDeserialize` directly. // Note that we can't derive or implement `CanonicalDeserialize` directly.
// This is because `CurveVar` notably does not implement the `Sync` trait. // This is because `CurveVar` notably does not implement the `Sync` trait.
impl<C1, GC1, C2, GC2, FC, CS1, CS2> Nova<C1, GC1, C2, GC2, FC, CS1, CS2>
impl<C1, GC1, C2, GC2, FC, CS1, CS2, const H: bool> Nova<C1, GC1, C2, GC2, FC, CS1, CS2, H>
where where
C1: CurveGroup, C1: CurveGroup,
C2: CurveGroup, C2: CurveGroup,
FC: FCircuit<CF1<C1>, Params = ()>, FC: FCircuit<CF1<C1>, Params = ()>,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
<C1 as CurveGroup>::BaseField: PrimeField, <C1 as CurveGroup>::BaseField: PrimeField,
<C2 as CurveGroup>::BaseField: PrimeField, <C2 as CurveGroup>::BaseField: PrimeField,
<C1 as Group>::ScalarField: Absorb, <C1 as Group>::ScalarField: Absorb,
@ -117,7 +118,7 @@ where
mut reader: R, mut reader: R,
compress: ark_serialize::Compress, compress: ark_serialize::Compress,
validate: ark_serialize::Validate, validate: ark_serialize::Validate,
prover_params: ProverParams<C1, C2, CS1, CS2>,
prover_params: ProverParams<C1, C2, CS1, CS2, H>,
poseidon_config: PoseidonConfig<C1::ScalarField>, poseidon_config: PoseidonConfig<C1::ScalarField>,
) -> Result<Self, ark_serialize::SerializationError> { ) -> Result<Self, ark_serialize::SerializationError> {
let pp_hash = C1::ScalarField::deserialize_with_mode(&mut reader, compress, validate)?; let pp_hash = C1::ScalarField::deserialize_with_mode(&mut reader, compress, validate)?;
@ -152,7 +153,6 @@ where
cs2.finalize(); cs2.finalize();
let cs2 = cs2.into_inner().ok_or(SerializationError::InvalidData)?; let cs2 = cs2.into_inner().ok_or(SerializationError::InvalidData)?;
let cf_r1cs = extract_r1cs::<C1::BaseField>(&cs2); let cf_r1cs = extract_r1cs::<C1::BaseField>(&cs2);
Ok(Nova { Ok(Nova {
_gc1: PhantomData, _gc1: PhantomData,
_c2: PhantomData, _c2: PhantomData,
@ -207,6 +207,7 @@ pub mod tests {
CubicFCircuit<Fr>, CubicFCircuit<Fr>,
KZG<'static, Bn254>, KZG<'static, Bn254>,
Pedersen<Projective2>, Pedersen<Projective2>,
false,
>; >;
let prep_param = PreprocessorParam::new(poseidon_config.clone(), F_circuit); let prep_param = PreprocessorParam::new(poseidon_config.clone(), F_circuit);
let nova_params = N::preprocess(&mut rng, &prep_param).unwrap(); let nova_params = N::preprocess(&mut rng, &prep_param).unwrap();
@ -242,6 +243,7 @@ pub mod tests {
CubicFCircuit<Fr>, CubicFCircuit<Fr>,
KZG<Bn254>, KZG<Bn254>,
Pedersen<Projective2>, Pedersen<Projective2>,
false,
>::deserialize_nova( >::deserialize_nova(
bytes.as_slice(), bytes.as_slice(),
Compress::No, Compress::No,

+ 2
- 2
folding-schemes/src/folding/nova/traits.rs

@ -1,6 +1,6 @@
use ark_crypto_primitives::sponge::Absorb; use ark_crypto_primitives::sponge::Absorb;
use ark_ec::{CurveGroup, Group}; use ark_ec::{CurveGroup, Group};
use ark_std::{One, Zero};
use ark_std::One;
use super::{CommittedInstance, Witness}; use super::{CommittedInstance, Witness};
use crate::arith::{r1cs::R1CS, Arith}; use crate::arith::{r1cs::R1CS, Arith};
@ -34,7 +34,7 @@ where
{ {
fn dummy_instance(&self) -> (Witness<C>, CommittedInstance<C>) { fn dummy_instance(&self) -> (Witness<C>, CommittedInstance<C>) {
let w_len = self.A.n_cols - 1 - self.l; let w_len = self.A.n_cols - 1 - self.l;
let w_dummy = Witness::<C>::new(vec![C::ScalarField::zero(); w_len], self.A.n_rows);
let w_dummy = Witness::<C>::dummy(w_len, self.A.n_rows);
let u_dummy = CommittedInstance::<C>::dummy(self.l); let u_dummy = CommittedInstance::<C>::dummy(self.l);
(w_dummy, u_dummy) (w_dummy, u_dummy)
} }

+ 2
- 0
folding-schemes/src/lib.rs

@ -77,6 +77,8 @@ pub enum Error {
PedersenParamsLen(usize, usize), PedersenParamsLen(usize, usize),
#[error("Blinding factor not 0 for Commitment without hiding")] #[error("Blinding factor not 0 for Commitment without hiding")]
BlindingNotZero, BlindingNotZero,
#[error("Blinding factors incorrect, blinding is set to {0} but blinding values are {1}")]
IncorrectBlinding(bool, String),
#[error("Commitment verification failed")] #[error("Commitment verification failed")]
CommitmentVerificationFail, CommitmentVerificationFail,

+ 3
- 3
folding-schemes/src/utils/mod.rs

@ -41,7 +41,7 @@ pub fn get_cm_coordinates(cm: &C) -> Vec {
} }
/// returns the hash of the given public parameters of the Folding Scheme /// returns the hash of the given public parameters of the Folding Scheme
pub fn pp_hash<C1, C2, CS1, CS2>(
pub fn pp_hash<C1, C2, CS1, CS2, const H: bool>(
arith: &impl Arith<C1::ScalarField>, arith: &impl Arith<C1::ScalarField>,
cf_arith: &impl Arith<C2::ScalarField>, cf_arith: &impl Arith<C2::ScalarField>,
cs_vp: &CS1::VerifierParams, cs_vp: &CS1::VerifierParams,
@ -51,8 +51,8 @@ pub fn pp_hash(
where where
C1: CurveGroup, C1: CurveGroup,
C2: CurveGroup, C2: CurveGroup,
CS1: CommitmentScheme<C1>,
CS2: CommitmentScheme<C2>,
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
{ {
let mut hasher = Sha3_256::new(); let mut hasher = Sha3_256::new();

+ 6
- 5
solidity-verifiers/src/verifiers/nova_cyclefold.rs

@ -166,7 +166,7 @@ mod tests {
NovaCycleFoldVerifierKey, ProtocolVerifierKey, NovaCycleFoldVerifierKey, ProtocolVerifierKey,
}; };
type NOVA<FC> = Nova<G1, GVar, G2, GVar2, FC, KZG<'static, Bn254>, Pedersen<G2>>;
type NOVA<FC> = Nova<G1, GVar, G2, GVar2, FC, KZG<'static, Bn254>, Pedersen<G2>, false>;
type DECIDER<FC> = DeciderEth< type DECIDER<FC> = DeciderEth<
G1, G1,
GVar, GVar,
@ -318,10 +318,11 @@ mod tests {
let poseidon_config = poseidon_canonical_config::<Fr>(); let poseidon_config = poseidon_canonical_config::<Fr>();
let f_circuit = FC::new(()).unwrap(); let f_circuit = FC::new(()).unwrap();
let prep_param = PreprocessorParam::<G1, G2, FC, KZG<'static, Bn254>, Pedersen<G2>>::new(
poseidon_config,
f_circuit.clone(),
);
let prep_param =
PreprocessorParam::<G1, G2, FC, KZG<'static, Bn254>, Pedersen<G2>, false>::new(
poseidon_config,
f_circuit.clone(),
);
let nova_params = NOVA::preprocess(&mut rng, &prep_param).unwrap(); let nova_params = NOVA::preprocess(&mut rng, &prep_param).unwrap();
let nova = NOVA::init( let nova = NOVA::init(
&nova_params, &nova_params,

Loading…
Cancel
Save