Skip to content
← Writing

STIR+

Notes on STIR-style proximity testing, where each round cuts the degree by k but only halves the domain: the construction, how to handle repeated queries, and round-by-round soundness.

· 9 min read · Proximity Testing, Reed–Solomon

Symbol Meaning
RS[F,L,d]\mathsf{RS}[\mathbb{F},\mathcal{L},d] {f:L→F∣∃f^∈F<d[X], f=f^∣L}\{f:\mathcal{L}\to\mathbb{F} \mid \exists \hat f\in\mathbb{F}^{<d}[X],\ f=\hat f\vert_{\mathcal{L}}\}
ρ\rho rate of the code, ρ:=d/∣L∣\rho := d/\lvert\mathcal{L}\rvert
f^\hat f hat = polynomial object (as opposed to the function ff)
Lk\mathcal{L}^k {xk:x∈L}\{x^k : x\in\mathcal{L}\}
smooth L\mathcal{L} is a multiplicative coset of F∗\mathbb{F}^* whose order is a power of 2
List(f,d,δ)\mathrm{List}(f,d,\delta) codewords of RS[F,L,d]\mathsf{RS}[\mathbb{F},\mathcal{L},d] within distance δ\delta of ff
(δ,ℓ)(\delta,\ell)-list decodable ∣List(f,d,δ)∣≤ℓ\lvert\mathrm{List}(f,d,\delta)\rvert\le\ell for every ff
V^S\hat V_S vanishing polynomial of SS, ∏a∈S(X−a)\prod_{a\in S}(X-a)

Fact — The Johnson Bound: The code RS[F,L,d]\mathsf{RS}[\mathbb{F},\mathcal{L},d] is (1−ρ−η, 12ηρ)\bigl(1-\sqrt{\rho}-\eta,\ \tfrac{1}{2\eta\sqrt{\rho}}\bigr)-list decodable for every η∈(0,1−ρ)\eta\in(0,1-\sqrt{\rho}).

1. The Idea

One STIR iteration reduces proximity testing of C=RS[F,L,d]\mathcal{C}=\mathsf{RS}[\mathbb{F},\mathcal{L},d] to proximity testing to C′=RS[F,L′,d/k]\mathcal{C}'=\mathsf{RS}[\mathbb{F},\mathcal{L}',d/k], where the degree drops by a factor kk but the domain only drops by a factor 2:

ρ′=d/k∣L∣/2=2k⋅ρ.\rho'=\frac{d/k}{\lvert\mathcal{L}\rvert/2}=\frac{2}{k}\cdot\rho.

Testing proximity to C′\mathcal{C}' is easier than testing proximity to C\mathcal{C} for two reasons:

  1. C′\mathcal{C}' is “smaller” than C\mathcal{C} in the sense that the degree is reduced from dd to d/kd/k and the evaluation domain size is reduced from nn to n/2n/2.
  2. The rate of the code is reduced by a factor of 2/k2/k.

Intuitively, testing proximity to a code with a smaller rate is easier because the code has more “redundancy”. Indeed, rate reduction in STIR is the key feature that facilitates smaller query complexity: the smaller the rate, the fewer queries are needed to achieve a target soundness error.

2. Tools

STIR rests on the following tools.

2.1 Out-of-Domain Sampling

Lemma 4.5 shows that the probability that there exist two distinct codewords in the list-decoding set of a function that both agree on a random point is small.

Lemma 4.5 If RS[F,L,d]\mathsf{RS}[\mathbb{F},\mathcal{L},d] is (δ,ℓ)(\delta,\ell)-list decodable, then

