Browse Source

Prepare Zexe for recursion (#241)

Co-authored-by: Pratyush Mishra <pratyushmishra@berkeley.edu>
master
Weikeng Chen 4 years ago
committed by GitHub
parent
commit
61c70ed644
20 changed files with 1071 additions and 15 deletions
  1. +13
    -1
      crypto-primitives/src/nizk/constraints.rs
  2. +161
    -3
      crypto-primitives/src/nizk/gm17/constraints.rs
  3. +136
    -2
      crypto-primitives/src/nizk/groth16/constraints.rs
  4. +57
    -0
      r1cs-std/src/bits/boolean.rs
  5. +1
    -1
      r1cs-std/src/bits/uint32.rs
  6. +9
    -0
      r1cs-std/src/fields/fp/mod.rs
  7. +21
    -0
      r1cs-std/src/fields/fp12.rs
  8. +19
    -0
      r1cs-std/src/fields/fp2.rs
  9. +21
    -0
      r1cs-std/src/fields/fp3.rs
  10. +21
    -0
      r1cs-std/src/fields/fp4.rs
  11. +22
    -0
      r1cs-std/src/fields/fp6_2over3.rs
  12. +23
    -0
      r1cs-std/src/fields/fp6_3over2.rs
  13. +9
    -1
      r1cs-std/src/fields/mod.rs
  14. +86
    -2
      r1cs-std/src/groups/curves/short_weierstrass/bls12/mod.rs
  15. +204
    -0
      r1cs-std/src/groups/curves/short_weierstrass/mnt4/mod.rs
  16. +207
    -0
      r1cs-std/src/groups/curves/short_weierstrass/mnt6/mod.rs
  17. +27
    -0
      r1cs-std/src/groups/curves/short_weierstrass/mod.rs
  18. +25
    -2
      r1cs-std/src/groups/curves/twisted_edwards/mod.rs
  19. +1
    -1
      r1cs-std/src/lib.rs
  20. +8
    -2
      r1cs-std/src/pairing/mod.rs

+ 13
- 1
crypto-primitives/src/nizk/constraints.rs

@ -5,9 +5,9 @@ use r1cs_std::prelude::*;
use crate::nizk::NIZK; use crate::nizk::NIZK;
pub trait NIZKVerifierGadget<N: NIZK, ConstraintF: Field> { pub trait NIZKVerifierGadget<N: NIZK, ConstraintF: Field> {
type PreparedVerificationKeyGadget;
type VerificationKeyGadget: AllocGadget<N::VerificationParameters, ConstraintF> type VerificationKeyGadget: AllocGadget<N::VerificationParameters, ConstraintF>
+ ToBytesGadget<ConstraintF>; + ToBytesGadget<ConstraintF>;
type ProofGadget: AllocGadget<N::Proof, ConstraintF>; type ProofGadget: AllocGadget<N::Proof, ConstraintF>;
fn check_verify<'a, CS, I, T>( fn check_verify<'a, CS, I, T>(
@ -32,4 +32,16 @@ pub trait NIZKVerifierGadget {
CS: ConstraintSystem<ConstraintF>, CS: ConstraintSystem<ConstraintF>,
I: Iterator<Item = &'a T>, I: Iterator<Item = &'a T>,
T: 'a + ToBitsGadget<ConstraintF> + ?Sized; T: 'a + ToBitsGadget<ConstraintF> + ?Sized;
fn conditional_check_verify_prepared<'a, CS, I, T>(
cs: CS,
prepared_verification_key: &Self::PreparedVerificationKeyGadget,
input: I,
proof: &Self::ProofGadget,
condition: &Boolean,
) -> Result<(), SynthesisError>
where
CS: ConstraintSystem<ConstraintF>,
I: Iterator<Item = &'a T>,
T: 'a + ToBitsGadget<ConstraintF> + ?Sized;
} }

+ 161
- 3
crypto-primitives/src/nizk/gm17/constraints.rs

@ -7,7 +7,7 @@ use r1cs_core::{ConstraintSynthesizer, ConstraintSystem, SynthesisError};
use r1cs_std::prelude::*; use r1cs_std::prelude::*;
use core::{borrow::Borrow, marker::PhantomData}; use core::{borrow::Borrow, marker::PhantomData};
use gm17::{Proof, VerifyingKey};
use gm17::{PreparedVerifyingKey, Proof, VerifyingKey};
#[derive(Derivative)] #[derive(Derivative)]
#[derivative(Clone(bound = "P::G1Gadget: Clone, P::G2Gadget: Clone"))] #[derivative(Clone(bound = "P::G1Gadget: Clone, P::G2Gadget: Clone"))]
@ -105,6 +105,7 @@ where
V: ToConstraintField<PairingE::Fr>, V: ToConstraintField<PairingE::Fr>,
P: PairingGadget<PairingE, ConstraintF>, P: PairingGadget<PairingE, ConstraintF>,
{ {
type PreparedVerificationKeyGadget = PreparedVerifyingKeyGadget<PairingE, ConstraintF, P>;
type VerificationKeyGadget = VerifyingKeyGadget<PairingE, ConstraintF, P>; type VerificationKeyGadget = VerifyingKeyGadget<PairingE, ConstraintF, P>;
type ProofGadget = ProofGadget<PairingE, ConstraintF, P>; type ProofGadget = ProofGadget<PairingE, ConstraintF, P>;
@ -131,7 +132,7 @@ where
fn conditional_check_verify<'a, CS, I, T>( fn conditional_check_verify<'a, CS, I, T>(
mut cs: CS, mut cs: CS,
vk: &Self::VerificationKeyGadget, vk: &Self::VerificationKeyGadget,
mut public_inputs: I,
public_inputs: I,
proof: &Self::ProofGadget, proof: &Self::ProofGadget,
condition: &Boolean, condition: &Boolean,
) -> Result<(), SynthesisError> ) -> Result<(), SynthesisError>
@ -141,9 +142,24 @@ where
T: 'a + ToBitsGadget<ConstraintF> + ?Sized, T: 'a + ToBitsGadget<ConstraintF> + ?Sized,
{ {
let pvk = vk.prepare(&mut cs.ns(|| "Prepare vk"))?; let pvk = vk.prepare(&mut cs.ns(|| "Prepare vk"))?;
<Self as NIZKVerifierGadget<Gm17<PairingE, C, V>, ConstraintF>>::conditional_check_verify_prepared(cs, &pvk, public_inputs, proof, condition)
}
fn conditional_check_verify_prepared<'a, CS, I, T>(
mut cs: CS,
pvk: &Self::PreparedVerificationKeyGadget,
mut public_inputs: I,
proof: &Self::ProofGadget,
condition: &Boolean,
) -> Result<(), SynthesisError>
where
CS: ConstraintSystem<ConstraintF>,
I: Iterator<Item = &'a T>,
T: 'a + ToBitsGadget<ConstraintF> + ?Sized,
{
let pvk = pvk.clone();
// e(A*G^{alpha}, B*H^{beta}) = e(G^{alpha}, H^{beta}) * e(G^{psi}, H^{gamma}) * // e(A*G^{alpha}, B*H^{beta}) = e(G^{alpha}, H^{beta}) * e(G^{psi}, H^{gamma}) *
// e(C, H) where psi = \sum_{i=0}^l input_i pvk.query[i] // e(C, H) where psi = \sum_{i=0}^l input_i pvk.query[i]
let g_psi = { let g_psi = {
let mut cs = cs.ns(|| "Process input"); let mut cs = cs.ns(|| "Process input");
let mut g_psi = pvk.query[0].clone(); let mut g_psi = pvk.query[0].clone();
@ -216,6 +232,148 @@ where
} }
} }
impl<PairingE, ConstraintF, P> AllocGadget<PreparedVerifyingKey<PairingE>, ConstraintF>
for PreparedVerifyingKeyGadget<PairingE, ConstraintF, P>
where
PairingE: PairingEngine,
ConstraintF: Field,
P: PairingGadget<PairingE, ConstraintF>,
P::G1PreparedGadget: AllocGadget<PairingE::G1Prepared, ConstraintF>,
P::G2PreparedGadget: AllocGadget<PairingE::G2Prepared, ConstraintF>,
{
#[inline]
fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>(
mut cs: CS,
val: T,
) -> Result<Self, SynthesisError>
where
T: Borrow<PreparedVerifyingKey<PairingE>>,
{
let pvk = val.borrow().clone();
let g_alpha =
P::G1Gadget::alloc_constant(cs.ns(|| "g_alpha"), pvk.g_alpha.into_projective())?;
let h_beta = P::G2Gadget::alloc_constant(cs.ns(|| "h_beta"), pvk.h_beta.into_projective())?;
let g_alpha_pc =
P::G1PreparedGadget::alloc_constant(cs.ns(|| "g_alpha_pc"), pvk.g_alpha.into())?;
let h_beta_pc =
P::G2PreparedGadget::alloc_constant(cs.ns(|| "h_beta_pc"), pvk.h_beta.into())?;
let g_gamma_pc =
P::G1PreparedGadget::alloc_constant(cs.ns(|| "g_gamma_pc"), pvk.g_gamma_pc)?;
let h_gamma_pc =
P::G2PreparedGadget::alloc_constant(cs.ns(|| "h_gamma_pc"), pvk.h_gamma_pc)?;
let h_pc = P::G2PreparedGadget::alloc_constant(cs.ns(|| "h_pc"), pvk.h_pc)?;
let mut query = Vec::<P::G1Gadget>::new();
for (i, item) in pvk.query.iter().enumerate() {
query.push(P::G1Gadget::alloc_constant(
&mut cs.ns(|| format!("query_{}", i)),
item.borrow().into_projective(),
)?);
}
Ok(Self {
g_alpha,
h_beta,
g_alpha_pc,
h_beta_pc,
g_gamma_pc,
h_gamma_pc,
h_pc,
query,
})
}
#[inline]
fn alloc<FN, T, CS: ConstraintSystem<ConstraintF>>(
mut cs: CS,
value_gen: FN,
) -> Result<Self, SynthesisError>
where
FN: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<PreparedVerifyingKey<PairingE>>,
{
let pvk = value_gen()?.borrow().clone();
let g_alpha =
P::G1Gadget::alloc(cs.ns(|| "g_alpha"), || Ok(pvk.g_alpha.into_projective()))?;
let h_beta = P::G2Gadget::alloc(cs.ns(|| "h_beta"), || Ok(pvk.h_beta.into_projective()))?;
let g_alpha_pc =
P::G1PreparedGadget::alloc(cs.ns(|| "g_alpha_pc"), || Ok(pvk.g_alpha.into()))?;
let h_beta_pc =
P::G2PreparedGadget::alloc(cs.ns(|| "h_beta_pc"), || Ok(pvk.h_beta.into()))?;
let g_gamma_pc =
P::G1PreparedGadget::alloc(cs.ns(|| "g_gamma_pc"), || Ok(&pvk.g_gamma_pc))?;
let h_gamma_pc =
P::G2PreparedGadget::alloc(cs.ns(|| "h_gamma_pc"), || Ok(&pvk.h_gamma_pc))?;
let h_pc = P::G2PreparedGadget::alloc(cs.ns(|| "h_pc"), || Ok(&pvk.h_pc))?;
let mut query = Vec::<P::G1Gadget>::new();
for (i, item) in pvk.query.iter().enumerate() {
query.push(P::G1Gadget::alloc(
cs.ns(|| format!("query_{}", i)),
|| Ok(item.borrow().into_projective()),
)?);
}
Ok(Self {
g_alpha,
h_beta,
g_alpha_pc,
h_beta_pc,
g_gamma_pc,
h_gamma_pc,
h_pc,
query,
})
}
#[inline]
fn alloc_input<FN, T, CS: ConstraintSystem<ConstraintF>>(
mut cs: CS,
value_gen: FN,
) -> Result<Self, SynthesisError>
where
FN: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<PreparedVerifyingKey<PairingE>>,
{
let pvk = value_gen()?.borrow().clone();
let g_alpha =
P::G1Gadget::alloc_input(cs.ns(|| "g_alpha"), || Ok(pvk.g_alpha.into_projective()))?;
let h_beta =
P::G2Gadget::alloc_input(cs.ns(|| "h_beta"), || Ok(pvk.h_beta.into_projective()))?;
let g_alpha_pc =
P::G1PreparedGadget::alloc_input(cs.ns(|| "g_alpha_pc"), || Ok(pvk.g_alpha.into()))?;
let h_beta_pc =
P::G2PreparedGadget::alloc_input(cs.ns(|| "h_beta_pc"), || Ok(pvk.h_beta.into()))?;
let g_gamma_pc =
P::G1PreparedGadget::alloc_input(cs.ns(|| "g_gamma_pc"), || Ok(&pvk.g_gamma_pc))?;
let h_gamma_pc =
P::G2PreparedGadget::alloc_input(cs.ns(|| "h_gamma_pc"), || Ok(&pvk.h_gamma_pc))?;
let h_pc = P::G2PreparedGadget::alloc_input(cs.ns(|| "h_pc"), || Ok(&pvk.h_pc))?;
let mut query = Vec::<P::G1Gadget>::new();
for (i, item) in pvk.query.iter().enumerate() {
query.push(P::G1Gadget::alloc_input(
&mut cs.ns(|| format!("query_{}", i)),
|| Ok(item.borrow().into_projective()),
)?);
}
Ok(Self {
g_alpha,
h_beta,
g_alpha_pc,
h_beta_pc,
g_gamma_pc,
h_gamma_pc,
h_pc,
query,
})
}
}
impl<PairingE, ConstraintF, P> AllocGadget<VerifyingKey<PairingE>, ConstraintF> impl<PairingE, ConstraintF, P> AllocGadget<VerifyingKey<PairingE>, ConstraintF>
for VerifyingKeyGadget<PairingE, ConstraintF, P> for VerifyingKeyGadget<PairingE, ConstraintF, P>
where where

+ 136
- 2
crypto-primitives/src/nizk/groth16/constraints.rs

@ -7,7 +7,7 @@ use r1cs_core::{ConstraintSynthesizer, ConstraintSystem, SynthesisError};
use r1cs_std::prelude::*; use r1cs_std::prelude::*;
use core::{borrow::Borrow, marker::PhantomData}; use core::{borrow::Borrow, marker::PhantomData};
use groth16::{Proof, VerifyingKey};
use groth16::{PreparedVerifyingKey, Proof, VerifyingKey};
#[derive(Derivative)] #[derive(Derivative)]
#[derivative(Clone(bound = "P::G1Gadget: Clone, P::G2Gadget: Clone"))] #[derivative(Clone(bound = "P::G1Gadget: Clone, P::G2Gadget: Clone"))]
@ -106,6 +106,7 @@ where
V: ToConstraintField<PairingE::Fr>, V: ToConstraintField<PairingE::Fr>,
P: PairingGadget<PairingE, ConstraintF>, P: PairingGadget<PairingE, ConstraintF>,
{ {
type PreparedVerificationKeyGadget = PreparedVerifyingKeyGadget<PairingE, ConstraintF, P>;
type VerificationKeyGadget = VerifyingKeyGadget<PairingE, ConstraintF, P>; type VerificationKeyGadget = VerifyingKeyGadget<PairingE, ConstraintF, P>;
type ProofGadget = ProofGadget<PairingE, ConstraintF, P>; type ProofGadget = ProofGadget<PairingE, ConstraintF, P>;
@ -132,7 +133,7 @@ where
fn conditional_check_verify<'a, CS, I, T>( fn conditional_check_verify<'a, CS, I, T>(
mut cs: CS, mut cs: CS,
vk: &Self::VerificationKeyGadget, vk: &Self::VerificationKeyGadget,
mut public_inputs: I,
public_inputs: I,
proof: &Self::ProofGadget, proof: &Self::ProofGadget,
condition: &Boolean, condition: &Boolean,
) -> Result<(), SynthesisError> ) -> Result<(), SynthesisError>
@ -142,6 +143,22 @@ where
T: 'a + ToBitsGadget<ConstraintF> + ?Sized, T: 'a + ToBitsGadget<ConstraintF> + ?Sized,
{ {
let pvk = vk.prepare(&mut cs.ns(|| "Prepare vk"))?; let pvk = vk.prepare(&mut cs.ns(|| "Prepare vk"))?;
<Self as NIZKVerifierGadget<Groth16<PairingE, C, V>, ConstraintF>>::conditional_check_verify_prepared(cs, &pvk, public_inputs, proof, condition)
}
fn conditional_check_verify_prepared<'a, CS, I, T>(
mut cs: CS,
pvk: &Self::PreparedVerificationKeyGadget,
mut public_inputs: I,
proof: &Self::ProofGadget,
condition: &Boolean,
) -> Result<(), SynthesisError>
where
CS: ConstraintSystem<ConstraintF>,
I: Iterator<Item = &'a T>,
T: 'a + ToBitsGadget<ConstraintF> + ?Sized,
{
let pvk = pvk.clone();
let g_ic = { let g_ic = {
let mut cs = cs.ns(|| "Process input"); let mut cs = cs.ns(|| "Process input");
@ -187,6 +204,123 @@ where
} }
} }
impl<PairingE, ConstraintF, P> AllocGadget<PreparedVerifyingKey<PairingE>, ConstraintF>
for PreparedVerifyingKeyGadget<PairingE, ConstraintF, P>
where
PairingE: PairingEngine,
ConstraintF: Field,
P: PairingGadget<PairingE, ConstraintF>,
P::G2PreparedGadget: AllocGadget<PairingE::G2Prepared, ConstraintF>,
{
fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>(
mut cs: CS,
val: T,
) -> Result<Self, SynthesisError>
where
T: Borrow<PreparedVerifyingKey<PairingE>>,
{
let pvk = val.borrow().clone();
let alpha_g1_beta_g2 =
P::GTGadget::alloc_constant(cs.ns(|| "alpha_g1_beta_g2"), pvk.alpha_g1_beta_g2)?;
let gamma_g2_neg_pc =
P::G2PreparedGadget::alloc_constant(cs.ns(|| "gamma_g2_neg_pc"), pvk.gamma_g2_neg_pc)?;
let delta_g2_neg_pc =
P::G2PreparedGadget::alloc_constant(cs.ns(|| "delta_g2_neg_pc"), pvk.delta_g2_neg_pc)?;
let mut gamma_abc_g1 = Vec::<P::G1Gadget>::new();
for (i, item) in pvk.gamma_abc_g1.iter().enumerate() {
gamma_abc_g1.push(P::G1Gadget::alloc_constant(
cs.ns(|| format!("query_{}", i)),
item.borrow().into_projective(),
)?);
}
Ok(Self {
alpha_g1_beta_g2,
gamma_g2_neg_pc,
delta_g2_neg_pc,
gamma_abc_g1,
})
}
fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>(
mut cs: CS,
f: F,
) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<PreparedVerifyingKey<PairingE>>,
{
let pvk = f()?.borrow().clone();
let alpha_g1_beta_g2 =
P::GTGadget::alloc(cs.ns(|| "alpha_g1_beta_g2"), || Ok(pvk.alpha_g1_beta_g2))?;
let gamma_g2_neg_pc =
P::G2PreparedGadget::alloc(cs.ns(|| "gamma_g2_neg_pc"), || Ok(&pvk.gamma_g2_neg_pc))?;
let delta_g2_neg_pc =
P::G2PreparedGadget::alloc(cs.ns(|| "delta_g2_neg_pc"), || Ok(&pvk.delta_g2_neg_pc))?;
let mut gamma_abc_g1 = Vec::<P::G1Gadget>::new();
for (i, item) in pvk.gamma_abc_g1.iter().enumerate() {
gamma_abc_g1.push(P::G1Gadget::alloc(
cs.ns(|| format!("query_{}", i)),
|| Ok(item.borrow().into_projective()),
)?);
}
Ok(Self {
alpha_g1_beta_g2,
gamma_g2_neg_pc,
delta_g2_neg_pc,
gamma_abc_g1,
})
}
fn alloc_input<F, T, CS: ConstraintSystem<ConstraintF>>(
mut cs: CS,
f: F,
) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<PreparedVerifyingKey<PairingE>>,
{
let pvk = f()?.borrow().clone();
let alpha_g1_beta_g2 =
P::GTGadget::alloc_input(cs.ns(|| "alpha_g1_beta_g2"), || Ok(pvk.alpha_g1_beta_g2))?;
let gamma_g2_neg_pc =
P::G2PreparedGadget::alloc_input(cs.ns(|| "gamma_g2_neg_pc"), || {
Ok(&pvk.gamma_g2_neg_pc)
})?;
let delta_g2_neg_pc =
P::G2PreparedGadget::alloc_input(cs.ns(|| "delta_g2_neg_pc"), || {
Ok(&pvk.delta_g2_neg_pc)
})?;
let mut gamma_abc_g1 = Vec::<P::G1Gadget>::new();
for (i, item) in pvk.gamma_abc_g1.iter().enumerate() {
gamma_abc_g1.push(P::G1Gadget::alloc_input(
cs.ns(|| format!("query_{}", i)),
|| Ok(item.borrow().into_projective()),
)?);
}
Ok(Self {
alpha_g1_beta_g2,
gamma_g2_neg_pc,
delta_g2_neg_pc,
gamma_abc_g1,
})
}
}
impl<PairingE, ConstraintF, P> AllocGadget<VerifyingKey<PairingE>, ConstraintF> impl<PairingE, ConstraintF, P> AllocGadget<VerifyingKey<PairingE>, ConstraintF>
for VerifyingKeyGadget<PairingE, ConstraintF, P> for VerifyingKeyGadget<PairingE, ConstraintF, P>
where where

+ 57
- 0
r1cs-std/src/bits/boolean.rs

@ -852,6 +852,63 @@ impl ToBytesGadget 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 { impl<ConstraintF: PrimeField> CondSelectGadget<ConstraintF> for Boolean {
fn conditionally_select<CS>( fn conditionally_select<CS>(
mut cs: CS, mut cs: CS,

+ 1
- 1
r1cs-std/src/bits/uint32.rs

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

+ 9
- 0
r1cs-std/src/fields/fp/mod.rs

@ -40,6 +40,15 @@ impl FpGadget {
} }
} }
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> { impl<F: PrimeField> FieldGadget<F, F> for FpGadget<F> {
type Variable = ConstraintVar<F>; type Variable = ConstraintVar<F>;

+ 21
- 0
r1cs-std/src/fields/fp12.rs

@ -37,6 +37,27 @@ where
_params: PhantomData<P>, _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> impl<P, ConstraintF: PrimeField> Fp12Gadget<P, ConstraintF>
where where
P: Fp12Parameters, P: Fp12Parameters,

+ 19
- 0
r1cs-std/src/fields/fp2.rs

@ -17,6 +17,25 @@ pub struct Fp2Gadget, ConstraintF: PrimeField
_params: PhantomData<P>, _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> { impl<P: Fp2Parameters<Fp = ConstraintF>, ConstraintF: PrimeField> Fp2Gadget<P, ConstraintF> {
pub fn new(c0: FpGadget<ConstraintF>, c1: FpGadget<ConstraintF>) -> Self { pub fn new(c0: FpGadget<ConstraintF>, c1: FpGadget<ConstraintF>) -> Self {
Self { Self {

+ 21
- 0
r1cs-std/src/fields/fp3.rs

@ -21,6 +21,27 @@ pub struct Fp3Gadget, ConstraintF: PrimeField
_params: PhantomData<P>, _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> impl<P: Fp3Parameters<Fp = ConstraintF>, ConstraintF: PrimeField + SquareRootField>
Fp3Gadget<P, ConstraintF> Fp3Gadget<P, ConstraintF>
{ {

+ 21
- 0
r1cs-std/src/fields/fp4.rs

@ -28,6 +28,27 @@ where
_params: PhantomData<P>, _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> impl<P, ConstraintF: PrimeField> Fp4Gadget<P, ConstraintF>
where where
P: Fp4Parameters, P: Fp4Parameters,

+ 22
- 0
r1cs-std/src/fields/fp6_2over3.rs

@ -31,6 +31,28 @@ where
_params: PhantomData<P>, _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> impl<P, ConstraintF: PrimeField + SquareRootField> Fp6Gadget<P, ConstraintF>
where where
P: Fp6Parameters, P: Fp6Parameters,

+ 23
- 0
r1cs-std/src/fields/fp6_3over2.rs

@ -28,6 +28,29 @@ where
_params: PhantomData<P>, _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> impl<P, ConstraintF: PrimeField> Fp6Gadget<P, ConstraintF>
where where
P: Fp6Parameters, P: Fp6Parameters,

+ 9
- 1
r1cs-std/src/fields/mod.rs

@ -1,4 +1,4 @@
use algebra::{fields::BitIterator, Field};
use algebra::{fields::BitIterator, Field, PrimeField, Vec};
use core::fmt::Debug; use core::fmt::Debug;
use r1cs_core::{ConstraintSystem, SynthesisError}; use r1cs_core::{ConstraintSystem, SynthesisError};
@ -12,6 +12,14 @@ pub mod fp4;
pub mod fp6_2over3; pub mod fp6_2over3;
pub mod fp6_3over2; 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>: pub trait FieldGadget<F: Field, ConstraintF: Field>:
Sized Sized
+ Clone + Clone

+ 86
- 2
r1cs-std/src/groups/curves/short_weierstrass/bls12/mod.rs

@ -1,5 +1,5 @@
use algebra::{ use algebra::{
curves::bls12::{Bls12Parameters, G1Prepared, TwistType},
curves::bls12::{Bls12Parameters, G1Prepared, G2Prepared, TwistType},
fields::Field, fields::Field,
BitIterator, One, ProjectiveCurve, BitIterator, One, ProjectiveCurve,
}; };
@ -12,7 +12,7 @@ use crate::{
Vec, Vec,
}; };
use core::fmt::Debug;
use core::{borrow::Borrow, fmt::Debug, ops::Mul};
pub type G1Gadget<P> = AffineGadget< pub type G1Gadget<P> = AffineGadget<
<P as Bls12Parameters>::G1Parameters, <P as Bls12Parameters>::G1Parameters,
@ -30,6 +30,42 @@ pub type G2Gadget

=

)] )]
pub struct G1PreparedGadget<P: Bls12Parameters>(pub G1Gadget<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> { impl<P: Bls12Parameters> G1PreparedGadget<P> {
pub fn get_value(&self) -> Option<G1Prepared<P>> { pub fn get_value(&self) -> Option<G1Prepared<P>> {
Some(G1Prepared::from(self.0.get_value().unwrap().into_affine())) Some(G1Prepared::from(self.0.get_value().unwrap().into_affine()))
@ -72,6 +108,54 @@ pub struct G2PreparedGadget {
pub ell_coeffs: Vec<LCoeff<P>>, 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> { impl<P: Bls12Parameters> ToBytesGadget<P::Fp> for G2PreparedGadget<P> {
#[inline] #[inline]
fn to_bytes<CS: ConstraintSystem<P::Fp>>( fn to_bytes<CS: ConstraintSystem<P::Fp>>(

+ 204
- 0
r1cs-std/src/groups/curves/short_weierstrass/mnt4/mod.rs

@ -14,6 +14,7 @@ use crate::{
prelude::*, prelude::*,
Vec, Vec,
}; };
use core::borrow::Borrow;
pub type G1Gadget<P> = AffineGadget< pub type G1Gadget<P> = AffineGadget<
<P as MNT4Parameters>::G1Parameters, <P as MNT4Parameters>::G1Parameters,
@ -72,6 +73,53 @@ impl G1PreparedGadget

{

} }
} }
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> { impl<P: MNT4Parameters> ToBytesGadget<P::Fp> for G1PreparedGadget<P> {
#[inline] #[inline]
fn to_bytes<CS: ConstraintSystem<P::Fp>>( fn to_bytes<CS: ConstraintSystem<P::Fp>>(
@ -121,6 +169,70 @@ pub struct G2PreparedGadget {
pub addition_coefficients: Vec<AteAdditionCoefficientsGadget<P>>, 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> { impl<P: MNT4Parameters> ToBytesGadget<P::Fp> for G2PreparedGadget<P> {
#[inline] #[inline]
fn to_bytes<CS: ConstraintSystem<P::Fp>>( fn to_bytes<CS: ConstraintSystem<P::Fp>>(
@ -308,6 +420,56 @@ pub struct AteDoubleCoefficientsGadget {
pub c_l: Fp2Gadget<P::Fp2Params, P::Fp>, 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> { impl<P: MNT4Parameters> ToBytesGadget<P::Fp> for AteDoubleCoefficientsGadget<P> {
#[inline] #[inline]
fn to_bytes<CS: ConstraintSystem<P::Fp>>( fn to_bytes<CS: ConstraintSystem<P::Fp>>(
@ -375,6 +537,48 @@ pub struct AteAdditionCoefficientsGadget {
pub c_rz: Fp2Gadget<P::Fp2Params, P::Fp>, 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> { impl<P: MNT4Parameters> ToBytesGadget<P::Fp> for AteAdditionCoefficientsGadget<P> {
#[inline] #[inline]
fn to_bytes<CS: ConstraintSystem<P::Fp>>( fn to_bytes<CS: ConstraintSystem<P::Fp>>(

+ 207
- 0
r1cs-std/src/groups/curves/short_weierstrass/mnt6/mod.rs

@ -5,6 +5,7 @@ use algebra::{
}, },
Field, Field,
}; };
use core::borrow::Borrow;
use r1cs_core::{ConstraintSystem, SynthesisError}; use r1cs_core::{ConstraintSystem, SynthesisError};
use crate::{ use crate::{
@ -33,6 +34,55 @@ pub struct G1PreparedGadget {
pub y_twist: Fp3Gadget<P::Fp3Params, P::Fp>, 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> { impl<P: MNT6Parameters> G1PreparedGadget<P> {
pub fn get_value(&self) -> Option<G1Prepared<P>> { pub fn get_value(&self) -> Option<G1Prepared<P>> {
match ( match (
@ -123,6 +173,76 @@ pub struct G2PreparedGadget {
pub addition_coefficients: Vec<AteAdditionCoefficientsGadget<P>>, 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> { impl<P: MNT6Parameters> ToBytesGadget<P::Fp> for G2PreparedGadget<P> {
#[inline] #[inline]
fn to_bytes<CS: ConstraintSystem<P::Fp>>( fn to_bytes<CS: ConstraintSystem<P::Fp>>(
@ -310,6 +430,55 @@ pub struct AteDoubleCoefficientsGadget {
pub c_l: Fp3Gadget<P::Fp3Params, P::Fp>, 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> { impl<P: MNT6Parameters> ToBytesGadget<P::Fp> for AteDoubleCoefficientsGadget<P> {
#[inline] #[inline]
fn to_bytes<CS: ConstraintSystem<P::Fp>>( fn to_bytes<CS: ConstraintSystem<P::Fp>>(
@ -377,6 +546,44 @@ pub struct AteAdditionCoefficientsGadget {
pub c_rz: Fp3Gadget<P::Fp3Params, P::Fp>, 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> { impl<P: MNT6Parameters> ToBytesGadget<P::Fp> for AteAdditionCoefficientsGadget<P> {
#[inline] #[inline]
fn to_bytes<CS: ConstraintSystem<P::Fp>>( fn to_bytes<CS: ConstraintSystem<P::Fp>>(

+ 27
- 0
r1cs-std/src/groups/curves/short_weierstrass/mod.rs

@ -29,6 +29,33 @@ pub struct AffineGadget<
_engine: PhantomData<ConstraintF>, _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>> impl<P: SWModelParameters, ConstraintF: Field, F: FieldGadget<P::BaseField, ConstraintF>>
AffineGadget<P, ConstraintF, F> AffineGadget<P, ConstraintF, F>
{ {

+ 25
- 2
r1cs-std/src/groups/curves/twisted_edwards/mod.rs

@ -3,13 +3,14 @@ use algebra::{
twisted_edwards_extended::GroupAffine as TEAffine, MontgomeryModelParameters, twisted_edwards_extended::GroupAffine as TEAffine, MontgomeryModelParameters,
TEModelParameters, TEModelParameters,
}, },
BitIterator, Field, One, Zero,
BitIterator, Field, One, PrimeField, Zero,
}; };
use r1cs_core::{ConstraintSystem, SynthesisError}; use r1cs_core::{ConstraintSystem, SynthesisError};
use crate::{prelude::*, Vec}; use crate::{prelude::*, Vec};
use crate::fields::fp::FpGadget;
use core::{borrow::Borrow, marker::PhantomData}; use core::{borrow::Borrow, marker::PhantomData};
#[derive(Derivative)] #[derive(Derivative)]
@ -235,6 +236,28 @@ impl
} }
} }
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> impl<P, ConstraintF, F> PartialEq for AffineGadget<P, ConstraintF, F>
where where
P: TEModelParameters, P: TEModelParameters,
@ -1449,7 +1472,7 @@ where
boolean::AllocatedBit, groups::test::group_test, prelude::*, boolean::AllocatedBit, groups::test::group_test, prelude::*,
test_constraint_system::TestConstraintSystem, test_constraint_system::TestConstraintSystem,
}; };
use algebra::{test_rng, Group, PrimeField, UniformRand};
use algebra::{test_rng, Group, UniformRand};
use rand::Rng; use rand::Rng;
group_test::<ConstraintF, TEAffine<P>, GG>(); group_test::<ConstraintF, TEAffine<P>, GG>();

+ 1
- 1
r1cs-std/src/lib.rs

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

+ 8
- 2
r1cs-std/src/pairing/mod.rs

@ -10,8 +10,14 @@ pub mod mnt6;
pub trait PairingGadget<PairingE: PairingEngine, ConstraintF: Field> { pub trait PairingGadget<PairingE: PairingEngine, ConstraintF: Field> {
type G1Gadget: GroupGadget<PairingE::G1Projective, ConstraintF>; type G1Gadget: GroupGadget<PairingE::G1Projective, ConstraintF>;
type G2Gadget: GroupGadget<PairingE::G2Projective, 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; type GTGadget: FieldGadget<PairingE::Fqk, ConstraintF> + Clone;
fn miller_loop<CS: ConstraintSystem<ConstraintF>>( fn miller_loop<CS: ConstraintSystem<ConstraintF>>(

Loading…
Cancel
Save