NIST-standardized post-quantum cryptography (ML-DSA-87, ML-KEM-1024, SLH-DSA, LMS) exposed as EVM precompiles for Frontier-based chains — validated against the official NIST ACVP known-answer test vectors, and proven end-to-end on a live network.
Every dollar-denominated asset and most on-chain value today is secured by ECDSA, which a cryptographically relevant quantum computer can forge. NIST IR 8547 deprecates ECDSA after 2030 and disallows it after 2035. This repository is working infrastructure for the migration: it lets EVM smart contracts verify post-quantum signatures on-chain, today.
Status — read this first. The implementations here are standards-validated (see Conformance) and exercised by differential tests and a live end-to-end deployment, but they have not yet been independently audited. Do not use them to secure production value until an external audit has been completed. No claim of certification is made.
| Address | Function | Standard | Notes |
|---|---|---|---|
0x0400 |
ML-DSA-87 verify (single, detached) | FIPS 204 | sig 4,627 B · pk 2,592 B; input [sig ‖ pk ‖ msg], returns 32-byte bool |
0x0401 |
ML-DSA-87 batch verify | FIPS 204 | amortized batch verification |
0x0402 |
SLH-DSA verify | FIPS 205 | pure Rust (fips205); four standardized "simple" parameter sets |
0x0403 |
ML-KEM-1024 decapsulate | FIPS 203 | key encapsulation for on-chain KEM flows |
0x0404 |
LMS/HSS verify | RFC 8554 / SP 800-208 | stateful hash-based signatures (Fraunhofer AISEC crate, Cisco-reference-compatible) |
0x0405 |
SHA-384 | FIPS 180-4 | CNSA 2.0 hash |
0x0406 |
SHA-512 | FIPS 180-4 |
All-or-nothing semantics: malformed input, wrong lengths, or an invalid signature revert/return false — there is no ECDSA fallback path.
┌──────────────── wasm runtime (no_std) ────────────────┐
│ qrs-precompiles │
│ ├─ SLH-DSA (fips205, pure Rust) — in-wasm │
│ ├─ LMS/HSS (hbs-lms, pure Rust) — in-wasm │
│ ├─ SHA-384/512 (sha2, pure Rust) — in-wasm │
│ └─ ML-DSA-87 / ML-KEM-1024 ──────────┐ │
└────────────────────────────────────────┼──────────────┘
▼ host function boundary
┌──────────────── native node ───────────────────────────┐
│ qrs-runtime-interface │
│ └─ PQClean C implementations (pqcrypto-mldsa/mlkem) │
└────────────────────────────────────────────────────────┘
ML-DSA-87 and ML-KEM-1024 use the PQClean C reference implementations, which cannot compile to
wasm32-unknown-unknown. They are reached through
sp-runtime-interface host functions: the wasm runtime stays
free of C dependencies, and the native node executes the verifier. SLH-DSA, LMS and the hashes are pure
Rust and compile straight into the runtime blob.
This split is itself a reusable pattern for any Substrate/Frontier chain that wants C-backed PQC without polluting its wasm build.
The test suite verifies the precompiles against the official NIST ACVP vectors committed in this repository (sourced from usnistgov/ACVP-Server):
| Vector file | Standard |
|---|---|
precompiles/src/ML_DSA_87_ACVP_sigVer_FIPS204.json |
ML-DSA-87 signature verification, FIPS 204 |
precompiles/src/ML_KEM_1024_ACVP_decap_FIPS203.json |
ML-KEM-1024 decapsulation, FIPS 203 |
precompiles/src/SLH_DSA_ACVP_sigVer_FIPS205.json |
SLH-DSA signature verification, FIPS 205 |
plus LMS KATs (test/fixtures/lms_kats.json, shared with a three-way differential fuzz against
independent implementations), self-generated accept/reject tests, tamper tests (bit-flipped signatures
must fail), and length/format rejection tests. The KATs run through the precompile interface itself
(a Frontier MockHandle), so they gate the deployed byte-level path, not just the underlying library.
Current suite: 25 tests, all passing (cargo test -p qrs-precompiles).
Requires Rust (the pinned toolchain in rust-toolchain.toml is installed automatically by rustup) and a
C compiler for the PQClean backends.
git clone <this-repo> && cd pq-evm
cargo test -p qrs-precompiles # full precompile + ACVP KAT suite
cargo test -p qrs-runtime-interface # host-function layer
cargo bench -p qrs-runtime-interface # ML-DSA-87 batch verification benchmarksPost-quantum authorization is expensive, and pretending otherwise helps nobody:
- An ML-DSA-87 signature is 4,627 bytes and essentially incompressible (≈1.0× under standard compressors — the signature is high-entropy by construction).
- A PQ-authenticated transfer costs a large multiple of an ECDSA ERC-20 transfer in gas; on our live deployment the per-block gas ceiling had to be raised >3× to sustain modest PQ throughput.
- Verification cost, batch amortization curves, and block-capacity impact are exactly what this project
exists to measure and publish. Benchmarks live in
runtime-interface/benches/.
Extracted from the chain workspace of a larger post-quantum settlement system, where these precompiles
run on a live Frontier L1 and authorize real end-to-end transfers (valid ML-DSA-87 signatures accepted,
tampered ones rejected, against 0x0400 on a running node). This repository is the standalone,
reusable, open-source core.