-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Comments
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 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. |
After discussing this with a few people whose opinions I highly value, the conclusion is that non-canonical 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! :) |
Thanks @ricmoo |
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.
The text was updated successfully, but these errors were encountered: