One table, for looking up. The explanations are on The five precompiles and Falcon input framing.
Mainnet
| Address | Function | Standard | Gas | Input | Output | ||||
|---|---|---|---|---|---|---|---|---|---|
0x0AE1 | Falcon-512 verify | NIST Falcon round 3 | 40,000 | `pk(897) \ | \ | sm` | 32-byte word, …01 valid | ||
0x0AE2 | Falcon-1024 verify | NIST Falcon round 3 | 75,000 | `pk(1793) \ | \ | sm` | 32-byte word, …01 valid | ||
0x0AE3 | ML-DSA-44 verify | FIPS 204 | 55,000 | `pk(1312) \ | \ | sig(2420) \ | \ | message` | 32-byte word, …01 valid |
0x0AE4 | SLH-DSA-SHA2-128s verify | FIPS 205 | 350,000 | `pk(32) \ | \ | sig(7856) \ | \ | message` | 32-byte word, …01 valid |
0x0AE5 | SHAKE256 XOF | FIPS 202 | 60 + 12 per 32-byte word of input plus output | 32-byte big-endian outLen, then data | outLen bytes |
Active from block 9,189,161. Gas is flat for the four verifiers.
Falcon sm layout
sm = sigLen(2, big-endian) || nonce(40) || message || esig
esig = (0x20 + logn) || compressedSignature
0x29 for Falcon-512, 0x2A for Falcon-1024
sigLen == len(esig)
pk = (0x00 + logn) || packed_h
0x09 for Falcon-512, 0x0A for Falcon-1024
The message is in the middle. Signature length is variable and must be read per call.
ML-DSA and SLH-DSA layout
sm = signature || message, with the fixed signature lengths above. Everything after pk || sig is the message.
SHAKE256 behaviour
Output length above 65,536 is capped to 65,536. A non-zero high 28 bytes of the length word also caps. Input shorter than 32 bytes returns empty output.
Failure behaviour
The verifiers never revert. Malformed input returns the 32-byte zero word, exactly as an invalid signature does. Put a known-good vector in the same run as a positive control, or a zero tells you nothing.
Testnet only
0x0AE6 (ML-KEM-768 deterministic encapsulation, FIPS 203) and 0x0AE7 exist on the public testnet and are not on mainnet.
Test vectors
The NIST Known-Answer Test vectors used against these implementations ship in the node package under vectors/.