forked from ethereum/EIPs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
EIP-7213: Falcon Signature verification
- Loading branch information
Showing
1 changed file
with
213 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
--- | ||
eip: xxxx | ||
title: Add Precompile for Falcon512 post-quantum signature verification function | ||
author: Erick Pacheco Pedraza (@eum602), Marcos Allende, Diego Lopez León | ||
discussions-to: https://ethereum-magicians.org/t/eip-xxxx-falcon512-signatures-verification | ||
status: Draft | ||
type: Standards Track | ||
category: Core | ||
created: 2023-07-03 | ||
--- | ||
|
||
## Abstract | ||
|
||
This standard proposes the inclusion of a precompiled signature verification function. The algorithm used is Falcon-512, standarized by NIST and quantum resistant with a security level I. | ||
|
||
A successful signature verification returns a Shake256 digest with 32 bytes output of the Falcon public key, which makes it suitable to be used by smart contracts without implying high transaction fees. | ||
|
||
## Motivation | ||
|
||
The advancement in Quantum Computers is moving faster, what was thought to be ready in 20 years seems to be coming soon due to the effort taken by different entities around the globe. One Step forward on this area is the work that NIST has done in order to analyze and standarize post quantum algorithms. | ||
|
||
## Specification | ||
|
||
The precompiled signature verification function runs at address `0x13`. The required inputs are: | ||
|
||
- `message digest` - a 32 bytes | ||
- `public key` - Falcon Public key of 897 bytes | ||
- `signature` - 666 bytes | ||
|
||
Output is: | ||
|
||
- `result digest` - Shake256 digest with 32 bytes output of the falcon public key. | ||
|
||
### Example Usage in Solidity | ||
|
||
The precompile can be wrapped in Solidity to provide a more development-friendly interface to `Falcon-512` signature verification. | ||
|
||
```solidity | ||
function _falconRecover( | ||
bytes calldata signature, | ||
bytes calldata publicKey, | ||
bytes32 data | ||
) private view returns (bytes32 signer) { | ||
(bool success, bytes memory verifies) = address( | ||
0x0000000000000000000000000000000000000013 | ||
).staticcall( | ||
abi.encodeWithSignature( | ||
"verify(bytes,bytes,bytes32)", | ||
signature, | ||
publicKey, | ||
data | ||
) | ||
); | ||
assembly { | ||
signer := mload(add(verifies, 0x20)) | ||
} | ||
require( | ||
success && verifies.length == 32 && signer != bytes32(0), | ||
"Invalid signature" | ||
); | ||
} | ||
``` | ||
|
||
### Gas costs and benchmarks | ||
|
||
Each operation to execute the precompiled call will require 2350 units of gas (approximate average value taken from 3 benchmark ourputs at 5,10 and 30 seconds). Values for each measurement is presented at the benchmark section. | ||
|
||
## Rationale | ||
|
||
Falcon-512 is a good candidate to be a new signature implementation. First of all, key sizes are relatively small compared to ther signature algorithms that are also quantum resistant. | ||
|
||
The following table shows a summary of the typicall values for keys and the approximate amount of time taken per second to execute signature verifications. [source](https://falcon-sign.info/) | ||
|
||
``` | ||
variant verify/s pub size(bytes) sig size(bytes) | ||
----------------------------------------- --------- ---------------- --------------- | ||
Falcon512 27933.0 897 666 | ||
``` | ||
|
||
Falcon uses shake256 under the hood, an implementation made in solidity showed it is not viable to implement this algorithm at that layer, on the other hand the implementation of falcon-512 by using precompiles turned to be the best approach since the gas cost (as show in the previous section) is relatively low. | ||
|
||
Since Falcon public keys are 897 bytes, the signature verification returns a digest shake256 of 32 bytes output of the falcon public key, otherwise returns bytes32(0). It was made that way to allow smart contracts that call that method to have a digest of the public key which can be used further in the custom contract logic to associate it to some other value or to perform some assertion, in that way contracts can avoid storing the public keys but just the public key digest. | ||
|
||
Implementing just the signature verification is sufficiently enough to open a wide range of use cases at smart contract level. To give an example, this method can perfectly work with the Account Abstraction concept, where the authentication process would rely on Falcon and the account is a smart contract. | ||
|
||
## Backwards Compatibility | ||
|
||
There is very little risk of breaking backwards-compatibility with this EIP, the sole issue being if someone were to build a contract relying on the address at `0x13` being empty. The likelihood of this is low, and should specific instances arise, the address could be chosen to be any arbitrary value with negligible risk of collision. | ||
|
||
## Test Cases | ||
|
||
#### Test vector 0 | ||
|
||
- description: empty input | ||
- input: (empty) | ||
- output: error "invalid input" | ||
|
||
#### Test vector 1 | ||
|
||
- descrption: signature lenght not present in input | ||
- input: | ||
`000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000003103d474d06cef2d8da1c97afd7d4993ba792297ca4e161967578494141cab04202` | ||
- output: error "invalid input" | ||
|
||
#### Test vector 2 | ||
|
||
- description: Signature indicated length is zero | ||
- input: | ||
`000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c03d474d06cef2d8da1c97afd7d4993ba792297ca4e161967578494141cab04202000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000` | ||
- output: error "invalid input" | ||
|
||
#### Test vector 3 | ||
|
||
- description: Public Key indicated length is zero | ||
- input: | ||
`000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c03d474d06cef2d8da1c97afd7d4993ba792297ca4e161967578494141cab04202000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000` | ||
- output: error "invalid input" | ||
|
||
#### Test vector 4 | ||
|
||
- description: Signature indicated length is too long | ||
- input: | ||
`000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c03d474d06cef2d8da1c97afd7d4993ba792297ca4e161967578494141cab04202000000000000000000000000000000000000000000000000000000000007774000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000` | ||
- output: error "invalid input" | ||
|
||
#### Test vector 5 | ||
|
||
- description: Public Key indicated length is too long | ||
- input: | ||
`000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c03d474d06cef2d8da1c97afd7d4993ba792297ca4e161967578494141cab04202000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004444000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000` | ||
- output: error "invalid input" | ||
|
||
#### Test vector 6 | ||
|
||
- description: Well formatted input but invalid signature | ||
- input: | ||
`000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000003103d474d06cef2d8da1c97afd7d4993ba792297ca4e161967578494141cab0420200000000000000000000000000000000000000000000000000000000000002901113b3c07507e4201748494d832b6ee2a6c93bff9b0ee343b550d1f85a3d0de0d704c6d1784295130960fbe956c6851e141ab3c09a5475bdda2d81ee113f1e16e2ddd8e408bbb3f5b06a555d8f1ac072e5be2f9a365b33ace3d8254709c185b6f3d3db4b50baf14536779f24b5e843fb36b5a00ca475d1801a964d09961c1959dad0f80f0615476c75f58e4ae9a9f8eb93e65f1a4753ca75a62269d74a49ddc75f539bfecd60fe3c8966e77b01d9c69a965a39907862b2de754ad319644d21134fccee194278b326aa4e94359f1d4a08814cad9b27d62687cc31cfcf057490cea0512e02b3b3834e6803c30679f2f2ae2bf4d4e670b283f5105dad272da0f8b95168ea1080b184d98787ba335c22a0a40fd5ba4a70d905c373304c2759e695214f741b98629184789ffdaf63731b43188bda77ed49924da34968ee347b973b525ce0b40af92889b479e5e8717c05c923d76f0bf4689747de1821c1c42968eb164a5fe7c25ef75629511ce220c9d71c4fdb4d60b927b1e473dcda691062b6977338e8666b8c82b8f0f118eefeb5e66e408e63aa9cf876a0a4249688aae132955f5ea98fff2bb4f565b4ec4db39d414dd9c9d3edd089ac74af2f9f3feffa72332982d5e470a74bb2b3b7462639ed89319a327e8a11aef2e3cc391789b4c616b1aef335e9b47a294a47d2c42e7daca30c119e8098b6895aa32bb989a675aa72e84dc1ccc8b9f1a6cd274adbb86fc5ca9c2744cd73f064eba715e06dce542ef0646c94f41d3f47bb7c1a6c4e91ee55996dec4cbbc931f0047e3ba251f71b0bbc7e8633cc7479b1361697a131436d5958ee6fd1ccc1a5d31a9a8391bde2d075cce140de8f1dc58a093310821ae1d26917bc2a17dec09225374ee078d977f901825955ec8623304459a51e5cf7fe60c68b16800000000000000000000000000000000000000000000000000000000000000381096ba86cb658a8f445c9a5e4c28374bec879c8655f68526923240918074d0147c03162e4a49200648c652803c6fd7509ae9aa799d6310d0bd42724e0635920186207000767ca5a8546b1755308c304b84fc93b069e265985b398d6b834698287ff829aa820f17a7f4226ab21f601ebd7175226bab256d8888f009032566d6383d68457ea155a94301870d589c678ed304259e9d37b193bc2a7ccbcbec51d69158c44073aec9792630253318bc954dbf50d15028290dc2d309c7b7b02a6823744d463da17749595cb77e6d16d20d1b4c3aad89d320ebe5a672bb96d6cd5c1efec8b811200cbb062e473352540eddef8af9499f8cdd1dc7c6873f0c7a6bcb7097560271f946849b7f373640bb69ca9b518aa380a6eb0a7275ee84e9c221aed88f5bfbaf43a3ede8e6aa42558104faf800e018441930376c6f6e751569971f47adbca5ca00c801988f317a18722a29298925ea154dbc9024e120524a2d41dc0f18fd8d909f6c50977404e201767078ba9a1f9e40a8b2ba9c01b7da3a0b73a4c2a6b4f518bbee3455d0af2204ddc031c805c72ccb647940b1e6794d859aaebcea0deb581d61b9248bd9697b5cb974a8176e8f910469cae0ab4ed92d2aee9f7eb50296daf8057476305c1189d1d9840a0944f0447fb81e511420e67891b98fa6c257034d5a063437d379177ce8d3fa6eaf12e2dbb7eb8e498481612b1929617da5fb45e4cdf893927d8ba842aa861d9c50471c6d0c6df7e2bb26465a0eb6a3a709de792aafaaf922aa95dd5920b72b4b8856c6e632860b10f5cc08450003671af388961872b466400adb815ba81ea794945d19a100622a6ca0d41c4ea620c21dc125119e372418f04402d9fa7180f7bc89afa54f8082244a42f46e5b5abce87b50a7d6febe8d7bbbac92657cbda1db7c25572a4c1d0baea30447a865a2b1036b880037e2f4d26d453e9e913259779e9169b28a62eb809a5c744e04e260e1f2bbda874f1ac674839ddb47b3148c5946de0180148b7973d63c58193b17cd05d16e80cd7928c2a338363a23a81c0608c87505589b9da1c617e7b70786b6754fbb30a5816810b9e126cfcc5aa49326e9d842973874b6359b5db75610ba68a98c7b5e83f125a82522e13b83fb8f864e2a97b73b5d544a7415b6504a13939eab1595d64faf41fab25a864a574de524405e878339877886d2fc07fa0311508252413edfa1158466667aff78386daf7cb4c9b850992f96e20525330599ab601d454688e294c8c3e` | ||
- output: | ||
`0000000000000000000000000000000000000000000000000000000000000000` | ||
|
||
#### Test vector 7 | ||
|
||
- description: Well formatted input and valid signature | ||
- input: | ||
`000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000003103d474d06cef2d8da1c97afd7d4993ba792297ca4e161967578494141cab0420200000000000000000000000000000000000000000000000000000000000002903933b3c07507e4201748494d832b6ee2a6c93bff9b0ee343b550d1f85a3d0de0d704c6d1784295130960fbe956c6851e141ab3c09a5475bdda2d81ee113f1e16e2ddd8e408bbb3f5b06a555d8f1ac072e5be2f9a365b33ace3d8254709c185b6f3d3db4b50baf14536779f24b5e843fb36b5a00ca475d1801a964d09961c1959dad0f80f0615476c75f58e4ae9a9f8eb93e65f1a4753ca75a62269d74a49ddc75f539bfecd60fe3c8966e77b01d9c69a965a39907862b2de754ad319644d21134fccee194278b326aa4e94359f1d4a08814cad9b27d62687cc31cfcf057490cea0512e02b3b3834e6803c30679f2f2ae2bf4d4e670b283f5105dad272da0f8b95168ea1080b184d98787ba335c22a0a40fd5ba4a70d905c373304c2759e695214f741b98629184789ffdaf63731b43188bda77ed49924da34968ee347b973b525ce0b40af92889b479e5e8717c05c923d76f0bf4689747de1821c1c42968eb164a5fe7c25ef75629511ce220c9d71c4fdb4d60b927b1e473dcda691062b6977338e8666b8c82b8f0f118eefeb5e66e408e63aa9cf876a0a4249688aae132955f5ea98fff2bb4f565b4ec4db39d414dd9c9d3edd089ac74af2f9f3feffa72332982d5e470a74bb2b3b7462639ed89319a327e8a11aef2e3cc391789b4c616b1aef335e9b47a294a47d2c42e7daca30c119e8098b6895aa32bb989a675aa72e84dc1ccc8b9f1a6cd274adbb86fc5ca9c2744cd73f064eba715e06dce542ef0646c94f41d3f47bb7c1a6c4e91ee55996dec4cbbc931f0047e3ba251f71b0bbc7e8633cc7479b1361697a131436d5958ee6fd1ccc1a5d31a9a8391bde2d075cce140de8f1dc58a093310821ae1d26917bc2a17dec09225374ee078d977f901825955ec8623304459a51e5cf7fe60c68b16800000000000000000000000000000000000000000000000000000000000000381096ba86cb658a8f445c9a5e4c28374bec879c8655f68526923240918074d0147c03162e4a49200648c652803c6fd7509ae9aa799d6310d0bd42724e0635920186207000767ca5a8546b1755308c304b84fc93b069e265985b398d6b834698287ff829aa820f17a7f4226ab21f601ebd7175226bab256d8888f009032566d6383d68457ea155a94301870d589c678ed304259e9d37b193bc2a7ccbcbec51d69158c44073aec9792630253318bc954dbf50d15028290dc2d309c7b7b02a6823744d463da17749595cb77e6d16d20d1b4c3aad89d320ebe5a672bb96d6cd5c1efec8b811200cbb062e473352540eddef8af9499f8cdd1dc7c6873f0c7a6bcb7097560271f946849b7f373640bb69ca9b518aa380a6eb0a7275ee84e9c221aed88f5bfbaf43a3ede8e6aa42558104faf800e018441930376c6f6e751569971f47adbca5ca00c801988f317a18722a29298925ea154dbc9024e120524a2d41dc0f18fd8d909f6c50977404e201767078ba9a1f9e40a8b2ba9c01b7da3a0b73a4c2a6b4f518bbee3455d0af2204ddc031c805c72ccb647940b1e6794d859aaebcea0deb581d61b9248bd9697b5cb974a8176e8f910469cae0ab4ed92d2aee9f7eb50296daf8057476305c1189d1d9840a0944f0447fb81e511420e67891b98fa6c257034d5a063437d379177ce8d3fa6eaf12e2dbb7eb8e498481612b1929617da5fb45e4cdf893927d8ba842aa861d9c50471c6d0c6df7e2bb26465a0eb6a3a709de792aafaaf922aa95dd5920b72b4b8856c6e632860b10f5cc08450003671af388961872b466400adb815ba81ea794945d19a100622a6ca0d41c4ea620c21dc125119e372418f04402d9fa7180f7bc89afa54f8082244a42f46e5b5abce87b50a7d6febe8d7bbbac92657cbda1db7c25572a4c1d0baea30447a865a2b1036b880037e2f4d26d453e9e913259779e9169b28a62eb809a5c744e04e260e1f2bbda874f1ac674839ddb47b3148c5946de0180148b7973d63c58193b17cd05d16e80cd7928c2a338363a23a81c0608c87505589b9da1c617e7b70786b6754fbb30a5816810b9e126cfcc5aa49326e9d842973874b6359b5db75610ba68a98c7b5e83f125a82522e13b83fb8f864e2a97b73b5d544a7415b6504a13939eab1595d64faf41fab25a864a574de524405e878339877886d2fc07fa0311508252413edfa1158466667aff78386daf7cb4c9b850992f96e20525330599ab601d454688e294c8c3e` | ||
- output: | ||
`73aa7ae4db8706ba89cbc14fa6ad475de55d65cb51c2c492ea4b1a1c4f1853e2` | ||
|
||
## Implementation | ||
|
||
- The implementation for Falcon-512 signature verification can be found in [Golang Liboqs-go](https://github.com/open-quantum-safe/liboqs-go). | ||
- The reference implementation for the precompiled signature using Falcon can be found at [Go-Ethereum](https://github.com/lacchain/go-ethereum/pull/1) | ||
- The reference iplementation for Hyperledger Besu Client can be found at [Besu Client](https://github.com/lacchain/besu/pull/1) | ||
|
||
## References | ||
|
||
For reference, further discussion on this EIP also occurred in the following PRs and issues | ||
|
||
- [Original Issue](https://github.com/ethereum/EIPs/issues/xxxx) | ||
- [Ethereum Magicians](https://ethereum-magicians.org/t/falcon-512-precompile/xxxx) | ||
- [PR xxxx](https://github.com/ethereum/EIPs/pull/xxxx) | ||
|
||
## Appendix - benchmarks | ||
|
||
Assuming ecRecover precompile is perfectly priced, a set of benchmarks were executed comparing Falcon-512 signature verification function precompile with ecRecover precompile. For benchmarks, it was used 2.6 GHz Intel Core i7 64-bit machine. | ||
|
||
```sh | ||
$ cat /proc/cpuinfo | grep "model name" | ||
Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz | ||
``` | ||
|
||
### 5 seconds benchmark | ||
|
||
An average gas price for Falcon-512 precompile call compared to ecRecover precompiled results in 2259 units of gas. | ||
|
||
``` | ||
Name Gascost Time (ns) MGas/S Gasprice for 10MGas/S Gasprice for ECDSA eq | ||
----------------------------------------- --------- ---------------- --------- ----------------------- ----------------------- | ||
PrecompiledEcrecover/ 3000 69396 43.2301 693.96 3000 | ||
PrecompiledFalcon512/ 1 52265 0.0191 522.65 2259.4241 | ||
``` | ||
|
||
### 10 seconds benchmark | ||
|
||
An average gas price for Falcon-512 precompile call compared to ecRecover precompiled results in 2433 units of gas. | ||
|
||
``` | ||
Name Gascost Time (ns) MGas/S Gasprice for 10MGas/S Gasprice for ECDSA eq | ||
----------------------------------------- --------- ---------------- --------- ----------------------- ----------------------- | ||
PrecompiledEcrecover/ 3000 63478 47.2604 634.78 3000 | ||
PrecompiledFalcon512/ 1 51485 0.0194 514.85 2433.2052 | ||
``` | ||
|
||
### 30 seconds benchmark | ||
|
||
An average gas price for Falcon-512 precompile call compared to ecRecover precompiled results in 2370 units of gas. | ||
|
||
``` | ||
Name Gascost Time (ns) MGas/S Gasprice for 10MGas/S Gasprice for ECDSA eq | ||
----------------------------------------- --------- ---------------- --------- ----------------------- ----------------------- | ||
PrecompiledEcrecover/ 3000 65715 45.6516 657.15 3000 | ||
PrecompiledFalcon512/ 1 51928 0.0192 519.28 2370.6003 | ||
``` | ||
|
||
Columns | ||
|
||
- `MGas/S` - Shows what MGas per second was measured on that machine at that time | ||
- `Gasprice for 10MGas/S` shows what the gasprice should have been, in order to reach 10 MGas/second | ||
- `Gasprice for ECDSA eq` shows what the gasprice should have been, in order to have the same cost/cycle as ecRecover | ||
|
||
## Copyright | ||
|
||
Copyright and related rights waived via [CC0](../LICENSE.md). |