mirror of
https://github.com/arnaucube/ark-r1cs-std.git
synced 2026-01-11 08:21:30 +01:00
Prepare Zexe for recursion (#241)
Co-authored-by: Pratyush Mishra <pratyushmishra@berkeley.edu>
This commit is contained in:
@@ -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<N: NIZK, ConstraintF: Field> {
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
impl<ConstraintF: PrimeField> CondSelectGadget<ConstraintF> for Boolean {
|
||||||
fn conditionally_select<CS>(
|
fn conditionally_select<CS>(
|
||||||
mut cs: CS,
|
mut cs: CS,
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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> {
|
impl<F: PrimeField> FieldGadget<F, F> for FpGadget<F> {
|
||||||
type Variable = ConstraintVar<F>;
|
type Variable = ConstraintVar<F>;
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -17,6 +17,25 @@ pub struct Fp2Gadget<P: Fp2Parameters<Fp = ConstraintF>, 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,6 +21,27 @@ pub struct Fp3Gadget<P: Fp3Parameters<Fp = ConstraintF>, 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>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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<P> =
|
|||||||
)]
|
)]
|
||||||
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<P: Bls12Parameters> {
|
|||||||
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>>(
|
||||||
|
|||||||
@@ -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<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> {
|
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<P: MNT4Parameters> {
|
|||||||
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<P: MNT4Parameters> {
|
|||||||
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<P: MNT4Parameters> {
|
|||||||
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>>(
|
||||||
|
|||||||
@@ -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<P: MNT6Parameters> {
|
|||||||
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<P: MNT6Parameters> {
|
|||||||
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<P: MNT6Parameters> {
|
|||||||
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<P: MNT6Parameters> {
|
|||||||
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>>(
|
||||||
|
|||||||
@@ -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>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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<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>
|
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>();
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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 G1PreparedGadget: AllocGadget<PairingE::G1Prepared, ConstraintF>
|
||||||
type G2PreparedGadget: ToBytesGadget<ConstraintF> + Clone + Debug;
|
+ 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>>(
|
||||||
|
|||||||
Reference in New Issue
Block a user