Pr⁡r1,…,rs←F∖L[∃ u≠u′∈List(f,d,δ): ∀i, u^(ri)=u^′(ri)] ≤ ds ℓ22(∣F∣−∣L∣)s\Pr_{r_1,\dots,r_s\leftarrow\mathbb{F}\setminus\mathcal{L}}\bigl[\exists\, u\ne u'\in\mathrm{List}(f,d,\delta):\ \forall i,\ \hat u(r_i)=\hat u'(r_i)\bigr]\ \le\ \frac{d^s\,\ell^2}{2(\lvert\mathbb{F}\rvert-\lvert\mathcal{L}\rvert)^s}

2.2 Folding

STIR relies on k-wise folding of functions and polynomials. Lemma 4.9 shows that folding a function preserves its proximity from the Reed–Solomon code with high probability

Folding Polynomials: Given a polynomial f^∈F<d[X]\hat{f} \in \mathbb{F}^{<d}[X], a folding parameter k∈Nk \in \mathbb{N} and r∈Fr \in \mathbb{F}, we define a polynomial PolyFold(f^,k,r)∈F<d/k[X]\mathrm{PolyFold}(\hat f,k,r) \in \mathbb{F}^{<d/k}[X] as follows. Let Q^∈F[X,Y]\hat{Q} \in \mathbb{F}[X,Y] be the bivariate polynomial derived from f^\hat{f} with deg⁡X(Q^)<d/k\deg_X(\hat{Q}) < d /k and deg⁡Y(Q^)<k\deg_Y(\hat{Q}) < k such that f^(Z)=Q^(Zk,Z)\hat{f}(Z) = \hat{Q}(Z^k, Z). Then PolyFold(f^,k,r)(X):=Q^(X,r)\mathrm{PolyFold}(\hat f,k,r)(X) := \hat{Q}(X,r).

Folding Functions: Let f:L→Ff : \mathcal{L} \to \mathbb{F} be a function, k∈Nk \in \mathbb{N} a folding parameter and α∈F\alpha \in \mathbb{F}. For every x∈Lkx\in\mathcal{L}^k let p^x∈F<k[X]\hat p_x\in\mathbb{F}^{<k}[X] be the polynomial interpolating {f(y):y∈L, yk=x}\{f(y): y\in\mathcal{L},\ y^k=x\}. We define Fold(f,k,α):Lk→F\mathrm{Fold}(f,k,\alpha): \mathcal{L}^k \to \mathbb{F} by Fold(f,k,α)(x):=p^x(α)\mathrm{Fold}(f,k,\alpha)(x) := \hat p_x(\alpha).

2.3 Quotienting

STIR also needs the quotient of functions and polynomials.

Quotienting Functions: Let f:L→Ff : \mathcal{L} \to \mathbb{F} be a function, S⊆FS\subseteq\mathbb{F} a set disjoint with L\mathcal{L}, and Ans:S→F\mathrm{Ans}: S \to \mathbb{F} be a function. Let Ans^∈F<∣S∣[X]\widehat{\mathrm{Ans}}\in\mathbb{F}^{<\lvert S\rvert}[X] be the polynomial interpolating {Ans(x):x∈S}\{\mathrm{Ans}(x): x\in S\}. The quotient function Quotient(f,S,Ans):L→F\mathrm{Quotient}(f,S,\mathrm{Ans}): \mathcal{L} \to \mathbb{F} is defined by:

Quotient(f,S,Ans)(x):=f(x)−Ans^(x)V^S(x)\mathrm{Quotient}(f,S,\mathrm{Ans})(x):=\dfrac{f(x)-\widehat{\mathrm{Ans}}(x)}{\hat V_S(x)}

Quotienting Polynomials: Let f^∈F<d[X]\hat{f} \in \mathbb{F}^{<d}[X] be a polynomial and S⊆FS\subseteq\mathbb{F}. The polynomial quotient PolyQuotient(f^,S)∈F<d−∣S∣[X]\mathrm{PolyQuotient}(\hat f,S) \in \mathbb{F}^{<d - |S|}[X] is defined by:

