Skip to content

Commit

Permalink
adjust nova types, make instance allocations on provided CS
Browse files Browse the repository at this point in the history
  • Loading branch information
KiriosK committed Dec 11, 2023
1 parent a8ad969 commit 5f2f743
Show file tree
Hide file tree
Showing 12 changed files with 127 additions and 105 deletions.
44 changes: 22 additions & 22 deletions nova/src/circuit/augmented.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ use zkstd::matrix::DenseVectors;
use zkstd::r1cs::R1cs;

#[derive(Debug, Clone)]
pub struct AugmentedFCircuit<C: CircuitDriver, FC: FunctionCircuit<C>> {
pub struct AugmentedFCircuit<C: CircuitDriver, FC: FunctionCircuit<C::Base>> {
pub i: usize,
pub z_0: DenseVectors<C::Scalar>,
pub z_i: DenseVectors<C::Scalar>,
pub z_0: DenseVectors<C::Base>,
pub z_i: DenseVectors<C::Base>,
pub u_single: RelaxedR1csInstance<C>,
pub u_range: RelaxedR1csInstance<C>,
pub u_range_next: RelaxedR1csInstance<C>,
pub commit_t: C::Affine,
pub f: PhantomData<FC>,
pub x: C::Scalar,
pub x: C::Base,
}

impl<C: CircuitDriver, FC: FunctionCircuit<C>> Default for AugmentedFCircuit<C, FC> {
impl<C: CircuitDriver, FC: FunctionCircuit<C::Base>> Default for AugmentedFCircuit<C, FC> {
fn default() -> Self {
Self {
i: 0,
Expand All @@ -44,10 +44,10 @@ impl<C: CircuitDriver, FC: FunctionCircuit<C>> Default for AugmentedFCircuit<C,
}
}

impl<C: CircuitDriver, FC: FunctionCircuit<C>> AugmentedFCircuit<C, FC> {
pub(crate) fn generate(&self, cs: &mut R1cs<C>) {
impl<C: CircuitDriver, FC: FunctionCircuit<C::Base>> AugmentedFCircuit<C, FC> {
pub(crate) fn generate<CS: CircuitDriver<Scalar = C::Base>>(&self, cs: &mut R1cs<CS>) {
// allocate inputs
let i = FieldAssignment::witness(cs, C::Scalar::from(self.i as u64));
let i = FieldAssignment::witness(cs, C::Base::from(self.i as u64));
let z_0 = self
.z_0
.iter()
Expand All @@ -59,7 +59,7 @@ impl<C: CircuitDriver, FC: FunctionCircuit<C>> AugmentedFCircuit<C, FC> {
.map(|x| FieldAssignment::witness(cs, x))
.collect::<Vec<_>>();

let u_dummy_native = RelaxedR1csInstance::dummy(1);
let u_dummy_native = RelaxedR1csInstance::<C>::dummy(1);
let u_dummy = RelaxedR1csInstanceAssignment::witness(cs, &u_dummy_native);
let u_i = RelaxedR1csInstanceAssignment::witness(cs, &self.u_single);
let u_range = RelaxedR1csInstanceAssignment::witness(cs, &self.u_range);
Expand All @@ -73,7 +73,7 @@ impl<C: CircuitDriver, FC: FunctionCircuit<C>> AugmentedFCircuit<C, FC> {
let x = FieldAssignment::instance(cs, self.x);

let z_next = FC::invoke_cs(cs, z_i.clone());
let zero = FieldAssignment::constant(&C::Scalar::zero());
let zero = FieldAssignment::constant(&C::Base::zero());
let bin_true = BinaryAssignment::witness(cs, 1);

let base_case = FieldAssignment::is_eq(cs, &i, &zero);
Expand Down Expand Up @@ -105,7 +105,7 @@ impl<C: CircuitDriver, FC: FunctionCircuit<C>> AugmentedFCircuit<C, FC> {
FieldAssignment::conditional_enforce_equal(
cs,
&u_i.u,
&FieldAssignment::constant(&C::Scalar::one()),
&FieldAssignment::constant(&C::Base::one()),
&not_base_case,
);

Expand All @@ -117,15 +117,15 @@ impl<C: CircuitDriver, FC: FunctionCircuit<C>> AugmentedFCircuit<C, FC> {
// 4. (base case) u_{i+1}.X == H(1, z_0, F(z_0)=F(z_i)=z_i1, U_i) (with U_i being dummy)
let u_next_x_basecase = u_range.hash(
cs,
FieldAssignment::constant(&C::Scalar::one()),
FieldAssignment::constant(&C::Base::one()),
z_0.clone(),
z_next.clone(),
);

// 4. (non-base case). u_{i+1}.x = H(i+1, z_0, z_i+1, U_{i+1})
let u_next_x = u_range_next.hash(
cs,
&i + &FieldAssignment::constant(&C::Scalar::one()),
&i + &FieldAssignment::constant(&C::Base::one()),
z_0,
z_next,
);
Expand All @@ -136,12 +136,12 @@ impl<C: CircuitDriver, FC: FunctionCircuit<C>> AugmentedFCircuit<C, FC> {
FieldAssignment::conditional_enforce_equal(cs, &u_next_x, &x, &not_base_case);
}

pub(crate) fn get_challenge(
cs: &mut R1cs<C>,
pub(crate) fn get_challenge<CS: CircuitDriver<Scalar = C::Base>>(
cs: &mut R1cs<CS>,
u_range: &RelaxedR1csInstanceAssignment<C>,
commit_t: PointAssignment<C::Scalar>,
) -> FieldAssignment<C::Scalar> {
let mut transcript = MimcROCircuit::<MIMC_ROUNDS, C::Base>::default();
commit_t: PointAssignment<C::Base>,
) -> FieldAssignment<C::Base> {
let mut transcript = MimcROCircuit::<MIMC_ROUNDS, C>::default();
transcript.append_point(commit_t);
u_range.absorb_by_transcript(&mut transcript);
transcript.squeeze(cs)
Expand All @@ -151,16 +151,16 @@ impl<C: CircuitDriver, FC: FunctionCircuit<C>> AugmentedFCircuit<C, FC> {
#[cfg(test)]
mod tests {
use super::*;
use crate::driver::GrumpkinDriver;
use crate::driver::{Bn254Driver, GrumpkinDriver};
use crate::relaxed_r1cs::RelaxedR1csWitness;
use crate::test::ExampleFunction;
use crate::RelaxedR1cs;
use bn_254::Fr;

#[test]
fn augmented_circuit_dummies() {
let mut cs = R1cs::<GrumpkinDriver>::default();
let augmented_circuit =
AugmentedFCircuit::<GrumpkinDriver, ExampleFunction<GrumpkinDriver>>::default();
let mut cs = R1cs::<Bn254Driver>::default();
let augmented_circuit = AugmentedFCircuit::<GrumpkinDriver, ExampleFunction<Fr>>::default();
augmented_circuit.generate(&mut cs);

assert!(cs.is_sat());
Expand Down
14 changes: 7 additions & 7 deletions nova/src/circuit/nifs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ pub(crate) struct NifsCircuit<C: CircuitDriver> {
}

impl<C: CircuitDriver> NifsCircuit<C> {
pub(crate) fn verify(
cs: &mut R1cs<C>,
r: FieldAssignment<C::Scalar>,
pub(crate) fn verify<CS: CircuitDriver<Scalar = C::Base>>(
cs: &mut R1cs<CS>,
r: FieldAssignment<C::Base>,
instance1: RelaxedR1csInstanceAssignment<C>,
instance2: RelaxedR1csInstanceAssignment<C>,
instance3: RelaxedR1csInstanceAssignment<C>,
Expand All @@ -26,7 +26,7 @@ impl<C: CircuitDriver> NifsCircuit<C> {
let r_x2 = FieldAssignment::mul(cs, &r, &x2);
x1 + &r_x2
})
.collect::<Vec<FieldAssignment<C::Scalar>>>();
.collect::<Vec<FieldAssignment<C::Base>>>();
let second_check =
x.iter()
.zip(instance3.x)
Expand All @@ -41,7 +41,7 @@ impl<C: CircuitDriver> NifsCircuit<C> {
#[cfg(test)]
mod tests {
use super::*;
use crate::driver::GrumpkinDriver;
use crate::driver::{Bn254Driver, GrumpkinDriver};
use crate::hash::{MimcRO, MIMC_ROUNDS};
use crate::prover::tests::example_prover;
use crate::RelaxedR1cs;
Expand All @@ -51,13 +51,13 @@ mod tests {
#[test]
fn nifs_circuit() {
let prover = example_prover();
let r1cs = example_r1cs(1);
let r1cs = example_r1cs::<Bn254Driver>(1);
let running_r1cs = RelaxedR1cs::new(r1cs);

let r1cs_to_fold = RelaxedR1cs::new(example_r1cs(2));
let (instance, witness, commit_t) = prover.prove(&r1cs_to_fold, &running_r1cs);

let mut transcript = MimcRO::<MIMC_ROUNDS, Fr>::default();
let mut transcript = MimcRO::<MIMC_ROUNDS, Bn254Driver>::default();
transcript.append_point(commit_t);
running_r1cs.absorb_by_transcript(&mut transcript);
let t = prover.compute_cross_term(&r1cs_to_fold, &running_r1cs);
Expand Down
39 changes: 20 additions & 19 deletions nova/src/circuit/transcript.rs
Original file line number Diff line number Diff line change
@@ -1,49 +1,49 @@
use crate::gadget::MimcAssignment;

use zkstd::circuit::prelude::{CircuitDriver, FieldAssignment, PointAssignment, R1cs};
use zkstd::common::{IntGroup, PrimeField};
use zkstd::common::IntGroup;

pub(crate) struct MimcROCircuit<const ROUND: usize, F: PrimeField> {
hasher: MimcAssignment<ROUND, F>,
state: Vec<FieldAssignment<F>>,
key: FieldAssignment<F>,
pub(crate) struct MimcROCircuit<const ROUND: usize, C: CircuitDriver> {
hasher: MimcAssignment<ROUND, C::Base>,
state: Vec<FieldAssignment<C::Base>>,
key: FieldAssignment<C::Base>,
}

impl<const ROUND: usize, F: PrimeField> Default for MimcROCircuit<ROUND, F> {
impl<const ROUND: usize, C: CircuitDriver> Default for MimcROCircuit<ROUND, C> {
fn default() -> Self {
Self {
hasher: MimcAssignment::default(),
state: Vec::default(),
key: FieldAssignment::constant(&F::zero()),
key: FieldAssignment::constant(&C::Base::zero()),
}
}
}

impl<const ROUND: usize, F: PrimeField> MimcROCircuit<ROUND, F> {
pub(crate) fn append(&mut self, absorb: FieldAssignment<F>) {
impl<const ROUND: usize, C: CircuitDriver> MimcROCircuit<ROUND, C> {
pub(crate) fn append(&mut self, absorb: FieldAssignment<C::Base>) {
self.state.push(absorb)
}
pub(crate) fn hash_vec<C: CircuitDriver<Base = F>>(
pub(crate) fn hash_vec<CS: CircuitDriver<Scalar = C::Base>>(
&mut self,
cs: &mut R1cs<C>,
values: Vec<FieldAssignment<F>>,
) -> FieldAssignment<F> {
cs: &mut R1cs<CS>,
values: Vec<FieldAssignment<C::Base>>,
) -> FieldAssignment<C::Base> {
for x in values {
self.state.push(x);
}
self.squeeze(cs)
}

pub(crate) fn append_point(&mut self, point: PointAssignment<F>) {
pub(crate) fn append_point(&mut self, point: PointAssignment<C::Base>) {
self.append(point.get_x());
self.append(point.get_y());
self.append(point.get_z());
}

pub(crate) fn squeeze<C: CircuitDriver<Base = F>>(
pub(crate) fn squeeze<CS: CircuitDriver<Scalar = C::Base>>(
&self,
cs: &mut R1cs<C>,
) -> FieldAssignment<F> {
cs: &mut R1cs<CS>,
) -> FieldAssignment<C::Base> {
self.state.iter().fold(self.key.clone(), |acc, scalar| {
let h = self.hasher.hash(cs, scalar.clone(), acc.clone());
&(&acc + scalar) + &h
Expand All @@ -57,7 +57,8 @@ mod tests {
use crate::hash::{MimcRO, MIMC_ROUNDS};

use crate::driver::{Bn254Driver, GrumpkinDriver};
use bn_254::{Fq, Fr, G1Affine};
use bn_254::Fr;
use grumpkin::Affine;
use rand_core::OsRng;
use zkstd::circuit::prelude::{FieldAssignment, PointAssignment, R1cs};
use zkstd::common::Group;
Expand All @@ -67,7 +68,7 @@ mod tests {
let mut mimc = MimcRO::<MIMC_ROUNDS, GrumpkinDriver>::default();
let mut mimc_circuit = MimcROCircuit::<MIMC_ROUNDS, GrumpkinDriver>::default(); // Base = Fr, Scalar = Fq
let mut cs: R1cs<Bn254Driver> = R1cs::default(); // Base = Fq, Scalar = Fr
let point = G1Affine::random(OsRng); // Base = Fq, Scalar = Fr
let point = Affine::random(OsRng); // Base = Fr, Scalar = Fq
let scalar = Fr::random(OsRng);

let point_assignment = PointAssignment::instance(&mut cs, point);
Expand Down
15 changes: 15 additions & 0 deletions nova/src/driver.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use bn_254::{params::PARAM_B3 as BN254_PARAM_B3, Fq, Fr, G1Affine};
use grumpkin::{params::PARAM_B3 as GRUMPKIN_PARAM_B3, Affine};
use zkstd::circuit::CircuitDriver;
use zkstd::common::{IntGroup, PrimeField, Ring};

#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct GrumpkinDriver;
Expand Down Expand Up @@ -34,6 +35,20 @@ impl CircuitDriver for Bn254Driver {
}
}

/// interpret scalar as base
pub fn scalar_as_base<C: CircuitDriver>(input: C::Scalar) -> C::Base {
let input_bits = input.to_bits();
let mut mult = C::Base::one();
let mut val = C::Base::zero();
for bit in input_bits.iter().rev() {
if *bit == 1 {
val += mult;
}
mult = mult + mult;
}
val
}

#[cfg(test)]
mod grumpkin_gadget_tests {
use super::{Fq as Scalar, Fr as Base, GrumpkinDriver};
Expand Down
13 changes: 7 additions & 6 deletions nova/src/function.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use std::fmt::Debug;
use zkstd::circuit::prelude::{CircuitDriver, FieldAssignment};
use zkstd::common::PrimeField;
use zkstd::matrix::DenseVectors;
use zkstd::r1cs::R1cs;

pub trait FunctionCircuit<C: CircuitDriver>: Clone + Debug + Default {
fn invoke(z_i: &DenseVectors<C::Scalar>) -> DenseVectors<C::Scalar>;
pub trait FunctionCircuit<F: PrimeField>: Clone + Debug + Default {
fn invoke(z_i: &DenseVectors<F>) -> DenseVectors<F>;

fn invoke_cs(
cs: &mut R1cs<C>,
z_i: Vec<FieldAssignment<C::Scalar>>,
) -> Vec<FieldAssignment<C::Scalar>>;
fn invoke_cs<CS: CircuitDriver<Scalar = F>>(
cs: &mut R1cs<CS>,
z_i: Vec<FieldAssignment<F>>,
) -> Vec<FieldAssignment<F>>;
}
2 changes: 1 addition & 1 deletion nova/src/gadget/mimc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ impl<const ROUND: usize, F: PrimeField> Default for MimcAssignment<ROUND, F> {
}

impl<const ROUND: usize, F: PrimeField> MimcAssignment<ROUND, F> {
pub(crate) fn hash<C: CircuitDriver<Base = F>>(
pub(crate) fn hash<C: CircuitDriver<Scalar = F>>(
&self,
cs: &mut R1cs<C>,
mut xl: FieldAssignment<F>,
Expand Down
38 changes: 21 additions & 17 deletions nova/src/gadget/relaxed_instance.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
use crate::relaxed_r1cs::RelaxedR1csInstance;

use crate::circuit::MimcROCircuit;
use crate::driver::scalar_as_base;
use crate::hash::MIMC_ROUNDS;
use zkstd::circuit::prelude::{CircuitDriver, FieldAssignment, PointAssignment, R1cs};
use zkstd::common::CurveGroup;

#[derive(Clone)]
pub(crate) struct RelaxedR1csInstanceAssignment<C: CircuitDriver> {
pub(crate) commit_w: PointAssignment<C::Scalar>,
pub(crate) commit_e: PointAssignment<C::Scalar>,
pub(crate) u: FieldAssignment<C::Scalar>,
pub(crate) x: Vec<FieldAssignment<C::Scalar>>,
pub(crate) commit_w: PointAssignment<C::Base>,
pub(crate) commit_e: PointAssignment<C::Base>,
pub(crate) u: FieldAssignment<C::Base>,
pub(crate) x: Vec<FieldAssignment<C::Base>>,
}

impl<C: CircuitDriver> RelaxedR1csInstanceAssignment<C> {
pub(crate) fn witness(
cs: &mut R1cs<C>,
pub(crate) fn witness<CS: CircuitDriver<Scalar = C::Base>>(
cs: &mut R1cs<CS>,
relaxed_r1cs_instance: &RelaxedR1csInstance<C>,
) -> Self {
let RelaxedR1csInstance {
Expand All @@ -27,8 +28,8 @@ impl<C: CircuitDriver> RelaxedR1csInstanceAssignment<C> {

let commit_w = PointAssignment::witness(
cs,
commit_w.get_x().into(),
commit_w.get_y().into(),
commit_w.get_x(),
commit_w.get_y(),
commit_w.is_identity(),
);
let commit_e = PointAssignment::witness(
Expand All @@ -37,8 +38,11 @@ impl<C: CircuitDriver> RelaxedR1csInstanceAssignment<C> {
commit_e.get_y().into(),
commit_e.is_identity(),
);
let u = FieldAssignment::witness(cs, *u);
let x = x.iter().map(|x| FieldAssignment::witness(cs, x)).collect();
let u = FieldAssignment::witness(cs, scalar_as_base::<C>(*u));
let x = x
.iter()
.map(|x| FieldAssignment::witness(cs, scalar_as_base::<C>(x)))
.collect();

Self {
commit_w,
Expand All @@ -50,7 +54,7 @@ impl<C: CircuitDriver> RelaxedR1csInstanceAssignment<C> {

pub(crate) fn absorb_by_transcript<const ROUNDS: usize>(
&self,
transcript: &mut MimcROCircuit<ROUNDS, C::Base>,
transcript: &mut MimcROCircuit<ROUNDS, C>,
) {
transcript.append_point(self.commit_w.clone());
transcript.append_point(self.commit_e.clone());
Expand All @@ -60,13 +64,13 @@ impl<C: CircuitDriver> RelaxedR1csInstanceAssignment<C> {
}
}

pub(crate) fn hash(
pub(crate) fn hash<CS: CircuitDriver<Scalar = C::Base>>(
&self,
cs: &mut R1cs<C>,
i: FieldAssignment<C::Scalar>,
z_0: Vec<FieldAssignment<C::Scalar>>,
z_i: Vec<FieldAssignment<C::Scalar>>,
) -> FieldAssignment<C::Scalar> {
cs: &mut R1cs<CS>,
i: FieldAssignment<C::Base>,
z_0: Vec<FieldAssignment<C::Base>>,
z_i: Vec<FieldAssignment<C::Base>>,
) -> FieldAssignment<C::Base> {
MimcROCircuit::<MIMC_ROUNDS, C>::default().hash_vec(
cs,
vec![
Expand Down
Loading

0 comments on commit 5f2f743

Please sign in to comment.