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

Optimize bls12 381 pairing #923

Merged
merged 16 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 Naive", |bencher| {
bencher.iter(|| black_box(miller(black_box(&a_g2), black_box(&a_g1))))
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is no longer the naive version.


// Final Exponentiation Optimized
group.bench_function("Final Exponentiation Optimized", |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
Loading