Commit 478d1b1a by Augusto Committed by Francisco Giordano

Removed safeRecover, using ecrecover method instead, recovering signature from entire hash

parent a68eaa4e
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -10,76 +10,35 @@ pragma solidity ^0.4.11; ...@@ -10,76 +10,35 @@ pragma solidity ^0.4.11;
library ECRecovery { library ECRecovery {
/** /**
* @dev Duplicate Solidity's ecrecover, but catching the CALL return value
* @param hash bytes32 messahe hash from which the signature will be recovered
* @param v uint8 signature version
* @param r bytes32 signature r value
* @param s bytes32 signature s value
*/
function safeRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) constant returns (bool, address) {
// We do our own memory management here. Solidity uses memory offset
// 0x40 to store the current end of memory. We write past it (as
// writes are memory extensions), but don't update the offset so
// Solidity will reuse it. The memory used here is only needed for
// this context.
bool ret;
address addr;
assembly {
let size := mload(0x40)
mstore(size, hash)
mstore(add(size, 32), v)
mstore(add(size, 64), r)
mstore(add(size, 96), s)
// NOTE: we can reuse the request memory because we deal with
// the return code
ret := call(3000, 1, 0, size, 128, size, 32)
addr := mload(size)
}
return (ret, addr);
}
/**
* @dev Recover signer address from a message by using his signature * @dev Recover signer address from a message by using his signature
* @param hash bytes32 messahe hash from which the signature will be recovered * @param hash bytes32 message hash from which the signature will be recovered
* @param sig bytes signature * @param sig bytes signature, the siganture is generated using web3.eth.sign()
*/ */
function recover(bytes32 hash, bytes sig) constant returns (address) { function recover(bytes32 hash, bytes sig) constant returns (address) {
bytes32 r; bytes32 r;
bytes32 s; bytes32 s;
uint8 v; uint8 v;
//Check the signature length
if (sig.length != 65) if (sig.length != 65)
return (address(0)); return (address(0));
// Divide the signature in r, s and v variables
assembly { assembly {
r := mload(add(sig, 32)) r := mload(add(sig, 32))
s := mload(add(sig, 64)) s := mload(add(sig, 64))
v := byte(0, mload(add(sig, 96))) v := byte(0, mload(add(sig, 96)))
} }
// albeit non-transactional signatures are not specified by the YP, one would expect it // Version of signature should be 27 or 28, but 0 and 1 are also possible versions
// to match the YP range of [27, 28]
//
// geth uses [0, 1] and some clients have followed. This might change, see:
// https://github.com/ethereum/go-ethereum/issues/2053
if (v < 27) if (v < 27)
v += 27; v += 27;
// If the version is correct return the signer address
if (v != 27 && v != 28) if (v != 27 && v != 28)
return (address(0)); return (address(0));
bool ret;
address addr;
(ret, addr) = safeRecover(hash, v, r, s);
if (!ret)
return address(0);
else else
return addr; return ecrecover(hash, v, r, s);
} }
} }
ECReovery ECReovery
============================================= =============================================
Recover the signer address of messages using elliptic curve signatures.
safeRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal returns (bool, address)
"""""""""""""""""""""""""""""""""""""""""""""""""
Returns the signer of the the hash using the signature divided in v, r, and s values. Returns the signer of the the hash using the signature divided in v, r, and s values.
recover(bytes32 hash, bytes sig) internal returns (address) recover(bytes32 hash, bytes sig) internal returns (address)
""""""""""""""""""""""""""""""""""""""""""""""""" """""""""""""""""""""""""""""""""""""""""""""""""
Returns the signer of the the hash using the signature that provides the web3.sign() method. Returns the signer of the the hash using the signature that provides the web3.eth.sign() method.
...@@ -22,28 +22,16 @@ contract('ECRecovery', function(accounts) { ...@@ -22,28 +22,16 @@ contract('ECRecovery', function(accounts) {
assert.equal(signer, await ecrecovery.recover(message, signature)); assert.equal(signer, await ecrecovery.recover(message, signature));
}); });
it("safeRecover v0", async function() { it("recover using web3.eth.sign()", async function() {
let signer = '0x58d5f9f841bcf9e502b438cc81d1ea3ba3f8f7f3'; let message = web3.sha3('OpenZeppelin');
let message = '0x7dbaf558b0a1a5dc7a67202117ab143c1d8605a983e4a743bc06fcc03162dc0d'; // web3.sha3('OpenZeppelin') let signature = web3.eth.sign(web3.eth.accounts[0], 'OpenZeppelin');
let signature = '3690f285f30200dfacd35b9ee9af4beaf2c2f4b7880d93dd9bdf776e8fdbec6a095d00c80e20e95a68c8effc038707dd740aabf94a6ca37c09733874f772d6e000'; assert.equal(web3.eth.accounts[0], await ecrecovery.recover(message, signature));
let v = (signature.substring(128,130) == '01') ? 28 : 27;
let r = '0x'+signature.substring(0,64);
let s = '0x'+signature.substring(64,128);
let result = await ecrecovery.safeRecover(message, v, r, s);
assert.equal(signer, result[1]);
assert.equal(true, result[0]);
}); });
it("safeRecover v1", async function() { it("recover using web3.eth.sign() should return wrong signer", async function() {
let signer = '0x0b8124c2429c44e8ca31e7db6f85845abf146415'; let message = web3.sha3('OpenZeppelin');
let message = '0x7dbaf558b0a1a5dc7a67202117ab143c1d8605a983e4a743bc06fcc03162dc0d'; // web3.sha3('OpenZeppelin') let signature = web3.eth.sign(web3.eth.accounts[0], message);
let signature = '7696f87b3f14e2f1c408c552c0005479bfe35df3a9efb493a2ad2bdf25d95c8c605b6f83699faca9bcbc3c665b434ed8d9c717aa71a1916f054fc41671dd38ad01'; assert.notEqual(web3.eth.accounts[0], await ecrecovery.recover(web3.sha3('OpenZeppelin2'), signature));
let v = (signature.substring(128,130) == '01') ? 28 : 27;
let r = '0x'+signature.substring(0,64);
let s = '0x'+signature.substring(64,128);
let result = await ecrecovery.safeRecover(message, v, r, s);
assert.equal(signer, result[1]);
assert.equal(true, result[0]);
}); });
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment