Submitted by fyamf, also found by 0xastronatey, Davymutinda77, and AshutoshSB
On Ethereum, its possible to create two different valid signatures for the same message (known as ECDSA Signature Malleability). However, on Kakarot, you can create three different valid signatures for the same message. This happens because, on Ethereum, if the value of s is higher than the maximum valid range, it returns address(0). On Kakarot, in this case, it returns a valid address.
If r and v are in the valid range, and s is between 1 and secp256k1n, the ecrecover function behaves the same on both Ethereum and Kakarot.
Heres an example for better clarity. The ecrecover function for the following inputs will return the same result 0x992FEaf0E360bffaeAcf57c28D2a3F5059Fe0982:
While inputs 1 and 2 behave as expected, input 3 highlights the problem. With input 3, Ethereums ecrecover returns address(0), but Kakarot returns the same result as input1 and input2.
This shows that a malleability attack on Kakarot can be done in two ways, whereas on Ethereum, it can only be done in one.
In simple terms, on Ethereum, a malleability attack can be done by changing the v from 27 to 28 (or vice versa) and swapping s with secp256k1n - s:
On Kakarot, the malleability attack can be done in two ways: either by changing s to secp256k1n + s (as long as its not larger than 2**256 - 1) or using the same method as Ethereum by changing the v and swapping s with secp256k1n - s:
OR:
The value of s needs to be limited in the ec_recover::run function to make sure its within the valid range.
https://github.com/kkrt-labs/kakarot/blob/7411a5520e8a00be6f5243a50c160e66ad285563/src/kakarot/precompiles/ec_recover.cairo#L40
In the following test, three different combinations of (r, s, v) are provided as parameters to the ecrecover function, and the result for all of them is the same.
To run the end-to-end tests correctly, the make test-end-to-end14 command should be used, as defined in the Makefile.
The output log is:
The following modifications are needed to constraint the valid range of s:
https://github.com/kkrt-labs/kakarot/blob/7411a5520e8a00be6f5243a50c160e66ad285563/src/kakarot/precompiles/ec_recover.cairo#L40
Context
ClementWalter (Kakarot) confirmed and commented:
Kakarot mitigated:
Status: Partially mitigated. Full details in report from RadiantLabs included in the Mitigation Review section below.
