Skip to content

Instantly share code, notes, and snippets.

@rumkin
Last active May 15, 2020 22:15
Show Gist options
  • Save rumkin/03002655aa11f38f16ff91e944d84b24 to your computer and use it in GitHub Desktop.
Save rumkin/03002655aa11f38f16ff91e944d84b24 to your computer and use it in GitHub Desktop.
Ethereum address from a signature.
pragma solidity ^0.6.0;
import "elliptic-curve-solidity/contracts/EllipticCurve.sol";
/**
* @title Secp256k1 Elliptic Curve
* @notice Example of particularization of Elliptic Curve for secp256k1 curve
* @author Witnet Foundation
*/
contract Secp256k1 {
uint256 public constant GX = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798;
uint256 public constant GY = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8;
uint256 public constant AA = 0;
uint256 public constant BB = 7;
uint256 public constant PP = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F;
/// @dev Public Key derivation from private key
/// @param privKey The private key
/// @return (qx, qy) The Public Key
function derivePubKey(uint256 privKey) external pure returns (uint256, uint256) {
return EllipticCurve.ecMul(
privKey,
GX,
GY,
AA,
PP
);
}
function generateAddress(uint256 privKey) external pure returns (address) {
(uint256 qx, uint256 qy) = EllipticCurve.ecMul(
privKey,
GX,
GY,
AA,
PP
);
address addr;
bytes32 hash = keccak256(encodePoint(qx,qy));
assembly {
mstore(0, hash)
addr := mload(0)
}
return addr;
}
function encodePoint(uint256 _x, uint256 _y) internal pure returns (bytes memory) {
uint8 prefix = uint8(2 + (_y % 2));
return abi.encodePacked(prefix, _x);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment