Browse Source

Requested changes and update from main

update-nifs-interface
Nick Dimitriou 3 weeks ago
parent
commit
f61d6605e7
4 changed files with 63 additions and 94 deletions
  1. +20
    -14
      folding-schemes/src/folding/mova/mod.rs
  2. +26
    -43
      folding-schemes/src/folding/mova/nifs.rs
  3. +1
    -0
      folding-schemes/src/folding/mova/pointvsline.rs
  4. +16
    -37
      folding-schemes/src/folding/mova/traits.rs

+ 20
- 14
folding-schemes/src/folding/mova/mod.rs

@ -11,6 +11,9 @@ use ark_poly::MultilinearExtension;
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use ark_std::rand::RngCore;
use crate::arith::r1cs::R1CS;
use crate::folding::circuits::CF1;
use crate::folding::traits::Dummy;
use ark_std::{log2, One, UniformRand, Zero};
/// Implements the scheme described in [Mova](https://eprint.iacr.org/2024/1220.pdf)
@ -22,12 +25,15 @@ mod traits;
pub struct CommittedInstance<C: CurveGroup> {
// Random evaluation point for the E
pub rE: Vec<C::ScalarField>,
// MLE of E
// Evaluation of the MLE of E at r_E
pub mleE: C::ScalarField,
pub u: C::ScalarField,
pub cmW: C,
pub x: Vec<C::ScalarField>,
}
/// Witness for the R1CS containing the W vector, the r_w used as randomness for the commitment and the Error term E.
/// The wi the prover receives in most protocols in the paper.
#[derive(Debug, Clone, Eq, PartialEq, CanonicalSerialize, CanonicalDeserialize)]
pub struct Witness<C: CurveGroup> {
pub E: Vec<C::ScalarField>,
@ -35,6 +41,7 @@ pub struct Witness {
pub rW: C::ScalarField,
}
/// A helper struct to group together the result of the folded witness and the folded committed instance
#[derive(Debug, Clone, Eq, PartialEq, CanonicalSerialize, CanonicalDeserialize)]
pub struct InstanceWitness<C: CurveGroup> {
pub ci: CommittedInstance<C>,
@ -56,17 +63,6 @@ impl Witness {
}
}
pub fn dummy(w_len: usize, e_len: usize) -> Self {
let rW = C::ScalarField::zero();
let w = vec![C::ScalarField::zero(); w_len];
Self {
E: vec![C::ScalarField::zero(); e_len],
W: w,
rW,
}
}
pub fn commit<CS: CommitmentScheme<C>>(
&self,
params: &CS::ProverParams,
@ -92,8 +88,18 @@ impl Witness {
}
}
impl<C: CurveGroup> CommittedInstance<C> {
pub fn dummy(io_len: usize) -> Self {
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],
W: vec![C::ScalarField::zero(); r1cs.A.n_cols - 1 - r1cs.l],
rW: C::ScalarField::zero(),
}
}
}
impl<C: CurveGroup> Dummy<usize> for CommittedInstance<C> {
fn dummy(io_len: usize) -> Self {
Self {
rE: vec![C::ScalarField::zero(); io_len],
mleE: C::ScalarField::zero(),

+ 26
- 43
folding-schemes/src/folding/mova/nifs.rs

@ -4,7 +4,7 @@ use crate::commitment::CommitmentScheme;
use crate::folding::mova::pointvsline::{
PointVsLine, PointVsLineProof, PointvsLineEvaluationClaim,
};
use crate::folding::nova::nifs::NIFS as Nova;
use crate::folding::nova::nifs::NIFS as NovaNIFS;
use crate::transcript::Transcript;
use crate::utils::mle::dense_vec_to_dense_mle;
use crate::utils::vec::{vec_add, vec_scalar_mul};
@ -41,18 +41,8 @@ impl, T: Transcript, c
NIFS<C, CS, T, H>
where
<C as Group>::ScalarField: Absorb,
<C as CurveGroup>::BaseField: PrimeField,
{
// Just a wrapper for Nova compute_T (compute cross-terms T) since the process is the same
pub fn compute_T(
r1cs: &R1CS<C::ScalarField>,
u1: C::ScalarField,
u2: C::ScalarField,
z1: &[C::ScalarField],
z2: &[C::ScalarField],
) -> Result<Vec<C::ScalarField>, Error> {
Nova::<C, CS, H>::compute_T(r1cs, u1, u2, z1, z2)
}
// Protocol 7 - point 3 (16)
pub fn fold_witness(
a: C::ScalarField,
@ -60,10 +50,10 @@ where
w2: &Witness<C>,
T: &[C::ScalarField],
) -> Result<Witness<C>, Error> {
let a2 = a * a;
let a_squared = a * a;
let E: Vec<C::ScalarField> = vec_add(
&vec_add(&w1.E, &vec_scalar_mul(T, &a))?,
&vec_scalar_mul(&w2.E, &a2),
&vec_scalar_mul(&w2.E, &a_squared),
)?;
let W: Vec<C::ScalarField> =
w1.W.iter()
@ -80,13 +70,13 @@ where
a: C::ScalarField,
ci1: &CommittedInstance<C>,
ci2: &CommittedInstance<C>,
rE_prime: &[C::ScalarField],
rE_prime: Vec<C::ScalarField>,
mleE1_prime: &C::ScalarField,
mleE2_prime: &C::ScalarField,
mleT: &C::ScalarField,
) -> Result<CommittedInstance<C>, Error> {
let a2 = a * a;
let mleE = *mleE1_prime + a * mleT + a2 * mleE2_prime;
let a_squared = a * a;
let mleE = *mleE1_prime + a * mleT + a_squared * mleE2_prime;
let u = ci1.u + a * ci2.u;
let cmW = ci1.cmW + ci2.cmW.mul(a);
let x = ci1
@ -132,7 +122,6 @@ where
) = PointVsLine::<C, T>::prove(transcript, ci1, ci2, w1, w2)?;
// Protocol 7
transcript.absorb(&mleE1_prime);
transcript.absorb(&mleE2_prime);
@ -140,7 +129,7 @@ where
let z1: Vec<C::ScalarField> = [vec![ci1.u], ci1.x.to_vec(), w1.W.to_vec()].concat();
let z2: Vec<C::ScalarField> = [vec![ci2.u], ci2.x.to_vec(), w2.W.to_vec()].concat();
let T = Self::compute_T(r1cs, ci1.u, ci2.u, &z1, &z2)?;
let T = NovaNIFS::<C, CS, H>::compute_T(r1cs, ci1.u, ci2.u, &z1, &z2)?;
let n_vars: usize = log2(w1.E.len()) as usize;
if log2(T.len()) as usize != n_vars {
@ -152,8 +141,6 @@ where
transcript.absorb(&mleT_evaluated);
let alpha_scalar = C::ScalarField::from_le_bytes_mod_order(b"alpha");
transcript.absorb(&alpha_scalar);
let alpha: C::ScalarField = transcript.get_challenge();
Ok((
@ -168,7 +155,7 @@ where
alpha,
ci1,
ci2,
&rE_prime,
rE_prime,
&mleE1_prime,
&mleE2_prime,
&mleT_evaluated,
@ -178,9 +165,9 @@ where
))
}
/// [Mova](https://eprint.iacr.org/2024/1220.pdf)'s section 4. It verifies the results from the proof
/// Both the folding and the pt-vs-line proof
/// returns the folded committed instance
/// [Mova](https://eprint.iacr.org/2024/1220.pdf)'s section 4.
/// It verifies the results from both the folding and the pt-vs-line proofs.
/// Returns the folded committed instance.
pub fn verify(
transcript: &mut impl Transcript<C::ScalarField>,
ci1: &CommittedInstance<C>,
@ -202,15 +189,13 @@ where
transcript.absorb(&proof.mleE2_prime);
transcript.absorb(&proof.mleT);
let alpha_scalar = C::ScalarField::from_le_bytes_mod_order(b"alpha");
transcript.absorb(&alpha_scalar);
let alpha: C::ScalarField = transcript.get_challenge();
Self::fold_committed_instance(
alpha,
ci1,
ci2,
&rE_prime,
rE_prime,
&proof.mleE1_prime,
&proof.mleE2_prime,
&proof.mleT,
@ -220,11 +205,10 @@ where
#[cfg(test)]
pub mod tests {
use crate::arith::r1cs::{
tests::{get_test_r1cs, get_test_z},
RelaxedR1CS,
};
use crate::arith::r1cs::tests::{get_test_r1cs, get_test_z};
use crate::arith::Arith;
use crate::commitment::pedersen::{Params as PedersenParams, Pedersen};
use crate::folding::traits::Dummy;
use crate::transcript::poseidon::poseidon_canonical_config;
use ark_crypto_primitives::sponge::{
poseidon::{PoseidonConfig, PoseidonSponge},
@ -318,7 +302,7 @@ pub mod tests {
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>>(
&pedersen_params,
@ -333,8 +317,8 @@ pub mod tests {
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 poseidon_config = poseidon_canonical_config::<ark_pallas::Fr>();
let mut transcript_p: PoseidonSponge<Fr> = PoseidonSponge::<Fr>::new(&poseidon_config);
@ -350,7 +334,7 @@ pub mod tests {
.unwrap();
let (_proof, instance_witness) = result;
r1cs.check_relaxed_relation(&instance_witness.w, &instance_witness.ci)
r1cs.check_relation(&instance_witness.w, &instance_witness.ci)
.unwrap();
}
@ -372,10 +356,9 @@ pub mod tests {
assert_eq!(ci3, instance.ci);
// 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(&instance.w, &instance.ci)
.unwrap();
r1cs.check_relation(&w1, &ci1).unwrap();
r1cs.check_relation(&w2, &ci2).unwrap();
r1cs.check_relation(&instance.w, &instance.ci).unwrap();
// check that folded commitments from folded instance (ci) are equal to folding the
// use folded rE, rW to commit w3
@ -403,7 +386,7 @@ pub mod tests {
.commit::<Pedersen<Projective>>(&pedersen_params, x, rE)
.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;
@ -417,7 +400,7 @@ pub mod tests {
let incoming_committed_instance = incoming_instance_w
.commit::<Pedersen<Projective>>(&pedersen_params, x, rE)
.unwrap();
r1cs.check_relaxed_relation(&incoming_instance_w, &incoming_committed_instance)
r1cs.check_relation(&incoming_instance_w, &incoming_committed_instance)
.unwrap();
// NIFS.P
@ -446,7 +429,7 @@ pub mod tests {
)
.unwrap();
r1cs.check_relaxed_relation(&instance_witness.w, &instance_witness.ci)
r1cs.check_relation(&instance_witness.w, &instance_witness.ci)
.unwrap();
// set running_instance for next loop iteration

+ 1
- 0
folding-schemes/src/folding/mova/pointvsline.rs

@ -18,6 +18,7 @@ pub struct PointvsLineEvaluationClaim {
pub mleE2_prime: C::ScalarField,
pub rE_prime: Vec<C::ScalarField>,
}
/// Proof from step 1 protocol 6
#[derive(Clone, Debug)]
pub struct PointVsLineProof<C: CurveGroup> {

+ 16
- 37
folding-schemes/src/folding/mova/traits.rs

@ -1,49 +1,28 @@
use crate::arith::r1cs::{RelaxedR1CS, R1CS};
use crate::arith::ccs::CCS;
use crate::arith::{r1cs::R1CS, Arith};
use crate::folding::circuits::CF1;
use crate::folding::mova::{CommittedInstance, Witness};
use crate::utils::mle::dense_vec_to_dense_mle;
use crate::utils::vec::mat_vec_mul;
use crate::Error;
use ark_ec::CurveGroup;
use ark_std::{rand::RngCore, One, Zero};
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)
}
fn dummy_incoming_instance(&self) -> (Witness<C>, CommittedInstance<C>) {
self.dummy_running_instance()
}
fn is_relaxed(_w: &Witness<C>, u: &CommittedInstance<C>) -> bool {
u.mleE != C::ScalarField::zero() || u.u != C::ScalarField::one()
}
impl<C: CurveGroup> Arith<Witness<C>, CommittedInstance<C>> for R1CS<CF1<C>> {
type Evaluation = Vec<CF1<C>>;
fn extract_z(w: &Witness<C>, u: &CommittedInstance<C>) -> Vec<C::ScalarField> {
[&[u.u][..], &u.x, &w.W].concat()
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 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)
}
}
fn sample<CS>(
&self,
_params: &CS::ProverParams,
_rng: impl RngCore,
) -> Result<(Witness<C>, CommittedInstance<C>), Error>
where
CS: crate::commitment::CommitmentScheme<C, true>,
{
unimplemented!()
(w.E == e).then_some(()).ok_or(Error::NotSatisfied)
}
}

Loading…
Cancel
Save