Implement HyperNova's IVC into the FoldingScheme trait (#116)

- implement the IVC `FoldingScheme` trait for HyperNova
- refactor Nova's preprocess logic to make it simplier to use
- add to Decider trait (& Nova's DeciderEth) a preprocess method
- get rid of the `init_nova_ivc_params` and `init_ivc_and_decider_params` methods in `examples` since this is achieved with the `FS::preprocess` & `Decider::preprocess` methods
  - (update the examples code to the simplified interface using
    FS::preprocess & Decider::preprocess)
This commit is contained in:
2024-07-04 11:14:31 +02:00
committed by GitHub
parent 456dc9f7a1
commit b5667968f4
25 changed files with 1144 additions and 465 deletions

View File

@@ -11,10 +11,7 @@ use ark_std::Zero;
use super::Witness;
use crate::ccs::CCS;
use crate::commitment::{
pedersen::{Params as PedersenParams, Pedersen},
CommitmentScheme,
};
use crate::commitment::CommitmentScheme;
use crate::folding::circuits::nonnative::affine::nonnative_affine_to_field_elements;
use crate::utils::mle::dense_vec_to_dense_mle;
use crate::utils::vec::mat_vec_mul;
@@ -36,10 +33,10 @@ pub struct LCCCS<C: CurveGroup> {
}
impl<F: PrimeField> CCS<F> {
pub fn to_lcccs<R: Rng, C: CurveGroup>(
pub fn to_lcccs<R: Rng, C: CurveGroup, CS: CommitmentScheme<C>>(
&self,
rng: &mut R,
pedersen_params: &PedersenParams<C>,
cs_params: &CS::ProverParams,
z: &[C::ScalarField],
) -> Result<(LCCCS<C>, Witness<C::ScalarField>), Error>
where
@@ -47,8 +44,13 @@ impl<F: PrimeField> CCS<F> {
C: CurveGroup<ScalarField = F>,
{
let w: Vec<C::ScalarField> = z[(1 + self.l)..].to_vec();
let r_w = C::ScalarField::rand(rng);
let C = Pedersen::<C, true>::commit(pedersen_params, &w, &r_w)?;
// if the commitment scheme is set to be hiding, set the random blinding parameter
let r_w = if CS::is_hiding() {
C::ScalarField::rand(rng)
} else {
C::ScalarField::zero()
};
let C = CS::commit(cs_params, &w, &r_w)?;
let r_x: Vec<C::ScalarField> = (0..self.s).map(|_| C::ScalarField::rand(rng)).collect();
@@ -91,19 +93,13 @@ impl<C: CurveGroup> LCCCS<C> {
}
}
/// Perform the check of the LCCCS instance described at section 4.2
/// Perform the check of the LCCCS instance described at section 4.2,
/// notice that this method does not check the commitment correctness
pub fn check_relation(
&self,
pedersen_params: &PedersenParams<C>,
ccs: &CCS<C::ScalarField>,
w: &Witness<C::ScalarField>,
) -> Result<(), Error> {
// check that C is the commitment of w. Notice that this is not verifying a Pedersen
// opening, but checking that the Commitment comes from committing to the witness.
if self.C != Pedersen::<C, true>::commit(pedersen_params, &w.w, &w.r_w)? {
return Err(Error::NotSatisfied);
}
// check CCS relation
let z: Vec<C::ScalarField> = [vec![self.u], self.x.clone(), w.w.to_vec()].concat();
@@ -172,6 +168,7 @@ pub mod tests {
r1cs::R1CS,
tests::{get_test_ccs, get_test_z},
};
use crate::commitment::pedersen::Pedersen;
use crate::utils::hypercube::BooleanHypercube;
use crate::utils::virtual_polynomial::{build_eq_x_r_vec, VirtualPolynomial};
@@ -206,14 +203,16 @@ pub mod tests {
let n_rows = 2_u32.pow(5) as usize;
let n_cols = 2_u32.pow(5) as usize;
let r1cs = R1CS::rand(&mut rng, n_rows, n_cols);
let r1cs = R1CS::<Fr>::rand(&mut rng, n_rows, n_cols);
let ccs = CCS::from_r1cs(r1cs);
let z: Vec<Fr> = (0..n_cols).map(|_| Fr::rand(&mut rng)).collect();
let (pedersen_params, _) =
Pedersen::<Projective>::setup(&mut rng, ccs.n - ccs.l - 1).unwrap();
let (lcccs, _) = ccs.to_lcccs(&mut rng, &pedersen_params, &z).unwrap();
let (lcccs, _) = ccs
.to_lcccs::<_, Projective, Pedersen<Projective>>(&mut rng, &pedersen_params, &z)
.unwrap();
// with our test vector coming from R1CS, v should have length 3
assert_eq!(lcccs.v.len(), 3);
@@ -245,7 +244,9 @@ pub mod tests {
let (pedersen_params, _) =
Pedersen::<Projective>::setup(&mut rng, ccs.n - ccs.l - 1).unwrap();
// Compute v_j with the right z
let (lcccs, _) = ccs.to_lcccs(&mut rng, &pedersen_params, &z).unwrap();
let (lcccs, _) = ccs
.to_lcccs::<_, Projective, Pedersen<Projective>>(&mut rng, &pedersen_params, &z)
.unwrap();
// with our test vector coming from R1CS, v should have length 3
assert_eq!(lcccs.v.len(), 3);