pqc-migration-toolkit/lib/precompiles.js
Aere Network de9a79298c Aere PQC migration toolkit: measure an address quantum exposure from its bytecode
Zero dependencies, no account, no API. Every command takes --rpc, so it runs
against a node you operate and never needs ours. That is the point: an exposure
measurement you cannot re-run is an opinion with a logo on it.

Ships with two self-checks meant to be run by you, not just by us. The second,
proba-vocabular.mjs, exists because of a real defect found on 2026-08-16: the
scanner emits RED / YELLOW / GREEN, two downstream files each wrote their own
copy of that list, and both wrote AMBER, so a hybrid contract, exactly a client
who has already started migrating, was reported as unmeasurable. Both sides were
self-consistent, so nothing we had could see it. The vocabulary now has one
exported source, and the test walks the whole path with a negative control that
makes it able to fail.

The same scanner returns RED about our own contracts. See VERIFY-US.md.
2026-08-17 10:31:31 +03:00

111 lines
4.7 KiB
JavaScript

// precompiles.js, the single source of truth for the address bands and the
// measured gas this toolkit reasons about. Every value here is sourced from a
// committed repo artifact; the citations are in the comments and in README.md.
//
// SCOPE BOUNDARY (never moves): these are signature/hash verification
// precompiles on the EVM/account path. NONE of them make Aere consensus
// post-quantum. Aere mainnet (chain 2800) seals blocks with classical
// secp256k1 QBFT. Migrating account authentication to a PQC scheme changes how
// an account authorizes, not how the chain reaches consensus.
// ── Classical, quantum-vulnerable primitives ─────────────────────────────────
// Broken by a large-scale quantum computer via Shor's algorithm.
export const CLASSICAL = {
ecrecover: {
address: 0x01n,
name: 'ECDSA ecrecover (secp256k1)',
quantum: 'VULNERABLE',
// ecrecover is a fixed EVM protocol constant, not Aere-specific.
// [VERIFY: G_ecrecover = 3000 is a fixed EVM constant.]
marginalGas: 3000,
},
p256: {
address: 0x100n,
name: 'P-256 / secp256r1 verify (RIP-7212 / RIP-7951, passkeys)',
quantum: 'VULNERABLE',
// Shared with Ethereum's Osaka; standards-aligned, not Aere-proprietary.
// [CITED: AERE-EIP-COMPATIBILITY-MATRIX.md 0x100 row, ~3,450 gas.]
marginalGas: 3450,
},
};
// ── Aere's live native post-quantum precompiles (chain 2800) ─────────────────
// Band 0x0AE1..0x0AE5, activated at the AerePQC fork, block 9,189,161.
// [CITED: AERE-PROTOCOL-SPECIFICATION.md section 4; AERE-EIP-COMPATIBILITY-MATRIX.md;
// AERE-BENCHMARK-REPORT.md Part C.1 (marginal gas + verify-and-record tx gasUsed).]
export const PQC = {
falcon512: {
address: 0x0ae1n,
name: 'Falcon-512 verify (NIST round-3)',
nistLevel: 1,
marginalGas: 40000,
verifyAndRecordTxGas: 86336,
live: true,
},
falcon1024: {
address: 0x0ae2n,
name: 'Falcon-1024 verify (NIST round-3)',
nistLevel: 5,
marginalGas: 75000,
verifyAndRecordTxGas: 145496,
live: true,
},
mldsa44: {
address: 0x0ae3n,
name: 'ML-DSA-44 verify (FIPS 204, Dilithium2)',
nistLevel: 2,
marginalGas: 55000,
verifyAndRecordTxGas: 351050,
live: true,
},
slhdsa128s: {
address: 0x0ae4n,
name: 'SLH-DSA-SHA2-128s verify (FIPS 205, SPHINCS+)',
nistLevel: 1,
marginalGas: 350000,
verifyAndRecordTxGas: 558276,
live: true,
},
shake256: {
address: 0x0ae5n,
name: 'SHAKE256 (FIPS 202 XOF)',
marginalGas: 72, // 60 base + 12/word; a 32-byte input is one word -> 72
verifyAndRecordTxGas: 21470,
live: true,
hashOnly: true,
},
};
// Testnet-only PQC precompiles, NOT on mainnet 2800. A mainnet staticcall to
// these hits an empty account and returns empty. Listed so the scanner can name
// them if it ever sees them, and so no one mistakes them for live mainnet.
// [CITED: AERE-EIP-COMPATIBILITY-MATRIX.md 0x0AE6..0x0AE8 rows.]
export const PQC_TESTNET = {
mlkem768: { address: 0x0ae6n, name: 'ML-KEM-768 encapsulation (FIPS 203)', marginalGas: 60000, live: false },
falconHashToPoint: { address: 0x0ae7n, name: 'Falcon HashToPoint (SHAKE256 sampler)', live: false },
sp1StarkVerify: { address: 0x0ae8n, name: 'SP1 inner STARK verify (reference skeleton)', live: false },
};
// Hybrid cost: one Falcon-512 native verify (40,000) plus one ecrecover (3,000).
// [Derived arithmetic from the two cited marginal-gas constants.]
export const HYBRID_MARGINAL_GAS = PQC.falcon512.marginalGas + CLASSICAL.ecrecover.marginalGas; // 43,000
// Two Falcon-512 verify paths exist and MUST NOT be conflated:
// - NATIVE precompile 0x0AE1: ~40,000 marginal / 86,336 verify-and-record tx.
// - SOLIDITY AereFalcon512Verifier (0x4E8e...D8fFC): ~10.5M gas (SHAKE256 run
// in-EVM). AerePQCAccount / AereHybridAuth currently delegate to this
// Solidity verifier, so a *deployed* AerePQCAccount authorization is ~10.5M
// gas today, NOT 86k. [CITED: contracts/deployments/pqc-account.json
// handleOpsGasUsed 10,278,313; AerePQCAccount.sol GAS/EIP-7825 note.]
export const FALCON512_SOLIDITY_VERIFIER_GAS = 10500000;
export const AERE_PQC_ACCOUNT_MEASURED_USEROP_GAS = 10278313; // real on-chain receipt
// Build a lookup of every known band address -> descriptor.
export function knownAddressTable() {
const t = new Map();
for (const [k, v] of Object.entries(CLASSICAL)) t.set(v.address, { key: k, band: 'classical', ...v });
for (const [k, v] of Object.entries(PQC)) t.set(v.address, { key: k, band: 'pqc-live', ...v });
for (const [k, v] of Object.entries(PQC_TESTNET)) t.set(v.address, { key: k, band: 'pqc-testnet', ...v });
return t;
}