Skip to content

Commit 30912dd

Browse files
authored
[protocol] Optimize signature checking (#1740)
1 parent dbba45e commit 30912dd

File tree

1 file changed

+23
-50
lines changed

1 file changed

+23
-50
lines changed

packages/loopring_v3/contracts/lib/SignatureUtil.sol

Lines changed: 23 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@ import "./MathUint.sol";
1010

1111
/// @title SignatureUtil
1212
/// @author Daniel Wang - <[email protected]>
13-
/// @dev This method supports multihash standard. Each signature's first byte indicates
14-
/// the signature's type, the second byte indicates the signature's length, therefore,
15-
/// each signature will have 2 extra bytes prefix. Mulitple signatures are concatenated
16-
/// together.
13+
/// @dev This method supports multihash standard. Each signature's last byte indicates
14+
/// the signature's type.
1715
library SignatureUtil
1816
{
1917
using BytesUtil for bytes;
@@ -82,8 +80,8 @@ library SignatureUtil
8280
returns (bool)
8381
{
8482
return signer.isContract() ?
85-
verifyERC1271Signature(data, signer, signature) :
86-
verifyEOASignature(data, signer, signature);
83+
verifyERC1271WithBytes(data, signer, signature) :
84+
verifyEOASignature(keccak256(data), signer, signature);
8785
}
8886

8987
function verifySignature(
@@ -95,7 +93,9 @@ library SignatureUtil
9593
view
9694
returns (bool)
9795
{
98-
return verifySignature(abi.encodePacked(signHash), signer, signature);
96+
return signer.isContract() ?
97+
verifyERC1271WithBytes32(signHash, signer, signature) :
98+
verifyEOASignature(signHash, signer, signature);
9999
}
100100

101101
function recoverECDSASigner(
@@ -132,28 +132,14 @@ library SignatureUtil
132132
}
133133
}
134134

135-
function recoverECDSASigner(
136-
bytes memory data,
137-
bytes memory signature
138-
)
139-
internal
140-
pure
141-
returns (address addr1, address addr2)
142-
{
143-
if (data.length == 32) {
144-
addr1 = recoverECDSASigner(data.toBytes32(0), signature);
145-
}
146-
addr2 = recoverECDSASigner(keccak256(data), signature);
147-
}
148-
149135
function verifyEOASignature(
150-
bytes memory data,
136+
bytes32 signHash,
151137
address signer,
152138
bytes memory signature
153139
)
154140
private
155141
pure
156-
returns (bool)
142+
returns (bool success)
157143
{
158144
if (signer == address(0)) {
159145
return false;
@@ -162,41 +148,28 @@ library SignatureUtil
162148
uint signatureTypeOffset = signature.length.sub(1);
163149
SignatureType signatureType = SignatureType(signature.toUint8(signatureTypeOffset));
164150

165-
bytes memory stripped = signature.slice(0, signatureTypeOffset);
151+
// Strip off the last byte of the signature by updating the length
152+
assembly {
153+
mstore(signature, signatureTypeOffset)
154+
}
166155

167156
if (signatureType == SignatureType.EIP_712) {
168-
(address addr1, address addr2) = recoverECDSASigner(data, stripped);
169-
return addr1 == signer || addr2 == signer;
157+
success = (signer == recoverECDSASigner(signHash, signature));
170158
} else if (signatureType == SignatureType.ETH_SIGN) {
171-
if (data.length == 32) {
172-
bytes32 hash = keccak256(
173-
abi.encodePacked("\x19Ethereum Signed Message:\n32", data.toBytes32(0))
174-
);
175-
if (recoverECDSASigner(hash, stripped) == signer) {
176-
return true;
177-
}
178-
}
179159
bytes32 hash = keccak256(
180-
abi.encodePacked("\x19Ethereum Signed Message:\n32", keccak256(data))
160+
abi.encodePacked("\x19Ethereum Signed Message:\n32", signHash)
181161
);
182-
return recoverECDSASigner(hash, stripped) == signer;
162+
success = (signer == recoverECDSASigner(hash, signature));
183163
} else {
184-
return false;
164+
success = false;
185165
}
186-
}
187166

188-
function verifyERC1271Signature(
189-
bytes memory data,
190-
address signer,
191-
bytes memory signature
192-
)
193-
private
194-
view
195-
returns (bool)
196-
{
197-
return data.length == 32 &&
198-
verifyERC1271WithBytes32(data.toBytes32(0), signer, signature) ||
199-
verifyERC1271WithBytes(data, signer, signature);
167+
// Restore the signature length
168+
assembly {
169+
mstore(signature, add(signatureTypeOffset, 1))
170+
}
171+
172+
return success;
200173
}
201174

202175
function verifyERC1271WithBytes(

0 commit comments

Comments
 (0)