Cleanup (#27) * VerificationCircuit --> NIFSVerifierCircuit, for clarity * InnerCircuit --> StepCircuit * Rename * cleanup imports * additional cleanup in the test * small cleanup
@@ -2,3 +2,4 @@ edition = "2018"
tab_spaces = 2 newline_style = "Unix" use_try_shorthand = true +imports_granularity = "crate"
@@ -2,8 +2,7 @@ //! Support for generating R1CS using bellperson.
#![allow(non_snake_case)] -use super::shape_cs::ShapeCS; -use super::solver::SatisfyingAssignment; +use super::{shape_cs::ShapeCS, solver::SatisfyingAssignment}; use bellperson::{Index, LinearCombination}; use ff::PrimeField;
@@ -1,7 +1,9 @@
//! Support for generating R1CS shape using bellperson. -use std::cmp::Ordering; -use std::collections::{BTreeMap, HashMap}; +use std::{ + cmp::Ordering, + collections::{BTreeMap, HashMap}, +}; use crate::traits::{Group, PrimeField as PF}; use ff::{Field, PrimeField};
@@ -10,18 +10,19 @@ //! h1 = H(params = H(shape, gens), u2, i, z0, zi) and h2 = H(u1, i)
//! otherwise //! h1 = H(u2, i) and h2 = H(params = H(shape, gens), u1, i, z0, zi) -use super::commitments::Commitment; -use super::gadgets::{ - ecc::AllocatedPoint, - utils::{ - alloc_bignat_constant, alloc_num_equals, alloc_one, alloc_zero, conditionally_select, - conditionally_select_bignat, le_bits_to_num, +use super::{ + commitments::Commitment, + gadgets::{ + ecc::AllocatedPoint, + utils::{ + alloc_bignat_constant, alloc_num_equals, alloc_one, alloc_zero, conditionally_select, + conditionally_select_bignat, le_bits_to_num, + }, }, + poseidon::{NovaPoseidonConstants, PoseidonROGadget}, + r1cs::RelaxedR1CSInstance, + traits::{Group, PrimeField, StepCircuit}, }; -use super::poseidon::NovaPoseidonConstants; -use super::poseidon::PoseidonROGadget; -use super::r1cs::RelaxedR1CSInstance; -use super::traits::{Group, InnerCircuit, PrimeField}; use bellperson::{ gadgets::{boolean::Boolean, num::AllocatedNum, Assignment}, Circuit, ConstraintSystem, SynthesisError,@@ -33,12 +34,12 @@ };
use ff::PrimeFieldBits; #[derive(Debug, Clone)] -pub struct VerificationCircuitParams { +pub struct NIFSVerifierCircuitParams { limb_width: usize, n_limbs: usize, } -impl VerificationCircuitParams { +impl NIFSVerifierCircuitParams { #[allow(dead_code)] pub fn new(limb_width: usize, n_limbs: usize) -> Self { Self {@@ -48,7 +49,7 @@ }
} } -pub struct VerificationCircuitInputs<G> +pub struct NIFSVerifierCircuitInputs<G> where G: Group, {@@ -63,7 +64,7 @@ T: Commitment<G>,
w: Commitment<G>, // The commitment to the witness of the fresh r1cs instance } -impl<G> VerificationCircuitInputs<G> +impl<G> NIFSVerifierCircuitInputs<G> where G: Group, {@@ -95,30 +96,30 @@ }
} /// Circuit that encodes only the folding verifier -pub struct VerificationCircuit<G, IC> +pub struct NIFSVerifierCircuit<G, SC> where G: Group, <G as Group>::Base: ff::PrimeField, - IC: InnerCircuit<G::Base>, + SC: StepCircuit<G::Base>, { - params: VerificationCircuitParams, - inputs: Option<VerificationCircuitInputs<G>>, - inner_circuit: Option<IC>, // The function that is applied for each step. may be None. + params: NIFSVerifierCircuitParams, + inputs: Option<NIFSVerifierCircuitInputs<G>>, + step_circuit: Option<SC>, // The function that is applied for each step. may be None. poseidon_constants: NovaPoseidonConstants<G::Base>, } -impl<G, IC> VerificationCircuit<G, IC> +impl<G, SC> NIFSVerifierCircuit<G, SC> where G: Group, <G as Group>::Base: ff::PrimeField, - IC: InnerCircuit<G::Base>, + SC: StepCircuit<G::Base>, { /// Create a new verification circuit for the input relaxed r1cs instances #[allow(dead_code)] pub fn new( - params: VerificationCircuitParams, - inputs: Option<VerificationCircuitInputs<G>>, - inner_circuit: Option<IC>, + params: NIFSVerifierCircuitParams, + inputs: Option<NIFSVerifierCircuitInputs<G>>, + step_circuit: Option<SC>, poseidon_constants: NovaPoseidonConstants<G::Base>, ) -> Self where@@ -127,18 +128,18 @@ {
Self { params, inputs, - inner_circuit, + step_circuit, poseidon_constants, } } } -impl<G, IC> Circuit<<G as Group>::Base> for VerificationCircuit<G, IC> +impl<G, SC> Circuit<<G as Group>::Base> for NIFSVerifierCircuit<G, SC> where G: Group, <G as Group>::Base: ff::PrimeField + PrimeField + PrimeFieldBits, <G as Group>::Scalar: PrimeFieldBits, - IC: InnerCircuit<G::Base>, + SC: StepCircuit<G::Base>, { fn synthesize<CS: ConstraintSystem<<G as Group>::Base>>( self,@@ -304,7 +305,7 @@ /***********************************************************************/
// Allocate W /***********************************************************************/ - // T = (x, y, infinity) + // W = (x, y, infinity) let W_x = AllocatedNum::alloc(cs.namespace(|| "W.x"), || { Ok(self.inputs.get()?.w.comm.to_coordinates().0) })?;@@ -336,7 +337,7 @@
// Compute default values of U2': let zero_commitment = AllocatedPoint::new(zero.clone(), zero.clone(), one); - //W_default and E_default are a commitment to zero + // W_default and E_default are a commitment to zero let W_default = zero_commitment.clone(); let E_default = zero_commitment;@@ -501,7 +502,7 @@ })
.collect::<Result<Vec<AllocatedNum<G::Base>>, _>>()?; /***********************************************************************/ - //Compute i + 1 + // Compute i + 1 /***********************************************************************/ let next_i = AllocatedNum::alloc(cs.namespace(|| "i + 1"), || {@@ -515,7 +516,7 @@ |lc| lc,
|lc| lc + next_i.get_variable() - CS::one() - i.get_variable(), ); - if self.inner_circuit.is_some() { + if self.step_circuit.is_some() { /***********************************************************************/ //Allocate z0 /***********************************************************************/@@ -590,7 +591,7 @@ // Compute z_{i+1}
/***********************************************************************/ let z_next = self - .inner_circuit + .step_circuit .unwrap() .synthesize(&mut cs.namespace(|| "F"), z_i)?;@@ -641,12 +642,12 @@ h1_hash.absorb(E_r_inf);
h1_hash.absorb(u_r); h1_hash.absorb(i.clone()); - //absorb each of the limbs of X_r[0] + // absorb each of the limbs of X_r[0] for limb in Xr0_bn.into_iter() { h1_hash.absorb(limb); } - //absorb each of the limbs of X_r[1] + // absorb each of the limbs of X_r[1] for limb in Xr1_bn.into_iter() { h1_hash.absorb(limb); }@@ -698,12 +699,13 @@
#[cfg(test)] mod tests { use super::*; - use crate::bellperson::shape_cs::ShapeCS; - use crate::bellperson::solver::SatisfyingAssignment; + use crate::bellperson::{shape_cs::ShapeCS, solver::SatisfyingAssignment}; type G1 = pasta_curves::pallas::Point; type G2 = pasta_curves::vesta::Point; - use crate::bellperson::r1cs::{NovaShape, NovaWitness}; - use crate::commitments::CommitTrait; + use crate::{ + bellperson::r1cs::{NovaShape, NovaWitness}, + commitments::CommitTrait, + }; use std::marker::PhantomData; struct TestCircuit<F>@@ -713,7 +715,7 @@ {
_p: PhantomData<F>, } - impl<F> InnerCircuit<F> for TestCircuit<F> + impl<F> StepCircuit<F> for TestCircuit<F> where F: PrimeField + ff::PrimeField, {@@ -729,12 +731,12 @@
#[test] fn test_verification_circuit() { // We experiment with 8 limbs of 32 bits each - let params = VerificationCircuitParams::new(32, 8); + let params = NIFSVerifierCircuitParams::new(32, 8); // The first circuit that verifies G2 let poseidon_constants1: NovaPoseidonConstants<<G2 as Group>::Base> = NovaPoseidonConstants::new(); - let circuit1: VerificationCircuit<G2, TestCircuit<<G2 as Group>::Base>> = - VerificationCircuit::new( + let circuit1: NIFSVerifierCircuit<G2, TestCircuit<<G2 as Group>::Base>> = + NIFSVerifierCircuit::new( params.clone(), None, Some(TestCircuit {@@ -745,8 +747,7 @@ );
// First create the shape let mut cs: ShapeCS<G1> = ShapeCS::new(); let _ = circuit1.synthesize(&mut cs); - let shape1 = cs.r1cs_shape(); - let gens1 = cs.r1cs_gens(); + let (shape1, gens1) = (cs.r1cs_shape(), cs.r1cs_gens()); println!( "Circuit1 -> Number of constraints: {}", cs.num_constraints()@@ -755,28 +756,29 @@
// The second circuit that verifies G1 let poseidon_constants2: NovaPoseidonConstants<<G1 as Group>::Base> = NovaPoseidonConstants::new(); - let circuit2: VerificationCircuit<G1, TestCircuit<<G1 as Group>::Base>> = - VerificationCircuit::new(params.clone(), None, None, poseidon_constants2); + let circuit2: NIFSVerifierCircuit<G1, TestCircuit<<G1 as Group>::Base>> = + NIFSVerifierCircuit::new(params.clone(), None, None, poseidon_constants2); // First create the shape let mut cs: ShapeCS<G2> = ShapeCS::new(); let _ = circuit2.synthesize(&mut cs); - let shape2 = cs.r1cs_shape(); - let gens2 = cs.r1cs_gens(); + let (shape2, gens2) = (cs.r1cs_shape(), cs.r1cs_gens()); println!( "Circuit2 -> Number of constraints: {}", cs.num_constraints() ); - //TODO: We need to hardwire default hash or give it as input + // TODO: We need to hardwire default hash or give it as input let default_hash = <<G2 as Group>::Base as ff::PrimeField>::from_str_vartime( "332553638888022689042501686561503049809", ) .unwrap(); + let T = vec![<G2 as Group>::Scalar::zero()].commit(&gens2.gens_E); let w = vec![<G2 as Group>::Scalar::zero()].commit(&gens2.gens_E); + // Now get an assignment let mut cs: SatisfyingAssignment<G1> = SatisfyingAssignment::new(); - let inputs: VerificationCircuitInputs<G2> = VerificationCircuitInputs::new( + let inputs: NIFSVerifierCircuitInputs<G2> = NIFSVerifierCircuitInputs::new( default_hash, RelaxedR1CSInstance::default(&gens2, &shape2), <<G2 as Group>::Base as PrimeField>::zero(), // TODO: provide real inputs@@ -787,8 +789,9 @@ <<G2 as Group>::Base as PrimeField>::zero(), // TODO: provide real inputs
T, // TODO: provide real inputs w, ); - let circuit: VerificationCircuit<G2, TestCircuit<<G2 as Group>::Base>> = - VerificationCircuit::new( + + let circuit: NIFSVerifierCircuit<G2, TestCircuit<<G2 as Group>::Base>> = + NIFSVerifierCircuit::new( params, Some(inputs), Some(TestCircuit {
@@ -1,7 +1,11 @@
-use super::errors::NovaError; -use super::traits::{CompressedGroup, Group}; -use core::fmt::Debug; -use core::ops::{Add, AddAssign, Mul, MulAssign}; +use super::{ + errors::NovaError, + traits::{CompressedGroup, Group}, +}; +use core::{ + fmt::Debug, + ops::{Add, AddAssign, Mul, MulAssign}, +}; use digest::{ExtendableOutput, Input}; use merlin::Transcript; use sha3::Shake256;
@@ -619,12 +619,9 @@ assert_eq!(d_pasta, d_pasta_2);
assert_eq!(e_pasta, e_pasta_2); } - use crate::bellperson::shape_cs::ShapeCS; - use crate::bellperson::solver::SatisfyingAssignment; + use crate::bellperson::{shape_cs::ShapeCS, solver::SatisfyingAssignment}; use ff::{Field, PrimeFieldBits}; - use pasta_curves::arithmetic::CurveAffine; - use pasta_curves::group::Curve; - use pasta_curves::EpAffine; + use pasta_curves::{arithmetic::CurveAffine, group::Curve, EpAffine}; use std::ops::Mul; type G = pasta_curves::pallas::Point; type Fp = pasta_curves::pallas::Scalar;
@@ -1,13 +1,15 @@
//! This module implements the Nova traits for pallas::Point, pallas::Scalar, vesta::Point, vesta::Scalar. use crate::traits::{ChallengeTrait, CompressedGroup, Group, PrimeField}; use merlin::Transcript; -use pasta_curves::arithmetic::{CurveAffine, CurveExt, FieldExt, Group as Grp}; -use pasta_curves::group::{Curve, GroupEncoding}; -use pasta_curves::{self, pallas, vesta, Ep, Eq, Fp, Fq}; +use pasta_curves::{ + self, + arithmetic::{CurveAffine, CurveExt, FieldExt, Group as Grp}, + group::{Curve, GroupEncoding}, + pallas, vesta, Ep, Eq, Fp, Fq, +}; use rand::{CryptoRng, RngCore}; use rug::Integer; -use std::borrow::Borrow; -use std::ops::Mul; +use std::{borrow::Borrow, ops::Mul}; //////////////////////////////////////Pallas///////////////////////////////////////////////
@@ -189,9 +189,9 @@ mod tests {
use super::*; type S = pasta_curves::pallas::Scalar; type G = pasta_curves::pallas::Point; - use crate::bellperson::solver::SatisfyingAssignment; - use crate::gadgets::utils::le_bits_to_num; - use crate::traits::PrimeField; + use crate::{ + bellperson::solver::SatisfyingAssignment, gadgets::utils::le_bits_to_num, traits::PrimeField, + }; use rand::rngs::OsRng; #[test]
@@ -1,8 +1,10 @@
//! This module defines R1CS related types and a folding scheme for Relaxed R1CS #![allow(clippy::type_complexity)] -use super::commitments::{CommitGens, CommitTrait, Commitment, CompressedCommitment}; -use super::errors::NovaError; -use super::traits::{Group, PrimeField}; +use super::{ + commitments::{CommitGens, CommitTrait, Commitment, CompressedCommitment}, + errors::NovaError, + traits::{Group, PrimeField}, +}; use itertools::concat; use rayon::prelude::*;
@@ -1,8 +1,10 @@
//! This module defines various traits required by the users of the library to implement. use bellperson::{gadgets::num::AllocatedNum, ConstraintSystem, SynthesisError}; -use core::borrow::Borrow; -use core::fmt::Debug; -use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::{ + borrow::Borrow, + fmt::Debug, + ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}, +}; use merlin::Transcript; use rand::{CryptoRng, RngCore}; use rug::Integer;@@ -131,9 +133,10 @@ /// A helper trait for references implementing group scalar multiplication.
pub trait ScalarMulOwned<Rhs, Output = Self>: for<'r> ScalarMul<&'r Rhs, Output> {} impl<T, Rhs, Output> ScalarMulOwned<Rhs, Output> for T where T: for<'r> ScalarMul<&'r Rhs, Output> {} -///A helper trait for the inner circuit F -pub trait InnerCircuit<F: PrimeField + ff::PrimeField> { - ///Sythesize the circuit for a computation step and return variable that corresponds to z_{i+1} +/// A helper trait for a step of the incremental computation (i.e., circuit for F) +pub trait StepCircuit<F: PrimeField + ff::PrimeField> { + /// Sythesize the circuit for a computation step and return variable + /// that corresponds to the output of the step z_{i+1} fn synthesize<CS: ConstraintSystem<F>>( &self, cs: &mut CS,