Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
110 changes: 110 additions & 0 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
name: Benchmarks

on:
push:
branches:
- main
pull_request:

jobs:
test:
name: Benchmark library
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v4

- name: Install Nargo
uses: noir-lang/[email protected]
with:
toolchain: 1.0.0-beta.7

- name: Install bb
run: |
curl -L https://bbup.aztec.network | bash
~/.bb/bbup -nv 1.0.0-beta.7
sudo apt install libc++-dev

- name: Build Noir benchmark programs
run: nargo export

- name: Generate gates report
run: ./scripts/build-gates-report.sh
env:
BACKEND: /home/runner/.bb/bb

- name: Store ACIR opcode benchmark result
uses: benchmark-action/github-action-benchmark@v1
with:
name: "ACIR Opcodes"
tool: "customSmallerIsBetter"
output-file-path: "benchmark-opcodes.json"
gh-pages-branch: "gh-pages"
benchmark-data-dir-path: "dev/bench"
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-push: ${{ github.ref == 'refs/heads/main' }}
comment-always: ${{ contains( github.event.pull_request.labels.*.name, 'bench-show') }}
comment-on-alert: true
alert-threshold: "101%"
fail-on-alert: false
max-items-in-chart: 50

- name: Store gates benchmark result
uses: benchmark-action/github-action-benchmark@v1
with:
name: "Circuit Size"
tool: "customSmallerIsBetter"
output-file-path: "benchmark-circuit.json"
gh-pages-branch: "gh-pages"
benchmark-data-dir-path: "dev/bench"
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-push: ${{ github.ref == 'refs/heads/main' }}
comment-always: ${{ contains( github.event.pull_request.labels.*.name, 'bench-show') }}
comment-on-alert: true
alert-threshold: "101%"
fail-on-alert: false
max-items-in-chart: 50
skip-fetch-gh-pages: true

- name: Add gates diff to sticky comment
if: github.event_name == 'pull_request' || github.event_name == 'pull_request_target'
uses: marocchino/sticky-pull-request-comment@v2
with:
# delete the comment in case changes no longer impact circuit sizes
delete: ${{ !steps.gates_diff.outputs.markdown }}
message: ${{ steps.gates_diff.outputs.markdown }}

# Delete the export files
- name: Delete export files
run: rm -rf export
# Run nargo export again with force-brillig flag
- name: Build Brillig benchmark programs
run: nargo export --force-brillig

- name: Generate brillig report
run: ./scripts/build-brillig-report.sh

- name: Store brillig benchmark result
uses: benchmark-action/github-action-benchmark@v1
with:
name: "Brillig Bytecode Size"
tool: "customSmallerIsBetter"
output-file-path: "benchmark-brillig.json"
gh-pages-branch: "gh-pages"
benchmark-data-dir-path: "dev/bench"
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-push: ${{ github.ref == 'refs/heads/main' }}
comment-always: ${{ contains( github.event.pull_request.labels.*.name, 'bench-show') }}
comment-on-alert: true
alert-threshold: "101%"
fail-on-alert: false
max-items-in-chart: 50
skip-fetch-gh-pages: true

