zorch.pcs.whir.scheme¶
The WHIR opening scheme — the four scheme-specific maps the round driver delegates, so a consumer can byte-match a specific reference (e.g. openvm-stark-backend's SWIRL) without forking the driver.
WHIR's round machinery (sumcheck folds, per-round RS re-encode + out-of-domain
sample, strided query consistency, final constraint) proves
claim = Σ_x f̂(x)·ŵ(x) for whatever initial message f̂ and weight ŵ it is
handed — it is agnostic to how those are built. Four things, and only four,
depend on the scheme:
- how the committed columns become the initial sumcheck message
f̂(combined_f_evals) — a plain MLE for the self-test, the prismalinear eval→coeff RS message for SWIRL; - how the columns' claimed evaluations are read off at the opening point
(
claimed_values); - the initial weight table
ŵthe sumcheck folds (initial_weight) — plaineq(z, ·)here, SWIRL's möbius-adjustedeqthere; - the matching closed form of that weight at the fully-folded point, the
final-constraint prefix (
final_prefix).
Everything else (the out-of-domain and per-query weight updates, which are plain
eq in every known WHIR variant) stays in the driver. A scheme instance is a
@jit static key on the prover/verifier, so it must be a frozen, hashable value;
its methods are pure and run inside the driver's @jit zone.
WhirScheme ¶
Bases: Protocol
The scheme-specific maps of a WHIR opening. Implementations are frozen,
hashable (they ride a prover/verifier @jit static key) and their methods are
jit-traceable pure functions. mle is the committed columns (S, num_polys),
z the opening point (m,), mu the batch-combine challenge, alphas the
(m,) stack of per-fold sumcheck challenges in fold order.
Source code in zorch/pcs/whir/scheme.py
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | |
bind ¶
bind(
transcript: TranscriptT,
commitment: Array,
values: Array,
) -> TranscriptT
Bind the commitment and claimed values into the transcript before μ is sampled. The default absorbs both — a standalone PCS must commit to what it opens. A consumer whose larger protocol already bound the commitment in an earlier stage (so WHIR opens against an existing commitment) overrides this to a no-op, keeping the Fiat-Shamir stream byte-exact with that reference.
Source code in zorch/pcs/whir/scheme.py
50 51 52 53 54 55 56 57 58 | |
claimed_values ¶
claimed_values(mle: Array, z: Array) -> Array
The per-column claimed evaluations (num_polys,) the proof opens to.
Source code in zorch/pcs/whir/scheme.py
60 61 62 | |
combined_f_evals ¶
combined_f_evals(mle: Array, mu: Array) -> Array
The initial sumcheck message f̂ (S,) — the columns reduced to one
polynomial by the μ-power batch combine.
Source code in zorch/pcs/whir/scheme.py
64 65 66 67 | |
initial_weight ¶
initial_weight(z: Array) -> Array
The initial weight table ŵ (2^m,) the first round's sumcheck folds;
its inner product with f̂ is the opened claim.
Source code in zorch/pcs/whir/scheme.py
69 70 71 72 | |
final_prefix ¶
final_prefix(z: Array, alphas: Array) -> Array
The final-constraint contribution of the initial weight: that weight
evaluated through every fold, i.e. the closed form of initial_weight's
multilinear at the fold challenges.
Source code in zorch/pcs/whir/scheme.py
74 75 76 77 78 | |
EqWhirScheme
dataclass
¶
The default scheme — a plain multilinear opening at a point. The columns are
used as MLEs directly, the weight is eq(z, ·) (so the claim is the MLE
evaluated at z), and the final prefix is eq(z, ᾱ) with the folds bound
LSB-first (hence the reversal, mirroring the [0::2]/[1::2] fold order). This
is the self-test scheme and the behaviour the driver had before the seam.
Source code in zorch/pcs/whir/scheme.py
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | |