Ziren: Succinct Arguments for MIPS32 Execution

Stephen Duan1,2,†, Jingping Yin1, Blake Hou1, Vangher Pham1, Ethan Zhu2 and Ming Guo1

1 ZKM Team · 2 GOAT Network · † Corresponding author:

October 2026 · Source code: https://github.com/ProjectZKM/Ziren · Also available as IACR ePrint 2026/2330 (PDF). Measurements name the configuration they were taken on (§10.1).

Abstract

A succinct argument for machine execution convinces a verifier that a program compiled for a real instruction set ran correctly, with a proof far shorter than the execution and a check far cheaper than replaying it. We present Ziren, a production zkVM for MIPS32: it proves 77 user-mode integer instructions of MIPS32r2 and has proved Ethereum mainnet blocks end to end in production.

Ziren is a CPU-less chip architecture: each executed instruction is one row of its opcode’s chip. Each shard is proved by one lookup argument for all of its buses and one zerocheck for all of its constraints, and the claims on its tens of thousands of columns of differing heights are reduced by a jagged sumcheck to a single evaluation, opened by one batched WHIR proof. A recursion tree composes the shard proofs under an enumerated allowlist of verifying keys, and the determinism of 57 of the core machine’s 62 chips (all but three preprocessed tables and two SHA-256 control chips) is extracted mechanically, as Lean 4 theorems, from the same constraint description the prover evaluates.

On a configuration that precedes four later changes, proving throughput reaches up to 7.3 MHz on one NVIDIA RTX 5090 and scales horizontally across GPUs, reaching 24 MHz on four.

Each proof stage of the analysed schedule has more than 100 bits of interactive soundness, and 93.5 bits of composite security over a block’s tree of about 150 proofs. The end-to-end statement is conditional: it assumes round-by-round knowledge soundness of every node, compatibility of the composed extractors, that the recursion programs, which are not extracted, enforce the compose relation, and a property of the cross-shard digest to which we assign no value; identifying the trace with an execution also needs determinism of the two SHA-256 control chips and real-row exhaustiveness. All 104 extracted determinism theorems are proved in Lean 4: a propagation analysis derives every output column, and the derivation is replayed as step lemmas over gadget theorems proved once.

Index terms: arithmetic circuits, formal verification, GPU acceleration, MIPS32, polynomial commitment schemes, round-by-round soundness, verifiable computation, zero-knowledge virtual machines.

1 Introduction

A succinct argument for machine execution convinces a verifier that a program, run on a given instruction-set architecture, produced a given output, with a proof far shorter and a check far cheaper than the execution. Such systems are commonly called zero-knowledge virtual machines (zkVMs), although the proofs studied here are succinct but not hiding. The benchmark throughout is an Ethereum block of several hundred million instructions [Eth26b], a hash-intensive workload that we use as a benchmark rather than as the application.

1.1 Succinct arguments for machine execution

A zkVM fixes an instruction set, a register file and a memory model, and proves that a program for that machine ran correctly. Representative systems that prove RISC-V programs are SP1, OpenVM, ZisK and Jolt [Suc24, Ope26b, Zis25, AST24], and system-level comparisons are restricted to these four. Such a system has two halves, a front end and a back end. The arithmetisation turns an execution into tables whose rows satisfy polynomial constraints and between which multiset relations hold; the commitment and its proximity test let the prover show that it knows such tables. The first decides how many field elements an executed instruction becomes, and the second is where the prover pays for each.

Why MIPS32. Ziren is a production zkVM for MIPS32. It proves 77 user-mode integer instructions of MIPS32r2 with the branch-delay slot (Appendix B, which also names the few it leaves out), and it has proved Ethereum mainnet blocks end to end in production; earlier proof systems address MIPS-like models or offer MIPS as one mode among several (§1.6). The specification is stable: its owner moved its roadmap to RISC-V in 2021 [Tur21, Har25], so the instruction set, and the verifying keys derived from it, do not change. It is uniform: fixed 32-bit encodings in a handful of formats let one row carry an instruction’s whole frame. And its toolchains are mature: Rust, Go and C programs compile to the same little-endian ELF, and the architecture is widely deployed [MIP26]. The fault-proof software of Ethereum rollups, Optimism’s Cannon and Kona [Opt23, OP 24], is therefore in range, subject to compatible runtime conventions and image formats.

What makes MIPS32 hard to prove. Four properties shape the design. The instruction after a branch executes before control transfers,1 so an instruction’s successor is data rather than the following address. The relations that hold the machine together are multiset relations across tables, so discharging them table by table would cost one argument per bus per table. A shard of the block workload commits up to about 3.6\cdot 10^4 columns whose heights run from 32 rows to millions, so neither one commitment per column nor a common height is affordable. And a 32-bit word does not fit the 31-bit field, so every word is a vector of bytes.

1.2 Ziren: one row per executed instruction

In Ziren, every executed instruction is one row of the table (the chip) for its opcode, and there is no central CPU table. Each chip embeds what we call an instruction frame, the fixed group of columns and bus interactions that surrounds every row’s own logic and makes the row an executed instruction whatever it computes: the frame fetches the row’s instruction from the committed program, performs its register and memory accesses at fixed sub-cycle positions, and receives and sends the machine state on a bus; the state is a program-counter pair, which absorbs the delay slot (§5.3). The committed trace is thus the execution regrouped by opcode, the device of vRAM [ZGK+18], with the state bus as its permutation check.

Above the rows there is one argument per shard. Registers and memory share one offline memory-checking argument, carried across shards by an elliptic-curve digest; every bus is discharged by one LogUp-GKR instance and every constraint by one zerocheck; and the jagged sumcheck of Hemo et al. [HJR+25] reduces the claims on tens of thousands of columns of differing heights to one evaluation, which a single batched WHIR opening [ACFY24b] authenticates against every commitment. Recursion composes the shard proofs, admitting only verifying keys enumerated from the machine’s declared shard shapes. A block proof is

\mathsf{Rec}\Big[\,\mathsf{FS}\big[\,\mathsf{JaggedWHIR}\big[\,\mathsf{LogUpGKR}\wedge\mathsf{Zerocheck}\,[\mathcal{R}_{\mathrm{shard}}]\,\big]\big]\Big],

and Figure 1 draws the pipeline. Section 3 describes the system as a stack of these arguments ending in a compressed proof for a native verifier, and two applications built on it, which verify that proof inside other proof systems: a pairing-based SNARK for an on-chain verifier (§8.1), and a binary-field argument for a garbled verifier, evaluated as a Boolean circuit (§3.5).

What is new. The commitment scheme, proximity test, lookup argument and recursion shape Ziren builds on are prior work, used as published; our contributions are the machine and three techniques around it.

  • The machine. An arithmetisation of MIPS32 with no CPU table, in which an instruction frame carries the delay slot as a program-counter pair (Sections 4 and 5); the concrete composition of the jagged reduction with WHIR, with its multi-root layout, parameter schedule and recursive verifier (Sections 6 and 7); and a verifying-key allowlist of about 6.4\cdot10^3 keys enumerated from the machine’s declared shapes without executing a guest (Section 8).
  • Determinism in Lean 4. The constraint system of every chip the extraction models (57 chips) is taken from the Rust description the prover evaluates, and its determinism is stated as a Lean 4 theorem; a propagation analysis derives each output from the inputs, and the generator replays that derivation as a proof, one step per determined column, over a library of hand-proved gadget lemmas (§9.7). All 104 theorems are closed, with no axiom beyond Lean 4’s standard three.
  • Pipelined proving. Recursion overlaps core proving: leaves and compose nodes are proved on the GPUs while the block’s core shards are still being proved, so only two serial composes remain after the last shard proof, and trace generation and the proof-of-work searches run on the device, so the host executes the guest, re-emulates each shard for its worker, and schedules (Section 3.3). This is a design property; its effect on wall-clock time is not separated from the rest (§10.5).
  • Four options for cross-shard memory. Multiset hashes over an elliptic curve and over a lattice, a global LogUp-GKR challenge drawn from a hash chain over every shard’s commitment, and Merkle roots over touched memory (§5.5). The elliptic-curve hash is the one component that is not hash-based; against it, on the same GPUs, the global challenge is 29 to 42 % slower and Merkle roots are 16.6 % faster on one GPU and 3.4 % slower on four, and the lattice hash, costed, would need at least 19.6× today’s committed area. Section 9.8 gives what each rests on against a quantum adversary.

1.3 Costs

The unit of cost. Ziren commits Merkle trees over Reed–Solomon encodings of a 31-bit field, where every cell costs the same whatever it holds; a small value is no cheaper than a large one, unlike under a commitment built from multi-scalar multiplication, where small values are cheaper [AST24]. The unit of cost is therefore the cell, together with the bus interactions each row raises, which size the lookup argument. Cost has two independent parts. Instruction efficiency is the cells and interactions per executed instruction, a property of the arithmetisation that does not change with the hardware; proving efficiency is the rate at which an implementation turns cells into a proof, in guest cycles per second on named hardware. End-to-end time is the work the first gives an execution, divided by the rate the second gives, and Section 10 states which of the two each measurement reports.

Prover costs. An executed instruction pays up to 32 columns of frame and program-counter pair before it computes anything, 22 of them for the three register accesses of an R-type instruction; the operation adds from four columns (AddSub) to over a hundred (DivRem) among the arithmetic chips, mostly byte-table lookups and witnessed carries (§§5.9 and 5.10). Block 25 955 640 (496 million cycles) commits about 59 cells and raises about 26 bus interactions per executed instruction, about 9 of those cells being the cross-shard rows of the memory argument. Cells per instruction is a property of the workload, not a constant: a precompile call is one guest cycle but many rows, and on precompile-heavy blocks a shard closes on a committed-area budget of 4.6\cdot10^8 cells before the configured shard size binds, so two mainnet blocks of 949 and 943 million cycles became 702 and 213 shards in production. Guest cycles, the unit block-proving dashboards report, therefore do not measure prover work (§10.2). One NVIDIA RTX 5090 proves at up to 7.3 MHz, and four reach 20–24 MHz on blocks of 420 to 912 million cycles (Table 10), on the measured configuration of §10.1, which precedes four later changes.

Verifier costs. The verifier reads one compressed proof of 274 KiB and checks it in about 73 ms on one host; the size does not depend on the execution’s length; it is set by the opening’s schedule, which trades it against prover work (§10.4). Soundness is a union bound over each proof stage’s two dozen transcript components rather than the smallest of them: every stage is above 100 bits, and the composite security of a block, the level of its whole recursion tree with every node’s error summed, is 93.5 bits for the measured block’s tree of about 150 proofs and falls with the logarithm of the proof count (§9.2). These bound the interactive protocol. Fiat–Shamir subtracts \log_2 Q against Q oracle queries. Taking each node’s round-by-round error to be its computed sum, which leaves out an unquantified function-binding loss, the compiled composite security is 93.5-\log_2 Q bits, 53.5 at Q=2^{40}. The cross-shard digest adds an error term to which we assign no value.

1.4 Auditable soundness

An accepting proof implies a satisfying trace; that the trace is an execution of the advertised machine needs the arithmetisation to admit one behaviour per input, which the proof system cannot establish about itself. Ziren audits its per-opcode constraints mechanically: it extracts the determinism of every chip it models as a theorem statement from the constraint description and discharges all 104 of them in Lean 4. A lookup-only design instead relies on tables fixed by the instruction set, which are easier to audit [AST24].

Theorem 1.1 (Conditional argument statement, informal). Let \mathsf{Emulate} be the MIPS32 execution relation of Section 4. The implemented protocol over the 31-bit field KoalaBear consists of one lookup argument and one zerocheck per shard, a jagged multilinear commitment opened through WHIR, and a recursion tree. Honest executions that halt with exit code zero produce accepting proofs (§4.4). Suppose that every shard and recursion-node protocol satisfies the round-by-round knowledge-soundness premise of Theorem 9.2, that child extractors accept the transcripts produced by parent extractors, that the recursion programs enforce the compose relation, and that Assumption 9.4 holds. Then the recursion tree is knowledge sound for its satisfying witness rows in the random-oracle model, with the conditional error bound of Theorem 9.2. Section 9 collects these hypotheses, and §9.3 separates this statement into three layers: each node’s protocol is a functional IOP read through evaluation queries; committing to it with the jagged WHIR opening gives an interactive argument that is knowledge sound under a function-binding hypothesis on the commitment; and Fiat–Shamir compiles it into the deployed proof. Identifying those rows with a unique \mathsf{Emulate} execution additionally requires the premises of Theorem 9.6, chip determinism, proved in Lean 4 for every extracted chip (§9.7), and real-row exhaustiveness (§9.1).

Theorem 1.2 (Chip determinism, informal). For every chip U of the core machine that the extraction models, there is a mechanically extracted Lean 4 theorem stating that two rows of U that satisfy its constraints and agree on their inputs (their bus inputs and the values the constraints leave to the prover by design) agree on their bus outputs. All 104 such theorems are closed: a propagation analysis in the manner of Picus [PCW+23] derives every output column from the inputs, and the generator replays the derivation as a chain of step lemmas, each closed in a context holding only the columns and conjuncts the step uses (§9.7). Together with the bus arguments, chip determinism implies that an accepting shard proof determines, up to permutation, every row reachable from the entry state along the state and memory buses, given the initial values of the words the shard touches and those declared free values (Theorem 9.6); that this exhausts the real rows is a property of the chip set, which we argue but do not prove.

1.5 Technical overview: one and

We illustrate with bitwise AND. A MIPS32 and executed at clock \mathsf{clk} is one row of the Bitwise chip, 37 columns wide: 30 of frame (shard, clock limbs, opcode, register indices, zero-register flag and three register accesses, each with value, previous timestamp and a difference limb) and the program-counter pair. The frame sends (\mathsf{pc},\mathsf{opcode},\ldots) on the program bus, receives (\mathsf{shard},\mathsf{clk},\mathsf{pc},\mathsf{next\_pc}) and sends (\mathsf{shard},\mathsf{clk}+5,\mathsf{next\_pc},\mathsf{next\_pc}+4) on the state bus, and performs the three accesses on the memory bus. The last five columns are four selectors and a gate: no constraint computes the result, which is four lookups into a 2^{16}-entry byte table, the original Jolt design’s decomposition [AST24, STW24] at four 8-bit chunks (§5.2).

The general case adds three difficulties: a delay-slot row’s successor is data fixed by the preceding branch (§5.3); a limb identity in \mathbb{F} need not hold over the integers; and memory crosses shards (§5.5). Section 3 states the protocol above the rows.

1.6 Related work

Table 1 places the systems discussed along the axes of this introduction. Its axes are design axes: no cross-system performance claim follows from them, and no same-hardware comparison is attempted. Machine-checked constraint-system correctness is compared only with the published verification work cited below.

Table 1: Design axes of Ziren and four systems it is most often read against, from their public descriptions at the release named in the last column, retrieved on 2026-09-24. The Regime column names the basis on which each project states its soundness level; regimes differ and levels are not comparable without the accounting of Section 9.2.

System ISA Field Instruction tables Lookup Commitment / IOPP Regime Release
Ziren MIPS32 KoalaBear (2^{31}) chip per opcode, frames LogUp-GKR Jagged over WHIR unique decoding, Johnson bound at the root; union bound this paper
SP1 Hypercube [Suc25a] RV64IM KoalaBear chip per opcode, readers LogUp-GKR Jagged over BaseFold unique decoding, no proximity-gap conjecture v6.8.0
ZisK [Zis25] RV64IMA Goldilocks micro-operations, PIL2 LogUp PIL2 (e)STARK not stated v1.3.0-alpha
OpenVM [Ope26b] own ISA, RV32IM transpiler BabyBear executor chips, adapter and core LogUp SWIRL: stacked WHIR unique decoding low in the tree, list decoding above v2.0.2
Jolt [AST24] RV64IMAC BN254 scalar (Dory), 128-bit (Akita) Twist and Shout, small R1CS Twist and Shout Dory (default), Akita (lattice) not stated v0.3.0-alpha

Chip-decomposed machines. SP1 [Suc24] decomposes a RISC-V machine into one chip per opcode with LogUp-GKR and recursive aggregation, SP1 Hypercube [Suc25a] adds the jagged commitment with a shard-level lookup and zerocheck, and SP1 also has a just-in-time executor [Suc25b]. SP1 has no CPU table either; §5.3 compares its per-chip register readers with the frame. Two of SP1’s devices are used here and credited where they appear: the elliptic-curve cross-shard digest [RR24] and the register shadow read. Ziren differs in the instruction set, in an instruction frame that carries the delay slot and replaces the CPU table, in its arithmetisation of MIPS32 family by family, in opening the jagged commitment with WHIR rather than BaseFold, and in a union-bound soundness level.

SP1 counts query soundness in the unique-decoding regime and relies on proximity-gap theorems rather than conjectures [Suc26b]; Ziren does the same below the root and uses the Johnson bound, also proved, for the root’s compress schedule (§9.2). OpenVM [Ope26b] likewise has no CPU chip: its executors pass (\mathsf{pc},t) on an execution bus, and an executor splits into an adapter that owns every interaction and a core that computes; the instruction frame plays the role of SP1’s state-and-reader columns and of OpenVM’s adapter for MIPS32, and Section 5.3 compares the three.

The commitment layer. OpenVM’s SWIRL combines stacked WHIR with LogUp-GKR [Ope26c], the same pair of ideas as our commitment layer. It pads columns to power-of-two heights with a univariate skip and reduces openings by a batch sumcheck fused with the lookup’s input layer, where we round heights to a multiple of 32 and use the jagged sumcheck. Three further differences follow: our WHIR rounds fold several variables at a time; KoalaBear rather than BabyBear changes the challenge extension and hence the fingerprinting term; and SWIRL composes round-by-round errors by their maximum per layer, a basis not comparable with our union bound. Ceno’s implementation offers a jagged reduction over BaseFold by default, and BaseFold or WHIR alone as alternatives [Scr26], while the Ceno paper leaves the commitment abstract [LZZ+24]; the jagged paper itself anticipates WHIR in place of its FRI-based opening [HJR+25, Rem. 7.1]. What we claim at this layer is the concrete composition, its multi-root layout, schedule, recursive verifier and soundness accounting, not the idea of combining them.

Where the prover’s work is put. Jolt [AST24] evaluates instructions by lookups rather than per-opcode constraints; since v0.2.0 it uses Twist and Shout [ST25] in place of the Lasso construction [STW24] of its original design, with a small R1CS instance for instruction fetch. Ziren uses lookups for byte-granular facts and buses and evaluates instructions by constraints. The two meet at three points (Section 5): the byte table is the original Jolt design’s decomposition of a 32-bit instruction table into four byte-pair lookups, since made unnecessary by Shout [ST25], applied here to bitwise operations and comparisons; the chip-per-opcode layout is the regrouping by instruction that Jolt, after vRAM [ZGK+18], names as one way to route a step to its table; and the memory argument is the timestamped check the original Jolt design took from Spice [SAGL18], where Jolt now uses Twist. ZisK [Zis25] instead lowers RV64IMA execution to micro-operations constrained in PIL2 and commits a STARK trace. Section 10 measures this system against itself.

Verifiable RAM and regrouped traces. Three of this system’s devices come from one line of work. Blum et al.’s offline memory check [BEG+94], with Spice’s timestamps [SAGL18], verifies a read–write memory without reordering the trace; Ziren’s registers and memory use it. vRAM [ZGK+18] avoided a circuit carrying every instruction at every step by regrouping the trace by instruction and proving the regrouping a permutation; Ceno’s per-opcode design [LZZ+24] published that regrouping in multiset form, as a set equality over (program counter, clock) records, and initialised only the memory a run touches. The frame is the same regrouping, with the delay slot’s counter pair and a shard field in the state and a proved chain lemma (Lemma 5.2); Ziren likewise initialises only touched words. Ceno’s basic-block design has no counterpart here, and its implementation is per opcode [Scr26].

Other systems. RISC Zero [BGt23] proves one trace of machine cycles under a fixed constraint set, selected per cycle by public control columns, with a sorted-column permutation for memory and a DEEP-ALI and FRI STARK, and, unlike Ziren, claims zero knowledge (2023 draft). Cairo [GPR21] and Valida [Lit24] design an instruction set for proving instead of inheriting a hardware one. Nexus 1.0 folded executions with Nova-family schemes in a tree of proof-carrying data [Nex24]; Nexus 3.0 replaced folding with a circle STARK over Mersenne-31, a single trace with a CPU component and a logarithmic-derivative memory check [Nex25]. Airbender [Mat25] targets Mersenne-31 with a degree-two arithmetisation and DEEP-FRI, and Cysic [Cys25] pursues dedicated proving hardware, outside the CPU–GPU scope of this paper. Among MIPS systems, Zilch’s zMIPS verifies a MIPS-like instruction model and composes instruction proofs [MT21]; o1VM documents a segmented prover with MIPS and RISC-V modes [BL24]; Cannon [Opt23] is a single-step MIPS interpreter for interactive fault proofs whose suite is one of our conformance inputs, and Kona [OP 24] the fault-proof program of the same ecosystem. On constrained devices, proofs today serve authentication and attestation [CJSC23, SD21, DDGM23, EH24]; a zkVM for the device’s instruction set makes its software execution the statement instead.

Primitives and verification. The field, Poseidon2 [GKS23], constraint interfaces and transforms come from Plonky3 [Pol24]. Circle STARKs [HLP24] reach smooth Mersenne-31 domains through the circle group, and Binius [DP23, DP24] avoids splitting words with binary towers; KoalaBear uses ordinary Reed–Solomon domains. The proximity line runs from FRI [BSBHR18] through DEEP-FRI [BSGKS20] and proximity gaps [BSCI+20] to BaseFold [ZCF23], STIR [ACFY24a] and WHIR [ACFY24b]; Ligero [AHIV17] and Brakedown [GLS+21] are linear-time alternatives. The jagged commitment is that of Hemo et al. [HJR+25], with the branching-program evaluation of Holmgren and Rothblum [HR18]. The lookup is Haböck’s logarithmic derivative [Hab22] in its GKR realisation [PH23]; Plookup [GW20] and cq [EFG22] are univariate alternatives that do not transfer to this multilinear many-bus workload. Picus [PCW+23] introduced the determinism formulation and an SMT solver for it; we discharge it in Lean 4, which gives kernel-checked proofs. OpenVM’s verification project proves refinement of its RV32IM and precompile chips to Lean specifications [Ope26d], a stronger property than determinism, for a different ISA. The soundness accounting follows the WHIR analysis [ACFY24b], computed with soundcalc [Eth26a], in the style of the ethSTARK documentation [Sta23].

1.7 Scope and limitations

This paper measures and accounts only Ziren, the path to the compressed proof; the applications built on that proof (§3.5) are outside its scope. The proofs are not zero-knowledge. Soundness rests on a computational assumption for the cross-shard digest in addition to the information-theoretic bounds of the proximity test, and that assumption, unlike the rest of the argument, does not survive a quantum adversary (§9.8). The determinism pipeline takes any chip written against the prover’s constraint interface; we have run it on the core machine, and the two SHA-256 control chips and the recursion machine’s chips, written against the same interface, are its next inputs rather than a new method. Real-row exhaustiveness and Theorem 9.6 itself are argued on paper (§9.1). The evaluation uses one workload class on one GPU model. The verifying-key allowlist is enumerated from the machine’s declared chip-set clusters, which are curated from its target workloads rather than exhaustive, so a shard outside them is refused rather than admitted (§8).

2 Technical preliminaries

This section fixes the field, the arguments and the chip model the rest of the paper builds on. Appendix C lists each result used from prior work and where this paper uses it.

2.1 Field and multilinear extensions

Field. All traces live over the prime field \mathbb{F}=\mathsf{KoalaBear}, p=2^{31}-2^{24}+1, whose multiplicative group has two-adicity 24; the rate schedule of Section 7 keeps the largest Reed–Solomon domain within that limit. Challenges and all sumcheck arithmetic use the extension \mathbb{F}_{p^4}=\mathbb{F}[X]/(X^4-3), so a sumcheck round of degree d has soundness error d/|\mathbb{F}_{p^4}|\approx d\cdot 2^{-124}. Since 2^{32}>p, a 32-bit word is not one field element, and every word in the arithmetisation is four field elements holding its little-endian bytes.

Multilinear extensions and sumcheck. For f:\{0,1\}^n\to\mathbb{F} the multilinear extension is \widetilde f(\boldsymbol z)=\sum_{\boldsymbol b} f(\boldsymbol b)\,\mathrm{eq}(\boldsymbol b,\boldsymbol z) with \mathrm{eq}(\boldsymbol b,\boldsymbol z)=\prod_i\big(b_iz_i+(1-b_i)(1-z_i)\big). The sumcheck protocol [LFKN92] reduces a claim \sum_{\boldsymbol b\in\{0,1\}^n} g(\boldsymbol b)=\sigma about a low-degree g to a claim g(\boldsymbol r)=\sigma' at a random \boldsymbol r\in\mathbb{F}_{p^4}^n in n rounds of degree \deg g. We write a claim \widetilde f(\boldsymbol z)=v as the pair (\boldsymbol z,v).

Zerocheck. To show g(\boldsymbol b)=0 on a subcube, the verifier samples \boldsymbol r and the prover runs a sumcheck on \sum_{\boldsymbol b}\mathrm{eq}(\boldsymbol b,\boldsymbol r)\,g(\boldsymbol b), which is zero for every \boldsymbol r exactly when g vanishes on the subcube, so a random \boldsymbol r errs with probability at most the number of variables over |\mathbb{F}_{p^4}|, plus the sumcheck’s error. Section 5.7 proves all constraints of a shard by one such check.

2.2 Arguments and polynomial commitments

Definition 2.1 (Argument of knowledge). Let \mathcal{R} be a relation over public parameters \mathsf{pp}, a structure s common to many instances, an instance u and a witness w. An argument of knowledge for \mathcal{R} is a tuple of algorithms (\mathsf{Setup},\mathsf{Prove},\mathsf{Verify}): \mathsf{Setup}(\mathsf{pp},s) outputs a proving key and a verifying key (\mathsf{pk},\mathsf{vk}); \mathsf{Prove}(\mathsf{pk},u,w) outputs a proof \pi; and \mathsf{Verify}(\mathsf{vk},u,\pi) outputs a bit. It is complete if an honest proof for (\mathsf{pp},s,u,w)\in\mathcal{R} always verifies, knowledge sound with error \varepsilon if for every efficient prover whose proof verifies with probability above \varepsilon an extractor outputs a w with (\mathsf{pp},s,u,w)\in\mathcal{R}, and succinct if the proof size and verification time are polylogarithmic in the size of the statement’s computation.

Here s is a program image, u the public values of an execution and w its input and hint streams (§4.4); the construction provides no zero knowledge.

Definition 2.2 (Multilinear polynomial commitment). A polynomial commitment scheme for multilinear polynomials is a tuple (\mathsf{Commit},\mathsf{Open},\mathsf{VerifyOpen}). \mathsf{Commit}(\mathsf{pp},f) outputs a commitment C to an m-variate multilinear f and a prover state; \mathsf{Open} is an interactive protocol, compiled by Fiat–Shamir, in which the prover convinces the verifier that f(\boldsymbol z)=v for a given point \boldsymbol z\in\mathbb{F}_{p^4}^m and value v, and \mathsf{VerifyOpen}(C,\boldsymbol z,v,\pi)\in\{0,1\} is its verifier. It is binding if no efficient prover opens one commitment to two different polynomials, and knowledge sound if an accepting opening yields an f consistent with C and f(\boldsymbol z)=v.

A polynomial interactive oracle proof, in which the verifier only evaluates the prover’s polynomials at a few points, compiled with a polynomial commitment gives a succinct argument [BSCS16]; every argument of this paper is of that kind.

