Skip to content

perf(keccak): inline HWSL shifts as linear identities (−6.8% pure-keccak prover time, z3-verified)#860

Draft
MauroToscano wants to merge 3 commits into
mainfrom
feat/keccak-hwsl-inline
Draft

perf(keccak): inline HWSL shifts as linear identities (−6.8% pure-keccak prover time, z3-verified)#860
MauroToscano wants to merge 3 commits into
mainfrom
feat/keccak-hwsl-inline

Conversation

@MauroToscano

Copy link
Copy Markdown
Contributor

What

Replace the 120 HWSL bus sends per KECCAK_RND row (θ rotate-by-1: 20, ρ shifts: 100) with μ-gated degree-2 linear identities over the same committed cells:

in · 2^rnc = right · 2^16 + left

All existing IS_BYTE (AreBytes) and IS_BIT checks are kept — they become load-bearing: given left, right ∈ [0, 2^16), the pair is the unique Euclidean quotient/remainder of in · 2^rnc ÷ 2^16 (values < 2^32 ≪ p, so field semantics = integer semantics). A shift by a compile-time constant is field-linear, so the lookup bought nothing the identity doesn't — it only paid LogUp aux.

  • Sends/row: 1151 → 1031 (HWSL → 0) ⇒ −60 aux extension columns = −180 committed base cells/row (~4.3k/permutation), zero new columns
  • Constraints: 20 → 140, all degree ≤ 3 (max_degree() unchanged)
  • spec/src/keccak_round_hwsl_inline.toml: alternative chip spec for this variant (original left untouched)
  • Not wire-identical (aux layout shrinks) — old proofs verify with old verifier, new with new

Formal verification (z3)

thoughts/keccak-hwsl-inline/ contains the full SMT gate + logs:

  • Baseline gate: free-variable model of the current circuit (bus interactions as chip contracts + eval constraints); asserting output ≠ FIPS-202 reference round is UNSAT for all 24 round indices. Positive control: constraints uniquely pin the output (UNSAT not vacuous). Negative controls: 9 injected bugs (dropped rotate, swapped ρ offsets, mangled χ, dropped RC, dropped carry pinning, …) — all correctly SAT.
  • Rewrite gate: HWSL contracts replaced by the linear identities + only the range checks that exist in the circuit → UNSAT for all 24 rounds (equivalent). Bound necessity proven in an Int-mod-p model (bitvectors can't test this — 2^16 is a zero divisor mod 2^64 but invertible mod p): dropping any range bound or IS_BIT yields a concrete forgery witness (SAT).
  • Coverage audit: every left/right halfword's 16-bit bound traces to an existing check — zero new sends needed.

Bench

Pure-keccak guest (5000 keccak-f syscalls, single-epoch continuation proof), 32-core box, alternated A/B ×4 after warm-up:

prover time (s) median
main 13.988 13.948 13.976 14.398 13.982
this PR 13.083 12.971 13.334 12.855 13.027

−6.8% median (−7.2% mean), distributions disjoint (cv ≈ 1.3%). keccak_rnd = 86.6% of committed cells in this bench; measured committed-cell delta 5.61% matches the predicted −180 cells/row; implied wall-time table delta ≈ 7.9% (beats the cell prediction — the removed cells are all cubic-extension aux). Expected real-workload gain ≈ 7.9% × keccak_rnd's share of committed cells.

Happy to run /bench-abba on the bench server for the real-block number if wanted.

Tests

  • check_table keccak_rnd: prover folder ≡ verifier folder ≡ IR interpreter; 140 constraints, every one measured degree ≤ 3
  • Updated test_keccak_constraint_counts, test_keccak_bitwise_ops_count (HWSL 2880 → 0), test_keccak_bus_interaction_counts
  • e2e: test_prove_elfs_keccak, _keccak_multi_call (tiny-keccak cross-check), _unaligned_state_addr (tamper still rejected), IR/window-capture agreement tests
  • make lint clean

…120 HWSL sends/row

Replace the keccak_rnd θ rotate-by-1 (20/row) and ρ (100/row) HWSL bus
lookups with inline μ-gated linear identities over the same committed
shift cells:

    μ · (in · 2^rnc − right · 2^16 − left) = 0    (degree 2)

Uniqueness of the (left, right) decomposition rests on the existing
ARE_BYTES range checks bounding both halves to [0, 2^16) and on 2^16
being invertible mod the Goldilocks prime; the θ IS_BIT carry constraint
is now load-bearing. Equivalence to the HWSL contract was z3-verified
(all 24 rounds UNSAT under the rewrite; bound-necessity confirmed).

Removing the 120 sends/row cuts the LogUp aux width by 3·⌈120/2⌉ = 180
base cells/row (~5.6% of the keccak_rnd table's committed cells) with no
new columns. The matching HWSL multiplicities are dropped on the BITWISE
side (collect_bitwise_from_keccak). max_degree stays 3; constraint count
20 → 140. Witness values are unchanged (same cells, same values).
…idence

Add spec/src/keccak_round_hwsl_inline.toml as an alternative KECCAK_RND
specification with the 120 HWSL interactions replaced by mu-gated linear
identities (in * 2^rnc = right * 2^16 + left), and thoughts/keccak-hwsl-inline/
with the z3 gate that proves the rewrite equivalent (UNSAT x24 rounds), the
bound-necessity proofs (dropping any range check yields a forgery witness),
the negative/positive controls, and the pure-keccak bench methodology
(-6.8% prover time, 5000-permutation single-epoch continuation proof).
Wire keccak_round_hwsl_inline.toml into keccak.typ as an explicit alternative
section (variables + changed theta/rho constraint groups; chi/iota/io are
identical to KECCAK_RND), with the Euclidean-uniqueness soundness argument in
prose. Rename the variant's constraint refs to keccak:c:inline_* to avoid
duplicate labels with the original chip. The spec machinery independently
derives KECCAK_RND_HWSL_INLINE = 1251 interactions vs KECCAK_RND = 1371,
confirming the -120 HWSL sends.
@MauroToscano
MauroToscano marked this pull request as draft July 23, 2026 20:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant