Skip to content

feat(stm): add recursive IVC circuit benchmarks#3432

Open
hjeljeli32 wants to merge 20 commits into
mainfrom
hjeljeli32/3412-ivc-recursive-circuit-benchmarks
Open

feat(stm): add recursive IVC circuit benchmarks#3432
hjeljeli32 wants to merge 20 commits into
mainfrom
hjeljeli32/3412-ivc-recursive-circuit-benchmarks

Conversation

@hjeljeli32

@hjeljeli32 hjeljeli32 commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Content

This PR adds benchmarks for the recursive IVC circuit's prover, verifier, off-circuit accumulator fold, and setup. They are driven end-to-end by a thin benchmark-internals-gated façade that delegates to the production IVC proof-system code, so the measured operations are the same code paths run in production. The inner circuit is the small committed (degree-13) non-recursive certificate, sourced from the committed golden assets plus one additive genesis fixture, and every transition path (genesis, same-epoch, next-epoch) is covered.

Each run builds the shared recursive setup once (a full keygen) and reports single-observation timings in consolidated tables. Given a degree-19 recursive proof costs tens of seconds and the keygen runs for minutes, Criterion's sampling is not used (mirroring the existing halo2_prover_modes bench).

Changes

  • Benchmark harness: new mithril-stm/benches/ivc_halo2_snark.rs (gated behind future_snark and
    benchmark-internals), a single-observation report driven by the IvcBenchEnv façade. One shared keygen
    per run; a per-path prove/verify/fold table and a setup cold-vs-warm table.
  • Asset layer / fixtures: moved the read-only IVC asset layer out of the test tree (embedded_assets)
    so benchmarks and tests can share it, and added one additive genesis benchmark fixture. Existing golden
    assets are unchanged.
  • Measured operations: recursive prover (create_proof, Poseidon and Blake2b transcripts); verification
    as both the isolated KZG opening and the full verification (opening plus the folded-accumulator check); the
    off-circuit accumulator fold per transition path (genesis is an accumulator passthrough, so it has no fold);
    and setup cold vs warm, measured separately for the SRS and for the certificate + recursive circuit keys.
  • Façade: added a warm-start SRS load through the production cached read path with the same downsize as
    production setup, symmetric cold_start/warm_start naming, and a measure_keys that mirrors production
    setup (certificate verifying key then recursive key pair) so cold and warm cover the same key layers.
  • CLI: a fail-closed argument parser (in a benchmark-internals-gated bench_cli module, unit-tested) —
    --list to print the ids, an optional single literal id/prefix filter, and rejection of anything that
    could otherwise trigger an accidental multi-minute keygen (e.g. value-taking options, --test,
    --profile-time, regex filters).

Pre-submit checklist

  • Branch
    • Tests are provided (if possible)
    • Crates versions are updated (if relevant)
    • CHANGELOG file is updated (if relevant)
    • Commit sequence broadly makes sense
    • Key commits have useful messages
  • PR
    • All check jobs of the CI have succeeded
    • Self-reviewed the diff
    • Useful pull request description
    • Reviewer requested
  • Documentation
    • No new TODOs introduced

Issue(s)

Closes #3412

Comment thread mithril-stm/src/circuits/halo2_ivc/bench_helpers.rs Fixed
@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown

Test Results

     5 files  ± 0     209 suites  ±0   1h 54m 28s ⏱️ - 1h 19m 22s
 3 373 tests  - 15   3 373 ✅  - 15  0 💤 ±0  0 ❌ ±0 
11 108 runs   - 18  11 108 ✅  - 18  0 💤 ±0  0 ❌ ±0 

Results for commit ec40622. ± Comparison against base commit 2eedbd2.

