mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-29 19:08:12 +00:00
core/tests: add new keychain tests
This commit is contained in:
parent
d5b4a570ff
commit
3e06f4779a
@ -1,6 +1,8 @@
|
|||||||
from common import *
|
from common import *
|
||||||
|
|
||||||
|
from storage import cache
|
||||||
from apps.common import HARDENED, coins
|
from apps.common import HARDENED, coins
|
||||||
from apps.common.seed import Keychain, Slip21Node, _path_hardened
|
from apps.common.seed import Keychain, Slip21Node, _path_hardened, get_keychain, with_slip44_keychain
|
||||||
from apps.wallet.sign_tx import scripts, addresses
|
from apps.wallet.sign_tx import scripts, addresses
|
||||||
from trezor import wire
|
from trezor import wire
|
||||||
from trezor.crypto import bip39
|
from trezor.crypto import bip39
|
||||||
@ -112,6 +114,63 @@ class TestKeychain(unittest.TestCase):
|
|||||||
with self.assertRaises(wire.DataError):
|
with self.assertRaises(wire.DataError):
|
||||||
keychain.derive([b"SLIP-9999", b"Authentication key"]).key()
|
keychain.derive([b"SLIP-9999", b"Authentication key"]).key()
|
||||||
|
|
||||||
|
def test_get_keychain(self):
|
||||||
|
seed = bip39.seed(' '.join(['all'] * 12), '')
|
||||||
|
cache.start_session()
|
||||||
|
cache.set(cache.APP_COMMON_SEED, seed)
|
||||||
|
|
||||||
|
namespaces = [("secp256k1", [44 | HARDENED])]
|
||||||
|
keychain = await_result(get_keychain(wire.DUMMY_CONTEXT, namespaces))
|
||||||
|
|
||||||
|
# valid path:
|
||||||
|
self.assertIsNotNone(keychain.derive([44 | HARDENED, 1 | HARDENED]))
|
||||||
|
|
||||||
|
# invalid path:
|
||||||
|
with self.assertRaises(wire.DataError):
|
||||||
|
keychain.derive([44])
|
||||||
|
|
||||||
|
def test_with_slip44(self):
|
||||||
|
seed = bip39.seed(' '.join(['all'] * 12), '')
|
||||||
|
cache.start_session()
|
||||||
|
cache.set(cache.APP_COMMON_SEED, seed)
|
||||||
|
|
||||||
|
slip44_id = 42
|
||||||
|
valid_path = [44 | HARDENED, slip44_id | HARDENED]
|
||||||
|
invalid_path = [44 | HARDENED, 99 | HARDENED]
|
||||||
|
testnet_path = [44 | HARDENED, 1 | HARDENED]
|
||||||
|
|
||||||
|
def check_valid_paths(keychain, *paths):
|
||||||
|
for path in paths:
|
||||||
|
self.assertIsNotNone(keychain.derive(path))
|
||||||
|
|
||||||
|
def check_invalid_paths(keychain, *paths):
|
||||||
|
for path in paths:
|
||||||
|
self.assertRaises(wire.DataError, keychain.derive, path)
|
||||||
|
|
||||||
|
@with_slip44_keychain(slip44_id)
|
||||||
|
async def func_id_only(ctx, msg, keychain):
|
||||||
|
check_valid_paths(keychain, valid_path)
|
||||||
|
check_invalid_paths(keychain, testnet_path, invalid_path)
|
||||||
|
|
||||||
|
@with_slip44_keychain(slip44_id, allow_testnet=True)
|
||||||
|
async def func_allow_testnet(ctx, msg, keychain):
|
||||||
|
check_valid_paths(keychain, valid_path, testnet_path)
|
||||||
|
check_invalid_paths(keychain, invalid_path)
|
||||||
|
|
||||||
|
@with_slip44_keychain(slip44_id, curve="ed25519")
|
||||||
|
async def func_with_curve(ctx, msg, keychain):
|
||||||
|
check_valid_paths(keychain, valid_path)
|
||||||
|
check_invalid_paths(keychain, testnet_path, invalid_path)
|
||||||
|
|
||||||
|
i, _ = keychain.match_path(valid_path)
|
||||||
|
ns_curve, ns = keychain.namespaces[i]
|
||||||
|
self.assertEqual(ns_curve, "ed25519")
|
||||||
|
|
||||||
|
await_result(func_id_only(wire.DUMMY_CONTEXT, None))
|
||||||
|
await_result(func_allow_testnet(wire.DUMMY_CONTEXT, None))
|
||||||
|
await_result(func_with_curve(wire.DUMMY_CONTEXT, None))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
216
core/tests/test_apps.ethereum.keychain.py
Normal file
216
core/tests/test_apps.ethereum.keychain.py
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
from common import *
|
||||||
|
from storage import cache
|
||||||
|
from trezor import wire
|
||||||
|
from trezor.crypto import bip39
|
||||||
|
from apps.common.paths import HARDENED
|
||||||
|
|
||||||
|
if not utils.BITCOIN_ONLY:
|
||||||
|
from apps.ethereum.keychain import (
|
||||||
|
from_address_n,
|
||||||
|
with_keychain_from_path,
|
||||||
|
with_keychain_from_chain_id,
|
||||||
|
)
|
||||||
|
from apps.ethereum.networks import by_chain_id, by_slip44
|
||||||
|
|
||||||
|
from trezor.messages.EthereumGetAddress import EthereumGetAddress
|
||||||
|
from trezor.messages.EthereumSignTx import EthereumSignTx
|
||||||
|
|
||||||
|
|
||||||
|
@unittest.skipUnless(not utils.BITCOIN_ONLY, "altcoin")
|
||||||
|
class TestEthereumKeychain(unittest.TestCase):
|
||||||
|
def _check_keychain(self, keychain, slip44_id):
|
||||||
|
# valid address should succeed
|
||||||
|
valid_addresses = (
|
||||||
|
[44 | HARDENED, slip44_id | HARDENED],
|
||||||
|
[44 | HARDENED, slip44_id | HARDENED, 0 | HARDENED],
|
||||||
|
[44 | HARDENED, slip44_id | HARDENED, 19 | HARDENED],
|
||||||
|
[44 | HARDENED, slip44_id | HARDENED, 0 | HARDENED, 0, 0],
|
||||||
|
)
|
||||||
|
for addr in valid_addresses:
|
||||||
|
keychain.derive(addr)
|
||||||
|
# invalid address should fail
|
||||||
|
invalid_addresses = (
|
||||||
|
[44 | HARDENED],
|
||||||
|
[44 | HARDENED, 0 | HARDENED],
|
||||||
|
[42 | HARDENED, slip44_id | HARDENED],
|
||||||
|
[0 | HARDENED, slip44_id | HARDENED, 0 | HARDENED],
|
||||||
|
)
|
||||||
|
for addr in invalid_addresses:
|
||||||
|
self.assertRaises(
|
||||||
|
wire.DataError, keychain.derive, addr,
|
||||||
|
)
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
cache.start_session()
|
||||||
|
seed = bip39.seed(" ".join(["all"] * 12), "")
|
||||||
|
cache.set(cache.APP_COMMON_SEED, seed)
|
||||||
|
|
||||||
|
def test_from_address_n(self):
|
||||||
|
# valid keychain m/44'/60'/0'
|
||||||
|
keychain = await_result(
|
||||||
|
from_address_n(
|
||||||
|
wire.DUMMY_CONTEXT, [44 | HARDENED, 60 | HARDENED, 0 | HARDENED]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self._check_keychain(keychain, 60)
|
||||||
|
|
||||||
|
def test_from_address_n_unknown(self):
|
||||||
|
# try Bitcoin slip44 id m/44'/0'/0'
|
||||||
|
with self.assertRaises(wire.DataError):
|
||||||
|
await_result(
|
||||||
|
from_address_n(
|
||||||
|
wire.DUMMY_CONTEXT, [44 | HARDENED, 0 | HARDENED, 0 | HARDENED]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_bad_address_n(self):
|
||||||
|
# keychain generated from valid slip44 id but invalid address m/0'/60'/0'
|
||||||
|
keychain = await_result(
|
||||||
|
from_address_n(
|
||||||
|
wire.DUMMY_CONTEXT, [0 | HARDENED, 60 | HARDENED, 0 | HARDENED]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self._check_keychain(keychain, 60)
|
||||||
|
|
||||||
|
def test_with_keychain_from_path(self):
|
||||||
|
@with_keychain_from_path
|
||||||
|
async def handler(ctx, msg, keychain):
|
||||||
|
self._check_keychain(keychain, msg.address_n[1] & ~HARDENED)
|
||||||
|
|
||||||
|
await_result(
|
||||||
|
handler(
|
||||||
|
wire.DUMMY_CONTEXT,
|
||||||
|
EthereumGetAddress(
|
||||||
|
address_n=[44 | HARDENED, 60 | HARDENED, 0 | HARDENED]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
await_result(
|
||||||
|
handler(
|
||||||
|
wire.DUMMY_CONTEXT,
|
||||||
|
EthereumGetAddress(
|
||||||
|
address_n=[44 | HARDENED, 108 | HARDENED, 0 | HARDENED]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
with self.assertRaises(wire.DataError):
|
||||||
|
await_result(
|
||||||
|
handler(
|
||||||
|
wire.DUMMY_CONTEXT,
|
||||||
|
EthereumGetAddress(
|
||||||
|
address_n=[44 | HARDENED, 0 | HARDENED, 0 | HARDENED]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_with_keychain_from_chain_id(self):
|
||||||
|
@with_keychain_from_chain_id
|
||||||
|
async def handler_chain_id(ctx, msg, keychain):
|
||||||
|
network = by_chain_id(msg.chain_id)
|
||||||
|
# standard tests
|
||||||
|
self._check_keychain(keychain, network.slip44)
|
||||||
|
# provided address should succeed too
|
||||||
|
keychain.derive(msg.address_n)
|
||||||
|
|
||||||
|
await_result( # Ethereum
|
||||||
|
handler_chain_id(
|
||||||
|
wire.DUMMY_CONTEXT,
|
||||||
|
EthereumSignTx(
|
||||||
|
address_n=[44 | HARDENED, 60 | HARDENED, 0 | HARDENED],
|
||||||
|
chain_id=1,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
await_result( # Ethereum Classic
|
||||||
|
handler_chain_id(
|
||||||
|
wire.DUMMY_CONTEXT,
|
||||||
|
EthereumSignTx(
|
||||||
|
address_n=[44 | HARDENED, 61 | HARDENED, 0 | HARDENED],
|
||||||
|
chain_id=61,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
with self.assertRaises(wire.DataError):
|
||||||
|
await_result( # unknown chain_id
|
||||||
|
handler_chain_id(
|
||||||
|
wire.DUMMY_CONTEXT,
|
||||||
|
EthereumSignTx(
|
||||||
|
address_n=[44 | HARDENED, 60 | HARDENED, 0 | HARDENED],
|
||||||
|
chain_id=123456789,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
with self.assertRaises(wire.DataError):
|
||||||
|
await_result( # chain_id and network mismatch
|
||||||
|
handler_chain_id(
|
||||||
|
wire.DUMMY_CONTEXT,
|
||||||
|
EthereumSignTx(
|
||||||
|
address_n=[44 | HARDENED, 60 | HARDENED, 0 | HARDENED],
|
||||||
|
chain_id=2,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_missing_chain_id(self):
|
||||||
|
@with_keychain_from_chain_id
|
||||||
|
async def handler_chain_id(ctx, msg, keychain):
|
||||||
|
network = by_slip44(msg.address_n[1] & ~HARDENED)
|
||||||
|
# standard tests
|
||||||
|
self._check_keychain(keychain, network.slip44)
|
||||||
|
# provided address should succeed too
|
||||||
|
keychain.derive(msg.address_n)
|
||||||
|
|
||||||
|
await_result( # Ethereum
|
||||||
|
handler_chain_id(
|
||||||
|
wire.DUMMY_CONTEXT,
|
||||||
|
EthereumSignTx(
|
||||||
|
address_n=[44 | HARDENED, 60 | HARDENED, 0 | HARDENED],
|
||||||
|
chain_id=None,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
await_result( # Ethereum Classic
|
||||||
|
handler_chain_id(
|
||||||
|
wire.DUMMY_CONTEXT,
|
||||||
|
EthereumSignTx(
|
||||||
|
address_n=[44 | HARDENED, 61 | HARDENED, 0 | HARDENED],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
with self.assertRaises(wire.DataError):
|
||||||
|
await_result( # unknown slip44 id
|
||||||
|
handler_chain_id(
|
||||||
|
wire.DUMMY_CONTEXT,
|
||||||
|
EthereumSignTx(
|
||||||
|
address_n=[44 | HARDENED, 0 | HARDENED, 0 | HARDENED],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_wanchain(self):
|
||||||
|
@with_keychain_from_chain_id
|
||||||
|
async def handler_wanchain(ctx, msg, keychain):
|
||||||
|
self._check_keychain(keychain, 5718350)
|
||||||
|
# provided address should succeed too
|
||||||
|
keychain.derive(msg.address_n)
|
||||||
|
|
||||||
|
await_result(
|
||||||
|
handler_wanchain(
|
||||||
|
wire.DUMMY_CONTEXT,
|
||||||
|
EthereumSignTx(
|
||||||
|
address_n=[44 | HARDENED, 5718350 | HARDENED, 0 | HARDENED],
|
||||||
|
chain_id=3,
|
||||||
|
tx_type=6,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
108
core/tests/test_apps.wallet.keychain.py
Normal file
108
core/tests/test_apps.wallet.keychain.py
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
from common import *
|
||||||
|
from storage import cache
|
||||||
|
from trezor import wire
|
||||||
|
from trezor.crypto import bip39
|
||||||
|
from apps.common.paths import HARDENED
|
||||||
|
|
||||||
|
from apps.wallet.keychain import get_keychain_for_coin
|
||||||
|
|
||||||
|
|
||||||
|
class TestBitcoinKeychain(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
cache.start_session()
|
||||||
|
seed = bip39.seed(" ".join(["all"] * 12), "")
|
||||||
|
cache.set(cache.APP_COMMON_SEED, seed)
|
||||||
|
|
||||||
|
def test_bitcoin(self):
|
||||||
|
keychain, coin = await_result(
|
||||||
|
get_keychain_for_coin(wire.DUMMY_CONTEXT, "Bitcoin")
|
||||||
|
)
|
||||||
|
self.assertEqual(coin.coin_name, "Bitcoin")
|
||||||
|
|
||||||
|
valid_addresses = (
|
||||||
|
[44 | HARDENED, 0 | HARDENED],
|
||||||
|
[45 | HARDENED, 123456],
|
||||||
|
[48 | HARDENED, 0 | HARDENED],
|
||||||
|
[49 | HARDENED, 0 | HARDENED],
|
||||||
|
[84 | HARDENED, 0 | HARDENED],
|
||||||
|
)
|
||||||
|
invalid_addresses = (
|
||||||
|
[43 | HARDENED, 0 | HARDENED],
|
||||||
|
[44 | HARDENED, 1 | HARDENED],
|
||||||
|
)
|
||||||
|
|
||||||
|
for addr in valid_addresses:
|
||||||
|
keychain.derive(addr)
|
||||||
|
|
||||||
|
for addr in invalid_addresses:
|
||||||
|
self.assertRaises(wire.DataError, keychain.derive, addr)
|
||||||
|
|
||||||
|
def test_testnet(self):
|
||||||
|
keychain, coin = await_result(
|
||||||
|
get_keychain_for_coin(wire.DUMMY_CONTEXT, "Testnet")
|
||||||
|
)
|
||||||
|
self.assertEqual(coin.coin_name, "Testnet")
|
||||||
|
|
||||||
|
valid_addresses = (
|
||||||
|
[44 | HARDENED, 1 | HARDENED],
|
||||||
|
[45 | HARDENED, 123456],
|
||||||
|
[48 | HARDENED, 1 | HARDENED],
|
||||||
|
[49 | HARDENED, 1 | HARDENED],
|
||||||
|
[84 | HARDENED, 1 | HARDENED],
|
||||||
|
)
|
||||||
|
invalid_addresses = (
|
||||||
|
[43 | HARDENED, 1 | HARDENED],
|
||||||
|
[44 | HARDENED, 0 | HARDENED],
|
||||||
|
)
|
||||||
|
|
||||||
|
for addr in valid_addresses:
|
||||||
|
keychain.derive(addr)
|
||||||
|
|
||||||
|
for addr in invalid_addresses:
|
||||||
|
self.assertRaises(wire.DataError, keychain.derive, addr)
|
||||||
|
|
||||||
|
def test_unspecified(self):
|
||||||
|
keychain, coin = await_result(get_keychain_for_coin(wire.DUMMY_CONTEXT, None))
|
||||||
|
self.assertEqual(coin.coin_name, "Bitcoin")
|
||||||
|
keychain.derive([44 | HARDENED, 0 | HARDENED])
|
||||||
|
|
||||||
|
def test_unknown(self):
|
||||||
|
with self.assertRaises(wire.DataError):
|
||||||
|
await_result(get_keychain_for_coin(wire.DUMMY_CONTEXT, "MadeUpCoin2020"))
|
||||||
|
|
||||||
|
|
||||||
|
@unittest.skipUnless(not utils.BITCOIN_ONLY, "altcoin")
|
||||||
|
class TestAltcoinKeychains(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
cache.start_session()
|
||||||
|
seed = bip39.seed(" ".join(["all"] * 12), "")
|
||||||
|
cache.set(cache.APP_COMMON_SEED, seed)
|
||||||
|
|
||||||
|
def test_bcash(self):
|
||||||
|
keychain, coin = await_result(
|
||||||
|
get_keychain_for_coin(wire.DUMMY_CONTEXT, "Bcash")
|
||||||
|
)
|
||||||
|
self.assertEqual(coin.coin_name, "Bcash")
|
||||||
|
|
||||||
|
self.assertFalse(coin.segwit)
|
||||||
|
valid_addresses = (
|
||||||
|
[44 | HARDENED, 145 | HARDENED],
|
||||||
|
[45 | HARDENED, 123456],
|
||||||
|
[48 | HARDENED, 145 | HARDENED],
|
||||||
|
)
|
||||||
|
invalid_addresses = (
|
||||||
|
[43 | HARDENED, 145 | HARDENED],
|
||||||
|
[44 | HARDENED, 0 | HARDENED],
|
||||||
|
[49 | HARDENED, 145 | HARDENED],
|
||||||
|
[84 | HARDENED, 145 | HARDENED],
|
||||||
|
)
|
||||||
|
|
||||||
|
for addr in valid_addresses:
|
||||||
|
keychain.derive(addr)
|
||||||
|
|
||||||
|
for addr in invalid_addresses:
|
||||||
|
self.assertRaises(wire.DataError, keychain.derive, addr)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
Loading…
Reference in New Issue
Block a user