make gadgets public, expose coords, cleanup (#39)

* make gadgets public, expose coords, cleanup

* fix clippy
This commit is contained in:
Srinath Setty
2022-04-25 16:11:56 -07:00
committed by GitHub
parent fd0b0b787b
commit 751b3434ec
6 changed files with 56 additions and 45 deletions

View File

@@ -1,3 +1,4 @@
//! This module implements various elliptic curve gadgets
#![allow(non_snake_case)] #![allow(non_snake_case)]
use crate::gadgets::utils::{ use crate::gadgets::utils::{
alloc_one, alloc_zero, conditionally_select, conditionally_select2, select_one_or, select_zero_or, alloc_one, alloc_zero, conditionally_select, conditionally_select2, select_one_or, select_zero_or,
@@ -12,6 +13,7 @@ use bellperson::{
}; };
use ff::PrimeField; use ff::PrimeField;
/// AllocatedPoint provides an elliptic curve abstraction inside a circuit.
#[derive(Clone)] #[derive(Clone)]
pub struct AllocatedPoint<Fp> pub struct AllocatedPoint<Fp>
where where
@@ -26,6 +28,7 @@ impl<Fp> AllocatedPoint<Fp>
where where
Fp: PrimeField, Fp: PrimeField,
{ {
/// Allocates a new point on the curve using coordinates provided by `coords`.
pub fn alloc<CS>(mut cs: CS, coords: Option<(Fp, Fp, bool)>) -> Result<Self, SynthesisError> pub fn alloc<CS>(mut cs: CS, coords: Option<(Fp, Fp, bool)>) -> Result<Self, SynthesisError>
where where
CS: ConstraintSystem<Fp>, CS: ConstraintSystem<Fp>,
@@ -49,9 +52,24 @@ where
Ok(AllocatedPoint { x, y, is_infinity }) Ok(AllocatedPoint { x, y, is_infinity })
} }
// Creates a new allocated point from allocated nums. /// Allocates a default point on the curve.
pub fn new(x: AllocatedNum<Fp>, y: AllocatedNum<Fp>, is_infinity: AllocatedNum<Fp>) -> Self { pub fn default<CS>(mut cs: CS) -> Result<Self, SynthesisError>
Self { x, y, is_infinity } where
CS: ConstraintSystem<Fp>,
{
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<Fp>, &AllocatedNum<Fp>, &AllocatedNum<Fp>) {
(&self.x, &self.y, &self.is_infinity)
} }
// Allocate a random point. Only used for testing // Allocate a random point. Only used for testing
@@ -64,7 +82,11 @@ where
let x_alloc = AllocatedNum::alloc(cs.namespace(|| "x"), || Ok(x))?; let x_alloc = AllocatedNum::alloc(cs.namespace(|| "x"), || Ok(x))?;
let y_alloc = AllocatedNum::alloc(cs.namespace(|| "y"), || Ok(y.unwrap()))?; let y_alloc = AllocatedNum::alloc(cs.namespace(|| "y"), || Ok(y.unwrap()))?;
let is_infinity = alloc_zero(cs.namespace(|| "Is Infinity"))?; 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(()) Ok(())
} }
// Adds other point to this point and returns the result /// Adds other point to this point and returns the result
// Assumes that both other.is_infinity and this.is_infinty are bits /// Assumes that both other.is_infinity and this.is_infinty are bits
pub fn add<CS: ConstraintSystem<Fp>>( pub fn add<CS: ConstraintSystem<Fp>>(
&self, &self,
mut cs: CS, mut cs: CS,
@@ -208,7 +230,7 @@ where
&x, &x,
&other.is_infinity, &other.is_infinity,
)?; )?;
let final_x = conditionally_select2( let x = conditionally_select2(
cs.namespace(|| "final x: outer if"), cs.namespace(|| "final x: outer if"),
&other.x, &other.x,
&inner_x, &inner_x,
@@ -222,7 +244,7 @@ where
&y, &y,
&other.is_infinity, &other.is_infinity,
)?; )?;
let final_y = conditionally_select2( let y = conditionally_select2(
cs.namespace(|| "final y: outer if"), cs.namespace(|| "final y: outer if"),
&other.y, &other.y,
&inner_y, &inner_y,
@@ -236,15 +258,16 @@ where
&is_infinity, &is_infinity,
&other.is_infinity, &other.is_infinity,
)?; )?;
let final_is_infinity = conditionally_select2( let is_infinity = conditionally_select2(
cs.namespace(|| "final is infinity: outer if"), cs.namespace(|| "final is infinity: outer if"),
&other.is_infinity, &other.is_infinity,
&inner_is_infinity, &inner_is_infinity,
&self.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<CS: ConstraintSystem<Fp>>(&self, mut cs: CS) -> Result<Self, SynthesisError> { pub fn double<CS: ConstraintSystem<Fp>>(&self, mut cs: CS) -> Result<Self, SynthesisError> {
//*************************************************************/ //*************************************************************/
// lambda = (Fp::one() + Fp::one() + Fp::one()) // lambda = (Fp::one() + Fp::one() + Fp::one())
@@ -359,35 +382,24 @@ where
/*************************************************************/ /*************************************************************/
// x // 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 // 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 // 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<CS: ConstraintSystem<Fp>>( pub fn scalar_mul<CS: ConstraintSystem<Fp>>(
&self, &self,
mut cs: CS, mut cs: CS,
scalar: Vec<AllocatedBit>, scalar: Vec<AllocatedBit>,
) -> Result<Self, SynthesisError> { ) -> Result<Self, SynthesisError> {
/*************************************************************/ let mut res = Self::default(cs.namespace(|| "res"))?;
// 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);
for i in (0..scalar.len()).rev() { for i in (0..scalar.len()).rev() {
/*************************************************************/ /*************************************************************/
// res = res.double(); // res = res.double();
@@ -430,7 +442,7 @@ where
condition, condition,
)?; )?;
Ok(Self::new(x, y, is_infinity)) Ok(Self { x, y, is_infinity })
} }
} }

