succinct profile and PCS bake-off — 2026-10-09
superseded (2026-10-27): the shipped choice below (succinct::params_for, 24 grinding bits) is no longer what the default prover uses — succinct::prove_default takes succinct::device_params (zheng#64: 16 grinding bits up to 2^17, folding 5 above 2^16); its figures are in soft3 audit/proof-latency-2026-10.md §3.
Work package E of the proof-system repair (soft3
proposals/proof-system-repair.md, §3 design, §5 phase 2). The succinct
profile (zheng::execution::succinct, envelope profile 1) proves the public
v3 / state v3 statements with the witness committed: the verifier derives the
relation and the pinned half p of z' = (w ‖ p) itself, checks Spartan over
Fp3 (outer sumcheck of the CCS degree, inner sumcheck batching the matrix
evaluations) and one PCS opening of w̃ at an Fp3 point. Protocol:
specs/execution.md § succinct; bound: specs/soundness.md.
Stand: zheng feat/succinct-profile (on feat/soundness-floor), lens
feat/rs-whir-pcs 8f188a9 (unchanged — no lens API addition was needed),
joy feat/succinct-profile. Machine: Apple M4 Max, 16 cores, macOS 26.4,
rustc 1.95.0, --release, no LTO. The machine was shared with other agents
during every run (load average 12–56, recorded per table); times are medians
of the stated repetitions under that load and are upper bounds of a quiet
machine. Sizes are deterministic.
columns
n = 2^ℓ committed witness slots (free columns of the relation, rounded
up); rows = CCS rows; proof B = PCS id + params + root + Spartan + opening
(no statement); envelope B = the whole ZHENGPF1 envelope (program
fixtures; synthetic relations have no statement type); spartan B = matrix
evaluations + compressed rounds + w̃(r') (Fp3 values only, length varints
excluded); opening B = the lens proof after its parameter header;
prove ms = relation + witness + commit + IOP + opening; verify ms =
statement → relation compile → IOP → opening (the public API);
vfy-rel ms = the same with the relation already compiled; pcs vfy ms =
the lens opening alone at the same size and parameters; pcs bits = lens's
proven round-by-round bound, grinding included; total bits =
−log2(ε_spartan + ε_pcs).
Fixtures: joy add.tri (7, 5) and hash.tri (7) as compiled; chain-11 =
eleven chained hemera noun-hashes d_{i+1} = H(d_i, 0⁴) built for the relation
compiler and checked against native nox (output and reductions,
tests/succinct_profile.rs::hash_chain_agrees_with_native_nox); synthetic
relations at 2^10 … 2^20 rows in the compiler's matrix shape (a·b = c and
x^7 = w rows, five matrices, degree 7). There is no Merkle-path program in
joy or trident fixtures, and a 32-hash chain does not compile: each hash of a
digest costs ~2,670 wires and the relation compiler caps a public statement at
32,768 ops/rows, so 11 hashes (27,520 free wires, 2^15) is the longest chain
it admits. A 32-hash path needs the uniform step relation of phase 3.
1. bake-off — TensorRs vs WHIR, same fixtures, same transcript
Command: cargo run --release -p zheng --example succinct_bakeoff -- bakeoff 3
on zheng 80e373e. Grinding 16 bits, Johnson decoding, final polynomial
≤ 2^8 (lens defaults) unless stated. Load: 13.5 at the start, 11.3 at the end.
| fixture | pcs | n (committed) | rows | proof B | envelope B | spartan B | opening B | prove ms | verify ms | vfy-rel ms | pcs vfy ms | pcs bits | total bits | notes |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| add.tri | TensorRs 1/4 | 2^4 | 2^4 | 1251 | 1425 | 624 | 584 | 0.7 | 0.634 | 0.619 | 0.116 | 186.09 | 185.54 | |
| add.tri | TensorRs 1/16 | 2^4 | 2^4 | 2787 | 2961 | 624 | 2120 | 1.2 | 0.926 | 0.901 | 0.400 | 184.09 | 183.93 | |
| add.tri | WHIR 1/4 k=2 | 2^4 | 2^4 | 1433 | 1607 | 624 | 764 | 0.9 | 0.837 | 0.816 | 0.311 | 142.96 | 142.96 | |
| add.tri | WHIR 1/4 k=3 | 2^4 | 2^4 | 1433 | 1607 | 624 | 764 | 0.8 | 0.750 | 0.730 | 0.228 | 142.96 | 142.96 | |
| add.tri | WHIR 1/4 k=4 | 2^4 | 2^4 | 1457 | 1631 | 624 | 788 | 0.8 | 0.697 | 0.676 | 0.175 | 142.96 | 142.96 | |
| add.tri | WHIR 1/4 k=5 | 2^4 | 2^4 | 1457 | 1631 | 624 | 788 | 0.8 | 0.697 | 0.674 | 0.175 | 142.96 | 142.96 | |
| add.tri | WHIR 1/4 k=6 | 2^4 | 2^4 | 1457 | 1631 | 624 | 788 | 0.8 | 0.699 | 0.674 | 0.174 | 142.96 | 142.96 | |
| add.tri | WHIR 1/16 k=2 | 2^4 | 2^4 | 2785 | 2959 | 624 | 2116 | 28.5 | 1.365 | 1.288 | 0.763 | 128.07 | 128.07 | |
| add.tri | WHIR 1/16 k=3 | 2^4 | 2^4 | 2969 | 3143 | 624 | 2300 | 1.2 | 1.172 | 1.152 | 0.675 | 142.60 | 142.60 | |
| add.tri | WHIR 1/16 k=4 | 2^4 | 2^4 | 2993 | 3167 | 624 | 2324 | 1.0 | 0.948 | 0.926 | 0.454 | 142.60 | 142.60 | |
| add.tri | WHIR 1/16 k=5 | 2^4 | 2^4 | 2993 | 3167 | 624 | 2324 | 1.0 | 0.958 | 0.927 | 0.438 | 142.60 | 142.60 | |
| add.tri | WHIR 1/16 k=6 | 2^4 | 2^4 | 2993 | 3167 | 624 | 2324 | 1.0 | 0.950 | 0.926 | 0.449 | 142.60 | 142.60 | |
| hash.tri | TensorRs 1/4 | 2^10 | 2^10 | 24747 | 24974 | 2592 | 22112 | 72.8 | 10.509 | 6.355 | 4.741 | 128.56 | 128.56 | |
| hash.tri | TensorRs 1/16 | 2^10 | 2^10 | 29483 | 29710 | 2592 | 26848 | 74.6 | 10.827 | 6.680 | 5.256 | 128.24 | 128.24 | |
| hash.tri | WHIR 1/4 k=2 | 2^10 | 2^10 | 20913 | 21140 | 2592 | 18276 | 42.9 | 9.544 | 5.361 | 4.176 | 128.01 | 128.01 | |
| hash.tri | WHIR 1/4 k=3 | 2^10 | 2^10 | 18369 | 18596 | 2592 | 15732 | 44.7 | 9.117 | 5.023 | 3.431 | 128.01 | 128.01 | |
| hash.tri | WHIR 1/4 k=4 | 2^10 | 2^10 | 19345 | 19572 | 2592 | 16708 | 71.0 | 8.316 | 4.395 | 3.194 | 128.01 | 128.01 | |
| hash.tri | WHIR 1/4 k=5 | 2^10 | 2^10 | 24193 | 24420 | 2592 | 21556 | 43.0 | 7.395 | 4.564 | 3.434 | 128.01 | 128.01 | |
| hash.tri | WHIR 1/4 k=6 | 2^10 | 2^10 | 36137 | 36364 | 2592 | 33500 | 17.7 | 8.795 | 5.209 | 3.939 | 130.96 | 130.96 | |
| hash.tri | WHIR 1/16 k=2 | 2^10 | 2^10 | 20689 | 20916 | 2592 | 18052 | 47.9 | 8.758 | 4.549 | 3.162 | 128.07 | 128.07 | |
| hash.tri | WHIR 1/16 k=3 | 2^10 | 2^10 | 16897 | 17124 | 2592 | 14260 | 72.8 | 8.286 | 4.128 | 2.859 | 128.07 | 128.07 | |
| hash.tri | WHIR 1/16 k=4 | 2^10 | 2^10 | 17937 | 18164 | 2592 | 15300 | 42.4 | 8.172 | 4.081 | 2.702 | 128.07 | 128.07 | |
| hash.tri | WHIR 1/16 k=5 | 2^10 | 2^10 | 22593 | 22820 | 2592 | 19956 | 58.6 | 8.431 | 4.291 | 2.841 | 128.07 | 128.07 | |
| hash.tri | WHIR 1/16 k=6 | 2^10 | 2^10 | 33329 | 33556 | 2592 | 30692 | 50.2 | 9.322 | 5.162 | 3.486 | 128.07 | 128.07 | |
| chain-11 (hemera) | TensorRs 1/4 | 2^15 | 2^15 | 114459 | 115371 | 3792 | 110624 | 461.4 | 161.764 | 25.326 | 17.355 | 128.56 | 128.56 | |
| chain-11 (hemera) | TensorRs 1/16 | 2^15 | 2^15 | 108923 | 109835 | 3792 | 105088 | 487.2 | 156.337 | 23.664 | 13.650 | 128.24 | 128.24 | |
| chain-11 (hemera) | WHIR 1/4 k=2 | 2^15 | 2^15 | 92501 | 93413 | 3792 | 88664 | 716.8 | 160.157 | 24.781 | 16.142 | 128.01 | 128.01 | |
| chain-11 (hemera) | WHIR 1/4 k=3 | 2^15 | 2^15 | 72857 | 73769 | 3792 | 69020 | 706.0 | 155.940 | 20.820 | 12.282 | 128.01 | 128.01 | |
| chain-11 (hemera) | WHIR 1/4 k=4 | 2^15 | 2^15 | 67453 | 68365 | 3792 | 63616 | 517.9 | 153.766 | 18.436 | 9.837 | 128.01 | 128.01 | |
| chain-11 (hemera) | WHIR 1/4 k=5 | 2^15 | 2^15 | 85421 | 86333 | 3792 | 81584 | 515.7 | 152.924 | 18.981 | 10.957 | 128.01 | 128.01 | |
| chain-11 (hemera) | WHIR 1/4 k=6 | 2^15 | 2^15 | 129933 | 130845 | 3792 | 126096 | 654.3 | 158.577 | 22.357 | 13.991 | 128.01 | 128.01 | |
| chain-11 (hemera) | WHIR 1/16 k=2 | 2^15 | 2^15 | 73253 | 74165 | 3792 | 69416 | 969.5 | 154.695 | 20.529 | 10.960 | 128.05 | 128.05 | |
| chain-11 (hemera) | WHIR 1/16 k=3 | 2^15 | 2^15 | 57945 | 58857 | 3792 | 54108 | 880.4 | 150.874 | 17.430 | 9.136 | 128.01 | 128.01 | |
| chain-11 (hemera) | WHIR 1/16 k=4 | 2^15 | 2^15 | 51741 | 52653 | 3792 | 47904 | 622.5 | 143.863 | 15.534 | 6.996 | 128.07 | 128.07 | |
| chain-11 (hemera) | WHIR 1/16 k=5 | 2^15 | 2^15 | 61733 | 62645 | 3792 | 57896 | 617.0 | 149.111 | 15.853 | 7.523 | 128.01 | 128.01 | |
| chain-11 (hemera) | WHIR 1/16 k=6 | 2^15 | 2^15 | 89453 | 90365 | 3792 | 85616 | 689.0 | 151.074 | 17.898 | 9.892 | 128.07 | 128.07 | |
| synthetic 2^10 | TensorRs 1/4 | 2^10 | 2^10 | 24299 | — | 2592 | 21664 | 70.8 | 5.922 | 5.922 | 4.647 | 128.56 | 128.56 | |
| synthetic 2^10 | TensorRs 1/16 | 2^10 | 2^10 | 29483 | — | 2592 | 26848 | 45.2 | 6.400 | 6.400 | 5.124 | 128.24 | 128.24 | |
| synthetic 2^10 | WHIR 1/4 k=2 | 2^10 | 2^10 | 21073 | — | 2592 | 18436 | 42.5 | 5.189 | 5.189 | 4.069 | 128.01 | 128.01 | |
| synthetic 2^10 | WHIR 1/4 k=3 | 2^10 | 2^10 | 18561 | — | 2592 | 15924 | 46.2 | 4.831 | 4.831 | 3.580 | 128.01 | 128.01 | |
| synthetic 2^10 | WHIR 1/4 k=4 | 2^10 | 2^10 | 19761 | — | 2592 | 17124 | 63.9 | 4.459 | 4.459 | 2.918 | 128.01 | 128.01 | |
| synthetic 2^10 | WHIR 1/4 k=5 | 2^10 | 2^10 | 23521 | — | 2592 | 20884 | 40.4 | 4.227 | 4.227 | 3.070 | 128.01 | 128.01 | |
| synthetic 2^10 | WHIR 1/4 k=6 | 2^10 | 2^10 | 36137 | — | 2592 | 33500 | 11.9 | 5.079 | 5.079 | 3.888 | 130.96 | 130.96 | |
| synthetic 2^10 | WHIR 1/16 k=2 | 2^10 | 2^10 | 19857 | — | 2592 | 17220 | 98.4 | 4.239 | 4.239 | 3.096 | 128.07 | 128.07 | |
| synthetic 2^10 | WHIR 1/16 k=3 | 2^10 | 2^10 | 17761 | — | 2592 | 15124 | 87.3 | 4.044 | 4.044 | 2.803 | 128.07 | 128.07 | |
| synthetic 2^10 | WHIR 1/16 k=4 | 2^10 | 2^10 | 17489 | — | 2592 | 14852 | 42.2 | 3.766 | 3.766 | 2.660 | 128.07 | 128.07 | |
| synthetic 2^10 | WHIR 1/16 k=5 | 2^10 | 2^10 | 22369 | — | 2592 | 19732 | 50.7 | 4.027 | 4.027 | 2.764 | 128.07 | 128.07 | |
| synthetic 2^10 | WHIR 1/16 k=6 | 2^10 | 2^10 | 34513 | — | 2592 | 31876 | 77.5 | 5.071 | 5.071 | 3.421 | 128.07 | 128.07 | |
| synthetic 2^14 | TensorRs 1/4 | 2^14 | 2^14 | 84811 | — | 3552 | 81216 | 188.1 | 15.179 | 15.179 | 11.748 | 128.56 | 128.56 | |
| synthetic 2^14 | TensorRs 1/16 | 2^14 | 2^14 | 78475 | — | 3552 | 74880 | 181.4 | 13.842 | 13.842 | 10.817 | 128.24 | 128.24 | |
| synthetic 2^14 | WHIR 1/4 k=2 | 2^14 | 2^14 | 73193 | — | 3552 | 69596 | 360.6 | 16.209 | 16.209 | 13.078 | 128.01 | 128.01 | |
| synthetic 2^14 | WHIR 1/4 k=3 | 2^14 | 2^14 | 57029 | — | 3552 | 53432 | 252.0 | 12.916 | 12.916 | 9.629 | 128.01 | 128.01 | |
| synthetic 2^14 | WHIR 1/4 k=4 | 2^14 | 2^14 | 60397 | — | 3552 | 56800 | 268.6 | 12.070 | 12.070 | 8.737 | 128.01 | 128.01 | |
| synthetic 2^14 | WHIR 1/4 k=5 | 2^14 | 2^14 | 78165 | — | 3552 | 74568 | 269.4 | 11.921 | 11.921 | 8.582 | 128.01 | 128.01 | |
| synthetic 2^14 | WHIR 1/4 k=6 | 2^14 | 2^14 | 74721 | — | 3552 | 71124 | 165.8 | 11.373 | 11.373 | 7.461 | 128.01 | 128.01 | |
| synthetic 2^14 | WHIR 1/16 k=2 | 2^14 | 2^14 | 59177 | — | 3552 | 55580 | 662.7 | 13.269 | 13.269 | 9.499 | 128.05 | 128.05 | |
| synthetic 2^14 | WHIR 1/16 k=3 | 2^14 | 2^14 | 45501 | — | 3552 | 41904 | 344.4 | 10.388 | 10.388 | 7.035 | 128.07 | 128.07 | |
| synthetic 2^14 | WHIR 1/16 k=4 | 2^14 | 2^14 | 46925 | — | 3552 | 43328 | 262.2 | 9.193 | 9.193 | 5.647 | 128.07 | 128.07 | |
| synthetic 2^14 | WHIR 1/16 k=5 | 2^14 | 2^14 | 59221 | — | 3552 | 55624 | 306.5 | 9.049 | 9.049 | 7.034 | 128.01 | 128.01 | |
| synthetic 2^14 | WHIR 1/16 k=6 | 2^14 | 2^14 | 48609 | — | 3552 | 45012 | 193.5 | 8.970 | 8.970 | 5.779 | 128.07 | 128.07 | |
| synthetic 2^16 | TensorRs 1/4 | 2^16 | 2^16 | 155307 | — | 4032 | 151232 | 568.7 | 30.519 | 30.519 | 20.712 | 128.56 | 128.56 | |
| synthetic 2^16 | TensorRs 1/16 | 2^16 | 2^16 | 141579 | — | 4032 | 137504 | 598.5 | 28.594 | 28.594 | 17.799 | 128.24 | 128.24 | |
| synthetic 2^16 | WHIR 1/4 k=2 | 2^16 | 2^16 | 104021 | — | 4032 | 99944 | 955.4 | 28.124 | 28.124 | 17.938 | 128.01 | 128.01 | |
| synthetic 2^16 | WHIR 1/4 k=3 | 2^16 | 2^16 | 81825 | — | 4032 | 77748 | 869.4 | 23.189 | 23.189 | 13.142 | 128.01 | 128.01 | |
| synthetic 2^16 | WHIR 1/4 k=4 | 2^16 | 2^16 | 75725 | — | 4032 | 71648 | 719.0 | 20.881 | 20.881 | 11.004 | 128.01 | 128.01 | |
| synthetic 2^16 | WHIR 1/4 k=5 | 2^16 | 2^16 | 89981 | — | 4032 | 85904 | 737.2 | 20.576 | 20.576 | 11.517 | 128.01 | 128.01 | |
| synthetic 2^16 | WHIR 1/4 k=6 | 2^16 | 2^16 | 135101 | — | 4032 | 131024 | 717.0 | 25.076 | 25.076 | 14.819 | 128.01 | 128.01 | |
| synthetic 2^16 | WHIR 1/16 k=2 | 2^16 | 2^16 | 81589 | — | 4032 | 77512 | 1361.5 | 23.162 | 23.162 | 13.113 | 128.05 | 128.05 | |
| synthetic 2^16 | WHIR 1/16 k=3 | 2^16 | 2^16 | 64041 | — | 4032 | 59964 | 1153.1 | 20.010 | 20.010 | 9.686 | 128.01 | 128.01 | |
| synthetic 2^16 | WHIR 1/16 k=4 | 2^16 | 2^16 | 57261 | — | 4032 | 53184 | 862.9 | 18.136 | 18.136 | 7.786 | 128.07 | 128.07 | |
| synthetic 2^16 | WHIR 1/16 k=5 | 2^16 | 2^16 | 65429 | — | 4032 | 61352 | 832.0 | 17.890 | 17.890 | 8.040 | 128.01 | 128.01 | |
| synthetic 2^16 | WHIR 1/16 k=6 | 2^16 | 2^16 | 93213 | — | 4032 | 89136 | 878.6 | 20.402 | 20.402 | 10.326 | 128.07 | 128.07 | |
| synthetic 2^18 | TensorRs 1/4 | 2^18 | 2^18 | 295115 | — | 4512 | 290560 | 2181.2 | 92.596 | 92.596 | 37.408 | 128.56 | 128.56 | |
| synthetic 2^18 | TensorRs 1/16 | 2^18 | 2^18 | 257291 | — | 4512 | 252736 | 2364.2 | 86.652 | 86.652 | 31.706 | 128.24 | 128.24 | |
| synthetic 2^18 | WHIR 1/4 k=2 | 2^18 | 2^18 | 136801 | — | 4512 | 132244 | 3416.5 | 80.295 | 80.295 | 23.330 | 128.01 | 128.01 | |
| synthetic 2^18 | WHIR 1/4 k=3 | 2^18 | 2^18 | 107149 | — | 4512 | 102592 | 2962.9 | 72.750 | 72.750 | 17.172 | 128.01 | 128.01 | |
| synthetic 2^18 | WHIR 1/4 k=4 | 2^18 | 2^18 | 100713 | — | 4512 | 96156 | 2781.4 | 70.073 | 70.073 | 14.644 | 128.01 | 128.01 | |
| synthetic 2^18 | WHIR 1/4 k=5 | 2^18 | 2^18 | 105629 | — | 4512 | 101072 | 2499.7 | 67.271 | 67.271 | 13.796 | 128.01 | 128.01 | |
| synthetic 2^18 | WHIR 1/4 k=6 | 2^18 | 2^18 | 146573 | — | 4512 | 142016 | 2532.0 | 71.892 | 71.892 | 13.756 | 128.01 | 128.01 | |
| synthetic 2^18 | WHIR 1/16 k=2 | 2^18 | 2^18 | 106337 | — | 4512 | 101780 | 4869.0 | 69.487 | 69.487 | 16.366 | 128.01 | 128.01 | |
| synthetic 2^18 | WHIR 1/16 k=3 | 2^18 | 2^18 | 82885 | — | 4512 | 78328 | 4266.6 | 65.835 | 65.835 | 12.160 | 128.01 | 128.01 | |
| synthetic 2^18 | WHIR 1/16 k=4 | 2^18 | 2^18 | 76361 | — | 4512 | 71804 | 3412.3 | 62.516 | 62.516 | 10.042 | 128.07 | 128.07 | |
| synthetic 2^18 | WHIR 1/16 k=5 | 2^18 | 2^18 | 76093 | — | 4512 | 71536 | 2914.3 | 61.866 | 61.866 | 9.231 | 128.01 | 128.01 | |
| synthetic 2^18 | WHIR 1/16 k=6 | 2^18 | 2^18 | 100941 | — | 4512 | 96384 | 2835.8 | 66.946 | 66.946 | 11.012 | 128.07 | 128.07 | |
| synthetic 2^20 | TensorRs 1/4 | 2^20 | 2^20 | 570155 | — | 4992 | 565120 | 8221.8 | 300.909 | 300.909 | 67.624 | 128.56 | 128.56 | |
| synthetic 2^20 | TensorRs 1/16 | 2^20 | 2^20 | 485547 | — | 4992 | 480512 | 8835.4 | 293.969 | 293.969 | 55.132 | 128.24 | 128.24 | |
| synthetic 2^20 | WHIR 1/4 k=2 | 2^20 | 2^20 | 172173 | — | 4992 | 167136 | 11844.5 | 269.352 | 269.352 | 28.933 | 128.05 | 128.05 | |
| synthetic 2^20 | WHIR 1/4 k=3 | 2^20 | 2^20 | 128077 | — | 4992 | 123040 | 10874.2 | 261.689 | 261.689 | 20.506 | 128.01 | 128.01 | |
| synthetic 2^20 | WHIR 1/4 k=4 | 2^20 | 2^20 | 117897 | — | 4992 | 112860 | 10098.0 | 259.265 | 259.265 | 17.090 | 128.01 | 128.01 | |
| synthetic 2^20 | WHIR 1/4 k=5 | 2^20 | 2^20 | 136241 | — | 4992 | 131204 | 9788.9 | 258.519 | 258.519 | 17.623 | 128.06 | 128.06 | |
| synthetic 2^20 | WHIR 1/4 k=6 | 2^20 | 2^20 | 161453 | — | 4992 | 156416 | 9401.4 | 260.308 | 260.308 | 18.726 | 128.06 | 128.06 | |
| synthetic 2^20 | WHIR 1/16 k=2 | 2^20 | 2^20 | 132749 | — | 4992 | 127712 | 20462.0 | 246.833 | 246.833 | 17.950 | 128.01 | 128.01 | |
| synthetic 2^20 | WHIR 1/16 k=3 | 2^20 | 2^20 | 97733 | — | 4992 | 92696 | 15356.5 | 248.146 | 248.146 | 14.360 | 128.01 | 128.01 | |
| synthetic 2^20 | WHIR 1/16 k=4 | 2^20 | 2^20 | 88777 | — | 4992 | 83740 | 12745.1 | 250.689 | 250.689 | 11.929 | 128.22 | 128.22 | |
| synthetic 2^20 | WHIR 1/16 k=5 | 2^20 | 2^20 | 100049 | — | 4992 | 95012 | 12289.4 | 253.717 | 253.717 | 12.380 | 128.01 | 128.01 | |
| synthetic 2^20 | WHIR 1/16 k=6 | 2^20 | 2^20 | 112237 | — | 4992 | 107200 | 11115.4 | 255.250 | 255.250 | 11.783 | 128.28 | 128.28 |
Every row is ≥ 128 proven bits (lens's bound; the Spartan term is 2^-184 or smaller everywhere and never the minimum).
Reading (best TensorRs proof ÷ best WHIR proof per fixture): add.tri 0.87
(TensorRs wins at 2^4, 1,251 B against 1,433 B, opening every column),
hash.tri 1.46, synthetic 2^10 1.39, 2^14 1.72, chain-11 2.11, 2^16 2.47,
2^18 3.38, 2^20 5.47. WHIR's best rate is 1/16 at every size above 2^4;
its best folding factor is 3 or 4.
2. levers, one at a time (proposal §A)
Command: … succinct_bakeoff -- levers 3. Fixtures hash.tri and synthetic
2^20; base WHIR 1/16, k = 4, grinding 16. Sizes deterministic; times from
an intermediate verifier build (the map-based matrix weight before the
closed-form eq(τ, ρ)), ~100 ms slower at 2^20 than the final verifier.
| fixture | pcs | n (committed) | rows | proof B | envelope B | spartan B | opening B | prove ms | verify ms | vfy-rel ms | pcs vfy ms | pcs bits | total bits | notes |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| hash.tri | WHIR 1/16 k=4 pow=16 | 2^10 | 2^10 | 17937 | 18164 | 2592 | 15300 | 43.0 | 8.172 | 4.093 | 2.651 | 128.07 | 128.07 | t=[57] siblings 206 (full paths 540, dedup saves 10688 B); u32 prefixes 9 (36 B); 2235 limbs: fixed 17880 B vs varint 21064 B |
| hash.tri | WHIR 1/16 k=4 pow=20 | 2^10 | 2^10 | 16913 | 17140 | 2592 | 14276 | 313.3 | 8.045 | 3.932 | 2.578 | 128.04 | 128.04 | t=[55] siblings 182 (full paths 520, dedup saves 10816 B); u32 prefixes 9 (36 B); 2107 limbs: fixed 16856 B vs varint 19865 B |
| hash.tri | WHIR 1/16 k=4 pow=24 | 2^10 | 2^10 | 17457 | 17684 | 2592 | 14820 | 9223.3 | 8.111 | 4.008 | 2.289 | 128.01 | 128.01 | t=[53] siblings 195 (full paths 530, dedup saves 10720 B); u32 prefixes 9 (36 B); 2175 limbs: fixed 17400 B vs varint 20544 B |
| hash.tri | WHIR 1/16 k=2 pow=16 | 2^10 | 2^10 | 20689 | 20916 | 2592 | 18052 | 51.2 | 8.727 | 4.601 | 2.814 | 128.07 | 128.07 | t=[57] siblings 310 (full paths 684, dedup saves 11968 B); u32 prefixes 9 (36 B); 2579 limbs: fixed 20632 B vs varint 24242 B |
| hash.tri | WHIR 1/16 k=3 pow=16 | 2^10 | 2^10 | 16897 | 17124 | 2592 | 14260 | 75.9 | 7.656 | 3.779 | 2.584 | 128.07 | 128.07 | t=[57] siblings 233 (full paths 605, dedup saves 11904 B); u32 prefixes 9 (36 B); 2105 limbs: fixed 16840 B vs varint 19823 B |
| hash.tri | WHIR 1/16 k=4 pow=16 | 2^10 | 2^10 | 17937 | 18164 | 2592 | 15300 | 46.7 | 8.007 | 4.076 | 2.650 | 128.07 | 128.07 | t=[57] siblings 206 (full paths 540, dedup saves 10688 B); u32 prefixes 9 (36 B); 2235 limbs: fixed 17880 B vs varint 21064 B |
| hash.tri | WHIR 1/16 k=5 pow=16 | 2^10 | 2^10 | 22593 | 22820 | 2592 | 19956 | 57.7 | 8.396 | 4.315 | 2.764 | 128.07 | 128.07 | t=[57] siblings 150 (full paths 495, dedup saves 11040 B); u32 prefixes 9 (36 B); 2817 limbs: fixed 22536 B vs varint 26475 B |
| hash.tri | WHIR 1/16 k=6 pow=16 | 2^10 | 2^10 | 33329 | 33556 | 2592 | 30692 | 51.0 | 9.243 | 5.184 | 3.401 | 128.07 | 128.07 | t=[57] siblings 88 (full paths 424, dedup saves 10752 B); u32 prefixes 9 (36 B); 4159 limbs: fixed 33272 B vs varint 38985 B |
| hash.tri | WHIR 1/2 k=4 pow=16 | 2^10 | 2^10 | 20809 | 21036 | 2592 | 18172 | 16.8 | 9.015 | 4.999 | 3.504 | 131.34 | 131.34 | t=[128] siblings 0 (full paths 896, dedup saves 28672 B); u32 prefixes 9 (36 B); 2595 limbs: fixed 20760 B vs varint 23495 B |
| hash.tri | WHIR 1/4 k=4 pow=16 | 2^10 | 2^10 | 19345 | 19572 | 2592 | 16708 | 68.1 | 8.691 | 4.636 | 3.281 | 128.01 | 128.01 | t=[114] siblings 102 (full paths 728, dedup saves 20032 B); u32 prefixes 9 (36 B); 2411 limbs: fixed 19288 B vs varint 22320 B |
| hash.tri | WHIR 1/8 k=4 pow=16 | 2^10 | 2^10 | 18961 | 19188 | 2592 | 16324 | 49.0 | 8.476 | 4.391 | 2.835 | 128.06 | 128.06 | t=[76] siblings 162 (full paths 657, dedup saves 15840 B); u32 prefixes 9 (36 B); 2363 limbs: fixed 18904 B vs varint 22133 B |
| hash.tri | WHIR 1/16 k=4 pow=16 | 2^10 | 2^10 | 17937 | 18164 | 2592 | 15300 | 45.8 | 8.136 | 4.099 | 2.650 | 128.07 | 128.07 | t=[57] siblings 206 (full paths 540, dedup saves 10688 B); u32 prefixes 9 (36 B); 2235 limbs: fixed 17880 B vs varint 21064 B |
| hash.tri | WHIR 1/32 k=4 pow=16 | 2^10 | 2^10 | 16625 | 16852 | 2592 | 13988 | 50.3 | 7.874 | 3.818 | 2.452 | 128.05 | 128.05 | t=[46] siblings 209 (full paths 473, dedup saves 8448 B); u32 prefixes 9 (36 B); 2071 limbs: fixed 16568 B vs varint 19520 B |
| synthetic 2^20 | WHIR 1/16 k=4 pow=16 | 2^20 | 2^20 | 88777 | — | 4992 | 83740 | 13073.8 | 343.965 | 343.965 | 11.449 | 128.22 | 128.22 | t=[58 33 23] siblings 1492 (full paths 2201, dedup saves 22688 B); u32 prefixes 23 (92 B); 11069 limbs: fixed 88552 B vs varint 105063 B |
| synthetic 2^20 | WHIR 1/16 k=4 pow=20 | 2^20 | 2^20 | 85929 | — | 4992 | 80892 | 13282.4 | 332.094 | 332.094 | 10.651 | 128.04 | 128.04 | t=[55 32 22] siblings 1439 (full paths 2104, dedup saves 21280 B); u32 prefixes 23 (92 B); 10713 limbs: fixed 85704 B vs varint 101728 B |
| synthetic 2^20 | WHIR 1/16 k=4 pow=24 | 2^20 | 2^20 | 81673 | — | 4992 | 76636 | 27546.2 | 359.430 | 359.430 | 8.944 | 128.01 | 128.01 | t=[53 30 21] siblings 1350 (full paths 2008, dedup saves 21056 B); u32 prefixes 23 (92 B); 10181 limbs: fixed 81448 B vs varint 96594 B |
| synthetic 2^20 | WHIR 1/16 k=2 pow=16 | 2^20 | 2^20 | 132749 | — | 4992 | 127712 | 18668.1 | 367.138 | 367.138 | 21.247 | 128.01 | 128.01 | t=[58 46 38 33 29 26] siblings 3188 (full paths 4593, dedup saves 44960 B); u32 prefixes 44 (176 B); 16554 limbs: fixed 132432 B vs varint 157143 B |
| synthetic 2^20 | WHIR 1/16 k=3 pow=16 | 2^20 | 2^20 | 97733 | — | 4992 | 92696 | 15504.9 | 335.539 | 335.539 | 15.041 | 128.01 | 128.01 | t=[58 38 29 23] siblings 2017 (full paths 2943, dedup saves 29632 B); u32 prefixes 30 (120 B); 12184 limbs: fixed 97472 B vs varint 115681 B |
| synthetic 2^20 | WHIR 1/16 k=4 pow=16 | 2^20 | 2^20 | 88777 | — | 4992 | 83740 | 13138.2 | 363.121 | 363.121 | 12.445 | 128.22 | 128.22 | t=[58 33 23] siblings 1492 (full paths 2201, dedup saves 22688 B); u32 prefixes 23 (92 B); 11069 limbs: fixed 88552 B vs varint 105063 B |
| synthetic 2^20 | WHIR 1/16 k=5 pow=16 | 2^20 | 2^20 | 100049 | — | 4992 | 95012 | 12206.7 | 360.191 | 360.191 | 12.594 | 128.01 | 128.01 | t=[58 29 19] siblings 1295 (full paths 1947, dedup saves 20864 B); u32 prefixes 23 (92 B); 12475 limbs: fixed 99800 B vs varint 118378 B |
| synthetic 2^20 | WHIR 1/16 k=6 pow=16 | 2^20 | 2^20 | 112237 | — | 4992 | 107200 | 11180.8 | 361.367 | 361.367 | 12.935 | 128.28 | 128.28 | t=[58 26] siblings 956 (full paths 1486, dedup saves 16960 B); u32 prefixes 16 (64 B); 14006 limbs: fixed 112048 B vs varint 132911 B |
| synthetic 2^20 | WHIR 1/2 k=4 pow=16 | 2^20 | 2^20 | 162921 | — | 4992 | 157884 | 9858.8 | 368.268 | 368.268 | 25.130 | 128.05 | 128.05 | t=[231 57 33] siblings 2709 (full paths 5334, dedup saves 84000 B); u32 prefixes 23 (92 B); 20337 limbs: fixed 162696 B vs varint 192999 B |
| synthetic 2^20 | WHIR 1/4 k=4 pow=16 | 2^20 | 2^20 | 117897 | — | 4992 | 112860 | 9984.2 | 369.412 | 369.412 | 17.226 | 128.01 | 128.01 | t=[115 46 29] siblings 1946 (full paths 3316, dedup saves 43840 B); u32 prefixes 23 (92 B); 14709 limbs: fixed 117672 B vs varint 139776 B |
| synthetic 2^20 | WHIR 1/8 k=4 pow=16 | 2^20 | 2^20 | 99721 | — | 4992 | 94684 | 11087.7 | 354.789 | 354.789 | 13.669 | 128.08 | 128.08 | t=[77 38 26] siblings 1662 (full paths 2589, dedup saves 29664 B); u32 prefixes 23 (92 B); 12437 limbs: fixed 99496 B vs varint 118115 B |
| synthetic 2^20 | WHIR 1/16 k=4 pow=16 | 2^20 | 2^20 | 88777 | — | 4992 | 83740 | 12588.1 | 359.980 | 359.980 | 12.398 | 128.22 | 128.22 | t=[58 33 23] siblings 1492 (full paths 2201, dedup saves 22688 B); u32 prefixes 23 (92 B); 11069 limbs: fixed 88552 B vs varint 105063 B |
| synthetic 2^20 | WHIR 1/32 k=4 pow=16 | 2^20 | 2^20 | 80969 | — | 4992 | 75932 | 17295.5 | 358.142 | 358.142 | 11.157 | 128.01 | 128.01 | t=[46 29 21] siblings 1368 (full paths 1945, dedup saves 18464 B); u32 prefixes 23 (92 B); 10093 limbs: fixed 80744 B vs varint 95886 B |
| lever | measured effect | status |
|---|---|---|
| Merkle path deduplication across queries | lens already sends only the siblings the verifier cannot recompute (rspcs/src/merkle.rs); against full per-query paths it saves 10.7 KB of 28.6 KB at hash.tri and 22.7 KB at 2^20 (column dedup saves) |
already in lens; nothing to add |
| grinding 16 → 20 → 24 | 2^10: 17,937 → 16,913 → 17,457 B (one round; query count 57 → 55 → 53, the leaf mix moves the bytes); 2^20: 88,777 → 85,929 → 81,673 B (−8 %); prover time grows with 2^pow |
taken: 24 |
| folding factor 2 … 6 | 2^10: 20,689 / 16,897 / 17,937 / 22,593 / 33,329 B; 2^20: 132,749 / 97,733 / 88,777 / 100,049 / 112,237 B |
3 at 2^10, 4 above; with rate 1/64 + grinding 4 wins everywhere (§3) |
| rate 1/2 … 1/32 | 2^10: 20,809 / 19,345 / 18,961 / 17,937 / 16,625 B; 2^20: 162,921 / 117,897 / 99,721 / 88,777 / 80,969 B |
taken: 1/64 after §3 |
| fixed 8-byte limbs vs LEB128 varints | every field element and digest limb as a varint is larger: 21,064 vs 17,880 B at hash.tri, 105,063 vs 88,552 B at 2^20 (+18 %) — challenge-field and hash outputs are uniform below p ≈ 2^64, so most need 9–10 varint bytes |
rejected: fixed limbs stay |
| lens u32 length prefixes | every one is implied by the parameters and the size; 9 prefixes (36 B) at 2^10, 23 (92 B) at 2^20 |
not taken: < 0.2 %, needs a lens wire change |
Spartan round compression (drop c_1) |
in from the start: saves (log m + ℓ + 1) × 24 B = 504 B at hash.tri, 984 B at 2^20 |
taken |
| zip (eprint 2025/1446) | — | not done: not implemented in this package; no number is claimed |
3. levers combined
Command: … succinct_bakeoff -- combos 1 (rates 1/16, 1/32, 1/64 × k 3, 4, 5
× grinding 16, 20 × final variables 8, 6, 4), then grind-small 1 and
grind 1 (rates 1/32, 1/64 × grinding 20, 24, k = 4). The five smallest per
fixture; sizes deterministic, times single runs under load.
| fixture | pcs | n (committed) | rows | proof B | envelope B | spartan B | opening B | prove ms | verify ms | vfy-rel ms | pcs vfy ms | pcs bits | total bits | notes |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| hash.tri | WHIR 1/64 k=4 pow=20 fin=6 | 2^10 | 2^10 | 16113 | 16340 | 2592 | 13476 | 685.0 | 6.420 | 2.974 | 2.236 | 128.11 | 128.11 | |
| hash.tri | WHIR 1/64 k=4 pow=20 fin=8 | 2^10 | 2^10 | 16145 | 16372 | 2592 | 13508 | 51.3 | 7.711 | 3.601 | 2.210 | 128.11 | 128.11 | |
| hash.tri | WHIR 1/32 k=4 pow=20 fin=8 | 2^10 | 2^10 | 16177 | 16404 | 2592 | 13540 | 760.0 | 7.137 | 3.297 | 2.165 | 128.05 | 128.05 | |
| hash.tri | WHIR 1/64 k=4 pow=16 fin=8 | 2^10 | 2^10 | 16337 | 16564 | 2592 | 13700 | 80.2 | 7.208 | 3.618 | 2.365 | 128.08 | 128.08 | |
| hash.tri | WHIR 1/64 k=4 pow=16 fin=6 | 2^10 | 2^10 | 16529 | 16756 | 2592 | 13892 | 56.6 | 7.802 | 3.643 | 2.329 | 128.08 | 128.08 | |
| chain-11 (hemera) | WHIR 1/64 k=4 pow=20 fin=8 | 2^15 | 2^15 | 43293 | 44205 | 3792 | 39456 | 2007.8 | 142.608 | 14.372 | 5.951 | 128.11 | 128.11 | |
| chain-11 (hemera) | WHIR 1/64 k=4 pow=16 fin=8 | 2^15 | 2^15 | 44189 | 45101 | 3792 | 40352 | 982.9 | 149.198 | 14.410 | 6.045 | 128.08 | 128.08 | |
| chain-11 (hemera) | WHIR 1/32 k=4 pow=20 fin=8 | 2^15 | 2^15 | 45373 | 46285 | 3792 | 41536 | 2182.4 | 139.504 | 14.076 | 6.325 | 128.05 | 128.05 | |
| chain-11 (hemera) | WHIR 1/32 k=4 pow=16 fin=8 | 2^15 | 2^15 | 47101 | 48013 | 3792 | 43264 | 665.2 | 139.564 | 13.496 | 5.790 | 128.01 | 128.01 | |
| chain-11 (hemera) | WHIR 1/16 k=4 pow=20 fin=8 | 2^15 | 2^15 | 49373 | 50285 | 3792 | 45536 | 2809.7 | 133.313 | 15.137 | 6.090 | 128.01 | 128.01 | |
| synthetic 2^16 | WHIR 1/64 k=4 pow=20 fin=8 | 2^16 | 2^16 | 48173 | — | 4032 | 44096 | 2028.9 | 15.190 | 15.190 | 6.395 | 128.11 | 128.11 | |
| synthetic 2^16 | WHIR 1/64 k=4 pow=16 fin=8 | 2^16 | 2^16 | 49805 | — | 4032 | 45728 | 1582.2 | 17.375 | 17.375 | 6.261 | 128.08 | 128.08 | |
| synthetic 2^16 | WHIR 1/32 k=4 pow=20 fin=8 | 2^16 | 2^16 | 51565 | — | 4032 | 47488 | 1089.1 | 17.897 | 17.897 | 7.035 | 128.05 | 128.05 | |
| synthetic 2^16 | WHIR 1/64 k=5 pow=20 fin=8 | 2^16 | 2^16 | 52829 | — | 4032 | 48752 | 1452.8 | 17.087 | 17.087 | 6.470 | 128.08 | 128.08 | |
| synthetic 2^16 | WHIR 1/64 k=5 pow=20 fin=6 | 2^16 | 2^16 | 52925 | — | 4032 | 48848 | 2161.9 | 16.564 | 16.564 | 6.459 | 128.08 | 128.08 | |
| synthetic 2^20 | WHIR 1/64 k=4 pow=20 fin=8 | 2^20 | 2^20 | 74153 | — | 4992 | 69116 | 28444.2 | 244.778 | 244.778 | 9.705 | 128.11 | 128.11 | |
| synthetic 2^20 | WHIR 1/64 k=4 pow=16 fin=8 | 2^20 | 2^20 | 77097 | — | 4992 | 72060 | 26043.9 | 245.811 | 245.811 | 9.992 | 128.50 | 128.50 | |
| synthetic 2^20 | WHIR 1/32 k=4 pow=20 fin=8 | 2^20 | 2^20 | 78249 | — | 4992 | 73212 | 19630.4 | 268.880 | 268.880 | 10.837 | 128.01 | 128.01 | |
| synthetic 2^20 | WHIR 1/32 k=4 pow=16 fin=8 | 2^20 | 2^20 | 80969 | — | 4992 | 75932 | 17412.1 | 245.429 | 245.429 | 11.168 | 128.01 | 128.01 | |
| synthetic 2^20 | WHIR 1/64 k=5 pow=20 fin=6 | 2^20 | 2^20 | 81041 | — | 4992 | 76004 | 37082.3 | 261.189 | 261.189 | 8.306 | 128.08 | 128.08 |
Grinding 24 at the two best rates:
| fixture | pcs | n (committed) | rows | proof B | envelope B | spartan B | opening B | prove ms | verify ms | vfy-rel ms | pcs vfy ms | pcs bits | total bits | notes |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| hash.tri | WHIR 1/32 k=4 pow=20 fin=8 | 2^10 | 2^10 | 16177 | 16404 | 2592 | 13540 | 754.5 | 8.091 | 3.719 | 2.309 | 128.05 | 128.05 | t=[44] siblings 195 (full paths 473, dedup saves 8896 B); u32 prefixes 9 (36 B); 2015 limbs: fixed 16120 B vs varint 18985 B |
| hash.tri | WHIR 1/32 k=4 pow=24 fin=8 | 2^10 | 2^10 | 16369 | 16596 | 2592 | 13732 | 9815.4 | 8.230 | 3.765 | 2.309 | 128.03 | 128.03 | t=[42] siblings 204 (full paths 462, dedup saves 8256 B); u32 prefixes 9 (36 B); 2035 limbs: fixed 16280 B vs varint 19154 B |
| hash.tri | WHIR 1/64 k=4 pow=20 fin=8 | 2^10 | 2^10 | 16145 | 16372 | 2592 | 13508 | 54.8 | 7.963 | 3.644 | 2.291 | 128.11 | 128.11 | t=[37] siblings 218 (full paths 444, dedup saves 7232 B); u32 prefixes 9 (36 B); 2011 limbs: fixed 16088 B vs varint 18948 B |
| hash.tri | WHIR 1/64 k=4 pow=24 fin=8 | 2^10 | 2^10 | 15921 | 16148 | 2592 | 13284 | 1623.3 | 6.721 | 2.935 | 2.020 | 128.00 | 128.00 | t=[35] siblings 218 (full paths 420, dedup saves 6464 B); u32 prefixes 9 (36 B); 1979 limbs: fixed 15832 B vs varint 18643 B |
| chain-11 (hemera) | WHIR 1/32 k=4 pow=20 fin=8 | 2^15 | 2^15 | 45373 | 46285 | 3792 | 41536 | 2053.1 | 140.405 | 13.635 | 5.803 | 128.05 | 128.05 | t=[44 28] siblings 672 (full paths 1124, dedup saves 14464 B); u32 prefixes 16 (64 B); 5656 limbs: fixed 45248 B vs varint 53126 B |
| chain-11 (hemera) | WHIR 1/32 k=4 pow=24 fin=8 | 2^15 | 2^15 | 44285 | 45197 | 3792 | 40448 | 35305.2 | 144.238 | 13.511 | 6.043 | 128.03 | 128.03 | t=[42 27] siblings 658 (full paths 1077, dedup saves 13408 B); u32 prefixes 16 (64 B); 5520 limbs: fixed 44160 B vs varint 51802 B |
| chain-11 (hemera) | WHIR 1/64 k=4 pow=20 fin=8 | 2^15 | 2^15 | 43293 | 44205 | 3792 | 39456 | 1985.2 | 151.503 | 13.217 | 5.976 | 128.11 | 128.11 | t=[37 25] siblings 670 (full paths 1029, dedup saves 11488 B); u32 prefixes 16 (64 B); 5392 limbs: fixed 43136 B vs varint 50652 B |
| chain-11 (hemera) | WHIR 1/64 k=4 pow=24 fin=8 | 2^15 | 2^15 | 41405 | 42317 | 3792 | 37568 | 36434.8 | 149.072 | 14.155 | 5.644 | 128.00 | 128.00 | t=[35 24] siblings 631 (full paths 979, dedup saves 11136 B); u32 prefixes 16 (64 B); 5156 limbs: fixed 41248 B vs varint 48368 B |
| synthetic 2^16 | WHIR 1/32 k=4 pow=20 fin=8 | 2^16 | 2^16 | 51565 | — | 4032 | 47488 | 1127.7 | 18.520 | 18.520 | 7.058 | 128.05 | 128.05 | t=[44 28] siblings 761 (full paths 1196, dedup saves 13920 B); u32 prefixes 16 (64 B); 6426 limbs: fixed 51408 B vs varint 60963 B |
| synthetic 2^16 | WHIR 1/32 k=4 pow=24 fin=8 | 2^16 | 2^16 | 50029 | — | 4032 | 45952 | 8644.3 | 17.809 | 17.809 | 6.757 | 128.03 | 128.03 | t=[42 27] siblings 733 (full paths 1146, dedup saves 13216 B); u32 prefixes 16 (64 B); 6234 limbs: fixed 49872 B vs varint 59086 B |
| synthetic 2^16 | WHIR 1/64 k=4 pow=20 fin=8 | 2^16 | 2^16 | 48173 | — | 4032 | 44096 | 2120.1 | 18.838 | 18.838 | 6.589 | 128.11 | 128.11 | t=[37 25] siblings 719 (full paths 1091, dedup saves 11904 B); u32 prefixes 16 (64 B); 6002 limbs: fixed 48016 B vs varint 56963 B |
| synthetic 2^16 | WHIR 1/64 k=4 pow=24 fin=8 | 2^16 | 2^16 | 47245 | — | 4032 | 43168 | 39846.0 | 21.339 | 21.339 | 6.339 | 128.00 | 128.00 | t=[35 24] siblings 710 (full paths 1038, dedup saves 10496 B); u32 prefixes 16 (64 B); 5886 limbs: fixed 47088 B vs varint 55881 B |
| synthetic 2^20 | WHIR 1/32 k=4 pow=20 fin=8 | 2^20 | 2^20 | 78249 | — | 4992 | 73212 | 19702.5 | 231.956 | 231.956 | 9.061 | 128.01 | 128.01 | t=[44 28 20] siblings 1315 (full paths 1864, dedup saves 17568 B); u32 prefixes 23 (92 B); 9753 limbs: fixed 78024 B vs varint 92614 B |
| synthetic 2^20 | WHIR 1/32 k=4 pow=24 fin=8 | 2^20 | 2^20 | 76521 | — | 4992 | 71484 | 61135.6 | 226.861 | 226.861 | 8.672 | 128.15 | 128.15 | t=[43 27 20] siblings 1277 (full paths 1823, dedup saves 17472 B); u32 prefixes 23 (92 B); 9537 limbs: fixed 76296 B vs varint 90446 B |
| synthetic 2^20 | WHIR 1/64 k=4 pow=20 fin=8 | 2^20 | 2^20 | 74153 | — | 4992 | 69116 | 43245.4 | 230.922 | 230.922 | 9.496 | 128.11 | 128.11 | t=[37 25 19] siblings 1263 (full paths 1719, dedup saves 14592 B); u32 prefixes 23 (92 B); 9241 limbs: fixed 73928 B vs varint 87632 B |
| synthetic 2^20 | WHIR 1/64 k=4 pow=24 fin=8 | 2^20 | 2^20 | 71081 | — | 4992 | 66044 | 78916.4 | 232.178 | 232.178 | 8.018 | 128.24 | 128.24 | t=[36 24 18] siblings 1195 (full paths 1656, dedup saves 14752 B); u32 prefixes 23 (92 B); 8857 limbs: fixed 70856 B vs varint 84137 B |
(The 2^20 grinding rows were measured while the zheng test suite ran concurrently; their times are noisier than the rest, their sizes are exact.)
4. decision
Rule (work package): per class, the smallest proof with ≥ 128 proven bits.
| class | winner | hash.tri | chain-11 (2^15) |
synthetic 2^16 |
synthetic 2^20 |
|---|---|---|---|---|---|
small (ℓ ≤ 16) |
WHIR, rate 1/64, k = 4, grinding 24, final ≤ 2^8 | 15,921 B proof · 16,148 B envelope | 41,405 B proof · 42,317 B envelope | 47,245 B | — |
large (ℓ > 16) |
the same | — | — | — | 71,081 B |
Within the small class TensorRs still wins at 2^4 (add.tri: 1,425 B against
5,607 B for the shipped WHIR parameters); the class winner is the scheme that is
smallest on the class's statements that matter (hash.tri, the hash chain, the
2^14/2^16 relations) and in total. Both classes chose the same
configuration; it is shipped as
succinct::params_for / prove_default and used by joy prove --succinct.
TensorRs loses every size above 2^4 and is the bake-off loser (proposal §7:
deleted in phase 5; it stays decodable under id 2 until then). Grinding 24
costs prover time: a proof takes seconds at 2^10 and 40–90 s at 2^15–2^20
(§3 and the table below). Grinding 20 gives +224 B at hash.tri, +3.1 KB at
2^20 for a fraction of that time; the rule as stated picks 24.
Shipped choice on every fixture (command … -- chosen 3, load 11.3 at the start, 19.0 at the end):
| fixture | pcs | n (committed) | rows | proof B | envelope B | spartan B | opening B | prove ms | verify ms | vfy-rel ms | pcs vfy ms | pcs bits | total bits | notes |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| add.tri | WHIR 1/64 k=4 pow=24 fin=8 (small) | 2^4 | 2^4 | 5433 | 5607 | 624 | 4764 | 265.0 | 1.235 | 1.208 | 0.772 | 128.00 | 128.00 | t=[35] siblings 24 (full paths 174, dedup saves 4800 B); u32 prefixes 9 (36 B); 672 limbs: fixed 5376 B vs varint 6336 B |
| hash.tri | WHIR 1/64 k=4 pow=24 fin=8 (small) | 2^10 | 2^10 | 15921 | 16148 | 2592 | 13284 | 1727.8 | 7.955 | 3.647 | 2.134 | 128.00 | 128.00 | t=[35] siblings 218 (full paths 420, dedup saves 6464 B); u32 prefixes 9 (36 B); 1979 limbs: fixed 15832 B vs varint 18643 B |
| chain-11 (hemera) | WHIR 1/64 k=4 pow=24 fin=8 (small) | 2^15 | 2^15 | 41405 | 42317 | 3792 | 37568 | 36313.4 | 142.290 | 13.300 | 5.343 | 128.00 | 128.00 | t=[35 24] siblings 631 (full paths 979, dedup saves 11136 B); u32 prefixes 16 (64 B); 5156 limbs: fixed 41248 B vs varint 48368 B |
| synthetic 2^10 | WHIR 1/64 k=4 pow=24 fin=8 (small) | 2^10 | 2^10 | 15441 | — | 2592 | 12804 | 1353.0 | 2.796 | 2.796 | 2.123 | 128.00 | 128.00 | t=[35] siblings 203 (full paths 420, dedup saves 6944 B); u32 prefixes 9 (36 B); 1919 limbs: fixed 15352 B vs varint 18177 B |
| synthetic 2^14 | WHIR 1/64 k=4 pow=24 fin=8 (small) | 2^14 | 2^14 | 38189 | — | 3552 | 34592 | 6134.6 | 7.370 | 7.370 | 5.183 | 128.00 | 128.00 | t=[35 24] siblings 586 (full paths 920, dedup saves 10688 B); u32 prefixes 16 (64 B); 4754 limbs: fixed 38032 B vs varint 45135 B |
| synthetic 2^16 | WHIR 1/64 k=4 pow=24 fin=8 (small) | 2^16 | 2^16 | 47245 | — | 4032 | 43168 | 37906.1 | 17.814 | 17.814 | 5.330 | 128.00 | 128.00 | t=[35 24] siblings 710 (full paths 1038, dedup saves 10496 B); u32 prefixes 16 (64 B); 5886 limbs: fixed 47088 B vs varint 55881 B |
| synthetic 2^18 | WHIR 1/64 k=4 pow=24 fin=8 (large) | 2^18 | 2^18 | 61545 | — | 4512 | 56988 | 34219.9 | 65.954 | 65.954 | 8.396 | 128.00 | 128.00 | t=[35 24 18] siblings 1060 (full paths 1480, dedup saves 13440 B); u32 prefixes 23 (92 B); 7665 limbs: fixed 61320 B vs varint 72711 B |
| synthetic 2^20 | WHIR 1/64 k=4 pow=24 fin=8 (large) | 2^20 | 2^20 | 71081 | — | 4992 | 66044 | 60263.8 | 270.499 | 270.499 | 9.842 | 128.24 | 128.24 | t=[36 24 18] siblings 1195 (full paths 1656, dedup saves 14752 B); u32 prefixes 23 (92 B); 8857 limbs: fixed 70856 B vs varint 84137 B |
5. against the goals
| goal (proposal §0) | measured | verdict |
|---|---|---|
| small ≤ 16 KB stretch / ≤ 20 KB | hash.tri: 15,921 B proof, 16,148 B envelope (15.77 KiB); the envelope is under 16 KiB (16,384 B) and over 16.0 kB (16,000 B) | ≤ 20 KB met; 16 KB met in KiB, missed by 148 B in kB |
large n = 2^20 ≤ 64 KB |
71,081 B (69.4 KiB) | missed by 7.1 KB (11 %) |
| verify ≤ 1 ms | shipped choice (§4 table): hash.tri 7.96 ms = relation compile 4.3 + Spartan 1.5 + opening 2.1; 2^20 270 ms = Spartan ~260 + opening 9.8 |
missed at every size above add.tri (1.2 ms) |
| ≥ 128 bits proven | 128.00 (hash.tri) … 128.24 (2^20), PCS-limited; Spartan ≤ 2^-184 |
met |
The verify-time miss has three separate causes, measured separately above:
(1) the opening — Merkle paths and WHIR's checks in hemera, 2.1 ms at hash.tri
and 9.8 ms at 2^20 (≈ 480 and 2,200 permutations at lens's measured
4.43 µs each); the 1 ms goal needs hemera ~2–10× faster (being optimised
separately); (2) the
Spartan verifier evaluates Σ γ^i M̃_i(ρ_x, r) over every nonzero of an
unstructured relation — O(nnz + n) Fp3 work, ~1.5 ms at 2^10 and ~260 ms
at 2^20 — which only a structured (uniform-step) relation or a sparse-matrix
commitment removes (phase 3); (3) recompiling the relation from the program
(4.3 ms for hash.tri, 129 ms for chain-11), which a cached vk digest would
skip. None of the three is hidden in the numbers above.
For scale: the public v3 certificate of the same hash.tri statement is
6,463 B (joy CLI test), because the 810 free witness values travel as varints
and are checked directly. At 2^10 a committed witness is larger than a
disclosed one; the succinct profile pays off from ~2^12 on and is the only
option when the witness must not travel (and, with VEIL in phase 4, when it
must stay hidden).
6. soundness tests
- completeness on add.tri (two inputs), hash.tri (two inputs), chain-11 and
synthetic
2^10under both schemes; state statements under WHIR; - forged input, output, extra output, cycles (±1), budget and program are
rejected; a valid proof of each of five statements verifies only for its
own statement (25 pairs); tampered
w̃(r'), every matrix evaluation, an outer and an inner round, the root and the parameters are rejected; a zeroed constant pin and a moved output pin are rejected; - parameters below policy are refused by prover and verifier (a target of 96
or 100, and any set with < 128 proven bits at the proof's
ℓ); - state: a wrong read value, a missing read, a forged statement with a matching forged certificate, each of four root limbs, and the context;
- determinism: identical envelopes from repeated proving under both schemes;
- bit-flip scan over the full serialized envelope of hash.tri (input 7),
every bit of every byte flipped and decoded + verified:
WHIR (lens defaults, 18,164 B): 145,312 flips, 0 accepted; TensorRs
(lens defaults, 24,974 B): 199,792 flips, 0 accepted (328.6 s for both
on 16 cores;
tests/succinct_bitflip.rs, the TensorRs scan is--ignoredby default).
Test commands: cargo test --release -p zheng and --features serde (all
green, 189 / 193 library tests plus integration suites), joy cargo test --workspace --release --locked (green).
7. not done
- zip (eprint 2025/1446): not implemented; no gain is claimed.
- Spartan outer-round trick that sends the round polynomial without its
eq(τ, ·)factor (one Fp3 coefficient per outer round, ~240 B at2^10): not done — it changes the IOP transcript shared with the retired v2 reader. - lens wire: the implied u32 length prefixes stay (≤ 92 B).
- the 64 KB large-class goal and the 1 ms verify goal (§5).
- a Merkle-32 path fixture: none exists; a 32-hash chain exceeds the relation compiler's 32,768-row cap (chain-11 measured instead).
- state statements in
joy prove --succinct: the CLI refuses--state; zheng proves and verifies succinct state statements (succinct::prove_state/verify_state, envelope profile 1 kind 1) but joy'sJOYST002wraps only the profile-3 envelope.