Skip to content

Commit

Permalink
Optimize bls12 381 pairing (#923)
Browse files Browse the repository at this point in the history
* added cyclotomic pow for x, cyclotomic square and frobenius map

* save work

* save work

* save work

* pairing works, changed frobenius_square

* small refactor, remove unused functions

* tested old vs new pairing. When using p and q generators the give different values.

* benchmarking functions

* Refactored code and added some comments

* save work

* clean old version

* clean readme and fix benches

* clippy

* Update bls12_381.rs

---------

Co-authored-by: diegokingston <[email protected]>
Co-authored-by: Diego K <[email protected]>
  • Loading branch information
3 people authored Oct 4, 2024
1 parent e25a464 commit bec0b1a
Show file tree
Hide file tree
Showing 5 changed files with 315 additions and 61 deletions.
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ This library provides efficient implementation of cryptographic primitives used

</div>

## Examples - mini apps

Below is a list of examples to understand lambdaworks and learn what you can build with the tools provided.

- [Merkle Tree CLI](./examples/merkle-tree-cli/)
- [Proving Miden](./examples/prove-miden/)
- [Shamir's secret sharing](./examples/shamir_secret_sharing/)
- [BabySNARK](./examples/baby-snark/)
- [Pinocchio](./examples/pinocchio/)

## Why we built lambdaworks

Zero-Knowledge and Validity Proofs have gained a lot of attention over the last few years. We strongly believe in this potential and that is why we decided to start working in this challenging ecosystem, where math, cryptography and distributed systems meet. The main barrier in the beginning was not the cryptography or math but the lack of good libraries which are performant and developer friendly. There are some exceptions, though, like gnark or halo2. Some have nice APIs and are easy to work with, but they are not written in Rust, and some are written in Rust but have poor programming and engineering practices. Most of them don't have support for CUDA, Metal and WebGPU or distributed FFT calculation using schedulers like Dask.
Expand All @@ -41,14 +51,6 @@ Most of math and crypto crates supports no-std without allocation with `no-defau

Both Math and Crypto support wasm with target `wasm32-unknown-unknown`. To see an example of how to use this to deploy a verifier in a browser, check the Cairo Prover wasm-pack verifier.

## Examples - mini apps

- [Merkle Tree CLI](https://github.com/lambdaclass/lambdaworks/tree/main/examples/merkle-tree-cli)
- [Proving Miden](https://github.com/lambdaclass/lambdaworks/tree/main/examples/prove-miden)
- [Shamir's secret sharing](https://github.com/lambdaclass/lambdaworks/tree/main/examples/shamir_secret_sharing)
- [BabySNARK](https://github.com/lambdaclass/lambdaworks/tree/main/examples/baby-snark)
- [Pinocchio](https://github.com/lambdaclass/lambdaworks/tree/main/examples/pinocchio)

## Exercises and Challenges

- [lambdaworks exercises and challenges](https://github.com/lambdaclass/lambdaworks_exercises/tree/main)
Expand Down
2 changes: 1 addition & 1 deletion math/benches/criterion_elliptic_curve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ use elliptic_curves::{
criterion_group!(
name = elliptic_curve_benches;
config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None)));
targets = bn_254_elliptic_curve_benchmarks,bls12_377_elliptic_curve_benchmarks,bls12_381_elliptic_curve_benchmarks
targets = bn_254_elliptic_curve_benchmarks,bls12_381_elliptic_curve_benchmarks,bls12_377_elliptic_curve_benchmarks
);
criterion_main!(elliptic_curve_benches);
16 changes: 15 additions & 1 deletion math/benches/elliptic_curves/bls12_381.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ use lambdaworks_math::{
elliptic_curve::{
short_weierstrass::{
curves::bls12_381::{
curve::BLS12381Curve, pairing::BLS12381AtePairing, twist::BLS12381TwistCurve,
curve::BLS12381Curve,
pairing::{final_exponentiation, miller, BLS12381AtePairing},
twist::BLS12381TwistCurve,
},
traits::Compress,
},
Expand All @@ -24,6 +26,8 @@ pub fn bls12_381_elliptic_curve_benchmarks(c: &mut Criterion) {
let a_g2 = BLS12381TwistCurve::generator();
let b_g2 = BLS12381TwistCurve::generator();

let miller_loop_output = miller(&a_g2, &a_g1);

let mut group = c.benchmark_group("BLS12-381 Ops");
group.significance_level(0.1).sample_size(10000);
group.throughput(criterion::Throughput::Elements(1));
Expand Down Expand Up @@ -93,4 +97,14 @@ pub fn bls12_381_elliptic_curve_benchmarks(c: &mut Criterion) {
))
});
});

// Miller
group.bench_function("Miller", |bencher| {
bencher.iter(|| black_box(miller(black_box(&a_g2), black_box(&a_g1))))
});

// Final Exponentiation Optimized
group.bench_function("Final Exponentiation", |bencher| {
bencher.iter(|| black_box(final_exponentiation(black_box(&miller_loop_output))))
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ impl IsModulus<U384> for BLS12381FieldModulus {
}

pub type BLS12381PrimeField = MontgomeryBackendPrimeField<BLS12381FieldModulus, 6>;
type Fp2E = FieldElement<Degree2ExtensionField>;

//////////////////
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -199,6 +200,16 @@ impl HasCubicNonResidue<Degree2ExtensionField> for LevelTwoResidue {
}
}

impl HasQuadraticNonResidue<Degree2ExtensionField> for LevelTwoResidue {
fn residue() -> FieldElement<Degree2ExtensionField> {
FieldElement::new([
FieldElement::new(U384::from("1")),
FieldElement::new(U384::from("1")),
])
}
}
pub type Degree4ExtensionField = QuadraticExtensionField<Degree2ExtensionField, LevelTwoResidue>;

pub type Degree6ExtensionField = CubicExtensionField<Degree2ExtensionField, LevelTwoResidue>;

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -284,6 +295,14 @@ impl FieldElement<Degree12ExtensionField> {
}
}

/// Computes the multiplication of an element of fp2 by the level two non-residue 9+u.
pub fn mul_fp2_by_nonresidue(a: &Fp2E) -> Fp2E {
// (c0 + c1 * u) * (1 + u) = (c0 - c1) + (c1 + c0) * u
let c0 = &a.value()[0] - &a.value()[1]; // c0 - c1
let c1 = &a.value()[0] + &a.value()[1]; // c1 + c0

Fp2E::new([c0, c1])
}
#[cfg(test)]
mod tests {
use crate::elliptic_curve::{
Expand Down
Loading

0 comments on commit bec0b1a

Please sign in to comment.