Reed–Solomon and constrained Reed–Solomon codes. For a smooth domain L\subset\mathbb{F}^* (a coset of a subgroup of order 2^d) the code \mathrm{RS}[\mathbb{F},L,m] is the set of functions L\to\mathbb{F} that agree with a polynomial of degree <2^m; its rate is \rho=2^m/|L|. A codeword is also the evaluation of an m-variate multilinear \widehat f at the points (x,x^2,x^4,\ldots,x^{2^{m-1}}), x\in L. Following Arnon et al. [ACFY24b], the constrained code \mathrm{CRS}[\mathbb{F},L,m,\widehat w,\sigma] is the subset of \mathrm{RS}[\mathbb{F},L,m] whose multilinear satisfies \sum_{\boldsymbol b\in\{0,1\}^m}\widehat w(\widehat f(\boldsymbol b),\boldsymbol b)=\sigma; the weight \widehat w(Z,\boldsymbol X)=Z\cdot\mathrm{eq}(\boldsymbol X,\boldsymbol z) expresses the claim \widehat f(\boldsymbol z)=\sigma. A fold by a challenge \alpha maps f:L\to\mathbb{F} to \mathrm{Fold}(f,\alpha)(x^2)=\frac{f(x)+f(-x)}{2}+\alpha\frac{f(x)-f(-x)}{2x}, a codeword of \mathrm{RS}[\mathbb{F},L^{(2)},m-1] whenever f is a codeword, equal to the partial evaluation of \widehat f at X_1=\alpha.

Hashing and transcripts. Merkle commitments and the Fiat–Shamir transcript [FS87] use a hash function \mathsf{H} with a digest of d bits, of which the argument requires collision resistance for the commitments and the random-oracle model for the transcript; nothing else in the protocol depends on which function it is. Two instantiations fit. The Poseidon2 permutation [GKS23] over \mathbb{F} is algebraic, so a recursive verifier evaluates it in few constraints, and it costs more to compute on the prover. BLAKE3 [OANWO20] is a byte-oriented hash that is faster to compute and costs more constraints inside a recursive verifier. Only the first is implemented and measured: every commitment, transcript, key and timing in this paper uses Poseidon2 at width 16 with d=248. Its S-box has degree three, so the schedule is eight full and twenty partial rounds; the thirteen partial rounds tabulated for a degree-seven S-box give less margin, and the configuration measured in Section 10 carried that count. The same permutation serves the transcript, commitment trees and recursion machine. Grinding b bits means searching for a nonce whose absorption yields b leading zero bits in the squeezed challenge; it multiplies the cost of the corresponding cheating strategy by 2^b.

2.3 Lookup arguments and memory checking

Lookups as fractions. A lookup argument proves that two multisets of tuples agree. In the logarithmic-derivative form of Haböck and its GKR realisation [Hab22, PH23], written LogUp-GKR, a tuple \boldsymbol f on bus \mathsf{bus} with multiplicity m contributes m/\big(\alpha-\mathsf{bus}-\sum_{j\ge1}\beta^j f_j\big) for random \alpha,\beta\in\mathbb{F}_{p^4}; senders and receivers must sum to the same value, which a layered GKR circuit [GKR08] computes and proves by sumcheck (§5.6).

Three uses of one argument. The buses ask this argument for three things, named by the distinctions introduced with Lasso [STW24] and used by Jolt [AST24]. An indexed lookup proves a_i=T[b_i] for committed indices b; an unindexed lookup proves only that each a_i occurs in T, as a range check does. An indexed lookup is a read from a read-only memory [ST25], so the program bus and the byte bus are indexed lookups into preprocessed tables, and range checks are unindexed. Registers and memory are read–write, where a lookup no longer suffices, since a read could be answered with a value written only later.

Definition 2.3 (Memory checking [ST25, §2.2]). Consider a memory of K cells, an initial content \mathit{init}\in\mathbb{F}^K and T accesses in time order, access j carrying an address a_j, a returned value v_j and a written value v'_j (for a read, v'_j=v_j). The accesses are consistent if every v_j equals v'_{j'} for the largest j'<j with a_{j'}=a_j, or \mathit{init}[a_j] if there is none. A memory-checking argument proves consistency of committed accesses; with no writes and public contents it is an indexed lookup.

Memory-checking arguments either reorder the trace by address or do not [ST25, App. A]. Ziren’s does not: it is Blum et al.’s offline check [BEG+94] with Spice’s timestamps [SAGL18]. Each access supplies the timestamp of the previous access to its address, proves it smaller than its own, and sends and receives the old and new (\mathsf{address},\mathsf{value},\mathsf{timestamp}) on a bus, so consistency becomes the balance of one multiset relation plus a range fact per access (Lemma 5.4). The timestamp is the frame’s (\mathsf{shard},\mathsf{clk}+\mathsf{pos}), already ordered by the state bus, so one range-checked difference suffices where Spice’s rule needs two. The fingerprinting error grows linearly in the number of accesses and cells [ST25, §2.7], which over \mathbb{F}_{p^4} is negligible and is charged in Section 9.2.

2.4 Chips, buses and determinism

Ziren’s constraint system is a set of chips, tables whose rows satisfy local polynomial constraints and which communicate only through buses.

Definition 2.4 (Chip). A chip is a table over \mathbb{F} of a fixed width w together with a set of polynomial constraints of degree at most three in the w columns of one row, a distinguished boolean column \mathsf{is\_real} gating every constraint, and a set of interactions. A row is satisfying if it satisfies every constraint.

Definition 2.5 (Interaction and bus). An interaction of a chip is a triple (\mathsf{bus},\boldsymbol f,m) where \mathsf{bus} is a name, \boldsymbol f is a tuple of linear expressions in the row’s columns and m is a linear expression in the columns (the multiplicity), marked as a send or a receive. Multiplicities are non-negative integers bounded well below p: senders use zero, one, or a value range-checked against the byte table, and the preprocessed Program, Byte and Range tables receive with use counts that the shard’s cycle budget bounds by 2^{25}. For a set of tables, the multiset of a bus is \{\boldsymbol f(r)\} with multiplicity \sum m(r) over the sends of all rows r of all chips, and likewise for the receives. A bus balances if its send and receive multisets are equal.

Two facts connect balance to the fraction identity over \mathbb{F}_{p^4}. The multiplicity bound stops the counters wrapping modulo p, so balance is a statement about integer multiplicities; the exact condition is a positive total below p and a negative total above -p [Ope26a, Cor. 3.6]. And the identity is checked after compressing tuples with sampled challenges, so an unbalanced bus can still satisfy it, with probability bounded by Schwartz–Zippel; Section 9.2 charges that error.

Definition 2.6 (Shard relation). A shard is a set of tables, one per chip, together with public values \mathsf{pv}=(\mathsf{sh},\mathsf{entry},\mathsf{exit},\mathsf{cur}_{\mathrm{in}},\mathsf{cur}_{\mathrm{out}},D,h,\mathsf{code}): its shard index; its entry and exit states, each a program-counter pair with the clock; the address cursors of the global memory tables before and after it; its cross-shard digest, a point of an elliptic curve over the degree-7 extension \mathbb{F}_{p^7} (§5.5); the digest of committed output; and the exit code. It is valid for a verifying key \mathsf{vk} if its preprocessed tables are those \mathsf{vk} commits to, every real row is satisfying and every bus balances, where the public-values table contributes the entry state as a send and the exit state as a receive on the state bus, and the program bus is received by the preprocessed program table with the recorded multiplicities.

