1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-17 21:22:10 +00:00

tests: add tests for different Cardano derivations

This commit is contained in:
matejcik 2021-10-22 16:05:33 +02:00 committed by matejcik
parent f8b9cda05d
commit 2c20016cfa
7 changed files with 269 additions and 37 deletions

View File

@ -0,0 +1,50 @@
{
"setup": {
"mnemonic": "very improve such purity recipe deer giggle shuffle bamboo sorry galaxy damp confirm note easy pause coast purse often hint west angle spare north",
"passphrase": ""
},
"tests": [
{
"name": "ledger-derivation",
"parameters": {
"derivation_type": "LEDGER",
"path": "m/1852'/1815'/0'/0/0",
"address_type": "base",
"staking_path": "m/1852'/1815'/0'/2/0",
"network_id": 1,
"protocol_magic": 764824073
},
"result": {
"expected_address": "addr1q8afdsv8q9hr4z8qljl3qz3rvm048g8j506j6umrpg63nytg4txp8fd25x5lnmkdh5p9wudkh4llu4dxyc3jyjef0gwqa5dzfd"
}
},
{
"name": "icarus-derivation",
"parameters": {
"derivation_type": "ICARUS",
"path": "m/1852'/1815'/0'/0/0",
"address_type": "base",
"staking_path": "m/1852'/1815'/0'/2/0",
"network_id": 1,
"protocol_magic": 764824073
},
"result": {
"expected_address": "addr1q996av5n0379tp8yllaxtgj3ffntmlrsl9sah237h65x6yt76a24dxtkgy59n8tvk00jf5dwfp8cz50g0uheuzfddcnqxp4njq"
}
},
{
"name": "icarus-trezor-derivation",
"parameters": {
"derivation_type": "ICARUS_TREZOR",
"path": "m/1852'/1815'/0'/0/0",
"address_type": "base",
"staking_path": "m/1852'/1815'/0'/2/0",
"network_id": 1,
"protocol_magic": 764824073
},
"result": {
"expected_address": "addr1q8g9th06vccxzl96nr905al0vgg2t0fqfxrxmv7ecye3x2e66sl9kvzd905ad5natzd5wghy2w3a9lm0y7u7c5sv0c2snql3c4"
}
}
]
}

View File

@ -0,0 +1,41 @@
{
"setup": {
"mnemonic": "very improve such purity recipe deer giggle shuffle bamboo sorry galaxy damp confirm note easy pause coast purse often hint west angle spare north",
"passphrase": ""
},
"tests": [
{
"name": "ledger-derivation",
"parameters": {
"path": "m/1852'/1815'/0'",
"derivation_type": "LEDGER"
},
"result": {
"public_key": "09a48c3390586bf1b5141e141fd2045b54f0a100af4254abb9bcf124eb82b078",
"chain_code": "abb4f1731e9bb4151fb8bbe4a63c64b84a6e6193ef2b97edd4176136d55c235f"
}
},
{
"name": "icarus-derivation",
"parameters": {
"path": "m/1852'/1815'/0'",
"derivation_type": "ICARUS"
},
"result": {
"public_key": "8946b80aaa2ab0839276ca373d0b7845803ae39e452ac2469986bf8b360b217f",
"chain_code": "85e096c7789c5aa29012633044750b1a79ab5ac2eb7189c91113e8ffbadd550f"
}
},
{
"name": "icarus-trezor-derivation",
"parameters": {
"path": "m/1852'/1815'/0'",
"derivation_type": "ICARUS_TREZOR"
},
"result": {
"public_key": "8a97a956fadbc79e09a867ed1e829af4f66a34903c9194de44c87262dfe19111",
"chain_code": "dd97903ff01f4fcb6375c8252b31a59d9b170c1b61f5786304dc676270f44a90"
}
}
]
}

View File

