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.
120 lines
4.9 KiB
JavaScript
120 lines
4.9 KiB
JavaScript
// AereHybridAuth — unit tests.
|
|
//
|
|
// The Falcon-512 leg is mocked here (real Falcon signatures cannot be produced
|
|
// inside the hardhat process); the REAL end-to-end Falcon verification is
|
|
// demonstrated on AERE mainnet against the live AereFalcon512Verifier by
|
|
// scripts/deploy-hybrid-auth.js. These tests pin the ECDSA leg + the "requires
|
|
// BOTH legs" composition logic.
|
|
|
|
const { expect } = require("chai");
|
|
const { ethers } = require("hardhat");
|
|
|
|
// 897-byte NIST Falcon-512 public key placeholder (0x09 header). The mock does
|
|
// not decode it; the on-chain demo uses a genuine reference-generated key.
|
|
function fakeFalconPk() {
|
|
const b = new Uint8Array(897);
|
|
b[0] = 0x09;
|
|
for (let i = 1; i < 897; i++) b[i] = (i * 7) & 0xff;
|
|
return ethers.hexlify(b);
|
|
}
|
|
|
|
const NONCE = "0x" + "ab".repeat(40);
|
|
const COMPSIG = "0x" + "cd".repeat(600);
|
|
|
|
describe("AereHybridAuth", function () {
|
|
let auth, falcon, signer, other;
|
|
const ID = ethers.id("identity-1");
|
|
const pk = fakeFalconPk();
|
|
|
|
beforeEach(async function () {
|
|
[, signer, other] = await ethers.getSigners();
|
|
const M = await ethers.getContractFactory("MockFalcon512Verifier");
|
|
falcon = await M.deploy();
|
|
await falcon.waitForDeployment();
|
|
const A = await ethers.getContractFactory("AereHybridAuth");
|
|
auth = await A.deploy(await falcon.getAddress());
|
|
await auth.waitForDeployment();
|
|
await auth.registerIdentity(ID, signer.address, pk);
|
|
});
|
|
|
|
it("registers a hybrid identity and rejects bad Falcon pubkeys", async function () {
|
|
const [reg, ecdsa, storedPk] = await auth.getIdentity(ID);
|
|
expect(reg).to.equal(true);
|
|
expect(ecdsa).to.equal(signer.address);
|
|
expect(storedPk).to.equal(pk);
|
|
expect(await auth.identityCount()).to.equal(1n);
|
|
|
|
await expect(auth.registerIdentity(ID, signer.address, pk)).to.be.revertedWithCustomError(auth, "AlreadyRegistered");
|
|
// wrong length
|
|
await expect(
|
|
auth.registerIdentity(ethers.id("id2"), signer.address, "0x0900")
|
|
).to.be.revertedWithCustomError(auth, "BadFalconPubKey");
|
|
// wrong header
|
|
const badHdr = ethers.hexlify(new Uint8Array(897));
|
|
await expect(
|
|
auth.registerIdentity(ethers.id("id3"), signer.address, badHdr)
|
|
).to.be.revertedWithCustomError(auth, "BadFalconPubKey");
|
|
});
|
|
|
|
async function ecdsaSig(wallet, messageHash) {
|
|
// EIP-191 personal-sign of the 32-byte messageHash.
|
|
return wallet.signMessage(ethers.getBytes(messageHash));
|
|
}
|
|
|
|
it("authorizes only when BOTH ECDSA and Falcon verify", async function () {
|
|
const messageHash = ethers.id("action:transfer-1000");
|
|
const falconMsg = messageHash; // contract signs abi.encodePacked(messageHash)
|
|
const good = await ecdsaSig(signer, messageHash);
|
|
|
|
// Falcon mock accepts this exact tuple.
|
|
await falcon.setResult(pk, falconMsg, NONCE, COMPSIG, true);
|
|
|
|
// both good -> accepted
|
|
let [e, f, ok] = await auth.checkHybrid(ID, messageHash, good, NONCE, COMPSIG);
|
|
expect(e).to.equal(true);
|
|
expect(f).to.equal(true);
|
|
expect(ok).to.equal(true);
|
|
|
|
const tx = await auth.authorize(ID, messageHash, good, NONCE, COMPSIG);
|
|
await tx.wait();
|
|
expect(await auth.isAuthorized(ID, messageHash)).to.equal(true);
|
|
expect(await auth.authCount()).to.equal(1n);
|
|
expect(await auth.lastMessageHash()).to.equal(messageHash);
|
|
});
|
|
|
|
it("rejects when the Falcon leg fails (wrong/tampered PQC sig)", async function () {
|
|
const messageHash = ethers.id("action:transfer-2000");
|
|
const good = await ecdsaSig(signer, messageHash);
|
|
// Falcon mock rejects (default false, no override).
|
|
const [e, f, ok] = await auth.checkHybrid(ID, messageHash, good, NONCE, COMPSIG);
|
|
expect(e).to.equal(true);
|
|
expect(f).to.equal(false);
|
|
expect(ok).to.equal(false);
|
|
await expect(auth.authorize(ID, messageHash, good, NONCE, COMPSIG))
|
|
.to.be.revertedWithCustomError(auth, "HybridAuthFailed")
|
|
.withArgs(true, false);
|
|
});
|
|
|
|
it("rejects when the ECDSA leg fails (wrong classical signer)", async function () {
|
|
const messageHash = ethers.id("action:transfer-3000");
|
|
const falconMsg = messageHash;
|
|
await falcon.setResult(pk, falconMsg, NONCE, COMPSIG, true); // Falcon would pass
|
|
const wrong = await ecdsaSig(other, messageHash); // signed by the wrong key
|
|
const [e, f, ok] = await auth.checkHybrid(ID, messageHash, wrong, NONCE, COMPSIG);
|
|
expect(e).to.equal(false);
|
|
expect(f).to.equal(true);
|
|
expect(ok).to.equal(false);
|
|
await expect(auth.authorize(ID, messageHash, wrong, NONCE, COMPSIG))
|
|
.to.be.revertedWithCustomError(auth, "HybridAuthFailed")
|
|
.withArgs(false, true);
|
|
});
|
|
|
|
it("reverts checking an unregistered identity", async function () {
|
|
const messageHash = ethers.id("x");
|
|
const good = await ecdsaSig(signer, messageHash);
|
|
await expect(
|
|
auth.checkHybrid(ethers.id("nope"), messageHash, good, NONCE, COMPSIG)
|
|
).to.be.revertedWithCustomError(auth, "NotRegistered");
|
|
});
|
|
});
|