Refactor Arith trait (#162)

* `Dummy` trait

* More generic design for `Arith`

* Distinguish between incoming and running instances in ProtoGalaxy

* Format

* Fix unit test

* Fix incorrect arguments supplied to `CycleFoldWitness::dummy`

* `RUNNING` and `INCOMING` constants

* Better name and docs for `eval_core`

* More docs  for `Arith` methods and implementations

* Fix missing imports
This commit is contained in:
winderica
2024-09-25 18:21:30 +08:00
committed by GitHub
parent 1e9c13f852
commit f1d82418ba
24 changed files with 729 additions and 537 deletions

View File

@@ -31,7 +31,10 @@ use crate::folding::circuits::{
};
use crate::frontend::FCircuit;
use crate::transcript::{AbsorbNonNativeGadget, Transcript, TranscriptVar};
use crate::{constants::NOVA_N_BITS_RO, folding::traits::CommittedInstanceVarOps};
use crate::{
constants::NOVA_N_BITS_RO,
folding::traits::{CommittedInstanceVarOps, Dummy},
};
/// CommittedInstanceVar contains the u, x, cmE and cmW values which are folded on the main Nova
/// constraints field (E1::Fr, where E1 is the main curve). The peculiarity is that cmE and cmW are

View File

@@ -40,7 +40,7 @@ use crate::folding::circuits::{
CF1, CF2,
};
use crate::folding::nova::NovaCycleFoldConfig;
use crate::folding::traits::CommittedInstanceVarOps;
use crate::folding::traits::{CommittedInstanceVarOps, Dummy};
use crate::frontend::FCircuit;
use crate::utils::vec::poly_from_vec;
use crate::Error;
@@ -214,11 +214,8 @@ where
Ok(self.z_i.unwrap_or(vec![CF1::<C1>::zero()]))
})?;
let u_dummy_native = CommittedInstance::<C1>::dummy(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,
);
let u_dummy_native = CommittedInstance::<C1>::dummy(&self.r1cs);
let w_dummy_native = Witness::<C1>::dummy(&self.r1cs);
let u_i = CommittedInstanceVar::<C1>::new_witness(cs.clone(), || {
Ok(self.u_i.unwrap_or(u_dummy_native.clone()))
@@ -436,9 +433,8 @@ where
Ok(self.pp_hash.unwrap_or_else(CF1::<C2>::zero))
})?;
let cf_u_dummy_native = CommittedInstance::<C2>::dummy(NovaCycleFoldConfig::<C1>::IO_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_dummy_native = CommittedInstance::<C2>::dummy(&self.cf_r1cs);
let w_dummy_native = Witness::<C2>::dummy(&self.cf_r1cs);
let cf_U_i = CommittedInstanceVar::<C2>::new_input(cs.clone(), || {
Ok(self.cf_U_i.unwrap_or_else(|| cf_u_dummy_native.clone()))
})?;

View File

@@ -29,6 +29,7 @@ use super::{
nifs::NIFS,
CommittedInstance, Nova, Witness,
};
use crate::commitment::{pedersen::Params as PedersenParams, CommitmentScheme};
use crate::folding::circuits::{
cyclefold::{CycleFoldCommittedInstance, CycleFoldWitness},
nonnative::{affine::NonNativeAffineVar, uint::NonNativeUintVar},
@@ -41,10 +42,9 @@ use crate::utils::{
vec::poly_from_vec,
};
use crate::Error;
use crate::{arith::r1cs::R1CS, folding::traits::WitnessVarOps};
use crate::{
commitment::{pedersen::Params as PedersenParams, CommitmentScheme},
folding::traits::CommittedInstanceVarOps,
arith::r1cs::R1CS,
folding::traits::{CommittedInstanceVarOps, Dummy, WitnessVarOps},
};
#[derive(Debug, Clone)]
@@ -356,11 +356,8 @@ where
Ok(self.z_i.unwrap_or(vec![CF1::<C1>::zero()]))
})?;
let u_dummy_native = CommittedInstance::<C1>::dummy(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,
);
let u_dummy_native = CommittedInstance::<C1>::dummy(&self.r1cs);
let w_dummy_native = Witness::<C1>::dummy(&self.r1cs);
let u_i = CommittedInstanceVar::<C1>::new_witness(cs.clone(), || {
Ok(self.u_i.unwrap_or(u_dummy_native.clone()))
@@ -437,10 +434,7 @@ where
let cf_u_dummy_native =
CycleFoldCommittedInstance::<C2>::dummy(NovaCycleFoldConfig::<C1>::IO_LEN);
let w_dummy_native = CycleFoldWitness::<C2>::dummy(
self.cf_r1cs.A.n_cols - 1 - self.cf_r1cs.l,
self.cf_E_len,
);
let w_dummy_native = CycleFoldWitness::<C2>::dummy(&self.cf_r1cs);
let cf_U_i = CycleFoldCommittedInstanceVar::<C2, GC2>::new_witness(cs.clone(), || {
Ok(self.cf_U_i.unwrap_or_else(|| cf_u_dummy_native.clone()))
})?;
@@ -608,7 +602,6 @@ pub mod tests {
r1cs::{
extract_r1cs, extract_w_x,
tests::{get_test_r1cs, get_test_z},
RelaxedR1CS,
},
Arith,
};
@@ -618,20 +611,18 @@ pub mod tests {
use crate::transcript::poseidon::poseidon_canonical_config;
use crate::FoldingScheme;
fn prepare_instances<C: CurveGroup, CS: CommitmentScheme<C>, R: Rng>(
// Convert `z` to a witness-instance pair for the relaxed R1CS
fn prepare_relaxed_witness_instance<C: CurveGroup, CS: CommitmentScheme<C>, R: Rng>(
mut rng: R,
r1cs: &R1CS<C::ScalarField>,
z: &[C::ScalarField],
) -> (Witness<C>, CommittedInstance<C>)
where
C::ScalarField: Absorb,
{
) -> (Witness<C>, CommittedInstance<C>) {
let (w, x) = r1cs.split_z(z);
let (cs_pp, _) = CS::setup(&mut rng, max(w.len(), r1cs.A.n_rows)).unwrap();
let mut w = Witness::new::<false>(w, r1cs.A.n_rows, &mut rng);
w.E = r1cs.eval_relation(z).unwrap();
w.E = r1cs.eval_at_z(z).unwrap();
let mut u = w.commit::<CS, false>(&cs_pp, x).unwrap();
u.u = z[0];
@@ -643,9 +634,10 @@ pub mod tests {
let rng = &mut thread_rng();
let r1cs: R1CS<Fr> = get_test_r1cs();
let mut z = get_test_z(3);
z[0] = Fr::rand(rng);
let (w, u) = prepare_instances::<_, Pedersen<Projective>, _>(rng, &r1cs, &z);
z[0] = Fr::rand(rng); // Randomize `z[0]` (i.e. `u.u`) to test the relaxed R1CS
let (w, u) = prepare_relaxed_witness_instance::<_, Pedersen<Projective>, _>(rng, &r1cs, &z);
let cs = ConstraintSystem::<Fr>::new_ref();
@@ -673,12 +665,11 @@ pub mod tests {
let r1cs = extract_r1cs::<Fr>(&cs);
let (w, x) = extract_w_x::<Fr>(&cs);
let mut z = [vec![Fr::one()], x, w].concat();
r1cs.check_relation(&z).unwrap();
r1cs.check_relation(&w, &x).unwrap();
z[0] = Fr::rand(rng);
let (w, u) = prepare_instances::<_, Pedersen<Projective>, _>(rng, &r1cs, &z);
r1cs.check_relaxed_relation(&w, &u).unwrap();
let z = [vec![Fr::rand(rng)], x, w].concat();
let (w, u) = prepare_relaxed_witness_instance::<_, Pedersen<Projective>, _>(rng, &r1cs, &z);
r1cs.check_relation(&w, &u).unwrap();
// set new CS for the circuit that checks the RelaxedR1CS of our original circuit
let cs = ConstraintSystem::<Fr>::new_ref();
@@ -767,9 +758,10 @@ pub mod tests {
let cs = cs.into_inner().unwrap();
let r1cs = extract_r1cs::<Fq>(&cs);
let (w, x) = extract_w_x::<Fq>(&cs);
let z = [vec![Fq::rand(rng)], x, w].concat();
let (w, u) = prepare_instances::<_, Pedersen<Projective2>, _>(rng, &r1cs, &z);
let z = [vec![Fq::rand(rng)], x, w].concat();
let (w, u) =
prepare_relaxed_witness_instance::<_, Pedersen<Projective2>, _>(rng, &r1cs, &z);
// natively
let cs = ConstraintSystem::<Fq>::new_ref();

View File

@@ -19,18 +19,21 @@ use crate::folding::circuits::cyclefold::{
fold_cyclefold_circuit, CycleFoldCircuit, CycleFoldCommittedInstance, CycleFoldConfig,
CycleFoldWitness,
};
use crate::folding::circuits::CF2;
use crate::folding::{
circuits::{CF1, CF2},
traits::Dummy,
};
use crate::frontend::FCircuit;
use crate::transcript::{poseidon::poseidon_canonical_config, AbsorbNonNative, Transcript};
use crate::utils::vec::is_zero_vec;
use crate::Error;
use crate::FoldingScheme;
use crate::{arith::r1cs::RelaxedR1CS, commitment::CommitmentScheme};
use crate::{
arith::r1cs::{extract_r1cs, extract_w_x, R1CS},
constants::NOVA_N_BITS_RO,
utils::{get_cm_coordinates, pp_hash},
};
use crate::{arith::Arith, commitment::CommitmentScheme};
use circuits::{AugmentedFCircuit, ChallengeGadget, CommittedInstanceVar};
use nifs::NIFS;
@@ -76,17 +79,23 @@ pub struct CommittedInstance<C: CurveGroup> {
pub x: Vec<C::ScalarField>,
}
impl<C: CurveGroup> CommittedInstance<C> {
pub fn dummy(io_len: usize) -> Self {
impl<C: CurveGroup> Dummy<usize> for CommittedInstance<C> {
fn dummy(io_len: usize) -> Self {
Self {
cmE: C::zero(),
u: C::ScalarField::zero(),
u: CF1::<C>::zero(),
cmW: C::zero(),
x: vec![C::ScalarField::zero(); io_len],
x: vec![CF1::<C>::zero(); io_len],
}
}
}
impl<C: CurveGroup> Dummy<&R1CS<CF1<C>>> for CommittedInstance<C> {
fn dummy(r1cs: &R1CS<CF1<C>>) -> Self {
Self::dummy(r1cs.l)
}
}
impl<C: CurveGroup> Absorb for CommittedInstance<C>
where
C::ScalarField: Absorb,
@@ -149,18 +158,6 @@ impl<C: CurveGroup> Witness<C> {
}
}
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 {
E: vec![C::ScalarField::zero(); e_len],
rE,
W: w,
rW,
}
}
pub fn commit<CS: CommitmentScheme<C, HC>, const HC: bool>(
&self,
params: &CS::ProverParams,
@@ -180,6 +177,17 @@ impl<C: CurveGroup> Witness<C> {
}
}
impl<C: CurveGroup> Dummy<&R1CS<CF1<C>>> for Witness<C> {
fn dummy(r1cs: &R1CS<CF1<C>>) -> Self {
Self {
E: vec![C::ScalarField::zero(); r1cs.A.n_rows],
rE: C::ScalarField::zero(),
W: vec![C::ScalarField::zero(); r1cs.A.n_cols - 1 - r1cs.l],
rW: C::ScalarField::zero(),
}
}
}
impl<C: CurveGroup> WitnessOps<C::ScalarField> for Witness<C> {
type Var = WitnessVar<C>;
@@ -562,9 +570,9 @@ where
let pp_hash = vp.pp_hash()?;
// setup the dummy instances
let (W_dummy, U_dummy) = r1cs.dummy_running_instance();
let (w_dummy, u_dummy) = r1cs.dummy_incoming_instance();
let (cf_W_dummy, cf_U_dummy) = cf_r1cs.dummy_running_instance();
let (W_dummy, U_dummy) = r1cs.dummy_witness_instance();
let (w_dummy, u_dummy) = r1cs.dummy_witness_instance();
let (cf_W_dummy, cf_U_dummy) = cf_r1cs.dummy_witness_instance();
// W_dummy=W_0 is a 'dummy witness', all zeroes, but with the size corresponding to the
// R1CS that we're working with.
@@ -815,10 +823,11 @@ where
#[cfg(test)]
{
self.cf_r1cs.check_tight_relation(&_cfW_w_i, &cfW_u_i)?;
self.cf_r1cs.check_tight_relation(&_cfE_w_i, &cfE_u_i)?;
self.cf_r1cs
.check_relaxed_relation(&self.cf_W_i, &self.cf_U_i)?;
cfW_u_i.check_incoming()?;
cfE_u_i.check_incoming()?;
self.cf_r1cs.check_relation(&_cfW_w_i, &cfW_u_i)?;
self.cf_r1cs.check_relation(&_cfE_w_i, &cfE_u_i)?;
self.cf_r1cs.check_relation(&self.cf_W_i, &self.cf_U_i)?;
}
}
@@ -850,8 +859,9 @@ where
#[cfg(test)]
{
self.r1cs.check_tight_relation(&self.w_i, &self.u_i)?;
self.r1cs.check_relaxed_relation(&self.W_i, &self.U_i)?;
self.u_i.check_incoming()?;
self.r1cs.check_relation(&self.w_i, &self.u_i)?;
self.r1cs.check_relation(&self.W_i, &self.U_i)?;
}
Ok(())
@@ -917,13 +927,15 @@ where
return Err(Error::IVCVerificationFail);
}
// check R1CS satisfiability, which also enforces u_i.cmE==0, u_i.u==1
vp.r1cs.check_tight_relation(&w_i, &u_i)?;
// check R1CS satisfiability, which is equivalent to checking if `u_i`
// is an incoming instance and if `w_i` and `u_i` satisfy RelaxedR1CS
u_i.check_incoming()?;
vp.r1cs.check_relation(&w_i, &u_i)?;
// check RelaxedR1CS satisfiability
vp.r1cs.check_relaxed_relation(&W_i, &U_i)?;
vp.r1cs.check_relation(&W_i, &U_i)?;
// check CycleFold RelaxedR1CS satisfiability
vp.cf_r1cs.check_relaxed_relation(&cf_W_i, &cf_U_i)?;
vp.cf_r1cs.check_relation(&cf_W_i, &cf_U_i)?;
Ok(())
}

View File

@@ -210,13 +210,16 @@ pub mod tests {
use ark_pallas::{Fr, Projective};
use ark_std::{ops::Mul, test_rng, UniformRand};
use crate::arith::r1cs::{
tests::{get_test_r1cs, get_test_z},
RelaxedR1CS,
};
use crate::commitment::pedersen::{Params as PedersenParams, Pedersen};
use crate::folding::nova::circuits::ChallengeGadget;
use crate::transcript::poseidon::poseidon_canonical_config;
use crate::{
arith::{
r1cs::tests::{get_test_r1cs, get_test_z},
Arith,
},
folding::traits::Dummy,
};
#[allow(clippy::type_complexity)]
pub(crate) fn prepare_simple_fold_inputs<C>() -> (
@@ -302,13 +305,13 @@ pub mod tests {
fn test_nifs_fold_dummy() {
let r1cs = get_test_r1cs::<Fr>();
let z1 = get_test_z(3);
let (w1, x1) = r1cs.split_z(&z1);
let (_, x1) = r1cs.split_z(&z1);
let mut rng = ark_std::test_rng();
let (pedersen_params, _) = Pedersen::<Projective>::setup(&mut rng, r1cs.A.n_cols).unwrap();
// dummy instance, witness and public inputs zeroes
let w_dummy = Witness::<Projective>::dummy(w1.len(), r1cs.A.n_rows);
let w_dummy = Witness::<Projective>::dummy(&r1cs);
let mut u_dummy = w_dummy
.commit::<Pedersen<Projective>, false>(&pedersen_params, vec![Fr::zero(); x1.len()])
.unwrap();
@@ -318,8 +321,8 @@ pub mod tests {
let u_i = u_dummy.clone();
let W_i = w_dummy.clone();
let U_i = u_dummy.clone();
r1cs.check_relaxed_relation(&w_i, &u_i).unwrap();
r1cs.check_relaxed_relation(&W_i, &U_i).unwrap();
r1cs.check_relation(&w_i, &u_i).unwrap();
r1cs.check_relation(&W_i, &U_i).unwrap();
let r_Fr = Fr::from(3_u32);
@@ -336,7 +339,7 @@ pub mod tests {
r_Fr, &w_i, &u_i, &W_i, &U_i, &T, cmT,
)
.unwrap();
r1cs.check_relaxed_relation(&W_i1, &U_i1).unwrap();
r1cs.check_relation(&W_i1, &U_i1).unwrap();
}
// fold 2 instances into one
@@ -350,9 +353,9 @@ pub mod tests {
assert_eq!(ci3_v, ci3);
// check that relations hold for the 2 inputted instances and the folded one
r1cs.check_relaxed_relation(&w1, &ci1).unwrap();
r1cs.check_relaxed_relation(&w2, &ci2).unwrap();
r1cs.check_relaxed_relation(&w3, &ci3).unwrap();
r1cs.check_relation(&w1, &ci1).unwrap();
r1cs.check_relation(&w2, &ci2).unwrap();
r1cs.check_relation(&w3, &ci3).unwrap();
// check that folded commitments from folded instance (ci) are equal to folding the
// use folded rE, rW to commit w3
@@ -427,7 +430,7 @@ pub mod tests {
.commit::<Pedersen<Projective>, false>(&pedersen_params, x)
.unwrap();
r1cs.check_relaxed_relation(&running_instance_w, &running_committed_instance)
r1cs.check_relation(&running_instance_w, &running_committed_instance)
.unwrap();
let num_iters = 10;
@@ -440,7 +443,7 @@ pub mod tests {
let incoming_committed_instance = incoming_instance_w
.commit::<Pedersen<Projective>, false>(&pedersen_params, x)
.unwrap();
r1cs.check_relaxed_relation(&incoming_instance_w, &incoming_committed_instance)
r1cs.check_relation(&incoming_instance_w, &incoming_committed_instance)
.unwrap();
let r = Fr::rand(&mut rng); // folding challenge would come from the RO
@@ -474,7 +477,7 @@ pub mod tests {
&cmT,
);
r1cs.check_relaxed_relation(&folded_w, &folded_committed_instance)
r1cs.check_relation(&folded_w, &folded_committed_instance)
.unwrap();
// set running_instance for next loop iteration

View File

@@ -1,50 +1,66 @@
use ark_ec::CurveGroup;
use ark_std::{rand::RngCore, One, UniformRand};
use ark_std::{rand::RngCore, UniformRand};
use super::{CommittedInstance, Witness};
use crate::arith::r1cs::{RelaxedR1CS, R1CS};
use crate::arith::ArithSampler;
use crate::arith::{r1cs::R1CS, Arith};
use crate::commitment::CommitmentScheme;
use crate::folding::circuits::CF1;
use crate::Error;
impl<C: CurveGroup> RelaxedR1CS<C, Witness<C>, CommittedInstance<C>> for R1CS<C::ScalarField> {
fn dummy_running_instance(&self) -> (Witness<C>, CommittedInstance<C>) {
let w_len = self.A.n_cols - 1 - self.l;
let w_dummy = Witness::<C>::dummy(w_len, self.A.n_rows);
let u_dummy = CommittedInstance::<C>::dummy(self.l);
(w_dummy, u_dummy)
/// Implements `Arith` for R1CS, where the witness is of type [`Witness`], and
/// the committed instance is of type [`CommittedInstance`].
///
/// Due to the error terms `Witness.E` and `CommittedInstance.u`, R1CS here is
/// considered as a relaxed R1CS.
///
/// One may wonder why we do not provide distinct structs for R1CS and relaxed
/// R1CS.
/// This is because both plain R1CS and relaxed R1CS have the same structure:
/// they are both represented by three matrices.
/// What makes them different is the error terms, which are not part of the R1CS
/// struct, but are part of the witness and committed instance.
///
/// As a follow-up, one may further ask why not providing a trait for relaxed
/// R1CS and implement it for the `R1CS` struct, where the relaxed R1CS trait
/// has methods for relaxed satisfiability check, while the `Arith` trait that
/// `R1CS` implements has methods for plain satisfiability check.
/// However, it would be more ideal if we have a single method that can smartly
/// choose the type of satisfiability check, which would make the code more
/// generic and easier to maintain.
///
/// This is achieved thanks to the new design of the [`Arith`] trait, where we
/// can implement the trait for the same constraint system with different types
/// of witnesses and committed instances.
/// For R1CS, whether it is relaxed or not is now determined by the types of `W`
/// and `U`: the satisfiability check is relaxed if `W` and `U` are defined by
/// folding schemes, and plain if they are vectors of field elements.
impl<C: CurveGroup> Arith<Witness<C>, CommittedInstance<C>> for R1CS<CF1<C>> {
type Evaluation = Vec<CF1<C>>;
fn eval_relation(
&self,
w: &Witness<C>,
u: &CommittedInstance<C>,
) -> Result<Self::Evaluation, Error> {
self.eval_at_z(&[&[u.u][..], &u.x, &w.W].concat())
}
fn dummy_incoming_instance(&self) -> (Witness<C>, CommittedInstance<C>) {
self.dummy_running_instance()
}
fn is_relaxed(_w: &Witness<C>, u: &CommittedInstance<C>) -> bool {
u.cmE != C::zero() || u.u != C::ScalarField::one()
}
fn extract_z(w: &Witness<C>, u: &CommittedInstance<C>) -> Vec<C::ScalarField> {
[&[u.u][..], &u.x, &w.W].concat()
}
fn check_error_terms(
fn check_evaluation(
w: &Witness<C>,
_u: &CommittedInstance<C>,
e: Vec<C::ScalarField>,
e: Self::Evaluation,
) -> Result<(), Error> {
if w.E == e {
Ok(())
} else {
Err(Error::NotSatisfied)
}
(w.E == e).then_some(()).ok_or(Error::NotSatisfied)
}
}
fn sample<CS>(
impl<C: CurveGroup> ArithSampler<C, Witness<C>, CommittedInstance<C>> for R1CS<CF1<C>> {
fn sample_witness_instance<CS: CommitmentScheme<C, true>>(
&self,
params: &CS::ProverParams,
mut rng: impl RngCore,
) -> Result<(Witness<C>, CommittedInstance<C>), Error>
where
CS: crate::commitment::CommitmentScheme<C, true>,
{
) -> Result<(Witness<C>, CommittedInstance<C>), Error> {
// Implements sampling a (committed) RelaxedR1CS
// See construction 5 in https://eprint.iacr.org/2023/573.pdf
let u = C::ScalarField::rand(&mut rng);
@@ -61,16 +77,7 @@ impl<C: CurveGroup> RelaxedR1CS<C, Witness<C>, CommittedInstance<C>> for R1CS<C:
z.extend(&x);
z.extend(&W);
let E = <Self as RelaxedR1CS<C, Witness<C>, CommittedInstance<C>>>::compute_E(
&self.A, &self.B, &self.C, &z, &u,
)?;
debug_assert!(
z.len() == self.A.n_cols,
"Length of z is {}, while A has {} columns.",
z.len(),
self.A.n_cols
);
let E = self.eval_at_z(&z)?;
let witness = Witness { E, rE, W, rW };
let mut cm_witness = witness.commit::<CS, true>(params, x)?;
@@ -79,7 +86,7 @@ impl<C: CurveGroup> RelaxedR1CS<C, Witness<C>, CommittedInstance<C>> for R1CS<C:
cm_witness.u = u;
debug_assert!(
self.check_relaxed_relation(&witness, &cm_witness).is_ok(),
self.check_relation(&witness, &cm_witness).is_ok(),
"Sampled a non satisfiable relaxed R1CS, sampled u: {}, computed E: {:?}",
u,
witness.E

View File

@@ -35,7 +35,7 @@ use ark_ff::{BigInteger, PrimeField};
use ark_std::{One, Zero};
use crate::{
arith::r1cs::{RelaxedR1CS, R1CS},
arith::{r1cs::R1CS, Arith, ArithSampler},
folding::traits::CommittedInstanceOps,
RngCore,
};
@@ -142,7 +142,9 @@ where
let pi = FoldingProof { cmT };
// 2. Sample a satisfying relaxed R1CS instance-witness pair (W_r, U_r)
let (W_r, U_r) = nova.r1cs.sample::<CS1>(&nova.cs_pp, &mut rng)?;
let (W_r, U_r) = nova
.r1cs
.sample_witness_instance::<CS1>(&nova.cs_pp, &mut rng)?;
// 3. Fold the instance-witness pair (U_f, W_f) with (U_r, W_r)
// a. Compute T
@@ -279,10 +281,10 @@ where
);
// 5. Check that W^{\prime}_i is a satisfying witness
r1cs.check_relaxed_relation(&proof.W_i_prime, &U_i_prime)?;
r1cs.check_relation(&proof.W_i_prime, &U_i_prime)?;
// 6. Check that the cyclefold instance-witness pair satisfies the cyclefold relaxed r1cs
cf_r1cs.check_relaxed_relation(&proof.cf_W_i, &proof.cf_U_i)?;
cf_r1cs.check_relation(&proof.cf_W_i, &proof.cf_U_i)?;
Ok(())
}
@@ -370,7 +372,7 @@ pub mod tests {
);
let (_, sampled_committed_instance) = nova
.r1cs
.sample::<Pedersen<Projective, true>>(&nova.cs_pp, rng)
.sample_witness_instance::<Pedersen<Projective, true>>(&nova.cs_pp, rng)
.unwrap();
// proof verification fails with incorrect running instance
@@ -407,7 +409,7 @@ pub mod tests {
);
let (sampled_committed_witness, _) = nova
.r1cs
.sample::<Pedersen<Projective, true>>(&nova.cs_pp, rng)
.sample_witness_instance::<Pedersen<Projective, true>>(&nova.cs_pp, rng)
.unwrap();
// proof generation fails with incorrect running witness