The ECRecover
precompile computes an incorrect key
Description
For the go-ethereum test case ValidKey
, Swisstronik's implementation of ECRecover
returns a zero-length output instead of the expected value. This is due to the presence of the check that the signature's s
value is no more than half the Secp256k1 group order. EIP-2↗, which specifies that signatures with an s
value above half the group order are invalid, also specifies "the ECDSA recover precompiled contract remains unchanged and will keep accepting high s-values; this is useful e.g. if a contract recovers old Bitcoin signatures".
The ValidKey
test case from go-ethereum is as follows and is run using the test described in section ref↗:
{
"Input": "18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c00
0000000000000000000000000000000000000000000000000000000000001c73b1693892219d736c
aba55bdb67216e485557ea6b6af75f37096c9aa6a5a75feeb940b1d03b21e36b0e47e79769f095fe
2ab855bd91e3a38756b7d75a9c4549",
"Expected": "000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"Gas": 3000,
"Name": "ValidKey",
"NoBenchmark": false
},
Impact
Contracts that make use of ECRecover
will fail to accept signatures that they would accept on other EVM implementations.
Recommendations
Remove the check that s > secp256k1n
from the ECRecover
precompile:
- if signature.s().is_high().into() {
- return (ExitSucceed::Returned.into(), [0u8; 0].to_vec());
- }
Remediation
This issue has been acknowledged by Sigma Assets GmbH, and a fix was implemented in commit 9e33b5a7↗.