This pull request removes 23 and adds 8 tests. Note that renamed tests count towards both.
mithril-stm ‑ membership_commitment::merkle_tree::tree::tests::snark::slow::test_create_invalid_proof
mithril-stm ‑ proof_system::halo2_snark::clerk::tests::slow::selection_distributes_fairly_across_index_range
mithril-stm ‑ proof_system::halo2_snark::proof::tests::slow::different_parameters_prove_and_verify_fails
mithril-stm ‑ proof_system::halo2_snark::proof::tests::slow::fails_with_empty_signatures
mithril-stm ‑ proof_system::halo2_snark::proof::tests::slow::fails_with_insufficient_signatures
mithril-stm ‑ proof_system::halo2_snark::proof::tests::slow::golden::golden_aggregate_signature_verifies_with_ancillary
mithril-stm ‑ proof_system::halo2_snark::proof::tests::slow::golden::golden_conversion
mithril-stm ‑ proof_system::halo2_snark::proof::tests::slow::non_deterministic_proofs_verify
mithril-stm ‑ proof_system::halo2_snark::proof::tests::slow::prepare_and_check_fails_with_random_bytes
mithril-stm ‑ proof_system::halo2_snark::proof::tests::slow::prepare_and_check_fails_with_wrong_message
…
mithril-stm ‑ circuits::halo2_ivc::bench::cli::tests::a_single_literal_filter_is_kept
mithril-stm ‑ circuits::halo2_ivc::bench::cli::tests::control_flags_map_to_their_variants
mithril-stm ‑ circuits::halo2_ivc::bench::cli::tests::help_and_version_take_precedence_over_control_flags
mithril-stm ‑ circuits::halo2_ivc::bench::cli::tests::no_args_runs_everything
mithril-stm ‑ circuits::halo2_ivc::bench::cli::tests::tolerated_valueless_flags_do_not_disturb_parsing
mithril-stm ‑ circuits::halo2_ivc::bench::cli::tests::unsupported_and_malformed_inputs_are_rejected
mithril-stm ‑ circuits::halo2_ivc::bench::cli::tests::value_taking_options_are_rejected_not_swallowed
mithril-stm ‑ circuits::halo2_ivc::tests::golden::positive::genesis_benchmark_fixture_is_deterministic_and_valid

♻️ This comment has been updated with latest results.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces an end-to-end benchmark suite for the recursive IVC Halo2 SNARK in mithril-stm, driven through a benchmark-internals-gated façade that delegates to the production proof-system paths. It also refactors the IVC golden-asset layer so both tests and benchmarks can share the same embedded fixtures, and adds a deterministic genesis benchmark fixture plus a fail-closed benchmark CLI filter.

Changes:

  • Add a new ivc_halo2_snark benchmark target with manual single-observation timing tables and a fail-closed CLI filter.
  • Move the read-only embedded golden-asset decoding into a shared embedded_assets module and add an additive genesis benchmark fixture (plus a test to guard determinism/validity).
  • Expose a small set of internal APIs under benchmark-internals to reuse production setup/prove/verify/fold code paths in benchmarks.

Reviewed changes

Copilot reviewed 16 out of 17 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
mithril-stm/src/proof_system/ivc_halo2_snark/verifier_setup.rs Extends test-only verifier-setup constructor gating to benchmarks.
mithril-stm/src/proof_system/ivc_halo2_snark/proof.rs Makes transcript-based proving helper accessible to the benchmark façade.
mithril-stm/src/proof_system/ivc_halo2_snark/mod.rs Re-exports IvcProverInput for benchmarks/tests.
mithril-stm/src/circuits/trusted_setup.rs Exposes unsafe-SRS helpers to benchmarks (previously tests only).
mithril-stm/src/circuits/halo2_ivc/types.rs Allows test helper conversion (from_field) for benchmarks.
mithril-stm/src/circuits/halo2_ivc/tests/golden/positive.rs Adds a determinism/validity guard test for the new genesis benchmark fixture.
mithril-stm/src/circuits/halo2_ivc/tests/common/generators/setup.rs Adds filesystem path for the additive genesis benchmark fixture asset.
mithril-stm/src/circuits/halo2_ivc/tests/common/generators/asset_generation.rs Adds generator + ignored entrypoint to produce the benchmark fixture asset.
mithril-stm/src/circuits/halo2_ivc/tests/common/field_encoding.rs Re-exports field-encoding helper from the shared embedded asset layer.
mithril-stm/src/circuits/halo2_ivc/tests/common/asset_readers.rs Keeps test-only asset writers; re-exports shared embedded loaders/types.
mithril-stm/src/circuits/halo2_ivc/mod.rs Wires in benchmark-only modules and the shared embedded asset module.
mithril-stm/src/circuits/halo2_ivc/embedded_assets.rs New shared read-only embedded asset layer (types + decoders + include_bytes!).
mithril-stm/src/circuits/halo2_ivc/bench_helpers.rs New benchmark façade building setup/fixtures and delegating to production code paths.
mithril-stm/src/circuits/halo2_ivc/bench_cli.rs New fail-closed CLI parser (unit-tested) for benchmark filtering.
mithril-stm/Cargo.toml Registers the new ivc_halo2_snark benchmark with required features.
mithril-stm/benches/ivc_halo2_snark.rs New benchmark harness producing consolidated timing tables (manual timing).
Comments suppressed due to low confidence (1)

