Skip to content
Oumuamua Labs

Hekate v0.31.0

Released Source v0.31.0 Mandatory upgrade
On this page

The Brakedown row code is now a true MDS Reed-Solomon code over an additive binary-field FFT, replacing a sparse expander whose minimum distance was capped at the generator's column weight. That cap was exploitable: a codeword-aware forgery against the real prove/verify pipeline accepted at up to 54% per attempt. It now accepts at <= 2^-128 as a Singleton bound, not a heuristic, and the verifier enforces 128 bits for the main trace and every chiplet at its own geometry. The evaluation argument is rebuilt on ring-switching, which lets whole-column MDS proximity coexist with virtual bit-packing, and zero-knowledge moves from appended noise columns to a random support block inside the message. Wire format, transcript schedule, and Config all change: 0.30.0 proofs and bundles no longer verify. Pair with the signed prover cdylib 0.8.0. Upgrade is mandatory for any deployment relying on the 128-bit security claim.

§ Soundness

  • MDS row code. Each committed row encodes as Reed-Solomon over the additive-FFT subspace chain (hekate-math 0.9.0), rate 1/inv_rate (default 1/2). Relative distance is exact Singleton, δ = (encoded_width − support − grid_cols) / encoded_width, in place of the expander's column-weight heuristic; the proximity bound (1−δ)^q holds with num_queries = 176.
  • Per-table security gate. check_security now gates every table, main plus each chiplet, at its own grid_cols. Any table whose geometry delivers fewer than 128 bits is rejected before verification proceeds.
  • Adaptive geometry. Config::table_geom picks per table: fractional support (encoded_width = grid_cols · inv_rate, ~+0% RAM) where the grid is wide enough, full-half fallback (δ = 0.5, wider codeword on that table only) where it is not. Small tables such as the ML-DSA chiplets, too narrow to host a 176-symbol support fractionally, keep guaranteed hiding at full distance.
  • Verifier hardening. The evaluator rejects claim vectors that disagree with the ring-switch plan, and opened columns must match the physical row layout exactly.
  • The verifier's encoder is hekate-math's AdditiveFft: field arithmetic and FFT level passes machine-checked upstream (Verus, 1865 obligations, 0 errors).

§ Ring-switched evaluation

Virtual bit-packing survives the code change. Bit extraction does not commute with RS scaling, hence the proximity check no longer folds virtual columns: a ring-switch sumcheck (Diamond-Posen 2024/504, Construction 3.1) reduces each packed column's bit-plane claims to one whole-column claim first, and proximity folds whole physical columns, which does commute. The proof gains a second folded opening (tensor_vec_ring); the transcript gains a post-claims bit-mixing challenge that binds every bit-plane by Schwartz-Zippel. Committed cells follow rs_field widths: Bit/B8/B16 columns commit as B32, wider columns commit native.

§ Zero knowledge

The encode is non-systematic: no committed column ever contains cleartext witness symbols. A random support block of ldt_support_size symbols (default 200, floor num_queries) rides inside the message at coordinates disjoint from the data, making any num_queries opened columns jointly uniform; the evaluation claim reads the data half alone, hence the support cancels and costs no soundness. The witness-leak detectors in the adversarial suite scan every opened byte and pass, with a planted-needle positive control validating the scan itself.

§ Prover speedups

Cdylib 0.8.0 ships three prover-internal levers landed after 0.30.0: the small-value sumcheck rounds skip polynomials they never read, round-poly interpolation point-steps via the char-2 XOR identity, and LogUp batch inversion runs chunk-parallel. Together 15-29% faster than 0.30.0 across the matrix, proof bytes untouched.

§ Performance

Signed public cdylib 0.8.0, table-math, Apple M3 Max, -C target-cpu=native. Peak memory is phys_footprint_peak.

WorkloadProveVerifyPeak memProof
ML-KEM-768893 ms17.53 ms612 MiB3.31 MB
ML-DSA-441.50 s22.18 ms557 MiB4.50 MB
ML-DSA-651.56 s22.16 ms598 MiB4.54 MB
ML-DSA-872.69 s28.46 ms1.11 GiB6.00 MB
AES-1282.01 s14.14 ms1.55 GiB6.40 MB
AES-2562.11 s15.86 ms1.96 GiB7.13 MB
keccak_inline 2^15323 ms5.62 ms181 MiB0.96 MB
keccak_inline 2^207.78 s10.81 ms3.41 GiB4.68 MB
keccak_inline 2^24155.4 s70.72 ms45.0 GiB18.42 MB

The speedup program bought 15-29% below 0.30.0; the MDS encode spent it back where commit dominates. Net against 0.30.0 every workload proves faster (keccak 2^20 -28%, PQC and fibonacci -6 to -14%) except AES (+17-20%). Real distance is paid in memory and proof size: peak memory 1.3-1.9x, proofs +20-60% with AES at 2.3-2.4x, the most commit-bound workload with the largest chiplet tables. Verify stays flat, 5.6-71 ms from 2^15 to 2^24 rows. The keccak 2^24 row is a lower bound measured under memory pressure on a 48 GiB host.

§ Removed

  • The sparse expander generator: expander_matrix.rs, the expander feature, and its aes/rand dependencies leave hekate-crypto.
  • Config::expansion_degree and Config::matrix_seed, with their wire fields and transcript absorption. The row code is deterministic; there is no matrix to seed.

§ Breaking

  • Proofs and bundles. Wire format version 2 and a changed transcript schedule: 0.30.0 proofs and bundles neither verify nor deserialize. Re-prove against this release.
  • Config. inv_rate (default 2) and ldt_support_size (renamed from ldt_blinding_factor, default 200) replace expansion_degree and matrix_seed; security estimation takes the table's grid_cols.
  • hekate-math 0.9.0 (from crates.io): Bit is a sealed GF(2) newtype, construct with Bit::new/try_new and read with get; TraceCompatibleField requires BinaryFieldExtras.
  • Prover cdylib 0.8.0, signed (SHA-256, Ed25519, ML-DSA-65). Pair it with this release; an older cdylib emits proofs this verifier rejects.
  • program_id is unchanged. Program definitions are untouched; only proofs are re-emitted.
  • Version. Workspace 0.30.0 -> 0.31.0; hekate-keccak and hekate-aes 0.4.0, hekate-pqc 0.5.0.