Skip to content
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

Using non-canonical v for verifying messages #601

Closed
prashanthbabu07 opened this issue Sep 5, 2019 · 3 comments
Closed

Using non-canonical v for verifying messages #601

prashanthbabu07 opened this issue Sep 5, 2019 · 3 comments
Labels
discussion Questions, feedback and general information.

Comments

@prashanthbabu07
Copy link

prashanthbabu07 commented Sep 5, 2019

let privateKey = '0x0123456789012345678901234567890123456789012345678901234567890123';
let wallet = new ethers.Wallet(privateKey);

wallet.signMessage("Hello").then(signedMessage => console.log(signedMessage));
0x238a9eb4bd1c49b43a900b47cdd285a2450f5f4e6dfc5574f8ae4d0b7c19d270391f076b7f77aa97938a1ad36620460f6f057b8ffecc1acb73604580698e900e1b

ethers.utils.verifyMessage("Hello", "0x238a9eb4bd1c49b43a900b47cdd285a2450f5f4e6dfc5574f8ae4d0b7c19d270391f076b7f77aa97938a1ad36620460f6f057b8ffecc1acb73604580698e900e1b") == wallet.address
true

ethers.utils.verifyMessage("Hello", "0x238a9eb4bd1c49b43a900b47cdd285a2450f5f4e6dfc5574f8ae4d0b7c19d270391f076b7f77aa97938a1ad36620460f6f057b8ffecc1acb73604580698e900eac") == wallet.address
true
Replacing last 2 chars with "ac" of the signed message results in a valid public address.

@ricmoo
Copy link
Member

ricmoo commented Sep 5, 2019

Those last 2 nibbles (1 byte) are used to indicate the recovery param. The canonical values are usually 27 and 28 (for 0 and 1) which indicates the signature parity.

With EIP-155, this value (also called v) also encodes the chain ID, using the formula 35 + 2 * chainId, so there are many values the last byte can take, as it also represents the chain ID.

It’s a good question, whether verify should require the canonical or allow a chainId adjusted v. I will ask a few people in the community whose opinion on such things has seldom let me me down. For now though, I think I will allow an EIP-155 v, but am willing to be convinced otherwise.

I also have an EIP open for a form of compressed signatures which encodes the v as the top bit of the r_x in the signature, allowing signatures to fit exactly into 64 bytes (128 nibbles).

Side note: Solidity ecrecover requires the canonical values and the signing in ethers will always generate the canonical values.

@ricmoo ricmoo added the discussion Questions, feedback and general information. label Sep 5, 2019
@ricmoo ricmoo changed the title verifyMessage issue Using non-canonical v for verifying messages Sep 5, 2019
@ricmoo
Copy link
Member

ricmoo commented Jan 8, 2020

After discussing this with a few people whose opinions I highly value, the conclusion is that non-canonical v should be fine, but that I should document this behaviour.

I've added a note in the docs for v5 which will be included in the next publish.

Please let me know if you have any further comments and thanks! :)

@ricmoo ricmoo closed this as completed Jan 8, 2020
@prashanthbabu07
Copy link
Author

Thanks @ricmoo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion Questions, feedback and general information.
Projects
None yet
Development

No branches or pull requests

2 participants