Definition 2.7 (Inputs, outputs and determinism of a chip). For a chip U, the inputs I_U(r) of a row r are the values the row consumes from elsewhere: the tuples of its receives, the program tuple it fetches, the previous-value part of its memory accesses, and its declared free values, the values its constraints leave to the prover by design, which the statements of §9.7.2 list. The outputs O_U(r) are the values it produces for elsewhere: the tuples of its sends other than the fetch, and the new-value part of its memory accesses. Fetch and previous value are sends in the sense of Definition 2.5, but inputs of the row, so the direction of an interaction is not the direction of the data. U is deterministic if for all satisfying real rows r,r', I_U(r)=I_U(r')\;\Rightarrow\;O_U(r)=O_U(r').

This is the notion of Picus [PCW+23] adapted to the interaction language.

Guest, host and cost metrics. The guest is the MIPS32 program and its runtime, whose execution is proved; guest cycles count its executed instructions. The host runs the executor and the prover, and the verifier trusts nothing it computes. The trace area of a shard or block is the sum over chips of rows × columns of the main trace, in cells; the (row, interaction) count is the number of bus interactions over all rows, the leaf count of the lookup circuit; and throughput is proved guest cycles per second of wall-clock time. Every committed value lies in the base field and costs one cell whatever its width, so instruction efficiency is improved by removing cells, not narrowing them (§1.3).

3 Architecture

Ziren proves one statement, the execution of a MIPS32 image (§4.4), and outputs a compressed proof of it. A native verifier checks that proof as a program, natively or compiled to WebAssembly, as the consumers of the proofs published for real-time proving of Ethereum blocks do; it pays for the proof’s size and its own running time. Algorithm 1 states Ziren up to that proof and Figure 1 draws it. The subsections below annotate the algorithm and state its core as two protocols, the shard argument (Protocol 3.1) and the block argument (Protocol 3.2), symbolic in the parameters of §3.4; Sections 4–8 construct their components and Section 9 states what they establish.

Verifiers that count cost differently are served by applications built on Ziren (§3.5). Each verifies the compressed proof inside another proof system, starting from one shrink node: a wrap into a pairing-based SNARK for an on-chain verifier, an Ethereum contract that pays gas, and a binary stage and narrow recursion for a garbled verifier, a Boolean circuit that pays for its AND gates and input bits.

Ziren proving stack: a guest program compiles to a MIPS32 image; execution cuts the run into shards proved in parallel over KoalaBear with Poseidon2; recursion composes shard proofs into a compressed proof for a native verifier. Applications re-prove the compressed proof: a shrink node, then a wrap into a Groth16 or PLONK SNARK over BN254 for an on-chain verifier, or a binary stage over F_2^128 with narrow recursion for a garbled verifier.
Figure 1: One proving stack ends in a 274 KiB compressed proof for a native verifier, and applications re-prove that proof for on-chain and garbled verifiers. Read left to right. Ziren (top): a guest program compiles to a MIPS32 image; execution cuts one run into shards, which accelerators prove in parallel over KoalaBear with Poseidon2 commitments (the dashed panel lists the objects built along the way), and recursion composes the shard proofs into the compressed proof that a native verifier checks. Applications (bottom): a shrink node re-proves the compressed proof under the hash an application reads; the wrap closes it with a pairing-based SNARK for an on-chain verifier, and a binary stage over \mathbb{F}_{2^{128}} and narrow recursion reach a garbled verifier.

Algorithm 1: Ziren, up to the compressed proof. Lines 3–9 run as a pipeline (§3.3).

Input: a program image P; input and hint streams (\mathit{in},\mathit{hint})
Output: the compressed proof \pi

  1. (\mathsf{pk},\mathsf{vk})\leftarrow\mathsf{Setup}(P) // commit the program and the preprocessed tables
  2. (d_0,\ldots,d_{N-1})\leftarrow\mathsf{Execute}(P,\mathit{in},\mathit{hint}) // one compiled run, cut into shard descriptors
  3. foreach i\in\{0,\ldots,N-1\} do // in parallel, one shard per accelerator
  4. T_i\leftarrow\mathsf{Replay}(d_i) // re-execute shard i to its event record
  5. \pi_i\leftarrow\mathsf{ShardProve}(\mathsf{pk},T_i) // over KoalaBear, committed under Poseidon2
  6. S\leftarrow\big(\mathsf{Leaf}_{\sigma(\pi_i)}(\pi_i)\big)_{i<N} // one leaf key per quantised shard shape
  7. while |S|>1 do
  8. S\leftarrow\mathsf{Compose}(S) // one level; a node takes ≤ 3 contiguous children
  9. \pi\leftarrow\mathsf{Root}(S) // arity one, under the compress schedule

// the native verifier runs \mathsf{Verify}(\mathsf{vk},h,\pi) (Protocol 3.2)

3.1 Execution

Line 2 runs once. An interpreter implements every instruction, syscall and error path and alone emits the event record the prover consumes. A just-in-time compiler runs the guest once and cuts the run into shards, each described by the values its reads observe and its boundary registers, so a worker replays its shard under the interpreter and no event record crosses a process boundary (§4.2). The two implementations are tested against each other, not proved equal, and nothing in the protocol depends on the compiler.

3.2 The shard argument

Line 5 proves one shard. Chips, with one row per executed instruction, and buses arithmetise it (Section 5); their constraints and buses are designed to hold exactly when the shard is a correct piece of the execution, and the premises that remain open are listed in §9.1. A bus argument BA (LogUp-GKR, §5.6) and a constraint argument CA (a zerocheck, §5.7) reduce every claim to column evaluations at one point; a jagged commitment JC reduces those to one evaluation of one dense polynomial (§6), which one WHIR opening authenticates (§7). Protocol 3.1 states the reduction. Each step ends with evaluation claims on committed columns, so the steps compose without the verifier reading a column, and the number, widths and heights of the chips are invisible above JC.

Protocol 3.1 (Shard argument). Statement: a verifying key committing to the program and the preprocessed tables, and the public values of one shard.
Witness: the shard’s execution record.

  1. Commit. The prover arranges each chip’s events into rows, places the columns of each commitment round into one dense vector and commits to it. Round order is fixed and the per-chip dimensions enter the transcript, so the geometry is public before any challenge is drawn (Section 6).
  2. Buses. The verifier draws the bus challenges. The prover runs the bus argument, which reduces every send and receive of every chip to column evaluations at one point (Section 5.6).
  3. Constraints. The verifier draws the constraint challenges. The prover runs the constraint argument on the same point, so each column is opened once for both arguments (Section 5.7).
  4. Jagged reduction. The column claims of the two previous steps, together with explicit zero claims for the gaps in the committed geometry, are batched and reduced to one evaluation of the dense polynomial (Section 6.2).
  5. Jagged assist. The verifier does not materialise the indicator table the previous step reduced against. A second sumcheck over the public column boundaries certifies its evaluation, and any point-extension coordinates are sampled here, in an order that is itself part of the protocol (Section 6.3).
  6. Opening. One batched opening authenticates that evaluation against every commitment of step 1 (Section 7).

Output: a shard proof for the public values \mathsf{pv} of Definition 2.6.

What the verifier checks. No quantity a soundness bound depends on is read from the proof beyond the declared heights, which the configuration caps (a column is at most 2^{22} rows, §6.6), and every algebraic identity the native verifier checks is also checked by the recursive verifier. The verifier (i) absorbs the verifying key, the public values and the per-chip dimensions before drawing any challenge; (ii) checks every sumcheck round of the bus argument, the constraint argument, the jagged sumcheck and the jagged assist, and each one’s closing identity, evaluating the constraint polynomials itself; (iii) checks Equation (4); (iv) runs the WHIR verifier with the query counts, folding factors and grinding bits of the schedule; and (v) checks that the public values are well formed. Preprocessed row counts come from the verifying key and the schedule from the verifier’s configuration.

Costs. With A the committed area of a shard, n_{\mathrm{int}} its number of bus interactions and K its number of columns, the prover performs O(A+n_{\mathrm{int}}) field operations outside the commitment and O(A/\rho) hashing and transform work inside it. The verifier checks O(\log^2 n_{\mathrm{int}}) sumcheck rounds for the layered lookup circuit and O(\log A) for each of the other three sumchecks, evaluates each chip’s constraints once, spends O(mK) on the jagged assist’s closing identity (Theorem 6.2), and checks the WHIR queries, whose count is fixed by the schedule. The proof size is dominated by the first WHIR round’s openings, t_0 queries times the stripes times 2^{k_0} (§7.2). Section 10 gives the concrete values.

3.3 The block argument

Lines 6–9 compose the shard proofs into one proof of the arithmetised relation \mathcal{R}_{\mathrm{arith}} of §9.1, which §9.7 connects to the relation \mathcal{R} of §4.4. Leaves and compose nodes are recursion programs proved with the same shard argument, and each checks its children’s keys against an allowlist enumerated from the machine’s declared shapes (§8). Protocol 3.2 states these lines, and the native verifier, with the conditions each node checks.

Protocol 3.2 (Block proof, end to end). Public parameters: the field \mathbb{F} and extension \mathbb{F}_{p^4}, the Poseidon2 transcript and Merkle trees, the WHIR schedule (Table 5), the bucket rule (§6.6), the compose arity (at most three), and the allowlist root \mathsf{root}_K of the admissible leaf and compose keys (Algorithm 3).

\mathsf{Setup}(P). Commit to the program ROM of image P and to the preprocessed Program, Byte and Range tables; output (\mathsf{pk},\mathsf{vk}).

\mathsf{Prove}(\mathsf{pk},P,\mathit{in},\mathit{hint}).

  1. Execute and shard. Execute P on (\mathit{in},\mathit{hint}) and cut the run into shards T_0,\ldots,T_{N-1}, shard T_i having index i+1 and its record emitted by re-executing it (§4.3), at the first of the clock fence, the shard size, a chip’s height budget and the area budget; each shard’s public values \mathsf{pv}_i are those of Definition 2.6 (§4.2).
  2. Prove the shards. As each record is produced, prove it with the shard argument (Protocol 3.1): commit, bus argument, zerocheck, jagged reduction and assist, and one WHIR opening, giving \pi_i.
  3. Leaves. Quantise each shard’s geometry into its class \sigma_i=(\mathsf{cluster},\mathsf{first},b_p,b_m,\mathsf{pad}(b_m)). The leaf program of that class verifies \pi_i, or a few fused shard proofs, against \mathsf{vk} and outputs the compose tuple of the range (§8).
  4. Compose. As soon as contiguous ranges are complete, merge up to three of them with a compose node (Algorithm 2): check each child’s key against \mathsf{root}_K and verify it, require consecutive shard indices, adjacent program-counter pairs and tiling cursors, and add the digests.
  5. Root. Once one node covers T_0,\ldots,T_{N-1}, a compose node of arity one over it, proved under the compress schedule, additionally requires the range to start at shard index 1, an exit program counter of zero, D=\mathcal{O} and exit code zero, and sets \mathsf{complete}; the first shard’s leaf has already required \mathsf{entry}_0=\mathsf{start}(\mathsf{vk}) and starting cursors of zero. Its proof, with the recursion key \mathsf{vk}^{\mathrm{rec}} that verifies it, is the compressed proof \pi.

\mathsf{Verify}(\mathsf{vk},h,\pi).

  1. Verify \pi under \mathsf{vk}^{\mathrm{rec}} with the shard verifier of §3.2 and the compress schedule, which the verifier fixes from the stage it expects and never reads from the proof.
  2. Require \mathsf{vk}^{\mathrm{rec}} to be in the allowlist, the exported root to equal \mathsf{root}_K, and the completion flag to be set (§9.4).
  3. Require the exported guest key to equal \mathsf{vk} and the exported output digest to equal h; accept.

Steps 2 to 4 of \mathsf{Prove} overlap: a shard is proved as soon as its record exists and a compose node as soon as its children are proved, with trace generation and proof-of-work on the accelerators. Only the root’s proof leaves the prover, so only the root uses the schedule tuned for size (§10.4). The start-up interval and the serial composes over the last shards remain, and they account for the gap between the multi-device speed-up and linear scaling (Table 10).

3.4 Parameters

The protocol is symbolic in the following parameters; numeric values are fixed where each component is built.

  • The base field \mathbb{F} and the challenge extension \mathbb{F}_{p^4}, whose size bounds every term of the form \deg/|\mathbb{F}_{p^4}|; the permutation of the transcript and commitment trees, with its round counts (§2), and the trees’ arity.
  • The committed geometry: the stacking height H=2^\ell, the row cube 2^n and the bucket rule (§6.6), which together fix the set of recursion programs a prover can produce.
  • The proximity test: the initial rate \rho, per-round folding factors, query counts, out-of-domain samples, the grinding bits of each query phase and of the bus challenges (Table 5), and the decoding regime.
  • Recursion: the compose arity and the height of the tree of admissible keys (§8).
  • The machine: the shard size, clock fence and per-chip height budgets (§4), and the guest-accelerator set, which fixes the chip set.
  • The cross-shard digest: the curve and its extension, the interaction bound N_{\mathrm{int}} and the multiplicity bound B (§9.5).

Query soundness needs no conjecture: it is counted in the unique-decoding regime for the core schedule and under the Johnson bound for the root’s compress schedule (§9.2).

3.5 Applications

An application verifies the compressed proof inside a proof system whose verifier its consumer can afford. Figure 1 (bottom) draws the two built on Ziren; neither changes the statement, and each output attests the same execution as \pi. This paper measures and accounts only Ziren (Algorithm 1).

The shrink. A shrink node is a recursion node that verifies the compressed proof. Both applications run the same program, proved under Poseidon2 for the wrap and under Blake3 [OANWO20], commitments and transcript alike, for garbled verification, so garbled verification changes the hash before it changes the field (§8.1).

On-chain verification. An on-chain verifier is an Ethereum contract; it pays gas, which precompiled BN254 pairings make small and independent of the statement only for a pairing-based argument over that curve with a constant-size proof [Gro16, GWC19]. A wrap node re-proves the shrink with its commitments and transcript under Poseidon2 over the BN254 scalar field, and a Groth16 or PLONK circuit over BN254 verifies the wrap proof, hashing natively; the circuit either fixes the wrap key or takes it as an input (§8.1). The on-chain verifier checks the result with a constant number of pairings.

Garbled verification. A garbled verifier is a Boolean circuit evaluated under garbling [Yao86], as in protocols that check a computation on Bitcoin only when it is disputed [Lin23]. Evaluating a garbled verifier on an invalid proof reveals a secret that serves as the fraud proof [Eag25]; later protocols build bridges on this [WAA+26], make the verification of pairing-based SNARKs far cheaper [EL26, GKS+26], and shrink the on-chain footprint of malicious security [KTA+26]. They garble the verifier of a pairing-based SNARK or of a designated-verifier variant of one, where this application garbles a hash-based verifier over a binary field. A garbled verifier pays for its AND gates and for its input bits, while XOR gates are free [KS08, ZRE15]. Over a 31-bit prime field an addition is a carry chain and a multiplication a reduction modulo p; over \mathbb{F}_{2^{128}} an addition is a XOR, so this application moves the arithmetic to a binary field and the hash to one built from word additions, XORs and rotations. The binary stage commits bit columns as packed elements of \mathbb{F}_{2^{128}} and opens them through ring switching [DP23, DP24], emulating the shrink verifier’s KoalaBear arithmetic over bits.

Its verifier is not rewritten as a circuit. A recorder runs it over a value type that appends every multiplication, inversion, bit decomposition and Blake3 hash to a tape, and every comparison as the condition it found, so the tape is fixed by the proof’s shape and key and enforces the control flow of the run that recorded it. A narrow machine native to \mathbb{F}_{2^{128}} proves a run of the tape, with a ledger of read cells and tables for arithmetic, bit rewiring and Blake3, and narrow recursion repeats the step on each narrow proof’s own verifier. The garbled circuit evaluates the last recorded tape on the bits of the last narrow proof; it pays AND gates for field products, Blake3 compressions and the per-claim tensor algebra of ring switching, and takes as input every value the proof opens and every Merkle path. The narrow machine follows from that cost: few tables, narrow ones, none reading its next row, power-of-two widths, and a low-rate opening.

4 MIPS32 and the execution relation

This section gives enough of MIPS32 to follow the paper and states the relation Ziren proves; the specification is the architecture manual [MIP10]. The guest has no floating-point unit, privileged state or interrupts; it executes the 77 instructions of Appendix B and reaches the outside world only through SYSCALL.

Definition 4.1 (Machine state). The machine state is (\mathsf{pc},\mathsf{next\_pc},R,M). R holds 32 general registers of 32 bits, register 0 reading as zero, together with the HI/LO pair written by multiplication and division; M is a little-endian, byte-addressed memory over a 32-bit address space. \mathsf{pc} is the address of the instruction about to execute and \mathsf{next\_pc} the address of the one that executes after it, which is not in general \mathsf{pc}+4.

Definition 4.2 (Instruction format). Every instruction of the guest is decoded, once and before proving, into a tuple (\mathsf{opcode},\mathsf{op\_a},\mathsf{op\_b},\mathsf{op\_c},\mathsf{imm\_b},\mathsf{imm\_c}). \mathsf{op\_a} is the index of the register the instruction writes (or, for a store or branch, reads); \mathsf{op\_b} and \mathsf{op\_c} are each either a register index or an immediate already sign- or zero-extended to 32 bits, as the flags \mathsf{imm\_b} and \mathsf{imm\_c} say.

The decoded form abstracts MIPS32’s three encodings as Jolt’s five-tuple abstracts RISC-V’s [AST24]; the correspondence (Table 2) is fixed by the opcode and recomputable by anyone from the image. Figure 2 gives the transition of one instruction.

Table 2: From the three MIPS32 encodings to the decoded tuple of Definition 4.2. Field widths are in bits, most significant first; off and imm are 16-bit, target 26-bit and sa 5-bit. Immediates are extended when decoded, as the opcode dictates.

Format Fields Instructions (\mathsf{op\_a},\mathsf{op\_b},\mathsf{op\_c})
R op 6 | rs 5 | rt 5 | rd 5 | sa 5 | func 6 register ALU (rd, rs, rt)
shift by sa (rd, rt, sa)
jr, jalr (rd, rs, −)
I op 6 | rs 5 | rt 5 | imm 16 immediate ALU, loads, stores (rt, rs, ext(imm))
branches (rs, rt, sext(off) ≪ 2)
J op 6 | target 26 j, jal (0 or 31, target ≪ 2, −)

Three features that shape the arithmetisation. Branch-delay slots: a sequential instruction advances the counter pair as (\mathsf{pc},\mathsf{next\_pc})\mapsto(\mathsf{next\_pc},\mathsf{next\_pc}+4) and a transfer sets \mathsf{next\_next\_pc}, so the successor of an instruction in a delay slot is the branch target and every row carries \mathsf{next\_pc} as a witnessed column. The pair is architectural state that crosses every shard boundary (§8). Unaligned and narrow accesses: LB, LBU, LH, LHU, SB, SH address bytes and half-words, and LWL/LWR/SWL/SWR merge part of an unaligned word with a register; memory is word-granular, so these select and merge bytes in-row, in chips of their own (§5.9.6). Bit manipulation: EXT, INS, WSBH, SEB/SEH, ROTR, CLO/CLZ and the conditional moves, common in hashing and serialisation code, are supported natively.

4.1 Formatting the program

Before proving, the image is decoded (Definition 4.2) into a preprocessed program table keyed by address, with immediates already extended. LO and HI are registers 32 and 33, so moves between them and the general registers need no chip, and two further slots hold the program break and heap pointer used only by memory-management syscalls. The program table and the other preprocessed tables are committed at setup; that commitment is the verifying key naming the program in the statement (§4.4).

\mathsf{Step}(\mathsf{pc},\mathsf{next\_pc},R,M)\to(\mathsf{pc}',\mathsf{next\_pc}',R',M') or reject

  1. Fetch. (\mathsf{opcode},\mathsf{op\_a},\mathsf{op\_b},\mathsf{op\_c},\mathsf{imm\_b},\mathsf{imm\_c})\leftarrow\mathsf{Decode}(M[\mathsf{pc}]); if the word does not decode, reject.
  2. Operands. b\leftarrow\mathsf{op\_b} if \mathsf{imm\_b} else R[\mathsf{op\_b}]; c\leftarrow\mathsf{op\_c} if \mathsf{imm\_c} else R[\mathsf{op\_c}]; a\leftarrow R[\mathsf{op\_a}].
  3. Execute, by family (§§5.9 and 5.10):
    • ALU, shift, bit-field, move: R[\mathsf{op\_a}]\leftarrow f_{\mathsf{opcode}}(a,b,c); multiplication and division also set HI; division by zero: reject.
    • load: \mathit{addr}\leftarrow b+c; R[\mathsf{op\_a}]\leftarrow the selected bytes of M[\mathit{addr}], extended; store: M[\mathit{addr}]\leftarrow the selected bytes of a merged into it.
    • branch or jump: t\leftarrow the target (b, \mathsf{next\_pc}+b, or \mathsf{next\_pc}+c); \mathit{taken}\leftarrow the condition on a,b (true for a jump); a linking jump sets R[\mathsf{op\_a}]\leftarrow\mathsf{next\_pc}+4.
    • teq with a=b: reject. syscall: the call of §5.10.4, which may halt.
  4. Register 0. R'[0]\leftarrow 0.
  5. Advance. \mathsf{next\_next\_pc}\leftarrow t if \mathit{taken} else \mathsf{next\_pc}+4; return (\mathsf{next\_pc},\mathsf{next\_next\_pc},R',M').

Figure 2: The transition function of the guest machine. Step 5 departs from RISC-V: a transfer sets the second component of the pair, so the instruction in its delay slot still executes. A transfer in a delay slot, which the manual leaves unpredictable, gets the meaning the same rule gives it. In Ziren the instruction frame performs fetch, operand reads, register writes and advance; the memory argument the memory access; and the chip’s own columns only the function f.

4.2 Clock, shards and the execution record

Execution is divided into shards. Within a shard a clock \mathsf{clk} advances by five per instruction, and a syscall by a bounded extra number of ticks so that a precompile’s accesses fit between the call and its successor. An instruction executes at \mathsf{clk}, and its accesses occupy five sub-cycle positions, one per role: a memory access at \mathsf{clk} itself, the reads of \mathsf{op\_c} and \mathsf{op\_b} and the access to \mathsf{op\_a} at \mathsf{clk}+1, +2 and +3, and a write of HI at \mathsf{clk}+4 (Section 5.3), so (\mathsf{shard},\mathsf{clk}+\mathsf{pos}) identifies and timestamps every access. The executor fences the clock below 2^{25}, capping a shard at about 6.71 M cycles; the circuit witnesses it as a 16-bit and a 10-bit limb, the decomposition the memory argument range-checks, which proves it below 2^{26} and so still excludes wrap-around. A shard closes on whichever binds first: that fence, the configured shard size of a few million cycles, a chip’s height budget, or a committed-area budget of 4.6\cdot10^8 cells, which binds on precompile-heavy blocks, while on the measured blocks the shard size binds for most shards (§10.2); Section 10 reports the resulting shard counts.

At a shard boundary the emulator emits, for every word touched in the shard, the value and timestamp of its first and last access, the leaves of the cross-shard memory argument. A shard record holds per-chip event lists, this ledger, the row counts and the public values of Definition 2.6, through which shards and recursion layers are chained; a deferred-proof digest beside them is zero here, since verifying other proofs inside the guest is out of scope.

4.3 The execution relation

Definition 4.3 (Execution). An execution of a program image P on streams (\mathsf{in},\mathsf{hint}) is a sequence of machine states \sigma_0,\sigma_1,\ldots,\sigma_T in which \sigma_0 is the state the image defines, with the counter pair (\mathit{entry},\mathit{entry}+4), the registers the image initialises (the stack pointer among them) and zero in the others, and the image’s memory, \sigma_{i+1}=\mathsf{Step}(\sigma_i) for every i<T (Figure 2), no step rejects, and step T is a halting system call with exit code e.

Write \mathsf{Emulate}(P,\mathsf{in},\mathsf{hint})=(\mathsf{out},e) for the output stream and exit status of that execution. It is deterministic: no step reads a clock, a random source or host state other than the streams. Where the manual leaves room, or describes behaviour a single-threaded guest cannot observe, \mathsf{Emulate} fixes a choice and the arithmetisation proves the same one: add and addi do not trap on signed overflow and behave as addu and addiu. j and jal take the region bits of the program counter as zero, which is exact for text below 2^{28}. ll places no reservation and sc always succeeds. And a trap, a division by zero, or an unrecognised instruction ends the execution with an error, which is not a halt the relation admits, so such an execution has no proof.

The relation is realised twice: an interpreter, which implements every path and alone emits the event record the prover consumes, and a just-in-time compiler for output-only runs and for the per-shard descriptors workers replay. Byte-identical descriptors on the tested corpus, the specification vectors of §9.7 and record digests in continuous integration connect them, without proving equivalence for every program. The compiler matters for rate, since a host feeding several accelerators is bound by the executor (§§3.1 and 10.3).

Where the arithmetisation is stricter than the relation. The arithmetisation refuses some executions the relation admits, which costs completeness, never soundness [GPR21, Note 1]. A shard’s clock is bounded by 2^{25}, so an execution is cut into shards; a cut never falls between a transfer and its delay slot. The only halt proved is exit code zero. A load or store must address memory above the 36 register slots, and every address and program counter must be a canonical field element, below p. And a shard whose chip set lies outside the machine’s declared clusters has no admissible verifying key (§8).

4.4 The statement being proved

With P a program image, \mathsf{in} an input stream and \mathsf{hint} a host-supplied hint stream, Ziren proves the relation

\mathcal{R}=\Big\{\big((\mathsf{vk},h),(P,\mathsf{in},\mathsf{hint})\big)\;:\;\mathsf{vk}=\mathsf{Setup}(P)\;\wedge\;\exists\,\mathsf{out}:\ \mathsf{Emulate}(P,\mathsf{in},\mathsf{hint})=(\mathsf{out},0)\;\wedge\;h=\mathsf{H}(\mathsf{out})\Big\},

where \mathsf{Setup} maps an image to its verifying key, a Merkle commitment to the program ROM and the preprocessed tables of Section 5, and \mathsf{H} is SHA-256 over the committed output (Blake3 in the wrap-key-as-input variant of §8.1). (\mathsf{vk},h) is public and pins the image; (\mathsf{in},\mathsf{hint}) is the witness and P is fixed by \mathsf{vk}, though without blinding it is not confidential. Only exit code zero is admitted, since it is the only halt the arithmetisation proves; \mathsf{Emulate} accepts a non-zero exit, and one Cannon test program does exactly that and cannot be proved (§9.7). Supported honest executions within the configured resource limits that halt with exit code zero produce accepting proofs; extraction of (\mathsf{in},\mathsf{hint}) is conditional on Theorem 9.2 and on the trace-to-execution premises of Theorem 9.6.

5 The arithmetisation: frame, buses and chips

Figure 3 shows instruction chips connected by buses to a program ROM, a memory subsystem and lookup tables. A chip (Definition 2.4) is a fixed-width table over \mathbb{F} whose constraints, of degree at most three, are local to one row; every relation between chips, or between rows of one chip, is an interaction on a named bus, and the lookup argument of Section 5.6 proves that every bus balances (Definition 2.5). No constraint reads the next row: the state bus carries everything one row passes to the next. The trace area is the sum over chips of rows × columns. The guest-accelerator set is a configuration choice: it fixes which precompile chips a shard may contain, and adding one changes the chip set and the verifying keys. This section builds the parts every chip shares and what one row costs (§§5.1–5.8), then gives the chips instruction by instruction, for the base instruction set (§5.9) and for the extended instruction set and system calls (§5.10).

5.1 Chips, words and padding

Appendix A catalogues the chips with their widths. Three families dominate the trace area of an Ethereum block: the memory-instruction chips, the ALU chips, and the Global chip that carries the cross-shard memory argument. Immediate forms of the ALU instructions have chips of their own, whose rows have one register read fewer and are about a tenth narrower.

Ziren chip and bus layout: instruction chips (ALU, Shift, Mul/Div, Control, Load/Store, Syscall) and accelerator chips connect over the program, state, memory, byte/range, global and syscall buses to the preprocessed Program ROM, the public values, MemoryBump, the Byte/Range tables, MemoryLocal, Global and MemoryGlobal Init/Finalize.
Figure 3: Each executed instruction occupies one opcode-chip row, and every relation between chips crosses a named bus. The program and lookup tables are preprocessed; public values close the state chain and carry the cross-shard digests.

Notation for words. A 32-bit word x is carried as four byte columns (x_0,x_1,x_2,x_3), least significant first, and denotes the integer \mathrm{int}(x)=\sum_{i<4}2^{8i}x_i; since 2^{32}>p that integer is never formed as a single field element. Its sign bit x_s is the top bit of x_3, and x_{<s} is the word with that bit cleared. A byte-checked word is one whose four columns are each proved to lie in [0,256) by the byte table. Signed instructions read a word in two’s complement, \mathrm{int}(x)-2^{32}x_s.

Lemma 5.1 (Limbs determine integers). Let x_0,\ldots,x_{\ell-1} be field elements proved to lie in [0,2^{b_i}) and let y\in[0,B), with 2^{b_0+\cdots+b_{\ell-1}}\le p and B\le p. If \sum_i 2^{b_0+\cdots+b_{i-1}}x_i=y holds in \mathbb{F}, it holds over the integers, and the x_i are the unique such limbs of y.

Proof. Both sides are integers in [0,p) that agree modulo p, so they are equal; uniqueness is that of positional notation. ∎

This is Cairo’s instruction-decoding theorem [GPR21, Thm. 1] in general form, and every word-level constraint of the machine must meet its hypothesis. A four-byte word cannot, since 2^{32}>p, so words stay as bytes. Two 16-bit half-words checked only against their sum in \mathbb{F} fail it for the same reason, which is why the syscall bus carries the half-words themselves (§5.10).

Padding. Row counts are rounded up to a multiple of 32, not to a power of two; the jagged commitment of Section 6 makes padding cost proportional to the padding. Padding rows have \mathsf{is\_real}=0, and every constraint and interaction multiplicity is gated so that they are vacuous.

5.2 Preprocessed tables

The byte table has 2^{16} rows indexed by a byte pair and one multiplicity column per operation (bitwise operations, shifts, comparisons and 8/16-bit range checks); every carry, borrow, comparison and range check in the machine is an interaction with it. A range table serves the clock limbs, and the program table holds the decoded program image. Preprocessed tables are committed at setup as part of the verifying key, which therefore binds the image; OpenVM instead commits the program as a cached trace bound at the root of its recursion, so its verifying key is program-independent [Ope26b, §4.4].

The byte table as a decomposed instruction table. One lookup into the 2^{64}-entry table of a 32-bit bitwise operation becomes four lookups into the 2^{16}-entry byte table, indexed by a byte pair: the decomposition the original Jolt design applies to instruction tables through Lasso [AST24, STW24], taken at W=32 with four 8-bit chunks. Two things separate the settings. Lasso never commits its subtables, because the verifier evaluates their multilinear extensions itself [STW24]; a 2^{16}-row table is small enough to commit once in the verifying key, and LogUp-GKR then charges the table side one multiplicity column per operation over 2^{16} rows per shard, about 6.6\cdot10^5 cells, under 0.2% of a shard’s 4.6\cdot10^8-cell area budget (§4.2). And Jolt routes every instruction through such tables, addition and multiplication included; this arithmetisation evaluates those by constraints with byte-checked carries and uses the table only for byte-granular facts (§§5.9 and 5.10).

5.3 The instruction frame

A conventional zkVM arithmetisation has a central CPU chip: one row per cycle fetches the instruction, performs the register accesses, chains the program counter and forwards a decoded instruction to an opcode chip, which spends a second row on it. Like SP1 and OpenVM for RISC-V [Suc24, Ope26b], Ziren has no such table. Each instruction chip embeds an instruction frame and performs those duties itself, so one executed instruction is one row of one chip. We call it a frame because it is the part of a row that is the same for every instruction and encloses the part that is not: whatever an opcode computes, its row sits inside a frame that says which instruction it is, when it ran, which registers it read and wrote, and which state it received and passed on. A chip’s own columns then only have to relate the frame’s operand values to its result. The name has nothing to do with a stack frame. The frame consists of:

  • Program fetch. The row sends (\mathsf{pc},\mathsf{opcode},\mathsf{op\_a},\mathsf{op\_b},\mathsf{op\_c},\mathsf{imm\_b},\mathsf{imm\_c}) on the program bus, and the preprocessed program table receives it with the multiplicity recorded at trace generation, so the instruction comes from the image committed in the verifying key.
  • Register accesses. Reads of \mathsf{op\_c} and \mathsf{op\_b} (unless immediate) and the read–write of \mathsf{op\_a} at sub-cycle positions 1, 2 and 3; position 0 is the memory access and 4 a write of HI. They use the register variant of the memory argument (§5.4). An \mathsf{op\_a\_0} flag pins a write to register 0 to zero, so chips bind their result through a (1-\mathsf{op\_a\_0}) factor.
  • State bus. The row receives (\mathsf{shard},\mathsf{clk},\mathsf{pc},\mathsf{next\_pc}) and sends (\mathsf{shard},\mathsf{clk}+\Delta,\mathsf{next\_pc},\mathsf{next\_next\_pc}), where \Delta is five, one per sub-cycle position, or a larger bounded value for a syscall, so that the accelerator’s memory accesses fit before the successor (§4). The public-values table sends the shard’s entry state and receives its exit state.
  • Clock. \mathsf{clk} is witnessed as a 16-bit and a 10-bit limb, both range-checked, so that clock differences in the memory argument decompose cheaply.

Lemma 5.2 (State-bus chain). In a valid shard (Definition 2.6) with entry state s_0 and exit state s_N, the real instruction rows can be ordered r_1,\ldots,r_N so that r_i receives s_{i-1} and sends s_i, with \mathsf{clk}(s_i)>\mathsf{clk}(s_{i-1}); every real instruction row is in the chain, and N is the number of real instruction rows.

Proof. Each real instruction row receives exactly one state tuple and sends exactly one, with a strictly larger clock, and the public-values table sends s_0 and receives s_N. Balance of the state bus means the multiset of sent tuples equals the multiset of received tuples. Consider the directed graph whose vertices are the distinct state tuples and whose edges are the rows (from received tuple to sent tuple). Every vertex other than s_0 and s_N has in-degree equal to out-degree, s_0 has out-degree one more than in-degree and s_N the reverse, so the edge multiset decomposes into one s_0\to s_N path and cycles. A cycle is impossible because the clock strictly increases along every edge. Hence the rows form a single path from s_0 to s_N. ∎

Figure 4 shows three consecutive rows and the buses that bind them. The frame comes in R-type (two register reads), I-type (a word immediate, used by the immediate ALU, memory and branch chips) and shift-amount (a 5-bit immediate) variants, and a universal variant for chips whose opcodes mix operand shapes. It byte-checks the word written to \mathsf{op\_a}, the single place where a register value is range-checked, which lets memory-instruction rows omit byte checks on the words they move.

Example 5.3 (A delay slot on the state bus). Take a taken beq at address 0x100 whose target is 0x200, the addiu in its delay slot at 0x104, and the instruction at the target. With the shard s and the branch’s clock \mathsf{clk}, the three rows exchange these tuples on the state bus:

Row Chip receives (\mathsf{shard},\mathsf{clk},\mathsf{pc},\mathsf{next\_pc}) sends
beq Branch (s,\mathsf{clk},\texttt{0x100},\texttt{0x104}) (s,\mathsf{clk}+5,\texttt{0x104},\texttt{0x200})
addiu AddSubImm (s,\mathsf{clk}+5,\texttt{0x104},\texttt{0x200}) (s,\mathsf{clk}+10,\texttt{0x200},\texttt{0x204})
target any (s,\mathsf{clk}+10,\texttt{0x200},\texttt{0x204}) (s,\mathsf{clk}+15,\texttt{0x204},\ldots)

The branch does not change its own successor, 0x104; it sets the one after it. The addiu row is an ordinary row that happens to receive \mathsf{next\_pc}=\texttt{0x200} and sends (\texttt{0x200},\texttt{0x204}) by the constraint every sequential row obeys. Not taken, the branch would have sent (\texttt{0x104},\texttt{0x108}) and nothing else would change. The pair crosses a shard boundary whole, so the recursion must pin both components (§8), and a shard is never cut between a transfer and its delay slot.

The frame beside other instruction interfaces. SP1 gives each instruction chip a column group that chains (\mathsf{clk},\mathsf{pc}) and an R-, I- or J-type register reader that fetches the instruction and reads its operands [Suc24]; the frame’s R-type, I-type and shift-amount variants correspond to those readers. OpenVM factors an instruction executor into an adapter, which owns every program, execution and memory interaction, and a core, which computes [Ope26b]. The frame fills the same role for MIPS32. It differs from both in carrying the delay slot, and from OpenVM in four respects. The state is (\mathsf{shard},\mathsf{clk},\mathsf{pc},\mathsf{next\_pc}) rather than (\mathsf{pc},t), because of the delay slot. Time advances by a fixed five per instruction with a fixed position per access, where OpenVM advances one tick per access; in both, the accesses of step i sit strictly between the states received and sent,

\mathsf{clk}_i<\mathsf{clk}_i+1<\mathsf{clk}_i+2<\mathsf{clk}_i+3<\mathsf{clk}_i+4<\mathsf{clk}_{i+1}=\mathsf{clk}_i+5,

with the memory access at \mathsf{clk}_i itself. Registers are shadow-read into the shard and use a six-column access (§5.4), where OpenVM’s are ordinary memory in a separate address space. And OpenVM’s connector chip is here the public-values table.

Both designs state their buses by the same kind of invariant: (\mathsf{shard},\mathsf{clk},\mathsf{pc},\mathsf{next\_pc}) is sent on the state bus exactly when it is the machine state at that clock, and (\mathsf{shard},\mathsf{clk},a,v) is on the memory bus exactly when address a held v after its access at that time.

The frame as a reordering of the trace. A per-step circuit that can execute any instruction must either contain every instruction’s logic at every step or be told which one runs. vRAM [ZGK+18] took the second route: the prover announces how often each instruction executed, commits the trace regrouped by instruction, and proves by a permutation check that it is a reordering of a time-ordered trace; Jolt names the same device as one way to route its lookups by opcode [AST24], and Ceno’s per-opcode design gives it in multiset form, as a set equality over (program counter, clock) state records [LZZ+24, §6.2]. The frame realises this regrouping with a program-counter pair and a shard field in the state. The chips are the groups, their heights are the instruction counts and enter the transcript before any challenge, and the state bus is the permutation check: Lemma 5.2 says the grouped rows re-assemble into one time-ordered chain. The regrouping is of instructions only; the memory argument below does not reorder the trace, which makes it reordering-free in the taxonomy of Twist and Shout [ST25, App. A].

The price of the regrouping is uniformity. A circuit that carries every instruction at every step has a trace shape that depends only on its length, as RISC Zero’s does [BGt23], or on its length and configured builtins, as Cairo’s does [GPR21, §2.8], which makes Cairo’s verifier program-independent and its recursion simple [GPR21, §2.2.4]. Here the shape depends on which counts are non-zero, so the key of the program that verifies a shard is a function of its chip set, and Section 8 enumerates those sets.

Instruction frame. Panel a: AddSubImm (addiu), Branch (bne) and LoadWord (lw, in the delay slot) rows chained on the state bus at clk, clk+5, clk+10, clk+15, each fetching from the program bus and accessing the memory bus. Panel b: one LoadWord row with five sub-cycle access positions from clk to clk+4: memory read, unused, read op_b, write op_a, unused.
Figure 4: The instruction frame binds consecutive opcode rows into one state chain (panel a) while assigning register and memory accesses to fixed sub-cycle positions (panel b). Each memory access sends the previous tuple (\mathsf{shard},\mathsf{clk}+\mathsf{pos},\mathsf{addr},\mathsf{value}) and receives the new one. In panel a the LoadWord row sits in the branch’s delay slot, so its successor arrives as the branch target rather than \mathsf{pc}+4; the rows are an AddSubImm, a Branch computing \mathit{taken}\leftarrow[a\ne b] on registers rs and rt, and the aligned four-lane load of panel b.

5.4 Registers and memory

Registers and memory share one offline memory-checking argument [BEG+94] in the multiset style used by SP1 [Suc24]. The state of address a is the tuple (\mathsf{shard},\mathsf{clk},a,\mathsf{value}) of its last access. An access at time (s,c) sends the previous tuple (s',c',a,v') and receives the new tuple (s,c,a,v) on the memory bus, with v=v' for a read. Every access enforces (s',c')<(s,c) by witnessing c-c'-1, or s-s'-1 when the shards differ (a one-bit \mathsf{compare\_clk} selector chooses), as a range-checked 16-bit limb and 10-bit high limb, which covers a \mathsf{clk}+\mathsf{pos} timestamp under the 25-bit clock fence. Words are carried as four byte columns. Figure 5 follows one address through two shards.

Lemma 5.4 (Memory argument). The memory bus with the timestamp constraints is a memory-checking argument in the sense of Definition 2.3, up to the fingerprinting error of the bus argument and provided the bus’s multiplicities satisfy the bound of Definition 2.5. Concretely, in a valid shard with at most one initial-state row and one final-state row per address, for every address a the accesses to a form a chain ordered by (\mathsf{shard},\mathsf{clk}) in which each access consumes exactly the tuple produced by the previous access to a, starting from the tuple supplied by the initial-state row of a and ending at the tuple consumed by its final-state row; in particular every read returns the value of the last write.

Proof. Each access sends its previous tuple and receives its new tuple on the memory bus, and its constraints enforce that the new timestamp strictly exceeds the previous one. Balance of the memory bus, restricted to the tuples with address a, gives a graph as in Lemma 5.2 with the initial-state row as source and the final-state row as sink; strictly increasing timestamps exclude cycles, so the accesses form one path, and along the path a read carries its previous value forward unchanged. ∎

Registers. A dedicated chip, MemoryBump, inserts, for every register at its first touch in a shard, a shadow read at (\mathsf{shard},0), a device SP1 introduced [Suc24]. Since \mathsf{clk} restarts at zero in every shard and real register accesses sit at positions 1..4, the previous access of a register is always in the current shard. The register variant of the access columns therefore drops \mathsf{prev\_shard}, the compare selector and one limb, re-derived linearly from the others: 9 columns become 6 on every register access.

Shard-local memory. Within a shard, the first access to a word consumes a tuple no access in the shard produced, and the last produces one nothing in the shard consumes. A shard-boundary chip, MemoryLocal, records, for every word the shard touches, its initial and final (\mathsf{shard},\mathsf{clk},\mathsf{value}); it receives the initial tuple on the memory bus, sends the final one, and forwards both as global interactions (§5.5) to be matched across shards. A shard of an Ethereum block executed by the reth client touches a few hundred thousand words, mostly a hot working set touched again in the next shard, and these two global rows per touched word are among the largest contributions to trace area, which is why shard size matters (Section 10).

Whole-execution memory. Two further chips, MemoryGlobalInit and MemoryGlobalFinalize, carry the memory’s initial contents (the program image and the hint data written into untouched words) and its final contents; an initial tuple carries timestamp (0,0), below every access. Both witness the word as 32 boolean columns, so every value that enters memory is byte-shaped by construction. Only words the execution touches appear, as in Ceno [LZZ+24, §5.1]. Addresses are 32-bit decomposed and proved strictly increasing along the table, and the address cursors are public values, so the recursion checks that consecutive tables tile the address space. The program image is bound by the verifying key: its digest (§5.5) is a public parameter the init table must consume.

What is byte-checked. Every value that enters a register is byte-checked by the frame at the write, and every value a precompile writes to memory is byte-checked or bit-decomposed by the precompile chip; memory-instruction rows therefore omit the two byte lookups per word that accesses otherwise carry.

Why not Twist. Twist and Shout [ST25] checks memory with one-hot addresses and increments far more cheaply than timestamped checking, but its costs assume commitments in which zeros are free or bits pack, and it notes that committing to zeros is not free under a hash-based commitment [ST25, §2.9]: a one-hot register address alone would be 32 cells against the six of a register access here. Across shards, Twist must commit the memory’s state at each boundary, which it leaves open [ST25, §2.9]; the digest below pays only for the words a shard touches.

5.5 Cross-shard interactions

Interactions whose two sides live in different shards (the initial and final tuples of every shard-touched word, memory initialisation and finalisation, and syscall pairings) cannot be balanced by a per-shard fraction sum. Each shard proof therefore publishes a commitment to its cross-shard state, and the recursion checks that the commitments of the shards compose; the per-shard argument is the same whatever that commitment is. There are four options: two multiset hashes, over an elliptic curve and over a lattice, a global challenge, and Merkle roots over touched memory. They differ in what a shard publishes, what composition checks and what soundness rests on, and they trade committed area against the order in which shards can be proved (Table 3); three are implemented and measured, and the lattice hash is costed. The choice among them is a practical one. The measurements of Section 10 and the soundness accounting of Section 9 are stated for the elliptic-curve multiset hash.

The chain of one memory address across a shard boundary: in shard s, MemoryLocal initial, a lw read, an sw write and MemoryLocal final; in shard s+1, MemoryLocal initial, a lw read and MemoryLocal final. The final tuple of shard s and the initial tuple of shard s+1 cancel in the cross-shard digest D. MemoryGlobalInit and MemoryGlobalFinalize bound the chain.
Figure 5: The chain of one address a across a shard boundary. A shard proof balances only tuples whose two sides it contains, so the shard-boundary rows stand in for the accesses it cannot see: the initial row supplies the tuple the shard’s first access consumes, and the final row consumes the tuple its last access produces. These are the same tuple on either side of the boundary, carried with opposite signs into the digest D of §5.5, so the chain closes over the execution without any shard proof depending on another.

Option 1: elliptic-curve multiset hash. Each interaction tuple is mapped into a commutative group, sends add its image and receives subtract it, each shard publishes its running sum, its cross-shard digest D, and the root compose node checks that the sums over the execution add to the identity: the multiset hash of Clarke et al. [CDvD+03] on the incremental hashing of Bellare and Micciancio [BM97]. On an elliptic curve [MSTA17], which SP1 introduced to zkVM memory checking [RR24], a tuple \boldsymbol m\in\mathbb{F}^7 is lifted to a point of E: y^2=x^3+3\zeta x-3 over \mathbb{F}_{p^7}=\mathbb{F}[\zeta]/(\zeta^7+2\zeta-8). One row per interaction witnesses the point, checks the curve equation and a sign band for y that separates sends from receives, and adds the point to a running sum on an accumulation bus; the sum starts at a public offset point D_{\mathrm{off}}, so two digests combine as D+D'-D_{\mathrm{off}} and the empty digest is D_{\mathrm{off}}. The lift applies no hash: the message is the x-coordinate, up to a prover-chosen byte offset that makes the curve’s right-hand side a square, which keeps the chip at a few dozen columns; §9.5 gives what soundness then rests on.

Option 2: lattice multiset hash. The group can instead be a lattice, as in LtHash [LKMW19], the instantiation of Bellare and Micciancio’s incremental hash over a product of small rings, which ZisK uses for its challenge derivation [Mas25]. A tuple \boldsymbol m is hashed to h(\boldsymbol m)\in\mathbb{F}^n, sends add h(\boldsymbol m) and receives subtract it, each shard publishes its running sum, and composition checks that the sums over the execution add to zero, exactly as for the curve. A collision is a short integer relation among hash outputs, a problem not known to be easy for quantum adversaries. The cost is h: it must be constrained in the chip for every interaction, and it must behave as a random function, since a linear h makes any two multisets with equal message sums collide, which is what our prototype with a fixed public linear map did. A map strong enough for the lattice assumption needs n=800 or more over the 31-bit field and at least 19.6× today’s committed area by our count, so this option is costed, not built.

Table 3: The four options for cross-shard interactions. Times are relative to the elliptic-curve multiset hash on the same GPUs (warm, compressed proofs, \mathsf{H}= Poseidon2); the global challenge was measured on one block, Merkle roots over six and twelve blocks with the two builds alternated (ABBA), the block count in parentheses. The lattice multiset hash is estimated, not built.

Option a shard publishes composition checks soundness rests on 1 GPU 4 GPUs other costs
1. Elliptic-curve multiset hash a running sum of points the sums add to the identity Assumption 9.4 – –
2. Lattice multiset hash a running sum of vectors the sums add to zero short integer relations ≥ 19.6× area not built
3. Global challenge a LogUp-GKR fraction sum the sums add to zero the hash chain, LogUp-GKR +29 % +42 % a commit pass before proving
4. Merkle roots memory roots before and after the roots chain from the image root collision resistance of \mathsf{H} −16.6 % (6) +3.4 % (12) −47 % shards; +20 GB per worker

Option 3: global challenge. Every shard commits its main trace first; one LogUp-GKR challenge is then drawn from a hash chain over all the commitments, each shard proves its cross-shard interactions as LogUp-GKR fractions under that challenge and publishes their sum, and the recursion checks that the sums over the execution add to zero. Soundness rests on the hash chain and on the LogUp-GKR argument the shards already use, and the option adds no hashing to the machine. The price is order: every shard must be committed before any can be proved, which on the GPU pipeline means a commit pass ahead of the proving pass.

Option 4: Merkle roots over touched memory. Memory is a Merkle tree under \mathsf{H}, a height-27 tree of four-word leaves and a height-4 tree of registers joined under one root, and each shard publishes the root before it and the root after it. A boundary unit recomputes, for every leaf the shard touches, its path in the initial tree and in the final tree: it sends the leaf’s initial words on the memory bus and receives its final words, so the shard’s accesses balance inside the shard, and the untouched siblings along the paths enter both trees through one lookup. A per-word initialisation bit replaces the initialisation table, and precompile and syscall pairings balance in the shard that issues them, the executor closing a shard before a precompile that would give its recursion leaf an area no recursion shape admits. Composition checks that each shard’s outgoing root is the next shard’s incoming root and that the first is the image root the verifying key fixes. Soundness rests only on the collision resistance of \mathsf{H}; the accumulation rows and cross-shard memory units leave the machine, the Merkle rows take their place, and every measured block proves through compression with the root chain closed.

5.6 The bus argument: one lookup per shard

One LogUp-GKR instance, the bus argument, proves all interactions of a shard on the program, state, memory, byte, range, syscall, global and accumulation buses. After the trace is committed, the verifier samples \alpha,\beta\in\mathbb{F}_{p^4}; every interaction (\mathsf{bus},\boldsymbol f,m) contributes m/\big(\alpha-\mathsf{bus}-\sum_{j\ge1}\beta^j f_j\big), and the prover shows that sends and receives have equal sums. The fractions are the leaves of a layered GKR circuit whose transitions sumcheck proves from the root down, and the final layer leaves evaluation claims on the participating columns. A reth shard has on the order of 10^8 leaves, one per (row, interaction) pair, so interactions per row cost separately from columns, and this circuit is the largest GPU-kernel consumer (Section 10). Its soundness is \deg/|\mathbb{F}_{p^4}| per sumcheck round plus the fingerprint’s collision probability, which grows with the number of leaves (§9.2); the schedule of Table 5 grinds the LogUp-GKR challenge by 22 bits.

5.7 The constraint argument: one zerocheck per shard

The constraint system is uniform: a chip imposes the same constraints on every row, so nothing about it is committed and the verifier evaluates the constraint polynomials itself at the closing point. All chips’ constraints are proved by one zerocheck. The verifier samples \eta to combine chips and \mu to combine a chip’s constraints, so that C_c(\boldsymbol X)=\sum_k\mu^k c_{c,k}(\mathrm{row}(\boldsymbol X)) must vanish on chip c’s real rows, and the prover proves \sum_{\boldsymbol b}\mathrm{eq}(\boldsymbol b,\boldsymbol r)\sum_c\eta^c C_c(\boldsymbol b)=0 for a random \boldsymbol r by sumcheck over the tallest chip’s variables, with shorter chips handled by an analytic “virtual ≥” factor rather than padding. Constraint degree three gives round polynomials of degree four. The GPU’s constraint kernels are compiled per chip from the description the verifier uses, except for the widest accelerator chips, which are interpreted (Table 9), and host verification catches any mismatch. The zerocheck is seeded from the LogUp-GKR openings, so the two share one opening of each column; what remains is about 3.6\cdot10^4 (chip, column, point, value) claims per shard, which the commitment layer reduces to one.

5.8 The cost of a row

Counting a step’s committed elements shows that an instruction’s cost lies in the state its row reads and writes, not in the function it computes. The R-type frame is 30 columns: eight for the shard, the two clock limbs, the opcode, the three register indices and the zero-register flag, and 22 for the three register accesses (ten for the read–write of \mathsf{op\_a}, its previous word plus six access columns, and six per read). The I-type frame is 27 columns and the shift-amount frame 24. With the program-counter pair each chip owns, an instruction pays 32 columns before it computes anything; Bitwise then adds five and AddSub four. The register memory check is therefore most of every common row, and the six-column register access saves three columns on every access of every instruction. §§5.9 and 5.10 report each chip against this floor, and Section 10.2 turns the widths into a cost per executed instruction.

5.9 Chips for the base instruction set

For each instruction family we give the chip, its frame, how the row fixes the result, and the lookups the chip adds to its frame’s. Operands follow Definition 4.2: a is the word written to (or, for stores and branches, read from) register \mathsf{op\_a}, and b and c are the words of \mathsf{op\_b} and \mathsf{op\_c}, from registers or decoded immediates, in the notation of §5.1. Every result is gated by (1-\mathsf{op\_a\_0}), which the tables omit.

Frames. The frame’s interactions are paid on every row (§5.3): 20 for the R-type frame and 16 for the I-type and shift-amount frames, itemised in Appendix A. A universal frame, for chips whose opcodes mix operand shapes, is the R-type frame with its reads gated by the immediate flags. The four frames play the part of OpenVM’s six RV32IM adapters [Ope26b]; loads, stores and branches share the I-type frame. Widths are from Table 12, and lookups are counted beyond the frame’s.

5.9.1 Logical instructions

Instructions Chip (width), frame Result Added lookups
and, or, xor, nor Bitwise (37), R a_i=\mathrm{OP}(b_i,c_i), i<4 4 byte-table
andi, ori, xori BitwiseImm (33), I a_i=\mathrm{OP}(b_i,c_i), i<4 4 byte-table

A bitwise operation has no constraint at all: each byte pair is one lookup into the byte table, whose operation index is a selector-weighted sum of the opcode flags (§5.2). The immediates of andi, ori and xori are zero-extended at decode, and nor has no immediate form.

5.9.2 Arithmetic instructions

Instructions Chip (width), frame Result Added lookups
add, addu AddSub (36), R a=b+c \bmod 2^{32} none
sub, subu AddSub (36), R a+c=b \bmod 2^{32} none
addi, addiu AddSubImm (33), I a=b+\mathrm{sext}(\mathit{imm}) \bmod 2^{32} none
lui AddSubImm (33), I a=0+(\mathit{imm}\ll 16) none
mfhi, mflo, mthi, mtlo AddSubImm (33), I a=b+0 none

Addition is checked byte by byte with carries that are not columns: the carry out of byte i is the linear expression \theta_i=(b_i+c_i-a_i+\theta_{i-1})/256, \theta_{-1}=0, and the chip asserts \theta_i(\theta_i-1)=0; subtraction asserts the same of a+c=b. The frame byte-checks the result, so the family adds four columns (two selectors, two gates) and no lookup. Jolt instead forms b+c as one element of a 256-bit field and looks up its low bits [AST24], which 2^{32}>p rules out here. lui adds an immediate shifted at decode to register 0, and the moves between HI (register 33), LO (register 32) and the general registers add zero. add and addi decode exactly as addu and addiu: the manual’s overflow trap is modelled by neither the executor nor the chip (§4.3).

5.9.3 Comparisons

Instructions Chip (width), frame Result Added lookups
sltu, slt Lt (50), R a=x_s(1-y_s)+\mathrm{eq}(x_s,y_s)\,\mathrm{LTU}(x_{<s},y_{<s}) 2 AND, 1 LTU
sltiu, slti LtImm (47), I as above, y=\mathrm{sext}(\mathit{imm}) 2 AND, 1 LTU

With x=b and y=c the result is Jolt’s signed less-than, while for the unsigned forms the sign bits are not split off and LTU compares the full words [AST24]. Two AND lookups clear the top bit of each high byte, which gives x_{<s}, y_{<s} and, by difference, the sign bits. The unsigned part is decomposed differently: Jolt sums over chunks, weighting each chunk’s less-than by the equality of every chunk above it, a less-than and an equality lookup per chunk; Lt witnesses a one-hot flag for the most significant differing byte, asserts by constraints that the bytes above it agree and, through a witnessed inverse, that the flagged bytes differ, and spends one LTU lookup on the flagged pair. The upper three result bytes are zero.

5.9.4 Shifts and rotates

Instructions Chip (width), frame Result Added lookups
sll ShiftLeftImm (45), shift a=b\cdot2^k \bmod 2^{32}, k=\mathit{sa} 4 range
sllv ShiftLeft (62), R a=b\cdot2^k \bmod 2^{32}, k=c \bmod 32 4 range
srl, sra, rotr ShiftRightImm (83), shift low word of (\hat b\gg k), k=\mathit{sa} 1 MSB, 8 ShrCarry, 16 range
srlv, srav, rotrv ShiftRight (89), R low word of (\hat b\gg k), k=c \bmod 32 1 MSB, 8 ShrCarry, 16 range

A shift by k=8q+r is a shift by r bits followed by a relabelling of whole bytes by q. The shift amount is decomposed into bits, of which the low five are used (the manual’s reduction modulo 32), and one-hot selectors for q\in[0,4) and r\in[0,8) are tied to them. A left shift multiplies by 2^r with witnessed per-byte carries, \rho_i=2^r b_i+\theta_{i-1}-256\theta_i, then moves byte i to byte i+q; the shift-amount form computes 2^r as (1+s_0)(1+3s_1)(1+15s_2) with no one-hot. A right shift first extends b to eight bytes \hat b, whose upper four are zero for srl, 0xFF times the sign bit for sra, and a copy of b for rotr, so one right shift leaves the rotation in the low half. The bit part uses eight ShrCarry lookups, each mapping a byte and a 3-bit shift to the shifted byte and the bits shifted out: Jolt’s shift decomposition [AST24], a subtable indexed by a chunk and the shift amount, with the byte part done by relabelling.

5.9.5 Branches and jumps

Instructions Chip (width), frame \mathsf{next\_next\_pc} Added lookups
beq, bne Branch (56), I \mathsf{next\_pc}+\mathit{off} if taken, else \mathsf{next\_pc}+4 ≤ 9 of 13
bgez, bgtz, blez, bltz Branch (56), I as above, comparing with register 0 ≤ 9 of 13
j, jal Jump (57), universal \mathit{target}\ll 2 3 LTU
jr, jalr Jump (57), universal b 3 LTU
bal Jump (57), universal \mathsf{next\_pc}+\mathit{off} 3 LTU, 6 range

A transfer does not change \mathsf{next\_pc}, the address of its delay slot; it sets \mathsf{next\_next\_pc}, the second component of the pair it sends, and the delay-slot instruction is simply the next row of the chain (Example 5.3). Branch compares a (register rs) with b (register rt, or register 0 for the compare-with-zero forms). Equality is two is-zero tests, by witnessed inverses, on the differences of the 16-bit halves; the sign of a is one MSB lookup, gated to the compare-with-zero forms; and a>0 is (1-a_s)(1-[a=0]). The offset is shifted and sign-extended at decode, so the taken target is one in-row addition with a byte-checked result, and one LTU lookup per counter word proves it canonical. Jump writes the link \mathsf{next\_pc}+4, which is \mathsf{pc}+8 through the chain, and takes its target from the immediate, from register b, or from an addition for bal. The region bits that j and jal take from the program counter in the manual are zero in both the executor and the chip, which is exact for text below 2^{28}, where the guest toolchain links it.

5.9.6 Loads and stores

Instructions Chip (width), frame Result Added interactions
lw, ll LoadWord (48), I a=M[\mathit{addr}] 9
sw, sc StoreWord (52), I M[\mathit{addr}]\leftarrow a; sc also sets a=1 9
lb, lbu, lh, lhu LoadNarrow (59), I selected byte or half, sign- or zero-extended 10
sb, sh StoreNarrow (55), I byte or half of a merged into M[\mathit{addr}] 9
lwl, lwr, swl, swr MemoryUnaligned (59), I byte-wise merge of M[\mathit{addr}] and a 9

The five memory chips share one block of columns and nine interactions. The effective address b+\mathrm{sext}(\mathit{off}) is one in-row addition with range-checked result bytes; one LTU proves it canonical and a second, with an is-zero test on its upper bytes, that it lies above the 36 register addresses; and one AND lookup extracts its two low bits, from which the aligned address is linear. The access is one word-granular access at sub-cycle position 0 (two memory-bus interactions and two timestamp lookups), and the word is not byte-checked again, since every value that enters memory is byte-shaped at its source (§5.4). The word forms assert that the low bits are zero; the narrow and unaligned forms turn them into one-hot offset flags and select or merge bytes polynomially, and a narrow signed load adds one MSB lookup and fills with 0xFF times the bit. For a single-threaded guest, ll is lw with no reservation, and sc always succeeds and writes 1.

OpenVM likewise accesses aligned four-cell blocks and selects bytes within the row [Ope26b, §3.2.4], where the original Jolt design spends one memory-checking operation per byte [AST24]; the price is the offset flags and merge columns that make the narrow and unaligned chips the widest of the family.

5.10 Chips for the extended instruction set and system calls

Each of these instructions is still one row of one chip, which carries as columns the work a lookup-based design spreads over a sequence of virtual instructions [AST24], and HI (register 33) is written by a second access at sub-cycle position 4. That access raises eight interactions, counted as “an access” in the tables below: a send and a receive on the memory bus, two timestamp lookups, and two byte lookups each for its previous and its new word.

5.10.1 Multiplication

Instructions Chip (width), frame Result Added lookups
mul Mul (74), R a=b\cdot c \bmod 2^{32} 14, and an access
mult, multu Mul (74), R (\texttt{HI},\texttt{LO})=b\cdot c, signed or unsigned 14, and an access
madd, maddu, msub, msubu MiscInstrs (432), universal (\texttt{HI},\texttt{LO})\mathrel{\pm}=b\cdot c 26, and an access

A 64-bit product exceeds the field, so it is formed as a convolution of bytes. Both operands are extended to eight bytes, with 0xFF times the sign bit for the signed forms mult, madd and msub (two MSB lookups) and zeros otherwise; the sign extension does in the row what Jolt’s virtual sequence for signed high multiplication does [AST24]. The uncarried convolution m_k=\sum_{i+j=k}b_ic_j, k<8, is tied to witnessed product bytes \pi_k and carries \theta_k by m_k+\theta_{k-1}=\pi_k+256\,\theta_k, with carries range-checked to 16 bits and product bytes to 8. The low word \pi_{0..3} goes to \mathsf{op\_a} (LO for mult and multu, rd for mul) and the high word to HI. The multiply–accumulate forms add the same product to the 64-bit (\texttt{HI},\texttt{LO}) with a byte-carry addition, and prove a subtraction as the addition that undoes it.

5.10.2 Division and remainder

Instructions Chip (width), frame Result Added lookups
div, divu DivRem (163), R \texttt{LO}=q, \texttt{HI}=r with b=qc+r, \lvert r\rvert<\lvert c\rvert 36, and an access

As in Jolt [AST24], the prover supplies the quotient q and remainder r as advice and the row checks them; Jolt’s check is eight virtual instructions; here it is 131 columns beyond the frame. qc is formed by the Mul convolution, signed for div, and r, sign-extended to eight bytes, is added with byte carries; the low word of the sum must equal b and the high word its sign extension. The remainder takes the dividend’s sign, and |r|<|c| compares absolute values, each proved by an addition to zero when negative, with the one-flag comparison of Lt. The overflowing case b=-2^{31}, c=-1 is detected by two word-equality tests and exempts the high word. Division by zero is an execution error (§4.3), and the row asserts c\ne0.

5.10.3 Bit manipulation and conditional moves

Instructions Chip (width), frame Result Added lookups
clz, clo CloClz (93), I leading zeros of b, or of \neg b 28
movz, movn MovCond (49), universal a=b if [c=0] (resp. \ne), else a unchanged none
wsbh MovCond (49), universal a=(b_1,b_0,b_3,b_2) none
seb, seh MiscInstrs (432), universal b_0 or (b_0,b_1), sign-extended 1 MSB
ext, ins MiscInstrs (432), universal bit-field extract, insert up to 113
teq MiscInstrs (432), universal no trap: a\ne b none

clo is clz of the complemented word. For clz, the zero word yields 32; otherwise the row proves, with the right-shift construction of §5.9.4 inlined, that shifting b right by 31-a leaves exactly 1, and an LTU lookup bounds a by 32. The conditional moves test c=0 by two witnessed inverses on its 16-bit halves and select between b and the previous value of \mathsf{op\_a}, which the frame’s read–write access carries; wsbh is a byte permutation. ext is a left shift followed by a right shift, and ins rotates the destination, shifts, adds the shifted source and rotates back. These rare opcodes share MiscInstrs, whose opcode-specific columns overlap in a union, so the row is as wide as ins and every lookup is gated by an opcode selector. teq is provable only when it does not trap.

5.10.4 System calls

Instructions Chip (width), frame Effect Added interactions
syscall SyscallInstrs (68), R sends id, b, c as 16-bit halves 2 LTU, 2 syscall-bus
Linux ABI calls SysLinux (100), none brk, mmap, read, write, … up to 50, gated
accelerators per precompile, none a hash or curve operation in memory per chip

SYSCALL is the one place a row hands work to another table. The call number in $v0 is read as bytes: the low two are the call identifier, the third says whether the call is sent to a table, and the fourth is a count of extra clock ticks, by which the frame advances the clock beyond five so that a precompile’s memory accesses fit before the successor. The two arguments travel on the syscall bus as exact 16-bit halves with a Linux flag. A halting call sets the next program counter to zero and exposes its first argument as the public exit code; a commit call compares its argument with the public output digest. SysLinux receives the Linux-ABI calls and performs their memory accesses at the calling cycle, and the precompile chips of Appendix A receive accelerator calls, routed across shards through the digest or, with Merkle roots, proved in the shard that issues them (§5.5). The Jolt design [AST24] has no precompile tables; cryptographic operations there are compiled into sequences of ordinary and virtual instructions.

6 The jagged commitment

After the bus argument and the zerocheck of a shard (§§5.6 and 5.7), the verifier holds evaluation claims on individual chip columns: about 3.6\cdot10^4 per reth shard, with heights from 32 rows to millions. Committing each column or table separately costs one Merkle root and one query phase per commitment, and puts every table’s height into the verifier, so that each height profile needs a verifier circuit of its own [HJR+25, p. 4]. The jagged polynomial commitment of Hemo et al. [HJR+25] commits the non-zero part of all columns as one dense multilinear and reduces every column claim to one evaluation of it. Ziren uses its basic construction [HJR+25, Thm. 1.4] with its jagged assist [HJR+25, Thm. 1.5]; it uses neither the “fancy” variant for columns of equal height (§6 there) nor committed heights proved by GKR (§1.1.2 there), because the machine’s columns are too heterogeneous for grouping into power-of-two tables to pay.

Sections 6.1–6.3 restate the construction in our notation. Sections 6.4–6.6 describe what Ziren adds: several ordered commitments opened as one, the stacked layout of the opening, and a quantised geometry that makes the verifier a function of a small class rather than of a shard’s row counts. A chip can therefore be widened, added or removed without changing the layer above it; the chip revisions of §10.2 left this protocol unchanged. Figure 6 shows the construction end to end.

The jagged commitment. Left, the sparse view: K columns c0 to c5 of different heights inside a 2^n-row box, with hatched synthetic padding columns. Right, the dense view: the columns laid end to end at prefix sums t0 to t6 up to area A, split into round 0 (root C0) and round 1 (root C1), zero-padded to 2^m, with the indicator W aligned cell for cell.
Figure 6: The jagged commitment. (a) The sparse view: K columns of different heights inside a 2^n-row box; the dotted cells above each column are virtual zeros, never committed; hatched columns, \mathbf c_3 and \mathbf c_6, are the synthetic padding of §6.4 and count among the K columns. (b) The dense representation \mathbf Q: the columns laid end to end, located by the public prefix sums t_k, split into two ordered input rounds with separate roots, and zero-padded to 2^m for free (the dashed tail, which has no column and so no weight in W); the indicator W is aligned with it cell for cell. Protocol 6.3 reduces the K column claims to one opening of \mathbf Q.

6.1 Jagged functions and the dense representation

Let there be K columns \mathbf c_0,\ldots,\mathbf c_{K-1} with heights h_0,\ldots,h_{K-1}\le 2^n, viewed as one function p:\{0,1\}^n\times\{0,1\}^\kappa\to\mathbb{F}, \kappa=\lceil\log_2K\rceil, with p(x,k)=\mathbf c_k[x] for x<h_k and p(x,k)=0 otherwise. Such a function is jagged [HJR+25, Def. 1.1]. Its non-zero part is the dense representation

\mathbf Q=\mathbf c_0\,\|\,\mathbf c_1\,\|\cdots\|\,\mathbf c_{K-1},\qquad t_0=0,\quad t_{k+1}=t_k+h_k,\quad A=t_K,

padded with zeros to M=2^m, m=\lceil\log_2A\rceil, and written \widetilde Q as a multilinear in m variables. Column k occupies [t_k,t_{k+1}) in \mathbf Q, and the prefix sums are public: they enter the transcript before any challenge. \mathbf Q and the prefix sums determine p [HJR+25, Fact 1.3], so committing to \widetilde Q commits to every column at the cost of the real area A rather than K\cdot2^n.

Table 4: Notation of this section against that of Hemo et al. [HJR+25].

Here [HJR+25] Meaning
K, \kappa=\lceil\log_2K\rceil 2^k, k number of columns
n, m, M=2^m n, m, M log height of the row cube; log and size of the dense domain
h_k, t_k (exclusive) h_y, t_y (inclusive) column heights and prefix sums
\mathbf Q, \widetilde Q q, \widehat q dense representation
W f_t(z_r,z_c,\cdot) the indicator of Equation (1)
\boldsymbol z_{\mathrm{row}}, \boldsymbol z_c, \boldsymbol z^* z_r, z_c, i row point, column point, dense point
\mathsf{BP}, u_k \widehat g, (t_{y-1},t_y) branching program and its boundary input

Table 4 maps our notation to the paper’s. Two differences are inessential: our prefix sums are exclusive (t_k starts column k), and a boundary takes m+1 bits because t_K=A may equal 2^m. Heights may reach 2^n rather than 2^n-1, which is harmless because only boundaries are encoded.

6.2 The jagged reduction

Let \boldsymbol z_{\mathrm{row}}\in\mathbb{F}_{p^4}^n be the common row point left by the zerocheck, and y_k the claimed evaluation of column k there, high zeros included:

y_k=\sum_{j=0}^{h_k-1}Q[t_k+j]\,\mathrm{eq}(j,\boldsymbol z_{\mathrm{row}})=\widetilde p(\boldsymbol z_{\mathrm{row}},k).

The verifier samples a column point \boldsymbol z_c\in\mathbb{F}_{p^4}^\kappa, which turns the K claims into the single claim

T=\sum_{k<K}\mathrm{eq}(k,\boldsymbol z_c)\,y_k=\widetilde p(\boldsymbol z_{\mathrm{row}},\boldsymbol z_c)

at an error of \kappa/|\mathbb{F}_{p^4}| by Schwartz–Zippel; this is the input of the basic jagged construction. With w_k=\mathrm{eq}(k,\boldsymbol z_c), the length-M table

W[t_k+j]=w_k\,\mathrm{eq}(j,\boldsymbol z_{\mathrm{row}})\quad(0\le j<h_k),\qquad W[i]=0\ \text{ elsewhere},

is the paper’s indicator f_t(\boldsymbol z_{\mathrm{row}},\boldsymbol z_c,\cdot) on the Boolean cube [HJR+25, Eqs. (3)–(4)], and

T=\sum_k w_k\sum_{j<h_k}Q[t_k+j]\,\mathrm{eq}(j,\boldsymbol z_{\mathrm{row}})=\sum_{i\in\{0,1\}^m}\widetilde Q(i)\,\widetilde W(i).\tag{1}

\widetilde W agrees with the product of equality polynomials only on the cube [HJR+25, Rem. 3.1], so the verifier cannot evaluate it by formula; §6.3 supplies it.

Theorem 6.1 (Basic jagged [HJR+25, Thm. 1.4]). There is an m-round protocol in which the prover holds \mathbf Q and the verifier holds only the prefix sums, (\boldsymbol z_{\mathrm{row}},\boldsymbol z_c) and T, and at whose end the verifier either rejects or outputs a point \boldsymbol z^*\in\mathbb{F}_{p^4}^m and a value v_Q. Completeness: if T=\widetilde p(\boldsymbol z_{\mathrm{row}},\boldsymbol z_c) then v_Q=\widetilde Q(\boldsymbol z^*). Soundness: if T\ne\widetilde p(\boldsymbol z_{\mathrm{row}},\boldsymbol z_c), then except with probability 2m/|\mathbb{F}_{p^4}| the verifier rejects or v_Q\ne\widetilde Q(\boldsymbol z^*). Efficiency: the prover performs at most 5\cdot2^m+2^n+K multiplications; the verifier’s work is an arithmetic circuit determined by m and K alone, dominated by one evaluation of \widetilde W(\boldsymbol z^*).

The protocol is the sumcheck for a product of two multilinears [HJR+25, Lemma 2.3] applied to Equation (1), the jagged sumcheck. Each round polynomial has degree two and is sent as its values at 0, 1, 2, one value more than the paper’s accounting [HJR+25, App. A]. With challenges \boldsymbol z^*=(r_0,\ldots,r_{m-1}) in sampling order, least-significant variable first, the closing claim is

T_{\mathrm{final}}=\widetilde Q(\boldsymbol z^*)\,\widetilde W(\boldsymbol z^*).\tag{2}

The proof carries v_Q=\widetilde Q(\boldsymbol z^*), which the opening of §6.5 authenticates; the verifier obtains \widetilde W(\boldsymbol z^*) from the public prefix sums.

6.3 Evaluating the indicator: the jagged assist

Materialising W would cost \Theta(M) extension-field elements. Instead, the indicator is a sum over columns of a function of each column’s boundaries [HJR+25, Claim 3.2.1, Eq. (5)],

\widetilde W(\boldsymbol z^*)=\sum_{k<K}w_k\,\widehat g(\boldsymbol z_{\mathrm{row}},\boldsymbol z^*,t_k,t_{k+1}),\qquad g(a,b,c,d)=1\iff b<d\ \wedge\ b=a+c,

where g is computed by a width-four read-once branching program that reads one bit of each of (a,b,c,d) at a time, least significant first, tracking the carry of a+c and whether b<d [HJR+25, Claim 3.2.2]. Its multilinear extension is evaluated by the dynamic program of Holmgren and Rothblum [HR18], stated and proved as in Hemo et al. [HJR+25, Lemma 4.2]: 48(m+1) multiplications per point at our width and alphabet. Points are passed to the program most-significant coordinate first [HJR+25, p. 5] while the sumcheck samples least-significant first, so the program’s point is \mathrm{rev}(\boldsymbol z^*). Evaluated directly, the indicator costs O(mK) [HJR+25, Prop. 3.2], too much for a recursion circuit at K\approx3.6\cdot10^4.

The jagged assist [HJR+25, Thm. 1.5] delegates it. With u_k=\mathrm{bits}_{\mathrm{BE}}(t_k)\,\|\,\mathrm{bits}_{\mathrm{BE}}(t_{k+1}) the 2(m+1) boundary bits of column k, the prover proves

\widetilde W(\boldsymbol z^*)=\sum_{x,y\in\{0,1\}^{m+1}}\ \sum_{k=0}^{K-1}w_k\,\mathrm{eq}\big((x,y),u_k\big)\,\mathsf{BP}\big(\boldsymbol z_{\mathrm{row}},\mathrm{rev}(\boldsymbol z^*),x,y\big)\tag{3}

by one degree-two sumcheck over the 2(m+1) boundary variables of Equation (3). This is the batch evaluation protocol of Hemo et al. [HJR+25, Lemma 5.1] specialised: the K evaluations are already combined by the weights w_k rather than by fresh random coefficients, so no further randomness is needed and the error is that of the sumcheck alone, 4(m+1)/|\mathbb{F}_{p^4}|.

Theorem 6.2 (Jagged assist [HJR+25, Thm. 1.5, Lemma 5.1], as instantiated). Completeness: if \widetilde W(\boldsymbol z^*) is claimed correctly, the verifier accepts. Soundness: otherwise it rejects except with probability 4(m+1)/|\mathbb{F}_{p^4}|. Efficiency: the verifier evaluates \mathsf{BP} once, 48(m+1) multiplications, and the K equality factors \sum_k w_k\,\mathrm{eq}(\boldsymbol\rho,u_k) at the closing point \boldsymbol\rho, O(mK) operations; the prover’s cost is O(mw^2(K+w)) operations for a program of width w [HJR+25, Lemma 4.6].

The second verifier term dominates: it is linear in the number of columns, about 2\cdot10^6 extension multiplications at the core shard’s m and K, against a few thousand for the branching program, consistent with the paper’s m\cdot2^k [HJR+25, p. 7]. The native verifier computes the value by the closed form and replays the assist transcript; the recursion circuit checks the assist’s closing identity explicitly.

6.4 Several commitments opened as one

The paper assumes one dense oracle. Ziren commits a shard in several ordered input-commitment rounds, preprocessed first and main last, each with its own root, and opens them together; each round uses the stacked layout of SP1 Hypercube [Suc25a], which the paper’s concrete evaluation also uses, cutting the dense side into 2^8 blocks of 2^{21} cells [HJR+25, §7].

Round r contains columns \mathbf c_{r,0},\ldots,\mathbf c_{r,K_r-1} of real area a_r=\sum_k h_{r,k}, committed over an area A_r\ge a_r that is a multiple of the stacking height H=2^\ell:

\mathbf q_r=\mathbf c_{r,0}\,\|\cdots\|\,\mathbf c_{r,K_r-1}\,\|\,\mathbf 0^{A_r-a_r},\qquad \mathbf Q=\mathbf q_0\,\|\,\mathbf q_1\,\|\cdots\|\,\mathbf q_{R-1},\qquad A=\sum_{r<R}A_r.

The reduction of §6.2 runs on this logical \mathbf Q; the roots C_0,\ldots,C_{R-1} remain separate and their order is load-bearing. Each gap A_r-a_r is represented by explicit synthetic zero columns of zero claim and height at most 2^n, so the prefix sums describe every committed cell and only the suffix from A to M is implicit. That suffix is the paper’s “free padding” [HJR+25, fn. 4], on which the indicator vanishes because g requires b<d. Under a recursion area pin the gap is split into a fixed number of columns, zero-height ones allowed, so the recursion program’s column count does not depend on a child’s row counts.

Each round is cut into S_r=A_r/H stripes of H consecutive entries under its own root. With S=\sum_r S_r and b=\lceil\log_2\max(S,1)\rceil, the opening domain has \ell+b variables, which for a nonempty ordinary instance equals m. Its point is (\boldsymbol z_{\mathrm{stack}},\boldsymbol z_{\mathrm{batch}}): \ell coordinates select a position inside a stripe and b interpolate the ordered list of stripes across all rounds.

Protocol 6.3 (Jagged opening).
Public input: ordered roots C_0,\ldots,C_{R-1}, the prefix sums (t_k)_k, a row point \boldsymbol z_{\mathrm{row}} and column claims (y_k)_{k<K} at \boldsymbol z_{\mathrm{row}}.
Witness: the committed rounds \mathbf q_0,\ldots,\mathbf q_{R-1}.

Prover \mathcal P Message Verifier \mathcal V
1. ← \boldsymbol z_c Sample \boldsymbol z_c\in\mathbb{F}_{p^4}^\kappa and set T=\sum_k\mathrm{eq}(k,\boldsymbol z_c)\,y_k.
2. Run the jagged sumcheck on \langle\widetilde Q,\widetilde W\rangle=T (m rounds, Theorem 6.1); send v_Q=\widetilde Q(\boldsymbol z^*). rounds, v_Q → Check every round; obtain \boldsymbol z^* and T_{\mathrm{final}}.
3. Run the jagged assist at \mathrm{rev}(\boldsymbol z^*) (2(m+1) rounds, Theorem 6.2). rounds → Obtain v_W=\widetilde W(\boldsymbol z^*); check T_{\mathrm{final}}=v_Q\,v_W (2).
4. ← \boldsymbol z_{\mathrm{ext}} Sample the point-extension coordinates, if any.
5. Send the stripe evaluations (e_{r,s})_{r,s}. (e_{r,s}) → Check (4).
6. Open every stripe at the common stack point in one batched stacked WHIR or BaseFold proof. ↔︎ opening Accept if and only if the opening verifies against C_0,\ldots,C_{R-1}.

6.5 One opening across all roots

If the reduction point has fewer than \ell+b coordinates, the prover appends Fiat–Shamir coordinates after the assist, each contributing a factor 1-r_j; in the ordinary multi-round layout m=\ell+b and this is a no-op. For round r and stripe s let e_{r,s}=\widetilde{q_{r,s}}(\boldsymbol z_{\mathrm{stack}}). The prover reports these in round-major, stripe-major order; the verifier zero-pads the list to 2^b and checks

v_Q=\widetilde{\big(e_{0,0},\ldots,e_{0,S_0-1},e_{1,0},\ldots,e_{R-1,S_{R-1}-1}\big)}(\boldsymbol z_{\mathrm{batch}}).\tag{4}

One stacked WHIR or BaseFold proof then authenticates every e_{r,s} against C_0,\ldots,C_{R-1} at the common stack point, so the reduction, assist and opening each run once while commitments stay per round. All rounds must share the stacking height and PCS mode; a mixed transcript is rejected. The implementation also offers BaseFold as the opening; every configuration in this paper uses WHIR.

The step order, the round order and the reversal convention fix the challenges; changing any of them is a protocol change.

Soundness. The three algebraic steps contribute \kappa/|\mathbb{F}_{p^4}| (column batching), 2m/|\mathbb{F}_{p^4}| (jagged sumcheck, Theorem 6.1) and 4(m+1)/|\mathbb{F}_{p^4}| (assist, Theorem 6.2), which together form the row “reduction to the dense polynomial” of Table 6. The paper states plain soundness of each reduction; the round-by-round form Theorem 9.2 assumes follows because each is a sumcheck, round-by-round sound with the same per-round errors [CY24]. The opening’s terms are those of Section 7, and all of them are accounted in §9.2.

6.6 Quantised committed geometry

The stacking height is H=2^{21}, so a round is committed as a whole number of 2^{21}-cell blocks, and a column is at most 2^{22} rows, which bounds the gap one synthetic column can absorb. A round with \nu=\lceil a_r/H\rceil blocks of real data is committed in a bucket of \hat\nu blocks, where \hat\nu=\nu for \nu\le4 and otherwise the next multiple of eight:

1,\ 2,\ 3,\ 4,\ 8,\ 16,\ 24,\ \ldots\ \text{blocks}.

For an unpinned round, which is every core round, the gap is split into

\left\lceil\frac{(\hat\nu-\hat\nu_{\mathrm{prev}})\,H}{2^{22}}\right\rceil\ \text{columns},\qquad \hat\nu_{\mathrm{prev}}=\text{the bucket below }\hat\nu,

at least one: the number the widest gap of the bucket needs, so the count depends on the bucket alone, and a narrower gap leaves trailing columns short or empty. A pinned round, as in the compress machine, uses a fixed column count.

Both rules make a shard’s committed geometry, and hence the recursion program that verifies it and that program’s key, a function of the chip set, the first-shard flag and the two buckets rather than of exact row counts. Rounding up to the next block, or letting the padding-column count follow the gap, would make every row profile a distinct verifier program. Under the quantised rule the key space is small enough to enumerate offline, one representative per (chip set, first-shard flag, preprocessed bucket, main bucket) class, which lets a verifier hold a fixed allowlist covering every shard shape the declared clusters admit (Section 8). The price is the padding inside a bucket, committed and opened like any other cell.

The reduction’s memory stays proportional to the real data: W is never materialised (§6.3); the suffix from A to M is treated as zero rather than allocated, which is why inter-round padding must be explicit and the suffix need not be; and the stripe evaluations of Equation (4) are read off the committed interleaved layout, so a round is traversed once to commit and once to open.

7 The WHIR opening

WHIR [ACFY24b] opens the jagged commitment of Section 6 (the commitment JC of §3.2). It authenticates the claim v_Q=\widetilde Q(\boldsymbol z^*) left by the jagged reduction, as an interactive oracle proof of proximity (IOPP) for constrained Reed–Solomon codes, whose multilinear also satisfies a stated weighted sum. This section gives the protocol as implemented and the commitment layout; the soundness of the schedule is accounted in §9.2. The schedule is the opening’s principal parameter: at a fixed soundness level it trades proof size against prover time.

7.1 The protocol

WHIR tests membership of f:L\to\mathbb{F} in \mathrm{CRS}[\mathbb{F},L,m,\widehat w,\sigma] (Section 2). An iteration with folding factor k runs k sumcheck rounds, sends a folded oracle re-encoded at the round’s rate, answers out-of-domain samples, answers t shift queries by opening 2^k symbols each, and recurses on a constrained code with k fewer variables; the final polynomial is sent in the clear. The out-of-domain samples distinguish WHIR from BaseFold: they pin the folded oracle to a unique nearby codeword before the shift queries are drawn. At the same provable level WHIR needs fewer queries in later rounds than BaseFold and a handful of committed rounds rather than one per variable, while sharing its prover skeleton (encode, Merkle-commit, fold).

7.2 Commitment layout

Ziren uses the interleaved commitment: a polynomial in \nu variables is reshaped into a 2^{\nu-k_0}\times2^{k_0} matrix whose column c is the stride-2^{k_0} slice f[h\cdot2^{k_0}+c]; each column is Reed–Solomon encoded independently (one DFT per column), and, for a single stripe, Merkle leaf j holds the 2^{k_0} column values at domain point x_j. Folding a leaf by the round’s challenge gives the folded polynomial at x_j, so a query answer enters the next sumcheck as an ordinary constraint whose weight folds in closed form.

The layout is applied separately to every input-commitment round of Section 6.4; the roots are not merged. Within a root the stripes are grouped 32 to a leaf, so a leaf of the first oracle authenticates one coset row from each stripe, 32\times2^{k_0} field elements. The first folding factor k_0 is therefore small: leaf width multiplies every first-round query, and re-hashing those leaves is the recursion verifier’s dominant cost. Later rounds query a single folded polynomial and fold more variables at a time. Each committed round re-encodes the folded polynomial at its new rate; the opening of a reth shard costs about 39 ms of host-visible time on the GPU with device-resident rounds, the round-0 re-encoding being the largest term. Under the core schedule no proof-of-work is spent on folding challenges, and grinding is spent only on the query phases and on the batching and LogUp-GKR challenges; the compress schedule also grinds every folding challenge (Table 5).

Table 5: The Jagged–WHIR schedules §9.2 accounts for: the core schedule, tuned for prover time, and the compress schedule, tuned for proof size. Analysis is the regime queries are counted in. Queries are per committed round, followed by the final query phase. OOD entries count samples after committed folds; the fold grind applies to every folding challenge. The stripe bound covers both ordered input-commitment rounds.

Profile first rate analysis folds queries OOD query grind fold grind batch grind LogUp-GKR grind stripe bound final variables
core 2^{-2} unique decoding [3, 6, 6] [124, 88, 85], 85 [2, 2] 22 bits 0 14 bits 22 bits 256 6
compress 2^{-3} Johnson, m=6 [2, 6, 6] [58, 28, 19], 14 [2, 2] 26 bits 27 bits 27 bits 22 bits 64 7

Table 5 gives one schedule, the one the soundness accounting of §9.2 is computed for; §10.4 describes how the schedule controls proof size. Each recommitment lowers the rate by three powers of two. The core schedule is tuned for prover time: the first oracle has rate 2^{-2}, and at log stacking height 21 the three folds consume 15 variables, the remaining six-variable polynomial being sent in the clear after its final query phase. The compress schedule, under which the root of the recursion tree proves, is tuned for the size of the published proof: it starts at 2^{-3}, the lowest rate the two-adicity of KoalaBear admits at this stacking height, counts queries under the Johnson bound, folds two variables first so that a first-round query opens half the leaf, and grinds every folding and batching challenge, which the list size of the Johnson-bound analysis requires. Each of its parameters is a setting, so a deployment with a different security requirement changes the schedule, not the prover.

8 Recursion

Shard proofs are aggregated by a recursion machine: a small register VM over the same field whose programs are compiled from a description of the verifier, executed to a trace, and proved by the same chip/LogUp-GKR/zerocheck/Jagged/WHIR pipeline. Its chips are the arithmetic of \mathbb{F} and \mathbb{F}_{p^4}, memory, the Poseidon2 permutation, a select gate and a batched folding gate for the FRI-style query checks. The root of the tree it builds is the compressed proof; the verifying-key allowlist binds that proof to the advertised machine. Shrink and wrap nodes extend the tree past the root for the applications (§8.1).

Leaves. A leaf (normalize) program verifies one core shard proof in four phases mirroring the host verifier: the transcript prologue (public values, commitment, chip dimensions), the LogUp-GKR layer replay, the zerocheck replay with the constraint evaluation of every chip present, and the jagged opening with its closing identity followed by the WHIR verifier. The jagged verifier depends only on the shard’s two geometry buckets and the constraint evaluation only on its chip set and whether it is the first shard, so the leaf programs form a bounded set that can be enumerated in advance; on one GPU, consecutive shards of the same class reuse a device-resident proving key. Adjacent leaves are fused into one node where shapes allow, and leaves are proved on the same GPU concurrently with core shards. Figure 7 shows the tree.

The compose relation. Write a node’s public values as

\mathsf{pv}=(\mathsf{vk},\mathsf{sh}_{\mathrm{in}},\mathsf{sh}_{\mathrm{out}},\mathsf{entry},\mathsf{exit},\mathsf{cur}_{\mathrm{in}},\mathsf{cur}_{\mathrm{out}},D,h,\mathsf{code},\mathsf{root}),

the guest’s verifying key, the index of the node’s first shard and the index after its last, the entry and exit machine states, the memory-address cursors the node opens and closes with, the accumulated cross-shard digest, the digest of committed output, the exit code, and the root of the allowlist of admissible recursion keys; a completion flag \mathsf{complete}, set only by the root, accompanies the tuple. With a delay slot the entry and exit states are pairs (\mathsf{pc},\mathsf{next\_pc}), so adjacency must pin both components. A compose node of arity k proves \mathcal{R}_{\mathrm{comp}}(\mathsf{pv};\pi_0,\ldots,\pi_{k-1}), which holds when each \pi_i verifies against a key the allowlist at \mathsf{root} contains; the children agree on \mathsf{vk}, h and \mathsf{code}; every \mathsf{root}_i equals the published \mathsf{root}; the ranges are adjacent, \mathsf{sh}_{\mathrm{out},i}=\mathsf{sh}_{\mathrm{in},i+1}, \mathsf{exit}_i=\mathsf{entry}_{i+1} and \mathsf{cur}_{\mathrm{out},i}=\mathsf{cur}_{\mathrm{in},i+1}; and \mathsf{sh}_{\mathrm{in}}=\mathsf{sh}_{\mathrm{in},0}, \mathsf{sh}_{\mathrm{out}}=\mathsf{sh}_{\mathrm{out},k-1}, \mathsf{entry}=\mathsf{entry}_0, \mathsf{exit}=\mathsf{exit}_{k-1}, \mathsf{cur}_{\mathrm{in}}=\mathsf{cur}_{\mathrm{in},0}, \mathsf{cur}_{\mathrm{out}}=\mathsf{cur}_{\mathrm{out},k-1} and D=\sum_i D_i. Digests are stored offset by the starting point D_{\mathrm{off}} of §5.5, so this sum is computed as D_0+D_1-D_{\mathrm{off}} and so on, and D=\mathcal O below means the stored value equals D_{\mathrm{off}}.

Recursion tree: three shard proofs feed three leaves, which feed one compose node of arity 3, which feeds the root. Annotations: the first-shard leaf requires entry = start(vk) and zero starting cursors; the compose node checks children's keys in the allowlist, consecutive shards, matching exit and entry, tiling cursors, summed digests and agreeing vk, h, exit code and root; the root starts at shard 1 with exit pc 0, D = O and exit code 0.
Figure 7: Every node of the tree carries the same public-value tuple, so a compose node checks its children by comparing tuples: the ranges must be adjacent, the cursors must tile and the digests must accumulate, while the verifying key, the output digest, the exit code and the allowlist root must agree. The root is where the memory argument and the cross-shard digest close, where the run is required to start at the first shard and end halted, and where the exit code is required to be the one the relation admits.

Leaves and the root. A leaf proves the same relation for its one or more fused children, except that each child is a core shard proof verified against the guest’s \mathsf{vk}; it is the leaf’s own key that the allowlist must contain, checked by its parent. A leaf sets \mathsf{sh}_{\mathrm{in}} and \mathsf{sh}_{\mathrm{out}} from the shard indices it verifies. The leaf of the first shard, index 1, also requires its entry state to be \mathsf{start}(\mathsf{vk}), the start state the guest key fixes, and its starting cursors to be zero. The root additionally requires \mathsf{sh}_{\mathrm{in}}=1, so that its leftmost leaf is the first-shard leaf. It also requires an exit program counter of zero, which the halt row sets (§5.10.4), D the identity and exit code zero, and it sets \mathsf{complete}, which closes the memory argument and the cross-shard digest over the execution and requires the exit code zero that the relation of Section 4.4 admits. Algorithm 2 states the checks.

Tree shape. The tree merges contiguous shard ranges as soon as they are complete rather than level by level, which shortens the tail after the last core shard from four serial composes to two, followed by the root (§3.3). A leaf is never the root, and neither is a compose of several children: once one node covers the execution, a compose of arity one over it closes the run, keeping leaf programs within the classes the enumeration below covers and giving the root one verifier program per child class, whatever the tree below it. The root alone is proved under the compress schedule (§10.4). Arity is capped at three by the recursion chips’ height budget; arity four was measured as neutral (41 nodes replaced by 27, −0.7% of wall time, unchanged tail).

Verifying-key binding. Each compose node checks its children’s recursion keys against a Merkle allowlist whose root it exports as a public value; why that binds the proof to the advertised machine, and what the external verifier checks of the root, are explained in §9.4.

Enumerating the leaf keys. A leaf program is determined by the geometry of the shard proof it verifies, which Section 6.6 quantises into buckets with a padding-column count fixed by the bucket. What remains is the shard’s chip set, one of the machine’s declared clusters, whether it is the execution’s first shard, and the two bucket indices. Enumerating those combinations yields, without running a guest, every leaf key a prover can produce for a shard in those clusters, at most 2\,|\mathcal C|\,|\mathcal B_{\mathrm{prep}}|\,|\mathcal B_{\mathrm{main}}| of them. A cluster is a chip-set combination declared by the shape configuration, curated from the target workloads rather than exhaustive over the chip powerset, so the allowlist covers an arbitrary guest only as far as the list does (§1.7). A shard outside the list produces a key the allowlist lacks and is refused: a loud failure of completeness, not of soundness. For the configuration this paper describes, the allowlist holds 6 362 leaf and compose keys. Sampling the leaf keys from a corpus of proved shards instead would leave every shard shape the corpus missed outside the allowlist. The enumeration is checked against such a corpus class by class and against the programs the classes generate. Algorithm 3 states it; every quantity it ranges over is fixed by the machine and the committed geometry.

Algorithm 2: The compose node of arity k, and what the root additionally requires. Line 2 is the binding of §9.4: without it the node would verify some proof rather than a proof of this machine.

Input: child proofs \pi_0,\ldots,\pi_{k-1} with public values \mathsf{pv}_0,\ldots,\mathsf{pv}_{k-1}, recursion keys \mathsf{vk}^{\mathrm{rec}}_0,\ldots,\mathsf{vk}^{\mathrm{rec}}_{k-1} and membership paths \mathsf{path}_0,\ldots,\mathsf{path}_{k-1}; a claimed allowlist root \mathsf{root}
Output: the node’s public values \mathsf{pv}, or \bot

  1. for i\leftarrow0 to k-1 do
  2. if \neg\,\mathsf{MerkleVerify}(\mathsf{root},\mathsf{vk}^{\mathrm{rec}}_i,\mathsf{path}_i) then return \bot // the child’s key is admissible
  3. if \neg\,\mathsf{Verify}(\mathsf{vk}^{\mathrm{rec}}_i,\mathsf{pv}_i,\pi_i) then return \bot
  4. if \exists\,i:\mathsf{root}_i\ne\mathsf{root} then return \bot // children share the root
  5. if \mathsf{vk}_i,h_i,\mathsf{code}_i not all equal over i then return \bot
  6. for i\leftarrow0 to k-2 do
  7. if \mathsf{sh}_{\mathrm{out},i}\ne\mathsf{sh}_{\mathrm{in},i+1}\ \vee\ \mathsf{exit}_i\ne\mathsf{entry}_{i+1} then return \bot // ranges adjacent
  8. if \mathsf{cur}_{\mathrm{out},i}\ne\mathsf{cur}_{\mathrm{in},i+1} then return \bot // cursors tile
  9. D\leftarrow\sum_i D_i // digests accumulate
  10. \mathsf{pv}\leftarrow(\mathsf{vk},\mathsf{sh}_{\mathrm{in},0},\mathsf{sh}_{\mathrm{out},k-1},\mathsf{entry}_0,\mathsf{exit}_{k-1},\mathsf{cur}_{\mathrm{in},0},\mathsf{cur}_{\mathrm{out},k-1},D,h,\mathsf{code},\mathsf{root})
  11. if this node is the root then
  12. if \mathsf{sh}_{\mathrm{in}}\ne1\ \vee\ \mathsf{pc}(\mathsf{exit})\ne0 then return \bot // first shard; exit pc zero
  13. if D\ne\mathcal O\ \vee\ \mathsf{code}\ne0 then return \bot
  14. set \mathsf{complete}
  15. return \mathsf{pv}

Algorithm 3: Enumerating the admissible leaf and compose keys. The loop bounds come from the machine’s chip clusters and from the bucket rule of §6.6; no guest is executed.

Input: chip clusters \mathcal C; bucket sets \mathcal B_{\mathrm{prep}},\mathcal B_{\mathrm{main}}; padding rule \mathsf{pad}(\cdot)
Output: the allowlist root \mathsf{root}

  1. \mathcal K\leftarrow\emptyset
  2. foreach cluster c\in\mathcal C do
  3. foreach b_p\in\mathcal B_{\mathrm{prep}},\ b_m\in\mathcal B_{\mathrm{main}} do
  4. n\leftarrow\mathsf{pad}(b_m) // a function of the bucket, not of the real count
  5. foreach \mathsf{first}\in\{\mathsf{true},\mathsf{false}\} do
  6. \sigma\leftarrow(c,\mathsf{first},b_p,b_m,n) // the shape a leaf can be asked to verify
  7. \mathcal K\leftarrow\mathcal K\cup\{\mathsf{vk}(\mathsf{CompileLeaf}(\sigma))\}
  8. foreach compose shape \gamma (arity k\le3 over the leaf and compose classes) do
  9. \mathcal K\leftarrow\mathcal K\cup\{\mathsf{vk}(\mathsf{CompileCompose}(\gamma))\}
  10. return \mathsf{MerkleRoot}(\mathcal K)

8.1 Beyond the root: shrink and wrap

The applications of §3.5 extend the tree past the root with nodes of arity one. Each verifies one child proof, checks the child’s key against the allowlist, and re-exports the child’s public values, so the statement is unchanged as the proof moves between configurations; the nodes differ only in the configuration they are proved under and in the verifier that reads their proof.

Shrink. A shrink node verifies the compressed proof under the compress schedule. One program has two variants, which differ only in how its proof is committed. The Poseidon2 variant is proved under the core configuration, KoalaBear traces and Poseidon2 commitments and transcript, and is the wrap’s input. The Blake3 variant commits the same traces, and runs its transcript, under Blake3, opened by jagged WHIR at a low rate, and is the binary stage’s input (§3.5).

Wrap. A wrap node verifies the Poseidon2 shrink. Its traces stay over KoalaBear, while its Merkle trees and transcript use Poseidon2 over the BN254 scalar field; the transcript absorbs KoalaBear elements several to one BN254 element and draws its KoalaBear challenges from BN254 outputs. A circuit over BN254 that verifies the wrap proof therefore hashes in its native field and emulates only the KoalaBear arithmetic.

The SNARK circuit. A Groth16 [Gro16] or PLONK [GWC19] circuit over BN254, written with gnark [Con24], verifies the wrap proof. Its public inputs are a hash of the guest’s key, the digest of the committed values and the allowlist root, read from the public values the wrap re-exports. The circuit checks no allowlist; it binds the wrap key itself, in one of two variants.

  • Fixed wrap key. The circuit constrains the wrap key’s preprocessed commitment and start address to constants, so a proof attests the wrap of some compressed proof under the allowlisted keys, and a new wrap key needs a new circuit and, for Groth16, a new setup. PLONK and the default Groth16 circuit take this form.
  • Wrap key as input. A Groth16 circuit leaves those two values free, and its public key hash becomes a Poseidon2 hash over BN254 of the guest key’s hash together with them, so the verifier names the wrap key it accepts and one setup serves every wrap key. In this variant the guest digests its committed values with Blake3 instead of SHA-256.

In both, an on-chain verifier checks the proof with a constant number of pairings.

9 Security

This section collects the security argument. It states the relation the block proof is an argument for (§9.1), the concrete soundness of each proof (§9.2), how those levels compose into a statement about the non-interactive block proof (§9.3), how the verifying keys tie that proof to the advertised machine (§9.4), the one assumption that is not about hashing (§9.5), what makes the satisfying trace unique (§9.6), why it is the MIPS32 execution, with the determinism of every extracted chip machine-checked in Lean 4 (§9.7), and what changes against quantum adversaries (§9.8). Every hypothesis the end-to-end statement carries is named in this section, and the ones that remain open are listed together in §9.1.

9.1 The proved relation

The shard argument proves one shard; the statement of Section 4.4 is about an execution. Between the two sits the arithmetised relation the recursion tree is knowledge sound for, displayed, as Ceno displays its own [LZZ+24], with each part assigned to the component that discharges it:

\mathcal{R}_{\mathrm{arith}}=\left\{(\mathsf{vk},h)\ :\ \begin{aligned}&\exists\,(\mathsf T_i,\mathsf{pv}_i)_{i<N}\ \forall i:\ \mathsf T_i\text{ is a valid shard for }\mathsf{pv}_i\text{ and }\mathsf{vk},\ h_i=h && \text{(shard argument)}\\ &\wedge\ \forall i<N-1:\ \mathsf{sh}_{i+1}=\mathsf{sh}_i+1,\ \mathsf{exit}_i=\mathsf{entry}_{i+1},\ \mathsf{cur}_{\mathrm{out},i}=\mathsf{cur}_{\mathrm{in},i+1} && \text{(compose nodes)}\\ &\wedge\ \mathsf{entry}_0=\mathsf{start}(\mathsf{vk}),\ \mathsf{cur}_{\mathrm{in},0}=0 && \text{(first-shard leaf)}\\ &\wedge\ \mathsf{sh}_0=1,\ \mathsf{pc}(\mathsf{exit}_{N-1})=0,\ \textstyle\sum_i D_i=\mathcal O,\ \forall i:\ \mathsf{code}_i=0 && \text{(root)}\end{aligned}\right\}

Validity is Definition 2.6; \mathsf{sh}_i, h_i and \mathsf{code}_i are fields of \mathsf{pv}_i; the halt row sets the exit program counter to zero; \mathsf{start}(\mathsf{vk}) is the start state the key fixes; the entry and exit states are program-counter pairs; \mathcal O is the identity of the digest’s curve group; the cursors tile the address space; D_i is the shard’s cross-shard digest net of the offset D_{\mathrm{off}} of §5.5. Theorem 9.2 (§9.3) is knowledge soundness for \mathcal R_{\mathrm{arith}}, and Theorem 9.6 (§9.6) with the conformance evidence of §9.7 is what connects \mathcal R_{\mathrm{arith}} to \mathcal R, through Lemma 9.5, which joins the shards’ memory into one execution.

What is proved, in one place. Theorem 9.2 bounds a cheating prover for the whole tree by the number of random-oracle queries times the sum of the per-node errors, plus the hash and digest terms, under a per-node round-by-round premise, a hypothesis about composed extractors and the hypothesis that the leaf and compose programs enforce the compose relation. Theorem 9.6 shows that two valid shards for the same program image and public values, which also agree on the initial values of the words they touch and on the values the chips leave to the prover by design, agree up to permutation on the rows reachable from the entry state, given chip determinism (§9.7) and real-row exhaustiveness; identifying that trace with an execution needs the conformance evidence of the same section. Neither statement depends on a particular chip set, field or proximity test. §9.3 places Theorem 9.2 as the last of three layers, after the functional IOP and the interactive commit-and-open argument, and states which hypothesis each layer carries.

Open hypotheses. The end-to-end statement holds under five hypotheses that this paper does not discharge:

  1. round-by-round knowledge soundness of every node’s committed protocol, which carries function binding of the jagged WHIR commitment with an unquantified loss (§9.3);
  2. that each node’s extractor succeeds on the transcripts its parent’s extractor produces (§9.3);
  3. that the leaf and compose programs, which are not extracted, enforce the compose relation, the key binding included (§9.4);
  4. Assumption 9.4, to which we assign no value (§9.5);
  5. determinism of the two SHA-256 control chips and real-row exhaustiveness, the open premises of Theorem 9.6 (§9.6).

Conformance evidence (§9.7), not a proof, identifies the arithmetised machine with the MIPS32 instruction set.

9.2 Soundness accounting

How the level is computed. We compute soundness with soundcalc [Eth26a], the Ethereum Foundation’s calculator for hash-based proof systems, from a configuration that records the field, the trace dimensions and the schedule of Table 5; a census program kept with the source emits its machine figures from the machine the prover builds. The calculator evaluates the error of every transcript component of the interactive protocol: the out-of-domain samples and shift queries of each WHIR round, the batching of the committed stripes in the opening (column batching is counted in the jagged reduction), each folding round, the final polynomial, the three terms of the jagged reduction (Section 6), the zerocheck and the LogUp-GKR argument, with grinding counted inside the term it protects. Query soundness is counted in the unique-decoding regime for the core schedule and under the Johnson bound for the compress schedule; neither needs a proximity-gap conjecture. A proof’s level is -\log_2 of the sum of its component errors, a union bound rather than the smallest component, and a block’s level sums over every node of its recursion tree. The analysis follows WHIR’s [ACFY24b], adding the batching over several commitments and the jagged terms; levels computed by other calculators, such as RISC Zero’s [RIS24], are comparable only when they charge the same components.

Result. Table 6 gives the components. Each stage is above 100 bits, 100.70 for core and 101.09 for compress, and 99.86 bits for the two together; the folding rounds are the largest error group in both schedules; the core schedule does not grind them, and the compress schedule grinds them and its batching by 27 bits, which the list size of the Johnson-bound analysis requires. We call -\log_2\sum_i\varepsilon_i, summed over every node i of a block’s recursion tree, the block’s composite security; it falls by \log_2 of the node count below the per-stage level. For the measured block’s tree of about 150 proofs, all but the root under the core schedule, it is 93.51 bits. These figures bound the interactive protocol’s information-theoretic terms. Taking each node’s error \varepsilon_i in Theorem 9.2 to be its sum in Table 6, which leaves out the unquantified function-binding loss of Layer 2 (§9.3), the Fiat–Shamir compiled composite security against an adversary making Q oracle queries is 93.51-\log_2Q bits, 53.5 bits at Q=2^{40}, before the digest term of Assumption 9.4.

Table 6: Soundness of the analysed configuration by component group, in bits (-\log_2 of the error) as computed by soundcalc [Eth26a], each component floored to whole bits, with each schedule’s final query phase (85 queries and 22 bits of grinding, 106 bits, for core; 14 queries and 26 bits, 108 bits, for compress), which the calculator’s model omits, added. A group’s figure is the union over its members, and the last row the union over the stage. All figures are for the interactive protocol.

Component group core compress
Query phases 104.42 104.91
Folding rounds 100.93 101.69
Final polynomial 106.00 108.00
LogUp-GKR 106.00 116.00
Batching 107.00 103.00
Zerocheck 109.00 114.00
Reduction to the dense polynomial 116.00 116.00
Out-of-domain samples 213.00 200.00
Union over the stage 100.70 101.09

9.3 Security in three layers

The figures above bound an interactive protocol, the proof that ships is its Fiat–Shamir compilation, and between the two sits the commitment. We separate the argument into the three layers of the commit-and-open paradigm in its functional form [CGKY26]: an information-theoretic protocol whose verifier reads the prover’s messages only through evaluation queries; the interactive argument obtained by committing to those messages; and the non-interactive argument obtained by Fiat–Shamir. Each layer has its own security statement, and the statements compose in that order.

Layer 1: a functional interactive oracle proof. Let \Sigma be an alphabet and \ell\in\mathbb N. A query class is a set \mathcal Q of functions \alpha:\Sigma^\ell\to D; a constraint is a pair (\alpha,\beta)\in\mathcal Q\times D, satisfied by \Pi when \alpha(\Pi)=\beta.

Definition 9.1 (Functional IOP [CGKY26]). A k-round public-coin functional interactive oracle proof (FIOP) with query class \mathcal Q is an interactive oracle proof in which, in round i, the prover sends a string \Pi_i\in\Sigma^{\ell_i} and the verifier replies with fresh randomness \rho_i, and in which the verifier accesses each \Pi_i only through constraints (\alpha,\alpha(\Pi_i)) with \alpha\in\mathcal Q. Knowledge soundness with error \varepsilon_{\mathrm{FIOP}} means that an extractor, given one accepting transcript (\Pi_1,\rho_1,\ldots,\Pi_k,\rho_k), outputs a witness except with probability \varepsilon_{\mathrm{FIOP}}.

The shard protocol of Section 3 is an FIOP for the evaluation query class \mathcal Q_{\mathrm{ev}} over \Sigma=\mathbb F: a committed table \Pi\in\mathbb F^{2^n} is read only through \alpha_{\boldsymbol z}(\Pi)=\widetilde\Pi(\boldsymbol z)\in\mathbb F_{p^4} for points \boldsymbol z\in\mathbb F_{p^4}^n, the claims (\boldsymbol z,v) of Section 2. Its rounds are the committed traces, the LogUp-GKR layers, the zerocheck, the batching of column claims and the jagged reduction; a message the verifier reads in full, such as a sumcheck round polynomial, is a short string queried at every position. In Table 6, the rows for LogUp-GKR, the zerocheck and the reduction to the dense polynomial bound \varepsilon_{\mathrm{FIOP}}, and the rows for query phases, folding rounds, the final polynomial and the out-of-domain samples belong to the opening of Layer 2; batching sits at the boundary, since it combines claims just before they are opened.

Layer 2: the interactive commit-and-open argument. The Funky compiler [CGKY26] replaces each oracle \Pi_i by a commitment under a functional commitment scheme for the same query class and, after the last round, opens every queried constraint. For Ziren the functional commitment is the jagged commitment of Section 6 opened through WHIR: the jagged reduction turns the shard’s column claims into one evaluation claim on the dense polynomial, and the batched WHIR proof opens it. Its security requirement is function binding: no efficient prover opens one commitment to constraints that no single string satisfies. Knowledge soundness of the interactive argument then reduces to the knowledge soundness of the FIOP, with error \varepsilon_{\mathrm{FIOP}}, and to function binding of the commitment [CGKY26].

What Layer 2 assumes. For the jagged WHIR commitment, function binding rests on the collision resistance of \mathsf H and on the soundness of WHIR. We have not proved it in that form, and we do not quantify the loss of the reduction; function binding is a hypothesis of this layer, and Theorem 9.2 carries it inside its per-node round-by-round premise, which is stated for the committed protocol. No figure of Table 6 depends on it: those bound the information-theoretic terms.

Layer 3: Fiat–Shamir in the random-oracle model. The deployed proof is non-interactive. In the random-oracle model a Merkle commitment admits straightline extraction, which reads the committed strings from the adversary’s oracle queries without rewinding [CY24], so the random-oracle bound carries no rewinding loss. The Fiat–Shamir security of arguments built from functional commitments is studied by Chiesa et al. [CGKY26]; for Ziren we state the compiled level through the per-round premise of the following theorem.

Theorem 9.2 (Conditional composition). Work in the random-oracle model, and let an adversary make at most Q oracle queries. Let every proof in the tree, including each shard, leaf and compose proof, be the Fiat–Shamir compilation [BSCS16] of an interactive protocol that is round-by-round knowledge sound with error \varepsilon_i=\sum_c\varepsilon_{i,c}. Let a block proof contain n_\pi such proofs, each verified once by its parent, with the root checked by the external verifier, every leaf and compose key, the root’s included, an entry of the allowlist, and every shard proof verified against the guest key \mathsf{vk} (§9.4). Assume further that each node extractor succeeds on transcripts produced by its parent extractor, not only on transcripts drawn from an honest interaction, and that the leaf and compose programs enforce the compose relation of Section 8, which no theorem of §9.7 covers. Then the block proof is an argument of knowledge for \mathcal R_{\mathrm{arith}} with knowledge error at most

Q\sum_{i=1}^{n_\pi}\varepsilon_i+\varepsilon_{\mathrm{hash}}+\varepsilon_{\mathrm{digest}},

where \varepsilon_{\mathrm{digest}} is the error of Assumption 9.4 and \varepsilon_{\mathrm{hash}}=O(Q^2/2^d) is the probability of a collision in the d-bit output of \mathsf H, which builds the transcript and the Merkle trees, with d=248 in the measured instantiation, the term SWIRL states explicitly for its own compilation [Ope26c, Cor. 4.2.6].

Proof sketch. Compiling a round-by-round knowledge sound protocol with Fiat–Shamir costs a factor in the number of oracle queries: an adversary may re-query the oracle on modified prefixes, and the standard analysis charges Q attempts against the per-round error [BSCS16, CY24]. Within the tree, the extractor of the compiled argument runs the extractor of each verified proof in turn: a compose node’s extractor yields its children’s transcripts, and so on down to the shard proofs, whose extractor yields the witness rows. The allowlist hypothesis makes each step an extraction from the intended verifier; without it a node could verify a program other than the compose or leaf program. The hypothesis about parent-produced transcripts is not discharged here: a child’s extractor is invoked on a transcript the parent’s extractor constructed, which is not the distribution its guarantee is stated against. Given it, the failure events combine by the union bound. ∎

Across the recursion tree. Theorem 9.2 assumes that each node’s extractor succeeds on the transcripts its parent’s extractor produces. A child’s extractor runs on a transcript that the parent’s extractor chose, and a compose node checks its children inside its own circuit rather than as further rounds of one protocol. Discharging that hypothesis is the step that would turn Theorem 9.2 into an unconditional statement; we leave it open.

9.4 Verifying-key binding

The statement of Section 4.4 concerns the advertised machine only if every leaf verified a core proof of that machine, every compose node ran the compose program, and the external verifier checked the root under a key of that machine. Three checks give this. A compose node checks that its children’s recursion keys belong to a Merkle allowlist (Algorithm 2, line 2); inside the tree that root is a prover-supplied witness, so it is exported as a public value of the root proof. A leaf verifies each shard proof against the guest key \mathsf{vk} its public values carry, and every node carries that \mathsf{vk} upward unchanged. The external verifier then checks the root proof under the recursion key the proof names, requires that key to be in the published allowlist and the exported root to equal the published root, requires the completion flag \mathsf{complete} that only the root sets (§8), and compares the exported \mathsf{vk} with the key of the guest program it expects. Every node’s key, the root’s included, is thus an allowlist entry or the expected guest key.

The recursion machine is outside the extraction of §9.7, so Theorem 9.2 takes as a hypothesis that the leaf and compose programs enforce the compose relation, this binding included. A prover configured to skip the in-circuit check produces a different compose key, which the allowlist does not contain, and is rejected. The allowlist is enumerated for leaf as well as compose programs (§8). The shard-to-leaf step is uniform per shard shape but not across shapes, and the allowlist lets one compose program accept the non-uniform set of leaves by committing to their keys in advance.

9.5 Security of the cross-shard digest

This subsection gives what the elliptic-curve option of §5.5 rests on: the addition row, the lift, and Assumption 9.4.

The addition row. The chord identities

C_x=(x_1+x_2+x_3)(x_2-x_1)^2-(y_2-y_1)^2,\qquad C_y=(y_1+y_3)(x_2-x_1)-(y_2-y_1)(x_1-x_3)

both carry the factor (x_2-x_1). At P_2=-P_1, C_x=-4y_1^2\ne0 whenever y_1\ne0; at P_2=P_1 both hold for every P_3, so the row witnesses (x_2-x_1)^{-1} and constrains (x_2-x_1)\cdot(x_2-x_1)^{-1}=1, which excludes both cases for points on the curve. The sum starts at a fixed public offset point D_{\mathrm{off}} with \pm D_{\mathrm{off}} outside the image of the map, so a running sum coinciding with the next interaction’s point is unprovable rather than unconstrained, and Assumption 9.4 bounds the probability of such a coincidence by \varepsilon_{\mathrm{digest}}.

The lift. SP1 derives the x-coordinate from a Poseidon2 permutation constrained inside the chip, with an 8-bit tweak hashed in and the sign of y fixed by range checks, so its points are random-oracle outputs; its tweak is uncanonicalised as ours is, which under that model is harmless [RR24, Suc26a]. Here the message is the x-coordinate, which changes the security argument: the lift is a map on pairs, \mathrm{enc}(\boldsymbol m,\mathsf{offset}). The chip constrains the offset only to be a byte in the low positions of x_6; the honest prover takes the smallest admissible one, but minimality is not an AIR constraint. Write \mathcal P for the reachable pairs (\boldsymbol m,\mathsf{offset}) an interaction of a satisfying trace can carry, given the sending chips’ range facts and the byte bound on the offset. \mathcal P is far smaller than \mathbb F^7\times[0,256), since every limb of a memory or syscall tuple is a byte, a bounded clock limb or a bounded address. A send and a receive cancel only if they agree on the offset, so the free offset costs completeness, not soundness; but an adversary seeking a vanishing combination searches over \mathcal P.

Lemma 9.3 (Injectivity of the lift). Assume the message limbs satisfy the range facts the sending chips enforce, so that 256\,m_6+\mathsf{offset}<p. Then \mathrm{enc} is injective: limbs x_0,\ldots,x_5 are m_0,\ldots,m_5; x_6 is m_6 shifted above a low byte holding the offset, which the bound makes separable; and the two sign bands are disjoint. So \boldsymbol m and the offset are recoverable from the point.

If a claimed execution has send and receive multisets S\ne R over \mathcal P with equal digests, then

\textstyle\sum_i c_i\,\mathrm{enc}(\boldsymbol m_i,\mathsf{offset}_i)=\mathcal O,\qquad c=\mathrm{mult}_S-\mathrm{mult}_R\ne0;

and by Lemma 9.3, equal encoded multisets give equal message multisets. Soundness is therefore exactly:

Assumption 9.4 (No reachable vanishing combination). Let \lambda be the security parameter, let N_{\mathrm{int}} bound the interactions a block proof may contain and B the per-interaction multiplicity bound, and let \mathcal P be the reachable pairs above. For every adversary \mathcal A running in time at most T(\lambda) and making at most q(\lambda) queries to the hash functions of the protocol,

\Pr\big[\,\mathcal E(\mathcal A)\,\big]\ \le\ \varepsilon_{\mathrm{digest}}(\lambda,T,q,N_{\mathrm{int}},B),

where \mathcal E(\mathcal A) is the event that \mathcal A outputs reachable pairs \{(\boldsymbol m_i,\mathsf{offset}_i)\}_{i\le N_{\mathrm{int}}}\subseteq\mathcal P together with a non-zero integer vector c\in\mathbb Z^{N_{\mathrm{int}}} satisfying \|c\|_\infty\le B and \sum_i c_i\,\mathrm{enc}(\boldsymbol m_i,\mathsf{offset}_i)=\mathcal O in E(\mathbb F_{p^7}).

Theorem 9.2 carries \varepsilon_{\mathrm{digest}} as an additive term of its bound; we claim no value for it, and §9.2 reports the levels before this term. With hashing, as in SP1, the points would be random-oracle outputs and a discrete-logarithm reduction would apply. Here the prover chooses points from a structured set, reading a message off a target x-coordinate by inverting the limb layout, and the offset widens the set by a factor of at most 256. The sparsity of \mathcal P blocks the obvious attack of reading messages off the x-coordinates of scalars that sum to zero, since almost no x has a reachable limb shape; this depends on every sending chip bounding every limb, an obligation not yet collected in one certificate. Sparsity gives no bit estimate: the generalised-birthday cost falls with the number of lists and must be bounded by the interactions a trace can hold, not only by |E(\mathbb F_{p^7})|\approx2^{217}.

That analysis is open, as is a parameter analysis of the curve: SP1’s memo cites a best known discrete-logarithm attack of about 2^{137} for its curve, which depends only on the base field and extension degree and so transfers [RR24], but this curve’s group order, twist, embedding degree and discriminant are not analysed here. OpenVM avoids the question by carrying memory across segments as Merkle roots over touched addresses, checked for adjacency during aggregation, which rests on collision resistance at the price of in-circuit Merkle paths [Ope26b]. The digest is also the one component of the argument that is not post-quantum; §9.8 gives three replacements, two hash-based and measured and one lattice-based and costed, and states, as a conditional threat model rather than a theorem, when fast proving limits a quantum attack on it (Remark 9.7).

9.6 Trace uniqueness

Uniqueness is argued shard by shard; what joins the shards is the memory carried across their boundaries.

Lemma 9.5 (Cross-shard memory). Let (\mathsf T_i,\mathsf{pv}_i)_{i<N} satisfy \mathcal R_{\mathrm{arith}} with at most N_{\mathrm{int}} interactions in all, and suppose no reachable vanishing combination of Assumption 9.4 occurs. Then every shard has at most one boundary row per word, and for every word the initial tuple that a shard’s boundary row receives is the final tuple of the latest earlier shard that touched the word, or the word’s initial-memory tuple if none did. The per-shard chains of Lemma 5.4 therefore join into one chain per word, ordered by (\mathsf{shard},\mathsf{clk}).

Proof sketch. Three facts fix the timestamps. Every access carries the timestamp (\mathsf{shard},\mathsf{clk}) of the instruction that makes it, a precompile’s accesses that of the instruction invoking it; the public-values table sends the entry state with the shard’s execution index, the state bus carries that index unchanged through the shard, and compose nodes chain these indices as they chain \mathsf{sh}, so timestamps of different instructions are distinct and ordered as the execution is. The initial-memory and finalisation tables prove their addresses strictly increasing, and their cursors start at zero and tile, so each address has at most one initial-memory row and one finalisation row in the execution; an initial-memory tuple has timestamp (0,0). Every boundary row receives a word’s initial tuple and sends its final tuple through the cross-shard digest (§5.5). By Lemma 9.3 and the hypothesis, \sum_iD_i=\mathcal O makes the sent and received multisets of tuples equal. Now induct, for one word, over the shards that touch it in the order of their timestamps. The k-th such shard receives tuples whose timestamps precede its own accesses, and the only sent tuples with such timestamps that no earlier shard has consumed are the initial-memory tuple, when k=1, and otherwise the final tuple of the (k-1)-th shard; each tuple is consumed once, so the shard has exactly one boundary row for the word, and that row receives this tuple. This is offline memory checking [BEG+94] across shards. ∎

Theorem 9.6 (From chip determinism to trace uniqueness). Fix a program image, public values and a valid shard with at most one boundary row per word. If every chip of the shard is deterministic in the sense of Definition 2.7, then the rows reachable from the entry state along the state and memory buses are determined by the program image, the public values, the initial values of the words the shard touches (the hint words of the memory-initialisation table and, in a shard after the first, the initial tuples of its boundary rows), and the declared free values, the values a chip’s constraints leave to the prover by design, which Definition 2.7 counts as inputs (Table 7): any two valid shards that agree on these agree on those rows up to permutation.

Proof. By Lemma 5.2 the instruction rows of either shard form one chain from the entry state; write r_1,\ldots,r_N for the chain of the first of the two shards compared, and let a step i be r_i together with the precompile rows it invokes, which access memory at r_i’s clock. We show by induction on i that the rows of step i have the same inputs and outputs in both shards. The inputs of r_i are its received state tuple s_{i-1}, its fetched instruction, and the previous values of the addresses it accesses. s_0 is public and s_{i-1} is the output of r_{i-1} by induction. The fetched instruction is a function of \mathsf{pc}(s_{i-1}) because the program bus is received only by the preprocessed program table, which is committed. The previous value of an address is, by Lemma 5.4, the value written by the last earlier access to that address, or the word’s initial value, which is fixed: an image word is bound to the program image and the public address cursors, and a hint word or boundary tuple is one of the initial values the statement fixes. Earlier accesses belong to steps j<i, whose outputs agree by induction. So the inputs of r_i agree, and determinism of its chip gives that its outputs agree; a precompile row of the step then receives its arguments from r_i’s syscall tuple and its previous values from earlier accesses, so the same argument applies to it, in the order of its accesses.

Rows of non-instruction chips (the memory-initialisation and finalisation tables, the shadow reads, the digest rows, the tables) are determined in the same way from the bus tuples they receive, which are outputs of instruction rows or public. Rows that participate in no bus reachable from the entry state are not covered by this argument; the arithmetisation admits none, because every real row carries a frame or a memory access, but that is a property of the chip set rather than of the buses, and we do not prove it here.

None of the declared free values makes the execution ambiguous. The address and value of a memory-initialisation row are the initial value of a touched word, already in the list; the length of a hint read is part of the untrusted hint, as the hint words are; and the lift offset of a digest row changes only the curve point that row adds to the digest, which no instruction row reads. ∎

For a fixed sequence of shard public values, applied to the shards in index order, the theorem extends to the whole execution: by Lemma 9.5 the initial tuples of a shard’s boundary rows are final tuples of earlier shards, which the induction over shards has already fixed.

The theorem is stated, not machine-checked; chip determinism, its main premise, is machine-checked for every extracted chip (§9.7.2), and the premises still open are item 5 of §9.1.

9.7 From constraints to MIPS32: conformance and determinism

The preceding subsections show, under the hypotheses of Theorem 9.2, that an accepting proof implies a trace satisfying every constraint, and Theorem 9.6 makes that trace unique given chip determinism. This subsection argues that such a trace is the MIPS32 execution, in two parts that no soundness theorem can supply: the second is proved, the first evidenced. The constraints must compute the instruction set’s function: a chip that computes the wrong one is sound for the wrong machine (§9.7.1). And they must admit only that function: a chip with two outputs for one input lets a cheating prover choose, which honest traces never expose (§9.7.2). Conformance suites carried through proving and an independent executable model provide the evidence; the proof is in Lean 4, chip by chip.

What has to be right, and for which property. Soundness rests only on the verifier and what it reads: every chip’s constraint description, the preprocessed tables and program commitment in the verifying key, the recursion programs, and the allowlist root. The executor, the just-in-time compiler, trace generation and the GPU kernels bear only on completeness: an error there yields a proof that fails to verify, not one that verifies falsely. For the chips, the determinism theorems show at most one behaviour per input, where an omission would be silent, and the conformance vectors are the evidence that this behaviour is the ISA’s. They cover the core chips; the recursion programs are a hypothesis of Theorem 9.2.

9.7.1 ISA conformance

Vectors from the specification. The encoding tables of the MIPS32 manual were transcribed into a machine-readable table of 77 instructions, reproduced with the chip proving each in Appendix B. For each, a generator emits ten programs with pseudo-random operands, boundary values and the delay-slot placements the instruction admits, assembled with llvm-mc. The reference is the Unicorn/QEMU MIPS32 emulator [QV15], which shares no code with Ziren’s; each vector compares the general registers, HI/LO and touched memory. All 770 vectors agree, on both the interpreter and the JIT.

Shared instruction suites. Fifteen hand-written suites, 144 cases, cover instructions with difficult semantics: signed and unsigned division, multiply-accumulate, bit-field and byte-order instructions, rotates, and leading-one and leading-zero counts. One crate supplies case data to both emulator and prover tests, as it does for the generated vectors, so a regression in either appears as a disagreement.

The Cannon suite. Optimism’s Cannon ships hand-written MIPS test programs [Opt23] from the fault-proof project whose semantics a hybrid fault and validity proof must match, exercising the machine against another team’s reading of the manual. A harness byte-swaps them to little-endian and adapts the halt convention; all 49 programs applicable to a little-endian guest pass.

From vectors to proofs. 224 of the generated programs and 48 of the 49 Cannon programs were also proved and verified end to end. The exception halts with a non-zero exit code, which the emulator accepts and the arithmetisation does not admit. Elsewhere the arithmetisation accepts every behaviour the reference exhibits. The next subsection gives part of the converse: the arithmetisation admits at most one behaviour per input; that this behaviour is the ISA’s rests on the vectors above.

Executable formal model. A Lean 4 model of the ISA was written independently of Ziren’s emulator: a decoder transcribed from the encoding tables, an interpreter with the delay-slot program-counter pair and little-endian byte memory, and an ALU. Two checks, both by native_decide, connect it to the implementation: its decoder agrees with the emulator’s on all 2 275 distinct instruction words in the vectors, and it reproduces the reference results on all 770 vectors. Digests of the emitted event records also agree between repeated runs and between interpreter and JIT, which is evidence of reproducibility rather than a proof of determinism.

9.7.2 Determinism of the chips

What is proved. For a chip U with constraint system C_U over a row w, inputs I_U(w) (the fetched instruction, the register and memory values read, the incoming state) and outputs O_U(w) (the values written, the outgoing state), determinism is

\forall w,w'.\ C_U(w)\wedge C_U(w')\wedge I_U(w)=I_U(w')\ \Rightarrow\ O_U(w)=O_U(w'),

which is Definition 2.7 with byte-table lookups lowered to range constraints or to an abstract table relation T. A theorem that uses such a relation takes \forall i,o,o'.\ T(i,o)\wedge T(i,o')\Rightarrow o=o' as a hypothesis; 32 of the 104 do, for the AND, XOR, OR, NOR and shift-carry operations of the Byte table, which is a function because the verifying key fixes it. Each theorem also takes the equality of a list of values assumed deterministic, which is empty for every chip. The inputs I_U include, besides bus receives, the declared free values of Definition 2.7: the prover choices that Table 7 records as inputs of the statements, which Theorem 9.6 accounts for. These theorems are the premises of Theorem 9.6.