@ -22,8 +22,7 @@ from trezorlib.cardano import (
get_public_key,
parse_optional_bytes,
)
from trezorlib.exceptions import TrezorFailure
from trezorlib.messages import CardanoAddressType
from trezorlib.messages import CardanoAddressType, CardanoDerivationType
from trezorlib.tools import parse_path
from ...common import parametrize_using_common_fixtures
@ -44,10 +43,15 @@ pytestmark = [
"cardano/get_enterprise_address.json",
"cardano/get_pointer_address.json",
"cardano/get_reward_address.json",
"cardano/get_base_address.derivations.json",
)
def test_cardano_get_address(client, parameters, result):
client.init_device(new_session=True, derive_cardano=True)
derivation_type = CardanoDerivationType.__members__[
parameters.get("derivation_type", "ICARUS_TREZOR")
]
address = get_address(
client,
address_parameters=create_address_parameters(
@ -74,6 +78,7 @@ def test_cardano_get_address(client, parameters, result):
protocol_magic=parameters["protocol_magic"],
network_id=parameters["network_id"],
show_display=True,
derivation_type=derivation_type,
)
assert address == result["expected_address"]
@ -81,22 +86,16 @@ def test_cardano_get_address(client, parameters, result):
@parametrize_using_common_fixtures(
"cardano/get_public_key.json",
"cardano/get_public_key.slip39.json",
"cardano/get_public_key.derivations.json",
)
def test_cardano_get_public_key(client, parameters, result):
client.init_device(new_session=True, derive_cardano=True)
key = get_public_key(client, parse_path(parameters["path"]))
derivation_type = CardanoDerivationType.__members__[
parameters.get("derivation_type", "ICARUS_TREZOR")
]
key = get_public_key(client, parse_path(parameters["path"]), derivation_type)
assert key.node.public_key.hex() == result["public_key"]
assert key.node.chain_code.hex() == result["chain_code"]
assert key.xpub == result["public_key"] + result["chain_code"]
def test_bad_session(client):
client.init_device(new_session=True)
with pytest.raises(TrezorFailure, match="not enabled"):
get_public_key(client, parse_path("m/1852'/1815'/0'"))
client.init_device(new_session=True, derive_cardano=False)
with pytest.raises(TrezorFailure, match="not enabled"):
get_public_key(client, parse_path("m/1852'/1815'/0'"))

View File

@ -0,0 +1,59 @@
# This file is part of the Trezor project.
#
# Copyright (C) 2012-2019 SatoshiLabs and contributors
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License version 3
# as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the License along with this library.
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
import pytest
from trezorlib.cardano import get_public_key
from trezorlib.exceptions import TrezorFailure
from trezorlib.messages import CardanoDerivationType as D
from trezorlib.tools import parse_path
from ...common import MNEMONIC_SLIP39_BASIC_20_3of6
pytestmark = [
pytest.mark.altcoin,
pytest.mark.cardano,
pytest.mark.skip_t1,
]
ADDRESS_N = parse_path("m/1852'/1815'/0'")
def test_bad_session(client):
client.init_device(new_session=True)
with pytest.raises(TrezorFailure, match="not enabled"):
get_public_key(client, ADDRESS_N, derivation_type=D.ICARUS)
client.init_device(new_session=True, derive_cardano=False)
with pytest.raises(TrezorFailure, match="not enabled"):
get_public_key(client, ADDRESS_N, derivation_type=D.ICARUS)
def test_ledger_available_always(client):
client.init_device(new_session=True, derive_cardano=False)
get_public_key(client, ADDRESS_N, derivation_type=D.LEDGER)
client.init_device(new_session=True, derive_cardano=True)
get_public_key(client, ADDRESS_N, derivation_type=D.LEDGER)
@pytest.mark.setup_client(mnemonic=MNEMONIC_SLIP39_BASIC_20_3of6)
@pytest.mark.parametrize("derivation_type", D) # try ALL derivation types
def test_derivation_irrelevant_on_slip39(client, derivation_type):
client.init_device(new_session=True, derive_cardano=False)
pubkey = get_public_key(client, ADDRESS_N, derivation_type=D.ICARUS)
test_pubkey = get_public_key(client, ADDRESS_N, derivation_type=derivation_type)
assert pubkey == test_pubkey

View File

@ -16,7 +16,7 @@
import pytest
from trezorlib import messages
from trezorlib import cardano, messages
from trezorlib.btc import get_public_node
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
@ -154,3 +154,69 @@ def test_session_recycling(client):
client.use_passphrase("TREZOR")
client.init_device(session_id=session_id_orig)
assert address == get_test_address(client)
@pytest.mark.altcoin
@pytest.mark.cardano
@pytest.mark.skip_t1
def test_derive_cardano_empty_session(client):
# start new session
client.init_device(new_session=True)
session_id = client.session_id
# restarting same session should go well
client.init_device()
assert session_id == client.session_id
# restarting same session should go well with any setting
client.init_device(derive_cardano=False)
assert session_id == client.session_id
client.init_device(derive_cardano=True)
assert session_id == client.session_id
@pytest.mark.altcoin
@pytest.mark.cardano
@pytest.mark.skip_t1
def test_derive_cardano_running_session(client):
# start new session
client.init_device(new_session=True)
session_id = client.session_id
# force derivation of seed
get_test_address(client)
# session should not have Cardano capability
with pytest.raises(TrezorFailure, match="not enabled"):
cardano.get_public_key(client, parse_path("m/44h/1815h/0h"))
# restarting same session should go well
client.init_device()
assert session_id == client.session_id
# restarting same session should go well if we _don't_ want to derive cardano
client.init_device(derive_cardano=False)
assert session_id == client.session_id
# restarting with derive_cardano=True should kill old session and create new one
client.init_device(derive_cardano=True)
assert session_id != client.session_id
session_id = client.session_id
# new session should have Cardano capability
cardano.get_public_key(client, parse_path("m/44h/1815h/0h"))
# restarting with derive_cardano=True should keep same session
client.init_device(derive_cardano=True)
assert session_id == client.session_id
# restarting with no setting should keep same session
client.init_device()
assert session_id == client.session_id
# restarting with derive_cardano=False should kill old session and create new one
client.init_device(derive_cardano=False)
assert session_id != client.session_id
with pytest.raises(TrezorFailure, match="not enabled"):
cardano.get_public_key(client, parse_path("m/44h/1815h/0h"))

View File

@ -35,6 +35,7 @@ XPUB_PASSPHRASES = {
"J": "xpub6CVeYPTG57D4tm9BvwCcakppwGJstbXyK8Yd611agusZuHmx7og3dNvr6pjMN6e4BoaNc5MZA4TjMLjMT2h2vJRU8rYLvHFUwrEL9zDbuqe",
}
XPUB_PASSPHRASE_NONE = "xpub6BiVtCpG9fQPxnPmHXG8PhtzQdWC2Su4qWu6XW9tpWFYhxydCLJGrWBJZ5H6qTAHdPQ7pQhtpjiYZVZARo14qHiay2fvrX996oEP42u8wZy"
XPUB_CARDANO_PASSPHRASE_A = "d37eba66d6183547b11b4d0c3e08e761da9f07c3ef32183f8b79360b2b66850e47e8eb3865251784c3c471a854ee40dfc067f7f3afe47d093388ea45239606fd"
XPUB_CARDANO_PASSPHRASE_B = "d80e770f6dfc3edb58eaab68aa091b2c27b08a47583471e93437ac5f8baa61880c7af4938a941c084c19731e6e57a5710e6ad1196263291aea297ce0eec0f177"
ADDRESS_N = parse_path("44h/0h/0h")
@ -43,9 +44,11 @@ XPUB_REQUEST = messages.GetPublicKey(address_n=ADDRESS_N, coin_name="Bitcoin")
SESSIONS_STORED = 10
def _init_session(client, session_id=None):
def _init_session(client, session_id=None, derive_cardano=False):
"""Call Initialize, check and return the session ID."""
response = client.call(messages.Initialize(session_id=session_id))
response = client.call(
messages.Initialize(session_id=session_id, derive_cardano=derive_cardano)
)
assert isinstance(response, messages.Features)
assert len(response.session_id) == 32
return response.session_id
@ -372,7 +375,10 @@ def test_passphrase_length(client):
def _get_xpub_cardano(client, passphrase):
msg = messages.CardanoGetPublicKey(address_n=parse_path("44'/1815'/0'/0/0"))
msg = messages.CardanoGetPublicKey(
address_n=parse_path("44'/1815'/0'/0/0"),
derivation_type=messages.CardanoDerivationType.ICARUS,
)
response = client.call_raw(msg)
if passphrase is not None:
assert isinstance(response, messages.PassphraseRequest)
@ -385,36 +391,35 @@ def _get_xpub_cardano(client, passphrase):
@pytest.mark.altcoin
@pytest.mark.setup_client(passphrase=True)
def test_cardano_passphrase(client):
# Cardano uses a variation of BIP-39 so we need to ask for the passphrase again.
# Cardano has a separate derivation method that needs to access the plaintext
# of the passphrase.
# Historically, Cardano calls would ask for passphrase again. Now, they should not.
session_id = _init_session(client)
session_id = _init_session(client, derive_cardano=True)
# GetPublicKey requires passphrase and since it is not cached,
# Trezor will prompt for it.
assert _get_xpub(client, passphrase="A") == XPUB_PASSPHRASES["A"]
assert _get_xpub(client, passphrase="B") == XPUB_PASSPHRASES["B"]
# The passphrase is now cached for non-Cardano coins.
assert _get_xpub(client, passphrase=None) == XPUB_PASSPHRASES["A"]
assert _get_xpub(client, passphrase=None) == XPUB_PASSPHRASES["B"]
# Cardano will prompt for it again.
assert _get_xpub_cardano(client, passphrase="B") == XPUB_CARDANO_PASSPHRASE_B
# But now also Cardano has it cached.
# The passphrase should be cached for Cardano as well
assert _get_xpub_cardano(client, passphrase=None) == XPUB_CARDANO_PASSPHRASE_B
# And others behaviour did not change.
assert _get_xpub(client, passphrase=None) == XPUB_PASSPHRASES["A"]
# Initialize with the session id does not destroy the state
_init_session(client, session_id=session_id)
assert _get_xpub(client, passphrase=None) == XPUB_PASSPHRASES["A"]
_init_session(client, session_id=session_id, derive_cardano=True)
assert _get_xpub(client, passphrase=None) == XPUB_PASSPHRASES["B"]
assert _get_xpub_cardano(client, passphrase=None) == XPUB_CARDANO_PASSPHRASE_B
# New session will destroy the state
_init_session(client)
_init_session(client, derive_cardano=True)
# GetPublicKey must ask for passphrase again
assert _get_xpub(client, passphrase="A") == XPUB_PASSPHRASES["A"]
# Cardano must ask for passphrase again
assert _get_xpub_cardano(client, passphrase="A") == XPUB_CARDANO_PASSPHRASE_A
# Cardano must also ask for passphrase again
assert _get_xpub_cardano(client, passphrase="B") == XPUB_CARDANO_PASSPHRASE_B
# Passphrase is now cached for Cardano
assert _get_xpub_cardano(client, passphrase=None) == XPUB_CARDANO_PASSPHRASE_A
# Passphrase is cached for non-Cardano coins too
assert _get_xpub(client, passphrase=None) == XPUB_PASSPHRASES["A"]

View File

@ -1,5 +1,7 @@
{
"cardano-test_address_public_key.py::test_bad_session": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1",
"cardano-test_address_public_key.py::test_cardano_get_address[icarus-derivation]": "61bf57f65a018283d5e314f95f5580fe751eb3f09cd175a8f9e47f677419cbf2",
"cardano-test_address_public_key.py::test_cardano_get_address[icarus-trezor-derivation]": "d2b12b3a3fe426785e5dad64d7b48e8e266983011f8a837abccc2f4a8f9c43e6",
"cardano-test_address_public_key.py::test_cardano_get_address[ledger-derivation]": "08b2ef82b653af85b33253a45faca36669e4fb044596c4595890efaa48c84595",
"cardano-test_address_public_key.py::test_cardano_get_address[parameters0-result0]": "e3be7c64097574e795bad1852f3eb7b9d5c4577ed88a845329bacc7350338d74",
"cardano-test_address_public_key.py::test_cardano_get_address[parameters1-result1]": "50b6d3e772e77d6f52c7883f89c3b5f196e43865982c6c5b5171a72546e68164",
"cardano-test_address_public_key.py::test_cardano_get_address[parameters10-result10]": "31b0bb5d4ab8cbd5293cbdc8c44f722e5e39c1f633eaa1db2186cb138d88dd5c",
@ -37,6 +39,9 @@
"cardano-test_address_public_key.py::test_cardano_get_address[parameters7-result7]": "d1e4b84dcafcf246d14f7093694df1e14831387e2fd519150949cbff077b82cd",
"cardano-test_address_public_key.py::test_cardano_get_address[parameters8-result8]": "124fdbdf78ad7cbb4e5bd81abe8d8b5738be7544b7fd939de800df5e3fde71ac",
"cardano-test_address_public_key.py::test_cardano_get_address[parameters9-result9]": "4b12964477d051513257ea78693ca3d0262be7f05d29db54a92398eb7add5ed1",
"cardano-test_address_public_key.py::test_cardano_get_public_key[icarus-derivation]": "095af81ec79e9b510c90d9fa34fed343f3840807190c67bc237af885695ae687",
"cardano-test_address_public_key.py::test_cardano_get_public_key[icarus-trezor-derivation]": "095af81ec79e9b510c90d9fa34fed343f3840807190c67bc237af885695ae687",
"cardano-test_address_public_key.py::test_cardano_get_public_key[ledger-derivation]": "095af81ec79e9b510c90d9fa34fed343f3840807190c67bc237af885695ae687",
"cardano-test_address_public_key.py::test_cardano_get_public_key[parameters0-result0]": "095af81ec79e9b510c90d9fa34fed343f3840807190c67bc237af885695ae687",
"cardano-test_address_public_key.py::test_cardano_get_public_key[parameters1-result1]": "095af81ec79e9b510c90d9fa34fed343f3840807190c67bc237af885695ae687",
"cardano-test_address_public_key.py::test_cardano_get_public_key[parameters10-result10]": "095af81ec79e9b510c90d9fa34fed343f3840807190c67bc237af885695ae687",
@ -54,6 +59,11 @@
"cardano-test_address_public_key.py::test_cardano_get_public_key[parameters7-result7]": "095af81ec79e9b510c90d9fa34fed343f3840807190c67bc237af885695ae687",
"cardano-test_address_public_key.py::test_cardano_get_public_key[parameters8-result8]": "095af81ec79e9b510c90d9fa34fed343f3840807190c67bc237af885695ae687",
"cardano-test_address_public_key.py::test_cardano_get_public_key[parameters9-result9]": "095af81ec79e9b510c90d9fa34fed343f3840807190c67bc237af885695ae687",
"cardano-test_derivations.py::test_bad_session": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1",
"cardano-test_derivations.py::test_derivation_irrelevant_on_slip39[CardanoDerivationType.ICA-3b0af713": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1",
"cardano-test_derivations.py::test_derivation_irrelevant_on_slip39[CardanoDerivationType.ICARUS]": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1",
"cardano-test_derivations.py::test_derivation_irrelevant_on_slip39[CardanoDerivationType.LEDGER]": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1",
"cardano-test_derivations.py::test_ledger_available_always": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1",
"cardano-test_get_native_script_hash.py::test_cardano_get_native_script_hash[all_script]": "96dfeb79b33a0b49b761fbd694423e57567ee932da5e75514315159aaad3288b",
"cardano-test_get_native_script_hash.py::test_cardano_get_native_script_hash[all_script_cont-aae1e6c3": "aef99839b7f2706cfb76aed84bfb862647bdd6d0013326aad1fc90d704c98e9e",
"cardano-test_get_native_script_hash.py::test_cardano_get_native_script_hash[all_script_cont-e4ca0ea5": "c488d5e29487e9a75f2146694c11699af6c2c2893f03773434996386f01469ea",
@ -816,10 +826,12 @@
"test_sdcard.py::test_sd_protect_unlock": "bc654959615d17f6d8d6dda4625b4ecf7798a7d8c05ff438fc1546d0f8547432",
"test_session.py::test_cannot_resume_ended_session": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1",
"test_session.py::test_clear_session": "a749e7ff817a859da0670e7810d683909b9c4db415594098981183adb9c6be2e",
"test_session.py::test_derive_cardano_empty_session": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1",
"test_session.py::test_derive_cardano_running_session": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1",
"test_session.py::test_end_session": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1",
"test_session.py::test_end_session_only_current": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1",
"test_session.py::test_session_recycling": "54fe7196c39e3f70734be72fc45a121670e891852354057b4d8ab094ced4b493",
"test_session_id_and_passphrase.py::test_cardano_passphrase": "cb1d3bb493357a2f07f3efdbe9695b9e0820165a78bb3265c7c7c4abdb535e92",
"test_session_id_and_passphrase.py::test_cardano_passphrase": "c35e3d1e5a374a3c55a062659f9ccf51cf950dfb11ef61fc08f8c6ce827bcef5",
"test_session_id_and_passphrase.py::test_max_sessions_with_passphrases": "a8e25f2a9ef380c9390568977c68de5167e75cc39989bec7939dcf2dd908da8b",
"test_session_id_and_passphrase.py::test_multiple_passphrases": "90bffec62c5f070b14d0ce7b505b1aa455b379c3c3c0a0a5d4f27af7a78325df",
"test_session_id_and_passphrase.py::test_multiple_sessions": "c09de07fbbf1e047442180e2facb5482d06a1a428891b875b7dd93c9e4704ae1",