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.
73 lines
3.4 KiB
JavaScript
73 lines
3.4 KiB
JavaScript
const { expect } = require("chai");
|
|
const { ethers } = require("hardhat");
|
|
const kat = require("./fixtures/sphincs-sha2-128s-acvp-tg31.json");
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// AereSphincsVerifier - validated bit-for-bit against the OFFICIAL NIST FIPS 205
|
|
// ACVP SLH-DSA-sigVer vectors, test group 31 (SLH-DSA-SHA2-128s, internal
|
|
// interface, preHash none). A full verify is ~1.8M gas (assembly SHA-256
|
|
// tweakable hash), so the whole 14-vector suite runs comfortably in-process.
|
|
//
|
|
// KAT source: NIST ACVP-Server gen-val/json-files/SLH-DSA-sigVer-FIPS205
|
|
// prompt.json sha256 4e7beb1233e47baa0acdd36417c66c45811aa40a4e32ffdb1a35d93b13b289fb
|
|
// expectedResults.json sha256 259f5e2a0665de0adc0fefa45b5db3a2a6ed13c3c44d14bdaf64a80aee12c687
|
|
// internalProjection.json sha a013fc2104f4ed4799d96d51141f65b965969b2cf10646626a021b6d456ce792
|
|
// ---------------------------------------------------------------------------
|
|
describe("AereSphincsVerifier (FIPS 205 SLH-DSA-SHA2-128s, NIST ACVP KAT)", function () {
|
|
this.timeout(600000);
|
|
let v;
|
|
const byId = (id) => kat.tests.find((t) => t.tcId === id);
|
|
const flip = (hex, i) => { const b = ethers.getBytes(hex); b[i] ^= 0x01; return ethers.hexlify(b); };
|
|
|
|
before(async () => {
|
|
const F = await ethers.getContractFactory("AereSphincsVerifier");
|
|
v = await F.deploy();
|
|
await v.waitForDeployment();
|
|
});
|
|
|
|
it("advertises the parameter set", async () => {
|
|
expect(await v.paramSet()).to.equal("SLH-DSA-SHA2-128s (SPHINCS+-SHA2-128s-simple), FIPS 205");
|
|
expect(await v.SIG_BYTES()).to.equal(7856n);
|
|
});
|
|
|
|
it("reproduces NIST's expected testPassed for all 14 ACVP vectors", async () => {
|
|
for (const t of kat.tests) {
|
|
expect(await v.verify(t.pk, t.message, t.signature), `tc${t.tcId} (${t.reason})`).to.equal(t.expectedPass);
|
|
}
|
|
});
|
|
|
|
it("accepts the official valid vectors (tc422, tc424)", async () => {
|
|
for (const id of [422, 424]) {
|
|
const t = byId(id);
|
|
expect(await v.verify(t.pk, t.message, t.signature)).to.equal(true);
|
|
}
|
|
});
|
|
|
|
it("rejects explicit byte-flips inside R / SIG_FORS / SIG_HT / message of a valid vector", async () => {
|
|
const t = byId(422);
|
|
expect(await v.verify(t.pk, t.message, t.signature)).to.equal(true);
|
|
expect(await v.verify(t.pk, t.message, flip(t.signature, 0))).to.equal(false); // R
|
|
expect(await v.verify(t.pk, t.message, flip(t.signature, 20))).to.equal(false); // SIG_FORS
|
|
expect(await v.verify(t.pk, t.message, flip(t.signature, 3000))).to.equal(false); // SIG_HT
|
|
expect(await v.verify(t.pk, flip(t.message, 0), t.signature)).to.equal(false); // message
|
|
});
|
|
|
|
it("rejects malformed lengths (cheap early-return)", async () => {
|
|
const t = byId(422);
|
|
expect(await v.verify(t.pk + "00", t.message, t.signature)).to.equal(false);
|
|
expect(await v.verify(t.pk, t.message, t.signature + "00")).to.equal(false);
|
|
expect(await v.verify(t.pk, t.message, t.signature.slice(0, -2))).to.equal(false);
|
|
});
|
|
|
|
it("verifyAndRecord fits under the EIP-7825 2^24 per-tx cap and records the result", async () => {
|
|
const t = byId(422);
|
|
const g = await v.verifyAndRecord.estimateGas(t.pk, t.message, t.signature);
|
|
expect(g).to.be.lessThan(16777216n);
|
|
const tx = await v.verifyAndRecord(t.pk, t.message, t.signature);
|
|
const rc = await tx.wait();
|
|
expect(rc.status).to.equal(1);
|
|
expect(await v.lastResult()).to.equal(true);
|
|
expect(await v.verifyCount()).to.equal(1n);
|
|
});
|
|
});
|