Some checks are pending
contracts-ci / Install (lockfile) → compile → full test suite (push) Waiting to run
contracts-ci / Ethereum interop (EIP-2537 BLS, prague hardfork) (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
22 lines
1.4 KiB
Solidity
22 lines
1.4 KiB
Solidity
// SPDX-License-Identifier: Apache-2.0
|
|
pragma solidity 0.8.23;
|
|
|
|
/// @title MockFalcon512 (TESTS ONLY; its runtime is placed at 0x0AE1 on the local test chain)
|
|
/// @notice A deterministic stand-in for the live Falcon-512 precompile, so the local probes can measure the framing, the pre-images,
|
|
/// the Merkle path and every refusal of PqEquivocationEvidence without a Falcon implementation in the EVM. It reads the input
|
|
/// EXACTLY as the live precompile does (pk(897) || u16(len esig) || nonce(40) || message || esig, esig = 0x29 || body) and
|
|
/// answers 1 iff the 32-byte body equals keccak256(pk || message). Real Falcon seals are measured against the live
|
|
/// precompile on testnet 28001, never with this contract.
|
|
contract MockFalcon512 {
|
|
fallback(bytes calldata input) external returns (bytes memory) {
|
|
if (input.length < 897 + 2 + 40 + 1) return abi.encode(uint256(0));
|
|
uint256 esigLen = uint16(bytes2(input[897:899]));
|
|
if (input.length < 939 + esigLen) return abi.encode(uint256(0));
|
|
uint256 msgLen = input.length - 939 - esigLen;
|
|
bytes calldata esig = input[939 + msgLen:];
|
|
if (esig.length != 33 || uint8(esig[0]) != 0x29) return abi.encode(uint256(0));
|
|
bytes32 want = keccak256(bytes.concat(input[0:897], input[939:939 + msgLen]));
|
|
return abi.encode(uint256(bytes32(esig[1:33]) == want ? 1 : 0));
|
|
}
|
|
}
|