Back to blog
Cryptography14 min read

PLONK Arithmetization Internals: How Modern ZK Proof Systems Actually Work

PLONK became the foundation for nearly every production ZK proof system — from zkSync to Polygon. Understanding its arithmetization, custom gates, and lookup arguments is essential for engineers building on top of it.

PLONK (Permutations over Lagrange-bases for Oecumenical Noninteractive arguments of Knowledge) was introduced by Gabizon, Williamson, and Ciobotaru in 2019. In the years since, it has become the de facto foundation for production zero-knowledge proof systems. zkSync Era, Polygon zkEVM, Aztec, and Scroll all build on PLONK or its derivatives. Understanding its internals is no longer optional for engineers working in this space.

This post is a deep technical walkthrough of PLONK's arithmetization — how computations are encoded into polynomials, how the constraint system works, and how modern extensions like custom gates and lookup arguments push performance to practical limits. We assume familiarity with elliptic curve cryptography and basic polynomial commitment schemes.

Why Arithmetization Matters

A ZK proof system proves that a prover knows a witness w such that a statement C(x, w) = true, without revealing w. The key challenge is transforming an arbitrary computation C into a form that a proof system can handle. That transformation is arithmetization — encoding the computation as polynomial constraints over a finite field.

The choice of arithmetization dominates the performance characteristics of the resulting proof system. Poor arithmetization leads to enormous circuit sizes, long proving times, and large proofs. Efficient arithmetization is what separates practical ZK systems from theoretical ones. PLONK introduced a flexible, universal arithmetization that can be instantiated with different proving backends — SNARKs, STARKs, or hybrid systems.

The PLONK Circuit Model

PLONK represents computation as an arithmetic circuit over a finite field F_p, where p is a large prime (typically 254 bits for BN254 or 255 bits for BLS12-381). Unlike earlier systems like Groth16 that used R1CS (Rank-1 Constraint Systems), PLONK introduces a more general gate model.

The PLONK Gate Equation

Each gate in a PLONK circuit is defined by the equation: q_L * a + q_R * b + q_O * c + q_M * a * b + q_C = 0. Here, a, b, c are the left input, right input, and output wire values. The selector polynomials q_L, q_R, q_O, q_M, q_C are fixed at circuit construction time and encode what type of gate this is.

This single parameterized gate equation is the core of PLONK's flexibility. By choosing selector values, any constraint expressible as a degree-2 polynomial over the wire values can be implemented as a PLONK gate. The system is 'universal' in the sense that the circuit structure (selector polynomial values) can be fixed before the prover's witness is known.

The Copy Constraint Problem

The gate equation handles local constraints within a single gate. But computations are not isolated gates — output values flow from one gate to another as inputs. Enforcing that the output wire of gate i equals the input wire of gate j is called a 'copy constraint' or 'wiring constraint.'

PLONK encodes copy constraints via a permutation argument. All wire values (a_1, b_1, c_1, a_2, b_2, c_2, ..., a_n, b_n, c_n) for n gates form a single vector. A permutation sigma maps indices such that if wire position i should equal wire position j, then sigma(i) = j. The prover must demonstrate that the wire vector is consistent with sigma — equivalently, that values at positions i and sigma(i) are identical.

PLONK's central insight is encoding both gate constraints and copy constraints as polynomial identities over a multiplicative subgroup of F_p. Both can be checked simultaneously with a single polynomial evaluation at a random point, enabling a universal and updatable structured reference string.

The Polynomial Encoding

PLONK works over a multiplicative subgroup H of F_p of order n, where n is the number of gates. For BN254, n can be up to 2^28 (268 million gates) with acceptable performance. The subgroup H = {omega^0, omega^1, ..., omega^{n-1}} where omega is an n-th root of unity.

Each row of the execution trace becomes a coefficient in a polynomial. The wire assignment a_i is encoded as the polynomial a(X) such that a(omega^i) = a_i. Similarly for b(X), c(X), and the selector polynomials. Gate satisfaction becomes: q_L(X)*a(X) + q_R(X)*b(X) + q_O(X)*c(X) + q_M(X)*a(X)*b(X) + q_C(X) = 0 for all X in H.

The vanishing polynomial Z_H(X) = X^n - 1 vanishes at every point in H. So the gate equation holds for all X in H if and only if Z_H(X) divides the left-hand side. This translates proving a constraint holds everywhere into a single polynomial divisibility check — the core trick that makes PLONK efficient.

