-
Notifications
You must be signed in to change notification settings - Fork 12.4k
Fix issue with detection of RIP7212 precompile #5620
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 7 commits
c0632e0
7edf9f6
b3d2219
3f58714
88fd7ad
65b1a53
a2e2d65
174db70
670b858
5e7f44b
2627809
a0da59a
a2a0bf2
dcac7dd
7478900
111a0a4
f640dca
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': patch | ||
| --- | ||
|
|
||
| `P256`: Fix precompile detection, avoiding revert in `verifyNative`, and reducing cost of `verify` when the signature is invalid. | ||
Amxx marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -90,10 +90,42 @@ library P256 { | |
| ) private view returns (bool valid, bool supported) { | ||
| if (!_isProperSignature(r, s) || !isValidPublicKey(qx, qy)) { | ||
| return (false, true); // signature is invalid, and its not because the precompile is missing | ||
| } else if (_rip7212(h, r, s, qx, qy)) { | ||
| return (true, true); // precompile is present, signature is valid | ||
| } else if ( | ||
| _rip7212( | ||
| 0x4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4d, | ||
| 0xa73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac, | ||
| 0x36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d60, | ||
| 0x4aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff3, | ||
| 0x7618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e | ||
| ) | ||
Amxx marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ) { | ||
| return (false, true); // precompile is present, signature is invalid | ||
| } else { | ||
| return (false, false); // precompile is absent | ||
| } | ||
| } | ||
|
|
||
| (bool success, bytes memory returndata) = address(0x100).staticcall(abi.encode(h, r, s, qx, qy)); | ||
| return (success && returndata.length == 0x20) ? (abi.decode(returndata, (bool)), true) : (false, false); | ||
| /** | ||
| * @dev Low level helper for {_tryVerifyNative}. Calls the precompile and checks if there is a return value. | ||
| * | ||
| * Note: According to RIP-7212, invalid signature are indistinguishable from the absence of the precompile. | ||
Amxx marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
Amxx marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| * Getting the success boolean, copying the returndata to memory, and loading it as a boolean, is not strictly | ||
| * necessary, but it protects against non-standard implementations that would return 0 (false) for | ||
| * invalid signatures. | ||
| */ | ||
| function _rip7212(bytes32 h, bytes32 r, bytes32 s, bytes32 qx, bytes32 qy) private view returns (bool isValid) { | ||
| assembly ("memory-safe") { | ||
| let ptr := mload(0x40) | ||
| mstore(ptr, h) | ||
| mstore(add(ptr, 0x20), r) | ||
| mstore(add(ptr, 0x40), s) | ||
| mstore(add(ptr, 0x60), qx) | ||
| mstore(add(ptr, 0x80), qy) | ||
ernestognw marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| let success := staticcall(gas(), 0x100, ptr, 0xa0, 0x00, 0x20) | ||
| isValid := and(success, and(eq(returndatasize(), 0x20), eq(mload(0), 1))) | ||
| } | ||
|
||
| } | ||
|
|
||
| /** | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.