WHIR

WHIR (Weights Help Improving Rate) is the polynomial commitment of zheng's succinct profile (envelope profile 1): the winner of the phase-2 bake-off of the proof-system repair for both size classes, shipped at rate 1/64 (parameters below). it is also the decider of the machine profile and, run field-natively, the opening inside the recursion circuit (profiles 4–6). it was zheng's first lens; the expander-code commitment that briefly replaced it is retired as unsound (recursive-brakedown). the implementation lives in lens (Whir, PCS id 1; contract lens/specs/whir.md).

Weights Help Improving Rate. an interactive oracle proof of proximity for constrained Reed-Solomon codes that simultaneously serves as a multilinear polynomial commitment scheme. Arnon, Chiesa, Fenzi, Yogev (EUROCRYPT 2025). ePrint 2024/1586.

protocol

WHIR provides three operations:

WHIR_commit(f) → C
  input:  multilinear polynomial f(x₁, ..., x_k) over Goldilocks
  output: commitment C (hemera Merkle root over evaluation table)
  cost:   O(2^k log 2^k) hemera hashes

WHIR_open(f, r) → (v, π)
  input:  polynomial f, evaluation point r ∈ Fp3^k (zheng draws evaluation points in the cubic extension)
  output: value v = f(r), proximity proof π
  cost:   O(2^k) field ops + O(log² 2^k) hemera hashes

WHIR_verify(C, r, v, π) → accept/reject
  input:  commitment C, point r, claimed value v, proof π
  output: accept if f(r) = v and f is close to a degree-bounded polynomial
  cost:   O(log² 2^k) hemera hashes + field ops

verification algorithm

WHIR_verify(C, r, v, proof):
  1. init transcript T from C
  2. for each folding round i = 1..log(N):
     a. absorb prover's round message into T
     b. squeeze challenge αᵢ from T
     c. verify Merkle paths for queried positions against round commitment
     d. fold polynomial: combine evaluations using αᵢ as weight
     e. check consistency: folded values match next round's commitment
  3. verify final polynomial is constant (degree 0)
  4. check that the accumulated evaluation equals v at point r

the folding formula per round: given evaluations f(x) on the current domain and challenge α, split into even and odd parts:

f_folded(x) = (f(x) + f(-x)) / 2 + α × (f(x) - f(-x)) / (2x)

this halves the number of evaluation points each round. the even part (f(x) + f(-x))/2 extracts the symmetric component; the odd part (f(x) - f(-x))/(2x) extracts the antisymmetric component. the challenge α linearly combines them into a single folded polynomial of half the degree.

for multilinear polynomials: folding over variable x_j with challenge r_j gives:

f'(x_1, ..., x_{j-1}, x_{j+1}, ..., x_k) = f(..., x_j=0) × (1 - r_j) + f(..., x_j=1) × r_j

each round eliminates one variable, reducing a k-variate multilinear polynomial to a (k-1)-variate one.

Reed-Solomon domain

the evaluation domain is a multiplicative coset of a 2-adic subgroup of the Goldilocks field (p = 2^64 - 2^32 + 1).

rate ρ is the inverse of the blowup factor. ρ = 1/2 means the evaluation domain is 2× the polynomial degree; ρ = 1/4 means 4×. lower rate increases proof size but improves soundness per query.

in zheng the committed polynomial is the witness w̃ of the compiled relation, with 2^ℓ evaluations; the Reed–Solomon evaluation domain has size 2^ℓ / ρ. at the shipped ρ = 1/64 that is 2^{ℓ+6}.

domain generator: a primitive 2^k-th root of unity ω in Goldilocks. the Goldilocks field has multiplicative order p - 1 = 2^32 × (2^32 - 1), so primitive 2^k-th roots of unity exist for k up to 32. the subgroup ⟨ω⟩ = {ω^0, ω^1, ..., ω^{2^k - 1}} forms the base domain.

coset shift: multiply the entire subgroup by a fixed non-unity element g ∈ F* to obtain the coset g⟨ω⟩ = {g, gω, gω², ...}. this avoids evaluating at zero and ensures the evaluation domain is disjoint from the polynomial's natural domain.

proof structure

a WHIRProof contains:

WHIRProof {
  rounds: [RoundData; log₂(N) / k]           // k variables folded per round
  final_value: F                          // constant polynomial value after all folds
}

RoundData {
  commitment: hemera Merkle root           // commitment to folded evaluations
  auth_paths: [MerklePath; num_queries]   // authentication paths for queried positions
  leaf_values: [F; num_queries]           // evaluation values at queried positions
}

