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.
104 lines
3.6 KiB
JavaScript
104 lines
3.6 KiB
JavaScript
// gen_vectors.mjs
|
|
//
|
|
// Generate `xmss-verify-core/src/vectors.rs` from the OFFICIAL RFC 8391
|
|
// XMSS-SHA2_10_256 known-answer vector committed at
|
|
// aerenew/contracts/test/fixtures/xmss-sha2_10_256-kat.json
|
|
// (github.com/XMSS/xmss-reference deterministic test/vectors.c, oid=1, idx=512, msg=0x25).
|
|
//
|
|
// This exists so the Rust test vector is provably DERIVED from the committed
|
|
// official fixture, with no hand transcription of the 67 WOTS+ chains and 10
|
|
// authentication-path nodes. Run:
|
|
// node scripts/gen_vectors.mjs
|
|
//
|
|
// Deterministic: same input JSON -> byte-identical vectors.rs.
|
|
|
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
import { fileURLToPath } from "node:url";
|
|
import { dirname, resolve } from "node:path";
|
|
|
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
const katPath = resolve(
|
|
here,
|
|
"../../../contracts/test/fixtures/xmss-sha2_10_256-kat.json"
|
|
);
|
|
const outPath = resolve(here, "../xmss-verify-core/src/vectors.rs");
|
|
|
|
const kat = JSON.parse(readFileSync(katPath, "utf8"));
|
|
|
|
const strip = (h) => h.replace(/^0x/, "");
|
|
const bytes = (h) => {
|
|
const s = strip(h);
|
|
if (s.length % 2 !== 0) throw new Error(`odd hex: ${h}`);
|
|
const out = [];
|
|
for (let i = 0; i < s.length; i += 2) out.push(parseInt(s.slice(i, i + 2), 16));
|
|
return out;
|
|
};
|
|
const arr32 = (h) => {
|
|
const b = bytes(h);
|
|
if (b.length !== 32) throw new Error(`expected 32 bytes, got ${b.length}: ${h}`);
|
|
return b;
|
|
};
|
|
|
|
const fmtHash = (b) =>
|
|
"[" + b.map((x) => "0x" + x.toString(16).padStart(2, "0")).join(", ") + "]";
|
|
|
|
const fmtHashArray = (list, indent) =>
|
|
list.map((h) => `${indent}${fmtHash(arr32(h))},`).join("\n");
|
|
|
|
const msgBytes = bytes(kat.msg);
|
|
|
|
if (kat.wots.length !== 67) throw new Error(`expected 67 WOTS chains, got ${kat.wots.length}`);
|
|
if (kat.auth.length !== 10) throw new Error(`expected 10 auth nodes, got ${kat.auth.length}`);
|
|
|
|
const out = `// GENERATED by scripts/gen_vectors.mjs from the OFFICIAL committed KAT
|
|
// aerenew/contracts/test/fixtures/xmss-sha2_10_256-kat.json
|
|
// Source: ${kat.source}
|
|
// Do NOT edit by hand: re-run \`node scripts/gen_vectors.mjs\`.
|
|
//
|
|
// RFC 8391 XMSS-SHA2_10_256 (OID 0x00000001): n=32, w=16, len=67, h=10, SHA-256.
|
|
// This is the same official reference vector the on-chain AereXmssVerifier.sol and
|
|
// its independent JS oracle (contracts/test/xmssVerifier.test.js) are validated with.
|
|
|
|
use crate::{Hash, XmssPubKey, XmssSig, H, LEN};
|
|
|
|
/// Long-term XMSS public root (first 32 bytes of the XMSS public key).
|
|
pub const PUB_ROOT: Hash = ${fmtHash(arr32(kat.pubRoot))};
|
|
|
|
/// XMSS public SEED (last 32 bytes of the XMSS public key).
|
|
pub const PUB_SEED: Hash = ${fmtHash(arr32(kat.pubSeed))};
|
|
|
|
/// Leaf index used by the signer for this signature.
|
|
pub const IDX: u32 = ${kat.idx};
|
|
|
|
/// Per-signature randomizer R (from the signature).
|
|
pub const R: Hash = ${fmtHash(arr32(kat.R))};
|
|
|
|
/// The signed message bytes.
|
|
pub const MSG: [u8; ${msgBytes.length}] = ${fmtHash(msgBytes)};
|
|
|
|
/// The 67 WOTS+ one-time-signature chain values.
|
|
pub const WOTS: [Hash; LEN] = [
|
|
${fmtHashArray(kat.wots, " ")}
|
|
];
|
|
|
|
/// The h = 10 Merkle authentication-path nodes.
|
|
pub const AUTH: [Hash; H] = [
|
|
${fmtHashArray(kat.auth, " ")}
|
|
];
|
|
|
|
/// The official reference public key as a [\`XmssPubKey\`].
|
|
pub fn official_pubkey() -> XmssPubKey {
|
|
XmssPubKey { root: PUB_ROOT, seed: PUB_SEED }
|
|
}
|
|
|
|
/// The official reference signature as a [\`XmssSig\`].
|
|
pub fn official_sig() -> XmssSig {
|
|
XmssSig { idx: IDX, r: R, wots: WOTS, auth: AUTH }
|
|
}
|
|
`;
|
|
|
|
writeFileSync(outPath, out);
|
|
console.log(`wrote ${outPath}`);
|
|
console.log(` pubRoot ${kat.pubRoot}`);
|
|
console.log(` idx ${kat.idx}, msg ${kat.msg}, ${kat.wots.length} WOTS chains, ${kat.auth.length} auth nodes`);
|