aere-contracts/test/AereCryptoRegistry.newprecompiles.test.js
Aere Network a13a649b77
Some checks are pending
contracts-ci / Install (lockfile) → compile → full test suite (push) Waiting to run
contracts-ci / PQC known-answer tests (NIST vectors) (push) Waiting to run
contracts-ci / Coverage (scoped, with artifacts) (push) Waiting to run
Initial public release
Aere Network public source. Everything here can be checked against the live
chain (chain id 2800, https://rpc.aere.network).

Scope note, stated up front rather than buried: consensus on chain 2800 is
classical secp256k1 ECDSA QBFT. The post-quantum work in this repository is at
the signature, precompile, account and transport layers. Nothing here makes the
consensus post-quantum, and no document in it should be read as claiming so.
2026-07-20 01:02:37 +03:00

106 lines
4.4 KiB
JavaScript

const { expect } = require("chai");
const { ethers } = require("hardhat");
// ---------------------------------------------------------------------------
// AereCryptoRegistry: additive entries for the two NEW native precompiles
// (ML-KEM-768 @ 0x0AE6 and Falcon HashToPoint @ 0x0AE7).
//
// These precompiles are TESTNET-ONLY today; mainnet 2800 still has exactly the five
// 0x0AE1..0x0AE5 (activated block 9,189,161). The registry change is PURELY ADDITIVE:
// - SCHEME_FALCON_HASHTOPOINT (id 15) is the new append-only auxiliary-primitive id,
// - the ML-KEM-768 precompile maps to the pre-existing SCHEME_MLKEM768 (id 13),
// - PRECOMPILE_MLKEM768_TESTNET / PRECOMPILE_FALCON_HASHTOPOINT_TESTNET are reference
// address constants only.
// This test asserts every new constant resolves to its canonical value, that id 15 is
// distinct from the existing ids 1..14, and that the additions changed NO behavior:
// seedLiveSchemes still seeds exactly the five live rows and neither new precompile is
// seeded or routed.
// ---------------------------------------------------------------------------
const MLKEM768_ADDR = ethers.getAddress("0x0000000000000000000000000000000000000ae6");
const HASHTOPOINT_ADDR = ethers.getAddress("0x0000000000000000000000000000000000000ae7");
// The full canonical scheme space that pre-existed this change (ids 1..14).
const EXISTING_SCHEMES = [
"SCHEME_FALCON512",
"SCHEME_FALCON1024",
"SCHEME_MLDSA44",
"SCHEME_SLHDSA128S",
"SCHEME_SHAKE256",
"SCHEME_MLDSA65",
"SCHEME_MLDSA87",
"SCHEME_FALCON512_PADDED",
"SCHEME_FALCON1024_PADDED",
"SCHEME_SLHDSA192S",
"SCHEME_SLHDSA256S",
"SCHEME_MLKEM512",
"SCHEME_MLKEM768",
"SCHEME_MLKEM1024",
];
describe("AereCryptoRegistry: new-precompile additive entries (0x0AE6 / 0x0AE7)", function () {
let reg;
beforeEach(async function () {
const R = await ethers.getContractFactory("AereCryptoRegistry");
reg = await R.deploy();
await reg.waitForDeployment();
});
it("SCHEME_FALCON_HASHTOPOINT resolves to the canonical id 15", async function () {
expect(Number(await reg.SCHEME_FALCON_HASHTOPOINT())).to.equal(15);
});
it("the ML-KEM-768 precompile maps to the pre-existing SCHEME_MLKEM768 (id 13)", async function () {
expect(Number(await reg.SCHEME_MLKEM768())).to.equal(13);
});
it("PRECOMPILE_MLKEM768_TESTNET resolves to 0x0AE6", async function () {
expect(await reg.PRECOMPILE_MLKEM768_TESTNET()).to.equal(MLKEM768_ADDR);
});
it("PRECOMPILE_FALCON_HASHTOPOINT_TESTNET resolves to 0x0AE7", async function () {
expect(await reg.PRECOMPILE_FALCON_HASHTOPOINT_TESTNET()).to.equal(HASHTOPOINT_ADDR);
});
it("id 15 is distinct from every pre-existing canonical id (1..14)", async function () {
const htp = Number(await reg.SCHEME_FALCON_HASHTOPOINT());
const seen = new Set();
for (const name of EXISTING_SCHEMES) {
seen.add(Number(await reg[name]()));
}
expect(seen.size).to.equal(14); // ids 1..14 all distinct
expect(seen.has(htp), "HashToPoint id collides with an existing id").to.equal(false);
// The whole space (existing + new) is 15 distinct ids: exactly 1..15.
seen.add(htp);
expect(seen.size).to.equal(15);
expect([...seen].sort((a, b) => a - b)).to.deep.equal(
Array.from({ length: 15 }, (_, i) => i + 1)
);
});
it("is purely additive: seedLiveSchemes still seeds exactly the five live rows", async function () {
await reg.seedLiveSchemes();
expect(Number(await reg.algorithmCount())).to.equal(5);
});
it("neither new precompile is seeded or routed (no behavior change)", async function () {
await reg.seedLiveSchemes();
// The ML-KEM-768 scheme (13) has no seeded row, so precompileFor must revert UnknownScheme.
await expect(reg.precompileFor(13)).to.be.revertedWithCustomError(reg, "UnknownScheme");
// The Falcon HashToPoint scheme (15) likewise has no seeded row.
await expect(reg.precompileFor(15)).to.be.revertedWithCustomError(reg, "UnknownScheme");
// The reference address constants are NOT wired into any routable row: the five seeded
// rows point only at 0x0AE1..0x0AE5, never at 0x0AE6 / 0x0AE7.
const seededVerifiers = new Set();
for (let id = 1; id <= 5; id++) {
const a = await reg.getAlgorithm(id);
seededVerifiers.add(a.verifier.toLowerCase());
}
expect(seededVerifiers.has(MLKEM768_ADDR.toLowerCase())).to.equal(false);
expect(seededVerifiers.has(HASHTOPOINT_ADDR.toLowerCase())).to.equal(false);
});
});