Extraction. The Rust constraint description that the prover evaluates and the verifier checks is evaluated once with symbolic columns; the resulting constraints, range facts and bus interactions are lowered to a first-order statement, and a generator emits one Lean 4 file per chip with a row record, the constraints, the input and output projections, and the theorem. Selector-specialised chips get one theorem per opcode selector, all restricted to real rows. The extraction covers every core chip of Appendix A except the three preprocessed tables, which carry no statement, and the two SHA-256 control chips, which it currently models as opaque helpers: 104 theorems over 57 chips. Nothing in the pipeline is specific to a chip: modelling those two, or the recursion machine’s chips, which are written against the same interface, extends it without a new technique.

Proof automation. As in Picus [PCW+23], a propagation analysis over the extracted constraints derives every output column of w' from the inputs as a sequence of steps: linear and inverse solving, bit and one-hot decoding, integer bounds, carry roots, and gadget summaries for recurring sub-circuits (a field operation with its carry rows, a byte comparison, a leading-one detector, a canonical word), with case splits on selector bits both witnesses share. The generator replays the derivation in Lean 4. Each step becomes a lemma stated over only the columns and conjuncts it uses, closed by a small tactic that lifts its statement from \mathbb F to the integers with each column’s range and decides it with omega, linear_combination or grind. Not everything is generated: the gadget library is written by hand, the accelerator, division and Global gadget proofs come from per-family generator scripts, and the selector-flag postconditions of ten chips are proved by hand where the automation runs out of budget.

