Prepare Zexe for recursion (#241)

Co-authored-by: Pratyush Mishra <pratyushmishra@berkeley.edu>
This commit is contained in:
Weikeng Chen
2020-07-20 15:42:25 -07:00
committed by GitHub
parent 36305e7247
commit 61c70ed644
20 changed files with 1071 additions and 15 deletions

View File

@@ -852,6 +852,63 @@ impl<ConstraintF: Field> ToBytesGadget<ConstraintF> for Boolean {
}
}
impl<ConstraintF: PrimeField> ToConstraintFieldGadget<ConstraintF> for Boolean {
fn to_constraint_field<CS: ConstraintSystem<ConstraintF>>(
&self,
mut cs: CS,
) -> Result<Vec<FpGadget<ConstraintF>>, SynthesisError> {
let gadget = match self {
Boolean::Constant(cond) => {
if *cond {
FpGadget::one(&mut cs.ns(|| "one"))?
} else {
FpGadget::zero(&mut cs.ns(|| "zero"))?
}
}
Boolean::Is(allocated_bit) => {
let value = match self.get_value() {
None => None,
Some(bool) => {
if bool {
Some(ConstraintF::one())
} else {
Some(ConstraintF::zero())
}
}
};
FpGadget::<ConstraintF> {
value,
variable: ConstraintVar::Var(allocated_bit.get_variable()),
}
}
Boolean::Not(allocated_bit) => {
let value = match self.get_value() {
None => None,
Some(bool) => {
if bool {
Some(ConstraintF::zero())
} else {
Some(ConstraintF::one())
}
}
};
let mut lc = LinearCombination::<ConstraintF>::zero();
lc += (ConstraintF::one(), CS::one());
lc += (-ConstraintF::one(), allocated_bit.get_variable());
FpGadget::<ConstraintF> {
value,
variable: ConstraintVar::LC(lc),
}
}
};
Ok(vec![gadget])
}
}
impl<ConstraintF: PrimeField> CondSelectGadget<ConstraintF> for Boolean {
fn conditionally_select<CS>(
mut cs: CS,

View File

@@ -14,7 +14,7 @@ use crate::{
pub struct UInt32 {
// Least significant bit_gadget first
bits: Vec<Boolean>,
value: Option<u32>,
pub value: Option<u32>,
}
impl UInt32 {

View File

@@ -40,6 +40,15 @@ impl<F: PrimeField> FpGadget<F> {
}
}
impl<F: PrimeField> ToConstraintFieldGadget<F> for FpGadget<F> {
fn to_constraint_field<CS: ConstraintSystem<F>>(
&self,
_cs: CS,
) -> Result<Vec<FpGadget<F>>, SynthesisError> {
Ok(vec![self.clone()])
}
}
impl<F: PrimeField> FieldGadget<F, F> for FpGadget<F> {
type Variable = ConstraintVar<F>;

View File

@@ -37,6 +37,27 @@ where
_params: PhantomData<P>,
}
impl<P, ConstraintF: PrimeField> ToConstraintFieldGadget<ConstraintF> for Fp12Gadget<P, ConstraintF>
where
P: Fp12Parameters,
<P::Fp6Params as Fp6Parameters>::Fp2Params: Fp2Parameters<Fp = ConstraintF>,
{
fn to_constraint_field<CS: ConstraintSystem<ConstraintF>>(
&self,
mut cs: CS,
) -> Result<Vec<FpGadget<ConstraintF>>, SynthesisError> {
let mut res = Vec::new();
let mut c0_gadget = self.c0.to_constraint_field(&mut cs.ns(|| "c0"))?;
let mut c1_gadget = self.c1.to_constraint_field(&mut cs.ns(|| "c1"))?;
res.append(&mut c0_gadget);
res.append(&mut c1_gadget);
Ok(res)
}
}
impl<P, ConstraintF: PrimeField> Fp12Gadget<P, ConstraintF>
where
P: Fp12Parameters,

View File

@@ -17,6 +17,25 @@ pub struct Fp2Gadget<P: Fp2Parameters<Fp = ConstraintF>, ConstraintF: PrimeField
_params: PhantomData<P>,
}
impl<P: Fp2Parameters<Fp = ConstraintF>, ConstraintF: PrimeField>
ToConstraintFieldGadget<ConstraintF> for Fp2Gadget<P, ConstraintF>
{
fn to_constraint_field<CS: ConstraintSystem<ConstraintF>>(
&self,
mut cs: CS,
) -> Result<Vec<FpGadget<ConstraintF>>, SynthesisError> {
let mut res = Vec::new();
let mut c0_gadget = self.c0.to_constraint_field(&mut cs.ns(|| "c0"))?;
let mut c1_gadget = self.c1.to_constraint_field(&mut cs.ns(|| "c1"))?;
res.append(&mut c0_gadget);
res.append(&mut c1_gadget);
Ok(res)
}
}
impl<P: Fp2Parameters<Fp = ConstraintF>, ConstraintF: PrimeField> Fp2Gadget<P, ConstraintF> {
pub fn new(c0: FpGadget<ConstraintF>, c1: FpGadget<ConstraintF>) -> Self {
Self {

View File

@@ -21,6 +21,27 @@ pub struct Fp3Gadget<P: Fp3Parameters<Fp = ConstraintF>, ConstraintF: PrimeField
_params: PhantomData<P>,
}
impl<P: Fp3Parameters<Fp = ConstraintF>, ConstraintF: PrimeField + SquareRootField>
ToConstraintFieldGadget<ConstraintF> for Fp3Gadget<P, ConstraintF>
{
fn to_constraint_field<CS: ConstraintSystem<ConstraintF>>(
&self,
mut cs: CS,
) -> Result<Vec<FpGadget<ConstraintF>>, SynthesisError> {
let mut res = Vec::new();
let mut c0_gadget = self.c0.to_constraint_field(&mut cs.ns(|| "c0"))?;
let mut c1_gadget = self.c1.to_constraint_field(&mut cs.ns(|| "c1"))?;
let mut c2_gadget = self.c2.to_constraint_field(&mut cs.ns(|| "c2"))?;
res.append(&mut c0_gadget);
res.append(&mut c1_gadget);
res.append(&mut c2_gadget);
Ok(res)
}
}
impl<P: Fp3Parameters<Fp = ConstraintF>, ConstraintF: PrimeField + SquareRootField>
Fp3Gadget<P, ConstraintF>
{

View File

@@ -28,6 +28,27 @@ where
_params: PhantomData<P>,
}
impl<P, ConstraintF: PrimeField> ToConstraintFieldGadget<ConstraintF> for Fp4Gadget<P, ConstraintF>
where
P: Fp4Parameters,
P::Fp2Params: Fp2Parameters<Fp = ConstraintF>,
{
fn to_constraint_field<CS: ConstraintSystem<ConstraintF>>(
&self,
mut cs: CS,
) -> Result<Vec<FpGadget<ConstraintF>>, SynthesisError> {
let mut res = Vec::new();
let mut c0_gadget = self.c0.to_constraint_field(&mut cs.ns(|| "c0"))?;
let mut c1_gadget = self.c1.to_constraint_field(&mut cs.ns(|| "c1"))?;
res.append(&mut c0_gadget);
res.append(&mut c1_gadget);
Ok(res)
}
}
impl<P, ConstraintF: PrimeField> Fp4Gadget<P, ConstraintF>
where
P: Fp4Parameters,

View File

@@ -31,6 +31,28 @@ where
_params: PhantomData<P>,
}
impl<P, ConstraintF: PrimeField + SquareRootField> ToConstraintFieldGadget<ConstraintF>
for Fp6Gadget<P, ConstraintF>
where
P: Fp6Parameters,
P::Fp3Params: Fp3Parameters<Fp = ConstraintF>,
{
fn to_constraint_field<CS: ConstraintSystem<ConstraintF>>(
&self,
mut cs: CS,
) -> Result<Vec<FpGadget<ConstraintF>>, SynthesisError> {
let mut res = Vec::new();
let mut c0_gadget = self.c0.to_constraint_field(&mut cs.ns(|| "c0"))?;
let mut c1_gadget = self.c1.to_constraint_field(&mut cs.ns(|| "c1"))?;
res.append(&mut c0_gadget);
res.append(&mut c1_gadget);
Ok(res)
}
}
impl<P, ConstraintF: PrimeField + SquareRootField> Fp6Gadget<P, ConstraintF>
where
P: Fp6Parameters,

View File

@@ -28,6 +28,29 @@ where
_params: PhantomData<P>,
}
impl<P, ConstraintF: PrimeField> ToConstraintFieldGadget<ConstraintF> for Fp6Gadget<P, ConstraintF>
where
P: Fp6Parameters,
P::Fp2Params: Fp2Parameters<Fp = ConstraintF>,
{
fn to_constraint_field<CS: ConstraintSystem<ConstraintF>>(
&self,
mut cs: CS,
) -> Result<Vec<FpGadget<ConstraintF>>, SynthesisError> {
let mut res = Vec::new();
let mut c0_gadget = self.c0.to_constraint_field(&mut cs.ns(|| "c0"))?;
let mut c1_gadget = self.c1.to_constraint_field(&mut cs.ns(|| "c1"))?;
let mut c2_gadget = self.c2.to_constraint_field(&mut cs.ns(|| "c2"))?;
res.append(&mut c0_gadget);
res.append(&mut c1_gadget);
res.append(&mut c2_gadget);
Ok(res)
}
}
impl<P, ConstraintF: PrimeField> Fp6Gadget<P, ConstraintF>
where
P: Fp6Parameters,

View File

@@ -1,4 +1,4 @@
use algebra::{fields::BitIterator, Field};
use algebra::{fields::BitIterator, Field, PrimeField, Vec};
use core::fmt::Debug;
use r1cs_core::{ConstraintSystem, SynthesisError};
@@ -12,6 +12,14 @@ pub mod fp4;
pub mod fp6_2over3;
pub mod fp6_3over2;
use crate::fields::fp::FpGadget;
pub trait ToConstraintFieldGadget<ConstraintF: PrimeField> {
fn to_constraint_field<CS: ConstraintSystem<ConstraintF>>(
&self,
cs: CS,
) -> Result<Vec<FpGadget<ConstraintF>>, SynthesisError>;
}
pub trait FieldGadget<F: Field, ConstraintF: Field>:
Sized
+ Clone

View File

@@ -1,5 +1,5 @@
use algebra::{
curves::bls12::{Bls12Parameters, G1Prepared, TwistType},
curves::bls12::{Bls12Parameters, G1Prepared, G2Prepared, TwistType},
fields::Field,
BitIterator, One, ProjectiveCurve,
};
@@ -12,7 +12,7 @@ use crate::{
Vec,
};
use core::fmt::Debug;
use core::{borrow::Borrow, fmt::Debug, ops::Mul};
pub type G1Gadget<P> = AffineGadget<
<P as Bls12Parameters>::G1Parameters,
@@ -30,6 +30,42 @@ pub type G2Gadget<P> =
)]
pub struct G1PreparedGadget<P: Bls12Parameters>(pub G1Gadget<P>);
impl<P: Bls12Parameters> AllocGadget<G1Prepared<P>, P::Fp> for G1PreparedGadget<P> {
fn alloc_constant<T, CS: ConstraintSystem<P::Fp>>(
mut cs: CS,
t: T,
) -> Result<Self, SynthesisError>
where
T: Borrow<G1Prepared<P>>,
{
let obj = t.borrow();
Ok(Self(G1Gadget::<P>::alloc_constant(
&mut cs.ns(|| "g1"),
&obj.0.into(),
)?))
}
fn alloc<F, T, CS: ConstraintSystem<P::Fp>>(_cs: CS, _f: F) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<G1Prepared<P>>,
{
todo!()
}
fn alloc_input<F, T, CS: ConstraintSystem<P::Fp>>(
_cs: CS,
_f: F,
) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<G1Prepared<P>>,
{
todo!()
}
}
impl<P: Bls12Parameters> G1PreparedGadget<P> {
pub fn get_value(&self) -> Option<G1Prepared<P>> {
Some(G1Prepared::from(self.0.get_value().unwrap().into_affine()))
@@ -72,6 +108,54 @@ pub struct G2PreparedGadget<P: Bls12Parameters> {
pub ell_coeffs: Vec<LCoeff<P>>,
}
impl<P: Bls12Parameters> AllocGadget<G2Prepared<P>, P::Fp> for G2PreparedGadget<P> {
fn alloc_constant<T, CS: ConstraintSystem<P::Fp>>(
mut cs: CS,
t: T,
) -> Result<Self, SynthesisError>
where
T: Borrow<G2Prepared<P>>,
{
let obj = t.borrow();
let mut res = Vec::<LCoeff<P>>::new();
for (i, (x, y, z)) in obj.ell_coeffs.iter().enumerate() {
let z_inverse = z.inverse().unwrap();
let x_normalized = x.mul(&z_inverse);
let y_normalized = y.mul(&z_inverse);
let x_gadget =
Fp2Gadget::alloc_constant(&mut cs.ns(|| format!("alloc_x#{}", i)), x_normalized)?;
let y_gadget =
Fp2Gadget::alloc_constant(&mut cs.ns(|| format!("alloc_y#{}", i)), y_normalized)?;
res.push((x_gadget, y_gadget));
}
Ok(Self { ell_coeffs: res })
}
fn alloc<F, T, CS: ConstraintSystem<P::Fp>>(_cs: CS, _f: F) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<G2Prepared<P>>,
{
todo!()
}
fn alloc_input<F, T, CS: ConstraintSystem<P::Fp>>(
_cs: CS,
_f: F,
) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<G2Prepared<P>>,
{
todo!()
}
}
impl<P: Bls12Parameters> ToBytesGadget<P::Fp> for G2PreparedGadget<P> {
#[inline]
fn to_bytes<CS: ConstraintSystem<P::Fp>>(

View File

@@ -14,6 +14,7 @@ use crate::{
prelude::*,
Vec,
};
use core::borrow::Borrow;
pub type G1Gadget<P> = AffineGadget<
<P as MNT4Parameters>::G1Parameters,
@@ -72,6 +73,53 @@ impl<P: MNT4Parameters> G1PreparedGadget<P> {
}
}
impl<P: MNT4Parameters> AllocGadget<G1Prepared<P>, P::Fp> for G1PreparedGadget<P> {
fn alloc_constant<T, CS: ConstraintSystem<P::Fp>>(
mut cs: CS,
t: T,
) -> Result<Self, SynthesisError>
where
T: Borrow<G1Prepared<P>>,
{
let obj = t.borrow();
let x = FpGadget::<P::Fp>::alloc_constant(&mut cs.ns(|| "alloc_x"), &obj.x)?;
let y = FpGadget::<P::Fp>::alloc_constant(&mut cs.ns(|| "alloc_y"), &obj.y)?;
let x_twist = Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(
&mut cs.ns(|| "alloc_x_twist"),
&obj.x_twist,
)?;
let y_twist = Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(
&mut cs.ns(|| "alloc_y_twist"),
&obj.y_twist,
)?;
Ok(G1PreparedGadget {
x,
y,
x_twist,
y_twist,
})
}
fn alloc<F, T, CS: ConstraintSystem<P::Fp>>(_cs: CS, _f: F) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<G1Prepared<P>>,
{
todo!()
}
fn alloc_input<F, T, CS: ConstraintSystem<P::Fp>>(
_cs: CS,
_f: F,
) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<G1Prepared<P>>,
{
todo!()
}
}
impl<P: MNT4Parameters> ToBytesGadget<P::Fp> for G1PreparedGadget<P> {
#[inline]
fn to_bytes<CS: ConstraintSystem<P::Fp>>(
@@ -121,6 +169,70 @@ pub struct G2PreparedGadget<P: MNT4Parameters> {
pub addition_coefficients: Vec<AteAdditionCoefficientsGadget<P>>,
}
impl<P: MNT4Parameters> AllocGadget<G2Prepared<P>, P::Fp> for G2PreparedGadget<P> {
fn alloc_constant<T, CS: ConstraintSystem<P::Fp>>(
mut cs: CS,
t: T,
) -> Result<Self, SynthesisError>
where
T: Borrow<G2Prepared<P>>,
{
let obj = t.borrow();
let x = Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(&mut cs.ns(|| "alloc_x"), &obj.x)?;
let y = Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(&mut cs.ns(|| "alloc_y"), &obj.y)?;
let x_over_twist = Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(
&mut cs.ns(|| "alloc_x_over_twist"),
&obj.x_over_twist,
)?;
let y_over_twist = Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(
&mut cs.ns(|| "alloc_y_over_twist"),
&obj.y_over_twist,
)?;
let mut double_coefficients = Vec::<AteDoubleCoefficientsGadget<P>>::new();
for (i, item) in obj.double_coefficients.iter().enumerate() {
double_coefficients.push(AteDoubleCoefficientsGadget::<P>::alloc_constant(
&mut cs.ns(|| format!("alloc_double_coefficients_{}", i)),
item,
)?);
}
let mut addition_coefficients = Vec::<AteAdditionCoefficientsGadget<P>>::new();
for (i, item) in obj.addition_coefficients.iter().enumerate() {
addition_coefficients.push(AteAdditionCoefficientsGadget::<P>::alloc_constant(
&mut cs.ns(|| format!("alloc_addition_coefficients_{}", i)),
item,
)?);
}
Ok(G2PreparedGadget {
x,
y,
x_over_twist,
y_over_twist,
double_coefficients,
addition_coefficients,
})
}
fn alloc<F, T, CS: ConstraintSystem<P::Fp>>(_cs: CS, _f: F) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<G2Prepared<P>>,
{
todo!()
}
fn alloc_input<F, T, CS: ConstraintSystem<P::Fp>>(
_cs: CS,
_f: F,
) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<G2Prepared<P>>,
{
todo!()
}
}
impl<P: MNT4Parameters> ToBytesGadget<P::Fp> for G2PreparedGadget<P> {
#[inline]
fn to_bytes<CS: ConstraintSystem<P::Fp>>(
@@ -308,6 +420,56 @@ pub struct AteDoubleCoefficientsGadget<P: MNT4Parameters> {
pub c_l: Fp2Gadget<P::Fp2Params, P::Fp>,
}
impl<P: MNT4Parameters> AllocGadget<AteDoubleCoefficients<P>, P::Fp>
for AteDoubleCoefficientsGadget<P>
{
fn alloc_constant<T, CS: ConstraintSystem<P::Fp>>(
mut cs: CS,
t: T,
) -> Result<Self, SynthesisError>
where
T: Borrow<AteDoubleCoefficients<P>>,
{
let obj = t.borrow();
let c_h =
Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(&mut cs.ns(|| "alloc_c_h"), &obj.c_h)?;
let c_4c = Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(
&mut cs.ns(|| "alloc_c_4c"),
&obj.c_4c,
)?;
let c_j =
Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(&mut cs.ns(|| "alloc_c_j"), &obj.c_j)?;
let c_l =
Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(&mut cs.ns(|| "alloc_c_l"), &obj.c_l)?;
Ok(AteDoubleCoefficientsGadget {
c_h,
c_4c,
c_j,
c_l,
})
}
fn alloc<F, T, CS: ConstraintSystem<P::Fp>>(_cs: CS, _f: F) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<AteDoubleCoefficients<P>>,
{
todo!()
}
fn alloc_input<F, T, CS: ConstraintSystem<P::Fp>>(
_cs: CS,
_f: F,
) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<AteDoubleCoefficients<P>>,
{
todo!()
}
}
impl<P: MNT4Parameters> ToBytesGadget<P::Fp> for AteDoubleCoefficientsGadget<P> {
#[inline]
fn to_bytes<CS: ConstraintSystem<P::Fp>>(
@@ -375,6 +537,48 @@ pub struct AteAdditionCoefficientsGadget<P: MNT4Parameters> {
pub c_rz: Fp2Gadget<P::Fp2Params, P::Fp>,
}
impl<P: MNT4Parameters> AllocGadget<AteAdditionCoefficients<P>, P::Fp>
for AteAdditionCoefficientsGadget<P>
{
fn alloc_constant<T, CS: ConstraintSystem<P::Fp>>(
mut cs: CS,
t: T,
) -> Result<Self, SynthesisError>
where
T: Borrow<AteAdditionCoefficients<P>>,
{
let obj = t.borrow();
let c_l1 = Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(
&mut cs.ns(|| "alloc_c_l1"),
&obj.c_l1,
)?;
let c_rz = Fp2Gadget::<P::Fp2Params, P::Fp>::alloc_constant(
&mut cs.ns(|| "alloc_c_rz"),
&obj.c_rz,
)?;
Ok(AteAdditionCoefficientsGadget { c_l1, c_rz })
}
fn alloc<F, T, CS: ConstraintSystem<P::Fp>>(_cs: CS, _f: F) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<AteAdditionCoefficients<P>>,
{
todo!()
}
fn alloc_input<F, T, CS: ConstraintSystem<P::Fp>>(
_cs: CS,
_f: F,
) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<AteAdditionCoefficients<P>>,
{
todo!()
}
}
impl<P: MNT4Parameters> ToBytesGadget<P::Fp> for AteAdditionCoefficientsGadget<P> {
#[inline]
fn to_bytes<CS: ConstraintSystem<P::Fp>>(

View File

@@ -5,6 +5,7 @@ use algebra::{
},
Field,
};
use core::borrow::Borrow;
use r1cs_core::{ConstraintSystem, SynthesisError};
use crate::{
@@ -33,6 +34,55 @@ pub struct G1PreparedGadget<P: MNT6Parameters> {
pub y_twist: Fp3Gadget<P::Fp3Params, P::Fp>,
}
impl<P: MNT6Parameters> AllocGadget<G1Prepared<P>, P::Fp> for G1PreparedGadget<P> {
fn alloc_constant<T, CS: ConstraintSystem<P::Fp>>(
mut cs: CS,
t: T,
) -> Result<Self, SynthesisError>
where
T: Borrow<G1Prepared<P>>,
{
let obj = t.borrow();
let x_gadget = FpGadget::<P::Fp>::alloc_constant(&mut cs.ns(|| "x"), &obj.x)?;
let y_gadget = FpGadget::<P::Fp>::alloc_constant(&mut cs.ns(|| "y"), &obj.y)?;
let x_twist_gadget = Fp3Gadget::<P::Fp3Params, P::Fp>::alloc_constant(
&mut cs.ns(|| "x_twist"),
&obj.x_twist,
)?;
let y_twist_gadget = Fp3Gadget::<P::Fp3Params, P::Fp>::alloc_constant(
&mut cs.ns(|| "y_twist"),
&obj.y_twist,
)?;
Ok(Self {
x: x_gadget,
y: y_gadget,
x_twist: x_twist_gadget,
y_twist: y_twist_gadget,
})
}
fn alloc<F, T, CS: ConstraintSystem<P::Fp>>(_cs: CS, _f: F) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<G1Prepared<P>>,
{
todo!()
}
fn alloc_input<F, T, CS: ConstraintSystem<P::Fp>>(
_cs: CS,
_f: F,
) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<G1Prepared<P>>,
{
todo!()
}
}
impl<P: MNT6Parameters> G1PreparedGadget<P> {
pub fn get_value(&self) -> Option<G1Prepared<P>> {
match (
@@ -123,6 +173,76 @@ pub struct G2PreparedGadget<P: MNT6Parameters> {
pub addition_coefficients: Vec<AteAdditionCoefficientsGadget<P>>,
}
impl<P: MNT6Parameters> AllocGadget<G2Prepared<P>, P::Fp> for G2PreparedGadget<P> {
fn alloc_constant<T, CS: ConstraintSystem<P::Fp>>(
mut cs: CS,
t: T,
) -> Result<Self, SynthesisError>
where
T: Borrow<G2Prepared<P>>,
{
let obj = t.borrow();
let x_gadget =
Fp3Gadget::<P::Fp3Params, P::Fp>::alloc_constant(&mut cs.ns(|| "x"), &obj.x)?;
let y_gadget =
Fp3Gadget::<P::Fp3Params, P::Fp>::alloc_constant(&mut cs.ns(|| "y"), &obj.y)?;
let x_over_twist_gadget = Fp3Gadget::<P::Fp3Params, P::Fp>::alloc_constant(
&mut cs.ns(|| "x_over_twist"),
&obj.x_over_twist,
)?;
let y_over_twist_gadget = Fp3Gadget::<P::Fp3Params, P::Fp>::alloc_constant(
&mut cs.ns(|| "y_over_twist"),
&obj.y_over_twist,
)?;
let mut double_coefficients_gadget = Vec::<AteDoubleCoefficientsGadget<P>>::new();
for (i, double_coefficient) in obj.double_coefficients.iter().enumerate() {
double_coefficients_gadget.push(AteDoubleCoefficientsGadget::<P>::alloc_constant(
&mut cs.ns(|| format!("double_coefficient#{}", i)),
double_coefficient,
)?);
}
let mut addition_coefficients_gadget = Vec::<AteAdditionCoefficientsGadget<P>>::new();
for (i, addition_coefficient) in obj.addition_coefficients.iter().enumerate() {
addition_coefficients_gadget.push(AteAdditionCoefficientsGadget::<P>::alloc_constant(
&mut cs.ns(|| format!("addition_coefficient#{}", i)),
addition_coefficient,
)?);
}
Ok(Self {
x: x_gadget,
y: y_gadget,
x_over_twist: x_over_twist_gadget,
y_over_twist: y_over_twist_gadget,
double_coefficients: double_coefficients_gadget,
addition_coefficients: addition_coefficients_gadget,
})
}
fn alloc<F, T, CS: ConstraintSystem<P::Fp>>(_cs: CS, _f: F) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<G2Prepared<P>>,
{
todo!()
}
fn alloc_input<F, T, CS: ConstraintSystem<P::Fp>>(
_cs: CS,
_f: F,
) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<G2Prepared<P>>,
{
todo!()
}
}
impl<P: MNT6Parameters> ToBytesGadget<P::Fp> for G2PreparedGadget<P> {
#[inline]
fn to_bytes<CS: ConstraintSystem<P::Fp>>(
@@ -310,6 +430,55 @@ pub struct AteDoubleCoefficientsGadget<P: MNT6Parameters> {
pub c_l: Fp3Gadget<P::Fp3Params, P::Fp>,
}
impl<P: MNT6Parameters> AllocGadget<AteDoubleCoefficients<P>, P::Fp>
for AteDoubleCoefficientsGadget<P>
{
fn alloc_constant<T, CS: ConstraintSystem<P::Fp>>(
mut cs: CS,
t: T,
) -> Result<Self, SynthesisError>
where
T: Borrow<AteDoubleCoefficients<P>>,
{
let obj = t.borrow();
let c_h_gadget =
Fp3Gadget::<P::Fp3Params, P::Fp>::alloc_constant(&mut cs.ns(|| "c_h"), &obj.c_h)?;
let c_4c_gadget =
Fp3Gadget::<P::Fp3Params, P::Fp>::alloc_constant(&mut cs.ns(|| "c_4c"), &obj.c_4c)?;
let c_j_gadget =
Fp3Gadget::<P::Fp3Params, P::Fp>::alloc_constant(&mut cs.ns(|| "c_j"), &obj.c_j)?;
let c_l_gadget =
Fp3Gadget::<P::Fp3Params, P::Fp>::alloc_constant(&mut cs.ns(|| "c_l"), &obj.c_l)?;
Ok(Self {
c_h: c_h_gadget,
c_4c: c_4c_gadget,
c_j: c_j_gadget,
c_l: c_l_gadget,
})
}
fn alloc<F, T, CS: ConstraintSystem<P::Fp>>(_cs: CS, _f: F) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<AteDoubleCoefficients<P>>,
{
todo!()
}
fn alloc_input<F, T, CS: ConstraintSystem<P::Fp>>(
_cs: CS,
_f: F,
) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<AteDoubleCoefficients<P>>,
{
todo!()
}
}
impl<P: MNT6Parameters> ToBytesGadget<P::Fp> for AteDoubleCoefficientsGadget<P> {
#[inline]
fn to_bytes<CS: ConstraintSystem<P::Fp>>(
@@ -377,6 +546,44 @@ pub struct AteAdditionCoefficientsGadget<P: MNT6Parameters> {
pub c_rz: Fp3Gadget<P::Fp3Params, P::Fp>,
}
impl<P: MNT6Parameters> AllocGadget<AteAdditionCoefficients<P>, P::Fp>
for AteAdditionCoefficientsGadget<P>
{
fn alloc_constant<T, CS: ConstraintSystem<P::Fp>>(
mut cs: CS,
t: T,
) -> Result<Self, SynthesisError>
where
T: Borrow<AteAdditionCoefficients<P>>,
{
let t = t.borrow();
let c_l1 = Fp3Gadget::alloc_constant(&mut cs.ns(|| "c_l1"), &t.c_l1)?;
let c_rz = Fp3Gadget::alloc_constant(&mut cs.ns(|| "c_rz"), &t.c_rz)?;
Ok(Self { c_l1, c_rz })
}
fn alloc<F, T, CS: ConstraintSystem<P::Fp>>(_cs: CS, _f: F) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<AteAdditionCoefficients<P>>,
{
todo!()
}
fn alloc_input<F, T, CS: ConstraintSystem<P::Fp>>(
_cs: CS,
_f: F,
) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<AteAdditionCoefficients<P>>,
{
todo!()
}
}
impl<P: MNT6Parameters> ToBytesGadget<P::Fp> for AteAdditionCoefficientsGadget<P> {
#[inline]
fn to_bytes<CS: ConstraintSystem<P::Fp>>(

View File

@@ -29,6 +29,33 @@ pub struct AffineGadget<
_engine: PhantomData<ConstraintF>,
}
impl<
P: SWModelParameters,
ConstraintF: PrimeField,
F: FieldGadget<P::BaseField, ConstraintF> + ToConstraintFieldGadget<ConstraintF>,
> ToConstraintFieldGadget<ConstraintF> for AffineGadget<P, ConstraintF, F>
{
fn to_constraint_field<CS: ConstraintSystem<ConstraintF>>(
&self,
mut cs: CS,
) -> Result<Vec<FpGadget<ConstraintF>>, SynthesisError> {
let mut res = Vec::new();
let mut x_gadget = self.x.to_constraint_field(&mut cs.ns(|| "x"))?;
let mut y_gadget = self.y.to_constraint_field(&mut cs.ns(|| "y"))?;
let mut infinity_gadget = self
.infinity
.to_constraint_field(&mut cs.ns(|| "infinity"))?;
res.append(&mut x_gadget);
res.append(&mut y_gadget);
res.append(&mut infinity_gadget);
Ok(res)
}
}
impl<P: SWModelParameters, ConstraintF: Field, F: FieldGadget<P::BaseField, ConstraintF>>
AffineGadget<P, ConstraintF, F>
{

View File

@@ -3,13 +3,14 @@ use algebra::{
twisted_edwards_extended::GroupAffine as TEAffine, MontgomeryModelParameters,
TEModelParameters,
},
BitIterator, Field, One, Zero,
BitIterator, Field, One, PrimeField, Zero,
};
use r1cs_core::{ConstraintSystem, SynthesisError};
use crate::{prelude::*, Vec};
use crate::fields::fp::FpGadget;
use core::{borrow::Borrow, marker::PhantomData};
#[derive(Derivative)]
@@ -235,6 +236,28 @@ impl<P: TEModelParameters, ConstraintF: Field, F: FieldGadget<P::BaseField, Cons
}
}
impl<P, ConstraintF, F> ToConstraintFieldGadget<ConstraintF> for AffineGadget<P, ConstraintF, F>
where
P: TEModelParameters,
ConstraintF: PrimeField,
F: FieldGadget<P::BaseField, ConstraintF> + ToConstraintFieldGadget<ConstraintF>,
{
fn to_constraint_field<CS: ConstraintSystem<ConstraintF>>(
&self,
mut cs: CS,
) -> Result<Vec<FpGadget<ConstraintF>>, SynthesisError> {
let mut res = Vec::new();
let mut x_gadget = self.x.to_constraint_field(&mut cs.ns(|| "x"))?;
let mut y_gadget = self.y.to_constraint_field(&mut cs.ns(|| "y"))?;
res.append(&mut x_gadget);
res.append(&mut y_gadget);
Ok(res)
}
}
impl<P, ConstraintF, F> PartialEq for AffineGadget<P, ConstraintF, F>
where
P: TEModelParameters,
@@ -1449,7 +1472,7 @@ where
boolean::AllocatedBit, groups::test::group_test, prelude::*,
test_constraint_system::TestConstraintSystem,
};
use algebra::{test_rng, Group, PrimeField, UniformRand};
use algebra::{test_rng, Group, UniformRand};
use rand::Rng;
group_test::<ConstraintF, TEAffine<P>, GG>();

View File

@@ -89,7 +89,7 @@ pub mod prelude {
alloc::*,
bits::{boolean::Boolean, uint32::UInt32, uint8::UInt8, ToBitsGadget, ToBytesGadget},
eq::*,
fields::FieldGadget,
fields::{fp::FpGadget, FieldGadget, ToConstraintFieldGadget},
groups::GroupGadget,
instantiated::*,
pairing::PairingGadget,

View File

@@ -10,8 +10,14 @@ pub mod mnt6;
pub trait PairingGadget<PairingE: PairingEngine, ConstraintF: Field> {
type G1Gadget: GroupGadget<PairingE::G1Projective, ConstraintF>;
type G2Gadget: GroupGadget<PairingE::G2Projective, ConstraintF>;
type G1PreparedGadget: ToBytesGadget<ConstraintF> + Clone + Debug;
type G2PreparedGadget: ToBytesGadget<ConstraintF> + Clone + Debug;
type G1PreparedGadget: AllocGadget<PairingE::G1Prepared, ConstraintF>
+ ToBytesGadget<ConstraintF>
+ Clone
+ Debug;
type G2PreparedGadget: AllocGadget<PairingE::G2Prepared, ConstraintF>
+ ToBytesGadget<ConstraintF>
+ Clone
+ Debug;
type GTGadget: FieldGadget<PairingE::Fqk, ConstraintF> + Clone;
fn miller_loop<CS: ConstraintSystem<ConstraintF>>(