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;
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
* @param hash bytes32 messahe hash from which the signature will be recovered
* @param sig bytes signature
* @param hash bytes32 message hash from which the signature will be recovered
* @param sig bytes signature, the siganture is generated using web3.eth.sign()
*/
function recover(bytes32 hash, bytes sig) constant returns (address) {
bytes32 r;
bytes32 s;
uint8 v;
//Check the signature length
if (sig.length != 65)
return (address(0));
// Divide the signature in r, s and v variables
assembly {
r := mload(add(sig, 32))
s := mload(add(sig, 64))
v := byte(0, mload(add(sig, 96)))
}
// albeit non-transactional signatures are not specified by the YP, one would expect it
// 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
// Version of signature should be 27 or 28, but 0 and 1 are also possible versions
if (v < 27)
v += 27;
// If the version is correct return the signer address
if (v != 27 && v != 28)
return (address(0));
bool ret;
address addr;
(ret, addr) = safeRecover(hash, v, r, s);
if (!ret)
return address(0);
else
return addr;
return ecrecover(hash, v, r, s);
}
}
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.
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) {
assert.equal(signer, await ecrecovery.recover(message, signature));
});
it("safeRecover v0", async function() {
let signer = '0x58d5f9f841bcf9e502b438cc81d1ea3ba3f8f7f3';
let message = '0x7dbaf558b0a1a5dc7a67202117ab143c1d8605a983e4a743bc06fcc03162dc0d'; // web3.sha3('OpenZeppelin')
let signature = '3690f285f30200dfacd35b9ee9af4beaf2c2f4b7880d93dd9bdf776e8fdbec6a095d00c80e20e95a68c8effc038707dd740aabf94a6ca37c09733874f772d6e000';
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("recover using web3.eth.sign()", async function() {
let message = web3.sha3('OpenZeppelin');
let signature = web3.eth.sign(web3.eth.accounts[0], 'OpenZeppelin');
assert.equal(web3.eth.accounts[0], await ecrecovery.recover(message, signature));
});
it("safeRecover v1", async function() {
let signer = '0x0b8124c2429c44e8ca31e7db6f85845abf146415';
let message = '0x7dbaf558b0a1a5dc7a67202117ab143c1d8605a983e4a743bc06fcc03162dc0d'; // web3.sha3('OpenZeppelin')
let signature = '7696f87b3f14e2f1c408c552c0005479bfe35df3a9efb493a2ad2bdf25d95c8c605b6f83699faca9bcbc3c665b434ed8d9c717aa71a1916f054fc41671dd38ad01';
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("recover using web3.eth.sign() should return wrong signer", async function() {
let message = web3.sha3('OpenZeppelin');
let signature = web3.eth.sign(web3.eth.accounts[0], message);
assert.notEqual(web3.eth.accounts[0], await ecrecovery.recover(web3.sha3('OpenZeppelin2'), signature));
});
});
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