Skip to content

Three minor optimizations - #149

Merged
zkfriendly merged 3 commits into
mainfrom
fs/minor-optimizations
Nov 12, 2026
Merged

zkfriendly merged 3 commits into
mainfrom
fs/minor-optimizations

Conversation

@frozenspider

@frozenspider frozenspider commented Nov 11, 2026 •

Copy link
Copy Markdown
Collaborator

This PR introduces 3 small optimizations:

(Timing verified using cargo run --release -p bitz-cli -- circuit-e2e --circuit sha256-chain --num-blocks 600 --threads 5 on my machine)

Precompute MaterializedMTranspose digest at setup.

Phase Step Before After
Setup Build virtual map ~480 ms ~600 ms
P/V Bind circuit statement ~100 ms <1 ms
P/V Bind virtual map digest ~100 ms <0.1 ms

StoredInteger used to be Box<[u64]>, now it can also store single u64 inline.

This allows trivial freeing of SHA-256 witness, and speeds up witness generation as well:

Phase Step Before After
Witness Witness generation ~25 ms ~10 ms
P Free witness ~25 ms ~1 ms

Compute $M^T * v$ without materializing full weights vector $v$

(where $v_{c \cdot 2^t + b} = \mathrm{row\_weights}[b] * \mathrm{column\_weights}[c]$)
Instead we keep row_weights and column_weights separately and materialize when needed.

Phase Step Before After
P/V Transpose claim ~32 ms ~13 ms

Overall, this reduces prover time from 1.5 s to 1.2 s and verifier time from 400 ms to 200 ms.


Some full measurements (highly inconsistent between runs, picked best ones)

Before:

