optimize the non-native arithmetic and hashing costs by using 4 limbs instead of 8 (#102)
Srinath Setty srinath@microsoft.com
Wed, 27 Jul 2022 17:09:49 -0700
4 files changed,
22 insertions(+),
22 deletions(-)
M
src/bellperson/mod.rs
→
src/bellperson/mod.rs
@@ -354,14 +354,14 @@ .unwrap();
// First create the shape 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 gens = cs.r1cs_gens(); println!("Add mod constraint no: {}", cs.num_constraints()); // Now get the assignment 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(); // Make sure that this is satisfiable
M
src/circuit.rs
→
src/circuit.rs
@@ -379,7 +379,7 @@ );
let mut cs: ShapeCS<G1> = ShapeCS::new(); let _ = circuit1.synthesize(&mut cs); 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 let circuit2: NovaAugmentedCircuit<G1, TrivialTestCircuit<<G1 as Group>::Base>> =@@ -392,7 +392,7 @@ );
let mut cs: ShapeCS<G2> = ShapeCS::new(); let _ = circuit2.synthesize(&mut cs); 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 let zero1 = <<G2 as Group>::Base as Field>::zero();
M
src/constants.rs
→
src/constants.rs
@@ -1,4 +1,4 @@
pub(crate) const NUM_CHALLENGE_BITS: usize = 128; pub(crate) const NUM_HASH_BITS: usize = 250; -pub(crate) const BN_LIMB_WIDTH: usize = 32; -pub(crate) const BN_N_LIMBS: usize = 8; +pub(crate) const BN_LIMB_WIDTH: usize = 64; +pub(crate) const BN_N_LIMBS: usize = 4;
M
src/poseidon.rs
→
src/poseidon.rs
@@ -9,7 +9,7 @@ ConstraintSystem, SynthesisError,
}; use core::marker::PhantomData; use ff::{PrimeField, PrimeFieldBits}; -use generic_array::typenum::{U27, U32}; +use generic_array::typenum::{U19, U24}; use neptune::{ circuit::poseidon_hash, poseidon::{Poseidon, PoseidonConstants},@@ -22,8 +22,8 @@ pub struct PoseidonConstantsCircuit<Scalar>
where Scalar: PrimeField, { - constants27: PoseidonConstants<Scalar, U27>, - constants32: PoseidonConstants<Scalar, U32>, + constants19: PoseidonConstants<Scalar, U19>, + constants24: PoseidonConstants<Scalar, U24>, } impl<Scalar> ROConstantsTrait<Scalar> for PoseidonConstantsCircuit<Scalar>@@ -33,11 +33,11 @@ {
/// Generate Poseidon constants for the arities that Nova uses #[allow(clippy::new_without_default)] fn new() -> Self { - let constants27 = PoseidonConstants::<Scalar, U27>::new_with_strength(Strength::Standard); - let constants32 = PoseidonConstants::<Scalar, U32>::new_with_strength(Strength::Standard); + let constants19 = PoseidonConstants::<Scalar, U19>::new_with_strength(Strength::Standard); + let constants24 = PoseidonConstants::<Scalar, U24>::new_with_strength(Strength::Standard); Self { - constants27, - constants32, + constants19, + constants24, } } }@@ -78,11 +78,11 @@
/// Compute a challenge by hashing the current state fn squeeze(&self, num_bits: usize) -> Scalar { let hash = match self.state.len() { - 27 => { - Poseidon::<Base, U27>::new_with_preimage(&self.state, &self.constants.constants27).hash() + 19 => { + Poseidon::<Base, U19>::new_with_preimage(&self.state, &self.constants.constants19).hash() } - 32 => { - Poseidon::<Base, U32>::new_with_preimage(&self.state, &self.constants.constants32).hash() + 24 => { + Poseidon::<Base, U24>::new_with_preimage(&self.state, &self.constants.constants24).hash() } _ => { panic!(@@ -145,15 +145,15 @@ where
CS: ConstraintSystem<Scalar>, { let hash = match self.state.len() { - 27 => poseidon_hash( + 19 => poseidon_hash( cs.namespace(|| "Poseidon hash"), self.state.clone(), - &self.constants.constants27, + &self.constants.constants19, )?, - 32 => poseidon_hash( + 24 => poseidon_hash( cs.namespace(|| "Posideon hash"), self.state.clone(), - &self.constants.constants32, + &self.constants.constants24, )?, _ => { panic!(@@ -199,7 +199,7 @@ let constants = PoseidonConstantsCircuit::new();
let mut ro: PoseidonRO<S, B> = PoseidonRO::new(constants.clone()); let mut ro_gadget: PoseidonROCircuit<S> = PoseidonROCircuit::new(constants); let mut cs: SatisfyingAssignment<G> = SatisfyingAssignment::new(); - for i in 0..27 { + for i in 0..19 { let num = S::random(&mut csprng); ro.absorb(num); let num_gadget =