The Permutation Argument in Detail

The permutation argument proves that a set of values f = (f_0, ..., f_{n-1}) is a permutation of another set g = (g_0, ..., g_{n-1}). PLONK uses the 'grand product' technique: construct the polynomial z(X) where z(omega^0) = 1 and z(omega^{i+1}) = z(omega^i) * prod((f_j + beta * j + gamma) / (g_j + beta * sigma(j) + gamma)) for j from 0 to i.

Here beta and gamma are random challenges from the verifier (or Fiat-Shamir hash of the transcript). The final value z(omega^n) = z(1) must equal 1. This can only happen if f is indeed a permutation of g. The entire permutation check reduces to: (a) z(omega^0) = 1, (b) z(omega^{n-1}) = 1, and (c) a polynomial identity relating consecutive values of z.

TurboPLONK and UltraPLONK: Custom Gates

Vanilla PLONK with its degree-2 gate equation requires large circuits for complex operations. A 256-bit integer multiplication needs roughly 2000 gates. An elliptic curve point addition over BN254 embedded in BN254 arithmetic needs hundreds more. Custom gates are the solution.

TurboPLONK (Aztec, 2019) extends the gate equation to arbitrary degree: q_1 * f_1(a,b,c,d) + q_2 * f_2(a,b,c,d) + ... = 0, where each gate can use up to 4 wire values (adding a fourth wire d) and the f_i can be arbitrary polynomials of arbitrary degree. This enables encoding entire cryptographic operations in a single gate.

Examples of Custom Gates

UltraPLONK (Aztec, 2022) further extends TurboPLONK with lookup tables — precomputed tables of valid input-output pairs for functions like XOR, AND, range checks, and bitwise operations. The prover proves that its wire values appear in the lookup table, which is far more efficient than computing the function gate-by-gate.

Lookup Arguments: PlonkUp and Caulk

A lookup argument proves that a set of values f = (f_0, ..., f_{m-1}) are all contained in a table T = (t_0, ..., t_{n-1}), without revealing which specific entries they are. For zkEVMs, this is essential — the EVM uses many bitwise operations and range checks that are expensive in pure arithmetic circuits.

The naive lookup argument in vanilla UltraPLONK requires O(n) prover work per lookup, where n is the table size. For large tables like the full 16-bit range check table (65536 entries), this becomes expensive. Caulk (EPFL, 2022) reduced prover time to O(m log m) independent of table size, a dramatic improvement for multi-column tables with hundreds of thousands of entries.

The Caulk Construction

Caulk uses a KZG polynomial commitment scheme where the table T is committed as a polynomial t(X) of degree n. A lookup of m values requires the prover to produce an opening proof that the queried values are contained in t(X) at some subset of positions. The key optimization is that the subset proof is O(m log m) regardless of n, using a subprotocol based on structured subsets of roots of unity.

Proving System Backends: KZG vs. FRI

PLONK's arithmetization is agnostic to the polynomial commitment scheme used. The two dominant choices are KZG (Kate-Zaverucha-Goldberg) and FRI (Fast Reed-Solomon IOP of Proximity).

The Prover Performance Picture

For a PLONK circuit of n gates, proving time is dominated by two operations: multi-scalar multiplication (MSM) over the elliptic curve, and fast Fourier transforms (FFTs) over F_p. Both are O(n log n) in asymptotic complexity, but the constants matter enormously in practice.

Modern PLONK provers achieve roughly 1-5 million gates per second on GPU hardware. A full Ethereum block translated to a zkEVM circuit has approximately 30-100 million gates, implying 10-100 seconds of proving time on a high-end GPU cluster. This is why zkEVM block times are typically 1-3 minutes — the proving latency is a fundamental constraint.

The zkEVM proving bottleneck today is not algebraic — it is hardware. The next 5x improvement in zkEVM throughput will come from ASIC provers and GPU kernel optimization, not from new arithmetization techniques. The arithmetization layer is largely solved.

Practical Implications for Protocol Designers

For engineers building ZK applications on top of PLONK-based systems, the key insight is that circuit size is the primary cost driver. Every operation your application performs translates to a circuit gate count, and gate count drives proving time, proof size, and verification cost.

Build Production ZK Systems with Accelar

Accelar designs and implements zero-knowledge proof systems for enterprise and protocol applications — from zkEVM circuit optimization to custom PLONK constraint systems and ZK-native application architectures. If you're building on ZK technology and need deep cryptographic engineering expertise, let's talk.