diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml new file mode 100644 index 0000000..1bdce66 --- /dev/null +++ b/.github/workflows/bench.yml @@ -0,0 +1,54 @@ +name: Benchmarks + +on: + push: + branches: [main, v2] + pull_request: + branches: [main, v2] + workflow_dispatch: + +env: + CARGO_TERM_COLOR: always + +jobs: + bench: + name: Run Criterion benchmarks + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-action@stable + + - name: Install capnp + run: sudo apt-get update && sudo apt-get install -y capnproto + + - name: Cache cargo + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-bench-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-bench- + + - name: Run benchmarks + run: cargo bench --package quicproquo-core -- --output-format=bencher 2>&1 | tee bench-output.txt + + - name: Upload HTML reports + uses: actions/upload-artifact@v4 + if: always() + with: + name: criterion-reports + path: target/criterion/ + retention-days: 30 + + - name: Upload raw output + uses: actions/upload-artifact@v4 + if: always() + with: + name: bench-output + path: bench-output.txt + retention-days: 30 diff --git a/crates/quicproquo-core/benches/crypto_benchmarks.rs b/crates/quicproquo-core/benches/crypto_benchmarks.rs index 796998f..260be36 100644 --- a/crates/quicproquo-core/benches/crypto_benchmarks.rs +++ b/crates/quicproquo-core/benches/crypto_benchmarks.rs @@ -8,7 +8,7 @@ use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion}; -use quicproquo_core::{IdentityKeypair, padding}; +use quicproquo_core::{compute_safety_number, IdentityKeypair, padding}; // ── Identity keypair benchmarks ────────────────────────────────────────────── @@ -127,6 +127,17 @@ fn bench_padding(c: &mut Criterion) { group.finish(); } +// ── Safety number benchmarks ───────────────────────────────────────────────── + +fn bench_safety_number(c: &mut Criterion) { + let key_a = [0x1au8; 32]; + let key_b = [0x2bu8; 32]; + + c.bench_function("safety_number", |b| { + b.iter(|| black_box(compute_safety_number(black_box(&key_a), black_box(&key_b)))); + }); +} + criterion_group!( benches, bench_identity_keygen, @@ -134,5 +145,6 @@ criterion_group!( bench_identity_verify, bench_sealed_sender, bench_padding, + bench_safety_number, ); criterion_main!(benches); diff --git a/crates/quicproquo-core/benches/mls_operations.rs b/crates/quicproquo-core/benches/mls_operations.rs index 545c71b..db9c583 100644 --- a/crates/quicproquo-core/benches/mls_operations.rs +++ b/crates/quicproquo-core/benches/mls_operations.rs @@ -62,8 +62,8 @@ fn bench_group_create(c: &mut Criterion) { fn bench_add_member(c: &mut Criterion) { let mut group = c.benchmark_group("mls_add_member"); - // Smaller sizes to keep setup time reasonable - for size in [2, 10, 50] { + group.sample_size(10); + for size in [2, 10, 50, 100] { group.bench_with_input(BenchmarkId::from_parameter(size), &size, |b, &size| { b.iter_batched( || { @@ -83,6 +83,29 @@ fn bench_add_member(c: &mut Criterion) { group.finish(); } +fn bench_epoch_rotation(c: &mut Criterion) { + let mut group = c.benchmark_group("mls_epoch_rotation"); + group.sample_size(10); + for size in [2, 10, 50] { + group.bench_with_input(BenchmarkId::from_parameter(size), &size, |b, &size| { + b.iter_batched( + || { + let (mut creator, members) = setup_group(size); + // Propose a self-update to simulate epoch rotation + let proposal = creator.propose_self_update().unwrap(); + (creator, members, proposal) + }, + |(mut creator, _members, _proposal)| { + // Commit pending proposals (the self-update) to advance the epoch + creator.commit_pending_proposals().unwrap(); + }, + BatchSize::SmallInput, + ); + }); + } + group.finish(); +} + fn bench_send_message(c: &mut Criterion) { let mut group = c.benchmark_group("mls_send_message"); for size in [2, 10, 50] { @@ -127,6 +150,7 @@ criterion_group!( bench_keygen, bench_group_create, bench_add_member, + bench_epoch_rotation, bench_send_message, bench_receive_message, );