A from-scratch Rust implementation of two multilinear polynomial commitment schemes — a BaseFold-style PCS, and the WHIR-shaped extension on top — following WHIR (eprint 2024/1586) and its BaseFold ancestor. Built as a learning exercise — not production-ready.
Single-variable folding (k = 1), cross-layer Merkle consistency, no OOD,
no constraint accumulation. Closest to BaseFold-as-PCS, simplest to read.
- Folding factor
k > 1: each iteration runsksumcheck rounds, one fold-by-2^k, and one Merkle commit.iterations = vars / k. - CRS constraint accumulation: a running fused
eqtable tracks the weightW(x) = ∑ s_i · eq(x, z_i)so sumcheck batches all constraints. - OOD sampling: each non-final iteration adds an
f_folded(z_ood) = y_oodconstraint at a random field point. - Queries as constraints: queries open
2^kcluster leaves in the previous codeword; the verifier folds the cluster to an implied value and adds it as a new constraint onf_folded. There are no Merkle openings into the freshly committed codeword — that's the WHIR win over BaseFold. - Final check: prover sends a single
f_final; verifier accepts ifff_final · S == TwhereSis the collapsed sum of all constraint scalars andTis the running target.
- BabyBear prime field (
p = 2³¹ − 2²⁷ + 1, 2-adicity 27). - NTT-based Reed–Solomon encoding on a coset.
- Blake3-Merkle commitments + Fiat–Shamir via Blake3 XOF.
- Multilinear sumcheck for
f · W(degree-2 round polys).
- Proof-of-work grinding (additive — a few lines per iteration).
- Multi-OOD per iteration (we use one).
- Soundness-tuned parameter selection (we expose
num_queriesand stop). - Performance work: no SIMD, naive NTT, no Montgomery field, single-threaded.
src/
field.rs BabyBear prime field arithmetic + 2-adic roots of unity
ml_poly.rs Multilinear polys (evals/coeffs), eq polynomial, Möbius transform
rs.rs Radix-2 NTT, RS encoding, BaseFold fold-by-2, WHIR fold_cluster
merkle.rs Blake3 binary Merkle tree
transcript.rs Fiat–Shamir transcript (Blake3 XOF, rejection-sampled challenges)
sumcheck.rs Sumcheck for the f · eq(·, z) product (degree-2 round polys)
basefold.rs BaseFold-style PCS (k=1, cross-layer Merkle consistency)
whir.rs WHIR-style PCS (k≥1, OOD, CRS, queries-as-constraints)
examples/
vector_commit.rs Demo: succinct vector commitment / opening at any index
cargo run --release --example vector_commit -- [m] [num_queries] [k]
m = log₂ of the vector length; num_queries = proximity-test query count;
k = WHIR folding factor (must divide m; defaults to 2, falls back to 1 if
not divisible).
Example output (16k-element vector, k=2):
[commit] ~9ms
[open] ~6ms / query
[verify] ~2ms / query
proof ≈ 170 KB
cargo test
38 tests covering field arithmetic, multilinear identities (the eq/evaluate
consistency that sumcheck relies on), NTT round-trip, RS-encode vs direct
evaluation, the BaseFold folding identity, fold_cluster vs sequential
folding, Merkle commit/open, transcript determinism, sumcheck completeness
and soundness, BaseFold PCS commit/open/verify with three tampering tests,
and WHIR PCS at k ∈ {1, 2, 4} with four tampering tests (claimed value,
f_final, OOD response, query leaf).
- WHIR paper: https://eprint.iacr.org/2024/1586
- Reference (arkworks): https://github.com/WizardOfMenlo/whir
- BaseFold (the foundation): https://eprint.iacr.org/2023/1705