示例#1
0
    def send_to_stealth_address(self, stealth_addr, ephemeral_private=None):
        if isinstance(stealth_addr, str):
            stealth_addr = bc.StealthAddress.from_string(stealth_addr)
            assert stealth_addr is not None

        # Sender generates a new ephemeral key.
        if ephemeral_private is None:
            ephemeral_private = StealthSender._random_ephemeral_secret()
        ephemeral_public = ephemeral_private.to_public()

        spend_keys = stealth_addr.spend_keys()
        assert spend_keys

        # Sender derives stealth public, requiring ephemeral private.
        self.sender_public = bc.uncover_stealth(stealth_addr.scan_key(),
                                                ephemeral_private,
                                                spend_keys[0])
        self._send_address = bc.PaymentAddress.from_point(
            self.sender_public, self._version)

        metadata = ephemeral_public.data[1:]
        assert len(metadata) == 32
        meta_script = bc.Script.from_ops(
            [bc.Opcode.return_, metadata + StealthSender._random_data(8)])
        return meta_script, self._send_address
示例#2
0
def stealth_round_trip():
    expected_stealth_private = bc.EcSecret.from_bytes(
        bytes.fromhex(STEALTH_PRIVATE))

    # Receiver generates a new scan private.
    scan_private = bc.EcSecret.from_bytes(bytes.fromhex(SCAN_PRIVATE))
    scan_public = scan_private.to_public()
    assert scan_public.data.hex() == SCAN_PUBLIC

    # Receiver generates a new spend private.
    spend_private = bc.EcSecret.from_bytes(bytes.fromhex(SPEND_PRIVATE))
    spend_public = spend_private.to_public()
    assert spend_public.data.hex() == SPEND_PUBLIC

    # Sender generates a new ephemeral key.
    ephemeral_private = bc.EcSecret.from_bytes(
        bytes.fromhex(EPHEMERAL_PRIVATE))
    ephemeral_public = ephemeral_private.to_public()
    assert ephemeral_public.data.hex() == EPHEMERAL_PUBLIC

    # Sender derives stealth public, requiring ephemeral private.
    sender_public = bc.uncover_stealth(scan_public, ephemeral_private,
                                       spend_public)
    assert sender_public.data.hex() == STEALTH_PUBLIC

    # Receiver derives stealth public, requiring scan private.
    receiver_public = bc.uncover_stealth(ephemeral_public, scan_private,
                                         spend_public)
    assert receiver_public.data.hex()

    # Only reciever can derive stealth private, as it requires both scan
    # and spend private.
    stealth_private = bc.uncover_stealth(ephemeral_public, scan_private,
                                         spend_private)

    # This shows that both parties have actually generated stealth public.
    stealth_public = stealth_private.to_public()
    assert stealth_public.data.hex() == STEALTH_PUBLIC

    # Both parties therefore have the ability to generate the p2pkh address.
    # versioning: stealth_address::main corresponds to payment_address::main_p2pkh
    public = bc.EcPublic.from_compressed(stealth_public)
    address = bc.PaymentAddress.from_point(public,
                                           bc.PaymentAddress.mainnet_p2kh)
    assert str(address) == P2PKH_ADDRESS
示例#3
0
    def derive_address(self, ephemeral_public):
        spend_public = self.spend_private.to_public()
        self.receiver_public = bc.uncover_stealth(ephemeral_public,
                                                  self.scan_private,
                                                  spend_public)

        self.derived_address = bc.PaymentAddress.from_point(
            self.receiver_public, self._version)
        return self.derived_address
示例#4
0
 def derive_private(self, ephemeral_public):
     receiver_private = bc.uncover_stealth(ephemeral_public,
                                           self.scan_private,
                                           self.spend_private)
     return receiver_private