Example #1
0
 def test_lots_of_inputs(self, client):
     # Tests if device implements serialization of len(inputs) correctly
     # tx 4a7b7e0403ae5607e473949cfa03f09f2cd8b0f404bf99ce10b7303d86280bf7 : 100 UTXO for spending for unit tests
     inputs = []
     for i in range(100):
         inputs.append(
             messages.TxInputType(
                 address_n=parse_path(f"44h/0h/0h/0/{i}"),
                 prev_hash=TXHASH_4a7b7e,
                 prev_index=i,
             ))
     out = messages.TxOutputType(
         address="19dvDdyxxptP9dGvozYe8BP6tgFV9L4jg5",
         amount=100 * 26000 - 15 * 10000,
         script_type=messages.OutputScriptType.PAYTOADDRESS,
     )
     _, serialized_tx = btc.sign_tx(client,
                                    "Bitcoin",
                                    inputs, [out],
                                    prev_txes=TX_CACHE_MAINNET)
     assert (
         tx_hash(serialized_tx).hex() ==
         "f90cdc2224366312be28166e2afe198ece7a60e86e25f5a50f5b14d811713da8")
    def test_spend_coinbase(self, client):
        inp1 = messages.TxInputType(
            address_n=parse_path("44h/1h/0h/0/0"),
            amount=2500278230,
            prev_hash=TXHASH_d6da21,
            prev_index=0,
        )

        out1 = messages.TxOutputType(
            address="mm6FM31rM5Vc3sw5D7kztiBg3jHUzyqF1g",
            amount=2500278230 - 10000,
            script_type=messages.OutputScriptType.PAYTOADDRESS,
        )

        with client:
            client.set_expected_responses([
                request_input(0),
                request_output(0),
                messages.ButtonRequest(code=B.ConfirmOutput),
                messages.ButtonRequest(code=B.SignTx),
                request_input(0),
                request_meta(TXHASH_d6da21),
                request_input(0, TXHASH_d6da21),
                request_output(0, TXHASH_d6da21),
                request_input(0),
                request_output(0),
                request_output(0),
                request_finished(),
            ])
            _, serialized_tx = btc.sign_tx(client,
                                           "Testnet", [inp1], [out1],
                                           prev_txes=TX_CACHE_TESTNET)

        # Accepted by network: tx
        assert (
            tx_hash(serialized_tx).hex() ==
            "cf5a8ad5a4f0211953e0d40d9145d6651f0d90203e52913e780065bd00840da3")
    def test_p2sh(self, client):
        inp1 = messages.TxInputType(
            address_n=parse_path("44h/0h/0h/0/0"),
            amount=400000,
            prev_hash=TXHASH_54aa56,
            prev_index=1,
        )

        out1 = messages.TxOutputType(
            address="3DKGE1pvPpBAgZj94MbCinwmksewUNNYVR",  # p2sh
            amount=400000 - 10000,
            script_type=messages.OutputScriptType.PAYTOSCRIPTHASH,
        )

        with client:
            client.set_expected_responses([
                request_input(0),
                request_output(0),
                messages.ButtonRequest(code=B.ConfirmOutput),
                messages.ButtonRequest(code=B.SignTx),
                request_input(0),
                request_meta(TXHASH_54aa56),
                request_input(0, TXHASH_54aa56),
                request_output(0, TXHASH_54aa56),
                request_output(1, TXHASH_54aa56),
                request_input(0),
                request_output(0),
                request_output(0),
                request_finished(),
            ])
            _, serialized_tx = btc.sign_tx(client,
                                           "Bitcoin", [inp1], [out1],
                                           prev_txes=TX_CACHE_MAINNET)

        assert (
            tx_hash(serialized_tx).hex() ==
            "5042aed319b9f018d693dbf8f3db926ee4ab4dae670a2911625b440a1366f79d")
