Skip to content

Commit

Permalink
Create tests for EIP1271 message prefix detection
Browse files Browse the repository at this point in the history
  • Loading branch information
popzxc committed Mar 7, 2022
1 parent ab8b895 commit 01b4915
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 5 deletions.
13 changes: 8 additions & 5 deletions sdk/zksync.js/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -502,11 +502,12 @@ export async function verifyERC1271Signature(
address: string,
message: Uint8Array,
signature: string,
signerOrProvider: ethers.Signer | ethers.providers.Provider
signerOrProvider: ethers.Signer | ethers.providers.Provider,
messagePrefixed: boolean = true
): Promise<boolean> {
const EIP1271_SUCCESS_VALUE = '0x1626ba7e';

const signMessage = getSignedBytesFromMessage(message, true);
const signMessage = getSignedBytesFromMessage(message, messagePrefixed);
const signMessageHash = utils.keccak256(signMessage);

const eip1271 = new ethers.Contract(address, IEIP1271_INTERFACE, signerOrProvider);
Expand All @@ -516,12 +517,14 @@ export async function verifyERC1271Signature(

export async function getEthSignatureType(
_provider: ethers.providers.Provider,
message: string,
message: utils.BytesLike | string,
signature: string,
address: string
): Promise<EthSignerType> {
const messageNoPrefix = getSignedBytesFromMessage(message, false);
const messageWithPrefix = getSignedBytesFromMessage(message, true);
const messageBytes = typeof message === 'string' ? utils.toUtf8Bytes(message) : utils.arrayify(message);

const messageNoPrefix = getSignedBytesFromMessage(messageBytes, false);
const messageWithPrefix = getSignedBytesFromMessage(messageBytes, true);

const prefixedECDSASigner = utils.recoverAddress(utils.keccak256(messageWithPrefix), signature);
if (prefixedECDSASigner.toLowerCase() === address.toLowerCase()) {
Expand Down
43 changes: 43 additions & 0 deletions sdk/zksync.js/tests/eip1271.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,47 @@ describe('EIP1271 signature check', function () {

expect(signatureValid, 'EIP1271 signature is invalid').to.be.true;
});

it('Test EIP1271 prefix detection', async () => {
const initialMessage = 'hello-world';
const initialMessageBytes = ethers.utils.toUtf8Bytes(initialMessage);
const message = zkUtils.getSignedBytesFromMessage(initialMessage, false);

// Sign with prefix.
const signaturePrefixed = await zkUtils.signMessagePersonalAPI(ethSigner, message);
const signatureTypePrefixed = await zkUtils.getEthSignatureType(
provider,
message,
signaturePrefixed,
testConfig.eip1271.contract_address
);

expect(signatureTypePrefixed.verificationMethod, 'Invalid signature type').to.eq('ERC-1271');
expect(signatureTypePrefixed.isSignedMsgPrefixed, 'Invalid prefix type detected').to.be.true;

// Sign without prefix. Ethers signer doesn't allow us to sign a message without prefix prepended,
// so we manually create a private key and sign the hash of the message.
const pkSigner = new ethers.utils.SigningKey(testConfig.eip1271.owner_private_key);
const messageHash = ethers.utils.arrayify(ethers.utils.keccak256(message));
const signatureNotPrefixed = ethers.utils.joinSignature(pkSigner.signDigest(messageHash));
const signatureTypeNotPrefixed = await zkUtils.getEthSignatureType(
provider,
message,
signatureNotPrefixed,
testConfig.eip1271.contract_address
);

// Sanity check. We've signed the message manually, so it's better to check that it's correct...
const signatureNotPrefixedValid = await zkUtils.verifyERC1271Signature(
testConfig.eip1271.contract_address,
initialMessageBytes,
signatureNotPrefixed,
ethSigner,
false
);
expect(signatureNotPrefixedValid, 'Not prefixed EIP1271 signature is invalid').to.be.true;

expect(signatureTypeNotPrefixed.verificationMethod, 'Invalid signature type').to.eq('ERC-1271');
expect(signatureTypeNotPrefixed.isSignedMsgPrefixed, 'Invalid prefix type detected').to.be.false;
});
});

0 comments on commit 01b4915

Please sign in to comment.