╮ bitz_cli::cmd::circuit_e2e::circuit_e2e circuit=sha256-chain threads=5 field="random-prime" pcs_round_target_bits=100 hash="Blake3"
├─╮ bitz_cli::cmd::circuit_e2e::generate_inputs
├─╯ generate_inputs: 1.26ms duration
├─╮ bitz_cli::end_to_end::setup
│ ├─╮ bitz_cli::end_to_end::Synthesize constraints
│ ├─╯ Synthesize constraints: 8.15s duration
│ ├─╮ spartan::matrix::Prepare integer matrices
│ ├─╯ Prepare integer matrices: 2.70s duration
│ ├─╮ bitz_cli::end_to_end::Build virtual map
│ ├─╯ Build virtual map: 571.60ms duration
├─╯ setup: 11.43s duration
│ 11.43s INFO Circuit prepared opening_path=Virtual pcs_round_target_bits=100 pcs_decoding="list" constraints=417856 assignment_bits=12581057 committed_bits=4132800 padded_committed_bits=4194304 prime_bits=121
├─╮ bitz_cli::end_to_end::witness
├─╯ witness: 31.56ms duration
├─╮ bitz_cli::end_to_end::commit
│ ├─╮ pcs::commitment::Commit witness
│ ├─╯ Commit witness: 1.19ms duration
├─╯ commit: 1.31ms duration
├─╮ bitz_cli::end_to_end::prove opening_path=Virtual
│ ├─╮ bitz_cli::end_to_end::Bind circuit statement
│ ├─╯ Bind circuit statement: 100.69ms duration
│ ├─╮ bitz_cli::end_to_end::Sample prime
│ │ │ 234.88µs INFO Fingerprint prime drawn bits=121 prime=2133862195229426945519506852267065857
│ ├─╯ Sample prime: 287.58µs duration
│ ├─╮ bitz_cli::end_to_end::Project constraint matrices onto random field
│ ├─╯ Project constraint matrices onto random field: 161.52ms duration
│ ├─╮ bitz_cli::end_to_end::Reduce witness modulo prime
│ ├─╯ Reduce witness modulo prime: 187.95ms duration
│ ├─╮ spartan::piop::Prove Spartan
│ │ ├─╮ spartan::sumcheck::Prove outer sumcheck
│ │ ├─╯ Prove outer sumcheck: 23.94ms duration
│ │ ├─╮ spartan::matrix::Bind Spartan matrices
│ │ ├─╯ Bind Spartan matrices: 171.80ms duration
│ │ ├─╮ spartan::sumcheck::Prove inner sumcheck
│ │ ├─╯ Prove inner sumcheck: 434.67ms duration
│ ├─╯ Prove Spartan: 630.66ms duration
│ ├─╮ prover::prove::Prove virtual BitZ
│ │ ├─╮ prover::prove::Bind virtual map digest
│ │ ├─╯ Bind virtual map digest: 98.90ms duration
│ │ ├─╮ prover::fold::Fold columns
│ │ ├─╯ Fold columns: 7.19ms duration
│ │ ├─╮ prover::reduce::Reduce grand products
│ │ │ ├─╮ gkr::Prove GKR
│ │ │ ├─╯ Prove GKR: 97.99ms duration
│ │ ├─╯ Reduce grand products: 212.87ms duration
│ │ ├─╮ prover::prove::Transpose claim
│ │ ├─╯ Transpose claim: 45.58ms duration
│ │ ├─╮ pcs::Prove PCS opening
│ │ │ ├─╮ pcs::opening::Bind opening statement
│ │ │ ├─╯ Bind opening statement: 26.70ms duration
│ │ │ ├─╮ post_gkr::Prove inner-product sumcheck
│ │ │ ├─╯ Prove inner-product sumcheck: 13.36ms duration
│ │ │ ├─╮ pcs::opening::Ring switch
│ │ │ ├─╯ Ring switch: 1.25ms duration
│ │ │ ├─╮ pcs::ligerito::Prove Ligerito
│ │ │ ├─╯ Prove Ligerito: 2.45ms duration
│ │ ├─╯ Prove PCS opening: 43.88ms duration
│ ├─╯ Prove virtual BitZ: 411.37ms duration
│ ├─╮ bitz_cli::end_to_end::Free witness
│ ├─╯ Free witness: 25.68ms duration
├─╯ prove: 1.52s duration
├─╮ bitz_cli::end_to_end::verify
│ ├─╮ bitz_cli::end_to_end::Bind circuit statement
│ ├─╯ Bind circuit statement: 98.62ms duration
│ ├─╮ bitz_cli::end_to_end::Sample prime
│ │ │ 347.79µs INFO Fingerprint prime drawn bits=121 prime=2133862195229426945519506852267065857
│ ├─╯ Sample prime: 554.00µs duration
│ ├─╮ bitz_cli::end_to_end::Project constraint matrices onto random field
│ ├─╯ Project constraint matrices onto random field: 13.99ms duration
│ ├─╮ spartan::piop::Verify Spartan
│ │ ├─╮ spartan::sumcheck::Verify outer sumcheck
│ │ ├─╯ Verify outer sumcheck: 64.96µs duration
│ │ ├─╮ spartan::piop::Verify inner sumcheck
│ │ ├─╯ Verify inner sumcheck: 15.04µs duration
│ ├─╯ Verify Spartan: 94.93ms duration
│ ├─╮ verifier::verify::Verify virtual BitZ
│ │ ├─╮ verifier::verify::Bind virtual map digest
│ │ ├─╯ Bind virtual map digest: 98.04ms duration
│ │ ├─╮ verifier::fold::Verify column folds
│ │ ├─╯ Verify column folds: 12.86ms duration
│ │ ├─╮ verifier::reduce::Verify grand-product reduction
│ │ │ ├─╮ gkr::Verify GKR
│ │ │ ├─╯ Verify GKR: 149.54µs duration
│ │ ├─╯ Verify grand-product reduction: 364.25µs duration
│ │ ├─╮ verifier::verify::Transpose claim
│ │ ├─╯ Transpose claim: 36.23ms duration
│ │ ├─╮ pcs::Verify PCS opening
│ │ │ ├─╮ pcs::opening::Bind opening statement
│ │ │ ├─╯ Bind opening statement: 26.87ms duration
│ │ │ ├─╮ post_gkr::Verify inner-product sumcheck
│ │ │ ├─╯ Verify inner-product sumcheck: 2.41ms duration
│ │ │ ├─╮ pcs::opening::Verify ring switch
│ │ │ ├─╯ Verify ring switch: 23.58µs duration
│ │ │ ├─╮ pcs::ligerito::Verify Ligerito
│ │ │ ├─╯ Verify Ligerito: 1.09ms duration
│ │ ├─╯ Verify PCS opening: 30.72ms duration
│ ├─╯ Verify virtual BitZ: 181.47ms duration
├─╯ verify: 398.15ms duration
│ 14.47s INFO Proof verified successfully
circuit=sha256-chain threads=5 field=random-prime pcs_round_target_bits=100 security_model=classical-pcs-round-budget relation=r1cs constraints_verified=true
opening_path=Virtual pcs_round_target_bits=100 constraints=417856 assignment_bits=12581057 committed_bits=4132800 padded_committed_bits=4194304 prime_bits=121 setup_ms=11426.000 witness_ms=31.589 commit_ms=1.320 prove_ms=1520.299 total_prove_ms=1521.619 verify_ms=398.181
╯ circuit_e2e: 14.47s duration

After:

╮ bitz_cli::cmd::circuit_e2e::circuit_e2e circuit=sha256-chain threads=5 field="random-prime" pcs_round_target_bits=100 hash="Blake3"
├─╮ bitz_cli::cmd::circuit_e2e::generate_inputs
├─╯ generate_inputs: 1.06ms duration
├─╮ bitz_cli::end_to_end::setup
│ ├─╮ bitz_cli::end_to_end::Synthesize constraints
│ ├─╯ Synthesize constraints: 6.33s duration
│ ├─╮ spartan::matrix::Prepare integer matrices
│ ├─╯ Prepare integer matrices: 2.45s duration
│ ├─╮ bitz_cli::end_to_end::Build virtual map
│ ├─╯ Build virtual map: 528.47ms duration
├─╯ setup: 9.31s duration
│ 9.31s INFO Circuit prepared opening_path=Virtual pcs_round_target_bits=100 pcs_decoding="list" constraints=417856 assignment_bits=12581057 committed_bits=4132800 padded_committed_bits=4194304 prime_bits=121
├─╮ bitz_cli::end_to_end::witness
├─╯ witness: 10.32ms duration
├─╮ bitz_cli::end_to_end::commit
│ ├─╮ pcs::commitment::Commit witness
│ ├─╯ Commit witness: 1.23ms duration
├─╯ commit: 1.25ms duration
├─╮ bitz_cli::end_to_end::prove opening_path=Virtual
│ ├─╮ bitz_cli::end_to_end::Bind circuit statement
│ ├─╯ Bind circuit statement: 315.92µs duration
│ ├─╮ bitz_cli::end_to_end::Sample prime
│ │ │ 313.14µs INFO Fingerprint prime drawn bits=121 prime=2569518001905800193744301660206921761
│ ├─╯ Sample prime: 365.57µs duration
│ ├─╮ bitz_cli::end_to_end::Project constraint matrices onto random field
│ ├─╯ Project constraint matrices onto random field: 131.13ms duration
│ ├─╮ bitz_cli::end_to_end::Reduce witness modulo prime
│ ├─╯ Reduce witness modulo prime: 207.07ms duration
│ ├─╮ spartan::piop::Prove Spartan
│ │ ├─╮ spartan::sumcheck::Prove outer sumcheck
│ │ ├─╯ Prove outer sumcheck: 22.40ms duration
│ │ ├─╮ spartan::matrix::Bind Spartan matrices
│ │ ├─╯ Bind Spartan matrices: 157.77ms duration
│ │ ├─╮ spartan::sumcheck::Prove inner sumcheck
│ │ ├─╯ Prove inner sumcheck: 410.38ms duration
│ ├─╯ Prove Spartan: 590.70ms duration
│ ├─╮ prover::prove::Prove virtual BitZ
│ │ ├─╮ prover::prove::Bind virtual map digest
│ │ ├─╯ Bind virtual map digest: 3.37µs duration
│ │ ├─╮ prover::fold::Fold columns
│ │ ├─╯ Fold columns: 5.89ms duration
│ │ ├─╮ prover::reduce::Reduce grand products
│ │ │ ├─╮ gkr::Prove GKR
│ │ │ ├─╯ Prove GKR: 81.02ms duration
│ │ ├─╯ Reduce grand products: 187.83ms duration
│ │ ├─╮ prover::prove::Transpose claim
│ │ ├─╯ Transpose claim: 14.77ms duration
│ │ ├─╮ pcs::Prove PCS opening
│ │ │ ├─╮ pcs::opening::Bind opening statement
│ │ │ ├─╯ Bind opening statement: 28.82ms duration
│ │ │ ├─╮ post_gkr::Prove inner-product sumcheck
│ │ │ ├─╯ Prove inner-product sumcheck: 12.97ms duration
│ │ │ ├─╮ pcs::opening::Ring switch
│ │ │ ├─╯ Ring switch: 981.38µs duration
│ │ │ ├─╮ pcs::ligerito::Prove Ligerito
│ │ │ ├─╯ Prove Ligerito: 2.63ms duration
│ │ ├─╯ Prove PCS opening: 45.59ms duration
│ ├─╯ Prove virtual BitZ: 256.97ms duration
│ ├─╮ bitz_cli::end_to_end::Free witness
│ ├─╯ Free witness: 971.06µs duration
├─╯ prove: 1.19s duration
├─╮ bitz_cli::end_to_end::verify
│ ├─╮ bitz_cli::end_to_end::Bind circuit statement
│ ├─╯ Bind circuit statement: 506.04µs duration
│ ├─╮ bitz_cli::end_to_end::Sample prime
│ │ │ 329.58µs INFO Fingerprint prime drawn bits=121 prime=2569518001905800193744301660206921761
│ ├─╯ Sample prime: 380.02µs duration
│ ├─╮ bitz_cli::end_to_end::Project constraint matrices onto random field
│ ├─╯ Project constraint matrices onto random field: 22.15ms duration
│ ├─╮ spartan::piop::Verify Spartan
│ │ ├─╮ spartan::sumcheck::Verify outer sumcheck
│ │ ├─╯ Verify outer sumcheck: 25.86µs duration
│ │ ├─╮ spartan::piop::Verify inner sumcheck
│ │ ├─╯ Verify inner sumcheck: 14.87µs duration
│ ├─╯ Verify Spartan: 94.83ms duration
│ ├─╮ verifier::verify::Verify virtual BitZ
│ │ ├─╮ verifier::verify::Bind virtual map digest
│ │ ├─╯ Bind virtual map digest: 2.79µs duration
│ │ ├─╮ verifier::fold::Verify column folds
│ │ ├─╯ Verify column folds: 12.67ms duration
│ │ ├─╮ verifier::reduce::Verify grand-product reduction
│ │ │ ├─╮ gkr::Verify GKR
│ │ │ ├─╯ Verify GKR: 152.30µs duration
│ │ ├─╯ Verify grand-product reduction: 370.11µs duration
│ │ ├─╮ verifier::verify::Transpose claim
│ │ ├─╯ Transpose claim: 13.44ms duration
│ │ ├─╮ pcs::Verify PCS opening
│ │ │ ├─╮ pcs::opening::Bind opening statement
│ │ │ ├─╯ Bind opening statement: 27.28ms duration
│ │ │ ├─╮ post_gkr::Verify inner-product sumcheck
│ │ │ ├─╯ Verify inner-product sumcheck: 2.63ms duration
│ │ │ ├─╮ pcs::opening::Verify ring switch
│ │ │ ├─╯ Verify ring switch: 29.40µs duration
│ │ │ ├─╮ pcs::ligerito::Verify Ligerito
│ │ │ ├─╯ Verify Ligerito: 1.18ms duration
│ │ ├─╯ Verify PCS opening: 31.52ms duration
│ ├─╯ Verify virtual BitZ: 60.86ms duration
├─╯ verify: 180.54ms duration
│ 11.50s INFO Proof verified successfully
circuit=sha256-chain threads=5 field=random-prime pcs_round_target_bits=100 security_model=classical-pcs-round-budget relation=r1cs constraints_verified=true
opening_path=Virtual pcs_round_target_bits=100 constraints=417856 assignment_bits=12581057 committed_bits=4132800 padded_committed_bits=4194304 prime_bits=121 setup_ms=9312.844 witness_ms=10.335 commit_ms=1.301 prove_ms=1189.104 total_prove_ms=1190.405 verify_ms=180.560
╯ circuit_e2e: 11.50s duration

@frozenspider
frozenspider added this pull request to stack #150 November 11, 2026 10:21
@frozenspider
frozenspider force-pushed the fs/minor-optimizations branch from 27f1498 to f5a3ed7 Compare November 11, 2026 11:47
@frozenspider frozenspider changed the title [WIP] Minor optimizations Three minor optimizations Nov 11, 2026
@frozenspider
frozenspider marked this pull request as ready for review November 11, 2026 16:28
Base automatically changed from f/better-bench to main November 11, 2026 16:53
@zkfriendly
zkfriendly force-pushed the fs/minor-optimizations branch from f5a3ed7 to 6681fd1 Compare November 11, 2026 16:53

@zkfriendly zkfriendly 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.

Thanks for the PR. Everything looks correct. I also ran the benchmarks on smaller and larger sha-256 inputs and 1 5 and 16 threads and all showed faster proofs overall.

@zkfriendly
zkfriendly merged commit c385abd into main Nov 12, 2026
3 checks passed
@zkfriendly
zkfriendly deleted the fs/minor-optimizations branch November 12, 2026 09:10
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.

2 participants