ERC-8231 — Post-Quantum Key Registry
Summary: ERC-8231 defines a standard registry for post-quantum cryptographic keys on EVM chains. It supports CRYSTALS-Dilithium-5 (FIPS 204) for signatures and CRYSTALS-Kyber-1024 (FIPS 203) for key encapsulation. Contracts can require PQ signatures on privileged actions to protect against quantum adversaries who might break ECDSA.
Why Post-Quantum
ECDSA (the signature scheme used for Ethereum transactions) is vulnerable to Shor’s algorithm on a sufficiently large quantum computer. Timeline estimates vary (5–20 years), but long-lived smart contracts — DAOs, protocol treasuries, 20-year bonds — may outlive ECDSA’s security.
ERC-8231 addresses this by standardizing how contracts can require Dilithium-5 signatures alongside (or instead of) ECDSA signatures.
Covenant Surface
| Construct | Description |
|---|---|
pq_key | Post-quantum public key type (2,592 bytes for Dilithium-5) |
@pq_signed(key) | Guard: require a valid Dilithium-5 signature from key |
pq_keygen() | Intrinsic: generate a PQ keypair (off-chain) |
pq_register(pk) | Register a PQ public key in the ERC-8231 registry |
pq_verify(sig, msg, pk) | Verify a Dilithium-5 signature |
Supported Algorithms
CRYSTALS-Dilithium-5 (FIPS 204) — Signatures
| Parameter | Value |
|---|---|
| NIST level | 5 (256-bit quantum security) |
| Public key size | 2,592 bytes |
| Signature size | 4,627 bytes |
| Private key size | 4,864 bytes |
| Signing time (off-chain) | ~1ms |
| Verification time (EVM precompile) | ~3ms / 80,000 gas |
Dilithium-5 is the largest/most secure of the Dilithium family. For less critical applications where gas is a concern, Dilithium-3 (FIPS 204 Level 3) is available via the --pq-level 3 compiler flag.
CRYSTALS-Kyber-1024 (FIPS 203) — Key Encapsulation
| Parameter | Value |
|---|---|
| NIST level | 5 (256-bit quantum security) |
| Public key size | 1,568 bytes |
| Ciphertext size | 1,568 bytes |
| Shared secret size | 32 bytes |
| Encapsulation gas | 60,000 |
| Decapsulation gas | 65,000 |
Kyber is used in Covenant for establishing encrypted communication channels between contracts — for example, when doing threshold decryption for ERC-8227 where validators need to exchange key material.
Key Format
PQ public key on-chain storage format:
bytes2600 pq_public_key = [
bytes2 algorithm_id, // 0x0001 = Dilithium-5, 0x0002 = Kyber-1024
bytes2590 key_material, // algorithm-specific public key
bytes8 reserved // must be zero in v1
]
The ERC-8231 registry contract stores a mapping address → pq_public_key. A single address can register one Dilithium key and one Kyber key.
ERC-8231 Registry Interface
{
"name": "IERC8231PQRegistry",
"functions": [
{
"name": "registerDilithiumKey",
"inputs": [{"name":"pk","type":"bytes2600"}],
"outputs": []
},
{
"name": "getDilithiumKey",
"inputs": [{"name":"account","type":"address"}],
"outputs": [{"name":"pk","type":"bytes2600"}]
},
{
"name": "verifyDilithiumSignature",
"inputs": [
{"name":"account","type":"address"},
{"name":"message","type":"bytes"},
{"name":"signature","type":"bytes4627"}
],
"outputs": [{"name":"valid","type":"bool"}]
}
]
}
Using @pq_signed
contract QuantumSafeVault {
field pq_admin: pq_key
field treasury: amount
action initialize_pq_admin(pk: pq_key) only deployer {
pq_admin = pk
}
// Requires BOTH ECDSA (from 'only admin') AND Dilithium-5 signature
action withdraw(to: address, amount: amount)
only admin
@pq_signed(pq_admin) {
given amount <= treasury or revert_with InsufficientFunds()
treasury = treasury - amount
transfer(to, amount)
}
}
The @pq_signed(pq_admin) guard causes the compiler to:
- Read
pq_adminfrom storage - Call the
0x41(pq_verify) precompile with the signature attached to the transaction - Revert if the signature is invalid or no signature is provided
Transactions to @pq_signed functions must include the PQ signature in the calldata via a special encoding. The Covenant SDK handles this automatically.
Hybrid Classical + PQ Mode
For contracts that need to remain compatible with existing wallets while offering optional PQ security:
action critical_upgrade(new_impl: address) {
// Accept if EITHER:
// 1. Classic multisig (3 of 5)
// 2. PQ signed by quantum_admin
given (
multisig_approvals >= 3
OR pq_verify(quantum_sig, msg_hash, quantum_admin_key)
)
proxy_upgrade(new_impl)
}
This “hybrid mode” is recommended for the 2026-2030 transition period.
When to Use PQ Signatures
Use ERC-8231 for:
- Protocol governance (DAO votes, parameter changes)
- Treasury management (withdrawals > $1M)
- Key rotation ceremonies
- Contracts with >5 year expected lifespan
- Regulatory-sensitive applications
Skip ERC-8231 for:
- Simple DeFi operations (trading, providing liquidity)
- Short-lived contracts
- High-frequency low-value operations (gas cost is 3-5× ECDSA)
Gas Comparison
| Operation | ECDSA | Dilithium-5 | Ratio |
|---|---|---|---|
| Key storage | 64 bytes | 2,600 bytes | 40× |
| Signature storage | 65 bytes | 4,627 bytes | 71× |
| On-chain verification | 3,000 gas | 80,000 gas | 27× |
| Calldata cost | 65×16 = 1,040 | 4,627×16 = 74,032 | 71× |
PQ verification on Aster Chain costs ~8,000 pGas (10× cheaper than L1), making it practical for medium-frequency operations.