Example #4
0
    def test_15_of_15(self, client):
        node = btc.get_public_node(
            client, parse_path("48h/0h/1h/0"), coin_name="Bitcoin"
        ).node
        pubs = [proto.HDNodePathType(node=node, address_n=[x]) for x in range(15)]

        signatures = [b""] * 15

        out1 = proto.TxOutputType(
            address="17kTB7qSk3MupQxWdiv5ZU3zcrZc2Azes1",
            amount=10000,
            script_type=proto.OutputScriptType.PAYTOADDRESS,
        )

        for x in range(15):
            multisig = proto.MultisigRedeemScriptType(
                pubkeys=pubs, signatures=signatures, m=15
            )

            inp1 = proto.TxInputType(
                address_n=parse_path(f"48h/0h/1h/0/{x}"),
                prev_hash=TXHASH_6189e3,
                prev_index=1,
                script_type=proto.InputScriptType.SPENDMULTISIG,
                multisig=multisig,
            )

            with client:
                sig, serialized_tx = btc.sign_tx(
                    client, "Bitcoin", [inp1], [out1], prev_txes=TX_API
                )
                signatures[x] = sig[0]

        assert (
            tx_hash(serialized_tx).hex()
            == "3bffdb495711c57b0e2cd4e0dbd0ddbccf28052aa67466eafa2d4f666e797e5f"
        )
Example #5
0
    def test_attack_change_outputs(self, client):
        inp1 = messages.TxInputType(
            address_n=parse_path("44h/0h/0h/0/0"),
            # amount=100000,
            prev_hash=TXHASH_c6be22,
            prev_index=1,
        )

        inp2 = messages.TxInputType(
            address_n=parse_path("44h/0h/0h/0/1"),
            # amount=110000,
            prev_hash=TXHASH_58497a,
            prev_index=1,
        )

        out1 = messages.TxOutputType(
            address="15Jvu3nZNP7u2ipw2533Q9VVgEu2Lu9F2B",
            amount=210000 - 100000 - 10000,
            script_type=messages.OutputScriptType.PAYTOADDRESS,
        )

        out2 = messages.TxOutputType(
            address_n=parse_path("44h/0h/0h/1/0"),
            amount=100000,
            script_type=messages.OutputScriptType.PAYTOADDRESS,
        )

        # Test if the transaction can be signed normally
        _, serialized_tx = btc.sign_tx(client,
                                       "Bitcoin", [inp1, inp2], [out1, out2],
                                       prev_txes=TX_CACHE_MAINNET)

        assert (
            tx_hash(serialized_tx).hex() ==
            "4601b738e1b0f8a7ff9ca5adf0c896fa39dfe8b8ead7ad0d716c98167e8a5d11")

        run_attack = False

        def attack_processor(msg):
            nonlocal run_attack
            if msg.tx.outputs and msg.tx.outputs[0] == out2:
                if not run_attack:
                    run_attack = True
                else:
                    # Sign output with another amount
                    msg.tx.outputs[0].amount = 9999999

            return msg

        # Set up attack processors
        client.set_filter(messages.TxAck, attack_processor)

        with pytest.raises(TrezorFailure,
                           match="Transaction has changed during signing"):
            btc.sign_tx(
                client,
                "Bitcoin",
                [inp1, inp2],
                [out1, out2],
                prev_txes=TX_CACHE_MAINNET,
            )
Example #6
0
    def test_lots_of_change(self, client):
        # Tests if device implements prompting for multiple change addresses correctly

        # tx: c63e24ed820c5851b60c54613fbc4bcb37df6cd49b4c96143e99580a472f79fb
        # index 1: 0.0010 BTC
        # tx: 39a29e954977662ab3879c66fb251ef753e0912223a83d1dcb009111d28265e5
        # index 1: 0.0254 BTC

        inp1 = messages.TxInputType(
            address_n=parse_path("44h/0h/1h/0/0"),
            # amount=100000,
            prev_hash=TXHASH_c63e24,
            prev_index=1,
        )

        inp2 = messages.TxInputType(
            address_n=parse_path("44h/0h/1h/0/1"),
            # amount=2540000,
            prev_hash=TXHASH_39a29e,
            prev_index=1,
        )

        outputs = [
            messages.TxOutputType(
                address="1NwN6UduuVkJi6sw3gSiKZaCY5rHgVXC2h",
                amount=500000,
                script_type=messages.OutputScriptType.PAYTOADDRESS,
            )
        ]

        cnt = 20
        for i in range(cnt):
            out = messages.TxOutputType(
                address_n=parse_path(f"44h/0h/1h/1/{i}"),
                amount=(100000 + 2540000 - 500000 - 39000) // cnt,
                script_type=messages.OutputScriptType.PAYTOADDRESS,
            )
            outputs.append(out)

        request_change_outputs = [request_output(i + 1) for i in range(cnt)]

        with client:
            client.set_expected_responses(
                [
                    request_input(0),
                    request_meta(TXHASH_c63e24),
                    request_input(0, TXHASH_c63e24),
                    request_input(1, TXHASH_c63e24),
                    request_output(0, TXHASH_c63e24),
                    request_output(1, TXHASH_c63e24),
                    request_input(1),
                    request_meta(TXHASH_39a29e),
                    request_input(0, TXHASH_39a29e),
                    request_output(0, TXHASH_39a29e),
                    request_output(1, TXHASH_39a29e),
                    request_output(0),
                    messages.ButtonRequest(code=B.ConfirmOutput),
                ] + request_change_outputs + [
                    messages.ButtonRequest(code=B.SignTx),
                    messages.ButtonRequest(code=B.SignTx),
                    request_input(0),
                    request_input(1),
                    request_output(0),
                ] + request_change_outputs +
                [request_input(0),
                 request_input(1),
                 request_output(0)] + request_change_outputs +
                [request_output(0)] + request_change_outputs +
                [request_finished()])

            _, serialized_tx = btc.sign_tx(client,
                                           "Bitcoin", [inp1, inp2],
                                           outputs,
                                           prev_txes=TX_CACHE_MAINNET)

        assert (
            tx_hash(serialized_tx).hex() ==
            "fae68e4a3a4b0540eb200e2218a6d8465eac469788ccb236e0d5822d105ddde9")
