def customer_private_key(): from eth_keys import KeyAPI from eth_utils import int_to_big_endian keys = KeyAPI() pk_bytes = int_to_big_endian(2).rjust(32, b'\x00') private_key = keys.PrivateKey(pk_bytes) return private_key
def _sign(seq, to, value, data, key): keys = KeyAPI() comb = seq.to_bytes(32, "big") + b'\x00' * 12 + to + value.to_bytes(32, "big") + data h1 = keccak(comb) h2 = keccak(b"\x19Ethereum Signed Message:\n32" + h1) sig = keys.ecdsa_sign(h2, key) return [28 if sig.v == 1 else 27, sig.r, sig.s]
def get_default_account_keys(quantity=None): keys = KeyAPI() quantity = quantity or 10 for i in range(1, quantity + 1): pk_bytes = int_to_big_endian(i).rjust(32, b'\x00') private_key = keys.PrivateKey(pk_bytes) yield private_key
def getPublicKey(transaction, signature): s = Signature(signature_bytes=bytes.fromhex(signature)) txID = hashlib.sha256(bytes.fromhex(transaction)).digest() keys = KeyAPI('eth_keys.backends.NativeECCBackend') public_key = keys.ecdsa_recover(txID, s) logger.debug(' PublicKey: {}'.format(public_key)) return public_key
def sign(msg_hash: bytes, priv_key: bytes) -> bytes: ''' Sign the message hash. (not the message itself) Parameters ---------- msg_hash: bytes The message hash. priv_key: bytes The private key in bytes. Returns ------- bytes The signing result. Raises ------ ValueError If the input is malformed. ''' if not _is_valid_private_key(priv_key): raise ValueError('Private Key not valid.') sig = KeyAPI().ecdsa_sign(msg_hash, KeyAPI.PrivateKey(priv_key)) r = sig.r.to_bytes(32, byteorder='big') s = sig.s.to_bytes(32, byteorder='big') v = sig.v.to_bytes(1, byteorder='big') # public key recovery bit. return b''.join([r, s, v]) # 32 + 32 + 1 bytes
def get_default_account_keys(): keys = KeyAPI() for i in range(1, 11): pk_bytes = int_to_big_endian(i).rjust(32, b'\x00') private_key = keys.PrivateKey(pk_bytes) yield private_key
def verify(msghash: bytes, signature, public_key): """Verify that data has been signed with Etheruem private key. :param signature: :return: """ key_api = KeyAPI('eth_keys.backends.NativeECCBackend') return key_api.ecdsa_verify(msghash, Signature(signature), PublicKey(public_key))
def get_account_keys_from_mnemonic(mnemonic, quantity=None): keys = KeyAPI() seed = seed_from_mnemonic(mnemonic, "") quantity = quantity or 10 for i in range(0, quantity): hd_path = HDPath(f"m/44'/60'/0'/{i}") private_key = keys.PrivateKey(hd_path.derive(seed)) yield private_key
def pub_bytes_to_eth_address(var): pub=var if len(pub) == 65: if pub[0] != 4: raise InvalidKey("unrecognised public key format for key: {}".format(pub)) pub=pub[1:] if len(pub) != 64: #print("Uncompressing pub: {}".format(pub)) pub = uncompress(pub) pk = KeyAPI().PublicKey(pub) return pk.to_checksum_address()
def validate(transaction, signature, public_key): try: s = Signature(signature_bytes=signature) txID = hashlib.sha256( bytes.fromhex(transaction) if type(transaction) is str else transaction).digest() keys = KeyAPI('eth_keys.backends.NativeECCBackend') publicKey = PublicKey(bytes.fromhex(public_key)) return keys.ecdsa_verify(txID, s, publicKey), txID.hex() except: return False, ""
def set_key_backend(self, backend): """ Change the backend used by the underlying eth-keys library. *(The default is fine for most users)* :param backend: any backend that works in `eth_keys.KeyApi(backend) <https://github.com/ethereum/eth-keys/#keyapibackendnone>`_ """ self._keys = KeyAPI(backend)
def recoverHash(message_hash, signature): """ :param message_hash: 32-bytes string :param signature: 130-length string without '0x' :return: """ if isinstance(signature, bytes): signature = signature.decode() signature = signature.replace('0x', '') publick_key = KeyAPI().ecdsa_recover(message_hash, Signature(binascii.a2b_hex(signature))) return checksum_encode(publick_key.to_address())
def recover(msg_hash: bytes, sig: bytes) -> bytes: ''' Recover the uncompressed public key from signature. Parameters ---------- msg_hash: bytes The message hash. sig: bytes The signature. Returns ------- bytes public key in uncompressed format. Raises ------ ValueError If the signature is bad, or recovery bit is bad, or cannot recover(sig and msg_hash doesn't match). ''' if not _is_valid_message_hash(msg_hash): raise ValueError('Message Hash must be 32 bytes.') if len(sig) != 65: raise ValueError('Signature must be 65 bytes.') if not (sig[64] == 0 or sig[64] == 1): raise ValueError('Signature last byte must be 0 or 1') pk = KeyAPI().ecdsa_recover(msg_hash, KeyAPI.Signature(signature_bytes=sig)) # uncompressed should have first byte = 04 return bytes([4]) + pk.to_bytes()
import logging import os from datetime import datetime from hashlib import sha256 from json import JSONDecodeError from eth_account import Account from eth_keys import KeyAPI from eth_keys.backends import NativeECCBackend from web3.main import Web3 from aquarius.app.auth_util import sanitize_addresses from aquarius.rbac import RBAC logger = logging.getLogger("aquarius") keys = KeyAPI(NativeECCBackend) def sanitize_record(data_record): if "_id" in data_record: data_record.pop("_id") if not os.getenv("RBAC_SERVER_URL"): return json.dumps(data_record, default=datetime_converter) return json.dumps(RBAC.sanitize_record(data_record)) def sanitize_query_result(query_result): if not os.getenv("RBAC_SERVER_URL"): return query_result
from eth_keys import KeyAPI, keys from eth_utils import keccak enc = 'utf8' message = "2017年の骨学的分析とDNA検査によって女性であることが判明している" pk = keys.PrivateKey(b'\01' * 32) addr = str(pk.public_key.to_checksum_address()) msg_bytes = message.encode(enc) msg_length = str(len(msg_bytes)).encode(enc) msg = b'\x19Ethereum Signed Message:\n' + msg_length + msg_bytes signature = pk.sign_msg(msg).to_hex() print(message) print(addr) print(signature) print('\nChecking Stage:') key_obj = KeyAPI() if '0x' in signature: signature = signature[2:] sign = KeyAPI.Signature(bytearray.fromhex(signature)) pub = key_obj.ecdsa_recover(message_hash=keccak(msg), signature=sign) print(addr == str(pub.to_checksum_address()))
def key_api(ecc_backend): return KeyAPI(ecc_backend)
from dataclasses import dataclass from typing import Optional from eth_account import Account from eth_account.hdaccount import Mnemonic from eth_keys import KeyAPI from eth_utils import decode_hex from eth_utils import is_address as is_address_ from mb_commons import Result from mb_ethereum.eth import eth_rpc key_api = KeyAPI() Account.enable_unaudited_hdwallet_features() @dataclass class GeneratedAccount: path: str address: str private_key: str def is_address(address: Optional[str]) -> bool: return is_address_(address) def is_valid_private_key(address: str, private_key: str) -> bool: # noinspection PyBroadException try:
def add_account(self, private_key): keys = KeyAPI() self.account_keys = self.account_keys + ( keys.PrivateKey(private_key), )
def coincurve_key_api(): return KeyAPI(backend=CoinCurveECCBackend())
def _load_and_maybe_generate(self, privkey_path, pubkey_path, yes_to_all=False): if os.path.exists(privkey_path): # node private key seems to exist already .. check! priv_tags = _parse_user_key_file(privkey_path, private=True) for tag in ['creator', 'created-at', 'user-id', 'public-key-ed25519', 'private-key-ed25519']: if tag not in priv_tags: raise Exception("Corrupt user private key file {} - {} tag not found".format(privkey_path, tag)) creator = priv_tags['creator'] created_at = priv_tags['created-at'] user_id = priv_tags['user-id'] privkey_hex = priv_tags['private-key-ed25519'] privkey = SigningKey(privkey_hex, encoder=HexEncoder) pubkey = privkey.verify_key pubkey_hex = pubkey.encode(encoder=HexEncoder).decode('ascii') if priv_tags['public-key-ed25519'] != pubkey_hex: raise Exception(("Inconsistent user private key file {} - public-key-ed25519 doesn't" " correspond to private-key-ed25519").format(pubkey_path)) eth_pubadr = None eth_privkey = None eth_privkey_seed_hex = priv_tags.get('private-key-eth', None) if eth_privkey_seed_hex: eth_privkey_seed = binascii.a2b_hex(eth_privkey_seed_hex) eth_privkey = KeyAPI(NativeECCBackend).PrivateKey(eth_privkey_seed) eth_pubadr = eth_privkey.public_key.to_checksum_address() if 'public-adr-eth' in priv_tags: if priv_tags['public-adr-eth'] != eth_pubadr: raise Exception(("Inconsistent node private key file {} - public-adr-eth doesn't" " correspond to private-key-eth").format(privkey_path)) if os.path.exists(pubkey_path): pub_tags = _parse_user_key_file(pubkey_path, private=False) for tag in ['creator', 'created-at', 'user-id', 'public-key-ed25519']: if tag not in pub_tags: raise Exception("Corrupt user public key file {} - {} tag not found".format(pubkey_path, tag)) if pub_tags['public-key-ed25519'] != pubkey_hex: raise Exception(("Inconsistent user public key file {} - public-key-ed25519 doesn't" " correspond to private-key-ed25519").format(pubkey_path)) if pub_tags.get('public-adr-eth', None) != eth_pubadr: raise Exception( ("Inconsistent user public key file {} - public-adr-eth doesn't" " correspond to private-key-eth in private key file {}").format(pubkey_path, privkey_path)) else: # public key is missing! recreate it pub_tags = OrderedDict([ ('creator', priv_tags['creator']), ('created-at', priv_tags['created-at']), ('user-id', priv_tags['user-id']), ('public-key-ed25519', pubkey_hex), ('public-adr-eth', eth_pubadr), ]) msg = 'Crossbar.io user public key\n\n' _write_user_key(pubkey_path, pub_tags, msg) click.echo('Re-created user public key from private key: {}'.format(style_ok(pubkey_path))) # click.echo('User public key loaded: {}'.format(style_ok(pubkey_path))) # click.echo('User private key loaded: {}'.format(style_ok(privkey_path))) else: # user private key does not yet exist: generate one creator = _creator(yes_to_all) created_at = utcnow() user_id = _user_id(yes_to_all) privkey = SigningKey.generate() privkey_hex = privkey.encode(encoder=HexEncoder).decode('ascii') pubkey = privkey.verify_key pubkey_hex = pubkey.encode(encoder=HexEncoder).decode('ascii') eth_privkey_seed = os.urandom(32) eth_privkey_seed_hex = binascii.b2a_hex(eth_privkey_seed).decode() eth_privkey = KeyAPI(NativeECCBackend).PrivateKey(eth_privkey_seed) eth_pubadr = eth_privkey.public_key.to_checksum_address() # first, write the public file tags = OrderedDict([ ('creator', creator), ('created-at', created_at), ('user-id', user_id), ('public-key-ed25519', pubkey_hex), ('public-adr-eth', eth_pubadr), ]) msg = 'Crossbar.io user public key\n\n' _write_user_key(pubkey_path, tags, msg) os.chmod(pubkey_path, 420) # now, add the private key and write the private file tags['private-key-ed25519'] = privkey_hex tags['private-key-eth'] = eth_privkey_seed_hex msg = 'Crossbar.io user private key - KEEP THIS SAFE!\n\n' _write_user_key(privkey_path, tags, msg) os.chmod(privkey_path, 384) click.echo('New user public key generated: {}'.format(style_ok(pubkey_path))) click.echo('New user private key generated ({}): {}'.format(style_error('keep this safe!'), style_ok(privkey_path))) # fix file permissions on node public/private key files # note: we use decimals instead of octals as octal literals have changed between Py2/3 if os.stat(pubkey_path).st_mode & 511 != 420: # 420 (decimal) == 0644 (octal) os.chmod(pubkey_path, 420) click.echo(style_error('File permissions on user public key fixed!')) if os.stat(privkey_path).st_mode & 511 != 384: # 384 (decimal) == 0600 (octal) os.chmod(privkey_path, 384) click.echo(style_error('File permissions on user private key fixed!')) # load keys into object self._creator = creator self._created_at = created_at self._privkey = privkey self._privkey_hex = privkey_hex self._pubkey = pubkey self._pubkey_hex = pubkey_hex self._eth_pubadr = eth_pubadr self._eth_privkey_seed_hex = eth_privkey_seed_hex self._eth_privkey = eth_privkey self.user_id = user_id self.key = cryptosign.CryptosignKey(privkey, can_sign=True)
def key_api(request): return KeyAPI(backend=request.param)
def test_supported_backend_formats(backend): keys = KeyAPI(backend=backend) assert isinstance(keys.backend, NativeECCBackend)
def _maybe_generate_node_key(cbdir, privfile='key.priv', pubfile='key.pub'): privkey_path = os.path.join(cbdir, privfile) pubkey_path = os.path.join(cbdir, pubfile) # node private key seems to exist already: read and check! if os.path.exists(privkey_path): # read all tags, including private tags priv_tags = _parse_node_key(privkey_path, private=True) # check mandatory tags - the following tags are optional: # - node-authid # - node-cluster-ip # - public-adr-eth # - private-key-eth for tag in [ 'creator', 'created-at', 'machine-id', 'public-key-ed25519', 'private-key-ed25519' ]: if tag not in priv_tags: raise Exception( "Corrupt node private key file {} - {} tag not found". format(privkey_path, tag)) privkey_hex = priv_tags['private-key-ed25519'] privkey = signing.SigningKey(privkey_hex, encoder=encoding.HexEncoder) pubkey = privkey.verify_key pubkey_hex = pubkey.encode(encoder=encoding.HexEncoder).decode('ascii') # check that the public key in the key file matches the private key therein if priv_tags['public-key-ed25519'] != pubkey_hex: raise Exception(( "Inconsistent node private key file {} - public-key-ed25519 doesn't" " correspond to private-key-ed25519").format(privkey_path)) eth_pubadr = None eth_privkey_seed_hex = priv_tags.get('private-key-eth', None) if eth_privkey_seed_hex: eth_privkey_seed = binascii.a2b_hex(eth_privkey_seed_hex) eth_privkey = KeyAPI(NativeECCBackend).PrivateKey(eth_privkey_seed) eth_pubadr = eth_privkey.public_key.to_checksum_address() if 'public-adr-eth' in priv_tags: if priv_tags['public-adr-eth'] != eth_pubadr: raise Exception(( "Inconsistent node private key file {} - public-adr-eth doesn't" " correspond to private-key-eth").format(privkey_path)) if os.path.exists(pubkey_path): pub_tags = _parse_node_key(pubkey_path, private=False) # node-authid and node-cluster-ip are optional! for tag in [ 'creator', 'created-at', 'machine-id', 'public-key-ed25519' ]: if tag not in pub_tags: raise Exception( "Corrupt node public key file {} - {} tag not found". format(pubkey_path, tag)) if pub_tags['public-key-ed25519'] != pubkey_hex: raise Exception(( "Inconsistent node public key file {} - public-key-ed25519 doesn't" " correspond to private-key-ed25519 in private key file {}" ).format(pubkey_path, privkey_path)) if pub_tags.get('public-adr-eth', None) != eth_pubadr: raise Exception(( "Inconsistent node public key file {} - public-adr-eth doesn't" " correspond to private-key-eth in private key file {}" ).format(pubkey_path, privkey_path)) else: log.info( "Node public key file {pub_path} not found - re-creating from node private key file {priv_path}", pub_path=pubkey_path, priv_path=privkey_path, ) pub_tags = OrderedDict([ ('creator', priv_tags['creator']), ('created-at', priv_tags['created-at']), ('machine-id', priv_tags['machine-id']), ('node-authid', priv_tags.get('node-authid', None)), ('node-cluster-ip', priv_tags.get('node-cluster-ip', None)), ('public-key-ed25519', pubkey_hex), ('public-adr-eth', eth_pubadr), ]) msg = 'Crossbar.io node public key\n\n' _write_node_key(pubkey_path, pub_tags, msg) log.info( 'Node key files exist and are valid. Node public key is {pubkey}', pubkey=hlid('0x' + pubkey_hex)) was_new = False else: # node private key does not yet exist: generate a new one # Node key (Ed25519) privkey = signing.SigningKey.generate() privkey_hex = privkey.encode( encoder=encoding.HexEncoder).decode('ascii') pubkey = privkey.verify_key pubkey_hex = pubkey.encode(encoder=encoding.HexEncoder).decode('ascii') # Node Ethereum key eth_privkey_seed = os.urandom(32) eth_privkey_seed_hex = binascii.b2a_hex(eth_privkey_seed).decode() eth_privkey = KeyAPI(NativeECCBackend).PrivateKey(eth_privkey_seed) eth_pubadr = eth_privkey.public_key.to_checksum_address() if 'CROSSBAR_NODE_ID' in os.environ and os.environ[ 'CROSSBAR_NODE_ID'].strip() != '': node_authid = os.environ['CROSSBAR_NODE_ID'] log.info( 'using node_authid from environment variable CROSSBAR_NODE_ID: "{node_authid}"', node_authid=node_authid) else: node_authid = socket.gethostname() log.info('using node_authid from hostname: "{node_authid}"', node_authid=node_authid) if 'CROSSBAR_NODE_CLUSTER_IP' in os.environ and os.environ[ 'CROSSBAR_NODE_CLUSTER_IP'].strip() != '': node_cluster_ip = os.environ['CROSSBAR_NODE_CLUSTER_IP'] log.info( 'using node_cluster_ip from environment variable CROSSBAR_NODE_CLUSTER_IP: "{node_cluster_ip}"', node_cluster_ip=node_cluster_ip) else: node_cluster_ip = '127.0.0.1' log.info( 'using node_cluster_ip for localhost (builtin): "{node_cluster_ip}"', node_cluster_ip=node_cluster_ip) # first, write the public file tags = OrderedDict([ ('creator', _creator()), ('created-at', utcnow()), ('machine-id', _machine_id()), ('node-authid', node_authid), ('node-cluster-ip', node_cluster_ip), ('public-key-ed25519', pubkey_hex), ('public-adr-eth', eth_pubadr), ]) msg = 'Crossbar.io node public key\n\n' _write_node_key(pubkey_path, tags, msg) # now, add the private key and write the private file tags['private-key-ed25519'] = privkey_hex tags['private-key-eth'] = eth_privkey_seed_hex msg = 'Crossbar.io node private key - KEEP THIS SAFE!\n\n' _write_node_key(privkey_path, tags, msg) log.info( 'New node key pair generated! public-key-ed25519={pubkey}, node-authid={node_authid}, public-adr-eth={eth_pubadr}', pubkey=hlid('0x' + pubkey_hex), node_authid=node_authid, eth_pubadr=hlid(eth_pubadr)) was_new = True # fix file permissions on node public/private key files # note: we use decimals instead of octals as octal literals have changed between Py2/3 # if os.stat( pubkey_path).st_mode & 511 != 420: # 420 (decimal) == 0644 (octal) os.chmod(pubkey_path, 420) log.info("File permissions on node public key fixed") if os.stat(privkey_path ).st_mode & 511 != 384: # 384 (decimal) == 0600 (octal) os.chmod(privkey_path, 384) log.info("File permissions on node private key fixed") log.info( 'Node key loaded from {priv_path}', priv_path=hlid(privkey_path), ) return was_new, cryptosign.CryptosignKey(privkey, can_sign=True)
def validateHASH(txID, signature, public_key): s = Signature(signature_bytes=signature) keys = KeyAPI('eth_keys.backends.NativeECCBackend') publicKey = PublicKey(bytes.fromhex(public_key)) return keys.ecdsa_verify(txID, s, publicKey)
def setKeyBackend(self, backend): self._keys = KeyAPI(backend)
def verify_signature(hash, sig, pub): keys = KeyAPI(NativeECCBackend) sign = keys.Signature(sig) public = keys.PublicKey(pub, base.BaseECCBackend) return keys.ecdsa_verify(hash, sign, public)
def funded_address_private_key(): return KeyAPI().PrivateKey( decode_hex( '0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8' ))
def get_pub_from_priv(priv): keys = KeyAPI(NativeECCBackend) pub = keys.private_key_to_public_key(priv) return pub.to_bytes()
def native_key_api(): return KeyAPI(backend=NativeECCBackend())
def chain_without_block_validation(): """ Return a Chain object containing just the genesis block. This Chain does not perform any validation when importing new blocks. The Chain's state includes one funded account and a private key for it, which can be found in the funded_address and private_keys variables in the chain itself. """ # Disable block validation so that we don't need to construct finalized blocks. overrides = { 'import_block': import_block_without_validation, 'validate_block': lambda self, block: None, } klass = Chain.configure( name='TestChainWithoutBlockValidation', vm_configuration=((constants.GENESIS_BLOCK_NUMBER, FrontierVM), ), **overrides, ) private_key = KeyAPI().PrivateKey( decode_hex( '0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8' )) funded_addr = private_key.public_key.to_canonical_address() initial_balance = 100000000 genesis_params = { 'block_number': constants.GENESIS_BLOCK_NUMBER, 'difficulty': constants.GENESIS_DIFFICULTY, 'gas_limit': constants.GENESIS_GAS_LIMIT, 'parent_hash': constants.GENESIS_PARENT_HASH, 'coinbase': constants.GENESIS_COINBASE, 'nonce': constants.GENESIS_NONCE, 'mix_hash': constants.GENESIS_MIX_HASH, 'extra_data': constants.GENESIS_EXTRA_DATA, 'timestamp': 1501851927, 'state_root': decode_hex( '0x9d354f9b5ba851a35eced279ef377111387197581429cfcc7f744ef89a30b5d4' ) } genesis_state = { funded_addr: { 'balance': initial_balance, 'nonce': 0, 'code': b'', 'storage': {}, } } chain = klass.from_genesis(ChainDB(get_db_backend()), genesis_params, genesis_state) chain.funded_address = funded_addr chain.funded_address_initial_balance = initial_balance chain.funded_address_private_key = private_key return chain