Refactor algebra API, split into algebra and algebra-core. (#100)

This commit is contained in:
Pratyush Mishra
2020-02-26 21:42:04 -08:00
committed by GitHub
parent d4896ade47
commit 8bf042a029
68 changed files with 417 additions and 572 deletions

View File

@@ -29,7 +29,18 @@ derivative = { version = "1", features = ["use_core"] }
[dev-dependencies]
rand = { version = "0.7", default-features = false }
rand_xorshift = { version = "0.2" }
# Currently this means that all downstream users of `r1cs-std` will be using
# `algebra` with the `bls12_381` feature.
algebra = { path = "../algebra", default-features = false, features = [ "bls12_381" ] }
[features]
default = ["std"]
std = ["algebra/std", "r1cs-core/std"]
full = [ "bls12_377", "jubjub", "edwards_bls12", "edwards_sw6", ]
bls12_377 = [ "algebra/bls12_377" ]
jubjub = [ "algebra/jubjub" ]
edwards_bls12 = [ "algebra/edwards_bls12" ]
edwards_sw6 = [ "algebra/edwards_sw6" ]
std = [ "algebra/std" ]
parallel = [ "std", "algebra/parallel" ]

View File

@@ -834,7 +834,7 @@ impl<ConstraintF: PrimeField> CondSelectGadget<ConstraintF> for Boolean {
mod test {
use super::{AllocatedBit, Boolean};
use crate::{prelude::*, test_constraint_system::TestConstraintSystem};
use algebra::{fields::bls12_381::Fr, BitIterator, Field, One, PrimeField, UniformRand, Zero};
use algebra::{bls12_381::Fr, BitIterator, Field, One, PrimeField, UniformRand, Zero};
use core::str::FromStr;
use r1cs_core::ConstraintSystem;
use rand::SeedableRng;

View File

@@ -344,7 +344,7 @@ impl<ConstraintF: Field> ConditionalEqGadget<ConstraintF> for UInt32 {
mod test {
use super::UInt32;
use crate::{bits::boolean::Boolean, test_constraint_system::TestConstraintSystem, Vec};
use algebra::{fields::bls12_381::Fr, One, Zero};
use algebra::{bls12_381::Fr, One, Zero};
use r1cs_core::ConstraintSystem;
use rand::{Rng, SeedableRng};
use rand_xorshift::XorShiftRng;

View File

@@ -298,7 +298,7 @@ impl<ConstraintF: Field> AllocGadget<u8, ConstraintF> for UInt8 {
mod test {
use super::UInt8;
use crate::{prelude::*, test_constraint_system::TestConstraintSystem, Vec};
use algebra::fields::bls12_381::Fr;
use algebra::bls12_381::Fr;
use r1cs_core::ConstraintSystem;
use rand::{Rng, SeedableRng};
use rand_xorshift::XorShiftRng;

View File

@@ -1,8 +0,0 @@
use algebra::fields::bls12_377::{Fq, Fq12Parameters, Fq2Parameters, Fq6Parameters};
use super::{fp::FpGadget, fp12::Fp12Gadget, fp2::Fp2Gadget, fp6_3over2::Fp6Gadget};
pub type FqGadget = FpGadget<Fq>;
pub type Fq2Gadget = Fp2Gadget<Fq2Parameters, Fq>;
pub type Fq6Gadget = Fp6Gadget<Fq6Parameters, Fq>;
pub type Fq12Gadget = Fp12Gadget<Fq12Parameters, Fq>;

View File

@@ -1,4 +0,0 @@
use crate::fields::fp::FpGadget;
use algebra::fields::edwards_bls12::fq::Fq;
pub type FqGadget = FpGadget<Fq>;

View File

@@ -1,4 +0,0 @@
use crate::fields::fp::FpGadget;
use algebra::fields::edwards_sw6::fq::Fq;
pub type FqGadget = FpGadget<Fq>;

View File

@@ -1,6 +0,0 @@
use algebra::fields::jubjub::fq::Fq;
use crate::fields::fp::FpGadget;
// JubJub Fq uses BLS12-381 Fr.
pub type FqGadget = FpGadget<Fq>;

View File

@@ -9,11 +9,6 @@ pub mod fp12;
pub mod fp2;
pub mod fp6_3over2;
pub mod bls12_377;
pub mod edwards_bls12;
pub mod edwards_sw6;
pub mod jubjub;
pub trait FieldGadget<F: Field, ConstraintF: Field>:
Sized
+ Clone
@@ -235,7 +230,7 @@ pub trait FieldGadget<F: Field, ConstraintF: Field>:
}
#[cfg(test)]
mod test {
pub(crate) mod tests {
use rand::{self, SeedableRng};
use rand_xorshift::XorShiftRng;
@@ -243,18 +238,15 @@ mod test {
use algebra::{test_rng, BitIterator, Field, UniformRand};
use r1cs_core::ConstraintSystem;
fn field_test<
FE: Field,
ConstraintF: Field,
F: FieldGadget<FE, ConstraintF>,
CS: ConstraintSystem<ConstraintF>,
>(
mut cs: CS,
a: F,
b: F,
) {
let a_native = a.get_value().unwrap();
let b_native = b.get_value().unwrap();
#[allow(dead_code)]
pub(crate) fn field_test<FE: Field, ConstraintF: Field, F: FieldGadget<FE, ConstraintF>>() {
let mut cs = TestConstraintSystem::<ConstraintF>::new();
let mut rng = test_rng();
let a_native = FE::rand(&mut rng);
let b_native = FE::rand(&mut rng);
let a = F::alloc(&mut cs.ns(|| "generate_a"), || Ok(a_native)).unwrap();
let b = F::alloc(&mut cs.ns(|| "generate_b"), || Ok(b_native)).unwrap();
let zero = F::zero(cs.ns(|| "zero")).unwrap();
let zero_native = zero.get_value().unwrap();
@@ -447,17 +439,22 @@ mod test {
)
.unwrap();
assert_eq!(ab_true.get_value().unwrap(), a_native + &b_native);
if !cs.is_satisfied() {
println!("{:?}", cs.which_is_unsatisfied().unwrap());
}
assert!(cs.is_satisfied());
}
fn random_frobenius_tests<
#[allow(dead_code)]
pub(crate) fn frobenius_tests<
FE: Field,
ConstraintF: Field,
F: FieldGadget<FE, ConstraintF>,
CS: ConstraintSystem<ConstraintF>,
>(
mut cs: CS,
maxpower: usize,
) {
let mut cs = TestConstraintSystem::<ConstraintF>::new();
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
for i in 0..=maxpower {
let mut a = FE::rand(&mut rng);
@@ -469,87 +466,7 @@ mod test {
assert_eq!(a_gadget.get_value().unwrap(), a);
}
}
#[test]
fn bls12_377_field_gadgets_test() {
use crate::fields::bls12_377::{Fq12Gadget, Fq2Gadget, Fq6Gadget, FqGadget};
use algebra::fields::bls12_377::{Fq, Fq12, Fq2, Fq6};
let mut cs = TestConstraintSystem::<Fq>::new();
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
let a = FqGadget::alloc(&mut cs.ns(|| "generate_a"), || Ok(Fq::rand(&mut rng))).unwrap();
let b = FqGadget::alloc(&mut cs.ns(|| "generate_b"), || Ok(Fq::rand(&mut rng))).unwrap();
field_test(cs.ns(|| "test_fq"), a, b);
if !cs.is_satisfied() {
println!("{:?}", cs.which_is_unsatisfied().unwrap());
}
let c = Fq2Gadget::alloc(&mut cs.ns(|| "generate_c"), || Ok(Fq2::rand(&mut rng))).unwrap();
let d = Fq2Gadget::alloc(&mut cs.ns(|| "generate_d"), || Ok(Fq2::rand(&mut rng))).unwrap();
field_test(cs.ns(|| "test_fq2"), c, d);
random_frobenius_tests::<Fq2, _, Fq2Gadget, _>(cs.ns(|| "test_frob_fq2"), 13);
if !cs.is_satisfied() {
println!("{:?}", cs.which_is_unsatisfied().unwrap());
}
let a = Fq6Gadget::alloc(&mut cs.ns(|| "generate_e"), || Ok(Fq6::rand(&mut rng))).unwrap();
let b = Fq6Gadget::alloc(&mut cs.ns(|| "generate_f"), || Ok(Fq6::rand(&mut rng))).unwrap();
field_test(cs.ns(|| "test_fq6"), a, b);
random_frobenius_tests::<Fq6, _, Fq6Gadget, _>(cs.ns(|| "test_frob_fq6"), 13);
if !cs.is_satisfied() {
println!("{:?}", cs.which_is_unsatisfied().unwrap());
}
let c =
Fq12Gadget::alloc(&mut cs.ns(|| "generate_g"), || Ok(Fq12::rand(&mut rng))).unwrap();
let d =
Fq12Gadget::alloc(&mut cs.ns(|| "generate_h"), || Ok(Fq12::rand(&mut rng))).unwrap();
field_test(cs.ns(|| "test_fq12"), c, d);
random_frobenius_tests::<Fq12, _, Fq12Gadget, _>(cs.ns(|| "test_frob_fq12"), 13);
if !cs.is_satisfied() {
println!("Here!");
println!("{:?}", cs.which_is_unsatisfied().unwrap());
}
assert!(cs.is_satisfied());
}
#[test]
fn jubjub_field_gadgets_test() {
use crate::fields::jubjub::FqGadget;
use algebra::fields::jubjub::fq::Fq;
let mut cs = TestConstraintSystem::<Fq>::new();
let mut rng = test_rng();
let a = FqGadget::alloc(&mut cs.ns(|| "generate_a"), || Ok(Fq::rand(&mut rng))).unwrap();
let b = FqGadget::alloc(&mut cs.ns(|| "generate_b"), || Ok(Fq::rand(&mut rng))).unwrap();
field_test(cs.ns(|| "test_fq"), a, b);
if !cs.is_satisfied() {
println!("{:?}", cs.which_is_unsatisfied().unwrap());
}
assert!(cs.is_satisfied());
}
#[test]
fn edwards_field_gadgets_test() {
use crate::fields::edwards_bls12::FqGadget;
use algebra::fields::edwards_bls12::fq::Fq;
let mut cs = TestConstraintSystem::<Fq>::new();
let mut rng = test_rng();
let a = FqGadget::alloc(&mut cs.ns(|| "generate_a"), || Ok(Fq::rand(&mut rng))).unwrap();
let b = FqGadget::alloc(&mut cs.ns(|| "generate_b"), || Ok(Fq::rand(&mut rng))).unwrap();
field_test(cs.ns(|| "test_fq"), a, b);
if !cs.is_satisfied() {
println!("{:?}", cs.which_is_unsatisfied().unwrap());
}
assert!(cs.is_satisfied());
}
}

View File

@@ -14,13 +14,12 @@ use crate::{
use core::fmt::Debug;
pub mod bls12_377;
pub type G1Gadget<P> = AffineGadget<
<P as Bls12Parameters>::G1Parameters,
<P as Bls12Parameters>::Fp,
FpGadget<<P as Bls12Parameters>::Fp>,
>;
pub type G2Gadget<P> =
AffineGadget<<P as Bls12Parameters>::G2Parameters, <P as Bls12Parameters>::Fp, Fp2G<P>>;
@@ -33,9 +32,7 @@ pub struct G1PreparedGadget<P: Bls12Parameters>(pub G1Gadget<P>);
impl<P: Bls12Parameters> G1PreparedGadget<P> {
pub fn get_value(&self) -> Option<G1Prepared<P>> {
Some(G1Prepared::from_affine(
self.0.get_value().unwrap().into_affine(),
))
Some(G1Prepared::from(self.0.get_value().unwrap().into_affine()))
}
pub fn from_affine<CS: ConstraintSystem<P::Fp>>(

View File

@@ -1,30 +0,0 @@
use crate::groups::curves::twisted_edwards::AffineGadget;
use algebra::{curves::edwards_bls12::EdwardsParameters, fields::edwards_bls12::fq::Fq};
use crate::fields::edwards_bls12::FqGadget;
pub type EdwardsBlsGadget = AffineGadget<EdwardsParameters, Fq, FqGadget>;
#[cfg(test)]
mod test {
use super::EdwardsBlsGadget as EdwardsG;
use crate::{
groups::curves::twisted_edwards::test::{edwards_constraint_costs, edwards_test},
test_constraint_system::TestConstraintSystem,
};
use algebra::{curves::edwards_bls12::EdwardsParameters, fields::edwards_bls12::fq::Fq};
#[test]
fn edwards_constraint_costs_test() {
let mut cs = TestConstraintSystem::<Fq>::new();
edwards_constraint_costs::<_, EdwardsParameters, EdwardsG, _>(&mut cs);
assert!(cs.is_satisfied());
}
#[test]
fn edwards_bls12_gadget_test() {
let mut cs = TestConstraintSystem::<Fq>::new();
edwards_test::<_, EdwardsParameters, EdwardsG, _>(&mut cs);
assert!(cs.is_satisfied());
}
}

View File

@@ -1,30 +0,0 @@
use crate::groups::curves::twisted_edwards::AffineGadget;
use algebra::{curves::edwards_sw6::EdwardsParameters, fields::edwards_sw6::fq::Fq};
use crate::fields::edwards_sw6::FqGadget;
pub type EdwardsSWGadget = AffineGadget<EdwardsParameters, Fq, FqGadget>;
#[cfg(test)]
mod test {
use super::EdwardsSWGadget as EdwardsG;
use crate::{
groups::curves::twisted_edwards::test::{edwards_constraint_costs, edwards_test},
test_constraint_system::TestConstraintSystem,
};
use algebra::{curves::edwards_sw6::EdwardsParameters, fields::edwards_sw6::fq::Fq};
#[test]
fn edwards_constraint_costs_test() {
let mut cs = TestConstraintSystem::<Fq>::new();
edwards_constraint_costs::<_, EdwardsParameters, EdwardsG, _>(&mut cs);
assert!(cs.is_satisfied());
}
#[test]
fn edwards_sw6_gadget_test() {
let mut cs = TestConstraintSystem::<Fq>::new();
edwards_test::<_, EdwardsParameters, EdwardsG, _>(&mut cs);
assert!(cs.is_satisfied());
}
}

View File

@@ -1,30 +0,0 @@
use crate::groups::curves::twisted_edwards::AffineGadget;
use algebra::{curves::jubjub::JubJubParameters, fields::jubjub::fq::Fq};
use crate::fields::jubjub::FqGadget;
pub type JubJubGadget = AffineGadget<JubJubParameters, Fq, FqGadget>;
#[cfg(test)]
mod test {
use super::JubJubGadget as EdwardsG;
use crate::{
groups::curves::twisted_edwards::test::{edwards_constraint_costs, edwards_test},
test_constraint_system::TestConstraintSystem,
};
use algebra::{curves::jubjub::JubJubParameters as EdwardsParameters, fields::jubjub::fq::Fq};
#[test]
fn edwards_constraint_costs_test() {
let mut cs = TestConstraintSystem::<Fq>::new();
edwards_constraint_costs::<_, EdwardsParameters, EdwardsG, _>(&mut cs);
assert!(cs.is_satisfied());
}
#[test]
fn jubjub_gadget_test() {
let mut cs = TestConstraintSystem::<Fq>::new();
edwards_test::<_, EdwardsParameters, EdwardsG, _>(&mut cs);
assert!(cs.is_satisfied());
}
}

View File

@@ -12,12 +12,6 @@ use crate::{prelude::*, Vec};
use core::{borrow::Borrow, marker::PhantomData};
pub mod edwards_bls12;
pub mod edwards_sw6;
pub mod jubjub;
#[cfg(test)]
mod test;
#[derive(Derivative)]
#[derivative(Debug, Clone)]
#[derivative(Debug(bound = "P: TEModelParameters, ConstraintF: Field"))]
@@ -1404,3 +1398,65 @@ where
Ok(x_bytes)
}
}
#[cfg(test)]
#[allow(dead_code)]
pub(crate) fn test<ConstraintF, P, GG>()
where
ConstraintF: Field,
P: TEModelParameters,
GG: GroupGadget<TEAffine<P>, ConstraintF, Value = TEAffine<P>>,
{
use crate::{
boolean::AllocatedBit, groups::test::group_test, prelude::*,
test_constraint_system::TestConstraintSystem,
};
use algebra::{test_rng, Group, PrimeField, UniformRand};
use rand::Rng;
group_test::<ConstraintF, TEAffine<P>, GG>();
let mut cs = TestConstraintSystem::new();
let a: TEAffine<P> = UniformRand::rand(&mut test_rng());
let gadget_a = GG::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
// Check mul_bits
let scalar: <TEAffine<P> as Group>::ScalarField = UniformRand::rand(&mut test_rng());
let native_result = a.mul(&scalar);
let mut scalar: Vec<bool> = BitIterator::new(scalar.into_repr()).collect();
// Get the scalar bits into little-endian form.
scalar.reverse();
let input = Vec::<Boolean>::alloc(cs.ns(|| "Input"), || Ok(scalar)).unwrap();
let zero = GG::zero(cs.ns(|| "zero")).unwrap();
let result = gadget_a
.mul_bits(cs.ns(|| "mul_bits"), &zero, input.iter())
.unwrap();
let gadget_value = result.get_value().expect("Gadget_result failed");
assert_eq!(native_result, gadget_value);
assert!(cs.is_satisfied());
// Test the cost of allocation, conditional selection, and point addition.
let mut cs = TestConstraintSystem::new();
let bit = AllocatedBit::alloc(&mut cs.ns(|| "bool"), || Ok(true))
.unwrap()
.into();
let mut rng = test_rng();
let a: TEAffine<P> = rng.gen();
let b: TEAffine<P> = rng.gen();
let gadget_a = GG::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
let gadget_b = GG::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap();
let alloc_cost = cs.num_constraints();
let _ =
GG::conditionally_select(&mut cs.ns(|| "cond_select"), &bit, &gadget_a, &gadget_b).unwrap();
let cond_select_cost = cs.num_constraints() - alloc_cost;
let _ = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap();
let add_cost = cs.num_constraints() - cond_select_cost - alloc_cost;
assert_eq!(cond_select_cost, <GG as CondSelectGadget<_>>::cost());
assert_eq!(add_cost, GG::cost_of_add());
assert!(cs.is_satisfied());
}

View File

@@ -1,72 +0,0 @@
use crate::{groups::test::group_test, prelude::*, Vec};
use algebra::{
curves::{models::TEModelParameters, twisted_edwards_extended::GroupAffine as TEAffine},
test_rng, BitIterator, Field, Group, PrimeField, UniformRand,
};
use rand::Rng;
use r1cs_core::ConstraintSystem;
pub(crate) fn edwards_test<ConstraintF, P, GG, CS>(cs: &mut CS)
where
ConstraintF: Field,
P: TEModelParameters,
GG: GroupGadget<TEAffine<P>, ConstraintF, Value = TEAffine<P>>,
CS: ConstraintSystem<ConstraintF>,
{
let a: TEAffine<P> = UniformRand::rand(&mut test_rng());
let b: TEAffine<P> = UniformRand::rand(&mut test_rng());
let gadget_a = GG::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
let gadget_b = GG::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap();
assert_eq!(gadget_a.get_value().unwrap(), a);
assert_eq!(gadget_b.get_value().unwrap(), b);
group_test::<ConstraintF, TEAffine<P>, GG, _>(
&mut cs.ns(|| "GroupTest(a, b)"),
gadget_a.clone(),
gadget_b,
);
// Check mul_bits
let scalar: <TEAffine<P> as Group>::ScalarField = UniformRand::rand(&mut test_rng());
let native_result = a.mul(&scalar);
let mut scalar: Vec<bool> = BitIterator::new(scalar.into_repr()).collect();
// Get the scalar bits into little-endian form.
scalar.reverse();
let input = Vec::<Boolean>::alloc(cs.ns(|| "Input"), || Ok(scalar)).unwrap();
let zero = GG::zero(cs.ns(|| "zero")).unwrap();
let result = gadget_a
.mul_bits(cs.ns(|| "mul_bits"), &zero, input.iter())
.unwrap();
let gadget_value = result.get_value().expect("Gadget_result failed");
assert_eq!(native_result, gadget_value);
}
pub(crate) fn edwards_constraint_costs<ConstraintF, P, GG, CS>(cs: &mut CS)
where
ConstraintF: Field,
P: TEModelParameters,
GG: GroupGadget<TEAffine<P>, ConstraintF, Value = TEAffine<P>>,
CS: ConstraintSystem<ConstraintF>,
{
use crate::boolean::AllocatedBit;
let bit = AllocatedBit::alloc(&mut cs.ns(|| "bool"), || Ok(true))
.unwrap()
.into();
let mut rng = test_rng();
let a: TEAffine<P> = rng.gen();
let b: TEAffine<P> = rng.gen();
let gadget_a = GG::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
let gadget_b = GG::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap();
let alloc_cost = cs.num_constraints();
let _ =
GG::conditionally_select(&mut cs.ns(|| "cond_select"), &bit, &gadget_a, &gadget_b).unwrap();
let cond_select_cost = cs.num_constraints() - alloc_cost;
let _ = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap();
let add_cost = cs.num_constraints() - cond_select_cost - alloc_cost;
assert_eq!(cond_select_cost, <GG as CondSelectGadget<_>>::cost());
assert_eq!(add_cost, GG::cost_of_add());
}

View File

@@ -6,10 +6,7 @@ use core::{borrow::Borrow, fmt::Debug};
pub mod curves;
pub use self::curves::{
short_weierstrass::bls12,
twisted_edwards::{edwards_sw6, jubjub},
};
pub use self::curves::short_weierstrass::bls12;
pub trait GroupGadget<G: Group, ConstraintF: Field>:
Sized
@@ -165,21 +162,19 @@ pub trait GroupGadget<G: Group, ConstraintF: Field>:
mod test {
use algebra::{test_rng, Field};
use r1cs_core::ConstraintSystem;
use rand::Rng;
use crate::{prelude::*, test_constraint_system::TestConstraintSystem};
use algebra::groups::Group;
pub(crate) fn group_test<
ConstraintF: Field,
G: Group,
GG: GroupGadget<G, ConstraintF>,
CS: ConstraintSystem<ConstraintF>,
>(
cs: &mut CS,
a: GG,
b: GG,
) {
pub(crate) fn group_test<ConstraintF: Field, G: Group, GG: GroupGadget<G, ConstraintF>>() {
let mut cs = TestConstraintSystem::<ConstraintF>::new();
let mut rng = test_rng();
let a_native = G::rand(&mut rng);
let b_native = G::rand(&mut rng);
let a = GG::alloc(&mut cs.ns(|| "generate_a"), || Ok(a_native)).unwrap();
let b = GG::alloc(&mut cs.ns(|| "generate_b"), || Ok(b_native)).unwrap();
let zero = GG::zero(cs.ns(|| "Zero")).unwrap();
assert_eq!(zero, zero);
@@ -217,21 +212,9 @@ mod test {
let _ = b
.to_bytes_strict(&mut cs.ns(|| "b ToBytes Strict"))
.unwrap();
}
#[test]
fn jubjub_group_gadgets_test() {
use crate::groups::jubjub::JubJubGadget;
use algebra::{curves::jubjub::JubJubProjective, fields::jubjub::fq::Fq};
let mut cs = TestConstraintSystem::<Fq>::new();
let mut rng = test_rng();
let a: JubJubProjective = rng.gen();
let b: JubJubProjective = rng.gen();
let a = JubJubGadget::alloc(&mut cs.ns(|| "generate_a"), || Ok(a)).unwrap();
let b = JubJubGadget::alloc(&mut cs.ns(|| "generate_b"), || Ok(b)).unwrap();
group_test::<_, JubJubProjective, _, _>(&mut cs.ns(|| "GroupTest(a, b)"), a, b);
if !cs.is_satisfied() {
println!("{:?}", cs.which_is_unsatisfied().unwrap());
}
assert!(cs.is_satisfied());
}
}

View File

@@ -1,14 +1,11 @@
use crate::groups::bls12::{
G1Gadget as Bls12G1Gadget, G1PreparedGadget as Bls12G1PreparedGadget,
G2Gadget as Bls12G2Gadget, G2PreparedGadget as Bls12G2PreparedGadget,
};
use algebra::curves::bls12_377::Bls12_377Parameters;
use crate::groups::bls12;
use algebra::bls12_377::Parameters;
pub type G1Gadget = Bls12G1Gadget<Bls12_377Parameters>;
pub type G2Gadget = Bls12G2Gadget<Bls12_377Parameters>;
pub type G1Gadget = bls12::G1Gadget<Parameters>;
pub type G2Gadget = bls12::G2Gadget<Parameters>;
pub type G1PreparedGadget = Bls12G1PreparedGadget<Bls12_377Parameters>;
pub type G2PreparedGadget = Bls12G2PreparedGadget<Bls12_377Parameters>;
pub type G1PreparedGadget = bls12::G1PreparedGadget<Parameters>;
pub type G2PreparedGadget = bls12::G2PreparedGadget<Parameters>;
#[cfg(test)]
mod test {
@@ -16,11 +13,7 @@ mod test {
use super::{G1Gadget, G2Gadget};
use crate::{prelude::*, test_constraint_system::TestConstraintSystem, Vec};
use algebra::{
curves::bls12_377::{G1Projective as G1, G2Projective as G2},
fields::bls12_377::{Fq, Fr},
test_rng, AffineCurve, BitIterator, PrimeField, ProjectiveCurve,
};
use algebra::{bls12_377::*, test_rng, AffineCurve, BitIterator, PrimeField, ProjectiveCurve};
use r1cs_core::ConstraintSystem;
#[test]
@@ -34,8 +27,8 @@ mod test {
.into();
let mut rng = test_rng();
let a: G1 = rng.gen();
let b: G1 = rng.gen();
let a: G1Projective = rng.gen();
let b: G1Projective = rng.gen();
let gadget_a = G1Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
let gadget_b = G1Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap();
let alloc_cost = cs.num_constraints();
@@ -67,8 +60,8 @@ mod test {
.into();
let mut rng = test_rng();
let a: G2 = rng.gen();
let b: G2 = rng.gen();
let a: G2Projective = rng.gen();
let b: G2Projective = rng.gen();
let gadget_a = G2Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
let gadget_b = G2Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap();
let alloc_cost = cs.num_constraints();
@@ -98,8 +91,8 @@ mod test {
let mut cs = TestConstraintSystem::<Fq>::new();
let a = G1::rand(&mut rng);
let b = G1::rand(&mut rng);
let a = G1Projective::rand(&mut rng);
let b = G1Projective::rand(&mut rng);
let a_affine = a.into_affine();
let b_affine = b.into_affine();
let mut gadget_a = G1Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
@@ -167,8 +160,8 @@ mod test {
let mut cs = TestConstraintSystem::<Fq>::new();
let mut rng = test_rng();
let a: G2 = rng.gen();
let b: G2 = rng.gen();
let a: G2Projective = rng.gen();
let b: G2Projective = rng.gen();
let a_affine = a.into_affine();
let b_affine = b.into_affine();

View File

@@ -0,0 +1,27 @@
use algebra::bls12_377::{Fq, Fq12Parameters, Fq2Parameters, Fq6Parameters};
use crate::fields::{fp::FpGadget, fp12::Fp12Gadget, fp2::Fp2Gadget, fp6_3over2::Fp6Gadget};
pub type FqGadget = FpGadget<Fq>;
pub type Fq2Gadget = Fp2Gadget<Fq2Parameters, Fq>;
pub type Fq6Gadget = Fp6Gadget<Fq6Parameters, Fq>;
pub type Fq12Gadget = Fp12Gadget<Fq12Parameters, Fq>;
#[test]
fn bls12_377_field_gadgets_test() {
use super::*;
use crate::fields::tests::*;
use algebra::bls12_377::{Fq, Fq12, Fq2, Fq6};
field_test::<_, Fq, FqGadget>();
frobenius_tests::<Fq, Fq, FqGadget>(13);
field_test::<_, Fq, Fq2Gadget>();
frobenius_tests::<Fq2, Fq, Fq2Gadget>(13);
field_test::<_, Fq, Fq6Gadget>();
frobenius_tests::<Fq6, Fq, Fq6Gadget>(13);
field_test::<_, Fq, Fq12Gadget>();
frobenius_tests::<Fq12, Fq, Fq12Gadget>(13);
}

View File

@@ -0,0 +1,7 @@
mod curves;
mod fields;
mod pairing;
pub use curves::*;
pub use fields::*;
pub use pairing::*;

View File

@@ -0,0 +1,8 @@
use algebra::bls12_377::Parameters;
pub type PairingGadget = crate::pairing::bls12::PairingGadget<Parameters>;
#[test]
fn test() {
crate::pairing::tests::bilinearity_test::<algebra::Bls12_377, _, PairingGadget>()
}

View File

@@ -0,0 +1,11 @@
use crate::groups::curves::twisted_edwards::AffineGadget;
use algebra::edwards_bls12::*;
use crate::edwards_bls12::FqGadget;
pub type EdwardsBlsGadget = AffineGadget<EdwardsParameters, Fq, FqGadget>;
#[test]
fn test() {
crate::groups::curves::twisted_edwards::test::<_, EdwardsParameters, EdwardsBlsGadget>();
}

View File

@@ -0,0 +1,9 @@
use crate::fields::fp::FpGadget;
use algebra::edwards_bls12::fq::Fq;
pub type FqGadget = FpGadget<Fq>;
#[test]
fn test() {
crate::fields::tests::field_test::<_, Fq, FqGadget>();
}

View File

@@ -0,0 +1,5 @@
mod curves;
mod fields;
pub use curves::*;
pub use fields::*;

View File

@@ -0,0 +1,11 @@
use crate::groups::curves::twisted_edwards::AffineGadget;
use algebra::edwards_sw6::*;
use crate::edwards_sw6::FqGadget;
pub type EdwardsSWGadget = AffineGadget<EdwardsParameters, Fq, FqGadget>;
#[test]
fn test() {
crate::groups::curves::twisted_edwards::test::<_, EdwardsParameters, EdwardsSWGadget>();
}

View File

@@ -0,0 +1,9 @@
use crate::fields::fp::FpGadget;
use algebra::edwards_sw6::fq::Fq;
pub type FqGadget = FpGadget<Fq>;
#[test]
fn test() {
crate::fields::tests::field_test::<_, Fq, FqGadget>();
}

View File

@@ -0,0 +1,5 @@
mod curves;
mod fields;
pub use curves::*;
pub use fields::*;

View File

@@ -0,0 +1,11 @@
use crate::groups::curves::twisted_edwards::AffineGadget;
use algebra::jubjub::*;
use crate::jubjub::FqGadget;
pub type JubJubGadget = AffineGadget<JubJubParameters, Fq, FqGadget>;
#[test]
fn test() {
crate::groups::curves::twisted_edwards::test::<Fq, _, JubJubGadget>();
}

View File

@@ -0,0 +1,8 @@
use crate::fields::fp::FpGadget;
pub type FqGadget = FpGadget<algebra::jubjub::Fq>;
#[test]
fn test() {
crate::fields::tests::field_test::<_, algebra::jubjub::Fq, FqGadget>();
}

View File

@@ -0,0 +1,5 @@
mod curves;
mod fields;
pub use curves::*;
pub use fields::*;

View File

@@ -0,0 +1,11 @@
#[cfg(feature = "bls12_377")]
pub mod bls12_377;
#[cfg(feature = "edwards_bls12")]
pub mod edwards_bls12;
#[cfg(feature = "edwards_sw6")]
pub mod edwards_sw6;
#[cfg(feature = "jubjub")]
pub mod jubjub;

View File

@@ -1,37 +1,10 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![deny(
unused_import_braces,
unused_qualifications,
trivial_casts,
trivial_numeric_casts
)]
#![deny(
unused_qualifications,
variant_size_differences,
stable_features,
unreachable_pub
)]
#![deny(
non_shorthand_field_patterns,
unused_attributes,
unused_imports,
unused_extern_crates
)]
#![deny(
renamed_and_removed_lints,
stable_features,
unused_allocation,
unused_comparisons,
bare_trait_objects
)]
#![deny(
const_err,
unused_must_use,
unused_mut,
unused_unsafe,
private_in_public,
unsafe_code
)]
#![deny(unused_import_braces, unused_qualifications, trivial_casts)]
#![deny(trivial_numeric_casts, variant_size_differences, unreachable_pub)]
#![deny(non_shorthand_field_patterns, unused_attributes, unused_imports)]
#![deny(unused_extern_crates, renamed_and_removed_lints, unused_allocation)]
#![deny(unused_comparisons, bare_trait_objects, const_err, unused_must_use)]
#![deny(unused_mut, unused_unsafe, private_in_public, unsafe_code)]
#![forbid(unsafe_code)]
#[cfg(all(test, not(feature = "std")))]
@@ -69,6 +42,20 @@ pub mod fields;
pub mod groups;
mod instantiated;
#[cfg(feature = "bls12_377")]
pub use instantiated::bls12_377;
#[cfg(feature = "edwards_bls12")]
pub use instantiated::edwards_bls12;
#[cfg(feature = "edwards_sw6")]
pub use instantiated::edwards_sw6;
#[cfg(feature = "jubjub")]
pub use instantiated::jubjub;
pub mod pairing;
pub mod alloc;
@@ -82,6 +69,7 @@ pub mod prelude {
eq::*,
fields::FieldGadget,
groups::GroupGadget,
instantiated::*,
pairing::PairingGadget,
select::*,
};

View File

@@ -1,4 +0,0 @@
use crate::pairing::bls12::PairingGadget as Bls12PG;
use algebra::curves::bls12_377::Bls12_377Parameters;
pub type PairingGadget = Bls12PG<Bls12_377Parameters>;

View File

@@ -7,20 +7,11 @@ use crate::{
groups::bls12::{G1Gadget, G1PreparedGadget, G2Gadget, G2PreparedGadget},
};
use algebra::{
curves::{
bls12::{
Bls12, Bls12Parameters, G1Affine, G1Prepared, G1Projective, G2Affine, G2Prepared,
G2Projective, TwistType,
},
models::ModelParameters,
PairingCurve,
},
fields::{fp12_2over3over2::Fp12, BitIterator},
curves::bls12::{Bls12, Bls12Parameters, TwistType},
fields::BitIterator,
};
use core::marker::PhantomData;
pub mod bls12_377;
pub struct PairingGadget<P: Bls12Parameters>(PhantomData<P>);
type Fp2G<P> = Fp2Gadget<<P as Bls12Parameters>::Fp2Params, <P as Bls12Parameters>::Fp>;
@@ -71,25 +62,7 @@ impl<P: Bls12Parameters> PairingGadget<P> {
}
}
impl<P: Bls12Parameters> PG<Bls12<P>, P::Fp> for PairingGadget<P>
where
G1Affine<P>: PairingCurve<
BaseField = <P::G1Parameters as ModelParameters>::BaseField,
ScalarField = <P::G1Parameters as ModelParameters>::ScalarField,
Projective = G1Projective<P>,
PairWith = G2Affine<P>,
Prepared = G1Prepared<P>,
PairingResult = Fp12<P::Fp12Params>,
>,
G2Affine<P>: PairingCurve<
BaseField = <P::G2Parameters as ModelParameters>::BaseField,
ScalarField = <P::G1Parameters as ModelParameters>::ScalarField,
Projective = G2Projective<P>,
PairWith = G1Affine<P>,
Prepared = G2Prepared<P>,
PairingResult = Fp12<P::Fp12Params>,
>,
{
impl<P: Bls12Parameters> PG<Bls12<P>, P::Fp> for PairingGadget<P> {
type G1Gadget = G1Gadget<P>;
type G2Gadget = G2Gadget<P>;
type G1PreparedGadget = G1PreparedGadget<P>;

View File

@@ -4,7 +4,6 @@ use core::fmt::Debug;
use r1cs_core::{ConstraintSystem, SynthesisError};
pub mod bls12;
pub use self::bls12::bls12_377;
pub trait PairingGadget<PairingE: PairingEngine, ConstraintF: Field> {
type G1Gadget: GroupGadget<PairingE::G1Projective, ConstraintF>;
@@ -56,67 +55,53 @@ pub trait PairingGadget<PairingE: PairingEngine, ConstraintF: Field> {
}
#[cfg(test)]
mod test {
use crate::{test_constraint_system::TestConstraintSystem, Vec};
use algebra::{BitIterator, Field, One};
pub(crate) mod tests {
use crate::{
bits::boolean::Boolean, prelude::*, test_constraint_system::TestConstraintSystem, Vec,
};
use algebra::{
test_rng, BitIterator, Field, PairingEngine, PrimeField, ProjectiveCurve, UniformRand,
};
use r1cs_core::ConstraintSystem;
#[test]
fn bls12_377_gadget_bilinearity_test() {
use algebra::{
fields::{
bls12_377::{fq::Fq, fr::Fr},
PrimeField,
},
PairingEngine, ProjectiveCurve,
};
#[allow(dead_code)]
pub(crate) fn bilinearity_test<
E: PairingEngine,
ConstraintF: Field,
P: PairingGadget<E, ConstraintF>,
>() {
let mut cs = TestConstraintSystem::<ConstraintF>::new();
use super::bls12_377::PairingGadget;
use crate::{
groups::bls12::bls12_377::{G1Gadget, G1PreparedGadget, G2Gadget, G2PreparedGadget},
pairing::PairingGadget as _,
prelude::*,
};
use algebra::curves::bls12_377::{Bls12_377, G1Projective, G2Projective};
use core::ops::Mul;
let mut rng = test_rng();
let a = E::G1Projective::rand(&mut rng);
let b = E::G2Projective::rand(&mut rng);
let s = E::Fr::rand(&mut rng);
let mut cs = TestConstraintSystem::<Fq>::new();
let mut sa = a;
sa.mul_assign(s);
let mut sb = b;
sb.mul_assign(s);
// let a: G1Projective = rand::random();
// let b: G2Projective = rand::random();
// let s: Fr = rand::random();
let a_g = P::G1Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
let b_g = P::G2Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap();
let sa_g = P::G1Gadget::alloc(&mut cs.ns(|| "sa"), || Ok(sa)).unwrap();
let sb_g = P::G2Gadget::alloc(&mut cs.ns(|| "sb"), || Ok(sb)).unwrap();
let a: G1Projective = G1Projective::prime_subgroup_generator();
let b: G2Projective = G2Projective::prime_subgroup_generator();
let s: Fr = Fr::one() + &Fr::one();
let a_prep_g = P::prepare_g1(&mut cs.ns(|| "a_prep"), &a_g).unwrap();
let b_prep_g = P::prepare_g2(&mut cs.ns(|| "b_prep"), &b_g).unwrap();
let sa = a.mul(&s);
let sb = b.mul(&s);
let a_g = G1Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
let b_g = G2Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap();
let sa_g = G1Gadget::alloc(&mut cs.ns(|| "sa"), || Ok(sa)).unwrap();
let sb_g = G2Gadget::alloc(&mut cs.ns(|| "sb"), || Ok(sb)).unwrap();
let a_prep_g = G1PreparedGadget::from_affine(&mut cs.ns(|| "a_prep"), &a_g).unwrap();
let b_prep_g = G2PreparedGadget::from_affine(&mut cs.ns(|| "b_prep"), &b_g).unwrap();
let sa_prep_g = G1PreparedGadget::from_affine(&mut cs.ns(|| "sa_prep"), &sa_g).unwrap();
let sb_prep_g = G2PreparedGadget::from_affine(&mut cs.ns(|| "sb_prep"), &sb_g).unwrap();
let sa_prep_g = P::prepare_g1(&mut cs.ns(|| "sa_prep"), &sa_g).unwrap();
let sb_prep_g = P::prepare_g2(&mut cs.ns(|| "sb_prep"), &sb_g).unwrap();
let (ans1_g, ans1_n) = {
let ans_g =
PairingGadget::pairing(cs.ns(|| "pair(sa, b)"), sa_prep_g, b_prep_g.clone())
.unwrap();
let ans_n = Bls12_377::pairing(sa, b);
let ans_g = P::pairing(cs.ns(|| "pair(sa, b)"), sa_prep_g, b_prep_g.clone()).unwrap();
let ans_n = E::pairing(sa, b);
(ans_g, ans_n)
};
let (ans2_g, ans2_n) = {
let ans_g =
PairingGadget::pairing(cs.ns(|| "pair(a, sb)"), a_prep_g.clone(), sb_prep_g)
.unwrap();
let ans_n = Bls12_377::pairing(a, sb);
let ans_g = P::pairing(cs.ns(|| "pair(a, sb)"), a_prep_g.clone(), sb_prep_g).unwrap();
let ans_n = E::pairing(a, sb);
(ans_g, ans_n)
};
@@ -125,9 +110,8 @@ mod test {
.map(Boolean::constant)
.collect::<Vec<_>>();
let mut ans_g =
PairingGadget::pairing(cs.ns(|| "pair(a, b)"), a_prep_g, b_prep_g).unwrap();
let mut ans_n = Bls12_377::pairing(a, b);
let mut ans_g = P::pairing(cs.ns(|| "pair(a, b)"), a_prep_g, b_prep_g).unwrap();
let mut ans_n = E::pairing(a, b);
ans_n = ans_n.pow(s.into_repr());
ans_g = ans_g.pow(cs.ns(|| "pow"), &s_iter).unwrap();