-
Notifications
You must be signed in to change notification settings - Fork 12.4k
Move ECDSA message hash methods to its own MessageHashUtils library
#4430
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 all commits
4dad3d5
c2ddcd8
491f622
b3e760f
940e9ee
048fe76
878f253
f5a1c55
d976a6f
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': major | ||
| --- | ||
|
|
||
| `MessageHashUtils`: Add a new library for creating message digest to be used along with signing or recovery such as ECDSA or ERC-1271. These functions are moved from the `ECDSA` library. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| // SPDX-License-Identifier: MIT | ||
|
|
||
| pragma solidity ^0.8.19; | ||
|
|
||
| import {Strings} from "../Strings.sol"; | ||
|
|
||
| /** | ||
| * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing. | ||
| * | ||
| * The library provides methods for generating a hash of a message that conforms to the | ||
| * https://eips.ethereum.org/EIPS/eip-191[EIP 191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712] | ||
| * specifications. | ||
| */ | ||
| library MessageHashUtils { | ||
| /** | ||
| * @dev Returns the keccak256 digest of an EIP-191 signed data with version | ||
| * `0x45` (`personal_sign` messages). | ||
| * | ||
| * The digest is calculated by prefixing a bytes32 `messageHash` with | ||
| * `"\x19Ethereum Signed Message:\n32"` and hashing the result. It corresponds with the | ||
| * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method. | ||
| * | ||
| * NOTE: The `hash` parameter is intended to be the result of hashing a raw message with | ||
| * keccak256, althoguh any bytes32 value can be safely used because the final digest will | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "althoguh" -> typo; I think for such a fix no need for a PR overhead and one of you maintainers can quickly fix it in
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| * be re-hashed. | ||
| * | ||
| * See {ECDSA-recover}. | ||
| */ | ||
| function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) { | ||
| /// @solidity memory-safe-assembly | ||
| assembly { | ||
| mstore(0x00, "\x19Ethereum Signed Message:\n32") // 32 is the bytes-length of messageHash | ||
| mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix | ||
| digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20) | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * @dev Returns the keccak256 digest of an EIP-191 signed data with version | ||
| * `0x45` (`personal_sign` messages). | ||
| * | ||
| * The digest is calculated by prefixing an arbitrary `message` with | ||
| * `"\x19Ethereum Signed Message:\n" + len(message)` and hashing the result. It corresponds with the | ||
| * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method. | ||
| * | ||
| * See {ECDSA-recover}. | ||
| */ | ||
| function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32 digest) { | ||
| return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(message.length), message)); | ||
| } | ||
|
|
||
| /** | ||
| * @dev Returns the keccak256 digest of an EIP-191 signed data with version | ||
| * `0x00` (data with intended validator). | ||
| * | ||
| * The digest is calculated by prefixing an arbitrary `data` with `"\x19\x00"` and the intended | ||
| * `validator` address. Then hashing the result. | ||
| * | ||
| * See {ECDSA-recover}. | ||
| */ | ||
| function toDataWithIntendedValidatorHash( | ||
| address validator, | ||
| bytes memory data | ||
| ) internal pure returns (bytes32 digest) { | ||
| return keccak256(abi.encodePacked(hex"19_00", validator, data)); | ||
| } | ||
|
|
||
| /** | ||
| * @dev Returns the keccak256 digest of an EIP-712 typed data (EIP-191 version `0x01`). | ||
| * | ||
| * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with | ||
| * `\x19\x01` and hashing the result. It corresponds to the hash signed by the | ||
| * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712. | ||
| * | ||
| * See {ECDSA-recover}. | ||
| */ | ||
| function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) { | ||
| /// @solidity memory-safe-assembly | ||
| assembly { | ||
| let ptr := mload(0x40) | ||
| mstore(ptr, hex"19_01") | ||
| mstore(add(ptr, 0x02), domainSeparator) | ||
| mstore(add(ptr, 0x22), structHash) | ||
| digest := keccak256(ptr, 0x42) | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.