-
Notifications
You must be signed in to change notification settings - Fork 12.4k
ECDSA: add parse and tryParse #5814
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
f839be4
144b0e2
e9d04b3
65f0059
7b80596
d409599
ec112c7
069e9d4
a63d6a0
4ead44c
23c393f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| 'openzeppelin-solidity': minor | ||
| --- | ||
|
|
||
| `ECDSA`: Add `parse` and `parseCalldata` to parse bytes signatures of length 65 or 64 (eip-2098) into its v,r,s components. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -196,6 +196,63 @@ library ECDSA { | |
| return recovered; | ||
| } | ||
|
|
||
| /** | ||
| * @dev Parse a signature into its `v`, `r` and `s` components. Supports both 65 bytes and 64 bytes (eip-2098) | ||
| * signature formats. Returns 0, 0, 0 is the signature is not in a proper format. | ||
ernestognw marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| */ | ||
Amxx marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| function parse(bytes memory signature) internal pure returns (int8 v, bytes32 r, bytes32 s) { | ||
|
||
| assembly ("memory-safe") { | ||
| // Check the signature length | ||
| switch mload(signature) | ||
| // - case 65: r,s,v signature (standard) | ||
| case 65 { | ||
| r := mload(add(signature, 0x20)) | ||
| s := mload(add(signature, 0x40)) | ||
| v := byte(0, mload(add(signature, 0x60))) | ||
| } | ||
| // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) | ||
| case 64 { | ||
| let vs := mload(add(signature, 0x40)) | ||
| r := mload(add(signature, 0x20)) | ||
| s := and(vs, shr(1, not(0))) | ||
| v := add(shr(255, vs), 27) | ||
| } | ||
| default { | ||
| r := 0 | ||
| s := 0 | ||
| v := 0 | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * @dev Variant of {parse} that takes a signature in calldata | ||
| */ | ||
| function parseCalldata(bytes calldata signature) internal pure returns (int8 v, bytes32 r, bytes32 s) { | ||
| assembly ("memory-safe") { | ||
| // Check the signature length | ||
| switch signature.length | ||
| // - case 65: r,s,v signature (standard) | ||
| case 65 { | ||
| r := calldataload(signature.offset) | ||
| s := calldataload(add(signature.offset, 0x20)) | ||
| v := byte(0, calldataload(add(signature.offset, 0x40))) | ||
| } | ||
| // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) | ||
| case 64 { | ||
| let vs := calldataload(add(signature.offset, 0x20)) | ||
| r := calldataload(signature.offset) | ||
| s := and(vs, shr(1, not(0))) | ||
| v := add(shr(255, vs), 27) | ||
| } | ||
| default { | ||
| r := 0 | ||
| s := 0 | ||
| v := 0 | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided. | ||
| */ | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.