Large chips. The gadget summaries are library theorems proved once; an accelerator whose outputs come from chained field operations or permutation rounds gets a generated proof that its output columns agree (gadget_det), split into a chain of segment lemmas of a few hundred steps, each taking the facts live at its start and ending by applying the next. The chip’s theorem never splits w and w' into their thousands of columns: it applies the step lemmas to projections of the two constraint sets, each step lemma restating its conjuncts in their original form and substituting what earlier steps proved inside its own small context. A theorem elaborated as one declaration in the full context of a precompile chip took hours; in this form every module of the check takes minutes.

What the statements exposed. A determinism statement fails exactly when a row admits two witnesses with the same inputs and different outputs, so every statement the automation could not close was read for the witness that breaks it. Table 7 lists what that reading found. Three are soundness gaps in the constraints, two exploitable and one (Global) latent while every sender sets a flag, each closed by new constraints; the others are prover freedom the protocol allows by design, which the statements now name as inputs rather than hide.

Coverage. All 104 theorems are closed: 23 for the integer ALU chips, 8 for the shifts, 9 for control flow, 14 for the memory instructions, 5 for the memory argument, 15 for the miscellaneous and syscall chips, and 30 for the accelerators, one per chip or per opcode-selector specialisation of it. For each, #print axioms lists only propext, Classical.choice and Quot.sound, so no proof rests on sorry or an added axiom, and every one of the 7 414 modules of the 62 chip files (57 with statements) builds without a sorry. The check splits each chip file into modules by dependency and builds them in parallel on the evaluation host of §10.1 (a virtual machine with 124 vCPUs and 925 GB of memory); with a 30-minute cap per module, the longest takes 22 minutes. The count is for the analysed constraint system. The checked chip files, gadget snippets and check scripts are archived2 with a per-chip table of theorems, modules and module times; the archived generators regenerate them byte for byte.

