mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-15 00:52:02 +00:00
chore(tests): removing classes from device test files
This commit is contained in:
parent
782f868717
commit
a92d29ddbf
@ -25,35 +25,34 @@ from ...common import MNEMONIC12
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.eos
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgEosGetpublickey:
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_eos_get_public_key(self, client):
|
||||
public_key = get_public_key(
|
||||
client, parse_path("m/44'/194'/0'/0/0"), show_display=True
|
||||
)
|
||||
assert (
|
||||
public_key.wif_public_key
|
||||
== "EOS4u6Sfnzj4Sh2pEQnkXyZQJqH3PkKjGByDCbsqqmyq6PttM9KyB"
|
||||
)
|
||||
assert (
|
||||
public_key.raw_public_key.hex()
|
||||
== "02015fabe197c955036bab25f4e7c16558f9f672f9f625314ab1ec8f64f7b1198e"
|
||||
)
|
||||
public_key = get_public_key(client, parse_path("m/44'/194'/0'/0/1"))
|
||||
assert (
|
||||
public_key.wif_public_key
|
||||
== "EOS5d1VP15RKxT4dSakWu2TFuEgnmaGC2ckfSvQwND7pZC1tXkfLP"
|
||||
)
|
||||
assert (
|
||||
public_key.raw_public_key.hex()
|
||||
== "02608bc2c431521dee0b9d5f2fe34053e15fc3b20d2895e0abda857b9ed8e77a78"
|
||||
)
|
||||
public_key = get_public_key(client, parse_path("m/44'/194'/1'/0/0"))
|
||||
assert (
|
||||
public_key.wif_public_key
|
||||
== "EOS7UuNeTf13nfcG85rDB7AHGugZi4C4wJ4ft12QRotqNfxdV2NvP"
|
||||
)
|
||||
assert (
|
||||
public_key.raw_public_key.hex()
|
||||
== "035588a197bd5a7356e8a702361b2d535c6372f843874bed6617cd1afe1dfcb502"
|
||||
)
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_eos_get_public_key(client):
|
||||
public_key = get_public_key(
|
||||
client, parse_path("m/44'/194'/0'/0/0"), show_display=True
|
||||
)
|
||||
assert (
|
||||
public_key.wif_public_key
|
||||
== "EOS4u6Sfnzj4Sh2pEQnkXyZQJqH3PkKjGByDCbsqqmyq6PttM9KyB"
|
||||
)
|
||||
assert (
|
||||
public_key.raw_public_key.hex()
|
||||
== "02015fabe197c955036bab25f4e7c16558f9f672f9f625314ab1ec8f64f7b1198e"
|
||||
)
|
||||
public_key = get_public_key(client, parse_path("m/44'/194'/0'/0/1"))
|
||||
assert (
|
||||
public_key.wif_public_key
|
||||
== "EOS5d1VP15RKxT4dSakWu2TFuEgnmaGC2ckfSvQwND7pZC1tXkfLP"
|
||||
)
|
||||
assert (
|
||||
public_key.raw_public_key.hex()
|
||||
== "02608bc2c431521dee0b9d5f2fe34053e15fc3b20d2895e0abda857b9ed8e77a78"
|
||||
)
|
||||
public_key = get_public_key(client, parse_path("m/44'/194'/1'/0/0"))
|
||||
assert (
|
||||
public_key.wif_public_key
|
||||
== "EOS7UuNeTf13nfcG85rDB7AHGugZi4C4wJ4ft12QRotqNfxdV2NvP"
|
||||
)
|
||||
assert (
|
||||
public_key.raw_public_key.hex()
|
||||
== "035588a197bd5a7356e8a702361b2d535c6372f843874bed6617cd1afe1dfcb502"
|
||||
)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -25,18 +25,17 @@ from ...common import MNEMONIC12
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.monero
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgMoneroGetaddress:
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_monero_getaddress(self, client):
|
||||
assert (
|
||||
monero.get_address(client, parse_path("m/44h/128h/0h"), show_display=True)
|
||||
== b"4Ahp23WfMrMFK3wYL2hLWQFGt87ZTeRkufS6JoQZu6MEFDokAQeGWmu9MA3GFq1yVLSJQbKJqVAn9F9DLYGpRzRAEXqAXKM"
|
||||
)
|
||||
assert (
|
||||
monero.get_address(client, parse_path("m/44h/128h/1h"), show_display=True)
|
||||
== b"44iAazhoAkv5a5RqLNVyh82a1n3ceNggmN4Ho7bUBJ14WkEVR8uFTe9f7v5rNnJ2kEbVXxfXiRzsD5Jtc6NvBi4D6WNHPie"
|
||||
)
|
||||
assert (
|
||||
monero.get_address(client, parse_path("m/44h/128h/2h"), show_display=True)
|
||||
== b"47ejhmbZ4wHUhXaqA4b7PN667oPMkokf4ZkNdWrMSPy9TNaLVr7vLqVUQHh2MnmaAEiyrvLsX8xUf99q3j1iAeMV8YvSFcH"
|
||||
)
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_monero_getaddress(client):
|
||||
assert (
|
||||
monero.get_address(client, parse_path("m/44h/128h/0h"), show_display=True)
|
||||
== b"4Ahp23WfMrMFK3wYL2hLWQFGt87ZTeRkufS6JoQZu6MEFDokAQeGWmu9MA3GFq1yVLSJQbKJqVAn9F9DLYGpRzRAEXqAXKM"
|
||||
)
|
||||
assert (
|
||||
monero.get_address(client, parse_path("m/44h/128h/1h"), show_display=True)
|
||||
== b"44iAazhoAkv5a5RqLNVyh82a1n3ceNggmN4Ho7bUBJ14WkEVR8uFTe9f7v5rNnJ2kEbVXxfXiRzsD5Jtc6NvBi4D6WNHPie"
|
||||
)
|
||||
assert (
|
||||
monero.get_address(client, parse_path("m/44h/128h/2h"), show_display=True)
|
||||
== b"47ejhmbZ4wHUhXaqA4b7PN667oPMkokf4ZkNdWrMSPy9TNaLVr7vLqVUQHh2MnmaAEiyrvLsX8xUf99q3j1iAeMV8YvSFcH"
|
||||
)
|
||||
|
@ -25,33 +25,32 @@ from ...common import MNEMONIC12
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.monero
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgMoneroGetwatchkey:
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_monero_getwatchkey(self, client):
|
||||
res = monero.get_watch_key(client, parse_path("m/44h/128h/0h"))
|
||||
assert (
|
||||
res.address
|
||||
== b"4Ahp23WfMrMFK3wYL2hLWQFGt87ZTeRkufS6JoQZu6MEFDokAQeGWmu9MA3GFq1yVLSJQbKJqVAn9F9DLYGpRzRAEXqAXKM"
|
||||
)
|
||||
assert (
|
||||
res.watch_key.hex()
|
||||
== "8722520a581e2a50cc1adab4a1692401effd37b0d63b9d9b60fd7f34ea2b950e"
|
||||
)
|
||||
res = monero.get_watch_key(client, parse_path("m/44h/128h/1h"))
|
||||
assert (
|
||||
res.address
|
||||
== b"44iAazhoAkv5a5RqLNVyh82a1n3ceNggmN4Ho7bUBJ14WkEVR8uFTe9f7v5rNnJ2kEbVXxfXiRzsD5Jtc6NvBi4D6WNHPie"
|
||||
)
|
||||
assert (
|
||||
res.watch_key.hex()
|
||||
== "1f70b7d9e86c11b7a5bee883b75c43d6be189c8f812726ea1ecd94b06bb7db04"
|
||||
)
|
||||
res = monero.get_watch_key(client, parse_path("m/44h/128h/2h"))
|
||||
assert (
|
||||
res.address
|
||||
== b"47ejhmbZ4wHUhXaqA4b7PN667oPMkokf4ZkNdWrMSPy9TNaLVr7vLqVUQHh2MnmaAEiyrvLsX8xUf99q3j1iAeMV8YvSFcH"
|
||||
)
|
||||
assert (
|
||||
res.watch_key.hex()
|
||||
== "e0671fbed2c9231fe4f286962862813a4a4d153c793bf5d0e3742119723f3000"
|
||||
)
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_monero_getwatchkey(client):
|
||||
res = monero.get_watch_key(client, parse_path("m/44h/128h/0h"))
|
||||
assert (
|
||||
res.address
|
||||
== b"4Ahp23WfMrMFK3wYL2hLWQFGt87ZTeRkufS6JoQZu6MEFDokAQeGWmu9MA3GFq1yVLSJQbKJqVAn9F9DLYGpRzRAEXqAXKM"
|
||||
)
|
||||
assert (
|
||||
res.watch_key.hex()
|
||||
== "8722520a581e2a50cc1adab4a1692401effd37b0d63b9d9b60fd7f34ea2b950e"
|
||||
)
|
||||
res = monero.get_watch_key(client, parse_path("m/44h/128h/1h"))
|
||||
assert (
|
||||
res.address
|
||||
== b"44iAazhoAkv5a5RqLNVyh82a1n3ceNggmN4Ho7bUBJ14WkEVR8uFTe9f7v5rNnJ2kEbVXxfXiRzsD5Jtc6NvBi4D6WNHPie"
|
||||
)
|
||||
assert (
|
||||
res.watch_key.hex()
|
||||
== "1f70b7d9e86c11b7a5bee883b75c43d6be189c8f812726ea1ecd94b06bb7db04"
|
||||
)
|
||||
res = monero.get_watch_key(client, parse_path("m/44h/128h/2h"))
|
||||
assert (
|
||||
res.address
|
||||
== b"47ejhmbZ4wHUhXaqA4b7PN667oPMkokf4ZkNdWrMSPy9TNaLVr7vLqVUQHh2MnmaAEiyrvLsX8xUf99q3j1iAeMV8YvSFcH"
|
||||
)
|
||||
assert (
|
||||
res.watch_key.hex()
|
||||
== "e0671fbed2c9231fe4f286962862813a4a4d153c793bf5d0e3742119723f3000"
|
||||
)
|
||||
|
@ -24,18 +24,17 @@ from ...common import MNEMONIC12
|
||||
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.nem
|
||||
class TestMsgNEMGetaddress:
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_getaddress(self, client):
|
||||
assert (
|
||||
nem.get_address(
|
||||
client, parse_path("m/44'/1'/0'/0'/0'"), 0x68, show_display=True
|
||||
)
|
||||
== "NB3JCHVARQNGDS3UVGAJPTFE22UQFGMCQGHUBWQN"
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_getaddress(client):
|
||||
assert (
|
||||
nem.get_address(
|
||||
client, parse_path("m/44'/1'/0'/0'/0'"), 0x68, show_display=True
|
||||
)
|
||||
assert (
|
||||
nem.get_address(
|
||||
client, parse_path("m/44'/1'/0'/0'/0'"), 0x98, show_display=True
|
||||
)
|
||||
== "TB3JCHVARQNGDS3UVGAJPTFE22UQFGMCQHSBNBMF"
|
||||
== "NB3JCHVARQNGDS3UVGAJPTFE22UQFGMCQGHUBWQN"
|
||||
)
|
||||
assert (
|
||||
nem.get_address(
|
||||
client, parse_path("m/44'/1'/0'/0'/0'"), 0x98, show_display=True
|
||||
)
|
||||
== "TB3JCHVARQNGDS3UVGAJPTFE22UQFGMCQHSBNBMF"
|
||||
)
|
||||
|
@ -21,148 +21,149 @@ from trezorlib.tools import parse_path
|
||||
|
||||
from ...common import MNEMONIC12
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.nem,
|
||||
pytest.mark.skip_t2,
|
||||
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
||||
]
|
||||
|
||||
# assertion data from T1
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.nem
|
||||
@pytest.mark.skip_t2
|
||||
class TestMsgNEMSignTxMosaics:
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_mosaic_supply_change(self, client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_SUPPLY_CHANGE,
|
||||
"deadline": 74735615,
|
||||
"message": {},
|
||||
"mosaicId": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"supplyType": 1,
|
||||
"delta": 1,
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
|
||||
def test_nem_signtx_mosaic_supply_change(client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_SUPPLY_CHANGE,
|
||||
"deadline": 74735615,
|
||||
"message": {},
|
||||
"mosaicId": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"supplyType": 1,
|
||||
"delta": 1,
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
},
|
||||
)
|
||||
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "02400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963010000000100000000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "928b03c4a69fff35ecf0912066ea705895b3028fad141197d7ea2b56f1eef2a2516455e6f35d318f6fa39e2bb40492ac4ae603260790f7ebc7ea69feb4ca4c0a"
|
||||
)
|
||||
|
||||
|
||||
def test_nem_signtx_mosaic_creation(client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_CREATION,
|
||||
"deadline": 74735615,
|
||||
"message": {},
|
||||
"mosaicDefinition": {
|
||||
"id": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"levy": {},
|
||||
"properties": {},
|
||||
"description": "lorem",
|
||||
},
|
||||
)
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
},
|
||||
)
|
||||
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "02400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963010000000100000000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "928b03c4a69fff35ecf0912066ea705895b3028fad141197d7ea2b56f1eef2a2516455e6f35d318f6fa39e2bb40492ac4ae603260790f7ebc7ea69feb4ca4c0a"
|
||||
)
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000030160000000d000000696e697469616c537570706c7901000000301a0000000d000000737570706c794d757461626c650500000066616c7365190000000c0000007472616e7366657261626c650500000066616c7365000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "537adf4fd9bd5b46e204b2db0a435257a951ed26008305e0aa9e1201dafa4c306d7601a8dbacabf36b5137724386124958d53202015ab31fb3d0849dfed2df0e"
|
||||
)
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_mosaic_creation(self, client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_CREATION,
|
||||
"deadline": 74735615,
|
||||
"message": {},
|
||||
"mosaicDefinition": {
|
||||
"id": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"levy": {},
|
||||
"properties": {},
|
||||
"description": "lorem",
|
||||
|
||||
def test_nem_signtx_mosaic_creation_properties(client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_CREATION,
|
||||
"deadline": 74735615,
|
||||
"message": {},
|
||||
"mosaicDefinition": {
|
||||
"id": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"levy": {},
|
||||
"properties": [
|
||||
{"name": "divisibility", "value": "4"},
|
||||
{"name": "initialSupply", "value": "200"},
|
||||
{"name": "supplyMutable", "value": "false"},
|
||||
{"name": "transferable", "value": "true"},
|
||||
],
|
||||
"description": "lorem",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
},
|
||||
)
|
||||
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c200000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c650400000074727565000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "f17c859710060f2ea9a0ab740ef427431cf36bdc7d263570ca282bd66032e9f5737a921be9839429732e663be2bb74ccc16f34f5157ff2ef00a65796b54e800e"
|
||||
)
|
||||
|
||||
|
||||
def test_nem_signtx_mosaic_creation_levy(client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_CREATION,
|
||||
"deadline": 74735615,
|
||||
"message": {},
|
||||
"mosaicDefinition": {
|
||||
"id": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"properties": [
|
||||
{"name": "divisibility", "value": "4"},
|
||||
{"name": "initialSupply", "value": "200"},
|
||||
{"name": "supplyMutable", "value": "false"},
|
||||
{"name": "transferable", "value": "true"},
|
||||
],
|
||||
"levy": {
|
||||
"type": 1,
|
||||
"fee": 2,
|
||||
"recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"mosaicId": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
"description": "lorem",
|
||||
},
|
||||
)
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
},
|
||||
)
|
||||
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000030160000000d000000696e697469616c537570706c7901000000301a0000000d000000737570706c794d757461626c650500000066616c7365190000000c0000007472616e7366657261626c650500000066616c7365000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "537adf4fd9bd5b46e204b2db0a435257a951ed26008305e0aa9e1201dafa4c306d7601a8dbacabf36b5137724386124958d53202015ab31fb3d0849dfed2df0e"
|
||||
)
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_mosaic_creation_properties(self, client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_CREATION,
|
||||
"deadline": 74735615,
|
||||
"message": {},
|
||||
"mosaicDefinition": {
|
||||
"id": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"levy": {},
|
||||
"properties": [
|
||||
{"name": "divisibility", "value": "4"},
|
||||
{"name": "initialSupply", "value": "200"},
|
||||
{"name": "supplyMutable", "value": "false"},
|
||||
{"name": "transferable", "value": "true"},
|
||||
],
|
||||
"description": "lorem",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
},
|
||||
)
|
||||
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c200000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c650400000074727565000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "f17c859710060f2ea9a0ab740ef427431cf36bdc7d263570ca282bd66032e9f5737a921be9839429732e663be2bb74ccc16f34f5157ff2ef00a65796b54e800e"
|
||||
)
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_mosaic_creation_levy(self, client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_CREATION,
|
||||
"deadline": 74735615,
|
||||
"message": {},
|
||||
"mosaicDefinition": {
|
||||
"id": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"properties": [
|
||||
{"name": "divisibility", "value": "4"},
|
||||
{"name": "initialSupply", "value": "200"},
|
||||
{"name": "supplyMutable", "value": "false"},
|
||||
{"name": "transferable", "value": "true"},
|
||||
],
|
||||
"levy": {
|
||||
"type": 1,
|
||||
"fee": 2,
|
||||
"recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"mosaicId": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
},
|
||||
"description": "lorem",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
},
|
||||
)
|
||||
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041801000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c65040000007472756556000000010000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a1a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f7361696302000000000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "b87aac1ddf146d35e6a7f3451f57e2fe504ac559031e010a51261257c37bd50fcfa7b2939dd7a3203b54c4807d458475182f5d3dc135ec0d1d4a9cd42159fd0a"
|
||||
)
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041801000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c65040000007472756556000000010000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a1a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f7361696302000000000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "b87aac1ddf146d35e6a7f3451f57e2fe504ac559031e010a51261257c37bd50fcfa7b2939dd7a3203b54c4807d458475182f5d3dc135ec0d1d4a9cd42159fd0a"
|
||||
)
|
||||
|
@ -23,142 +23,146 @@ from ...common import MNEMONIC12
|
||||
|
||||
ADDRESS_N = parse_path("m/44'/1'/0'/0'/0'")
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.nem,
|
||||
pytest.mark.skip_t1,
|
||||
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
||||
]
|
||||
|
||||
|
||||
# assertion data from T1
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.nem
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgNEMSignTxMosaics:
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_mosaic_supply_change(self, client):
|
||||
with client:
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_SUPPLY_CHANGE,
|
||||
"deadline": 74735615,
|
||||
"message": {},
|
||||
"mosaicId": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"supplyType": 1,
|
||||
"delta": 1,
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
},
|
||||
)
|
||||
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "02400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963010000000100000000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "928b03c4a69fff35ecf0912066ea705895b3028fad141197d7ea2b56f1eef2a2516455e6f35d318f6fa39e2bb40492ac4ae603260790f7ebc7ea69feb4ca4c0a"
|
||||
)
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_mosaic_creation(self, client):
|
||||
test_suite = {
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_CREATION,
|
||||
"deadline": 74735615,
|
||||
"message": {},
|
||||
"mosaicDefinition": {
|
||||
"id": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"levy": {},
|
||||
"properties": {},
|
||||
"description": "lorem",
|
||||
def test_nem_signtx_mosaic_supply_change(client):
|
||||
with client:
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_SUPPLY_CHANGE,
|
||||
"deadline": 74735615,
|
||||
"message": {},
|
||||
"mosaicId": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"supplyType": 1,
|
||||
"delta": 1,
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
}
|
||||
)
|
||||
|
||||
# not using client.nem_sign_tx() because of swiping
|
||||
tx = nem.sign_tx(client, ADDRESS_N, test_suite)
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000030160000000d000000696e697469616c537570706c7901000000301a0000000d000000737570706c794d757461626c650500000066616c7365190000000c0000007472616e7366657261626c650500000066616c7365000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||
== "02400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963010000000100000000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "537adf4fd9bd5b46e204b2db0a435257a951ed26008305e0aa9e1201dafa4c306d7601a8dbacabf36b5137724386124958d53202015ab31fb3d0849dfed2df0e"
|
||||
== "928b03c4a69fff35ecf0912066ea705895b3028fad141197d7ea2b56f1eef2a2516455e6f35d318f6fa39e2bb40492ac4ae603260790f7ebc7ea69feb4ca4c0a"
|
||||
)
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_mosaic_creation_properties(self, client):
|
||||
test_suite = {
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_CREATION,
|
||||
"deadline": 74735615,
|
||||
"message": {},
|
||||
"mosaicDefinition": {
|
||||
"id": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"levy": {},
|
||||
"properties": [
|
||||
{"name": "divisibility", "value": "4"},
|
||||
{"name": "initialSupply", "value": "200"},
|
||||
{"name": "supplyMutable", "value": "false"},
|
||||
{"name": "transferable", "value": "true"},
|
||||
],
|
||||
"description": "lorem",
|
||||
|
||||
def test_nem_signtx_mosaic_creation(client):
|
||||
test_suite = {
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_CREATION,
|
||||
"deadline": 74735615,
|
||||
"message": {},
|
||||
"mosaicDefinition": {
|
||||
"id": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"levy": {},
|
||||
"properties": {},
|
||||
"description": "lorem",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
}
|
||||
|
||||
# not using client.nem_sign_tx() because of swiping
|
||||
tx = nem.sign_tx(client, ADDRESS_N, test_suite)
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000030160000000d000000696e697469616c537570706c7901000000301a0000000d000000737570706c794d757461626c650500000066616c7365190000000c0000007472616e7366657261626c650500000066616c7365000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "537adf4fd9bd5b46e204b2db0a435257a951ed26008305e0aa9e1201dafa4c306d7601a8dbacabf36b5137724386124958d53202015ab31fb3d0849dfed2df0e"
|
||||
)
|
||||
|
||||
|
||||
def test_nem_signtx_mosaic_creation_properties(client):
|
||||
test_suite = {
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_CREATION,
|
||||
"deadline": 74735615,
|
||||
"message": {},
|
||||
"mosaicDefinition": {
|
||||
"id": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"levy": {},
|
||||
"properties": [
|
||||
{"name": "divisibility", "value": "4"},
|
||||
{"name": "initialSupply", "value": "200"},
|
||||
{"name": "supplyMutable", "value": "false"},
|
||||
{"name": "transferable", "value": "true"},
|
||||
],
|
||||
"description": "lorem",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
}
|
||||
|
||||
# not using client.nem_sign_tx() because of swiping
|
||||
tx = nem.sign_tx(client, ADDRESS_N, test_suite)
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c200000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c650400000074727565000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "f17c859710060f2ea9a0ab740ef427431cf36bdc7d263570ca282bd66032e9f5737a921be9839429732e663be2bb74ccc16f34f5157ff2ef00a65796b54e800e"
|
||||
)
|
||||
|
||||
|
||||
def test_nem_signtx_mosaic_creation_levy(client):
|
||||
test_suite = {
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_CREATION,
|
||||
"deadline": 74735615,
|
||||
"message": {},
|
||||
"mosaicDefinition": {
|
||||
"id": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"properties": [
|
||||
{"name": "divisibility", "value": "4"},
|
||||
{"name": "initialSupply", "value": "200"},
|
||||
{"name": "supplyMutable", "value": "false"},
|
||||
{"name": "transferable", "value": "true"},
|
||||
],
|
||||
"levy": {
|
||||
"type": 1,
|
||||
"fee": 2,
|
||||
"recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"mosaicId": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
}
|
||||
"description": "lorem",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
}
|
||||
|
||||
# not using client.nem_sign_tx() because of swiping
|
||||
tx = nem.sign_tx(client, ADDRESS_N, test_suite)
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f7404c200000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c650400000074727565000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "f17c859710060f2ea9a0ab740ef427431cf36bdc7d263570ca282bd66032e9f5737a921be9839429732e663be2bb74ccc16f34f5157ff2ef00a65796b54e800e"
|
||||
)
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_mosaic_creation_levy(self, client):
|
||||
test_suite = {
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_MOSAIC_CREATION,
|
||||
"deadline": 74735615,
|
||||
"message": {},
|
||||
"mosaicDefinition": {
|
||||
"id": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"properties": [
|
||||
{"name": "divisibility", "value": "4"},
|
||||
{"name": "initialSupply", "value": "200"},
|
||||
{"name": "supplyMutable", "value": "false"},
|
||||
{"name": "transferable", "value": "true"},
|
||||
],
|
||||
"levy": {
|
||||
"type": 1,
|
||||
"fee": 2,
|
||||
"recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"mosaicId": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
},
|
||||
"description": "lorem",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
}
|
||||
|
||||
tx = nem.sign_tx(client, ADDRESS_N, test_suite)
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041801000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c65040000007472756556000000010000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a1a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f7361696302000000000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "b87aac1ddf146d35e6a7f3451f57e2fe504ac559031e010a51261257c37bd50fcfa7b2939dd7a3203b54c4807d458475182f5d3dc135ec0d1d4a9cd42159fd0a"
|
||||
)
|
||||
tx = nem.sign_tx(client, ADDRESS_N, test_suite)
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "01400000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74041801000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f73616963050000006c6f72656d04000000150000000c00000064697669736962696c6974790100000034180000000d000000696e697469616c537570706c79030000003230301a0000000d000000737570706c794d757461626c650500000066616c7365180000000c0000007472616e7366657261626c65040000007472756556000000010000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a1a0000000600000068656c6c6f6d0c00000048656c6c6f206d6f7361696302000000000000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "b87aac1ddf146d35e6a7f3451f57e2fe504ac559031e010a51261257c37bd50fcfa7b2939dd7a3203b54c4807d458475182f5d3dc135ec0d1d4a9cd42159fd0a"
|
||||
)
|
||||
|
@ -21,180 +21,182 @@ from trezorlib.tools import parse_path
|
||||
|
||||
from ...common import MNEMONIC12
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.nem,
|
||||
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
||||
]
|
||||
|
||||
|
||||
# assertion data from T1
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.nem
|
||||
class TestMsgNEMSignTxMultisig:
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_aggregate_modification(self, client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_AGGREGATE_MODIFICATION,
|
||||
"deadline": 74735615,
|
||||
"message": {},
|
||||
"modifications": [
|
||||
{
|
||||
"modificationType": 1, # Add
|
||||
"cosignatoryAccount": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844",
|
||||
}
|
||||
],
|
||||
"minCosignatories": {"relativeChange": 3},
|
||||
"version": (0x98 << 24),
|
||||
},
|
||||
)
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "01100000020000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f740401000000280000000100000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f878440400000003000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "1200e552d8732ce3eae96719731194abfc5a09d98f61bb35684f4eeaeff15b1bdf326ee7b1bbbe89d3f68c8e07ad3daf72e4c7f031094ad2236b97918ad98601"
|
||||
)
|
||||
def test_nem_signtx_aggregate_modification(client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_AGGREGATE_MODIFICATION,
|
||||
"deadline": 74735615,
|
||||
"message": {},
|
||||
"modifications": [
|
||||
{
|
||||
"modificationType": 1, # Add
|
||||
"cosignatoryAccount": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844",
|
||||
}
|
||||
],
|
||||
"minCosignatories": {"relativeChange": 3},
|
||||
"version": (0x98 << 24),
|
||||
},
|
||||
)
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "01100000020000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f740401000000280000000100000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f878440400000003000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "1200e552d8732ce3eae96719731194abfc5a09d98f61bb35684f4eeaeff15b1bdf326ee7b1bbbe89d3f68c8e07ad3daf72e4c7f031094ad2236b97918ad98601"
|
||||
)
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_multisig(self, client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 1,
|
||||
"fee": 10000,
|
||||
"type": nem.TYPE_MULTISIG,
|
||||
"deadline": 74735615,
|
||||
"otherTrans": { # simple transaction transfer
|
||||
"timeStamp": 2,
|
||||
"amount": 2000000,
|
||||
"fee": 15000,
|
||||
"recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 67890,
|
||||
"message": {
|
||||
"payload": b"test_nem_transaction_transfer".hex(),
|
||||
"type": 1,
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"signer": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844",
|
||||
|
||||
def test_nem_signtx_multisig(client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 1,
|
||||
"fee": 10000,
|
||||
"type": nem.TYPE_MULTISIG,
|
||||
"deadline": 74735615,
|
||||
"otherTrans": { # simple transaction transfer
|
||||
"timeStamp": 2,
|
||||
"amount": 2000000,
|
||||
"fee": 15000,
|
||||
"recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 67890,
|
||||
"message": {
|
||||
"payload": b"test_nem_transaction_transfer".hex(),
|
||||
"type": 1,
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"signer": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844",
|
||||
},
|
||||
)
|
||||
"version": (0x98 << 24),
|
||||
},
|
||||
)
|
||||
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "04100000010000980100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841027000000000000ff5f74049900000001010000010000980200000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844983a000000000000320901002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e000000000025000000010000001d000000746573745f6e656d5f7472616e73616374696f6e5f7472616e73666572"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "0cab2fddf2f02b5d7201675b9a71869292fe25ed33a366c7d2cbea7676fed491faaa03310079b7e17884b6ba2e3ea21c4f728d1cca8f190b8288207f6514820a"
|
||||
)
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "04100000010000980100000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620841027000000000000ff5f74049900000001010000010000980200000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844983a000000000000320901002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e000000000025000000010000001d000000746573745f6e656d5f7472616e73616374696f6e5f7472616e73666572"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "0cab2fddf2f02b5d7201675b9a71869292fe25ed33a366c7d2cbea7676fed491faaa03310079b7e17884b6ba2e3ea21c4f728d1cca8f190b8288207f6514820a"
|
||||
)
|
||||
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 150,
|
||||
"type": nem.TYPE_MULTISIG,
|
||||
"deadline": 789,
|
||||
"otherTrans": {
|
||||
"timeStamp": 123456,
|
||||
"fee": 2000,
|
||||
"type": nem.TYPE_PROVISION_NAMESPACE,
|
||||
"deadline": 100,
|
||||
"message": {},
|
||||
"newPart": "ABCDE",
|
||||
"rentalFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"rentalFee": 1500,
|
||||
"parent": None,
|
||||
"version": (0x98 << 24),
|
||||
"signer": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
},
|
||||
)
|
||||
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "04100000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620849600000000000000150300007d000000012000000100009840e2010020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844d007000000000000640000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000050000004142434445ffffffff"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "c915ca3332380925f4050301cdc62269cf29437ac5955321b18da34e570c7fdbb1aec2940a2a553a2a5c90950a4db3c8d3ef899c1a108582e0657f66fbbb0b04"
|
||||
)
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_multisig_signer(self, client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 333,
|
||||
"fee": 200,
|
||||
"type": nem.TYPE_MULTISIG_SIGNATURE,
|
||||
"deadline": 444,
|
||||
"otherTrans": { # simple transaction transfer
|
||||
"timeStamp": 555,
|
||||
"amount": 2000000,
|
||||
"fee": 2000000,
|
||||
"recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 666,
|
||||
"message": {
|
||||
"payload": b"test_nem_transaction_transfer".hex(),
|
||||
"type": 1,
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"signer": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
},
|
||||
)
|
||||
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "02100000010000984d01000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b4062084c800000000000000bc010000240000002000000087923cd4805f3babe6b5af9cbb2b08be4458e39531618aed73c911f160c8e38528000000544444324354364c514c49595135364b49584933454e544d36454b3344343450354b5a50464d4b32"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "286358a16ae545bff798feab93a713440c7c2f236d52ac0e995669d17a1915b0903667c97fa04418eccb42333cba95b19bccc8ac1faa8224dcfaeb41890ae807"
|
||||
)
|
||||
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 900000,
|
||||
"fee": 200000,
|
||||
"type": nem.TYPE_MULTISIG_SIGNATURE,
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 150,
|
||||
"type": nem.TYPE_MULTISIG,
|
||||
"deadline": 789,
|
||||
"otherTrans": {
|
||||
"timeStamp": 123456,
|
||||
"fee": 2000,
|
||||
"type": nem.TYPE_PROVISION_NAMESPACE,
|
||||
"deadline": 100,
|
||||
"otherTrans": { # simple transaction transfer
|
||||
"timeStamp": 101111,
|
||||
"fee": 1000,
|
||||
"type": nem.TYPE_MOSAIC_SUPPLY_CHANGE,
|
||||
"deadline": 13123,
|
||||
"message": {},
|
||||
"mosaicId": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"supplyType": 1,
|
||||
"delta": 1,
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
"signer": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844",
|
||||
"message": {},
|
||||
"newPart": "ABCDE",
|
||||
"rentalFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"rentalFee": 1500,
|
||||
"parent": None,
|
||||
"version": (0x98 << 24),
|
||||
"signer": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
},
|
||||
)
|
||||
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "04100000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b40620849600000000000000150300007d000000012000000100009840e2010020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844d007000000000000640000002800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000050000004142434445ffffffff"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "c915ca3332380925f4050301cdc62269cf29437ac5955321b18da34e570c7fdbb1aec2940a2a553a2a5c90950a4db3c8d3ef899c1a108582e0657f66fbbb0b04"
|
||||
)
|
||||
|
||||
|
||||
def test_nem_signtx_multisig_signer(client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 333,
|
||||
"fee": 200,
|
||||
"type": nem.TYPE_MULTISIG_SIGNATURE,
|
||||
"deadline": 444,
|
||||
"otherTrans": { # simple transaction transfer
|
||||
"timeStamp": 555,
|
||||
"amount": 2000000,
|
||||
"fee": 2000000,
|
||||
"recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 666,
|
||||
"message": {
|
||||
"payload": b"test_nem_transaction_transfer".hex(),
|
||||
"type": 1,
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"signer": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844",
|
||||
},
|
||||
)
|
||||
"version": (0x98 << 24),
|
||||
},
|
||||
)
|
||||
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "0210000001000098a0bb0d0020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b4062084400d030000000000640000002400000020000000c51395626a89a71c1ed785fb5974307a049b3b9e2165d56ed0302fe6b4f02a0128000000544444324354364c514c49595135364b49584933454e544d36454b3344343450354b5a50464d4b32"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "32b1fdf788c4a90c01eedf5972b7709745831d620c13e1e97b0de6481837e162ee551573f2409822754ae940731909ec4b79cf836487e898df476adb10467506"
|
||||
)
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "02100000010000984d01000020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b4062084c800000000000000bc010000240000002000000087923cd4805f3babe6b5af9cbb2b08be4458e39531618aed73c911f160c8e38528000000544444324354364c514c49595135364b49584933454e544d36454b3344343450354b5a50464d4b32"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "286358a16ae545bff798feab93a713440c7c2f236d52ac0e995669d17a1915b0903667c97fa04418eccb42333cba95b19bccc8ac1faa8224dcfaeb41890ae807"
|
||||
)
|
||||
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 900000,
|
||||
"fee": 200000,
|
||||
"type": nem.TYPE_MULTISIG_SIGNATURE,
|
||||
"deadline": 100,
|
||||
"otherTrans": { # simple transaction transfer
|
||||
"timeStamp": 101111,
|
||||
"fee": 1000,
|
||||
"type": nem.TYPE_MOSAIC_SUPPLY_CHANGE,
|
||||
"deadline": 13123,
|
||||
"message": {},
|
||||
"mosaicId": {"namespaceId": "hellom", "name": "Hello mosaic"},
|
||||
"supplyType": 1,
|
||||
"delta": 1,
|
||||
"version": (0x98 << 24),
|
||||
"creationFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"creationFee": 1500,
|
||||
"signer": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
},
|
||||
)
|
||||
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "0210000001000098a0bb0d0020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b4062084400d030000000000640000002400000020000000c51395626a89a71c1ed785fb5974307a049b3b9e2165d56ed0302fe6b4f02a0128000000544444324354364c514c49595135364b49584933454e544d36454b3344343450354b5a50464d4b32"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "32b1fdf788c4a90c01eedf5972b7709745831d620c13e1e97b0de6481837e162ee551573f2409822754ae940731909ec4b79cf836487e898df476adb10467506"
|
||||
)
|
||||
|
@ -21,64 +21,66 @@ from trezorlib.tools import parse_path
|
||||
|
||||
from ...common import MNEMONIC12
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.nem,
|
||||
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
||||
]
|
||||
|
||||
|
||||
# assertion data from T1
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.nem
|
||||
class TestMsgNEMSignTxOther:
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_importance_transfer(self, client):
|
||||
with client:
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 12349215,
|
||||
"fee": 9900,
|
||||
"type": nem.TYPE_IMPORTANCE_TRANSFER,
|
||||
"deadline": 99,
|
||||
"message": {},
|
||||
"importanceTransfer": {
|
||||
"mode": 1, # activate
|
||||
"publicKey": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
},
|
||||
)
|
||||
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "01080000010000981f6fbc0020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b4062084ac26000000000000630000000100000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "b6d9434ec5df80e65e6e45d7f0f3c579b4adfe8567c42d981b06e8ac368b1aad2b24eebecd5efd41f4497051fca8ea8a5e77636a79afc46ee1a8e0fe9e3ba90b"
|
||||
)
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_provision_namespace(self, client):
|
||||
def test_nem_signtx_importance_transfer(client):
|
||||
with client:
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_PROVISION_NAMESPACE,
|
||||
"deadline": 74735615,
|
||||
"timeStamp": 12349215,
|
||||
"fee": 9900,
|
||||
"type": nem.TYPE_IMPORTANCE_TRANSFER,
|
||||
"deadline": 99,
|
||||
"message": {},
|
||||
"newPart": "ABCDE",
|
||||
"rentalFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"rentalFee": 1500,
|
||||
"parent": None,
|
||||
"importanceTransfer": {
|
||||
"mode": 1, # activate
|
||||
"publicKey": "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844",
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
},
|
||||
)
|
||||
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "01200000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000050000004142434445ffffffff"
|
||||
== "01080000010000981f6fbc0020000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b4062084ac26000000000000630000000100000020000000c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "f047ae7987cd3a60c0d5ad123aba211185cb6266a7469dfb0491a0df6b5cd9c92b2e2b9f396cc2a3146ee185ba02df4f9e7fb238fe479917b3d274d97336640d"
|
||||
== "b6d9434ec5df80e65e6e45d7f0f3c579b4adfe8567c42d981b06e8ac368b1aad2b24eebecd5efd41f4497051fca8ea8a5e77636a79afc46ee1a8e0fe9e3ba90b"
|
||||
)
|
||||
|
||||
|
||||
def test_nem_signtx_provision_namespace(client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"fee": 2000000,
|
||||
"type": nem.TYPE_PROVISION_NAMESPACE,
|
||||
"deadline": 74735615,
|
||||
"message": {},
|
||||
"newPart": "ABCDE",
|
||||
"rentalFeeSink": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"rentalFee": 1500,
|
||||
"parent": None,
|
||||
"version": (0x98 << 24),
|
||||
},
|
||||
)
|
||||
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "01200000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324adc05000000000000050000004142434445ffffffff"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "f047ae7987cd3a60c0d5ad123aba211185cb6266a7469dfb0491a0df6b5cd9c92b2e2b9f396cc2a3146ee185ba02df4f9e7fb238fe479917b3d274d97336640d"
|
||||
)
|
||||
|
@ -21,276 +21,284 @@ from trezorlib.tools import parse_path
|
||||
|
||||
from ...common import MNEMONIC12
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.nem,
|
||||
pytest.mark.setup_client(mnemonic=MNEMONIC12),
|
||||
]
|
||||
|
||||
|
||||
# assertion data from T1
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.nem
|
||||
class TestMsgNEMSignTx:
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_simple(self, client):
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
# Confirm transfer and network fee
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
# Unencrypted message
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
# Confirm recipient
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.NEMSignedTx,
|
||||
]
|
||||
)
|
||||
def test_nem_signtx_simple(client):
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
# Confirm transfer and network fee
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
# Unencrypted message
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
# Confirm recipient
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.NEMSignedTx,
|
||||
]
|
||||
)
|
||||
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"amount": 2000000,
|
||||
"fee": 2000000,
|
||||
"recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 74735615,
|
||||
"message": {
|
||||
"payload": b"test_nem_transaction_transfer".hex(),
|
||||
"type": 1,
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
},
|
||||
)
|
||||
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "01010000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e000000000025000000010000001d000000746573745f6e656d5f7472616e73616374696f6e5f7472616e73666572"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "9cda2045324d05c791a4fc312ecceb62954e7740482f8df8928560d63cf273dea595023640179f112de755c79717757ef76962175378d6d87360ddb3f3e5f70f"
|
||||
)
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_encrypted_payload(self, client):
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
# Confirm transfer and network fee
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
# Ask for encryption
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
# Confirm recipient
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.NEMSignedTx,
|
||||
]
|
||||
)
|
||||
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 74649215,
|
||||
"amount": 2000000,
|
||||
"fee": 2000000,
|
||||
"recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 74735615,
|
||||
"message": {
|
||||
# plain text is 32B long => cipher text is 48B
|
||||
# as per PKCS#7 another block containing padding is added
|
||||
"payload": b"this message should be encrypted".hex(),
|
||||
"publicKey": "5a5e14c633d7d269302849d739d80344ff14db51d7bcda86045723f05c4e4541",
|
||||
"type": 2,
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
},
|
||||
)
|
||||
|
||||
assert (
|
||||
tx.data[:124].hex()
|
||||
== "01010000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e0000000000680000000200000060000000"
|
||||
)
|
||||
# after 124th byte comes iv (16B) salt (32B) and encrypted payload (48B)
|
||||
assert len(tx.data[124:]) == 16 + 32 + 48
|
||||
# because IV and salt are random (therefore the encrypted payload as well) those data can't be asserted
|
||||
assert len(tx.signature) == 64
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_xem_as_mosaic(self, client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 76809215,
|
||||
"amount": 5000000,
|
||||
"fee": 1000000,
|
||||
"timeStamp": 74649215,
|
||||
"amount": 2000000,
|
||||
"fee": 2000000,
|
||||
"recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 76895615,
|
||||
"deadline": 74735615,
|
||||
"message": {
|
||||
"payload": b"test_nem_transaction_transfer".hex(),
|
||||
"type": 1,
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"message": {},
|
||||
"mosaics": [
|
||||
{
|
||||
"mosaicId": {"namespaceId": "nem", "name": "xem"},
|
||||
"quantity": 9000000,
|
||||
}
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
# trezor should display 45 XEM (multiplied by amount)
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a404b4c000000000000000000010000001a0000000e000000030000006e656d0300000078656d4054890000000000"
|
||||
== "01010000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e000000000025000000010000001d000000746573745f6e656d5f7472616e73616374696f6e5f7472616e73666572"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "7b25a84b65adb489ea55739f1ca2d83a0ae069c3c58d0ea075fc30bfe8f649519199ad2324ca229c6c3214191469f95326e99712124592cae7cd3a092c93ac0c"
|
||||
== "9cda2045324d05c791a4fc312ecceb62954e7740482f8df8928560d63cf273dea595023640179f112de755c79717757ef76962175378d6d87360ddb3f3e5f70f"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_encrypted_payload(client):
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
# Confirm transfer and network fee
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
# Ask for encryption
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
# Confirm recipient
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
proto.NEMSignedTx,
|
||||
]
|
||||
)
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_unknown_mosaic(self, client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 76809215,
|
||||
"timeStamp": 74649215,
|
||||
"amount": 2000000,
|
||||
"fee": 1000000,
|
||||
"fee": 2000000,
|
||||
"recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 76895615,
|
||||
"deadline": 74735615,
|
||||
"message": {
|
||||
# plain text is 32B long => cipher text is 48B
|
||||
# as per PKCS#7 another block containing padding is added
|
||||
"payload": b"this message should be encrypted".hex(),
|
||||
"publicKey": "5a5e14c633d7d269302849d739d80344ff14db51d7bcda86045723f05c4e4541",
|
||||
"type": 2,
|
||||
},
|
||||
"version": (0x98 << 24),
|
||||
"message": {},
|
||||
"mosaics": [
|
||||
{
|
||||
"mosaicId": {"namespaceId": "xxx", "name": "aa"},
|
||||
"quantity": 3500000,
|
||||
}
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
# trezor should display warning about unknown mosaic and then dialog for 7000000 raw units of xxx.aa and 0 XEM
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e00000000000000000001000000190000000d00000003000000787878020000006161e067350000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "2f0280420eceb41ef9e5d94fa44ddda9cdc70b8f423ae18af577f6d85df64bb4aaf40cf24fc6eef47c63b0963611f8682348cecdc49a9b64eafcbe7afcb49102"
|
||||
tx.data[:124].hex()
|
||||
== "01010000010000987f0e730420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208480841e0000000000ff5f74042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e0000000000680000000200000060000000"
|
||||
)
|
||||
# after 124th byte comes iv (16B) salt (32B) and encrypted payload (48B)
|
||||
assert len(tx.data[124:]) == 16 + 32 + 48
|
||||
# because IV and salt are random (therefore the encrypted payload as well) those data can't be asserted
|
||||
assert len(tx.signature) == 64
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_known_mosaic(self, client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 76809215,
|
||||
"amount": 3000000,
|
||||
"fee": 1000000,
|
||||
"recipient": "NDMYSLXI4L3FYUQWO4MJOVL6BSTJJXKDSZRMT4LT",
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 76895615,
|
||||
"version": (0x68 << 24),
|
||||
"message": {},
|
||||
"mosaics": [
|
||||
{
|
||||
"mosaicId": {"namespaceId": "dim", "name": "token"},
|
||||
"quantity": 111000,
|
||||
}
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
# trezor should display 0 XEM and 0.333 DIMTOK
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "0101000002000068ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f559504280000004e444d59534c5849344c3346595551574f344d4a4f564c364253544a4a584b44535a524d54344c54c0c62d000000000000000000010000001c000000100000000300000064696d05000000746f6b656e98b1010000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "e7f14ef8c39727bfd257e109cd5acac31542f2e41f2e5deb258fc1db602b690eb1cabca41a627fe2adc51f3193db85c76b41c80bb60161eb8738ebf20b507104"
|
||||
)
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_xem_as_mosaic(client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 76809215,
|
||||
"amount": 5000000,
|
||||
"fee": 1000000,
|
||||
"recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 76895615,
|
||||
"version": (0x98 << 24),
|
||||
"message": {},
|
||||
"mosaics": [
|
||||
{
|
||||
"mosaicId": {"namespaceId": "nem", "name": "xem"},
|
||||
"quantity": 9000000,
|
||||
}
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_known_mosaic_with_levy(self, client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 76809215,
|
||||
"amount": 2000000,
|
||||
"fee": 1000000,
|
||||
"recipient": "NDMYSLXI4L3FYUQWO4MJOVL6BSTJJXKDSZRMT4LT",
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 76895615,
|
||||
"version": (0x68 << 24),
|
||||
"message": {},
|
||||
"mosaics": [
|
||||
{
|
||||
"mosaicId": {"namespaceId": "dim", "name": "coin"},
|
||||
"quantity": 222000,
|
||||
}
|
||||
],
|
||||
},
|
||||
)
|
||||
# trezor should display 45 XEM (multiplied by amount)
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a404b4c000000000000000000010000001a0000000e000000030000006e656d0300000078656d4054890000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "7b25a84b65adb489ea55739f1ca2d83a0ae069c3c58d0ea075fc30bfe8f649519199ad2324ca229c6c3214191469f95326e99712124592cae7cd3a092c93ac0c"
|
||||
)
|
||||
|
||||
# trezor should display 0 XEM and 0.444 DIM and levy of 0.000444 DIM
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "0101000002000068ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f559504280000004e444d59534c5849344c3346595551574f344d4a4f564c364253544a4a584b44535a524d54344c5480841e000000000000000000010000001b0000000f0000000300000064696d04000000636f696e3063030000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "d3222dd7b83d66bda0539827ac6f909d06e40350b5e5e893d6fa762f954e9bf7da61022ef04950e7b6dfa88a2278f2f8a1b21df2bc3af22b388cb3a90bf76f07"
|
||||
)
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_multiple_mosaics(self, client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 76809215,
|
||||
"amount": 2000000,
|
||||
"fee": 1000000,
|
||||
"recipient": "NDMYSLXI4L3FYUQWO4MJOVL6BSTJJXKDSZRMT4LT",
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 76895615,
|
||||
"version": (0x68 << 24),
|
||||
"message": {},
|
||||
"mosaics": [
|
||||
{
|
||||
"mosaicId": {"namespaceId": "nem", "name": "xem"},
|
||||
"quantity": 3000000,
|
||||
},
|
||||
{
|
||||
"mosaicId": {"namespaceId": "abc", "name": "mosaic"},
|
||||
"quantity": 200,
|
||||
},
|
||||
{
|
||||
"mosaicId": {"namespaceId": "nem", "name": "xem"},
|
||||
"quantity": 30000,
|
||||
},
|
||||
{
|
||||
"mosaicId": {"namespaceId": "abc", "name": "mosaic"},
|
||||
"quantity": 2000000,
|
||||
},
|
||||
{
|
||||
"mosaicId": {"namespaceId": "breeze", "name": "breeze-token"},
|
||||
"quantity": 111000,
|
||||
},
|
||||
],
|
||||
},
|
||||
)
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_unknown_mosaic(client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 76809215,
|
||||
"amount": 2000000,
|
||||
"fee": 1000000,
|
||||
"recipient": "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J",
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 76895615,
|
||||
"version": (0x98 << 24),
|
||||
"message": {},
|
||||
"mosaics": [
|
||||
{
|
||||
"mosaicId": {"namespaceId": "xxx", "name": "aa"},
|
||||
"quantity": 3500000,
|
||||
}
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
# trezor should display warning, 6.06 XEM, 4000400 raw units of abc.mosaic (mosaics are merged)
|
||||
# and 222000 BREEZE
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "0101000002000068ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f559504280000004e444d59534c5849344c3346595551574f344d4a4f564c364253544a4a584b44535a524d54344c5480841e000000000000000000030000001d0000001100000003000000616263060000006d6f7361696348851e0000000000260000001a00000006000000627265657a650c000000627265657a652d746f6b656e98b10100000000001a0000000e000000030000006e656d0300000078656df03b2e0000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "b2b9319fca87a05bee17108edd9a8f78aeffef74bf6b4badc6da5d46e8ff4fe82e24bf69d8e6c4097d072adf39d0c753e7580f8afb21e3288ebfb7c4d84e470d"
|
||||
)
|
||||
# trezor should display warning about unknown mosaic and then dialog for 7000000 raw units of xxx.aa and 0 XEM
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "0101000002000098ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f5595042800000054414c49434532474d4133344358484437584c4a513533364e4d35554e4b5148544f524e4e54324a80841e00000000000000000001000000190000000d00000003000000787878020000006161e067350000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "2f0280420eceb41ef9e5d94fa44ddda9cdc70b8f423ae18af577f6d85df64bb4aaf40cf24fc6eef47c63b0963611f8682348cecdc49a9b64eafcbe7afcb49102"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_known_mosaic(client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 76809215,
|
||||
"amount": 3000000,
|
||||
"fee": 1000000,
|
||||
"recipient": "NDMYSLXI4L3FYUQWO4MJOVL6BSTJJXKDSZRMT4LT",
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 76895615,
|
||||
"version": (0x68 << 24),
|
||||
"message": {},
|
||||
"mosaics": [
|
||||
{
|
||||
"mosaicId": {"namespaceId": "dim", "name": "token"},
|
||||
"quantity": 111000,
|
||||
}
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
# trezor should display 0 XEM and 0.333 DIMTOK
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "0101000002000068ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f559504280000004e444d59534c5849344c3346595551574f344d4a4f564c364253544a4a584b44535a524d54344c54c0c62d000000000000000000010000001c000000100000000300000064696d05000000746f6b656e98b1010000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "e7f14ef8c39727bfd257e109cd5acac31542f2e41f2e5deb258fc1db602b690eb1cabca41a627fe2adc51f3193db85c76b41c80bb60161eb8738ebf20b507104"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_known_mosaic_with_levy(client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 76809215,
|
||||
"amount": 2000000,
|
||||
"fee": 1000000,
|
||||
"recipient": "NDMYSLXI4L3FYUQWO4MJOVL6BSTJJXKDSZRMT4LT",
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 76895615,
|
||||
"version": (0x68 << 24),
|
||||
"message": {},
|
||||
"mosaics": [
|
||||
{
|
||||
"mosaicId": {"namespaceId": "dim", "name": "coin"},
|
||||
"quantity": 222000,
|
||||
}
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
# trezor should display 0 XEM and 0.444 DIM and levy of 0.000444 DIM
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "0101000002000068ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f559504280000004e444d59534c5849344c3346595551574f344d4a4f564c364253544a4a584b44535a524d54344c5480841e000000000000000000010000001b0000000f0000000300000064696d04000000636f696e3063030000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "d3222dd7b83d66bda0539827ac6f909d06e40350b5e5e893d6fa762f954e9bf7da61022ef04950e7b6dfa88a2278f2f8a1b21df2bc3af22b388cb3a90bf76f07"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_multiple_mosaics(client):
|
||||
tx = nem.sign_tx(
|
||||
client,
|
||||
parse_path("m/44'/1'/0'/0'/0'"),
|
||||
{
|
||||
"timeStamp": 76809215,
|
||||
"amount": 2000000,
|
||||
"fee": 1000000,
|
||||
"recipient": "NDMYSLXI4L3FYUQWO4MJOVL6BSTJJXKDSZRMT4LT",
|
||||
"type": nem.TYPE_TRANSACTION_TRANSFER,
|
||||
"deadline": 76895615,
|
||||
"version": (0x68 << 24),
|
||||
"message": {},
|
||||
"mosaics": [
|
||||
{
|
||||
"mosaicId": {"namespaceId": "nem", "name": "xem"},
|
||||
"quantity": 3000000,
|
||||
},
|
||||
{
|
||||
"mosaicId": {"namespaceId": "abc", "name": "mosaic"},
|
||||
"quantity": 200,
|
||||
},
|
||||
{
|
||||
"mosaicId": {"namespaceId": "nem", "name": "xem"},
|
||||
"quantity": 30000,
|
||||
},
|
||||
{
|
||||
"mosaicId": {"namespaceId": "abc", "name": "mosaic"},
|
||||
"quantity": 2000000,
|
||||
},
|
||||
{
|
||||
"mosaicId": {"namespaceId": "breeze", "name": "breeze-token"},
|
||||
"quantity": 111000,
|
||||
},
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
# trezor should display warning, 6.06 XEM, 4000400 raw units of abc.mosaic (mosaics are merged)
|
||||
# and 222000 BREEZE
|
||||
assert (
|
||||
tx.data.hex()
|
||||
== "0101000002000068ff03940420000000edfd32f6e760648c032f9acb4b30d514265f6a5b5f8a7154f2618922b406208440420f00000000007f559504280000004e444d59534c5849344c3346595551574f344d4a4f564c364253544a4a584b44535a524d54344c5480841e000000000000000000030000001d0000001100000003000000616263060000006d6f7361696348851e0000000000260000001a00000006000000627265657a650c000000627265657a652d746f6b656e98b10100000000001a0000000e000000030000006e656d0300000078656df03b2e0000000000"
|
||||
)
|
||||
assert (
|
||||
tx.signature.hex()
|
||||
== "b2b9319fca87a05bee17108edd9a8f78aeffef74bf6b4badc6da5d46e8ff4fe82e24bf69d8e6c4097d072adf39d0c753e7580f8afb21e3288ebfb7c4d84e470d"
|
||||
)
|
||||
|
@ -23,189 +23,193 @@ from ...common import MNEMONIC12
|
||||
PIN4 = "1234"
|
||||
PIN6 = "789456"
|
||||
|
||||
pytestmark = [pytest.mark.skip_t2]
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
class TestMsgRecoverydevice:
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_pin_passphrase(self, client):
|
||||
mnemonic = MNEMONIC12.split(" ")
|
||||
ret = client.call_raw(
|
||||
proto.RecoveryDevice(
|
||||
word_count=12,
|
||||
passphrase_protection=True,
|
||||
pin_protection=True,
|
||||
label="label",
|
||||
language="en-US",
|
||||
enforce_wordlist=True,
|
||||
)
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_pin_passphrase(client):
|
||||
mnemonic = MNEMONIC12.split(" ")
|
||||
ret = client.call_raw(
|
||||
proto.RecoveryDevice(
|
||||
word_count=12,
|
||||
passphrase_protection=True,
|
||||
pin_protection=True,
|
||||
label="label",
|
||||
language="en-US",
|
||||
enforce_wordlist=True,
|
||||
)
|
||||
)
|
||||
|
||||
# click through confirmation
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
# click through confirmation
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
|
||||
# Enter PIN for first time
|
||||
pin_encoded = client.debug.encode_pin(PIN6)
|
||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
# Enter PIN for first time
|
||||
pin_encoded = client.debug.encode_pin(PIN6)
|
||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
|
||||
# Enter PIN for second time
|
||||
pin_encoded = client.debug.encode_pin(PIN6)
|
||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
||||
|
||||
fakes = 0
|
||||
for _ in range(int(12 * 2)):
|
||||
assert isinstance(ret, proto.WordRequest)
|
||||
(word, pos) = client.debug.read_recovery_word()
|
||||
|
||||
if pos != 0:
|
||||
ret = client.call_raw(proto.WordAck(word=mnemonic[pos - 1]))
|
||||
mnemonic[pos - 1] = None
|
||||
else:
|
||||
ret = client.call_raw(proto.WordAck(word=word))
|
||||
fakes += 1
|
||||
|
||||
# Workflow succesfully ended
|
||||
assert isinstance(ret, proto.Success)
|
||||
|
||||
# 12 expected fake words and all words of mnemonic are used
|
||||
assert fakes == 12
|
||||
assert mnemonic == [None] * 12
|
||||
|
||||
# Mnemonic is the same
|
||||
client.init_device()
|
||||
assert client.debug.state().mnemonic_secret == MNEMONIC12.encode()
|
||||
|
||||
assert client.features.pin_protection is True
|
||||
assert client.features.passphrase_protection is True
|
||||
|
||||
# Do passphrase-protected action, PassphraseRequest should be raised
|
||||
resp = client.call_raw(proto.GetAddress())
|
||||
assert isinstance(resp, proto.PassphraseRequest)
|
||||
client.call_raw(proto.Cancel())
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_nopin_nopassphrase(self, client):
|
||||
mnemonic = MNEMONIC12.split(" ")
|
||||
ret = client.call_raw(
|
||||
proto.RecoveryDevice(
|
||||
word_count=12,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
label="label",
|
||||
language="en-US",
|
||||
enforce_wordlist=True,
|
||||
)
|
||||
)
|
||||
|
||||
# click through confirmation
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
fakes = 0
|
||||
for _ in range(int(12 * 2)):
|
||||
assert isinstance(ret, proto.WordRequest)
|
||||
(word, pos) = client.debug.read_recovery_word()
|
||||
|
||||
if pos != 0:
|
||||
ret = client.call_raw(proto.WordAck(word=mnemonic[pos - 1]))
|
||||
mnemonic[pos - 1] = None
|
||||
else:
|
||||
ret = client.call_raw(proto.WordAck(word=word))
|
||||
fakes += 1
|
||||
|
||||
# Workflow succesfully ended
|
||||
assert isinstance(ret, proto.Success)
|
||||
|
||||
# 12 expected fake words and all words of mnemonic are used
|
||||
assert fakes == 12
|
||||
assert mnemonic == [None] * 12
|
||||
|
||||
# Mnemonic is the same
|
||||
client.init_device()
|
||||
assert client.debug.state().mnemonic_secret == MNEMONIC12.encode()
|
||||
|
||||
assert client.features.pin_protection is False
|
||||
assert client.features.passphrase_protection is False
|
||||
|
||||
# Do pin & passphrase-protected action, PassphraseRequest should NOT be raised
|
||||
resp = client.call_raw(proto.GetAddress())
|
||||
assert isinstance(resp, proto.Address)
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_word_fail(self, client):
|
||||
ret = client.call_raw(
|
||||
proto.RecoveryDevice(
|
||||
word_count=12,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
label="label",
|
||||
language="en-US",
|
||||
enforce_wordlist=True,
|
||||
)
|
||||
)
|
||||
|
||||
# click through confirmation
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
# Enter PIN for second time
|
||||
pin_encoded = client.debug.encode_pin(PIN6)
|
||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
||||
|
||||
fakes = 0
|
||||
for _ in range(int(12 * 2)):
|
||||
assert isinstance(ret, proto.WordRequest)
|
||||
for _ in range(int(12 * 2)):
|
||||
(word, pos) = client.debug.read_recovery_word()
|
||||
if pos != 0:
|
||||
ret = client.call_raw(proto.WordAck(word="kwyjibo"))
|
||||
assert isinstance(ret, proto.Failure)
|
||||
break
|
||||
else:
|
||||
client.call_raw(proto.WordAck(word=word))
|
||||
(word, pos) = client.debug.read_recovery_word()
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_pin_fail(self, client):
|
||||
ret = client.call_raw(
|
||||
proto.RecoveryDevice(
|
||||
word_count=12,
|
||||
passphrase_protection=True,
|
||||
pin_protection=True,
|
||||
label="label",
|
||||
language="en-US",
|
||||
enforce_wordlist=True,
|
||||
)
|
||||
if pos != 0:
|
||||
ret = client.call_raw(proto.WordAck(word=mnemonic[pos - 1]))
|
||||
mnemonic[pos - 1] = None
|
||||
else:
|
||||
ret = client.call_raw(proto.WordAck(word=word))
|
||||
fakes += 1
|
||||
|
||||
# Workflow succesfully ended
|
||||
assert isinstance(ret, proto.Success)
|
||||
|
||||
# 12 expected fake words and all words of mnemonic are used
|
||||
assert fakes == 12
|
||||
assert mnemonic == [None] * 12
|
||||
|
||||
# Mnemonic is the same
|
||||
client.init_device()
|
||||
assert client.debug.state().mnemonic_secret == MNEMONIC12.encode()
|
||||
|
||||
assert client.features.pin_protection is True
|
||||
assert client.features.passphrase_protection is True
|
||||
|
||||
# Do passphrase-protected action, PassphraseRequest should be raised
|
||||
resp = client.call_raw(proto.GetAddress())
|
||||
assert isinstance(resp, proto.PassphraseRequest)
|
||||
client.call_raw(proto.Cancel())
|
||||
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_nopin_nopassphrase(client):
|
||||
mnemonic = MNEMONIC12.split(" ")
|
||||
ret = client.call_raw(
|
||||
proto.RecoveryDevice(
|
||||
word_count=12,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
label="label",
|
||||
language="en-US",
|
||||
enforce_wordlist=True,
|
||||
)
|
||||
)
|
||||
|
||||
# click through confirmation
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
fakes = 0
|
||||
for _ in range(int(12 * 2)):
|
||||
assert isinstance(ret, proto.WordRequest)
|
||||
(word, pos) = client.debug.read_recovery_word()
|
||||
|
||||
if pos != 0:
|
||||
ret = client.call_raw(proto.WordAck(word=mnemonic[pos - 1]))
|
||||
mnemonic[pos - 1] = None
|
||||
else:
|
||||
ret = client.call_raw(proto.WordAck(word=word))
|
||||
fakes += 1
|
||||
|
||||
# Workflow succesfully ended
|
||||
assert isinstance(ret, proto.Success)
|
||||
|
||||
# 12 expected fake words and all words of mnemonic are used
|
||||
assert fakes == 12
|
||||
assert mnemonic == [None] * 12
|
||||
|
||||
# Mnemonic is the same
|
||||
client.init_device()
|
||||
assert client.debug.state().mnemonic_secret == MNEMONIC12.encode()
|
||||
|
||||
assert client.features.pin_protection is False
|
||||
assert client.features.passphrase_protection is False
|
||||
|
||||
# Do pin & passphrase-protected action, PassphraseRequest should NOT be raised
|
||||
resp = client.call_raw(proto.GetAddress())
|
||||
assert isinstance(resp, proto.Address)
|
||||
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_word_fail(client):
|
||||
ret = client.call_raw(
|
||||
proto.RecoveryDevice(
|
||||
word_count=12,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
label="label",
|
||||
language="en-US",
|
||||
enforce_wordlist=True,
|
||||
)
|
||||
)
|
||||
|
||||
# click through confirmation
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
assert isinstance(ret, proto.WordRequest)
|
||||
for _ in range(int(12 * 2)):
|
||||
(word, pos) = client.debug.read_recovery_word()
|
||||
if pos != 0:
|
||||
ret = client.call_raw(proto.WordAck(word="kwyjibo"))
|
||||
assert isinstance(ret, proto.Failure)
|
||||
break
|
||||
else:
|
||||
client.call_raw(proto.WordAck(word=word))
|
||||
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_pin_fail(client):
|
||||
ret = client.call_raw(
|
||||
proto.RecoveryDevice(
|
||||
word_count=12,
|
||||
passphrase_protection=True,
|
||||
pin_protection=True,
|
||||
label="label",
|
||||
language="en-US",
|
||||
enforce_wordlist=True,
|
||||
)
|
||||
)
|
||||
|
||||
# click through confirmation
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
|
||||
# Enter PIN for first time
|
||||
pin_encoded = client.debug.encode_pin(PIN4)
|
||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
|
||||
# Enter PIN for second time, but different one
|
||||
pin_encoded = client.debug.encode_pin(PIN6)
|
||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
||||
|
||||
# Failure should be raised
|
||||
assert isinstance(ret, proto.Failure)
|
||||
|
||||
|
||||
def test_already_initialized(client):
|
||||
with pytest.raises(RuntimeError):
|
||||
device.recover(
|
||||
client, 12, False, False, "label", "en-US", client.mnemonic_callback
|
||||
)
|
||||
|
||||
# click through confirmation
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
|
||||
# Enter PIN for first time
|
||||
pin_encoded = client.debug.encode_pin(PIN4)
|
||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
|
||||
# Enter PIN for second time, but different one
|
||||
pin_encoded = client.debug.encode_pin(PIN6)
|
||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
||||
|
||||
# Failure should be raised
|
||||
assert isinstance(ret, proto.Failure)
|
||||
|
||||
def test_already_initialized(self, client):
|
||||
with pytest.raises(RuntimeError):
|
||||
device.recover(
|
||||
client, 12, False, False, "label", "en-US", client.mnemonic_callback
|
||||
)
|
||||
|
||||
ret = client.call_raw(
|
||||
proto.RecoveryDevice(
|
||||
word_count=12, type=proto.RecoveryDeviceType.ScrambledWords
|
||||
)
|
||||
ret = client.call_raw(
|
||||
proto.RecoveryDevice(
|
||||
word_count=12, type=proto.RecoveryDeviceType.ScrambledWords
|
||||
)
|
||||
assert isinstance(ret, proto.Failure)
|
||||
assert "Device is already initialized" in ret.message
|
||||
)
|
||||
assert isinstance(ret, proto.Failure)
|
||||
assert "Device is already initialized" in ret.message
|
||||
|
@ -21,6 +21,8 @@ from trezorlib import device, messages as proto
|
||||
|
||||
from ...common import generate_entropy
|
||||
|
||||
pytestmark = [pytest.mark.skip_t1]
|
||||
|
||||
|
||||
def reset_device(client, strength):
|
||||
# No PIN, no passphrase
|
||||
@ -88,149 +90,151 @@ def reset_device(client, strength):
|
||||
assert isinstance(resp, proto.Address)
|
||||
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
class TestMsgResetDevice:
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_128(self, client):
|
||||
reset_device(client, 128)
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_128(client):
|
||||
reset_device(client, 128)
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_192(self, client):
|
||||
reset_device(client, 192)
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_256_pin(self, client):
|
||||
external_entropy = b"zlutoucky kun upel divoke ody" * 2
|
||||
strength = 256
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_192(client):
|
||||
reset_device(client, 192)
|
||||
|
||||
ret = client.call_raw(
|
||||
proto.ResetDevice(
|
||||
display_random=True,
|
||||
strength=strength,
|
||||
passphrase_protection=True,
|
||||
pin_protection=True,
|
||||
language="en-US",
|
||||
label="test",
|
||||
)
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_256_pin(client):
|
||||
external_entropy = b"zlutoucky kun upel divoke ody" * 2
|
||||
strength = 256
|
||||
|
||||
ret = client.call_raw(
|
||||
proto.ResetDevice(
|
||||
display_random=True,
|
||||
strength=strength,
|
||||
passphrase_protection=True,
|
||||
pin_protection=True,
|
||||
language="en-US",
|
||||
label="test",
|
||||
)
|
||||
)
|
||||
|
||||
# Do you want ... ?
|
||||
# Do you want ... ?
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
# Entropy screen #1
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
# Entropy screen #2
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
|
||||
# Enter PIN for first time
|
||||
pin_encoded = client.debug.encode_pin("654")
|
||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
|
||||
# Enter PIN for second time
|
||||
pin_encoded = client.debug.encode_pin("654")
|
||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
||||
|
||||
# Provide entropy
|
||||
assert isinstance(ret, proto.EntropyRequest)
|
||||
internal_entropy = client.debug.state().reset_entropy
|
||||
ret = client.call_raw(proto.EntropyAck(entropy=external_entropy))
|
||||
|
||||
# Generate mnemonic locally
|
||||
entropy = generate_entropy(strength, internal_entropy, external_entropy)
|
||||
expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)
|
||||
|
||||
mnemonic = []
|
||||
for _ in range(strength // 32 * 3):
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
mnemonic.append(client.debug.read_reset_word())
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
client.call_raw(proto.ButtonAck())
|
||||
|
||||
# Entropy screen #1
|
||||
mnemonic = " ".join(mnemonic)
|
||||
|
||||
# Compare that device generated proper mnemonic for given entropies
|
||||
assert mnemonic == expected_mnemonic
|
||||
|
||||
mnemonic = []
|
||||
for _ in range(strength // 32 * 3):
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
mnemonic.append(client.debug.read_reset_word())
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
resp = client.call_raw(proto.ButtonAck())
|
||||
|
||||
# Entropy screen #2
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
assert isinstance(resp, proto.Success)
|
||||
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
mnemonic = " ".join(mnemonic)
|
||||
|
||||
# Enter PIN for first time
|
||||
pin_encoded = client.debug.encode_pin("654")
|
||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
# Compare that second pass printed out the same mnemonic once again
|
||||
assert mnemonic == expected_mnemonic
|
||||
|
||||
# Enter PIN for second time
|
||||
pin_encoded = client.debug.encode_pin("654")
|
||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
||||
# Check if device is properly initialized
|
||||
resp = client.call_raw(proto.Initialize())
|
||||
assert resp.initialized is True
|
||||
assert resp.needs_backup is False
|
||||
assert resp.pin_protection is True
|
||||
assert resp.passphrase_protection is True
|
||||
|
||||
# Provide entropy
|
||||
assert isinstance(ret, proto.EntropyRequest)
|
||||
internal_entropy = client.debug.state().reset_entropy
|
||||
ret = client.call_raw(proto.EntropyAck(entropy=external_entropy))
|
||||
# Do passphrase-protected action, PassphraseRequest should be raised
|
||||
resp = client.call_raw(proto.GetAddress())
|
||||
assert isinstance(resp, proto.PassphraseRequest)
|
||||
client.call_raw(proto.Cancel())
|
||||
|
||||
# Generate mnemonic locally
|
||||
entropy = generate_entropy(strength, internal_entropy, external_entropy)
|
||||
expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)
|
||||
|
||||
mnemonic = []
|
||||
for _ in range(strength // 32 * 3):
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
mnemonic.append(client.debug.read_reset_word())
|
||||
client.debug.press_yes()
|
||||
client.call_raw(proto.ButtonAck())
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_failed_pin(client):
|
||||
# external_entropy = b'zlutoucky kun upel divoke ody' * 2
|
||||
strength = 128
|
||||
|
||||
mnemonic = " ".join(mnemonic)
|
||||
|
||||
# Compare that device generated proper mnemonic for given entropies
|
||||
assert mnemonic == expected_mnemonic
|
||||
|
||||
mnemonic = []
|
||||
for _ in range(strength // 32 * 3):
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
mnemonic.append(client.debug.read_reset_word())
|
||||
client.debug.press_yes()
|
||||
resp = client.call_raw(proto.ButtonAck())
|
||||
|
||||
assert isinstance(resp, proto.Success)
|
||||
|
||||
mnemonic = " ".join(mnemonic)
|
||||
|
||||
# Compare that second pass printed out the same mnemonic once again
|
||||
assert mnemonic == expected_mnemonic
|
||||
|
||||
# Check if device is properly initialized
|
||||
resp = client.call_raw(proto.Initialize())
|
||||
assert resp.initialized is True
|
||||
assert resp.needs_backup is False
|
||||
assert resp.pin_protection is True
|
||||
assert resp.passphrase_protection is True
|
||||
|
||||
# Do passphrase-protected action, PassphraseRequest should be raised
|
||||
resp = client.call_raw(proto.GetAddress())
|
||||
assert isinstance(resp, proto.PassphraseRequest)
|
||||
client.call_raw(proto.Cancel())
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_failed_pin(self, client):
|
||||
# external_entropy = b'zlutoucky kun upel divoke ody' * 2
|
||||
strength = 128
|
||||
|
||||
ret = client.call_raw(
|
||||
proto.ResetDevice(
|
||||
display_random=True,
|
||||
strength=strength,
|
||||
passphrase_protection=True,
|
||||
pin_protection=True,
|
||||
language="en-US",
|
||||
label="test",
|
||||
)
|
||||
ret = client.call_raw(
|
||||
proto.ResetDevice(
|
||||
display_random=True,
|
||||
strength=strength,
|
||||
passphrase_protection=True,
|
||||
pin_protection=True,
|
||||
language="en-US",
|
||||
label="test",
|
||||
)
|
||||
)
|
||||
|
||||
# Do you want ... ?
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
# Do you want ... ?
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
# Entropy screen #1
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
# Entropy screen #1
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
# Entropy screen #2
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
# Entropy screen #2
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
|
||||
# Enter PIN for first time
|
||||
pin_encoded = client.debug.encode_pin("1234")
|
||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
# Enter PIN for first time
|
||||
pin_encoded = client.debug.encode_pin("1234")
|
||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
||||
assert isinstance(ret, proto.PinMatrixRequest)
|
||||
|
||||
# Enter PIN for second time
|
||||
pin_encoded = client.debug.encode_pin("6789")
|
||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
||||
# Enter PIN for second time
|
||||
pin_encoded = client.debug.encode_pin("6789")
|
||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
||||
|
||||
assert isinstance(ret, proto.Failure)
|
||||
assert isinstance(ret, proto.Failure)
|
||||
|
||||
def test_already_initialized(self, client):
|
||||
with pytest.raises(Exception):
|
||||
device.reset(client, False, 128, True, True, "label", "en-US")
|
||||
|
||||
def test_already_initialized(client):
|
||||
with pytest.raises(Exception):
|
||||
device.reset(client, False, 128, True, True, "label", "en-US")
|
||||
|
@ -21,151 +21,151 @@ from trezorlib import messages as proto
|
||||
|
||||
from ...common import generate_entropy
|
||||
|
||||
pytestmark = [pytest.mark.skip_t2]
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
class TestMsgResetDeviceSkipbackup:
|
||||
EXTERNAL_ENTROPY = b"zlutoucky kun upel divoke ody" * 2
|
||||
STRENGTH = 128
|
||||
|
||||
external_entropy = b"zlutoucky kun upel divoke ody" * 2
|
||||
strength = 128
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_skip_backup(self, client):
|
||||
ret = client.call_raw(
|
||||
proto.ResetDevice(
|
||||
display_random=False,
|
||||
strength=self.strength,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
language="en-US",
|
||||
label="test",
|
||||
skip_backup=True,
|
||||
)
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_skip_backup(client):
|
||||
ret = client.call_raw(
|
||||
proto.ResetDevice(
|
||||
display_random=False,
|
||||
strength=STRENGTH,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
language="en-US",
|
||||
label="test",
|
||||
skip_backup=True,
|
||||
)
|
||||
)
|
||||
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
# Provide entropy
|
||||
assert isinstance(ret, proto.EntropyRequest)
|
||||
internal_entropy = client.debug.state().reset_entropy
|
||||
ret = client.call_raw(proto.EntropyAck(entropy=EXTERNAL_ENTROPY))
|
||||
assert isinstance(ret, proto.Success)
|
||||
|
||||
# Check if device is properly initialized
|
||||
ret = client.call_raw(proto.Initialize())
|
||||
assert ret.initialized is True
|
||||
assert ret.needs_backup is True
|
||||
assert ret.unfinished_backup is False
|
||||
assert ret.no_backup is False
|
||||
|
||||
# Generate mnemonic locally
|
||||
entropy = generate_entropy(STRENGTH, internal_entropy, EXTERNAL_ENTROPY)
|
||||
expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)
|
||||
|
||||
# start Backup workflow
|
||||
ret = client.call_raw(proto.BackupDevice())
|
||||
|
||||
mnemonic = []
|
||||
for _ in range(STRENGTH // 32 * 3):
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
mnemonic.append(client.debug.read_reset_word())
|
||||
client.debug.press_yes()
|
||||
client.call_raw(proto.ButtonAck())
|
||||
|
||||
mnemonic = " ".join(mnemonic)
|
||||
|
||||
# Compare that device generated proper mnemonic for given entropies
|
||||
assert mnemonic == expected_mnemonic
|
||||
|
||||
mnemonic = []
|
||||
for _ in range(STRENGTH // 32 * 3):
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
mnemonic.append(client.debug.read_reset_word())
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
# Provide entropy
|
||||
assert isinstance(ret, proto.EntropyRequest)
|
||||
internal_entropy = client.debug.state().reset_entropy
|
||||
ret = client.call_raw(proto.EntropyAck(entropy=self.external_entropy))
|
||||
assert isinstance(ret, proto.Success)
|
||||
assert isinstance(ret, proto.Success)
|
||||
|
||||
# Check if device is properly initialized
|
||||
ret = client.call_raw(proto.Initialize())
|
||||
assert ret.initialized is True
|
||||
assert ret.needs_backup is True
|
||||
assert ret.unfinished_backup is False
|
||||
assert ret.no_backup is False
|
||||
mnemonic = " ".join(mnemonic)
|
||||
|
||||
# Generate mnemonic locally
|
||||
entropy = generate_entropy(
|
||||
self.strength, internal_entropy, self.external_entropy
|
||||
# Compare that second pass printed out the same mnemonic once again
|
||||
assert mnemonic == expected_mnemonic
|
||||
|
||||
# start backup again - should fail
|
||||
ret = client.call_raw(proto.BackupDevice())
|
||||
assert isinstance(ret, proto.Failure)
|
||||
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_skip_backup_break(client):
|
||||
ret = client.call_raw(
|
||||
proto.ResetDevice(
|
||||
display_random=False,
|
||||
strength=STRENGTH,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
language="en-US",
|
||||
label="test",
|
||||
skip_backup=True,
|
||||
)
|
||||
expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)
|
||||
)
|
||||
|
||||
# start Backup workflow
|
||||
ret = client.call_raw(proto.BackupDevice())
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
mnemonic = []
|
||||
for _ in range(self.strength // 32 * 3):
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
mnemonic.append(client.debug.read_reset_word())
|
||||
client.debug.press_yes()
|
||||
client.call_raw(proto.ButtonAck())
|
||||
# Provide entropy
|
||||
assert isinstance(ret, proto.EntropyRequest)
|
||||
ret = client.call_raw(proto.EntropyAck(entropy=EXTERNAL_ENTROPY))
|
||||
assert isinstance(ret, proto.Success)
|
||||
|
||||
mnemonic = " ".join(mnemonic)
|
||||
# Check if device is properly initialized
|
||||
ret = client.call_raw(proto.Initialize())
|
||||
assert ret.initialized is True
|
||||
assert ret.needs_backup is True
|
||||
assert ret.unfinished_backup is False
|
||||
assert ret.no_backup is False
|
||||
|
||||
# Compare that device generated proper mnemonic for given entropies
|
||||
assert mnemonic == expected_mnemonic
|
||||
# start Backup workflow
|
||||
ret = client.call_raw(proto.BackupDevice())
|
||||
|
||||
mnemonic = []
|
||||
for _ in range(self.strength // 32 * 3):
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
mnemonic.append(client.debug.read_reset_word())
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
# send Initialize -> break workflow
|
||||
ret = client.call_raw(proto.Initialize())
|
||||
assert isinstance(ret, proto.Features)
|
||||
assert ret.initialized is True
|
||||
assert ret.needs_backup is False
|
||||
assert ret.unfinished_backup is True
|
||||
assert ret.no_backup is False
|
||||
|
||||
assert isinstance(ret, proto.Success)
|
||||
# start backup again - should fail
|
||||
ret = client.call_raw(proto.BackupDevice())
|
||||
assert isinstance(ret, proto.Failure)
|
||||
|
||||
mnemonic = " ".join(mnemonic)
|
||||
# read Features again
|
||||
ret = client.call_raw(proto.Initialize())
|
||||
assert isinstance(ret, proto.Features)
|
||||
assert ret.initialized is True
|
||||
assert ret.needs_backup is False
|
||||
assert ret.unfinished_backup is True
|
||||
assert ret.no_backup is False
|
||||
|
||||
# Compare that second pass printed out the same mnemonic once again
|
||||
assert mnemonic == expected_mnemonic
|
||||
|
||||
# start backup again - should fail
|
||||
ret = client.call_raw(proto.BackupDevice())
|
||||
assert isinstance(ret, proto.Failure)
|
||||
def test_initialized_device_backup_fail(client):
|
||||
ret = client.call_raw(proto.BackupDevice())
|
||||
assert isinstance(ret, proto.Failure)
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_skip_backup_break(self, client):
|
||||
ret = client.call_raw(
|
||||
proto.ResetDevice(
|
||||
display_random=False,
|
||||
strength=self.strength,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
language="en-US",
|
||||
label="test",
|
||||
skip_backup=True,
|
||||
)
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_skip_backup_show_entropy_fail(client):
|
||||
ret = client.call_raw(
|
||||
proto.ResetDevice(
|
||||
display_random=True,
|
||||
strength=STRENGTH,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
language="en-US",
|
||||
label="test",
|
||||
skip_backup=True,
|
||||
)
|
||||
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
# Provide entropy
|
||||
assert isinstance(ret, proto.EntropyRequest)
|
||||
ret = client.call_raw(proto.EntropyAck(entropy=self.external_entropy))
|
||||
assert isinstance(ret, proto.Success)
|
||||
|
||||
# Check if device is properly initialized
|
||||
ret = client.call_raw(proto.Initialize())
|
||||
assert ret.initialized is True
|
||||
assert ret.needs_backup is True
|
||||
assert ret.unfinished_backup is False
|
||||
assert ret.no_backup is False
|
||||
|
||||
# start Backup workflow
|
||||
ret = client.call_raw(proto.BackupDevice())
|
||||
|
||||
# send Initialize -> break workflow
|
||||
ret = client.call_raw(proto.Initialize())
|
||||
assert isinstance(ret, proto.Features)
|
||||
assert ret.initialized is True
|
||||
assert ret.needs_backup is False
|
||||
assert ret.unfinished_backup is True
|
||||
assert ret.no_backup is False
|
||||
|
||||
# start backup again - should fail
|
||||
ret = client.call_raw(proto.BackupDevice())
|
||||
assert isinstance(ret, proto.Failure)
|
||||
|
||||
# read Features again
|
||||
ret = client.call_raw(proto.Initialize())
|
||||
assert isinstance(ret, proto.Features)
|
||||
assert ret.initialized is True
|
||||
assert ret.needs_backup is False
|
||||
assert ret.unfinished_backup is True
|
||||
assert ret.no_backup is False
|
||||
|
||||
def test_initialized_device_backup_fail(self, client):
|
||||
ret = client.call_raw(proto.BackupDevice())
|
||||
assert isinstance(ret, proto.Failure)
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_skip_backup_show_entropy_fail(self, client):
|
||||
ret = client.call_raw(
|
||||
proto.ResetDevice(
|
||||
display_random=True,
|
||||
strength=self.strength,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
language="en-US",
|
||||
label="test",
|
||||
skip_backup=True,
|
||||
)
|
||||
)
|
||||
assert isinstance(ret, proto.Failure)
|
||||
)
|
||||
assert isinstance(ret, proto.Failure)
|
||||
|
@ -30,6 +30,8 @@ from ...common import (
|
||||
read_and_confirm_mnemonic,
|
||||
)
|
||||
|
||||
pytestmark = [pytest.mark.skip_t1]
|
||||
|
||||
EXTERNAL_ENTROPY = b"zlutoucky kun upel divoke ody" * 2
|
||||
|
||||
|
||||
@ -105,218 +107,219 @@ def reset_device(client, strength):
|
||||
device.backup(client)
|
||||
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgResetDeviceT2:
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device(self, client):
|
||||
reset_device(client, 128) # 12 words
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device(client):
|
||||
reset_device(client, 128) # 12 words
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_192(self, client):
|
||||
reset_device(client, 192) # 18 words
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_pin(self, client):
|
||||
mnemonic = None
|
||||
strength = 256 # 24 words
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_192(client):
|
||||
reset_device(client, 192) # 18 words
|
||||
|
||||
def input_flow():
|
||||
nonlocal mnemonic
|
||||
|
||||
# Confirm Reset
|
||||
br = yield
|
||||
assert br.code == B.ResetDevice
|
||||
client.debug.press_yes()
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_pin(client):
|
||||
mnemonic = None
|
||||
strength = 256 # 24 words
|
||||
|
||||
# Enter new PIN
|
||||
yield
|
||||
client.debug.input("654")
|
||||
|
||||
# Confirm PIN
|
||||
yield
|
||||
client.debug.input("654")
|
||||
|
||||
# Confirm entropy
|
||||
br = yield
|
||||
assert br.code == B.ResetDevice
|
||||
client.debug.press_yes()
|
||||
|
||||
# Backup your seed
|
||||
br = yield
|
||||
assert br.code == B.ResetDevice
|
||||
client.debug.press_yes()
|
||||
|
||||
# Confirm warning
|
||||
br = yield
|
||||
assert br.code == B.ResetDevice
|
||||
client.debug.press_yes()
|
||||
|
||||
# mnemonic phrases
|
||||
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||
|
||||
# confirm recovery seed check
|
||||
br = yield
|
||||
assert br.code == B.Success
|
||||
client.debug.press_yes()
|
||||
|
||||
# confirm success
|
||||
br = yield
|
||||
assert br.code == B.Success
|
||||
client.debug.press_yes()
|
||||
|
||||
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
|
||||
with mock.patch("os.urandom", os_urandom), client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.PinEntry),
|
||||
proto.ButtonRequest(code=B.PinEntry),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.EntropyRequest(),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.Success),
|
||||
proto.ButtonRequest(code=B.Success),
|
||||
proto.Success,
|
||||
proto.Features,
|
||||
]
|
||||
)
|
||||
client.set_input_flow(input_flow)
|
||||
|
||||
# PIN, passphrase, display random
|
||||
device.reset(
|
||||
client,
|
||||
display_random=True,
|
||||
strength=strength,
|
||||
passphrase_protection=True,
|
||||
pin_protection=True,
|
||||
label="test",
|
||||
language="en-US",
|
||||
)
|
||||
|
||||
# generate mnemonic locally
|
||||
internal_entropy = client.debug.state().reset_entropy
|
||||
entropy = generate_entropy(strength, internal_entropy, EXTERNAL_ENTROPY)
|
||||
expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)
|
||||
|
||||
# Compare that device generated proper mnemonic for given entropies
|
||||
assert mnemonic == expected_mnemonic
|
||||
|
||||
# Check if device is properly initialized
|
||||
resp = client.call_raw(proto.Initialize())
|
||||
assert resp.initialized is True
|
||||
assert resp.needs_backup is False
|
||||
assert resp.pin_protection is True
|
||||
assert resp.passphrase_protection is True
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_failed_check(self, client):
|
||||
mnemonic = None
|
||||
strength = 256 # 24 words
|
||||
|
||||
def input_flow():
|
||||
nonlocal mnemonic
|
||||
# 1. Confirm Reset
|
||||
# 2. Backup your seed
|
||||
# 3. Confirm warning
|
||||
yield from click_through(client.debug, screens=3, code=B.ResetDevice)
|
||||
|
||||
# mnemonic phrases, wrong answer
|
||||
mnemonic = yield from read_and_confirm_mnemonic(
|
||||
client.debug, choose_wrong=True
|
||||
)
|
||||
|
||||
# warning screen
|
||||
br = yield
|
||||
assert br.code == B.ResetDevice
|
||||
client.debug.press_yes()
|
||||
|
||||
# mnemonic phrases
|
||||
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||
|
||||
# confirm recovery seed check
|
||||
br = yield
|
||||
assert br.code == B.Success
|
||||
client.debug.press_yes()
|
||||
|
||||
# confirm success
|
||||
br = yield
|
||||
assert br.code == B.Success
|
||||
client.debug.press_yes()
|
||||
|
||||
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
|
||||
with mock.patch("os.urandom", os_urandom), client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.EntropyRequest(),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.Success),
|
||||
proto.ButtonRequest(code=B.Success),
|
||||
proto.Success,
|
||||
proto.Features,
|
||||
]
|
||||
)
|
||||
client.set_input_flow(input_flow)
|
||||
|
||||
# PIN, passphrase, display random
|
||||
device.reset(
|
||||
client,
|
||||
display_random=False,
|
||||
strength=strength,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
label="test",
|
||||
language="en-US",
|
||||
)
|
||||
|
||||
# generate mnemonic locally
|
||||
internal_entropy = client.debug.state().reset_entropy
|
||||
entropy = generate_entropy(strength, internal_entropy, EXTERNAL_ENTROPY)
|
||||
expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)
|
||||
|
||||
# Compare that device generated proper mnemonic for given entropies
|
||||
assert mnemonic == expected_mnemonic
|
||||
|
||||
# Check if device is properly initialized
|
||||
resp = client.call_raw(proto.Initialize())
|
||||
assert resp.initialized is True
|
||||
assert resp.needs_backup is False
|
||||
assert resp.pin_protection is False
|
||||
assert resp.passphrase_protection is False
|
||||
assert resp.backup_type is proto.BackupType.Bip39
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_failed_pin(self, client):
|
||||
# external_entropy = b'zlutoucky kun upel divoke ody' * 2
|
||||
strength = 128
|
||||
ret = client.call_raw(
|
||||
proto.ResetDevice(strength=strength, pin_protection=True, label="test")
|
||||
)
|
||||
def input_flow():
|
||||
nonlocal mnemonic
|
||||
|
||||
# Confirm Reset
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
br = yield
|
||||
assert br.code == B.ResetDevice
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
# Enter PIN for first time
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
# Enter new PIN
|
||||
yield
|
||||
client.debug.input("654")
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
# Enter PIN for second time
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.input("456")
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
# Confirm PIN
|
||||
yield
|
||||
client.debug.input("654")
|
||||
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
# Confirm entropy
|
||||
br = yield
|
||||
assert br.code == B.ResetDevice
|
||||
client.debug.press_yes()
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_already_initialized(self, client):
|
||||
with pytest.raises(Exception):
|
||||
device.reset(client, False, 128, True, True, "label", "en-US")
|
||||
# Backup your seed
|
||||
br = yield
|
||||
assert br.code == B.ResetDevice
|
||||
client.debug.press_yes()
|
||||
|
||||
# Confirm warning
|
||||
br = yield
|
||||
assert br.code == B.ResetDevice
|
||||
client.debug.press_yes()
|
||||
|
||||
# mnemonic phrases
|
||||
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||
|
||||
# confirm recovery seed check
|
||||
br = yield
|
||||
assert br.code == B.Success
|
||||
client.debug.press_yes()
|
||||
|
||||
# confirm success
|
||||
br = yield
|
||||
assert br.code == B.Success
|
||||
client.debug.press_yes()
|
||||
|
||||
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
|
||||
with mock.patch("os.urandom", os_urandom), client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.PinEntry),
|
||||
proto.ButtonRequest(code=B.PinEntry),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.EntropyRequest(),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.Success),
|
||||
proto.ButtonRequest(code=B.Success),
|
||||
proto.Success,
|
||||
proto.Features,
|
||||
]
|
||||
)
|
||||
client.set_input_flow(input_flow)
|
||||
|
||||
# PIN, passphrase, display random
|
||||
device.reset(
|
||||
client,
|
||||
display_random=True,
|
||||
strength=strength,
|
||||
passphrase_protection=True,
|
||||
pin_protection=True,
|
||||
label="test",
|
||||
language="en-US",
|
||||
)
|
||||
|
||||
# generate mnemonic locally
|
||||
internal_entropy = client.debug.state().reset_entropy
|
||||
entropy = generate_entropy(strength, internal_entropy, EXTERNAL_ENTROPY)
|
||||
expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)
|
||||
|
||||
# Compare that device generated proper mnemonic for given entropies
|
||||
assert mnemonic == expected_mnemonic
|
||||
|
||||
# Check if device is properly initialized
|
||||
resp = client.call_raw(proto.Initialize())
|
||||
assert resp.initialized is True
|
||||
assert resp.needs_backup is False
|
||||
assert resp.pin_protection is True
|
||||
assert resp.passphrase_protection is True
|
||||
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_failed_check(client):
|
||||
mnemonic = None
|
||||
strength = 256 # 24 words
|
||||
|
||||
def input_flow():
|
||||
nonlocal mnemonic
|
||||
# 1. Confirm Reset
|
||||
# 2. Backup your seed
|
||||
# 3. Confirm warning
|
||||
yield from click_through(client.debug, screens=3, code=B.ResetDevice)
|
||||
|
||||
# mnemonic phrases, wrong answer
|
||||
mnemonic = yield from read_and_confirm_mnemonic(client.debug, choose_wrong=True)
|
||||
|
||||
# warning screen
|
||||
br = yield
|
||||
assert br.code == B.ResetDevice
|
||||
client.debug.press_yes()
|
||||
|
||||
# mnemonic phrases
|
||||
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||
|
||||
# confirm recovery seed check
|
||||
br = yield
|
||||
assert br.code == B.Success
|
||||
client.debug.press_yes()
|
||||
|
||||
# confirm success
|
||||
br = yield
|
||||
assert br.code == B.Success
|
||||
client.debug.press_yes()
|
||||
|
||||
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
|
||||
with mock.patch("os.urandom", os_urandom), client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.EntropyRequest(),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.Success),
|
||||
proto.ButtonRequest(code=B.Success),
|
||||
proto.Success,
|
||||
proto.Features,
|
||||
]
|
||||
)
|
||||
client.set_input_flow(input_flow)
|
||||
|
||||
# PIN, passphrase, display random
|
||||
device.reset(
|
||||
client,
|
||||
display_random=False,
|
||||
strength=strength,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
label="test",
|
||||
language="en-US",
|
||||
)
|
||||
|
||||
# generate mnemonic locally
|
||||
internal_entropy = client.debug.state().reset_entropy
|
||||
entropy = generate_entropy(strength, internal_entropy, EXTERNAL_ENTROPY)
|
||||
expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)
|
||||
|
||||
# Compare that device generated proper mnemonic for given entropies
|
||||
assert mnemonic == expected_mnemonic
|
||||
|
||||
# Check if device is properly initialized
|
||||
resp = client.call_raw(proto.Initialize())
|
||||
assert resp.initialized is True
|
||||
assert resp.needs_backup is False
|
||||
assert resp.pin_protection is False
|
||||
assert resp.passphrase_protection is False
|
||||
assert resp.backup_type is proto.BackupType.Bip39
|
||||
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_failed_pin(client):
|
||||
# external_entropy = b'zlutoucky kun upel divoke ody' * 2
|
||||
strength = 128
|
||||
ret = client.call_raw(
|
||||
proto.ResetDevice(strength=strength, pin_protection=True, label="test")
|
||||
)
|
||||
|
||||
# Confirm Reset
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.press_yes()
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
# Enter PIN for first time
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.input("654")
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
# Enter PIN for second time
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
client.debug.input("456")
|
||||
ret = client.call_raw(proto.ButtonAck())
|
||||
|
||||
assert isinstance(ret, proto.ButtonRequest)
|
||||
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_already_initialized(client):
|
||||
with pytest.raises(Exception):
|
||||
device.reset(client, False, 128, True, True, "label", "en-US")
|
||||
|
@ -25,116 +25,116 @@ from trezorlib.messages import BackupType, ButtonRequestType as B
|
||||
|
||||
from ...common import click_through, generate_entropy, read_and_confirm_mnemonic
|
||||
|
||||
pytestmark = [pytest.mark.skip_t1]
|
||||
|
||||
EXTERNAL_ENTROPY = b"zlutoucky kun upel divoke ody" * 2
|
||||
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgResetDeviceT2:
|
||||
# TODO: test with different options
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_slip39_advanced(self, client):
|
||||
strength = 128
|
||||
member_threshold = 3
|
||||
all_mnemonics = []
|
||||
# TODO: test with different options
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_slip39_advanced(client):
|
||||
strength = 128
|
||||
member_threshold = 3
|
||||
all_mnemonics = []
|
||||
|
||||
def input_flow():
|
||||
# 1. Confirm Reset
|
||||
# 2. Backup your seed
|
||||
# 3. Confirm warning
|
||||
# 4. shares info
|
||||
# 5. Set & Confirm number of groups
|
||||
# 6. threshold info
|
||||
# 7. Set & confirm group threshold value
|
||||
# 8-17: for each of 5 groups:
|
||||
# 1. Set & Confirm number of shares
|
||||
# 2. Set & confirm share threshold value
|
||||
# 18. Confirm show seeds
|
||||
yield from click_through(client.debug, screens=18, code=B.ResetDevice)
|
||||
def input_flow():
|
||||
# 1. Confirm Reset
|
||||
# 2. Backup your seed
|
||||
# 3. Confirm warning
|
||||
# 4. shares info
|
||||
# 5. Set & Confirm number of groups
|
||||
# 6. threshold info
|
||||
# 7. Set & confirm group threshold value
|
||||
# 8-17: for each of 5 groups:
|
||||
# 1. Set & Confirm number of shares
|
||||
# 2. Set & confirm share threshold value
|
||||
# 18. Confirm show seeds
|
||||
yield from click_through(client.debug, screens=18, code=B.ResetDevice)
|
||||
|
||||
# show & confirm shares for all groups
|
||||
for _g in range(5):
|
||||
for _h in range(5):
|
||||
# mnemonic phrases
|
||||
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||
all_mnemonics.append(mnemonic)
|
||||
# show & confirm shares for all groups
|
||||
for _g in range(5):
|
||||
for _h in range(5):
|
||||
# mnemonic phrases
|
||||
mnemonic = yield from read_and_confirm_mnemonic(client.debug)
|
||||
all_mnemonics.append(mnemonic)
|
||||
|
||||
# Confirm continue to next share
|
||||
br = yield
|
||||
assert br.code == B.Success
|
||||
client.debug.press_yes()
|
||||
# Confirm continue to next share
|
||||
br = yield
|
||||
assert br.code == B.Success
|
||||
client.debug.press_yes()
|
||||
|
||||
# safety warning
|
||||
br = yield
|
||||
assert br.code == B.Success
|
||||
client.debug.press_yes()
|
||||
# safety warning
|
||||
br = yield
|
||||
assert br.code == B.Success
|
||||
client.debug.press_yes()
|
||||
|
||||
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
|
||||
with mock.patch("os.urandom", os_urandom), client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.EntropyRequest(),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice), # group #1 counts
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice), # group #2 counts
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice), # group #3 counts
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice), # group #4 counts
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice), # group #5 counts
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
]
|
||||
+ [
|
||||
# individual mnemonic
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.Success),
|
||||
]
|
||||
* (5 * 5) # groups * shares
|
||||
+ [
|
||||
proto.ButtonRequest(code=B.Success),
|
||||
proto.Success,
|
||||
proto.Features,
|
||||
]
|
||||
)
|
||||
client.set_input_flow(input_flow)
|
||||
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
|
||||
with mock.patch("os.urandom", os_urandom), client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.EntropyRequest(),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice), # group #1 counts
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice), # group #2 counts
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice), # group #3 counts
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice), # group #4 counts
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.ResetDevice), # group #5 counts
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
]
|
||||
+ [
|
||||
# individual mnemonic
|
||||
proto.ButtonRequest(code=B.ResetDevice),
|
||||
proto.ButtonRequest(code=B.Success),
|
||||
]
|
||||
* (5 * 5) # groups * shares
|
||||
+ [
|
||||
proto.ButtonRequest(code=B.Success),
|
||||
proto.Success,
|
||||
proto.Features,
|
||||
]
|
||||
)
|
||||
client.set_input_flow(input_flow)
|
||||
|
||||
# No PIN, no passphrase, don't display random
|
||||
device.reset(
|
||||
client,
|
||||
display_random=False,
|
||||
strength=strength,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
label="test",
|
||||
language="en-US",
|
||||
backup_type=BackupType.Slip39_Advanced,
|
||||
)
|
||||
# No PIN, no passphrase, don't display random
|
||||
device.reset(
|
||||
client,
|
||||
display_random=False,
|
||||
strength=strength,
|
||||
passphrase_protection=False,
|
||||
pin_protection=False,
|
||||
label="test",
|
||||
language="en-US",
|
||||
backup_type=BackupType.Slip39_Advanced,
|
||||
)
|
||||
|
||||
# generate secret locally
|
||||
internal_entropy = client.debug.state().reset_entropy
|
||||
secret = generate_entropy(strength, internal_entropy, EXTERNAL_ENTROPY)
|
||||
# generate secret locally
|
||||
internal_entropy = client.debug.state().reset_entropy
|
||||
secret = generate_entropy(strength, internal_entropy, EXTERNAL_ENTROPY)
|
||||
|
||||
# validate that all combinations will result in the correct master secret
|
||||
validate_mnemonics(all_mnemonics, member_threshold, secret)
|
||||
# validate that all combinations will result in the correct master secret
|
||||
validate_mnemonics(all_mnemonics, member_threshold, secret)
|
||||
|
||||
# Check if device is properly initialized
|
||||
assert client.features.initialized is True
|
||||
assert client.features.needs_backup is False
|
||||
assert client.features.pin_protection is False
|
||||
assert client.features.passphrase_protection is False
|
||||
assert client.features.backup_type is BackupType.Slip39_Advanced
|
||||
# Check if device is properly initialized
|
||||
assert client.features.initialized is True
|
||||
assert client.features.needs_backup is False
|
||||
assert client.features.pin_protection is False
|
||||
assert client.features.passphrase_protection is False
|
||||
assert client.features.backup_type is BackupType.Slip39_Advanced
|
||||
|
||||
# backup attempt fails because backup was done in reset
|
||||
with pytest.raises(TrezorFailure, match="ProcessError: Seed already backed up"):
|
||||
device.backup(client)
|
||||
# backup attempt fails because backup was done in reset
|
||||
with pytest.raises(TrezorFailure, match="ProcessError: Seed already backed up"):
|
||||
device.backup(client)
|
||||
|
||||
|
||||
def validate_mnemonics(mnemonics, threshold, expected_ems):
|
||||
|
@ -31,6 +31,8 @@ from ...common import (
|
||||
read_and_confirm_mnemonic,
|
||||
)
|
||||
|
||||
pytestmark = [pytest.mark.skip_t1]
|
||||
|
||||
|
||||
def reset_device(client, strength):
|
||||
member_threshold = 3
|
||||
@ -122,15 +124,14 @@ def reset_device(client, strength):
|
||||
device.backup(client)
|
||||
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgResetDeviceT2:
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_slip39_basic(self, client):
|
||||
reset_device(client, 128)
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_slip39_basic(client):
|
||||
reset_device(client, 128)
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_slip39_basic_256(self, client):
|
||||
reset_device(client, 256)
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_reset_device_slip39_basic_256(client):
|
||||
reset_device(client, 256)
|
||||
|
||||
|
||||
def validate_mnemonics(mnemonics, threshold, expected_ems):
|
||||
|
@ -25,24 +25,27 @@ CUSTOM_MNEMONIC = (
|
||||
"whip snack decide blur unfold fiction pumpkin athlete"
|
||||
)
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.ripple,
|
||||
pytest.mark.skip_t1, # T1 support is not planned
|
||||
]
|
||||
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.ripple
|
||||
@pytest.mark.skip_t1 # T1 support is not planned
|
||||
class TestMsgRippleGetAddress:
|
||||
def test_ripple_get_address(self, client):
|
||||
# data from https://iancoleman.io/bip39/
|
||||
address = get_address(client, parse_path("m/44'/144'/0'/0/0"))
|
||||
assert address == "rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H"
|
||||
address = get_address(client, parse_path("m/44'/144'/0'/0/1"))
|
||||
assert address == "rBKz5MC2iXdoS3XgnNSYmF69K1Yo4NS3Ws"
|
||||
address = get_address(client, parse_path("m/44'/144'/1'/0/0"))
|
||||
assert address == "rJX2KwzaLJDyFhhtXKi3htaLfaUH2tptEX"
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=CUSTOM_MNEMONIC)
|
||||
def test_ripple_get_address_other(self, client):
|
||||
# data from https://github.com/you21979/node-ripple-bip32/blob/master/test/test.js
|
||||
address = get_address(client, parse_path("m/44'/144'/0'/0/0"))
|
||||
assert address == "r4ocGE47gm4G4LkA9mriVHQqzpMLBTgnTY"
|
||||
address = get_address(client, parse_path("m/44'/144'/0'/0/1"))
|
||||
assert address == "rUt9ULSrUvfCmke8HTFU1szbmFpWzVbBXW"
|
||||
def test_ripple_get_address(client):
|
||||
# data from https://iancoleman.io/bip39/
|
||||
address = get_address(client, parse_path("m/44'/144'/0'/0/0"))
|
||||
assert address == "rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H"
|
||||
address = get_address(client, parse_path("m/44'/144'/0'/0/1"))
|
||||
assert address == "rBKz5MC2iXdoS3XgnNSYmF69K1Yo4NS3Ws"
|
||||
address = get_address(client, parse_path("m/44'/144'/1'/0/0"))
|
||||
assert address == "rJX2KwzaLJDyFhhtXKi3htaLfaUH2tptEX"
|
||||
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=CUSTOM_MNEMONIC)
|
||||
def test_ripple_get_address_other(client):
|
||||
# data from https://github.com/you21979/node-ripple-bip32/blob/master/test/test.js
|
||||
address = get_address(client, parse_path("m/44'/144'/0'/0/0"))
|
||||
assert address == "r4ocGE47gm4G4LkA9mriVHQqzpMLBTgnTY"
|
||||
address = get_address(client, parse_path("m/44'/144'/0'/0/1"))
|
||||
assert address == "rUt9ULSrUvfCmke8HTFU1szbmFpWzVbBXW"
|
||||
|
@ -20,94 +20,97 @@ from trezorlib import ripple
|
||||
from trezorlib.exceptions import TrezorFailure
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.ripple,
|
||||
pytest.mark.skip_t1, # T1 support is not planned
|
||||
]
|
||||
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.ripple
|
||||
@pytest.mark.skip_t1 # T1 support is not planned
|
||||
class TestMsgRippleSignTx:
|
||||
def test_ripple_sign_simple_tx(self, client):
|
||||
msg = ripple.create_sign_tx_msg(
|
||||
{
|
||||
"TransactionType": "Payment",
|
||||
"Payment": {
|
||||
"Amount": 100000000,
|
||||
"Destination": "rBKz5MC2iXdoS3XgnNSYmF69K1Yo4NS3Ws",
|
||||
},
|
||||
"Flags": 0x80000000,
|
||||
"Fee": 100000,
|
||||
"Sequence": 25,
|
||||
}
|
||||
)
|
||||
resp = ripple.sign_tx(client, parse_path("m/44'/144'/0'/0/0"), msg)
|
||||
assert (
|
||||
resp.signature.hex()
|
||||
== "3045022100e243ef623675eeeb95965c35c3e06d63a9fc68bb37e17dc87af9c0af83ec057e02206ca8aa5eaab8396397aef6d38d25710441faf7c79d292ee1d627df15ad9346c0"
|
||||
)
|
||||
assert (
|
||||
resp.serialized_tx.hex()
|
||||
== "12000022800000002400000019614000000005f5e1006840000000000186a0732102131facd1eab748d6cddc492f54b04e8c35658894f4add2232ebc5afe7521dbe474473045022100e243ef623675eeeb95965c35c3e06d63a9fc68bb37e17dc87af9c0af83ec057e02206ca8aa5eaab8396397aef6d38d25710441faf7c79d292ee1d627df15ad9346c081148fb40e1ffa5d557ce9851a535af94965e0dd098883147148ebebf7304ccdf1676fefcf9734cf1e780826"
|
||||
)
|
||||
|
||||
msg = ripple.create_sign_tx_msg(
|
||||
{
|
||||
"TransactionType": "Payment",
|
||||
"Payment": {
|
||||
"Amount": 1,
|
||||
"Destination": "rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H",
|
||||
},
|
||||
"Fee": 10,
|
||||
"Sequence": 1,
|
||||
}
|
||||
)
|
||||
resp = ripple.sign_tx(client, parse_path("m/44'/144'/0'/0/2"), msg)
|
||||
assert (
|
||||
resp.signature.hex()
|
||||
== "3044022069900e6e578997fad5189981b74b16badc7ba8b9f1052694033fa2779113ddc002206c8006ada310edf099fb22c0c12073550c8fc73247b236a974c5f1144831dd5f"
|
||||
)
|
||||
assert (
|
||||
resp.serialized_tx.hex()
|
||||
== "1200002280000000240000000161400000000000000168400000000000000a732103dbed1e77cb91a005e2ec71afbccce5444c9be58276665a3859040f692de8fed274463044022069900e6e578997fad5189981b74b16badc7ba8b9f1052694033fa2779113ddc002206c8006ada310edf099fb22c0c12073550c8fc73247b236a974c5f1144831dd5f8114bdf86f3ae715ba346b7772ea0e133f48828b766483148fb40e1ffa5d557ce9851a535af94965e0dd0988"
|
||||
)
|
||||
def test_ripple_sign_simple_tx(client):
|
||||
msg = ripple.create_sign_tx_msg(
|
||||
{
|
||||
"TransactionType": "Payment",
|
||||
"Payment": {
|
||||
"Amount": 100000000,
|
||||
"Destination": "rBKz5MC2iXdoS3XgnNSYmF69K1Yo4NS3Ws",
|
||||
},
|
||||
"Flags": 0x80000000,
|
||||
"Fee": 100000,
|
||||
"Sequence": 25,
|
||||
}
|
||||
)
|
||||
resp = ripple.sign_tx(client, parse_path("m/44'/144'/0'/0/0"), msg)
|
||||
assert (
|
||||
resp.signature.hex()
|
||||
== "3045022100e243ef623675eeeb95965c35c3e06d63a9fc68bb37e17dc87af9c0af83ec057e02206ca8aa5eaab8396397aef6d38d25710441faf7c79d292ee1d627df15ad9346c0"
|
||||
)
|
||||
assert (
|
||||
resp.serialized_tx.hex()
|
||||
== "12000022800000002400000019614000000005f5e1006840000000000186a0732102131facd1eab748d6cddc492f54b04e8c35658894f4add2232ebc5afe7521dbe474473045022100e243ef623675eeeb95965c35c3e06d63a9fc68bb37e17dc87af9c0af83ec057e02206ca8aa5eaab8396397aef6d38d25710441faf7c79d292ee1d627df15ad9346c081148fb40e1ffa5d557ce9851a535af94965e0dd098883147148ebebf7304ccdf1676fefcf9734cf1e780826"
|
||||
)
|
||||
|
||||
msg = ripple.create_sign_tx_msg(
|
||||
{
|
||||
"TransactionType": "Payment",
|
||||
"Payment": {
|
||||
"Amount": 100000009,
|
||||
"Destination": "rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H",
|
||||
"DestinationTag": 123456,
|
||||
},
|
||||
"Flags": 0,
|
||||
"Fee": 100,
|
||||
"Sequence": 100,
|
||||
"LastLedgerSequence": 333111,
|
||||
}
|
||||
)
|
||||
resp = ripple.sign_tx(client, parse_path("m/44'/144'/0'/0/2"), msg)
|
||||
assert (
|
||||
resp.signature.hex()
|
||||
== "30450221008770743a472bb2d1c746a53ef131cc17cc118d538ec910ca928d221db4494cf702201e4ef242d6c3bff110c3cc3897a471fed0f5ac10987ea57da63f98dfa01e94df"
|
||||
)
|
||||
assert (
|
||||
resp.serialized_tx.hex()
|
||||
== "120000228000000024000000642e0001e240201b00051537614000000005f5e109684000000000000064732103dbed1e77cb91a005e2ec71afbccce5444c9be58276665a3859040f692de8fed2744730450221008770743a472bb2d1c746a53ef131cc17cc118d538ec910ca928d221db4494cf702201e4ef242d6c3bff110c3cc3897a471fed0f5ac10987ea57da63f98dfa01e94df8114bdf86f3ae715ba346b7772ea0e133f48828b766483148fb40e1ffa5d557ce9851a535af94965e0dd0988"
|
||||
)
|
||||
msg = ripple.create_sign_tx_msg(
|
||||
{
|
||||
"TransactionType": "Payment",
|
||||
"Payment": {
|
||||
"Amount": 1,
|
||||
"Destination": "rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H",
|
||||
},
|
||||
"Fee": 10,
|
||||
"Sequence": 1,
|
||||
}
|
||||
)
|
||||
resp = ripple.sign_tx(client, parse_path("m/44'/144'/0'/0/2"), msg)
|
||||
assert (
|
||||
resp.signature.hex()
|
||||
== "3044022069900e6e578997fad5189981b74b16badc7ba8b9f1052694033fa2779113ddc002206c8006ada310edf099fb22c0c12073550c8fc73247b236a974c5f1144831dd5f"
|
||||
)
|
||||
assert (
|
||||
resp.serialized_tx.hex()
|
||||
== "1200002280000000240000000161400000000000000168400000000000000a732103dbed1e77cb91a005e2ec71afbccce5444c9be58276665a3859040f692de8fed274463044022069900e6e578997fad5189981b74b16badc7ba8b9f1052694033fa2779113ddc002206c8006ada310edf099fb22c0c12073550c8fc73247b236a974c5f1144831dd5f8114bdf86f3ae715ba346b7772ea0e133f48828b766483148fb40e1ffa5d557ce9851a535af94965e0dd0988"
|
||||
)
|
||||
|
||||
def test_ripple_sign_invalid_fee(self, client):
|
||||
msg = ripple.create_sign_tx_msg(
|
||||
{
|
||||
"TransactionType": "Payment",
|
||||
"Payment": {
|
||||
"Amount": 1,
|
||||
"Destination": "rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H",
|
||||
},
|
||||
"Flags": 1,
|
||||
"Fee": 1,
|
||||
"Sequence": 1,
|
||||
}
|
||||
)
|
||||
with pytest.raises(
|
||||
TrezorFailure,
|
||||
match="ProcessError: Fee must be in the range of 10 to 10,000 drops",
|
||||
):
|
||||
ripple.sign_tx(client, parse_path("m/44'/144'/0'/0/2"), msg)
|
||||
msg = ripple.create_sign_tx_msg(
|
||||
{
|
||||
"TransactionType": "Payment",
|
||||
"Payment": {
|
||||
"Amount": 100000009,
|
||||
"Destination": "rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H",
|
||||
"DestinationTag": 123456,
|
||||
},
|
||||
"Flags": 0,
|
||||
"Fee": 100,
|
||||
"Sequence": 100,
|
||||
"LastLedgerSequence": 333111,
|
||||
}
|
||||
)
|
||||
resp = ripple.sign_tx(client, parse_path("m/44'/144'/0'/0/2"), msg)
|
||||
assert (
|
||||
resp.signature.hex()
|
||||
== "30450221008770743a472bb2d1c746a53ef131cc17cc118d538ec910ca928d221db4494cf702201e4ef242d6c3bff110c3cc3897a471fed0f5ac10987ea57da63f98dfa01e94df"
|
||||
)
|
||||
assert (
|
||||
resp.serialized_tx.hex()
|
||||
== "120000228000000024000000642e0001e240201b00051537614000000005f5e109684000000000000064732103dbed1e77cb91a005e2ec71afbccce5444c9be58276665a3859040f692de8fed2744730450221008770743a472bb2d1c746a53ef131cc17cc118d538ec910ca928d221db4494cf702201e4ef242d6c3bff110c3cc3897a471fed0f5ac10987ea57da63f98dfa01e94df8114bdf86f3ae715ba346b7772ea0e133f48828b766483148fb40e1ffa5d557ce9851a535af94965e0dd0988"
|
||||
)
|
||||
|
||||
|
||||
def test_ripple_sign_invalid_fee(client):
|
||||
msg = ripple.create_sign_tx_msg(
|
||||
{
|
||||
"TransactionType": "Payment",
|
||||
"Payment": {
|
||||
"Amount": 1,
|
||||
"Destination": "rNaqKtKrMSwpwZSzRckPf7S96DkimjkF4H",
|
||||
},
|
||||
"Flags": 1,
|
||||
"Fee": 1,
|
||||
"Sequence": 1,
|
||||
}
|
||||
)
|
||||
with pytest.raises(
|
||||
TrezorFailure,
|
||||
match="ProcessError: Fee must be in the range of 10 to 10,000 drops",
|
||||
):
|
||||
ripple.sign_tx(client, parse_path("m/44'/144'/0'/0/2"), msg)
|
||||
|
@ -17,33 +17,35 @@
|
||||
from trezorlib import device, messages
|
||||
|
||||
|
||||
class TestBasic:
|
||||
def test_features(self, client):
|
||||
f0 = client.features
|
||||
# client erases session_id from its features
|
||||
f0.session_id = client.session_id
|
||||
f1 = client.call(messages.Initialize(session_id=f0.session_id))
|
||||
assert f0 == f1
|
||||
def test_features(client):
|
||||
f0 = client.features
|
||||
# client erases session_id from its features
|
||||
f0.session_id = client.session_id
|
||||
f1 = client.call(messages.Initialize(session_id=f0.session_id))
|
||||
assert f0 == f1
|
||||
|
||||
def test_ping(self, client):
|
||||
ping = client.call(messages.Ping(message="ahoj!"))
|
||||
assert ping == messages.Success(message="ahoj!")
|
||||
|
||||
def test_device_id_same(self, client):
|
||||
id1 = client.get_device_id()
|
||||
client.init_device()
|
||||
id2 = client.get_device_id()
|
||||
def test_ping(client):
|
||||
ping = client.call(messages.Ping(message="ahoj!"))
|
||||
assert ping == messages.Success(message="ahoj!")
|
||||
|
||||
# ID must be at least 12 characters
|
||||
assert len(id1) >= 12
|
||||
|
||||
# Every resulf of UUID must be the same
|
||||
assert id1 == id2
|
||||
def test_device_id_same(client):
|
||||
id1 = client.get_device_id()
|
||||
client.init_device()
|
||||
id2 = client.get_device_id()
|
||||
|
||||
def test_device_id_different(self, client):
|
||||
id1 = client.get_device_id()
|
||||
device.wipe(client)
|
||||
id2 = client.get_device_id()
|
||||
# ID must be at least 12 characters
|
||||
assert len(id1) >= 12
|
||||
|
||||
# Device ID must be fresh after every reset
|
||||
assert id1 != id2
|
||||
# Every resulf of UUID must be the same
|
||||
assert id1 == id2
|
||||
|
||||
|
||||
def test_device_id_different(client):
|
||||
id1 = client.get_device_id()
|
||||
device.wipe(client)
|
||||
id2 = client.get_device_id()
|
||||
|
||||
# Device ID must be fresh after every reset
|
||||
assert id1 != id2
|
||||
|
@ -21,48 +21,50 @@ import pytest
|
||||
from trezorlib import btc
|
||||
from trezorlib.tools import H_
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.skip_t2,
|
||||
pytest.mark.flaky(max_runs=5),
|
||||
]
|
||||
|
||||
@pytest.mark.flaky(max_runs=5)
|
||||
class TestBip32Speed:
|
||||
@pytest.mark.skip_t2
|
||||
def test_public_ckd(self, client):
|
||||
btc.get_address(client, "Bitcoin", []) # to compute root node via BIP39
|
||||
|
||||
for depth in range(8):
|
||||
start = time.time()
|
||||
btc.get_address(client, "Bitcoin", range(depth))
|
||||
delay = time.time() - start
|
||||
expected = (depth + 1) * 0.26
|
||||
print("DEPTH", depth, "EXPECTED DELAY", expected, "REAL DELAY", delay)
|
||||
assert delay <= expected
|
||||
def test_public_ckd(client):
|
||||
btc.get_address(client, "Bitcoin", []) # to compute root node via BIP39
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
def test_private_ckd(self, client):
|
||||
btc.get_address(client, "Bitcoin", []) # to compute root node via BIP39
|
||||
|
||||
for depth in range(8):
|
||||
start = time.time()
|
||||
address_n = [H_(-i) for i in range(-depth, 0)]
|
||||
btc.get_address(client, "Bitcoin", address_n)
|
||||
delay = time.time() - start
|
||||
expected = (depth + 1) * 0.26
|
||||
print("DEPTH", depth, "EXPECTED DELAY", expected, "REAL DELAY", delay)
|
||||
assert delay <= expected
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
def test_cache(self, client):
|
||||
for depth in range(8):
|
||||
start = time.time()
|
||||
for x in range(10):
|
||||
btc.get_address(client, "Bitcoin", [x, 2, 3, 4, 5, 6, 7, 8])
|
||||
nocache_time = time.time() - start
|
||||
btc.get_address(client, "Bitcoin", range(depth))
|
||||
delay = time.time() - start
|
||||
expected = (depth + 1) * 0.26
|
||||
print("DEPTH", depth, "EXPECTED DELAY", expected, "REAL DELAY", delay)
|
||||
assert delay <= expected
|
||||
|
||||
|
||||
def test_private_ckd(client):
|
||||
btc.get_address(client, "Bitcoin", []) # to compute root node via BIP39
|
||||
|
||||
for depth in range(8):
|
||||
start = time.time()
|
||||
for x in range(10):
|
||||
btc.get_address(client, "Bitcoin", [1, 2, 3, 4, 5, 6, 7, x])
|
||||
cache_time = time.time() - start
|
||||
address_n = [H_(-i) for i in range(-depth, 0)]
|
||||
btc.get_address(client, "Bitcoin", address_n)
|
||||
delay = time.time() - start
|
||||
expected = (depth + 1) * 0.26
|
||||
print("DEPTH", depth, "EXPECTED DELAY", expected, "REAL DELAY", delay)
|
||||
assert delay <= expected
|
||||
|
||||
print("NOCACHE TIME", nocache_time)
|
||||
print("CACHED TIME", cache_time)
|
||||
|
||||
# Cached time expected to be at least 2x faster
|
||||
assert cache_time <= nocache_time / 2.0
|
||||
def test_cache(client):
|
||||
start = time.time()
|
||||
for x in range(10):
|
||||
btc.get_address(client, "Bitcoin", [x, 2, 3, 4, 5, 6, 7, 8])
|
||||
nocache_time = time.time() - start
|
||||
|
||||
start = time.time()
|
||||
for x in range(10):
|
||||
btc.get_address(client, "Bitcoin", [1, 2, 3, 4, 5, 6, 7, x])
|
||||
cache_time = time.time() - start
|
||||
|
||||
print("NOCACHE TIME", nocache_time)
|
||||
print("CACHED TIME", cache_time)
|
||||
|
||||
# Cached time expected to be at least 2x faster
|
||||
assert cache_time <= nocache_time / 2.0
|
||||
|
@ -21,77 +21,75 @@ import pytest
|
||||
from trezorlib import cosi
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
pytestmark = pytest.mark.skip_t2
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
class TestCosi:
|
||||
def test_cosi_commit(self, client):
|
||||
digest = sha256(b"this is a message").digest()
|
||||
|
||||
c0 = cosi.commit(client, parse_path("10018'/0'"), digest)
|
||||
c1 = cosi.commit(client, parse_path("10018'/1'"), digest)
|
||||
c2 = cosi.commit(client, parse_path("10018'/2'"), digest)
|
||||
def test_cosi_commit(client):
|
||||
digest = sha256(b"this is a message").digest()
|
||||
|
||||
assert c0.pubkey != c1.pubkey
|
||||
assert c0.pubkey != c2.pubkey
|
||||
assert c1.pubkey != c2.pubkey
|
||||
c0 = cosi.commit(client, parse_path("10018'/0'"), digest)
|
||||
c1 = cosi.commit(client, parse_path("10018'/1'"), digest)
|
||||
c2 = cosi.commit(client, parse_path("10018'/2'"), digest)
|
||||
|
||||
assert c0.commitment != c1.commitment
|
||||
assert c0.commitment != c2.commitment
|
||||
assert c1.commitment != c2.commitment
|
||||
assert c0.pubkey != c1.pubkey
|
||||
assert c0.pubkey != c2.pubkey
|
||||
assert c1.pubkey != c2.pubkey
|
||||
|
||||
digestb = sha256(b"this is a different message").digest()
|
||||
assert c0.commitment != c1.commitment
|
||||
assert c0.commitment != c2.commitment
|
||||
assert c1.commitment != c2.commitment
|
||||
|
||||
c0b = cosi.commit(client, parse_path("10018'/0'"), digestb)
|
||||
c1b = cosi.commit(client, parse_path("10018'/1'"), digestb)
|
||||
c2b = cosi.commit(client, parse_path("10018'/2'"), digestb)
|
||||
digestb = sha256(b"this is a different message").digest()
|
||||
|
||||
assert c0.pubkey == c0b.pubkey
|
||||
assert c1.pubkey == c1b.pubkey
|
||||
assert c2.pubkey == c2b.pubkey
|
||||
c0b = cosi.commit(client, parse_path("10018'/0'"), digestb)
|
||||
c1b = cosi.commit(client, parse_path("10018'/1'"), digestb)
|
||||
c2b = cosi.commit(client, parse_path("10018'/2'"), digestb)
|
||||
|
||||
assert c0.commitment != c0b.commitment
|
||||
assert c1.commitment != c1b.commitment
|
||||
assert c2.commitment != c2b.commitment
|
||||
assert c0.pubkey == c0b.pubkey
|
||||
assert c1.pubkey == c1b.pubkey
|
||||
assert c2.pubkey == c2b.pubkey
|
||||
|
||||
def test_cosi_sign(self, client):
|
||||
digest = sha256(b"this is a message").digest()
|
||||
assert c0.commitment != c0b.commitment
|
||||
assert c1.commitment != c1b.commitment
|
||||
assert c2.commitment != c2b.commitment
|
||||
|
||||
c0 = cosi.commit(client, parse_path("10018'/0'"), digest)
|
||||
c1 = cosi.commit(client, parse_path("10018'/1'"), digest)
|
||||
c2 = cosi.commit(client, parse_path("10018'/2'"), digest)
|
||||
|
||||
global_pk = cosi.combine_keys([c0.pubkey, c1.pubkey, c2.pubkey])
|
||||
global_R = cosi.combine_keys([c0.commitment, c1.commitment, c2.commitment])
|
||||
def test_cosi_sign(client):
|
||||
digest = sha256(b"this is a message").digest()
|
||||
|
||||
# fmt: off
|
||||
sig0 = cosi.sign(client, parse_path("10018'/0'"), digest, global_R, global_pk)
|
||||
sig1 = cosi.sign(client, parse_path("10018'/1'"), digest, global_R, global_pk)
|
||||
sig2 = cosi.sign(client, parse_path("10018'/2'"), digest, global_R, global_pk)
|
||||
# fmt: on
|
||||
c0 = cosi.commit(client, parse_path("10018'/0'"), digest)
|
||||
c1 = cosi.commit(client, parse_path("10018'/1'"), digest)
|
||||
c2 = cosi.commit(client, parse_path("10018'/2'"), digest)
|
||||
|
||||
sig = cosi.combine_sig(
|
||||
global_R, [sig0.signature, sig1.signature, sig2.signature]
|
||||
)
|
||||
global_pk = cosi.combine_keys([c0.pubkey, c1.pubkey, c2.pubkey])
|
||||
global_R = cosi.combine_keys([c0.commitment, c1.commitment, c2.commitment])
|
||||
|
||||
cosi.verify_combined(sig, digest, global_pk)
|
||||
# fmt: off
|
||||
sig0 = cosi.sign(client, parse_path("10018'/0'"), digest, global_R, global_pk)
|
||||
sig1 = cosi.sign(client, parse_path("10018'/1'"), digest, global_R, global_pk)
|
||||
sig2 = cosi.sign(client, parse_path("10018'/2'"), digest, global_R, global_pk)
|
||||
# fmt: on
|
||||
|
||||
def test_cosi_compat(self, client):
|
||||
digest = sha256(b"this is not a pipe").digest()
|
||||
remote_commit = cosi.commit(client, parse_path("10018'/0'"), digest)
|
||||
sig = cosi.combine_sig(global_R, [sig0.signature, sig1.signature, sig2.signature])
|
||||
|
||||
local_privkey = sha256(b"private key").digest()[:32]
|
||||
local_pubkey = cosi.pubkey_from_privkey(local_privkey)
|
||||
local_nonce, local_commitment = cosi.get_nonce(local_privkey, digest, 42)
|
||||
cosi.verify_combined(sig, digest, global_pk)
|
||||
|
||||
global_pk = cosi.combine_keys([remote_commit.pubkey, local_pubkey])
|
||||
global_R = cosi.combine_keys([remote_commit.commitment, local_commitment])
|
||||
|
||||
remote_sig = cosi.sign(
|
||||
client, parse_path("10018'/0'"), digest, global_R, global_pk
|
||||
)
|
||||
local_sig = cosi.sign_with_privkey(
|
||||
digest, local_privkey, global_pk, local_nonce, global_R
|
||||
)
|
||||
sig = cosi.combine_sig(global_R, [remote_sig.signature, local_sig])
|
||||
def test_cosi_compat(client):
|
||||
digest = sha256(b"this is not a pipe").digest()
|
||||
remote_commit = cosi.commit(client, parse_path("10018'/0'"), digest)
|
||||
|
||||
cosi.verify_combined(sig, digest, global_pk)
|
||||
local_privkey = sha256(b"private key").digest()[:32]
|
||||
local_pubkey = cosi.pubkey_from_privkey(local_privkey)
|
||||
local_nonce, local_commitment = cosi.get_nonce(local_privkey, digest, 42)
|
||||
|
||||
global_pk = cosi.combine_keys([remote_commit.pubkey, local_pubkey])
|
||||
global_R = cosi.combine_keys([remote_commit.commitment, local_commitment])
|
||||
|
||||
remote_sig = cosi.sign(client, parse_path("10018'/0'"), digest, global_R, global_pk)
|
||||
local_sig = cosi.sign_with_privkey(
|
||||
digest, local_privkey, global_pk, local_nonce, global_R
|
||||
)
|
||||
sig = cosi.combine_sig(global_R, [remote_sig.signature, local_sig])
|
||||
|
||||
cosi.verify_combined(sig, digest, global_pk)
|
||||
|
@ -23,32 +23,35 @@ from ..common import MNEMONIC12
|
||||
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
class TestDebuglink:
|
||||
def test_layout(self, client):
|
||||
layout = client.debug.state().layout
|
||||
assert len(layout) == 1024
|
||||
def test_layout(client):
|
||||
layout = client.debug.state().layout
|
||||
assert len(layout) == 1024
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_mnemonic(self, client):
|
||||
client.ensure_unlocked()
|
||||
mnemonic = client.debug.state().mnemonic_secret
|
||||
assert mnemonic == MNEMONIC12.encode()
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12, pin="1234", passphrase="")
|
||||
def test_pin(self, client):
|
||||
resp = client.call_raw(messages.GetAddress())
|
||||
assert isinstance(resp, messages.PinMatrixRequest)
|
||||
@pytest.mark.skip_t2
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_mnemonic(client):
|
||||
client.ensure_unlocked()
|
||||
mnemonic = client.debug.state().mnemonic_secret
|
||||
assert mnemonic == MNEMONIC12.encode()
|
||||
|
||||
state = client.debug.state()
|
||||
assert state.pin == "1234"
|
||||
assert state.matrix != ""
|
||||
|
||||
pin_encoded = client.debug.encode_pin("1234")
|
||||
resp = client.call_raw(messages.PinMatrixAck(pin=pin_encoded))
|
||||
assert isinstance(resp, messages.PassphraseRequest)
|
||||
@pytest.mark.skip_t2
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12, pin="1234", passphrase="")
|
||||
def test_pin(client):
|
||||
resp = client.call_raw(messages.GetAddress())
|
||||
assert isinstance(resp, messages.PinMatrixRequest)
|
||||
|
||||
resp = client.call_raw(messages.PassphraseAck(passphrase=""))
|
||||
assert isinstance(resp, messages.Address)
|
||||
state = client.debug.state()
|
||||
assert state.pin == "1234"
|
||||
assert state.matrix != ""
|
||||
|
||||
pin_encoded = client.debug.encode_pin("1234")
|
||||
resp = client.call_raw(messages.PinMatrixAck(pin=pin_encoded))
|
||||
assert isinstance(resp, messages.PassphraseRequest)
|
||||
|
||||
resp = client.call_raw(messages.PassphraseAck(passphrase=""))
|
||||
assert isinstance(resp, messages.Address)
|
||||
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
|
@ -29,6 +29,8 @@ EXPECTED_RESPONSES_PIN_TT = [messages.ButtonRequest()] + EXPECTED_RESPONSES_NOPI
|
||||
|
||||
PIN4 = "1234"
|
||||
|
||||
pytestmark = pytest.mark.setup_client(pin=PIN4)
|
||||
|
||||
|
||||
def _set_expected_responses(client):
|
||||
client.use_pin_sequence([PIN4])
|
||||
@ -38,184 +40,156 @@ def _set_expected_responses(client):
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_PIN_TT)
|
||||
|
||||
|
||||
@pytest.mark.setup_client(pin=PIN4)
|
||||
class TestMsgApplysettings:
|
||||
def test_apply_settings(self, client):
|
||||
assert client.features.label == "test"
|
||||
def test_apply_settings(client):
|
||||
assert client.features.label == "test"
|
||||
|
||||
with client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(client, label="new label")
|
||||
with client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(client, label="new label")
|
||||
|
||||
assert client.features.label == "new label"
|
||||
assert client.features.label == "new label"
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
def test_apply_settings_rotation(self, client):
|
||||
assert client.features.display_rotation is None
|
||||
|
||||
with client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(client, display_rotation=270)
|
||||
@pytest.mark.skip_t1
|
||||
def test_apply_settings_rotation(client):
|
||||
assert client.features.display_rotation is None
|
||||
|
||||
assert client.features.display_rotation == 270
|
||||
with client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(client, display_rotation=270)
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
def test_invalid_language(self, client):
|
||||
assert client.features.language == "en-US"
|
||||
assert client.features.display_rotation == 270
|
||||
|
||||
with client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(client, language="nonexistent")
|
||||
|
||||
assert client.features.language == "en-US"
|
||||
@pytest.mark.skip_t2
|
||||
def test_invalid_language(client):
|
||||
assert client.features.language == "en-US"
|
||||
|
||||
@pytest.mark.setup_client(pin=PIN4, passphrase=False)
|
||||
def test_apply_settings_passphrase(self, client):
|
||||
with client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(client, use_passphrase=True)
|
||||
with client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(client, language="nonexistent")
|
||||
|
||||
assert client.features.passphrase_protection is True
|
||||
assert client.features.language == "en-US"
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(client, use_passphrase=False)
|
||||
|
||||
assert client.features.passphrase_protection is False
|
||||
@pytest.mark.setup_client(pin=PIN4, passphrase=False)
|
||||
def test_apply_settings_passphrase(client):
|
||||
with client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(client, use_passphrase=True)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(client, use_passphrase=True)
|
||||
assert client.features.passphrase_protection is True
|
||||
|
||||
assert client.features.passphrase_protection is True
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(client, use_passphrase=False)
|
||||
|
||||
@pytest.mark.setup_client(passphrase=False)
|
||||
@pytest.mark.skip_t1
|
||||
def test_apply_settings_passphrase_on_device(self, client):
|
||||
# enable passphrase
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(client, use_passphrase=True)
|
||||
assert client.features.passphrase_protection is False
|
||||
|
||||
assert client.features.passphrase_protection is True
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(client, use_passphrase=True)
|
||||
|
||||
# enable force on device
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(client, passphrase_always_on_device=True)
|
||||
assert client.features.passphrase_protection is True
|
||||
|
||||
assert client.features.passphrase_protection is True
|
||||
assert client.features.passphrase_always_on_device is True
|
||||
|
||||
# turning off the passphrase should also clear the always_on_device setting
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(client, use_passphrase=False)
|
||||
@pytest.mark.setup_client(passphrase=False)
|
||||
@pytest.mark.skip_t1
|
||||
def test_apply_settings_passphrase_on_device(client):
|
||||
# enable passphrase
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(client, use_passphrase=True)
|
||||
|
||||
assert client.features.passphrase_protection is False
|
||||
assert client.features.passphrase_always_on_device is False
|
||||
assert client.features.passphrase_protection is True
|
||||
|
||||
# and turning it back on does not modify always_on_device
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(client, use_passphrase=True)
|
||||
# enable force on device
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(client, passphrase_always_on_device=True)
|
||||
|
||||
assert client.features.passphrase_protection is True
|
||||
assert client.features.passphrase_always_on_device is False
|
||||
assert client.features.passphrase_protection is True
|
||||
assert client.features.passphrase_always_on_device is True
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
def test_apply_homescreen_toif(self, client):
|
||||
img = b"TOIf\x90\x00\x90\x00~\x00\x00\x00\xed\xd2\xcb\r\x83@\x10D\xc1^.\xde#!\xac31\x99\x10\x8aC%\x14~\x16\x92Y9\x02WI3\x01<\xf5cI2d\x1es(\xe1[\xdbn\xba\xca\xe8s7\xa4\xd5\xd4\xb3\x13\xbdw\xf6:\xf3\xd1\xe7%\xc7]\xdd_\xb3\x9e\x9f\x9e\x9fN\xed\xaaE\xef\xdc\xcf$D\xa7\xa4X\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0OV"
|
||||
# turning off the passphrase should also clear the always_on_device setting
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(client, use_passphrase=False)
|
||||
|
||||
with client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(client, homescreen=img)
|
||||
assert client.features.passphrase_protection is False
|
||||
assert client.features.passphrase_always_on_device is False
|
||||
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(client, homescreen=b"")
|
||||
# and turning it back on does not modify always_on_device
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(client, use_passphrase=True)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"toif_data",
|
||||
[
|
||||
# incomplete header
|
||||
b"TOIf\x90\00\x90\x00~"
|
||||
# wrong magic
|
||||
b"XXXf\x90\x00\x90\x00~\x00\x00\x00\xed\xd2\xcb\r\x83@\x10D\xc1^.\xde#!\xac31\x99\x10\x8aC%\x14~\x16\x92Y9\x02WI3\x01<\xf5cI2d\x1es(\xe1[\xdbn\xba\xca\xe8s7\xa4\xd5\xd4\xb3\x13\xbdw\xf6:\xf3\xd1\xe7%\xc7]\xdd_\xb3\x9e\x9f\x9e\x9fN\xed\xaaE\xef\xdc\xcf$D\xa7\xa4X\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0OV"
|
||||
# wrong datasize in header
|
||||
b"TOIf\x90\x00\x90\x00~\x00\x00\x00\xed\xd2\xcb\r\x83@\x10D\xc1^.\xde#!\xac31\x99\x10\x8aC%\x14~\x16\x92Y9\x02WI3\x01<\xf5cI2d\x1es(\xe1[\xdbn\xba\xca\xe8s7\xa4\xd5\xd4\xb3\x13\xbdw\xf6:\xf3\xd1\xe7%\xc7]\xdd_\xb3\x9e\x9f\x9e\x9fN\xed\xaaE\xef\xdc\xcf$D\xa7\xa4X\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
# grayscale 144x144
|
||||
b"TOIg\x90\x00\x90\x00~\x00\x00\x00\xed\xd2\xcb\r\x83@\x10D\xc1^.\xde#!\xac31\x99\x10\x8aC%\x14~\x16\x92Y9\x02WI3\x01<\xf5cI2d\x1es(\xe1[\xdbn\xba\xca\xe8s7\xa4\xd5\xd4\xb3\x13\xbdw\xf6:\xf3\xd1\xe7%\xc7]\xdd_\xb3\x9e\x9f\x9e\x9fN\xed\xaaE\xef\xdc\xcf$D\xa7\xa4X\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0OV",
|
||||
# fullcolor 128x128
|
||||
b"TOIf\x80\x00\x80\x00~\x00\x00\x00\xed\xd2\xcb\r\x83@\x10D\xc1^.\xde#!\xac31\x99\x10\x8aC%\x14~\x16\x92Y9\x02WI3\x01<\xf5cI2d\x1es(\xe1[\xdbn\xba\xca\xe8s7\xa4\xd5\xd4\xb3\x13\xbdw\xf6:\xf3\xd1\xe7%\xc7]\xdd_\xb3\x9e\x9f\x9e\x9fN\xed\xaaE\xef\xdc\xcf$D\xa7\xa4X\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0OV",
|
||||
],
|
||||
)
|
||||
@pytest.mark.skip_t1
|
||||
def test_apply_homescreen_toif_fail(self, client, toif_data):
|
||||
with pytest.raises(exceptions.TrezorFailure), client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
device.apply_settings(client, homescreen=toif_data)
|
||||
assert client.features.passphrase_protection is True
|
||||
assert client.features.passphrase_always_on_device is False
|
||||
|
||||
@pytest.mark.skip_t2
|
||||
def test_apply_homescreen(self, client):
|
||||
img = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\x00\x00\x00\x00\x04\x80\x00\x00\x00\x00\x00\x00\x00\x00\x04\x88\x02\x00\x00\x00\x02\x91\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x90@\x00\x11@\x00\x00\x00\x00\x00\x00\x08\x00\x10\x92\x12\x04\x00\x00\x05\x12D\x00\x00\x00\x00\x00 \x00\x00\x08\x00Q\x00\x00\x02\xc0\x00\x00\x00\x00\x00\x00\x00\x10\x02 \x01\x04J\x00)$\x00\x00\x00\x00\x80\x00\x00\x00\x00\x08\x10\xa1\x00\x00\x02\x81 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\tP\x00\x00\x00\x00\x00\x00 \x00\x00\xa0\x00\xa0R \x12\x84\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x08\x00\tP\x00\x00\x00\x00 \x00\x04 \x00\x80\x02\x00@\x02T\xc2 \x00\x00\x00\x00\x00\x00\x00\x10@\x00)\t@\n\xa0\x80\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x80@\x14\xa9H\x04\x00\x00\x88@\x00\x00\x00\x00\x00\x02\x02$\x00\x15B@\x00\nP\x00\x00\x00\x00\x00\x80\x00\x00\x91\x01UP\x00\x00 \x02\x00\x00\x00\x00\x00\x00\x02\x08@ Z\xa5 \x00\x00\x80\x00\x00\x00\x00\x00\x00\x08\xa1%\x14*\xa0\x00\x00\x02\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00@\xaa\x91 \x00\x05E\x80\x00\x00\x00\x00\x00\x02*T\x05-D\x00\x00\x05 @\x00\x00\x00\x00\x00%@\x80\x11V\xa0\x88\x00\x05@\xb0\x00\x00\x00\x00\x00\x818$\x04\xabD \x00\x06\xa1T\x00\x00\x00\x00\x02\x03\xb8\x01R\xd5\x01\x00\x00\x05AP\x00\x00\x00\x00\x08\xadT\x00\x05j\xa4@\x00\x87ah\x00\x00\x00\x00\x02\x8d\xb8\x08\x00.\x01\x00\x00\x02\xa5\xa8\x10\x00\x00\x00*\xc1\xec \n\xaa\x88 \x02@\xf6\xd0\x02\x00\x00\x00\x0bB\xb6\x14@U"\x80\x00\x01{`\x00\x00\x00\x00M\xa3\xf8 \x15*\x00\x00\x00\x10n\xc0\x04\x00\x00\x02\x06\xc2\xa8)\x00\x96\x84\x80\x00\x00\x1b\x00\x00\x80@\x10\x87\xa7\xf0\x84\x10\xaa\x10\x00\x00D\x00\x00\x02 \x00\x8a\x06\xfa\xe0P\n-\x02@\x00\x12\x00\x00\x00\x00\x10@\x83\xdf\xa0\x00\x08\xaa@\x00\x00\x01H\x00\x05H\x04\x12\x01\xf7\x81P\x02T\t\x00\x00\x00 \x00\x00\x84\x10\x00\x00z\x00@)* \x00\x00\x01\n\xa0\x02 \x05\n\x00\x00\x05\x10\x84\xa8\x84\x80\x00\x00@\x14\x00\x92\x10\x80\x00\x04\x11@\tT\x00\x00\x00\x00\n@\x00\x08\x84@$\x00H\x00\x12Q\x02\x00\x00\x00\x00\x90\x02A\x12\xa8\n\xaa\x92\x10\x04\xa8\x10@\x00\x00\x04\x04\x00\x04I\x00\x04\x14H\x80"R\x01\x00\x00\x00!@\x00\x00$\xa0EB\x80\x08\x95hH\x00\x00\x00\x84\x10 \x05Z\x00\x00(\x00\x02\x00\xa1\x01\x00\x00\x04\x00@\x82\x00\xadH*\x92P\x00\xaaP\x00\x00\x00\x00\x11\x02\x01*\xad\x01\x00\x01\x01"\x11D\x08\x00\x00\x10\x80 \x00\x81W\x80J\x94\x04\x08\xa5 !\x00\x00\x00\x02\x00B*\xae\xa1\x00\x80\x10\x01\x08\xa4\x00\x00\x00\x00\x00\x84\x00\t[@"HA\x04E\x00\x84\x00\x00\x00\x10\x00\x01J\xd5\x82\x90\x02\x00!\x02\xa2\x00\x00\x00\x00\x00\x00\x00\x05~\xa0\x00 \x10\n)\x00\x11\x00\x00\x00\x00\x00\x00!U\x80\xa8\x88\x82\x80\x01\x00\x00\x00\x00\x00\x00H@\x11\xaa\xc0\x82\x00 *\n\x00\x00\x00\x00\x00\x00\x00\x00\n\xabb@ \x04\x00! \x84\x00\x00\x00\x00\x02@\xa5\x15A$\x04\x81(\n\x00\x00\x00\x00\x00\x00 \x01\x10\x02\xe0\x91\x02\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01 \xa9\tQH@\x91 P\x00\x00\x00\x00\x00\x00\x08\x00\x00\xa0T\xa5\x00@\x80\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\x00\x00\x00\x00\xa2\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00 T\xa0\t\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00@\x02\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x10\x00\x00\x10\x02\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00@\x04\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x08@\x10\x00\x00\x00\x00'
|
||||
|
||||
with client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(client, homescreen=img)
|
||||
@pytest.mark.skip_t1
|
||||
def test_apply_homescreen_toif(client):
|
||||
img = b"TOIf\x90\x00\x90\x00~\x00\x00\x00\xed\xd2\xcb\r\x83@\x10D\xc1^.\xde#!\xac31\x99\x10\x8aC%\x14~\x16\x92Y9\x02WI3\x01<\xf5cI2d\x1es(\xe1[\xdbn\xba\xca\xe8s7\xa4\xd5\xd4\xb3\x13\xbdw\xf6:\xf3\xd1\xe7%\xc7]\xdd_\xb3\x9e\x9f\x9e\x9fN\xed\xaaE\xef\xdc\xcf$D\xa7\xa4X\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0OV"
|
||||
|
||||
@pytest.mark.setup_client(pin=None)
|
||||
def test_safety_checks(self, client):
|
||||
def get_bad_address():
|
||||
btc.get_address(client, "Bitcoin", parse_path("m/44'"), show_display=True)
|
||||
with client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(client, homescreen=img)
|
||||
|
||||
assert client.features.safety_checks == messages.SafetyCheckLevel.Strict
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(client, homescreen=b"")
|
||||
|
||||
with pytest.raises(
|
||||
exceptions.TrezorFailure, match="Forbidden key path"
|
||||
), client:
|
||||
client.set_expected_responses([messages.Failure])
|
||||
get_bad_address()
|
||||
|
||||
if client.features.model != "1":
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(
|
||||
client, safety_checks=messages.SafetyCheckLevel.PromptAlways
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"toif_data",
|
||||
[
|
||||
# incomplete header
|
||||
b"TOIf\x90\00\x90\x00~"
|
||||
# wrong magic
|
||||
b"XXXf\x90\x00\x90\x00~\x00\x00\x00\xed\xd2\xcb\r\x83@\x10D\xc1^.\xde#!\xac31\x99\x10\x8aC%\x14~\x16\x92Y9\x02WI3\x01<\xf5cI2d\x1es(\xe1[\xdbn\xba\xca\xe8s7\xa4\xd5\xd4\xb3\x13\xbdw\xf6:\xf3\xd1\xe7%\xc7]\xdd_\xb3\x9e\x9f\x9e\x9fN\xed\xaaE\xef\xdc\xcf$D\xa7\xa4X\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0OV"
|
||||
# wrong datasize in header
|
||||
b"TOIf\x90\x00\x90\x00~\x00\x00\x00\xed\xd2\xcb\r\x83@\x10D\xc1^.\xde#!\xac31\x99\x10\x8aC%\x14~\x16\x92Y9\x02WI3\x01<\xf5cI2d\x1es(\xe1[\xdbn\xba\xca\xe8s7\xa4\xd5\xd4\xb3\x13\xbdw\xf6:\xf3\xd1\xe7%\xc7]\xdd_\xb3\x9e\x9f\x9e\x9fN\xed\xaaE\xef\xdc\xcf$D\xa7\xa4X\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
# grayscale 144x144
|
||||
b"TOIg\x90\x00\x90\x00~\x00\x00\x00\xed\xd2\xcb\r\x83@\x10D\xc1^.\xde#!\xac31\x99\x10\x8aC%\x14~\x16\x92Y9\x02WI3\x01<\xf5cI2d\x1es(\xe1[\xdbn\xba\xca\xe8s7\xa4\xd5\xd4\xb3\x13\xbdw\xf6:\xf3\xd1\xe7%\xc7]\xdd_\xb3\x9e\x9f\x9e\x9fN\xed\xaaE\xef\xdc\xcf$D\xa7\xa4X\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0OV",
|
||||
# fullcolor 128x128
|
||||
b"TOIf\x80\x00\x80\x00~\x00\x00\x00\xed\xd2\xcb\r\x83@\x10D\xc1^.\xde#!\xac31\x99\x10\x8aC%\x14~\x16\x92Y9\x02WI3\x01<\xf5cI2d\x1es(\xe1[\xdbn\xba\xca\xe8s7\xa4\xd5\xd4\xb3\x13\xbdw\xf6:\xf3\xd1\xe7%\xc7]\xdd_\xb3\x9e\x9f\x9e\x9fN\xed\xaaE\xef\xdc\xcf$D\xa7\xa4X\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0OV",
|
||||
],
|
||||
)
|
||||
@pytest.mark.skip_t1
|
||||
def test_apply_homescreen_toif_fail(client, toif_data):
|
||||
with pytest.raises(exceptions.TrezorFailure), client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
device.apply_settings(client, homescreen=toif_data)
|
||||
|
||||
assert (
|
||||
client.features.safety_checks == messages.SafetyCheckLevel.PromptAlways
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[messages.ButtonRequest, messages.ButtonRequest, messages.Address]
|
||||
)
|
||||
get_bad_address()
|
||||
@pytest.mark.skip_t2
|
||||
def test_apply_homescreen(client):
|
||||
img = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\x00\x00\x00\x00\x04\x80\x00\x00\x00\x00\x00\x00\x00\x00\x04\x88\x02\x00\x00\x00\x02\x91\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x90@\x00\x11@\x00\x00\x00\x00\x00\x00\x08\x00\x10\x92\x12\x04\x00\x00\x05\x12D\x00\x00\x00\x00\x00 \x00\x00\x08\x00Q\x00\x00\x02\xc0\x00\x00\x00\x00\x00\x00\x00\x10\x02 \x01\x04J\x00)$\x00\x00\x00\x00\x80\x00\x00\x00\x00\x08\x10\xa1\x00\x00\x02\x81 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\tP\x00\x00\x00\x00\x00\x00 \x00\x00\xa0\x00\xa0R \x12\x84\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x08\x00\tP\x00\x00\x00\x00 \x00\x04 \x00\x80\x02\x00@\x02T\xc2 \x00\x00\x00\x00\x00\x00\x00\x10@\x00)\t@\n\xa0\x80\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x80@\x14\xa9H\x04\x00\x00\x88@\x00\x00\x00\x00\x00\x02\x02$\x00\x15B@\x00\nP\x00\x00\x00\x00\x00\x80\x00\x00\x91\x01UP\x00\x00 \x02\x00\x00\x00\x00\x00\x00\x02\x08@ Z\xa5 \x00\x00\x80\x00\x00\x00\x00\x00\x00\x08\xa1%\x14*\xa0\x00\x00\x02\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00@\xaa\x91 \x00\x05E\x80\x00\x00\x00\x00\x00\x02*T\x05-D\x00\x00\x05 @\x00\x00\x00\x00\x00%@\x80\x11V\xa0\x88\x00\x05@\xb0\x00\x00\x00\x00\x00\x818$\x04\xabD \x00\x06\xa1T\x00\x00\x00\x00\x02\x03\xb8\x01R\xd5\x01\x00\x00\x05AP\x00\x00\x00\x00\x08\xadT\x00\x05j\xa4@\x00\x87ah\x00\x00\x00\x00\x02\x8d\xb8\x08\x00.\x01\x00\x00\x02\xa5\xa8\x10\x00\x00\x00*\xc1\xec \n\xaa\x88 \x02@\xf6\xd0\x02\x00\x00\x00\x0bB\xb6\x14@U"\x80\x00\x01{`\x00\x00\x00\x00M\xa3\xf8 \x15*\x00\x00\x00\x10n\xc0\x04\x00\x00\x02\x06\xc2\xa8)\x00\x96\x84\x80\x00\x00\x1b\x00\x00\x80@\x10\x87\xa7\xf0\x84\x10\xaa\x10\x00\x00D\x00\x00\x02 \x00\x8a\x06\xfa\xe0P\n-\x02@\x00\x12\x00\x00\x00\x00\x10@\x83\xdf\xa0\x00\x08\xaa@\x00\x00\x01H\x00\x05H\x04\x12\x01\xf7\x81P\x02T\t\x00\x00\x00 \x00\x00\x84\x10\x00\x00z\x00@)* \x00\x00\x01\n\xa0\x02 \x05\n\x00\x00\x05\x10\x84\xa8\x84\x80\x00\x00@\x14\x00\x92\x10\x80\x00\x04\x11@\tT\x00\x00\x00\x00\n@\x00\x08\x84@$\x00H\x00\x12Q\x02\x00\x00\x00\x00\x90\x02A\x12\xa8\n\xaa\x92\x10\x04\xa8\x10@\x00\x00\x04\x04\x00\x04I\x00\x04\x14H\x80"R\x01\x00\x00\x00!@\x00\x00$\xa0EB\x80\x08\x95hH\x00\x00\x00\x84\x10 \x05Z\x00\x00(\x00\x02\x00\xa1\x01\x00\x00\x04\x00@\x82\x00\xadH*\x92P\x00\xaaP\x00\x00\x00\x00\x11\x02\x01*\xad\x01\x00\x01\x01"\x11D\x08\x00\x00\x10\x80 \x00\x81W\x80J\x94\x04\x08\xa5 !\x00\x00\x00\x02\x00B*\xae\xa1\x00\x80\x10\x01\x08\xa4\x00\x00\x00\x00\x00\x84\x00\t[@"HA\x04E\x00\x84\x00\x00\x00\x10\x00\x01J\xd5\x82\x90\x02\x00!\x02\xa2\x00\x00\x00\x00\x00\x00\x00\x05~\xa0\x00 \x10\n)\x00\x11\x00\x00\x00\x00\x00\x00!U\x80\xa8\x88\x82\x80\x01\x00\x00\x00\x00\x00\x00H@\x11\xaa\xc0\x82\x00 *\n\x00\x00\x00\x00\x00\x00\x00\x00\n\xabb@ \x04\x00! \x84\x00\x00\x00\x00\x02@\xa5\x15A$\x04\x81(\n\x00\x00\x00\x00\x00\x00 \x01\x10\x02\xe0\x91\x02\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01 \xa9\tQH@\x91 P\x00\x00\x00\x00\x00\x00\x08\x00\x00\xa0T\xa5\x00@\x80\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\x00\x00\x00\x00\xa2\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00 T\xa0\t\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00@\x02\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x10\x00\x00\x10\x02\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00@\x04\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x08@\x10\x00\x00\x00\x00'
|
||||
|
||||
with client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(client, homescreen=img)
|
||||
|
||||
|
||||
@pytest.mark.setup_client(pin=None)
|
||||
def test_safety_checks(client):
|
||||
def get_bad_address():
|
||||
btc.get_address(client, "Bitcoin", parse_path("m/44'"), show_display=True)
|
||||
|
||||
assert client.features.safety_checks == messages.SafetyCheckLevel.Strict
|
||||
|
||||
with pytest.raises(exceptions.TrezorFailure, match="Forbidden key path"), client:
|
||||
client.set_expected_responses([messages.Failure])
|
||||
get_bad_address()
|
||||
|
||||
if client.features.model != "1":
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(
|
||||
client, safety_checks=messages.SafetyCheckLevel.Strict
|
||||
client, safety_checks=messages.SafetyCheckLevel.PromptAlways
|
||||
)
|
||||
|
||||
assert client.features.safety_checks == messages.SafetyCheckLevel.Strict
|
||||
|
||||
with pytest.raises(
|
||||
exceptions.TrezorFailure, match="Forbidden key path"
|
||||
), client:
|
||||
client.set_expected_responses([messages.Failure])
|
||||
get_bad_address()
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(
|
||||
client, safety_checks=messages.SafetyCheckLevel.PromptTemporarily
|
||||
)
|
||||
|
||||
assert (
|
||||
client.features.safety_checks == messages.SafetyCheckLevel.PromptTemporarily
|
||||
)
|
||||
assert client.features.safety_checks == messages.SafetyCheckLevel.PromptAlways
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
@ -223,61 +197,87 @@ class TestMsgApplysettings:
|
||||
)
|
||||
get_bad_address()
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
def test_experimental_features(self, client):
|
||||
def experimental_call():
|
||||
btc.authorize_coinjoin(
|
||||
client,
|
||||
coordinator="www.example.com",
|
||||
max_total_fee=10010,
|
||||
fee_per_anonymity=5000000, # 0.005 %
|
||||
n=parse_path("m/84'/1'/0'"),
|
||||
coin_name="Testnet",
|
||||
script_type=messages.InputScriptType.SPENDWITNESS,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(client, safety_checks=messages.SafetyCheckLevel.Strict)
|
||||
|
||||
assert client.features.experimental_features is None
|
||||
assert client.features.safety_checks == messages.SafetyCheckLevel.Strict
|
||||
|
||||
# unlock
|
||||
with client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(client, label="new label")
|
||||
with pytest.raises(exceptions.TrezorFailure, match="Forbidden key path"), client:
|
||||
client.set_expected_responses([messages.Failure])
|
||||
get_bad_address()
|
||||
|
||||
assert client.features.experimental_features
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(
|
||||
client, safety_checks=messages.SafetyCheckLevel.PromptTemporarily
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[messages.ButtonRequest, messages.ButtonRequest, messages.Success]
|
||||
)
|
||||
experimental_call()
|
||||
assert client.features.safety_checks == messages.SafetyCheckLevel.PromptTemporarily
|
||||
|
||||
# relock and try again
|
||||
client.lock()
|
||||
with client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest,
|
||||
messages.ButtonRequest,
|
||||
messages.ButtonRequest,
|
||||
messages.Success,
|
||||
]
|
||||
)
|
||||
experimental_call()
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[messages.ButtonRequest, messages.ButtonRequest, messages.Address]
|
||||
)
|
||||
get_bad_address()
|
||||
|
||||
# unset experimental features
|
||||
with client:
|
||||
client.set_expected_responses([messages.Success, messages.Features])
|
||||
device.apply_settings(client, experimental_features=False)
|
||||
|
||||
assert not client.features.experimental_features
|
||||
@pytest.mark.skip_t1
|
||||
def test_experimental_features(client):
|
||||
def experimental_call():
|
||||
btc.authorize_coinjoin(
|
||||
client,
|
||||
coordinator="www.example.com",
|
||||
max_total_fee=10010,
|
||||
fee_per_anonymity=5000000, # 0.005 %
|
||||
n=parse_path("m/84'/1'/0'"),
|
||||
coin_name="Testnet",
|
||||
script_type=messages.InputScriptType.SPENDWITNESS,
|
||||
)
|
||||
|
||||
with pytest.raises(exceptions.TrezorFailure, match="DataError"), client:
|
||||
client.set_expected_responses([messages.Failure])
|
||||
experimental_call()
|
||||
assert client.features.experimental_features is None
|
||||
|
||||
@pytest.mark.setup_client(pin=None)
|
||||
def test_label_too_long(self, client):
|
||||
with pytest.raises(exceptions.TrezorFailure), client:
|
||||
client.set_expected_responses([messages.Failure])
|
||||
device.apply_settings(client, label="A" * 33)
|
||||
# unlock
|
||||
with client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(client, label="new label")
|
||||
|
||||
assert client.features.experimental_features
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[messages.ButtonRequest, messages.ButtonRequest, messages.Success]
|
||||
)
|
||||
experimental_call()
|
||||
|
||||
# relock and try again
|
||||
client.lock()
|
||||
with client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest,
|
||||
messages.ButtonRequest,
|
||||
messages.ButtonRequest,
|
||||
messages.Success,
|
||||
]
|
||||
)
|
||||
experimental_call()
|
||||
|
||||
# unset experimental features
|
||||
with client:
|
||||
client.set_expected_responses([messages.Success, messages.Features])
|
||||
device.apply_settings(client, experimental_features=False)
|
||||
|
||||
assert not client.features.experimental_features
|
||||
|
||||
with pytest.raises(exceptions.TrezorFailure, match="DataError"), client:
|
||||
client.set_expected_responses([messages.Failure])
|
||||
experimental_call()
|
||||
|
||||
|
||||
@pytest.mark.setup_client(pin=None)
|
||||
def test_label_too_long(client):
|
||||
with pytest.raises(exceptions.TrezorFailure), client:
|
||||
client.set_expected_responses([messages.Failure])
|
||||
device.apply_settings(client, label="A" * 33)
|
||||
|
@ -21,166 +21,167 @@ from trezorlib import misc
|
||||
from ..common import MNEMONIC12
|
||||
|
||||
|
||||
class TestMsgCipherkeyvalue:
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_encrypt(self, client):
|
||||
res = misc.encrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test",
|
||||
b"testing message!",
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res.hex() == "676faf8f13272af601776bc31bc14e8f"
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_encrypt(client):
|
||||
res = misc.encrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test",
|
||||
b"testing message!",
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res.hex() == "676faf8f13272af601776bc31bc14e8f"
|
||||
|
||||
res = misc.encrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test",
|
||||
b"testing message!",
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=False,
|
||||
)
|
||||
assert res.hex() == "5aa0fbcb9d7fa669880745479d80c622"
|
||||
res = misc.encrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test",
|
||||
b"testing message!",
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=False,
|
||||
)
|
||||
assert res.hex() == "5aa0fbcb9d7fa669880745479d80c622"
|
||||
|
||||
res = misc.encrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test",
|
||||
b"testing message!",
|
||||
ask_on_encrypt=False,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res.hex() == "958d4f63269b61044aaedc900c8d6208"
|
||||
res = misc.encrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test",
|
||||
b"testing message!",
|
||||
ask_on_encrypt=False,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res.hex() == "958d4f63269b61044aaedc900c8d6208"
|
||||
|
||||
res = misc.encrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test",
|
||||
b"testing message!",
|
||||
ask_on_encrypt=False,
|
||||
ask_on_decrypt=False,
|
||||
)
|
||||
assert res.hex() == "e0cf0eb0425947000eb546cc3994bc6c"
|
||||
res = misc.encrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test",
|
||||
b"testing message!",
|
||||
ask_on_encrypt=False,
|
||||
ask_on_decrypt=False,
|
||||
)
|
||||
assert res.hex() == "e0cf0eb0425947000eb546cc3994bc6c"
|
||||
|
||||
# different key
|
||||
res = misc.encrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test2",
|
||||
b"testing message!",
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res.hex() == "de247a6aa6be77a134bb3f3f925f13af"
|
||||
# different key
|
||||
res = misc.encrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test2",
|
||||
b"testing message!",
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res.hex() == "de247a6aa6be77a134bb3f3f925f13af"
|
||||
|
||||
# different message
|
||||
res = misc.encrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test",
|
||||
b"testing message! it is different",
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert (
|
||||
res.hex()
|
||||
== "676faf8f13272af601776bc31bc14e8f3ae1c88536bf18f1b44f1e4c2c4a613d"
|
||||
)
|
||||
# different message
|
||||
res = misc.encrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test",
|
||||
b"testing message! it is different",
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert (
|
||||
res.hex() == "676faf8f13272af601776bc31bc14e8f3ae1c88536bf18f1b44f1e4c2c4a613d"
|
||||
)
|
||||
|
||||
# different path
|
||||
res = misc.encrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 3],
|
||||
"test",
|
||||
b"testing message!",
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res.hex() == "b4811a9d492f5355a5186ddbfccaae7b"
|
||||
# different path
|
||||
res = misc.encrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 3],
|
||||
"test",
|
||||
b"testing message!",
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res.hex() == "b4811a9d492f5355a5186ddbfccaae7b"
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_decrypt(self, client):
|
||||
res = misc.decrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test",
|
||||
bytes.fromhex("676faf8f13272af601776bc31bc14e8f"),
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res == b"testing message!"
|
||||
|
||||
res = misc.decrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test",
|
||||
bytes.fromhex("5aa0fbcb9d7fa669880745479d80c622"),
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=False,
|
||||
)
|
||||
assert res == b"testing message!"
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_decrypt(client):
|
||||
res = misc.decrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test",
|
||||
bytes.fromhex("676faf8f13272af601776bc31bc14e8f"),
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res == b"testing message!"
|
||||
|
||||
res = misc.decrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test",
|
||||
bytes.fromhex("958d4f63269b61044aaedc900c8d6208"),
|
||||
ask_on_encrypt=False,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res == b"testing message!"
|
||||
res = misc.decrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test",
|
||||
bytes.fromhex("5aa0fbcb9d7fa669880745479d80c622"),
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=False,
|
||||
)
|
||||
assert res == b"testing message!"
|
||||
|
||||
res = misc.decrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test",
|
||||
bytes.fromhex("e0cf0eb0425947000eb546cc3994bc6c"),
|
||||
ask_on_encrypt=False,
|
||||
ask_on_decrypt=False,
|
||||
)
|
||||
assert res == b"testing message!"
|
||||
res = misc.decrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test",
|
||||
bytes.fromhex("958d4f63269b61044aaedc900c8d6208"),
|
||||
ask_on_encrypt=False,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res == b"testing message!"
|
||||
|
||||
# different key
|
||||
res = misc.decrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test2",
|
||||
bytes.fromhex("de247a6aa6be77a134bb3f3f925f13af"),
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res == b"testing message!"
|
||||
res = misc.decrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test",
|
||||
bytes.fromhex("e0cf0eb0425947000eb546cc3994bc6c"),
|
||||
ask_on_encrypt=False,
|
||||
ask_on_decrypt=False,
|
||||
)
|
||||
assert res == b"testing message!"
|
||||
|
||||
# different message
|
||||
res = misc.decrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test",
|
||||
bytes.fromhex(
|
||||
"676faf8f13272af601776bc31bc14e8f3ae1c88536bf18f1b44f1e4c2c4a613d"
|
||||
),
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res == b"testing message! it is different"
|
||||
# different key
|
||||
res = misc.decrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test2",
|
||||
bytes.fromhex("de247a6aa6be77a134bb3f3f925f13af"),
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res == b"testing message!"
|
||||
|
||||
# different path
|
||||
res = misc.decrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 3],
|
||||
"test",
|
||||
bytes.fromhex("b4811a9d492f5355a5186ddbfccaae7b"),
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res == b"testing message!"
|
||||
# different message
|
||||
res = misc.decrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 2],
|
||||
"test",
|
||||
bytes.fromhex(
|
||||
"676faf8f13272af601776bc31bc14e8f3ae1c88536bf18f1b44f1e4c2c4a613d"
|
||||
),
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res == b"testing message! it is different"
|
||||
|
||||
def test_encrypt_badlen(self, client):
|
||||
with pytest.raises(Exception):
|
||||
misc.encrypt_keyvalue(client, [0, 1, 2], "test", b"testing")
|
||||
# different path
|
||||
res = misc.decrypt_keyvalue(
|
||||
client,
|
||||
[0, 1, 3],
|
||||
"test",
|
||||
bytes.fromhex("b4811a9d492f5355a5186ddbfccaae7b"),
|
||||
ask_on_encrypt=True,
|
||||
ask_on_decrypt=True,
|
||||
)
|
||||
assert res == b"testing message!"
|
||||
|
||||
def test_decrypt_badlen(self, client):
|
||||
with pytest.raises(Exception):
|
||||
misc.decrypt_keyvalue(client, [0, 1, 2], "test", b"testing")
|
||||
|
||||
def test_encrypt_badlen(client):
|
||||
with pytest.raises(Exception):
|
||||
misc.encrypt_keyvalue(client, [0, 1, 2], "test", b"testing")
|
||||
|
||||
|
||||
def test_decrypt_badlen(client):
|
||||
with pytest.raises(Exception):
|
||||
misc.decrypt_keyvalue(client, [0, 1, 2], "test", b"testing")
|
||||
|
@ -33,200 +33,208 @@ def getmultisig(chain, nr, xpubs):
|
||||
)
|
||||
|
||||
|
||||
class TestMsgGetaddress:
|
||||
def test_btc(self, client):
|
||||
assert (
|
||||
btc.get_address(client, "Bitcoin", parse_path("m/44'/0'/0'/0/0"))
|
||||
== "1JAd7XCBzGudGpJQSDSfpmJhiygtLQWaGL"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(client, "Bitcoin", parse_path("m/44'/0'/0'/0/1"))
|
||||
== "1GWFxtwWmNVqotUPXLcKVL2mUKpshuJYo"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(client, "Bitcoin", parse_path("m/44'/0'/0'/1/0"))
|
||||
== "1DyHzbQUoQEsLxJn6M7fMD8Xdt1XvNiwNE"
|
||||
)
|
||||
def test_btc(client):
|
||||
assert (
|
||||
btc.get_address(client, "Bitcoin", parse_path("m/44'/0'/0'/0/0"))
|
||||
== "1JAd7XCBzGudGpJQSDSfpmJhiygtLQWaGL"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(client, "Bitcoin", parse_path("m/44'/0'/0'/0/1"))
|
||||
== "1GWFxtwWmNVqotUPXLcKVL2mUKpshuJYo"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(client, "Bitcoin", parse_path("m/44'/0'/0'/1/0"))
|
||||
== "1DyHzbQUoQEsLxJn6M7fMD8Xdt1XvNiwNE"
|
||||
)
|
||||
|
||||
@pytest.mark.altcoin
|
||||
def test_ltc(self, client):
|
||||
assert (
|
||||
btc.get_address(client, "Litecoin", parse_path("m/44'/2'/0'/0/0"))
|
||||
== "LcubERmHD31PWup1fbozpKuiqjHZ4anxcL"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(client, "Litecoin", parse_path("m/44'/2'/0'/0/1"))
|
||||
== "LVWBmHBkCGNjSPHucvL2PmnuRAJnucmRE6"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(client, "Litecoin", parse_path("m/44'/2'/0'/1/0"))
|
||||
== "LWj6ApswZxay4cJEJES2sGe7fLMLRvvv8h"
|
||||
)
|
||||
|
||||
def test_tbtc(self, client):
|
||||
assert (
|
||||
btc.get_address(client, "Testnet", parse_path("m/44'/1'/0'/0/0"))
|
||||
== "mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(client, "Testnet", parse_path("m/44'/1'/0'/0/1"))
|
||||
== "mopZWqZZyQc3F2Sy33cvDtJchSAMsnLi7b"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(client, "Testnet", parse_path("m/44'/1'/0'/1/0"))
|
||||
== "mm6kLYbGEL1tGe4ZA8xacfgRPdW1NLjCbZ"
|
||||
)
|
||||
@pytest.mark.altcoin
|
||||
def test_ltc(client):
|
||||
assert (
|
||||
btc.get_address(client, "Litecoin", parse_path("m/44'/2'/0'/0/0"))
|
||||
== "LcubERmHD31PWup1fbozpKuiqjHZ4anxcL"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(client, "Litecoin", parse_path("m/44'/2'/0'/0/1"))
|
||||
== "LVWBmHBkCGNjSPHucvL2PmnuRAJnucmRE6"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(client, "Litecoin", parse_path("m/44'/2'/0'/1/0"))
|
||||
== "LWj6ApswZxay4cJEJES2sGe7fLMLRvvv8h"
|
||||
)
|
||||
|
||||
@pytest.mark.altcoin
|
||||
def test_bch(self, client):
|
||||
assert (
|
||||
btc.get_address(client, "Bcash", parse_path("44'/145'/0'/0/0"))
|
||||
== "bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(client, "Bcash", parse_path("44'/145'/0'/0/1"))
|
||||
== "bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(client, "Bcash", parse_path("44'/145'/0'/1/0"))
|
||||
== "bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw"
|
||||
)
|
||||
|
||||
@pytest.mark.altcoin
|
||||
def test_grs(self, client):
|
||||
assert (
|
||||
btc.get_address(client, "Groestlcoin", parse_path("44'/17'/0'/0/0"))
|
||||
== "Fj62rBJi8LvbmWu2jzkaUX1NFXLEqDLoZM"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(client, "Groestlcoin", parse_path("44'/17'/0'/1/0"))
|
||||
== "FmRaqvVBRrAp2Umfqx9V1ectZy8gw54QDN"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(client, "Groestlcoin", parse_path("44'/17'/0'/1/1"))
|
||||
== "Fmhtxeh7YdCBkyQF7AQG4QnY8y3rJg89di"
|
||||
)
|
||||
def test_tbtc(client):
|
||||
assert (
|
||||
btc.get_address(client, "Testnet", parse_path("m/44'/1'/0'/0/0"))
|
||||
== "mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(client, "Testnet", parse_path("m/44'/1'/0'/0/1"))
|
||||
== "mopZWqZZyQc3F2Sy33cvDtJchSAMsnLi7b"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(client, "Testnet", parse_path("m/44'/1'/0'/1/0"))
|
||||
== "mm6kLYbGEL1tGe4ZA8xacfgRPdW1NLjCbZ"
|
||||
)
|
||||
|
||||
@pytest.mark.altcoin
|
||||
def test_elements(self, client):
|
||||
|
||||
@pytest.mark.altcoin
|
||||
def test_bch(client):
|
||||
assert (
|
||||
btc.get_address(client, "Bcash", parse_path("44'/145'/0'/0/0"))
|
||||
== "bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(client, "Bcash", parse_path("44'/145'/0'/0/1"))
|
||||
== "bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(client, "Bcash", parse_path("44'/145'/0'/1/0"))
|
||||
== "bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.altcoin
|
||||
def test_grs(client):
|
||||
assert (
|
||||
btc.get_address(client, "Groestlcoin", parse_path("44'/17'/0'/0/0"))
|
||||
== "Fj62rBJi8LvbmWu2jzkaUX1NFXLEqDLoZM"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(client, "Groestlcoin", parse_path("44'/17'/0'/1/0"))
|
||||
== "FmRaqvVBRrAp2Umfqx9V1ectZy8gw54QDN"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(client, "Groestlcoin", parse_path("44'/17'/0'/1/1"))
|
||||
== "Fmhtxeh7YdCBkyQF7AQG4QnY8y3rJg89di"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.altcoin
|
||||
def test_elements(client):
|
||||
assert (
|
||||
btc.get_address(client, "Elements", parse_path("m/44'/1'/0'/0/0"))
|
||||
== "2dpWh6jbhAowNsQ5agtFzi7j6nKscj6UnEr"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.multisig
|
||||
def test_multisig(client):
|
||||
xpubs = []
|
||||
for n in range(1, 4):
|
||||
node = btc.get_public_node(client, parse_path(f"44'/0'/{n}'"))
|
||||
xpubs.append(node.xpub)
|
||||
|
||||
for nr in range(1, 4):
|
||||
assert (
|
||||
btc.get_address(client, "Elements", parse_path("m/44'/1'/0'/0/0"))
|
||||
== "2dpWh6jbhAowNsQ5agtFzi7j6nKscj6UnEr"
|
||||
)
|
||||
|
||||
@pytest.mark.multisig
|
||||
def test_multisig(self, client):
|
||||
xpubs = []
|
||||
for n in range(1, 4):
|
||||
node = btc.get_public_node(client, parse_path(f"44'/0'/{n}'"))
|
||||
xpubs.append(node.xpub)
|
||||
|
||||
for nr in range(1, 4):
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Bitcoin",
|
||||
parse_path(f"44'/0'/{nr}'/0/0"),
|
||||
show_display=(nr == 1),
|
||||
multisig=getmultisig(0, 0, xpubs=xpubs),
|
||||
)
|
||||
== "3Pdz86KtfJBuHLcSv4DysJo4aQfanTqCzG"
|
||||
btc.get_address(
|
||||
client,
|
||||
"Bitcoin",
|
||||
parse_path(f"44'/0'/{nr}'/0/0"),
|
||||
show_display=(nr == 1),
|
||||
multisig=getmultisig(0, 0, xpubs=xpubs),
|
||||
)
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Bitcoin",
|
||||
parse_path(f"44'/0'/{nr}'/1/0"),
|
||||
show_display=(nr == 1),
|
||||
multisig=getmultisig(1, 0, xpubs=xpubs),
|
||||
)
|
||||
== "36gP3KVx1ooStZ9quZDXbAF3GCr42b2zzd"
|
||||
== "3Pdz86KtfJBuHLcSv4DysJo4aQfanTqCzG"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Bitcoin",
|
||||
parse_path(f"44'/0'/{nr}'/1/0"),
|
||||
show_display=(nr == 1),
|
||||
multisig=getmultisig(1, 0, xpubs=xpubs),
|
||||
)
|
||||
== "36gP3KVx1ooStZ9quZDXbAF3GCr42b2zzd"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.multisig
|
||||
@pytest.mark.parametrize("show_display", (True, False))
|
||||
def test_multisig_missing(client, show_display):
|
||||
# Multisig with global suffix specification.
|
||||
# Use account numbers 1, 2 and 3 to create a valid multisig,
|
||||
# but not containing the keys from account 0 used below.
|
||||
nodes = [
|
||||
btc.get_public_node(client, parse_path(f"44'/0'/{i}'")).node
|
||||
for i in range(1, 4)
|
||||
]
|
||||
multisig1 = messages.MultisigRedeemScriptType(
|
||||
nodes=nodes, address_n=[0, 0], signatures=[b"", b"", b""], m=2
|
||||
)
|
||||
|
||||
# Multisig with per-node suffix specification.
|
||||
node = btc.get_public_node(
|
||||
client, parse_path("44h/0h/0h/0"), coin_name="Bitcoin"
|
||||
).node
|
||||
|
||||
multisig2 = messages.MultisigRedeemScriptType(
|
||||
pubkeys=[
|
||||
messages.HDNodePathType(node=node, address_n=[1]),
|
||||
messages.HDNodePathType(node=node, address_n=[2]),
|
||||
messages.HDNodePathType(node=node, address_n=[3]),
|
||||
],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
for multisig in (multisig1, multisig2):
|
||||
with pytest.raises(TrezorFailure):
|
||||
btc.get_address(
|
||||
client,
|
||||
"Bitcoin",
|
||||
parse_path("44'/0'/0'/0/0"),
|
||||
show_display=show_display,
|
||||
multisig=multisig,
|
||||
)
|
||||
|
||||
@pytest.mark.multisig
|
||||
@pytest.mark.parametrize("show_display", (True, False))
|
||||
def test_multisig_missing(self, client, show_display):
|
||||
# Multisig with global suffix specification.
|
||||
# Use account numbers 1, 2 and 3 to create a valid multisig,
|
||||
# but not containing the keys from account 0 used below.
|
||||
nodes = [
|
||||
btc.get_public_node(client, parse_path(f"44'/0'/{i}'")).node
|
||||
for i in range(1, 4)
|
||||
]
|
||||
multisig1 = messages.MultisigRedeemScriptType(
|
||||
nodes=nodes, address_n=[0, 0], signatures=[b"", b"", b""], m=2
|
||||
)
|
||||
|
||||
# Multisig with per-node suffix specification.
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.multisig
|
||||
def test_bch_multisig(client):
|
||||
xpubs = []
|
||||
for n in range(1, 4):
|
||||
node = btc.get_public_node(
|
||||
client, parse_path("44h/0h/0h/0"), coin_name="Bitcoin"
|
||||
).node
|
||||
client, parse_path(f"44'/145'/{n}'"), coin_name="Bcash"
|
||||
)
|
||||
xpubs.append(node.xpub)
|
||||
|
||||
multisig2 = messages.MultisigRedeemScriptType(
|
||||
pubkeys=[
|
||||
messages.HDNodePathType(node=node, address_n=[1]),
|
||||
messages.HDNodePathType(node=node, address_n=[2]),
|
||||
messages.HDNodePathType(node=node, address_n=[3]),
|
||||
],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
for nr in range(1, 4):
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Bcash",
|
||||
parse_path(f"44'/145'/{nr}'/0/0"),
|
||||
show_display=(nr == 1),
|
||||
multisig=getmultisig(0, 0, xpubs=xpubs),
|
||||
)
|
||||
== "bitcoincash:pqguz4nqq64jhr5v3kvpq4dsjrkda75hwy86gq0qzw"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Bcash",
|
||||
parse_path(f"44'/145'/{nr}'/1/0"),
|
||||
show_display=(nr == 1),
|
||||
multisig=getmultisig(1, 0, xpubs=xpubs),
|
||||
)
|
||||
== "bitcoincash:pp6kcpkhua7789g2vyj0qfkcux3yvje7euhyhltn0a"
|
||||
)
|
||||
|
||||
for multisig in (multisig1, multisig2):
|
||||
with pytest.raises(TrezorFailure):
|
||||
btc.get_address(
|
||||
client,
|
||||
"Bitcoin",
|
||||
parse_path("44'/0'/0'/0/0"),
|
||||
show_display=show_display,
|
||||
multisig=multisig,
|
||||
)
|
||||
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.multisig
|
||||
def test_bch_multisig(self, client):
|
||||
xpubs = []
|
||||
for n in range(1, 4):
|
||||
node = btc.get_public_node(
|
||||
client, parse_path(f"44'/145'/{n}'"), coin_name="Bcash"
|
||||
)
|
||||
xpubs.append(node.xpub)
|
||||
def test_public_ckd(client):
|
||||
node = btc.get_public_node(client, parse_path("m/44'/0'/0'")).node
|
||||
node_sub1 = btc.get_public_node(client, parse_path("m/44'/0'/0'/1/0")).node
|
||||
node_sub2 = bip32.public_ckd(node, [1, 0])
|
||||
|
||||
for nr in range(1, 4):
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Bcash",
|
||||
parse_path(f"44'/145'/{nr}'/0/0"),
|
||||
show_display=(nr == 1),
|
||||
multisig=getmultisig(0, 0, xpubs=xpubs),
|
||||
)
|
||||
== "bitcoincash:pqguz4nqq64jhr5v3kvpq4dsjrkda75hwy86gq0qzw"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Bcash",
|
||||
parse_path(f"44'/145'/{nr}'/1/0"),
|
||||
show_display=(nr == 1),
|
||||
multisig=getmultisig(1, 0, xpubs=xpubs),
|
||||
)
|
||||
== "bitcoincash:pp6kcpkhua7789g2vyj0qfkcux3yvje7euhyhltn0a"
|
||||
)
|
||||
assert node_sub1.chain_code == node_sub2.chain_code
|
||||
assert node_sub1.public_key == node_sub2.public_key
|
||||
|
||||
def test_public_ckd(self, client):
|
||||
node = btc.get_public_node(client, parse_path("m/44'/0'/0'")).node
|
||||
node_sub1 = btc.get_public_node(client, parse_path("m/44'/0'/0'/1/0")).node
|
||||
node_sub2 = bip32.public_ckd(node, [1, 0])
|
||||
address1 = btc.get_address(client, "Bitcoin", parse_path("m/44'/0'/0'/1/0"))
|
||||
address2 = bip32.get_address(node_sub2, 0)
|
||||
|
||||
assert node_sub1.chain_code == node_sub2.chain_code
|
||||
assert node_sub1.public_key == node_sub2.public_key
|
||||
|
||||
address1 = btc.get_address(client, "Bitcoin", parse_path("m/44'/0'/0'/1/0"))
|
||||
address2 = bip32.get_address(node_sub2, 0)
|
||||
|
||||
assert address2 == "1DyHzbQUoQEsLxJn6M7fMD8Xdt1XvNiwNE"
|
||||
assert address1 == address2
|
||||
assert address2 == "1DyHzbQUoQEsLxJn6M7fMD8Xdt1XvNiwNE"
|
||||
assert address1 == address2
|
||||
|
||||
|
||||
def test_invalid_path(client):
|
||||
|
@ -21,143 +21,145 @@ from trezorlib.exceptions import TrezorFailure
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
|
||||
class TestMsgGetaddressSegwit:
|
||||
def test_show_segwit(self, client):
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Testnet",
|
||||
parse_path("49'/1'/0'/1/0"),
|
||||
True,
|
||||
None,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
== "2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX"
|
||||
def test_show_segwit(client):
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Testnet",
|
||||
parse_path("49'/1'/0'/1/0"),
|
||||
True,
|
||||
None,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Testnet",
|
||||
parse_path("49'/1'/0'/0/0"),
|
||||
False,
|
||||
None,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
== "2N4Q5FhU2497BryFfUgbqkAJE87aKHUhXMp"
|
||||
== "2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Testnet",
|
||||
parse_path("49'/1'/0'/0/0"),
|
||||
False,
|
||||
None,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Testnet",
|
||||
parse_path("44'/1'/0'/0/0"),
|
||||
False,
|
||||
None,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
== "2N6UeBoqYEEnybg4cReFYDammpsyDw8R2Mc"
|
||||
== "2N4Q5FhU2497BryFfUgbqkAJE87aKHUhXMp"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Testnet",
|
||||
parse_path("44'/1'/0'/0/0"),
|
||||
False,
|
||||
None,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Testnet",
|
||||
parse_path("44'/1'/0'/0/0"),
|
||||
False,
|
||||
None,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
== "mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q"
|
||||
== "2N6UeBoqYEEnybg4cReFYDammpsyDw8R2Mc"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Testnet",
|
||||
parse_path("44'/1'/0'/0/0"),
|
||||
False,
|
||||
None,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
== "mvbu1Gdy8SUjTenqerxUaZyYjmveZvt33q"
|
||||
)
|
||||
|
||||
@pytest.mark.altcoin
|
||||
def test_show_segwit_altcoin(self, client):
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Groestlcoin Testnet",
|
||||
parse_path("49'/1'/0'/0/0"),
|
||||
False,
|
||||
None,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
== "2N4Q5FhU2497BryFfUgbqkAJE87aKDv3V3e"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Elements",
|
||||
parse_path("m/49'/1'/0'/0/0"),
|
||||
False,
|
||||
None,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
== "XNW67ZQA9K3AuXPBWvJH4zN2y5QBDTwy2Z"
|
||||
)
|
||||
|
||||
@pytest.mark.multisig
|
||||
def test_show_multisig_3(self, client):
|
||||
nodes = [
|
||||
btc.get_public_node(
|
||||
client, parse_path(f"49'/1'/{i}'"), coin_name="Testnet"
|
||||
).node
|
||||
for i in range(1, 4)
|
||||
]
|
||||
|
||||
multisig1 = proto.MultisigRedeemScriptType(
|
||||
nodes=nodes, address_n=[0, 7], signatures=[b"", b"", b""], m=2
|
||||
@pytest.mark.altcoin
|
||||
def test_show_segwit_altcoin(client):
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Groestlcoin Testnet",
|
||||
parse_path("49'/1'/0'/0/0"),
|
||||
False,
|
||||
None,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
# multisig2 = proto.MultisigRedeemScriptType(
|
||||
# pubkeys=map(lambda n: proto.HDNodePathType(node=bip32.deserialize(n.xpub), address_n=[2, 1]), nodes),
|
||||
# signatures=[b'', b'', b''],
|
||||
# m=2,
|
||||
# )
|
||||
for i in [1, 2, 3]:
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Testnet",
|
||||
parse_path(f"49'/1'/{i}'/0/7"),
|
||||
False,
|
||||
multisig1,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
== "2MwuUwUzPG17wiKQpfXmzfxJEoe7RXZDRad"
|
||||
)
|
||||
|
||||
@pytest.mark.multisig
|
||||
@pytest.mark.parametrize("show_display", (True, False))
|
||||
def test_multisig_missing(self, client, show_display):
|
||||
# Multisig with global suffix specification.
|
||||
# Use account numbers 1, 2 and 3 to create a valid multisig,
|
||||
# but not containing the keys from account 0 used below.
|
||||
nodes = [
|
||||
btc.get_public_node(client, parse_path(f"49'/0'/{i}'")).node
|
||||
for i in range(1, 4)
|
||||
]
|
||||
multisig1 = proto.MultisigRedeemScriptType(
|
||||
nodes=nodes, address_n=[0, 0], signatures=[b"", b"", b""], m=2
|
||||
== "2N4Q5FhU2497BryFfUgbqkAJE87aKDv3V3e"
|
||||
)
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Elements",
|
||||
parse_path("m/49'/1'/0'/0/0"),
|
||||
False,
|
||||
None,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
== "XNW67ZQA9K3AuXPBWvJH4zN2y5QBDTwy2Z"
|
||||
)
|
||||
|
||||
# Multisig with per-node suffix specification.
|
||||
node = btc.get_public_node(
|
||||
client, parse_path("49h/0h/0h/0"), coin_name="Bitcoin"
|
||||
|
||||
@pytest.mark.multisig
|
||||
def test_show_multisig_3(client):
|
||||
nodes = [
|
||||
btc.get_public_node(
|
||||
client, parse_path(f"49'/1'/{i}'"), coin_name="Testnet"
|
||||
).node
|
||||
multisig2 = proto.MultisigRedeemScriptType(
|
||||
pubkeys=[
|
||||
proto.HDNodePathType(node=node, address_n=[1]),
|
||||
proto.HDNodePathType(node=node, address_n=[2]),
|
||||
proto.HDNodePathType(node=node, address_n=[3]),
|
||||
],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
for i in range(1, 4)
|
||||
]
|
||||
|
||||
multisig1 = proto.MultisigRedeemScriptType(
|
||||
nodes=nodes, address_n=[0, 7], signatures=[b"", b"", b""], m=2
|
||||
)
|
||||
# multisig2 = proto.MultisigRedeemScriptType(
|
||||
# pubkeys=map(lambda n: proto.HDNodePathType(node=bip32.deserialize(n.xpub), address_n=[2, 1]), nodes),
|
||||
# signatures=[b'', b'', b''],
|
||||
# m=2,
|
||||
# )
|
||||
for i in [1, 2, 3]:
|
||||
assert (
|
||||
btc.get_address(
|
||||
client,
|
||||
"Testnet",
|
||||
parse_path(f"49'/1'/{i}'/0/7"),
|
||||
False,
|
||||
multisig1,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
== "2MwuUwUzPG17wiKQpfXmzfxJEoe7RXZDRad"
|
||||
)
|
||||
|
||||
for multisig in (multisig1, multisig2):
|
||||
with pytest.raises(TrezorFailure):
|
||||
btc.get_address(
|
||||
client,
|
||||
"Bitcoin",
|
||||
parse_path("49'/0'/0'/0/0"),
|
||||
show_display=show_display,
|
||||
multisig=multisig,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
|
||||
@pytest.mark.multisig
|
||||
@pytest.mark.parametrize("show_display", (True, False))
|
||||
def test_multisig_missing(client, show_display):
|
||||
# Multisig with global suffix specification.
|
||||
# Use account numbers 1, 2 and 3 to create a valid multisig,
|
||||
# but not containing the keys from account 0 used below.
|
||||
nodes = [
|
||||
btc.get_public_node(client, parse_path(f"49'/0'/{i}'")).node
|
||||
for i in range(1, 4)
|
||||
]
|
||||
multisig1 = proto.MultisigRedeemScriptType(
|
||||
nodes=nodes, address_n=[0, 0], signatures=[b"", b"", b""], m=2
|
||||
)
|
||||
|
||||
# Multisig with per-node suffix specification.
|
||||
node = btc.get_public_node(
|
||||
client, parse_path("49h/0h/0h/0"), coin_name="Bitcoin"
|
||||
).node
|
||||
multisig2 = proto.MultisigRedeemScriptType(
|
||||
pubkeys=[
|
||||
proto.HDNodePathType(node=node, address_n=[1]),
|
||||
proto.HDNodePathType(node=node, address_n=[2]),
|
||||
proto.HDNodePathType(node=node, address_n=[3]),
|
||||
],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
for multisig in (multisig1, multisig2):
|
||||
with pytest.raises(TrezorFailure):
|
||||
btc.get_address(
|
||||
client,
|
||||
"Bitcoin",
|
||||
parse_path("49'/0'/0'/0/0"),
|
||||
show_display=show_display,
|
||||
multisig=multisig,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
|
@ -21,68 +21,67 @@ from trezorlib import messages as proto, misc
|
||||
from ..common import MNEMONIC12
|
||||
|
||||
|
||||
class TestMsgGetECDHSessionKey:
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_ecdh(self, client):
|
||||
identity = proto.IdentityType(
|
||||
proto="gpg",
|
||||
user="",
|
||||
host="Satoshi Nakamoto <satoshi@bitcoin.org>",
|
||||
port="",
|
||||
path="",
|
||||
index=0,
|
||||
)
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_ecdh(client):
|
||||
identity = proto.IdentityType(
|
||||
proto="gpg",
|
||||
user="",
|
||||
host="Satoshi Nakamoto <satoshi@bitcoin.org>",
|
||||
port="",
|
||||
path="",
|
||||
index=0,
|
||||
)
|
||||
|
||||
peer_public_key = bytes.fromhex(
|
||||
"0407f2c6e5becf3213c1d07df0cfbe8e39f70a8c643df7575e5c56859ec52c45ca950499c019719dae0fda04248d851e52cf9d66eeb211d89a77be40de22b6c89d"
|
||||
)
|
||||
result = misc.get_ecdh_session_key(
|
||||
client,
|
||||
identity=identity,
|
||||
peer_public_key=peer_public_key,
|
||||
ecdsa_curve_name="secp256k1",
|
||||
)
|
||||
assert (
|
||||
result.session_key.hex()
|
||||
== "0495e5d8c9e5cc09e7cf4908774f52decb381ce97f2fc9ba56e959c13f03f9f47a03dd151cbc908bc1db84d46e2c33e7bbb9daddc800f985244c924fd64adf6647"
|
||||
)
|
||||
assert (
|
||||
result.public_key.hex()
|
||||
== "02a3b34db999f994aa91accb7b73ecafe0ce8ce228e17a45525ccbf73feeb7c809"
|
||||
)
|
||||
peer_public_key = bytes.fromhex(
|
||||
"0407f2c6e5becf3213c1d07df0cfbe8e39f70a8c643df7575e5c56859ec52c45ca950499c019719dae0fda04248d851e52cf9d66eeb211d89a77be40de22b6c89d"
|
||||
)
|
||||
result = misc.get_ecdh_session_key(
|
||||
client,
|
||||
identity=identity,
|
||||
peer_public_key=peer_public_key,
|
||||
ecdsa_curve_name="secp256k1",
|
||||
)
|
||||
assert (
|
||||
result.session_key.hex()
|
||||
== "0495e5d8c9e5cc09e7cf4908774f52decb381ce97f2fc9ba56e959c13f03f9f47a03dd151cbc908bc1db84d46e2c33e7bbb9daddc800f985244c924fd64adf6647"
|
||||
)
|
||||
assert (
|
||||
result.public_key.hex()
|
||||
== "02a3b34db999f994aa91accb7b73ecafe0ce8ce228e17a45525ccbf73feeb7c809"
|
||||
)
|
||||
|
||||
peer_public_key = bytes.fromhex(
|
||||
"04811a6c2bd2a547d0dd84747297fec47719e7c3f9b0024f027c2b237be99aac39a9230acbd163d0cb1524a0f5ea4bfed6058cec6f18368f72a12aa0c4d083ff64"
|
||||
)
|
||||
result = misc.get_ecdh_session_key(
|
||||
client,
|
||||
identity=identity,
|
||||
peer_public_key=peer_public_key,
|
||||
ecdsa_curve_name="nist256p1",
|
||||
)
|
||||
assert (
|
||||
result.session_key.hex()
|
||||
== "046d1f5c48af2cf2c57076ac2c9d7808db2086f614cb7b8107119ff2c6270cd209749809efe0196f01a0cc633788cef1f4a2bd650c99570d06962f923fca6d8fdf"
|
||||
)
|
||||
assert (
|
||||
result.public_key.hex()
|
||||
== "03fda61bc6e6be9b1dd99f7f9d04836d1bf2a6ea2426095210c8ce65091b09000a"
|
||||
)
|
||||
peer_public_key = bytes.fromhex(
|
||||
"04811a6c2bd2a547d0dd84747297fec47719e7c3f9b0024f027c2b237be99aac39a9230acbd163d0cb1524a0f5ea4bfed6058cec6f18368f72a12aa0c4d083ff64"
|
||||
)
|
||||
result = misc.get_ecdh_session_key(
|
||||
client,
|
||||
identity=identity,
|
||||
peer_public_key=peer_public_key,
|
||||
ecdsa_curve_name="nist256p1",
|
||||
)
|
||||
assert (
|
||||
result.session_key.hex()
|
||||
== "046d1f5c48af2cf2c57076ac2c9d7808db2086f614cb7b8107119ff2c6270cd209749809efe0196f01a0cc633788cef1f4a2bd650c99570d06962f923fca6d8fdf"
|
||||
)
|
||||
assert (
|
||||
result.public_key.hex()
|
||||
== "03fda61bc6e6be9b1dd99f7f9d04836d1bf2a6ea2426095210c8ce65091b09000a"
|
||||
)
|
||||
|
||||
peer_public_key = bytes.fromhex(
|
||||
"40a8cf4b6a64c4314e80f15a8ea55812bd735fbb365936a48b2d78807b575fa17a"
|
||||
)
|
||||
result = misc.get_ecdh_session_key(
|
||||
client,
|
||||
identity=identity,
|
||||
peer_public_key=peer_public_key,
|
||||
ecdsa_curve_name="curve25519",
|
||||
)
|
||||
assert (
|
||||
result.session_key.hex()
|
||||
== "04e24516669e0b7d3d72e5129fddd07b6644c30915f5c8b7f1f62324afb3624311"
|
||||
)
|
||||
assert (
|
||||
result.public_key.hex()
|
||||
== "019753a0738c55c7ba7c17dd4a9a975ce9b0d2b62e8a1ecef4a76767fad99d3c71"
|
||||
)
|
||||
peer_public_key = bytes.fromhex(
|
||||
"40a8cf4b6a64c4314e80f15a8ea55812bd735fbb365936a48b2d78807b575fa17a"
|
||||
)
|
||||
result = misc.get_ecdh_session_key(
|
||||
client,
|
||||
identity=identity,
|
||||
peer_public_key=peer_public_key,
|
||||
ecdsa_curve_name="curve25519",
|
||||
)
|
||||
assert (
|
||||
result.session_key.hex()
|
||||
== "04e24516669e0b7d3d72e5129fddd07b6644c30915f5c8b7f1f62324afb3624311"
|
||||
)
|
||||
assert (
|
||||
result.public_key.hex()
|
||||
== "019753a0738c55c7ba7c17dd4a9a975ce9b0d2b62e8a1ecef4a76767fad99d3c71"
|
||||
)
|
||||
|
@ -26,137 +26,137 @@ from ..common import (
|
||||
get_test_address,
|
||||
)
|
||||
|
||||
pytestmark = pytest.mark.setup_client(uninitialized=True)
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
class TestDeviceLoad:
|
||||
def test_load_device_1(self, client):
|
||||
debuglink.load_device(
|
||||
client,
|
||||
mnemonic=MNEMONIC12,
|
||||
pin="",
|
||||
passphrase_protection=False,
|
||||
label="test",
|
||||
)
|
||||
state = client.debug.state()
|
||||
assert state.mnemonic_secret == MNEMONIC12.encode()
|
||||
assert state.pin is None
|
||||
assert state.passphrase_protection is False
|
||||
|
||||
address = get_test_address(client)
|
||||
assert address == "mkqRFzxmkCGX9jxgpqqFHcxRUmLJcLDBer"
|
||||
def test_load_device_1(client):
|
||||
debuglink.load_device(
|
||||
client,
|
||||
mnemonic=MNEMONIC12,
|
||||
pin="",
|
||||
passphrase_protection=False,
|
||||
label="test",
|
||||
)
|
||||
state = client.debug.state()
|
||||
assert state.mnemonic_secret == MNEMONIC12.encode()
|
||||
assert state.pin is None
|
||||
assert state.passphrase_protection is False
|
||||
|
||||
def test_load_device_2(self, client):
|
||||
debuglink.load_device(
|
||||
client,
|
||||
mnemonic=MNEMONIC12,
|
||||
pin="1234",
|
||||
passphrase_protection=True,
|
||||
label="test",
|
||||
)
|
||||
client.use_passphrase("passphrase")
|
||||
state = client.debug.state()
|
||||
assert state.mnemonic_secret == MNEMONIC12.encode()
|
||||
address = get_test_address(client)
|
||||
assert address == "mkqRFzxmkCGX9jxgpqqFHcxRUmLJcLDBer"
|
||||
|
||||
if client.features.model == "1":
|
||||
# we do not send PIN in DebugLinkState in Core
|
||||
assert state.pin == "1234"
|
||||
assert state.passphrase_protection is True
|
||||
|
||||
address = get_test_address(client)
|
||||
assert address == "mx77VZjTVixVsU7nCtAKHnGFdsyNCnsWWw"
|
||||
def test_load_device_2(client):
|
||||
debuglink.load_device(
|
||||
client,
|
||||
mnemonic=MNEMONIC12,
|
||||
pin="1234",
|
||||
passphrase_protection=True,
|
||||
label="test",
|
||||
)
|
||||
client.use_passphrase("passphrase")
|
||||
state = client.debug.state()
|
||||
assert state.mnemonic_secret == MNEMONIC12.encode()
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
def test_load_device_slip39_basic(self, client):
|
||||
debuglink.load_device(
|
||||
client,
|
||||
mnemonic=MNEMONIC_SLIP39_BASIC_20_3of6,
|
||||
pin="",
|
||||
passphrase_protection=False,
|
||||
label="test",
|
||||
)
|
||||
assert client.features.backup_type == BackupType.Slip39_Basic
|
||||
if client.features.model == "1":
|
||||
# we do not send PIN in DebugLinkState in Core
|
||||
assert state.pin == "1234"
|
||||
assert state.passphrase_protection is True
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
def test_load_device_slip39_advanced(self, client):
|
||||
debuglink.load_device(
|
||||
client,
|
||||
mnemonic=MNEMONIC_SLIP39_ADVANCED_20,
|
||||
pin="",
|
||||
passphrase_protection=False,
|
||||
label="test",
|
||||
)
|
||||
assert client.features.backup_type == BackupType.Slip39_Advanced
|
||||
address = get_test_address(client)
|
||||
assert address == "mx77VZjTVixVsU7nCtAKHnGFdsyNCnsWWw"
|
||||
|
||||
def test_load_device_utf(self, client):
|
||||
words_nfkd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
|
||||
words_nfc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
|
||||
words_nfkc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
|
||||
words_nfd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
|
||||
|
||||
passphrase_nfkd = (
|
||||
u"Neuve\u030cr\u030citelne\u030c bezpec\u030cne\u0301 hesli\u0301c\u030cko"
|
||||
)
|
||||
passphrase_nfc = (
|
||||
u"Neuv\u011b\u0159iteln\u011b bezpe\u010dn\xe9 hesl\xed\u010dko"
|
||||
)
|
||||
passphrase_nfkc = (
|
||||
u"Neuv\u011b\u0159iteln\u011b bezpe\u010dn\xe9 hesl\xed\u010dko"
|
||||
)
|
||||
passphrase_nfd = (
|
||||
u"Neuve\u030cr\u030citelne\u030c bezpec\u030cne\u0301 hesli\u0301c\u030cko"
|
||||
)
|
||||
@pytest.mark.skip_t1
|
||||
def test_load_device_slip39_basic(client):
|
||||
debuglink.load_device(
|
||||
client,
|
||||
mnemonic=MNEMONIC_SLIP39_BASIC_20_3of6,
|
||||
pin="",
|
||||
passphrase_protection=False,
|
||||
label="test",
|
||||
)
|
||||
assert client.features.backup_type == BackupType.Slip39_Basic
|
||||
|
||||
debuglink.load_device(
|
||||
client,
|
||||
mnemonic=words_nfkd,
|
||||
pin="",
|
||||
passphrase_protection=True,
|
||||
label="test",
|
||||
language="en-US",
|
||||
skip_checksum=True,
|
||||
)
|
||||
client.use_passphrase(passphrase_nfkd)
|
||||
address_nfkd = get_test_address(client)
|
||||
|
||||
device.wipe(client)
|
||||
debuglink.load_device(
|
||||
client,
|
||||
mnemonic=words_nfc,
|
||||
pin="",
|
||||
passphrase_protection=True,
|
||||
label="test",
|
||||
language="en-US",
|
||||
skip_checksum=True,
|
||||
)
|
||||
client.use_passphrase(passphrase_nfc)
|
||||
address_nfc = get_test_address(client)
|
||||
@pytest.mark.skip_t1
|
||||
def test_load_device_slip39_advanced(client):
|
||||
debuglink.load_device(
|
||||
client,
|
||||
mnemonic=MNEMONIC_SLIP39_ADVANCED_20,
|
||||
pin="",
|
||||
passphrase_protection=False,
|
||||
label="test",
|
||||
)
|
||||
assert client.features.backup_type == BackupType.Slip39_Advanced
|
||||
|
||||
device.wipe(client)
|
||||
debuglink.load_device(
|
||||
client,
|
||||
mnemonic=words_nfkc,
|
||||
pin="",
|
||||
passphrase_protection=True,
|
||||
label="test",
|
||||
language="en-US",
|
||||
skip_checksum=True,
|
||||
)
|
||||
client.use_passphrase(passphrase_nfkc)
|
||||
address_nfkc = get_test_address(client)
|
||||
|
||||
device.wipe(client)
|
||||
debuglink.load_device(
|
||||
client,
|
||||
mnemonic=words_nfd,
|
||||
pin="",
|
||||
passphrase_protection=True,
|
||||
label="test",
|
||||
language="en-US",
|
||||
skip_checksum=True,
|
||||
)
|
||||
client.use_passphrase(passphrase_nfd)
|
||||
address_nfd = get_test_address(client)
|
||||
def test_load_device_utf(client):
|
||||
words_nfkd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
|
||||
words_nfc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
|
||||
words_nfkc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
|
||||
words_nfd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
|
||||
|
||||
assert address_nfkd == address_nfc
|
||||
assert address_nfkd == address_nfkc
|
||||
assert address_nfkd == address_nfd
|
||||
passphrase_nfkd = (
|
||||
u"Neuve\u030cr\u030citelne\u030c bezpec\u030cne\u0301 hesli\u0301c\u030cko"
|
||||
)
|
||||
passphrase_nfc = u"Neuv\u011b\u0159iteln\u011b bezpe\u010dn\xe9 hesl\xed\u010dko"
|
||||
passphrase_nfkc = u"Neuv\u011b\u0159iteln\u011b bezpe\u010dn\xe9 hesl\xed\u010dko"
|
||||
passphrase_nfd = (
|
||||
u"Neuve\u030cr\u030citelne\u030c bezpec\u030cne\u0301 hesli\u0301c\u030cko"
|
||||
)
|
||||
|
||||
debuglink.load_device(
|
||||
client,
|
||||
mnemonic=words_nfkd,
|
||||
pin="",
|
||||
passphrase_protection=True,
|
||||
label="test",
|
||||
language="en-US",
|
||||
skip_checksum=True,
|
||||
)
|
||||
client.use_passphrase(passphrase_nfkd)
|
||||
address_nfkd = get_test_address(client)
|
||||
|
||||
device.wipe(client)
|
||||
debuglink.load_device(
|
||||
client,
|
||||
mnemonic=words_nfc,
|
||||
pin="",
|
||||
passphrase_protection=True,
|
||||
label="test",
|
||||
language="en-US",
|
||||
skip_checksum=True,
|
||||
)
|
||||
client.use_passphrase(passphrase_nfc)
|
||||
address_nfc = get_test_address(client)
|
||||
|
||||
device.wipe(client)
|
||||
debuglink.load_device(
|
||||
client,
|
||||
mnemonic=words_nfkc,
|
||||
pin="",
|
||||
passphrase_protection=True,
|
||||
label="test",
|
||||
language="en-US",
|
||||
skip_checksum=True,
|
||||
)
|
||||
client.use_passphrase(passphrase_nfkc)
|
||||
address_nfkc = get_test_address(client)
|
||||
|
||||
device.wipe(client)
|
||||
debuglink.load_device(
|
||||
client,
|
||||
mnemonic=words_nfd,
|
||||
pin="",
|
||||
passphrase_protection=True,
|
||||
label="test",
|
||||
language="en-US",
|
||||
skip_checksum=True,
|
||||
)
|
||||
client.use_passphrase(passphrase_nfd)
|
||||
address_nfd = get_test_address(client)
|
||||
|
||||
assert address_nfkd == address_nfc
|
||||
assert address_nfkd == address_nfkc
|
||||
assert address_nfkd == address_nfd
|
||||
|
@ -21,126 +21,125 @@ from trezorlib import messages as proto, misc
|
||||
from ..common import MNEMONIC12
|
||||
|
||||
|
||||
class TestMsgSignidentity:
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_sign(self, client):
|
||||
hidden = bytes.fromhex(
|
||||
"cd8552569d6e4509266ef137584d1e62c7579b5b8ed69bbafa4b864c6521e7c2"
|
||||
)
|
||||
visual = "2015-03-23 17:39:22"
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_sign(client):
|
||||
hidden = bytes.fromhex(
|
||||
"cd8552569d6e4509266ef137584d1e62c7579b5b8ed69bbafa4b864c6521e7c2"
|
||||
)
|
||||
visual = "2015-03-23 17:39:22"
|
||||
|
||||
# URI : https://satoshi@bitcoin.org/login
|
||||
# hash : d0e2389d4c8394a9f3e32de01104bf6e8db2d9e2bb0905d60fffa5a18fd696db
|
||||
# path : m/2147483661/2637750992/2845082444/3761103859/4005495825
|
||||
identity = proto.IdentityType(
|
||||
proto="https",
|
||||
user="satoshi",
|
||||
host="bitcoin.org",
|
||||
port="",
|
||||
path="/login",
|
||||
index=0,
|
||||
)
|
||||
sig = misc.sign_identity(client, identity, hidden, visual)
|
||||
assert sig.address == "17F17smBTX9VTZA9Mj8LM5QGYNZnmziCjL"
|
||||
assert (
|
||||
sig.public_key.hex()
|
||||
== "023a472219ad3327b07c18273717bb3a40b39b743756bf287fbd5fa9d263237f45"
|
||||
)
|
||||
assert (
|
||||
sig.signature.hex()
|
||||
== "20f2d1a42d08c3a362be49275c3ffeeaa415fc040971985548b9f910812237bb41770bf2c8d488428799fbb7e52c11f1a3404011375e4080e077e0e42ab7a5ba02"
|
||||
)
|
||||
# URI : https://satoshi@bitcoin.org/login
|
||||
# hash : d0e2389d4c8394a9f3e32de01104bf6e8db2d9e2bb0905d60fffa5a18fd696db
|
||||
# path : m/2147483661/2637750992/2845082444/3761103859/4005495825
|
||||
identity = proto.IdentityType(
|
||||
proto="https",
|
||||
user="satoshi",
|
||||
host="bitcoin.org",
|
||||
port="",
|
||||
path="/login",
|
||||
index=0,
|
||||
)
|
||||
sig = misc.sign_identity(client, identity, hidden, visual)
|
||||
assert sig.address == "17F17smBTX9VTZA9Mj8LM5QGYNZnmziCjL"
|
||||
assert (
|
||||
sig.public_key.hex()
|
||||
== "023a472219ad3327b07c18273717bb3a40b39b743756bf287fbd5fa9d263237f45"
|
||||
)
|
||||
assert (
|
||||
sig.signature.hex()
|
||||
== "20f2d1a42d08c3a362be49275c3ffeeaa415fc040971985548b9f910812237bb41770bf2c8d488428799fbb7e52c11f1a3404011375e4080e077e0e42ab7a5ba02"
|
||||
)
|
||||
|
||||
# URI : ftp://satoshi@bitcoin.org:2323/pub
|
||||
# hash : 79a6b53831c6ff224fb283587adc4ebae8fb0d734734a46c876838f52dff53f3
|
||||
# path : m/2147483661/3098912377/2734671409/3632509519/3125730426
|
||||
identity = proto.IdentityType(
|
||||
proto="ftp",
|
||||
user="satoshi",
|
||||
host="bitcoin.org",
|
||||
port="2323",
|
||||
path="/pub",
|
||||
index=3,
|
||||
)
|
||||
sig = misc.sign_identity(client, identity, hidden, visual)
|
||||
assert sig.address == "1KAr6r5qF2kADL8bAaRQBjGKYEGxn9WrbS"
|
||||
assert (
|
||||
sig.public_key.hex()
|
||||
== "0266cf12d2ba381c5fd797da0d64f59c07a6f1b034ad276cca6bf2729e92b20d9c"
|
||||
)
|
||||
assert (
|
||||
sig.signature.hex()
|
||||
== "20bbd12dc657d534fc0f7e40186e22c447e0866a016f654f380adffa9a84e9faf412a1bb0ae908296537838cf91145e77da08681c63d07b7dca40728b9e6cb17cf"
|
||||
)
|
||||
# URI : ftp://satoshi@bitcoin.org:2323/pub
|
||||
# hash : 79a6b53831c6ff224fb283587adc4ebae8fb0d734734a46c876838f52dff53f3
|
||||
# path : m/2147483661/3098912377/2734671409/3632509519/3125730426
|
||||
identity = proto.IdentityType(
|
||||
proto="ftp",
|
||||
user="satoshi",
|
||||
host="bitcoin.org",
|
||||
port="2323",
|
||||
path="/pub",
|
||||
index=3,
|
||||
)
|
||||
sig = misc.sign_identity(client, identity, hidden, visual)
|
||||
assert sig.address == "1KAr6r5qF2kADL8bAaRQBjGKYEGxn9WrbS"
|
||||
assert (
|
||||
sig.public_key.hex()
|
||||
== "0266cf12d2ba381c5fd797da0d64f59c07a6f1b034ad276cca6bf2729e92b20d9c"
|
||||
)
|
||||
assert (
|
||||
sig.signature.hex()
|
||||
== "20bbd12dc657d534fc0f7e40186e22c447e0866a016f654f380adffa9a84e9faf412a1bb0ae908296537838cf91145e77da08681c63d07b7dca40728b9e6cb17cf"
|
||||
)
|
||||
|
||||
# URI : ssh://satoshi@bitcoin.org
|
||||
# hash : 5fa612f558a1a3b1fb7f010b2ea0a25cb02520a0ffa202ce74a92fc6145da5f3
|
||||
# path : m/2147483661/4111640159/2980290904/2332131323/3701645358
|
||||
identity = proto.IdentityType(
|
||||
proto="ssh", user="satoshi", host="bitcoin.org", port="", path="", index=47
|
||||
)
|
||||
sig = misc.sign_identity(
|
||||
client, identity, hidden, visual, ecdsa_curve_name="nist256p1"
|
||||
)
|
||||
assert sig.address is None
|
||||
assert (
|
||||
sig.public_key.hex()
|
||||
== "0373f21a3da3d0e96fc2189f81dd826658c3d76b2d55bd1da349bc6c3573b13ae4"
|
||||
)
|
||||
assert (
|
||||
sig.signature.hex()
|
||||
== "005122cebabb852cdd32103b602662afa88e54c0c0c1b38d7099c64dcd49efe908288114e66ed2d8c82f23a70b769a4db723173ec53840c08aafb840d3f09a18d3"
|
||||
)
|
||||
# URI : ssh://satoshi@bitcoin.org
|
||||
# hash : 5fa612f558a1a3b1fb7f010b2ea0a25cb02520a0ffa202ce74a92fc6145da5f3
|
||||
# path : m/2147483661/4111640159/2980290904/2332131323/3701645358
|
||||
identity = proto.IdentityType(
|
||||
proto="ssh", user="satoshi", host="bitcoin.org", port="", path="", index=47
|
||||
)
|
||||
sig = misc.sign_identity(
|
||||
client, identity, hidden, visual, ecdsa_curve_name="nist256p1"
|
||||
)
|
||||
assert sig.address is None
|
||||
assert (
|
||||
sig.public_key.hex()
|
||||
== "0373f21a3da3d0e96fc2189f81dd826658c3d76b2d55bd1da349bc6c3573b13ae4"
|
||||
)
|
||||
assert (
|
||||
sig.signature.hex()
|
||||
== "005122cebabb852cdd32103b602662afa88e54c0c0c1b38d7099c64dcd49efe908288114e66ed2d8c82f23a70b769a4db723173ec53840c08aafb840d3f09a18d3"
|
||||
)
|
||||
|
||||
# URI : ssh://satoshi@bitcoin.org
|
||||
# hash : 5fa612f558a1a3b1fb7f010b2ea0a25cb02520a0ffa202ce74a92fc6145da5f3
|
||||
# path : m/2147483661/4111640159/2980290904/2332131323/3701645358
|
||||
identity = proto.IdentityType(
|
||||
proto="ssh", user="satoshi", host="bitcoin.org", port="", path="", index=47
|
||||
)
|
||||
sig = misc.sign_identity(
|
||||
client, identity, hidden, visual, ecdsa_curve_name="ed25519"
|
||||
)
|
||||
assert sig.address is None
|
||||
assert (
|
||||
sig.public_key.hex()
|
||||
== "000fac2a491e0f5b871dc48288a4cae551bac5cb0ed19df0764d6e721ec5fade18"
|
||||
)
|
||||
assert (
|
||||
sig.signature.hex()
|
||||
== "00f05e5085e666429de397c70a081932654369619c0bd2a6579ea6c1ef2af112ef79998d6c862a16b932d44b1ac1b83c8cbcd0fbda228274fde9e0d0ca6e9cb709"
|
||||
)
|
||||
# URI : ssh://satoshi@bitcoin.org
|
||||
# hash : 5fa612f558a1a3b1fb7f010b2ea0a25cb02520a0ffa202ce74a92fc6145da5f3
|
||||
# path : m/2147483661/4111640159/2980290904/2332131323/3701645358
|
||||
identity = proto.IdentityType(
|
||||
proto="ssh", user="satoshi", host="bitcoin.org", port="", path="", index=47
|
||||
)
|
||||
sig = misc.sign_identity(
|
||||
client, identity, hidden, visual, ecdsa_curve_name="ed25519"
|
||||
)
|
||||
assert sig.address is None
|
||||
assert (
|
||||
sig.public_key.hex()
|
||||
== "000fac2a491e0f5b871dc48288a4cae551bac5cb0ed19df0764d6e721ec5fade18"
|
||||
)
|
||||
assert (
|
||||
sig.signature.hex()
|
||||
== "00f05e5085e666429de397c70a081932654369619c0bd2a6579ea6c1ef2af112ef79998d6c862a16b932d44b1ac1b83c8cbcd0fbda228274fde9e0d0ca6e9cb709"
|
||||
)
|
||||
|
||||
# URI : gpg://satoshi@bitcoin.org
|
||||
identity = proto.IdentityType(
|
||||
proto="gpg", user="satoshi", host="bitcoin.org", port="", path=""
|
||||
)
|
||||
sig = misc.sign_identity(
|
||||
client, identity, hidden, visual, ecdsa_curve_name="ed25519"
|
||||
)
|
||||
assert sig.address is None
|
||||
assert (
|
||||
sig.public_key.hex()
|
||||
== "00d18cdf4dbdbb50ef1fdba1ae0539451f3354a366d6a35313712ab82f16d4cd9e"
|
||||
)
|
||||
assert (
|
||||
sig.signature.hex()
|
||||
== "00f47f1a09a2875b971811ebbece19c3004c3ecbe84e65666dc8c36cc2fc002544af8a3f545375ebe53d73b41c700df2f9020256c31bb774a7eb03ed9819226407"
|
||||
)
|
||||
# URI : gpg://satoshi@bitcoin.org
|
||||
identity = proto.IdentityType(
|
||||
proto="gpg", user="satoshi", host="bitcoin.org", port="", path=""
|
||||
)
|
||||
sig = misc.sign_identity(
|
||||
client, identity, hidden, visual, ecdsa_curve_name="ed25519"
|
||||
)
|
||||
assert sig.address is None
|
||||
assert (
|
||||
sig.public_key.hex()
|
||||
== "00d18cdf4dbdbb50ef1fdba1ae0539451f3354a366d6a35313712ab82f16d4cd9e"
|
||||
)
|
||||
assert (
|
||||
sig.signature.hex()
|
||||
== "00f47f1a09a2875b971811ebbece19c3004c3ecbe84e65666dc8c36cc2fc002544af8a3f545375ebe53d73b41c700df2f9020256c31bb774a7eb03ed9819226407"
|
||||
)
|
||||
|
||||
# URI : signify://satoshi@bitcoin.org
|
||||
identity = proto.IdentityType(
|
||||
proto="signify", user="satoshi", host="bitcoin.org", port="", path=""
|
||||
)
|
||||
sig = misc.sign_identity(
|
||||
client, identity, hidden, visual, ecdsa_curve_name="ed25519"
|
||||
)
|
||||
assert sig.address is None
|
||||
assert (
|
||||
sig.public_key.hex()
|
||||
== "0038c0f42c0e47b233e837763098f029fd01009b74fdf4b0d60db114fb0f4f8b17"
|
||||
)
|
||||
assert (
|
||||
sig.signature.hex()
|
||||
== "009bb30a7a894e6cdd86e2b75803745e93bd5294b979f9e00ce9dc870642c7f6ad7322af4c54d401ea793494e8a5fdf2bf8b88c6e875094512bd67b94f9188000d"
|
||||
)
|
||||
# URI : signify://satoshi@bitcoin.org
|
||||
identity = proto.IdentityType(
|
||||
proto="signify", user="satoshi", host="bitcoin.org", port="", path=""
|
||||
)
|
||||
sig = misc.sign_identity(
|
||||
client, identity, hidden, visual, ecdsa_curve_name="ed25519"
|
||||
)
|
||||
assert sig.address is None
|
||||
assert (
|
||||
sig.public_key.hex()
|
||||
== "0038c0f42c0e47b233e837763098f029fd01009b74fdf4b0d60db114fb0f4f8b17"
|
||||
)
|
||||
assert (
|
||||
sig.signature.hex()
|
||||
== "009bb30a7a894e6cdd86e2b75803745e93bd5294b979f9e00ce9dc870642c7f6ad7322af4c54d401ea793494e8a5fdf2bf8b88c6e875094512bd67b94f9188000d"
|
||||
)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -39,459 +39,465 @@ TXHASH_8b6db9 = bytes.fromhex(
|
||||
"8b6db9b8ba24235d86b053ea2ccb484fc32b96f89c3c39f98d86f90db16076a0"
|
||||
)
|
||||
|
||||
pytestmark = pytest.mark.altcoin
|
||||
|
||||
@pytest.mark.altcoin
|
||||
class TestMsgSigntxBch:
|
||||
def test_send_bch_change(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/145'/0'/0/0"),
|
||||
# bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv
|
||||
amount=1995344,
|
||||
prev_hash=TXHASH_bc37c2,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=parse_path("44'/145'/0'/1/0"),
|
||||
amount=1896050,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address="bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4",
|
||||
amount=73452,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_bc37c2),
|
||||
request_input(0, TXHASH_bc37c2),
|
||||
request_output(0, TXHASH_bc37c2),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000001781a716b1e15b41b07157933e5d777392a75bf87132650cb2e7d46fb8dc237bc000000006a473044022061aee4f17abe044d5df8c52c9ffd3b84e5a29743517e488b20ecf1ae0b3e4d3a02206bb84c55e407f3b684ff8d9bea0a3409cfd865795a19d10b3d3c31f12795c34a412103a020b36130021a0f037c1d1a02042e325c0cb666d6478c1afdcd9d913b9ef080ffffffff0272ee1c00000000001976a914b1401fce7e8bf123c88a0467e0ed11e3b9fbef5488acec1e0100000000001976a914d51eca49695cdf47e7f4b55507893e3ad53fe9d888ac00000000"
|
||||
def test_send_bch_change(client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/145'/0'/0/0"),
|
||||
# bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv
|
||||
amount=1995344,
|
||||
prev_hash=TXHASH_bc37c2,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=parse_path("44'/145'/0'/1/0"),
|
||||
amount=1896050,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address="bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4",
|
||||
amount=73452,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_bc37c2),
|
||||
request_input(0, TXHASH_bc37c2),
|
||||
request_output(0, TXHASH_bc37c2),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API
|
||||
)
|
||||
|
||||
def test_send_bch_nochange(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/145'/0'/1/0"),
|
||||
# bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw
|
||||
amount=1896050,
|
||||
prev_hash=TXHASH_502e85,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
inp2 = proto.TxInputType(
|
||||
address_n=parse_path("44'/145'/0'/0/1"),
|
||||
# bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4
|
||||
amount=73452,
|
||||
prev_hash=TXHASH_502e85,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="bitcoincash:qq6wnnkrz7ykaqvxrx4hmjvayvzjzml54uyk76arx4",
|
||||
amount=1934960,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_502e85),
|
||||
request_input(0, TXHASH_502e85),
|
||||
request_output(0, TXHASH_502e85),
|
||||
request_output(1, TXHASH_502e85),
|
||||
request_input(1),
|
||||
request_meta(TXHASH_502e85),
|
||||
request_input(0, TXHASH_502e85),
|
||||
request_output(0, TXHASH_502e85),
|
||||
request_output(1, TXHASH_502e85),
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Bcash", [inp1, inp2], [out1], prev_txes=TX_API
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000001781a716b1e15b41b07157933e5d777392a75bf87132650cb2e7d46fb8dc237bc000000006a473044022061aee4f17abe044d5df8c52c9ffd3b84e5a29743517e488b20ecf1ae0b3e4d3a02206bb84c55e407f3b684ff8d9bea0a3409cfd865795a19d10b3d3c31f12795c34a412103a020b36130021a0f037c1d1a02042e325c0cb666d6478c1afdcd9d913b9ef080ffffffff0272ee1c00000000001976a914b1401fce7e8bf123c88a0467e0ed11e3b9fbef5488acec1e0100000000001976a914d51eca49695cdf47e7f4b55507893e3ad53fe9d888ac00000000"
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000022c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50000000006a47304402207a2a955f1cb3dc5f03f2c82934f55654882af4e852e5159639f6349e9386ec4002205fb8419dce4e648eae8f67bc4e369adfb130a87d2ea2d668f8144213b12bb457412103174c61e9c5362507e8061e28d2c0ce3d4df4e73f3535ae0b12f37809e0f92d2dffffffff2c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50010000006a473044022062151cf960b71823bbe68c7ed2c2a93ad1b9706a30255fddb02fcbe056d8c26102207bad1f0872bc5f0cfaf22e45c925c35d6c1466e303163b75cb7688038f1a5541412102595caf9aeb6ffdd0e82b150739a83297358b9a77564de382671056ad9e5b8c58ffffffff0170861d00000000001976a91434e9cec317896e818619ab7dc99d2305216ff4af88ac00000000"
|
||||
|
||||
def test_send_bch_nochange(client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/145'/0'/1/0"),
|
||||
# bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw
|
||||
amount=1896050,
|
||||
prev_hash=TXHASH_502e85,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
inp2 = proto.TxInputType(
|
||||
address_n=parse_path("44'/145'/0'/0/1"),
|
||||
# bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4
|
||||
amount=73452,
|
||||
prev_hash=TXHASH_502e85,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="bitcoincash:qq6wnnkrz7ykaqvxrx4hmjvayvzjzml54uyk76arx4",
|
||||
amount=1934960,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_502e85),
|
||||
request_input(0, TXHASH_502e85),
|
||||
request_output(0, TXHASH_502e85),
|
||||
request_output(1, TXHASH_502e85),
|
||||
request_input(1),
|
||||
request_meta(TXHASH_502e85),
|
||||
request_input(0, TXHASH_502e85),
|
||||
request_output(0, TXHASH_502e85),
|
||||
request_output(1, TXHASH_502e85),
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Bcash", [inp1, inp2], [out1], prev_txes=TX_API
|
||||
)
|
||||
|
||||
def test_send_bch_oldaddr(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/145'/0'/1/0"),
|
||||
# bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw
|
||||
amount=1896050,
|
||||
prev_hash=TXHASH_502e85,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
inp2 = proto.TxInputType(
|
||||
address_n=parse_path("44'/145'/0'/0/1"),
|
||||
# bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4
|
||||
amount=73452,
|
||||
prev_hash=TXHASH_502e85,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="15pnEDZJo3ycPUamqP3tEDnEju1oW5fBCz",
|
||||
amount=1934960,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_502e85),
|
||||
request_input(0, TXHASH_502e85),
|
||||
request_output(0, TXHASH_502e85),
|
||||
request_output(1, TXHASH_502e85),
|
||||
request_input(1),
|
||||
request_meta(TXHASH_502e85),
|
||||
request_input(0, TXHASH_502e85),
|
||||
request_output(0, TXHASH_502e85),
|
||||
request_output(1, TXHASH_502e85),
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Bcash", [inp1, inp2], [out1], prev_txes=TX_API
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000022c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50000000006a47304402207a2a955f1cb3dc5f03f2c82934f55654882af4e852e5159639f6349e9386ec4002205fb8419dce4e648eae8f67bc4e369adfb130a87d2ea2d668f8144213b12bb457412103174c61e9c5362507e8061e28d2c0ce3d4df4e73f3535ae0b12f37809e0f92d2dffffffff2c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50010000006a473044022062151cf960b71823bbe68c7ed2c2a93ad1b9706a30255fddb02fcbe056d8c26102207bad1f0872bc5f0cfaf22e45c925c35d6c1466e303163b75cb7688038f1a5541412102595caf9aeb6ffdd0e82b150739a83297358b9a77564de382671056ad9e5b8c58ffffffff0170861d00000000001976a91434e9cec317896e818619ab7dc99d2305216ff4af88ac00000000"
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000022c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50000000006a47304402207a2a955f1cb3dc5f03f2c82934f55654882af4e852e5159639f6349e9386ec4002205fb8419dce4e648eae8f67bc4e369adfb130a87d2ea2d668f8144213b12bb457412103174c61e9c5362507e8061e28d2c0ce3d4df4e73f3535ae0b12f37809e0f92d2dffffffff2c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50010000006a473044022062151cf960b71823bbe68c7ed2c2a93ad1b9706a30255fddb02fcbe056d8c26102207bad1f0872bc5f0cfaf22e45c925c35d6c1466e303163b75cb7688038f1a5541412102595caf9aeb6ffdd0e82b150739a83297358b9a77564de382671056ad9e5b8c58ffffffff0170861d00000000001976a91434e9cec317896e818619ab7dc99d2305216ff4af88ac00000000"
|
||||
|
||||
def test_send_bch_oldaddr(client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/145'/0'/1/0"),
|
||||
# bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw
|
||||
amount=1896050,
|
||||
prev_hash=TXHASH_502e85,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
inp2 = proto.TxInputType(
|
||||
address_n=parse_path("44'/145'/0'/0/1"),
|
||||
# bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4
|
||||
amount=73452,
|
||||
prev_hash=TXHASH_502e85,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="15pnEDZJo3ycPUamqP3tEDnEju1oW5fBCz",
|
||||
amount=1934960,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_502e85),
|
||||
request_input(0, TXHASH_502e85),
|
||||
request_output(0, TXHASH_502e85),
|
||||
request_output(1, TXHASH_502e85),
|
||||
request_input(1),
|
||||
request_meta(TXHASH_502e85),
|
||||
request_input(0, TXHASH_502e85),
|
||||
request_output(0, TXHASH_502e85),
|
||||
request_output(1, TXHASH_502e85),
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Bcash", [inp1, inp2], [out1], prev_txes=TX_API
|
||||
)
|
||||
|
||||
def test_attack_change_input(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/145'/10'/0/0"),
|
||||
amount=1995344,
|
||||
prev_hash=TXHASH_bc37c2,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000022c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50000000006a47304402207a2a955f1cb3dc5f03f2c82934f55654882af4e852e5159639f6349e9386ec4002205fb8419dce4e648eae8f67bc4e369adfb130a87d2ea2d668f8144213b12bb457412103174c61e9c5362507e8061e28d2c0ce3d4df4e73f3535ae0b12f37809e0f92d2dffffffff2c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50010000006a473044022062151cf960b71823bbe68c7ed2c2a93ad1b9706a30255fddb02fcbe056d8c26102207bad1f0872bc5f0cfaf22e45c925c35d6c1466e303163b75cb7688038f1a5541412102595caf9aeb6ffdd0e82b150739a83297358b9a77564de382671056ad9e5b8c58ffffffff0170861d00000000001976a91434e9cec317896e818619ab7dc99d2305216ff4af88ac00000000"
|
||||
)
|
||||
|
||||
|
||||
def test_attack_change_input(client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/145'/10'/0/0"),
|
||||
amount=1995344,
|
||||
prev_hash=TXHASH_bc37c2,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=parse_path("44'/145'/10'/1/0"),
|
||||
amount=1896050,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address="bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4",
|
||||
amount=73452,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
attack_count = 2
|
||||
|
||||
def attack_processor(msg):
|
||||
nonlocal attack_count
|
||||
|
||||
if msg.tx.inputs and msg.tx.inputs[0] == inp1:
|
||||
if attack_count > 0:
|
||||
attack_count -= 1
|
||||
else:
|
||||
msg.tx.inputs[0].address_n[2] = H_(1)
|
||||
|
||||
return msg
|
||||
|
||||
with client:
|
||||
client.set_filter(proto.TxAck, attack_processor)
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_bc37c2),
|
||||
request_input(0, TXHASH_bc37c2),
|
||||
request_output(0, TXHASH_bc37c2),
|
||||
request_input(0),
|
||||
proto.Failure(code=proto.FailureType.ProcessError),
|
||||
]
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=parse_path("44'/145'/10'/1/0"),
|
||||
amount=1896050,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address="bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4",
|
||||
amount=73452,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
with pytest.raises(TrezorFailure):
|
||||
btc.sign_tx(client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API)
|
||||
|
||||
|
||||
@pytest.mark.multisig
|
||||
def test_send_bch_multisig_wrongchange(client):
|
||||
nodes = [
|
||||
btc.get_public_node(
|
||||
client, parse_path(f"48'/145'/{i}'/0'"), coin_name="Bcash"
|
||||
).node
|
||||
for i in range(1, 4)
|
||||
]
|
||||
|
||||
def getmultisig(chain, nr, signatures):
|
||||
return proto.MultisigRedeemScriptType(
|
||||
nodes=nodes, address_n=[chain, nr], signatures=signatures, m=2
|
||||
)
|
||||
|
||||
attack_count = 2
|
||||
|
||||
def attack_processor(msg):
|
||||
nonlocal attack_count
|
||||
|
||||
if msg.tx.inputs and msg.tx.inputs[0] == inp1:
|
||||
if attack_count > 0:
|
||||
attack_count -= 1
|
||||
else:
|
||||
msg.tx.inputs[0].address_n[2] = H_(1)
|
||||
|
||||
return msg
|
||||
|
||||
with client:
|
||||
client.set_filter(proto.TxAck, attack_processor)
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_bc37c2),
|
||||
request_input(0, TXHASH_bc37c2),
|
||||
request_output(0, TXHASH_bc37c2),
|
||||
request_input(0),
|
||||
proto.Failure(code=proto.FailureType.ProcessError),
|
||||
]
|
||||
)
|
||||
with pytest.raises(TrezorFailure):
|
||||
btc.sign_tx(client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API)
|
||||
|
||||
@pytest.mark.multisig
|
||||
def test_send_bch_multisig_wrongchange(self, client):
|
||||
nodes = [
|
||||
btc.get_public_node(
|
||||
client, parse_path(f"48'/145'/{i}'/0'"), coin_name="Bcash"
|
||||
).node
|
||||
for i in range(1, 4)
|
||||
]
|
||||
|
||||
def getmultisig(chain, nr, signatures):
|
||||
return proto.MultisigRedeemScriptType(
|
||||
nodes=nodes, address_n=[chain, nr], signatures=signatures, m=2
|
||||
)
|
||||
|
||||
correcthorse = proto.HDNodeType(
|
||||
depth=1,
|
||||
fingerprint=0,
|
||||
child_num=0,
|
||||
chain_code=bytes.fromhex(
|
||||
"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
),
|
||||
public_key=bytes.fromhex(
|
||||
"0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71"
|
||||
),
|
||||
correcthorse = proto.HDNodeType(
|
||||
depth=1,
|
||||
fingerprint=0,
|
||||
child_num=0,
|
||||
chain_code=bytes.fromhex(
|
||||
"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
),
|
||||
public_key=bytes.fromhex(
|
||||
"0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71"
|
||||
),
|
||||
)
|
||||
sig = bytes.fromhex(
|
||||
"304402207274b5a4d15e75f3df7319a375557b0efba9b27bc63f9f183a17da95a6125c94022000efac57629f1522e2d3958430e2ef073b0706cfac06cce492651b79858f09ae"
|
||||
)
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("48'/145'/1'/0'/1/0"),
|
||||
multisig=getmultisig(1, 0, [b"", sig, b""]),
|
||||
# bitcoincash:pp6kcpkhua7789g2vyj0qfkcux3yvje7euhyhltn0a
|
||||
amount=24000,
|
||||
prev_hash=TXHASH_f68caf,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=parse_path("48'/145'/1'/0'/1/1"),
|
||||
multisig=proto.MultisigRedeemScriptType(
|
||||
pubkeys=[
|
||||
proto.HDNodePathType(node=nodes[0], address_n=[1, 1]),
|
||||
proto.HDNodePathType(node=correcthorse, address_n=[]),
|
||||
proto.HDNodePathType(node=correcthorse, address_n=[]),
|
||||
],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
),
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
amount=23000,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_f68caf),
|
||||
request_input(0, TXHASH_f68caf),
|
||||
request_output(0, TXHASH_f68caf),
|
||||
request_output(1, TXHASH_f68caf),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
sig = bytes.fromhex(
|
||||
"304402207274b5a4d15e75f3df7319a375557b0efba9b27bc63f9f183a17da95a6125c94022000efac57629f1522e2d3958430e2ef073b0706cfac06cce492651b79858f09ae"
|
||||
(signatures1, serialized_tx) = btc.sign_tx(
|
||||
client, "Bcash", [inp1], [out1], prev_txes=TX_API
|
||||
)
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("48'/145'/1'/0'/1/0"),
|
||||
multisig=getmultisig(1, 0, [b"", sig, b""]),
|
||||
# bitcoincash:pp6kcpkhua7789g2vyj0qfkcux3yvje7euhyhltn0a
|
||||
amount=24000,
|
||||
prev_hash=TXHASH_f68caf,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=parse_path("48'/145'/1'/0'/1/1"),
|
||||
multisig=proto.MultisigRedeemScriptType(
|
||||
pubkeys=[
|
||||
proto.HDNodePathType(node=nodes[0], address_n=[1, 1]),
|
||||
proto.HDNodePathType(node=correcthorse, address_n=[]),
|
||||
proto.HDNodePathType(node=correcthorse, address_n=[]),
|
||||
],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
),
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
amount=23000,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_f68caf),
|
||||
request_input(0, TXHASH_f68caf),
|
||||
request_output(0, TXHASH_f68caf),
|
||||
request_output(1, TXHASH_f68caf),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
(signatures1, serialized_tx) = btc.sign_tx(
|
||||
client, "Bcash", [inp1], [out1], prev_txes=TX_API
|
||||
)
|
||||
assert (
|
||||
signatures1[0].hex()
|
||||
== "304402205ce02f7bf3ef225e4a17e2b5a98dc6ca5536a6b68088f94200390a1d505c4f3e022045657781095e01422736c5541b03b014101d76e54089eda030cb016dfce10e98"
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000015f3d291cae106548f3be5ed0f4cbedc65668fa881d60347ab0d512df10af8cf601000000fc0047304402205ce02f7bf3ef225e4a17e2b5a98dc6ca5536a6b68088f94200390a1d505c4f3e022045657781095e01422736c5541b03b014101d76e54089eda030cb016dfce10e984147304402207274b5a4d15e75f3df7319a375557b0efba9b27bc63f9f183a17da95a6125c94022000efac57629f1522e2d3958430e2ef073b0706cfac06cce492651b79858f09ae414c69522102962724052105f03332ab700812afc5ca665d264b13339be1fe7f7fdd3a2a685821024364cd1fdc2aa05bc8b09874a57aa1082a47ac9062d35f22ed5f4afefb3f67fc21024d375b44804f3b0c3493ea0806eb25cc85f51e0d616d6bd6e4ef0388e71cd29e53aeffffffff01d85900000000000017a9140d5566bfc721e6c3d5ab583841d387f3939ffed38700000000"
|
||||
assert (
|
||||
signatures1[0].hex()
|
||||
== "304402205ce02f7bf3ef225e4a17e2b5a98dc6ca5536a6b68088f94200390a1d505c4f3e022045657781095e01422736c5541b03b014101d76e54089eda030cb016dfce10e98"
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000015f3d291cae106548f3be5ed0f4cbedc65668fa881d60347ab0d512df10af8cf601000000fc0047304402205ce02f7bf3ef225e4a17e2b5a98dc6ca5536a6b68088f94200390a1d505c4f3e022045657781095e01422736c5541b03b014101d76e54089eda030cb016dfce10e984147304402207274b5a4d15e75f3df7319a375557b0efba9b27bc63f9f183a17da95a6125c94022000efac57629f1522e2d3958430e2ef073b0706cfac06cce492651b79858f09ae414c69522102962724052105f03332ab700812afc5ca665d264b13339be1fe7f7fdd3a2a685821024364cd1fdc2aa05bc8b09874a57aa1082a47ac9062d35f22ed5f4afefb3f67fc21024d375b44804f3b0c3493ea0806eb25cc85f51e0d616d6bd6e4ef0388e71cd29e53aeffffffff01d85900000000000017a9140d5566bfc721e6c3d5ab583841d387f3939ffed38700000000"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.multisig
|
||||
def test_send_bch_multisig_change(client):
|
||||
nodes = [
|
||||
btc.get_public_node(
|
||||
client, parse_path(f"48'/145'/{i}'/0'"), coin_name="Bcash"
|
||||
).node
|
||||
for i in range(1, 4)
|
||||
]
|
||||
|
||||
EMPTY_SIGNATURES = [b"", b"", b""]
|
||||
|
||||
def getmultisig(chain, nr, signatures):
|
||||
return proto.MultisigRedeemScriptType(
|
||||
nodes=nodes, address_n=[chain, nr], signatures=signatures, m=2
|
||||
)
|
||||
|
||||
@pytest.mark.multisig
|
||||
def test_send_bch_multisig_change(self, client):
|
||||
nodes = [
|
||||
btc.get_public_node(
|
||||
client, parse_path(f"48'/145'/{i}'/0'"), coin_name="Bcash"
|
||||
).node
|
||||
for i in range(1, 4)
|
||||
]
|
||||
|
||||
EMPTY_SIGNATURES = [b"", b"", b""]
|
||||
|
||||
def getmultisig(chain, nr, signatures):
|
||||
return proto.MultisigRedeemScriptType(
|
||||
nodes=nodes, address_n=[chain, nr], signatures=signatures, m=2
|
||||
)
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("48'/145'/3'/0'/0/0"),
|
||||
multisig=getmultisig(0, 0, EMPTY_SIGNATURES),
|
||||
amount=48490,
|
||||
prev_hash=TXHASH_8b6db9,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("48'/145'/3'/0'/0/0"),
|
||||
multisig=getmultisig(0, 0, EMPTY_SIGNATURES),
|
||||
amount=48490,
|
||||
prev_hash=TXHASH_8b6db9,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="bitcoincash:qqq8gx2j76nw4dfefumxmdwvtf2tpsjznusgsmzex9",
|
||||
amount=24000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=parse_path("48'/145'/3'/0'/1/0"),
|
||||
multisig=getmultisig(1, 0, EMPTY_SIGNATURES),
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
amount=24000,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_8b6db9),
|
||||
request_input(0, TXHASH_8b6db9),
|
||||
request_output(0, TXHASH_8b6db9),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="bitcoincash:qqq8gx2j76nw4dfefumxmdwvtf2tpsjznusgsmzex9",
|
||||
amount=24000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=parse_path("48'/145'/3'/0'/1/0"),
|
||||
multisig=getmultisig(1, 0, EMPTY_SIGNATURES),
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
amount=24000,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_8b6db9),
|
||||
request_input(0, TXHASH_8b6db9),
|
||||
request_output(0, TXHASH_8b6db9),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
(signatures1, serialized_tx) = btc.sign_tx(
|
||||
client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API
|
||||
)
|
||||
|
||||
assert (
|
||||
signatures1[0].hex()
|
||||
== "304402202b75dbb307d2556b9a85851d27ab118b3f06344bccb6e21b0a5dfcf74e0e644f02206611c59396d44741d34fd7bb602be06ef91690b22b47c3f3c271e15e20176ac0"
|
||||
(signatures1, serialized_tx) = btc.sign_tx(
|
||||
client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API
|
||||
)
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("48'/145'/1'/0'/0/0"),
|
||||
multisig=getmultisig(0, 0, [b"", b"", signatures1[0]]),
|
||||
# bitcoincash:pqguz4nqq64jhr5v3kvpq4dsjrkda75hwy86gq0qzw
|
||||
amount=48490,
|
||||
prev_hash=TXHASH_8b6db9,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
)
|
||||
out2.address_n[2] = H_(1)
|
||||
assert (
|
||||
signatures1[0].hex()
|
||||
== "304402202b75dbb307d2556b9a85851d27ab118b3f06344bccb6e21b0a5dfcf74e0e644f02206611c59396d44741d34fd7bb602be06ef91690b22b47c3f3c271e15e20176ac0"
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_8b6db9),
|
||||
request_input(0, TXHASH_8b6db9),
|
||||
request_output(0, TXHASH_8b6db9),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
(signatures1, serialized_tx) = btc.sign_tx(
|
||||
client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API
|
||||
)
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("48'/145'/1'/0'/0/0"),
|
||||
multisig=getmultisig(0, 0, [b"", b"", signatures1[0]]),
|
||||
# bitcoincash:pqguz4nqq64jhr5v3kvpq4dsjrkda75hwy86gq0qzw
|
||||
amount=48490,
|
||||
prev_hash=TXHASH_8b6db9,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
)
|
||||
out2.address_n[2] = H_(1)
|
||||
|
||||
assert (
|
||||
signatures1[0].hex()
|
||||
== "3045022100cc12faf18a489d8014e978ef7ca0760aa6487cdb40b49dd991bfe9c66625f5a802206088fef49ecad30679d55eaa870741bbb8b83fac08eb078872ac276c8139015d"
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_8b6db9),
|
||||
request_input(0, TXHASH_8b6db9),
|
||||
request_output(0, TXHASH_8b6db9),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000001a07660b10df9868df9393c9cf8962bc34f48cb2cea53b0865d2324bab8b96d8b00000000fdfd0000483045022100cc12faf18a489d8014e978ef7ca0760aa6487cdb40b49dd991bfe9c66625f5a802206088fef49ecad30679d55eaa870741bbb8b83fac08eb078872ac276c8139015d4147304402202b75dbb307d2556b9a85851d27ab118b3f06344bccb6e21b0a5dfcf74e0e644f02206611c59396d44741d34fd7bb602be06ef91690b22b47c3f3c271e15e20176ac0414c6952210290cc724ccb90a6c7c1c3b291938449464ea474390183909e51bcd2807ecb779d210222f537684e2933563f737192fbf1947fd9034402e5708d10f6decd8e1f03e172210350df5cb41013d6b06581230556006b0a85ccccd205745cc10c927755193c241b53aeffffffff02c05d0000000000001976a91400741952f6a6eab5394f366db5cc5a54b0c2429f88acc05d00000000000017a914dfc8c2dda26f7151ed7df8aeeca24089e6410fdd8700000000"
|
||||
(signatures1, serialized_tx) = btc.sign_tx(
|
||||
client, "Bcash", [inp1], [out1, out2], prev_txes=TX_API
|
||||
)
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
def test_send_bch_external_presigned(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
# address_n=parse_path("44'/145'/0'/1/0"),
|
||||
# bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw
|
||||
amount=1896050,
|
||||
prev_hash=TXHASH_502e85,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.EXTERNAL,
|
||||
script_pubkey=bytes.fromhex(
|
||||
"76a914b1401fce7e8bf123c88a0467e0ed11e3b9fbef5488ac"
|
||||
),
|
||||
script_sig=bytes.fromhex(
|
||||
"47304402207a2a955f1cb3dc5f03f2c82934f55654882af4e852e5159639f6349e9386ec4002205fb8419dce4e648eae8f67bc4e369adfb130a87d2ea2d668f8144213b12bb457412103174c61e9c5362507e8061e28d2c0ce3d4df4e73f3535ae0b12f37809e0f92d2d"
|
||||
),
|
||||
)
|
||||
inp2 = proto.TxInputType(
|
||||
address_n=parse_path("44'/145'/0'/0/1"),
|
||||
# bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4
|
||||
amount=73452,
|
||||
prev_hash=TXHASH_502e85,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="bitcoincash:qq6wnnkrz7ykaqvxrx4hmjvayvzjzml54uyk76arx4",
|
||||
amount=1934960,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_502e85),
|
||||
request_input(0, TXHASH_502e85),
|
||||
request_output(0, TXHASH_502e85),
|
||||
request_output(1, TXHASH_502e85),
|
||||
request_input(1),
|
||||
request_meta(TXHASH_502e85),
|
||||
request_input(0, TXHASH_502e85),
|
||||
request_output(0, TXHASH_502e85),
|
||||
request_output(1, TXHASH_502e85),
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Bcash", [inp1, inp2], [out1], prev_txes=TX_API
|
||||
)
|
||||
assert (
|
||||
signatures1[0].hex()
|
||||
== "3045022100cc12faf18a489d8014e978ef7ca0760aa6487cdb40b49dd991bfe9c66625f5a802206088fef49ecad30679d55eaa870741bbb8b83fac08eb078872ac276c8139015d"
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000001a07660b10df9868df9393c9cf8962bc34f48cb2cea53b0865d2324bab8b96d8b00000000fdfd0000483045022100cc12faf18a489d8014e978ef7ca0760aa6487cdb40b49dd991bfe9c66625f5a802206088fef49ecad30679d55eaa870741bbb8b83fac08eb078872ac276c8139015d4147304402202b75dbb307d2556b9a85851d27ab118b3f06344bccb6e21b0a5dfcf74e0e644f02206611c59396d44741d34fd7bb602be06ef91690b22b47c3f3c271e15e20176ac0414c6952210290cc724ccb90a6c7c1c3b291938449464ea474390183909e51bcd2807ecb779d210222f537684e2933563f737192fbf1947fd9034402e5708d10f6decd8e1f03e172210350df5cb41013d6b06581230556006b0a85ccccd205745cc10c927755193c241b53aeffffffff02c05d0000000000001976a91400741952f6a6eab5394f366db5cc5a54b0c2429f88acc05d00000000000017a914dfc8c2dda26f7151ed7df8aeeca24089e6410fdd8700000000"
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000022c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50000000006a47304402207a2a955f1cb3dc5f03f2c82934f55654882af4e852e5159639f6349e9386ec4002205fb8419dce4e648eae8f67bc4e369adfb130a87d2ea2d668f8144213b12bb457412103174c61e9c5362507e8061e28d2c0ce3d4df4e73f3535ae0b12f37809e0f92d2dffffffff2c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50010000006a473044022062151cf960b71823bbe68c7ed2c2a93ad1b9706a30255fddb02fcbe056d8c26102207bad1f0872bc5f0cfaf22e45c925c35d6c1466e303163b75cb7688038f1a5541412102595caf9aeb6ffdd0e82b150739a83297358b9a77564de382671056ad9e5b8c58ffffffff0170861d00000000001976a91434e9cec317896e818619ab7dc99d2305216ff4af88ac00000000"
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
def test_send_bch_external_presigned(client):
|
||||
inp1 = proto.TxInputType(
|
||||
# address_n=parse_path("44'/145'/0'/1/0"),
|
||||
# bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw
|
||||
amount=1896050,
|
||||
prev_hash=TXHASH_502e85,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.EXTERNAL,
|
||||
script_pubkey=bytes.fromhex(
|
||||
"76a914b1401fce7e8bf123c88a0467e0ed11e3b9fbef5488ac"
|
||||
),
|
||||
script_sig=bytes.fromhex(
|
||||
"47304402207a2a955f1cb3dc5f03f2c82934f55654882af4e852e5159639f6349e9386ec4002205fb8419dce4e648eae8f67bc4e369adfb130a87d2ea2d668f8144213b12bb457412103174c61e9c5362507e8061e28d2c0ce3d4df4e73f3535ae0b12f37809e0f92d2d"
|
||||
),
|
||||
)
|
||||
inp2 = proto.TxInputType(
|
||||
address_n=parse_path("44'/145'/0'/0/1"),
|
||||
# bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4
|
||||
amount=73452,
|
||||
prev_hash=TXHASH_502e85,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="bitcoincash:qq6wnnkrz7ykaqvxrx4hmjvayvzjzml54uyk76arx4",
|
||||
amount=1934960,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_502e85),
|
||||
request_input(0, TXHASH_502e85),
|
||||
request_output(0, TXHASH_502e85),
|
||||
request_output(1, TXHASH_502e85),
|
||||
request_input(1),
|
||||
request_meta(TXHASH_502e85),
|
||||
request_input(0, TXHASH_502e85),
|
||||
request_output(0, TXHASH_502e85),
|
||||
request_output(1, TXHASH_502e85),
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Bcash", [inp1, inp2], [out1], prev_txes=TX_API
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000022c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50000000006a47304402207a2a955f1cb3dc5f03f2c82934f55654882af4e852e5159639f6349e9386ec4002205fb8419dce4e648eae8f67bc4e369adfb130a87d2ea2d668f8144213b12bb457412103174c61e9c5362507e8061e28d2c0ce3d4df4e73f3535ae0b12f37809e0f92d2dffffffff2c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50010000006a473044022062151cf960b71823bbe68c7ed2c2a93ad1b9706a30255fddb02fcbe056d8c26102207bad1f0872bc5f0cfaf22e45c925c35d6c1466e303163b75cb7688038f1a5541412102595caf9aeb6ffdd0e82b150739a83297358b9a77564de382671056ad9e5b8c58ffffffff0170861d00000000001976a91434e9cec317896e818619ab7dc99d2305216ff4af88ac00000000"
|
||||
)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -38,97 +38,96 @@ TXHASH_15575a = bytes.fromhex(
|
||||
"15575a1c874bd60a819884e116c42e6791c8283ce1fc3b79f0d18531a61bbb8a"
|
||||
)
|
||||
|
||||
pytestmark = pytest.mark.altcoin
|
||||
|
||||
@pytest.mark.altcoin
|
||||
class TestMsgSigntxDash:
|
||||
def test_send_dash(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/5'/0'/0/0"),
|
||||
# dash:XdTw4G5AWW4cogGd7ayybyBNDbuB45UpgH
|
||||
amount=1000000000,
|
||||
prev_hash=TXHASH_5579ea,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="XpTc36DPAeWmaueNBA9JqCg2GC8XDLKSYe",
|
||||
amount=999999000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(inp1.prev_hash),
|
||||
request_input(0, inp1.prev_hash),
|
||||
request_input(1, inp1.prev_hash),
|
||||
request_output(0, inp1.prev_hash),
|
||||
request_output(1, inp1.prev_hash),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Dash", [inp1], [out1], prev_txes=TX_API
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000014fb02af26dca339e7e06c4f148dfce57c9afa5f537d0d8e733022a4ba6ea7955010000006a4730440220387be4d1e4b5e355614091416373e99e1a3532b8cc9a8629368060aff2681bdb02200a0c4a5e9eb2ce6adb6c2e01ec8f954463dcc04f531ed8a89a2b40019d5aeb0b012102936f80cac2ba719ddb238646eb6b78a170a55a52a9b9f08c43523a4a6bd5c896ffffffff0118c69a3b000000001976a9149710d6545407e78c326aa8c8ae386ec7f883b0af88ac00000000"
|
||||
def test_send_dash(client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/5'/0'/0/0"),
|
||||
# dash:XdTw4G5AWW4cogGd7ayybyBNDbuB45UpgH
|
||||
amount=1000000000,
|
||||
prev_hash=TXHASH_5579ea,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="XpTc36DPAeWmaueNBA9JqCg2GC8XDLKSYe",
|
||||
amount=999999000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(inp1.prev_hash),
|
||||
request_input(0, inp1.prev_hash),
|
||||
request_input(1, inp1.prev_hash),
|
||||
request_output(0, inp1.prev_hash),
|
||||
request_output(1, inp1.prev_hash),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(client, "Dash", [inp1], [out1], prev_txes=TX_API)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000014fb02af26dca339e7e06c4f148dfce57c9afa5f537d0d8e733022a4ba6ea7955010000006a4730440220387be4d1e4b5e355614091416373e99e1a3532b8cc9a8629368060aff2681bdb02200a0c4a5e9eb2ce6adb6c2e01ec8f954463dcc04f531ed8a89a2b40019d5aeb0b012102936f80cac2ba719ddb238646eb6b78a170a55a52a9b9f08c43523a4a6bd5c896ffffffff0118c69a3b000000001976a9149710d6545407e78c326aa8c8ae386ec7f883b0af88ac00000000"
|
||||
)
|
||||
|
||||
|
||||
def test_send_dash_dip2_input(client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/5'/0'/0/0"),
|
||||
# dash:XdTw4G5AWW4cogGd7ayybyBNDbuB45UpgH
|
||||
amount=4095000260,
|
||||
prev_hash=TXHASH_15575a,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=parse_path("44'/5'/0'/1/0"),
|
||||
amount=4000000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address="XrEFMNkxeipYHgEQKiJuqch8XzwrtfH5fm",
|
||||
amount=95000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(inp1.prev_hash),
|
||||
request_input(0, inp1.prev_hash),
|
||||
request_output(0, inp1.prev_hash),
|
||||
request_output(1, inp1.prev_hash),
|
||||
request_extra_data(0, 39, inp1.prev_hash),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Dash", [inp1], [out1, out2], prev_txes=TX_API
|
||||
)
|
||||
|
||||
def test_send_dash_dip2_input(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/5'/0'/0/0"),
|
||||
# dash:XdTw4G5AWW4cogGd7ayybyBNDbuB45UpgH
|
||||
amount=4095000260,
|
||||
prev_hash=TXHASH_15575a,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=parse_path("44'/5'/0'/1/0"),
|
||||
amount=4000000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address="XrEFMNkxeipYHgEQKiJuqch8XzwrtfH5fm",
|
||||
amount=95000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(inp1.prev_hash),
|
||||
request_input(0, inp1.prev_hash),
|
||||
request_output(0, inp1.prev_hash),
|
||||
request_output(1, inp1.prev_hash),
|
||||
request_extra_data(0, 39, inp1.prev_hash),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Dash", [inp1], [out1, out2], prev_txes=TX_API
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000018abb1ba63185d1f0793bfce13c28c891672ec416e18498810ad64b871c5a5715010000006b483045022100f0442b6d9c7533cd6f74afa993b280ed9475276d69df4dac631bc3b5591ba71b022051daf125372c1c477681bbd804a6445d8ff6840901854fb0b485b1c6c7866c44012102936f80cac2ba719ddb238646eb6b78a170a55a52a9b9f08c43523a4a6bd5c896ffffffff0200286bee000000001976a914fd61dd017dad1f505c0511142cc9ac51ef3a5beb88acc095a905000000001976a914aa7a6a1f43dfc34d17e562ce1845b804b73fc31e88ac00000000"
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000018abb1ba63185d1f0793bfce13c28c891672ec416e18498810ad64b871c5a5715010000006b483045022100f0442b6d9c7533cd6f74afa993b280ed9475276d69df4dac631bc3b5591ba71b022051daf125372c1c477681bbd804a6445d8ff6840901854fb0b485b1c6c7866c44012102936f80cac2ba719ddb238646eb6b78a170a55a52a9b9f08c43523a4a6bd5c896ffffffff0200286bee000000001976a914fd61dd017dad1f505c0511142cc9ac51ef3a5beb88acc095a905000000001976a914aa7a6a1f43dfc34d17e562ce1845b804b73fc31e88ac00000000"
|
||||
)
|
||||
|
@ -51,214 +51,318 @@ TXHASH_1f00fc = bytes.fromhex(
|
||||
"1f00fc54530d7c4877f5032e91b6c507f6a1531861dede2ab134e5c0b5dfe8c8"
|
||||
)
|
||||
|
||||
pytestmark = [pytest.mark.altcoin, pytest.mark.decred]
|
||||
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.decred
|
||||
class TestMsgSigntxDecred:
|
||||
def test_send_decred(self, client):
|
||||
|
||||
def test_send_decred(client):
|
||||
inp1 = proto.TxInputType(
|
||||
# TscqTv1he8MZrV321SfRghw7LFBCJDKB3oz
|
||||
address_n=parse_path("m/44'/1'/0'/0/0"),
|
||||
prev_hash=TXHASH_e16248,
|
||||
prev_index=1,
|
||||
amount=200000000,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
decred_tree=0,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="TscqTv1he8MZrV321SfRghw7LFBCJDKB3oz",
|
||||
amount=190000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.FeeOverThreshold),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_e16248),
|
||||
request_input(0, TXHASH_e16248),
|
||||
request_output(0, TXHASH_e16248),
|
||||
request_output(1, TXHASH_e16248),
|
||||
request_input(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Decred Testnet", [inp1], [out1], prev_txes=TX_API
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000001edd579e9462ee0e80127a817e0500d4f942a4cf8f2d6530e0c0a9ab3f04862e10100000000ffffffff01802b530b0000000000001976a914819d291a2f7fbf770e784bfd78b5ce92c58e95ea88ac00000000000000000100c2eb0b0000000000000000ffffffff6a473044022009e394c7dec76ab6988270b467839b1462ad781556bce37383b76e026418ce6302204f7f6ef535d2986b095d7c96232a0990a0b9ce3004894b39c167bb18e5833ac30121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
def test_purchase_ticket_decred(client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("m/44'/1'/0'/0/0"),
|
||||
prev_hash=TXHASH_e16248,
|
||||
prev_index=1,
|
||||
amount=200000000,
|
||||
decred_tree=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="TscqTv1he8MZrV321SfRghw7LFBCJDKB3oz",
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
amount=199900000,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=parse_path("m/44'/1'/0'/0/0"),
|
||||
amount=200000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out3 = proto.TxOutputType(
|
||||
address="TsR28UZRprhgQQhzWns2M6cAwchrNVvbYq2",
|
||||
amount=0,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
request_output(2),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_e16248),
|
||||
request_input(0, TXHASH_e16248),
|
||||
request_output(0, TXHASH_e16248),
|
||||
request_output(1, TXHASH_e16248),
|
||||
request_input(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Decred Testnet",
|
||||
[inp1],
|
||||
[out1, out2, out3],
|
||||
prev_txes=TX_API,
|
||||
decred_staking_ticket=True,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000001edd579e9462ee0e80127a817e0500d4f942a4cf8f2d6530e0c0a9ab3f04862e10100000000ffffffff03603bea0b0000000000001aba76a914819d291a2f7fbf770e784bfd78b5ce92c58e95ea88ac00000000000000000000206a1edc1a98d791735eb9a8715a2a219c23680edcedad00c2eb0b000000000058000000000000000000001abd76a914000000000000000000000000000000000000000088ac00000000000000000100c2eb0b0000000000000000ffffffff6b4830450221008ced5411a6d92b761bdd8b9f7fbc5bfae3c31f9369050c218977f4540ab1ec9602206e89c821878ebfd959d1c4a63100eec5b1154c8d9508c039bb78e333498a73b40121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
def test_spend_from_stake_generation_and_revocation_decred(client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("m/44'/1'/0'/0/0"),
|
||||
prev_hash=TXHASH_8b6890,
|
||||
prev_index=2,
|
||||
amount=200000000,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
decred_staking_spend=proto.DecredStakingSpendType.SSGen,
|
||||
decred_tree=1,
|
||||
)
|
||||
|
||||
inp2 = proto.TxInputType(
|
||||
address_n=parse_path("m/44'/1'/0'/0/0"),
|
||||
prev_hash=TXHASH_1f00fc,
|
||||
prev_index=0,
|
||||
amount=200000000,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
decred_staking_spend=proto.DecredStakingSpendType.SSRTX,
|
||||
decred_tree=1,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="TscqTv1he8MZrV321SfRghw7LFBCJDKB3oz",
|
||||
amount=399900000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_8b6890),
|
||||
request_input(0, TXHASH_8b6890),
|
||||
request_input(1, TXHASH_8b6890),
|
||||
request_output(0, TXHASH_8b6890),
|
||||
request_output(1, TXHASH_8b6890),
|
||||
request_output(2, TXHASH_8b6890),
|
||||
request_input(1),
|
||||
request_meta(TXHASH_1f00fc),
|
||||
request_input(0, TXHASH_1f00fc),
|
||||
request_output(0, TXHASH_1f00fc),
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Decred Testnet", [inp1, inp2], [out1], prev_txes=TX_API
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "010000000254e249113666e84c70de1dbee976f18d1438e4b7c58b376ffe64370ac190688b0200000001ffffffffc8e8dfb5c0e534b12adede611853a1f607c5b6912e03f577487c0d5354fc001f0000000001ffffffff0160fdd5170000000000001976a914819d291a2f7fbf770e784bfd78b5ce92c58e95ea88ac00000000000000000200c2eb0b0000000000000000ffffffff6b483045022100bdcb877c97d72db74eca06fefa21a7f7b00afcd5d916fce2155ed7df1ca5546102201e1f9efd7d652b449474c2c70171bfc4535544927bed62021f7334447d1ea4740121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd000c2eb0b0000000000000000ffffffff6a473044022030c5743c442bd696d19dcf73d54e95526e726de965c2e2b4b9fd70248eaae21d02201305a3bcc2bb0e33122277763990e3b48f317d61264a68d190fb8acfc004cc640121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0"
|
||||
)
|
||||
|
||||
|
||||
def test_send_decred_change(client):
|
||||
inp1 = proto.TxInputType(
|
||||
# TscqTv1he8MZrV321SfRghw7LFBCJDKB3oz
|
||||
address_n=parse_path("m/44'/1'/0'/0/0"),
|
||||
amount=190000000,
|
||||
prev_hash=TXHASH_5e6e35,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
decred_tree=0,
|
||||
)
|
||||
|
||||
inp2 = proto.TxInputType(
|
||||
# TscqTv1he8MZrV321SfRghw7LFBCJDKB3oz
|
||||
address_n=parse_path("m/44'/1'/0'/0/0"),
|
||||
amount=200000000,
|
||||
prev_hash=TXHASH_ccf95b,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
decred_tree=0,
|
||||
)
|
||||
|
||||
inp3 = proto.TxInputType(
|
||||
# Tskt39YEvzoJ5KBDH4f1auNzG3jViVjZ2RV
|
||||
address_n=parse_path("m/44'/1'/0'/0/1"),
|
||||
amount=200000000,
|
||||
prev_hash=TXHASH_f395ef,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
decred_tree=0,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="TsWjioPrP8E1TuTMmTrVMM2BA4iPrjQXBpR",
|
||||
amount=489975000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
# TsaSFRwfN9muW5F6ZX36iSksc9hruiC5F97
|
||||
address_n=parse_path("m/44'/1'/0'/1/0"),
|
||||
amount=100000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_input(2),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_5e6e35),
|
||||
request_input(0, TXHASH_5e6e35),
|
||||
request_output(0, TXHASH_5e6e35),
|
||||
request_input(1),
|
||||
request_meta(TXHASH_ccf95b),
|
||||
request_input(0, TXHASH_ccf95b),
|
||||
request_output(0, TXHASH_ccf95b),
|
||||
request_output(1, TXHASH_ccf95b),
|
||||
request_input(2),
|
||||
request_meta(TXHASH_f395ef),
|
||||
request_input(0, TXHASH_f395ef),
|
||||
request_output(0, TXHASH_f395ef),
|
||||
request_output(1, TXHASH_f395ef),
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_input(2),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Decred Testnet",
|
||||
[inp1, inp2, inp3],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "010000000370b95980a47b9bcb4ec2c2b450888a53179b1a5fdb23f5023cc533a300356e5e0000000000ffffffff74bc93bcfce18aff2e522d6822817522e2815a00175b2eae59ef20d20f5bf9cc0100000000ffffffff13317ab453832deabd684d2302eed42580c28ba3e715db66a731a8723eef95f30000000000ffffffff02d86c341d0000000000001976a9143eb656115197956125365348c542e37b6d3d259988ac00e1f5050000000000001976a9143ee6f9d662e7be18373d80e5eb44627014c2bf6688ac000000000000000003802b530b0000000000000000ffffffff6a47304402200e50a6d43c462045917792e7d03b4354900c3baccb7abef66f556a32b12f2ca6022031ae94fdf2a41dd6ed2e081faf0f8f1c64411a1b46eb26f7f35d94402b2bde110121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd000c2eb0b0000000000000000ffffffff6a47304402204894c2f8e76c4645d2df600cdd01443aeb48807b72150c4bc10eebd126529532022054cd37462a3f0ddb85c75b4e874ab0c2aad7eebcff3e6c1ac20e1c16babe36720121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd000c2eb0b0000000000000000ffffffff6b4830450221009f1ba584023da8aafd57374e83be68f1a097b906967ec9e50736f31bfc7989f102204a190fc2885e394572b5c2ced046657b1dd07abdb19144e21e78987968c7f17601210294e3e5e77e22eea0e4c0d30d89beb4db7f69b4bf1ae709e411d6a06618b8f852"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.multisig
|
||||
def test_decred_multisig_change(client):
|
||||
paths = [parse_path(f"m/48'/1'/{index}'/0'") for index in range(3)]
|
||||
nodes = [
|
||||
btc.get_public_node(client, address_n, coin_name="Decred Testnet").node
|
||||
for address_n in paths
|
||||
]
|
||||
|
||||
signatures = [[b"", b"", b""], [b"", b"", b""]]
|
||||
|
||||
def create_multisig(index, address, signatures=None):
|
||||
address_n = parse_path(address)
|
||||
multisig = proto.MultisigRedeemScriptType(
|
||||
nodes=nodes, address_n=address_n, signatures=signatures, m=2
|
||||
)
|
||||
|
||||
return (paths[index] + address_n), multisig
|
||||
|
||||
def test_multisig(index):
|
||||
address_n, multisig = create_multisig(index, "m/0/0", signatures[0])
|
||||
inp1 = proto.TxInputType(
|
||||
# TscqTv1he8MZrV321SfRghw7LFBCJDKB3oz
|
||||
address_n=parse_path("m/44'/1'/0'/0/0"),
|
||||
prev_hash=TXHASH_e16248,
|
||||
prev_index=1,
|
||||
address_n=address_n,
|
||||
# TchpthUkRys1VQWgnQyLJNaA4MLBjVmRL2c
|
||||
multisig=multisig,
|
||||
amount=200000000,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
prev_hash=TXHASH_3f7c39,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
decred_tree=0,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="TscqTv1he8MZrV321SfRghw7LFBCJDKB3oz",
|
||||
amount=190000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.FeeOverThreshold),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_e16248),
|
||||
request_input(0, TXHASH_e16248),
|
||||
request_output(0, TXHASH_e16248),
|
||||
request_output(1, TXHASH_e16248),
|
||||
request_input(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Decred Testnet", [inp1], [out1], prev_txes=TX_API
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000001edd579e9462ee0e80127a817e0500d4f942a4cf8f2d6530e0c0a9ab3f04862e10100000000ffffffff01802b530b0000000000001976a914819d291a2f7fbf770e784bfd78b5ce92c58e95ea88ac00000000000000000100c2eb0b0000000000000000ffffffff6a473044022009e394c7dec76ab6988270b467839b1462ad781556bce37383b76e026418ce6302204f7f6ef535d2986b095d7c96232a0990a0b9ce3004894b39c167bb18e5833ac30121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0"
|
||||
)
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
def test_purchase_ticket_decred(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("m/44'/1'/0'/0/0"),
|
||||
prev_hash=TXHASH_e16248,
|
||||
prev_index=1,
|
||||
address_n, multisig = create_multisig(index, "m/0/1", signatures[1])
|
||||
inp2 = proto.TxInputType(
|
||||
address_n=address_n,
|
||||
# TcnfDEfMhkM3oLWqiq9v9GmYgLK7qfjitKG
|
||||
multisig=multisig,
|
||||
amount=200000000,
|
||||
prev_hash=TXHASH_16da18,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
decred_tree=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
)
|
||||
|
||||
address_n, multisig = create_multisig(index, "m/1/0")
|
||||
out1 = proto.TxOutputType(
|
||||
address="TscqTv1he8MZrV321SfRghw7LFBCJDKB3oz",
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
amount=199900000,
|
||||
address_n=address_n,
|
||||
# TcrrURA3Bzj4isGU48PdSP9SDoU5oCpjEcb
|
||||
multisig=multisig,
|
||||
amount=99900000,
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=parse_path("m/44'/1'/0'/0/0"),
|
||||
amount=200000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out3 = proto.TxOutputType(
|
||||
address="TsR28UZRprhgQQhzWns2M6cAwchrNVvbYq2",
|
||||
amount=0,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
request_output(2),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_e16248),
|
||||
request_input(0, TXHASH_e16248),
|
||||
request_output(0, TXHASH_e16248),
|
||||
request_output(1, TXHASH_e16248),
|
||||
request_input(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Decred Testnet",
|
||||
[inp1],
|
||||
[out1, out2, out3],
|
||||
prev_txes=TX_API,
|
||||
decred_staking_ticket=True,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000001edd579e9462ee0e80127a817e0500d4f942a4cf8f2d6530e0c0a9ab3f04862e10100000000ffffffff03603bea0b0000000000001aba76a914819d291a2f7fbf770e784bfd78b5ce92c58e95ea88ac00000000000000000000206a1edc1a98d791735eb9a8715a2a219c23680edcedad00c2eb0b000000000058000000000000000000001abd76a914000000000000000000000000000000000000000088ac00000000000000000100c2eb0b0000000000000000ffffffff6b4830450221008ced5411a6d92b761bdd8b9f7fbc5bfae3c31f9369050c218977f4540ab1ec9602206e89c821878ebfd959d1c4a63100eec5b1154c8d9508c039bb78e333498a73b40121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0"
|
||||
)
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
def test_spend_from_stake_generation_and_revocation_decred(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("m/44'/1'/0'/0/0"),
|
||||
prev_hash=TXHASH_8b6890,
|
||||
prev_index=2,
|
||||
amount=200000000,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
decred_staking_spend=proto.DecredStakingSpendType.SSGen,
|
||||
decred_tree=1,
|
||||
)
|
||||
|
||||
inp2 = proto.TxInputType(
|
||||
address_n=parse_path("m/44'/1'/0'/0/0"),
|
||||
prev_hash=TXHASH_1f00fc,
|
||||
prev_index=0,
|
||||
amount=200000000,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
decred_staking_spend=proto.DecredStakingSpendType.SSRTX,
|
||||
decred_tree=1,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="TscqTv1he8MZrV321SfRghw7LFBCJDKB3oz",
|
||||
amount=399900000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_8b6890),
|
||||
request_input(0, TXHASH_8b6890),
|
||||
request_input(1, TXHASH_8b6890),
|
||||
request_output(0, TXHASH_8b6890),
|
||||
request_output(1, TXHASH_8b6890),
|
||||
request_output(2, TXHASH_8b6890),
|
||||
request_input(1),
|
||||
request_meta(TXHASH_1f00fc),
|
||||
request_input(0, TXHASH_1f00fc),
|
||||
request_output(0, TXHASH_1f00fc),
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Decred Testnet", [inp1, inp2], [out1], prev_txes=TX_API
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "010000000254e249113666e84c70de1dbee976f18d1438e4b7c58b376ffe64370ac190688b0200000001ffffffffc8e8dfb5c0e534b12adede611853a1f607c5b6912e03f577487c0d5354fc001f0000000001ffffffff0160fdd5170000000000001976a914819d291a2f7fbf770e784bfd78b5ce92c58e95ea88ac00000000000000000200c2eb0b0000000000000000ffffffff6b483045022100bdcb877c97d72db74eca06fefa21a7f7b00afcd5d916fce2155ed7df1ca5546102201e1f9efd7d652b449474c2c70171bfc4535544927bed62021f7334447d1ea4740121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd000c2eb0b0000000000000000ffffffff6a473044022030c5743c442bd696d19dcf73d54e95526e726de965c2e2b4b9fd70248eaae21d02201305a3bcc2bb0e33122277763990e3b48f317d61264a68d190fb8acfc004cc640121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0"
|
||||
)
|
||||
|
||||
def test_send_decred_change(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
# TscqTv1he8MZrV321SfRghw7LFBCJDKB3oz
|
||||
address_n=parse_path("m/44'/1'/0'/0/0"),
|
||||
amount=190000000,
|
||||
prev_hash=TXHASH_5e6e35,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
decred_tree=0,
|
||||
)
|
||||
|
||||
inp2 = proto.TxInputType(
|
||||
# TscqTv1he8MZrV321SfRghw7LFBCJDKB3oz
|
||||
address_n=parse_path("m/44'/1'/0'/0/0"),
|
||||
amount=200000000,
|
||||
prev_hash=TXHASH_ccf95b,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
decred_tree=0,
|
||||
)
|
||||
|
||||
inp3 = proto.TxInputType(
|
||||
# Tskt39YEvzoJ5KBDH4f1auNzG3jViVjZ2RV
|
||||
address_n=parse_path("m/44'/1'/0'/0/1"),
|
||||
amount=200000000,
|
||||
prev_hash=TXHASH_f395ef,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
decred_tree=0,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="TsWjioPrP8E1TuTMmTrVMM2BA4iPrjQXBpR",
|
||||
amount=489975000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
# TsaSFRwfN9muW5F6ZX36iSksc9hruiC5F97
|
||||
address_n=parse_path("m/44'/1'/0'/1/0"),
|
||||
amount=100000000,
|
||||
amount=300000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
@ -267,142 +371,41 @@ class TestMsgSigntxDecred:
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_input(2),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_5e6e35),
|
||||
request_input(0, TXHASH_5e6e35),
|
||||
request_output(0, TXHASH_5e6e35),
|
||||
request_meta(TXHASH_3f7c39),
|
||||
request_input(0, TXHASH_3f7c39),
|
||||
request_output(0, TXHASH_3f7c39),
|
||||
request_output(1, TXHASH_3f7c39),
|
||||
request_input(1),
|
||||
request_meta(TXHASH_ccf95b),
|
||||
request_input(0, TXHASH_ccf95b),
|
||||
request_output(0, TXHASH_ccf95b),
|
||||
request_output(1, TXHASH_ccf95b),
|
||||
request_input(2),
|
||||
request_meta(TXHASH_f395ef),
|
||||
request_input(0, TXHASH_f395ef),
|
||||
request_output(0, TXHASH_f395ef),
|
||||
request_output(1, TXHASH_f395ef),
|
||||
request_meta(TXHASH_16da18),
|
||||
request_input(0, TXHASH_16da18),
|
||||
request_output(0, TXHASH_16da18),
|
||||
request_output(1, TXHASH_16da18),
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_input(2),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
signature, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Decred Testnet",
|
||||
[inp1, inp2, inp3],
|
||||
[inp1, inp2],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "010000000370b95980a47b9bcb4ec2c2b450888a53179b1a5fdb23f5023cc533a300356e5e0000000000ffffffff74bc93bcfce18aff2e522d6822817522e2815a00175b2eae59ef20d20f5bf9cc0100000000ffffffff13317ab453832deabd684d2302eed42580c28ba3e715db66a731a8723eef95f30000000000ffffffff02d86c341d0000000000001976a9143eb656115197956125365348c542e37b6d3d259988ac00e1f5050000000000001976a9143ee6f9d662e7be18373d80e5eb44627014c2bf6688ac000000000000000003802b530b0000000000000000ffffffff6a47304402200e50a6d43c462045917792e7d03b4354900c3baccb7abef66f556a32b12f2ca6022031ae94fdf2a41dd6ed2e081faf0f8f1c64411a1b46eb26f7f35d94402b2bde110121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd000c2eb0b0000000000000000ffffffff6a47304402204894c2f8e76c4645d2df600cdd01443aeb48807b72150c4bc10eebd126529532022054cd37462a3f0ddb85c75b4e874ab0c2aad7eebcff3e6c1ac20e1c16babe36720121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd000c2eb0b0000000000000000ffffffff6b4830450221009f1ba584023da8aafd57374e83be68f1a097b906967ec9e50736f31bfc7989f102204a190fc2885e394572b5c2ced046657b1dd07abdb19144e21e78987968c7f17601210294e3e5e77e22eea0e4c0d30d89beb4db7f69b4bf1ae709e411d6a06618b8f852"
|
||||
)
|
||||
signatures[0][index] = signature[0]
|
||||
signatures[1][index] = signature[1]
|
||||
return serialized_tx
|
||||
|
||||
@pytest.mark.multisig
|
||||
def test_decred_multisig_change(self, client):
|
||||
paths = [parse_path(f"m/48'/1'/{index}'/0'") for index in range(3)]
|
||||
nodes = [
|
||||
btc.get_public_node(client, address_n, coin_name="Decred Testnet").node
|
||||
for address_n in paths
|
||||
]
|
||||
test_multisig(2)
|
||||
serialized_tx = test_multisig(0)
|
||||
|
||||
signatures = [[b"", b"", b""], [b"", b"", b""]]
|
||||
|
||||
def create_multisig(index, address, signatures=None):
|
||||
address_n = parse_path(address)
|
||||
multisig = proto.MultisigRedeemScriptType(
|
||||
nodes=nodes, address_n=address_n, signatures=signatures, m=2
|
||||
)
|
||||
|
||||
return (paths[index] + address_n), multisig
|
||||
|
||||
def test_multisig(index):
|
||||
address_n, multisig = create_multisig(index, "m/0/0", signatures[0])
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=address_n,
|
||||
# TchpthUkRys1VQWgnQyLJNaA4MLBjVmRL2c
|
||||
multisig=multisig,
|
||||
amount=200000000,
|
||||
prev_hash=TXHASH_3f7c39,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
decred_tree=0,
|
||||
)
|
||||
|
||||
address_n, multisig = create_multisig(index, "m/0/1", signatures[1])
|
||||
inp2 = proto.TxInputType(
|
||||
address_n=address_n,
|
||||
# TcnfDEfMhkM3oLWqiq9v9GmYgLK7qfjitKG
|
||||
multisig=multisig,
|
||||
amount=200000000,
|
||||
prev_hash=TXHASH_16da18,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
decred_tree=0,
|
||||
)
|
||||
|
||||
address_n, multisig = create_multisig(index, "m/1/0")
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=address_n,
|
||||
# TcrrURA3Bzj4isGU48PdSP9SDoU5oCpjEcb
|
||||
multisig=multisig,
|
||||
amount=99900000,
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address="TsWjioPrP8E1TuTMmTrVMM2BA4iPrjQXBpR",
|
||||
amount=300000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_3f7c39),
|
||||
request_input(0, TXHASH_3f7c39),
|
||||
request_output(0, TXHASH_3f7c39),
|
||||
request_output(1, TXHASH_3f7c39),
|
||||
request_input(1),
|
||||
request_meta(TXHASH_16da18),
|
||||
request_input(0, TXHASH_16da18),
|
||||
request_output(0, TXHASH_16da18),
|
||||
request_output(1, TXHASH_16da18),
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
signature, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Decred Testnet",
|
||||
[inp1, inp2],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
signatures[0][index] = signature[0]
|
||||
signatures[1][index] = signature[1]
|
||||
return serialized_tx
|
||||
|
||||
test_multisig(2)
|
||||
serialized_tx = test_multisig(0)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000023f4c9e61b1cf469cad3785a03566ef23876217fe657561e78783d32155397c3f0100000000ffffffffa806ca135db5160eb91202506ce2645b215805149ce730a6850d74525018da160000000000ffffffff02605af40500000000000017a914d4ea4e064d969064ca56a4cede56f7bf6cf62f118700a3e1110000000000001976a9143eb656115197956125365348c542e37b6d3d259988ac00000000000000000200c2eb0b0000000000000000fffffffffc483045022100a35fd1ed579362ac65b583ba910a3d814c5e9b87da835993bf4166a6b3a8482b02204b3e167fad7d37dd62aa585c68d3c8e00c3c43bf7a25d74f6407870a4a7499e9014730440220720fd7b6dfd337056c5e6dad76e307b3758e702ccfd39471bf90e0db3a5f5eba02205bd062c78fcdd56057723a0e39d661a790f325e59e643b54c47b7218a5781684014c69522103defea6f243b97354449bb348446a97e38df2fbed33afc3a7185bfdd26757cfdb2103725d6c5253f2040a9a73af24bcc196bf302d6cc94374dd7197b138e10912670121038924e94fff15302a3fb45ad4fc0ed17178800f0f1c2bdacb1017f4db951aa9f153ae00c2eb0b0000000000000000fffffffffc4730440220625357288f0880be21d6a44275033fd84cf04bc23227eef810455ad711507e4402207d303548bb0476f98c52f223fe4430f82a78a73f757b186453948b0908f5af3101483045022100e140f586e370824b13576c77cf9f2855294fd415316f2a130126d8412a7cf08c0220308d1f5c83847458b271c93bfca5eba7fc1691b9c5d6e57955985affd1110e24014c695221021ef4b5d81f21593071b993bd4d8c564c569a6f84de0d4511135cbc66d8bf7bcd2103f1e53b6e0ff99adf7e8fa826a94bdac83163d8abbc1d19a8d6b88a4af91b9a67210390c8ea70e1f2f60e0052be65183c43bb01b2f02dfa4e448f74e359997f74e6ad53ae"
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000023f4c9e61b1cf469cad3785a03566ef23876217fe657561e78783d32155397c3f0100000000ffffffffa806ca135db5160eb91202506ce2645b215805149ce730a6850d74525018da160000000000ffffffff02605af40500000000000017a914d4ea4e064d969064ca56a4cede56f7bf6cf62f118700a3e1110000000000001976a9143eb656115197956125365348c542e37b6d3d259988ac00000000000000000200c2eb0b0000000000000000fffffffffc483045022100a35fd1ed579362ac65b583ba910a3d814c5e9b87da835993bf4166a6b3a8482b02204b3e167fad7d37dd62aa585c68d3c8e00c3c43bf7a25d74f6407870a4a7499e9014730440220720fd7b6dfd337056c5e6dad76e307b3758e702ccfd39471bf90e0db3a5f5eba02205bd062c78fcdd56057723a0e39d661a790f325e59e643b54c47b7218a5781684014c69522103defea6f243b97354449bb348446a97e38df2fbed33afc3a7185bfdd26757cfdb2103725d6c5253f2040a9a73af24bcc196bf302d6cc94374dd7197b138e10912670121038924e94fff15302a3fb45ad4fc0ed17178800f0f1c2bdacb1017f4db951aa9f153ae00c2eb0b0000000000000000fffffffffc4730440220625357288f0880be21d6a44275033fd84cf04bc23227eef810455ad711507e4402207d303548bb0476f98c52f223fe4430f82a78a73f757b186453948b0908f5af3101483045022100e140f586e370824b13576c77cf9f2855294fd415316f2a130126d8412a7cf08c0220308d1f5c83847458b271c93bfca5eba7fc1691b9c5d6e57955985affd1110e24014c695221021ef4b5d81f21593071b993bd4d8c564c569a6f84de0d4511135cbc66d8bf7bcd2103f1e53b6e0ff99adf7e8fa826a94bdac83163d8abbc1d19a8d6b88a4af91b9a67210390c8ea70e1f2f60e0052be65183c43bb01b2f02dfa4e448f74e359997f74e6ad53ae"
|
||||
)
|
||||
|
@ -35,179 +35,182 @@ TXHASH_4f2f85 = bytes.fromhex(
|
||||
"4f2f857f39ed1afe05542d058fb0be865a387446e32fc876d086203f483f61d1"
|
||||
)
|
||||
|
||||
pytestmark = pytest.mark.altcoin
|
||||
|
||||
@pytest.mark.altcoin
|
||||
class TestMsgSigntxGRS:
|
||||
def test_legacy(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
# FXHDsC5ZqWQHkDmShzgRVZ1MatpWhwxTAA
|
||||
address_n=parse_path("44'/17'/0'/0/2"),
|
||||
amount=210016,
|
||||
prev_hash=TXHASH_cb74c8,
|
||||
prev_index=0,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="FtM4zAn9aVYgHgxmamWBgWPyZsb6RhvkA9",
|
||||
amount=210016 - 192,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Groestlcoin", [inp1], [out1], prev_txes=TX_API
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000014a9d1fdba915e0907ab02f04f88898863112a2b4fdcf872c7414588c47c874cb000000006a47304402201fb96d20d0778f54520ab59afe70d5fb20e500ecc9f02281cf57934e8029e8e10220383d5a3e80f2e1eb92765b6da0f23d454aecbd8236f083d483e9a7430236876101210331693756f749180aeed0a65a0fab0625a2250bd9abca502282a4cf0723152e67ffffffff01a0330300000000001976a914fe40329c95c5598ac60752a5310b320cb52d18e688ac00000000"
|
||||
)
|
||||
|
||||
def test_legacy_change(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
# FXHDsC5ZqWQHkDmShzgRVZ1MatpWhwxTAA
|
||||
address_n=parse_path("44'/17'/0'/0/2"),
|
||||
amount=210016,
|
||||
prev_hash=TXHASH_cb74c8,
|
||||
prev_index=0,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=parse_path(
|
||||
"44'/17'/0'/0/3"
|
||||
), # FtM4zAn9aVYgHgxmamWBgWPyZsb6RhvkA9
|
||||
amount=210016 - 192,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Groestlcoin", [inp1], [out1], prev_txes=TX_API
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000014a9d1fdba915e0907ab02f04f88898863112a2b4fdcf872c7414588c47c874cb000000006a47304402201fb96d20d0778f54520ab59afe70d5fb20e500ecc9f02281cf57934e8029e8e10220383d5a3e80f2e1eb92765b6da0f23d454aecbd8236f083d483e9a7430236876101210331693756f749180aeed0a65a0fab0625a2250bd9abca502282a4cf0723152e67ffffffff01a0330300000000001976a914fe40329c95c5598ac60752a5310b320cb52d18e688ac00000000"
|
||||
)
|
||||
def test_legacy(client):
|
||||
inp1 = proto.TxInputType(
|
||||
# FXHDsC5ZqWQHkDmShzgRVZ1MatpWhwxTAA
|
||||
address_n=parse_path("44'/17'/0'/0/2"),
|
||||
amount=210016,
|
||||
prev_hash=TXHASH_cb74c8,
|
||||
prev_index=0,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="FtM4zAn9aVYgHgxmamWBgWPyZsb6RhvkA9",
|
||||
amount=210016 - 192,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Groestlcoin", [inp1], [out1], prev_txes=TX_API
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000014a9d1fdba915e0907ab02f04f88898863112a2b4fdcf872c7414588c47c874cb000000006a47304402201fb96d20d0778f54520ab59afe70d5fb20e500ecc9f02281cf57934e8029e8e10220383d5a3e80f2e1eb92765b6da0f23d454aecbd8236f083d483e9a7430236876101210331693756f749180aeed0a65a0fab0625a2250bd9abca502282a4cf0723152e67ffffffff01a0330300000000001976a914fe40329c95c5598ac60752a5310b320cb52d18e688ac00000000"
|
||||
)
|
||||
|
||||
def test_send_segwit_p2sh(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZYBtBZ7
|
||||
address_n=parse_path("49'/1'/0'/1/0"),
|
||||
amount=123456789,
|
||||
prev_hash=TXHASH_09a48b,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
sequence=0xFFFFFFFE,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="mvbu1Gdy8SUjTenqerxUaZyYjmvedc787y",
|
||||
amount=12300000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address="2N1LGaGg836mqSQqiuUBLfcyGBhyZYBtBZ7",
|
||||
amount=123456789 - 11000 - 12300000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Groestlcoin Testnet",
|
||||
[inp1],
|
||||
[out1, out2],
|
||||
lock_time=650756,
|
||||
prev_txes=TX_API_TESTNET,
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000000101cf60ded29a2bd7ebf93453feace8551889d0321beab90c4f6e5c9d2fce8ba4090000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5feffffff02e0aebb00000000001976a914a579388225827d9f2fe9014add644487808c695d88ac3df39f060000000017a91458b53ea7f832e8f096e896b8713a8c6df0e892ca8702483045022100b7ce2972bcbc3a661fe320ba901e680913b2753fcb47055c9c6ba632fc4acf81022001c3cfd6c2fe92eb60f5176ce0f43707114dd7223da19c56f2df89c13c2fef80012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7904ee0900"
|
||||
)
|
||||
|
||||
def test_send_segwit_p2sh_change(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZYBtBZ7
|
||||
address_n=parse_path("49'/1'/0'/1/0"),
|
||||
amount=123456789,
|
||||
prev_hash=TXHASH_09a48b,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
sequence=0xFFFFFFFE,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="mvbu1Gdy8SUjTenqerxUaZyYjmvedc787y",
|
||||
amount=12300000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=parse_path("49'/1'/0'/1/0"),
|
||||
script_type=proto.OutputScriptType.PAYTOP2SHWITNESS,
|
||||
amount=123456789 - 11000 - 12300000,
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Groestlcoin Testnet",
|
||||
[inp1],
|
||||
[out1, out2],
|
||||
lock_time=650756,
|
||||
prev_txes=TX_API_TESTNET,
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000000101cf60ded29a2bd7ebf93453feace8551889d0321beab90c4f6e5c9d2fce8ba4090000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5feffffff02e0aebb00000000001976a914a579388225827d9f2fe9014add644487808c695d88ac3df39f060000000017a91458b53ea7f832e8f096e896b8713a8c6df0e892ca8702483045022100b7ce2972bcbc3a661fe320ba901e680913b2753fcb47055c9c6ba632fc4acf81022001c3cfd6c2fe92eb60f5176ce0f43707114dd7223da19c56f2df89c13c2fef80012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7904ee0900"
|
||||
)
|
||||
def test_legacy_change(client):
|
||||
inp1 = proto.TxInputType(
|
||||
# FXHDsC5ZqWQHkDmShzgRVZ1MatpWhwxTAA
|
||||
address_n=parse_path("44'/17'/0'/0/2"),
|
||||
amount=210016,
|
||||
prev_hash=TXHASH_cb74c8,
|
||||
prev_index=0,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=parse_path("44'/17'/0'/0/3"), # FtM4zAn9aVYgHgxmamWBgWPyZsb6RhvkA9
|
||||
amount=210016 - 192,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Groestlcoin", [inp1], [out1], prev_txes=TX_API
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000014a9d1fdba915e0907ab02f04f88898863112a2b4fdcf872c7414588c47c874cb000000006a47304402201fb96d20d0778f54520ab59afe70d5fb20e500ecc9f02281cf57934e8029e8e10220383d5a3e80f2e1eb92765b6da0f23d454aecbd8236f083d483e9a7430236876101210331693756f749180aeed0a65a0fab0625a2250bd9abca502282a4cf0723152e67ffffffff01a0330300000000001976a914fe40329c95c5598ac60752a5310b320cb52d18e688ac00000000"
|
||||
)
|
||||
|
||||
def test_send_segwit_native(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("84'/1'/0'/0/0"),
|
||||
amount=12300000,
|
||||
prev_hash=TXHASH_4f2f85,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDWITNESS,
|
||||
sequence=0xFFFFFFFE,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="2N4Q5FhU2497BryFfUgbqkAJE87aKDv3V3e",
|
||||
amount=5000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address="tgrs1qejqxwzfld7zr6mf7ygqy5s5se5xq7vmt9lkd57",
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
amount=12300000 - 11000 - 5000000,
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Groestlcoin Testnet",
|
||||
[inp1],
|
||||
[out1, out2],
|
||||
lock_time=650713,
|
||||
prev_txes=TX_API_TESTNET,
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000000101d1613f483f2086d076c82fe34674385a86beb08f052d5405fe1aed397f852f4f0000000000feffffff02404b4c000000000017a9147a55d61848e77ca266e79a39bfc85c580a6426c987a8386f0000000000160014cc8067093f6f843d6d3e22004a4290cd0c0f336b02483045022100ea8780bc1e60e14e945a80654a41748bbf1aa7d6f2e40a88d91dfc2de1f34bd10220181a474a3420444bd188501d8d270736e1e9fe379da9970de992ff445b0972e3012103adc58245cf28406af0ef5cc24b8afba7f1be6c72f279b642d85c48798685f862d9ed0900"
|
||||
)
|
||||
|
||||
def test_send_segwit_native_change(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("84'/1'/0'/0/0"),
|
||||
amount=12300000,
|
||||
prev_hash=TXHASH_4f2f85,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDWITNESS,
|
||||
sequence=0xFFFFFFFE,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="2N4Q5FhU2497BryFfUgbqkAJE87aKDv3V3e",
|
||||
amount=5000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=parse_path("84'/1'/0'/1/0"),
|
||||
script_type=proto.OutputScriptType.PAYTOWITNESS,
|
||||
amount=12300000 - 11000 - 5000000,
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Groestlcoin Testnet",
|
||||
[inp1],
|
||||
[out1, out2],
|
||||
lock_time=650713,
|
||||
prev_txes=TX_API_TESTNET,
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000000101d1613f483f2086d076c82fe34674385a86beb08f052d5405fe1aed397f852f4f0000000000feffffff02404b4c000000000017a9147a55d61848e77ca266e79a39bfc85c580a6426c987a8386f0000000000160014cc8067093f6f843d6d3e22004a4290cd0c0f336b02483045022100ea8780bc1e60e14e945a80654a41748bbf1aa7d6f2e40a88d91dfc2de1f34bd10220181a474a3420444bd188501d8d270736e1e9fe379da9970de992ff445b0972e3012103adc58245cf28406af0ef5cc24b8afba7f1be6c72f279b642d85c48798685f862d9ed0900"
|
||||
)
|
||||
def test_send_segwit_p2sh(client):
|
||||
inp1 = proto.TxInputType(
|
||||
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZYBtBZ7
|
||||
address_n=parse_path("49'/1'/0'/1/0"),
|
||||
amount=123456789,
|
||||
prev_hash=TXHASH_09a48b,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
sequence=0xFFFFFFFE,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="mvbu1Gdy8SUjTenqerxUaZyYjmvedc787y",
|
||||
amount=12300000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address="2N1LGaGg836mqSQqiuUBLfcyGBhyZYBtBZ7",
|
||||
amount=123456789 - 11000 - 12300000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Groestlcoin Testnet",
|
||||
[inp1],
|
||||
[out1, out2],
|
||||
lock_time=650756,
|
||||
prev_txes=TX_API_TESTNET,
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000000101cf60ded29a2bd7ebf93453feace8551889d0321beab90c4f6e5c9d2fce8ba4090000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5feffffff02e0aebb00000000001976a914a579388225827d9f2fe9014add644487808c695d88ac3df39f060000000017a91458b53ea7f832e8f096e896b8713a8c6df0e892ca8702483045022100b7ce2972bcbc3a661fe320ba901e680913b2753fcb47055c9c6ba632fc4acf81022001c3cfd6c2fe92eb60f5176ce0f43707114dd7223da19c56f2df89c13c2fef80012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7904ee0900"
|
||||
)
|
||||
|
||||
|
||||
def test_send_segwit_p2sh_change(client):
|
||||
inp1 = proto.TxInputType(
|
||||
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZYBtBZ7
|
||||
address_n=parse_path("49'/1'/0'/1/0"),
|
||||
amount=123456789,
|
||||
prev_hash=TXHASH_09a48b,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
sequence=0xFFFFFFFE,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="mvbu1Gdy8SUjTenqerxUaZyYjmvedc787y",
|
||||
amount=12300000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=parse_path("49'/1'/0'/1/0"),
|
||||
script_type=proto.OutputScriptType.PAYTOP2SHWITNESS,
|
||||
amount=123456789 - 11000 - 12300000,
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Groestlcoin Testnet",
|
||||
[inp1],
|
||||
[out1, out2],
|
||||
lock_time=650756,
|
||||
prev_txes=TX_API_TESTNET,
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000000101cf60ded29a2bd7ebf93453feace8551889d0321beab90c4f6e5c9d2fce8ba4090000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5feffffff02e0aebb00000000001976a914a579388225827d9f2fe9014add644487808c695d88ac3df39f060000000017a91458b53ea7f832e8f096e896b8713a8c6df0e892ca8702483045022100b7ce2972bcbc3a661fe320ba901e680913b2753fcb47055c9c6ba632fc4acf81022001c3cfd6c2fe92eb60f5176ce0f43707114dd7223da19c56f2df89c13c2fef80012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7904ee0900"
|
||||
)
|
||||
|
||||
|
||||
def test_send_segwit_native(client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("84'/1'/0'/0/0"),
|
||||
amount=12300000,
|
||||
prev_hash=TXHASH_4f2f85,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDWITNESS,
|
||||
sequence=0xFFFFFFFE,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="2N4Q5FhU2497BryFfUgbqkAJE87aKDv3V3e",
|
||||
amount=5000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address="tgrs1qejqxwzfld7zr6mf7ygqy5s5se5xq7vmt9lkd57",
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
amount=12300000 - 11000 - 5000000,
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Groestlcoin Testnet",
|
||||
[inp1],
|
||||
[out1, out2],
|
||||
lock_time=650713,
|
||||
prev_txes=TX_API_TESTNET,
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000000101d1613f483f2086d076c82fe34674385a86beb08f052d5405fe1aed397f852f4f0000000000feffffff02404b4c000000000017a9147a55d61848e77ca266e79a39bfc85c580a6426c987a8386f0000000000160014cc8067093f6f843d6d3e22004a4290cd0c0f336b02483045022100ea8780bc1e60e14e945a80654a41748bbf1aa7d6f2e40a88d91dfc2de1f34bd10220181a474a3420444bd188501d8d270736e1e9fe379da9970de992ff445b0972e3012103adc58245cf28406af0ef5cc24b8afba7f1be6c72f279b642d85c48798685f862d9ed0900"
|
||||
)
|
||||
|
||||
|
||||
def test_send_segwit_native_change(client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("84'/1'/0'/0/0"),
|
||||
amount=12300000,
|
||||
prev_hash=TXHASH_4f2f85,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDWITNESS,
|
||||
sequence=0xFFFFFFFE,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="2N4Q5FhU2497BryFfUgbqkAJE87aKDv3V3e",
|
||||
amount=5000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=parse_path("84'/1'/0'/1/0"),
|
||||
script_type=proto.OutputScriptType.PAYTOWITNESS,
|
||||
amount=12300000 - 11000 - 5000000,
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Groestlcoin Testnet",
|
||||
[inp1],
|
||||
[out1, out2],
|
||||
lock_time=650713,
|
||||
prev_txes=TX_API_TESTNET,
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000000101d1613f483f2086d076c82fe34674385a86beb08f052d5405fe1aed397f852f4f0000000000feffffff02404b4c000000000017a9147a55d61848e77ca266e79a39bfc85c580a6426c987a8386f0000000000160014cc8067093f6f843d6d3e22004a4290cd0c0f336b02483045022100ea8780bc1e60e14e945a80654a41748bbf1aa7d6f2e40a88d91dfc2de1f34bd10220181a474a3420444bd188501d8d270736e1e9fe379da9970de992ff445b0972e3012103adc58245cf28406af0ef5cc24b8afba7f1be6c72f279b642d85c48798685f862d9ed0900"
|
||||
)
|
||||
|
@ -32,88 +32,86 @@ TXHASH_d5f65e = bytes.fromhex(
|
||||
"d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"
|
||||
)
|
||||
|
||||
pytestmark = pytest.mark.altcoin
|
||||
|
||||
class TestMsgSigntxInvalidPath:
|
||||
# Adapted from TestMsgSigntx.test_one_one_fee,
|
||||
# only changed the coin from Bitcoin to Litecoin.
|
||||
# Litecoin does not have strong replay protection using SIGHASH_FORKID,
|
||||
# spending from Bitcoin path should fail.
|
||||
def test_invalid_path_fail(client):
|
||||
# tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
|
||||
# input 0: 0.0039 BTC
|
||||
|
||||
# Adapted from TestMsgSigntx.test_one_one_fee,
|
||||
# only changed the coin from Bitcoin to Litecoin.
|
||||
# Litecoin does not have strong replay protection using SIGHASH_FORKID,
|
||||
# spending from Bitcoin path should fail.
|
||||
@pytest.mark.altcoin
|
||||
def test_invalid_path_fail(self, client):
|
||||
# tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
|
||||
# input 0: 0.0039 BTC
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44h/0h/0h/0/0"),
|
||||
amount=390000,
|
||||
prev_hash=TXHASH_d5f65e,
|
||||
prev_index=0,
|
||||
)
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44h/0h/0h/0/0"),
|
||||
amount=390000,
|
||||
prev_hash=TXHASH_d5f65e,
|
||||
prev_index=0,
|
||||
)
|
||||
|
||||
# address is converted from 1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1 by changing the version
|
||||
out1 = proto.TxOutputType(
|
||||
address="LfWz9wLHmqU9HoDkMg9NqbRosrHvEixeVZ",
|
||||
amount=390000 - 10000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with pytest.raises(TrezorFailure) as exc:
|
||||
btc.sign_tx(client, "Litecoin", [inp1], [out1], prev_txes=TX_CACHE_MAINNET)
|
||||
|
||||
assert exc.value.code == proto.FailureType.DataError
|
||||
assert exc.value.message.endswith("Forbidden key path")
|
||||
|
||||
# Adapted from TestMsgSigntx.test_one_one_fee,
|
||||
# only changed the coin from Bitcoin to Litecoin and set safety checks to prompt.
|
||||
# Litecoin does not have strong replay protection using SIGHASH_FORKID, but
|
||||
# spending from Bitcoin path should pass with safety checks set to prompt.
|
||||
@pytest.mark.altcoin
|
||||
def test_invalid_path_prompt(self, client):
|
||||
# tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
|
||||
# input 0: 0.0039 BTC
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44h/0h/0h/0/0"),
|
||||
amount=390000,
|
||||
prev_hash=TXHASH_d5f65e,
|
||||
prev_index=0,
|
||||
)
|
||||
|
||||
# address is converted from 1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1 by changing the version
|
||||
out1 = proto.TxOutputType(
|
||||
address="LfWz9wLHmqU9HoDkMg9NqbRosrHvEixeVZ",
|
||||
amount=390000 - 10000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
device.apply_settings(
|
||||
client, safety_checks=proto.SafetyCheckLevel.PromptTemporarily
|
||||
)
|
||||
# address is converted from 1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1 by changing the version
|
||||
out1 = proto.TxOutputType(
|
||||
address="LfWz9wLHmqU9HoDkMg9NqbRosrHvEixeVZ",
|
||||
amount=390000 - 10000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with pytest.raises(TrezorFailure) as exc:
|
||||
btc.sign_tx(client, "Litecoin", [inp1], [out1], prev_txes=TX_CACHE_MAINNET)
|
||||
|
||||
# Adapted from TestMsgSigntx.test_one_one_fee,
|
||||
# only changed the coin from Bitcoin to Bcash.
|
||||
# Bcash does have strong replay protection using SIGHASH_FORKID,
|
||||
# spending from Bitcoin path should work.
|
||||
@pytest.mark.altcoin
|
||||
def test_invalid_path_pass_forkid(self, client):
|
||||
# tx: 8cc1f4adf7224ce855cf535a5104594a0004cb3b640d6714fdb00b9128832dd5
|
||||
# input 0: 0.0039 BTC
|
||||
assert exc.value.code == proto.FailureType.DataError
|
||||
assert exc.value.message.endswith("Forbidden key path")
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44h/0h/0h/0/0"),
|
||||
amount=390000,
|
||||
prev_hash=TXHASH_8cc1f4,
|
||||
prev_index=0,
|
||||
)
|
||||
|
||||
# address is converted from 1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1 to cashaddr format
|
||||
out1 = proto.TxOutputType(
|
||||
address="bitcoincash:qr0fk25d5zygyn50u5w7h6jkvctas52n0qxff9ja6r",
|
||||
amount=390000 - 10000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
# Adapted from TestMsgSigntx.test_one_one_fee,
|
||||
# only changed the coin from Bitcoin to Litecoin and set safety checks to prompt.
|
||||
# Litecoin does not have strong replay protection using SIGHASH_FORKID, but
|
||||
# spending from Bitcoin path should pass with safety checks set to prompt.
|
||||
def test_invalid_path_prompt(client):
|
||||
# tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
|
||||
# input 0: 0.0039 BTC
|
||||
|
||||
btc.sign_tx(client, "Bcash", [inp1], [out1], prev_txes=TX_CACHE_BCASH)
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44h/0h/0h/0/0"),
|
||||
amount=390000,
|
||||
prev_hash=TXHASH_d5f65e,
|
||||
prev_index=0,
|
||||
)
|
||||
|
||||
# address is converted from 1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1 by changing the version
|
||||
out1 = proto.TxOutputType(
|
||||
address="LfWz9wLHmqU9HoDkMg9NqbRosrHvEixeVZ",
|
||||
amount=390000 - 10000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
device.apply_settings(
|
||||
client, safety_checks=proto.SafetyCheckLevel.PromptTemporarily
|
||||
)
|
||||
|
||||
btc.sign_tx(client, "Litecoin", [inp1], [out1], prev_txes=TX_CACHE_MAINNET)
|
||||
|
||||
|
||||
# Adapted from TestMsgSigntx.test_one_one_fee,
|
||||
# only changed the coin from Bitcoin to Bcash.
|
||||
# Bcash does have strong replay protection using SIGHASH_FORKID,
|
||||
# spending from Bitcoin path should work.
|
||||
def test_invalid_path_pass_forkid(client):
|
||||
# tx: 8cc1f4adf7224ce855cf535a5104594a0004cb3b640d6714fdb00b9128832dd5
|
||||
# input 0: 0.0039 BTC
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44h/0h/0h/0/0"),
|
||||
amount=390000,
|
||||
prev_hash=TXHASH_8cc1f4,
|
||||
prev_index=0,
|
||||
)
|
||||
|
||||
# address is converted from 1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1 to cashaddr format
|
||||
out1 = proto.TxOutputType(
|
||||
address="bitcoincash:qr0fk25d5zygyn50u5w7h6jkvctas52n0qxff9ja6r",
|
||||
amount=390000 - 10000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
btc.sign_tx(client, "Bcash", [inp1], [out1], prev_txes=TX_CACHE_BCASH)
|
||||
|
@ -38,126 +38,126 @@ TXHASH_7b28bd = bytes.fromhex(
|
||||
"7b28bd91119e9776f0d4ebd80e570165818a829bbf4477cd1afe5149dbcd34b1"
|
||||
)
|
||||
|
||||
pytestmark = [pytest.mark.altcoin, pytest.mark.komodo]
|
||||
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.komodo
|
||||
class TestMsgSigntxKomodo:
|
||||
def test_one_one_fee_sapling(self, client):
|
||||
# prevout: 2807c5b126ec8e2b078cab0f12e4c8b4ce1d7724905f8ebef8dca26b0c8e0f1d:0
|
||||
# input 1: 10.9998 KMD
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
# R9HgJZo6JBKmPvhm7whLSR8wiHyZrEDVRi
|
||||
address_n=parse_path("44'/141'/0'/0/0"),
|
||||
amount=1099980000,
|
||||
prev_hash=TXHASH_2807c,
|
||||
prev_index=0,
|
||||
def test_one_one_fee_sapling(client):
|
||||
# prevout: 2807c5b126ec8e2b078cab0f12e4c8b4ce1d7724905f8ebef8dca26b0c8e0f1d:0
|
||||
# input 1: 10.9998 KMD
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
# R9HgJZo6JBKmPvhm7whLSR8wiHyZrEDVRi
|
||||
address_n=parse_path("44'/141'/0'/0/0"),
|
||||
amount=1099980000,
|
||||
prev_hash=TXHASH_2807c,
|
||||
prev_index=0,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="R9HgJZo6JBKmPvhm7whLSR8wiHyZrEDVRi",
|
||||
amount=1099980000 - 10000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_2807c),
|
||||
request_input(0, TXHASH_2807c),
|
||||
request_output(0, TXHASH_2807c),
|
||||
request_extra_data(0, 11, TXHASH_2807c),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="R9HgJZo6JBKmPvhm7whLSR8wiHyZrEDVRi",
|
||||
amount=1099980000 - 10000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Komodo",
|
||||
[inp1],
|
||||
[out1],
|
||||
version=4,
|
||||
version_group_id=0x892F2085,
|
||||
branch_id=0x76B809BB,
|
||||
lock_time=0x5D2A30B8,
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_2807c),
|
||||
request_input(0, TXHASH_2807c),
|
||||
request_output(0, TXHASH_2807c),
|
||||
request_extra_data(0, 11, TXHASH_2807c),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
# Accepted by network: tx 7b28bd91119e9776f0d4ebd80e570165818a829bbf4477cd1afe5149dbcd34b1
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0400008085202f89011d0f8e0c6ba2dcf8be8e5f9024771dceb4c8e4120fab8c072b8eec26b1c50728000000006a4730440220158c970ca2fc6bcc33026eb5366f0342f63b35d178f7efb334b1df78fe90b67202207bc4ff69f67cf843b08564a5adc77bf5593e28ab4d5104911824ac13fe885d8f012102a87aef7b1a8f676e452d6240767699719cd58b0261c822472c25df146938bca5ffffffff01d0359041000000001976a91400178fa0b6fc253a3a402ee2cadd8a7bfec08f6388acb8302a5d000000000000000000000000000000"
|
||||
)
|
||||
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Komodo",
|
||||
[inp1],
|
||||
[out1],
|
||||
version=4,
|
||||
version_group_id=0x892F2085,
|
||||
branch_id=0x76B809BB,
|
||||
lock_time=0x5D2A30B8,
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
# Accepted by network: tx 7b28bd91119e9776f0d4ebd80e570165818a829bbf4477cd1afe5149dbcd34b1
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0400008085202f89011d0f8e0c6ba2dcf8be8e5f9024771dceb4c8e4120fab8c072b8eec26b1c50728000000006a4730440220158c970ca2fc6bcc33026eb5366f0342f63b35d178f7efb334b1df78fe90b67202207bc4ff69f67cf843b08564a5adc77bf5593e28ab4d5104911824ac13fe885d8f012102a87aef7b1a8f676e452d6240767699719cd58b0261c822472c25df146938bca5ffffffff01d0359041000000001976a91400178fa0b6fc253a3a402ee2cadd8a7bfec08f6388acb8302a5d000000000000000000000000000000"
|
||||
def test_one_one_rewards_claim(client):
|
||||
# prevout: 7b28bd91119e9776f0d4ebd80e570165818a829bbf4477cd1afe5149dbcd34b1:0
|
||||
# input 1: 10.9997 KMD
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
# R9HgJZo6JBKmPvhm7whLSR8wiHyZrEDVRi
|
||||
address_n=parse_path("44'/141'/0'/0/0"),
|
||||
amount=1099970000,
|
||||
prev_hash=TXHASH_7b28bd,
|
||||
prev_index=0,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="R9HgJZo6JBKmPvhm7whLSR8wiHyZrEDVRi",
|
||||
amount=1099970000 - 10000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
# kmd interest, vout sum > vin sum
|
||||
out2 = proto.TxOutputType(
|
||||
address="R9HgJZo6JBKmPvhm7whLSR8wiHyZrEDVRi",
|
||||
amount=79605,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_7b28bd),
|
||||
request_input(0, TXHASH_7b28bd),
|
||||
request_output(0, TXHASH_7b28bd),
|
||||
request_extra_data(0, 11, TXHASH_7b28bd),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
|
||||
def test_one_one_rewards_claim(self, client):
|
||||
# prevout: 7b28bd91119e9776f0d4ebd80e570165818a829bbf4477cd1afe5149dbcd34b1:0
|
||||
# input 1: 10.9997 KMD
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
# R9HgJZo6JBKmPvhm7whLSR8wiHyZrEDVRi
|
||||
address_n=parse_path("44'/141'/0'/0/0"),
|
||||
amount=1099970000,
|
||||
prev_hash=TXHASH_7b28bd,
|
||||
prev_index=0,
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Komodo",
|
||||
[inp1],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
version=4,
|
||||
version_group_id=0x892F2085,
|
||||
branch_id=0x76B809BB,
|
||||
lock_time=0x5D2AF1F2,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="R9HgJZo6JBKmPvhm7whLSR8wiHyZrEDVRi",
|
||||
amount=1099970000 - 10000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
# kmd interest, vout sum > vin sum
|
||||
out2 = proto.TxOutputType(
|
||||
address="R9HgJZo6JBKmPvhm7whLSR8wiHyZrEDVRi",
|
||||
amount=79605,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_7b28bd),
|
||||
request_input(0, TXHASH_7b28bd),
|
||||
request_output(0, TXHASH_7b28bd),
|
||||
request_extra_data(0, 11, TXHASH_7b28bd),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Komodo",
|
||||
[inp1],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
version=4,
|
||||
version_group_id=0x892F2085,
|
||||
branch_id=0x76B809BB,
|
||||
lock_time=0x5D2AF1F2,
|
||||
)
|
||||
|
||||
# Accepted by network: tx c775678ceb18277729b427c7acf2f8ce63ac02fc2366f47ce08a3f443ff0e059
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0400008085202f8901b134cddb4951fe1acd7744bf9b828a816501570ed8ebd4f076979e1191bd287b000000006a4730440220483a58f5be3a147c773c663008c992a7fcea4d03bdf4c1d4bc0535c0d98ddf0602207b19d69140dd00c7a94f048c712aeaed55dfd27f581c7212d9cc5e476fe1dc9f012102a87aef7b1a8f676e452d6240767699719cd58b0261c822472c25df146938bca5ffffffff02c00e9041000000001976a91400178fa0b6fc253a3a402ee2cadd8a7bfec08f6388acf5360100000000001976a91400178fa0b6fc253a3a402ee2cadd8a7bfec08f6388acf2f12a5d000000000000000000000000000000"
|
||||
)
|
||||
# Accepted by network: tx c775678ceb18277729b427c7acf2f8ce63ac02fc2366f47ce08a3f443ff0e059
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0400008085202f8901b134cddb4951fe1acd7744bf9b828a816501570ed8ebd4f076979e1191bd287b000000006a4730440220483a58f5be3a147c773c663008c992a7fcea4d03bdf4c1d4bc0535c0d98ddf0602207b19d69140dd00c7a94f048c712aeaed55dfd27f581c7212d9cc5e476fe1dc9f012102a87aef7b1a8f676e452d6240767699719cd58b0261c822472c25df146938bca5ffffffff02c00e9041000000001976a91400178fa0b6fc253a3a402ee2cadd8a7bfec08f6388acf5360100000000001976a91400178fa0b6fc253a3a402ee2cadd8a7bfec08f6388acf2f12a5d000000000000000000000000000000"
|
||||
)
|
||||
|
@ -40,397 +40,399 @@ TXHASH_e5040e = bytes.fromhex(
|
||||
)
|
||||
|
||||
|
||||
class TestMsgSigntxSegwit:
|
||||
def test_send_p2sh(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("49'/1'/0'/1/0"),
|
||||
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
|
||||
amount=123456789,
|
||||
prev_hash=TXHASH_20912f,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
def test_send_p2sh(client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("49'/1'/0'/1/0"),
|
||||
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
|
||||
amount=123456789,
|
||||
prev_hash=TXHASH_20912f,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC",
|
||||
amount=12300000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address="2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX",
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
amount=123456789 - 11000 - 12300000,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.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_output(0),
|
||||
request_output(1),
|
||||
request_input(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC",
|
||||
amount=12300000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address="2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX",
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
amount=123456789 - 11000 - 12300000,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.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_output(0),
|
||||
request_output(1),
|
||||
request_input(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Testnet", [inp1], [out1, out2], prev_txes=TX_API
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000000010137c361fb8f2d9056ba8c98c5611930fcb48cacfdd0fe2e0449d83eea982f91200000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff02e0aebb00000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac3df39f060000000017a91458b53ea7f832e8f096e896b8713a8c6df0e892ca8702483045022100ccd253bfdf8a5593cd7b6701370c531199f0f05a418cd547dfc7da3f21515f0f02203fa08a0753688871c220648f9edadbdb98af42e5d8269364a326572cf703895b012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000"
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Testnet", [inp1], [out1, out2], prev_txes=TX_API
|
||||
)
|
||||
|
||||
def test_send_p2sh_change(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("49'/1'/0'/1/0"),
|
||||
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
|
||||
amount=123456789,
|
||||
prev_hash=TXHASH_20912f,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC",
|
||||
amount=12300000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=parse_path("49'/1'/0'/1/0"),
|
||||
script_type=proto.OutputScriptType.PAYTOP2SHWITNESS,
|
||||
amount=123456789 - 11000 - 12300000,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
proto.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_output(0),
|
||||
request_output(1),
|
||||
request_input(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Testnet", [inp1], [out1, out2], prev_txes=TX_API
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000000010137c361fb8f2d9056ba8c98c5611930fcb48cacfdd0fe2e0449d83eea982f91200000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff02e0aebb00000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac3df39f060000000017a91458b53ea7f832e8f096e896b8713a8c6df0e892ca8702483045022100ccd253bfdf8a5593cd7b6701370c531199f0f05a418cd547dfc7da3f21515f0f02203fa08a0753688871c220648f9edadbdb98af42e5d8269364a326572cf703895b012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000"
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000000010137c361fb8f2d9056ba8c98c5611930fcb48cacfdd0fe2e0449d83eea982f91200000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff02e0aebb00000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac3df39f060000000017a91458b53ea7f832e8f096e896b8713a8c6df0e892ca8702483045022100ccd253bfdf8a5593cd7b6701370c531199f0f05a418cd547dfc7da3f21515f0f02203fa08a0753688871c220648f9edadbdb98af42e5d8269364a326572cf703895b012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000"
|
||||
|
||||
def test_send_p2sh_change(client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("49'/1'/0'/1/0"),
|
||||
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
|
||||
amount=123456789,
|
||||
prev_hash=TXHASH_20912f,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC",
|
||||
amount=12300000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=parse_path("49'/1'/0'/1/0"),
|
||||
script_type=proto.OutputScriptType.PAYTOP2SHWITNESS,
|
||||
amount=123456789 - 11000 - 12300000,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
proto.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_output(0),
|
||||
request_output(1),
|
||||
request_input(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Testnet", [inp1], [out1, out2], prev_txes=TX_API
|
||||
)
|
||||
|
||||
def test_testnet_segwit_big_amount(self, client):
|
||||
# This test is testing transaction with amount bigger than fits to uint32
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000000010137c361fb8f2d9056ba8c98c5611930fcb48cacfdd0fe2e0449d83eea982f91200000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff02e0aebb00000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac3df39f060000000017a91458b53ea7f832e8f096e896b8713a8c6df0e892ca8702483045022100ccd253bfdf8a5593cd7b6701370c531199f0f05a418cd547dfc7da3f21515f0f02203fa08a0753688871c220648f9edadbdb98af42e5d8269364a326572cf703895b012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000"
|
||||
)
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("m/49'/1'/0'/0/0"),
|
||||
amount=2 ** 32 + 1,
|
||||
prev_hash=TXHASH_dee13c,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
|
||||
def test_testnet_segwit_big_amount(client):
|
||||
# This test is testing transaction with amount bigger than fits to uint32
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("m/49'/1'/0'/0/0"),
|
||||
amount=2 ** 32 + 1,
|
||||
prev_hash=TXHASH_dee13c,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="2Mt7P2BAfE922zmfXrdcYTLyR7GUvbwSEns", # seed allallall, bip32: m/49'/1'/0'/0/1, script type:p2shsegwit
|
||||
amount=2 ** 32 + 1,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_dee13c),
|
||||
request_output(0, TXHASH_dee13c),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_input(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="2Mt7P2BAfE922zmfXrdcYTLyR7GUvbwSEns", # seed allallall, bip32: m/49'/1'/0'/0/1, script type:p2shsegwit
|
||||
amount=2 ** 32 + 1,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Testnet", [inp1], [out1], prev_txes=TX_API
|
||||
)
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_dee13c),
|
||||
request_output(0, TXHASH_dee13c),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_input(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Testnet", [inp1], [out1], prev_txes=TX_API
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000000101023a2995a4a60c59df1b9559b49b6d8940cb740d47cea10881b27a9e463ce1de00000000171600140099a7ecbd938ed1839f5f6bf6d50933c6db9d5cffffffff01010000000100000017a914097c569095163e84475d07aa95a1f736df895b7b8702483045022100965aa8897c7cd5f0bff830481ed5259bf662ed0415ab497a6a152a3c335eb0a1022060acbbbada909b6575ac6f19382a6bdf4cab2fa1c5421aa66677806f380ddb870121033add1f0e8e3c3136f7428dd4a4de1057380bd311f5b0856e2269170b4ffa65bf00000000"
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000000101023a2995a4a60c59df1b9559b49b6d8940cb740d47cea10881b27a9e463ce1de00000000171600140099a7ecbd938ed1839f5f6bf6d50933c6db9d5cffffffff01010000000100000017a914097c569095163e84475d07aa95a1f736df895b7b8702483045022100965aa8897c7cd5f0bff830481ed5259bf662ed0415ab497a6a152a3c335eb0a1022060acbbbada909b6575ac6f19382a6bdf4cab2fa1c5421aa66677806f380ddb870121033add1f0e8e3c3136f7428dd4a4de1057380bd311f5b0856e2269170b4ffa65bf00000000"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.multisig
|
||||
def test_send_multisig_1(client):
|
||||
nodes = [
|
||||
btc.get_public_node(
|
||||
client, parse_path(f"49'/1'/{i}'"), coin_name="Testnet"
|
||||
).node
|
||||
for i in range(1, 4)
|
||||
]
|
||||
|
||||
multisig = proto.MultisigRedeemScriptType(
|
||||
nodes=nodes, address_n=[1, 0], signatures=[b"", b"", b""], m=2
|
||||
)
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("49'/1'/1'/1/0"),
|
||||
prev_hash=TXHASH_9c3192,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
multisig=multisig,
|
||||
amount=1610436,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC",
|
||||
amount=1605000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_9c3192),
|
||||
request_input(0, TXHASH_9c3192),
|
||||
request_output(0, TXHASH_9c3192),
|
||||
request_output(1, TXHASH_9c3192),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_input(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
signatures, _ = btc.sign_tx(client, "Testnet", [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),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_9c3192),
|
||||
request_input(0, TXHASH_9c3192),
|
||||
request_output(0, TXHASH_9c3192),
|
||||
request_output(1, TXHASH_9c3192),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_input(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Testnet", [inp1], [out1], prev_txes=TX_API
|
||||
)
|
||||
|
||||
@pytest.mark.multisig
|
||||
def test_send_multisig_1(self, client):
|
||||
nodes = [
|
||||
btc.get_public_node(
|
||||
client, parse_path(f"49'/1'/{i}'"), coin_name="Testnet"
|
||||
).node
|
||||
for i in range(1, 4)
|
||||
]
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000000101be0210025c5be68a473f6a38bf53b53bc88d5c46567616026dc056e72b92319c0100000023220020cf28684ff8a6dda1a7a9704dde113ddfcf236558da5ce35ad3f8477474dbdaf7ffffffff01887d1800000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac040047304402203fc3fbe6cd6250d82ace4a585debc07587c07d2efc8bb56558c91e1f810fe65402206025bd9a4e80960f617b6e5bfdd568e34aa085d093471b7976e6b14c2a2402a7014730440220327abf491a57964d75c67fad204eb782fa74aa4abde40e5ad30fb0b7696102b7022049e31f2302417be0a87e2f818b93a862a7e67d4178b7cbeee680264f0882113f0169522103d54ab3c8b81cb7f8f8088df4c62c105e8acaa2fb53b180f6bc6f922faecf3fdc21036aa47994f3f18f0976d6073ca79997003c3fa29c4f93907998fefc1151b4529b2102a092580f2828272517c402da9461425c5032860ab40180e041fbbb88ea2a520453ae00000000"
|
||||
)
|
||||
|
||||
multisig = proto.MultisigRedeemScriptType(
|
||||
nodes=nodes, address_n=[1, 0], signatures=[b"", b"", b""], m=2
|
||||
|
||||
def test_attack_change_input_address(client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("49'/1'/0'/1/0"),
|
||||
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
|
||||
amount=123456789,
|
||||
prev_hash=TXHASH_20912f,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC",
|
||||
amount=12300000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=parse_path("49'/1'/12'/1/0"),
|
||||
script_type=proto.OutputScriptType.PAYTOP2SHWITNESS,
|
||||
amount=123456789 - 11000 - 12300000,
|
||||
)
|
||||
|
||||
# Test if the transaction can be signed normally
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.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_output(0),
|
||||
request_output(1),
|
||||
request_input(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Testnet", [inp1], [out1, out2], prev_txes=TX_API
|
||||
)
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("49'/1'/1'/1/0"),
|
||||
prev_hash=TXHASH_9c3192,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
multisig=multisig,
|
||||
amount=1610436,
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000000010137c361fb8f2d9056ba8c98c5611930fcb48cacfdd0fe2e0449d83eea982f91200000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff02e0aebb00000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac3df39f060000000017a9142f98413cb83ff8b3eaf1926192e68973cbd68a3a8702473044022013cbce7c575337ca05dbe03b5920a0805b510cd8dfd3180bd7c5d01cec6439cd0220050001be4bcefb585caf973caae0ffec682347f2127cc22f26efd93ee54fd852012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000"
|
||||
)
|
||||
|
||||
attack_count = 2
|
||||
|
||||
def attack_processor(msg):
|
||||
nonlocal attack_count
|
||||
|
||||
if attack_count > 0 and msg.tx.inputs and msg.tx.inputs[0] == inp1:
|
||||
attack_count -= 1
|
||||
msg.tx.inputs[0].address_n[2] = H_(12)
|
||||
|
||||
return msg
|
||||
|
||||
# Now run the attack, must trigger the exception
|
||||
with client:
|
||||
client.set_filter(proto.TxAck, attack_processor)
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
proto.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),
|
||||
proto.Failure(code=proto.FailureType.ProcessError),
|
||||
]
|
||||
)
|
||||
with pytest.raises(TrezorFailure) as exc:
|
||||
btc.sign_tx(client, "Testnet", [inp1], [out1, out2], prev_txes=TX_API)
|
||||
assert exc.value.code == proto.FailureType.ProcessError
|
||||
assert exc.value.message.endswith("Transaction has changed during signing")
|
||||
|
||||
|
||||
def test_attack_mixed_inputs(client):
|
||||
TRUE_AMOUNT = 123456789
|
||||
FAKE_AMOUNT = 120000000
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/1'/0'/0/0"),
|
||||
amount=31000000,
|
||||
prev_hash=TXHASH_e5040e,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
sequence=0xFFFFFFFD,
|
||||
)
|
||||
inp2 = proto.TxInputType(
|
||||
address_n=parse_path("49'/1'/0'/1/0"),
|
||||
amount=TRUE_AMOUNT,
|
||||
prev_hash=TXHASH_20912f,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
sequence=0xFFFFFFFD,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC",
|
||||
amount=31000000 + TRUE_AMOUNT - 3456789,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
expected_responses = [
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.FeeOverThreshold),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_e5040e),
|
||||
request_input(0, TXHASH_e5040e),
|
||||
request_output(0, TXHASH_e5040e),
|
||||
request_output(1, TXHASH_e5040e),
|
||||
request_input(1),
|
||||
request_meta(TXHASH_20912f),
|
||||
request_input(0, TXHASH_20912f),
|
||||
request_output(0, TXHASH_20912f),
|
||||
request_output(1, TXHASH_20912f),
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
request_input(1),
|
||||
request_finished(),
|
||||
]
|
||||
|
||||
if client.features.model == "1":
|
||||
# T1 asks for first input for witness again
|
||||
expected_responses.insert(-2, request_input(0))
|
||||
|
||||
with client:
|
||||
# Sign unmodified transaction.
|
||||
# "Fee over threshold" warning is displayed - fee is the whole TRUE_AMOUNT
|
||||
client.set_expected_responses(expected_responses)
|
||||
btc.sign_tx(
|
||||
client,
|
||||
"Testnet",
|
||||
[inp1, inp2],
|
||||
[out1],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC",
|
||||
amount=1605000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
# In Phase 1 make the user confirm a lower value of the segwit input.
|
||||
inp2.amount = FAKE_AMOUNT
|
||||
|
||||
if client.features.model == "1":
|
||||
# T1 fails as soon as it encounters the fake amount.
|
||||
expected_responses = (
|
||||
expected_responses[:4] + expected_responses[5:15] + [proto.Failure()]
|
||||
)
|
||||
else:
|
||||
expected_responses = (
|
||||
expected_responses[:4] + expected_responses[5:16] + [proto.Failure()]
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_9c3192),
|
||||
request_input(0, TXHASH_9c3192),
|
||||
request_output(0, TXHASH_9c3192),
|
||||
request_output(1, TXHASH_9c3192),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_input(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
signatures, _ = btc.sign_tx(
|
||||
client, "Testnet", [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),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_9c3192),
|
||||
request_input(0, TXHASH_9c3192),
|
||||
request_output(0, TXHASH_9c3192),
|
||||
request_output(1, TXHASH_9c3192),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_input(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Testnet", [inp1], [out1], prev_txes=TX_API
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "01000000000101be0210025c5be68a473f6a38bf53b53bc88d5c46567616026dc056e72b92319c0100000023220020cf28684ff8a6dda1a7a9704dde113ddfcf236558da5ce35ad3f8477474dbdaf7ffffffff01887d1800000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac040047304402203fc3fbe6cd6250d82ace4a585debc07587c07d2efc8bb56558c91e1f810fe65402206025bd9a4e80960f617b6e5bfdd568e34aa085d093471b7976e6b14c2a2402a7014730440220327abf491a57964d75c67fad204eb782fa74aa4abde40e5ad30fb0b7696102b7022049e31f2302417be0a87e2f818b93a862a7e67d4178b7cbeee680264f0882113f0169522103d54ab3c8b81cb7f8f8088df4c62c105e8acaa2fb53b180f6bc6f922faecf3fdc21036aa47994f3f18f0976d6073ca79997003c3fa29c4f93907998fefc1151b4529b2102a092580f2828272517c402da9461425c5032860ab40180e041fbbb88ea2a520453ae00000000"
|
||||
with pytest.raises(TrezorFailure) as e, client:
|
||||
client.set_expected_responses(expected_responses)
|
||||
btc.sign_tx(
|
||||
client,
|
||||
"Testnet",
|
||||
[inp1, inp2],
|
||||
[out1],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
def test_attack_change_input_address(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("49'/1'/0'/1/0"),
|
||||
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
|
||||
amount=123456789,
|
||||
prev_hash=TXHASH_20912f,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC",
|
||||
amount=12300000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=parse_path("49'/1'/12'/1/0"),
|
||||
script_type=proto.OutputScriptType.PAYTOP2SHWITNESS,
|
||||
amount=123456789 - 11000 - 12300000,
|
||||
)
|
||||
|
||||
# Test if the transaction can be signed normally
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.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_output(0),
|
||||
request_output(1),
|
||||
request_input(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Testnet", [inp1], [out1, out2], prev_txes=TX_API
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000000010137c361fb8f2d9056ba8c98c5611930fcb48cacfdd0fe2e0449d83eea982f91200000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff02e0aebb00000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac3df39f060000000017a9142f98413cb83ff8b3eaf1926192e68973cbd68a3a8702473044022013cbce7c575337ca05dbe03b5920a0805b510cd8dfd3180bd7c5d01cec6439cd0220050001be4bcefb585caf973caae0ffec682347f2127cc22f26efd93ee54fd852012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000"
|
||||
)
|
||||
|
||||
attack_count = 2
|
||||
|
||||
def attack_processor(msg):
|
||||
nonlocal attack_count
|
||||
|
||||
if attack_count > 0 and msg.tx.inputs and msg.tx.inputs[0] == inp1:
|
||||
attack_count -= 1
|
||||
msg.tx.inputs[0].address_n[2] = H_(12)
|
||||
|
||||
return msg
|
||||
|
||||
# Now run the attack, must trigger the exception
|
||||
with client:
|
||||
client.set_filter(proto.TxAck, attack_processor)
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
proto.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),
|
||||
proto.Failure(code=proto.FailureType.ProcessError),
|
||||
]
|
||||
)
|
||||
with pytest.raises(TrezorFailure) as exc:
|
||||
btc.sign_tx(client, "Testnet", [inp1], [out1, out2], prev_txes=TX_API)
|
||||
assert exc.value.code == proto.FailureType.ProcessError
|
||||
assert exc.value.message.endswith("Transaction has changed during signing")
|
||||
|
||||
def test_attack_mixed_inputs(self, client):
|
||||
TRUE_AMOUNT = 123456789
|
||||
FAKE_AMOUNT = 120000000
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/1'/0'/0/0"),
|
||||
amount=31000000,
|
||||
prev_hash=TXHASH_e5040e,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDADDRESS,
|
||||
sequence=0xFFFFFFFD,
|
||||
)
|
||||
inp2 = proto.TxInputType(
|
||||
address_n=parse_path("49'/1'/0'/1/0"),
|
||||
amount=TRUE_AMOUNT,
|
||||
prev_hash=TXHASH_20912f,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
sequence=0xFFFFFFFD,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC",
|
||||
amount=31000000 + TRUE_AMOUNT - 3456789,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
expected_responses = [
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.FeeOverThreshold),
|
||||
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_e5040e),
|
||||
request_input(0, TXHASH_e5040e),
|
||||
request_output(0, TXHASH_e5040e),
|
||||
request_output(1, TXHASH_e5040e),
|
||||
request_input(1),
|
||||
request_meta(TXHASH_20912f),
|
||||
request_input(0, TXHASH_20912f),
|
||||
request_output(0, TXHASH_20912f),
|
||||
request_output(1, TXHASH_20912f),
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
request_input(1),
|
||||
request_finished(),
|
||||
]
|
||||
|
||||
if client.features.model == "1":
|
||||
# T1 asks for first input for witness again
|
||||
expected_responses.insert(-2, request_input(0))
|
||||
|
||||
with client:
|
||||
# Sign unmodified transaction.
|
||||
# "Fee over threshold" warning is displayed - fee is the whole TRUE_AMOUNT
|
||||
client.set_expected_responses(expected_responses)
|
||||
btc.sign_tx(
|
||||
client,
|
||||
"Testnet",
|
||||
[inp1, inp2],
|
||||
[out1],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
# In Phase 1 make the user confirm a lower value of the segwit input.
|
||||
inp2.amount = FAKE_AMOUNT
|
||||
|
||||
if client.features.model == "1":
|
||||
# T1 fails as soon as it encounters the fake amount.
|
||||
expected_responses = (
|
||||
expected_responses[:4] + expected_responses[5:15] + [proto.Failure()]
|
||||
)
|
||||
else:
|
||||
expected_responses = (
|
||||
expected_responses[:4] + expected_responses[5:16] + [proto.Failure()]
|
||||
)
|
||||
|
||||
with pytest.raises(TrezorFailure) as e, client:
|
||||
client.set_expected_responses(expected_responses)
|
||||
btc.sign_tx(
|
||||
client,
|
||||
"Testnet",
|
||||
[inp1, inp2],
|
||||
[out1],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
assert e.value.failure.message.endswith("Invalid amount specified")
|
||||
assert e.value.failure.message.endswith("Invalid amount specified")
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -52,246 +52,249 @@ TXHASH_v4 = bytes.fromhex(
|
||||
"5d8de67264b08eecc8e3bee19a11a7f54a2bce1dc4f2a699538e372ae92e9c0f"
|
||||
)
|
||||
|
||||
pytestmark = [pytest.mark.altcoin, pytest.mark.zcash]
|
||||
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.zcash
|
||||
class TestMsgSigntxZcash:
|
||||
def test_v3_not_supported(self, client):
|
||||
# prevout: aaf51e4606c264e47e5c42c958fe4cf1539c5172684721e38e69f4ef634d75dc:1
|
||||
# input 1: 3.0 TAZ
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
# tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu
|
||||
address_n=parse_path("m/44h/1h/0h/0/0"),
|
||||
amount=300000000,
|
||||
prev_hash=TXHASH_aaf51e,
|
||||
prev_index=1,
|
||||
def test_v3_not_supported(client):
|
||||
# prevout: aaf51e4606c264e47e5c42c958fe4cf1539c5172684721e38e69f4ef634d75dc:1
|
||||
# input 1: 3.0 TAZ
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
# tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu
|
||||
address_n=parse_path("m/44h/1h/0h/0/0"),
|
||||
amount=300000000,
|
||||
prev_hash=TXHASH_aaf51e,
|
||||
prev_index=1,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="tmJ1xYxP8XNTtCoDgvdmQPSrxh5qZJgy65Z",
|
||||
amount=300000000 - 1940,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client, pytest.raises(TrezorFailure, match="DataError"):
|
||||
btc.sign_tx(
|
||||
client,
|
||||
"Zcash Testnet",
|
||||
[inp1],
|
||||
[out1],
|
||||
version=3,
|
||||
version_group_id=0x03C48270,
|
||||
branch_id=0x5BA81B19,
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="tmJ1xYxP8XNTtCoDgvdmQPSrxh5qZJgy65Z",
|
||||
amount=300000000 - 1940,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
|
||||
def test_one_one_fee_sapling(client):
|
||||
# prevout: e3820602226974b1dd87b7113cc8aea8c63e5ae29293991e7bfa80c126930368:0
|
||||
# input 1: 3.0 TAZ
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
# tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu
|
||||
address_n=parse_path("m/44h/1h/0h/0/0"),
|
||||
amount=300000000,
|
||||
prev_hash=TXHASH_e38206,
|
||||
prev_index=0,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="tmJ1xYxP8XNTtCoDgvdmQPSrxh5qZJgy65Z",
|
||||
amount=300000000 - 1940,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_e38206),
|
||||
request_input(0, TXHASH_e38206),
|
||||
request_input(1, TXHASH_e38206),
|
||||
request_output(0, TXHASH_e38206),
|
||||
request_output(1, TXHASH_e38206),
|
||||
request_extra_data(0, 1, TXHASH_e38206),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
|
||||
with client, pytest.raises(TrezorFailure, match="DataError"):
|
||||
btc.sign_tx(
|
||||
client,
|
||||
"Zcash Testnet",
|
||||
[inp1],
|
||||
[out1],
|
||||
version=3,
|
||||
version_group_id=0x03C48270,
|
||||
branch_id=0x5BA81B19,
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
def test_one_one_fee_sapling(self, client):
|
||||
# prevout: e3820602226974b1dd87b7113cc8aea8c63e5ae29293991e7bfa80c126930368:0
|
||||
# input 1: 3.0 TAZ
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
# tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu
|
||||
address_n=parse_path("m/44h/1h/0h/0/0"),
|
||||
amount=300000000,
|
||||
prev_hash=TXHASH_e38206,
|
||||
prev_index=0,
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Zcash Testnet",
|
||||
[inp1],
|
||||
[out1],
|
||||
version=4,
|
||||
version_group_id=0x892F2085,
|
||||
branch_id=0x76B809BB,
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="tmJ1xYxP8XNTtCoDgvdmQPSrxh5qZJgy65Z",
|
||||
amount=300000000 - 1940,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
# Accepted by network: tx 0cef132c1d6d67f11cfa48f7fca3209da29cf872ac782354bedb686e61a17a78
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0400008085202f890168039326c180fa7b1e999392e25a3ec6a8aec83c11b787ddb1746922020682e3000000006b483045022100f28298891f48706697a6f898ac18e39ce2c7cebe547b585d51cc22d80b1b21a602201a807b8a18544832d95d1e3ada82c0617bc6d97d3f24d1fb4801ac396647aa880121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffff016c9be111000000001976a9145b157a678a10021243307e4bb58f36375aa80e1088ac00000000000000000000000000000000000000"
|
||||
)
|
||||
|
||||
|
||||
def test_version_group_id_missing(client):
|
||||
inp1 = proto.TxInputType(
|
||||
# tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu
|
||||
address_n=parse_path("m/44h/1h/0h/0/0"),
|
||||
amount=300000000,
|
||||
prev_hash=TXHASH_e38206,
|
||||
prev_index=0,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="tmJ1xYxP8XNTtCoDgvdmQPSrxh5qZJgy65Z",
|
||||
amount=300000000 - 1940,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with pytest.raises(TrezorFailure, match="Version group ID must be set."):
|
||||
btc.sign_tx(
|
||||
client,
|
||||
"Zcash Testnet",
|
||||
[inp1],
|
||||
[out1],
|
||||
version=4,
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_e38206),
|
||||
request_input(0, TXHASH_e38206),
|
||||
request_input(1, TXHASH_e38206),
|
||||
request_output(0, TXHASH_e38206),
|
||||
request_output(1, TXHASH_e38206),
|
||||
request_extra_data(0, 1, TXHASH_e38206),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Zcash Testnet",
|
||||
[inp1],
|
||||
[out1],
|
||||
version=4,
|
||||
version_group_id=0x892F2085,
|
||||
branch_id=0x76B809BB,
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
def test_spend_old_versions(client):
|
||||
# inputs are NOT OWNED by this seed
|
||||
input_v1 = proto.TxInputType(
|
||||
address_n=parse_path("m/44h/1h/0h/0/0"),
|
||||
amount=123000000,
|
||||
prev_hash=TXHASH_v1,
|
||||
prev_index=0,
|
||||
)
|
||||
input_v2 = proto.TxInputType(
|
||||
address_n=parse_path("m/44h/1h/0h/0/1"),
|
||||
amount=49990000,
|
||||
prev_hash=TXHASH_v2,
|
||||
prev_index=0,
|
||||
)
|
||||
input_v3 = proto.TxInputType(
|
||||
address_n=parse_path("m/44h/1h/0h/0/2"),
|
||||
amount=300000000,
|
||||
prev_hash=TXHASH_v3,
|
||||
prev_index=1,
|
||||
)
|
||||
input_v4 = proto.TxInputType(
|
||||
address_n=parse_path("m/44h/1h/0h/0/3"),
|
||||
amount=100000,
|
||||
prev_hash=TXHASH_v4,
|
||||
prev_index=0,
|
||||
)
|
||||
|
||||
# Accepted by network: tx 0cef132c1d6d67f11cfa48f7fca3209da29cf872ac782354bedb686e61a17a78
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0400008085202f890168039326c180fa7b1e999392e25a3ec6a8aec83c11b787ddb1746922020682e3000000006b483045022100f28298891f48706697a6f898ac18e39ce2c7cebe547b585d51cc22d80b1b21a602201a807b8a18544832d95d1e3ada82c0617bc6d97d3f24d1fb4801ac396647aa880121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffff016c9be111000000001976a9145b157a678a10021243307e4bb58f36375aa80e1088ac00000000000000000000000000000000000000"
|
||||
inputs = [input_v1, input_v2, input_v3, input_v4]
|
||||
|
||||
for i, txi in enumerate(inputs, 1):
|
||||
txdata = TX_API[txi.prev_hash]
|
||||
assert txdata.version == i
|
||||
|
||||
output = proto.TxOutputType(
|
||||
address="tmNvfeKR5PkcQazLEqddTskFr6Ev9tsovfQ",
|
||||
amount=sum(txi.amount for txi in inputs),
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Zcash Testnet",
|
||||
inputs,
|
||||
[output],
|
||||
version=4,
|
||||
version_group_id=0x892F2085,
|
||||
branch_id=0x76B809BB,
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
def test_version_group_id_missing(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
# tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu
|
||||
address_n=parse_path("m/44h/1h/0h/0/0"),
|
||||
amount=300000000,
|
||||
prev_hash=TXHASH_e38206,
|
||||
prev_index=0,
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="tmJ1xYxP8XNTtCoDgvdmQPSrxh5qZJgy65Z",
|
||||
amount=300000000 - 1940,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0400008085202f890446828054c6c81a8c370c47dc1cfd6f1b200af5623ac3d5b62501121b74ae91fb000000006b483045022100d40e85efbadd378fc603dc8b11c70774086de631fe5b1418ac2b95a478f86507022072e999d8ddd75a0b33bd2adcc88e7234e6251b9e73c9223e7c59e0d1f8d1ff220121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffffef42e249deb8e7bc1d5ec7c4590c70c5b89734b2b896c72ad6469d95190ed303000000006b483045022100917d96445d64c80f9569cb9ca45c04c9b6d7b0fda6b9fd0b1d311837366c699202202cd6140489cf38b5d97ed271ba28603f4693c2a36113cc6ec423301f077c5a8e01210294e3e5e77e22eea0e4c0d30d89beb4db7f69b4bf1ae709e411d6a06618b8f852ffffffff6cb78ae689ae1334f4b03c6f613b280c70088b963f1c965f814081d1298841f9010000006a473044022058768c74c9b1698070636388d7d2ae8223748f13b0a5f402716e4d49fc5bc5f30220658d1e6095dcfbe66669b4141d23af28c9ed5bae73480889429b41742be85f32012103f5008445568548bd745a3dedccc6048969436bf1a49411f60938ff1938941f14ffffffff0f9c2ee92a378e5399a6f2c41dce2b4af5a7119ae1bee3c8ec8eb06472e68d5d000000006b483045022100e64853d86bed039c4edce4abaf80d41486cd21c63bec79c0308ea05a351663e302206732aa22a5dee7bd7f3cc8268faebe31a08abadb4b7e3a4257509bc7baa052b60121029ad0b9519779c540b34fa8d11d24d14a5475546bfa28c7de50573d22a503ce21ffffffff01d0c7321c000000001976a91490ede9de4bed6e39008375eace793949de9a533288ac00000000000000000000000000000000000000"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
def test_external_presigned(client):
|
||||
inp1 = proto.TxInputType(
|
||||
# tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu
|
||||
address_n=parse_path("m/44h/1h/0h/0/0"),
|
||||
amount=300000000,
|
||||
prev_hash=TXHASH_e38206,
|
||||
prev_index=0,
|
||||
)
|
||||
|
||||
inp2 = proto.TxInputType(
|
||||
# tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu
|
||||
# address_n=parse_path("m/44h/1h/0h/0/0"),
|
||||
amount=300000000,
|
||||
prev_hash=TXHASH_aaf51e,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.EXTERNAL,
|
||||
script_pubkey=bytes.fromhex(
|
||||
"76a914a579388225827d9f2fe9014add644487808c695d88ac"
|
||||
),
|
||||
script_sig=bytes.fromhex(
|
||||
"47304402202495a38e5b368569a1a0c9fc95aa7e57a0dd5ae43f51300d7222dc139015233d022047833eaa571578f72c8468c8b537b36410388b7eb5001d75d1f4b954e1997d590121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0"
|
||||
),
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="tmJ1xYxP8XNTtCoDgvdmQPSrxh5qZJgy65Z",
|
||||
amount=300000000 + 300000000 - 1940,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_e38206),
|
||||
request_input(0, TXHASH_e38206),
|
||||
request_input(1, TXHASH_e38206),
|
||||
request_output(0, TXHASH_e38206),
|
||||
request_output(1, TXHASH_e38206),
|
||||
request_extra_data(0, 1, TXHASH_e38206),
|
||||
request_input(1),
|
||||
request_meta(TXHASH_aaf51e),
|
||||
request_input(0, TXHASH_aaf51e),
|
||||
request_output(0, TXHASH_aaf51e),
|
||||
request_output(1, TXHASH_aaf51e),
|
||||
request_extra_data(0, 1, TXHASH_aaf51e),
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
|
||||
with pytest.raises(TrezorFailure, match="Version group ID must be set."):
|
||||
btc.sign_tx(
|
||||
client,
|
||||
"Zcash Testnet",
|
||||
[inp1],
|
||||
[out1],
|
||||
version=4,
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
def test_spend_old_versions(self, client):
|
||||
# inputs are NOT OWNED by this seed
|
||||
input_v1 = proto.TxInputType(
|
||||
address_n=parse_path("m/44h/1h/0h/0/0"),
|
||||
amount=123000000,
|
||||
prev_hash=TXHASH_v1,
|
||||
prev_index=0,
|
||||
)
|
||||
input_v2 = proto.TxInputType(
|
||||
address_n=parse_path("m/44h/1h/0h/0/1"),
|
||||
amount=49990000,
|
||||
prev_hash=TXHASH_v2,
|
||||
prev_index=0,
|
||||
)
|
||||
input_v3 = proto.TxInputType(
|
||||
address_n=parse_path("m/44h/1h/0h/0/2"),
|
||||
amount=300000000,
|
||||
prev_hash=TXHASH_v3,
|
||||
prev_index=1,
|
||||
)
|
||||
input_v4 = proto.TxInputType(
|
||||
address_n=parse_path("m/44h/1h/0h/0/3"),
|
||||
amount=100000,
|
||||
prev_hash=TXHASH_v4,
|
||||
prev_index=0,
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Zcash Testnet",
|
||||
[inp1, inp2],
|
||||
[out1],
|
||||
version=4,
|
||||
version_group_id=0x892F2085,
|
||||
branch_id=0x76B809BB,
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
inputs = [input_v1, input_v2, input_v3, input_v4]
|
||||
|
||||
for i, txi in enumerate(inputs, 1):
|
||||
txdata = TX_API[txi.prev_hash]
|
||||
assert txdata.version == i
|
||||
|
||||
output = proto.TxOutputType(
|
||||
address="tmNvfeKR5PkcQazLEqddTskFr6Ev9tsovfQ",
|
||||
amount=sum(txi.amount for txi in inputs),
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Zcash Testnet",
|
||||
inputs,
|
||||
[output],
|
||||
version=4,
|
||||
version_group_id=0x892F2085,
|
||||
branch_id=0x76B809BB,
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0400008085202f890446828054c6c81a8c370c47dc1cfd6f1b200af5623ac3d5b62501121b74ae91fb000000006b483045022100d40e85efbadd378fc603dc8b11c70774086de631fe5b1418ac2b95a478f86507022072e999d8ddd75a0b33bd2adcc88e7234e6251b9e73c9223e7c59e0d1f8d1ff220121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffffef42e249deb8e7bc1d5ec7c4590c70c5b89734b2b896c72ad6469d95190ed303000000006b483045022100917d96445d64c80f9569cb9ca45c04c9b6d7b0fda6b9fd0b1d311837366c699202202cd6140489cf38b5d97ed271ba28603f4693c2a36113cc6ec423301f077c5a8e01210294e3e5e77e22eea0e4c0d30d89beb4db7f69b4bf1ae709e411d6a06618b8f852ffffffff6cb78ae689ae1334f4b03c6f613b280c70088b963f1c965f814081d1298841f9010000006a473044022058768c74c9b1698070636388d7d2ae8223748f13b0a5f402716e4d49fc5bc5f30220658d1e6095dcfbe66669b4141d23af28c9ed5bae73480889429b41742be85f32012103f5008445568548bd745a3dedccc6048969436bf1a49411f60938ff1938941f14ffffffff0f9c2ee92a378e5399a6f2c41dce2b4af5a7119ae1bee3c8ec8eb06472e68d5d000000006b483045022100e64853d86bed039c4edce4abaf80d41486cd21c63bec79c0308ea05a351663e302206732aa22a5dee7bd7f3cc8268faebe31a08abadb4b7e3a4257509bc7baa052b60121029ad0b9519779c540b34fa8d11d24d14a5475546bfa28c7de50573d22a503ce21ffffffff01d0c7321c000000001976a91490ede9de4bed6e39008375eace793949de9a533288ac00000000000000000000000000000000000000"
|
||||
)
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
def test_external_presigned(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
# tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu
|
||||
address_n=parse_path("m/44h/1h/0h/0/0"),
|
||||
amount=300000000,
|
||||
prev_hash=TXHASH_e38206,
|
||||
prev_index=0,
|
||||
)
|
||||
|
||||
inp2 = proto.TxInputType(
|
||||
# tmQoJ3PTXgQLaRRZZYT6xk8XtjRbr2kCqwu
|
||||
# address_n=parse_path("m/44h/1h/0h/0/0"),
|
||||
amount=300000000,
|
||||
prev_hash=TXHASH_aaf51e,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.EXTERNAL,
|
||||
script_pubkey=bytes.fromhex(
|
||||
"76a914a579388225827d9f2fe9014add644487808c695d88ac"
|
||||
),
|
||||
script_sig=bytes.fromhex(
|
||||
"47304402202495a38e5b368569a1a0c9fc95aa7e57a0dd5ae43f51300d7222dc139015233d022047833eaa571578f72c8468c8b537b36410388b7eb5001d75d1f4b954e1997d590121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0"
|
||||
),
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="tmJ1xYxP8XNTtCoDgvdmQPSrxh5qZJgy65Z",
|
||||
amount=300000000 + 300000000 - 1940,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_e38206),
|
||||
request_input(0, TXHASH_e38206),
|
||||
request_input(1, TXHASH_e38206),
|
||||
request_output(0, TXHASH_e38206),
|
||||
request_output(1, TXHASH_e38206),
|
||||
request_extra_data(0, 1, TXHASH_e38206),
|
||||
request_input(1),
|
||||
request_meta(TXHASH_aaf51e),
|
||||
request_input(0, TXHASH_aaf51e),
|
||||
request_output(0, TXHASH_aaf51e),
|
||||
request_output(1, TXHASH_aaf51e),
|
||||
request_extra_data(0, 1, TXHASH_aaf51e),
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Zcash Testnet",
|
||||
[inp1, inp2],
|
||||
[out1],
|
||||
version=4,
|
||||
version_group_id=0x892F2085,
|
||||
branch_id=0x76B809BB,
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0400008085202f890268039326c180fa7b1e999392e25a3ec6a8aec83c11b787ddb1746922020682e3000000006a473044022007efbf539f8d612d8e140c6af2289b447c34e3d36edd75d539f269fe5526878302206830f6b0398494bca09afdd967fedcd016f49468711cfcd7aafd9a128ee568d20121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffffdc754d63eff4698ee321476872519c53f14cfe58c9425c7ee464c206461ef5aa010000006a47304402202495a38e5b368569a1a0c9fc95aa7e57a0dd5ae43f51300d7222dc139015233d022047833eaa571578f72c8468c8b537b36410388b7eb5001d75d1f4b954e1997d590121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffff016c3ec323000000001976a9145b157a678a10021243307e4bb58f36375aa80e1088ac00000000000000000000000000000000000000"
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0400008085202f890268039326c180fa7b1e999392e25a3ec6a8aec83c11b787ddb1746922020682e3000000006a473044022007efbf539f8d612d8e140c6af2289b447c34e3d36edd75d539f269fe5526878302206830f6b0398494bca09afdd967fedcd016f49468711cfcd7aafd9a128ee568d20121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffffdc754d63eff4698ee321476872519c53f14cfe58c9425c7ee464c206461ef5aa010000006a47304402202495a38e5b368569a1a0c9fc95aa7e57a0dd5ae43f51300d7222dc139015233d022047833eaa571578f72c8468c8b537b36410388b7eb5001d75d1f4b954e1997d590121030e669acac1f280d1ddf441cd2ba5e97417bf2689e4bbec86df4f831bf9f7ffd0ffffffff016c3ec323000000001976a9145b157a678a10021243307e4bb58f36375aa80e1088ac00000000000000000000000000000000000000"
|
||||
)
|
||||
|
@ -21,201 +21,206 @@ import pytest
|
||||
from trezorlib import btc
|
||||
|
||||
|
||||
class TestMsgVerifymessage:
|
||||
def test_message_long(self, client):
|
||||
ret = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
|
||||
bytes.fromhex(
|
||||
"205ff795c29aef7538f8b3bdb2e8add0d0722ad630a140b6aefd504a5a895cbd867cbb00981afc50edd0398211e8d7c304bb8efa461181bc0afa67ea4a720a89ed"
|
||||
),
|
||||
"VeryLongMessage!" * 64,
|
||||
)
|
||||
assert ret is True
|
||||
def test_message_long(client):
|
||||
ret = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
|
||||
bytes.fromhex(
|
||||
"205ff795c29aef7538f8b3bdb2e8add0d0722ad630a140b6aefd504a5a895cbd867cbb00981afc50edd0398211e8d7c304bb8efa461181bc0afa67ea4a720a89ed"
|
||||
),
|
||||
"VeryLongMessage!" * 64,
|
||||
)
|
||||
assert ret is True
|
||||
|
||||
def test_message_testnet(self, client):
|
||||
ret = btc.verify_message(
|
||||
client,
|
||||
"Testnet",
|
||||
"mirio8q3gtv7fhdnmb3TpZ4EuafdzSs7zL",
|
||||
bytes.fromhex(
|
||||
"209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert ret is True
|
||||
|
||||
@pytest.mark.altcoin
|
||||
def test_message_grs(self, client):
|
||||
ret = btc.verify_message(
|
||||
client,
|
||||
"Groestlcoin",
|
||||
"Fj62rBJi8LvbmWu2jzkaUX1NFXLEqDLoZM",
|
||||
base64.b64decode(
|
||||
"INOYaa/jj8Yxz3mD5k+bZfUmjkjB9VzoV4dNG7+RsBUyK30xL7I9yMgWWVvsL46C5yQtxtZY0cRRk7q9N6b+YTM="
|
||||
),
|
||||
"test",
|
||||
)
|
||||
assert ret is True
|
||||
def test_message_testnet(client):
|
||||
ret = btc.verify_message(
|
||||
client,
|
||||
"Testnet",
|
||||
"mirio8q3gtv7fhdnmb3TpZ4EuafdzSs7zL",
|
||||
bytes.fromhex(
|
||||
"209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert ret is True
|
||||
|
||||
def test_message_verify(self, client):
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T",
|
||||
bytes.fromhex(
|
||||
"1ba77e01a9e17ba158b962cfef5f13dfed676ffc2b4bada24e58f784458b52b97421470d001d53d5880cf5e10e76f02be3e80bf21e18398cbd41e8c3b4af74c8c2"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is True
|
||||
|
||||
# uncompressed pubkey - FAIL - wrong sig
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T",
|
||||
bytes.fromhex(
|
||||
"1ba77e01a9e17ba158b962cfef5f13dfed676ffc2b4bada24e58f784458b52b97421470d001d53d5880cf5e10e76f02be3e80bf21e18398cbd41e8c3b4af74c800"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is False
|
||||
@pytest.mark.altcoin
|
||||
def test_message_grs(client):
|
||||
ret = btc.verify_message(
|
||||
client,
|
||||
"Groestlcoin",
|
||||
"Fj62rBJi8LvbmWu2jzkaUX1NFXLEqDLoZM",
|
||||
base64.b64decode(
|
||||
"INOYaa/jj8Yxz3mD5k+bZfUmjkjB9VzoV4dNG7+RsBUyK30xL7I9yMgWWVvsL46C5yQtxtZY0cRRk7q9N6b+YTM="
|
||||
),
|
||||
"test",
|
||||
)
|
||||
assert ret is True
|
||||
|
||||
# uncompressed pubkey - FAIL - wrong msg
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T",
|
||||
bytes.fromhex(
|
||||
"1ba77e01a9e17ba158b962cfef5f13dfed676ffc2b4bada24e58f784458b52b97421470d001d53d5880cf5e10e76f02be3e80bf21e18398cbd41e8c3b4af74c8c2"
|
||||
),
|
||||
"This is an example of a signed message!",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
# compressed pubkey - OK
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8",
|
||||
bytes.fromhex(
|
||||
"1f44e3e461f7ca9f57c472ce1a28214df1de1dadefb6551a32d1907b80c74d5a1fbfd6daaba12dd8cb06699ce3f6941fbe0f3957b5802d13076181046e741eaaaf"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is True
|
||||
def test_message_verify(client):
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T",
|
||||
bytes.fromhex(
|
||||
"1ba77e01a9e17ba158b962cfef5f13dfed676ffc2b4bada24e58f784458b52b97421470d001d53d5880cf5e10e76f02be3e80bf21e18398cbd41e8c3b4af74c8c2"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is True
|
||||
|
||||
# compressed pubkey - FAIL - wrong sig
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8",
|
||||
bytes.fromhex(
|
||||
"1f44e3e461f7ca9f57c472ce1a28214df1de1dadefb6551a32d1907b80c74d5a1fbfd6daaba12dd8cb06699ce3f6941fbe0f3957b5802d13076181046e741eaa00"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is False
|
||||
# uncompressed pubkey - FAIL - wrong sig
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T",
|
||||
bytes.fromhex(
|
||||
"1ba77e01a9e17ba158b962cfef5f13dfed676ffc2b4bada24e58f784458b52b97421470d001d53d5880cf5e10e76f02be3e80bf21e18398cbd41e8c3b4af74c800"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
# compressed pubkey - FAIL - wrong msg
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8",
|
||||
bytes.fromhex(
|
||||
"1f44e3e461f7ca9f57c472ce1a28214df1de1dadefb6551a32d1907b80c74d5a1fbfd6daaba12dd8cb06699ce3f6941fbe0f3957b5802d13076181046e741eaaaf"
|
||||
),
|
||||
"This is an example of a signed message!",
|
||||
)
|
||||
assert res is False
|
||||
# uncompressed pubkey - FAIL - wrong msg
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T",
|
||||
bytes.fromhex(
|
||||
"1ba77e01a9e17ba158b962cfef5f13dfed676ffc2b4bada24e58f784458b52b97421470d001d53d5880cf5e10e76f02be3e80bf21e18398cbd41e8c3b4af74c8c2"
|
||||
),
|
||||
"This is an example of a signed message!",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
# trezor pubkey - OK
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
|
||||
bytes.fromhex(
|
||||
"209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is True
|
||||
# compressed pubkey - OK
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8",
|
||||
bytes.fromhex(
|
||||
"1f44e3e461f7ca9f57c472ce1a28214df1de1dadefb6551a32d1907b80c74d5a1fbfd6daaba12dd8cb06699ce3f6941fbe0f3957b5802d13076181046e741eaaaf"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is True
|
||||
|
||||
# trezor pubkey - FAIL - wrong sig
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
|
||||
bytes.fromhex(
|
||||
"209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be00"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is False
|
||||
# compressed pubkey - FAIL - wrong sig
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8",
|
||||
bytes.fromhex(
|
||||
"1f44e3e461f7ca9f57c472ce1a28214df1de1dadefb6551a32d1907b80c74d5a1fbfd6daaba12dd8cb06699ce3f6941fbe0f3957b5802d13076181046e741eaa00"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
# trezor pubkey - FAIL - wrong msg
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
|
||||
bytes.fromhex(
|
||||
"209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message!",
|
||||
)
|
||||
assert res is False
|
||||
# compressed pubkey - FAIL - wrong msg
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8",
|
||||
bytes.fromhex(
|
||||
"1f44e3e461f7ca9f57c472ce1a28214df1de1dadefb6551a32d1907b80c74d5a1fbfd6daaba12dd8cb06699ce3f6941fbe0f3957b5802d13076181046e741eaaaf"
|
||||
),
|
||||
"This is an example of a signed message!",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
@pytest.mark.altcoin
|
||||
def test_message_verify_bcash(self, client):
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bcash",
|
||||
"bitcoincash:qqj22md58nm09vpwsw82fyletkxkq36zxyxh322pru",
|
||||
bytes.fromhex(
|
||||
"209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is True
|
||||
# trezor pubkey - OK
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
|
||||
bytes.fromhex(
|
||||
"209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is True
|
||||
|
||||
def test_verify_bitcoind(self, client):
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"1KzXE97kV7DrpxCViCN3HbGbiKhzzPM7TQ",
|
||||
bytes.fromhex(
|
||||
"1cc694f0f23901dfe3603789142f36a3fc582d0d5c0ec7215cf2ccd641e4e37228504f3d4dc3eea28bbdbf5da27c49d4635c097004d9f228750ccd836a8e1460c0"
|
||||
),
|
||||
u"\u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy",
|
||||
)
|
||||
# trezor pubkey - FAIL - wrong sig
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
|
||||
bytes.fromhex(
|
||||
"209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be00"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
assert res is True
|
||||
# trezor pubkey - FAIL - wrong msg
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
|
||||
bytes.fromhex(
|
||||
"209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message!",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
def test_verify_utf(self, client):
|
||||
words_nfkd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
|
||||
words_nfc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
|
||||
|
||||
res_nfkd = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
|
||||
bytes.fromhex(
|
||||
"20d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
),
|
||||
words_nfkd,
|
||||
)
|
||||
@pytest.mark.altcoin
|
||||
def test_message_verify_bcash(client):
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bcash",
|
||||
"bitcoincash:qqj22md58nm09vpwsw82fyletkxkq36zxyxh322pru",
|
||||
bytes.fromhex(
|
||||
"209e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is True
|
||||
|
||||
res_nfc = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
|
||||
bytes.fromhex(
|
||||
"20d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
),
|
||||
words_nfc,
|
||||
)
|
||||
|
||||
assert res_nfkd is True
|
||||
assert res_nfc is True
|
||||
def test_verify_bitcoind(client):
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"1KzXE97kV7DrpxCViCN3HbGbiKhzzPM7TQ",
|
||||
bytes.fromhex(
|
||||
"1cc694f0f23901dfe3603789142f36a3fc582d0d5c0ec7215cf2ccd641e4e37228504f3d4dc3eea28bbdbf5da27c49d4635c097004d9f228750ccd836a8e1460c0"
|
||||
),
|
||||
u"\u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy",
|
||||
)
|
||||
|
||||
assert res is True
|
||||
|
||||
|
||||
def test_verify_utf(client):
|
||||
words_nfkd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
|
||||
words_nfc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
|
||||
|
||||
res_nfkd = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
|
||||
bytes.fromhex(
|
||||
"20d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
),
|
||||
words_nfkd,
|
||||
)
|
||||
|
||||
res_nfc = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e",
|
||||
bytes.fromhex(
|
||||
"20d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
),
|
||||
words_nfc,
|
||||
)
|
||||
|
||||
assert res_nfkd is True
|
||||
assert res_nfc is True
|
||||
|
@ -17,90 +17,92 @@
|
||||
from trezorlib import btc
|
||||
|
||||
|
||||
class TestMsgVerifymessageSegwit:
|
||||
def test_message_long(self, client):
|
||||
ret = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
|
||||
bytes.fromhex(
|
||||
"245ff795c29aef7538f8b3bdb2e8add0d0722ad630a140b6aefd504a5a895cbd867cbb00981afc50edd0398211e8d7c304bb8efa461181bc0afa67ea4a720a89ed"
|
||||
),
|
||||
"VeryLongMessage!" * 64,
|
||||
)
|
||||
assert ret is True
|
||||
def test_message_long(client):
|
||||
ret = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
|
||||
bytes.fromhex(
|
||||
"245ff795c29aef7538f8b3bdb2e8add0d0722ad630a140b6aefd504a5a895cbd867cbb00981afc50edd0398211e8d7c304bb8efa461181bc0afa67ea4a720a89ed"
|
||||
),
|
||||
"VeryLongMessage!" * 64,
|
||||
)
|
||||
assert ret is True
|
||||
|
||||
def test_message_testnet(self, client):
|
||||
ret = btc.verify_message(
|
||||
client,
|
||||
"Testnet",
|
||||
"2N4VkePSzKH2sv5YBikLHGvzUYvfPxV6zS9",
|
||||
bytes.fromhex(
|
||||
"249e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert ret is True
|
||||
|
||||
def test_message_verify(self, client):
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
|
||||
bytes.fromhex(
|
||||
"249e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is True
|
||||
def test_message_testnet(client):
|
||||
ret = btc.verify_message(
|
||||
client,
|
||||
"Testnet",
|
||||
"2N4VkePSzKH2sv5YBikLHGvzUYvfPxV6zS9",
|
||||
bytes.fromhex(
|
||||
"249e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert ret is True
|
||||
|
||||
# trezor pubkey - FAIL - wrong sig
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
|
||||
bytes.fromhex(
|
||||
"249e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be00"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
# trezor pubkey - FAIL - wrong msg
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
|
||||
bytes.fromhex(
|
||||
"249e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message!",
|
||||
)
|
||||
assert res is False
|
||||
def test_message_verify(client):
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
|
||||
bytes.fromhex(
|
||||
"249e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is True
|
||||
|
||||
def test_verify_utf(self, client):
|
||||
words_nfkd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
|
||||
words_nfc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
|
||||
# trezor pubkey - FAIL - wrong sig
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
|
||||
bytes.fromhex(
|
||||
"249e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be00"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
res_nfkd = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
|
||||
bytes.fromhex(
|
||||
"24d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
),
|
||||
words_nfkd,
|
||||
)
|
||||
# trezor pubkey - FAIL - wrong msg
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
|
||||
bytes.fromhex(
|
||||
"249e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message!",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
res_nfc = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
|
||||
bytes.fromhex(
|
||||
"24d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
),
|
||||
words_nfc,
|
||||
)
|
||||
|
||||
assert res_nfkd is True
|
||||
assert res_nfc is True
|
||||
def test_verify_utf(client):
|
||||
words_nfkd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
|
||||
words_nfc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
|
||||
|
||||
res_nfkd = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
|
||||
bytes.fromhex(
|
||||
"24d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
),
|
||||
words_nfkd,
|
||||
)
|
||||
|
||||
res_nfc = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"3CwYaeWxhpXXiHue3ciQez1DLaTEAXcKa1",
|
||||
bytes.fromhex(
|
||||
"24d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
),
|
||||
words_nfc,
|
||||
)
|
||||
|
||||
assert res_nfkd is True
|
||||
assert res_nfc is True
|
||||
|
@ -17,90 +17,92 @@
|
||||
from trezorlib import btc
|
||||
|
||||
|
||||
class TestMsgVerifymessageSegwitNative:
|
||||
def test_message_long(self, client):
|
||||
ret = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
|
||||
bytes.fromhex(
|
||||
"285ff795c29aef7538f8b3bdb2e8add0d0722ad630a140b6aefd504a5a895cbd867cbb00981afc50edd0398211e8d7c304bb8efa461181bc0afa67ea4a720a89ed"
|
||||
),
|
||||
"VeryLongMessage!" * 64,
|
||||
)
|
||||
assert ret is True
|
||||
def test_message_long(client):
|
||||
ret = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
|
||||
bytes.fromhex(
|
||||
"285ff795c29aef7538f8b3bdb2e8add0d0722ad630a140b6aefd504a5a895cbd867cbb00981afc50edd0398211e8d7c304bb8efa461181bc0afa67ea4a720a89ed"
|
||||
),
|
||||
"VeryLongMessage!" * 64,
|
||||
)
|
||||
assert ret is True
|
||||
|
||||
def test_message_testnet(self, client):
|
||||
ret = btc.verify_message(
|
||||
client,
|
||||
"Testnet",
|
||||
"tb1qyjjkmdpu7metqt5r36jf872a34syws336p3n3p",
|
||||
bytes.fromhex(
|
||||
"289e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert ret is True
|
||||
|
||||
def test_message_verify(self, client):
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
|
||||
bytes.fromhex(
|
||||
"289e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is True
|
||||
def test_message_testnet(client):
|
||||
ret = btc.verify_message(
|
||||
client,
|
||||
"Testnet",
|
||||
"tb1qyjjkmdpu7metqt5r36jf872a34syws336p3n3p",
|
||||
bytes.fromhex(
|
||||
"289e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert ret is True
|
||||
|
||||
# trezor pubkey - FAIL - wrong sig
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
|
||||
bytes.fromhex(
|
||||
"289e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be00"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
# trezor pubkey - FAIL - wrong msg
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
|
||||
bytes.fromhex(
|
||||
"289e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message!",
|
||||
)
|
||||
assert res is False
|
||||
def test_message_verify(client):
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
|
||||
bytes.fromhex(
|
||||
"289e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is True
|
||||
|
||||
def test_verify_utf(self, client):
|
||||
words_nfkd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
|
||||
words_nfc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
|
||||
# trezor pubkey - FAIL - wrong sig
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
|
||||
bytes.fromhex(
|
||||
"289e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be00"
|
||||
),
|
||||
"This is an example of a signed message.",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
res_nfkd = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
|
||||
bytes.fromhex(
|
||||
"28d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
),
|
||||
words_nfkd,
|
||||
)
|
||||
# trezor pubkey - FAIL - wrong msg
|
||||
res = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
|
||||
bytes.fromhex(
|
||||
"289e23edf0e4e47ff1dec27f32cd78c50e74ef018ee8a6adf35ae17c7a9b0dd96f48b493fd7dbab03efb6f439c6383c9523b3bbc5f1a7d158a6af90ab154e9be80"
|
||||
),
|
||||
"This is an example of a signed message!",
|
||||
)
|
||||
assert res is False
|
||||
|
||||
res_nfc = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
|
||||
bytes.fromhex(
|
||||
"28d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
),
|
||||
words_nfc,
|
||||
)
|
||||
|
||||
assert res_nfkd is True
|
||||
assert res_nfc is True
|
||||
def test_verify_utf(client):
|
||||
words_nfkd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
|
||||
words_nfc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
|
||||
|
||||
res_nfkd = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
|
||||
bytes.fromhex(
|
||||
"28d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
),
|
||||
words_nfkd,
|
||||
)
|
||||
|
||||
res_nfc = btc.verify_message(
|
||||
client,
|
||||
"Bitcoin",
|
||||
"bc1qyjjkmdpu7metqt5r36jf872a34syws33s82q2j",
|
||||
bytes.fromhex(
|
||||
"28d0ec02ed8da8df23e7fe9e680e7867cc290312fe1c970749d8306ddad1a1eda41c6a771b13d495dd225b13b0a9d0f915a984ee3d0703f92287bf8009fbb9f7d6"
|
||||
),
|
||||
words_nfc,
|
||||
)
|
||||
|
||||
assert res_nfkd is True
|
||||
assert res_nfc is True
|
||||
|
@ -37,300 +37,301 @@ TXHASH_fbbff7 = bytes.fromhex(
|
||||
"fbbff7f3c85f8067453d7c062bd5efb8ad839953376ae5eceaf92774102c6e39"
|
||||
)
|
||||
|
||||
pytestmark = pytest.mark.multisig
|
||||
|
||||
class TestMultisig:
|
||||
@pytest.mark.multisig
|
||||
def test_2_of_3(self, client):
|
||||
nodes = [
|
||||
btc.get_public_node(client, parse_path(f"48'/0'/{index}'/0'")).node
|
||||
for index in range(1, 4)
|
||||
]
|
||||
|
||||
multisig = proto.MultisigRedeemScriptType(
|
||||
nodes=nodes, address_n=[0, 0], signatures=[b"", b"", b""], m=2
|
||||
def test_2_of_3(client):
|
||||
nodes = [
|
||||
btc.get_public_node(client, parse_path(f"48'/0'/{index}'/0'")).node
|
||||
for index in range(1, 4)
|
||||
]
|
||||
|
||||
multisig = proto.MultisigRedeemScriptType(
|
||||
nodes=nodes, address_n=[0, 0], signatures=[b"", b"", b""], m=2
|
||||
)
|
||||
# Let's go to sign with key 1
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("48'/0'/1'/0'/0/0"),
|
||||
amount=100000,
|
||||
prev_hash=TXHASH_c6091a,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
multisig=multisig,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="12iyMbUb4R2K3gre4dHSrbu5azG5KaqVss",
|
||||
amount=100000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_c6091a),
|
||||
request_input(0, TXHASH_c6091a),
|
||||
request_output(0, TXHASH_c6091a),
|
||||
request_output(1, TXHASH_c6091a),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
# Let's go to sign with key 1
|
||||
|
||||
# Now we have first signature
|
||||
signatures1, _ = btc.sign_tx(
|
||||
client, "Bitcoin", [inp1], [out1], prev_txes=TX_API
|
||||
)
|
||||
|
||||
assert (
|
||||
signatures1[0].hex()
|
||||
== "30450221009276eea820aa54a24bd9f1a056cb09a15f50c0816570a7c7878bd1c5ee7248540220677d200aec5e2f25bcf4000bdfab3faa9e1746d7f80c4ae4bfa1f5892eb5dcbf"
|
||||
)
|
||||
|
||||
# ---------------------------------------
|
||||
# Let's do second signature using 3rd key
|
||||
|
||||
multisig = proto.MultisigRedeemScriptType(
|
||||
nodes=nodes,
|
||||
address_n=[0, 0],
|
||||
signatures=[
|
||||
signatures1[0],
|
||||
b"",
|
||||
b"",
|
||||
], # Fill signature from previous signing process
|
||||
m=2,
|
||||
)
|
||||
|
||||
# Let's do a second signature with key 3
|
||||
inp3 = proto.TxInputType(
|
||||
address_n=parse_path("48'/0'/3'/0'/0/0"),
|
||||
amount=100000,
|
||||
prev_hash=TXHASH_c6091a,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
multisig=multisig,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_c6091a),
|
||||
request_input(0, TXHASH_c6091a),
|
||||
request_output(0, TXHASH_c6091a),
|
||||
request_output(1, TXHASH_c6091a),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
signatures2, serialized_tx = btc.sign_tx(
|
||||
client, "Bitcoin", [inp3], [out1], prev_txes=TX_API
|
||||
)
|
||||
|
||||
assert (
|
||||
signatures2[0].hex()
|
||||
== "3045022100c2a9fbfbff1be87036d8a6a22745512b158154f7f3d8f4cad4ba7ed130b37b83022058f5299b4c26222588dcc669399bd88b6f2bc6e04b48276373683853187a4fd6"
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "010000000152ba4dfcde9c4bed88f55479cdea03e711ae586e9a89352a98230c4cdf1a09c601000000fdfe00004830450221009276eea820aa54a24bd9f1a056cb09a15f50c0816570a7c7878bd1c5ee7248540220677d200aec5e2f25bcf4000bdfab3faa9e1746d7f80c4ae4bfa1f5892eb5dcbf01483045022100c2a9fbfbff1be87036d8a6a22745512b158154f7f3d8f4cad4ba7ed130b37b83022058f5299b4c26222588dcc669399bd88b6f2bc6e04b48276373683853187a4fd6014c69522103dc0ff15b9c85c0d2c87099758bf47d36229c2514aeefcf8dea123f0f93c679762102bfe426e8671601ad46d54d09ee15aa035610d36d411961c87474908d403fbc122102a5d57129c6c96df663ad29492aa18605dad97231e043be8a92f9406073815c5d53aeffffffff01a0860100000000001976a91412e8391ad256dcdc023365978418d658dfecba1c88ac00000000"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_15_of_15(client):
|
||||
node = btc.get_public_node(
|
||||
client, parse_path("48h/0h/1h/0h"), coin_name="Bitcoin"
|
||||
).node
|
||||
pubs = [proto.HDNodePathType(node=node, address_n=[0, 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("48'/0'/1'/0'/0/0"),
|
||||
amount=100000,
|
||||
prev_hash=TXHASH_c6091a,
|
||||
address_n=parse_path(f"48h/0h/1h/0h/0/{x}"),
|
||||
amount=20000,
|
||||
prev_hash=TXHASH_6189e3,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
multisig=multisig,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="12iyMbUb4R2K3gre4dHSrbu5azG5KaqVss",
|
||||
amount=100000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_c6091a),
|
||||
request_input(0, TXHASH_c6091a),
|
||||
request_output(0, TXHASH_c6091a),
|
||||
request_output(1, TXHASH_c6091a),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
|
||||
# Now we have first signature
|
||||
signatures1, _ = btc.sign_tx(
|
||||
sig, serialized_tx = btc.sign_tx(
|
||||
client, "Bitcoin", [inp1], [out1], prev_txes=TX_API
|
||||
)
|
||||
signatures[x] = sig[0]
|
||||
|
||||
assert (
|
||||
signatures1[0].hex()
|
||||
== "30450221009276eea820aa54a24bd9f1a056cb09a15f50c0816570a7c7878bd1c5ee7248540220677d200aec5e2f25bcf4000bdfab3faa9e1746d7f80c4ae4bfa1f5892eb5dcbf"
|
||||
)
|
||||
assert (
|
||||
tx_hash(serialized_tx).hex()
|
||||
== "63b16e3107df552c5c74bb5d91bb8fcd0069bac461fb42ebef982c5b2cfc4cf4"
|
||||
)
|
||||
|
||||
# ---------------------------------------
|
||||
# Let's do second signature using 3rd key
|
||||
|
||||
multisig = proto.MultisigRedeemScriptType(
|
||||
nodes=nodes,
|
||||
address_n=[0, 0],
|
||||
signatures=[
|
||||
signatures1[0],
|
||||
b"",
|
||||
b"",
|
||||
], # Fill signature from previous signing process
|
||||
m=2,
|
||||
)
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_missing_pubkey(client):
|
||||
node = btc.get_public_node(
|
||||
client, parse_path("48h/0h/1h/0h/0"), coin_name="Bitcoin"
|
||||
).node
|
||||
|
||||
# Let's do a second signature with key 3
|
||||
inp3 = proto.TxInputType(
|
||||
address_n=parse_path("48'/0'/3'/0'/0/0"),
|
||||
amount=100000,
|
||||
prev_hash=TXHASH_c6091a,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
multisig=multisig,
|
||||
)
|
||||
multisig = proto.MultisigRedeemScriptType(
|
||||
pubkeys=[
|
||||
proto.HDNodePathType(node=node, address_n=[1]),
|
||||
proto.HDNodePathType(node=node, address_n=[2]),
|
||||
proto.HDNodePathType(node=node, address_n=[3]),
|
||||
],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_c6091a),
|
||||
request_input(0, TXHASH_c6091a),
|
||||
request_output(0, TXHASH_c6091a),
|
||||
request_output(1, TXHASH_c6091a),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(0),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
signatures2, serialized_tx = btc.sign_tx(
|
||||
client, "Bitcoin", [inp3], [out1], prev_txes=TX_API
|
||||
)
|
||||
# Let's go to sign with key 10, which is NOT in pubkeys
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("48h/0h/1h/0h/0/10"),
|
||||
amount=100000,
|
||||
prev_hash=TXHASH_c6091a,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
multisig=multisig,
|
||||
)
|
||||
|
||||
assert (
|
||||
signatures2[0].hex()
|
||||
== "3045022100c2a9fbfbff1be87036d8a6a22745512b158154f7f3d8f4cad4ba7ed130b37b83022058f5299b4c26222588dcc669399bd88b6f2bc6e04b48276373683853187a4fd6"
|
||||
)
|
||||
out1 = proto.TxOutputType(
|
||||
address="12iyMbUb4R2K3gre4dHSrbu5azG5KaqVss",
|
||||
amount=100000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "010000000152ba4dfcde9c4bed88f55479cdea03e711ae586e9a89352a98230c4cdf1a09c601000000fdfe00004830450221009276eea820aa54a24bd9f1a056cb09a15f50c0816570a7c7878bd1c5ee7248540220677d200aec5e2f25bcf4000bdfab3faa9e1746d7f80c4ae4bfa1f5892eb5dcbf01483045022100c2a9fbfbff1be87036d8a6a22745512b158154f7f3d8f4cad4ba7ed130b37b83022058f5299b4c26222588dcc669399bd88b6f2bc6e04b48276373683853187a4fd6014c69522103dc0ff15b9c85c0d2c87099758bf47d36229c2514aeefcf8dea123f0f93c679762102bfe426e8671601ad46d54d09ee15aa035610d36d411961c87474908d403fbc122102a5d57129c6c96df663ad29492aa18605dad97231e043be8a92f9406073815c5d53aeffffffff01a0860100000000001976a91412e8391ad256dcdc023365978418d658dfecba1c88ac00000000"
|
||||
)
|
||||
with pytest.raises(TrezorFailure) as exc:
|
||||
btc.sign_tx(client, "Bitcoin", [inp1], [out1], prev_txes=TX_API)
|
||||
|
||||
@pytest.mark.multisig
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_15_of_15(self, client):
|
||||
node = btc.get_public_node(
|
||||
client, parse_path("48h/0h/1h/0h"), coin_name="Bitcoin"
|
||||
).node
|
||||
pubs = [proto.HDNodePathType(node=node, address_n=[0, x]) for x in range(15)]
|
||||
if client.features.model == "1":
|
||||
assert exc.value.message.endswith("Failed to derive scriptPubKey")
|
||||
else:
|
||||
assert exc.value.message.endswith("Pubkey not found in multisig script")
|
||||
|
||||
signatures = [b""] * 15
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="17kTB7qSk3MupQxWdiv5ZU3zcrZc2Azes1",
|
||||
amount=10000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
def test_attack_change_input(client):
|
||||
"""
|
||||
In Phases 1 and 2 the attacker replaces a non-multisig input
|
||||
`input_real` with a multisig input `input_fake`, which allows the
|
||||
attacker to provide a 1-of-2 multisig change address. When `input_real`
|
||||
is provided in the signing phase, an error must occur.
|
||||
"""
|
||||
address_n = parse_path("48'/1'/0'/1'/0/0")
|
||||
attacker_multisig_public_key = bytes.fromhex(
|
||||
"03653a148b68584acb97947344a7d4fd6a6f8b8485cad12987ff8edac874268088"
|
||||
)
|
||||
|
||||
for x in range(15):
|
||||
multisig = proto.MultisigRedeemScriptType(
|
||||
pubkeys=pubs, signatures=signatures, m=15
|
||||
)
|
||||
input_real = proto.TxInputType(
|
||||
address_n=address_n,
|
||||
prev_hash=TXHASH_fbbff7,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
amount=1000000,
|
||||
)
|
||||
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path(f"48h/0h/1h/0h/0/{x}"),
|
||||
amount=20000,
|
||||
prev_hash=TXHASH_6189e3,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
multisig=multisig,
|
||||
)
|
||||
multisig_fake = proto.MultisigRedeemScriptType(
|
||||
m=1,
|
||||
nodes=[
|
||||
btc.get_public_node(client, address_n, coin_name="Testnet").node,
|
||||
proto.HDNodeType(
|
||||
depth=0,
|
||||
fingerprint=0,
|
||||
child_num=0,
|
||||
chain_code=bytes(32),
|
||||
public_key=attacker_multisig_public_key,
|
||||
),
|
||||
],
|
||||
address_n=[],
|
||||
)
|
||||
|
||||
with client:
|
||||
sig, serialized_tx = btc.sign_tx(
|
||||
client, "Bitcoin", [inp1], [out1], prev_txes=TX_API
|
||||
)
|
||||
signatures[x] = sig[0]
|
||||
input_fake = proto.TxInputType(
|
||||
address_n=address_n,
|
||||
prev_hash=input_real.prev_hash,
|
||||
prev_index=input_real.prev_index,
|
||||
script_type=input_real.script_type,
|
||||
multisig=multisig_fake,
|
||||
amount=input_real.amount,
|
||||
)
|
||||
|
||||
assert (
|
||||
tx_hash(serialized_tx).hex()
|
||||
== "63b16e3107df552c5c74bb5d91bb8fcd0069bac461fb42ebef982c5b2cfc4cf4"
|
||||
)
|
||||
output_payee = proto.TxOutputType(
|
||||
address="n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi",
|
||||
amount=1000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
@pytest.mark.multisig
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_missing_pubkey(self, client):
|
||||
node = btc.get_public_node(
|
||||
client, parse_path("48h/0h/1h/0h/0"), coin_name="Bitcoin"
|
||||
).node
|
||||
output_change = proto.TxOutputType(
|
||||
address_n=address_n,
|
||||
amount=input_real.amount - output_payee.amount - 1000,
|
||||
script_type=proto.OutputScriptType.PAYTOP2SHWITNESS,
|
||||
multisig=multisig_fake,
|
||||
)
|
||||
|
||||
multisig = proto.MultisigRedeemScriptType(
|
||||
pubkeys=[
|
||||
proto.HDNodePathType(node=node, address_n=[1]),
|
||||
proto.HDNodePathType(node=node, address_n=[2]),
|
||||
proto.HDNodePathType(node=node, address_n=[3]),
|
||||
],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
attack_count = 3
|
||||
|
||||
# Let's go to sign with key 10, which is NOT in pubkeys
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("48h/0h/1h/0h/0/10"),
|
||||
amount=100000,
|
||||
prev_hash=TXHASH_c6091a,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
multisig=multisig,
|
||||
)
|
||||
def attack_processor(msg):
|
||||
nonlocal attack_count
|
||||
# replace the first input_real with input_fake
|
||||
if attack_count > 0 and msg.tx.inputs and msg.tx.inputs[0] == input_real:
|
||||
msg.tx.inputs[0] = input_fake
|
||||
attack_count -= 1
|
||||
return msg
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="12iyMbUb4R2K3gre4dHSrbu5azG5KaqVss",
|
||||
amount=100000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
with client:
|
||||
client.set_filter(proto.TxAck, attack_processor)
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_fbbff7),
|
||||
request_input(0, TXHASH_fbbff7),
|
||||
request_output(0, TXHASH_fbbff7),
|
||||
request_output(1, TXHASH_fbbff7),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
request_input(0),
|
||||
proto.Failure(code=proto.FailureType.ProcessError),
|
||||
]
|
||||
)
|
||||
|
||||
with pytest.raises(TrezorFailure) as exc:
|
||||
btc.sign_tx(client, "Bitcoin", [inp1], [out1], prev_txes=TX_API)
|
||||
|
||||
if client.features.model == "1":
|
||||
assert exc.value.message.endswith("Failed to derive scriptPubKey")
|
||||
else:
|
||||
assert exc.value.message.endswith("Pubkey not found in multisig script")
|
||||
|
||||
def test_attack_change_input(self, client):
|
||||
"""
|
||||
In Phases 1 and 2 the attacker replaces a non-multisig input
|
||||
`input_real` with a multisig input `input_fake`, which allows the
|
||||
attacker to provide a 1-of-2 multisig change address. When `input_real`
|
||||
is provided in the signing phase, an error must occur.
|
||||
"""
|
||||
address_n = parse_path("48'/1'/0'/1'/0/0")
|
||||
attacker_multisig_public_key = bytes.fromhex(
|
||||
"03653a148b68584acb97947344a7d4fd6a6f8b8485cad12987ff8edac874268088"
|
||||
)
|
||||
|
||||
input_real = proto.TxInputType(
|
||||
address_n=address_n,
|
||||
prev_hash=TXHASH_fbbff7,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDP2SHWITNESS,
|
||||
amount=1000000,
|
||||
)
|
||||
|
||||
multisig_fake = proto.MultisigRedeemScriptType(
|
||||
m=1,
|
||||
nodes=[
|
||||
btc.get_public_node(client, address_n, coin_name="Testnet").node,
|
||||
proto.HDNodeType(
|
||||
depth=0,
|
||||
fingerprint=0,
|
||||
child_num=0,
|
||||
chain_code=bytes(32),
|
||||
public_key=attacker_multisig_public_key,
|
||||
),
|
||||
],
|
||||
address_n=[],
|
||||
)
|
||||
|
||||
input_fake = proto.TxInputType(
|
||||
address_n=address_n,
|
||||
prev_hash=input_real.prev_hash,
|
||||
prev_index=input_real.prev_index,
|
||||
script_type=input_real.script_type,
|
||||
multisig=multisig_fake,
|
||||
amount=input_real.amount,
|
||||
)
|
||||
|
||||
output_payee = proto.TxOutputType(
|
||||
address="n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi",
|
||||
amount=1000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
output_change = proto.TxOutputType(
|
||||
address_n=address_n,
|
||||
amount=input_real.amount - output_payee.amount - 1000,
|
||||
script_type=proto.OutputScriptType.PAYTOP2SHWITNESS,
|
||||
multisig=multisig_fake,
|
||||
)
|
||||
|
||||
attack_count = 3
|
||||
|
||||
def attack_processor(msg):
|
||||
nonlocal attack_count
|
||||
# replace the first input_real with input_fake
|
||||
if attack_count > 0 and msg.tx.inputs and msg.tx.inputs[0] == input_real:
|
||||
msg.tx.inputs[0] = input_fake
|
||||
attack_count -= 1
|
||||
return msg
|
||||
|
||||
with client:
|
||||
client.set_filter(proto.TxAck, attack_processor)
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_fbbff7),
|
||||
request_input(0, TXHASH_fbbff7),
|
||||
request_output(0, TXHASH_fbbff7),
|
||||
request_output(1, TXHASH_fbbff7),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
request_input(0),
|
||||
proto.Failure(code=proto.FailureType.ProcessError),
|
||||
]
|
||||
btc.sign_tx(
|
||||
client,
|
||||
"Testnet",
|
||||
[input_real],
|
||||
[output_payee, output_change],
|
||||
prev_txes=TxCache("Testnet"),
|
||||
)
|
||||
# must not produce this tx:
|
||||
# 01000000000101396e2c107427f9eaece56a37539983adb8efd52b067c3d4567805fc8f3f7bffb01000000171600147a876a07b366f79000b441335f2907f777a0280bffffffff02e8030000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac703a0f000000000017a914a1261837f1b40e84346b1504ffe294e402965f2687024830450221009ff835e861be4e36ca1f2b6224aee2f253dfb9f456b13e4b1724bb4aaff4c9c802205e10679c2ead85743119f468cba5661f68b7da84dd2d477a7215fef98516f1f9012102af12ddd0d55e4fa2fcd084148eaf5b0b641320d0431d63d1e9a90f3cbd0d540700000000
|
||||
|
||||
with pytest.raises(TrezorFailure) as exc:
|
||||
btc.sign_tx(
|
||||
client,
|
||||
"Testnet",
|
||||
[input_real],
|
||||
[output_payee, output_change],
|
||||
prev_txes=TxCache("Testnet"),
|
||||
)
|
||||
# must not produce this tx:
|
||||
# 01000000000101396e2c107427f9eaece56a37539983adb8efd52b067c3d4567805fc8f3f7bffb01000000171600147a876a07b366f79000b441335f2907f777a0280bffffffff02e8030000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac703a0f000000000017a914a1261837f1b40e84346b1504ffe294e402965f2687024830450221009ff835e861be4e36ca1f2b6224aee2f253dfb9f456b13e4b1724bb4aaff4c9c802205e10679c2ead85743119f468cba5661f68b7da84dd2d477a7215fef98516f1f9012102af12ddd0d55e4fa2fcd084148eaf5b0b641320d0431d63d1e9a90f3cbd0d540700000000
|
||||
|
||||
assert exc.value.code == proto.FailureType.ProcessError
|
||||
assert exc.value.message.endswith("Transaction has changed during signing")
|
||||
assert exc.value.code == proto.FailureType.ProcessError
|
||||
assert exc.value.message.endswith("Transaction has changed during signing")
|
||||
|
@ -40,422 +40,415 @@ TXHASH_b0946d = bytes.fromhex(
|
||||
"b0946dc27ba308a749b11afecc2018980af18f79e89ad6b080b58220d856f739"
|
||||
)
|
||||
|
||||
pytestmark = [pytest.mark.multisig, pytest.mark.setup_client(mnemonic=MNEMONIC12)]
|
||||
|
||||
class TestMultisigChange:
|
||||
node_ext1 = bip32.deserialize(
|
||||
"xpub69qexv5TppjJQtXwSGeGXNtgGWyUzvsHACMt4Rr61Be4CmCf55eFcuXX828aySNuNR7hQYUCvUgZpioNxfs2HTAZWUUSFywhErg7JfTPv3Y"
|
||||
|
||||
NODE_EXT1 = bip32.deserialize(
|
||||
"xpub69qexv5TppjJQtXwSGeGXNtgGWyUzvsHACMt4Rr61Be4CmCf55eFcuXX828aySNuNR7hQYUCvUgZpioNxfs2HTAZWUUSFywhErg7JfTPv3Y"
|
||||
)
|
||||
# m/1 => 02c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e
|
||||
# m/2 => 0375b9dfaad928ce1a7eed88df7c084e67d99e9ab74332419458a9a45779706801
|
||||
|
||||
NODE_EXT2 = bip32.deserialize(
|
||||
"xpub69qexv5TppjJRiLLK2K1FZNCFcErkXprCo3jabCXMiqX5CFF4LHedwcXvXkTuBL9tFLWVxuGWrdeerXjiWpC1gynTNUaySDsr8SU5xMpj5R"
|
||||
)
|
||||
# m/1 => 0388460dc439f4c8f5bcfc268c36e11b4375cad5c3535c336cfdf8c32c3afad5c1
|
||||
# m/2 => 03a04f945d5a3685729dde697d574076de4bdf38e904f813b22a851548e1110fc0
|
||||
|
||||
NODE_EXT3 = bip32.deserialize(
|
||||
"xpub69qexv5TppjJVYtxFKSBFxcVGyaC8VJDa1RugAYwEDLVUBuaXrVgznvQB44piM8MRerfVf1pNCBK1L1NzhyKd4Ay25BVZX3S8twWfZDxmz7"
|
||||
)
|
||||
# m/1 => 02e0c21e2a7cf00b94c5421725acff97f9826598b91f2340c5ddda730caca7d648
|
||||
# m/2 => 03928301ffb8c0d7a364b794914c716ba3107cc78a6fe581028b0d8638b22e8573
|
||||
|
||||
NODE_INT = bip32.deserialize(
|
||||
"xpub69qexv5TppjJNEK5bfX8vQ6ASXDUQ5PohSajrHgeknHZ4SJipn7edmpRmiiBLLDtPur71mekZFazhgas8rkUMnS7quk5qp64TLLV8ShrxZJ"
|
||||
)
|
||||
# m/1 => 03f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff35
|
||||
# m/2 => 038caebd6f753bbbd2bb1f3346a43cd32140648583673a31d62f2dfb56ad0ab9e3
|
||||
|
||||
# ext1 + ext2 + int
|
||||
# redeemscript (2 of 3): 522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e210388460dc439f4c8f5bcfc268c36e11b4375cad5c3535c336cfdf8c32c3afad5c1210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a653ae
|
||||
# multisig address: 2N9W4z9AhAPaHghtqVQPbaTAGHdbrhKeBQw
|
||||
# tx: 16c6c8471b8db7a628f2b2bb86bfeefae1766463ce8692438c7fd3fce3f43ce5
|
||||
# input 0: 0.5 BTC
|
||||
|
||||
# ext1 + int + ext2
|
||||
# redeemscript (2 of 3): 522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6210388460dc439f4c8f5bcfc268c36e11b4375cad5c3535c336cfdf8c32c3afad5c153ae
|
||||
# multisig address: 2NDBG6QXQLtnQ3jRGkrqo53BiCeXfQXLdj4
|
||||
# tx: d80c34ee14143a8bf61125102b7ef594118a3796cad670fa8ee15080ae155318
|
||||
# input 0: 0.345 BTC
|
||||
|
||||
# ext1 + ext3 + int
|
||||
# redeemscript (2 of 3): 522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e2102e0c21e2a7cf00b94c5421725acff97f9826598b91f2340c5ddda730caca7d648210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a653ae
|
||||
# multisig address: 2MvwPWfp2XPU3S1cMwgEMKBPUw38VP5SBE4
|
||||
# tx: b0946dc27ba308a749b11afecc2018980af18f79e89ad6b080b58220d856f739
|
||||
# input 1: 0.555 BTC
|
||||
|
||||
multisig_in1 = proto.MultisigRedeemScriptType(
|
||||
nodes=[NODE_EXT2, NODE_EXT1, NODE_INT],
|
||||
address_n=[0, 0],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
multisig_in2 = proto.MultisigRedeemScriptType(
|
||||
nodes=[NODE_EXT1, NODE_EXT2, NODE_INT],
|
||||
address_n=[0, 1],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
multisig_in3 = proto.MultisigRedeemScriptType(
|
||||
nodes=[NODE_EXT1, NODE_EXT3, NODE_INT],
|
||||
address_n=[0, 1],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
# 2N9W4z9AhAPaHghtqVQPbaTAGHdbrhKeBQw
|
||||
INP1 = proto.TxInputType(
|
||||
address_n=[H_(45), 0, 0, 0],
|
||||
amount=50000000,
|
||||
prev_hash=TXHASH_16c6c8,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
multisig=multisig_in1,
|
||||
)
|
||||
|
||||
# 2NDBG6QXQLtnQ3jRGkrqo53BiCeXfQXLdj4
|
||||
INP2 = proto.TxInputType(
|
||||
address_n=[H_(45), 0, 0, 1],
|
||||
amount=34500000,
|
||||
prev_hash=TXHASH_d80c34,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
multisig=multisig_in2,
|
||||
)
|
||||
|
||||
# 2MvwPWfp2XPU3S1cMwgEMKBPUw38VP5SBE4
|
||||
INP3 = proto.TxInputType(
|
||||
address_n=[H_(45), 0, 0, 1],
|
||||
amount=55500000,
|
||||
prev_hash=TXHASH_b0946d,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
multisig=multisig_in3,
|
||||
)
|
||||
|
||||
def _responses(INP1, INP2, change=0):
|
||||
resp = [
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
]
|
||||
if change != 1:
|
||||
resp.append(proto.ButtonRequest(code=B.ConfirmOutput))
|
||||
resp.append(request_output(1))
|
||||
if change != 2:
|
||||
resp.append(proto.ButtonRequest(code=B.ConfirmOutput))
|
||||
resp += [
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(INP1.prev_hash),
|
||||
request_input(0, INP1.prev_hash),
|
||||
request_output(0, INP1.prev_hash),
|
||||
request_output(1, INP1.prev_hash),
|
||||
request_input(1),
|
||||
request_meta(INP2.prev_hash),
|
||||
request_input(0, INP2.prev_hash),
|
||||
request_output(0, INP2.prev_hash),
|
||||
request_output(1, INP2.prev_hash),
|
||||
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(),
|
||||
]
|
||||
return resp
|
||||
|
||||
|
||||
# both outputs are external
|
||||
def test_external_external(client):
|
||||
out1 = proto.TxOutputType(
|
||||
address="1F8yBZB2NZhPZvJekhjTwjhQRRvQeTjjXr",
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
# m/1 => 02c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e
|
||||
# m/2 => 0375b9dfaad928ce1a7eed88df7c084e67d99e9ab74332419458a9a45779706801
|
||||
|
||||
node_ext2 = bip32.deserialize(
|
||||
"xpub69qexv5TppjJRiLLK2K1FZNCFcErkXprCo3jabCXMiqX5CFF4LHedwcXvXkTuBL9tFLWVxuGWrdeerXjiWpC1gynTNUaySDsr8SU5xMpj5R"
|
||||
out2 = proto.TxOutputType(
|
||||
address="1H7uXJQTVwXca2BXF2opTrvuZapk8Cm8zY",
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
# m/1 => 0388460dc439f4c8f5bcfc268c36e11b4375cad5c3535c336cfdf8c32c3afad5c1
|
||||
# m/2 => 03a04f945d5a3685729dde697d574076de4bdf38e904f813b22a851548e1110fc0
|
||||
|
||||
node_ext3 = bip32.deserialize(
|
||||
"xpub69qexv5TppjJVYtxFKSBFxcVGyaC8VJDa1RugAYwEDLVUBuaXrVgznvQB44piM8MRerfVf1pNCBK1L1NzhyKd4Ay25BVZX3S8twWfZDxmz7"
|
||||
with client:
|
||||
client.set_expected_responses(_responses(INP1, INP2))
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Bitcoin",
|
||||
[INP1, INP2],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022064f13801744a6c21b694f62cdb5d834e852f13ecf85ed4d0a56ba279571c24e3022010fab4cb05bdd7b24c8376dda4f62a418548eea6eb483e58675fa06e0d5c642c014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b4004730440220727b2522268f913acd213c507d7801b146e5b6cef666ad44b769c26d6c762e4d022021c0c2e9e8298dee2a490d956f7ab1b2d3160c1e37a50cc6d19a5e62eb484fc9014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a6202000000001976a9149b139230e4fe91c05a37ec334dc8378f3dbe377088ac00639f02000000001976a914b0d05a10926a7925508febdbab9a5bd4cda8c8f688ac00000000"
|
||||
)
|
||||
# m/1 => 02e0c21e2a7cf00b94c5421725acff97f9826598b91f2340c5ddda730caca7d648
|
||||
# m/2 => 03928301ffb8c0d7a364b794914c716ba3107cc78a6fe581028b0d8638b22e8573
|
||||
|
||||
node_int = bip32.deserialize(
|
||||
"xpub69qexv5TppjJNEK5bfX8vQ6ASXDUQ5PohSajrHgeknHZ4SJipn7edmpRmiiBLLDtPur71mekZFazhgas8rkUMnS7quk5qp64TLLV8ShrxZJ"
|
||||
|
||||
# first external, second internal
|
||||
def test_external_internal(client):
|
||||
out1 = proto.TxOutputType(
|
||||
address="1F8yBZB2NZhPZvJekhjTwjhQRRvQeTjjXr",
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
# m/1 => 03f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff35
|
||||
# m/2 => 038caebd6f753bbbd2bb1f3346a43cd32140648583673a31d62f2dfb56ad0ab9e3
|
||||
|
||||
# ext1 + ext2 + int
|
||||
# redeemscript (2 of 3): 522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e210388460dc439f4c8f5bcfc268c36e11b4375cad5c3535c336cfdf8c32c3afad5c1210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a653ae
|
||||
# multisig address: 2N9W4z9AhAPaHghtqVQPbaTAGHdbrhKeBQw
|
||||
# tx: 16c6c8471b8db7a628f2b2bb86bfeefae1766463ce8692438c7fd3fce3f43ce5
|
||||
# input 0: 0.5 BTC
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=parse_path("45'/0/1/1"),
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
# ext1 + int + ext2
|
||||
# redeemscript (2 of 3): 522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6210388460dc439f4c8f5bcfc268c36e11b4375cad5c3535c336cfdf8c32c3afad5c153ae
|
||||
# multisig address: 2NDBG6QXQLtnQ3jRGkrqo53BiCeXfQXLdj4
|
||||
# tx: d80c34ee14143a8bf61125102b7ef594118a3796cad670fa8ee15080ae155318
|
||||
# input 0: 0.345 BTC
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
_responses(INP1, INP2, change=2)
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Bitcoin",
|
||||
[INP1, INP2],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
# ext1 + ext3 + int
|
||||
# redeemscript (2 of 3): 522102c0d0c5fee952620757c6128dbf327c996cd72ed3358d15d6518a1186099bc15e2102e0c21e2a7cf00b94c5421725acff97f9826598b91f2340c5ddda730caca7d648210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a653ae
|
||||
# multisig address: 2MvwPWfp2XPU3S1cMwgEMKBPUw38VP5SBE4
|
||||
# tx: b0946dc27ba308a749b11afecc2018980af18f79e89ad6b080b58220d856f739
|
||||
# input 1: 0.555 BTC
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022064f13801744a6c21b694f62cdb5d834e852f13ecf85ed4d0a56ba279571c24e3022010fab4cb05bdd7b24c8376dda4f62a418548eea6eb483e58675fa06e0d5c642c014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b4004730440220727b2522268f913acd213c507d7801b146e5b6cef666ad44b769c26d6c762e4d022021c0c2e9e8298dee2a490d956f7ab1b2d3160c1e37a50cc6d19a5e62eb484fc9014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a6202000000001976a9149b139230e4fe91c05a37ec334dc8378f3dbe377088ac00639f02000000001976a914b0d05a10926a7925508febdbab9a5bd4cda8c8f688ac00000000"
|
||||
)
|
||||
|
||||
multisig_in1 = proto.MultisigRedeemScriptType(
|
||||
nodes=[node_ext2, node_ext1, node_int],
|
||||
address_n=[0, 0],
|
||||
|
||||
# first internal, second external
|
||||
def test_internal_external(client):
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=parse_path("45'/0/1/0"),
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address="1H7uXJQTVwXca2BXF2opTrvuZapk8Cm8zY",
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
_responses(INP1, INP2, change=1)
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Bitcoin",
|
||||
[INP1, INP2],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022064f13801744a6c21b694f62cdb5d834e852f13ecf85ed4d0a56ba279571c24e3022010fab4cb05bdd7b24c8376dda4f62a418548eea6eb483e58675fa06e0d5c642c014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b4004730440220727b2522268f913acd213c507d7801b146e5b6cef666ad44b769c26d6c762e4d022021c0c2e9e8298dee2a490d956f7ab1b2d3160c1e37a50cc6d19a5e62eb484fc9014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a6202000000001976a9149b139230e4fe91c05a37ec334dc8378f3dbe377088ac00639f02000000001976a914b0d05a10926a7925508febdbab9a5bd4cda8c8f688ac00000000"
|
||||
)
|
||||
|
||||
|
||||
# both outputs are external
|
||||
def test_multisig_external_external(client):
|
||||
out1 = proto.TxOutputType(
|
||||
address="3B23k4kFBRtu49zvpG3Z9xuFzfpHvxBcwt",
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address="3PkXLsY7AUZCrCKGvX8FfP2EawowUBMbcg",
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(_responses(INP1, INP2))
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Bitcoin",
|
||||
[INP1, INP2],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022059394e0dfcb2d2f4a6108703f801545ca5a820c0ac6a1859d0a3854813de55fa02207b6a57d70b82932ff58163336c461653a2dc82c78ed8157159e5178ac7325390014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b40047304402205a911685f5b974b2fc4a19d5ce056218773a4d20b5eaae2c2f9594929308182002201e03449f5a8813ec19f408bf1b6f4f334886d6fcf9920e300fd7678ef0724f81014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000"
|
||||
)
|
||||
|
||||
|
||||
# inputs match, change matches (first is change)
|
||||
def test_multisig_change_match_first(client):
|
||||
multisig_out1 = proto.MultisigRedeemScriptType(
|
||||
nodes=[NODE_EXT2, NODE_EXT1, NODE_INT],
|
||||
address_n=[1, 0],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
multisig_in2 = proto.MultisigRedeemScriptType(
|
||||
nodes=[node_ext1, node_ext2, node_int],
|
||||
address_n=[0, 1],
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=[H_(45), 0, 1, 0],
|
||||
multisig=multisig_out1,
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address="3PkXLsY7AUZCrCKGvX8FfP2EawowUBMbcg",
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
_responses(INP1, INP2, change=1)
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Bitcoin",
|
||||
[INP1, INP2],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022059394e0dfcb2d2f4a6108703f801545ca5a820c0ac6a1859d0a3854813de55fa02207b6a57d70b82932ff58163336c461653a2dc82c78ed8157159e5178ac7325390014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b40047304402205a911685f5b974b2fc4a19d5ce056218773a4d20b5eaae2c2f9594929308182002201e03449f5a8813ec19f408bf1b6f4f334886d6fcf9920e300fd7678ef0724f81014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000"
|
||||
)
|
||||
|
||||
|
||||
# inputs match, change matches (second is change)
|
||||
def test_multisig_change_match_second(client):
|
||||
multisig_out2 = proto.MultisigRedeemScriptType(
|
||||
nodes=[NODE_EXT1, NODE_EXT2, NODE_INT],
|
||||
address_n=[1, 1],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
multisig_in3 = proto.MultisigRedeemScriptType(
|
||||
nodes=[node_ext1, node_ext3, node_int],
|
||||
address_n=[0, 1],
|
||||
out1 = proto.TxOutputType(
|
||||
address="3B23k4kFBRtu49zvpG3Z9xuFzfpHvxBcwt",
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=[H_(45), 0, 1, 1],
|
||||
multisig=multisig_out2,
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
_responses(INP1, INP2, change=2)
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Bitcoin",
|
||||
[INP1, INP2],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022059394e0dfcb2d2f4a6108703f801545ca5a820c0ac6a1859d0a3854813de55fa02207b6a57d70b82932ff58163336c461653a2dc82c78ed8157159e5178ac7325390014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b40047304402205a911685f5b974b2fc4a19d5ce056218773a4d20b5eaae2c2f9594929308182002201e03449f5a8813ec19f408bf1b6f4f334886d6fcf9920e300fd7678ef0724f81014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000"
|
||||
)
|
||||
|
||||
|
||||
# inputs match, change mismatches (second tries to be change but isn't)
|
||||
def test_multisig_mismatch_change(client):
|
||||
multisig_out2 = proto.MultisigRedeemScriptType(
|
||||
nodes=[NODE_EXT1, NODE_INT, NODE_EXT3],
|
||||
address_n=[1, 0],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
# 2N9W4z9AhAPaHghtqVQPbaTAGHdbrhKeBQw
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=[H_(45), 0, 0, 0],
|
||||
amount=50000000,
|
||||
prev_hash=TXHASH_16c6c8,
|
||||
prev_index=1,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
multisig=multisig_in1,
|
||||
out1 = proto.TxOutputType(
|
||||
address="3B23k4kFBRtu49zvpG3Z9xuFzfpHvxBcwt",
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
# 2NDBG6QXQLtnQ3jRGkrqo53BiCeXfQXLdj4
|
||||
inp2 = proto.TxInputType(
|
||||
address_n=[H_(45), 0, 0, 1],
|
||||
amount=34500000,
|
||||
prev_hash=TXHASH_d80c34,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
multisig=multisig_in2,
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=[H_(45), 0, 1, 0],
|
||||
multisig=multisig_out2,
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
)
|
||||
|
||||
# 2MvwPWfp2XPU3S1cMwgEMKBPUw38VP5SBE4
|
||||
inp3 = proto.TxInputType(
|
||||
address_n=[H_(45), 0, 0, 1],
|
||||
amount=55500000,
|
||||
prev_hash=TXHASH_b0946d,
|
||||
prev_index=0,
|
||||
script_type=proto.InputScriptType.SPENDMULTISIG,
|
||||
multisig=multisig_in3,
|
||||
with client:
|
||||
client.set_expected_responses(_responses(INP1, INP2))
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Bitcoin",
|
||||
[INP1, INP2],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b40047304402207f9992cc0230527faf54ec6bd233307db82bc8fac039dcee418bc6feb4e96a3a02206bb4cb157ad27c123277328a877572563a45d70b844d9ab07cc42238112f8c2a014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b400473044022078a41bfa87d72d6ba810d84bf568b5a29acf8b851ba6c3a8dbff079b34a7feb0022037b770c776db0b6c883c38a684a121b90a59ed1958774cbf64de70e53e29639f014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914e6a3e2fbadb7f559f8d20c46aceae78c96fcf1d18700000000"
|
||||
)
|
||||
|
||||
def _responses(self, inp1, inp2, change=0):
|
||||
resp = [
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
request_output(0),
|
||||
]
|
||||
if change != 1:
|
||||
resp.append(proto.ButtonRequest(code=B.ConfirmOutput))
|
||||
resp.append(request_output(1))
|
||||
if change != 2:
|
||||
resp.append(proto.ButtonRequest(code=B.ConfirmOutput))
|
||||
resp += [
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(inp1.prev_hash),
|
||||
request_input(0, inp1.prev_hash),
|
||||
request_output(0, inp1.prev_hash),
|
||||
request_output(1, inp1.prev_hash),
|
||||
request_input(1),
|
||||
request_meta(inp2.prev_hash),
|
||||
request_input(0, inp2.prev_hash),
|
||||
request_output(0, inp2.prev_hash),
|
||||
request_output(1, inp2.prev_hash),
|
||||
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(),
|
||||
]
|
||||
return resp
|
||||
|
||||
# both outputs are external
|
||||
@pytest.mark.multisig
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_external_external(self, client):
|
||||
out1 = proto.TxOutputType(
|
||||
address="1F8yBZB2NZhPZvJekhjTwjhQRRvQeTjjXr",
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
# inputs mismatch, change matches with first input
|
||||
def test_multisig_mismatch_inputs(client):
|
||||
multisig_out1 = proto.MultisigRedeemScriptType(
|
||||
nodes=[NODE_EXT2, NODE_EXT1, NODE_INT],
|
||||
address_n=[1, 0],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=[H_(45), 0, 1, 0],
|
||||
multisig=multisig_out1,
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address="3PkXLsY7AUZCrCKGvX8FfP2EawowUBMbcg",
|
||||
amount=65000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(_responses(INP1, INP3))
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Bitcoin",
|
||||
[INP1, INP3],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address="1H7uXJQTVwXca2BXF2opTrvuZapk8Cm8zY",
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(self._responses(self.inp1, self.inp2))
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Bitcoin",
|
||||
[self.inp1, self.inp2],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022064f13801744a6c21b694f62cdb5d834e852f13ecf85ed4d0a56ba279571c24e3022010fab4cb05bdd7b24c8376dda4f62a418548eea6eb483e58675fa06e0d5c642c014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b4004730440220727b2522268f913acd213c507d7801b146e5b6cef666ad44b769c26d6c762e4d022021c0c2e9e8298dee2a490d956f7ab1b2d3160c1e37a50cc6d19a5e62eb484fc9014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a6202000000001976a9149b139230e4fe91c05a37ec334dc8378f3dbe377088ac00639f02000000001976a914b0d05a10926a7925508febdbab9a5bd4cda8c8f688ac00000000"
|
||||
)
|
||||
|
||||
# first external, second internal
|
||||
@pytest.mark.multisig
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_external_internal(self, client):
|
||||
out1 = proto.TxOutputType(
|
||||
address="1F8yBZB2NZhPZvJekhjTwjhQRRvQeTjjXr",
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=parse_path("45'/0/1/1"),
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
self._responses(self.inp1, self.inp2, change=2)
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Bitcoin",
|
||||
[self.inp1, self.inp2],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022064f13801744a6c21b694f62cdb5d834e852f13ecf85ed4d0a56ba279571c24e3022010fab4cb05bdd7b24c8376dda4f62a418548eea6eb483e58675fa06e0d5c642c014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b4004730440220727b2522268f913acd213c507d7801b146e5b6cef666ad44b769c26d6c762e4d022021c0c2e9e8298dee2a490d956f7ab1b2d3160c1e37a50cc6d19a5e62eb484fc9014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a6202000000001976a9149b139230e4fe91c05a37ec334dc8378f3dbe377088ac00639f02000000001976a914b0d05a10926a7925508febdbab9a5bd4cda8c8f688ac00000000"
|
||||
)
|
||||
|
||||
# first internal, second external
|
||||
@pytest.mark.multisig
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_internal_external(self, client):
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=parse_path("45'/0/1/0"),
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address="1H7uXJQTVwXca2BXF2opTrvuZapk8Cm8zY",
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
self._responses(self.inp1, self.inp2, change=1)
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Bitcoin",
|
||||
[self.inp1, self.inp2],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022064f13801744a6c21b694f62cdb5d834e852f13ecf85ed4d0a56ba279571c24e3022010fab4cb05bdd7b24c8376dda4f62a418548eea6eb483e58675fa06e0d5c642c014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b4004730440220727b2522268f913acd213c507d7801b146e5b6cef666ad44b769c26d6c762e4d022021c0c2e9e8298dee2a490d956f7ab1b2d3160c1e37a50cc6d19a5e62eb484fc9014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a6202000000001976a9149b139230e4fe91c05a37ec334dc8378f3dbe377088ac00639f02000000001976a914b0d05a10926a7925508febdbab9a5bd4cda8c8f688ac00000000"
|
||||
)
|
||||
|
||||
# both outputs are external
|
||||
@pytest.mark.multisig
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_multisig_external_external(self, client):
|
||||
out1 = proto.TxOutputType(
|
||||
address="3B23k4kFBRtu49zvpG3Z9xuFzfpHvxBcwt",
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address="3PkXLsY7AUZCrCKGvX8FfP2EawowUBMbcg",
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(self._responses(self.inp1, self.inp2))
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Bitcoin",
|
||||
[self.inp1, self.inp2],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022059394e0dfcb2d2f4a6108703f801545ca5a820c0ac6a1859d0a3854813de55fa02207b6a57d70b82932ff58163336c461653a2dc82c78ed8157159e5178ac7325390014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b40047304402205a911685f5b974b2fc4a19d5ce056218773a4d20b5eaae2c2f9594929308182002201e03449f5a8813ec19f408bf1b6f4f334886d6fcf9920e300fd7678ef0724f81014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000"
|
||||
)
|
||||
|
||||
# inputs match, change matches (first is change)
|
||||
@pytest.mark.multisig
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_multisig_change_match_first(self, client):
|
||||
multisig_out1 = proto.MultisigRedeemScriptType(
|
||||
nodes=[self.node_ext2, self.node_ext1, self.node_int],
|
||||
address_n=[1, 0],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=[H_(45), 0, 1, 0],
|
||||
multisig=multisig_out1,
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address="3PkXLsY7AUZCrCKGvX8FfP2EawowUBMbcg",
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
self._responses(self.inp1, self.inp2, change=1)
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Bitcoin",
|
||||
[self.inp1, self.inp2],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022059394e0dfcb2d2f4a6108703f801545ca5a820c0ac6a1859d0a3854813de55fa02207b6a57d70b82932ff58163336c461653a2dc82c78ed8157159e5178ac7325390014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b40047304402205a911685f5b974b2fc4a19d5ce056218773a4d20b5eaae2c2f9594929308182002201e03449f5a8813ec19f408bf1b6f4f334886d6fcf9920e300fd7678ef0724f81014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000"
|
||||
)
|
||||
|
||||
# inputs match, change matches (second is change)
|
||||
@pytest.mark.multisig
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_multisig_change_match_second(self, client):
|
||||
multisig_out2 = proto.MultisigRedeemScriptType(
|
||||
nodes=[self.node_ext1, self.node_ext2, self.node_int],
|
||||
address_n=[1, 1],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="3B23k4kFBRtu49zvpG3Z9xuFzfpHvxBcwt",
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=[H_(45), 0, 1, 1],
|
||||
multisig=multisig_out2,
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
self._responses(self.inp1, self.inp2, change=2)
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Bitcoin",
|
||||
[self.inp1, self.inp2],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022059394e0dfcb2d2f4a6108703f801545ca5a820c0ac6a1859d0a3854813de55fa02207b6a57d70b82932ff58163336c461653a2dc82c78ed8157159e5178ac7325390014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b40047304402205a911685f5b974b2fc4a19d5ce056218773a4d20b5eaae2c2f9594929308182002201e03449f5a8813ec19f408bf1b6f4f334886d6fcf9920e300fd7678ef0724f81014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000"
|
||||
)
|
||||
|
||||
# inputs match, change mismatches (second tries to be change but isn't)
|
||||
@pytest.mark.multisig
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_multisig_mismatch_change(self, client):
|
||||
multisig_out2 = proto.MultisigRedeemScriptType(
|
||||
nodes=[self.node_ext1, self.node_int, self.node_ext3],
|
||||
address_n=[1, 0],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="3B23k4kFBRtu49zvpG3Z9xuFzfpHvxBcwt",
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address_n=[H_(45), 0, 1, 0],
|
||||
multisig=multisig_out2,
|
||||
amount=44000000,
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(self._responses(self.inp1, self.inp2))
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Bitcoin",
|
||||
[self.inp1, self.inp2],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b40047304402207f9992cc0230527faf54ec6bd233307db82bc8fac039dcee418bc6feb4e96a3a02206bb4cb157ad27c123277328a877572563a45d70b844d9ab07cc42238112f8c2a014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b400473044022078a41bfa87d72d6ba810d84bf568b5a29acf8b851ba6c3a8dbff079b34a7feb0022037b770c776db0b6c883c38a684a121b90a59ed1958774cbf64de70e53e29639f014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914e6a3e2fbadb7f559f8d20c46aceae78c96fcf1d18700000000"
|
||||
)
|
||||
|
||||
# inputs mismatch, change matches with first input
|
||||
@pytest.mark.multisig
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_multisig_mismatch_inputs(self, client):
|
||||
multisig_out1 = proto.MultisigRedeemScriptType(
|
||||
nodes=[self.node_ext2, self.node_ext1, self.node_int],
|
||||
address_n=[1, 0],
|
||||
signatures=[b"", b"", b""],
|
||||
m=2,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=[H_(45), 0, 1, 0],
|
||||
multisig=multisig_out1,
|
||||
amount=40000000,
|
||||
script_type=proto.OutputScriptType.PAYTOMULTISIG,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
address="3PkXLsY7AUZCrCKGvX8FfP2EawowUBMbcg",
|
||||
amount=65000000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(self._responses(self.inp1, self.inp3))
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client,
|
||||
"Bitcoin",
|
||||
[self.inp1, self.inp3],
|
||||
[out1, out2],
|
||||
prev_txes=TX_API,
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b500483045022100d907b9339951c96ef4515ef7aff8b3c28c4c8c5875d7421aa1de9f3a94e3508302205cdc311a6c91dfbb74f1a9a940a994a65dbfb0cf6dedcaaaeee839e0b8fd016d014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff39f756d82082b580b0d69ae8798ff10a981820ccfe1ab149a708a37bc26d94b000000000b500483045022100fdad4a47d15f47cc364fe0cbed11b1ced1f9ef210bc1bd413ec4384f630c63720220752e4f09ea4e5e6623f5ebe89b3983ec6e5702f63f9bce696f10b2d594d23532014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103b6321a1194e5cc47b6b7edc3f67a096e6f71ccb72440f84f390b6e98df0ea8ec2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948740d2df030000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000"
|
||||
)
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b500483045022100d907b9339951c96ef4515ef7aff8b3c28c4c8c5875d7421aa1de9f3a94e3508302205cdc311a6c91dfbb74f1a9a940a994a65dbfb0cf6dedcaaaeee839e0b8fd016d014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff39f756d82082b580b0d69ae8798ff10a981820ccfe1ab149a708a37bc26d94b000000000b500483045022100fdad4a47d15f47cc364fe0cbed11b1ced1f9ef210bc1bd413ec4384f630c63720220752e4f09ea4e5e6623f5ebe89b3983ec6e5702f63f9bce696f10b2d594d23532014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103b6321a1194e5cc47b6b7edc3f67a096e6f71ccb72440f84f390b6e98df0ea8ec2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948740d2df030000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000"
|
||||
)
|
||||
|
@ -31,102 +31,103 @@ TXHASH_d5f65e = bytes.fromhex(
|
||||
)
|
||||
|
||||
|
||||
class TestOpReturn:
|
||||
def test_opreturn(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/0'/0'/0/2"),
|
||||
amount=390000,
|
||||
prev_hash=TXHASH_d5f65e,
|
||||
prev_index=0,
|
||||
def test_opreturn(client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/0'/0'/0/2"),
|
||||
amount=390000,
|
||||
prev_hash=TXHASH_d5f65e,
|
||||
prev_index=0,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1",
|
||||
amount=390000 - 10000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
op_return_data=b"test of the op_return data",
|
||||
amount=0,
|
||||
script_type=proto.OutputScriptType.PAYTOOPRETURN,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_d5f65e),
|
||||
request_input(0, TXHASH_d5f65e),
|
||||
request_input(1, TXHASH_d5f65e),
|
||||
request_output(0, TXHASH_d5f65e),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Bitcoin", [inp1], [out1, out2], prev_txes=TX_API
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address="1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1",
|
||||
amount=390000 - 10000,
|
||||
script_type=proto.OutputScriptType.PAYTOADDRESS,
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "010000000182488650ef25a58fef6788bd71b8212038d7f2bbe4750bc7bcb44701e85ef6d5000000006b483045022100bc36e1227b334e856c532bbef86d30a96823a5f2461738f4dbf969dfbcf1b40b022078c5353ec9a4bce2bb05bd1ec466f2ab379c1aad926e208738407bba4e09784b012103330236b68aa6fdcaca0ea72e11b360c84ed19a338509aa527b678a7ec9076882ffffffff0260cc0500000000001976a914de9b2a8da088824e8fe51debea566617d851537888ac00000000000000001c6a1a74657374206f6620746865206f705f72657475726e206461746100000000"
|
||||
)
|
||||
|
||||
|
||||
def test_nonzero_opreturn(client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/0'/10'/0/5"),
|
||||
amount=390000,
|
||||
prev_hash=TXHASH_d5f65e,
|
||||
prev_index=0,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
op_return_data=b"test of the op_return data",
|
||||
amount=10000,
|
||||
script_type=proto.OutputScriptType.PAYTOOPRETURN,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[request_input(0), request_output(0), proto.Failure()]
|
||||
)
|
||||
|
||||
out2 = proto.TxOutputType(
|
||||
op_return_data=b"test of the op_return data",
|
||||
amount=0,
|
||||
script_type=proto.OutputScriptType.PAYTOOPRETURN,
|
||||
with pytest.raises(
|
||||
TrezorFailure, match="OP_RETURN output with non-zero amount"
|
||||
):
|
||||
btc.sign_tx(client, "Bitcoin", [inp1], [out1], prev_txes=TX_API)
|
||||
|
||||
|
||||
def test_opreturn_address(client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/0'/0'/0/2"),
|
||||
amount=390000,
|
||||
prev_hash=TXHASH_d5f65e,
|
||||
prev_index=0,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=parse_path("44'/0'/0'/1/2"),
|
||||
amount=0,
|
||||
op_return_data=b"OMNI TRANSACTION GOES HERE",
|
||||
script_type=proto.OutputScriptType.PAYTOOPRETURN,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[request_input(0), request_output(0), proto.Failure()]
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
request_output(1),
|
||||
proto.ButtonRequest(code=B.ConfirmOutput),
|
||||
proto.ButtonRequest(code=B.SignTx),
|
||||
request_input(0),
|
||||
request_meta(TXHASH_d5f65e),
|
||||
request_input(0, TXHASH_d5f65e),
|
||||
request_input(1, TXHASH_d5f65e),
|
||||
request_output(0, TXHASH_d5f65e),
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
request_output(0),
|
||||
request_output(1),
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
client, "Bitcoin", [inp1], [out1, out2], prev_txes=TX_API
|
||||
)
|
||||
|
||||
assert (
|
||||
serialized_tx.hex()
|
||||
== "010000000182488650ef25a58fef6788bd71b8212038d7f2bbe4750bc7bcb44701e85ef6d5000000006b483045022100bc36e1227b334e856c532bbef86d30a96823a5f2461738f4dbf969dfbcf1b40b022078c5353ec9a4bce2bb05bd1ec466f2ab379c1aad926e208738407bba4e09784b012103330236b68aa6fdcaca0ea72e11b360c84ed19a338509aa527b678a7ec9076882ffffffff0260cc0500000000001976a914de9b2a8da088824e8fe51debea566617d851537888ac00000000000000001c6a1a74657374206f6620746865206f705f72657475726e206461746100000000"
|
||||
)
|
||||
|
||||
def test_nonzero_opreturn(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/0'/10'/0/5"),
|
||||
amount=390000,
|
||||
prev_hash=TXHASH_d5f65e,
|
||||
prev_index=0,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
op_return_data=b"test of the op_return data",
|
||||
amount=10000,
|
||||
script_type=proto.OutputScriptType.PAYTOOPRETURN,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[request_input(0), request_output(0), proto.Failure()]
|
||||
)
|
||||
|
||||
with pytest.raises(
|
||||
TrezorFailure, match="OP_RETURN output with non-zero amount"
|
||||
):
|
||||
btc.sign_tx(client, "Bitcoin", [inp1], [out1], prev_txes=TX_API)
|
||||
|
||||
def test_opreturn_address(self, client):
|
||||
inp1 = proto.TxInputType(
|
||||
address_n=parse_path("44'/0'/0'/0/2"),
|
||||
amount=390000,
|
||||
prev_hash=TXHASH_d5f65e,
|
||||
prev_index=0,
|
||||
)
|
||||
|
||||
out1 = proto.TxOutputType(
|
||||
address_n=parse_path("44'/0'/0'/1/2"),
|
||||
amount=0,
|
||||
op_return_data=b"OMNI TRANSACTION GOES HERE",
|
||||
script_type=proto.OutputScriptType.PAYTOOPRETURN,
|
||||
)
|
||||
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[request_input(0), request_output(0), proto.Failure()]
|
||||
)
|
||||
with pytest.raises(
|
||||
TrezorFailure, match="Output's address_n provided but not expected."
|
||||
):
|
||||
btc.sign_tx(client, "Bitcoin", [inp1], [out1], prev_txes=TX_API)
|
||||
with pytest.raises(
|
||||
TrezorFailure, match="Output's address_n provided but not expected."
|
||||
):
|
||||
btc.sign_tx(client, "Bitcoin", [inp1], [out1], prev_txes=TX_API)
|
||||
|
@ -23,12 +23,11 @@ from trezorlib.tools import parse_path
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.tezos
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgTezosGetAddress:
|
||||
def test_tezos_get_address(self, client):
|
||||
path = parse_path("m/44'/1729'/0'")
|
||||
address = get_address(client, path, show_display=True)
|
||||
assert address == "tz1Kef7BSg6fo75jk37WkKRYSnJDs69KVqt9"
|
||||
def test_tezos_get_address(client):
|
||||
path = parse_path("m/44'/1729'/0'")
|
||||
address = get_address(client, path, show_display=True)
|
||||
assert address == "tz1Kef7BSg6fo75jk37WkKRYSnJDs69KVqt9"
|
||||
|
||||
path = parse_path("m/44'/1729'/1'")
|
||||
address = get_address(client, path, show_display=True)
|
||||
assert address == "tz1ekQapZCX4AXxTJhJZhroDKDYLHDHegvm1"
|
||||
path = parse_path("m/44'/1729'/1'")
|
||||
address = get_address(client, path, show_display=True)
|
||||
assert address == "tz1ekQapZCX4AXxTJhJZhroDKDYLHDHegvm1"
|
||||
|
@ -23,12 +23,11 @@ from trezorlib.tools import parse_path
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.tezos
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgTezosGetPublicKey:
|
||||
def test_tezos_get_public_key(self, client):
|
||||
path = parse_path("m/44'/1729'/0'")
|
||||
pk = get_public_key(client, path)
|
||||
assert pk == "edpkttLhEbVfMC3DhyVVFzdwh8ncRnEWiLD1x8TAuPU7vSJak7RtBX"
|
||||
def test_tezos_get_public_key(client):
|
||||
path = parse_path("m/44'/1729'/0'")
|
||||
pk = get_public_key(client, path)
|
||||
assert pk == "edpkttLhEbVfMC3DhyVVFzdwh8ncRnEWiLD1x8TAuPU7vSJak7RtBX"
|
||||
|
||||
path = parse_path("m/44'/1729'/1'")
|
||||
pk = get_public_key(client, path)
|
||||
assert pk == "edpkuTPqWjcApwyD3VdJhviKM5C13zGk8c4m87crgFarQboF3Mp56f"
|
||||
path = parse_path("m/44'/1729'/1'")
|
||||
pk = get_public_key(client, path)
|
||||
assert pk == "edpkuTPqWjcApwyD3VdJhviKM5C13zGk8c4m87crgFarQboF3Mp56f"
|
||||
|
@ -24,443 +24,437 @@ TEZOS_PATH = parse_path("m/44'/1729'/0'")
|
||||
TEZOS_PATH_10 = parse_path("m/44'/1729'/10'")
|
||||
TEZOS_PATH_15 = parse_path("m/44'/1729'/15'")
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.tezos,
|
||||
pytest.mark.skip_t1,
|
||||
]
|
||||
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.tezos
|
||||
@pytest.mark.skip_t1
|
||||
class TestMsgTezosSignTx:
|
||||
def test_tezos_sign_tx_proposal(self, client):
|
||||
with client:
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_10,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "dee04042c0832d68a43699b2001c0a38065436eb05e578071a763e1972d0bc81",
|
||||
"proposal": {
|
||||
"source": "005f450441f41ee11eee78a31d1e1e55627c783bd6",
|
||||
"period": 17,
|
||||
"proposals": [
|
||||
"dfa974df171c2dad9a9b8f25d99af41fd9702ce5d04521d2f9943c84d88aa572"
|
||||
],
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigtfY16R32k2WVMYfFr7ymnro4ib5zMckk28vsuViYNN77DJAvCJLRNArd9L531pUCxT4YdcvCvBym5dhcZ1rknEVm6yZ8bB"
|
||||
)
|
||||
assert (
|
||||
resp.sig_op_contents.hex()
|
||||
== "dee04042c0832d68a43699b2001c0a38065436eb05e578071a763e1972d0bc8105005f450441f41ee11eee78a31d1e1e55627c783bd60000001100000020dfa974df171c2dad9a9b8f25d99af41fd9702ce5d04521d2f9943c84d88aa5723b12621296a679b3a74ea790df5347995a76e20a09e76590baaacf4e09341965a04123f5cbbba8427f045b5f7d59157a3098e44839babe7c247d19b58bbb2405"
|
||||
)
|
||||
assert (
|
||||
resp.operation_hash == "opLqntFUu984M7LnGsFvfGW6kWe9QjAz4AfPDqQvwJ1wPM4Si4c"
|
||||
)
|
||||
|
||||
def test_tezos_sign_tx_multiple_proposals(self, client):
|
||||
with client:
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_10,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "7e0be36a90c663c73c60da3889ffefff1383fb65cc29f0639f173d8f95a52df7",
|
||||
"proposal": {
|
||||
"source": "005f450441f41ee11eee78a31d1e1e55627c783bd6",
|
||||
"period": 17,
|
||||
"proposals": [
|
||||
"2a6ff28ab4d0ccb18f7129aaaf9a4b8027d794f2562849665fdb6999db2a4e57",
|
||||
"47cd60c09ab8437cc9fe19add494dce1b9844100f660f02ce77510a0c66d2762",
|
||||
],
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigu6GAjhiWAQ64ctWTGEDYAZ16tYzLgzWzqc4CUyixK4FGRE8YUBVzFaVJ2fUCexZjZLMLdiNZGcUdzeL1bQhZ2h5oLrh7pA"
|
||||
)
|
||||
assert (
|
||||
resp.sig_op_contents.hex()
|
||||
== "7e0be36a90c663c73c60da3889ffefff1383fb65cc29f0639f173d8f95a52df705005f450441f41ee11eee78a31d1e1e55627c783bd600000011000000402a6ff28ab4d0ccb18f7129aaaf9a4b8027d794f2562849665fdb6999db2a4e5747cd60c09ab8437cc9fe19add494dce1b9844100f660f02ce77510a0c66d2762f813361ac00ada7e3256f23973ae25b112229476a3cb3e506fe929ea1e9358299fed22178d1be689cddeedd1f303abfef859b664f159a528576a1c807079f005"
|
||||
)
|
||||
assert (
|
||||
resp.operation_hash == "onobSyNgiitGXxSVFJN6949MhUomkkxvH4ZJ2owgWwNeDdntF9Y"
|
||||
)
|
||||
|
||||
def test_tezos_sing_tx_ballot_yay(self, client):
|
||||
def test_tezos_sign_tx_proposal(client):
|
||||
with client:
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_10,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "3a8f60c4cd394cee5b50136c7fc8cb157e8aaa476a9e5c68709be6fc1cdb5395",
|
||||
"ballot": {
|
||||
"source": "0002298c03ed7d454a101eb7022bc95f7e5f41ac78",
|
||||
"period": 2,
|
||||
"proposal": "def7ed9c84af23ab37ebb60dd83cd103d1272ad6c63d4c05931567e65ed027e3",
|
||||
"ballot": 0,
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigtkxNm6YXwtV24DqeuimeZFTeFCn2jDYheSsXT4rHMcEjNvzsiSo55nVyVsQxtEe8M7U4PWJWT4rGYYGckQCgtkNJkd2roX"
|
||||
)
|
||||
|
||||
def test_tezos_sing_tx_ballot_nay(self, client):
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_10,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "3a8f60c4cd394cee5b50136c7fc8cb157e8aaa476a9e5c68709be6fc1cdb5395",
|
||||
"ballot": {
|
||||
"source": "0002298c03ed7d454a101eb7022bc95f7e5f41ac78",
|
||||
"period": 2,
|
||||
"proposal": "def7ed9c84af23ab37ebb60dd83cd103d1272ad6c63d4c05931567e65ed027e3",
|
||||
"ballot": 1,
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigtqLaizfF6Cfc2JQL7TrsyniGhpZEojZAKMFW6AeudaUoU8KGXEHJH69Q4Lf27qFyUSTfbeHNnnCt69SGEPWkmpkgkgqMbL"
|
||||
)
|
||||
|
||||
def test_tezos_sing_tx_ballot_pass(self, client):
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_10,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "3a8f60c4cd394cee5b50136c7fc8cb157e8aaa476a9e5c68709be6fc1cdb5395",
|
||||
"ballot": {
|
||||
"source": "0002298c03ed7d454a101eb7022bc95f7e5f41ac78",
|
||||
"period": 2,
|
||||
"proposal": "def7ed9c84af23ab37ebb60dd83cd103d1272ad6c63d4c05931567e65ed027e3",
|
||||
"ballot": 2,
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigu6YX7EegPwrpcEbdNQsNhrRiEagBNGJBmFamP4mixZZw1UynhahGQ8RNiZLSUVLERUZwygrsSVenBqXGt9VnknTxtzjKzv"
|
||||
)
|
||||
|
||||
def test_tezos_sign_tx_tranasaction(self, client):
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_10,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "3b85532b5a468cd26b6d3c7e762ae53b795d19c6db4838ed2750df8e063aedb8",
|
||||
"transaction": {
|
||||
"branch": "dee04042c0832d68a43699b2001c0a38065436eb05e578071a763e1972d0bc81",
|
||||
"proposal": {
|
||||
"source": "005f450441f41ee11eee78a31d1e1e55627c783bd6",
|
||||
"fee": 10000,
|
||||
"counter": 274,
|
||||
"gas_limit": 20000,
|
||||
"storage_limit": 0,
|
||||
"amount": 100000,
|
||||
"destination": {
|
||||
"tag": 0,
|
||||
"hash": "003325df8851047421605ae7d6b09b49f70c8ce460",
|
||||
},
|
||||
"period": 17,
|
||||
"proposals": [
|
||||
"dfa974df171c2dad9a9b8f25d99af41fd9702ce5d04521d2f9943c84d88aa572"
|
||||
],
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigtvRTDegGy83x5AHQwhzPAbKteJ7MsLukhLRS9RLMRX5UdmtV1xiHEhQCUrGNv6h9CbV1cvuUVzRgLd6Af4XfVQgGkkYUuY"
|
||||
)
|
||||
assert (
|
||||
resp.sig_op_contents.hex()
|
||||
== "3b85532b5a468cd26b6d3c7e762ae53b795d19c6db4838ed2750df8e063aedb86c005f450441f41ee11eee78a31d1e1e55627c783bd6904e9202a09c0100a08d0600003325df8851047421605ae7d6b09b49f70c8ce46000acdcd3df9daaa79c7345c068ffddc2113047fc00c1eed3503838d15fc6690821ee6eaa1e67b4a8d40dcf30a9ec456bbbda18ef2bcc021053d7d8c3f1473df809"
|
||||
)
|
||||
assert (
|
||||
resp.operation_hash == "oon8PNUsPETGKzfESv1Epv4535rviGS7RdCfAEKcPvzojrcuufb"
|
||||
)
|
||||
|
||||
def test_tezos_sign_tx_delegation(self, client):
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_15,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "447d51450749763989c1aa5e1939aae623abb5a050f9cf1c04c247d91ca67593",
|
||||
"delegation": {
|
||||
"source": "0002eca091abc1e0f5c38a155c1313c410b47e1549",
|
||||
"fee": 20000,
|
||||
"counter": 458069,
|
||||
"gas_limit": 20000,
|
||||
"storage_limit": 0,
|
||||
"delegate": "005f450441f41ee11eee78a31d1e1e55627c783bd6",
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigu2ZsDXXm7RzMF2oSKHK54ZfSUPvU2jekJBQmAprMe8ksnofMScKd3Kc3RTTExwzaJGENzoe94ZDiW86eWWnWBTPNw2xu5m"
|
||||
)
|
||||
assert (
|
||||
resp.sig_op_contents.hex()
|
||||
== "447d51450749763989c1aa5e1939aae623abb5a050f9cf1c04c247d91ca675936e0002eca091abc1e0f5c38a155c1313c410b47e1549a09c01d5fa1ba09c0100ff005f450441f41ee11eee78a31d1e1e55627c783bd6dbd53f9129387e82548e5d20b1479a46a876ac7516001fae01488dfbe9dcfc732cb8664d52fd7e1bc25a9845714131fd498ef65ea91f84e180688a41e06fe700"
|
||||
)
|
||||
assert (
|
||||
resp.operation_hash == "op79C1tR7wkUgYNid2zC1WNXmGorS38mTXZwtAjmCQm2kG7XG59"
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigtfY16R32k2WVMYfFr7ymnro4ib5zMckk28vsuViYNN77DJAvCJLRNArd9L531pUCxT4YdcvCvBym5dhcZ1rknEVm6yZ8bB"
|
||||
)
|
||||
assert (
|
||||
resp.sig_op_contents.hex()
|
||||
== "dee04042c0832d68a43699b2001c0a38065436eb05e578071a763e1972d0bc8105005f450441f41ee11eee78a31d1e1e55627c783bd60000001100000020dfa974df171c2dad9a9b8f25d99af41fd9702ce5d04521d2f9943c84d88aa5723b12621296a679b3a74ea790df5347995a76e20a09e76590baaacf4e09341965a04123f5cbbba8427f045b5f7d59157a3098e44839babe7c247d19b58bbb2405"
|
||||
)
|
||||
assert resp.operation_hash == "opLqntFUu984M7LnGsFvfGW6kWe9QjAz4AfPDqQvwJ1wPM4Si4c"
|
||||
|
||||
def test_tezos_sign_tx_origination(self, client):
|
||||
|
||||
def test_tezos_sign_tx_multiple_proposals(client):
|
||||
with client:
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_10,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "927ac7cd7969bde606e7537712584eb0d34fc52d9f5a88cc908994d817170a16",
|
||||
"origination": {
|
||||
"branch": "7e0be36a90c663c73c60da3889ffefff1383fb65cc29f0639f173d8f95a52df7",
|
||||
"proposal": {
|
||||
"source": "005f450441f41ee11eee78a31d1e1e55627c783bd6",
|
||||
"fee": 20000,
|
||||
"counter": 276,
|
||||
"gas_limit": 20000,
|
||||
"storage_limit": 10000,
|
||||
"balance": 100000,
|
||||
"script": "0000001c02000000170500036805010368050202000000080316053d036d03420000000a010000000568656c6c6f",
|
||||
"period": 17,
|
||||
"proposals": [
|
||||
"2a6ff28ab4d0ccb18f7129aaaf9a4b8027d794f2562849665fdb6999db2a4e57",
|
||||
"47cd60c09ab8437cc9fe19add494dce1b9844100f660f02ce77510a0c66d2762",
|
||||
],
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigtcAamBz7cL8whbLvaeMNYUdsQieh6RADrzWLCPhDjzqn7JtdX9Yy4vYWKcpMnycY6YTMWCAYMegPaKMNJVM4zbxypALAyN"
|
||||
)
|
||||
assert (
|
||||
resp.sig_op_contents.hex()
|
||||
== "927ac7cd7969bde606e7537712584eb0d34fc52d9f5a88cc908994d817170a166d005f450441f41ee11eee78a31d1e1e55627c783bd6a09c019402a09c01904ea08d06000000001c02000000170500036805010368050202000000080316053d036d03420000000a010000000568656c6c6f2151774735e1659a7d0f54659e98fbcbd86a667717a9a2a9961292a170e5e8d1608a1dbf805a03981be2f7389ba1738841ac8b1069fe5978a72d441a97de3505"
|
||||
)
|
||||
assert (
|
||||
resp.operation_hash == "onmq9FFZzvG2zghNdr1bgv9jzdbzNycXjSSNmCVhXCGSnV3WA9g"
|
||||
)
|
||||
|
||||
def test_tezos_sign_tx_reveal(self, client):
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "f26502c204619c4bdab2e59efc50c79bc0136d781304b8f7fad389263550300e",
|
||||
"reveal": {
|
||||
"source": "00001e65c88ae6317cd62a638c8abd1e71c83c8475",
|
||||
"fee": 20000,
|
||||
"counter": 564560,
|
||||
"gas_limit": 20000,
|
||||
"storage_limit": 0,
|
||||
"public_key": "00200da2c0200927dd8168b2b62e1322637521fcefb3184e61c1c3123c7c00bb95",
|
||||
},
|
||||
"transaction": {
|
||||
"source": "00001e65c88ae6317cd62a638c8abd1e71c83c8475",
|
||||
"fee": 50000,
|
||||
"counter": 564561,
|
||||
"gas_limit": 20000,
|
||||
"storage_limit": 0,
|
||||
"amount": 100000,
|
||||
"destination": {
|
||||
"tag": 0,
|
||||
"hash": "005f450441f41ee11eee78a31d1e1e55627c783bd6",
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigtcqDr47paEVgr8X8gmvFt9UnNWACkMVCGdVFZ2yUq849oxmTbx2FqjToveUNwNujC9qmoi5kXWy78qZY2d5Qeryx6kCbGs"
|
||||
)
|
||||
assert (
|
||||
resp.sig_op_contents.hex()
|
||||
== "f26502c204619c4bdab2e59efc50c79bc0136d781304b8f7fad389263550300e6b00001e65c88ae6317cd62a638c8abd1e71c83c8475a09c01d0ba22a09c010000200da2c0200927dd8168b2b62e1322637521fcefb3184e61c1c3123c7c00bb956c00001e65c88ae6317cd62a638c8abd1e71c83c8475d08603d1ba22a09c0100a08d0600005f450441f41ee11eee78a31d1e1e55627c783bd60026690d65407d6cda03cde8e3c17a22ffd0351f78c18c500f3997cbe311e12e6cc4b5ff40b339c7fba8b4c7d62329ea45da662340113a6da98b7510b40042f204"
|
||||
)
|
||||
assert (
|
||||
resp.operation_hash == "oo9JFiWTnTSvUZfajMNwQe1VyFN2pqwiJzZPkpSAGfGD57Z6mZJ"
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigu6GAjhiWAQ64ctWTGEDYAZ16tYzLgzWzqc4CUyixK4FGRE8YUBVzFaVJ2fUCexZjZLMLdiNZGcUdzeL1bQhZ2h5oLrh7pA"
|
||||
)
|
||||
assert (
|
||||
resp.sig_op_contents.hex()
|
||||
== "7e0be36a90c663c73c60da3889ffefff1383fb65cc29f0639f173d8f95a52df705005f450441f41ee11eee78a31d1e1e55627c783bd600000011000000402a6ff28ab4d0ccb18f7129aaaf9a4b8027d794f2562849665fdb6999db2a4e5747cd60c09ab8437cc9fe19add494dce1b9844100f660f02ce77510a0c66d2762f813361ac00ada7e3256f23973ae25b112229476a3cb3e506fe929ea1e9358299fed22178d1be689cddeedd1f303abfef859b664f159a528576a1c807079f005"
|
||||
)
|
||||
assert resp.operation_hash == "onobSyNgiitGXxSVFJN6949MhUomkkxvH4ZJ2owgWwNeDdntF9Y"
|
||||
|
||||
def test_tezos_smart_contract_delegation(self, client):
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_10,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "49eead995833934ee2571c6cd6439897ee71b72a9e4d22f127e0c3d4ca69ba15",
|
||||
"transaction": {
|
||||
"source": "005f450441f41ee11eee78a31d1e1e55627c783bd6",
|
||||
"fee": 10000,
|
||||
"counter": 278,
|
||||
"gas_limit": 25822,
|
||||
"storage_limit": 0,
|
||||
"amount": 0,
|
||||
"destination": {
|
||||
"tag": 1,
|
||||
"hash": "c116a6c74bf00a5839b593838215fe1fcf2db59c00",
|
||||
},
|
||||
"parameters_manager": {
|
||||
"set_delegate": "005f450441f41ee11eee78a31d1e1e55627c783bd6"
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigtw8uSW99pT4GUd1mS14DbczxVfTCJrKBy6bMckBknwAxwAF53yBXnQAZwZ9WWMKyGmbta8RgPs262b7hGGNxFyTM8zdPBd"
|
||||
)
|
||||
assert (
|
||||
resp.sig_op_contents.hex()
|
||||
== "49eead995833934ee2571c6cd6439897ee71b72a9e4d22f127e0c3d4ca69ba156c005f450441f41ee11eee78a31d1e1e55627c783bd6904e9602dec901000001c116a6c74bf00a5839b593838215fe1fcf2db59c00ff020000002f020000002a0320053d036d0743035d0a00000015005f450441f41ee11eee78a31d1e1e55627c783bd60346034e031bb2534eb5478c31d5ffbc13b4692a7f2b73aad16e2d8e0f7068110955aa9480a6432775ba301f24bc20e4c12cffc9fd1f27b44204f830ea7f4dec23a18e25450d"
|
||||
)
|
||||
assert (
|
||||
resp.operation_hash == "oo75gfQGGPEPChXZzcPPAGtYqCpsg2BS5q9gmhrU3NQP7CEffpU"
|
||||
)
|
||||
|
||||
def test_tezos_kt_remove_delegation(self, client):
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_10,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "77a1800dd37b54f61755bd97b2a6759627c53a5f8afb00bdcf8255b5d23eff44",
|
||||
"transaction": {
|
||||
"source": "005f450441f41ee11eee78a31d1e1e55627c783bd6",
|
||||
"fee": 10000,
|
||||
"counter": 279,
|
||||
"gas_limit": 25822,
|
||||
"storage_limit": 0,
|
||||
"amount": 0,
|
||||
"destination": {
|
||||
"tag": 1,
|
||||
"hash": "c116a6c74bf00a5839b593838215fe1fcf2db59c00",
|
||||
},
|
||||
"parameters_manager": {"cancel_delegate": True},
|
||||
},
|
||||
def test_tezos_sing_tx_ballot_yay(client):
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_10,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "3a8f60c4cd394cee5b50136c7fc8cb157e8aaa476a9e5c68709be6fc1cdb5395",
|
||||
"ballot": {
|
||||
"source": "0002298c03ed7d454a101eb7022bc95f7e5f41ac78",
|
||||
"period": 2,
|
||||
"proposal": "def7ed9c84af23ab37ebb60dd83cd103d1272ad6c63d4c05931567e65ed027e3",
|
||||
"ballot": 0,
|
||||
},
|
||||
),
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigtqZZd8r2cww5GvTpaJANizYyAAB8n2sByKJWYwgEQQu6gjzSi7mQ7NAxbwsCaHGUS3F87oDJ1J5mz8SM8KYVidQj1NUz8E"
|
||||
)
|
||||
assert (
|
||||
resp.sig_op_contents.hex()
|
||||
== "77a1800dd37b54f61755bd97b2a6759627c53a5f8afb00bdcf8255b5d23eff446c005f450441f41ee11eee78a31d1e1e55627c783bd6904e9702dec901000001c116a6c74bf00a5839b593838215fe1fcf2db59c00ff0200000013020000000e0320053d036d053e035d034e031b87b6a5f01c0689f8f453f2b23582a2891792087197e01276648eec734850999e54e9edd687efb9297e24a96d126dc1e6636e772aeab80d5bc6b3f9b55aa3a701"
|
||||
)
|
||||
assert (
|
||||
resp.operation_hash == "ootMi1tXbfoVgFyzJa8iXyR4mnHd5TxLm9hmxVzMVRkbyVjKaHt"
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
def test_tezos_smart_contract_transfer(self, client):
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_10,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "442b86e27a7b79d893262b4daee229818f71073827570c74fa3aa1da7929d16d",
|
||||
"transaction": {
|
||||
"source": "005f450441f41ee11eee78a31d1e1e55627c783bd6",
|
||||
"fee": 10000,
|
||||
"counter": 280,
|
||||
"gas_limit": 36000,
|
||||
"storage_limit": 0,
|
||||
"amount": 0,
|
||||
"destination": {
|
||||
"tag": 1,
|
||||
"hash": "c116a6c74bf00a5839b593838215fe1fcf2db59c00",
|
||||
},
|
||||
"parameters_manager": {
|
||||
"transfer": {
|
||||
"amount": 20000,
|
||||
"destination": {
|
||||
"tag": 0,
|
||||
"hash": "005f450441f41ee11eee78a31d1e1e55627c783bd6",
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigtaY4HzLQ2oVDqnUAzbkSjGMQVBNHnBLq5t4TmVnsdAG8W4FWzeEnWbJXRQSTUKme3sXijve9vmDyAtim7HXeu9XhFJDrMo"
|
||||
)
|
||||
assert (
|
||||
resp.sig_op_contents.hex()
|
||||
== "442b86e27a7b79d893262b4daee229818f71073827570c74fa3aa1da7929d16d6c005f450441f41ee11eee78a31d1e1e55627c783bd6904e9802a09902000001c116a6c74bf00a5839b593838215fe1fcf2db59c00ff020000003902000000340320053d036d0743035d0a00000015005f450441f41ee11eee78a31d1e1e55627c783bd6031e0743036a00a0b802034f034d031b14dc70ef8db46c4b8f53e387ff3d642644af458f757ab85f9291727dc18bb09d7ec5790136b8cc428b165aec9cf628eeefc90aad526dc75e2aab203e57b8920f"
|
||||
)
|
||||
assert (
|
||||
resp.operation_hash == "ooRGGtCmoQDgB36XvQqmM7govc3yb77YDUoa7p2QS7on27wGRns"
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigtkxNm6YXwtV24DqeuimeZFTeFCn2jDYheSsXT4rHMcEjNvzsiSo55nVyVsQxtEe8M7U4PWJWT4rGYYGckQCgtkNJkd2roX"
|
||||
)
|
||||
|
||||
def test_tezos_smart_contract_transfer_to_contract(self, client):
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_10,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "8c696f9eb98cd641e33b680f424f7334b903d2b0108f0f896e73e921c44bf4c9",
|
||||
"transaction": {
|
||||
"source": "005f450441f41ee11eee78a31d1e1e55627c783bd6",
|
||||
"fee": 4813,
|
||||
"counter": 272,
|
||||
"gas_limit": 44725,
|
||||
"storage_limit": 0,
|
||||
"amount": 0,
|
||||
"destination": {
|
||||
"tag": 1,
|
||||
"hash": "c116a6c74bf00a5839b593838215fe1fcf2db59c00",
|
||||
},
|
||||
"parameters_manager": {
|
||||
"transfer": {
|
||||
"amount": 200,
|
||||
"destination": {
|
||||
"tag": 1,
|
||||
"hash": "8b83360512c6045c1185f8000de41302e23a220c00",
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
def test_tezos_sing_tx_ballot_nay(client):
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_10,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "3a8f60c4cd394cee5b50136c7fc8cb157e8aaa476a9e5c68709be6fc1cdb5395",
|
||||
"ballot": {
|
||||
"source": "0002298c03ed7d454a101eb7022bc95f7e5f41ac78",
|
||||
"period": 2,
|
||||
"proposal": "def7ed9c84af23ab37ebb60dd83cd103d1272ad6c63d4c05931567e65ed027e3",
|
||||
"ballot": 1,
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigtqLaizfF6Cfc2JQL7TrsyniGhpZEojZAKMFW6AeudaUoU8KGXEHJH69Q4Lf27qFyUSTfbeHNnnCt69SGEPWkmpkgkgqMbL"
|
||||
)
|
||||
|
||||
|
||||
def test_tezos_sing_tx_ballot_pass(client):
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_10,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "3a8f60c4cd394cee5b50136c7fc8cb157e8aaa476a9e5c68709be6fc1cdb5395",
|
||||
"ballot": {
|
||||
"source": "0002298c03ed7d454a101eb7022bc95f7e5f41ac78",
|
||||
"period": 2,
|
||||
"proposal": "def7ed9c84af23ab37ebb60dd83cd103d1272ad6c63d4c05931567e65ed027e3",
|
||||
"ballot": 2,
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigu6YX7EegPwrpcEbdNQsNhrRiEagBNGJBmFamP4mixZZw1UynhahGQ8RNiZLSUVLERUZwygrsSVenBqXGt9VnknTxtzjKzv"
|
||||
)
|
||||
|
||||
|
||||
def test_tezos_sign_tx_tranasaction(client):
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_10,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "3b85532b5a468cd26b6d3c7e762ae53b795d19c6db4838ed2750df8e063aedb8",
|
||||
"transaction": {
|
||||
"source": "005f450441f41ee11eee78a31d1e1e55627c783bd6",
|
||||
"fee": 10000,
|
||||
"counter": 274,
|
||||
"gas_limit": 20000,
|
||||
"storage_limit": 0,
|
||||
"amount": 100000,
|
||||
"destination": {
|
||||
"tag": 0,
|
||||
"hash": "003325df8851047421605ae7d6b09b49f70c8ce460",
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
assert (
|
||||
resp.sig_op_contents.hex()
|
||||
== "8c696f9eb98cd641e33b680f424f7334b903d2b0108f0f896e73e921c44bf4c96c005f450441f41ee11eee78a31d1e1e55627c783bd6cd259002b5dd02000001c116a6c74bf00a5839b593838215fe1fcf2db59c00ff020000005502000000500320053d036d0743036e0a00000016018b83360512c6045c1185f8000de41302e23a220c000555036c0200000015072f02000000090200000004034f032702000000000743036a008803034f034d031b911b8e7f22acdacc78e6d40566636a7029773c9ebfa741bb94bb58fb9e705d3ad695ac24fd1a58943c3070e9c38b0660671adb478233ae31005cd9139c84a80b"
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigtrnr4jXpPZK1yFVGtsapR4VHKp9Gnz1Uj7G4AdAXVn8ug16tgUx5u3TsyYJFp9MzENKuVqotaEwco3JhAhKpbjxbBQhEsT"
|
||||
)
|
||||
assert (
|
||||
resp.operation_hash == "opUE4xNkiUyYmJwUUgAab9xqHE66FXEc6VNZq4ZXDiBJcYwqNJX"
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigtvRTDegGy83x5AHQwhzPAbKteJ7MsLukhLRS9RLMRX5UdmtV1xiHEhQCUrGNv6h9CbV1cvuUVzRgLd6Af4XfVQgGkkYUuY"
|
||||
)
|
||||
assert (
|
||||
resp.sig_op_contents.hex()
|
||||
== "3b85532b5a468cd26b6d3c7e762ae53b795d19c6db4838ed2750df8e063aedb86c005f450441f41ee11eee78a31d1e1e55627c783bd6904e9202a09c0100a08d0600003325df8851047421605ae7d6b09b49f70c8ce46000acdcd3df9daaa79c7345c068ffddc2113047fc00c1eed3503838d15fc6690821ee6eaa1e67b4a8d40dcf30a9ec456bbbda18ef2bcc021053d7d8c3f1473df809"
|
||||
)
|
||||
assert resp.operation_hash == "oon8PNUsPETGKzfESv1Epv4535rviGS7RdCfAEKcPvzojrcuufb"
|
||||
|
||||
|
||||
def test_tezos_sign_tx_delegation(client):
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_15,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "447d51450749763989c1aa5e1939aae623abb5a050f9cf1c04c247d91ca67593",
|
||||
"delegation": {
|
||||
"source": "0002eca091abc1e0f5c38a155c1313c410b47e1549",
|
||||
"fee": 20000,
|
||||
"counter": 458069,
|
||||
"gas_limit": 20000,
|
||||
"storage_limit": 0,
|
||||
"delegate": "005f450441f41ee11eee78a31d1e1e55627c783bd6",
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigu2ZsDXXm7RzMF2oSKHK54ZfSUPvU2jekJBQmAprMe8ksnofMScKd3Kc3RTTExwzaJGENzoe94ZDiW86eWWnWBTPNw2xu5m"
|
||||
)
|
||||
assert (
|
||||
resp.sig_op_contents.hex()
|
||||
== "447d51450749763989c1aa5e1939aae623abb5a050f9cf1c04c247d91ca675936e0002eca091abc1e0f5c38a155c1313c410b47e1549a09c01d5fa1ba09c0100ff005f450441f41ee11eee78a31d1e1e55627c783bd6dbd53f9129387e82548e5d20b1479a46a876ac7516001fae01488dfbe9dcfc732cb8664d52fd7e1bc25a9845714131fd498ef65ea91f84e180688a41e06fe700"
|
||||
)
|
||||
assert resp.operation_hash == "op79C1tR7wkUgYNid2zC1WNXmGorS38mTXZwtAjmCQm2kG7XG59"
|
||||
|
||||
|
||||
def test_tezos_sign_tx_origination(client):
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_10,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "927ac7cd7969bde606e7537712584eb0d34fc52d9f5a88cc908994d817170a16",
|
||||
"origination": {
|
||||
"source": "005f450441f41ee11eee78a31d1e1e55627c783bd6",
|
||||
"fee": 20000,
|
||||
"counter": 276,
|
||||
"gas_limit": 20000,
|
||||
"storage_limit": 10000,
|
||||
"balance": 100000,
|
||||
"script": "0000001c02000000170500036805010368050202000000080316053d036d03420000000a010000000568656c6c6f",
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigtcAamBz7cL8whbLvaeMNYUdsQieh6RADrzWLCPhDjzqn7JtdX9Yy4vYWKcpMnycY6YTMWCAYMegPaKMNJVM4zbxypALAyN"
|
||||
)
|
||||
assert (
|
||||
resp.sig_op_contents.hex()
|
||||
== "927ac7cd7969bde606e7537712584eb0d34fc52d9f5a88cc908994d817170a166d005f450441f41ee11eee78a31d1e1e55627c783bd6a09c019402a09c01904ea08d06000000001c02000000170500036805010368050202000000080316053d036d03420000000a010000000568656c6c6f2151774735e1659a7d0f54659e98fbcbd86a667717a9a2a9961292a170e5e8d1608a1dbf805a03981be2f7389ba1738841ac8b1069fe5978a72d441a97de3505"
|
||||
)
|
||||
assert resp.operation_hash == "onmq9FFZzvG2zghNdr1bgv9jzdbzNycXjSSNmCVhXCGSnV3WA9g"
|
||||
|
||||
|
||||
def test_tezos_sign_tx_reveal(client):
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "f26502c204619c4bdab2e59efc50c79bc0136d781304b8f7fad389263550300e",
|
||||
"reveal": {
|
||||
"source": "00001e65c88ae6317cd62a638c8abd1e71c83c8475",
|
||||
"fee": 20000,
|
||||
"counter": 564560,
|
||||
"gas_limit": 20000,
|
||||
"storage_limit": 0,
|
||||
"public_key": "00200da2c0200927dd8168b2b62e1322637521fcefb3184e61c1c3123c7c00bb95",
|
||||
},
|
||||
"transaction": {
|
||||
"source": "00001e65c88ae6317cd62a638c8abd1e71c83c8475",
|
||||
"fee": 50000,
|
||||
"counter": 564561,
|
||||
"gas_limit": 20000,
|
||||
"storage_limit": 0,
|
||||
"amount": 100000,
|
||||
"destination": {
|
||||
"tag": 0,
|
||||
"hash": "005f450441f41ee11eee78a31d1e1e55627c783bd6",
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigtcqDr47paEVgr8X8gmvFt9UnNWACkMVCGdVFZ2yUq849oxmTbx2FqjToveUNwNujC9qmoi5kXWy78qZY2d5Qeryx6kCbGs"
|
||||
)
|
||||
assert (
|
||||
resp.sig_op_contents.hex()
|
||||
== "f26502c204619c4bdab2e59efc50c79bc0136d781304b8f7fad389263550300e6b00001e65c88ae6317cd62a638c8abd1e71c83c8475a09c01d0ba22a09c010000200da2c0200927dd8168b2b62e1322637521fcefb3184e61c1c3123c7c00bb956c00001e65c88ae6317cd62a638c8abd1e71c83c8475d08603d1ba22a09c0100a08d0600005f450441f41ee11eee78a31d1e1e55627c783bd60026690d65407d6cda03cde8e3c17a22ffd0351f78c18c500f3997cbe311e12e6cc4b5ff40b339c7fba8b4c7d62329ea45da662340113a6da98b7510b40042f204"
|
||||
)
|
||||
assert resp.operation_hash == "oo9JFiWTnTSvUZfajMNwQe1VyFN2pqwiJzZPkpSAGfGD57Z6mZJ"
|
||||
|
||||
|
||||
def test_tezos_smart_contract_delegation(client):
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_10,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "49eead995833934ee2571c6cd6439897ee71b72a9e4d22f127e0c3d4ca69ba15",
|
||||
"transaction": {
|
||||
"source": "005f450441f41ee11eee78a31d1e1e55627c783bd6",
|
||||
"fee": 10000,
|
||||
"counter": 278,
|
||||
"gas_limit": 25822,
|
||||
"storage_limit": 0,
|
||||
"amount": 0,
|
||||
"destination": {
|
||||
"tag": 1,
|
||||
"hash": "c116a6c74bf00a5839b593838215fe1fcf2db59c00",
|
||||
},
|
||||
"parameters_manager": {
|
||||
"set_delegate": "005f450441f41ee11eee78a31d1e1e55627c783bd6"
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigtw8uSW99pT4GUd1mS14DbczxVfTCJrKBy6bMckBknwAxwAF53yBXnQAZwZ9WWMKyGmbta8RgPs262b7hGGNxFyTM8zdPBd"
|
||||
)
|
||||
assert (
|
||||
resp.sig_op_contents.hex()
|
||||
== "49eead995833934ee2571c6cd6439897ee71b72a9e4d22f127e0c3d4ca69ba156c005f450441f41ee11eee78a31d1e1e55627c783bd6904e9602dec901000001c116a6c74bf00a5839b593838215fe1fcf2db59c00ff020000002f020000002a0320053d036d0743035d0a00000015005f450441f41ee11eee78a31d1e1e55627c783bd60346034e031bb2534eb5478c31d5ffbc13b4692a7f2b73aad16e2d8e0f7068110955aa9480a6432775ba301f24bc20e4c12cffc9fd1f27b44204f830ea7f4dec23a18e25450d"
|
||||
)
|
||||
assert resp.operation_hash == "oo75gfQGGPEPChXZzcPPAGtYqCpsg2BS5q9gmhrU3NQP7CEffpU"
|
||||
|
||||
|
||||
def test_tezos_kt_remove_delegation(client):
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_10,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "77a1800dd37b54f61755bd97b2a6759627c53a5f8afb00bdcf8255b5d23eff44",
|
||||
"transaction": {
|
||||
"source": "005f450441f41ee11eee78a31d1e1e55627c783bd6",
|
||||
"fee": 10000,
|
||||
"counter": 279,
|
||||
"gas_limit": 25822,
|
||||
"storage_limit": 0,
|
||||
"amount": 0,
|
||||
"destination": {
|
||||
"tag": 1,
|
||||
"hash": "c116a6c74bf00a5839b593838215fe1fcf2db59c00",
|
||||
},
|
||||
"parameters_manager": {"cancel_delegate": True},
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigtqZZd8r2cww5GvTpaJANizYyAAB8n2sByKJWYwgEQQu6gjzSi7mQ7NAxbwsCaHGUS3F87oDJ1J5mz8SM8KYVidQj1NUz8E"
|
||||
)
|
||||
assert (
|
||||
resp.sig_op_contents.hex()
|
||||
== "77a1800dd37b54f61755bd97b2a6759627c53a5f8afb00bdcf8255b5d23eff446c005f450441f41ee11eee78a31d1e1e55627c783bd6904e9702dec901000001c116a6c74bf00a5839b593838215fe1fcf2db59c00ff0200000013020000000e0320053d036d053e035d034e031b87b6a5f01c0689f8f453f2b23582a2891792087197e01276648eec734850999e54e9edd687efb9297e24a96d126dc1e6636e772aeab80d5bc6b3f9b55aa3a701"
|
||||
)
|
||||
assert resp.operation_hash == "ootMi1tXbfoVgFyzJa8iXyR4mnHd5TxLm9hmxVzMVRkbyVjKaHt"
|
||||
|
||||
|
||||
def test_tezos_smart_contract_transfer(client):
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_10,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "442b86e27a7b79d893262b4daee229818f71073827570c74fa3aa1da7929d16d",
|
||||
"transaction": {
|
||||
"source": "005f450441f41ee11eee78a31d1e1e55627c783bd6",
|
||||
"fee": 10000,
|
||||
"counter": 280,
|
||||
"gas_limit": 36000,
|
||||
"storage_limit": 0,
|
||||
"amount": 0,
|
||||
"destination": {
|
||||
"tag": 1,
|
||||
"hash": "c116a6c74bf00a5839b593838215fe1fcf2db59c00",
|
||||
},
|
||||
"parameters_manager": {
|
||||
"transfer": {
|
||||
"amount": 20000,
|
||||
"destination": {
|
||||
"tag": 0,
|
||||
"hash": "005f450441f41ee11eee78a31d1e1e55627c783bd6",
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigtaY4HzLQ2oVDqnUAzbkSjGMQVBNHnBLq5t4TmVnsdAG8W4FWzeEnWbJXRQSTUKme3sXijve9vmDyAtim7HXeu9XhFJDrMo"
|
||||
)
|
||||
assert (
|
||||
resp.sig_op_contents.hex()
|
||||
== "442b86e27a7b79d893262b4daee229818f71073827570c74fa3aa1da7929d16d6c005f450441f41ee11eee78a31d1e1e55627c783bd6904e9802a09902000001c116a6c74bf00a5839b593838215fe1fcf2db59c00ff020000003902000000340320053d036d0743035d0a00000015005f450441f41ee11eee78a31d1e1e55627c783bd6031e0743036a00a0b802034f034d031b14dc70ef8db46c4b8f53e387ff3d642644af458f757ab85f9291727dc18bb09d7ec5790136b8cc428b165aec9cf628eeefc90aad526dc75e2aab203e57b8920f"
|
||||
)
|
||||
assert resp.operation_hash == "ooRGGtCmoQDgB36XvQqmM7govc3yb77YDUoa7p2QS7on27wGRns"
|
||||
|
||||
|
||||
def test_tezos_smart_contract_transfer_to_contract(client):
|
||||
resp = tezos.sign_tx(
|
||||
client,
|
||||
TEZOS_PATH_10,
|
||||
dict_to_proto(
|
||||
messages.TezosSignTx,
|
||||
{
|
||||
"branch": "8c696f9eb98cd641e33b680f424f7334b903d2b0108f0f896e73e921c44bf4c9",
|
||||
"transaction": {
|
||||
"source": "005f450441f41ee11eee78a31d1e1e55627c783bd6",
|
||||
"fee": 4813,
|
||||
"counter": 272,
|
||||
"gas_limit": 44725,
|
||||
"storage_limit": 0,
|
||||
"amount": 0,
|
||||
"destination": {
|
||||
"tag": 1,
|
||||
"hash": "c116a6c74bf00a5839b593838215fe1fcf2db59c00",
|
||||
},
|
||||
"parameters_manager": {
|
||||
"transfer": {
|
||||
"amount": 200,
|
||||
"destination": {
|
||||
"tag": 1,
|
||||
"hash": "8b83360512c6045c1185f8000de41302e23a220c00",
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
assert (
|
||||
resp.sig_op_contents.hex()
|
||||
== "8c696f9eb98cd641e33b680f424f7334b903d2b0108f0f896e73e921c44bf4c96c005f450441f41ee11eee78a31d1e1e55627c783bd6cd259002b5dd02000001c116a6c74bf00a5839b593838215fe1fcf2db59c00ff020000005502000000500320053d036d0743036e0a00000016018b83360512c6045c1185f8000de41302e23a220c000555036c0200000015072f02000000090200000004034f032702000000000743036a008803034f034d031b911b8e7f22acdacc78e6d40566636a7029773c9ebfa741bb94bb58fb9e705d3ad695ac24fd1a58943c3070e9c38b0660671adb478233ae31005cd9139c84a80b"
|
||||
)
|
||||
assert (
|
||||
resp.signature
|
||||
== "edsigtrnr4jXpPZK1yFVGtsapR4VHKp9Gnz1Uj7G4AdAXVn8ug16tgUx5u3TsyYJFp9MzENKuVqotaEwco3JhAhKpbjxbBQhEsT"
|
||||
)
|
||||
assert resp.operation_hash == "opUE4xNkiUyYmJwUUgAab9xqHE66FXEc6VNZq4ZXDiBJcYwqNJX"
|
||||
|
Loading…
Reference in New Issue
Block a user