Where Part 1 left us
Part 1 built the foundations of an HVZK IOPP for constrained interleaved codes:
- Zero-knowledge encodings. Randomized encodings where any coordinates of the codeword can be simulated from positions alone.
- The committed sumcheck relation . Succinct linear forms to kill the verifier’s cost, plus small mask oracles folded into a joint constraint to hide the target .
- Composable HVZK for IORs. The standard HVZK definition breaks under composition (Part 1’s counterexample). Fix: a distinguisher class that the simulator must additionally handle, and a composition theorem that chains errors across the seam.
- HVZK sumcheck reduction. Reduces a -interleaved code to its base code via small per-round masks (not a full mask), with mask oracles carried forward through the joint constraint. Drops problem size by a factor of at sublinear masking cost.
We can now test the interleaving of any zero-knowledge code in zero knowledge — by reducing to the base code. But the base code is still big. To get a polylog verifier we need to recursively shrink the code, and the move that does that is code-switching: an IOR from a test for code to a test for some smaller code .
The non-zero-knowledge version is well-trodden ([RR20]; [BCFW25]; WHIR’s recursion shape). The zero-knowledge version breaks in two distinct places. This part fixes both, assembles the HVZK WHIR/Ligerito corollary, and tackles the R1CS reduction.
Code-switching without zero-knowledge
Code-switching follows a clean template. The verifier has an oracle that — honestly — equals for some message satisfying a predicate . The prover wants to convince the verifier of this fact using a smaller proximity test.
- Prover sends . A new oracle . In the honest case, — the same message encoded under the new, smaller code .
- Verifier spot-queries . Sample , query .
- Run a proximity protocol for the new claim ” encodes some such that and for every .”
The added clauses are the consistency check: they tie the new oracle’s message to the old oracle’s message. Without them, the prover could swap at the switch.
This template is everywhere — [RR20], [RR22], [BCFW25], the [BMMS25] family of FICS/FACS protocols, WHIR’s recursion. It has not been applied to zero-knowledge codes outside [RW24], whose construction leans on specific properties of zero-knowledge tensor codes. We need a code-agnostic ZK version.
Why ZK encodings break the template
The first break: the consistency check assumes the codeword is a function of the message alone. With a ZK encoding it isn’t.
Concretely, depends on both the message and the randomness. The consistency check doesn’t even type-check anymore — you need to predict .
The obvious fix: have encode both the message and the randomness under . That works, but it requires padding ‘s message space, which means is twice the size, every subsequent sumcheck operates on a -blown object, and we’re back to overhead. Dead.
The actual fix reuses the committed sumcheck relation. Introduce an additional mask encoding the randomness under the ZK mask code . Now write the per-symbol claim by splitting ‘s generator matrix into a message part and a randomness part: where acts on the message and acts on the randomness. Then
which is a linear constraint on . The first piece accumulates into the existing main-oracle constraint via the succinct linear form ; the second piece accumulates as a constraint on the mask . Both go into the joint constraint of the next committed sumcheck relation. No padding, no .
That handles the randomness break. But the bigger break is structural: the WHIR-style recursion uses out-of-domain sampling in the list-decoding regime, and OOD’s whole job is to leak information.
OOD sampling and the second tension
Quick recap (see the WHIR post for the proper treatment). In the list-decoding regime — where the verifier picks a proximity parameter larger than the unique-decoding radius — multiple codewords in can be close to a malicious oracle . The verifier needs a way to force the prover to commit to one codeword, not a list.
WHIR’s version of the fix: the codewords are evaluations of low-degree polynomials, so the verifier sends a random point outside the evaluation domain and the prover answers with a claimed value . Two distinct low-degree polynomials agree at a random point with probability at most , so with high probability at most one polynomial in the list is consistent with — by answering, the prover has picked one. That’s an out-of-domain (OOD) sample.
The code-agnostic version abstracts the only property this used: evaluation at is a linear function of the message — the inner product of the coefficient vector with . So replace “evaluate at a random point” with “answer a random linear probe.” The verifier samples randomness , which determines a public matrix ( for zero-evader — defined next section), and the prover answers
random linear combinations of the message coordinates. The verifier’s later checks enforce that the message it ends up trusting answers the probe with exactly . This pins one codeword for the same reason the random point did: two distinct list codewords have distinct messages, their difference is a fixed nonzero vector, and a random probe sends a fixed nonzero vector to only with small probability — so no two list elements share an answer, and selects at most one.
Now look at what the prover just sent: linear combinations of with public coefficients, in the clear. leaks information about , hence about the witness.
And the leak is inherent. OOD is designed to uniquely identify the codeword (i.e., the witness). Zero-knowledge forbids revealing the witness. The two cannot literally coexist — you have to weaken one.
The paper weakens neither. It restructures OOD so the leak hits randomness instead of the witness.
Zero-evaders and private zero-evaders
The revised OOD sample is
with the difference being that the probe now also covers freshly sampled randomness — not the encoding coins, new randomness whose only job is privacy. The function is asked to satisfy two conditions:
- It’s still a good OOD sample. Equivalently, is a zero-evader [BCFW25]: for every nonzero vector , I.e. the matrix is, in expectation, full-rank enough to detect any nonzero input difference. This is what enables list-decoding-regime soundness.
- It leaks no information about . Formalized: is an -private zero-evader if can be efficiently simulated, with statistical error at most , without knowing .
Condition (2) sounds abstract; the construction that achieves it is not. Take any zero-evader and append columns sampled as a random rank- matrix :
This is the surjectivity argument from Part 1’s ZK encodings again: ‘s columns span , so with uniform, is uniform — a one-time pad on top of . Then is uniform even conditioned on , and the simulator just outputs a uniform . Zero-evasion survives: a nonzero with is caught by the random except with probability ; with it reduces to the original .
Lemma (informal, Lemma 2.13; formally Lemma 9.3). Any zero-evader with error extends, for any , to an -private zero-evader with error . Perfect privacy costs nothing.
What the constraint can — and can’t — pin
Recall what the OOD constraint does with the list: a candidate codeword in survives if its message answers the probe with . In the non-ZK world the encoding is a bijection — one message, one codeword — so “at most one surviving message” and “at most one surviving codeword” are the same statement, and [BCFW25] proves it.
A ZK encoding breaks the bijection. Decoding a candidate now yields a pair — message part and coins — and the probe is applied to the message part only. So list elements can differ in two ways, and the constraint treats them very differently:
- Same message, different coins. Both answer the probe identically. Both survive — the constraint cannot separate them. And it must not: privacy requires the honest codeword to be indistinguishable among all encodings of ; a constraint that singled out one encoding would itself leak the coins.
- Different messages. The message difference is a nonzero vector, and a zero-evader kills nonzero vectors: they share an answer with probability at most .
So the constraint partitions the list into classes — one per message — and with high probability at most one class is consistent with . The message is pinned; which encoding of it sits near stays ambiguous. That is exactly the split we need: soundness pinned the thing it uses, privacy kept the thing it hides behind.
Why is a pinned message enough, when the non-ZK analysis pinned a codeword? Because “which codeword” was never the question. Everything downstream is a statement about the message: the predicate , consistency between and across the switch, the witness the extractor must output. The non-ZK proofs pinned the codeword only because there it was the same thing.
Formally, stated for the joint probe over oracle-and-mask pairs:
Lemma (informal, Lemma 2.14). Take any two candidates with , that answer the probe identically. Then their decoded message parts are equal, except with probability for that fixed pair — and some bad pair exists anywhere in the lists with probability at most over . The coins are unconstrained.
The proof is the union bound you’d guess: fix two candidates whose message parts differ, zero-evasion kills their difference except with probability , union over all pairs of list elements.
There’s one last knot. The fresh randomness must be included in the code-switch claim too — otherwise the next round won’t know about it. Padding into would reintroduce the overhead we were just trying to avoid. The fix: a joint OOD sample of both and the mask , treating the pair as one object. The committed sumcheck relation, with its accumulating joint constraint, is exactly the right vehicle for this — and the entire reason it was designed the way it was.
The code-switch construction
Re-anchor what the IOR starts from, because everything below refers to it. The input is one committed-sumcheck claim over — Part 1’s relation:
Concretely the verifier holds: the oracle , hiding message behind coins ; the mask oracles left behind by earlier rounds, hiding messages ; and the public data — state , target , and the coefficient vectors each mask enters through. The output must be a claim of the same shape, one size smaller: a new oracle under , one more mask, a new target , over . That closure is what lets the step recurse.
The four pieces built so far — ZK-encoding-aware consistency, the joint OOD sample, the private zero-evader, and the committed sumcheck relation as the carrier — slot together like this:
A counterintuitive efficiency property: the prover and verifier time of this code-switch are independent of the starting code . The dominant cost is the encoding under (the new, smaller code) and the verifier’s computation of . The starting code’s structure pushes through into the next relation’s succinct linear form — captured by a quantity the paper calls the code-switching friendliness of — but doesn’t show up in this protocol’s local cost. People reach for “the slow code makes the switch slow”; that’s not what happens.
From building blocks to the theorems
Compose the HVZK sumcheck reduction (Part 1) with the code-switch IOR above, all of it under the composable HVZK-for-IORs framework, and three named theorems fall out. The composition is sound exactly because each IOR explicitly handles the “future distinguisher” — namely, the simulator of whatever IOR consumes its output — so HVZK chains end-to-end.
Theorem 1 — sublinear HVZK IOPP
Compose two things: the HVZK sumcheck reduction (Part 1’s §6), reducing to ; followed by a non-succinct base-case HVZK IOPP (a generalization of the simple -overhead protocol from §2.2 of the paper, applied at a much smaller scale).
The sublinear regime comes from picking — i.e. setting the interleaving factor to roughly the codeword block length. Then the encoded message in has size with , the post-reduction instance is -sized, and the base-case IOPP (which does pay overhead) runs on a -size sub-instance. Total proof length: alphabet symbols. Verifier time: sublinear. Overhead vs the non-private IOPP: — because the from the base case is amortized over a -size piece of the original -size problem.
The full mask in the base case is affordable only because it runs on the small piece. That asymmetry is how this paper buys sublinear masking globally.
Theorem 2 — HVZK code-switching
The full reduction from to , for arbitrary codes that can themselves be interleaved. Composition: run the HVZK sumcheck reduction first (drops interleaving), then run the code-switch IOR (drops to ). HVZK with respect to a bounded distinguisher class; RBR knowledge soundness with error at suitable field size.
This is the engine of the polylog-verifier theorem.
Theorem 4 — polylogarithmic HVZK verifier
Iterate Theorem 2 along a chain of codes , picked so that the -interleaving of has the same message size as (non-interleaved). Each application of Theorem 2 reduces the problem size by a factor of ; after steps the problem is small enough to finish with a small variant of the §2.2 base case. Theorem 4 is parametrized over an arbitrary chain length; specific instantiations (next subsection) pin .
This is the WHIR/Ligerito recursion shape — same idea, ZK-augmented. (See the WHIR post for the non-ZK version of this recursion.)
Corollary 3 — HVZK Reed–Solomon ⇒ HVZK WHIR/Ligerito
Instantiate Theorem 4’s chain with Reed–Solomon codes:
- (folding factor per step).
- Each is Reed–Solomon over an evaluation domain of size .
- instantiated with Reed–Solomon at rate , mask size .
This is the parameter regime of WHIR ([ACFY25]) and Ligerito ([NA25]), with ZK encodings substituted for the plain encodings throughout. The result:
- alphabet symbols sent by the prover; verifier makes queries.
- RBR knowledge soundness error .
- Perfect honest-verifier zero-knowledge (, thanks to RS having perfect ZK encodings with appended randomness).
- Proof length and query complexity match the non-private WHIR/Ligerito up to overhead.
This is the headline. Theorem 2 plus the building blocks above directly yield an HVZK variant of WHIR and Ligerito — a drop-in zero-knowledge replacement for the code-agnostic IOP family at overhead, in the list-decoding regime, with negligible RBR soundness error. The first such result.
Comparison
| Protocol | Overhead | Soundness regime | Code family | Verifier |
|---|---|---|---|---|
| [BCL22] | Unique decoding | Any ZK code (tensor-style) | Polylog | |
| [RW24] | Constant error only | ZK tensor codes | — | |
| Naive full-mask ZK WHIR | List decoding | Reed–Solomon only | Sublinear / polylog | |
| HVZK WHIR (this paper) | List decoding | Any -additive ZK code | Polylog |
The two rows that previously each owned one of these properties no longer dominate. This work is the first to put all four boxes ticked at once.
R1CS reduction with sublinear masking
The IOPP above tests proximity to constrained interleaved codes. To turn it into an end-to-end HVZK argument for NP, you reduce R1CS to that proximity test. The paper does this with overhead by reusing the same masking idea.
Backbone: an interleaved variant of [ACFY25]‘s -IOP for R1CS. Standard R1CS-to-sumcheck-to-codeword pipeline, but with two types of sublinear masks plugged in:
- R1CS witness masks. Protect the matrix-vector products , , from leaking. [BCL22] handles this by padding the R1CS instance with full-size random witness — overhead. This paper uses sublinear masks instead — .
- Sumcheck masks. Same as Part 1’s §6 — small per-round masks accumulated into the joint constraint.
Both mask types are syntactically identical from the relation’s perspective — they propagate into an instance of which our protocols can test in zero-knowledge end-to-end. Compose with Theorem 1 or Theorem 4 and you get an HVZK IOP for NP with list-decoding soundness and overhead over sending a single interleaved codeword — where [BCL22] pays a constant factor and only reaches unique-decoding soundness.
One honest caveat: the verifier here is non-succinct on R1CS-side cost, because this paper deliberately does not employ holographic preprocessing (the way [BCL22] and [RW24] do). The IOPP itself remains polylog-verifier.
If you want background on the R1CS-to-sumcheck step, Spartan and SPARK cover it.
What we didn’t cover
A few honest cuts.
High-distance codes from dispersers (Section 12 of the paper). The protocols here are code-agnostic, so you can buy more distance via the ABNNR construction [ABNNR92] — distance amplification through bipartite-disperser graphs. Plugged into Reed–Solomon, this gives amplified Reed–Solomon (ARS): RS at a low-cost base distance, then distance-boosted by gathering disperser neighbors. ARS shaves encoding time in the regime where plain RS pays for FFT-based evaluation, replacing it with . Cost: alphabet inflates by a factor of , so spot-checks cost more bytes per opening. Under reasonable parameters the paper reports a ≈ 30% argument-size win. Orthogonal to the ZK story and worth a separate read.
Round-by-round knowledge soundness proofs. We stated the errors qualitatively but skipped the full mutual-correlated-agreement accounting (the paper’s §6 and §9). WHIR treats MCA and list-decoding-regime soundness analysis for the non-ZK case; the ZK accounting is structurally similar but adds extra terms for the mask oracles.
Memory-efficient streaming prover. The paper notes that Theorem 1 is plausibly amenable to space-efficient streaming proving (à la [BBHV22], [CTY11]) — the encoding of can be done in space proportional to a single base encoding, and the sumcheck can stream too. Not pursued in the paper but flagged as future work.
Malicious-verifier ZK. Out of scope. Fiat–Shamir turns HVZK into malicious-verifier ZK for free in the non-interactive setting, which is what all deployed hash-based SNARKs care about.
Conclusion
The construction lands on five interlocking moves:
- The committed sumcheck relation — succinct linear forms plus mask oracles folded into a joint constraint, set up so the protocol can carry mask state through composition.
- Composable HVZK for IORs — the distinguisher class , the composition theorem, and the discipline of making “future queries” explicit so naive composition stops shipping the witness.
- HVZK sumcheck via interleaved folding — small per-round masks, encode-then-fold = fold-then-encode, and correlated queries over the bigger alphabet to keep list-decoding-regime soundness affordable.
- Private zero-evaders for ZK-compatible OOD — randomized OOD samples that still pin a unique message while looking uniform to the verifier, plus the joint OOD sample over the message and an extra mask piece.
- Code-agnostic assembly — Theorems 1/2/4 plus the RS instantiation give the first HVZK variant of WHIR and Ligerito.
The practical upshot is concrete. Anonymous-credential stacks like [Fs24], built on the sublinear hash-based zkSNARK in [AHIV17], pay overhead today because the underlying IOP is private but old. The corresponding non-private IOPs are no longer state of the art. This work gives a drop-in path: swap the old private IOP for an HVZK WHIR/Ligerito built from the protocols above, eat overhead instead of , and the effect compounds because we’re measuring against the modern non-private state of the art rather than the 2017 baseline.
The longer-term effect is structural. The code-agnostic IOP family was the wrong place to look for ZK because the existing zero-knowledge moves were tied to polynomial codes. This paper unties them. Once the framework is in place — ZK encodings, composable HVZK-for-IORs, sublinear masking, private OOD — the next ZK variant of the next code-agnostic IOP is a much shorter walk.
References
- This paper — Chiesa, A., Fenzi, G., & Weissenberg, G. (Feb 2026). Zero-Knowledge IOPPs for Constrained Interleaved Codes.
- WHIR — Arnon, G., Chiesa, A., Fenzi, G., & Yogev, E. (2025). WHIR: Reed–Solomon Proximity Testing with Super-Fast Verification. EUROCRYPT ‘25.
- Ligerito — Novakovic, A., & Angeris, G. (2025). Ligerito: A Small and Concretely Fast Polynomial Commitment Scheme. eprint 2025/1187
- BCFW25 — Bünz, B., Chiesa, A., Fenzi, G., & Wang, W. (2025). Linear-Time Accumulation Schemes. TCC ‘25.
- BCL22 — Bootle, J., Chiesa, A., & Liu, S. (2022). Zero-Knowledge IOPs with Linear-Time Prover and Polylogarithmic-Time Verifier. EUROCRYPT ‘22.
- RW24 — Ron-Zewi, N., & Weiss, M. (2024). Zero-knowledge IOPs Approaching Witness Length. CRYPTO ‘24.
- RR20 — Ron-Zewi, N., & Rothblum, R. (2020). Local Proofs Approaching the Witness Length. FOCS ‘20.
- RR22 — Ron-Zewi, N., & Rothblum, R.D. (2022). Proving as Fast as Computing: Succinct Arguments with Constant Prover Overhead. STOC ‘22.
- BMMS25 — Baweja, A., Mishra, P., Mopuri, T., & Shtepel, M. (2025). FICS and FACS: Fast IOPPs and Accumulation via Code-Switching. eprint 2025/737
- ABNNR92 — Alon, N., Bruck, J., Naor, J., Naor, M., & Roth, R.M. (1992). Construction of asymptotically good low-rate error-correcting codes through pseudo-random graphs. IEEE TIT 38(2).
- AHIV17 (Ligero) — Ames, S., Hazay, C., Ishai, Y., & Venkitasubramaniam, M. (2017). Ligero: Lightweight Sublinear Arguments Without a Trusted Setup. CCS ‘17.
- Fs24 — Frigo, M., & Shelat, A. (2024). Anonymous credentials from ECDSA. eprint 2024/2010
- BBHV22 — Bangalore, L., Bhadauria, R., Hazay, C., & Venkitasubramaniam, M. (2022). On Black-Box Constructions of Time and Space Efficient Sublinear Arguments from Symmetric-Key Primitives. TCC ‘22.
- CTY11 — Cormode, G., Thaler, J., & Yi, K. (2011). Verifying computations with streaming interactive proofs. VLDB.
- ACFY25 — Arnon, G., Chiesa, A., Fenzi, G., & Yogev, E. (2025). WHIR: Reed–Solomon Proximity Testing with Super-Fast Verification. EUROCRYPT ‘25.
- Companion blogs. WHIR, TensorSwitch I, TensorSwitch II, Spartan, SPARK, Part 1 of this series.