From 7b7aa2d9719d9c2206c3e3a50a4d4a2f59fb3fb8 Mon Sep 17 00:00:00 2001 From: Andrew Kozlik Date: Wed, 1 Dec 2021 14:23:18 +0100 Subject: [PATCH] feat(tests): Add device tests for Taproot ownership proofs. --- .../bitcoin/test_getownershipproof.py | 28 ++++++- .../bitcoin/test_signtx_external.py | 73 +++++++++++++++++++ ...42ce9a6c1459aaf5327dcac16c80f9eff1cbf.json | 18 +++++ ...cda3294d80d43b8e508865c1e2d648f6d4dae.json | 32 ++++++++ tests/ui_tests/fixtures.json | 5 +- 5 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 tests/txcache/testnet/4012d9abb675243758b8f2cfd0042ce9a6c1459aaf5327dcac16c80f9eff1cbf.json create mode 100644 tests/txcache/testnet/afde2d41702948e922150825742cda3294d80d43b8e508865c1e2d648f6d4dae.json diff --git a/tests/device_tests/bitcoin/test_getownershipproof.py b/tests/device_tests/bitcoin/test_getownershipproof.py index 3e00beca1..a030bd47b 100644 --- a/tests/device_tests/bitcoin/test_getownershipproof.py +++ b/tests/device_tests/bitcoin/test_getownershipproof.py @@ -23,7 +23,7 @@ from trezorlib.tools import parse_path pytestmark = pytest.mark.skip_t1 -def test_ownership_id(client): +def test_p2wpkh_ownership_id(client): ownership_id = btc.get_ownership_id( client, "Bitcoin", @@ -36,6 +36,19 @@ def test_ownership_id(client): ) +def test_p2tr_ownership_id(client): + ownership_id = btc.get_ownership_id( + client, + "Bitcoin", + parse_path("m/86'/0'/0'/1/0"), + script_type=messages.InputScriptType.SPENDTAPROOT, + ) + assert ( + ownership_id.hex() + == "dc18066224b9e30e306303436dc18ab881c7266c13790350a3fe415e438135ec" + ) + + def test_attack_ownership_id(client): # Multisig with global suffix specification. # Use account numbers 1, 2 and 3 to create a valid multisig, @@ -86,6 +99,19 @@ def test_p2wpkh_ownership_proof(client): ) +def test_p2tr_ownership_proof(client): + ownership_proof, _ = btc.get_ownership_proof( + client, + "Bitcoin", + parse_path("m/86'/0'/0'/1/0"), + script_type=messages.InputScriptType.SPENDTAPROOT, + ) + assert ( + ownership_proof.hex() + == "534c00190001dc18066224b9e30e306303436dc18ab881c7266c13790350a3fe415e438135ec0001406cd08474ea019c9ab4b9b7b76ec03c4dd4db76abc3a460434a91cfc1b190174949eb7111c8e762407730a215421a0da0b5e01f48de62d7ccea0abea046e2a496" + ) + + def test_fake_ownership_id(client): with pytest.raises(TrezorFailure, match="Invalid ownership identifier"): btc.get_ownership_proof( diff --git a/tests/device_tests/bitcoin/test_signtx_external.py b/tests/device_tests/bitcoin/test_signtx_external.py index 2574f523a..6db2925c0 100644 --- a/tests/device_tests/bitcoin/test_signtx_external.py +++ b/tests/device_tests/bitcoin/test_signtx_external.py @@ -58,6 +58,12 @@ TXHASH_3ac32e = bytes.fromhex( TXHASH_df862e = bytes.fromhex( "df862e31da31ff84addd392f6aa89af18978a398ea258e4901ae72894b66679f" ) +TXHASH_afde2d = bytes.fromhex( + "afde2d41702948e922150825742cda3294d80d43b8e508865c1e2d648f6d4dae" +) +TXHASH_4012d9 = bytes.fromhex( + "4012d9abb675243758b8f2cfd0042ce9a6c1459aaf5327dcac16c80f9eff1cbf" +) @pytest.mark.skip_t1 @@ -622,6 +628,73 @@ def test_p2wpkh_with_proof(client): ) +@pytest.mark.skip_t1 +@pytest.mark.setup_client( + mnemonic="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" +) +def test_p2tr_with_proof(client): + # Resulting TXID 48ec6dc7bb772ff18cbce0135fedda7c0e85212c7b2f85a5d0cc7a917d77c48a + + inp1 = messages.TxInputType( + # seed "all all all all all all all all all all all all" + # 86'/1'/2'/0/0 + # tb1pyu3e8expmey3n5mhra64c9lhz8865rftmaedwa7dddxrlktuv6us6snqxg + # afde2d41702948e922150825742cda3294d80d43b8e508865c1e2d648f6d4dae + amount=100892, + prev_hash=TXHASH_afde2d, + prev_index=2, + script_type=messages.InputScriptType.EXTERNAL, + script_pubkey=bytes.fromhex( + "5120272393e4c1de4919d3771f755c17f711cfaa0d2bdf72d777cd6b4c3fd97c66b9" + ), + ownership_proof=bytearray.fromhex( + "534c001900015f6c298a141152b5aef9ef31badea5ceaf9f628a968bed0a14d5ad660761cf1c00014088cb80b8c559d9991c1403eed4ff27717a46ee5d11feb4996ce1f3247504d888e7f04675f6c78961893997b2416431d046439c6740d6c262895d0857e11d2aa0" + ), + ) + inp2 = messages.TxInputType( + address_n=parse_path("86'/1'/0'/0/0"), + amount=6456, + prev_hash=TXHASH_4012d9, + prev_index=0, + script_type=messages.InputScriptType.SPENDTAPROOT, + ) + out1 = messages.TxOutputType( + address="tb1puyst6yj0x3w5z253k5xt0crk2zjy36g0fzhascd4wknxfwv9h9lszyhefk", + amount=100892 + 6456 - 300, + script_type=messages.OutputScriptType.PAYTOADDRESS, + ) + + with client: + client.set_expected_responses( + [ + request_input(0), + request_input(1), + request_output(0), + messages.ButtonRequest(code=B.ConfirmOutput), + messages.ButtonRequest(code=B.SignTx), + request_input(0), + request_input(0), + request_input(1), + request_output(0), + request_input(1), + request_finished(), + ] + ) + _, serialized_tx = btc.sign_tx( + client, "Testnet", [inp1, inp2], [out1], prev_txes=TX_CACHE_TESTNET + ) + + assert ( + serialized_tx.hex() + == "01000000000102ae4d6d8f642d1e5c8608e5b8430dd89432da2c7425081522e9482970412ddeaf0200000000ffffffffbf1cff9e0fc816acdc2753af9a45c1a6e92c04d0cff2b858372475b6abd912400000000000ffffffff0128a2010000000000225120e120bd124f345d412a91b50cb7e07650a448e90f48afd861b575a664b985b97f000140af196d0b64cfe8b5e7a2074b43ec1f11bfdea1df3ecb3b9d6c17e7542d7ca43b698237b5b9788cb49fa758f787311bc79bcbfa4e6046271c682927d7a9c2480900000000" + ) + + # Test corrupted ownership proof. + inp1.ownership_proof[10] ^= 1 + with pytest.raises(TrezorFailure, match="Invalid signature"): + btc.sign_tx(client, "Testnet", [inp1, inp2], [out1], prev_txes=TX_CACHE_TESTNET) + + @pytest.mark.skip_t1 def test_p2wpkh_with_false_proof(client): inp1 = messages.TxInputType( diff --git a/tests/txcache/testnet/4012d9abb675243758b8f2cfd0042ce9a6c1459aaf5327dcac16c80f9eff1cbf.json b/tests/txcache/testnet/4012d9abb675243758b8f2cfd0042ce9a6c1459aaf5327dcac16c80f9eff1cbf.json new file mode 100644 index 000000000..d2acbbe9e --- /dev/null +++ b/tests/txcache/testnet/4012d9abb675243758b8f2cfd0042ce9a6c1459aaf5327dcac16c80f9eff1cbf.json @@ -0,0 +1,18 @@ +{ + "bin_outputs": [ + { + "amount": 6456, + "script_pubkey": "51203b82b2b2a9185315da6f80da5f06d0440d8a5e1457fa93387c2d919c86ec8786" + } + ], + "inputs": [ + { + "prev_hash": "afde2d41702948e922150825742cda3294d80d43b8e508865c1e2d648f6d4dae", + "prev_index": 1, + "script_sig": "", + "sequence": 4294967293 + } + ], + "lock_time": 0, + "version": 1 +} diff --git a/tests/txcache/testnet/afde2d41702948e922150825742cda3294d80d43b8e508865c1e2d648f6d4dae.json b/tests/txcache/testnet/afde2d41702948e922150825742cda3294d80d43b8e508865c1e2d648f6d4dae.json new file mode 100644 index 000000000..c0f70a70f --- /dev/null +++ b/tests/txcache/testnet/afde2d41702948e922150825742cda3294d80d43b8e508865c1e2d648f6d4dae.json @@ -0,0 +1,32 @@ +{ + "bin_outputs": [ + { + "amount": 0, + "script_pubkey": "6a0d61686f6a20746170726f6f7465" + }, + { + "amount": 6700, + "script_pubkey": "00145258d3b3544267f4baaa1e9e68651344c0c55888" + }, + { + "amount": 100892, + "script_pubkey": "5120272393e4c1de4919d3771f755c17f711cfaa0d2bdf72d777cd6b4c3fd97c66b9" + } + ], + "inputs": [ + { + "prev_hash": "40d6800280e1aac808978fb1e85a62bf725de507ea0e3d224239f855efc2771b", + "prev_index": 0, + "script_sig": "", + "sequence": 4294967295 + }, + { + "prev_hash": "6f1b399a2f0291ed7383c9110a886194126f465279d65b0da20f8ce14cbf5f12", + "prev_index": 1, + "script_sig": "", + "sequence": 4294967295 + } + ], + "lock_time": 0, + "version": 1 +} diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json index aa8eb1f70..527f51c8d 100644 --- a/tests/ui_tests/fixtures.json +++ b/tests/ui_tests/fixtures.json @@ -112,7 +112,9 @@ "bitcoin-test_getownershipproof.py::test_confirm_ownership_proof": "a79fd462b99f5ffc755917b6d06d3c5a3061c971649cdfa752cbc9ef068e6acf", "bitcoin-test_getownershipproof.py::test_confirm_ownership_proof_with_data": "b03f5a83ce82847ebe61a78a823fced50a597e7a1269357100745aef1301716d", "bitcoin-test_getownershipproof.py::test_fake_ownership_id": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1", -"bitcoin-test_getownershipproof.py::test_ownership_id": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1", +"bitcoin-test_getownershipproof.py::test_p2tr_ownership_id": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1", +"bitcoin-test_getownershipproof.py::test_p2tr_ownership_proof": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1", +"bitcoin-test_getownershipproof.py::test_p2wpkh_ownership_id": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1", "bitcoin-test_getownershipproof.py::test_p2wpkh_ownership_proof": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1", "bitcoin-test_getpublickey.py::test_get_public_node[Bitcoin-76067358-path0-xpub6BiVtCpG9fQPx-40a56ca3": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1", "bitcoin-test_getpublickey.py::test_get_public_node[Bitcoin-76067358-path1-xpub6BiVtCpG9fQQR-1abafc98": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1", @@ -279,6 +281,7 @@ "bitcoin-test_signtx_external.py::test_p2pkh_presigned": "8dd8089941ceb0d82c9425c69d54240f99e3ae7932ef24acd49313d28389b683", "bitcoin-test_signtx_external.py::test_p2pkh_with_proof": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1", "bitcoin-test_signtx_external.py::test_p2tr_external_presigned": "d4855cb0ec8bbb713d3bb27d2b08cf42e2128bae06b2be385f44a107d457ad6d", +"bitcoin-test_signtx_external.py::test_p2tr_with_proof": "d6723e2243bc38231ec4eb9ed63afd39610460c0d859b4c576b12db1f7915d02", "bitcoin-test_signtx_external.py::test_p2wpkh_in_p2sh_presigned": "a5a48f7d133331109339d1dbd417d31f64e58859742263d472cdff8c3ea8e7e1", "bitcoin-test_signtx_external.py::test_p2wpkh_in_p2sh_with_proof": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1", "bitcoin-test_signtx_external.py::test_p2wpkh_presigned": "4608478b1d61415cf0ec93a0ea4397c35d17a91d4b6d25e9c024b77330e398eb",