This is an ERC4337 implementation that includes a smart contract which will verify a falcon 512 signature (FIPS 206)
Falcon consists of:
- Falcon1024: The implementation of the logic for falcon 1024 that includes two external functions: verifySignature and loadPublicKey
- Falcon512: The implementation of the logic for falcon 1024 that includes two external functions: verifySignature and loadPublicKey
- FalconConstants: Values used for the NTT transformations, iNTT transformations, and the acceptance boundary.
- FalconHelperFunctions: Functions that provide outputs modolo Q (12289) includes add, subtract, Montgomery multiplication and division by 2.
- ZKNOX_shake: Functions used to generate the hash message.
These are the only functions required for signature verification.
QuantumAccount is an extension of BaseAccount with the following modifications:
- Constructor: In addition to the EntryPoint address, the constructor takes a falcon address, and a public key in bytes format. The public key uses a raw bytes format instead of the encoding logic used in Falcon; this is to reduce gas consumption. The public key is either 1026 bytes for Falcon512 or 2050 bytes for Falcon1024 where both include a header. The constructor will call the loadPublicKey function.
- _validateSignature: In addition to using the userOp and userOpHash values, the public keys are passed to the Falcon contract for a verifySignature execution.
- updatePublicKeys: This function allows the user to rotate the public keys associated with the QuantumAccount.
This has been tested against EntryPointv0.8.0
The FIPS 206 algorithm uses SHAKE256 to generate the hashed message. The previous version used a Keccak-variant to reduce gas consumption. This newer version uses SHAKE256 and consumes ~4.7 million units of gas for the 512 version and 9.2 million units of gas for the 1024 version.
There is a discord channel that includes the ABIs for QuantumAccount and Falcon and instructions on how to verify the transaction done on Mainnet on October 3rd. That transaction used the older code that was the keccak variant. https://discord.gg/Qc2FcNJD
I have included an archive folder with the original implementation I had written. This implementation uses 40 million gas so it will not work except locally. It has a cleaner, aesthetic style where functions have been organised into various folders and included a lot of validation on values to ensure they were always modolo Q.
In case it was not obvious, the bundlers would still be vulnerable to Shor's algorithm once a quantum computer with sufficient qubits is built. In such a case the worst an attacker could do is drain all the bundlers balances and inhibit transaction flow. Estimates as when that could happen vary between 5 and 15 years. Ethereum will switch from ECDSA before then and falcon is likely a good contender because its public keys and signatures are small when compared with other PQCs. To reduce gas consumption on verification, the public keys are transformed ready for Montgomery multiplication when loaded so they do not need to be transformed with each verification.
If using the C library or python library for generating keys and signatures, ensure the keys are encoded in a raw format when loaded into the contract. The header should be 0x09 for Falcon512 and 0x0A for Falcon1024. The bytes can then be read in pairs to get the key array elements where the first byte is multiplied by 256 and added to the second byte. Failure to not follow this standard could result in loss of contract.