From 751b3434ec4dfba93178dd8b5d6fa714d62234c3 Mon Sep 17 00:00:00 2001 From: Srinath Setty Date: Mon, 25 Apr 2022 16:11:56 -0700 Subject: [PATCH] make gadgets public, expose coords, cleanup (#39) * make gadgets public, expose coords, cleanup * fix clippy --- src/gadgets/ecc.rs | 68 ++++++++++++++++++++++++++------------------ src/gadgets/mod.rs | 2 ++ src/gadgets/r1cs.rs | 27 +++++++----------- src/gadgets/utils.rs | 1 + src/lib.rs | 2 +- src/poseidon.rs | 1 + 6 files changed, 56 insertions(+), 45 deletions(-) diff --git a/src/gadgets/ecc.rs b/src/gadgets/ecc.rs index c6471bd..1e82f93 100644 --- a/src/gadgets/ecc.rs +++ b/src/gadgets/ecc.rs @@ -1,3 +1,4 @@ +//! This module implements various elliptic curve gadgets #![allow(non_snake_case)] use crate::gadgets::utils::{ alloc_one, alloc_zero, conditionally_select, conditionally_select2, select_one_or, select_zero_or, @@ -12,6 +13,7 @@ use bellperson::{ }; use ff::PrimeField; +/// AllocatedPoint provides an elliptic curve abstraction inside a circuit. #[derive(Clone)] pub struct AllocatedPoint where @@ -26,6 +28,7 @@ impl AllocatedPoint where Fp: PrimeField, { + /// Allocates a new point on the curve using coordinates provided by `coords`. pub fn alloc(mut cs: CS, coords: Option<(Fp, Fp, bool)>) -> Result where CS: ConstraintSystem, @@ -49,9 +52,24 @@ where Ok(AllocatedPoint { x, y, is_infinity }) } - // Creates a new allocated point from allocated nums. - pub fn new(x: AllocatedNum, y: AllocatedNum, is_infinity: AllocatedNum) -> Self { - Self { x, y, is_infinity } + /// Allocates a default point on the curve. + pub fn default(mut cs: CS) -> Result + where + CS: ConstraintSystem, + { + let zero = alloc_zero(cs.namespace(|| "zero"))?; + let one = alloc_one(cs.namespace(|| "one"))?; + + Ok(AllocatedPoint { + x: zero.clone(), + y: zero, + is_infinity: one, + }) + } + + /// Returns coordinates associated with the point. + pub fn get_coordinates(&self) -> (&AllocatedNum, &AllocatedNum, &AllocatedNum) { + (&self.x, &self.y, &self.is_infinity) } // Allocate a random point. Only used for testing @@ -64,7 +82,11 @@ where let x_alloc = AllocatedNum::alloc(cs.namespace(|| "x"), || Ok(x))?; let y_alloc = AllocatedNum::alloc(cs.namespace(|| "y"), || Ok(y.unwrap()))?; let is_infinity = alloc_zero(cs.namespace(|| "Is Infinity"))?; - return Ok(Self::new(x_alloc, y_alloc, is_infinity)); + return Ok(Self { + x: x_alloc, + y: y_alloc, + is_infinity, + }); } } } @@ -80,8 +102,8 @@ where Ok(()) } - // Adds other point to this point and returns the result - // Assumes that both other.is_infinity and this.is_infinty are bits + /// Adds other point to this point and returns the result + /// Assumes that both other.is_infinity and this.is_infinty are bits pub fn add>( &self, mut cs: CS, @@ -208,7 +230,7 @@ where &x, &other.is_infinity, )?; - let final_x = conditionally_select2( + let x = conditionally_select2( cs.namespace(|| "final x: outer if"), &other.x, &inner_x, @@ -222,7 +244,7 @@ where &y, &other.is_infinity, )?; - let final_y = conditionally_select2( + let y = conditionally_select2( cs.namespace(|| "final y: outer if"), &other.y, &inner_y, @@ -236,15 +258,16 @@ where &is_infinity, &other.is_infinity, )?; - let final_is_infinity = conditionally_select2( + let is_infinity = conditionally_select2( cs.namespace(|| "final is infinity: outer if"), &other.is_infinity, &inner_is_infinity, &self.is_infinity, )?; - Ok(Self::new(final_x, final_y, final_is_infinity)) + Ok(Self { x, y, is_infinity }) } + /// Doubles the supplied point. pub fn double>(&self, mut cs: CS) -> Result { //*************************************************************/ // lambda = (Fp::one() + Fp::one() + Fp::one()) @@ -359,35 +382,24 @@ where /*************************************************************/ // x - let final_x = select_zero_or(cs.namespace(|| "final x"), &x, &self.is_infinity)?; + let x = select_zero_or(cs.namespace(|| "final x"), &x, &self.is_infinity)?; // y - let final_y = select_zero_or(cs.namespace(|| "final y"), &y, &self.is_infinity)?; + let y = select_zero_or(cs.namespace(|| "final y"), &y, &self.is_infinity)?; // is_infinity - let final_is_infinity = self.is_infinity.clone(); + let is_infinity = self.is_infinity.clone(); - Ok(Self::new(final_x, final_y, final_is_infinity)) + Ok(Self { x, y, is_infinity }) } + /// A gadget for scalar multiplication. pub fn scalar_mul>( &self, mut cs: CS, scalar: Vec, ) -> Result { - /*************************************************************/ - // Initialize res = Self { - // x: Fp::zero(), - // y: Fp::zero(), - // is_infinity: true, - // _p: Default::default(), - //}; - /*************************************************************/ - - let zero = alloc_zero(cs.namespace(|| "Allocate zero"))?; - let one = alloc_one(cs.namespace(|| "Allocate one"))?; - let mut res = Self::new(zero.clone(), zero, one); - + let mut res = Self::default(cs.namespace(|| "res"))?; for i in (0..scalar.len()).rev() { /*************************************************************/ // res = res.double(); @@ -430,7 +442,7 @@ where condition, )?; - Ok(Self::new(x, y, is_infinity)) + Ok(Self { x, y, is_infinity }) } } diff --git a/src/gadgets/mod.rs b/src/gadgets/mod.rs index b8f53e0..0047b34 100644 --- a/src/gadgets/mod.rs +++ b/src/gadgets/mod.rs @@ -1,3 +1,5 @@ +//! This module implements various gadgets necessary for Nova +//! and applications built with Nova. pub mod ecc; pub mod r1cs; pub mod utils; diff --git a/src/gadgets/r1cs.rs b/src/gadgets/r1cs.rs index 2b229ce..43a2f05 100644 --- a/src/gadgets/r1cs.rs +++ b/src/gadgets/r1cs.rs @@ -1,8 +1,9 @@ +//! This module implements various gadgets necessary for folding R1CS types. use crate::{ gadgets::{ ecc::AllocatedPoint, utils::{ - alloc_bignat_constant, alloc_one, alloc_scalar_as_base, alloc_zero, conditionally_select, + alloc_bignat_constant, alloc_scalar_as_base, conditionally_select, conditionally_select_bignat, le_bits_to_num, }, }, @@ -59,6 +60,7 @@ where Ok(AllocatedR1CSInstance { W, X0, X1 }) } + /// Absorb the provided instance in the RO pub fn absorb_in_ro(&self, ro: &mut PoseidonROGadget) { ro.absorb(self.W.x.clone()); ro.absorb(self.W.y.clone()); @@ -136,36 +138,29 @@ where limb_width: usize, n_limbs: usize, ) -> Result { - let zero = alloc_zero(cs.namespace(|| "zero"))?; - let one = alloc_one(cs.namespace(|| "one"))?; + let W = AllocatedPoint::default(cs.namespace(|| "allocate W"))?; + let E = W.clone(); - let W_default = AllocatedPoint::new(zero.clone(), zero.clone(), one); - let E_default = W_default.clone(); + let u = W.x.clone(); // In the default case, W.x = u = 0 - let u_default = zero; - - let X0_default = BigNat::alloc_from_nat( + let X0 = BigNat::alloc_from_nat( cs.namespace(|| "allocate x_default[0]"), || Ok(f_to_nat(&G::Scalar::zero())), limb_width, n_limbs, )?; - let X1_default = BigNat::alloc_from_nat( + let X1 = BigNat::alloc_from_nat( cs.namespace(|| "allocate x_default[1]"), || Ok(f_to_nat(&G::Scalar::zero())), limb_width, n_limbs, )?; - Ok(AllocatedRelaxedR1CSInstance { - W: W_default, - E: E_default, - u: u_default, - X0: X0_default, - X1: X1_default, - }) + + Ok(AllocatedRelaxedR1CSInstance { W, E, u, X0, X1 }) } + /// Absorb the provided instance in the RO pub fn absorb_in_ro::Base>>( &self, mut cs: CS, diff --git a/src/gadgets/utils.rs b/src/gadgets/utils.rs index fea1ef0..075bdd7 100644 --- a/src/gadgets/utils.rs +++ b/src/gadgets/utils.rs @@ -1,3 +1,4 @@ +//! This module implements various low-level gadgets use crate::traits::Group; use bellperson::{ gadgets::{ diff --git a/src/lib.rs b/src/lib.rs index 8035469..99a8508 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,7 +8,7 @@ mod commitments; pub mod bellperson; mod circuit; pub mod errors; -mod gadgets; +pub mod gadgets; pub mod pasta; mod poseidon; pub mod r1cs; diff --git a/src/poseidon.rs b/src/poseidon.rs index d9d89c5..ed4ea82 100644 --- a/src/poseidon.rs +++ b/src/poseidon.rs @@ -34,6 +34,7 @@ where F: PrimeField, { /// Generate Poseidon constants for the arities that Nova uses + #[allow(clippy::new_without_default)] pub fn new() -> Self { let constants8 = PoseidonConstants::::new_with_strength(Strength::Strengthened); let constants25 = PoseidonConstants::::new_with_strength(Strength::Strengthened);