mithril-stm/src/circuits/trusted_setup.rs:212

  • TrustedSetupProvider::with_unsafe_srs now compiles under feature = "benchmark-internals", but it still uses multiple unwrap() calls for serialization and filesystem IO. This can panic during benchmark runs (e.g. permission / disk full / temp dir issues) and also violates the project’s “no unwrap outside tests” guideline. Consider returning StmResult<Self> and propagating errors with ? (and Context) instead of panicking.
        let mut srs_bytes = Vec::new();
        srs.write_custom(&mut srs_bytes, SerdeFormat::RawBytes).unwrap();

        let srs_dir = base_dir.join(MITHRIL_CIRCUIT_SRS_FOLDER);
        create_dir_all(&srs_dir).unwrap();

Comment thread mithril-stm/src/proof_system/ivc_halo2_snark/verifier_setup.rs
Comment thread mithril-stm/src/circuits/halo2_ivc/mod.rs
Comment thread mithril-stm/src/circuits/halo2_ivc/embedded_assets.rs
Comment thread mithril-stm/src/proof_system/ivc_halo2_snark/verifier_setup.rs
@hjeljeli32
hjeljeli32 temporarily deployed to testing-2-preview July 24, 2026 00:37 — with GitHub Actions Inactive
@hjeljeli32
hjeljeli32 temporarily deployed to testing-preview July 24, 2026 00:37 — with GitHub Actions Inactive

@jpraynaud jpraynaud left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM 👍

Comment thread mithril-stm/src/proof_system/ivc_halo2_snark/mod.rs Outdated
Comment thread mithril-stm/src/circuits/halo2_ivc/bench/helpers.rs
Comment thread mithril-stm/src/circuits/halo2_ivc/bench/helpers.rs
Comment thread mithril-stm/src/circuits/halo2_ivc/bench_helpers.rs Outdated
Comment thread mithril-stm/src/circuits/halo2_ivc/bench_helpers.rs Outdated
Comment thread mithril-stm/benches/ivc_halo2_snark.rs
Comment thread mithril-stm/benches/ivc_halo2_snark.rs

@damrobi damrobi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM 👍

Comment thread mithril-stm/src/circuits/halo2_ivc/tests/golden/positive.rs Outdated
Comment thread mithril-stm/src/circuits/halo2_ivc/bench_cli.rs Outdated
Comment thread mithril-stm/src/circuits/halo2_ivc/bench_helpers.rs Outdated
…nch modules

Move the benchmark façades and the IVC bench CLI out of the production module namespace into dedicated `bench` submodules (`circuits::halo2_ivc::bench::{helpers,cli}` and `circuits::halo2::bench::helpers`), update the harness imports, and narrow the `IvcProverInput` re-export to the `benchmark-internals` feature.
Split the ~130-line `prepare_certificate_step` into an orchestrator plus `build_certificate_fold_inputs` and `ensure_certificate_prepared_matches_committed`, add a `CertificateStepAsset` (with `From` impls) to unify the same-/next-epoch assets, move the `IvcBenchEnv` definition above its `impl`, and rewrite comments to be self-explanatory (no implementation-plan item references).
Document how to run both circuits' Halo2 benchmarks and, in detail, the recursive IVC harness's CLI (`--list`, `--help`, literal id/prefix filters, the fail-closed rejection rules, and the full benchmark-id scheme), plus the certificate tiers and prerequisites.
Move the sha2 and BaseFieldElement `use` statements out of genesis_benchmark_fixture_is_deterministic_and_valid up to the module's top-level imports.
No benches are ignored, so the Ignored variant never did anything meaningful. Remove it; --ignored is now rejected as an unsupported option (still fail-closed), which also lets the control-mode conflict bookkeeping go. Tests and the harness dispatch updated.
The harness measures the SRS and circuit keys separately (measure_srs_cold_start / measure_srs_warm_start / measure_keys); the combined measure_full_setup loader was never called (undetected because pub lib items are not dead-code-checked).
Align the markdown tables to satisfy `make check-format` (prettier --check); no content change.
@hjeljeli32
hjeljeli32 force-pushed the hjeljeli32/3412-ivc-recursive-circuit-benchmarks branch from a51287a to 671a28b Compare July 27, 2026 00:03
A no-filter run does minutes of silent keygen and proving; emit per-phase progress to stderr (environment build, per-path prove/verify/fold, setup cold/warm) before each step so runs visibly advance. Logging happens outside the timed regions, so measurements are unaffected.
@hjeljeli32
hjeljeli32 force-pushed the hjeljeli32/3412-ivc-recursive-circuit-benchmarks branch from 671a28b to ec40622 Compare July 27, 2026 00:40
@hjeljeli32
hjeljeli32 deployed to testing-preview July 27, 2026 01:45 — with GitHub Actions Active
@hjeljeli32
hjeljeli32 deployed to testing-2-preview July 27, 2026 01:45 — with GitHub Actions Active
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add benchmarks for the IVC SNARK recursive circuit

5 participants