View File

@@ -1,3 +1,5 @@
//! This module implements various gadgets necessary for Nova
//! and applications built with Nova.
pub mod ecc; pub mod ecc;
pub mod r1cs; pub mod r1cs;
pub mod utils; pub mod utils;

View File

@@ -1,8 +1,9 @@
//! This module implements various gadgets necessary for folding R1CS types.
use crate::{ use crate::{
gadgets::{ gadgets::{
ecc::AllocatedPoint, ecc::AllocatedPoint,
utils::{ 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, conditionally_select_bignat, le_bits_to_num,
}, },
}, },
@@ -59,6 +60,7 @@ where
Ok(AllocatedR1CSInstance { W, X0, X1 }) Ok(AllocatedR1CSInstance { W, X0, X1 })
} }
/// Absorb the provided instance in the RO
pub fn absorb_in_ro(&self, ro: &mut PoseidonROGadget<G::Base>) { pub fn absorb_in_ro(&self, ro: &mut PoseidonROGadget<G::Base>) {
ro.absorb(self.W.x.clone()); ro.absorb(self.W.x.clone());
ro.absorb(self.W.y.clone()); ro.absorb(self.W.y.clone());
@@ -136,36 +138,29 @@ where
limb_width: usize, limb_width: usize,
n_limbs: usize, n_limbs: usize,
) -> Result<Self, SynthesisError> { ) -> Result<Self, SynthesisError> {
let zero = alloc_zero(cs.namespace(|| "zero"))?; let W = AllocatedPoint::default(cs.namespace(|| "allocate W"))?;
let one = alloc_one(cs.namespace(|| "one"))?; let E = W.clone();
let W_default = AllocatedPoint::new(zero.clone(), zero.clone(), one); let u = W.x.clone(); // In the default case, W.x = u = 0
let E_default = W_default.clone();
let u_default = zero; let X0 = BigNat::alloc_from_nat(
let X0_default = BigNat::alloc_from_nat(
cs.namespace(|| "allocate x_default[0]"), cs.namespace(|| "allocate x_default[0]"),
|| Ok(f_to_nat(&G::Scalar::zero())), || Ok(f_to_nat(&G::Scalar::zero())),
limb_width, limb_width,
n_limbs, n_limbs,
)?; )?;
let X1_default = BigNat::alloc_from_nat( let X1 = BigNat::alloc_from_nat(
cs.namespace(|| "allocate x_default[1]"), cs.namespace(|| "allocate x_default[1]"),
|| Ok(f_to_nat(&G::Scalar::zero())), || Ok(f_to_nat(&G::Scalar::zero())),
limb_width, limb_width,
n_limbs, n_limbs,
)?; )?;
Ok(AllocatedRelaxedR1CSInstance {
W: W_default, Ok(AllocatedRelaxedR1CSInstance { W, E, u, X0, X1 })
E: E_default,
u: u_default,
X0: X0_default,
X1: X1_default,
})
} }
/// Absorb the provided instance in the RO
pub fn absorb_in_ro<CS: ConstraintSystem<<G as Group>::Base>>( pub fn absorb_in_ro<CS: ConstraintSystem<<G as Group>::Base>>(
&self, &self,
mut cs: CS, mut cs: CS,

View File

@@ -1,3 +1,4 @@
//! This module implements various low-level gadgets
use crate::traits::Group; use crate::traits::Group;
use bellperson::{ use bellperson::{
gadgets::{ gadgets::{

View File

@@ -8,7 +8,7 @@ mod commitments;
pub mod bellperson; pub mod bellperson;
mod circuit; mod circuit;
pub mod errors; pub mod errors;
mod gadgets; pub mod gadgets;
pub mod pasta; pub mod pasta;
mod poseidon; mod poseidon;
pub mod r1cs; pub mod r1cs;

View File

@@ -34,6 +34,7 @@ where
F: PrimeField, F: PrimeField,
{ {
/// Generate Poseidon constants for the arities that Nova uses /// Generate Poseidon constants for the arities that Nova uses
#[allow(clippy::new_without_default)]
pub fn new() -> Self { pub fn new() -> Self {
let constants8 = PoseidonConstants::<F, U8>::new_with_strength(Strength::Strengthened); let constants8 = PoseidonConstants::<F, U8>::new_with_strength(Strength::Strengthened);
let constants25 = PoseidonConstants::<F, U25>::new_with_strength(Strength::Strengthened); let constants25 = PoseidonConstants::<F, U25>::new_with_strength(Strength::Strengthened);