Signature Malleability: (#1622)

* Transaction Malleability:
If you allow for both values 0/1 and 27/28, you allow two different
signatures both resulting in a same valid recovery. (r,s,0/1) and
(r,s,27/28) would both be valid, recover the same public key and sign
the same data. Furthermore, given (r,s,0/1), (r,s,27/28) can be
constructed by anyone.

* Transaction Malleability:
EIP-2 still allows signature malleabality for ecrecover(), remove this
possibility and force the signature to be unique.

* Added a reference to appendix F to the yellow paper and improved
comment.

* better test description for testing the version 0, which returns
a zero address

* Check that the conversion from 0/1 to 27/28 only happens if its 0/1

* improved formatting

* Refactor ECDSA code a bit.

* Refactor ECDSA tests a bit.

* Add changelog entry.

* Add high-s check test.
This commit is contained in:
Thomas Bocek
2019-03-07 16:44:28 +01:00
committed by Nicolás Venturo
parent 547a5f242a
commit 79dd498b16
4 changed files with 66 additions and 35 deletions

View File

@ -9,9 +9,21 @@ function toEthSignedMessageHash (messageHex) {
return web3.utils.sha3(Buffer.concat([prefix, messageBuffer]));
}
function fixSignature (signature) {
// in geth its always 27/28, in ganache its 0/1. Change to 27/28 to prevent
// signature malleability if version is 0/1
// see https://github.com/ethereum/go-ethereum/blob/v1.8.23/internal/ethapi/api.go#L465
let v = parseInt(signature.slice(130, 132), 16);
if (v < 27) {
v += 27;
}
const vHex = v.toString(16);
return signature.slice(0, 130) + vHex;
}
// signs message in node (ganache auto-applies "Ethereum Signed Message" prefix)
const signMessage = (signer, messageHex = '0x') => {
return web3.eth.sign(messageHex, signer);
async function signMessage (signer, messageHex = '0x') {
return fixSignature(await web3.eth.sign(messageHex, signer));
};
/**
@ -50,5 +62,6 @@ const getSignFor = (contract, signer) => (redeemer, methodName, methodArgs = [])
module.exports = {
signMessage,
toEthSignedMessageHash,
fixSignature,
getSignFor,
};