perf(prover): run the first sumcheck round in the base field#471
Draft
BornPsych wants to merge 5 commits into
Draft
perf(prover): run the first sumcheck round in the base field#471BornPsych wants to merge 5 commits into
BornPsych wants to merge 5 commits into
Conversation
Two #[ignore] probes for manual profiling: a size sweep (BF vs EF vs bn254, 2^14..2^20) and a 2^20 goldilocks-BF flamegraph + stage breakdown. Timing excludes scheme construction and harness clones (prove_setup builds inputs outside the timer; time_prove_core measures only commit + prove_noir), and the flame layer installs after fixture generation, so the numbers reflect the true prove core. Profiling-only deps (inferno, tracing-flame).
cargo fmt rewrapping of comments trimmed in earlier commits; no code change.
Round 1 of the Spartan sumcheck can consume base-field a, b, c directly (one mixed mul per point against the ext eq) instead of lifting them first; the fold at the first challenge does the lift. These helpers provide that round evaluation and fold, with parity against the existing fused ext path pinned by tests.
The witness bounds a, b, c were lifted to the extension before the sumcheck, paying ext arithmetic on base data for every round. The first round (half the sumcheck work) now consumes them directly — base products with one mixed mul per point against the ext eq — and the fold at the first challenge does the lift. Transcript values are unchanged (subfield arithmetic, same elements), so the verifier and proof format are untouched; bn254 rides the same path via Identity. ~5% prove @2^20 goldilocks-BF, no bn254 regression.
- prover: precompute 1/2 once and pass it into combined_round_message instead of recomputing a field inverse every round (transcript-identical) - deps: move inferno/tracing-flame to root [workspace.dependencies] - fixtures: relocate the single-commit timed prove into harness.rs and point the flamegraph probe at target/profile/
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
CSP benchmarks
Prover time, peak RSS, peak heap, and verifier time are arithmetic means across the iterations. Peak heap comes from the largest Each metric cell shows the current value followed by the percentage delta against the latest successful Results
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Runs the first Spartan sumcheck round over the base field. After the witness became
base-committed (#470), the opening round still lifted the
a, b, cmles into the extensionbefore folding. This computes round 0's cubic evaluations directly on the base-field mles
(one mixed base×ext multiply per point against the extension
eq), then lifts into theextension only at the round-0 challenge. It also extracts the per-round message construction
into a shared
combined_round_messagehelper and adds the base-field sumcheck primitives itneeds. A pair of
#[ignore]d profiling probes are included so the win is reproducible in-tree.Stacks on #470 (base-field witness commitment). Independent of the CI guard (#469).
Why
On the Goldilocks base-field path the witness mles are 64-bit
Field64, but the sumcheckeqand challenges live in the degree-3 extension
Field64_3. Liftinga, b, cto the extensionbefore the first fold pays extension-width multiplies for data that is still base-valued. Doing
round 0 in the base field removes one round's worth of extension multiplies — ~5% prove-time at
2^20 on the goldilocks base-field path. bn254 rides the identity embedding, so its path is a
no-op (base == ext) and its proofs are unchanged.
What changed
provekit-common—common/src/utils/sumcheck.rsgainsmixed_sumcheck_map_reduceandmixed_fold: reduce/fold the leading variable of base-field mles against an extension-fieldeq/challenge. Because the base→ext embeddingmapis a ring homomorphism, fold-then-lift isbit-identical to the old lift-then-fold — pinned by
test_mixed_map_reduce_matches_liftedandtest_explicit_mixed_fold_matches_fused_fold.provekit-prover—prover/src/whir_r1cs.rs: round 0 is hoisted out of the sumcheck loopand computed on the base-field mles (the loop now runs
1..m_0); the per-round coefficientcombination (
hhat + rho·g_poly, saved-value equality) is extracted verbatim intocombined_round_messageand shared by round 0 and the loop.provekit-backend-bn254—mavros_prove.rspasses the embedding (&Identity::new()) andthe base-field mles into the prover; identity embedding ⇒ no-op, transcript unchanged.
#[ignore]d) —tooling/provekit-fixtures/tests/profile.rs: a size sweep(BF vs EF vs bn254, 2^14..2^20) and a 2^20 goldilocks-BF flamegraph + stage breakdown. Timing
excludes scheme construction and harness clones. Dev-deps
inferno/tracing-flamearescoped to
provekit-fixturesonly.Transcript / soundness
The prover round messages, challenge draw order, and the separate ext blinding commitment are
unchanged from #470 — the verifier is untouched and replays the identical Fiat-Shamir transcript.
Round 0's base-field evaluations equal the old extension-lifted ones because
mapis a ringhomomorphism (
map(a·b − c) = map(a)·map(b) − map(c),map(0) = 0for zero-padding). Both bn254and goldilocks fixtures still prove→verify.
Out of scope (tracked separately)
Same as #470: this does not touch the Go
recursive-verifier/or theprovekit-gnarkbridge.The reported ~5% is from the local flamegraph probe, not a CI-enforced benchmark.
Verification
cargo fmt --all --check,cargo clippy --all-targets --all-features,cargo build --all-targets --all-features— all green, no new warnings.cargo build --locked -p provekit-fixtures— mergedCargo.lockself-consistent with the newinferno/tracing-flamepins.provekit-common87 (incl. the base/ext parity tests),provekit-r1cs-compiler41.Profiling probes are
#[ignore]d.Commits
5 commits: profiling probes (ignored) · doc-comment rewrap · base-field sumcheck round helpers
(
common) · first sumcheck round in the base field (prover+ bn254 call-site) · reviewfollow-ups (hoist
1/2inverse out of the per-round loop, move the profiling dev-deps to[workspace.dependencies], dedup the single-commit timed prove into the fixtures harness).