You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
🧐 Motivation
Secp256k1 signatures produced by EOA to sign transaction and messages are usually encode on 65 bytes:
R: 32 bytes
S: 32 bytes
V: 1 bytes.
However, the V parameter can be reduced to only one single bit, and the S parameter only requiers 255 bits to be encoded (due to parity constraints). This result in the signature space fitting inside 64 bytes! EIP2098 describes how to pack the R,S,V values into a shorter R,VS format tat would take less space and thus me less expensive to transmit/store
Ethers.js already include tooling to produce such signatures.
📝 Details
EIP details are available here.
Implementation in the ECDSA only requires to accept 65 & 64 bytes long signatures, split them into R,S,V values, and call the recover method. Since the changes that only in the "bytes unpacking" part of the function, and the actual cryptography check done in ECDSA.recover are not modified or bypassed, there should be no security concern.
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
// Divide the signature in r, s and v variables
bytes32 r;
bytes32 s;
uint8 v;
// 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 {
r := mload(add(signature, 0x20))
s := and(mload(add(signature, 0x40)), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
v := add(shr(7, byte(0, mload(add(signature, 0x40)))), 27)
}
} else {
revert("ECDSA: invalid signature length");
}
return recover(hash, v, r, s);
}
The text was updated successfully, but these errors were encountered:
🧐 Motivation
Secp256k1 signatures produced by EOA to sign transaction and messages are usually encode on 65 bytes:
However, the V parameter can be reduced to only one single bit, and the S parameter only requiers 255 bits to be encoded (due to parity constraints). This result in the signature space fitting inside 64 bytes! EIP2098 describes how to pack the R,S,V values into a shorter R,VS format tat would take less space and thus me less expensive to transmit/store
Ethers.js already include tooling to produce such signatures.
📝 Details
EIP details are available here.
Implementation in the ECDSA only requires to accept 65 & 64 bytes long signatures, split them into R,S,V values, and call the recover method. Since the changes that only in the "bytes unpacking" part of the function, and the actual cryptography check done in ECDSA.recover are not modified or bypassed, there should be no security concern.
The text was updated successfully, but these errors were encountered: