aere-contracts/test/hybridAuth.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

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");
});
});