Skip to content

feat: merge-train/barretenberg#22689

Merged
AztecBot merged 6 commits into
nextfrom
merge-train/barretenberg
Apr 21, 2026
Merged

feat: merge-train/barretenberg#22689
AztecBot merged 6 commits into
nextfrom
merge-train/barretenberg

Conversation

@AztecBot

@AztecBot AztecBot commented Apr 21, 2026

Copy link
Copy Markdown
Collaborator

BEGIN_COMMIT_OVERRIDE
chore!: masking at the top of the trace (#22334)
chore: Fix translator's static assert (#22695)
chore: bump mem for large circuit test (#22690)
END_COMMIT_OVERRIDE

## Summary

### Motivation

Previously, ZK masking used tail masking: random values were stored in
separate `MaskingTailData` polynomials at the end of the trace. This
forced all PCS code to be `dyadic_size` dependent — the batched
polynomial `A₀`, Gemini folds, and Shplonk quotient all had to be
allocated and operated at `dyadic_size` because the masking tails
extended to the last rows. The row-disabling polynomial was also
circuit-size dependent (`1 - L_{n-1} - ... - L_{n-4}`), requiring a
`padding_indicator_array` to handle padded sumcheck rounds.

### What Changed

Top-of-trace masking: Random masking values are written directly into
witness polynomials at rows `{1, 2, 3}` during allocation. The
row-disabling polynomial disables the first 4 rows (`0–3`) instead of
the last 4. `lagrange_first` moves from row `0` to row `TRACE_OFFSET (=
4)`.

### Key Benefits

* PCS decoupled from `dyadic_size`: With masking at low indices,
committed polynomials only extend to `max_end_index()` (the actual trace
extent), not `dyadic_size`. Gemini fold polynomials already track
`actual_size` from `A_0.end_index()`. This enables future non-dyadic PCS
proving where sparse circuits avoid paying for the full power-of-2
padding.
* Circuit-size-independent row-disabling: The polynomial `1 -
∏_{i≥2}(1-u_i)` depends only on sumcheck challenges, not circuit size.
The `padding_indicator_array` is eliminated.
* Simpler code: Removed `MaskingTailData` (218 lines),
`padding_indicator_array` (93+134 lines), and all tail-batching logic.
Net `-707` lines across 103 files.
* Unified verifier paths: Sumcheck and Shplemini verifiers no longer
take `padding_indicator_array` parameters. This simplifies native,
recursive, and AVM verifier flows alike.

### Merge Protocol and ECC Op Wire Changes

Moving `lagrange_first` from row `0` to row `TRACE_OFFSET (= 4)` shifts
the entire execution trace down by 4 rows. In Mega, the `ecc_op` block
now starts at `trace_offset() = TRACE_OFFSET + 1 = 5`, and `ecc_op_wire`
data sits one row before at row `TRACE_OFFSET = 4` (to satisfy the
`ecc_op_wire[row] == w_shift[row]` constraint).

The merge protocol must match this layout: it prepends `TRACE_OFFSET`
zeros to its table polynomials (`L`, `R`, and `M` in PREPEND mode) so
that the prover's Shplonk quotient is consistent with the `ecc_op_wire`
commitments held by the verifier. Previously, these polynomials started
at row `0`; now they start at row `TRACE_OFFSET` to align with the
shifted circuit layout.

The Translator receives its op queue data from Mega's `ecc_op_wires`.
Since the merge protocol handles the offset alignment in chonk, standard
Mega → Translator flows work correctly. However, the two-layer AVM flow
(AVM recursive verifier inside a Mega circuit) required adding
`TRACE_OFFSET = 0` to the standalone AVM flavor. The `MegaAVM` flavor
inherits Mega's `TRACE_OFFSET = 4`, so `ecc_op_wires` in the outer Mega
circuit are offset. The inner AVM has no disabled region (`TRACE_OFFSET
= 0`), but since it runs inside a Mega wrapper that handles the merge
protocol, the op queue data alignment stays consistent across the
boundary.

### Files Changed (103 files, +1484/-2191)

#### Deleted

* `sumcheck/masking_tail_data.hpp` — tail masking infrastructure
* `stdlib/primitives/padding_indicator_array/` — virtual-round indicator
for old row-disabling

#### Added

* `ultra_honk/zk_boundary.test.cpp` — tests for masking layout, `ecc_op`
alignment, row-disabling

#### Core changes

* Prover instance (`prover_instance.cpp`): Polynomials allocated with
`add_masking()` at rows `{1,2,3}`; `lagrange_first` at `TRACE_OFFSET`;
trace blocks start at `TRACE_OFFSET + 1`
* Oink prover (`oink_prover.cpp`): Removed all tail references;
commitments use base polynomials directly
* Ultra prover (`ultra_prover.cpp`): CRS sized to `max_end_index()`
instead of `dyadic_size()` for ZK
* ECCVM flavor (`eccvm_flavor.hpp`): Polynomial allocation with trace
offset; Lagrange polys shifted
* ECCVM prover (`eccvm_prover.cpp`): Removed tail batching and
`extend_with_tail` copies for translation polys
* Sumcheck (`sumcheck.hpp`): Unified ZK/non-ZK virtual round paths;
removed `padding_indicator_array` from verifier
* Row-disabling (`row_disabling_polynomial.hpp`): Simplified to `1 -
∏_{i≥2}(1-u_i)`
* Gemini (`gemini_impl.hpp`): Fold polynomials track `actual_size` from
`A_0.end_index()`
* Shplemini (`shplemini.hpp`): Removed `padding_indicator_array` from
`compute_batch_opening_claim`
* AVM (`vm2/constraining/`): Removed `padding_indicator_array` from
native and recursive AVM verifiers; added `TRACE_OFFSET = 0` to AVM
flavor
* Merge protocol (`merge_prover.cpp/hpp`, `merge_verifier.cpp/hpp`):
Prepends `TRACE_OFFSET` zeros to table polynomials; verifier accounts
for offset in commitment checks
* Grand product / log-derivative: Start after disabled region via
`gp_start` / `start_index` parameters
* Databus (`databus.hpp`): `DEFAULT_VALUE = 0` (point-at-infinity
commitment matches default)

### Known Issues / Follow-ups

* The zk ultra prover efficiency needs to be investigated.

---

---------

Co-authored-by: notnotraju <raju@aztec-labs.com>
federicobarbacovi and others added 5 commits April 21, 2026 15:03
Fix the static assert in Translator: the size for the translator is
determined by the `MINI_CIRCUIT_SIZE * CONCATENATION_GROUP_SIZE`. This
number must be bigger than `SORTED_STEPS` (which is the max size of the
microlimbs divided by 3) times `NUM_ORDERED_RANGE` (1 + the number of
interleaved polynomials) plus the masking rows in the overflow column
(which are equal to `4 * 64 / 5` (see the README).

The old static assert compared `SORTED_STEPS` times `1 +
NUM_CONCATENATED_POLYS` with the size of the translator.

@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 added this pull request to the merge queue Apr 21, 2026
@AztecBot

Copy link
Copy Markdown
Collaborator Author

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

1 similar comment
@AztecBot

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 ba8eec4 Apr 21, 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.

5 participants