Skip to content

Repository files navigation

pq-evm — Post-Quantum Signature Verification for EVM Execution Layers

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.


The precompile set (0x04000x0406)

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.

Architecture — why the native/wasm split

┌──────────────── 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.

Conformance — NIST ACVP known-answer tests

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).

Reproduce it

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 benchmarks

Cost reality — the honest numbers

Post-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/.

Provenance

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.

License

Apache-2.0.

About

Post-quantum signature verification precompiles for EVM execution layers (ML-DSA-87, ML-KEM-1024, SLH-DSA, LMS) — NIST ACVP conformance-tested

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages