cleanup(stark/constraints): drop coefficient-form leftovers, dedupe eval#604
Conversation
Behaviour-preserving cleanup of `crypto/stark/src/constraints` (plan
items 1-5). The eval-form STARK migration left several pieces of
coefficient-form scaffolding behind.
boundary.rs — remove vestigial pre-eval-form code
- The eval-form prover evaluates boundaries on-the-fly in `evaluator.rs`
(`trace[col] - value`); it never interpolates boundary polynomials.
Deleted the now-unused `steps`, `steps_for_boundary`, `cols_for_boundary`,
`generate_roots_of_unity`, `values`, `compute_zerofier`, and the dead
`new_simple_aux`. Production keeps only the `BoundaryConstraint` /
`BoundaryConstraints` structs, `new_main`/`new_aux`/`new_simple_main`
and `from_constraints`. 153 -> 57 LOC; drops the `itertools` use.
- `tests/boundary_tests.rs` only exercised `compute_zerofier`; removed.
evaluator.rs — remove a no-op debug check
- `check_boundary_polys_divisibility` was called with two always-empty
vecs, so it iterated nothing — a check that checked nothing. Removed
the dead `#[cfg(debug_assertions)]` block (`boundary_polys`,
`boundary_zerofiers`, the unused `_transition_evaluations`), the
function from `debug.rs` (no other caller), and the imports it needed.
This also clears the `unused import: Polynomial` warning in release
builds.
evaluator.rs — deduplicate `evaluate_transitions`
- The parallel and sequential arms repeated ~32 lines of identical
per-row accumulation. Extracted a shared `eval_row` closure; only the
iterator (`into_par_iter().map_init` vs `into_iter().map`) now differs.
Per-thread buffer reuse is unchanged.
transition.rs — hygiene
- `evaluate_zerofier` used `unsafe { …unwrap_unchecked() }` while the
sibling branch used a safe `.unwrap()` on the same invariant. Replaced
with `.expect(...)` — no `unsafe` for skipping one zero-check.
- `std::ops::Div` / `std::iter::zip` -> `core::` to match the module.
123 stark lib tests pass (124 minus the deleted compute_zerofier test);
273 prover lib tests pass; all build configs + lint clean.
Codex Code ReviewNo findings in the PR diff. I reviewed the changed constraint evaluator, boundary cleanup, unsafe-to- Verification note: I attempted to run |
ReviewClean, well-scoped refactor. The deletions are confirmed dead code (no remaining callers), the Low – inconsistency in
|
Codex Code ReviewNo issues found in the PR diff. Security: no Critical/High/Medium/Low vulnerabilities identified in the changed code. The removal of I could not run |
|
Clean, behaviour-preserving refactor. No security issues or bugs found. |
|
unsafe removal (transition.rs) - Replacing unsafe unwrap_unchecked with .expect() is a genuine safety improvement. The original invokes UB if the invariant ever breaks; the new code panics cleanly instead. |
|
Dead debug code removal (evaluator.rs, debug.rs) - check_boundary_polys_divisibility was called with two always-empty Vec::new() vectors so the loop body never executed. Removing it is correct and eliminates the misleading impression that boundary divisibility was being checked in debug builds. |
|
eval_row closure extraction (evaluator.rs) - The parallel and sequential arms are structurally identical to their originals. All captured variables are immutable borrows so Sync constraints for the parallel path are unchanged. The coercions from &mut Vec to &mut slice on the call sites are standard. |
|
Minor - public API break: BoundaryConstraints::new_simple_aux is pub on a pub struct. Removing it is a semver-breaking change for external consumers. If this crate is purely internal or semver is managed separately, no action needed - just note it in the changelog. |
Replaces the coefficient-form `end_exemptions_poly: Polynomial<F>` with two eval-form helpers, removing transition.rs's last dependency on `Polynomial` arithmetic. Stacks on #604 (which removed boundary.rs's `Polynomial` dependency). With both landed, no production code in the prover uses `Polynomial` operators. - `end_exemptions_roots` returns the roots r_i of prod(x - r_i) (<= 2 in the example AIRs, 0 in every VM table). - `end_exemptions_lde_evaluations(domain)` evaluates the product over the precomputed LDE coset directly: an O(N * end_exemptions) loop replaces an O(N log N) FFT. - `evaluate_zerofier`'s OOD path computes prod(z - r_i) directly instead of `Polynomial::evaluate`. Performance: the VM's dominant path (end_exemptions == 0) is unchanged - the existing else-branch early-return is preserved bit-for-bit, so that case still returns the short cyclic vector instead of expanding it. The k > 0 path (example AIRs only) goes from FFT to direct product, strictly faster. Correctness verified by `cargo test -p stark` (125/125, includes the fibonacci and read-only-memory AIRs with end_exemptions = 1 and 2 - exactly the eval-form k > 0 path). VM prover lib test counts are identical to the #604 baseline (273 pass, 77 pre-existing failures unrelated to constraints).
Behaviour-preserving cleanup of
crypto/stark/src/constraints(plan items 1-5). The eval-form STARK migration left several pieces of coefficient-form scaffolding behind.boundary.rs — remove vestigial pre-eval-form code
evaluator.rs(trace[col] - value); it never interpolates boundary polynomials. Deleted the now-unusedsteps,steps_for_boundary,cols_for_boundary,generate_roots_of_unity,values,compute_zerofier, and the deadnew_simple_aux. Production keeps only theBoundaryConstraint/BoundaryConstraintsstructs,new_main/new_aux/new_simple_mainandfrom_constraints. 153 -> 57 LOC; drops theitertoolsuse.tests/boundary_tests.rsonly exercisedcompute_zerofier; removed.evaluator.rs — remove a no-op debug check
check_boundary_polys_divisibilitywas called with two always-empty vecs, so it iterated nothing — a check that checked nothing. Removed the dead#[cfg(debug_assertions)]block (boundary_polys,boundary_zerofiers, the unused_transition_evaluations), the function fromdebug.rs(no other caller), and the imports it needed. This also clears theunused import: Polynomialwarning in release builds.evaluator.rs — deduplicate
evaluate_transitionseval_rowclosure; only the iterator (into_par_iter().map_initvsinto_iter().map) now differs. Per-thread buffer reuse is unchanged.transition.rs — hygiene
evaluate_zerofierusedunsafe { …unwrap_unchecked() }while the sibling branch used a safe.unwrap()on the same invariant. Replaced with.expect(...)— nounsafefor skipping one zero-check.std::ops::Div/std::iter::zip->core::to match the module.123 stark lib tests pass (124 minus the deleted compute_zerofier test); 273 prover lib tests pass; all build configs + lint clean.