Table 7: What the determinism statements exposed. Each row is a chip whose statement, as first extracted, did not hold; the last column is how the constraints or the statement were changed. The three new constraint sets change the verifying key.

Chip What the statement exposed Consequence Resolution
*DoubleAssign (secp256k1, secp256r1, BN254, BLS12-381) The slope gadget proves s\cdot2y=3x^2+a and nothing about 2y. For an input with y\equiv0, such as (0,0) on a curve with a=0, every slope satisfies the chip, and the row writes (s^2,-s^3). Soundness gap: the written point is the prover’s choice. An AIR-level test forges it for three slopes. An inverse check proves \mathsf{is\_real}/2y exists, and the executor refuses y\equiv0.
Global (flags) \mathsf{is\_send} and \mathsf{is\_receive} choose the sign of the lifted point’s y and were neither boolean nor tied to \mathsf{is\_real}: with both zero, (x,y) and (x,-y) both satisfy the row and give different digests. Soundness rests on the senders: every current sender sets exactly one flag, so a (0,0) row cannot balance the bus today. SP1 v6 constrains the flags the same way. Both flags boolean and \mathsf{is\_send}+\mathsf{is\_receive}=\mathsf{is\_real}.
KeccakSpongeControl Of a multi-block sponge, only the first block’s input and output addresses were bound to the syscall; later blocks’ addresses were free, and nothing tied the number of blocks to the input length. Soundness gap: a prover can absorb later blocks from any address, stop early or late, and write the digest anywhere. Each block carries the input address, output address and length on the block bus; the first block is block 0 and binds the length read from memory, its top byte range-checked; the final block has (b+1)\cdot36=\mathit{len} (36 words, the chip’s 1152-bit rate).
Global The lift_x offset is a byte the prover picks among those that lift the message to a curve point. None: the encoding stays injective because the top message field is below 2^{16}; SP1 is the same. The offset is an input of the statement.
SyscallInstrs The length of a hint read is chosen by the host. None: hints are untrusted input by definition. The hint length is an input of the statement.
MemoryGlobalInit The address and value of an initial-memory row are the prover’s choice. None: the global memory argument fixes them against the image and the first access. Address and value are inputs of the statement.

