Beispiel #1
0
def _set_out_derivation(
    state: State,
    dst_entr: MoneroTransactionDestinationEntry,
    additional_txkey_priv: Sc25519,
) -> Ge25519:
    """
    Calculates derivation which is then used in the one-time address as
    `P = H(derivation)*G + B`.
    For change outputs the derivation equals a*R, because we know the
    private view key. For others it is either `r*A` for traditional
    addresses, or `s*C` for subaddresses. Both `r` and `s` are random
    scalars, `s` is used in the context of subaddresses, but it's
    basically the same thing.
    """
    from apps.monero.xmr.addresses import addr_eq

    change_addr = state.change_address()
    if change_addr and addr_eq(dst_entr.addr, change_addr):
        # sending change to yourself; derivation = a*R
        derivation = crypto.generate_key_derivation(
            state.tx_pub, state.creds.view_key_private)

    else:
        # sending to the recipient; derivation = r*A (or s*C in the subaddress scheme)
        if dst_entr.is_subaddress and state.need_additional_txkeys:
            deriv_priv = additional_txkey_priv
        else:
            deriv_priv = state.tx_priv
        derivation = crypto.generate_key_derivation(
            crypto.decodepoint(dst_entr.addr.view_public_key), deriv_priv)
    return derivation
Beispiel #2
0
def generate_tx_spend_and_key_image_and_derivation(
    creds: AccountCreds,
    subaddresses: Subaddresses,
    out_key: Ge25519,
    tx_public_key: Ge25519,
    additional_tx_public_key: Ge25519,
    real_output_index: int,
    sub_addr_major: int = None,
    sub_addr_minor: int = None,
) -> Tuple[Sc25519, Ge25519, Ge25519]:
    """
    Generates UTXO spending key and key image and corresponding derivation.
    Supports subaddresses.
    Corresponds to generate_key_image_helper() in the Monero codebase.

    :param creds:
    :param subaddresses:
    :param out_key: real output (from input RCT) destination key
    :param tx_public_key: R, transaction public key
    :param additional_tx_public_key: Additional Rs, for subaddress destinations
    :param real_output_index: index of the real output in the RCT
    :param sub_addr_major: subaddress major index
    :param sub_addr_minor: subaddress minor index
    :return:
    """
    recv_derivation = crypto.generate_key_derivation(
        tx_public_key, creds.view_key_private
    )

    additional_recv_derivation = (
        crypto.generate_key_derivation(additional_tx_public_key, creds.view_key_private)
        if additional_tx_public_key
        else None
    )

    subaddr_recv_info = is_out_to_account(
        subaddresses,
        out_key,
        recv_derivation,
        additional_recv_derivation,
        real_output_index,
        creds,
        sub_addr_major,
        sub_addr_minor,
    )
    if subaddr_recv_info is None:
        raise XmrNoSuchAddressException("No such addr")

    xi, ki = generate_tx_spend_and_key_image(
        creds, out_key, subaddr_recv_info[1], real_output_index, subaddr_recv_info[0]
    )
    return xi, ki, recv_derivation
def _encrypt_payment_id(payment_id, public_key, secret_key):
    """
    Encrypts payment_id hex.
    Used in the transaction extra. Only recipient is able to decrypt.
    """
    derivation_p = crypto.generate_key_derivation(public_key, secret_key)
    derivation = bytearray(33)
    derivation = crypto.encodepoint_into(derivation, derivation_p)
    derivation[32] = 0x8D  # ENCRYPTED_PAYMENT_ID_TAIL
    hash = crypto.cn_fast_hash(derivation)
    pm_copy = bytearray(payment_id)
    return crypto.xor8(pm_copy, hash)
Beispiel #4
0
def _encrypt_payment_id(payment_id, public_key, secret_key):
    """
    Encrypts payment_id hex.
    Used in the transaction extra. Only recipient is able to decrypt.
    """
    derivation_p = crypto.generate_key_derivation(public_key, secret_key)
    derivation = bytearray(33)
    derivation = crypto.encodepoint_into(derivation, derivation_p)
    derivation[32] = 0x8B
    hash = crypto.cn_fast_hash(derivation)
    pm_copy = bytearray(payment_id)
    for i in range(8):
        pm_copy[i] ^= hash[i]
    return pm_copy
    def test_generate_key_derivation(self):
        key_pub = crypto.decodepoint(
            unhexlify(
                b"7739c95d3298e2f87362dba9e0e0b3980a692ae8e2f16796b0e382098cd6bd83"
            ))
        key_priv = crypto.decodeint(
            unhexlify(
                b"3482fb9735ef879fcae5ec7721b5d3646e155c4fb58d6cc11c732c9c9b76620a"
            ))
        deriv_exp = unhexlify(
            b"fa188a45a0e4daccc0e6d4f6f6858fd46392104be74183ec0047e7e9f4eaf739"
        )

        self.assertEqual(
            deriv_exp,
            crypto.encodepoint(
                crypto.generate_key_derivation(key_pub, key_priv)),
        )