PolyQuotient(f^,S)(X):=f^(X)−Ans^(X)V^S(X),\mathrm{PolyQuotient}(\hat f,S)(X):=\dfrac{\hat f(X)-\widehat{\mathrm{Ans}}(X)}{\hat V_S(X)},

where Ans^∈F<∣S∣[X]\widehat{\mathrm{Ans}}\in\mathbb{F}^{<\lvert S\rvert}[X] is the polynomial interpolating {f^(x):x∈S}\{\hat f(x): x\in S\}.

Lemma 4.4 shows that if a function is “quotiented by the wrong value”, then its quotient is far from low-degree.

Note that SS must be a set: if a point appeared twice, V^S\hat V_S would have a double root there while f^−Ans^\hat f - \widehat{\mathrm{Ans}} only vanishes to first order, and the honest quotient would not be a polynomial. Section 4 discusses what this means once the points of SS are sampled at random.

2.4 Degree Correction

Finally, STIR also shows how to properly perform a degree correction.

Given target degree d∈Nd \in \mathbb{N}, shifting parameter rr, function f:L→Ff : \mathcal{L} \to \mathbb{F}, and degree 0≤d≤d∗0 \leq d \leq d^*, we define DegCor(d∗,r,f,d):L→F\mathrm{DegCor}(d^*,r,f,d) : \mathcal{L} \to \mathbb{F} by:

