diff --git a/src/apps/monero/protocol/signing/step_04_input_vini.py b/src/apps/monero/protocol/signing/step_04_input_vini.py index 242c07f38..f279c3fa7 100644 --- a/src/apps/monero/protocol/signing/step_04_input_vini.py +++ b/src/apps/monero/protocol/signing/step_04_input_vini.py @@ -1,7 +1,7 @@ """ -Set tx.vin[i] for incremental tx prefix hash computation. -After sorting by key images on host. -Hashes pseudo_out to the final_message. +This step successively hashes the inputs in the order +received in the previous step. +Also hashes `pseudo_out` to the final_message. """ from .state import State @@ -10,9 +10,19 @@ from apps.monero.protocol import hmac_encryption_keys from apps.monero.xmr import common, crypto +if False: + from trezor.messages.MoneroTransactionSourceEntry import ( + MoneroTransactionSourceEntry, + ) + async def input_vini( - state: State, src_entr, vini_bin, hmac, pseudo_out, pseudo_out_hmac + state: State, + src_entr: MoneroTransactionSourceEntry, + vini_bin: bytes, + vini_hmac: bytes, + pseudo_out: bytes, + pseudo_out_hmac: bytes, ): from trezor.messages.MoneroTransactionInputViniAck import ( MoneroTransactionInputViniAck, @@ -21,43 +31,39 @@ async def input_vini( await confirms.transaction_step( state.ctx, state.STEP_VINI, state.current_input_index + 1, state.input_count ) - if state.current_input_index >= state.input_count: raise ValueError("Too many inputs") state.current_input_index += 1 # HMAC(T_in,i || vin_i) - hmac_vini = await hmac_encryption_keys.gen_hmac_vini( + hmac_vini_comp = await hmac_encryption_keys.gen_hmac_vini( state.key_hmac, src_entr, vini_bin, state.source_permutation[state.current_input_index], ) - if not common.ct_equal(hmac_vini, hmac): + if not common.ct_equal(hmac_vini_comp, vini_hmac): raise ValueError("HMAC is not correct") - hash_vini_pseudo_out( - state, vini_bin, state.current_input_index, pseudo_out, pseudo_out_hmac - ) + """ + Incremental hasing of tx.vin[i] + """ + state.tx_prefix_hasher.buffer(vini_bin) + + # in monero version >= 8 pseudo outs were moved to a different place + # use_bulletproofs implies version >= 8 + if state.use_simple_rct and not state.use_bulletproof: + _hash_vini_pseudo_out(state, pseudo_out, pseudo_out_hmac) - # TODO check input count? return MoneroTransactionInputViniAck() -def hash_vini_pseudo_out( - state: State, vini_bin, inp_idx, pseudo_out=None, pseudo_out_hmac=None -): +def _hash_vini_pseudo_out(state: State, pseudo_out: bytes, pseudo_out_hmac: bytes): """ - Incremental hasing of tx.vin[i] and pseudo output + Incremental hasing of pseudo output. Only applicable for simple rct. """ - state.tx_prefix_hasher.buffer(vini_bin) - - # Pseudo_out incremental hashing - applicable only in simple rct - if not state.use_simple_rct or state.use_bulletproof: - return - - idx = state.source_permutation[inp_idx] + idx = state.source_permutation[state.current_input_index] pseudo_out_hmac_comp = crypto.compute_hmac( hmac_encryption_keys.hmac_key_txin_comm(state.key_hmac, idx), pseudo_out ) diff --git a/src/apps/monero/protocol/signing/step_05_all_in_set.py b/src/apps/monero/protocol/signing/step_05_all_inputs_set.py similarity index 85% rename from src/apps/monero/protocol/signing/step_05_all_in_set.py rename to src/apps/monero/protocol/signing/step_05_all_inputs_set.py index 3fa0f960b..3111fb78c 100644 --- a/src/apps/monero/protocol/signing/step_05_all_in_set.py +++ b/src/apps/monero/protocol/signing/step_05_all_inputs_set.py @@ -1,5 +1,6 @@ """ -All inputs set. Defining rsig parameters. +All inputs set. Defining range signature parameters. +If in the applicable offloading mode, generate commitment masks. """ from trezor import utils @@ -10,12 +11,9 @@ from apps.monero.xmr import crypto -async def all_in_set(state: State, rsig_data): # todo: rsig_data not used? - """ - If in the applicable offloading mode, generate commitment masks. - """ +async def all_inputs_set(state: State): state.mem_trace(0) - # state.state.input_all_done() todo check if needed? + await confirms.transaction_step(state.ctx, state.STEP_ALL_IN) from trezor.messages.MoneroTransactionAllInputsSetAck import ( @@ -31,6 +29,7 @@ async def all_in_set(state: State, rsig_data): # todo: rsig_data not used? # Simple range proof offloading # Generate random commitment masks that sum to the input mask sum. + # TODO review together with step 6 tmp_buff = bytearray(32) rsig_data.mask = bytearray(32 * state.output_count) state.sumout = crypto.sc_init(0) diff --git a/src/apps/monero/protocol/signing/step_06_set_out1.py b/src/apps/monero/protocol/signing/step_06_set_output.py similarity index 68% rename from src/apps/monero/protocol/signing/step_06_set_out1.py rename to src/apps/monero/protocol/signing/step_06_set_output.py index a1e2e7e4d..cdac66573 100644 --- a/src/apps/monero/protocol/signing/step_06_set_out1.py +++ b/src/apps/monero/protocol/signing/step_06_set_output.py @@ -1,6 +1,6 @@ """ -Set destination entry one by one. -Computes destination stealth address, amount key, range proof + HMAC, out_pk, ecdh_info. +Output destinations are streamed one by one. +Computes destination one-time address, amount key, range proof + HMAC, out_pk, ecdh_info. """ import gc @@ -14,7 +14,7 @@ from apps.monero.xmr import common, crypto -async def set_out1(state: State, dst_entr, dst_entr_hmac, rsig_data=None): +async def set_output(state: State, dst_entr, dst_entr_hmac, rsig_data): state.mem_trace(0, True) mods = utils.unimport_begin() @@ -23,46 +23,32 @@ async def set_out1(state: State, dst_entr, dst_entr_hmac, rsig_data=None): ) state.mem_trace(1) - if ( - state.current_input_index + 1 != state.input_count - ): # todo check state.state.is_input_vins() - needed? - raise ValueError("Invalid number of inputs") - state.current_output_index += 1 state.mem_trace(2, True) + await _validate(state, dst_entr, dst_entr_hmac) - if dst_entr.amount <= 0 and state.tx.version <= 1: - raise ValueError("Destination with wrong amount: %s" % dst_entr.amount) - - # HMAC check of the destination - dst_entr_hmac_computed = await hmac_encryption_keys.gen_hmac_tsxdest( - state.key_hmac, dst_entr, state.current_output_index - ) - if not common.ct_equal(dst_entr_hmac, dst_entr_hmac_computed): - raise ValueError("HMAC invalid") - del (dst_entr_hmac, dst_entr_hmac_computed) - state.mem_trace(3, True) - - # First output - tx prefix hasher - size of the container + # 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, state.current_output_index, dst_entr.amount, rsig_data - ) + # Range proof first, memory intensive TODO range proof, TODO mask + rsig, mask = _range_proof(state, dst_entr.amount, rsig_data) utils.unimport_end(mods) state.mem_trace(6, True) - # Amount key, tx out key - additional_txkey_priv = _set_out1_additional_keys(state, dst_entr) - derivation = _set_out1_derivation(state, dst_entr, additional_txkey_priv) + # 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, @@ -72,13 +58,12 @@ async def set_out1(state: State, dst_entr, dst_entr_hmac, rsig_data=None): state.mem_trace(7, True) # Tx header prefix hashing, hmac dst_entr - tx_out_bin, hmac_vouti = await _set_out1_tx_out(state, dst_entr, tx_out_key) + tx_out_bin, hmac_vouti = await _set_out_tx_out(state, dst_entr, tx_out_key) state.mem_trace(11, True) - # Out_pk, ecdh_info - out_pk, ecdh_info_bin = _set_out1_ecdh( + out_pk, ecdh_info_bin = _get_ecdh_info_and_out_pk( state=state, - dest_pub_key=tx_out_key, + tx_out_key=tx_out_key, amount=dst_entr.amount, mask=mask, amount_key=amount_key, @@ -88,12 +73,12 @@ async def set_out1(state: State, dst_entr, dst_entr_hmac, rsig_data=None): # Incremental hashing of the ECDH info. # RctSigBase allows to hash only one of the (ecdh, out_pk) as they are serialized - # as whole vectors. Hashing ECDH info saves state space. + # 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 is stored to the state as it is used during the signature and hashed to the - # RctSigBase later. + # RctSigBase later. No need to store amount, it was already stored. state.output_pk_masks.append(out_pk.mask) state.mem_trace(14, True) @@ -108,14 +93,32 @@ async def set_out1(state: State, dst_entr, dst_entr_hmac, rsig_data=None): return MoneroTransactionSetOutputAck( tx_out=tx_out_bin, vouti_hmac=hmac_vouti, - rsig_data=_return_rsig_data(state, rsig), + rsig_data=_return_rsig_data(rsig), # TODO out_pk=out_pk_bin, ecdh_info=ecdh_info_bin, ) -async def _set_out1_tx_out(state: State, dst_entr, tx_out_key): - # Manual serialization of TxOut(0, TxoutToKey(key)) +async def _validate(state: State, dst_entr, dst_entr_hmac): + if state.current_input_index + 1 != state.input_count: + raise ValueError("Invalid number of inputs") + if dst_entr.amount <= 0: + raise ValueError("Destination with wrong amount: %s" % dst_entr.amount) + + # HMAC check of the destination + dst_entr_hmac_computed = await hmac_encryption_keys.gen_hmac_tsxdest( + state.key_hmac, dst_entr, state.current_output_index + ) + if not common.ct_equal(dst_entr_hmac, dst_entr_hmac_computed): + raise ValueError("HMAC invalid") + del (dst_entr_hmac, dst_entr_hmac_computed) + state.mem_trace(3, True) + + +async def _set_out_tx_out(state: State, dst_entr, tx_out_key): + """ + Manually serializes TxOut(0, TxoutToKey(key)) and calculates hmac. + """ tx_out_bin = bytearray(34) tx_out_bin[0] = 0 # amount varint tx_out_bin[1] = 2 # variant code TxoutToKey @@ -126,7 +129,7 @@ async def _set_out1_tx_out(state: State, dst_entr, tx_out_key): state.tx_prefix_hasher.buffer(tx_out_bin) state.mem_trace(9, True) - # Hmac dest_entr. + # Hmac dst_entr hmac_vouti = await hmac_encryption_keys.gen_hmac_vouti( state.key_hmac, dst_entr, tx_out_bin, state.current_output_index ) @@ -134,7 +137,7 @@ async def _set_out1_tx_out(state: State, dst_entr, tx_out_key): return tx_out_bin, hmac_vouti -def _range_proof(state, idx, amount, rsig_data=None): +def _range_proof(state, amount, rsig_data=None): # TODO Heeeere """ Computes rangeproof and related information - out_sk, out_pk, ecdh_info. In order to optimize incremental transaction build, the mask computation is changed compared @@ -148,8 +151,8 @@ def _range_proof(state, idx, amount, rsig_data=None): """ from apps.monero.xmr import ring_ct + idx = state.current_output_index mask = _get_out_mask(state, idx) - state.output_amounts.append(amount) provided_rsig = ( rsig_data.rsig if rsig_data and rsig_data.rsig and len(rsig_data.rsig) > 0 @@ -235,7 +238,7 @@ def _range_proof(state, idx, amount, rsig_data=None): return rsig, mask -def _return_rsig_data(state, rsig): +def _return_rsig_data(rsig): if rsig is None: return None from trezor.messages.MoneroTransactionRsigData import MoneroTransactionRsigData @@ -246,27 +249,23 @@ def _return_rsig_data(state, rsig): return MoneroTransactionRsigData(rsig=rsig) -def _set_out1_ecdh(state: State, dest_pub_key, amount, mask, amount_key): - from apps.monero.xmr import ring_ct +def _get_ecdh_info_and_out_pk(state: State, tx_out_key, amount, mask, amount_key): + """ + Calculates the Pedersen commitment C = aG + bH and returns it as CtKey. + Also encodes the two items - `mask` and `amount` - into ecdh info, + so the recipient is able to reconstruct the commitment. + """ from apps.monero.xmr.serialize_messages.ct_keys import CtKey - # Mask sum out_pk = CtKey( - dest=crypto.encodepoint(dest_pub_key), + dest=crypto.encodepoint(tx_out_key), mask=crypto.encodepoint(crypto.gen_commitment(mask, amount)), ) state.sumout = crypto.sc_add(state.sumout, mask) state.output_sk_masks.append(mask) - # ECDH masking - from apps.monero.xmr.serialize_messages.tx_ecdh import EcdhTuple - from apps.monero.xmr.sub.recode import recode_ecdh - - ecdh_info = EcdhTuple(mask=mask, amount=crypto.sc_init(amount)) - ring_ct.ecdh_encode_into( - ecdh_info, ecdh_info, derivation=crypto.encodeint(amount_key) - ) - recode_ecdh(ecdh_info, encode=True) + # masking of mask and amount + ecdh_info = _ecdh_encode(mask, amount, crypto.encodeint(amount_key)) # Manual ECDH info serialization ecdh_info_bin = bytearray(64) @@ -277,26 +276,74 @@ def _set_out1_ecdh(state: State, dest_pub_key, amount, mask, amount_key): return out_pk, ecdh_info_bin -def _set_out1_additional_keys(state: State, dst_entr): - additional_txkey = None - additional_txkey_priv = None - if state.need_additional_txkeys: - additional_txkey_priv = crypto.random_scalar() +def _ecdh_encode(mask, amount, amount_key): + """ + Output recipients need be able to reconstruct the amount commitments. + This means the blinding factor `mask` and `amount` must be communicated + to the receiver somehow. + + The mask and amount are stored as: + - mask = mask + Hs(amount_key) + - amount = amount + Hs(Hs(amount_key)) + Because the receiver can derive the `amount_key` they can + easily derive both mask and amount as well. + """ + from apps.monero.xmr.serialize_messages.tx_ecdh import EcdhTuple - if dst_entr.is_subaddress: - additional_txkey = crypto.scalarmult( - crypto.decodepoint(dst_entr.addr.spend_public_key), - additional_txkey_priv, - ) - else: - additional_txkey = crypto.scalarmult_base(additional_txkey_priv) + ecdh_info = EcdhTuple(mask=mask, amount=crypto.sc_init(amount)) + amount_key_hash_single = crypto.hash_to_scalar(amount_key) + amount_key_hash_double = crypto.hash_to_scalar( + crypto.encodeint(amount_key_hash_single) + ) + + ecdh_info.mask = crypto.sc_add(ecdh_info.mask, amount_key_hash_single) + ecdh_info.amount = crypto.sc_add(ecdh_info.amount, amount_key_hash_double) + return _recode_ecdh(ecdh_info) + + +def _recode_ecdh(ecdh_info): + """ + In-place ecdh_info tuple recoding + """ + ecdh_info.mask = crypto.encodeint(ecdh_info.mask) + ecdh_info.amount = crypto.encodeint(ecdh_info.amount) + return ecdh_info + + +def _set_out_additional_keys(state: State, dst_entr): + """ + If needed (decided in step 1), additional tx keys are calculated + for this particular output. + """ + if not state.need_additional_txkeys: + return None + + additional_txkey_priv = crypto.random_scalar() - state.additional_tx_public_keys.append(crypto.encodepoint(additional_txkey)) - state.additional_tx_private_keys.append(additional_txkey_priv) + if dst_entr.is_subaddress: + # R=r*D + additional_txkey = crypto.scalarmult( + crypto.decodepoint(dst_entr.addr.spend_public_key), additional_txkey_priv + ) + else: + # R=r*G + additional_txkey = crypto.scalarmult_base(additional_txkey_priv) + + state.additional_tx_public_keys.append(crypto.encodepoint(additional_txkey)) + state.additional_tx_private_keys.append(additional_txkey_priv) return additional_txkey_priv -def _set_out1_derivation(state: State, dst_entr, additional_txkey_priv): +def _set_out_derivation(state: State, dst_entr, additional_txkey_priv): + """ + 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.sub.addr import addr_eq change_addr = state.change_address() @@ -308,11 +355,10 @@ def _set_out1_derivation(state: State, dst_entr, additional_txkey_priv): else: # sending to the recipient; derivation = r*A (or s*C in the subaddress scheme) - deriv_priv = ( - additional_txkey_priv - if dst_entr.is_subaddress and state.need_additional_txkeys - else state.tx_priv - ) + 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 ) diff --git a/src/apps/monero/protocol/signing/step_07_all_out1_set.py b/src/apps/monero/protocol/signing/step_07_all_outputs_set.py similarity index 81% rename from src/apps/monero/protocol/signing/step_07_all_out1_set.py rename to src/apps/monero/protocol/signing/step_07_all_outputs_set.py index 8eb3b41e3..b3b043ad1 100644 --- a/src/apps/monero/protocol/signing/step_07_all_out1_set.py +++ b/src/apps/monero/protocol/signing/step_07_all_outputs_set.py @@ -1,7 +1,7 @@ """ -All outputs were set in this phase. Computes additional public keys (if needed), tx.extra and -transaction prefix hash. -Adds additional public keys to the tx.extra +All outputs were set in this phase. This step serializes tx pub keys +into the tx extra field and then hashes it into the prefix hash. +The prefix hash is then complete. """ import gc @@ -12,49 +12,23 @@ from apps.monero.xmr import crypto -async def all_out1_set(state: State): - print("07") - +async def all_outputs_set(state: State): state.mem_trace(0) - # state.state.set_output_done() todo needed? await confirms.transaction_step(state.ctx, state.STEP_ALL_OUT) state.mem_trace(1) - if state.current_output_index + 1 != state.output_count: - raise ValueError("Invalid out num") - - # Test if \sum Alpha == \sum A - if state.use_simple_rct: - state.assrt(crypto.sc_eq(state.sumout, state.sumpouts_alphas)) - - # Fee test - if state.fee != (state.summary_inputs_money - state.summary_outs_money): - raise ValueError( - "Fee invalid %s vs %s, out: %s" - % ( - state.fee, - state.summary_inputs_money - state.summary_outs_money, - state.summary_outs_money, - ) - ) + _validate(state) state.mem_trace(2) - # Set public key to the extra - # Not needed to remove - extra is clean _set_tx_extra(state) + # tx public keys not needed anymore state.additional_tx_public_keys = None - + state.tx_pub = None gc.collect() state.mem_trace(3) - if state.summary_outs_money > state.summary_inputs_money: - raise ValueError( - "Transaction inputs money (%s) less than outputs money (%s)" - % (state.summary_inputs_money, state.summary_outs_money) - ) - - # Hashing transaction prefix + # Completes the transaction prefix hash by including extra _set_tx_prefix(state) extra_b = state.tx.extra state.tx = None @@ -80,7 +54,36 @@ async def all_out1_set(state: State): ) +def _validate(state: State): + if state.current_output_index + 1 != state.output_count: + raise ValueError("Invalid out num") + + # Test if \sum Alpha == \sum A + if state.use_simple_rct: + state.assrt(crypto.sc_eq(state.sumout, state.sumpouts_alphas)) + + # Fee test + if state.fee != (state.summary_inputs_money - state.summary_outs_money): + raise ValueError( + "Fee invalid %s vs %s, out: %s" + % ( + state.fee, + state.summary_inputs_money - state.summary_outs_money, + state.summary_outs_money, + ) + ) + + if state.summary_outs_money > state.summary_inputs_money: + raise ValueError( + "Transaction inputs money (%s) less than outputs money (%s)" + % (state.summary_inputs_money, state.summary_outs_money) + ) + + def _set_tx_extra(state: State): + """ + Sets tx public keys into transaction's extra. + """ state.tx.extra = _add_tx_pub_key_to_extra(state.tx.extra, state.tx_pub) if state.need_additional_txkeys: @@ -90,6 +93,11 @@ def _set_tx_extra(state: State): def _set_tx_prefix(state: State): + """ + Adds `extra` to the tx_prefix_hash, which is the last needed item, + so the tx_prefix_hash is now complete and can be incorporated + into full_message_hash. + """ # Serializing "extra" type as BlobType. # uvarint(len(extra)) || extra state.tx_prefix_hasher.uvarint(len(state.tx.extra)) @@ -98,7 +106,6 @@ def _set_tx_prefix(state: State): state.tx_prefix_hash = state.tx_prefix_hasher.get_digest() state.tx_prefix_hasher = None - # Hash message to the final_message state.full_message_hasher.set_message(state.tx_prefix_hash) @@ -112,14 +119,14 @@ def _add_tx_pub_key_to_extra(tx_extra, pub_key): return tx_extra + to_add -def _add_additional_tx_pub_keys_to_extra(tx_extra, pub_enc): +def _add_additional_tx_pub_keys_to_extra(tx_extra, pub_keys): """ Adds all additional tx public keys to the extra buffer """ from apps.monero.xmr.serialize import int_serialize # format: variant_tag (0x4) | array len varint | 32B | 32B | ... - num_keys = len(pub_enc) + num_keys = len(pub_keys) len_size = int_serialize.uvarint_size(num_keys) buffer = bytearray(1 + len_size + 32 * num_keys) @@ -128,7 +135,7 @@ def _add_additional_tx_pub_keys_to_extra(tx_extra, pub_enc): offset = 1 + len_size for idx in range(num_keys): - buffer[offset : offset + 32] = pub_enc[idx] + buffer[offset : offset + 32] = pub_keys[idx] offset += 32 tx_extra += buffer diff --git a/src/apps/monero/protocol/signing/step_09_sign_input.py b/src/apps/monero/protocol/signing/step_09_sign_input.py index 56bc6cbe1..d989a6e07 100644 --- a/src/apps/monero/protocol/signing/step_09_sign_input.py +++ b/src/apps/monero/protocol/signing/step_09_sign_input.py @@ -152,9 +152,7 @@ async def sign_input( state.mem_trace(5) # Encode - from apps.monero.xmr.sub.recode import recode_msg - - mgs = recode_msg([mg]) + mgs = _recode_msg([mg]) cout = None gc.collect() @@ -175,3 +173,25 @@ async def sign_input( return MoneroTransactionSignInputAck( signature=misc.dump_msg_gc(mgs[0], preallocate=488), cout=cout ) + + +def _recode_msg(mgs, encode=True): + """ + Recodes MGs signatures from raw forms to bytearrays so it works with serialization + :param mgs: + :param encode: if true encodes to byte representation, otherwise decodes from byte representation + :return: + """ + recode_int = crypto.encodeint if encode else crypto.decodeint + recode_point = crypto.encodepoint if encode else crypto.decodepoint + + for idx in range(len(mgs)): + mgs[idx].cc = recode_int(mgs[idx].cc) + if hasattr(mgs[idx], "II") and mgs[idx].II: + for i in range(len(mgs[idx].II)): + mgs[idx].II[i] = recode_point(mgs[idx].II[i]) + + for i in range(len(mgs[idx].ss)): + for j in range(len(mgs[idx].ss[i])): + mgs[idx].ss[i][j] = recode_int(mgs[idx].ss[i][j]) + return mgs diff --git a/src/apps/monero/sign_tx.py b/src/apps/monero/sign_tx.py index 6d0158b8a..02c341286 100644 --- a/src/apps/monero/sign_tx.py +++ b/src/apps/monero/sign_tx.py @@ -81,21 +81,21 @@ async def sign_tx_dispatch(state, msg): ) elif msg.MESSAGE_WIRE_TYPE == MessageType.MoneroTransactionAllInputsSetRequest: - from apps.monero.protocol.signing import step_05_all_in_set + from apps.monero.protocol.signing import step_05_all_inputs_set return ( - await step_05_all_in_set.all_in_set(state, msg.rsig_data), + await step_05_all_inputs_set.all_inputs_set(state), (MessageType.MoneroTransactionSetOutputRequest,), ) elif msg.MESSAGE_WIRE_TYPE == MessageType.MoneroTransactionSetOutputRequest: - from apps.monero.protocol.signing import step_06_set_out1 + from apps.monero.protocol.signing import step_06_set_output dst, dst_hmac, rsig_data = msg.dst_entr, msg.dst_entr_hmac, msg.rsig_data - del (msg) + del msg return ( - await step_06_set_out1.set_out1(state, dst, dst_hmac, rsig_data), + await step_06_set_output.set_output(state, dst, dst_hmac, rsig_data), ( MessageType.MoneroTransactionSetOutputRequest, MessageType.MoneroTransactionAllOutSetRequest, @@ -103,11 +103,11 @@ async def sign_tx_dispatch(state, msg): ) elif msg.MESSAGE_WIRE_TYPE == MessageType.MoneroTransactionAllOutSetRequest: - from apps.monero.protocol.signing import step_07_all_out1_set + from apps.monero.protocol.signing import step_07_all_outputs_set # todo check TrezorTxPrefixHashNotMatchingError return ( - await step_07_all_out1_set.all_out1_set(state), + await step_07_all_outputs_set.all_outputs_set(state), (MessageType.MoneroTransactionMlsagDoneRequest,), ) diff --git a/src/apps/monero/xmr/crypto.py b/src/apps/monero/xmr/crypto.py index 6429de206..5cf353a30 100644 --- a/src/apps/monero/xmr/crypto.py +++ b/src/apps/monero/xmr/crypto.py @@ -455,15 +455,15 @@ def derivation_to_scalar(derivation, output_index): return tcry.xmr_derivation_to_scalar(derivation, output_index) -def derive_public_key(derivation, output_index, base): +def derive_public_key(derivation, output_index, B): """ - H_s(derivation || varint(output_index))G + base + H_s(derivation || varint(output_index))G + B """ - if ge_frombytes_vartime_check(base) != 0: # check some conditions on the point + if ge_frombytes_vartime_check(B) != 0: # check some conditions on the point raise ValueError("derive pub key bad point") - check_ed25519point(base) + check_ed25519point(B) - return tcry.xmr_derive_public_key(derivation, output_index, base) + return tcry.xmr_derive_public_key(derivation, output_index, B) def derive_secret_key(derivation, output_index, base): diff --git a/src/apps/monero/xmr/ring_ct.py b/src/apps/monero/xmr/ring_ct.py index b95f92b8a..9fa2b5cf4 100644 --- a/src/apps/monero/xmr/ring_ct.py +++ b/src/apps/monero/xmr/ring_ct.py @@ -160,19 +160,6 @@ def prove_range_chunked(amount, last_mask=None): # verifies the above sig is created corretly -def ecdh_encode_into(dst, unmasked, derivation=None): - """ - Elliptic Curve Diffie-Helman: encodes and decodes the amount b and mask a - where C= aG + bH - """ - sec1 = crypto.hash_to_scalar(derivation) - sec2 = crypto.hash_to_scalar(crypto.encodeint(sec1)) - - dst.mask = crypto.sc_add(unmasked.mask, sec1) - dst.amount = crypto.sc_add(unmasked.amount, sec2) - return dst - - # # Key image import / export # diff --git a/src/apps/monero/xmr/sub/recode.py b/src/apps/monero/xmr/sub/recode.py deleted file mode 100644 index dabb39e17..000000000 --- a/src/apps/monero/xmr/sub/recode.py +++ /dev/null @@ -1,36 +0,0 @@ -from apps.monero.xmr import crypto - - -def recode_ecdh(ecdh, encode=True): - """ - In-place ecdhtuple recoding - :param ecdh: - :param encode: if true encodes to byte representation, otherwise decodes from byte representation - :return: - """ - recode_int = crypto.encodeint if encode else crypto.decodeint - ecdh.mask = recode_int(ecdh.mask) - ecdh.amount = recode_int(ecdh.amount) - return ecdh - - -def recode_msg(mgs, encode=True): - """ - Recodes MGs signatures from raw forms to bytearrays so it works with serialization - :param mgs: - :param encode: if true encodes to byte representation, otherwise decodes from byte representation - :return: - """ - recode_int = crypto.encodeint if encode else crypto.decodeint - recode_point = crypto.encodepoint if encode else crypto.decodepoint - - for idx in range(len(mgs)): - mgs[idx].cc = recode_int(mgs[idx].cc) - if hasattr(mgs[idx], "II") and mgs[idx].II: - for i in range(len(mgs[idx].II)): - mgs[idx].II[i] = recode_point(mgs[idx].II[i]) - - for i in range(len(mgs[idx].ss)): - for j in range(len(mgs[idx].ss[i])): - mgs[idx].ss[i][j] = recode_int(mgs[idx].ss[i][j]) - return mgs