Example #7
0
    def test_two_two(self, client):
        # tx: c6be22d34946593bcad1d2b013e12f74159e69574ffea21581dad115572e031c
        # input 1: 0.0010 BTC
        # tx: 58497a7757224d1ff1941488d23087071103e5bf855f4c1c44e5c8d9d82ca46e
        # input 1: 0.0011 BTC

        inp1 = messages.TxInputType(
            address_n=parse_path("44h/0h/0h/0/0"),
            # amount=100000,
            prev_hash=TXHASH_c6be22,
            prev_index=1,
        )

        inp2 = messages.TxInputType(
            address_n=parse_path("44h/0h/0h/0/1"),
            # amount=110000,
            prev_hash=TXHASH_58497a,
            prev_index=1,
        )

        out1 = messages.TxOutputType(
            address="15Jvu3nZNP7u2ipw2533Q9VVgEu2Lu9F2B",
            amount=210000 - 100000 - 10000,
            script_type=messages.OutputScriptType.PAYTOADDRESS,
        )

        out2 = messages.TxOutputType(
            address_n=parse_path("44h/0h/0h/1/0"),
            amount=100000,
            script_type=messages.OutputScriptType.PAYTOADDRESS,
        )

        with client:
            client.set_expected_responses([
                request_input(0),
                request_meta(TXHASH_c6be22),
                request_input(0, TXHASH_c6be22),
                request_output(0, TXHASH_c6be22),
                request_output(1, TXHASH_c6be22),
                request_input(1),
                request_meta(TXHASH_58497a),
                request_input(0, TXHASH_58497a),
                request_output(0, TXHASH_58497a),
                request_output(1, TXHASH_58497a),
                request_output(0),
                messages.ButtonRequest(code=B.ConfirmOutput),
                request_output(1),
                messages.ButtonRequest(code=B.SignTx),
                request_input(0),
                request_input(1),
                request_output(0),
                request_output(1),
                request_input(0),
                request_input(1),
                request_output(0),
                request_output(1),
                request_output(0),
                request_output(1),
                request_finished(),
            ])
            _, serialized_tx = btc.sign_tx(
                client,
                "Bitcoin",
                [inp1, inp2],
                [out1, out2],
                prev_txes=TX_CACHE_MAINNET,
            )

        # Accepted by network: tx c63e24ed820c5851b60c54613fbc4bcb37df6cd49b4c96143e99580a472f79fb
        # The transaction was produced before Trezor implemented BIP-66, so the signature
        # is now different and txhash doesn't match what is on the blockchain.
        assert (
            tx_hash(serialized_tx).hex() ==
            "6f9775545830731a316a4c2a39515b1890e9c8ab0f9e21e7c6a6ca2c1499116d")
Example #8
0
    def test_one_three_fee(self, client):
        # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
        # input 0: 0.0039 BTC

        inp1 = messages.TxInputType(
            address_n=parse_path("44'/0'/0'/0/0"),
            # amount=390000,
            prev_hash=TXHASH_d5f65e,
            prev_index=0,
        )

        out1 = messages.TxOutputType(
            address="1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1",
            amount=390000 - 80000 - 12000 - 10000,
            script_type=messages.OutputScriptType.PAYTOADDRESS,
        )

        out2 = messages.TxOutputType(
            address="13uaUYn6XAooo88QvAqAVsiVvr2mAXutqP",
            amount=12000,
            script_type=messages.OutputScriptType.PAYTOADDRESS,
        )

        out3 = messages.TxOutputType(
            address_n=parse_path("44'/0'/0'/1/0"),
            amount=80000,
            script_type=messages.OutputScriptType.PAYTOADDRESS,
        )

        with client:
            client.set_expected_responses([
                request_input(0),
                request_meta(TXHASH_d5f65e),
                request_input(0, TXHASH_d5f65e),
                request_input(1, TXHASH_d5f65e),
                request_output(0, TXHASH_d5f65e),
                request_output(0),
                messages.ButtonRequest(code=B.ConfirmOutput),
                request_output(1),
                messages.ButtonRequest(code=B.ConfirmOutput),
                request_output(2),
                messages.ButtonRequest(code=B.SignTx),
                request_input(0),
                request_output(0),
                request_output(1),
                request_output(2),
                request_output(0),
                request_output(1),
                request_output(2),
                request_finished(),
            ])
            _, serialized_tx = btc.sign_tx(
                client,
                "Bitcoin",
                [inp1],
                [out1, out2, out3],
                prev_txes=TX_CACHE_MAINNET,
            )

        assert (
            tx_hash(serialized_tx).hex() ==
            "fedbba83b115725a713c2b1a13db09fd33de582132d520a3f6ff72503ca5da61")
Example #9
0
def test_send_multisig_1(client: Client):
    # NOTE: fake input tx used

    nodes = [
        btc.get_public_node(client,
                            parse_path(f"m/49h/156h/{i}h"),
                            coin_name="Bgold").node for i in range(1, 4)
    ]
    multisig = messages.MultisigRedeemScriptType(nodes=nodes,
                                                 address_n=[1, 0],
                                                 signatures=[b"", b"", b""],
                                                 m=2)

    inp1 = messages.TxInputType(
        address_n=parse_path("m/49h/156h/1h/1/0"),
        prev_hash=FAKE_TXHASH_7f1f6b,
        prev_index=0,
        script_type=messages.InputScriptType.SPENDP2SHWITNESS,
        multisig=multisig,
        amount=1_252_382_934,
    )

    out1 = messages.TxOutputType(
        address="GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe",
        amount=1_252_382_934 - 1_000,
        script_type=messages.OutputScriptType.PAYTOADDRESS,
    )

    with client:
        client.set_expected_responses([
            request_input(0),
            request_output(0),
            messages.ButtonRequest(code=B.ConfirmOutput),
            messages.ButtonRequest(code=B.SignTx),
            request_input(0),
            request_meta(FAKE_TXHASH_7f1f6b),
            request_input(0, FAKE_TXHASH_7f1f6b),
            request_output(0, FAKE_TXHASH_7f1f6b),
            request_output(1, FAKE_TXHASH_7f1f6b),
            request_input(0),
            request_output(0),
            request_input(0),
            request_finished(),
        ])
        signatures, _ = btc.sign_tx(client,
                                    "Bgold", [inp1], [out1],
                                    prev_txes=TX_API)
        # store signature
        inp1.multisig.signatures[0] = signatures[0]
        # sign with third key
        inp1.address_n[2] = H_(3)
        client.set_expected_responses([
            request_input(0),
            request_output(0),
            messages.ButtonRequest(code=B.ConfirmOutput),
            messages.ButtonRequest(code=B.SignTx),
            request_input(0),
            request_meta(FAKE_TXHASH_7f1f6b),
            request_input(0, FAKE_TXHASH_7f1f6b),
            request_output(0, FAKE_TXHASH_7f1f6b),
            request_output(1, FAKE_TXHASH_7f1f6b),
            request_input(0),
            request_output(0),
            request_input(0),
            request_finished(),
        ])
        _, serialized_tx = btc.sign_tx(client,
                                       "Bgold", [inp1], [out1],
                                       prev_txes=TX_API)

    assert (tx_hash(serialized_tx).hex() ==
            "98e87ee2b5254e9346f2768993950dbfc3a3a4bd084983d0fb78337f1deeca3c")