DegCor(d∗,r,f,d)(x):=f(x)∑ℓ=0d∗−d(rx)ℓ={f(x)⋅1−(xr)d∗−d+11−xrxr≠1f(x)⋅(d∗−d+1)xr=1\mathrm{DegCor}(d^*,r,f,d)(x):=f(x)\sum_{\ell=0}^{d^*-d}(rx)^{\ell}=\begin{cases}f(x)\cdot\dfrac{1-(xr)^{d^*-d+1}}{1-xr} & xr\ne 1\\[2ex] f(x)\cdot(d^*-d+1) & xr=1\end{cases}

The closed form of the geometric sum is the efficiency contribution: O(log⁡(d∗−d))O(\log(d^*-d)) operations and a single query to ff, instead of O(d∗−d)O(d^*-d).

2.5 Checking the Interpolant: the Shake Polynomial

Quotienting makes the verifier evaluate Ans^\widehat{\mathrm{Ans}}, the interpolant of ∣S∣\lvert S\rvert points. Interpolating costs O(∣S∣2)O(\lvert S\rvert^2) field operations, and so does the obvious alternative: let the prover send Ans^\widehat{\mathrm{Ans}} and check it at every point of SS, ∣S∣\lvert S\rvert evaluations of a degree-∣S∣\lvert S\rvert polynomial. Both are the dominant verifier cost of an iteration when ∣S∣\lvert S\rvert is in the hundreds.

The fix is to let the prover send Ans^\widehat{\mathrm{Ans}} together with a witness that it interpolates, and check the witness at one random point. Define the shake polynomial

Sh(X):=∑a∈SAns^(X)−Ans(a)X−a.\mathrm{Sh}(X):=\sum_{a\in S}\frac{\widehat{\mathrm{Ans}}(X)-\mathrm{Ans}(a)}{X-a}.

The check. V samples ρ←F∖S\rho\leftarrow\mathbb{F}\setminus S after receiving Ans^\widehat{\mathrm{Ans}} and Sh\mathrm{Sh}, and accepts iff

Sh(ρ)=∑a∈SAns^(ρ)−Ans(a)ρ−a.\mathrm{Sh}(\rho)=\sum_{a\in S}\frac{\widehat{\mathrm{Ans}}(\rho)-\mathrm{Ans}(a)}{\rho-a}.

Cost: two polynomial evaluations and one batched inversion: O(∣S∣)O(\lvert S\rvert).

Two degree bounds must be enforced for this argument: deg⁡(Ans^)<∣S∣\deg(\widehat{\mathrm{Ans}})<\lvert S\rvert (a longer polynomial through the same points is not the interpolant) and deg⁡(Sh)<∣S∣−1\deg(\mathrm{Sh})<\lvert S\rvert-1.

3. Construction

3.1 Ingredients

  • A field F\mathbb{F}.
  • An iteration count M∈NM\in\mathbb{N}.
  • An initial degree d∈Nd\in\mathbb{N} that is a power of 2.
  • Folding parameters k0,…,kM−1∈Nk_0,\dots,k_{M-1}\in\mathbb{N}, powers of two, with d≥∏ikid\ge\prod_i k_i.
  • Evaluation domains L0,…,LM−1⊆F\mathcal{L}_0,\dots,\mathcal{L}_{M-1}\subseteq\mathbb{F}, each Li\mathcal{L}_i a smooth coset of F∗\mathbb{F}^* with ∣Li∣>d/∏j<ikj\lvert\mathcal{L}_i\rvert>d/\prod_{j<i}k_j (i.e. ρi<1\rho_i<1), and Li−1ki−1∩Li=∅\mathcal{L}_{i-1}^{k_{i-1}}\cap\mathcal{L}_i=\emptyset for every i∈[M−1]i\in[M-1].
  • Repetition parameters t0,…,tM−1∈Nt_0,\dots,t_{M-1}\in\mathbb{N} with ti+1<d/∏j≤ikjt_i+1<d/\prod_{j\le i}k_j for i<M−1i<M-1.

Per-round degrees, for i=0,…,Mi=0,\dots,M: di:=d∏j<ikj\boxed{d_i:=\dfrac{d}{\prod_{j<i}k_j}} (so d0=dd_0=d), and ρi:=di/∣Li∣\rho_i:=d_i/\lvert\mathcal{L}_i\rvert.

3.2 Interaction phase

Initial function: f0:L0→Ff_0:\mathcal{L}_0\to\mathbb{F}, an oracle. Honest case: f0∈RS[F,L0,d0]f_0\in\mathsf{RS}[\mathbb{F},\mathcal{L}_0,d_0] and the prover holds f^0∈F<d0[X]\hat f_0\in\mathbb{F}^{<d_0}[X].

Initial folding: V sends r0fold←Fr_0^{\mathsf{fold}}\leftarrow\mathbb{F}.

Loop, for i=1,…,M−1i=1,\dots,M-1:

  1. Send folded function. P sends gi:Li→Fg_i:\mathcal{L}_i\to\mathbb{F}. Honest: gig_i is the evaluation over Li\mathcal{L}_i of g^i:=PolyFold(f^i−1,ki−1,ri−1fold)∈F<di[X].\hat g_i:=\mathrm{PolyFold}(\hat f_{i-1},k_{i-1},r_{i-1}^{\mathsf{fold}})\in\mathbb{F}^{<d_i}[X]. (Note the domain jump: the fold naturally lives on Li−1ki−1\mathcal{L}_{i-1}^{k_{i-1}}, of size ∣Li−1∣/ki−1\lvert\mathcal{L}_{i-1}\rvert/k_{i-1}, but the prover re-evaluates it over Li\mathcal{L}_i, of size ∣Li−1∣/2\lvert\mathcal{L}_{i-1}\rvert/2. That is the “shift to improve rate”.)
  2. Out-of-domain sample. V sends riout←F∖Lir_{i}^{\mathsf{out}}\leftarrow\mathbb{F}\setminus\mathcal{L}_i.
  3. Out-of-domain reply. P sends βi∈F\beta_{i}\in\mathbb{F}. Honest: βi:=g^i(riout)\beta_{i}:=\hat g_i(r_{i}^{\mathsf{out}}).
  4. STIR message. V sends rifold,ricomb←Fr_i^{\mathsf{fold}},r_i^{\mathsf{comb}}\leftarrow\mathbb{F} and ri,1shift,…,ri,ti−1shift←Li−1ki−1r_{i,1}^{\mathsf{shift}},\dots,r_{i,t_{i-1}}^{\mathsf{shift}}\leftarrow\mathcal{L}_{i-1}^{k_{i-1}}.
  5. Quotient set and answers (both parties, no message). View Gi:={riout}∪{ri,1shift,…,ri,ti−1shift}\mathcal{G}_i:=\{r_{i}^{\mathsf{out}}\}\cup\{r_{i,1}^{\mathsf{shift}},\dots,r_{i,t_{i-1}}^{\mathsf{shift}}\} as a set (repeated shift points counted once, see Section 4), and Ansi:Gi→F\mathrm{Ans}_i:\mathcal{G}_i\to\mathbb{F}, Ansi(riout)=βi,Ansi(ri,jshift)=Fold(fi−1,ki−1,ri−1fold)(ri,jshift).\mathrm{Ans}_i(r_{i}^{\mathsf{out}})=\beta_{i},\qquad \mathrm{Ans}_i(r_{i,j}^{\mathsf{shift}})=\mathrm{Fold}(f_{i-1},k_{i-1},r_{i-1}^{\mathsf{fold}})(r_{i,j}^{\mathsf{shift}}).
  6. Interpolant and shake polynomial. P sends Ans^i∈F<∣Gi∣[X]\widehat{\mathrm{Ans}}_i\in\mathbb{F}^{<\lvert\mathcal{G}_i\rvert}[X] and Shi∈F<∣Gi∣−1[X]\mathrm{Sh}_i\in\mathbb{F}^{<\lvert\mathcal{G}_i\rvert-1}[X] as coefficients. Honest: Ans^i\widehat{\mathrm{Ans}}_i interpolates Ansi\mathrm{Ans}_i on Gi\mathcal{G}_i and Shi(X):=∑a∈GiAns^i(X)−Ansi(a)X−a. \mathrm{Sh}_i(X):=\sum_{a\in\mathcal{G}_i} \frac{\widehat{\mathrm{Ans}}_i(X)-\mathrm{Ans}_i(a)}{X-a}.
  7. Shake challenge. V sends ρi←F\rho_i\leftarrow\mathbb{F}.
  8. Define next polynomial (prover-local, no message). With g^i′:=PolyQuotient(g^i,Gi)\hat g_i':=\mathrm{PolyQuotient}(\hat g_i,\mathcal{G}_i), the prover defines the degree-corrected polynomial f^i:=DegCor(di, ricomb, g^i′, di−∣Gi∣)∈F<di[X],\hat f_i:=\mathrm{DegCor}\bigl(d_i,\,r_i^{\mathsf{comb}},\,\hat g_i',\,d_i-\lvert\mathcal{G}_i\rvert\bigr)\in\mathbb{F}^{<d_i}[X], and the protocol proceeds to the next iteration with f^i\hat f_i.

