pairing: Extract Engine::miller_loop into a MultiMillerLoop trait
This enables MultiMillerLoop to be conditionally implemented, for example in libraries where Engine::pairing supports no-std, but MultiMillerLoop requires an allocator.
This commit is contained in:
parent
ee6e00b0e7
commit
02dc1763a3
|
@ -1,6 +1,6 @@
|
||||||
use ff::{Field, PrimeField};
|
use ff::{Field, PrimeField};
|
||||||
use group::{CurveAffine, CurveProjective, Group, PrimeGroup};
|
use group::{CurveAffine, CurveProjective, Group, PrimeGroup};
|
||||||
use pairing::{Engine, MillerLoopResult, PairingCurveAffine};
|
use pairing::{Engine, MillerLoopResult, MultiMillerLoop, PairingCurveAffine};
|
||||||
|
|
||||||
use rand_core::RngCore;
|
use rand_core::RngCore;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -332,21 +332,26 @@ impl Engine for DummyEngine {
|
||||||
type G2Affine = Fr;
|
type G2Affine = Fr;
|
||||||
|
|
||||||
// TODO: This should be F_645131 or something. Doesn't matter for now.
|
// TODO: This should be F_645131 or something. Doesn't matter for now.
|
||||||
type MillerLoopResult = Fr;
|
|
||||||
type Gt = Fr;
|
type Gt = Fr;
|
||||||
|
|
||||||
fn miller_loop<'a, I>(i: I) -> Self::MillerLoopResult
|
fn pairing(p: &Self::G1Affine, q: &Self::G2Affine) -> Self::Gt {
|
||||||
where
|
Self::multi_miller_loop(&[(p, &(q.prepare()))]).final_exponentiation()
|
||||||
I: IntoIterator<
|
}
|
||||||
Item = &'a (
|
}
|
||||||
&'a <Self::G1Affine as PairingCurveAffine>::Prepared,
|
|
||||||
&'a <Self::G2Affine as PairingCurveAffine>::Prepared,
|
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();
|
let mut acc = <Fr as Field>::zero();
|
||||||
|
|
||||||
for &(a, b) in i {
|
for &(a, b) in terms {
|
||||||
let mut tmp = *a;
|
let mut tmp = *a;
|
||||||
MulAssign::mul_assign(&mut tmp, b);
|
MulAssign::mul_assign(&mut tmp, b);
|
||||||
AddAssign::add_assign(&mut acc, &tmp);
|
AddAssign::add_assign(&mut acc, &tmp);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use group::{CurveAffine, CurveProjective};
|
use group::{CurveAffine, CurveProjective};
|
||||||
use pairing::{Engine, MillerLoopResult, PairingCurveAffine};
|
use pairing::{Engine, MillerLoopResult, MultiMillerLoop, PairingCurveAffine};
|
||||||
use std::ops::{AddAssign, Neg};
|
use std::ops::{AddAssign, Neg};
|
||||||
|
|
||||||
use super::{PreparedVerifyingKey, Proof, VerifyingKey};
|
use super::{PreparedVerifyingKey, Proof, VerifyingKey};
|
||||||
|
@ -18,7 +18,7 @@ pub fn prepare_verifying_key<E: Engine>(vk: &VerifyingKey<E>) -> PreparedVerifyi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn verify_proof<'a, E: Engine>(
|
pub fn verify_proof<'a, E: MultiMillerLoop>(
|
||||||
pvk: &'a PreparedVerifyingKey<E>,
|
pvk: &'a PreparedVerifyingKey<E>,
|
||||||
proof: &Proof<E>,
|
proof: &Proof<E>,
|
||||||
public_inputs: &[E::Fr],
|
public_inputs: &[E::Fr],
|
||||||
|
@ -41,14 +41,11 @@ pub fn verify_proof<'a, E: Engine>(
|
||||||
// A * B + inputs * (-gamma) + C * (-delta) = alpha * beta
|
// A * B + inputs * (-gamma) + C * (-delta) = alpha * beta
|
||||||
// which allows us to do a single final exponentiation.
|
// which allows us to do a single final exponentiation.
|
||||||
|
|
||||||
Ok(E::miller_loop(
|
Ok(E::multi_miller_loop(&[
|
||||||
[
|
(&proof.a, &proof.b.prepare()),
|
||||||
(&proof.a.prepare(), &proof.b.prepare()),
|
(&acc.to_affine(), &pvk.neg_gamma_g2),
|
||||||
(&acc.to_affine().prepare(), &pvk.neg_gamma_g2),
|
(&proof.c, &pvk.neg_delta_g2),
|
||||||
(&proof.c.prepare(), &pvk.neg_delta_g2),
|
])
|
||||||
]
|
|
||||||
.iter(),
|
|
||||||
)
|
|
||||||
.final_exponentiation()
|
.final_exponentiation()
|
||||||
== pvk.alpha_g1_beta_g2)
|
== pvk.alpha_g1_beta_g2)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue