Browse Source

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

* make gadgets public, expose coords, cleanup

* fix clippy
main
Srinath Setty 2 years ago
committed by GitHub
parent
commit
751b3434ec
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 56 additions and 45 deletions
  1. +40
    -28
      src/gadgets/ecc.rs
  2. +2
    -0
      src/gadgets/mod.rs
  3. +11
    -16
      src/gadgets/r1cs.rs
  4. +1
    -0
      src/gadgets/utils.rs
  5. +1
    -1
      src/lib.rs
  6. +1
    -0
      src/poseidon.rs

+ 40
- 28
src/gadgets/ecc.rs

@ -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 AllocatedPoint
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.
pub fn new(x: AllocatedNum<Fp>, y: AllocatedNum<Fp>, is_infinity: AllocatedNum<Fp>) -> Self {
Self { x, y, is_infinity }
/// Allocates a default point on the curve.
pub fn default<CS>(mut cs: CS) -> Result<Self, SynthesisError>
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
// 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<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> {
/*************************************************************/
// 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() { 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 })
} }
} }

+ 2
- 0
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 ecc;
pub mod r1cs; pub mod r1cs;
pub mod utils; pub mod utils;

+ 11
- 16
src/gadgets/r1cs.rs

@ -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 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]"), 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,
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<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,

+ 1
- 0
src/gadgets/utils.rs

@ -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::{

+ 1
- 1
src/lib.rs

@ -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;

+ 1
- 0
src/poseidon.rs

@ -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);

Loading…
Cancel
Save