Perf/verifier recursion opts#636
Conversation
…fy; borrow lookup challenges
Codex Code ReviewNo issues found in the PR diff. I reviewed the changed verifier logic for security, correctness, significant performance regressions, and unnecessary complexity, and didn’t find an actionable concern limited to these changes. |
| // it is the number of composition poly parts the proof advertises (the | ||
| // same array the consumer validates against). Hoist `z^N` once. | ||
| let number_of_parts = proof.composition_poly_parts_ood_evaluation.len(); | ||
| let z_pow = challenges.z.pow(number_of_parts); |
There was a problem hiding this comment.
Low – silent semantic change for malformed proofs
number_of_parts is now taken from proof.composition_poly_parts_ood_evaluation.len() (the OOD header), whereas the old code took it from lde_composition_poly_parts_evaluation.len() (the LDE opening evaluations slice).
For valid proofs these are always equal, so there is no regression. For a malformed proof where the opening carries fewer parts than the header (M < N), the old code silently computed z^M (wrong denominator) and then hit None on the subsequent gammas.get(j)?; the new code computes the correct z^N from the start. This is actually a fix, but it is an implicit behavioral change worth calling out explicitly.
Consider adding a validation check so the caller fails fast and the intent is clear:
| let z_pow = challenges.z.pow(number_of_parts); | |
| let number_of_parts = proof.composition_poly_parts_ood_evaluation.len(); | |
| let z_pow = challenges.z.pow(number_of_parts); | |
| // All openings must carry the same part count as the OOD header; validated | |
| // per-entry inside reconstruct_deep_composition_poly_evaluation via the | |
| // gammas/ood bounds checks there. |
| // (it is stored owned in the returned `Challenges`). Clone exactly once | ||
| // here, where ownership is actually required — this removes the | ||
| // per-table clone that previously lived at the `multi_verify` call site. |
There was a problem hiding this comment.
Low – comment overstates the allocation saving
The clone is not eliminated — it moves from the call site (lookup_challenges.clone()) into verify_rounds_2_to_4 (rap_challenges.to_vec()). Total allocations per-table is unchanged.
The real wins from this PR are:
logup_alpha_powerscomputed once globally instead of once per table.- A single
inplace_batch_inverseacross all query denominators instead of one per query.
The comment should reflect that, so future readers don't expect a measurable per-table allocation reduction from this line change alone.
Review: Perf/verifier recursion optsSummaryTwo orthogonal performance improvements to the STARK verifier:
The two-pass refactoring (collect denominators → batch invert → reconstruct) is sound. Ordering of IssuesLow — Low — misleading clone comment (see inline comment on L1155-1157) No issues found with
|
|
/bench 5 |
Benchmark — fib_iterative_8M (median of 5)Table parallelism: auto (cores / 3)
Commit: 2a4cb75 · Baseline: cached · Runner: self-hosted bench |
…erify, opening short-circuit)
Toggles the keccak-precompile [patch] in an external recursion-guest Cargo.toml, runs the verify bench both ways, prints the cycle comparison. Parameterized by GUEST_DIR + VERIFY_BENCH_CMD (the guest harness lives outside this repo).
No description provided.