Protogalaxy based IVC (#123)

* Parallelize vector and matrix operations

* Implement convenient methods for `NonNativeAffineVar`

* Return `L_X_evals` and intermediate `phi_star`s from ProtoGalaxy prover.

These values will be used as hints to the augmented circuit

* Correctly use number of variables, number of constraints, and `t`

* Fix the size of `F_coeffs` and `K_coeffs` for in-circuit consistency

* Improve prover's performance

* Make `prepare_inputs` generic

* Remove redundant parameters in verifier

* Move `eval_f` to arith

* `u` is unnecessary in ProtoGalaxy

* Convert `RelaxedR1CS` to a trait that can be used in both Nova and ProtoGalaxy

* Implement several traits for ProtoGalaxy

* Move `FCircuit` impls to `utils.rs` and add `DummyCircuit`

* `AugmentedFCircuit` and ProtoGalaxy-based IVC

* Add explanations about IVC prover and in-circuit operations

* Avoid using unstable features

* Rename `PROTOGALAXY` to `PG` to make clippy happy

* Fix merge conflicts in `RelaxedR1CS::sample`

* Fix merge conflicts in `CycleFoldCircuit`

* Swap `m` and `n` for protogalaxy

* Add `#[cfg(test)]` to test-only util circuits

* Prefer unit struct over empty struct

* Add documents to `AugmentedFCircuit` for ProtoGalaxy

* Fix the names for CycleFold cricuits in ProtoGalaxy

* Fix usize conversion when targeting wasm

* Restrict the visibility of fields in `AugmentedFCircuit` to `pub(super)`

* Make CycleFold circuits and configs public

* Add docs for `ProverParams` and `VerifierParams`

* Refactor `pow_i`

* Fix imports

* Remove lint reasons

* Fix type inference
This commit is contained in:
winderica
2024-09-12 15:08:53 +01:00
committed by GitHub
parent 0ad54576ec
commit 1322767a1e
26 changed files with 2222 additions and 695 deletions

View File

@@ -475,30 +475,30 @@ pub struct AugmentedFCircuit<
> where
for<'a> &'a GC2: GroupOpsBounds<'a, C2, GC2>,
{
pub _c2: PhantomData<C2>,
pub _gc2: PhantomData<GC2>,
pub poseidon_config: PoseidonConfig<CF1<C1>>,
pub ccs: CCS<C1::ScalarField>, // CCS of the AugmentedFCircuit
pub pp_hash: Option<CF1<C1>>,
pub i: Option<CF1<C1>>,
pub i_usize: Option<usize>,
pub z_0: Option<Vec<C1::ScalarField>>,
pub z_i: Option<Vec<C1::ScalarField>>,
pub external_inputs: Option<Vec<C1::ScalarField>>,
pub U_i: Option<LCCCS<C1>>,
pub Us: Option<Vec<LCCCS<C1>>>, // other U_i's to be folded that are not the main running instance
pub u_i_C: Option<C1>, // u_i.C
pub us: Option<Vec<CCCS<C1>>>, // other u_i's to be folded that are not the main incoming instance
pub U_i1_C: Option<C1>, // U_{i+1}.C
pub F: FC, // F circuit
pub x: Option<CF1<C1>>, // public input (u_{i+1}.x[0])
pub nimfs_proof: Option<NIMFSProof<C1>>,
pub(super) _c2: PhantomData<C2>,
pub(super) _gc2: PhantomData<GC2>,
pub(super) poseidon_config: PoseidonConfig<CF1<C1>>,
pub(super) ccs: CCS<C1::ScalarField>, // CCS of the AugmentedFCircuit
pub(super) pp_hash: Option<CF1<C1>>,
pub(super) i: Option<CF1<C1>>,
pub(super) i_usize: Option<usize>,
pub(super) z_0: Option<Vec<C1::ScalarField>>,
pub(super) z_i: Option<Vec<C1::ScalarField>>,
pub(super) external_inputs: Option<Vec<C1::ScalarField>>,
pub(super) U_i: Option<LCCCS<C1>>,
pub(super) Us: Option<Vec<LCCCS<C1>>>, // other U_i's to be folded that are not the main running instance
pub(super) u_i_C: Option<C1>, // u_i.C
pub(super) us: Option<Vec<CCCS<C1>>>, // other u_i's to be folded that are not the main incoming instance
pub(super) U_i1_C: Option<C1>, // U_{i+1}.C
pub(super) F: FC, // F circuit
pub(super) x: Option<CF1<C1>>, // public input (u_{i+1}.x[0])
pub(super) nimfs_proof: Option<NIMFSProof<C1>>,
// cyclefold verifier on C1
pub cf_u_i_cmW: Option<C2>, // input, cf_u_i.cmW
pub cf_U_i: Option<CycleFoldCommittedInstance<C2>>, // input, RelaxedR1CS CycleFold instance
pub cf_x: Option<CF1<C1>>, // public input (cf_u_{i+1}.x[1])
pub cf_cmT: Option<C2>,
pub(super) cf_u_i_cmW: Option<C2>, // input, cf_u_i.cmW
pub(super) cf_U_i: Option<CycleFoldCommittedInstance<C2>>, // input, RelaxedR1CS CycleFold instance
pub(super) cf_x: Option<CF1<C1>>, // public input (cf_u_{i+1}.x[1])
pub(super) cf_cmT: Option<C2>,
}
impl<C1, C2, GC2, FC, const MU: usize, const NU: usize> AugmentedFCircuit<C1, C2, GC2, FC, MU, NU>
@@ -891,7 +891,7 @@ mod tests {
use crate::{
arith::{
ccs::tests::{get_test_ccs, get_test_z},
r1cs::extract_w_x,
r1cs::{extract_w_x, RelaxedR1CS},
},
commitment::{pedersen::Pedersen, CommitmentScheme},
folding::{
@@ -900,9 +900,8 @@ mod tests {
utils::{compute_c, compute_sigmas_thetas},
HyperNovaCycleFoldCircuit,
},
nova::traits::NovaR1CS,
},
frontend::tests::CubicFCircuit,
frontend::utils::CubicFCircuit,
transcript::poseidon::poseidon_canonical_config,
utils::get_cm_coordinates,
};
@@ -1216,7 +1215,7 @@ mod tests {
let (cf_W_dummy, cf_U_dummy): (
CycleFoldWitness<Projective2>,
CycleFoldCommittedInstance<Projective2>,
) = cf_r1cs.dummy_instance();
) = cf_r1cs.dummy_running_instance();
// set the initial dummy instances
let mut W_i = W_dummy.clone();
@@ -1455,9 +1454,7 @@ mod tests {
u_i.check_relation(&ccs, &w_i).unwrap();
// check the CycleFold instance relation
cf_r1cs
.check_relaxed_instance_relation(&cf_W_i, &cf_U_i)
.unwrap();
cf_r1cs.check_relaxed_relation(&cf_W_i, &cf_U_i).unwrap();
println!("augmented_f_circuit step {}: {:?}", i, start.elapsed());
}

View File

@@ -228,7 +228,7 @@ pub mod tests {
use super::*;
use crate::commitment::{kzg::KZG, pedersen::Pedersen};
use crate::folding::hypernova::PreprocessorParam;
use crate::frontend::tests::CubicFCircuit;
use crate::frontend::utils::CubicFCircuit;
use crate::transcript::poseidon::poseidon_canonical_config;
#[test]

View File

@@ -517,7 +517,7 @@ pub mod tests {
use super::*;
use crate::commitment::pedersen::Pedersen;
use crate::folding::nova::PreprocessorParam;
use crate::frontend::tests::CubicFCircuit;
use crate::frontend::utils::CubicFCircuit;
use crate::transcript::poseidon::poseidon_canonical_config;
use crate::FoldingScheme;

View File

@@ -21,7 +21,6 @@ use circuits::AugmentedFCircuit;
use lcccs::LCCCS;
use nimfs::NIMFS;
use crate::commitment::CommitmentScheme;
use crate::constants::NOVA_N_BITS_RO;
use crate::folding::circuits::{
cyclefold::{
@@ -30,10 +29,11 @@ use crate::folding::circuits::{
},
CF2,
};
use crate::folding::nova::{get_r1cs_from_cs, traits::NovaR1CS, PreprocessorParam};
use crate::folding::nova::{get_r1cs_from_cs, PreprocessorParam};
use crate::frontend::FCircuit;
use crate::utils::{get_cm_coordinates, pp_hash};
use crate::Error;
use crate::{arith::r1cs::RelaxedR1CS, commitment::CommitmentScheme};
use crate::{
arith::{
ccs::CCS,
@@ -42,7 +42,8 @@ use crate::{
FoldingScheme, MultiFolding,
};
struct HyperNovaCycleFoldConfig<C: CurveGroup, const MU: usize, const NU: usize> {
/// Configuration for HyperNova's CycleFold circuit
pub struct HyperNovaCycleFoldConfig<C: CurveGroup, const MU: usize, const NU: usize> {
_c: PhantomData<C>,
}
@@ -55,7 +56,9 @@ impl<C: CurveGroup, const MU: usize, const NU: usize> CycleFoldConfig
type F = C::BaseField;
}
type HyperNovaCycleFoldCircuit<C, GC, const MU: usize, const NU: usize> =
/// CycleFold circuit for computing random linear combinations of group elements
/// in HyperNova instances.
pub type HyperNovaCycleFoldCircuit<C, GC, const MU: usize, const NU: usize> =
CycleFoldCircuit<HyperNovaCycleFoldConfig<C, MU, NU>, GC>;
/// Witness for the LCCCS & CCCS, containing the w vector, and the r_w used as randomness in the Pedersen commitment.
@@ -76,6 +79,7 @@ impl<F: PrimeField> Witness<F> {
}
}
/// Proving parameters for HyperNova-based IVC
#[derive(Debug, Clone)]
pub struct ProverParams<C1, C2, CS1, CS2, const H: bool>
where
@@ -84,13 +88,18 @@ where
CS1: CommitmentScheme<C1, H>,
CS2: CommitmentScheme<C2, H>,
{
/// Poseidon sponge configuration
pub poseidon_config: PoseidonConfig<C1::ScalarField>,
/// Proving parameters of the underlying commitment scheme over C1
pub cs_pp: CS1::ProverParams,
/// Proving parameters of the underlying commitment scheme over C2
pub cf_cs_pp: CS2::ProverParams,
// if ccs is set, it will be used, if not, it will be computed at runtime
/// CCS of the Augmented Function circuit
/// If ccs is set, it will be used, if not, it will be computed at runtime
pub ccs: Option<CCS<C1::ScalarField>>,
}
/// Verification parameters for HyperNova-based IVC
#[derive(Debug, Clone)]
pub struct VerifierParams<
C1: CurveGroup,
@@ -99,10 +108,15 @@ pub struct VerifierParams<
CS2: CommitmentScheme<C2, H>,
const H: bool,
> {
/// Poseidon sponge configuration
pub poseidon_config: PoseidonConfig<C1::ScalarField>,
/// CCS of the Augmented step circuit
pub ccs: CCS<C1::ScalarField>,
/// R1CS of the CycleFold circuit
pub cf_r1cs: R1CS<C2::ScalarField>,
/// Verification parameters of the underlying commitment scheme over C1
pub cs_vp: CS1::VerifierParams,
/// Verification parameters of the underlying commitment scheme over C2
pub cf_cs_vp: CS2::VerifierParams,
}
@@ -282,7 +296,7 @@ where
let U_i = LCCCS::<C1>::dummy(self.ccs.l, self.ccs.t, self.ccs.s);
let mut u_i = CCCS::<C1>::dummy(self.ccs.l);
let (_, cf_U_i): (CycleFoldWitness<C2>, CycleFoldCommittedInstance<C2>) =
self.cf_r1cs.dummy_instance();
self.cf_r1cs.dummy_running_instance();
let sponge = PoseidonSponge::<C1::ScalarField>::new(&self.poseidon_config);
@@ -476,7 +490,7 @@ where
let w_dummy = W_dummy.clone();
let mut u_dummy = CCCS::<C1>::dummy(ccs.l);
let (cf_W_dummy, cf_U_dummy): (CycleFoldWitness<C2>, CycleFoldCommittedInstance<C2>) =
cf_r1cs.dummy_instance();
cf_r1cs.dummy_running_instance();
u_dummy.x = vec![
U_dummy.hash(
&sponge,
@@ -884,8 +898,7 @@ where
u_i.check_relation(&vp.ccs, &w_i)?;
// check CycleFold's RelaxedR1CS satisfiability
vp.cf_r1cs
.check_relaxed_instance_relation(&cf_W_i, &cf_U_i)?;
vp.cf_r1cs.check_relaxed_relation(&cf_W_i, &cf_U_i)?;
Ok(())
}
@@ -900,7 +913,7 @@ mod tests {
use super::*;
use crate::commitment::pedersen::Pedersen;
use crate::frontend::tests::CubicFCircuit;
use crate::frontend::utils::CubicFCircuit;
use crate::transcript::poseidon::poseidon_canonical_config;
#[test]