9.7.3 A negative control for the height claims

The verifying key depends on the chip set (§8) and the committed geometry is quantised from declared heights (§6.6), so the argument must reject a shard whose declared shape is false. A harness proves real shard proofs for an arithmetic and a hash-heavy guest and tampers with them in eighteen ways: over- and under-claimed heights, false chip activity, and tampered column and row counts, each injected into the degree mask, the Fiat–Shamir prologue, or both. Every case is rejected: height and activity lies in the degree mask by the LogUp-GKR last-layer reconstruction, lies confined to the transcript by the grinding witness (the prologue observes the declared heights), a tampered column count by the jagged verifier, and a tampered row count by the preprocessed round, which reads it from the verifying key.

9.8 Post-quantum security

Every component of the shard and recursion arguments except the elliptic-curve multiset hash is hash-based: the Merkle commitments under \mathsf H, the WHIR (or BaseFold) proximity test, the sumchecks and LogUp-GKR. The Fiat–Shamir compilation of such interactive oracle proofs remains sound against quantum adversaries in the quantum random-oracle model [CMS19], with weaker concrete bounds: a quantum collision search on the 248-bit digest of the measured instantiation costs about 2^{83} rather than 2^{124} evaluations [BHT98], so the levels of §9.2 are classical. The digest is the exception. Shor’s algorithm computes discrete logarithms in E(\mathbb F_{p^7}) [Sho97], which reduces Assumption 9.4 to finding a short integer relation among known scalars, and at the interaction counts of a block such a relation should be assumed easy to find. Against a quantum adversary the options of §5.5 therefore differ: the global challenge and Merkle roots rest on hashes, and a lattice multiset hash on a problem not known to be easy for quantum adversaries, while the elliptic-curve multiset hash does not survive. Table 3 gives their costs; this paper claims post-quantum security for no configuration.

Of the two hash-based options, Merkle roots perform best: on one GPU, where the card is the bottleneck, their smaller committed area makes them faster; on four GPUs their proving work is smaller but arrives in execution order, and the cards idle while the last leaves and compositions of a block drain, a tail the elliptic-curve multiset hash fills with its independent precompile and memory shards.

Remark 9.7 (Real-time quantum adversaries). Proving a block in time close to linear in its trace does not by itself protect the elliptic-curve digest. The lift applies no salt: a point is a fixed function of its message, so a quantum adversary can compute a vanishing combination once, offline, and reuse it in a false proof for any later block, and the speed of honest proving does not bound that attack. A time-bounded claim holds under two further conditions, neither of which the configuration of this paper meets. (i) Salting: the lift mixes a per-block value \sigma that is unknown before the block is fixed, such as the block hash or a challenge drawn after the shards’ trace commitments, constrained in the chip and checked by the verifier, so that a relation among one block’s points is useless for another. (ii) Timeliness: a proof for block b has value only if it is delivered within a window \omega after b appears, as in real-time proving where a late proof is not consumed. Under (i) and (ii) an adversary must find its relation for block b’s salted points within \omega, while the honest proof, and its verification, completes in about the honest proving time; if solving the discrete logarithms such a relation needs takes longer than \omega, the forgery arrives after the proof has lost its value, and fast proving lets \omega shrink toward the honest proving time, 10 to 31 s per block on four GPUs for the twelve blocks of Table 3. This is a threat-model argument, not a theorem. It needs (i), which changes the digest and the verifying key; a lower bound on quantum discrete-logarithm time, which we do not have; and a deployment rule that enforces \omega. It gives no protection after \omega, and none for proofs that keep their value later, such as archived or bridged proofs.

10 Evaluation

We evaluate three quantities: instruction efficiency, the committed area and bus interactions an executed instruction costs, which is a property of the arithmetisation (§10.2); proving efficiency, the rate at which an implementation turns that area into a proof on named hardware (§10.3); and proof size, the bytes of the compressed proof a verifier reads, with the parameters that control it (§10.4). One primary workload, one GPU model and one host are used, with interleaved repetitions, so that differences between configurations are attributable. No cross-system comparison is attempted: other systems’ figures are self-reported on different guests and mostly on clusters, and nothing here is a same-hardware baseline. The evaluation is controlled: fixed blocks are measured so that configurations are compared on identical input.

10.1 Experimental setup

Workload. Ethereum mainnet block 25 907 955, executed by a MIPS32 build of the reth execution client with an arena-represented witness trie; the guest hashes trie nodes, recomputes a Merkle root over state it does not hold and verifies signatures. A word-wise memcmp, a zero-copy Keccak wrapper and the arena trie reduce it from 379 to 288 million cycles. The single-GPU timing of Memory traffic and shard size (§10.3) uses that cached record; the multi-GPU measurements of §10.3 add blocks of 420, 530 and 912 M cycles, and the instruction-efficiency census of §10.2 uses block 25 955 640 (495.6 M cycles) in the analysed configuration.

Hardware. One NVIDIA RTX 5090 (32 GB) in a virtual machine with eight such GPUs, 124 vCPUs of AMD EPYC 9355 and 925 GB of memory; the multi-GPU runs use four (driver 570.153.02, CUDA 12.8, Ubuntu 22.04). The GPU backend is a separate CUDA implementation of the same protocol and is not open source.

Configurations. Sections 5–9 describe the analysed configuration. The timings below, and the proof-size comparison of §10.3, were taken on an earlier measured configuration, which differs in four respects: the Poseidon2 permutation used 13 partial rounds rather than the corrected 20; the lookup challenge was not ground; the syscall bus carried the sum of two 16-bit half-words rather than the half-words themselves (§5.1); and the set of three soundness fixes of Table 7 was not applied, each of which adds constraints. The comparisons below are therefore internal to the measured configuration, and the soundness figures of §9.2 are for the analysed one. Unless a caption says otherwise, every timing below is of the measured configuration and every area of the analysed one.

Metrics and protocol. Trace area is the sum over chips of rows × columns from the emulator’s shard-close census; Table 9 takes its kernel shares from the measured configuration. Wall-clock time runs from reading the cached input to writing the compressed proof and includes 2–3 s of host verification of the proof; proving throughput is guest cycles divided by it, and is not a clock frequency. Proof size is the serialised compressed proof. A ten-shard nsys sample attributes kernel time. Table 10 reports three consecutive warm proofs per configuration, warm meaning after a first proof has loaded the keys and compiled the programs. Medians are reported, and the spread was within ±0.8 s for Table 10. The measured GPU was otherwise idle, but an unrelated proving process ran on another GPU of the host.

10.2 Instruction efficiency

We first estimate what one executed instruction costs, from the chip widths and interaction counts of §§5.9 and 5.10, in committed cells and bus interactions (§1.3). Table 8 counts an instruction’s own row only; the memory-argument rows for each shard’s first and last access to a word, and the tables’ multiplicity columns, are paid per shard and are measured below.

Table 8: Committed cells and bus interactions per executed instruction, for the most frequent chips. The frame includes the program-counter pair; interactions count the program fetch, the state bus, the memory bus and table lookups.

Chip cells: frame cells: own cells: row interactions: frame interactions: own interactions: row
AddSubImm 29 4 33 16 0 16
AddSub 32 4 36 20 0 20
Bitwise 32 5 37 20 4 24
Lt 32 18 50 20 3 23
ShiftLeftImm 26 19 45 16 4 20
ShiftRight 32 57 89 20 25 45
Branch 29 27 56 16 ≤ 9 ≤ 25
LoadWord 29 19 48 16 9 25
StoreWord 29 23 52 16 9 25
LoadNarrow 29 30 59 16 10 26
Mul 32 42 74 20 22 42
DivRem 32 131 163 20 44 64

Per instruction. The frame is most of every common row: an addition or bitwise operation pays 29–32 cells and 16–20 interactions of frame for at most five cells and four interactions of its own, so the per-instruction floor is set by the register memory check. Expensive instructions are expensive in columns, not rows: a division is one row of 163 cells where Jolt’s sequence takes eight steps [AST24]. Per-opcode chips are what keep the common rows narrow: one table carrying every opcode’s columns would pay the widest row on every instruction, over 400 cells (MiscInstrs alone has 432 columns) where the common instructions pay 33 to 37; SP1 makes the same choice [Suc24].

Per block. Block 25 955 640, 495.6 million cycles, commits 29.2 G cells and raises 12.8 G (row, interaction) pairs, 58.9 cells and 25.8 pairs per executed instruction (Table 9, Figure 8a). This is larger than the single-row costs of Table 8 mainly because of the per-shard memory-argument rows: the Global chip holds 15% of the area, 8.8 cells per instruction, because every word a shard touches costs two rows of it, which is the cost of sharding. The figure depends on the workload, not only on the instruction set. A precompile call is one guest cycle and many rows of an accelerator chip, and since a shard closes when its committed area reaches 4.6\cdot10^8 cells, the precompile share sets both the cells per cycle and the shard count: two mainnet blocks of 949 and 943 million cycles proved in production as 702 and 213 shards. These are cells of a 31-bit field and do not convert into Jolt’s bit-weighted count.

What reducing area buys. The census says where to cut: area for the commitment and constraint argument, pairs for the bus argument. Two changes follow from it, both mechanisms rather than tuning: replacing a boolean sign decomposition in the cross-shard digest chip with three byte lookups, and dropping byte checks on memory-instruction accesses that another chip already enforces. Both change the constraint system, and with it the chip keys and the recursion-key allowlist; neither changes the statement proved.

10.3 Proving efficiency

Where the time goes. Kernels account for about 340 ms of the 500 ms of GPU time per shard, launch gaps and host synchronisation the rest (Table 9, Figure 8b). The lookup argument is the largest consumer, and its cost scales with (row, interaction) pairs rather than with columns: memory-instruction chips carry 25–26 interactions per row and 47% of all pairs, while the Global chip holds 15% of the area but 3.7% of the pairs. The cost model is therefore area for the commitment and zerocheck and pairs for the lookup, one pair weighted as about two cells.

Table 9: LogUp-GKR consumes 42% of kernel time, and LoadWord, Global and StoreWord hold about 15% of the trace area each. Kernel shares are from a ten-shard nsys sample; area is rows × columns from the executor’s census of block 25 955 640 (29.2 G cells).

Kernel group share Chip area share
LogUp-GKR layers (fold-and-sum, transitions, first layer) 42% LoadWord (92.6 M rows × 48) 15.2%
Zerocheck, compiled constraint kernels 16.5% Global (67.2 M × 65) 15.0%
Zerocheck, interpreted (wide precompile chips) 7.1% StoreWord (81.8 M × 52) 14.6%
Zerocheck fold 2.3% MemoryUnaligned (42.7 M × 59) 8.6%
WHIR commit and open (Merkle absorb, DFT) 19% Branch (36.1 M × 56) 6.9%
Jagged reduction 8% AddSubImm (59.4 M × 33) 6.7%
Other 5% ShiftLeftImm (34.8 M × 45) 5.4%
Two bar charts. Left, share of trace area by chip: LoadWord 15.2, Global 15, StoreWord 14.6, MemoryUnaligned 8.6, Branch 6.9, AddSubImm 6.7, ShiftLeftImm 5.4, AddSub 4.4, Bitwise 4.1, LoadNarrow 3.1, Other 15.9 percent. Right, share of core-proving kernel time: LogUp-GKR layers 42, WHIR commit and open 19, Zerocheck compiled 16.5, Jagged reduction 8, Zerocheck interpreted 7.1, Zerocheck fold 2.3, Other 5 percent.
Figure 8: Global and three memory-instruction chips hold 53% of the trace area of block 25 955 640, and LogUp-GKR takes 42% of kernel time. (a) Trace area by chip (29.2 G cells); Global and the three largest memory-instruction chips hold 53%. (b) LogUp-GKR is the largest kernel group at 42%, ahead of WHIR commit and open at 19% (nsys, ten-shard sample).

Memory traffic and shard size. A byte-level profile of the LogUp-GKR circuit showed that its first layer paired fractions across the most-significant index bit, so short chips were carried through every layer of the tallest and the traffic summed over layers was 5.2× that of the first. The prover therefore pairs on the least-significant bit, so each chip folds out after \log_2 of its own height, and the memory this frees admits shards of twice the size. The two changes are enabled together: the old-pairing, doubled-shard configuration does not fit in memory, so their effects are not separated. With both, the cached 288 M-cycle block 25 907 955 proves in 48.7 s on one GPU (5.9 MHz), against 67.8 s for the revision without either at the largest shard size it could run (−28%), with the compressed proof unchanged in size.

Scaling across devices. Table 10 and Figure 9 report proving throughput on one to four GPUs for blocks of 420, 530 and 912 M cycles. Throughput varies by at most 20% across blocks and scales by 1.9× to two GPUs and 3.1–3.3× to four, reaching 20–24 MHz. The gap to linear scaling is the serial recursion tail and the start-up interval before the emulator has produced a shard for every GPU.

Line chart of proved guest cycles per second of wall time (MHz) against 1, 2 and 4 RTX 5090 GPUs for 420, 530 and 912 million-cycle blocks, with a dotted linear-scaling reference for the 420 million-cycle block. Four GPUs reach about 20 to 24 MHz.
Figure 9: Throughput on one to four GPUs for three block sizes; four GPUs reach 3.1–3.3× one GPU. The dotted line is linear scaling from one GPU on the 420 M-cycle block.

Table 10: Four GPUs reach 3.1–3.3× one-GPU throughput (20–24 MHz) on all three blocks. Median warm wall-clock time of three consecutive proofs.

Block (guest cycles) wall-clock (s): 1 GPU 2 4 throughput (MHz): 1 GPU 2 4
420 M 65.9 34.3 21.0 6.4 12.2 20.0
530 M 84.3 44.7 26.5 6.3 11.9 20.0
912 M 124.3 65.0 38.0 7.3 14.0 24.0

The host. On one core of an AMD EPYC 9355, the just-in-time compiler executes block 25 955 640 (496 M cycles) at 198 MHz once compiled (166 MHz including its single compilation pass), and the interpreter at 40.6 MHz without the event record and 14.6 MHz with it; the coordinator’s whole producer job takes 6.1 s for a 420 M-cycle block, some 69 MHz. On one GPU, emulation does not bind. It binds when one host feeds several GPUs, because each shard is re-emulated by the worker that proves it, at about one second of host time per shard against half a second of GPU time, so the event record carries only what a column witnesses and the coordinator never holds the whole execution (§3.1).

Where the GPU work sits. Three kinds of engineering act on different costs. Fused kernels cut memory traffic: the jagged fold and the round polynomial it feeds are one kernel, as are the layer transition and the round over the mixed round-0 slab. A cross-stage pipeline cuts idleness: leaves and compose nodes are proved while core shards are still being proved (§3.3). Occupancy tuning caps the register budget for the measured card. Field arithmetic rests on the inline-PTX Montgomery primitives of sppark [Sup25], which we use and did not write.

What the soundness target costs the prover. The level of §9.2 is paid for in queries and in proof-of-work. We measured the grinds separately, on four GPUs, at a build that grinds the lookup challenge, with the arms interleaved on one cached block. The 22/22/14-bit query, LogUp-GKR and batching grinds took 33.4 s against 33.9 s for 16/16/8, a difference within run-to-run spread, while buying the same bits with queries (133, 95 and 91 queries in the three WHIR rounds at a 16-bit grind) cost 8.6%. That holds only because the search runs on the device: with the grinds on the host the same schedule took 166 s, 123 s of it the LogUp-GKR grind.

10.4 Controlling proof size

The shard proofs of a block total on the order of 10^8 bytes before recursion; the published object is the compressed proof at the root of the tree, whose size does not grow with the execution. It is dominated by the openings of the first WHIR oracle, about four fifths of it in the instrumented proofs, because each query authenticates one coset row of every stripe; the later WHIR rounds, the LogUp-GKR layer proofs and the other sumchecks share the rest. To first order the size is

t_0\cdot\big(\text{stripes}\cdot2^{k_0}+\text{roots}\cdot\log_2(\text{leaves})\cdot|\text{digest}|\big)+\sum_{i\ge1}t_i\cdot(\text{folded leaf}+\text{path}),

with t_i the queries of round i and k_0 the first folding factor. Every lever on it is a parameter of the schedule (§7), fixed per stage, and each trades against something else at a fixed soundness level:

  • Queries per round. A query at rate \rho yields -\log_2\frac{1+\rho}{2} bits under unique decoding and close to \frac12\log_2\frac1\rho under the Johnson bound, which is also proven but adds larger proximity-gap terms that must be paid for by grinding the folding and batching challenges. Lowering \rho therefore cuts every round’s queries, most of all under the Johnson-bound analysis; the first round’s rate is bounded by the field, since the stacking height times 1/\rho must not exceed the two-adic subgroup (2^{24} for KoalaBear), and the prover’s encoding work and memory grow as 1/\rho.
  • Grinding. Each bit of query grinding removes about one bit’s worth of queries, at a doubling of the search, which on the device is cheap (§10.3); the size of a grinding witness, one field element, bounds how far this goes.
  • Leaf width. A smaller first folding factor k_0 narrows every first-round leaf and moves the variables to later rounds, whose queries are fewer.
  • Stripes. The number of stripes a query opens follows the committed area of the stage, which for a compress node is set by the recursion verifier program rather than by the guest.

The parameters that make the proof small need to apply only to the published proof: the core shards and every recursion node below the root keep the schedule tuned for prover time, since each of those proofs is consumed by its parent and never leaves the prover, and the root alone proves under the compress schedule of Table 5. The root is a compose of arity one over the node that covers the execution (§8), so its verifier program, and with it the committed area that sets the number of stripes, is the same small one for every tree, and it fits the smallest area class, 16 stripes per round. The two schedules are two instances of one ring type, so the field, the hash and the transcript are shared and only the schedule differs; a verifier takes the schedule from the stage it expects, never from the proof, and every parameter of the compress schedule is a setting, so a different security requirement is a different schedule under the same prover.

Taken together, the Johnson-bound schedule at a first rate of 2^{-3} with k_0=2 roughly halves the first-oracle openings against the unique-decoding schedule at rate 2^{-2} with k_0=3, at the same union soundness (Table 6), for 27 bits of grinding on the folding and batching challenges, paid once per proof at the root, which is the prover-time cost of the smaller proof. Measured on the analysed configuration with a fibonacci guest, whose root verifier program is that of any block, the compressed proof is 280 653 bytes (274 KiB) under the compress schedule, against 846 401 bytes when the root proves under the core schedule; since the root program is the same for every tree, the size does not depend on the guest. The native verifier checks it in 73 ms (median of five runs, 63–89 ms) on the host of §10.1. This run omits the in-circuit allowlist check of the root’s children, since the guest’s leaf key lies outside the enumerated clusters (§8).

10.5 Threats to validity

Internal. Comparisons are interleaved and repeated, and the spread is small relative to the effects reported; the host processor was shared with an unrelated process. Construct. Every timing and proof-size measurement predates the Poseidon2 correction, which adds seven partial rounds to commitments, transcripts and recursion and changes absolute performance by an unmeasured amount; the ablations are evidence about mechanisms to the extent the correction leaves relative costs unchanged. Wall-clock time includes host verification, and trace area is a model where the kernel profile is the measurement. The pipelining of §3.3 is not ablated: no run defers recursion until every shard is proved, so its effect on wall-clock time is not separated from the rest. External. The primary workload is one Ethereum block, and other guests have different instruction mixes. The raw per-run timings are not retained, and the retained area census is for the analysed configuration rather than the measured one.

11 Conclusion

We have presented Ziren, a succinct argument for MIPS32 execution. Its architecture is one proving stack whose compressed proof a native verifier checks, with applications built on it that verify that proof inside other proof systems: a pairing-based SNARK for an on-chain verifier, and, through a change of hash and then of field, a garbled verifier whose cost is counted in AND gates and input bits (Section 3). One row of one chip per executed instruction, carried by an instruction frame, replaces the CPU table; one lookup argument and one zerocheck per shard discharge every bus and constraint; a jagged reduction opened by WHIR commits columns of any height at the cost of their real area; and a recursion tree with an enumerated key allowlist composes the shards into one proof. Conformance suites and an executable Lean 4 model test the emulator. Determinism is extracted from the constraint description the prover evaluates and proved by replaying a propagation analysis as step lemmas over gadget theorems proved once; all 104 extracted theorems are closed in Lean 4, the statements exposed three soundness gaps that the constraints now close, and the same pipeline extends to the remaining control chips and to the recursion machine.

Beyond determinism, two techniques surround the machine. Proving is pipelined: shards are proved as the emulator produces them, recursion nodes are proved while core shards are still in flight, and trace generation and the proof-of-work searches run on the device, so what remains serial is the start-up interval and the recursion tail (§3.3). And cross-shard memory has four options: an elliptic-curve multiset hash, the one component that is not hash-based; a lattice multiset hash, which would cost no less than 19.6× the committed area; a global challenge, 29 to 42% slower; and Merkle roots over touched memory, faster on one GPU and 3.4% slower on four (§§5.5 and 9.8).

The performance study identifies trace area, lookup interactions, layer order and shard size as distinct cost levers. The two largest costs it identifies are the lookup argument, 42% of kernel time, and the cross-shard digest, 15% of the block’s area, which a digest of per-shard deltas or a larger shard would reduce. The open proof obligations are the five hypotheses of §9.1; future work should measure the corrected Poseidon2 schedule against one configuration, soundness report, key set and proof.

Acknowledgements

The Plonky3 [Pol24] toolkit supplies the field, the Poseidon2 permutation [GKS23], the constraint interfaces and the transforms this implementation is written against. We thank the developers of SP1 [Suc24, Suc25a] and OpenVM [Ope26b] for publishing their systems openly; the components of theirs that this paper uses are cited where they are used.

A The frame and the chips in detail

This appendix itemises the columns and interactions of the instruction frame (Table 11) and the width of every chip (Table 12).

Table 11: Columns of the R-type instruction frame. The I-type frame replaces the \mathsf{op\_c} index and access (7 columns) by a word immediate (4), 27 columns in all; the shift-amount frame replaces them by a scalar immediate (1) and drops the access, 24 columns. The program-counter pair is owned by the chip and passed to the frame.

Element Purpose Columns
shard shard index, the high part of every timestamp; 16-bit range check 1
clk limbs the instruction’s clock as a 16-bit and a 10-bit limb, both range-checked 2
opcode, op_a, op_b, op_c the decoded instruction, sent on the program bus with pc 4
op_a_0 set when the destination is register 0, which pins the written word to zero 1
op_a access previous word, written word, previous timestamp and one limb of the timestamp difference 10
op_b access word read, previous timestamp, one difference limb 6
op_c access word read, previous timestamp, one difference limb 6
Frame 30
pc, next_pc the counter pair received on the state bus; owned by the chip 2

A.1 The instruction frame

The R-type frame raises 20 interactions per row: one program fetch; a receive of (\mathsf{shard},\mathsf{clk},\mathsf{pc},\mathsf{next\_pc}) and a send of (\mathsf{shard},\mathsf{clk}+5+\delta,\mathsf{next\_pc},\mathsf{next\_next\_pc}) on the state bus, where \delta is zero except for a system call; a send of the previous and a receive of the new tuple on the memory bus for each of its three accesses; and eleven table lookups, one 16-bit check of the shard, two for the clock limbs, two per access for the timestamp difference, and two for the four bytes of the written word, which the byte table checks in pairs. The I-type and shift-amount frames have one access fewer, and raise 16.

A.2 The chips

Table 12 lists all 62 chips with their widths in the analysed configuration. Global differs most from the measured configuration: it has 65 columns here, against 100 in the measured baseline and 58 after the change of §10.2, because the analysed configuration keeps seven chord-witness columns that change removed.

Table 12: The 62 chips of the core machine with their main-trace widths (columns over \mathbb F), in the analysed configuration; a second figure is a preprocessed width. The immediate (Imm) variants take the second operand from the instruction word. MovCond proves movn, movz and wsbh, and SysLinux the Linux-ABI syscalls of §5.10.4; Appendix B gives the instruction-to-chip map.

Family Chips (width)
Integer ALU AddSub (36), AddSubImm (33), Bitwise (37), BitwiseImm (33), Mul (74), DivRem (163), Lt (50), LtImm (47), CloClz (93)
Shifts ShiftLeft (62), ShiftLeftImm (45), ShiftRight (89), ShiftRightImm (83)
Control flow Branch (56), Jump (57)
Memory instructions LoadWord (48), LoadNarrow (59), StoreWord (52), StoreNarrow (55), MemoryUnaligned (59)
Misc. / syscall MiscInstrs (432), MovCond (49), SyscallInstrs (68), SyscallCore (11), SyscallPrecompile (11), SysLinux (100)
Memory argument MemoryLocal (80), MemoryBump (12), MemoryGlobalInit (152), MemoryGlobalFinalize (152), Global (65)
Tables Program (1, +14), Byte (10, +12), Range (1, +2)
Hash precompiles ShaExtend (166) and control (4), ShaCompress (249) and control (69), KeccakSponge (2637) and control (1095), Poseidon2Permute (571)
Curve precompiles add (1685) and double (1666) for Secp256k1, Secp256r1 and Bn254, decompress (1040) for the first two; Bls12381 add (2533), double (2506), decompress (1613); Ed25519 add (1433), decompress (1166)
Field precompiles Bls12381Fp (512), Bls12381Fp2AddSub (1014), Bls12381Fp2Mul (1773), Bn254Fp (344), Bn254Fp2AddSub (678), Bn254Fp2Mul (1181), Uint256MulMod (417), U256XU2048Mul (2627)

