From 8177c4620e049b2749c2069651d7d5b4691e23d2 Mon Sep 17 00:00:00 2001 From: TheGreatHB <74754077+TheGreatHB@users.noreply.github.com> Date: Wed, 8 Feb 2023 10:18:33 +0900 Subject: [PATCH] Improve gas efficiency in ECDSA (#3853) Signed-off-by: Pascal Marco Caversaccio Co-authored-by: Hadrien Croubois Co-authored-by: Pascal Marco Caversaccio --- .changeset/thin-dragons-report.md | 5 +++++ contracts/utils/cryptography/ECDSA.sol | 20 ++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 .changeset/thin-dragons-report.md diff --git a/.changeset/thin-dragons-report.md b/.changeset/thin-dragons-report.md new file mode 100644 index 000000000..b73730f7f --- /dev/null +++ b/.changeset/thin-dragons-report.md @@ -0,0 +1,5 @@ +--- +'openzeppelin-solidity': minor +--- + +`ECDSA`: optimize bytes32 computation by using assembly instead of `abi.encodePacked`. diff --git a/contracts/utils/cryptography/ECDSA.sol b/contracts/utils/cryptography/ECDSA.sol index 3f996520e..a499b546b 100644 --- a/contracts/utils/cryptography/ECDSA.sol +++ b/contracts/utils/cryptography/ECDSA.sol @@ -162,10 +162,15 @@ library ECDSA { * * See {recover}. */ - function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { + function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above - return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, "\x19Ethereum Signed Message:\n32") + mstore(0x1c, hash) + message := keccak256(0x00, 0x3c) + } } /** @@ -189,7 +194,14 @@ library ECDSA { * * See {recover}. */ - function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { - return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); + function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { + /// @solidity memory-safe-assembly + assembly { + let ptr := mload(0x40) + mstore(ptr, "\x19\x01") + mstore(add(ptr, 0x02), domainSeparator) + mstore(add(ptr, 0x22), structHash) + data := keccak256(ptr, 0x42) + } } }