Skip to content

Commit

Permalink
Merge pull request #180 from KogarashiNetwork/nova/nifs
Browse files Browse the repository at this point in the history
Nifs tests
  • Loading branch information
ashWhiteHat authored Dec 5, 2023
2 parents 06041d8 + ea4e689 commit 11c4bfd
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 14 deletions.
82 changes: 71 additions & 11 deletions nova/src/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl<C: CircuitDriver> Prover<C> {
}

// T = AZ1 ◦ BZ2 + AZ2 ◦ BZ1 − u1 · CZ2 − u2 · CZ1
fn compute_cross_term(
pub(crate) fn compute_cross_term(
&self,
r1cs: &R1cs<C>,
relaxed_r1cs: &RelaxedR1cs<C>,
Expand Down Expand Up @@ -88,9 +88,14 @@ impl<C: CircuitDriver> Prover<C> {
#[cfg(test)]
pub(crate) mod tests {
use super::{Prover, RelaxedR1cs};
use bn_254::{Fq, Fr};

use crate::hash::{MimcRO, MIMC_ROUNDS};
use crate::relaxed_r1cs::{RelaxedR1csInstance, RelaxedR1csWitness};
use crate::Verifier;
use grumpkin::driver::GrumpkinDriver;
use zkstd::common::OsRng;
use zkstd::matrix::DenseVectors;
use zkstd::r1cs::test::example_r1cs;

pub(crate) fn example_prover() -> Prover<GrumpkinDriver> {
Expand All @@ -99,16 +104,71 @@ pub(crate) mod tests {
}

#[test]
fn folding_scheme_prover_test() {
fn nifs_folding_test() {
let prover = example_prover();
let r1cs = example_r1cs(1);
let mut relaxed_r1cs = RelaxedR1cs::new(r1cs);
for i in 1..10 {
let r1cs = example_r1cs(i);
let (instance, witness, _) = prover.prove(&r1cs, &relaxed_r1cs);
relaxed_r1cs = relaxed_r1cs.update(&instance, &witness);
}

assert!(relaxed_r1cs.is_sat())
let mut transcript = MimcRO::<MIMC_ROUNDS, Fq>::default();
let r1cs_1 = example_r1cs(4);
let r1cs_2 = example_r1cs(3);

let mut relaxed_r1cs = RelaxedR1cs::new(r1cs_2);

let (folded_instance, witness, commit_t) = prover.prove(&r1cs_1, &relaxed_r1cs);
let verified_instance = Verifier::verify(commit_t, &r1cs_1, &relaxed_r1cs);
assert_eq!(folded_instance, verified_instance);

transcript.append_point(commit_t);
relaxed_r1cs.absorb_by_transcript(&mut transcript);
let t = prover.compute_cross_term(&r1cs_1, &relaxed_r1cs);
let r = Fr::from(transcript.squeeze());

// naive check that the folded witness satisfies the relaxed r1cs
let z3: Vec<Fr> = [
vec![verified_instance.u],
verified_instance.x.get(),
witness.w.get(),
]
.concat();

let z1 = [vec![Fr::one()], r1cs_1.x(), r1cs_1.w()].concat();
let z2 = [
vec![relaxed_r1cs.instance.u],
relaxed_r1cs.x().get(),
relaxed_r1cs.w().get(),
]
.concat();

let z3_aux: Vec<Fr> = z2
.iter()
.map(|x| x * r)
.zip(z1)
.map(|(x, y)| x + y)
.collect();

assert_eq!(z3, z3_aux);

// check that relations hold for the 2 inputted instances and the folded one
let instance1 = RelaxedR1csInstance::default(DenseVectors::new(r1cs_1.x()));
let instance2 = relaxed_r1cs.instance.clone();
assert!(relaxed_r1cs.is_sat());
relaxed_r1cs = relaxed_r1cs.update(
&instance1,
&RelaxedR1csWitness::default(DenseVectors::new(r1cs_1.w())),
);
assert!(relaxed_r1cs.is_sat());
relaxed_r1cs = relaxed_r1cs.update(&folded_instance, &witness);
assert!(relaxed_r1cs.is_sat());

// next equalities should hold since we started from two cmE of zero-vector E's
assert_eq!(verified_instance.commit_e, (commit_t * r).into());
assert_eq!(witness.e, t * r);

let r2 = r * r;
assert!(
folded_instance.commit_e
== (instance1.commit_e + commit_t * r + instance2.commit_e * r2).into()
&& folded_instance.u == instance1.u + r * instance2.u
&& folded_instance.commit_w == (instance1.commit_w + instance2.commit_w * r).into()
&& folded_instance.x == &instance1.x + &(&instance2.x * r)
);
}
}
5 changes: 2 additions & 3 deletions nova/src/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ mod tests {
use zkstd::r1cs::test::example_r1cs;

#[test]
fn folding_scheme_verifier_test() {
fn recursive_nifs_test() {
let prover = example_prover();
let r1cs = example_r1cs(1);
let mut relaxed_r1cs = RelaxedR1cs::new(r1cs);
Expand All @@ -43,8 +43,7 @@ mod tests {
let verified_instance = Verifier::verify(commit_t, &r1cs, &relaxed_r1cs);
assert_eq!(instance, verified_instance);
relaxed_r1cs = relaxed_r1cs.update(&instance, &witness);
assert!(relaxed_r1cs.is_sat());
}

assert!(relaxed_r1cs.is_sat())
}
}
18 changes: 18 additions & 0 deletions zkstd/src/matrix/vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ impl<F: PrimeField> Mul<F> for DenseVectors<F> {
}
}

impl<F: PrimeField> Mul<F> for &DenseVectors<F> {
type Output = DenseVectors<F>;

fn mul(self, rhs: F) -> DenseVectors<F> {
DenseVectors(self.iter().map(|element| element * rhs).collect())
}
}

/// Hadamard product
impl<F: PrimeField> Mul for DenseVectors<F> {
type Output = Self;
Expand All @@ -103,6 +111,16 @@ impl<F: PrimeField> Add for DenseVectors<F> {
}
}

impl<F: PrimeField> Add for &DenseVectors<F> {
type Output = DenseVectors<F>;

fn add(self, rhs: Self) -> Self::Output {
assert_eq!(self.0.len(), rhs.0.len());

DenseVectors(self.iter().zip(rhs.iter()).map(|(a, b)| a + b).collect())
}
}

impl<F: PrimeField> Sub for DenseVectors<F> {
type Output = Self;

Expand Down

0 comments on commit 11c4bfd

Please sign in to comment.