Final round: P sends dMd_M coefficients of a polynomial p^∈F<dM[X]\hat p\in\mathbb{F}^{<d_M}[X]; honest p^:=PolyFold(f^M−1,kM−1,rM−1fold)\hat p:=\mathrm{PolyFold}(\hat f_{M-1},k_{M-1},r_{M-1}^{\mathsf{fold}}).

The disjointness Li−1ki−1∩Li=∅\mathcal{L}_{i-1}^{k_{i-1}}\cap\mathcal{L}_i=\emptyset is what makes Gi∩Li=∅\mathcal{G}_i\cap\mathcal{L}_i=\emptyset automatic (the out-of-domain sample is drawn outside Li\mathcal{L}_i, the shift points live in Li−1ki−1\mathcal{L}_{i-1}^{k_{i-1}}), so the quotient’s denominator never vanishes on Li\mathcal{L}_i and the paper’s Fill\mathrm{Fill} polynomial is never needed.

3.3 Verifier decision phase

1. Main loop, for i=1,…,M−1i=1,\dots,M-1:

  • (a) For every j∈[ti−1]j\in[t_{i-1}], query Fold(fi−1,ki−1,ri−1fold)\mathrm{Fold}(f_{i-1},k_{i-1},r_{i-1}^{\mathsf{fold}}) at ri,jshiftr_{i,j}^{\mathsf{shift}}. This involves querying fi−1f_{i-1} at all ki−1k_{i-1} points x∈Li−1x\in\mathcal{L}_{i-1} with xki−1=ri,jshiftx^{k_{i-1}}=r_{i,j}^{\mathsf{shift}}. (For i≥2i\ge2, fi−1f_{i-1} is the virtual oracle of (c) below, so each of those is one query to gi−1g_{i-1} plus the quotient/degree-correction arithmetic.)
  • (b) Build Gi\mathcal{G}_i and Ansi\mathrm{Ans}_i as in step 5 of the interaction, and check the shake identity Shi(ρi)=∑a∈GiAns^i(ρi)−Ansi(a)ρi−a,\mathrm{Sh}_i(\rho_i)=\sum_{a\in\mathcal{G}_i}\frac{\widehat{\mathrm{Ans}}_i(\rho_i)-\mathrm{Ans}_i(a)}{\rho_i-a}, rejecting if ρi∈Gi\rho_i\in\mathcal{G}_i.Then, (virtually) set, for every x∈Lix\in\mathcal{L}_i, gi′(x):=gi(x)−Ans^i(x)V^Gi(x)g_i'(x):=\frac{g_i(x)-\widehat{\mathrm{Ans}}_i(x)}{\hat V_{\mathcal{G}_i}(x)}
  • (c) Define the virtual oracle fi:Li→Ff_i:\mathcal{L}_i\to\mathbb{F} as follows:fi:=DegCor(di,ricomb,gi′,di−∣Gi∣)f_i:=\mathrm{DegCor}(d_i,r_i^{\mathsf{comb}},g_i',d_i-\lvert\mathcal{G}_i\rvert) Notice that every query xx to fif_i translates into a single query to gig_i.

2. Consistency with the final polynomial: sample r1fin,…,rtM−1fin←LM−1kM−1r_1^{\mathsf{fin}},\dots,r_{t_{M-1}}^{\mathsf{fin}}\leftarrow\mathcal{L}_{M-1}^{k_{M-1}} and check p^(rjfin)=Fold(fM−1,kM−1,rM−1fold)(rjfin)∀j∈[tM−1].\hat p(r_j^{\mathsf{fin}})=\mathrm{Fold}(f_{M-1},k_{M-1},r_{M-1}^{\mathsf{fold}})(r_j^{\mathsf{fin}})\quad\forall j\in[t_{M-1}]. This is the only explicit equality check of the protocol. Everything before it binds the prover through quotients: a gig_i that disagrees with Ansi\mathrm{Ans}_i on Gi\mathcal{G}_i makes fif_i far from low degree (Lemma 4.4), and that is what the next iteration’s queries detect.

4. Repeated Queries

The ti−1t_{i-1} shift points are sampled i.i.d. from Li−1ki−1\mathcal{L}_{i-1}^{k_{i-1}} so they are sampled with replacement. Two of them coincide with probability about (ti−12)/∣Li−1ki−1∣\binom{t_{i-1}}{2}/\lvert\mathcal{L}_{i-1}^{k_{i-1}}\rvert. For concreteness, a schedule with t0=200t_0=200 queries into a folded domain of 2202^{20} points collides in around 2.5%2.5\% of executions, and summing over the quotient rounds of a realistic schedule gives a few percent per proof. This is not a negligible event.

4.1 Why it Matters

Gi\mathcal{G}_i enters the protocol as a set: in V^Gi\hat V_{\mathcal{G}_i}, in the interpolant Ans^i\widehat{\mathrm{Ans}}_i and in the degree correction through ∣Gi∣\lvert\mathcal{G}_i\rvert. If a repeated point were kept as a multiset, V^\hat V would acquire a double root at it while g^i−Ans^i\hat g_i-\widehat{\mathrm{Ans}}_i only vanishes there to first order, so the honest f^i\hat f_i would not be a polynomial and the honest prover would fail. If, instead, one party deduplicates and the other does not, they disagree on ∣Gi∣\lvert\mathcal{G}_i\rvert, on Ans^i\widehat{\mathrm{Ans}}_i and on V^Gi\hat V_{\mathcal{G}_i}, and every honest proof fails. So both parties must apply the same rule, and the rule must produce a set.

4.2 Solution A: Deduplicate

Drop every shift point that already occurred. Natively this is a sorted set and costs nothing. Its consequence is that ∣Gi∣\lvert\mathcal{G}_i\rvert is data-dependent: it is only known once the queries are, which is harmless natively but shapes a circuit verifier substantially:

  • ∣Gi∣\lvert\mathcal{G}_i\rvert becomes only known at proving time, so the exponent of the degree correction ∑ℓ≤∣Gi∣(rcombx)ℓ\sum_{\ell\le\lvert\mathcal{G}_i\rvert}(r^{\mathsf{comb}}x)^\ell is data-dependent.
  • Ans^i\widehat{\mathrm{Ans}}_i and Shi\mathrm{Sh}_i are sent zero-padded to ti−1+1t_{i-1}+1 coefficients and the tail beyond ∣Gi∣\lvert\mathcal{G}_i\rvert must be pinned to zero, to keep the degree bounds of Section 2.5.
  • The freshness flags themselves cost O(ti−12)O(t_{i-1}^2) comparisons: all quereies are diferent iff ∏i≠j(rishift−rjshift)≠0\prod_{i \neq j}(r_i^{\mathsf{shift}}-r_j^{\mathsf{shift}})\ne0.
  • V^Gi\hat V_{\mathcal{G}_i} cannot be built as a product over a set of unknown size. One builds instead U(X):=∏q(X−freshq⋅rqshift)=V^fresh(X)⋅XδU(X):=\prod_{q}\bigl(X-\mathrm{fresh}_q\cdot r_q^{\mathsf{shift}}\bigr)=\hat V_{\text{fresh}}(X)\cdot X^{\delta}, where a dropped repeat contributes the factor XX and δ\delta is the number of drops; UU is monic of degree exactly ti−1t_{i-1}, and the spurious xδx^{\delta} is divided out at evaluation time.

Deduplication is therefore correct and simple, but it is where most of the STIR-specific circuit cost lives.

4.4 Solution B: Hinted Freshness

Keep i.i.d. sampling, but let the prover supply the freshness flags and have the verifier check them in O(tlog⁡t)O(t\log t) through a sorted permutation argument instead of recomputing them in O(t2)O(t^2). This keeps everything in Section 4.2 except the quadratic term, and is only worth it if the sampling cannot be changed.

5. Round-by-Round Soundness

Under the hypotheses: f∉RS[F,L0,d0]f\notin\mathsf{RS}[\mathbb{F},\mathcal{L}_0,d_0],

  • δ0∈(0,Δ(f,RS[F,L0,d0])]∩(0,1−B⋆(ρ0))\delta_0\in(0,\Delta(f,\mathsf{RS}[\mathbb{F},\mathcal{L}_0,d_0])]\cap(0,1-\mathsf{B}^\star(\rho_0)),
  • δi∈(0,min⁡{1−ρi−1/∣Li∣, 1−B⋆(ρi)})\delta_i\in\bigl(0,\min\{1-\rho_i-1/\lvert\mathcal{L}_i\rvert,\ 1-\mathsf{B}^\star(\rho_i)\}\bigr) for 0<i<M−10<i< M-1,
  • RS[F,Li,di]\mathsf{RS}[\mathbb{F},\mathcal{L}_i,d_i] is (δi,ℓi)(\delta_i,\ell_i)-list decodable,

STIR has rbr soundness error (εfold,ε1out,ε1shift,…,εM−1out,εM−1shift,εfin)(\varepsilon_{\mathsf{fold}},\varepsilon_1^{\mathsf{out}},\varepsilon_1^{\mathsf{shift}},\dots,\varepsilon_{M-1}^{\mathsf{out}},\varepsilon_{M-1}^{\mathsf{shift}},\varepsilon_{\mathsf{fin}}) with

εfold≤err⋆(d0/k0,ρ0,δ0,k0),εiout≤ℓi22⋅di∣F∣−∣Li∣,εishift≤(1−δi−1)ti−1+err⋆(di,ρi,δi,ti−1+s)+err⋆(di/ki,ρi,δi,ki),εishake≤di∣F∣−∣Li∣,εfin≤(1−δM−1)tM−1.\begin{aligned} \varepsilon_{\mathsf{fold}} &\le \mathrm{err}^\star(d_0/k_0,\rho_0,\delta_0,k_0),\\ \varepsilon_i^{\mathsf{out}} &\le \frac{\ell_i^2}{2} \cdot \frac{d_i}{\lvert\mathbb{F}\rvert-\lvert\mathcal{L}_i\rvert},\\ \varepsilon_i^{\mathsf{shift}} &\le (1-\delta_{i-1})^{t_{i-1}}+\mathrm{err}^\star(d_i,\rho_i,\delta_i,t_{i-1}+s)+\mathrm{err}^\star(d_i/k_i,\rho_i,\delta_i,k_i),\\ \varepsilon_i^{\mathsf{shake}} &\le \frac{d_i}{\lvert\mathbb{F}\rvert-\lvert\mathcal{L}_i\rvert}, \\ \varepsilon_{\mathsf{fin}} &\le (1-\delta_{M-1})^{t_{M-1}}. \end{aligned}

5.1 How to read each term

The state function is essentially “the current fold is within δi\delta_i of the code” ∧\wedge “every consistency-with-Ans\mathrm{Ans} check so far holds”. The four errors correspond to the four ways the state can flip from 0 to 1:

  1. εfold\varepsilon_{\mathsf{fold}}. The initial folding brings ff close to the code by chance.
  2. εiout\varepsilon_i^{\mathsf{out}}. Two distinct codewords of List(gi,di,δi)\mathrm{List}(g_i,d_i,\delta_i) agree on the out-of-domain point. If this does not happen, there is at most one uu with u^(riout)=βi\hat u(r_{i}^{\mathsf{out}})=\beta_{i}.
  3. εishift\varepsilon_i^{\mathsf{shift}}. Three summands, one per tool:
    • (1−δi−1)ti−1(1-\delta_{i-1})^{t_{i-1}}: if that unique uu exists, u^\hat u disagrees with the fold of fi−1f_{i-1} on ≥δi−1\ge\delta_{i-1} of the domain, so the ti−1t_{i-1} shift queries catch it except with that probability.
    • err⋆(di,ρi,δi,ti−1+s)\mathrm{err}^\star(d_i,\rho_i,\delta_i,t_{i-1}+s): DegCor with ricombr_i^{\mathsf{comb}} failing to preserve distance.
    • err⋆(di/ki,ρi,δi,ki)\mathrm{err}^\star(d_i/k_i,\rho_i,\delta_i,k_i): the next fold with rifoldr_i^{\mathsf{fold}} failing to preserve distance.
  4. εfin\varepsilon_{\mathsf{fin}}. The final fold agrees with p^\hat p on all tM−1t_{M-1} points despite being δM−1\delta_{M-1}-far.

References

  • STIR: Reed–Solomon Proximity Testing with Fewer Queries - Arnon, Chiesa, Fenzi and Yogev [2024/390].
  • Giacomo Fenzi’s implementation.

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