Skip to content

feat: merge-train/barretenberg#23861

Merged
AztecBot merged 4 commits into
nextfrom
merge-train/barretenberg
Jun 4, 2026
Merged

feat: merge-train/barretenberg#23861
AztecBot merged 4 commits into
nextfrom
merge-train/barretenberg

Conversation

@AztecBot

@AztecBot AztecBot commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

BEGIN_COMMIT_OVERRIDE
feat: optimize sumcheck in ECCVM and Translator (#23615)
END_COMMIT_OVERRIDE

# ECCVM & Translator sumcheck prover optimizations

Summary of the prover-side sumcheck optimizations introduced for the
ECCVM and Translator
Goblin VMs (PR #23615, `feat: optimize sumcheck in ECCVM and
Translator`).

## Invariant: prover-only, soundness-safe

Every optimization here changes **only the prover**. The native and
recursive verifiers evaluate
all relations unconditionally and consume a proof and verification key
**identical** to the legacy
`ECCVMFlavor` / `TranslatorFlavor`. Consequences:

- A faulty skip or shortened length can only break **completeness** (the
honest proof fails to
  verify), never **soundness**.
- The prover runs sumcheck on dedicated `ECCVMShortMonomialFlavor` /
`TranslatorShortMonomialFlavor`
classes that inherit all entity/VK definitions from the legacy flavors.
`ECCVMProver`,
`TranslatorProver` and `TranslatorProvingKey` are bound to these short
flavors.
- The edge-by-edge equivalence tests
(`ShortMonomialRelationsMatchFullEdgeRelations` for both VMs)
assert each short relation reproduces its legacy counterpart's
per-subrelation output exactly,
guarding the completeness risk. `ShortMonomialProverVerifies` runs the
full short-prover →
  legacy-verifier roundtrip.

## The six techniques

### 1. Coefficient-basis ("short monomial") accumulation — the
foundation

Relations accumulate in the monomial/coefficient basis
(`CoefficientAccumulator`) instead of the
evaluation (Lagrange) basis. A degree-1 edge is carried as its 2
coefficients `{c0, c1}` rather than
evaluations at many points, so per-edge multiplies happen on short
coefficient vectors and are
extended to full `Univariate` length only at the end. This is what
"short" refers to.

### 2. Per-subrelation partial-length tightening

The legacy flavor over-provisions every subrelation to a single
conservative
`MAX_PARTIAL_RELATION_LENGTH`. Each short relation overrides
`SUBRELATION_PARTIAL_LENGTHS` to its
true `degree + 1`:

- Independent "tail" subrelations (`INACTIVE_*`, `CONTINUITY_*`,
`PHASE_SELECTOR_*`, degree-2
  boundary/infinity checks) shrink to their real minimum (2–5).
- Subrelations that share promoted intermediates (LAMBDA, ACCUMULATOR
updates, SLOPE / COLLISION
groups) are deliberately kept at length 8 to preserve reuse of those
intermediates.
- Flavor-level `MAX_PARTIAL_RELATION_LENGTH` is unchanged, so the proof
and alpha batching are
  identical.

### 3. Region-skip predicates per relation

Each short relation carries a `skip()` predicate that short-circuits the
whole relation on edges
where its contribution is identically zero. The predicate must remain
sound on **boundary edges**
(a zero row adjacent to an active row) and on the **randomized disabled
(ZK-masking) rows**.

| Relation | Skip condition | Subtlety handled |
|---|---|---|
| ECCVM transcript (outside transcript region) | all op selectors +
`msm_count` + accumulator state + boundary Lagranges zero |
accumulator-state wires keep the *finalize* row live; `lagrange_third`
must be included (omitting it broke an earlier attempt) |
| ECCVM wnaf (outside precompute region) | `precompute_select` **and**
`precompute_select_shift` both zero | the shift keeps the region's first
row live |
| Translator delta-range (constant sorted runs) | all 5 deltas constant
over edge **and** `lagrange_real_last` zero | sorted wires are constant
across runs, so `δ(δ−1)(δ−2)(δ−3)` vanishes; max-value subrelations
guarded behind `lagrange_real_last` |
| Translator zero-constraints | `s = lagrange_odd + lagrange_even +
lagrange_mini_masking` constant over edge | also elides the large
zero-padding tail that previously dominated this relation's cost |

### 4. Splitting monolithic relations to enable finer skips

A single relation spanning several subtables can only skip on the global
tail (already excluded by
the active-prefix manifest). Splitting lets each piece carry its own
region skip:

- **Bools** (23 booleanity checks) → `ECCVMBoolsTranscriptShortRelation`
(13 transcript-family) +
`ECCVMBoolsMsmShortRelation` (10 msm/precompute-family), each skipping
when its group's summed
wires are zero. `w·(w−1)` has no shift, so it vanishes exactly where the
wire is constant 0/1
  across the edge.
- **Transcript** → main relation +
`ECCVMTranscriptMsmTransitionShortRelation` holding the five
degree-3–5 curve-arithmetic subrelations (offset-generator,
MSM-infinity) gated by
`msm_transition` (active on ≤1 row per MSM), skipped via
`msm_transition.is_zero()`.

Both splits reorder the legacy subrelation enum so the split groups are
contiguous and the global
subrelation order — hence alpha batching and the proof — is preserved.
(This is the renumbering in
`relations/ecc_vm/ecc_msm_relation.hpp`.)

### 5. Translator permutation boundary-subrelation skip

The two grand-product boundary subrelations (`lagrange_last ·
z_perm_shift`,
`lagrange_first · z_perm`) are nonzero only on the last/first row but
were computed on every edge.
The prover now skips the product where the selector is identically zero,
while the verifier computes
unconditionally. Guarded by the accumulator type so the in-circuit
recursive verifier — where
branching on a witness value is invalid — never branches:

```cpp
if constexpr (std::is_same_v<Accumulator, FF>) {          // verifier: single point
    std::get<1>(accumulators) += Accumulator(lagrange_last_scaled * z_perm_shift);
} else if (!in.lagrange_last.is_zero()) {                 // prover: skip off-boundary edges
    std::get<1>(accumulators) += Accumulator(lagrange_last_scaled * z_perm_shift);
}
```

Lives in
`relations/translator_vm/translator_permutation_short_relation_impl.hpp`.

> A more aggressive variant — computing the degree-4 permutation
grand-product factors via a
> subproduct tree at the minimal Lagrange length (3) before extending —
was committed against the
> **shared** `relations/permutation_relation.hpp` and then fully
reverted (commits `5e8b9063` →
> `fe19ea0`). The shared file is byte-for-byte identical to baseline;
only the lightweight
> per-edge boundary skip above remains. Also note `perf: fold translator
short relation scaling`
> and `perf: pair translator short relation products` restructure the
permutation factor multiplies
> to share work.

### 6. Sumcheck-level row-skip scan (`sumcheck/sumcheck_round.hpp`)

Instead of running `skip_entire_row` over the whole padded trace every
round:

- **ECCVM** exposes a *static* active-prefix manifest
(`row_skip_active_prefix_end`): the prover
scans only `[head, active_prefix)` plus the final Lagrange-last
edge-pair. The prefix is halved
each round and threaded through `PartiallyEvaluatedMultivariates` /
`partially_evaluate`. It is
  tight by construction.
- **Translator** uses the *dynamic* `skip_entire_row` scan. A static
manifest was tried but
over-covered the fixed-size translator trace and regressed the Chonk
joint sumcheck
(~+50% on `execute_joint_sumcheck_rounds`, ~2–4% end-to-end), so it was
removed along with the
`RowSkipRange` / `fold_row_skip_ranges` / `compute_row_skip_ranges`
machinery.

---------

Co-authored-by: AztecBot <tech@aztec-labs.com>

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

🤖 Auto-approved

@AztecBot AztecBot enabled auto-merge June 4, 2026 17:51
@AztecBot

AztecBot commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator Author

🤖 Auto-merge enabled after 4 hours of inactivity. This PR will be merged automatically once all checks pass.

@AztecBot AztecBot added this pull request to the merge queue Jun 4, 2026
@AztecBot

AztecBot commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator Author

🤖 Auto-merge enabled after 4 hours of inactivity. This PR will be merged automatically once all checks pass.

Merged via the queue into next with commit 18a23b8 Jun 4, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants