From 30a76459663d2d254216cc7e6a93c4438bbdae88 Mon Sep 17 00:00:00 2001 From: Pascal Marco Caversaccio Date: Wed, 3 Aug 2022 18:42:19 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20=202098=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pascal Marco Caversaccio --- .gitmodules | 3 +++ .prettierignore | 1 + .solhintignore | 1 + lib/solidity-bytes-utils | 1 + test/utils/ECDSA.t.sol | 39 ++++++++++++++++++++++++++++++++++----- 5 files changed, 40 insertions(+), 5 deletions(-) create mode 160000 lib/solidity-bytes-utils diff --git a/.gitmodules b/.gitmodules index 724fdfec..b1be9e7e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "lib/create-util"] path = lib/create-util url = https://github.com/pcaversaccio/create-util.git +[submodule "lib/solidity-bytes-utils"] + path = lib/solidity-bytes-utils + url = https://github.com/GNSPS/solidity-bytes-utils.git diff --git a/.prettierignore b/.prettierignore index 950824b5..f0b66238 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,6 +1,7 @@ node_modules lib/create-util lib/forge-std +lib/solidity-bytes-utils bin cache out diff --git a/.solhintignore b/.solhintignore index f226775b..2d74911a 100644 --- a/.solhintignore +++ b/.solhintignore @@ -1,3 +1,4 @@ node_modules lib/create-util lib/forge-std +lib/solidity-bytes-utils diff --git a/lib/solidity-bytes-utils b/lib/solidity-bytes-utils new file mode 160000 index 00000000..6458fb27 --- /dev/null +++ b/lib/solidity-bytes-utils @@ -0,0 +1 @@ +Subproject commit 6458fb2780a3092bc756e737f246be1de6d3d362 diff --git a/test/utils/ECDSA.t.sol b/test/utils/ECDSA.t.sol index 76e8a74a..13c61161 100644 --- a/test/utils/ECDSA.t.sol +++ b/test/utils/ECDSA.t.sol @@ -3,23 +3,26 @@ pragma solidity ^0.8.15; import {Test} from "../../lib/forge-std/src/Test.sol"; import {console} from "../../lib/forge-std/src/console.sol"; +import {BytesLib} from "../../lib/solidity-bytes-utils/contracts/BytesLib.sol"; import {VyperDeployer} from "../../lib/utils/VyperDeployer.sol"; import {IECDSA} from "../../test/utils/IECDSA.sol"; contract ECDSATest is Test { + using BytesLib for bytes; + VyperDeployer private vyperDeployer = new VyperDeployer(); // solhint-disable-next-line var-name-mixedcase IECDSA private ECDSA; - function to2098Format(bytes calldata signature) + function to2098Format(bytes memory signature) public pure returns (bytes memory) { require(signature.length == 65, "invalid signature length"); require(uint8(signature[32]) >> 7 != 1, "invalid signature 's' value"); - bytes memory short = signature[0:32]; + bytes memory short = signature.slice(0, 64); uint8 parityBit = uint8(short[32]) | ((uint8(signature[64]) % 27) << 7); short[32] = bytes1(parityBit); return short; @@ -37,15 +40,18 @@ contract ECDSATest is Test { assertEq(alice, ECDSA.recover_sig(hash, signature)); // EIP-2098 - // console.logBytes1(signature[32]); - // bytes memory signature2098 = to2098Format(signature); - // assertEq(alice, ECDSA.recover_sig(hash, signature2098)); + bytes memory signature2098 = to2098Format(signature); + assertEq(alice, ECDSA.recover_sig(hash, signature2098)); } function testRecoverWithTooShortSignature() public { bytes32 hash = keccak256("WAGMI"); bytes memory signature = "0x0123456789"; assertEq(address(0), ECDSA.recover_sig(hash, signature)); + + // EIP-2098 + vm.expectRevert(bytes("invalid signature length")); + to2098Format(signature); } function testRecoverWithTooLongSignature() public { @@ -55,6 +61,10 @@ contract ECDSATest is Test { ); vm.expectRevert(); ECDSA.recover_sig(hash, signature); + + // EIP-2098 + vm.expectRevert(bytes("invalid signature length")); + to2098Format(signature); } function testRecoverWithArbitraryMessage() public { @@ -63,6 +73,10 @@ contract ECDSATest is Test { (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, hash); bytes memory signature = abi.encodePacked(r, s, v); assertEq(alice, ECDSA.recover_sig(hash, signature)); + + // EIP-2098 + bytes memory signature2098 = to2098Format(signature); + assertEq(alice, ECDSA.recover_sig(hash, signature2098)); } function testRecoverWithWrongMessage() public { @@ -73,6 +87,10 @@ contract ECDSATest is Test { bytes32 hashWrong = keccak256("WAGMI1"); address recoveredAddress = ECDSA.recover_sig(hashWrong, signature); assertTrue(alice != recoveredAddress); + + // EIP-2098 + bytes memory signature2098 = to2098Format(signature); + assertTrue(alice != ECDSA.recover_sig(hashWrong, signature2098)); } function testRecoverWithInvalidSignature() public { @@ -119,6 +137,12 @@ contract ECDSATest is Test { abi.encodePacked(signatureWithoutVersion, v) ) ); + + // EIP-2098 + bytes memory signature2098 = to2098Format( + abi.encodePacked(signatureWithoutVersion, v) + ); + assertEq(alice, ECDSA.recover_sig(hash, signature2098)); } function testRecoverWithTooHighSValue() public { @@ -129,6 +153,11 @@ contract ECDSATest is Test { bytes memory signature = abi.encodePacked(r, bytes32(sTooHigh), v); vm.expectRevert(bytes("ECDSA: invalid signature 's' value")); ECDSA.recover_sig(hash, signature); + + // EIP-2098 + vm.expectRevert(bytes("invalid signature 's' value")); + bytes memory signature2098 = to2098Format(signature); + vm.expectRevert(bytes("invalid signature 's' value")); } function testEthSignedMessageHash() public {