Created
June 26, 2019 16:57
-
-
Save jMyles/9526dee62674718ab97b93793ac45bfa to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.5.3; | |
/** | |
* @notice Library to recover address and verify signatures | |
* @dev Simple wrapper for `ecrecover` | |
**/ | |
library SignatureVerifier { | |
enum HashAlgorithm {KECCAK256, SHA256, RIPEMD160} | |
/** | |
* @notice Recover signer address from hash and signature | |
* @param _hash 32 bytes message hash | |
* @param _signature Signature of hash - 32 bytes r + 32 bytes s + 1 byte v (could be 0, 1, 27, 28) | |
**/ | |
function recover(bytes32 _hash, bytes memory _signature) | |
internal | |
pure | |
returns (address) | |
{ | |
require(_signature.length == 65); | |
bytes32 r; | |
bytes32 s; | |
uint8 v; | |
assembly { | |
r := mload(add(_signature, 32)) | |
s := mload(add(_signature, 64)) | |
v := byte(0, mload(add(_signature, 96))) | |
} | |
// Version of signature should be 27 or 28, but 0 and 1 are also possible versions | |
if (v < 27) { | |
v += 27; | |
} | |
require(v == 27 || v == 28); | |
return ecrecover(_hash, v, r, s); | |
} | |
/** | |
* @notice Transform public key to address | |
* @param _publicKey secp256k1 public key | |
**/ | |
function toAddress(bytes memory _publicKey) internal pure returns (address) { | |
return address(uint160(uint256(keccak256(_publicKey)))); | |
} | |
/** | |
* @notice Hash using one of pre built hashing algorithm | |
* @param _message Signed message | |
* @param _algorithm Hashing algorithm | |
**/ | |
function hash(bytes memory _message, HashAlgorithm _algorithm) | |
internal | |
pure | |
returns (bytes32 result) | |
{ | |
if (_algorithm == HashAlgorithm.KECCAK256) { | |
result = keccak256(_message); | |
} else if (_algorithm == HashAlgorithm.SHA256) { | |
result = sha256(_message); | |
} else { | |
result = ripemd160(_message); | |
} | |
} | |
/** | |
* @notice Verify ECDSA signature | |
* @dev Uses one of pre built hashing algorithm | |
* @param _message Signed message | |
* @param _signature Signature of message hash | |
* @param _publicKey secp256k1 public key in uncompressed format without prefix byte (64 bytes) | |
* @param _algorithm Hashing algorithm | |
**/ | |
function verify( | |
bytes memory _message, | |
bytes memory _signature, | |
bytes memory _publicKey, | |
HashAlgorithm _algorithm | |
) | |
internal | |
pure | |
returns (bool) | |
{ | |
require(_publicKey.length == 64); | |
return toAddress(_publicKey) == recover(hash(_message, _algorithm), _signature); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment