Prove AES-128 and AES-256 encryption in zero knowledge, key expansion included, with the key kept private and constant-time trace generation by default.
The AES chiplet proves FIPS 197 block encryption with AES-128 and AES-256: for every block, the ciphertext is the
encryption of the block's input under the key, key expansion included.
The round table implements the FIPS 197 round function, SubBytes, ShiftRows, MixColumns and AddRoundKey, as a
binary-field AIR. Its SubBytes values come from an S-box ROM table that proves the GF(2^8) inversion and the affine
map, and the key schedule, SubWord included, is constrained in the round AIR itself. The host program sends each
block's input and its key to the round table over LogUp buses and receives the ciphertext. A block's input is its
plaintext XORed with round key 0, the first AddRoundKey, which the chiplet does not check: the host program must.
The host program decides what becomes public. The README's Usage section publishes nothing, and the ML-KEM
sender publishes a message and its AES-256-CTR ciphertext while the key stays private.
Without table-math, the default, trace generation never indexes a table with a secret. The S-box is field
arithmetic, the GF(2^8) inverse x²⁵⁴ followed by the FIPS 197 affine map, with no key-dependent index, branch or
memory access, which keeps the key out of reach of cache-timing observation.
hekate/examples/aes.rs proves and verifies AES-128 or AES-256 over a run of blocks, at the key size
HEKATE_LEVEL selects. From a hekate checkout:
bash
HEKATE_LEVEL=256just example aes public # 128 | 256
public builds the variable-time table-math prover that the README's measurements use. Without it the recipe builds
the constant-time prover, the one to use when the witness is private.
The program below turns the example into a statement a verifier can use: one AES-128 key, kept private, encrypts each
of four published plaintext blocks to its published ciphertext block. Block 0 is the FIPS 197 Appendix B example. The
program takes three files:
src/program.rs attaches the round table and the S-box ROM, keeps the key unchanged on every host row, constrains
each block's input to its plaintext XOR the key (the first AddRoundKey) and publishes every plaintext and
ciphertext block.
src/trace.rs expands the key, reads the ciphertexts from the round table and fills the host table.
src/main.rs proves and verifies.
Start from the crates in Installation and add hekate-aes and rand.
Zero-knowledge proofs, measured on Apple M3 Max, 16 cores. Build: --release, std parallel blake3 table-math public. Best of three on an otherwise idle machine. The Benchmarks page has the base-protocol figures and the command for each run.
The crate has not been audited and may contain bugs and security flaws, as its README states. Hekate proves 100 bits
of soundness, below both AES key sizes, which makes the proof the weaker link for AES-128 and AES-256 alike; the
ciphertext is still full AES.
hekate-aes is AGPL-3.0-only. Commercial licenses are available from Oumuamua Labs at
info@oumuamua.dev. The README's Usage section builds an AES-256 host program, and
the API reference is on docs.rs.