def _sha3_secp256k1_deploy_data(current_height, bytecode, value, quota, privatekey, version, receiver=None): sender = get_sender(privatekey, False) if privatekey is None: temp = private_key() privkey = PrivateKey(hex2bytes(temp)) else: privkey = PrivateKey(hex2bytes(privatekey)) logger.debug(sender) nonce = get_nonce() logger.debug("nonce is {}".format(nonce)) tx = Transaction() tx.valid_until_block = current_height + 88 tx.nonce = nonce tx.version = version if version == 0: chainid = get_chainid() logger.info("version-{}, chainid-{}".format(version, chainid)) tx.chain_id = chainid elif version < 3: chainid = get_chainid_v1() logger.info("version-{}, chainid_v1-{}".format(version, chainid)) tx.chain_id_v1 = chainid.to_bytes(32, byteorder='big') else: logger.error("unexpected version {}".format(version)) if receiver is not None: if version == 0: tx.to = receiver elif version < 3: tx.to_v1 = hex2bytes(receiver) else: logger.error("unexpected version {}".format(version)) tx.data = hex2bytes(bytecode) tx.value = value.to_bytes(32, byteorder='big') tx.quota = quota message = sha3(tx.SerializeToString()) logger.debug("hash message: {}") sign_recover = privkey.ecdsa_sign_recoverable(message, raw=True) sig = privkey.ecdsa_recoverable_serialize(sign_recover) signature = binascii.hexlify(sig[0]) + binascii.hexlify( bytes(bytearray([sig[1]]))) unverify_tx = UnverifiedTransaction() unverify_tx.transaction.CopyFrom(tx) unverify_tx.signature = hex2bytes(signature) unverify_tx.crypto = Crypto.Value('DEFAULT') logger.info("unverify_tx is {}".format( binascii.hexlify(unverify_tx.SerializeToString()))) return binascii.hexlify(unverify_tx.SerializeToString())
def generate_deploy_data(bytecode, privatekey, receiver=None): privkey = PrivateKey(hex2bytes(privatekey)) sender = get_sender() print(sender) nonce = get_nonce(sender) print("nonce is {}".format(nonce)) tx = Transaction() tx.valid_until_block = 4294967296 tx.nonce = nonce if receiver is not None: tx.to = receiver tx.data = hex2bytes(bytecode) message = sha3(tx.SerializeToString()) sign_recover = privkey.ecdsa_sign_recoverable(message, raw=True) sig = privkey.ecdsa_recoverable_serialize(sign_recover) signature = binascii.hexlify( sig[0]) + binascii.hexlify(bytes(bytearray([sig[1]]))) unverify_tx = UnverifiedTransaction() unverify_tx.transaction.CopyFrom(tx) unverify_tx.signature = hex2bytes(signature) unverify_tx.crypto = Crypto.Value('SECP') signed_transaction = SignedTransaction() signed_transaction.transaction_with_sig.CopyFrom(unverify_tx) signed_transaction.tx_hash = sha3(unverify_tx.SerializeToString()) pub = recover_pub(hex2bytes(privatekey)) signed_transaction.signer = pub #print(binascii.hexlify(pub)) return binascii.hexlify(signed_transaction.SerializeToString())
def ecdsa_sign(msghash, privkey): assert len(msghash) == 32 pk = PrivateKey(privkey, raw=True, ctx=ctx) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(msghash, raw=True)) new = signature[0] + chr(signature[1]) return new
def sign(data: bytes, private_key_seed_ascii: str): priv = private_key_seed_ascii pk = PrivateKey(priv, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(data, raw=True)) signature = signature[0] + utils.bytearray_to_bytestr([signature[1]]) return signature, eth_privtoaddr(priv)
def test_ecrecover(): s = tester.state() c = s.abi_contract(ecrecover_code) priv = utils.sha3('some big long brainwallet password') pub = bitcoin.privtopub(priv) msghash = utils.sha3('the quick brown fox jumps over the lazy dog') pk = PrivateKey(priv, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(msghash, raw=True)) signature = signature[0] + utils.bytearray_to_bytestr([signature[1]]) V = utils.safe_ord(signature[64]) + 27 R = big_endian_to_int(signature[0:32]) S = big_endian_to_int(signature[32:64]) assert bitcoin.ecdsa_raw_verify(msghash, (V, R, S), pub) addr = utils.big_endian_to_int( utils.sha3(bitcoin.encode_pubkey(pub, 'bin')[1:])[12:]) assert utils.big_endian_to_int(utils.privtoaddr(priv)) == addr result = c.test_ecrecover(utils.big_endian_to_int(msghash), V, R, S) assert result == addr
def sign(self, privkey): """Sign this with a private key""" if self.v: raise InvalidSignature("already signed") if privkey in (0, '', '\x00' * 32): raise InvalidSignature("Zero privkey cannot sign") rawhash = sha3( rlp.encode(self, self.__class__.exclude(['v', 'r', 's']))) if len(privkey) == 64: privkey = encode_privkey(privkey, 'bin') pk = PrivateKey(privkey, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(rawhash, raw=True)) signature = signature[0] + chr(signature[1]) self.v = ord(signature[64]) + 27 self.r = big_endian_to_int(signature[0:32]) self.s = big_endian_to_int(signature[32:64]) self._sender = None return self
def test_ecrecover(): s = tester.state() c = s.abi_contract(ecrecover_code) priv = utils.sha3('some big long brainwallet password') pub = bitcoin.privtopub(priv) msghash = utils.sha3('the quick brown fox jumps over the lazy dog') pk = PrivateKey(priv, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(msghash, raw=True) ) signature = signature[0] + utils.bytearray_to_bytestr([signature[1]]) V = utils.safe_ord(signature[64]) + 27 R = big_endian_to_int(signature[0:32]) S = big_endian_to_int(signature[32:64]) assert bitcoin.ecdsa_raw_verify(msghash, (V, R, S), pub) addr = utils.big_endian_to_int(utils.sha3(bitcoin.encode_pubkey(pub, 'bin')[1:])[12:]) assert utils.big_endian_to_int(utils.privtoaddr(priv)) == addr result = c.test_ecrecover(utils.big_endian_to_int(msghash), V, R, S) assert result == addr
class Account: priv_key_hex = None priv_key = None def __init__(self, priv_key): self.priv_key_hex = priv_key self.priv_key = PrivateKey(bytes(bytearray.fromhex(priv_key))) def sign(self, tx): tx['v'] = 1 tx['r'] = 0 tx['s'] = 0 unsigned_transaction = w3.eth.account.unsigned_transaction(tx) sig = self.priv_key.ecdsa_sign_recoverable(unsigned_transaction.hash(), raw=True) serialized, v = self.priv_key.ecdsa_recoverable_serialize(sig) r = int.from_bytes(serialized[:32], byteorder='big') s = int.from_bytes(serialized[32:], byteorder='big') raw = w3.eth.account.encode_signed_transaction(unsigned_transaction, vrs=(v + 37, r, s)) return raw, keccak(raw) def address(self): return blocksmith.EthereumWallet.generate_address(self.priv_key_hex)
def sign(self, key): """Sign this transaction with a private key. A potentially already existing signature would be overridden. """ if not is_bitcoin_available() or not is_secp256k1_available(): raise ImportError( "In order to sign transactions the " "`bitcoin` and `secp256k1` packages must be installed." ) from bitcoin import privtopub from secp256k1 import PrivateKey if key in (0, b'', b'\x00' * 32, b'0' * 64): raise ValueError("Zero privkey cannot sign") rawhash = decode_hex(sha3(rlp.encode(self, UnsignedTransaction))) if len(key) in {64, 66}: # we need a binary key key = decode_hex(key) pk = PrivateKey(key, raw=True) sig_bytes, rec_id = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(rawhash, raw=True) ) signature = sig_bytes + force_bytes(chr(rec_id)) self.v = (ord(signature[64]) if is_string(signature[64]) else signature[64]) + 27 self.r = decode_big_endian_int(signature[0:32]) self.s = decode_big_endian_int(signature[32:64]) self.sender = to_address(sha3(privtopub(key)[1:])[-40:]) return self
class Secp256k1_compact(object): def __init__(self): self.priv_key = PrivateKey() self.pub_key = PublicKey(pubkey=None, raw=False, flags=secp256k1.ALL_FLAGS) def ecdsa_compact_sign(self, msg32, privkey): if type(privkey) == unicode: privkey = privkey.encode('utf-8') self.priv_key.set_raw_privkey(privkey) sig = self.priv_key.ecdsa_sign_recoverable(msg32, raw=True) return self.priv_key.ecdsa_recoverable_serialize(sig) def ecdsa_compact_recover(self, msg32, sign): if not len(sign) == 2: sign = (sign[:64], ord(sign[64])) assert len(sign) == 2 deserialized_sig = self.pub_key.ecdsa_recoverable_deserialize(sign[0], sign[1]) self.pub_key.public_key = self.pub_key.ecdsa_recover(msg32, deserialized_sig, raw=True) return self.pub_key.serialize(compressed=False) def ecdsa_compact_verify(self, msg32, sign, pub): # Check if pubkey has been bin_electrum encoded. # If so, append \04 to the front of the key, to make sure the length is 65 if len(pub) == 64: pub = '\04'+pub pub_k = PublicKey().deserialize(pub) pub_key = PublicKey(pub_k, raw=False, flags=secp256k1.ALL_FLAGS) der_sig = pub_key.ecdsa_recoverable_deserialize(sign[0], sign[1]) raw_sig = pub_key.ecdsa_recoverable_convert(der_sig) return pub_key.ecdsa_verify(msg32, raw_sig, raw=True)
def sign(self, key): """Sign this transaction with a private key. A potentially already existing signature would be overridden. """ if not is_bitcoin_available() or not is_secp256k1_available(): raise ImportError( "In order to sign transactions the " "`bitcoin` and `secp256k1` packages must be installed.") from bitcoin import privtopub from secp256k1 import PrivateKey if key in (0, b'', b'\x00' * 32, b'0' * 64): raise ValueError("Zero privkey cannot sign") rawhash = decode_hex(sha3(rlp.encode(self, UnsignedTransaction))) if len(key) in {64, 66}: # we need a binary key key = decode_hex(key) pk = PrivateKey(key, raw=True) sig_bytes, rec_id = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(rawhash, raw=True)) signature = sig_bytes + force_bytes(chr(rec_id)) self.v = (ord(signature[64]) if is_string(signature[64]) else signature[64]) + 27 self.r = decode_big_endian_int(signature[0:32]) self.s = decode_big_endian_int(signature[32:64]) self.sender = to_address(sha3(privtopub(key)[1:])[-40:]) return self
def test_eth_sign(web3, skip_if_testrpc): skip_if_testrpc(web3) private_key_hex = '0x5e95384d8050109aab08c1922d3c230739bc16976553c317e5d0b87b59371f2a' private_key = decode_hex(private_key_hex) # This imports the private key into the running geth instance and unlocks # the account so that it can sign things. # `0xa5df35f30ba0ce878b1061ae086289adff3ba1e0` address = web3.personal.importRawKey(private_key, "password") web3.personal.unlockAccount(address, "password") assert add_0x_prefix(encode_hex(privtoaddr(private_key))) == add_0x_prefix(address) assert address == '0xa5df35f30ba0ce878b1061ae086289adff3ba1e0' # the data to be signed data = b'1234567890abcdefghijklmnopqrstuvwxyz' # the hash of the data `0x089c33d56ed10bd8b571a0f493cedb28db1ae0f40c6cd266243001528c06eab3` data_hash = web3.sha3(data, encoding=None) data_hash_bytes = decode_hex(data_hash) assert force_bytes(data_hash) == sha3(data) priv_key = PrivateKey(flags=ALL_FLAGS) priv_key.set_raw_privkey(private_key) # sanit check the extract_ecdsa_signer function works as expected. vector_sig = priv_key.ecdsa_sign_recoverable(data_hash_bytes, raw=True, digest=sha3_256) vector_sig_bytes, rec_id = priv_key.ecdsa_recoverable_serialize(vector_sig) vector_sig_bytes_full = vector_sig_bytes + force_bytes(chr(rec_id)) vector_address = force_text(extract_ecdsa_signer(data_hash_bytes, vector_sig_bytes_full)) assert vector_address == address # Now have geth sign some data. signature_hex = web3.eth.sign(address, data) signature_bytes = decode_hex(signature_hex) actual_signer = extract_ecdsa_signer(data_hash_bytes, signature_bytes) assert actual_signer == address # Verify the signature against the public key derived from the # original private key. It fails. rec_id = signature_bytes[64] if is_string(rec_id): rec_id = ord(rec_id) recoverable_signature = priv_key.ecdsa_recoverable_deserialize( signature_bytes[:64], rec_id, ) signature = priv_key.ecdsa_recoverable_convert(recoverable_signature) is_valid = priv_key.pubkey.ecdsa_verify( msg=data, raw_sig=signature, digest=sha3_256, ) assert is_valid
def sign(data: str, private_key_seed_ascii: str): data = eth_message_hex(data) print("--eth_message_hex hash", data) priv = private_key_seed_ascii pk = PrivateKey(priv, raw=True) signature = pk.ecdsa_recoverable_serialize(pk.ecdsa_sign_recoverable(data, raw=True)) signature = signature[0] + utils.bytearray_to_bytestr([signature[1]]) return signature, eth_privtoaddr(priv)
def sign(private_key: PrivateKey, random_bytes): raw_sig = private_key.ecdsa_sign_recoverable(msg=random_bytes, raw=True, digest=hashlib.sha3_256) serialized_sig, recover_id = private_key.ecdsa_recoverable_serialize(raw_sig) signature = serialized_sig + bytes((recover_id,)) signature_base64str = base64.b64encode(signature).decode('utf-8') return signature_base64str
def sign_message(pri_key, message): privkey = PrivateKey( pri_key, raw=True ) # we expect to have a private key as bytes. unhexlify it before passing. sig_check = privkey.ecdsa_sign(MESSAGE_TEMPLATE.format(message)) sig_ser, recid = privkey.ecdsa_recoverable_serialize(sig_check) return (sig_ser, recid)
def sign(data: bytes, private_key_seed_ascii: str, hash_function=bitcoin.bin_sha256): """Sign data using Ethereum private key. :param private_key_seed_ascii: Private key seed as ASCII string """ msghash = hash_function(data) priv = utils.sha3(private_key_seed_ascii) pub = bitcoin.privtopub(priv) # Based on ethereum/tesrt_contracts.py test_ecrecover pk = PrivateKey(priv, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(msghash, raw=True)) signature = signature[0] + utils.bytearray_to_bytestr([signature[1]]) # Enforce non-tightly-packed arguments for signing # (0x00 left pad) # https://github.com/ethereum/web3.py/issues/466 v = utils.safe_ord(signature[64]) + 27 r_bytes = signature[0:32] r_bytes = pad_left(r_bytes, 32, b"\0") r = big_endian_to_int(r_bytes) s_bytes = signature[32:64] s_bytes = pad_left(s_bytes, 32, b"\0") s = big_endian_to_int(s_bytes) # Make sure we use bytes data and zero padding stays # good across different systems r_hex = binascii.hexlify(r_bytes).decode("ascii") s_hex = binascii.hexlify(s_bytes).decode("ascii") # Convert to Etheruem address format addr = utils.big_endian_to_int( utils.sha3(bitcoin.encode_pubkey(pub, 'bin')[1:])[12:]) # Return various bits about signing so it's easier to debug return { "signature": signature, "v": v, "r": r, "s": s, "r_bytes": r_bytes, "s_bytes": s_bytes, "r_hex": "0x" + r_hex, "s_hex": "0x" + s_hex, "address_bitcoin": addr, "address_ethereum": get_ethereum_address_from_private_key(priv), "public_key": pub, "hash": msghash, "payload": binascii.hexlify(bytes([v] + list(r_bytes) + list(s_bytes, ))) }
def sign_eth(rawhash, priv): pk = PrivateKey(priv, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(rawhash, raw=True)) signature = signature[0] + utils.bytearray_to_bytestr([signature[1]]) v = utils.safe_ord(signature[64]) + 27 r = utils.big_endian_to_int(signature[0:32]) s = utils.big_endian_to_int(signature[32:64]) return (v, r, s)
def sign_eth(rawhash, priv): pk = PrivateKey(priv, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(rawhash, raw=True) ) signature = signature[0] + utils.bytearray_to_bytestr([signature[1]]) v = utils.safe_ord(signature[64]) + 27 r = utils.big_endian_to_int(signature[0:32]) s = utils.big_endian_to_int(signature[32:64]) return (v, r, s)
def sign_payload(private_key, payload): if isinstance(private_key, str): private_key = data_decoder(private_key) rawhash = sha3(payload) pk = PrivateKey(private_key, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(rawhash, raw=True)) signature = signature[0] + bytearray_to_bytestr([signature[1]]) return data_encoder(signature)
def sign(data: bytes, private_key: bytes) -> bytes: """ Generates on the ECDSA-SHA256 signature in bytes from data. It refers to a document on https://github.com/ludbb/secp256k1-py. :param data: data to be signed :param private_key: private key :return signature: signature made from input data """ private_key_object = PrivateKey(private_key, raw=True) recoverable_sign = private_key_object.ecdsa_sign_recoverable(data, raw=True) sign_bytes, sign_recovery = private_key_object.ecdsa_recoverable_serialize(recoverable_sign) return sign_bytes + sign_recovery.to_bytes(1, 'big')
def personal_sign(private_key, message): if isinstance(private_key, str): private_key = data_decoder(private_key) rawhash = sha3("\x19Ethereum Signed Message:\n{}{}".format( len(message), message)) pk = PrivateKey(private_key, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(rawhash, raw=True)) signature = signature[0] + bytearray_to_bytestr([signature[1] + 27]) return data_encoder(signature)
def make_raw_tx(self, private_key: bytes, receiver: bytes, bytecode: bytes, valid_until_block: int, value: int, quota: int) -> bytes: """ 对交易数据进行签名. :param private_key: 私钥. :param receiver: 接收方地址. 如果是合约部署, 则为b''. :param bytecode: 字节码. :param valid_until_block: 交易的最后期限. 默认为当前区块高度+88 :param value: 金额. :param quota: 调用配额. :return: 签名后的bytes. """ _, _, sender = self.generate_account(private_key) pri_key = PrivateKey(private_key) tx = Transaction() tx.valid_until_block = valid_until_block tx.nonce = get_nonce() tx.version = self.version if self.version == 0: tx.chain_id = self.chain_id else: tx.chain_id_v1 = self.chain_id.to_bytes(32, byteorder='big') if receiver: if self.version == 0: tx.to = receiver else: tx.to_v1 = receiver tx.data = bytecode tx.value = value.to_bytes(32, byteorder='big') tx.quota = quota keccak = sha3.keccak_256() keccak.update(tx.SerializeToString()) message = keccak.digest() sign_recover = pri_key.ecdsa_sign_recoverable(message, raw=True) sig = pri_key.ecdsa_recoverable_serialize(sign_recover) signature = param_to_str(sig[0] + bytes(bytearray([sig[1]]))) unverify_tx = UnverifiedTransaction() unverify_tx.transaction.CopyFrom(tx) unverify_tx.signature = param_to_bytes(signature) unverify_tx.crypto = Crypto.Value('DEFAULT') return unverify_tx.SerializeToString()
def make_deploycode(tx, message, privkey): """ Generate Hexadecimal representation of the binary signature transactions """ privkey = PrivateKey(hex2bytes(privkey)) sign_recover = privkey.ecdsa_sign_recoverable(message, raw=True) sig = privkey.ecdsa_recoverable_serialize(sign_recover) signature = binascii.hexlify(sig[0]) + binascii.hexlify( bytes(bytearray([sig[1]]))) unverify_tx = proto.UnverifiedTransaction() unverify_tx.transaction.CopyFrom(tx) unverify_tx.signature = hex2bytes(signature) unverify_tx.crypto = proto.Crypto.Value('SECP') return binascii.hexlify(unverify_tx.SerializeToString())
def sign(messagedata, private_key): if not isinstance(private_key, bytes) or len(private_key) != 32: raise ValueError('invalid private_key') key = PrivateKey(private_key, raw=True) message_hash = sha3(messagedata) secp_signature = key.ecdsa_sign_recoverable(message_hash, raw=True) signature_data = key.ecdsa_recoverable_serialize(secp_signature) signature = signature_data[0] + chr(signature_data[1]) if len(signature) != 65: raise ValueError('invalid signature') publickey = key.pubkey.serialize(compressed=False) return signature, publickey
def sign(self, key): '''Sign this transaction with a private key. A potentially already existing signature would be overridden. ''' if key in (0, "", b"\x00" * 32, "0" * 64): raise Exception("Zero privkey cannot sign") if len(key) == 64: key = encode_privkey(key, "bin") # we need a binary key h = blake2b(digest_size=32) h.update(rlp.encode(self, ThorTransaction.exclude(["Signature"]))) rawhash = h.digest() pk = PrivateKey(key, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(rawhash, raw=True)) self.Signature = signature[0] + bytearray_to_bytestr([signature[1]])
def sign(data: bytes, private_key_seed_ascii: str, hash_function=bitcoin.bin_sha256): """Sign data using Ethereum private key. :param private_key_seed_ascii: Private key seed as ASCII string """ msghash = hash_function(data) priv = utils.sha3(private_key_seed_ascii) pub = bitcoin.privtopub(priv) # Based on ethereum/tesrt_contracts.py test_ecrecover pk = PrivateKey(priv, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(msghash, raw=True)) signature = signature[0] + utils.bytearray_to_bytestr([signature[1]]) v = utils.safe_ord(signature[64]) + 27 r_bytes = signature[0:32] r = big_endian_to_int(r_bytes) s_bytes = signature[32:64] s = big_endian_to_int(s_bytes) #: XXX Ethereum wants its address in different format addr = utils.big_endian_to_int( utils.sha3(bitcoin.encode_pubkey(pub, 'bin')[1:])[12:]) return { "signature": signature, "v": v, "r": r, "s": s, "r_bytes": r_bytes, "s_bytes": s_bytes, "address_bitcoin": addr, "address_ethereum": eth_privtoaddr(priv), "public_key": pub, "hash": msghash, "payload": bytes([v] + list(r_bytes) + list(s_bytes, )) }
def eth_sign_with_keyfile(message: bytes, raw: bool, keyfile: str, password: str): assert(isinstance(message, bytes)) assert(isinstance(raw, bool)) assert(isinstance(keyfile, str)) assert(isinstance(password, str)) if not raw: message = hexstring_to_bytes(Eth._recoveryMessageHash(data=message)) key = eth_keyfile.decode_keyfile_json(eth_keyfile.load_keyfile(keyfile), bytes(password, 'utf-8')) pk = PrivateKey(key, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(message, raw=True) ) signature = signature[0] + utils.bytearray_to_bytestr([signature[1]]) signature_hex = signature.hex()[0:128] + int_to_bytes(ord(bytes.fromhex(signature.hex()[128:130]))+27).hex() return '0x' + signature_hex
def _sha3_secp256k1_deploy_data(current_height, bytecode, privatekey, receiver=None): sender = get_sender(privatekey, False) if privatekey is None: temp = private_key() privkey = PrivateKey(hex2bytes(temp)) else: privkey = PrivateKey(hex2bytes(privatekey)) print(sender) nonce = get_nonce(sender) print("nonce is {}".format(nonce)) tx = Transaction() tx.valid_until_block = current_height + 88 tx.nonce = nonce tx.quota = 9999999 if receiver is not None: tx.to = receiver tx.data = hex2bytes(bytecode) message = sha3(tx.SerializeToString()) print("message: {}".format(message)) sign_recover = privkey.ecdsa_sign_recoverable(message, raw=True) sig = privkey.ecdsa_recoverable_serialize(sign_recover) signature = binascii.hexlify(sig[0]) + binascii.hexlify( bytes(bytearray([sig[1]]))) unverify_tx = UnverifiedTransaction() unverify_tx.transaction.CopyFrom(tx) unverify_tx.signature = hex2bytes(signature) unverify_tx.crypto = Crypto.Value('SECP') print("unverify_tx is {}".format( binascii.hexlify(unverify_tx.SerializeToString()))) return binascii.hexlify(unverify_tx.SerializeToString())
class PingServer(object): def __init__(self, my_endpoint: EndPoint): self.endpoint = my_endpoint # get private key with open('priv_key', 'r') as priv_key_file: priv_key_serialized = priv_key_file.read() self.priv_key = PrivateKey() # type: PrivateKey self.priv_key.deserialize(priv_key_serialized) # init socket self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock.bind(('0.0.0.0', self.endpoint.udpPort)) def wrap_packet(self, packet): payload = packet.packet_type + rlp.encode(packet.pack()) sig = self.priv_key.ecdsa_sign_recoverable(keccak256(payload), raw=True) sig_serialized = self.priv_key.ecdsa_recoverable_serialize(sig) payload = b''.join( [sig_serialized[0], str.encode(chr(sig_serialized[1])), payload]) payload_hash = keccak256(payload) return payload_hash + payload def udp_listen(self): def receive_ping(): print("listening...") data, addr = self.sock.recvfrom(1024) print("received message[", addr, "]") return threading.Thread(target=receive_ping) def ping(self, endpoint: EndPoint): ping = PingNode(self.endpoint, endpoint) message = self.wrap_packet(ping) print("sending ping...") self.sock.sendto(message, (endpoint.address.exploded, endpoint.udpPort))
def sign(data: bytes, private_key_seed_ascii: str, hash_function=bitcoin.bin_sha256): """Sign data using Ethereum private key. :param private_key_seed_ascii: Private key seed as ASCII string """ msghash = hash_function(data) priv = utils.sha3(private_key_seed_ascii) pub = bitcoin.privtopub(priv) # Based on ethereum/tesrt_contracts.py test_ecrecover pk = PrivateKey(priv, raw=True) signature = pk.ecdsa_recoverable_serialize(pk.ecdsa_sign_recoverable(msghash, raw=True)) signature = signature[0] + utils.bytearray_to_bytestr([signature[1]]) v = utils.safe_ord(signature[64]) + 27 r_bytes = signature[0:32] r = big_endian_to_int(r_bytes) s_bytes = signature[32:64] s = big_endian_to_int(s_bytes) #: XXX Ethereum wants its address in different format addr = utils.big_endian_to_int(utils.sha3(bitcoin.encode_pubkey(pub, 'bin')[1:])[12:]) return { "signature": signature, "v": v, "r": r, "s": s, "r_bytes": r_bytes, "s_bytes": s_bytes, "address_bitcoin": addr, "address_ethereum": eth_privtoaddr(priv), "public_key": pub, "hash": msghash, "payload": bytes([v] + list(r_bytes)+ list(s_bytes,)) }
def eth_sign(message: bytes, web3: Web3): assert(isinstance(message, bytes)) assert(isinstance(web3, Web3)) # as `EthereumTesterProvider` does not support `eth_sign`, we implement it ourselves if str(web3.providers[0]) == 'EthereumTesterProvider': key = k0 msg = hexstring_to_bytes(Eth._recoveryMessageHash(data=message)) pk = PrivateKey(key, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(msg, raw=True) ) signature = signature[0] + utils.bytearray_to_bytestr([signature[1]]) signature_hex = signature.hex()[0:128] + int_to_bytes(ord(bytes.fromhex(signature.hex()[128:130]))+27).hex() return '0x' + signature_hex return web3.manager.request_blocking( "eth_sign", [web3.eth.defaultAccount, encode_hex(message)], )
def sign(self, key): """Sign this transaction with a private key. A potentially already existing signature would be overridden. """ if key in (0, '', b'\x00' * 32, '0' * 64): raise InvalidTransaction("Zero privkey cannot sign") rawhash = utils.sha3(rlp.encode(self, UnsignedTransaction)) if len(key) == 64: # we need a binary key key = encode_privkey(key, 'bin') pk = PrivateKey(key, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(rawhash, raw=True)) signature = signature[0] + utils.bytearray_to_bytestr([signature[1]]) self.v = utils.safe_ord(signature[64]) + 27 self.r = big_endian_to_int(signature[0:32]) self.s = big_endian_to_int(signature[32:64]) self.sender = utils.privtoaddr(key) return self
def _inner_sign(account, data_to_sign): signature_hash_hex = web3.sha3(encode_hex(data_to_sign)) signature_hash_bytes = decode_hex(signature_hash_hex) private_key = tester.keys[tester.accounts.index(decode_hex(account))] priv_key = PrivateKey(flags=ALL_FLAGS) priv_key.set_raw_privkey(private_key) signature_raw = priv_key.ecdsa_sign_recoverable( signature_hash_bytes, raw=True, digest=sha3_256, ) signature_bytes, rec_id = priv_key.ecdsa_recoverable_serialize(signature_raw) signature = signature_bytes + force_bytes(chr(rec_id)) # Sanity check that the signature is valid. signer_address = force_text(extract_ecdsa_signer( signature_hash_bytes, signature, )) assert signer_address == account return signature
def sign(self, key): """Sign this transaction with a private key. A potentially already existing signature would be overridden. """ if key in (0, '', b'\x00' * 32, '0' * 64): raise InvalidTransaction("Zero privkey cannot sign") rawhash = utils.sha3(rlp.encode(self, UnsignedTransaction)) if len(key) == 64: # we need a binary key key = encode_privkey(key, 'bin') pk = PrivateKey(key, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(rawhash, raw=True) ) signature = signature[0] + utils.bytearray_to_bytestr([signature[1]]) self.v = utils.safe_ord(signature[64]) + 27 self.r = big_endian_to_int(signature[0:32]) self.s = big_endian_to_int(signature[32:64]) self.sender = utils.privtoaddr(key) return self
class Server(object): def __init__(self, my_endpoint): self.endpoint = my_endpoint # 获取私钥 priv_key_file = open('priv_key', 'r') priv_key_serialized = priv_key_file.read() priv_key_file.close() self.priv_key = PrivateKey() self.priv_key.deserialize(priv_key_serialized) # 初始化套接字 self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock.bind(('0.0.0.0', self.endpoint.udpPort)) # set socket non-blocking mode self.sock.setblocking(0) def wrap_packet(self, packet): payload = packet.packet_type + rlp.encode(packet.pack()) sig = self.priv_key.ecdsa_sign_recoverable(keccak256(payload), raw=True) sig_serialized = self.priv_key.ecdsa_recoverable_serialize(sig) payload = sig_serialized[0] + chr(sig_serialized[1]) + payload payload_hash = keccak256(payload) return payload_hash + payload def listen(self): print "listening..." while True: ready = select.select([self.sock], [], [], 1.0) if ready[0]: data, addr = self.sock.recvfrom(2048) print "received message[", addr, "]:" self.receive(data) def listen_thread(self): thread = threading.Thread(target=self.listen) thread.daemon = True return thread def receive(self, data): # verify hash msg_hash = data[:32] if msg_hash != keccak256(data[32:]): print " First 32 bytes are not keccak256 hash of the rest." return else: print " Verified message hash." # verify signature signature = data[32:97] signed_data = data[97:] deserialized_sig = self.priv_key.ecdsa_recoverable_deserialize( signature[:64], ord(signature[64])) remote_pubkey = self.priv_key.ecdsa_recover(keccak256(signed_data), deserialized_sig, raw=True) pub = PublicKey() pub.public_key = remote_pubkey verified = pub.ecdsa_verify( keccak256(signed_data), pub.ecdsa_recoverable_convert(deserialized_sig), raw=True) if not verified: print " Signature invalid" return else: print " Verified signature." response_types = { PingNode.packet_type: self.receive_ping, Pong.packet_type: self.receive_pong, FindNeighbors.packet_type: self.receive_find_neighbors, Neighbors.packet_type: self.receive_neighbors } try: packet_type = data[97] dispatch = response_types[packet_type] except KeyError: print " Unknown message type: " + data[97] return payload = data[98:] dispatch(payload, msg_hash) def receive_pong(self, payload, msg_hash): print " received Pong" print "", Pong.unpack(rlp.decode(payload)) def receive_ping(self, payload, msg_hash): print " received Ping" ping = PingNode.unpack(rlp.decode(payload)) pong = Pong(ping.endpoint_from, msg_hash, time.time() + 60) print " sending Pong response: " + str(pong) self.send(pong, pong.to) def receive_find_neighbors(self, payload, msg_hash): print " received FindNeighbors" print "", FindNeighbors.unpack(rlp.decode(payload)) def receive_neighbors(self, payload, msg_hash): print " received Neighbors" print "", Neighbors.unpack(rlp.decode(payload)) def ping(self, endpoint): ping = PingNode(self.endpoint, endpoint, time.time() + 60) message = self.wrap_packet(ping) print "sending " + str(ping) self.sock.sendto(message, (endpoint.address.exploded, endpoint.udpPort)) def send(self, packet, endpoint): message = self.wrap_packet(packet) print "sending " + str(packet) self.sock.sendto(message, (endpoint.address.exploded, endpoint.udpPort))
class PingServer(object): def __init__(self, my_endpoint): self.endpoint = my_endpoint # get private key priv_key_file = open('priv_key', 'r') priv_key_serialized = priv_key_file.read() priv_key_file.close() self.priv_key = PrivateKey() self.priv_key.deserialize(priv_key_serialized) # init socket self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock.bind(('0.0.0.0', self.endpoint.udpPort)) def wrap_packet(self, packet): payload = packet.packet_type + rlp.encode(packet.pack()) sig = self.priv_key.ecdsa_sign_recoverable(keccak256(payload), raw=True) sig_serialized = self.priv_key.ecdsa_recoverable_serialize(sig) payload = sig_serialized[0] + chr(sig_serialized[1]) + payload payload_hash = keccak256(payload) return payload_hash + payload def udp_listen(self): return threading.Thread(target=self.receive) def receive(self): print "listening..." data, addr = self.sock.recvfrom(1024) print "received message[", addr, "]" ## decode packet below ## verify hash msg_hash = data[:32] if msg_hash != keccak256(data[32:]): print " First 32 bytes are not keccak256 hash of the rest." return else: print " Verified message hash." ## verify signature signature = data[32:97] signed_data = data[97:] deserialized_sig = self.priv_key.ecdsa_recoverable_deserialize( signature[:64], ord(signature[64])) remote_pubkey = self.priv_key.ecdsa_recover(keccak256(signed_data), deserialized_sig, raw=True) pub = PublicKey() pub.public_key = remote_pubkey verified = pub.ecdsa_verify( keccak256(signed_data), pub.ecdsa_recoverable_convert(deserialized_sig), raw=True) if not verified: print " Signature invalid" return else: print " Verified signature." response_types = { PingNode.packet_type: self.receive_ping, Pong.packet_type: self.receive_pong } try: packet_type = data[97] dispatch = response_types[packet_type] except KeyError: print " Unknown message type: " + data[97] return payload = data[98:] dispatch(payload) def receive_pong(self, payload): print " received Pong" print "", Pong.unpack(rlp.decode(payload)) def receive_ping(self, payload): print " received Ping" print "", PingNode.unpack(rlp.decode(payload)) def ping(self, endpoint): ping = PingNode(self.endpoint, endpoint, time.time() + 60) message = self.wrap_packet(ping) print "sending " + str(ping) self.sock.sendto(message, (endpoint.address.exploded, endpoint.udpPort))
def sign(data: bytes, private_key_seed_ascii: str): priv = private_key_seed_ascii pk = PrivateKey(priv, raw=True) signature = pk.ecdsa_recoverable_serialize(pk.ecdsa_sign_recoverable(data, raw=True)) signature = signature[0] + utils.bytearray_to_bytestr([signature[1]]) return signature, eth_privtoaddr(priv)
class TestTxValidator(unittest.TestCase): def setUp(self): # create private key and sender_address receive_address self.private_key = PrivateKey() self.send_address = self.__create_address(self.private_key.pubkey) logging.debug(f"create sender address : {self.send_address}") self.receive_address = self.__create_address(PrivateKey().pubkey) logging.debug(f"create sender address : {self.receive_address}") self.hash_generator = get_tx_hash_generator(conf.LOOPCHAIN_DEFAULT_CHANNEL) self.tx_validator = TxValidator(conf.LOOPCHAIN_DEFAULT_CHANNEL, conf.SendTxType.icx, self.hash_generator) def __create_address(self, public_key: PublicKey) -> str: serialized_pub = public_key.serialize(compressed=False) hashed_pub = hashlib.sha3_256(serialized_pub[1:]).hexdigest() return f'hx{hashed_pub[-40:]}' def __create_icx_origin(self): icx_origin = dict() icx_origin["from"] = self.send_address icx_origin["to"] = self.receive_address icx_origin["value"] = "0xde0b6b3a7640000" icx_origin["fee"] = "0x2386f26fc10000" icx_origin["timestamp"] = str(util.get_now_time_stamp()) icx_origin["nonce"] = "0x3" tx_hash = self.__create_hash(icx_origin) self.tx_hash = tx_hash icx_origin["tx_hash"] = tx_hash logging.debug(f"tx_hash : {tx_hash}") self.__create_signature_to_origin(icx_origin, tx_hash) return icx_origin def __create_icx_origin_v3(self): icx_origin = dict() icx_origin["from"] = self.send_address icx_origin["to"] = self.receive_address icx_origin["value"] = "0xde0b6b3a7640000" icx_origin["fee"] = "0x2386f26fc10000" icx_origin["timestamp"] = str(util.get_now_time_stamp()) icx_origin["nonce"] = "0x3" icx_origin["nid"] = NID.testnet.value icx_origin["stepLimit"] = "0x12345" icx_origin["version"] = "0x3" tx_hash = self.__create_hash(icx_origin) self.tx_hash = tx_hash self.__create_signature_to_origin(icx_origin, tx_hash) return icx_origin def __create_signature_to_origin(self, icx_origin, tx_hash): signature = self.private_key.ecdsa_sign_recoverable(msg=binascii.unhexlify(tx_hash), raw=True, digest=hashlib.sha3_256) serialized_sig = self.private_key.ecdsa_recoverable_serialize(signature) logging.debug(f"serialized_sig : {serialized_sig} " f"\n not_recover_msg size : {sys.getsizeof(serialized_sig[0])}") sig_message = b''.join([serialized_sig[0], bytes([serialized_sig[1]])]) logging.debug(f"sig message :{sig_message} " f"\n with_recover_msg size : {sys.getsizeof(sig_message)}") icx_origin['signature'] = base64.b64encode(sig_message).decode() def __create_hash(self, icx_origin): # gen origin gen = self.gen_ordered_items(icx_origin) origin = ".".join(gen) origin = f"icx_sendTransaction.{origin}" logging.debug(f"origin data : {origin}") logging.debug(f"encode origin : {origin.encode()}") # gen hash return hashlib.sha3_256(origin.encode()).hexdigest() def gen_ordered_items(self, parameter): ordered_keys = list(parameter) ordered_keys.sort() for key in ordered_keys: logging.debug(f"item : {key}, {parameter[key]}") yield key if isinstance(parameter[key], str): yield parameter[key] elif isinstance(parameter[key], dict): yield from self.gen_ordered_items(parameter[key]) else: raise TypeError(f"{key} must be dict or str") def test_validate_icx_tx(self): """ GIVEN icx transaction that type of string, create TxValidator with sent_tx_type to icx WHEN restore tx THEN can create correct tx WHEN validate tx_object THEN return true :return: """ for i in range(1000): icx_origin = self.__create_icx_origin() # type: Dict[str, str] message = json.dumps(icx_origin) tx = self.tx_validator.validate_dumped_tx_message(message) self.assertEqual(tx.tx_hash, self.tx_hash) self.assertEqual(tx.signature, base64.b64decode(icx_origin['signature'].encode())) self.assertTrue(self.tx_validator.validate(tx)) def test_validate_nid_v3(self): ChannelProperty().nid = NID.testnet.value icx_origin = self.__create_icx_origin_v3() # type: Dict[str, str] message = json.dumps(icx_origin) tx = self.tx_validator.validate_dumped_tx_message(message) self.assertEqual(tx.icx_origin_data_v3["version"], hex(conf.ApiVersion.v3)) self.assertEqual(tx.icx_origin_data_v3["nid"], ChannelProperty().nid) self.assertTrue(self.tx_validator.validate(tx)) ChannelProperty().nid = None def test_validate_repeat(self): """ for validate ctx sharing :return: """ for i in range(1000): icx_origin = self.__create_icx_origin() # type: Dict[str, str] message = json.dumps(icx_origin) tx = self.tx_validator.validate_dumped_tx_message(message) self.assertEqual(tx.tx_hash, self.tx_hash) self.assertEqual(tx.signature, base64.b64decode(icx_origin['signature'].encode())) self.assertTrue(self.tx_validator.validate(tx)) def test_transaction_invalid_hash_foramt(self): wallet = IcxWallet() wallet.value = 1 params = wallet.create_icx_origin() params['tx_hash'] = "12312" self.__test_wallet_exception(params, TransactionInvalidHashForamtError) def test_transaction_invalid_address(self): wallet = IcxWallet() wallet.value = 1 wallet._IcxWallet__address = "hx2983" params = wallet.create_icx_origin() self.__test_wallet_exception(params, TransactionInvalidAddressError) params = wallet.create_icx_origin_v3() self.__test_wallet_exception(params, TransactionInvalidAddressError) def test_transcation_invalid_address_not_match(self): wallet = IcxWallet() wallet.value = 1 paramsv2 = wallet.create_icx_origin() paramsv3 = wallet.create_icx_origin_v3() another_wallet = IcxWallet() # sign hash with another wallet's private key paramsv2['signature'] = another_wallet.create_signature(self.hash_generator.generate_hash(paramsv2)) paramsv3['signature'] = another_wallet.create_signature(self.hash_generator.generate_hash(paramsv3)) logging.info("address: " + wallet.address) logging.info("another addres: " + another_wallet.address) ChannelProperty().nid = '0x3' exception: TransactionInvalidAddressNotMatchError = self.__test_wallet_exception( paramsv2, TransactionInvalidAddressNotMatchError) self.assertEquals(exception.address, wallet.address) self.assertEquals(exception.expected_address, another_wallet.address) exception: TransactionInvalidAddressNotMatchError = self.__test_wallet_exception( paramsv3, TransactionInvalidAddressNotMatchError) self.assertEquals(exception.address, wallet.address) self.assertEquals(exception.expected_address, another_wallet.address) # These codes below affects hash generation. # V3 params does not have `txHash`. # So it cannot raise `HashNotMatch` Exception but `AddressNotMatch` paramsv3 = wallet.create_icx_origin_v3() paramsv3["timestamp"] = hex(utils.get_now_time_stamp()) exception: TransactionInvalidAddressNotMatchError = self.__test_wallet_exception( paramsv3, TransactionInvalidAddressNotMatchError) self.assertEquals(exception.address, wallet.address) def test_transaction_invalid_hash_not_match(self): wallet = IcxWallet() wallet.value = 1 # V3 params does not have `txHash`. # So it cannot raise `HashNotMatch` Exception but `AddressNotMatch` paramsv2 = wallet.create_icx_origin() time.sleep(0.1) paramsv2["timestamp"] = str(utils.get_now_time_stamp()) self.__test_wallet_exception(paramsv2, TransactionInvalidHashNotMatchError) def test_transaction_invalid_hash_generation(self): wallet = IcxWallet() wallet.value = 1 paramsv2 = wallet.create_icx_origin() # make recursion for raising an exception. paramsv2['recursion'] = paramsv2 try: icon_validator = IconValidateStrategy(self.hash_generator) icon_validator._IconValidateStrategy__validate_icx_params(paramsv2, paramsv2['tx_hash']) except TransactionInvalidHashGenerationError as e: logging.info(TransactionInvalidHashGenerationError.__name__) logging.info(e) else: raise RuntimeError(f"{TransactionInvalidHashGenerationError.__name__} did not raise.") def test_transacion_invalid_signature(self): wallet = IcxWallet() wallet.value = 1 paramsv2 = wallet.create_icx_origin() try: icon_validator = IconValidateStrategy(self.hash_generator) icon_validator._IconValidateStrategy__validate_icx_signature( paramsv2['tx_hash'], "weds", paramsv2['from']) except TransactionInvalidSignatureError as e: logging.info(TransactionInvalidSignatureError.__name__) logging.info(e) else: raise RuntimeError(f"{TransactionInvalidSignatureError.__name__} did not raise.") def test_transaction_invalid_wrong_nid(self): wallet = IcxWallet() wallet.value = 1 wallet.nid = '0x5' ChannelProperty().nid = '0x3' param3 = wallet.create_icx_origin_v3() exception: TransactionInvalidNoNidError = self.__test_wallet_exception(param3, TransactionInvalidNoNidError) self.assertEqual(exception.expected_nid, ChannelProperty().nid) self.assertEqual(exception.nid, wallet.nid) def __test_wallet_exception(self, wallet_params, error_type): dumped_params = json.dumps(wallet_params) try: self.tx_validator.validate_dumped_tx_message(dumped_params) except error_type as e: logging.info(error_type.__name__) logging.info(e) return e else: raise RuntimeError(f"{error_type.__name__} did not raise.")