Skip to content
Oumuamua Labs

Hekate v0.32.0

Released Source v0.32.0 Mandatory upgrade
On this page

Two verifier soundness fixes. The LogUp fraction helper h was never committed: a prover fits its evaluation after r_final is drawn, the final check collapses to 0 = 0, and every constraint on the table, AIR and boundary as well as bus, goes unenforced. Deterministic, not probabilistic, and it reaches every table carrying a permutation or lookup bus. Separately, a table declaring no bus could inject an unbound claimed_sums entry into cross-bus matching and forge cancellation in characteristic two. Wire format moves to v3; 0.31.0 proofs are rejected. Pair with the signed prover cdylib 0.9.0. Upgrade is mandatory.

Full analysis of both gaps, and of the 0.31.0 row-code break they follow: postmortem.

§ Soundness

  • h is committed and opened. Every bus-carrying table now carries a Brakedown commitment to h. The verifier absorbs its root before α, binding the ZeroCheck challenges to it, opens h at r_final, and rejects unless every reported h_eval equals the opened value. The affine bus term now runs on a bound scalar. No algebraic shortcut exists: h(r_final) is rational in the trace, and a polynomial commitment is mandatory.
  • Presence is checked against the trusted bus specs. h_commitment and h_eval_proof are Some exactly when the table declares a bus, and the commitment's num_rows/num_cols must match the table height and bus count. Dropping the binding fails, it is not ignored.
  • The h opening inherits the full 0.31.0 posture. Its geometry runs the same per-table check_security gate at its own grid_cols, and hiding comes from the same codeword blind.
  • Zero-bus tables present empty LogUp aux. The claimed_sums and h_evals length and bus_id ordering checks moved out of the if !bus_specs.is_empty() guard, closing the injection term before cross-bus matching. Verifier-only, no proof bytes change.

§ Base-only h opening

h has no transition constraint. Its opening carries base columns only. EvalVerifyContext gains next_row: false parses one value per committed column and folds the base claim alone, halving the opened row width. The opening scales with sqrt(row_bytes), which buys about 1.4x on the binding, not 2x. The trace opening is unchanged.

§ Performance

Signed public cdylib 0.9.0, table-math, Apple M3 Max, -C target-cpu=native, quiesced host. Peak memory is phys_footprint_peak. PQC and AES are the mean of three runs.

WorkloadProveVerifyPeak memProof
ML-KEM-768919 ms23.6 ms556 MiB4.35 MB
ML-DSA-441.60 s29.2 ms603 MiB5.69 MB
ML-DSA-651.66 s29.5 ms566 MiB5.71 MB
ML-DSA-872.95 s35.1 ms1.25 GiB7.71 MB
AES-1282.08 s18.2 ms1.59 GiB7.48 MB
AES-2562.27 s18.3 ms2.01 GiB8.21 MB
keccak_inline 2^15323 ms6.1 ms175 MiB1.08 MB
keccak_inline 2^207.58 s13.1 ms3.51 GiB5.32 MB

Against 0.31.0: proof +14 to 32%, verify +9 to 35%, prove within ±10%, peak memory flat. The binding scales with bus count, not trace width: 24% of the ML-KEM proof, 21% ML-DSA-65, 15% AES-128, 12% keccak 2^20. keccak_inline 2^24 was not re-measured.

§ Breaking

  • Proofs and bundles. WIRE_PROOF_VERSION 2 to 3. v2 proofs are rejected and must be re-proved. LogUpAux gains nullable h_commitment and h_eval_proof.
  • EvalVerifyContext gains next_row; opened_row_bytes takes it as a third argument and opened_row_bytes_variants is removed.
  • Prover cdylib 0.9.0, signed (SHA-256, Ed25519, ML-DSA-65). An older cdylib emits proofs this verifier rejects.
  • Config and program_id are unchanged. Only proofs are re-emitted.
  • Version. Workspace 0.31.0 -> 0.32.0; hekate-keccak and hekate-aes 0.5.0, hekate-pqc 0.6.0.