Skip to content
← Writing

Fast OOD Evaluation

Computing a STARK's out-of-domain evaluations quickly with barycentric interpolation over the trace subgroup.

· 1 min read · STARKs, Polynomials

Preliminaries

Let F\mathbb{F} be a finite field of prime order pp and let ℓ\ell be the largest positive integer such that 2ℓ∣(p−1)2^\ell \mid (p-1). Let k<ℓk < \ell and let G⊂F∗G \subset \mathbb{F}^* be a multiplicative subgroup of order n=2kn = 2^k. Also, let K\mathbb{K} denote an extension field over F\mathbb{F}.

The vanishing polynomial over a domain D⊆F∗D \subseteq \mathbb{F}^* is the monic polynomial whose simple roots are precisely the elements of DD: VD(X)=∏a∈D(X−a)V_D(X) = \prod_{a \in D}(X - a). For any multiplicative subgroup HH it collapses to VH(X)=X∣H∣−1V_H(X) = X^{|H|} - 1, and for a coset cHcH to VcH(X)=X∣H∣−c∣H∣V_{cH}(X) = X^{|H|} - c^{|H|}.

DEEP-ALI

The verifier samples the out-of-domain point z←K∖Kz \leftarrow \mathbb{K} \setminus K. The prover answers with the OOD evaluations: the translated column values and the chunk values

vj,s:=wj(gsz)(j∈[m], s∈S),viQ:=Qi(z)(i<⌈d∗/n⌉).v_{j,s} := w_j(g^s z) \quad (j \in [m],\ s \in \mathcal{S}), \qquad v^Q_i := Q_i(z) \quad (i < \lceil d^{*} / n\rceil).

all computed barycentrically. The verifier then checks the constraint algebra on the claims — this is the ALI identity:

∑i=1⌈d∗/n⌉z(i−1)⋅n⋅viQ  =?  ∑t=1mβ t−1⋅Ct((vj,s)j,s)VHt(z).\sum_{i=1}^{\lceil d^{*} / n\rceil} z^{(i-1) \cdot n}\cdot v^Q_i \;\stackrel{?}{=}\; \sum_{t=1}^{m} \beta^{\,t-1}\cdot \frac{C_t\big((v_{j,s})_{j,s}\big)}{V_{H_t}(z)}.

DEEP is the remaining half: binding the claimed values vj,s,viQv_{j,s}, v^Q_i to the committed words, which is exactly what the quotients of Step 5 do, at which point “close to a codeword” is also discharged by the proximity test.

Barycentric Evaluation

Notice that for x∉Gx \notin G:

f(x)=∑u∈Gf(u)⋅Lu(x)=VG(x)n∑u∈Gu⋅f(u)x−u.f(x) = \sum_{u \in G} f(u) \cdot L_u(x) = \frac{V_G(x)}{n} \sum_{u \in G} \frac{u \cdot f(u)}{x - u}.

If we enumerate the elements of GG by u1,…,uℓu_1,\dots,u_\ell, the previous can be computed by precomputing the shared constant and vector

VG(x)n,(u1x−u1,…,uℓx−uℓ)\frac{V_G(x)}{n}, \quad \left(\frac{u_1}{x-u_1}, \dots, \frac{u_\ell}{x-u_\ell}\right)

for each xx and then computing the inner product per column:

f(x)=VG(x)n⋅⟨(u1x−u1,…,uℓx−uℓ),(f(u1),…,f(uℓ))⟩f(x) = \frac{V_G(x)}{n} \cdot \left\langle\left(\frac{u_1}{x-u_1}, \dots, \frac{u_\ell}{x-u_\ell}\right), (f(u_1), \dots, f(u_\ell)) \right\rangle

Break my circuit

You are the prover. The verifier doesn't run the program; it only checks the constraints. Each circuit here is missing one, which is the most common bug in real ZK systems. Find a witness that fools it.

circuit.circom

Public (verifier sees)

Witness (you choose)

Constraints · everything mod 97