B The guest instruction set

This appendix lists the MIPS32 instructions a guest may execute, which is the set the relation of §4.4 quantifies over. It is also the table from which the conformance corpus of §9.7 is generated: each row produces ten programs with pseudo-random operands, boundary values and the delay-slot placements the instruction admits, giving the 770 vectors compared against an independent emulator. The last column names the chip that arithmetises the instruction, so the table fixes which rows of Appendix A a program can occupy, and with it the chip set that Section 8 enumerates over.

Three conventions apply. LO and HI occupy the register file as registers 32 and 33, so the four moves between them and the general registers are additions of an immediate zero rather than a chip of their own. SYNC, SYNCI and PREF are accepted and retire as no-ops on AddSubImm, as an addition of zero. SYSCALL is absent from the table because it is the boundary of the machine rather than a computation within it; it is arithmetised by SyscallInstrs and described in §5.10.4. MIPS32r2 user-mode integer instructions outside the table (the conditional traps other than teq, the linking conditional branches bgezal and bltzal, the branch-likely forms, break and rdhwr) are not supported: the decoder maps them to an unimplemented opcode and execution stops with an error.

Table 13: The 77 guest instructions, their primary encoding fields and the chip that proves each. Op is bits 31–26 and func bits 5–0; a dash marks a field the format does not use, and the immediate forms are distinguished from the register forms by Op alone. Rows that share both fields are told apart by another field: bgez, bltz, bal and synci by rt, rotr and rotrv from srl and srlv by one bit of rs or sa, and wsbh, seb and seh by sa. Semantics are as transcribed from the architecture manual into the specification table that generates the conformance corpus; on rows marked † the implementation fixes a choice (§4.3): j and jal take the region bits (PC + 4)[31:28] as zero, exact for text below 2^{28}, and sc always succeeds, setting rt = 1. Bit ranges x[h:l] include both ends.

Mnemonic Op func Family Semantics Chip
add 000000 100000 Integer arithmetic rd = rs + rt AddSub
addu 000000 100001 rd = rs + rt AddSub
addi 001000 – rt = rs + sext(imm) AddSubImm
addiu 001001 – rt = rs + sext(imm) AddSubImm
sub 000000 100010 rd = rs - rt AddSub
subu 000000 100011 rd = rs - rt AddSub
mul 011100 000010 rd = rs * rt Mul
mult 000000 011000 (hi, lo) = rs * rt Mul
multu 000000 011001 (hi, lo) = rs * rt Mul
div 000000 011010 (hi, lo) = (rs%rt, rs/rt), signed DivRem
divu 000000 011011 (hi, lo) = (rs%rt, rs/rt), unsigned DivRem
madd 011100 000000 (hi, lo) = (hi,lo) + rs * rt (signed) MiscInstrs
maddu 011100 000001 (hi, lo) = (hi,lo) + rs * rt (unsigned) MiscInstrs
msub 011100 000100 (hi, lo) = (hi,lo) - rs * rt (signed) MiscInstrs
msubu 011100 000101 (hi, lo) = (hi,lo) - rs * rt (unsigned) MiscInstrs
clo 011100 100001 rd = count_leading_ones(rs) CloClz
clz 011100 100000 rd = count_leading_zeros(rs) CloClz
slt 000000 101010 Comparison and logic rd = rs < rt Lt
sltu 000000 101011 rd = rs < rt (unsigned) Lt
slti 001010 – rt = rs < sext(imm) LtImm
sltiu 001011 – rt = rs < sext(imm) (unsigned) LtImm
and 000000 100100 rd = rs & rt Bitwise
andi 001100 – rt = rs & zext(imm) BitwiseImm
or 000000 100101 rd = rs \| rt Bitwise
ori 001101 – rt = rs \| zext(imm) BitwiseImm
xor 000000 100110 rd = rs ^ rt Bitwise
xori 001110 – rt = rs ^ zext(imm) BitwiseImm
nor 000000 100111 rd = ~(rs \| rt) Bitwise
lui 001111 – rt = imm<<16 AddSubImm
sll 000000 000000 Shifts and bit fields rd = rt<<sa ShiftLeftImm
sllv 000000 000100 rd = rt << rs[4:0] ShiftLeft
srl 000000 000010 rd = rt >> sa ShiftRightImm
srlv 000000 000110 rd = rt >> rs[4:0] ShiftRight
sra 000000 000011 rd = rt >> sa (arithmetic) ShiftRightImm
srav 000000 000111 rd = rt >> rs[4:0] (arithmetic) ShiftRight
rotr 000000 000010 rd = rotate_right(rt, sa) ShiftRightImm
rotrv 000000 000110 rd = rotate_right(rt, rs[4:0]) ShiftRight
ext 011111 000000 rt = rs[msbd+lsb:lsb] MiscInstrs
ins 011111 000100 rt = rt[31:msb+1] \|\| rs[msb-lsb:0] \|\| rt[lsb-1:0] MiscInstrs
wsbh 011111 100000 rd = swaphalf(rt) MovCond
seb 011111 100000 rd = signExtend(rt[7:0]) MiscInstrs
seh 011111 100000 rd = signExtend(rt[15:0]) MiscInstrs
beq 000100 – Control transfer PC = PC + 4 + sext(offset<<2), if rs == rt Branch
bne 000101 – PC = PC + 4 + sext(offset<<2), if rs != rt Branch
bgez 000001 – PC = PC + 4 + sext(offset<<2), if rs >= 0 Branch
bgtz 000111 – PC = PC + 4 + sext(offset<<2), if rs > 0 Branch
blez 000110 – PC = PC + 4 + sext(offset<<2), if rs <= 0 Branch
bltz 000001 – PC = PC + 4 + sext(offset<<2), if rs < 0 Branch
j 000010 – PC = (PC + 4)[31:28] \|\| instr_index \|\| 00 † Jump
jal 000011 – r31 = PC + 8, PC = (PC + 4)[31:28] \|\| instr_index \|\| 00 † Jump
jr 000000 001000 PC = rs Jump
jalr 000000 001001 rd = PC + 8, PC = rs Jump
bal 000001 – r31 = PC + 8, PC = PC + 4 + sext(offset<<2) Jump
teq 000000 110100 trap, if rs == rt MiscInstrs
lb 100000 – Aligned memory rt = sext(mem_byte(base + offset)) LoadNarrow
lbu 100100 – rt = zext(mem_byte(base + offset)) LoadNarrow
lh 100001 – rt = sext(mem_halfword(base + offset)) LoadNarrow
lhu 100101 – rt = zext(mem_halfword(base + offset)) LoadNarrow
lw 100011 – rt = mem_word(base + offset) LoadWord
ll 110000 – rt = mem_word(base + offset) LoadWord
sb 101000 – mem_byte(base + offset) = rt StoreNarrow
sh 101001 – mem_halfword(base + offset) = rt StoreNarrow
sw 101011 – mem_word(base + offset) = rt StoreWord
sc 111000 – mem_word(base + offset) = rt, rt = 1, if atomic update, else rt = 0 † StoreWord
lwl 100010 – Unaligned memory rt = rt merge most significant part of mem(base+offset) MemoryUnaligned
lwr 100110 – rt = rt merge least significant part of mem(base+offset) MemoryUnaligned
swl 101010 – store most significant part of rt MemoryUnaligned
swr 101110 – store least significant part of rt MemoryUnaligned
mfhi 000000 010000 Moves and no-ops rd = hi AddSubImm
mflo 000000 010010 rd = lo AddSubImm
mthi 000000 010001 hi = rs AddSubImm
mtlo 000000 010011 lo = rs AddSubImm
movn 000000 001011 rd = rs, if rt != 0 MovCond
movz 000000 001010 rd = rs, if rt == 0 MovCond
sync 000000 001111 sync (nop) AddSubImm
synci 000001 – sync (nop) AddSubImm
pref 110011 – prefetch (nop) AddSubImm

C Results used from prior work

Table 14 lists each result proved elsewhere that this paper uses, with its number in the source; where a result is specialised, the section using it says how.

Table 14: Results imported from prior work.

Result Source Used in
Basic jagged reduction, soundness 2m/\lvert\mathbb F_{p^4}\rvert [HJR+25, Thm. 1.4] Theorem 6.1
Jagged assist; batch evaluation [HJR+25, Thm. 1.5, Lemma 5.1] Theorem 6.2
Indicator as a sum over columns [HJR+25, Claim 3.2.1, Eq. (5)] §6.3
Width-four branching program for g [HJR+25, Claim 3.2.2] §6.3
Evaluating a read-once branching program’s extension [HJR+25, Lemma 4.2], after Holmgren and Rothblum [HR18] §6.3
Sumcheck for a product of multilinears [HJR+25, Lemma 2.3] §6.2
Round-by-round soundness of WHIR [ACFY24b] §9.2
Round-by-round soundness of sumcheck; Fiat–Shamir compilation [BSCS16, CY24] Theorem 9.2
Hash-collision term of the compilation [Ope26c, Cor. 4.2.6] Theorem 9.2
Integer reading of balanced LogUp-GKR buses [Ope26a, Cor. 3.6] Definition 2.5
Limbs determine integers [GPR21, Thm. 1] Lemma 5.1
Offline memory checking [BEG+94, SAGL18] Lemma 5.4
Functional IOPs and the commit-and-open compiler [CGKY26] Definition 9.1, §9.3
Fiat–Shamir against quantum adversaries; quantum collision search [CMS19, BHT98] §9.8
Multiset hashing; on an elliptic curve [CDvD+03, BM97, MSTA17] §5.5; the security argument of §9.5 is not inherited

References

  1. [ACFY24a] Gal Arnon, Alessandro Chiesa, Giacomo Fenzi, and Eylon Yogev. STIR: Reed–Solomon Proximity Testing with Fewer Queries. Cryptology ePrint Archive, Paper 2024/390, 2024.
  2. [ACFY24b] Gal Arnon, Alessandro Chiesa, Giacomo Fenzi, and Eylon Yogev. WHIR: Reed–Solomon Proximity Testing with Super-Fast Verification. Cryptology ePrint Archive, Paper 2024/1586, 2024.
  3. [AHIV17] Scott Ames, Carmit Hazay, Yuval Ishai, and Muthuramakrishnan Venkitasubramaniam. Ligero: Lightweight sublinear arguments without a trusted setup. In ACM CCS, 2017.
  4. [AST24] Arasu Arun, Srinath Setty, and Justin Thaler. Jolt: SNARKs for virtual machines via lookups. EUROCRYPT 2024; Cryptology ePrint Archive, Paper 2023/1217, 2024.
  5. [BEG+94] Manuel Blum, Will Evans, Peter Gemmell, Sampath Kannan, and Moni Naor. Checking the Correctness of Memories. In Algorithmica, volume 12, pages 225–244, 1994.
  6. [BGt23] Jeremy Bruestle, Paul Gafni, and the RISC Zero Team. RISC Zero zkVM: Scalable, transparent arguments of RISC-V integrity. https://dev.risczero.com/proof-system-in-detail.pdf, 2023. Draft.
  7. [BHT98] Gilles Brassard, Peter Høyer, and Alain Tapp. Quantum cryptanalysis of hash and claw-free functions. In LATIN’98: Theoretical Informatics, volume 1380 of LNCS, pages 163–169, 1998.
  8. [BL24] Marc Beunardeau and O(1) Labs. Research meets ecosystem: The applied cryptography team roadmap. https://www.o1labs.org/blog/applied-cryptography-team-roadmap, December 2024.
  9. [BM97] Mihir Bellare and Daniele Micciancio. A new paradigm for collision-free hashing: Incrementality at reduced cost. In Advances in Cryptology – EUROCRYPT, 1997.
  10. [BSBHR18] Eli Ben-Sasson, Iddo Bentov, Yinon Horesh, and Michael Riabzev. Fast Reed–Solomon Interactive Oracle Proofs of Proximity. In Proceedings of the 45th International Colloquium on Automata, Languages, and Programming (ICALP), pages 14:1–14:17, 2018.
  11. [BSCI+20] Eli Ben-Sasson, Dan Carmon, Yuval Ishai, Swastik Kopparty, and Shubhangi Saraf. Proximity gaps for Reed–Solomon codes. In FOCS, 2020.
  12. [BSCS16] Eli Ben-Sasson, Alessandro Chiesa, and Nicholas Spooner. Interactive Oracle Proofs. In Theory of Cryptography — TCC 2016-B, pages 31–60, 2016.
  13. [BSGKS20] Eli Ben-Sasson, Lior Goldberg, Swastik Kopparty, and Shubhangi Saraf. DEEP-FRI: Sampling outside the box improves soundness. In ITCS, 2020.
  14. [CDvD+03] Dwaine Clarke, Srinivas Devadas, Marten van Dijk, Blaise Gassend, and G. Edward Suh. Incremental multiset hash functions and their application to memory integrity checking. In Advances in Cryptology – ASIACRYPT, 2003.
  15. [CGKY26] Alessandro Chiesa, Ziyi Guan, Christian Knabenhans, and Zihan Yu. On the Fiat–Shamir Security of Succinct Arguments from Functional Commitments. In Advances in Cryptology — CRYPTO 2026, pages 189–213, 2026.
  16. [CJSC23] Zhigang Chen, Yuting Jiang, Xinxia Song, and Liqun Chen. A survey on zero-knowledge authentication for Internet of Things. Electronics, 12(5):1145, 2023.
  17. [CMS19] Alessandro Chiesa, Peter Manohar, and Nicholas Spooner. Succinct arguments in the quantum random oracle model. In Theory of Cryptography Conference (TCC), 2019. Cryptology ePrint Archive, Paper 2019/834.
  18. [Con24] Consensys. gnark: A fast zk-SNARK library in Go. https://github.com/Consensys/gnark, 2024.
  19. [CY24] Alessandro Chiesa and Eylon Yogev. Building Cryptographic Proofs from Hash Functions. https://github.com/hash-based-snargs-book, 2024.
  20. [Cys25] Cysic. Cysic: hardware-accelerated proof generation. https://cysic.xyz, 2025.
  21. [DDGM23] Heini Bergsson Debes, Edlira Dushku, Thanassis Giannetsos, and Ali Marandi. ZEKRA: Zero-knowledge control-flow attestation. In ACM ASIA Conference on Computer and Communications Security (ASIA CCS), 2023.
  22. [DP23] Benjamin E. Diamond and Jim Posen. Succinct arguments over towers of binary fields. Cryptology ePrint Archive, Paper 2023/1784, 2023.
  23. [DP24] Benjamin E. Diamond and Jim Posen. Polylogarithmic proofs for multilinears over binary towers. Cryptology ePrint Archive, Paper 2024/504, 2024.
  24. [Eag25] Liam Eagen. Glock: Garbled locks for Bitcoin. Cryptology ePrint Archive, Paper 2025/1485, 2025.
  25. [EFG22] Liam Eagen, Dario Fiore, and Ariel Gabizon. cq: Cached quotients for fast lookups. Cryptology ePrint Archive, Paper 2022/1763, 2022.
  26. [EH24] Shahriar Ebrahimi and Parisa Hassanizadeh. From interaction to independence: zkSNARKs for transparent and non-interactive remote attestation. In Network and Distributed System Security Symposium (NDSS), 2024. IACR ePrint 2024/1068.
  27. [EL26] Liam Eagen and Ying Tong Lai. Argo MAC: Garbling with elliptic curve MACs. Cryptology ePrint Archive, Paper 2026/049, 2026.
  28. [Eth26a] Ethereum Foundation. soundcalc: security calculator for hash-based proof systems. https://github.com/ethereum/soundcalc, 2026.
  29. [Eth26b] Ethproofs. Ethproofs: real-time proving of Ethereum blocks. https://ethproofs.org, 2026.
  30. [FS87] Amos Fiat and Adi Shamir. How to Prove Yourself: Practical Solutions to Identification and Signature Problems. In Advances in Cryptology — CRYPTO ’86, pages 186–194, 1987.
  31. [GKR08] Shafi Goldwasser, Yael Tauman Kalai, and Guy N. Rothblum. Delegating Computation: Interactive Proofs for Muggles. In Proceedings of the 40th ACM Symposium on Theory of Computing (STOC), pages 113–122, 2008.
  32. [GKS23] Lorenzo Grassi, Dmitry Khovratovich, and Markus Schofnegger. Poseidon2: A faster version of the Poseidon hash function. In AFRICACRYPT, 2023.
  33. [GKS+26] Sanjam Garg, Dimitris Kolonelos, Mikhail Sergeevitch, Srivatsan Sridhar, and David Tse. BABE: Verifying proofs on Bitcoin made 1000x cheaper. Cryptology ePrint Archive, Paper 2026/065, 2026.
  34. [GLS+21] Alexander Golovnev, Jonathan Lee, Srinath Setty, Justin Thaler, and Riad Wahby. Brakedown: Linear-time and field-agnostic SNARKs for R1CS. Cryptology ePrint Archive, Paper 2021/1043, 2021.
  35. [GPR21] Lior Goldberg, Shahar Papini, and Michael Riabzev. Cairo – a Turing-complete STARK-friendly CPU architecture. Cryptology ePrint Archive, Paper 2021/1063, 2021. Revision of February 2025.
  36. [Gro16] Jens Groth. On the size of pairing-based non-interactive arguments. In Advances in Cryptology – EUROCRYPT 2016, pages 305–326, 2016.
  37. [GW20] Ariel Gabizon and Zachary J. Williamson. plookup: A simplified polynomial protocol for lookup tables. Cryptology ePrint Archive, Paper 2020/315, 2020. https://eprint.iacr.org/2020/315.
  38. [GWC19] Ariel Gabizon, Zachary J. Williamson, and Oana Ciobotaru. PLONK: Permutations over Lagrange-bases for oecumenical noninteractive arguments of knowledge. Cryptology ePrint Archive, Paper 2019/953, 2019.
  39. [Hab22] Ulrich Haböck. Multivariate lookups based on logarithmic derivatives. Cryptology ePrint Archive, Paper 2022/1530, 2022.
  40. [Har25] David Harold. MIPS at 40. Jon Peddie Research, https://www.jonpeddie.com/news/mips-at-40/, January 2025.
  41. [HJR+25] Tamir Hemo, Kevin Jue, Eugene Rabinovich, Gyumin Roh, and Ron D. Rothblum. Jagged Polynomial Commitments (or: How to Stack Multilinears). Cryptology ePrint Archive, Paper 2025/917, 2025. Version of April 10, 2026.
  42. [HLP24] Ulrich Haböck, David Levit, and Shahar Papini. Circle STARKs. Cryptology ePrint Archive, Paper 2024/278, 2024.
  43. [HR18] Justin Holmgren and Ron Rothblum. Delegating Computations with (almost) Minimal Time and Space Overhead. Electronic Colloquium on Computational Complexity, Report TR18-161, 2018.
  44. [KS08] Vladimir Kolesnikov and Thomas Schneider. Improved garbled circuit: Free XOR gates and applications. In ICALP, volume 5126 of LNCS, pages 486–498, 2008.
  45. [KTA+26] Nakul Khambhati, Mukesh Tiwari, Azz, Sapin Bajracharya, Manish Bista, Liam Eagen, Christian Lewe, and Aaron Feickert. Mosaic: Practical malicious security for garbled circuits on Bitcoin. Cryptology ePrint Archive, Paper 2026/812, 2026.
  46. [LFKN92] Carsten Lund, Lance Fortnow, Howard Karloff, and Noam Nisan. Algebraic Methods for Interactive Proof Systems. Journal of the ACM, 39(4):859–868, 1992.
  47. [Lin23] Robin Linus. BitVM: Compute anything on Bitcoin. https://bitvm.org/bitvm.pdf, 2023.
  48. [Lit24] Lita Foundation. Valida ISA specification, version 1.0: A zk-optimized instruction set architecture. https://github.com/lita-xyz/valida-releases, 2024.
  49. [LKMW19] Kevin Lewi, Wonho Kim, Ilya Maykov, and Stephen Weis. Securing update propagation with homomorphic hashing. Cryptology ePrint Archive, Paper 2019/227, 2019.
  50. [LZZ+24] Tianyi Liu, Zhenfei Zhang, Yuncong Zhang, Wenqing Hu, and Ye Zhang. Ceno: Non-uniform, segment and parallel zero-knowledge virtual machine. Cryptology ePrint Archive, Paper 2024/387, 2024.
  51. [Mas25] Hector Massip. Secure challenge derivation in ZisK. ZisK blog, October 2025.
  52. [Mat25] Matter Labs. ZKsync Airbender: A RISC-V zkVM over Mersenne-31. https://github.com/matter-labs/zksync-airbender, 2025.
  53. [MIP10] MIPS Technologies. MIPS32 architecture for programmers volume II-A: The MIPS32 instruction set. Document MD00086, 2010.
  54. [MIP26] MIPS Tech LLC. IP processors. https://mips.com/products/hardware/, 2026. Accessed September 2026.
  55. [MSTA17] Jeremy Maitin-Shepard, Mehdi Tibouchi, and Diego F. Aranha. Elliptic curve multiset hash. The Computer Journal, 2017.
  56. [MT21] Dimitris Mouris and Nektarios Georgios Tsoutsos. Zilch: A framework for deploying transparent zero-knowledge proofs. IEEE Transactions on Information Forensics and Security, 2021. IACR ePrint 2020/1155, https://eprint.iacr.org/2020/1155.
  57. [Nex24] Nexus Labs. Nexus 1.0: Enabling verifiable computation. https://nexus-xyz.github.io/assets/nexus_whitepaper.pdf, 2024. January 2024.
  58. [Nex25] Nexus Labs. Nexus zkVM 3.0 specification. https://specification.nexus.xyz/, 2025. March 2025.
  59. [OANWO20] Jack O’Connor, Jean-Philippe Aumasson, Samuel Neves, and Zooko Wilcox-O’Hearn. BLAKE3: one function, fast everywhere. https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf, 2020.
  60. [OP 24] OP Labs. Kona: A Rust implementation of the OP Stack fault-proof program. https://github.com/op-rs/kona, 2024.
  61. [Ope26a] OpenVM Contributors. On the soundness of interactions via LogUp. https://github.com/openvm-org/stark-backend, 2026.
  62. [Ope26b] OpenVM Contributors. OpenVM whitepaper. https://openvm.dev/whitepaper.pdf, 2026. Version of July 21, 2026.
  63. [Ope26c] OpenVM Contributors. SWIRL: Stacked WHIR with interaction reductions via LogUp. https://openvm.dev/swirl.pdf, 2026. March 13, 2026.
  64. [Ope26d] OpenVM Project. Formal verification of the OpenVM RISC-V, Keccak, and SHA-2 extensions. https://github.com/openvm-org/openvm-fv, 2026.
  65. [Opt23] Optimism Foundation. Cannon: A MIPS interpreter for Optimism fault proofs. https://github.com/ethereum-optimism/optimism, 2023.
  66. [PCW+23] Shankara Pailoor, Yanju Chen, Franklyn Wang, Clara Rodríguez, Jacob Van Geffen, Jason Morton, Michael Chu, Brian Gu, Yu Feng, and Işil Dillig. Automated detection of underconstrained circuits in zero-knowledge proofs. In PLDI, 2023.
  67. [PH23] Shahar Papini and Ulrich Haböck. Improving logarithmic derivative lookups using GKR. Cryptology ePrint Archive, Paper 2023/1284, 2023.
  68. [Pol24] Polygon Zero and contributors. Plonky3: A toolkit for STARKs over small fields. https://github.com/Plonky3/Plonky3, 2024.
  69. [QV15] Nguyen Anh Quynh and Dang Hoang Vu. Unicorn: The ultimate CPU emulator. Black Hat USA; https://www.unicorn-engine.org/, 2015.
  70. [RIS24] RISC Zero. STARK soundness calculator. https://github.com/risc0/risc0/tree/main/risc0/zkp/src/prove/soundness.rs, 2024.
  71. [RR24] Gyumin Roh and Ron D. Rothblum. SP1 V4 Turbo: Memory argument via elliptic curve based multiset hashing. Succinct Labs technical memo, 2024. December 2024.
  72. [SAGL18] Srinath Setty, Sebastian Angel, Trinabh Gupta, and Jonathan Lee. Proving the correct execution of concurrent services in zero-knowledge. In USENIX Symposium on Operating Systems Design and Implementation (OSDI), 2018.
  73. [Scr26] Scroll. Ceno. https://github.com/scroll-tech/ceno, 2026. Revision 7c58fdd4, retrieved 2026-09-24.
  74. [SD21] Xavier Salleras and Vanesa Daza. ZPiE: Zero-knowledge proofs in embedded systems. Mathematics, 9(20):2569, 2021. IACR ePrint 2021/1382.
  75. [Sho97] Peter W. Shor. Polynomial-time algorithms for prime factorization and discrete logarithms on a quantum computer. SIAM Journal on Computing, 26(5):1484–1509, 1997.
  76. [ST25] Srinath Setty and Justin Thaler. Twist and Shout: faster memory checking arguments via one-hot addressing and increments. Cryptology ePrint Archive, Paper 2025/105, 2025.
  77. [Sta23] StarkWare. ethSTARK documentation—version 1.2. Cryptology ePrint Archive, Paper 2021/582, 2023.
  78. [STW24] Srinath Setty, Justin Thaler, and Riad Wahby. Unlocking the lookup singularity with Lasso. EUROCRYPT 2024; Cryptology ePrint Archive, Paper 2023/1216, 2024.
  79. [Suc24] Succinct Labs. SP1: A performant, open-source, contributor-friendly zkVM. https://github.com/succinctlabs/sp1, 2024. Accessed 2026.
  80. [Suc25a] Succinct Labs. SP1 Hypercube: Proving Ethereum in real-time. https://blog.succinct.xyz/sp1-hypercube/, 2025. Announcement, May 20, 2025.
  81. [Suc25b] Succinct Labs. sp1-jit: Just-in-time RISC-V executor for SP1. https://github.com/succinctlabs/sp1, 2025.
  82. [Suc26a] Succinct Labs. SP1 proof system. https://docs.succinct.xyz, 2026.
  83. [Suc26b] Succinct Labs. SP1 security model. https://docs.succinct.xyz/docs/sp1/security/security-model, 2026. Retrieved 2026-09-24.
  84. [Sup25] Supranational. sppark: Zero-knowledge template library for accelerating SNARK provers. https://github.com/supranational/sppark, 2025. Retrieved 2026-09-25.
  85. [Tur21] Jim Turley. Wait, what? MIPS becomes RISC-V. EE Journal, March 2021. https://www.eejournal.com/article/wait-what-mips-becomes-risc-v/.
  86. [WAA+26] Robin Linus Woll, Ioannis Alexopoulos, Lukas Aumayr, Zeta Avarikioti, Matteo Maffei, and David Tse. BitVM3: Efficient Bitcoin bridges via garbled circuits. Cryptology ePrint Archive, Paper 2026/933, 2026.
  87. [Yao86] Andrew Chi-Chih Yao. How to generate and exchange secrets. In 27th Annual Symposium on Foundations of Computer Science (FOCS), pages 162–167, 1986.
  88. [ZCF23] Hadas Zeilberger, Binyi Chen, and Ben Fisch. BaseFold: Efficient Field-Agnostic Polynomial Commitment Schemes from Foldable Codes. Cryptology ePrint Archive, Paper 2023/1705, 2023.
  89. [ZGK+18] Yupeng Zhang, Daniel Genkin, Jonathan Katz, Dimitrios Papadopoulos, and Charalampos Papamanthou. vRAM: Faster verifiable RAM with program-independent preprocessing. In IEEE Symposium on Security and Privacy (S&P), 2018.
  90. [Zis25] ZisK Project. ZisK: A high-performance zkVM. https://github.com/0xPolygonHermez/zisk, 2025.
  91. [ZRE15] Samee Zahur, Mike Rosulek, and David Evans. Two halves make a whole: Reducing data transfer in garbled circuits using half gates. In EUROCRYPT, volume 9057 of LNCS, pages 220–250, 2015.