Example #10
0
def test_send_btg_multisig_change(client: Client):
    # NOTE: fake input tx used

    nodes = [
        btc.get_public_node(client,
                            parse_path(f"m/48h/156h/{i}h/0h"),
                            coin_name="Bgold").node for i in range(1, 4)
    ]

    EMPTY_SIGS = [b"", b"", b""]

    def getmultisig(chain, nr, signatures):
        return messages.MultisigRedeemScriptType(nodes=nodes,
                                                 address_n=[chain, nr],
                                                 signatures=signatures,
                                                 m=2)

    inp1 = messages.TxInputType(
        address_n=parse_path("m/48h/156h/3h/0h/0/0"),
        multisig=getmultisig(0, 0, EMPTY_SIGS),
        # 33Ju286QvonBz5N1V754ZekQv4GLJqcc5R
        amount=1_252_382_934,
        prev_hash=FAKE_TXHASH_a63dbe,
        prev_index=0,
        script_type=messages.InputScriptType.SPENDMULTISIG,
    )
    out1 = messages.TxOutputType(
        address="GfDB1tvjfm3bukeoBTtfNqrJVFohS2kCTe",
        amount=24_000,
        script_type=messages.OutputScriptType.PAYTOADDRESS,
    )
    out2 = messages.TxOutputType(
        address_n=parse_path("m/48h/156h/3h/0h/1/0"),
        multisig=getmultisig(1, 0, EMPTY_SIGS),
        script_type=messages.OutputScriptType.PAYTOMULTISIG,
        amount=1_252_382_934 - 24_000 - 1_000,
    )
    with client:
        client.set_expected_responses([
            request_input(0),
            request_output(0),
            messages.ButtonRequest(code=B.ConfirmOutput),
            request_output(1),
            messages.ButtonRequest(code=B.SignTx),
            request_input(0),
            request_meta(FAKE_TXHASH_a63dbe),
            request_input(0, FAKE_TXHASH_a63dbe),
            request_output(0, FAKE_TXHASH_a63dbe),
            request_output(1, FAKE_TXHASH_a63dbe),
            request_input(0),
            request_output(0),
            request_output(1),
            request_finished(),
        ])
        signatures, serialized_tx = btc.sign_tx(client,
                                                "Bgold", [inp1], [out1, out2],
                                                prev_txes=TX_API)

    assert (
        signatures[0].hex() ==
        "3045022100bb9b465d2bd7a22b17adc4d8c4600282cfaced0469969f32a2d85e152a528074022030a3698f460c7c935c284f4ffa97d6e44afc200b0c38319d259d15d3deb7c5ac"
    )

    inp1 = messages.TxInputType(
        address_n=parse_path("m/48h/156h/1h/0h/0/0"),
        multisig=getmultisig(0, 0, [b"", b"", signatures[0]]),
        amount=1_252_382_934,
        prev_hash=FAKE_TXHASH_a63dbe,
        prev_index=0,
        script_type=messages.InputScriptType.SPENDMULTISIG,
    )
    out2.address_n[2] = H_(1)

    with client:
        client.set_expected_responses([
            request_input(0),
            request_output(0),
            messages.ButtonRequest(code=B.ConfirmOutput),
            request_output(1),
            messages.ButtonRequest(code=B.SignTx),
            request_input(0),
            request_meta(FAKE_TXHASH_a63dbe),
            request_input(0, FAKE_TXHASH_a63dbe),
            request_output(0, FAKE_TXHASH_a63dbe),
            request_output(1, FAKE_TXHASH_a63dbe),
            request_input(0),
            request_output(0),
            request_output(1),
            request_finished(),
        ])
        signatures, serialized_tx = btc.sign_tx(client,
                                                "Bgold", [inp1], [out1, out2],
                                                prev_txes=TX_API)

    assert (
        signatures[0].hex() ==
        "30440220093c9b193883cd50e81668eb80efe6f82faf01ea707c16c4c33ce1eb40419ccf02200c81b328991389b53a04fcc091365bcc71c2a5c17f62982240b39f1bdefb91f7"
    )
    assert (tx_hash(serialized_tx).hex() ==
            "e5f0bea13c61bf0d02972bbe66f4ca107abd13803015aa785f013114ecec55b7")