Add support for EIP2098 "short signatures" in the ECDSA library (#2582)
Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
This commit is contained in:
@ -24,23 +24,35 @@ library ECDSA {
|
||||
* be too long), and then calling {toEthSignedMessageHash} on it.
|
||||
*/
|
||||
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
|
||||
// Check the signature length
|
||||
if (signature.length != 65) {
|
||||
revert("ECDSA: invalid signature length");
|
||||
}
|
||||
|
||||
// Divide the signature in r, s and v variables
|
||||
bytes32 r;
|
||||
bytes32 s;
|
||||
uint8 v;
|
||||
|
||||
// ecrecover takes the signature parameters, and the only way to get them
|
||||
// currently is to use assembly.
|
||||
// solhint-disable-next-line no-inline-assembly
|
||||
assembly {
|
||||
r := mload(add(signature, 0x20))
|
||||
s := mload(add(signature, 0x40))
|
||||
v := byte(0, mload(add(signature, 0x60)))
|
||||
// Check the signature length
|
||||
// - case 65: r,s,v signature (standard)
|
||||
// - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098)
|
||||
if (signature.length == 65) {
|
||||
// ecrecover takes the signature parameters, and the only way to get them
|
||||
// currently is to use assembly.
|
||||
// solhint-disable-next-line no-inline-assembly
|
||||
assembly {
|
||||
r := mload(add(signature, 0x20))
|
||||
s := mload(add(signature, 0x40))
|
||||
v := byte(0, mload(add(signature, 0x60)))
|
||||
}
|
||||
} else if (signature.length == 64) {
|
||||
// ecrecover takes the signature parameters, and the only way to get them
|
||||
// currently is to use assembly.
|
||||
// solhint-disable-next-line no-inline-assembly
|
||||
assembly {
|
||||
let vs := mload(add(signature, 0x40))
|
||||
r := mload(add(signature, 0x20))
|
||||
s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
|
||||
v := add(shr(255, vs), 27)
|
||||
}
|
||||
} else {
|
||||
revert("ECDSA: invalid signature length");
|
||||
}
|
||||
|
||||
return recover(hash, v, r, s);
|
||||
|
||||
Reference in New Issue
Block a user