def make_privatekey_address( privatekey: PrivateKey = EMPTY, ) -> typing.Tuple[PrivateKey, typing.Address]: privatekey = if_empty(privatekey, make_privatekey()) publickey = privatekey.public_key.format(compressed=False) address = publickey_to_address(publickey) return privatekey, address
def decode(cls, data): packed = messages.wrap(data) if packed is None: return # signature must be at the end message_type = type(packed) signature = message_type.fields_spec[-1] assert signature.name == 'signature', 'signature is not the last field' data_that_was_signed = data[:-signature.size_bytes] message_signature = data[-signature.size_bytes:] try: publickey = recover_publickey(data_that_was_signed, message_signature) except ValueError: # raised if the signature has the wrong length log.error('invalid signature') return except TypeError as e: # raised if the PublicKey instantiation failed log.error('invalid key data: {}'.format(e.message)) return except Exception as e: # pylint: disable=broad-except # secp256k1 is using bare Exception classes: raised if the recovery failed log.error('error while recovering pubkey: {}'.format(e.message)) return message = cls.unpack(packed) # pylint: disable=no-member message.sender = publickey_to_address(publickey) return message
def decode(cls, data): packed = messages.wrap(data) if packed is None: return # signature must be at the end message_type = type(packed) signature = message_type.fields_spec[-1] assert signature.name == 'signature', 'signature is not the last field' message_data = data[:-signature.size_bytes] message_signature = data[-signature.size_bytes:] message_hash = sha3(message_data) data_that_was_signed = pack_signing_data( message_type.get_bytes_from(data, 'nonce'), message_type.get_bytes_from(data, 'transferred_amount'), message_type.get_bytes_from(data, 'channel'), message_type.get_bytes_from(data, 'locksroot'), message_hash, ) publickey = recover_publickey_safe(data_that_was_signed, message_signature) message = cls.unpack(packed) # pylint: disable=no-member message.sender = publickey_to_address(publickey) return message
def is_valid_signature( balance_proof: BalanceProofSignedState, sender_address: typing.Address, ) -> typing.SuccessOrError: data_that_was_signed = signing_data( balance_proof.nonce, balance_proof.transferred_amount, balance_proof.channel_address, balance_proof.locksroot, balance_proof.message_hash, ) try: # ValueError is raised if the PublicKey instantiation failed, let it # propagate because it's a memory pressure problem publickey = recover_publickey( data_that_was_signed, balance_proof.signature, ) except Exception: # pylint: disable=broad-except # secp256k1 is using bare Exception classes # raised if the recovery failed msg = 'Signature invalid, could not be recovered.' return (False, msg) is_correct_sender = sender_address == publickey_to_address(publickey) if is_correct_sender: return (True, None) msg = 'Signature was valid but the expected address does not match.' return (False, msg)
def decode(cls, data): result = messages.wrap_and_validate(data) if result is None: return packed, public_key = result message = cls.unpack(packed) # pylint: disable=no-member message.sender = publickey_to_address(public_key) return message
def make_signed_transfer_for( channel_state, amount, initiator, target, expiration, secret, identifier=1, nonce=1, transferred_amount=0, pkey=UNIT_TRANSFER_PKEY, sender=UNIT_TRANSFER_SENDER, ): pubkey = pkey.public_key.format(compressed=False) assert publickey_to_address(pubkey) == sender assert sender in (channel_state.our_state.address, channel_state.partner_state.address) if sender == channel_state.our_state.address: recipient = channel_state.partner_state.address else: recipient = channel_state.our_state.address channel_address = channel_state.identifier token_address = channel_state.token_address mediated_transfer = make_signed_transfer( amount, initiator, target, expiration, secret, payment_identifier=identifier, nonce=nonce, transferred_amount=transferred_amount, recipient=recipient, channel_identifier=channel_address, token=token_address, pkey=pkey, sender=sender, ) # Do *not* register the transfer here is_valid, msg, _ = channel.is_valid_lockedtransfer( mediated_transfer, channel_state, channel_state.partner_state, channel_state.our_state, ) assert is_valid, msg return mediated_transfer
def sign(self, private_key): """ Sign message using `private_key`. """ packed = self.packed() field = packed.fields_spec[-1] assert field.name == 'signature', 'signature is not the last field' message_data = packed.data[:-field. size_bytes] # XXX: this slice must be from the end of the buffer signature, public_key = signing.sign(message_data, private_key) packed.data[-field.size_bytes:] = signature self.sender = publickey_to_address(public_key) self.signature = signature
def decode(cls, data): packed = messages.wrap(data) if packed is None: return # signature must be at the end message_type = type(packed) signature = message_type.fields_spec[-1] assert signature.name == 'signature', 'signature is not the last field' message_data = data[:-signature.size_bytes] message_signature = data[-signature.size_bytes:] message_hash = sha3(message_data) nonce = message_type.get_bytes_from(data, 'nonce') transferred_amount = message_type.get_bytes_from( data, 'transferred_amount') locksroot = message_type.get_bytes_from(data, 'locksroot') channel_address = message_type.get_bytes_from(data, 'channel') data_that_was_signed = (nonce + transferred_amount + locksroot + channel_address + message_hash) try: publickey = recover_publickey(data_that_was_signed, message_signature) except ValueError: # raised if the signature has the wrong length log.error('invalid signature') return except TypeError as e: # raised if the PublicKey instantiation failed log.error('invalid key data: {}'.format(e.message)) return except Exception as e: # pylint: disable=broad-except # secp256k1 is using bare Exception classes: raised if the recovery failed log.error('error while recovering pubkey: {}'.format(e.message)) return message = cls.unpack(packed) # pylint: disable=no-member message.sender = publickey_to_address(publickey) return message
def decode(cls, data): packed = messages.wrap(data) if packed is None: return # signature must be at the end message_type = type(packed) signature = message_type.fields_spec[-1] assert signature.name == 'signature', 'signature is not the last field' data_that_was_signed = data[:-signature.size_bytes] message_signature = data[-signature.size_bytes:] publickey = recover_publickey_safe(data_that_was_signed, message_signature) message = cls.unpack(packed) # pylint: disable=no-member message.sender = publickey_to_address(publickey) return message
def make_privkey_address(): private_key_bin = os.urandom(32) privkey = PrivateKey(private_key_bin) pubkey = privkey.public_key.format(compressed=False) address = publickey_to_address(pubkey) return privkey, address
def recover_address(messagedata, signature, hasher=sha3): public_key = recover_publickey_safe(messagedata, signature, hasher) if public_key is None: return None return publickey_to_address(public_key)
def make_signed_transfer_for( channel_state: NettingChannelState = EMPTY, properties: LockedTransferSignedStateProperties = None, defaults: LockedTransferSignedStateProperties = None, compute_locksroot: bool = False, allow_invalid: bool = False, only_transfer: bool = True, ) -> LockedTransferSignedState: properties: LockedTransferSignedStateProperties = create_properties( properties or LockedTransferSignedStateProperties(), defaults or SIGNED_TRANSFER_FOR_CHANNEL_DEFAULTS, ) channel_state = if_empty(channel_state, create(NettingChannelStateProperties())) if not allow_invalid: expiration = properties.transfer.expiration valid = channel_state.reveal_timeout < expiration < channel_state.settle_timeout assert valid, 'Expiration must be between reveal_timeout and settle_timeout.' pubkey = properties.pkey.public_key.format(compressed=False) assert publickey_to_address(pubkey) == properties.sender if properties.sender == channel_state.our_state.address: recipient = channel_state.partner_state.address elif properties.sender == channel_state.partner_state.address: recipient = channel_state.our_state.address else: assert False, 'Given sender does not participate in given channel.' if compute_locksroot: lock = Lock( amount=properties.transfer.amount, expiration=properties.transfer.expiration, secrethash=sha3(properties.transfer.secret), ) locksroot = merkleroot( channel.compute_merkletree_with( merkletree=channel_state.partner_state.merkletree, lockhash=sha3(lock.as_bytes), )) else: locksroot = properties.transfer.balance_proof.locksroot if only_transfer: balance_proof_properties = BalanceProofProperties( locksroot=locksroot, channel_identifier=channel_state.identifier, transferred_amount=0, locked_amount=properties.transfer.amount, ) else: balance_proof_properties = BalanceProofProperties( locksroot=locksroot, channel_identifier=channel_state.identifier, ) transfer = create( LockedTransferSignedStateProperties( recipient=recipient, transfer=LockedTransferProperties( balance_proof=balance_proof_properties, ), ), defaults=properties, ) if not allow_invalid: is_valid, msg, _ = channel.is_valid_lockedtransfer( transfer_state=transfer, channel_state=channel_state, sender_state=channel_state.partner_state, receiver_state=channel_state.our_state, ) assert is_valid, msg return transfer
def make_signed_transfer_for( channel_state, amount, initiator, target, expiration, secret, identifier=1, nonce=1, transferred_amount=0, locked_amount=None, pkey=UNIT_TRANSFER_PKEY, sender=UNIT_TRANSFER_SENDER, compute_locksroot=False, allow_invalid=False, ): if not allow_invalid: msg = 'expiration must be lower than settle_timeout' assert expiration < channel_state.settle_timeout, msg msg = 'expiration must be larger than settle_timeout' assert expiration > channel_state.reveal_timeout, msg pubkey = pkey.public_key.format(compressed=False) assert publickey_to_address(pubkey) == sender assert sender in (channel_state.our_state.address, channel_state.partner_state.address) if sender == channel_state.our_state.address: recipient = channel_state.partner_state.address else: recipient = channel_state.our_state.address channel_identifier = channel_state.identifier token_address = channel_state.token_address if compute_locksroot: locksroot = merkleroot( channel.compute_merkletree_with( channel_state.partner_state.merkletree, sha3(Lock(amount, expiration, sha3(secret)).as_bytes), )) else: locksroot = EMPTY_MERKLE_ROOT mediated_transfer = make_signed_transfer( amount, initiator, target, expiration, secret, payment_identifier=identifier, nonce=nonce, transferred_amount=transferred_amount, locked_amount=locked_amount, recipient=recipient, channel_identifier=channel_identifier, token=token_address, pkey=pkey, sender=sender, locksroot=locksroot, ) # Do *not* register the transfer here if not allow_invalid: is_valid, msg, _ = channel.is_valid_lockedtransfer( mediated_transfer, channel_state, channel_state.partner_state, channel_state.our_state, ) assert is_valid, msg return mediated_transfer
def make_transfers_pair(privatekeys, amount, block_number): transfers_pair = list() channel_map = dict() pseudo_random_generator = random.Random() addresses = list() for pkey in privatekeys: pubkey = pkey.public_key.format(compressed=False) address = publickey_to_address(pubkey) addresses.append(address) key_address = list(zip(privatekeys, addresses)) deposit_amount = amount * 5 channels_state = { address: make_channel( our_address=HOP1, our_balance=deposit_amount, partner_balance=deposit_amount, partner_address=address, token_address=UNIT_TOKEN_ADDRESS, token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS, ) for address in addresses } lock_expiration = block_number + UNIT_REVEAL_TIMEOUT * 2 for (payer_key, payer_address), payee_address in zip(key_address[:-1], addresses[1:]): pay_channel = channels_state[payee_address] receive_channel = channels_state[payer_address] received_transfer = make_signed_transfer( amount=amount, initiator=UNIT_TRANSFER_INITIATOR, target=UNIT_TRANSFER_TARGET, expiration=lock_expiration, secret=UNIT_SECRET, payment_identifier=UNIT_TRANSFER_IDENTIFIER, channel_identifier=receive_channel.identifier, pkey=payer_key, sender=payer_address, ) is_valid, _, msg = channel.handle_receive_lockedtransfer( receive_channel, received_transfer, ) assert is_valid, msg message_identifier = message_identifier_from_prng( pseudo_random_generator) lockedtransfer_event = channel.send_lockedtransfer( channel_state=pay_channel, initiator=UNIT_TRANSFER_INITIATOR, target=UNIT_TRANSFER_TARGET, amount=amount, message_identifier=message_identifier, payment_identifier=UNIT_TRANSFER_IDENTIFIER, expiration=lock_expiration, secrethash=UNIT_SECRETHASH, ) assert lockedtransfer_event lock_timeout = lock_expiration - block_number assert mediator.is_channel_usable( candidate_channel_state=pay_channel, transfer_amount=amount, lock_timeout=lock_timeout, ) sent_transfer = lockedtransfer_event.transfer pair = MediationPairState( received_transfer, lockedtransfer_event.recipient, sent_transfer, ) transfers_pair.append(pair) channel_map[receive_channel.identifier] = receive_channel channel_map[pay_channel.identifier] = pay_channel assert channel.is_lock_locked(receive_channel.partner_state, UNIT_SECRETHASH) assert channel.is_lock_locked(pay_channel.our_state, UNIT_SECRETHASH) return channel_map, transfers_pair
def make_signed_transfer_for( channel_state: NettingChannelState = EMPTY, amount: typing.TokenAmount = EMPTY, initiator: typing.InitiatorAddress = EMPTY, target: typing.TargetAddress = EMPTY, expiration: typing.BlockExpiration = EMPTY, secret: typing.Secret = EMPTY, identifier: typing.PaymentID = EMPTY, nonce: typing.Nonce = EMPTY, transferred_amount: typing.TokenAmount = EMPTY, locked_amount: typing.TokenAmount = EMPTY, pkey: PrivateKey = EMPTY, sender: typing.Address = EMPTY, compute_locksroot: typing.Locksroot = EMPTY, allow_invalid: bool = EMPTY, ) -> LockedTransferSignedState: channel_state = if_empty(channel_state, make_channel_state()) amount = if_empty(amount, 0) initiator = if_empty(initiator, make_address()) target = if_empty(target, make_address()) expiration = if_empty(expiration, UNIT_REVEAL_TIMEOUT) secret = if_empty(secret, make_secret()) identifier = if_empty(identifier, 1) nonce = if_empty(nonce, 1) transferred_amount = if_empty(transferred_amount, 0) pkey = if_empty(pkey, UNIT_TRANSFER_PKEY) sender = if_empty(sender, UNIT_TRANSFER_SENDER) compute_locksroot = if_empty(compute_locksroot, False) allow_invalid = if_empty(allow_invalid, False) if not allow_invalid: msg = 'expiration must be lower than settle_timeout' assert expiration < channel_state.settle_timeout, msg msg = 'expiration must be larger than reveal_timeout' assert expiration > channel_state.reveal_timeout, msg pubkey = pkey.public_key.format(compressed=False) assert publickey_to_address(pubkey) == sender assert sender in (channel_state.our_state.address, channel_state.partner_state.address) if sender == channel_state.our_state.address: recipient = channel_state.partner_state.address else: recipient = channel_state.our_state.address channel_identifier = channel_state.identifier token_address = channel_state.token_address if compute_locksroot: locksroot = merkleroot( channel.compute_merkletree_with( channel_state.partner_state.merkletree, sha3(Lock(amount, expiration, sha3(secret)).as_bytes), )) else: locksroot = EMPTY_MERKLE_ROOT mediated_transfer = make_signed_transfer( amount=amount, initiator=initiator, target=target, expiration=expiration, secret=secret, payment_identifier=identifier, nonce=nonce, transferred_amount=transferred_amount, locksroot=locksroot, locked_amount=locked_amount, recipient=recipient, channel_identifier=channel_identifier, token_network_address=channel_state.token_network_identifier, token=token_address, pkey=pkey, sender=sender, ) # Do *not* register the transfer here if not allow_invalid: is_valid, msg, _ = channel.is_valid_lockedtransfer( transfer_state=mediated_transfer, channel_state=channel_state, sender_state=channel_state.partner_state, receiver_state=channel_state.our_state, ) assert is_valid, msg return mediated_transfer
def make_privkey_address(): private_key_bin = sha3(''.join(random.choice(string.printable) for _ in range(20)).encode()) privkey = PrivateKey(private_key_bin) pubkey = privkey.public_key.format(compressed=False) address = publickey_to_address(pubkey) return privkey, address
def make_signed_transfer_for( channel_state: NettingChannelState = EMPTY, properties: LockedTransferSignedStateProperties = None, defaults: LockedTransferSignedStateProperties = None, compute_locksroot: bool = False, allow_invalid: bool = False, only_transfer: bool = True, ) -> LockedTransferSignedState: properties: LockedTransferSignedStateProperties = create_properties( properties or LockedTransferSignedStateProperties(), defaults or SIGNED_TRANSFER_FOR_CHANNEL_DEFAULTS, ) channel_state = if_empty(channel_state, create(NettingChannelStateProperties())) if not allow_invalid: expiration = properties.transfer.expiration valid = channel_state.reveal_timeout < expiration < channel_state.settle_timeout assert valid, 'Expiration must be between reveal_timeout and settle_timeout.' pubkey = properties.pkey.public_key.format(compressed=False) assert publickey_to_address(pubkey) == properties.sender if properties.sender == channel_state.our_state.address: recipient = channel_state.partner_state.address elif properties.sender == channel_state.partner_state.address: recipient = channel_state.our_state.address else: assert False, 'Given sender does not participate in given channel.' if compute_locksroot: lock = Lock( amount=properties.transfer.amount, expiration=properties.transfer.expiration, secrethash=sha3(properties.transfer.secret), ) locksroot = merkleroot(channel.compute_merkletree_with( merkletree=channel_state.partner_state.merkletree, lockhash=sha3(lock.as_bytes), )) else: locksroot = properties.transfer.balance_proof.locksroot if only_transfer: balance_proof_properties = BalanceProofProperties( locksroot=locksroot, channel_identifier=channel_state.identifier, transferred_amount=0, locked_amount=properties.transfer.amount, ) else: balance_proof_properties = BalanceProofProperties( locksroot=locksroot, channel_identifier=channel_state.identifier, ) transfer = create( LockedTransferSignedStateProperties( recipient=recipient, transfer=LockedTransferProperties( balance_proof=balance_proof_properties, ), ), defaults=properties, ) if not allow_invalid: is_valid, msg, _ = channel.is_valid_lockedtransfer( transfer_state=transfer, channel_state=channel_state, sender_state=channel_state.partner_state, receiver_state=channel_state.our_state, ) assert is_valid, msg return transfer