| Row | Advice | Fixed | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| \(w_l\) | \(w_r\) | \(w_o\) | \(q_r\) | \(q_l\) | \(q_o\) | \(q_c\) | \(q_m\) | \(q_\text{sha2}\) | \(q_\text{lookup}\) | \(t_\text{lookup}\) | |
| (...) | |||||||||||
| \(i-1\) | \(x_1\) | \(x_2\) | \(x_3\) | \(1\) | \(1\) | \(-1\) | \(\cdot\) | \(\cdot\) | \(\cdot\) | \(\cdot\) | \(\cdot\) |
| \(i\) | \(x_3\) | \(x_4\) | \(x_5\) | \(\cdot\) | \(\cdot\) | \(2\) | \(7\) | \(5\) | \(\cdot\) | \(\cdot\) | \(\cdot\) |
| \(i+1\) | \(x_1\) | \(x_3\) | \(x_6\) | \(\cdot\) | \(\cdot\) | \(\cdot\) | \(\cdot\) | \(\cdot\) | \(1\) | \(1\) | \(\cdot\) |
| (...) | |||||||||||
The wires \(w_l\), \(w_r\), \(w_o\) are the prover's left, right and output registers at each row. The 5 selector columns \(q_l, q_r, q_o, q_c, q_m\) enable arithmetic constraints; \(q_\text{sha2}\) enables a hash constraint; \(q_\text{lookup}\) triggers a membership check against the table \(t_\text{lookup}\). The following equations must hold at every row:
- \(\displaystyle q_l \cdot w_l + q_r \cdot w_r + q_o \cdot w_o + q_m \cdot w_l \cdot w_r + q_c = 0\)
- \(\displaystyle q_\text{sha2} \cdot \bigl(\text{sha2}(w_l,\, w_r) - w_o\bigr) = 0\)
- \(\displaystyle q_\text{lookup} \cdot w_l \in t_\text{lookup}\)
A selector set to 0 disables its constraint entirely. For instance, only at row \(i+1\) are \(q_\text{sha2}\) and \(q_\text{lookup}\) active, enforcing \(\text{sha2}(x_1, x_3) = x_6\) with \(x_1\) looked up in the table.
Selectors
A selector holds 0 or 1 at each row. Setting it to 1 activates the associated gate constraint at that row; 0 disables it entirely. A circuit may have many selectors, each switching a different rule on or off per step.
Lookup Tables
A table column holds a fixed set of allowed values defined at circuit creation time. Lookup arguments check that a wire value appears somewhere in the table — a range check, a set membership test, or a function table.
Fixed Parameters
Any constant embedded in the circuit: curve coefficients, hash round constants, domain parameters. Unlike selectors, these are not binary — they hold arbitrary field elements fixed by the designer for every proof.
Wires
The primary variables of the circuit: inputs, intermediate values, and outputs the prover supplies. Each cell is checked by the active gate constraints at its row and may be copy-constrained to appear consistently in other rows.
Temporary Registers
Extra advice columns used to break complex expressions into simpler constraints, e.g., storing an intermediate product before it is used in a later gate. Often unconstrained by copy — they do not participate in the permutation argument, saving VK commitments.
| Property | Description |
|---|---|
| copy-constrained | Copy-constraining a column means its cells may be equated with cells in other columns or rows — this is how the same variable (e.g., \(x_1\) at rows \(i-1\) and \(i+1\)) is enforced to hold the same value across the table. Each copy-constrained column participates in the permutation argument and contributes one permutation polynomial, adding one G1 commitment to the VK. Advice columns are usually copy-constrained; unconstrained ones act as temporary registers. |
The KZG polynomial commitment scheme opens all columns simultaneously, but columns with different rotation sets require separate multi-opening proofs (each producing one additional Q commitment and one π commitment in the proof). Minimising the number of distinct rotation sets across all columns directly reduces proof size and the number of MSM calls during verification.
Point Sets (derived)
// Distinct rotation groups across all // column queries — one KZG multi-open // proof per group. nb_point_sets ≈ 1 // {curr} — always present + (cc > 0 || lkp > 0 ? 1 : 0) // {curr, next} + (perm_chunks > 1 ? 1 : 0) // {curr, next, last} + (lkp > 0 ? 1 : 0) // {prev, curr}
Cost Impact
Each distinct point set adds: 1 Q commitment (proof) 1 π commitment (proof) And one extra MSM group during verification — so keeping columns on the same rotation set (or a subset of another set) is the primary lever for reducing both proof size and verifier cost.
Gates
Polynomial constraints over
advice and fixed columns.
Gates add no commitments or
evaluations to the proof —
their cost is scalar operations
only (field arithmetic during
argument recomputation).
Permutation
Enforces copy constraints: cells equated across rows and columns hold the same value. Adds per chunk of cc columns: ⌈cc/(deg−2)⌉ commits cc + 3×⌈cc/(deg−2)⌉ − 1 evals Requires degree ≥ 3.
Lookups
Checks that wire values appear in a fixed table. Per lookup argument: 3 commits (Z, A_perm, S_perm) 5 scalar evaluations Requires degree ≥ 5.
Trashcans
Range arguments that bound intermediate values in foreign-field arithmetic. Per trashcan: 1 commitment 1 scalar evaluation Requires degree ≥ 4. Multiple chips may share one trashcan column (deduplicated).
Once each argument is internally batched, their contributions to proof size are accumulated across all argument types: gate scalar ops are summed, lookup and trashcan counts grow additively, and permutation chunks scale with the total number of copy-constrained columns. The degree of the circuit is the maximum required by any active argument type or chip gate.
Degree (derived)
degree = max( degree_hint, cc > 0 ? 3 : 0, // permutation nb_lookups > 0 ? 5 : 0, // PlookUp nb_trash > 0 ? 4 : 0, // trashcan max chip degree // gate polynomials )
Total Proof Commitments
nb_commitments = nb_advice // one per advice col + ⌈cc / (degree − 2)⌉ // permutation + nb_trash // trashcans + 1 + (degree − 1) // vanishing + 3 × nb_lookups // PlookUp + 2 // H2MO PCS: F and π
Advice Columns — max-count merge
Chips declare groups of advice columns. Within a group, the chip with the most columns wins; the rest are absorbed. Example: JubJub (9 cols) absorbs Arith (5 cols). Combined count stays 9, not 5 + 9 = 14. Extra advice columns (--nb-advice) are appended after the merged set.
Fixed Columns — exclusive or shared
Fixed columns are either shared or exclusive. Shared columns are deduplicated: if two chips declare the same shared column, it appears once in the circuit. Exclusive columns are always summed: each chip instance adds its own copy. Lookup table columns are handled separately — see Lookup Tables.
Shared Across Chips
A single table can be referenced by lookup arguments from different chips. When chips are combined, tables are unioned: if two chips declare the same table, it appears only once in the final circuit. This deduplication is independent of the advice and fixed column merging.
One Commit per Column
Unlike gate fixed columns — which could in principle share commitments — each lookup table column receives its own G1 commitment in the VK. The total lookup table footprint is: nb_table_cols = union of all table columns across active chips Each adds 48 bytes to the VK.
No Concatenation
Tables of the same width could
theoretically be concatenated into
one taller table, reducing the
column count to 1.
Halo2 does not perform this
optimisation: each table column is
committed independently, even if
two tables have identical structure.