Benchmarks
Proving time, verification, proof size and peak memory for ML-DSA, ML-KEM, AES, Keccak, SHA-256 and RSA in Hekate, with the commands to reproduce each run.
- Machine
- Apple M3 Max, 16 cores
- Build
--release,std parallel blake3 table-math public- Runs
- Best of three on an otherwise idle machine
- Peak memory
- The larger of peak physical footprint and peak resident set size
Hashing
Keccak-f[1600] and SHA-256 at a small and a large trace.
| Workload | Proving | Verify | Proof size | Peak memory |
|---|---|---|---|---|
| Keccak-f[1600], 2^15 rows~178 KB | 163 ms152 ms | Verify4.7 ms3.6 ms | Proof852 KiB674 KiB | Peak mem143 MiB136 MiB |
| Keccak-f[1600], 2^20 rows~5.4 MB | 3.23 s3.19 s | Verify7.0 ms5.8 ms | Proof3,539 KiB3,232 KiB | Peak mem2,428 MiB2,428 MiB |
| SHA-256, 2^11 rows2.5 KB | 56 ms45 ms | Verify3.2 ms1.8 ms | Proof522 KiB303 KiB | Peak mem60 MiB55 MiB |
| SHA-256, 2^21 rows8.4 MB | 8.37 s8.31 s | Verify10.8 ms9.0 ms | Proof5,480 KiB5,156 KiB | Peak mem5,096 MiB4,940 MiB |
Keccak runs 1,310 permutations at 2^15 and 41,943 at 2^20. SHA-256 runs 40 blocks at 2 rounds per row and 131,072 blocks at 4 rounds per row.
HEKATE_NUM_VARS=20
HEKATE_NUM_VARS=21 HEKATE_ROUNDS_PER_ROW=4 Digital signatures
Post-quantum ML-DSA verification at all three FIPS 204 levels, and RSA-2048 PKCS#1 v1.5.
| Workload | Proving | Verify | Proof size | Peak memory |
|---|---|---|---|---|
| ML-DSA-44FIPS 204 | 433 ms390 ms | Verify10.2 ms7.5 ms | Proof1,537 KiB1,140 KiB | Peak mem249 MiB203 MiB |
| ML-DSA-65FIPS 204 | 478 ms433 ms | Verify10.1 ms7.8 ms | Proof1,575 KiB1,180 KiB | Peak mem236 MiB194 MiB |
| ML-DSA-87FIPS 204 | 624 ms575 ms | Verify11.1 ms8.6 ms | Proof1,810 KiB1,417 KiB | Peak mem332 MiB299 MiB |
| RSA-2048 PKCS#1 v1.5RFC 8017 | 209 ms174 ms | Verify8.0 ms5.5 ms | Proof1,813 KiB1,475 KiB | Peak mem401 MiB401 MiB |
Each ML-DSA level runs 6 chiplet tables. RSA-2048 proves s^65537 mod N == PKCS1-v1_5(H) over a 200-byte message, with the modulus public and the signature witness.
HEKATE_LEVEL=65 Encryption and key exchange
Post-quantum ML-KEM-768 on both sides of the exchange, and AES over about 500 KB of plaintext.
| Workload | Proving | Verify | Proof size | Peak memory |
|---|---|---|---|---|
| ML-KEM-768 senderFIPS 203 | 413 ms360 ms | Verify11.7 ms8.4 ms | Proof1,541 KiB982 KiB | Peak mem190 MiB137 MiB |
| ML-KEM-768 receiverFIPS 203 | 558 ms487 ms | Verify13.9 ms9.8 ms | Proof1,884 KiB1,327 KiB | Peak mem269 MiB211 MiB |
| AES-12831,250 blocks | 885 ms849 ms | Verify6.4 ms5.3 ms | Proof2,967 KiB2,700 KiB | Peak mem777 MiB772 MiB |
| AES-25631,250 blocks | 981 ms939 ms | Verify6.4 ms5.3 ms | Proof3,198 KiB2,924 KiB | Peak mem963 MiB969 MiB |
The ML-KEM sender proves Encaps and AES-256-CTR over the default 87-byte message on 6 ML-KEM tables and 2 AES tables. The receiver proves KeyGen chained into Decaps on 7 tables. Each AES run covers ~500 KB of plaintext on a 2^16-row CPU trace with Round-AIR and S-box ROM chiplets at 2^19, which is ~28 µs per block for AES-128 and ~31 µs for AES-256.
HEKATE_LEVEL=768 HEKATE_LEVEL=768 HEKATE_LEVEL=256 Integer arithmetic
The smallest circuit in the workspace and the scaling reference for the rest: each row is a bit-sliced 32-bit add with an explicit carry chain, virtual-expanded into 32 bit, 32 sum and 32 carry columns.
| Workload | Proving | Verify | Proof size | Peak memory |
|---|---|---|---|---|
| 2^20 rows32-bit add | 259 ms233 ms | Verify3.8 ms2.5 ms | Proof1,147 KiB678 KiB | Peak mem254 MiB173 MiB |
| 2^24 rows32-bit add | 4.06 s3.45 s | Verify8.1 ms4.2 ms | Proof4,099 KiB2,537 KiB | Peak mem3,320 MiB2,230 MiB |
| 2^26 rows32-bit add | 18.40 s15.61 s | Verify13.0 ms7.6 ms | Proof8,022 KiB5,001 KiB | Peak mem13,082 MiB8,682 MiB |
From 2^20 to 2^26 rows, 64 times the trace, proving takes about 71 times as long and peak memory grows about 52 times.
HEKATE_NUM_VARS=26 Numbers are for aarch64 with PMULL and NEON; x86_64 runs a software fallback.
The examples live in hekate/examples.