From 08afab19f686b0b28b8fd43f3c65a587769f5af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Vejpustek?= Date: Wed, 5 Mar 2025 17:16:34 +0100 Subject: [PATCH] feat(test): test bitcoin-like transaction signing anti-exfil protocol [no changelog] --- tests/device_tests/bitcoin/signtx.py | 7 + tests/device_tests/bitcoin/test_decred.py | 77 +++++++++- tests/device_tests/bitcoin/test_signtx.py | 144 ++++++++++++++++++ .../bitcoin/test_signtx_segwit_native.py | 64 ++++++++ tests/device_tests/zcash/test_sign_tx.py | 70 ++++++++- tests/ui_tests/fixtures.json | 16 ++ 6 files changed, 376 insertions(+), 2 deletions(-) diff --git a/tests/device_tests/bitcoin/signtx.py b/tests/device_tests/bitcoin/signtx.py index 7d19ebaba9..45d3d8cfe3 100644 --- a/tests/device_tests/bitcoin/signtx.py +++ b/tests/device_tests/bitcoin/signtx.py @@ -19,6 +19,13 @@ def request_input(n: int, tx_hash: bytes = None) -> messages.TxRequest: ) +def request_entropy(n: int, nonce: bytes) -> messages.TxRequest: + return messages.TxRequest( + request_type=T.TXENTROPY, + details=messages.TxRequestDetailsType(request_index=n, nonce_commitment=nonce), + ) + + def request_output(n: int, tx_hash: bytes = None) -> messages.TxRequest: return messages.TxRequest( request_type=T.TXOUTPUT, diff --git a/tests/device_tests/bitcoin/test_decred.py b/tests/device_tests/bitcoin/test_decred.py index 78bb1b0c3a..644255f3b6 100644 --- a/tests/device_tests/bitcoin/test_decred.py +++ b/tests/device_tests/bitcoin/test_decred.py @@ -22,7 +22,13 @@ from trezorlib.tools import parse_path from ...common import is_core from ...tx_cache import TxCache -from .signtx import request_finished, request_input, request_meta, request_output +from .signtx import ( + request_entropy, + request_finished, + request_input, + request_meta, + request_output, +) B = messages.ButtonRequestType TX_API = TxCache("Decred Testnet") @@ -428,3 +434,72 @@ def test_decred_multisig_change(client: Client): serialized_tx.hex() == "0100000002d18f50c5e465b727fee4af645350093a8baf7e04ee8ef34ecf0c46f422d2c79a0100000000fffffffff32d5470c1a96b2d9d5215066bd2e254f191d4ce8873d0d096f71c8b5fb8f5480000000000ffffffff02605af40500000000000017a914d4ea4e064d969064ca56a4cede56f7bf6cf62f118700a3e1110000000000001976a9143eb656115197956125365348c542e37b6d3d259988ac00000000000000000200c2eb0b0000000000000000fffffffffc483045022100e7056e4cbc0941a1255e85ab95634fd9ae497be9a8ab0e793d6049f7dd97fa07022031c17d6279211843ea1e0815a1831748aa44c3a3083669293805f8e9e803d78d01473044022039b74918f67afd24f20c0bf4d0ea40637d85005bbb942e7c79e17694e4729e0902202563fa43376220261bb177fc87d637d39809e0ffa4991a1477dbc60a1c2e3997014c69522103defea6f243b97354449bb348446a97e38df2fbed33afc3a7185bfdd26757cfdb2103725d6c5253f2040a9a73af24bcc196bf302d6cc94374dd7197b138e10912670121038924e94fff15302a3fb45ad4fc0ed17178800f0f1c2bdacb1017f4db951aa9f153ae00c2eb0b0000000000000000fffffffffb473044022047afb55f956ef7ac7d4a32e97fe35b3981cd827866ccd76e66b7f186a5338f9302201415cdd987876e8c6c13037e53d055aac467acece41d9357657e4fd8290d914101473044022005cb0efd5889d697e040b2db5d56ef7e1d29fcd20b74a8cc44d670092b6cfaee02202150837c1f5108af8b6cc022bd2d40e54170869ad39b2d1d61c67a47ad21e019014c695221021ef4b5d81f21593071b993bd4d8c564c569a6f84de0d4511135cbc66d8bf7bcd2103f1e53b6e0ff99adf7e8fa826a94bdac83163d8abbc1d19a8d6b88a4af91b9a67210390c8ea70e1f2f60e0052be65183c43bb01b2f02dfa4e448f74e359997f74e6ad53ae" ) + + +@pytest.mark.models(skip="legacy", reason="Not implemented") +def test_anti_exfil(client: Client): + # NOTE: fake input tx used + + inp1 = messages.TxInputType( + # TscqTv1he8MZrV321SfRghw7LFBCJDKB3oz + address_n=parse_path("m/44h/1h/0h/0/0"), + prev_hash=FAKE_TXHASH_4d8acd, + prev_index=1, + amount=200_000_000, + script_type=messages.InputScriptType.SPENDADDRESS, + decred_tree=0, + ) + + out1 = messages.TxOutputType( + address="TscqTv1he8MZrV321SfRghw7LFBCJDKB3oz", + amount=190_000_000, + script_type=messages.OutputScriptType.PAYTOADDRESS, + ) + + with client: + client.set_expected_responses( + [ + request_input(0), + request_output(0), + messages.ButtonRequest(code=B.ConfirmOutput), + (is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)), + messages.ButtonRequest(code=B.FeeOverThreshold), + messages.ButtonRequest(code=B.SignTx), + request_input(0), + request_meta(FAKE_TXHASH_4d8acd), + request_input(0, FAKE_TXHASH_4d8acd), + request_output(0, FAKE_TXHASH_4d8acd), + request_output(1, FAKE_TXHASH_4d8acd), + request_input(0), + request_entropy( + 0, + bytes.fromhex( + "0309f0bcf850a01d36ed5ec89e8cff0ba4801f2a2e631d6e571940e8adbf841499" + ), + ), + request_finished(), + ] + ) + anti_exfil_signatures = btc.sign_tx_new( + client, + "Decred Testnet", + [inp1], + [out1], + prev_txes=TX_API, + use_anti_exfil=True, + entropy_list=[bytes(32)], + ) + + assert anti_exfil_signatures == [ + btc.AntiExfilSignature( + signature=bytes.fromhex( + "d998b0138e90ec207fd268949edafdc8fc53ec73da3459675392841da75b12d975d54857b076650ac6b3b698079f6336c870c57bc6246b77af66a0167701251b" + ), + entropy=bytes.fromhex( + "0000000000000000000000000000000000000000000000000000000000000000" + ), + nonce_commitment=bytes.fromhex( + "0309f0bcf850a01d36ed5ec89e8cff0ba4801f2a2e631d6e571940e8adbf841499" + ), + ) + ] diff --git a/tests/device_tests/bitcoin/test_signtx.py b/tests/device_tests/bitcoin/test_signtx.py index e35c7fc83f..cb3b3fa2ed 100644 --- a/tests/device_tests/bitcoin/test_signtx.py +++ b/tests/device_tests/bitcoin/test_signtx.py @@ -36,6 +36,7 @@ from ...input_flows import ( from ...tx_cache import TxCache from .signtx import ( assert_tx_matches, + request_entropy, request_finished, request_input, request_meta, @@ -1659,3 +1660,146 @@ def test_information_replacement(client: Client): [out1], prev_txes=TX_CACHE_TESTNET, ) + + +@pytest.mark.models(skip="legacy", reason="Not implemented") +def test_anti_exfil(client: Client): + # input tx: 0dac366fd8a67b2a89fbb0d31086e7acded7a5bbf9ef9daa935bc873229ef5b5 + + inp1 = messages.TxInputType( + address_n=parse_path("m/44h/0h/5h/0/9"), # 1H2CRJBrDMhkvCGZMW7T4oQwYbL8eVuh7p + amount=63_988, + prev_hash=TXHASH_0dac36, + prev_index=0, + ) + + out1 = messages.TxOutputType( + address="13Hbso8zgV5Wmqn3uA7h3QVtmPzs47wcJ7", + amount=50_248, + script_type=messages.OutputScriptType.PAYTOADDRESS, + ) + + with client: + client.set_expected_responses( + [ + request_input(0), + request_output(0), + messages.ButtonRequest(code=B.ConfirmOutput), + (is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)), + messages.ButtonRequest(code=B.SignTx), + request_input(0), + request_meta(TXHASH_0dac36), + request_input(0, TXHASH_0dac36), + request_output(0, TXHASH_0dac36), + request_output(1, TXHASH_0dac36), + request_input(0), + request_output(0), + request_entropy( + 0, + bytes.fromhex( + "021b55a31b3140751f4fad664e209877543b6c037ab87edef429c19ed1933015e6" + ), + ), + request_finished(), + ] + ) + + anti_exfil_signatures = btc.sign_tx_new( + client, + "Bitcoin", + [inp1], + [out1], + prev_txes=TX_CACHE_MAINNET, + use_anti_exfil=True, + entropy_list=[bytes(32)], + ) + + assert anti_exfil_signatures == [ + btc.AntiExfilSignature( + signature=bytes.fromhex( + "fa787ddb2d69e4fb42294317aeca89aa4a3cc31294f447cd6e0771eea10aa1801f7d3684853ee6f61ffe22bfe0370e0d6c96a88812e62d3d5cda8c7e6ef8b5b1" + ), + entropy=bytes.fromhex( + "0000000000000000000000000000000000000000000000000000000000000000" + ), + nonce_commitment=bytes.fromhex( + "021b55a31b3140751f4fad664e209877543b6c037ab87edef429c19ed1933015e6" + ), + ) + ] + + +@pytest.mark.models(skip="legacy", reason="Not implemented") +def test_anti_exfil_attack_1(client: Client): + # This test verifies that the host detects if the signature returned by the device is invalid. + + # input tx: 0dac366fd8a67b2a89fbb0d31086e7acded7a5bbf9ef9daa935bc873229ef5b5 + inp1 = messages.TxInputType( + address_n=parse_path("m/44h/0h/5h/0/9"), # 1H2CRJBrDMhkvCGZMW7T4oQwYbL8eVuh7p + amount=63_988, + prev_hash=TXHASH_0dac36, + prev_index=0, + ) + + out1 = messages.TxOutputType( + address="13Hbso8zgV5Wmqn3uA7h3QVtmPzs47wcJ7", + amount=50_248, + script_type=messages.OutputScriptType.PAYTOADDRESS, + ) + + def attack_processor(msg): + msg.serialized.signature = bytes(64) + return msg + + with client, pytest.raises(ValueError, match="Invalid signature for index 0"): + # with client: + # Set up attack processors + client.set_filter(messages.TxRequest, attack_processor) + + _ = btc.sign_tx_new( + client, + "Bitcoin", + [inp1], + [out1], + prev_txes=TX_CACHE_MAINNET, + use_anti_exfil=True, + entropy_list=[bytes(32)], + ) + + +@pytest.mark.models(skip="legacy", reason="Not implemented") +def test_anti_exfil_attack_2(client: Client): + # This test verifies that the host detects if the device asks for a entropy but not provides nonce commitment. + + # input tx: 0dac366fd8a67b2a89fbb0d31086e7acded7a5bbf9ef9daa935bc873229ef5b5 + inp1 = messages.TxInputType( + address_n=parse_path("m/44h/0h/5h/0/9"), # 1H2CRJBrDMhkvCGZMW7T4oQwYbL8eVuh7p + amount=63_988, + prev_hash=TXHASH_0dac36, + prev_index=0, + ) + + out1 = messages.TxOutputType( + address="13Hbso8zgV5Wmqn3uA7h3QVtmPzs47wcJ7", + amount=50_248, + script_type=messages.OutputScriptType.PAYTOADDRESS, + ) + + def attack_processor(msg): + msg.details.nonce_commitment = None + return msg + + with client, pytest.raises( + ValueError, match="Nonce commitment for index 0 not provided" + ): + client.set_filter(messages.TxRequest, attack_processor) + + _ = btc.sign_tx_new( + client, + "Bitcoin", + [inp1], + [out1], + prev_txes=TX_CACHE_MAINNET, + use_anti_exfil=True, + entropy_list=[bytes(32)], + ) diff --git a/tests/device_tests/bitcoin/test_signtx_segwit_native.py b/tests/device_tests/bitcoin/test_signtx_segwit_native.py index 0c779c777e..79a7545738 100644 --- a/tests/device_tests/bitcoin/test_signtx_segwit_native.py +++ b/tests/device_tests/bitcoin/test_signtx_segwit_native.py @@ -26,6 +26,7 @@ from ...input_flows import InputFlowConfirmAllWarnings from ...tx_cache import TxCache from .signtx import ( assert_tx_matches, + request_entropy, request_finished, request_input, request_meta, @@ -832,3 +833,66 @@ def test_multisig_mismatch_inputs_single(client: Client): hash_link="https://tbtc1.trezor.io/api/tx/d3b2ec2a540363ffbb231c6cf0a311ec84c8404c7ec2819c146dfb90a69c593a", tx_hex="01000000000102b5da4da56cabc57097abb376af10e843c3f2c8427c612acfc88baaa39d2d021c0100000000ffffffffb5da4da56cabc57097abb376af10e843c3f2c8427c612acfc88baaa39d2d021c0200000000ffffffff0250c300000000000017a9147a55d61848e77ca266e79a39bfc85c580a6426c987e022020000000000220020733ecfbbe7e47a74dde6c7645b60cdf627e90a585cde7733bc7fdaf9fe30b3740247304402207076385a688713bd380d7e01858254161c11981a0f549098c77ab8afbaec38b40220713854182527e3f32e6910b7a4c5154969039e665bdec0ab4e12e2d3a9543e65012103adc58245cf28406af0ef5cc24b8afba7f1be6c72f279b642d85c48798685f86203004730440220096cf4bff1590e005ff86cf10462b320b9b0eccfc45b8ea4badd276ad9cc536702207502c0dc037f64c58fde74925b4593dcd842d76085538083b6450bf9e73384420147512103505f0d82bbdd251511591b34f36ad5eea37d3220c2b81a1189084431ddb3aa3d2103adc58245cf28406af0ef5cc24b8afba7f1be6c72f279b642d85c48798685f86252ae00000000", ) + + +@pytest.mark.models(skip="legacy", reason="Not implemented") +def test_anti_exfil(client: Client): + inp1 = messages.TxInputType( + address_n=parse_path("m/49h/1h/0h/1/0"), + # 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX + amount=123_456_789, + prev_hash=TXHASH_20912f, + prev_index=0, + script_type=messages.InputScriptType.SPENDP2SHWITNESS, + ) + out1 = messages.TxOutputType( + address="tb1qqzv60m9ajw8drqulta4ld4gfx0rdh82un5s65s", + amount=123_456_789 - 11_000, + script_type=messages.OutputScriptType.PAYTOADDRESS, + ) + with client: + client.set_expected_responses( + [ + request_input(0), + request_output(0), + messages.ButtonRequest(code=B.ConfirmOutput), + (is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)), + messages.ButtonRequest(code=B.SignTx), + request_input(0), + request_meta(TXHASH_20912f), + request_input(0, TXHASH_20912f), + request_output(0, TXHASH_20912f), + request_output(1, TXHASH_20912f), + request_input(0), + request_entropy( + 0, + bytes.fromhex( + "031b25a130a4ef74a9dc9224c3203a1b81fffa0f7ad8550ed6eb702dc610b3b80c" + ), + ), + request_finished(), + ] + ) + anti_exfil_signatures = btc.sign_tx_new( + client, + "Testnet", + [inp1], + [out1], + prev_txes=TX_API_TESTNET, + use_anti_exfil=True, + entropy_list=[bytes(32)], + ) + + assert anti_exfil_signatures == [ + btc.AntiExfilSignature( + signature=bytes.fromhex( + "e594458850cda408cd8d65f90494bfece139f389e66ca0f8c45d4fdaf9b363af48f7608c2e7de857a3d94469686cfb83d2838d73afe4e7f921cc2e86da46e018" + ), + entropy=bytes.fromhex( + "0000000000000000000000000000000000000000000000000000000000000000" + ), + nonce_commitment=bytes.fromhex( + "031b25a130a4ef74a9dc9224c3203a1b81fffa0f7ad8550ed6eb702dc610b3b80c" + ), + ) + ] diff --git a/tests/device_tests/zcash/test_sign_tx.py b/tests/device_tests/zcash/test_sign_tx.py index d689c8af96..93694586b3 100644 --- a/tests/device_tests/zcash/test_sign_tx.py +++ b/tests/device_tests/zcash/test_sign_tx.py @@ -22,7 +22,12 @@ from trezorlib.exceptions import TrezorFailure from trezorlib.tools import parse_path from ...common import is_core -from ..bitcoin.signtx import request_finished, request_input, request_output +from ..bitcoin.signtx import ( + request_entropy, + request_finished, + request_input, + request_output, +) B = messages.ButtonRequestType @@ -551,3 +556,66 @@ def test_spend_multisig(client: Client): serialized_tx.hex() == "050000800a27a726b4d0d6c2000000000000000001a372ba233da275280170a7b00a6b60b51fbae4bdf936a9a91b9a7970c1681b4300000000fdfd0000483045022100d1f91921391ca4a985cbe080ce8be71f1b8ceba6049151bffe7dc6cc27a4a4d80220082fb171f7536779cd216f0508e0205039b2f20988d05455dac9bc22bc71300501473044022058bb0b1ac0d6b62b6f86bdb32879e9240369387282e73a96cb6fbeba56f5493e02206dabb42fc4ce4f5d97bc641f353e7351949695d8e6383764e76eebe572cc33fc014c69522103725d6c5253f2040a9a73af24bcc196bf302d6cc94374dd7197b138e10912670121038924e94fff15302a3fb45ad4fc0ed17178800f0f1c2bdacb1017f4db951aa9f12102aae8affd0eb8e1181d665daef4de1828f23053c548ec9bafc3a787f558aa014153aeffffffff0168cf0e00000000001976a914548cb80e45b1d36312fe0cb075e5e337e3c54cef88ac000000" ) + + +@pytest.mark.models(skip="legacy", reason="Not implemented") +def test_anti_exfil(client: Client): + inp1 = messages.TxInputType( + # tmBMyeJebzkP5naji8XUKqLyL1NDwNkgJFt + address_n=parse_path("m/44h/1h/0h/0/9"), + amount=4_154_120, + prev_hash=TXHASH_f9231f, + prev_index=0, + ) + + out1 = messages.TxOutputType( + # m/44h/1h/0h/0/0 + address="tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu", + amount=4_154_120 - 19_400, + script_type=messages.OutputScriptType.PAYTOADDRESS, + ) + + with client: + client.set_expected_responses( + [ + request_input(0), + request_output(0), + messages.ButtonRequest(code=B.ConfirmOutput), + (is_core(client), messages.ButtonRequest(code=B.ConfirmOutput)), + messages.ButtonRequest(code=B.SignTx), + request_input(0), + request_entropy( + 0, + bytes.fromhex( + "038571129568dfe3d5b4d38aa3f162ce1285f53b5652c49ef48ef2c94674c29dc6" + ), + ), + request_finished(), + ] + ) + + anti_exfil_signatures = btc.sign_tx_new( + client, + "Zcash Testnet", + [inp1], + [out1], + version=5, + version_group_id=VERSION_GROUP_ID, + branch_id=BRANCH_ID, + user_anti_exfil=True, + entropy_list=[bytes(32)], + ) + + assert anti_exfil_signatures == [ + btc.AntiExfilSignature( + signature=bytes.fromhex( + "d8014ab713494b098b2201170dafff07cf5d9cd42d4aa743e5fd282074a6358f10d700caea729a19d20ca0a0de740d160e785b3dbc2ab8a6ebc2f4968a5442e4" + ), + entropy=bytes.fromhex( + "0000000000000000000000000000000000000000000000000000000000000000" + ), + nonce_commitment=bytes.fromhex( + "038571129568dfe3d5b4d38aa3f162ce1285f53b5652c49ef48ef2c94674c29dc6" + ), + ) + ] diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json index 49fb019984..14202ed712 100644 --- a/tests/ui_tests/fixtures.json +++ b/tests/ui_tests/fixtures.json @@ -4019,6 +4019,7 @@ "T2T1_en_bitcoin-test_bgold.py::test_send_p2sh_witness_change": "cb0e7759881c691c31e6af7a90f1b068d04a7e7e6c007085a4b2af1eedc5c583", "T2T1_en_bitcoin-test_dash.py::test_send_dash": "0a398a7e8b0affbc7393a1a1cede11bb4be61687be63db9b4393e74385f103f9", "T2T1_en_bitcoin-test_dash.py::test_send_dash_dip2_input": "4fdefc93094efee762db81b966f31dde57ed2b8018b55450de08abc11469132a", +"T2T1_en_bitcoin-test_decred.py::test_anti_exfil": "04227a8922b5f3085d16030e4df68dea8a130f0b566fe73d7cbe93dc85f0b6c0", "T2T1_en_bitcoin-test_decred.py::test_decred_multisig_change": "20997c9c1263a28e16bf9b4b46360a854e606edf2b1f266bb4e621a58b38115e", "T2T1_en_bitcoin-test_decred.py::test_purchase_ticket_decred": "8c458d69ce5f85f973386567e2f8597f5792d812b0d5507be22732564868d2cb", "T2T1_en_bitcoin-test_decred.py::test_send_decred": "04227a8922b5f3085d16030e4df68dea8a130f0b566fe73d7cbe93dc85f0b6c0", @@ -4311,6 +4312,9 @@ "T2T1_en_bitcoin-test_signmessage.py::test_signmessage_pagination[utf_text]": "4ce16bc9bca3ae902c5292efaa848f5fe0e406133fa3b916e96d060ba52a4bc5", "T2T1_en_bitcoin-test_signmessage.py::test_signmessage_pagination_trailing_newline": "2f990b8d0e1bae6e0b0918884a36850cc69830830e047a7ebfd6969db9d2252e", "T2T1_en_bitcoin-test_signmessage.py::test_signmessage_path_warning": "0f13376f2e27715a1cea78454a6fe59ecc3f8e42beaa8f7932caf62a01a54d49", +"T2T1_en_bitcoin-test_signtx.py::test_anti_exfil": "cd7bb2b45401fdf8e5adcdb694aca8e9f1cd9254aba7f3676b734990ff3ccbbf", +"T2T1_en_bitcoin-test_signtx.py::test_anti_exfil_attack_1": "cd7bb2b45401fdf8e5adcdb694aca8e9f1cd9254aba7f3676b734990ff3ccbbf", +"T2T1_en_bitcoin-test_signtx.py::test_anti_exfil_attack_2": "cd7bb2b45401fdf8e5adcdb694aca8e9f1cd9254aba7f3676b734990ff3ccbbf", "T2T1_en_bitcoin-test_signtx.py::test_attack_change_input_address": "85495cf2eb840bed17279da62c748e5a5b290941a0cd37581a55dfd11b9c17fe", "T2T1_en_bitcoin-test_signtx.py::test_attack_change_outputs": "f8d0add4bd2e9e559e16ca4bb49656680cce48cbf0f76a2f2fbf2e8415b51d88", "T2T1_en_bitcoin-test_signtx.py::test_attack_modify_change_address": "93f156763ab2ce7afdeec8368b03ea041c684f8d2b8c1f3ef1e4ac450fdfc5be", @@ -4436,6 +4440,7 @@ "T2T1_en_bitcoin-test_signtx_segwit.py::test_send_p2sh[True]": "a3bc6104454c3fa5f28e5a2156b9ad498f02a61b53fa57db9a4510b057ab913d", "T2T1_en_bitcoin-test_signtx_segwit.py::test_send_p2sh_change": "1916b6719237e65af0b87fd481913a57dae4ee0e582bbf28826dabb3f31ae3af", "T2T1_en_bitcoin-test_signtx_segwit.py::test_testnet_segwit_big_amount": "b7998e39496e3e45d306a3b05bdaf2e5002d89dda5c9fd4053c771d3a75990dd", +"T2T1_en_bitcoin-test_signtx_segwit_native.py::test_anti_exfil": "9e46e66b94f09edd3755c46ff56390805da810bc940706be59ca0aa31d0840eb", "T2T1_en_bitcoin-test_signtx_segwit_native.py::test_multisig_mismatch_inputs_single": "230a79fa1c844c9e55f7034d20bb93f4ae304d117071fbc2ee64382bf4fd2cba", "T2T1_en_bitcoin-test_signtx_segwit_native.py::test_send_both": "61fbd0d709d7b82e419222a96f9f91d15a057f1662893faf6c973dafd181f4fd", "T2T1_en_bitcoin-test_signtx_segwit_native.py::test_send_multisig_1": "17a3e850718edfa0a125ff520076dd6382d3bb5d908eb7b3a3ca4bc197e3d56f", @@ -5438,6 +5443,7 @@ "T2T1_en_tezos-test_sign_tx.py::test_tezos_smart_contract_transfer_to_contract": "53277bbff8dd0cfc963a9caec361e4d714d449dcf973acbd9af3807bfe51af6e", "T2T1_en_webauthn-test_msg_webauthn.py::test_add_remove": "97ee18cd5d7ad234fd9470af75be7b45cbb2f790897ca37fe76c0c835309c882", "T2T1_en_webauthn-test_u2f_counter.py::test_u2f_counter": "f740248e1b4e4289052807569a0a1defdd88d8fc0532a47850da0ea26277276d", +"T2T1_en_zcash-test_sign_tx.py::test_anti_exfil": "667a0a9ceb7527fba7b6a631d5be771921785076897425c1b30cad36eddc1bea", "T2T1_en_zcash-test_sign_tx.py::test_external_presigned": "2492bd16ea82738cec9778d3afed746d21da8181d7e2782b701fa240dffbb42a", "T2T1_en_zcash-test_sign_tx.py::test_one_two": "1b8ab64581bdb61d2937911eba35a08514d3ef5e7d2b8c3ebea643c911ef0655", "T2T1_en_zcash-test_sign_tx.py::test_refuse_replacement_tx": "9b99080f761b1ce5c9d0223b6c1fde56d0822d77ba25896bc714358cdc91056c", @@ -13240,6 +13246,9 @@ "T3B1_en_bitcoin-test_signmessage.py::test_signmessage_pagination[utf_nospace]": "5bdd4a576dff7806900e87e7d54aef46b9691993d764088a08bc23b57027d920", "T3B1_en_bitcoin-test_signmessage.py::test_signmessage_pagination[utf_text]": "7e80afd3c74e0ccb77fc226890df74109a9fcbb63858918e86c17edc5125779e", "T3B1_en_bitcoin-test_signmessage.py::test_signmessage_path_warning": "b0495fbca071511743036265b15f9eb242bda7d0bcea0c691a14ae3e597d8fec", +"T3B1_en_bitcoin-test_signtx.py::test_anti_exfil": "89d4ecf2bc8362b03253c5ef675ecbd0e1358276a0e554e3c62e1ff4f7ad211a", +"T3B1_en_bitcoin-test_signtx.py::test_anti_exfil_attack_1": "89d4ecf2bc8362b03253c5ef675ecbd0e1358276a0e554e3c62e1ff4f7ad211a", +"T3B1_en_bitcoin-test_signtx.py::test_anti_exfil_attack_2": "89d4ecf2bc8362b03253c5ef675ecbd0e1358276a0e554e3c62e1ff4f7ad211a", "T3B1_en_bitcoin-test_signtx.py::test_attack_change_input_address": "c2ad390cbd29d23443b951d661385158cc848212a3cc3ccc4f67edac04b24c56", "T3B1_en_bitcoin-test_signtx.py::test_attack_change_outputs": "fd3fe5a7f8a1124fb923d0a67bfa062fe7ec7bed4e06ae2e8b75d12cca58eaad", "T3B1_en_bitcoin-test_signtx.py::test_attack_modify_change_address": "20085bbcedc7e6d42e00002f85a2e2da6f9cff35c5e761576d9ac9f46cf979ef", @@ -13361,6 +13370,7 @@ "T3B1_en_bitcoin-test_signtx_segwit.py::test_send_p2sh[True]": "b5d8c092ed234cf627b5c9354f537a982d35cc4443d9a5027db74623986ee7d8", "T3B1_en_bitcoin-test_signtx_segwit.py::test_send_p2sh_change": "d8950a5dd2970fdbe2268674d1a2bcd6ef774a2edeed4c0f501904fb39224006", "T3B1_en_bitcoin-test_signtx_segwit.py::test_testnet_segwit_big_amount": "73f4ddc65db5c984d11451f59824c5113644cba304cae13031145de186aecb43", +"T3B1_en_bitcoin-test_signtx_segwit_native.py::test_anti_exfil": "c8c7351e9e54fd2b4c1d0ba9f5e1bdb53f78b31896dc0ba7b19294009298af4c", "T3B1_en_bitcoin-test_signtx_segwit_native.py::test_multisig_mismatch_inputs_single": "bbcd94709ef9ff3e9ae19a1e7ef41694cd41dfc4c44ee4a8b81787832ec136aa", "T3B1_en_bitcoin-test_signtx_segwit_native.py::test_send_both": "5833c910d0f5a15fa5c4ad266523c5d0a42d9301023f0fd82a23fe117bc965ba", "T3B1_en_bitcoin-test_signtx_segwit_native.py::test_send_multisig_1": "4c687a399249e38678b47e281b1c57b207bc829ba0c38823e811f4793168fbc9", @@ -14323,6 +14333,7 @@ "T3B1_en_tezos-test_sign_tx.py::test_tezos_smart_contract_transfer_to_contract": "8849dd6d70cc9109c84e2716396f96c390c39857361b63c5f494a96af91cf5fa", "T3B1_en_webauthn-test_msg_webauthn.py::test_add_remove": "540214b367b638082b9beb67e492b59b5ac523b5dedb972ace9b4caca974ef6e", "T3B1_en_webauthn-test_u2f_counter.py::test_u2f_counter": "49f01fce798fe9d5a22cea12d7f276fb91cd77c04087b1dd2c3e37a6106cc350", +"T3B1_en_zcash-test_sign_tx.py::test_anti_exfil": "ba3b17241d241d9c4109163b9630421819f8ed1bdca4f67441d94c816a46c288", "T3B1_en_zcash-test_sign_tx.py::test_external_presigned": "6bc1f0b265163f105b4b084e518a23e6a248849f3141d82dbe25538a43d69883", "T3B1_en_zcash-test_sign_tx.py::test_one_two": "7ddbc26901a06270c93e55ceee3365472cafc2ffb4b7cc87b9fb2af980a1b9a3", "T3B1_en_zcash-test_sign_tx.py::test_refuse_replacement_tx": "49a73b70cadcaad8baec45e6c64ee910071db73fae8c39dfa590fea95f749448", @@ -21966,6 +21977,9 @@ "T3T1_en_bitcoin-test_signmessage.py::test_signmessage_pagination[utf_nospace]": "649fa459e9d566c82f1e03b1e8a8075cc06f04653a343231c48a2ae549275f91", "T3T1_en_bitcoin-test_signmessage.py::test_signmessage_pagination[utf_text]": "81d10945f6721c6dcdaa4e5738b32a17981041ba5c3feaf078ecddff808c6dd4", "T3T1_en_bitcoin-test_signmessage.py::test_signmessage_path_warning": "a49442a30d3e0b449f0d0aadeb98ed82048b39018906b56c588f7f0ea470850d", +"T3T1_en_bitcoin-test_signtx.py::test_anti_exfil": "2749648676858ef457541f0aeb2df1f01fcf2a2ced3ea2b175869c809d887979", +"T3T1_en_bitcoin-test_signtx.py::test_anti_exfil_attack_1": "2749648676858ef457541f0aeb2df1f01fcf2a2ced3ea2b175869c809d887979", +"T3T1_en_bitcoin-test_signtx.py::test_anti_exfil_attack_2": "2749648676858ef457541f0aeb2df1f01fcf2a2ced3ea2b175869c809d887979", "T3T1_en_bitcoin-test_signtx.py::test_attack_change_input_address": "4e244806460590ffb19eab5a920e9840c50d3553b3683e62da045ee95166cbf8", "T3T1_en_bitcoin-test_signtx.py::test_attack_change_outputs": "1abb4fa643ca070ac7469b037dc99f46d64448d23de07672126248711c6259e5", "T3T1_en_bitcoin-test_signtx.py::test_attack_modify_change_address": "9a9b9e95401ac9d20d186936b875fcce358c6647b6a425546c48c41dc03b57ce", @@ -22087,6 +22101,7 @@ "T3T1_en_bitcoin-test_signtx_segwit.py::test_send_p2sh[True]": "3e4257a114e84678d87228b754dc0b915f8b3855d9045f66752aa9be97e49afc", "T3T1_en_bitcoin-test_signtx_segwit.py::test_send_p2sh_change": "119d1c978825cf97682cd73a105df95d0e56ecc5685095db85b141490bb86c60", "T3T1_en_bitcoin-test_signtx_segwit.py::test_testnet_segwit_big_amount": "27ebe88e942fda401d29bff04d20c3d960939841faf324ede646744bddd9c11f", +"T3T1_en_bitcoin-test_signtx_segwit_native.py::test_anti_exfil": "10c2fb45ae956218a54d98a76603ba88705c1e2449cfb7a7752bd129ab384ed9", "T3T1_en_bitcoin-test_signtx_segwit_native.py::test_multisig_mismatch_inputs_single": "a649345253be88aa6dbd4f5f4f7554396b3b7f7c0d5d6572afae74b5554a50ef", "T3T1_en_bitcoin-test_signtx_segwit_native.py::test_send_both": "3fa63703ee3e28712c8a47c05e5447fdaf3c9216a8b989b010eeb89fc7e9f545", "T3T1_en_bitcoin-test_signtx_segwit_native.py::test_send_multisig_1": "869b7fb1a274726ef5a597a8f3ce1ec8df15af8c9ffb8916c2fd6eb72f4de2bf", @@ -23053,6 +23068,7 @@ "T3T1_en_tezos-test_sign_tx.py::test_tezos_smart_contract_transfer_to_contract": "28e75ce0a5038595368f320911924509c728454160f1ac8e684facbb2ea86edf", "T3T1_en_webauthn-test_msg_webauthn.py::test_add_remove": "275c22fe43e6d9ac591c3551c77864ecb948cead0d6bee01dc05e62a85e99483", "T3T1_en_webauthn-test_u2f_counter.py::test_u2f_counter": "3570492cd8f28fd890fe7f05602220a817d1217ecc54b954a1e5de7d0a89c5f5", +"T3T1_en_zcash-test_sign_tx.py::test_anti_exfil": "849545517154af8a9d31f493424b0dbc9666469e24ab30bf5c25ab5e91d2be58", "T3T1_en_zcash-test_sign_tx.py::test_external_presigned": "8b8fa1e4d7fdd246b07a399943dbf77704317eb717d657f942fca2d1b0720ebb", "T3T1_en_zcash-test_sign_tx.py::test_one_two": "28f87c95a6b1d177336ba8825850061befa3bc7d8186cf2d74a7b2cb83232186", "T3T1_en_zcash-test_sign_tx.py::test_refuse_replacement_tx": "d1c743332c28d4d5495d5f81be802906982c5bbaef9ac79787321730e3f29726",