query positions are derived deterministically from the Fiat-Shamir transcript: after absorbing each round commitment, the verifier squeezes query indices from the transcript. this makes the proof non-interactive.

number of queries per round: security_bits / log₂(1/ρ). at 100-bit security with ρ = 1/2: 100 / log₂(2) = 100 queries per round. at ρ = 1/4: 100 / log₂(4) = 50 queries per round. lower rate reduces queries but increases evaluation domain size.

parameters

the succinct profile's default prover (succinct::device_params, lens WhirConfig, Johnson-bound decoding); the bake-off set succinct::params_for is the same with folding 4 and 24 grinding bits at every size:

parameter value
rate ρ 1/64
folding factor k 4 up to 2^16 committed variables, 5 above
grinding 16 bits up to 2^17, 22 at 2^18, 24 beyond — the least that keeps the proof ≤ 64 KB
challenge and evaluation field Fp3 over Goldilocks (p³ ≈ 2^192)
hash hemera (Poseidon2 over Goldilocks), Merkle trees and Fiat–Shamir
proven soundness ≥ 128 bits, round-by-round, grinding included (the policy rejects any set below 128)

measured inside the succinct profile (Apple M4 Max, shared machine): with the device parameters, one hemera hash (hash.tri, 2^10 committed slots) — 16,756 B, verify under 10 ms; Merkle membership at depth 32 (2^18) — 64,071 B, 310 ms (soft3 audit/proof-latency-2026-10.md). with the bake-off parameters, hash.tri — 15,921 B, 7.96 ms; a synthetic 2^20-row relation — 71,081 B, 270 ms (audit/succinct-profile-2026-10.md). the goal of the repair is ≤ 64 KB and verify ≤ 1 ms; one relation misses 64 KB above 2^18 and every size misses 1 ms. bit-flip scans: 0 accepted.

performance comparison

published figures from the WHIR paper, eprint 2024/1586 (its own hash and field, not hemera; not zheng measurements). at d = 2²⁴, 128-bit security:

scheme argument size verifier hashes verification time
FRI 306 KiB 5,600 3.9 ms
STIR 160 KiB 2,600 3.8 ms
WHIR 157 KiB 2,700 1.0 ms

properties

property value
trusted setup none (transparent)
post-quantum yes (hash-only security)
dual nature IOPP (proximity test) + multilinear lens
field any with large multiplicative subgroup
soundness mutual correlated agreement

WHIR inside a proof

WHIR's verifier is proved today, not planned: the recursion circuit runs a field-native WHIR (rs/src/recursion/whir/: a duplex transcript over hemera's permutation, 4-ary field-native Merkle trees, batched openings) as rows of each IVC step and of each wrap level, and the final wrap level's proof is checked natively (recursion, audit/recursion-2026-10.md). its soundness rows are in the soundness ledger § field-native WHIR.

design notes (ideas, not built)

WHIR-compressed Merkle proofs

a binary hemera Merkle path of depth 20 carries 20 sibling digests, 640 bytes. WHIR alternative: commit each tree level as a multilinear polynomial, open at queried positions.

encoding: f_ℓ(b₁, ..., b_ℓ) = hash of node reached by path bits b₁...b_ℓ
crossover: k > ~80 leaves for depth 20 (below this, standard proofs are smaller)
hybrid:    prover selects mode; verifier accepts both via mode flag

open questions: evaluation table layout, root finalization domain separation, hybrid mode protocol.

incremental commitment updates

EdgeSet polynomial commitments face re-commitment cost when edges are added. with a fixed evaluation domain:

insert edge k+1:
  1. evaluate P at new point
  2. update one Merkle leaf
  3. rehash path: log₂(D) × 2 permutations

for D = 2^16: 32 permutations per insertion
vs full re-commit: O(N log N) hashes

domain sizing strategy: start at 2^10, double when 75% full. amortized O(1) per insertion.

see polynomial-commitments for the commitment abstraction, sumcheck for the weight polynomial mechanism, verifier for the full zheng verification algorithm, whirlaway for the architecture

Homonyms

cybics/crystal/whir
WHIR: a lookup argument protocol based on the sum-check mechanism WHIR allows a prover to demonstrate that a set of committed values all appear in a predefined table, without revealing which entries were looked up. the protocol reduces the lookup argument to a sum-check instance, leveraging the…
soft3/zheng/rs/src/recursion/whir
whir

Graph