mirror of
https://github.com/arnaucube/Nova.git
synced 2026-01-10 16:11:29 +01:00
Cleanup (#27)
* VerificationCircuit --> NIFSVerifierCircuit, for clarity * InnerCircuit --> StepCircuit * Rename * cleanup imports * additional cleanup in the test * small cleanup
This commit is contained in:
@@ -2,3 +2,4 @@ edition = "2018"
|
||||
tab_spaces = 2
|
||||
newline_style = "Unix"
|
||||
use_try_shorthand = true
|
||||
imports_granularity = "crate"
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
#![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};
|
||||
|
||||
107
src/circuit.rs
107
src/circuit.rs
@@ -10,18 +10,19 @@
|
||||
//! 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 bellperson_nonnative::{
|
||||
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 @@ impl VerificationCircuitParams {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VerificationCircuitInputs<G>
|
||||
pub struct NIFSVerifierCircuitInputs<G>
|
||||
where
|
||||
G: Group,
|
||||
{
|
||||
@@ -63,7 +64,7 @@ where
|
||||
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 @@ where
|
||||
}
|
||||
|
||||
/// 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 @@ where
|
||||
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 @@ where
|
||||
// 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 @@ where
|
||||
// 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 @@ where
|
||||
.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 @@ where
|
||||
|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 @@ where
|
||||
/***********************************************************************/
|
||||
|
||||
let z_next = self
|
||||
.inner_circuit
|
||||
.step_circuit
|
||||
.unwrap()
|
||||
.synthesize(&mut cs.namespace(|| "F"), z_i)?;
|
||||
|
||||
@@ -641,12 +642,12 @@ where
|
||||
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 @@ where
|
||||
#[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 @@ mod tests {
|
||||
_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 @@ mod tests {
|
||||
#[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 @@ mod tests {
|
||||
// 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 @@ mod tests {
|
||||
// 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 @@ mod tests {
|
||||
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 @@ mod tests {
|
||||
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;
|
||||
|
||||
12
src/pasta.rs
12
src/pasta.rs
@@ -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 @@ impl<T, Rhs, Output> ScalarMul<Rhs, Output> for T where T: Mul<Rhs, Output = Out
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user