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.
88 lines
3.5 KiB
JavaScript
88 lines
3.5 KiB
JavaScript
const { expect } = require("chai");
|
|
const { ethers } = require("hardhat");
|
|
const kat = require("./falcon512_kat0.json");
|
|
|
|
|
|
// Validates the on-chain Falcon-512 verifier stage-by-stage against oracles
|
|
// dumped from the OFFICIAL NIST Falcon-512 reference (falcon512-KAT.rsp, vector 0,
|
|
// SHA-256 dd75c946...b5cd, reproduced byte-for-byte from the round-3 submission).
|
|
|
|
describe("AereFalcon512Verifier: NIST KAT", function () {
|
|
let v;
|
|
before(async function () {
|
|
const F = await ethers.getContractFactory("AereFalcon512Verifier");
|
|
v = await F.deploy();
|
|
await v.waitForDeployment();
|
|
});
|
|
|
|
it("SHAKE256 matches the FIPS 202 empty-string KAT", async function () {
|
|
const out = await v.shake256("0x", 32);
|
|
expect(out.toLowerCase()).to.equal(
|
|
"0x46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f"
|
|
);
|
|
});
|
|
|
|
it("HashToPoint(nonce||msg) reproduces the reference challenge polynomial c", async function () {
|
|
const c = await v.hashToPoint(kat.nonce, kat.msg);
|
|
const got = c.map((x) => Number(x));
|
|
expect(got).to.deep.equal(kat.c);
|
|
});
|
|
|
|
it("decodePublicKey reproduces h and accepts the 897-byte key", async function () {
|
|
const [h, ok] = await v.decodePublicKey(kat.pk);
|
|
expect(ok).to.equal(true);
|
|
expect(h.map((x) => Number(x))).to.deep.equal(kat.h);
|
|
});
|
|
|
|
it("decodeSignature reproduces s2 and consumes the whole compressed blob", async function () {
|
|
const [s2, ok] = await v.decodeSignature(kat.compsig);
|
|
expect(ok).to.equal(true);
|
|
expect(s2.map((x) => Number(x))).to.deep.equal(kat.s2);
|
|
});
|
|
|
|
it("verify() ACCEPTS the official NIST KAT signature", async function () {
|
|
expect(await v.verify(kat.pk, kat.msg, kat.nonce, kat.compsig)).to.equal(true);
|
|
});
|
|
|
|
it("verifySignedMessage() ACCEPTS the raw NIST signed-message blob", async function () {
|
|
expect(await v.verifySignedMessage(kat.pk, kat.sm)).to.equal(true);
|
|
});
|
|
|
|
it("REJECTS a tampered signature (flip one byte of compSig)", async function () {
|
|
const bytes = ethers.getBytes(kat.compsig);
|
|
bytes[100] ^= 0x01; // flip a bit deep in the compressed signature
|
|
const tampered = ethers.hexlify(bytes);
|
|
expect(await v.verify(kat.pk, kat.msg, kat.nonce, tampered)).to.equal(false);
|
|
});
|
|
|
|
it("REJECTS a tampered message (flip one byte of msg)", async function () {
|
|
const bytes = ethers.getBytes(kat.msg);
|
|
bytes[0] ^= 0x01;
|
|
const tampered = ethers.hexlify(bytes);
|
|
expect(await v.verify(kat.pk, tampered, kat.nonce, kat.compsig)).to.equal(false);
|
|
});
|
|
|
|
it("REJECTS a tampered signed-message blob", async function () {
|
|
const bytes = ethers.getBytes(kat.sm);
|
|
bytes[bytes.length - 5] ^= 0x02; // flip a byte inside the signature region
|
|
const tampered = ethers.hexlify(bytes);
|
|
expect(await v.verifySignedMessage(kat.pk, tampered)).to.equal(false);
|
|
});
|
|
|
|
it("ACCEPTS a second official NIST KAT vector (count=1, mlen=66)", async function () {
|
|
expect(await v.verifySignedMessage(kat.pk1, kat.sm1)).to.equal(true);
|
|
});
|
|
|
|
it("REJECTS KAT vector 1 signature under the WRONG public key", async function () {
|
|
expect(await v.verifySignedMessage(kat.pk, kat.sm1)).to.equal(false);
|
|
});
|
|
|
|
it("verifyAndRecord() writes the result on-chain", async function () {
|
|
const tx = await v.verifyAndRecord(kat.pk, kat.sm);
|
|
const rc = await tx.wait();
|
|
console.log(" gas used by verifyAndRecord:", rc.gasUsed.toString());
|
|
expect(await v.lastResult()).to.equal(true);
|
|
expect(await v.verifyCount()).to.equal(1n);
|
|
});
|
|
});
|