- name: Add brillig diff to sticky comment
if: github.event_name == 'pull_request' || github.event_name == 'pull_request_target'
uses: marocchino/sticky-pull-request-comment@v2
with:
# delete the comment in case changes no longer impact circuit sizes
delete: ${{ !steps.brillig_diff.outputs.markdown }}
message: ${{ steps.brillig_diff.outputs.markdown }}
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ The most efficient method to evaluate curve operations is `BigCurve::evaluate_li
- Add method to check point is in prime-order subgroup for curves with a cofactor
- Parametrise and test with a degree-2 extension field instead of `BigNum`
- [x] Add curve parameters for commonly used curves (BN254, BLS12-381, MNT4, MNT6, Pasta, Vella, Secp256K1, Secp256R1)
- Create benchmarks
- Add support for curve endomorphisms where applicable (if base field and scalar field both contain cube roots of unity, we can reduce the number of point doublings required for an MSM in half)

# FAQ
Expand Down
29 changes: 29 additions & 0 deletions scripts/build-brillig-report.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env bash
set -e

INSPECTOR=${INSPECTOR:-noir-inspector}
cd $(dirname "$0")/../

artifacts_path="./export"
artifacts=$(ls $artifacts_path)

# Start the JSON array
REPORTS=$(jq --null-input '[]')

for artifact in $artifacts; do
# Get and format the opcode info
OP_CODE_INFO=$($INSPECTOR info --json "$artifacts_path/$artifact")

# Simplified jq expression to output only package_name and opcodes from unconstrained_functions
REPORTS=$(echo $OP_CODE_INFO | jq -c '.programs[0] | del(.functions)' | jq -c --argjson old_reports $REPORTS '$old_reports + [.]')
done

echo $REPORTS | jq '{ programs: . }' > brillig_report.json

# Convert brillig report to benchmark format
output_file_brillig="benchmark-brillig.json"
jq -r '[.programs[] | .unconstrained_functions[] | {
"name": (if (.package_name // "") == "" then .name else "\(.package_name | sub("^null/"; ""))/\(.name)" end),
"unit": "opcodes",
"value": (.opcodes // 0)
}]' brillig_report.json > $output_file_brillig
51 changes: 51 additions & 0 deletions scripts/build-gates-report.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/usr/bin/env bash
set -e

BACKEND=${BACKEND:-bb}

cd $(dirname "$0")/../

artifacts_path="./export"
artifacts=$(ls $artifacts_path)

echo "{\"programs\": [" > gates_report.json

# Bound for checking where to place last parentheses
NUM_ARTIFACTS=$(ls -1q "$artifacts_path" | wc -l)

ITER="1"
for artifact in $artifacts; do
ARTIFACT_NAME=$(basename "$artifact")

GATES_INFO=$($BACKEND gates -b "$artifacts_path/$artifact")
MAIN_FUNCTION_INFO=$(echo $GATES_INFO | jq -r '.functions[0] | .name = "main"')
echo "{\"package_name\": \"$ARTIFACT_NAME\", \"functions\": [$MAIN_FUNCTION_INFO]" >> gates_report.json

if (($ITER == $NUM_ARTIFACTS)); then
echo "}" >> gates_report.json
else
echo "}, " >> gates_report.json
fi

ITER=$(( $ITER + 1 ))
done

echo "]}" >> gates_report.json

# Convert the gates report into separate benchmark files
output_file_opcodes="benchmark-opcodes.json"
output_file_circuit="benchmark-circuit.json"

# Convert gates report - opcodes
jq -r '[.programs[] | {
"name": "\(.package_name)/main",
"unit": "acir_opcodes",
"value": (.functions[0].acir_opcodes // 0)
}]' gates_report.json > $output_file_opcodes

# Convert gates report - circuit size
jq -r '[.programs[] | {
"name": "\(.package_name)/main",
"unit": "circuit_size",
"value": (.functions[0].circuit_size // 0)
}]' gates_report.json > $output_file_circuit
98 changes: 98 additions & 0 deletions src/benchmarks/bigcurve_benchmarks.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
use crate::curves::bls12_377::BLS12_377;
use crate::curves::bls12_381::BLS12_381;
use crate::curves::bn254::BN254;
use crate::curves::mnt4_753::MNT4_753;
use crate::curves::mnt6_753::MNT6_753;
use crate::curves::pallas::Pallas;
use crate::curves::secp256k1::Secp256k1;
use crate::curves::secp256r1::Secp256r1;
use crate::curves::secp384r1::Secp384r1;
use crate::curves::vesta::Vesta;
comptime fn make_bench(m: Module, params: Quoted) -> Quoted {
let module_name = m.name();
let add_bench_name = f"add_{module_name}".quoted_contents();
let sub_bench_name = f"sub_{module_name}".quoted_contents();
let neg_bench_name = f"neg_{module_name}".quoted_contents();
let mul_bench_name = f"mul_{module_name}".quoted_contents();
let eq_bench_name = f"eq_{module_name}".quoted_contents();
let validate_on_curve_bench_name = f"validate_on_curve_{module_name}".quoted_contents();
let evaluate_linear_expression_bench_name =
f"evaluate_linear_expression_{module_name}".quoted_contents();
let hash_to_curve_bench_name = f"hash_to_curve_{module_name}".quoted_contents();
let BigCurve = quote { crate::BigCurve };
let ScalarField = quote { crate::ScalarField };

let typ = params.as_type();

quote {
#[export]
fn $add_bench_name(a: $typ, b: $typ) -> $typ {
a + b
}

#[export]
fn $sub_bench_name(a: $typ, b: $typ) -> $typ {
a-b
}

#[export]
fn $neg_bench_name(a: $typ) -> $typ {
-a
}

#[export]
fn $eq_bench_name(a: $typ, b: $typ) -> bool {
a==b
}
#[export]
fn $validate_on_curve_bench_name(a: $typ) {
$BigCurve::validate_on_curve(a);
}

#[export]
fn $mul_bench_name(a: $typ, b: $ScalarField<64>) -> $typ {
$BigCurve::mul(a, b)
}

#[export]
fn $hash_to_curve_bench_name(a: [u8; 10]) -> $typ {
$BigCurve::hash_to_curve(a)
}

#[export]
fn $evaluate_linear_expression_bench_name(a: [$typ; 3], b: [$ScalarField<64>; 3], c: [$typ; 2]) -> $typ {
$BigCurve::evaluate_linear_expression(a, b, c)
}

}
}

#[make_bench(quote { BN254 })]
mod BN254_Bench {}

#[make_bench(quote { BLS12_381 })]
mod BLS12_381_Bench {}

#[make_bench(quote { BLS12_377 })]
mod BLS12_377_Bench {}

#[make_bench(quote { MNT4_753 })]
mod MNT4_753_Bench {}

#[make_bench(quote { MNT6_753 })]
mod MNT6_753_Bench {}

#[make_bench(quote { Pallas })]
mod Pallas_Bench {}

#[make_bench(quote { Secp256k1 })]
mod Secp256k1_Bench {}

#[make_bench(quote { Secp256r1 })]
mod Secp256r1_Bench {}

#[make_bench(quote { Secp384r1 })]
mod Secp384r1_Bench {}

#[make_bench(quote { Vesta })]
mod Vesta_Bench {}
1 change: 1 addition & 0 deletions src/benchmarks/mod.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mod bigcurve_benchmarks;
3 changes: 2 additions & 1 deletion src/lib.nr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pub mod scalar_field;
pub(crate) mod curve_jac;
mod test_data;
mod bigcurve_test;
pub mod scalar_field;
pub(crate) mod utils;
pub(crate) mod curves;

Expand All @@ -11,6 +11,7 @@ use bignum::bignum::evaluate_quadratic_expression;
use crate::curve_jac::AffineTranscript;
use crate::scalar_field::ScalarField;
use std::ops::{Add, Neg, Sub};
mod benchmarks;

/// Implements an elliptic curve over a prime field that is not the circuit's native field.

Expand Down
2 changes: 1 addition & 1 deletion src/utils/derive_offset_generators.nr
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ where
#[test]
fn test_compute_and_print_offset_generators() {
unsafe {
let _ = <BN254 as BigCurve<BN254_Fq>>::one();
let _ = BN254::one();
compute_and_print_offset_generators::<BN254_Fq, _, _, 64, BN254>("BN254_Fq", "BN254", 1);
// compute_and_print_offset_generators::<PallasBN, _, _, 64>("Pallas_Fq", "Pallas", 1);
// compute_and_print_offset_generators::<VestaBN, _, _, 64>("Vesta_Fq", "Vesta", 1);
Expand Down