예제 #1
0
def _compute_tx_keys(
        state: State, dst_entr: MoneroTransactionDestinationEntry
) -> Tuple[Ge25519, Sc25519]:
    """Computes tx_out_key, amount_key"""

    if state.is_processing_offloaded:
        return None, None  # no need to recompute

    # additional tx key if applicable
    additional_txkey_priv = _set_out_additional_keys(state, dst_entr)
    # derivation = a*R or r*A or s*C
    derivation = _set_out_derivation(state, dst_entr, additional_txkey_priv)
    # amount key = H_s(derivation || i)
    amount_key = crypto.derivation_to_scalar(derivation,
                                             state.current_output_index)
    # one-time destination address P = H_s(derivation || i)*G + B
    tx_out_key = crypto.derive_public_key(
        derivation,
        state.current_output_index,
        crypto.decodepoint(dst_entr.addr.spend_public_key),
    )
    del (derivation, additional_txkey_priv)

    from apps.monero.xmr import monero

    mask = monero.commitment_mask(crypto.encodeint(amount_key))
    state.output_masks.append(mask)
    return tx_out_key, amount_key
    def test_public_spend(self):
        derivation = unhexlify(
            b"e720a09f2e3a0bbf4e4ba7ad93653bb296885510121f806acb2a5f9168fafa01"
        )
        base = unhexlify(
            b"7d996b0f2db6dbb5f2a086211f2399a4a7479b2c911af307fdc3f7f61a88cb0e"
        )
        pkey_ex = unhexlify(
            b"0846cae7405077b6b7800f0b932c10a186448370b6db318f8c9e13f781dab546"
        )

        pkey_comp = crypto.derive_public_key(crypto.decodepoint(derivation), 0,
                                             crypto.decodepoint(base))
        self.assertEqual(pkey_ex, crypto.encodepoint(pkey_comp))
예제 #3
0
def _compute_tx_keys(state: State, dst_entr):
    """Computes tx_out_key, amount_key"""

    if state.is_processing_offloaded:
        return None, None  # no need to recompute

    # additional tx key if applicable
    additional_txkey_priv = _set_out_additional_keys(state, dst_entr)
    # derivation = a*R or r*A or s*C
    derivation = _set_out_derivation(state, dst_entr, additional_txkey_priv)
    # amount key = H_s(derivation || i)
    amount_key = crypto.derivation_to_scalar(derivation,
                                             state.current_output_index)
    # one-time destination address P = H_s(derivation || i)*G + B
    tx_out_key = crypto.derive_public_key(
        derivation,
        state.current_output_index,
        crypto.decodepoint(dst_entr.addr.spend_public_key),
    )
    del (derivation, additional_txkey_priv)

    # Computes the newest mask if applicable
    if state.is_det_mask():
        from apps.monero.xmr import monero

        mask = monero.commitment_mask(crypto.encodeint(amount_key))

    elif state.current_output_index + 1 < state.output_count:
        mask = offloading_keys.det_comm_masks(state.key_enc,
                                              state.current_output_index)

    else:
        mask = state.output_last_mask
        state.output_last_mask = None

    state.output_masks.append(mask)
    return tx_out_key, amount_key
예제 #4
0
async def set_output(state: State, dst_entr, dst_entr_hmac, rsig_data):
    state.mem_trace(0, True)
    mods = utils.unimport_begin()

    await confirms.transaction_step(state.ctx, state.STEP_OUT,
                                    state.current_output_index + 1,
                                    state.output_count)
    state.mem_trace(1)

    state.current_output_index += 1
    state.mem_trace(2, True)
    await _validate(state, dst_entr, dst_entr_hmac)

    # First output - we include the size of the container into the tx prefix hasher
    if state.current_output_index == 0:
        state.tx_prefix_hasher.uvarint(state.output_count)
    state.mem_trace(4, True)

    state.output_amounts.append(dst_entr.amount)
    state.summary_outs_money += dst_entr.amount
    utils.unimport_end(mods)
    state.mem_trace(5, True)

    # Range proof first, memory intensive
    rsig, mask = _range_proof(state, dst_entr.amount, rsig_data)
    utils.unimport_end(mods)
    state.mem_trace(6, True)

    # additional tx key if applicable
    additional_txkey_priv = _set_out_additional_keys(state, dst_entr)
    # derivation = a*R or r*A or s*C
    derivation = _set_out_derivation(state, dst_entr, additional_txkey_priv)
    # amount key = H_s(derivation || i)
    amount_key = crypto.derivation_to_scalar(derivation,
                                             state.current_output_index)
    # one-time destination address P = H_s(derivation || i)*G + B
    tx_out_key = crypto.derive_public_key(
        derivation,
        state.current_output_index,
        crypto.decodepoint(dst_entr.addr.spend_public_key),
    )
    del (derivation, additional_txkey_priv)
    state.mem_trace(7, True)

    # Tx header prefix hashing, hmac dst_entr
    tx_out_bin, hmac_vouti = await _set_out_tx_out(state, dst_entr, tx_out_key)
    state.mem_trace(11, True)

    out_pk_dest, out_pk_commitment, ecdh_info_bin = _get_ecdh_info_and_out_pk(
        state=state,
        tx_out_key=tx_out_key,
        amount=dst_entr.amount,
        mask=mask,
        amount_key=amount_key,
    )
    del (dst_entr, mask, amount_key, tx_out_key)
    state.mem_trace(12, True)

    # Incremental hashing of the ECDH info.
    # RctSigBase allows to hash only one of the (ecdh, out_pk) as they are serialized
    # as whole vectors. We choose to hash ECDH first, because it saves state space.
    state.full_message_hasher.set_ecdh(ecdh_info_bin)
    state.mem_trace(13, True)

    # output_pk_commitment is stored to the state as it is used during the signature and hashed to the
    # RctSigBase later. No need to store amount, it was already stored.
    state.output_pk_commitments.append(out_pk_commitment)
    state.mem_trace(14, True)

    from trezor.messages.MoneroTransactionSetOutputAck import (
        MoneroTransactionSetOutputAck, )

    out_pk_bin = bytearray(64)
    utils.memcpy(out_pk_bin, 0, out_pk_dest, 0, 32)
    utils.memcpy(out_pk_bin, 32, out_pk_commitment, 0, 32)

    return MoneroTransactionSetOutputAck(
        tx_out=tx_out_bin,
        vouti_hmac=hmac_vouti,
        rsig_data=_return_rsig_data(rsig),
        out_pk=out_pk_bin,
        ecdh_info=ecdh_info_bin,
    )