mirror of
https://github.com/arnaucube/Nova.git
synced 2026-01-11 08:31:29 +01:00
make gadgets public, expose coords, cleanup (#39)
* make gadgets public, expose coords, cleanup * fix clippy
This commit is contained in:
@@ -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 })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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::{
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user