Пример #1
0
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
Пример #2
0
    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
Пример #3
0
    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
Пример #4
0
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
Пример #5
0
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)
Пример #6
0
    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
Пример #7
0
    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
Пример #8
0
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
Пример #9
0
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
Пример #10
0
    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
Пример #11
0
    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
Пример #12
0
    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
Пример #13
0
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
Пример #14
0
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)
Пример #15
0
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
Пример #16
0
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
Пример #17
0
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
Пример #18
0
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
Пример #19
0
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
Пример #20
0
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
Пример #21
0
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
Пример #22
0
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)