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.
55 lines
2.4 KiB
Solidity
55 lines
2.4 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity 0.8.23;
|
|
|
|
interface IAereFalcon512Verifier {
|
|
function verifySignedMessage(bytes calldata pk, bytes calldata sm) external pure returns (bool);
|
|
}
|
|
|
|
/**
|
|
* @title RealFalcon512PrecompileAdapter, TEST-ONLY real-crypto stand-in for the 0x0AE1 precompile
|
|
*
|
|
* @notice Hardhat has no native PQC precompile. Where MockPQCPrecompile models the precompile's
|
|
* SEMANTICS (accept iff a keccak commitment matches), this adapter runs ACTUAL Falcon-512
|
|
* verification: install it at 0x0AE1 via hardhat_setCode and every registry precompile
|
|
* staticcall (`pk || sm`) is routed into the audited, NIST-KAT-proven AereFalcon512Verifier
|
|
* (see AereFalcon512Verifier.test.js, which accepts the official round-3 KAT vector 0).
|
|
*
|
|
* The precompile wire format is IDENTICAL to the live mainnet precompile and to what
|
|
* AerePQCKeyRegistry / AerePQCThreshold build:
|
|
* input = pk(897) || sm , sm = sigLen(2, big-endian) || nonce(40) || message || esig
|
|
* so a positive result here proves the registry assembled the input at the exact NIST
|
|
* offsets AND that a genuine Falcon-512 signature (not a mock commitment) is accepted. The
|
|
* raw 32-byte return word (0x..01 / 0x..00) matches the live precompile byte layout, so the
|
|
* caller's `ret.length >= 32 && ret[31] == 0x01` check behaves exactly as on chain 2800.
|
|
*
|
|
* The immutable verifier address is baked into runtime bytecode, so it survives the
|
|
* hardhat_setCode copy to 0x0AE1.
|
|
*/
|
|
contract RealFalcon512PrecompileAdapter {
|
|
address public immutable verifier;
|
|
uint256 internal constant PK_LEN = 897; // Falcon-512 public key length
|
|
|
|
constructor(address _verifier) {
|
|
verifier = _verifier;
|
|
}
|
|
|
|
fallback() external {
|
|
bool valid = _check(msg.data);
|
|
bytes32 w = valid ? bytes32(uint256(1)) : bytes32(0);
|
|
assembly {
|
|
mstore(0x0, w)
|
|
return(0x0, 32)
|
|
}
|
|
}
|
|
|
|
function _check(bytes calldata input) internal view returns (bool) {
|
|
if (input.length <= PK_LEN) return false;
|
|
bytes calldata pk = input[0:PK_LEN];
|
|
bytes calldata sm = input[PK_LEN:];
|
|
(bool ok, bytes memory ret) = verifier.staticcall(
|
|
abi.encodeWithSelector(IAereFalcon512Verifier.verifySignedMessage.selector, pk, sm)
|
|
);
|
|
return ok && ret.length >= 32 && abi.decode(ret, (bool));
|
|
}
|
|
}
|