def test_sig_seal(self): mst = ubinascii.unhexlify( b"ca3bbe08a178a4508c3992a47ba775799e7626a365ed136e803fe5f2df2ce01c" ) st = State(None) st.last_step = st.STEP_SIGN st.opening_key = mst st.current_input_index = 3 mg_buff = [ '0b', '02fe9ee789007254215b41351109f186620624a3c1ad2ba89628194528672adf04f900ebf9ad3b0cc1ac9ae1f03167f74d6e04175df5001c91d09d29dbefd6bc0b', '021d46f6db8a349caca48a4dfee155b9dee927d0f25cdf5bcd724358c611b47906de6cedad47fd26070927f3954bcaf7a0e126699bf961ca4e8124abefe8aaeb05', '02ae933994effe2b348b09bfab783bf9adb58b09659d8f5bd058cca252d763b600541807dcb0ea9fe253e59f23ce36cc811d627acae5e2abdc00b7ed155f3e6b0f', '0203dd7138c7378444fe3c1b1572a351f88505aeab2d9f8ed4a8f67d66e76983072d8ae6e496b3953a8603543c2dc64749ee15fe3575e4505b502bfe696f06690e', '0287b572b6c096bc11a8c10fe1fc4ba2085633f8e1bdd2e39df8f46c9bf733ca068261d8006f22ee2bfaf4366e26d42b00befdddd9058a5c87a0f39c757f121909', '021e2ea38aa07601e07a3d7623a97e68d3251525304d2a748548c7b46d07c20b0c78506b19cae49d569d0a8c4979c74f7d8d19f7e595d307ddf00faf3d8f621c0d', '0214f758c8fb4a521a1e3d25b9fb535974f6aab1c1dda5988e986dda7e17140909a7b7bdb3d5e17a2ebd5deb3530d10c6f5d6966f525c1cbca408059949ff65304', '02f707c4a37066a692986ddfdd2ca71f68c6f45a956d45eaf6e8e7a2e5272ac3033eb26ca2b55bf86e90ab8ddcdbad88a82ded88deb552614190440169afcee004', '02edb8a5b8cc02a2e03b95ea068084ae2496f21d4dfd0842c63836137e37047b06d5a0160994396c98630d8b47878e9c18fea4fb824588c143e05c4b18bfea2301', '02aa59c2ef76ac97c261279a1c6ed3724d66a437fe8df0b85e8858703947a2b10f04e49912a0626c09849c3b4a3ea46166cd909b9fd561257730c91cbccf4abe07', '02c64a98c59c4a3d7c583de65404c5a54b350a25011dfca70cd84e3f6e570428026236028fce31bfd8d9fc5401867ab5349eb0859c65df05b380899a7bdfee9003', '03da465e27f7feec31353cb668f0e8965391f983b06c0684b35b00af38533603', ] mg_buff = [ubinascii.unhexlify(x) for x in mg_buff] mg_buff_b = list(mg_buff) mg_res = step_09_sign_input._protect_signature(st, mg_buff) iv = offloading_keys.key_signature(mst, st.current_input_index, True)[:12] key = offloading_keys.key_signature(mst, st.current_input_index, False) cipher = chacha20poly1305(key, iv) ciphertext = cipher.encrypt(b"".join(mg_buff_b)) ciphertext += cipher.finish() self.assertEqual(b"".join(mg_res), ciphertext) cipher = chacha20poly1305(key, iv) ciphertext = b"".join(mg_res) exp_tag, ciphertext = ciphertext[-16:], ciphertext[:-16] plaintext = cipher.decrypt(ciphertext) tag = cipher.finish() self.assertEqual(tag, exp_tag) self.assertEqual(plaintext, b"".join(mg_buff_b))
async def init_transaction( state: State, address_n: list, network_type: int, tsx_data: MoneroTransactionData, keychain, ) -> MoneroTransactionInitAck: from apps.monero.signing import offloading_keys from apps.common import paths await paths.validate_path(state.ctx, misc.validate_full_path, keychain, address_n, CURVE) state.creds = misc.get_creds(keychain, address_n, network_type) state.client_version = tsx_data.client_version or 0 if state.client_version == 0: raise ValueError("Client version not supported") state.fee = state.fee if state.fee > 0 else 0 state.tx_priv = crypto.random_scalar() state.tx_pub = crypto.scalarmult_base(state.tx_priv) state.mem_trace(1) state.input_count = tsx_data.num_inputs state.output_count = len(tsx_data.outputs) state.progress_total = 4 + 3 * state.input_count + state.output_count state.progress_cur = 0 # Ask for confirmation await confirms.require_confirm_transaction(state.ctx, state, tsx_data, state.creds.network_type) state.creds.address = None state.creds.network_type = None gc.collect() state.mem_trace(3) # Basic transaction parameters state.output_change = tsx_data.change_dts state.mixin = tsx_data.mixin state.fee = tsx_data.fee state.account_idx = tsx_data.account state.last_step = state.STEP_INIT if tsx_data.hard_fork: state.hard_fork = tsx_data.hard_fork # Ensure change is correct _check_change(state, tsx_data.outputs) # At least two outpus are required, this applies also for sweep txs # where one fake output is added. See _check_change for more info if state.output_count < 2: raise signing.NotEnoughOutputsError( "At least two outputs are required") _check_rsig_data(state, tsx_data.rsig_data) _check_subaddresses(state, tsx_data.outputs) # Extra processing, payment id _process_payment_id(state, tsx_data) await _compute_sec_keys(state, tsx_data) gc.collect() # Iterative tx_prefix_hash hash computation state.tx_prefix_hasher.uvarint( 2) # current Monero transaction format (RingCT = 2) state.tx_prefix_hasher.uvarint(tsx_data.unlock_time) state.tx_prefix_hasher.uvarint(state.input_count) # ContainerType, size state.mem_trace(10, True) # Final message hasher state.full_message_hasher.init() state.full_message_hasher.set_type_fee(signing.RctType.Bulletproof2, state.fee) # Sub address precomputation if tsx_data.account is not None and tsx_data.minor_indices: _precompute_subaddr(state, tsx_data.account, tsx_data.minor_indices) state.mem_trace(5, True) # HMACs all outputs to disallow tampering. # Each HMAC is then sent alongside the output # and trezor validates it. hmacs = [] for idx in range(state.output_count): c_hmac = await offloading_keys.gen_hmac_tsxdest( state.key_hmac, tsx_data.outputs[idx], idx) hmacs.append(c_hmac) gc.collect() state.mem_trace(6) from trezor.messages.MoneroTransactionInitAck import MoneroTransactionInitAck from trezor.messages.MoneroTransactionRsigData import MoneroTransactionRsigData rsig_data = MoneroTransactionRsigData(offload_type=state.rsig_offload) return MoneroTransactionInitAck(hmacs=hmacs, rsig_data=rsig_data)