diff --git a/math/Cargo.toml b/math/Cargo.toml index 44b7dbb4f..02df065d4 100644 --- a/math/Cargo.toml +++ b/math/Cargo.toml @@ -59,6 +59,10 @@ cuda = ["dep:cudarc", "dep:lambdaworks-gpu"] name = "criterion_elliptic_curve" harness = false +[[bench]] +name = "iai_elliptic_curve" +harness = false + [[bench]] name = "criterion_polynomial" harness = false diff --git a/math/benches/criterion_elliptic_curve.rs b/math/benches/criterion_elliptic_curve.rs index 52b450507..53c73aaa0 100644 --- a/math/benches/criterion_elliptic_curve.rs +++ b/math/benches/criterion_elliptic_curve.rs @@ -1,39 +1,14 @@ -use criterion::{black_box, criterion_group, criterion_main, Criterion}; -use lambdaworks_math::{ - cyclic_group::IsGroup, - elliptic_curve::{ - short_weierstrass::{ - curves::bls12_381::{ - curve::BLS12381Curve, pairing::BLS12381AtePairing, twist::BLS12381TwistCurve, - }, - point::ShortWeierstrassProjectivePoint, - }, - traits::{IsEllipticCurve, IsPairing}, - }, -}; -use rand::{rngs::StdRng, Rng, SeedableRng}; - -mod utils; - -type G1 = ShortWeierstrassProjectivePoint; -type G2 = ShortWeierstrassProjectivePoint; +use criterion::{criterion_group, criterion_main, Criterion}; +use pprof::criterion::{Output, PProfProfiler}; -fn generate_points() -> (G1, G2) { - let mut rng = StdRng::seed_from_u64(42); - - let g1 = BLS12381Curve::generator(); - let g2 = BLS12381TwistCurve::generator(); - let a: u128 = rng.gen(); - let b: u128 = rng.gen(); - (g1.operate_with_self(a), g2.operate_with_self(b)) -} - -pub fn bls12381_elliptic_curve_benchmarks(c: &mut Criterion) { - let (p, q) = generate_points(); - c.bench_function("BLS12381 Ate pairing", |b| { - b.iter(|| BLS12381AtePairing::compute(black_box(&p), black_box(&q))) - }); -} +mod elliptic_curves; +use elliptic_curves::{ + bls12_377::bls12_377_elliptic_curve_benchmarks, bls12_381::bls12_381_elliptic_curve_benchmarks, +}; -criterion_group!(bls12381, bls12381_elliptic_curve_benchmarks); -criterion_main!(bls12381); +criterion_group!( + name = elliptic_curve_benches; + config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None))); + targets = bls12_381_elliptic_curve_benchmarks, bls12_377_elliptic_curve_benchmarks +); +criterion_main!(elliptic_curve_benches); diff --git a/math/benches/elliptic_curves/bls12_377.rs b/math/benches/elliptic_curves/bls12_377.rs new file mode 100644 index 000000000..0708c8951 --- /dev/null +++ b/math/benches/elliptic_curves/bls12_377.rs @@ -0,0 +1,41 @@ +use criterion::{black_box, Criterion}; +use lambdaworks_math::{ + cyclic_group::IsGroup, + elliptic_curve::{ + short_weierstrass::curves::bls12_377::curve::BLS12377Curve, traits::IsEllipticCurve, + }, +}; +use rand::{rngs::StdRng, Rng, SeedableRng}; + +#[allow(dead_code)] +pub fn bls12_377_elliptic_curve_benchmarks(c: &mut Criterion) { + let mut rng = StdRng::seed_from_u64(42); + let a_val: u128 = rng.gen(); + let b_val: u128 = rng.gen(); + let a = BLS12377Curve::generator().operate_with_self(a_val); + let b = BLS12377Curve::generator().operate_with_self(b_val); + + let mut group = c.benchmark_group("BLS12-381 Ops"); + group.significance_level(0.1).sample_size(10000); + group.throughput(criterion::Throughput::Elements(1)); + + // Operate_with G1 + group.bench_function("Operate_with_G1", |bencher| { + bencher.iter(|| black_box(black_box(&a).operate_with(black_box(&b)))); + }); + + // Operate_with_self G1 + group.bench_function("Operate_with_self_G1", |bencher| { + bencher.iter(|| black_box(black_box(&a).operate_with_self(black_box(b_val)))); + }); + + // Double G1 + group.bench_function("Double G1 {:?}", |bencher| { + bencher.iter(|| black_box(black_box(&a).operate_with_self(black_box(2u64)))); + }); + + // Neg G1 + group.bench_function("Neg G1 {:?}", |bencher| { + bencher.iter(|| black_box(black_box(&a).neg())); + }); +} diff --git a/math/benches/elliptic_curves/bls12_381.rs b/math/benches/elliptic_curves/bls12_381.rs new file mode 100644 index 000000000..44613e5b1 --- /dev/null +++ b/math/benches/elliptic_curves/bls12_381.rs @@ -0,0 +1,96 @@ +use criterion::{black_box, Criterion}; +use lambdaworks_math::{ + cyclic_group::IsGroup, + elliptic_curve::{ + short_weierstrass::curves::bls12_381::{ + compression::{compress_g1_point, decompress_g1_point}, + curve::BLS12381Curve, + pairing::BLS12381AtePairing, + twist::BLS12381TwistCurve, + }, + traits::{IsEllipticCurve, IsPairing}, + }, +}; +use rand::{rngs::StdRng, Rng, SeedableRng}; + +#[allow(dead_code)] +pub fn bls12_381_elliptic_curve_benchmarks(c: &mut Criterion) { + let mut rng = StdRng::seed_from_u64(42); + let a_val: u128 = rng.gen(); + let b_val: u128 = rng.gen(); + let a_g1 = BLS12381Curve::generator().operate_with_self(a_val); + let b_g1 = BLS12381Curve::generator().operate_with_self(b_val); + + let a_g2 = BLS12381TwistCurve::generator(); + let b_g2 = BLS12381TwistCurve::generator(); + + let mut group = c.benchmark_group("BLS12-381 Ops"); + group.significance_level(0.1).sample_size(10000); + group.throughput(criterion::Throughput::Elements(1)); + + // Operate_with G1 + group.bench_function("Operate_with_G1", |bencher| { + bencher.iter(|| black_box(black_box(&a_g1).operate_with(black_box(&b_g1)))); + }); + + // Operate_with G2 + group.bench_function("Operate_with_G2 {:?}", |bencher| { + bencher.iter(|| black_box(black_box(&a_g2).operate_with(black_box(&b_g2)))); + }); + + // Operate_with_self G1 + group.bench_function("Operate_with_self_G1", |bencher| { + bencher.iter(|| black_box(black_box(&a_g1).operate_with_self(black_box(b_val)))); + }); + + // Operate_with_self G2 + group.bench_function("Operate_with_self_G2", |bencher| { + bencher.iter(|| black_box(black_box(&a_g2).operate_with_self(black_box(b_val)))); + }); + + // Double G1 + group.bench_function("Double G1", |bencher| { + bencher.iter(|| black_box(black_box(&a_g1).operate_with_self(black_box(2u64)))); + }); + + // Double G2 + group.bench_function("Double G2 {:?}", |bencher| { + bencher.iter(|| black_box(black_box(&a_g2).operate_with_self(black_box(2u64)))); + }); + + // Neg G1 + group.bench_function("Neg G1", |bencher| { + bencher.iter(|| black_box(black_box(&a_g1).neg())); + }); + + // Neg G2 + group.bench_function("Neg G2", |bencher| { + bencher.iter(|| black_box(black_box(&a_g2).neg())); + }); + + // Compress_G1_point + group.bench_function("Compress G1 point", |bencher| { + bencher.iter(|| black_box(compress_g1_point(black_box(&a_g1)))); + }); + + // Decompress_G1_point + group.bench_function("Decompress G1 Point", |bencher| { + let a: [u8; 48] = compress_g1_point(&a_g1).try_into().unwrap(); + bencher.iter(|| black_box(decompress_g1_point(&mut black_box(a))).unwrap()); + }); + + // Subgroup Check G1 + group.bench_function("Subgroup Check G1", |bencher| { + bencher.iter(|| (black_box(a_g1.is_in_subgroup()))); + }); + + // Ate Pairing + group.bench_function("Ate Pairing", |bencher| { + bencher.iter(|| { + black_box(BLS12381AtePairing::compute( + black_box(&a_g1), + black_box(&a_g2), + )) + }); + }); +} diff --git a/math/benches/elliptic_curves/iai_bls12_377.rs b/math/benches/elliptic_curves/iai_bls12_377.rs new file mode 100644 index 000000000..988131c4a --- /dev/null +++ b/math/benches/elliptic_curves/iai_bls12_377.rs @@ -0,0 +1,47 @@ +use criterion::black_box; +use lambdaworks_math::{ + cyclic_group::IsGroup, + elliptic_curve::{ + short_weierstrass::{ + curves::bls12_377::curve::BLS12377Curve, point::ShortWeierstrassProjectivePoint, + }, + traits::IsEllipticCurve, + }, +}; +use rand::{rngs::StdRng, Rng, SeedableRng}; +#[allow(dead_code)] +type G1 = ShortWeierstrassProjectivePoint; + +#[allow(dead_code)] +pub fn rand_points_g1() -> (G1, G1, u128, u128) { + let mut rng = StdRng::seed_from_u64(42); + let a_val = rng.gen(); + let b_val = rng.gen(); + let a = BLS12377Curve::generator().operate_with_self(a_val); + let b = BLS12377Curve::generator().operate_with_self(b_val); + (a, b, a_val, b_val) +} + +#[allow(dead_code)] +pub fn bls12_377_operate_with_g1() { + let (a, b, _, _) = rand_points_g1(); + let _ = black_box(black_box(&a).operate_with(black_box(&b))); +} + +#[allow(dead_code)] +pub fn bls12_377_operate_with_self_g1() { + let (a, _, _, b_val) = rand_points_g1(); + let _ = black_box(black_box(&a).operate_with_self(black_box(b_val))); +} + +#[allow(dead_code)] +pub fn bls12_377_double_g1() { + let (a, _, _, _) = rand_points_g1(); + let _ = black_box(black_box(&a).operate_with_self(black_box(2u64))); +} + +#[allow(dead_code)] +pub fn bls12_377_neg_g1() { + let (a, _, _, _) = rand_points_g1(); + let _ = black_box(black_box(&a).neg()); +} diff --git a/math/benches/elliptic_curves/iai_bls12_381.rs b/math/benches/elliptic_curves/iai_bls12_381.rs new file mode 100644 index 000000000..b743e9bf8 --- /dev/null +++ b/math/benches/elliptic_curves/iai_bls12_381.rs @@ -0,0 +1,115 @@ +use criterion::black_box; +use lambdaworks_math::{ + cyclic_group::IsGroup, + elliptic_curve::{ + short_weierstrass::{ + curves::bls12_381::{ + compression::{compress_g1_point, decompress_g1_point}, + curve::BLS12381Curve, + pairing::BLS12381AtePairing, + twist::BLS12381TwistCurve, + }, + point::ShortWeierstrassProjectivePoint, + }, + traits::{IsEllipticCurve, IsPairing}, + }, +}; +use rand::{rngs::StdRng, Rng, SeedableRng}; +#[allow(dead_code)] +type G1 = ShortWeierstrassProjectivePoint; +#[allow(dead_code)] +type G2 = ShortWeierstrassProjectivePoint; + +#[allow(dead_code)] +pub fn rand_points_g1() -> (G1, G1, u128, u128) { + let mut rng = StdRng::seed_from_u64(42); + let a_val = rng.gen(); + let b_val = rng.gen(); + let a = BLS12381Curve::generator().operate_with_self(a_val); + let b = BLS12381Curve::generator().operate_with_self(b_val); + (a, b, a_val, b_val) +} + +#[allow(dead_code)] +pub fn rand_points_g2() -> (G2, G2, u128, u128) { + let mut rng = StdRng::seed_from_u64(42); + let a_val = rng.gen(); + let b_val = rng.gen(); + let a = BLS12381TwistCurve::generator().operate_with_self(a_val); + let b = BLS12381TwistCurve::generator().operate_with_self(b_val); + (a, b, a_val, b_val) +} + +#[allow(dead_code)] +pub fn bls12_381_operate_with_g1() { + let (a, b, _, _) = rand_points_g1(); + let _ = black_box(black_box(&a).operate_with(black_box(&b))); +} + +#[allow(dead_code)] +pub fn bls12_381_operate_with_g2() { + let (a, b, _, _) = rand_points_g1(); + let _ = black_box(black_box(&a).operate_with(black_box(&b))); +} + +#[allow(dead_code)] +pub fn bls12_381_operate_with_self_g1() { + let (a, _, _, b_val) = rand_points_g1(); + let _ = black_box(black_box(&a).operate_with_self(black_box(b_val))); +} + +#[allow(dead_code)] +pub fn bls12_381_operate_with_self_g2() { + let (a, _, _, b_val) = rand_points_g2(); + let _ = black_box(black_box(&a).operate_with_self(black_box(b_val))); +} + +#[allow(dead_code)] +pub fn bls12_381_double_g1() { + let (a, _, _, _) = rand_points_g1(); + let _ = black_box(black_box(&a).operate_with_self(black_box(2u64))); +} + +#[allow(dead_code)] +pub fn bls12_381_double_g2() { + let (a, _, _, _) = rand_points_g2(); + let _ = black_box(black_box(&a).operate_with_self(black_box(2u64))); +} + +#[allow(dead_code)] +pub fn bls12_381_neg_g1() { + let (a, _, _, _) = rand_points_g1(); + let _ = black_box(black_box(&a).neg()); +} + +#[allow(dead_code)] +pub fn bls12_381_neg_g2() { + let (a, _, _, _) = rand_points_g2(); + let _ = black_box(black_box(&a).neg()); +} + +#[allow(dead_code)] +pub fn bls12_381_compress_g1() { + let (a, _, _, _) = rand_points_g1(); + let _ = black_box(compress_g1_point(black_box(&a))); +} + +#[allow(dead_code)] +pub fn bls12_381_decompress_g1() { + let (a, _, _, _) = rand_points_g1(); + let a: [u8; 48] = compress_g1_point(&a).try_into().unwrap(); + let _ = black_box(decompress_g1_point(&mut black_box(a))).unwrap(); +} + +#[allow(dead_code)] +pub fn bls12_381_subgroup_check_g1() { + let (a, _, _, _) = rand_points_g1(); + let _ = black_box(black_box(&a.is_in_subgroup())); +} + +#[allow(dead_code)] +pub fn bls12_381_ate_pairing() { + let (a, _, _, _) = rand_points_g1(); + let (_, b, _, _) = rand_points_g2(); + let _ = black_box(BLS12381AtePairing::compute(black_box(&a), black_box(&b))); +} diff --git a/math/benches/elliptic_curves/mod.rs b/math/benches/elliptic_curves/mod.rs new file mode 100644 index 000000000..7ec614dad --- /dev/null +++ b/math/benches/elliptic_curves/mod.rs @@ -0,0 +1,4 @@ +pub mod bls12_377; +pub mod bls12_381; +pub mod iai_bls12_377; +pub mod iai_bls12_381; diff --git a/math/benches/iai_elliptic_curve.rs b/math/benches/iai_elliptic_curve.rs new file mode 100644 index 000000000..7af98abe6 --- /dev/null +++ b/math/benches/iai_elliptic_curve.rs @@ -0,0 +1,23 @@ +mod elliptic_curves; + +use elliptic_curves::{iai_bls12_377::*, iai_bls12_381::*}; + +iai_callgrind::main!( + callgrind_args = "toggle-collect=util::*"; + functions = bls12_381_operate_with_g1, + bls12_381_operate_with_g2, + bls12_381_operate_with_self_g1, + bls12_381_operate_with_self_g2, + bls12_381_double_g1, + bls12_381_double_g2, + bls12_381_neg_g1, + bls12_381_neg_g2, + bls12_381_compress_g1, + bls12_381_decompress_g1, + bls12_381_subgroup_check_g1, + bls12_381_ate_pairing, + bls12_377_operate_with_g1, + bls12_377_operate_with_self_g1, + bls12_377_double_g1, + bls12_377_neg_g1, +);