mirror of
https://github.com/arnaucube/Nova.git
synced 2026-01-11 08:31:29 +01:00
optimize the non-native arithmetic and hashing costs by using 4 limbs instead of 8 (#102)
This commit is contained in:
@@ -354,14 +354,14 @@ mod tests {
|
|||||||
|
|
||||||
// First create the shape
|
// First create the shape
|
||||||
let mut cs: ShapeCS<G> = ShapeCS::new();
|
let mut cs: ShapeCS<G> = ShapeCS::new();
|
||||||
let _ = synthesize_add(&mut cs, &a_val, &b_val, &c_val, 32, 8);
|
let _ = synthesize_add(&mut cs, &a_val, &b_val, &c_val, 64, 4);
|
||||||
let shape = cs.r1cs_shape();
|
let shape = cs.r1cs_shape();
|
||||||
let gens = cs.r1cs_gens();
|
let gens = cs.r1cs_gens();
|
||||||
println!("Add mod constraint no: {}", cs.num_constraints());
|
println!("Add mod constraint no: {}", cs.num_constraints());
|
||||||
|
|
||||||
// Now get the assignment
|
// Now get the assignment
|
||||||
let mut cs: SatisfyingAssignment<G> = SatisfyingAssignment::new();
|
let mut cs: SatisfyingAssignment<G> = SatisfyingAssignment::new();
|
||||||
let _ = synthesize_add(&mut cs, &a_val, &b_val, &c_val, 32, 8);
|
let _ = synthesize_add(&mut cs, &a_val, &b_val, &c_val, 64, 4);
|
||||||
let (inst, witness) = cs.r1cs_instance_and_witness(&shape, &gens).unwrap();
|
let (inst, witness) = cs.r1cs_instance_and_witness(&shape, &gens).unwrap();
|
||||||
|
|
||||||
// Make sure that this is satisfiable
|
// Make sure that this is satisfiable
|
||||||
|
|||||||
@@ -379,7 +379,7 @@ mod tests {
|
|||||||
let mut cs: ShapeCS<G1> = ShapeCS::new();
|
let mut cs: ShapeCS<G1> = ShapeCS::new();
|
||||||
let _ = circuit1.synthesize(&mut cs);
|
let _ = circuit1.synthesize(&mut cs);
|
||||||
let (shape1, gens1) = (cs.r1cs_shape(), cs.r1cs_gens());
|
let (shape1, gens1) = (cs.r1cs_shape(), cs.r1cs_gens());
|
||||||
assert_eq!(cs.num_constraints(), 20584);
|
assert_eq!(cs.num_constraints(), 20122);
|
||||||
|
|
||||||
// Initialize the shape and gens for the secondary
|
// Initialize the shape and gens for the secondary
|
||||||
let circuit2: NovaAugmentedCircuit<G1, TrivialTestCircuit<<G1 as Group>::Base>> =
|
let circuit2: NovaAugmentedCircuit<G1, TrivialTestCircuit<<G1 as Group>::Base>> =
|
||||||
@@ -392,7 +392,7 @@ mod tests {
|
|||||||
let mut cs: ShapeCS<G2> = ShapeCS::new();
|
let mut cs: ShapeCS<G2> = ShapeCS::new();
|
||||||
let _ = circuit2.synthesize(&mut cs);
|
let _ = circuit2.synthesize(&mut cs);
|
||||||
let (shape2, gens2) = (cs.r1cs_shape(), cs.r1cs_gens());
|
let (shape2, gens2) = (cs.r1cs_shape(), cs.r1cs_gens());
|
||||||
assert_eq!(cs.num_constraints(), 21124);
|
assert_eq!(cs.num_constraints(), 20654);
|
||||||
|
|
||||||
// Execute the base case for the primary
|
// Execute the base case for the primary
|
||||||
let zero1 = <<G2 as Group>::Base as Field>::zero();
|
let zero1 = <<G2 as Group>::Base as Field>::zero();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
pub(crate) const NUM_CHALLENGE_BITS: usize = 128;
|
pub(crate) const NUM_CHALLENGE_BITS: usize = 128;
|
||||||
pub(crate) const NUM_HASH_BITS: usize = 250;
|
pub(crate) const NUM_HASH_BITS: usize = 250;
|
||||||
pub(crate) const BN_LIMB_WIDTH: usize = 32;
|
pub(crate) const BN_LIMB_WIDTH: usize = 64;
|
||||||
pub(crate) const BN_N_LIMBS: usize = 8;
|
pub(crate) const BN_N_LIMBS: usize = 4;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use bellperson::{
|
|||||||
};
|
};
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use ff::{PrimeField, PrimeFieldBits};
|
use ff::{PrimeField, PrimeFieldBits};
|
||||||
use generic_array::typenum::{U27, U32};
|
use generic_array::typenum::{U19, U24};
|
||||||
use neptune::{
|
use neptune::{
|
||||||
circuit::poseidon_hash,
|
circuit::poseidon_hash,
|
||||||
poseidon::{Poseidon, PoseidonConstants},
|
poseidon::{Poseidon, PoseidonConstants},
|
||||||
@@ -22,8 +22,8 @@ pub struct PoseidonConstantsCircuit<Scalar>
|
|||||||
where
|
where
|
||||||
Scalar: PrimeField,
|
Scalar: PrimeField,
|
||||||
{
|
{
|
||||||
constants27: PoseidonConstants<Scalar, U27>,
|
constants19: PoseidonConstants<Scalar, U19>,
|
||||||
constants32: PoseidonConstants<Scalar, U32>,
|
constants24: PoseidonConstants<Scalar, U24>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Scalar> ROConstantsTrait<Scalar> for PoseidonConstantsCircuit<Scalar>
|
impl<Scalar> ROConstantsTrait<Scalar> for PoseidonConstantsCircuit<Scalar>
|
||||||
@@ -33,11 +33,11 @@ where
|
|||||||
/// Generate Poseidon constants for the arities that Nova uses
|
/// Generate Poseidon constants for the arities that Nova uses
|
||||||
#[allow(clippy::new_without_default)]
|
#[allow(clippy::new_without_default)]
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
let constants27 = PoseidonConstants::<Scalar, U27>::new_with_strength(Strength::Standard);
|
let constants19 = PoseidonConstants::<Scalar, U19>::new_with_strength(Strength::Standard);
|
||||||
let constants32 = PoseidonConstants::<Scalar, U32>::new_with_strength(Strength::Standard);
|
let constants24 = PoseidonConstants::<Scalar, U24>::new_with_strength(Strength::Standard);
|
||||||
Self {
|
Self {
|
||||||
constants27,
|
constants19,
|
||||||
constants32,
|
constants24,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,11 +78,11 @@ where
|
|||||||
/// Compute a challenge by hashing the current state
|
/// Compute a challenge by hashing the current state
|
||||||
fn squeeze(&self, num_bits: usize) -> Scalar {
|
fn squeeze(&self, num_bits: usize) -> Scalar {
|
||||||
let hash = match self.state.len() {
|
let hash = match self.state.len() {
|
||||||
27 => {
|
19 => {
|
||||||
Poseidon::<Base, U27>::new_with_preimage(&self.state, &self.constants.constants27).hash()
|
Poseidon::<Base, U19>::new_with_preimage(&self.state, &self.constants.constants19).hash()
|
||||||
}
|
}
|
||||||
32 => {
|
24 => {
|
||||||
Poseidon::<Base, U32>::new_with_preimage(&self.state, &self.constants.constants32).hash()
|
Poseidon::<Base, U24>::new_with_preimage(&self.state, &self.constants.constants24).hash()
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
panic!(
|
panic!(
|
||||||
@@ -145,15 +145,15 @@ where
|
|||||||
CS: ConstraintSystem<Scalar>,
|
CS: ConstraintSystem<Scalar>,
|
||||||
{
|
{
|
||||||
let hash = match self.state.len() {
|
let hash = match self.state.len() {
|
||||||
27 => poseidon_hash(
|
19 => poseidon_hash(
|
||||||
cs.namespace(|| "Poseidon hash"),
|
cs.namespace(|| "Poseidon hash"),
|
||||||
self.state.clone(),
|
self.state.clone(),
|
||||||
&self.constants.constants27,
|
&self.constants.constants19,
|
||||||
)?,
|
)?,
|
||||||
32 => poseidon_hash(
|
24 => poseidon_hash(
|
||||||
cs.namespace(|| "Posideon hash"),
|
cs.namespace(|| "Posideon hash"),
|
||||||
self.state.clone(),
|
self.state.clone(),
|
||||||
&self.constants.constants32,
|
&self.constants.constants24,
|
||||||
)?,
|
)?,
|
||||||
_ => {
|
_ => {
|
||||||
panic!(
|
panic!(
|
||||||
@@ -199,7 +199,7 @@ mod tests {
|
|||||||
let mut ro: PoseidonRO<S, B> = PoseidonRO::new(constants.clone());
|
let mut ro: PoseidonRO<S, B> = PoseidonRO::new(constants.clone());
|
||||||
let mut ro_gadget: PoseidonROCircuit<S> = PoseidonROCircuit::new(constants);
|
let mut ro_gadget: PoseidonROCircuit<S> = PoseidonROCircuit::new(constants);
|
||||||
let mut cs: SatisfyingAssignment<G> = SatisfyingAssignment::new();
|
let mut cs: SatisfyingAssignment<G> = SatisfyingAssignment::new();
|
||||||
for i in 0..27 {
|
for i in 0..19 {
|
||||||
let num = S::random(&mut csprng);
|
let num = S::random(&mut csprng);
|
||||||
ro.absorb(num);
|
ro.absorb(num);
|
||||||
let num_gadget =
|
let num_gadget =
|
||||||
|
|||||||
Reference in New Issue
Block a user