Skip to content

Commit

Permalink
Add parallel miller loop (#279)
Browse files Browse the repository at this point in the history
* parallelize miller loops

* completed bls12 miller_loop parallelization

* restores logic for when parallel feature is off

* cargo cleanups

* cleanups

* cargo fmt

* adds changelog entry

* fixed changelog

* moved to cfg_iter, cleanups

* formatting

* minor fixes

* minor fixes

* Bump the version of super-linter (#283)

* Fix the panicking `subgroup_fft_in_place` benchmark for MNT6-753's Fr (#284)

* fix the bench test failure

* update the CHANGELOG

* lint

* lint

* Implement `Into<BigUint>` and `From<BigUint>` for `BigInteger` and `PrimeField` (#280)

* add into and from BigUint for BigInteger

* update changelog, cargo fmt

* linter

* update changelog, cargo fmt

* change the algorithm; implement for PrimeField as well

* less confusing variable name

* for BigInteger, do TryFrom instead of From; for PrimeField, do a mod

* handle the error of TryFrom; add a test for Fr into/from BigUint

* fmt, clippy

* Add sparse scalar mul and sub (#259)

* Add/Sub impl for Sparse and Dense polys, Mul<F> for SparsePolynomial

* Add test and update changelog

* Fmt

* Update CHANGELOG.md

* add add_assign and sub_assign

* fmt

Co-authored-by: Weikeng Chen <[email protected]>

* parallelize miller loops

* completed bls12 miller_loop parallelization

* restores logic for when parallel feature is off

* cargo cleanups

* cleanups

* cargo fmt

* adds changelog entry

* fixed changelog

* moved to cfg_iter, cleanups

* formatting

* minor fixes

* minor fixes

Co-authored-by: Weikeng Chen <[email protected]>
Co-authored-by: Ryan Lehmkuhl <[email protected]>
  • Loading branch information
3 people authored May 28, 2021
1 parent 846c90b commit ff550af
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 7 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@
- [\#263](https://github.com/arkworks-rs/algebra/pull/263) (ark-ff) Add `From<iXXX>` implementations to fields.
- [\#265](https://github.com/arkworks-rs/algebra/pull/265) (ark-serialize) Add hashing as an extension trait of `CanonicalSerialize`.
- [\#280](https://github.com/arkworks-rs/algebra/pull/280) (ark-ff) Add `Into<BigUint>` and `From<BigUint>` implementations to `BigInteger` and `PrimeField`.
- [\#279](https://github.com/arkworks-rs/algebra/pull/279) (ark-ec) Parallelize miller loop operations for BLS12.

### Improvements
- [\#279](https://github.com/arkworks-rs/algebra/pull/279) (ark-ec) Parallelize miller loop operations for BLS12.

### Bug fixes
- [\#252](https://github.com/arkworks-rs/algebra/pull/252) (ark-ff) Fix prime field sampling when `REPR_SHIFT_BITS` is 64.

- [\#252](https://github.com/arkworks-rs/algebra/pull/252) (ark-ff) Fix prime field sampling when `REPR_SHIFT_BITS` is 64.
- [\#284](https://github.com/arkworks-rs/algebra/pull/284) (ark-poly-benches) Fix the panic `subgroup_fft_in_place` benchmark for MNT6-753's Fr.
Expand Down
76 changes: 69 additions & 7 deletions ec/src/models/bls12/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,20 @@ use ark_ff::fields::{
fp6_3over2::Fp6Parameters,
BitIteratorBE, Field, Fp2, PrimeField, SquareRootField,
};
use core::marker::PhantomData;
use num_traits::{One, Zero};

use core::marker::PhantomData;
#[cfg(feature = "parallel")]
use ark_ff::{Fp12ParamsWrapper, Fp2ParamsWrapper, QuadExtField};
#[cfg(feature = "parallel")]
use ark_std::cfg_iter;
#[cfg(feature = "parallel")]
use core::slice::Iter;
#[cfg(feature = "parallel")]
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};

/// A particular BLS12 group can have G2 being either a multiplicative or a divisive twist.
/// A particular BLS12 group can have G2 being either a multiplicative or a
/// divisive twist.
pub enum TwistType {
M,
D,
Expand Down Expand Up @@ -91,6 +100,7 @@ impl<P: Bls12Parameters> PairingEngine for Bls12<P> {
type Fqe = Fp2<P::Fp2Params>;
type Fqk = Fp12<P::Fp12Params>;

#[cfg(not(feature = "parallel"))]
fn miller_loop<'a, I>(i: I) -> Self::Fqk
where
I: IntoIterator<Item = &'a (Self::G1Prepared, Self::G2Prepared)>,
Expand All @@ -101,27 +111,79 @@ impl<P: Bls12Parameters> PairingEngine for Bls12<P> {
pairs.push((p, q.ell_coeffs.iter()));
}
}

let mut f = Self::Fqk::one();

for i in BitIteratorBE::new(P::X).skip(1) {
f.square_in_place();

for (p, ref mut coeffs) in &mut pairs {
Self::ell(&mut f, coeffs.next().unwrap(), &p.0);
}

if i {
for &mut (p, ref mut coeffs) in &mut pairs {
Self::ell(&mut f, coeffs.next().unwrap(), &p.0);
}
}
}

if P::X_IS_NEGATIVE {
f.conjugate();
}
f
}

#[cfg(feature = "parallel")]
fn miller_loop<'a, I>(i: I) -> Self::Fqk
where
I: IntoIterator<Item = &'a (Self::G1Prepared, Self::G2Prepared)>,
{
let mut pairs = vec![];
for (p, q) in i {
if !p.is_zero() && !q.is_zero() {
pairs.push((p, q.ell_coeffs.iter()));
}
}

let mut f_vec = vec![];
for _ in 0..pairs.len() {
f_vec.push(Self::Fqk::one());
}

let a = |p: &&G1Prepared<P>,
coeffs: &Iter<
'_,
(
QuadExtField<Fp2ParamsWrapper<<P as Bls12Parameters>::Fp2Params>>,
QuadExtField<Fp2ParamsWrapper<<P as Bls12Parameters>::Fp2Params>>,
QuadExtField<Fp2ParamsWrapper<<P as Bls12Parameters>::Fp2Params>>,
),
>,
mut f: QuadExtField<Fp12ParamsWrapper<<P as Bls12Parameters>::Fp12Params>>|
-> QuadExtField<Fp12ParamsWrapper<<P as Bls12Parameters>::Fp12Params>> {
let coeffs = coeffs.as_slice();
let mut j = 0;
for i in BitIteratorBE::new(P::X).skip(1) {
f.square_in_place();
Self::ell(&mut f, &coeffs[j], &p.0);
j += 1;
if i {
Self::ell(&mut f, &coeffs[j], &p.0);
j += 1;
}
}
f
};

let mut products = vec![];
cfg_iter!(pairs)
.zip(f_vec)
.map(|(p, f)| a(&p.0, &p.1, f))
.collect_into_vec(&mut products);

let mut f = Self::Fqk::one();
for ff in products {
f *= ff;
}
if P::X_IS_NEGATIVE {
f.conjugate();
}
f
}

Expand Down

0 comments on commit ff550af

Please sign in to comment.