Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pairing: Refactor traits to reflect bls12_381 crate API #238

Merged
merged 7 commits into from
Jun 16, 2020
2 changes: 1 addition & 1 deletion bellman/src/groth16/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ impl<E: Engine> Parameters<E> {

pub struct PreparedVerifyingKey<E: Engine> {
/// Pairing result of alpha*beta
alpha_g1_beta_g2: E::Fqk,
alpha_g1_beta_g2: E::Gt,
/// -gamma in G2
neg_gamma_g2: <E::G2Affine as PairingCurveAffine>::Prepared,
/// -delta in G2
Expand Down
44 changes: 25 additions & 19 deletions bellman/src/groth16/tests/dummy_engine.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use ff::{Field, PrimeField, ScalarEngine};
use group::{CurveAffine, CurveProjective, Group, PrimeGroup};
use pairing::{Engine, PairingCurveAffine};
use pairing::{Engine, MillerLoopResult, MultiMillerLoop, PairingCurveAffine};

use rand_core::RngCore;
use std::fmt;
Expand Down Expand Up @@ -333,35 +333,43 @@ impl Engine for DummyEngine {
type G1Affine = Fr;
type G2 = Fr;
type G2Affine = Fr;
type Fq = Fr;
type Fqe = Fr;

// TODO: This should be F_645131 or something. Doesn't matter for now.
type Fqk = Fr;

fn miller_loop<'a, I>(i: I) -> Self::Fqk
where
I: IntoIterator<
Item = &'a (
&'a <Self::G1Affine as PairingCurveAffine>::Prepared,
&'a <Self::G2Affine as PairingCurveAffine>::Prepared,
),
>,
{
type Gt = Fr;

fn pairing(p: &Self::G1Affine, q: &Self::G2Affine) -> Self::Gt {
Self::multi_miller_loop(&[(p, &(q.prepare()))]).final_exponentiation()
}
}

impl MultiMillerLoop for DummyEngine {
// TODO: This should be F_645131 or something. Doesn't matter for now.
type Result = Fr;

fn multi_miller_loop(
terms: &[(
&Self::G1Affine,
&<Self::G2Affine as PairingCurveAffine>::Prepared,
)],
) -> Self::Result {
let mut acc = <Fr as Field>::zero();

for &(a, b) in i {
for &(a, b) in terms {
let mut tmp = *a;
MulAssign::mul_assign(&mut tmp, b);
AddAssign::add_assign(&mut acc, &tmp);
}

acc
}
}

impl MillerLoopResult for Fr {
type Gt = Fr;

/// Perform final exponentiation of the result of a miller loop.
fn final_exponentiation(this: &Self::Fqk) -> CtOption<Self::Fqk> {
CtOption::new(*this, Choice::from(1))
fn final_exponentiation(&self) -> Self::Gt {
*self
}
}

Expand Down Expand Up @@ -394,7 +402,6 @@ impl PrimeGroup for Fr {}

impl CurveProjective for Fr {
type Affine = Fr;
type Base = Fr;

fn batch_normalize(p: &[Self], q: &mut [Self::Affine]) {
assert_eq!(p.len(), q.len());
Expand Down Expand Up @@ -436,7 +443,6 @@ impl CurveAffine for Fr {
type Compressed = FakePoint;
type Uncompressed = FakePoint;
type Projective = Fr;
type Base = Fr;
type Scalar = Fr;

fn identity() -> Self {
Expand Down
21 changes: 9 additions & 12 deletions bellman/src/groth16/verifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use group::{CurveAffine, CurveProjective};
use pairing::{Engine, PairingCurveAffine};
use pairing::{Engine, MillerLoopResult, MultiMillerLoop, PairingCurveAffine};
use std::ops::{AddAssign, Neg};

use super::{PreparedVerifyingKey, Proof, VerifyingKey};
Expand All @@ -11,14 +11,14 @@ pub fn prepare_verifying_key<E: Engine>(vk: &VerifyingKey<E>) -> PreparedVerifyi
let delta = vk.delta_g2.neg();

PreparedVerifyingKey {
alpha_g1_beta_g2: E::pairing(vk.alpha_g1, vk.beta_g2),
alpha_g1_beta_g2: E::pairing(&vk.alpha_g1, &vk.beta_g2),
neg_gamma_g2: gamma.prepare(),
neg_delta_g2: delta.prepare(),
ic: vk.ic.clone(),
}
}

pub fn verify_proof<'a, E: Engine>(
pub fn verify_proof<'a, E: MultiMillerLoop>(
pvk: &'a PreparedVerifyingKey<E>,
proof: &Proof<E>,
public_inputs: &[E::Fr],
Expand All @@ -41,14 +41,11 @@ pub fn verify_proof<'a, E: Engine>(
// A * B + inputs * (-gamma) + C * (-delta) = alpha * beta
// which allows us to do a single final exponentiation.

Ok(E::final_exponentiation(&E::miller_loop(
[
(&proof.a.prepare(), &proof.b.prepare()),
(&acc.to_affine().prepare(), &pvk.neg_gamma_g2),
(&proof.c.prepare(), &pvk.neg_delta_g2),
]
.iter(),
))
.unwrap()
Ok(E::multi_miller_loop(&[
(&proof.a, &proof.b.prepare()),
(&acc.to_affine(), &pvk.neg_gamma_g2),
(&proof.c, &pvk.neg_delta_g2),
])
.final_exponentiation()
== pvk.alpha_g1_beta_g2)
}
4 changes: 1 addition & 3 deletions group/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Catch documentation errors caused by code changes.
#![deny(intra_doc_link_resolution_failure)]

use ff::{Field, PrimeField};
use ff::PrimeField;
use rand::RngCore;
use std::fmt;
use std::iter::Sum;
Expand Down Expand Up @@ -97,7 +97,6 @@ pub trait CurveProjective:
+ GroupOps<<Self as CurveProjective>::Affine>
+ GroupOpsOwned<<Self as CurveProjective>::Affine>
{
type Base: Field;
type Affine: CurveAffine<Projective = Self, Scalar = Self::Scalar>
+ Mul<Self::Scalar, Output = Self>
+ for<'r> Mul<Self::Scalar, Output = Self>;
Expand Down Expand Up @@ -136,7 +135,6 @@ pub trait CurveAffine:
+ for<'r> Mul<<Self as CurveAffine>::Scalar, Output = <Self as CurveAffine>::Projective>
{
type Scalar: PrimeField;
type Base: Field;
type Projective: CurveProjective<Affine = Self, Scalar = Self::Scalar>;
type Uncompressed: Default + AsRef<[u8]> + AsMut<[u8]>;
type Compressed: Default + AsRef<[u8]> + AsMut<[u8]>;
Expand Down
20 changes: 10 additions & 10 deletions pairing/benches/bls12_381/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use rand_xorshift::XorShiftRng;

use group::Group;
use pairing::bls12_381::*;
use pairing::{Engine, PairingCurveAffine};
use pairing::{Engine, MillerLoopResult, MultiMillerLoop, PairingCurveAffine};

fn bench_pairing_g1_preparation(c: &mut Criterion) {
const SAMPLES: usize = 1000;
Expand Down Expand Up @@ -60,10 +60,10 @@ fn bench_pairing_miller_loop(c: &mut Criterion) {
0xe5,
]);

let v: Vec<(G1Prepared, G2Prepared)> = (0..SAMPLES)
let v: Vec<(G1Affine, G2Prepared)> = (0..SAMPLES)
.map(|_| {
(
G1Affine::from(G1::random(&mut rng)).prepare(),
G1Affine::from(G1::random(&mut rng)),
G2Affine::from(G2::random(&mut rng)).prepare(),
)
})
Expand All @@ -72,7 +72,7 @@ fn bench_pairing_miller_loop(c: &mut Criterion) {
let mut count = 0;
c.bench_function("Miller loop", |b| {
b.iter(|| {
let tmp = Bls12::miller_loop(&[(&v[count].0, &v[count].1)]);
let tmp = Bls12::multi_miller_loop(&[(&v[count].0, &v[count].1)]);
count = (count + 1) % SAMPLES;
tmp
})
Expand All @@ -90,17 +90,17 @@ fn bench_pairing_final_exponentiation(c: &mut Criterion) {
let v: Vec<Fq12> = (0..SAMPLES)
.map(|_| {
(
G1Affine::from(G1::random(&mut rng)).prepare(),
G1Affine::from(G1::random(&mut rng)),
G2Affine::from(G2::random(&mut rng)).prepare(),
)
})
.map(|(ref p, ref q)| Bls12::miller_loop(&[(p, q)]))
.map(|(ref p, ref q)| Bls12::multi_miller_loop(&[(p, q)]))
.collect();

let mut count = 0;
c.bench_function("Final exponentiation", |b| {
b.iter(|| {
let tmp = Bls12::final_exponentiation(&v[count]);
let tmp = v[count].final_exponentiation();
count = (count + 1) % SAMPLES;
tmp
})
Expand All @@ -115,14 +115,14 @@ fn bench_pairing_full(c: &mut Criterion) {
0xe5,
]);

let v: Vec<(G1, G2)> = (0..SAMPLES)
.map(|_| (G1::random(&mut rng), G2::random(&mut rng)))
let v: Vec<(G1Affine, G2Affine)> = (0..SAMPLES)
.map(|_| (G1::random(&mut rng).into(), G2::random(&mut rng).into()))
.collect();

let mut count = 0;
c.bench_function("Full pairing", |b| {
b.iter(|| {
let tmp = Bls12::pairing(v[count].0, v[count].1);
let tmp = Bls12::pairing(&v[count].0, &v[count].1);
count = (count + 1) % SAMPLES;
tmp
})
Expand Down
6 changes: 2 additions & 4 deletions pairing/src/bls12_381/ec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@ macro_rules! curve_impl {

impl CurveAffine for $affine {
type Scalar = $scalarfield;
type Base = $basefield;
type Projective = $projective;
type Uncompressed = $uncompressed;
type Compressed = $compressed;
Expand Down Expand Up @@ -748,7 +747,6 @@ macro_rules! curve_impl {
impl PrimeGroup for $projective {}

impl CurveProjective for $projective {
type Base = $basefield;
type Affine = $affine;

fn batch_normalize(p: &[Self], q: &mut [$affine]) {
Expand Down Expand Up @@ -1143,7 +1141,7 @@ pub mod g1 {
}

fn perform_pairing(&self, other: &G2Affine) -> Fq12 {
super::super::Bls12::pairing(*self, *other)
super::super::Bls12::pairing(self, other)
}
}

Expand Down Expand Up @@ -1782,7 +1780,7 @@ pub mod g2 {
}

fn perform_pairing(&self, other: &G1Affine) -> Fq12 {
super::super::Bls12::pairing(*other, *self)
super::super::Bls12::pairing(other, self)
}
}

Expand Down
Loading