mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-27 00:28:10 +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 storage import cache
|
||||
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 trezor import wire
|
||||
from trezor.crypto import bip39
|
||||
@ -112,6 +114,63 @@ class TestKeychain(unittest.TestCase):
|
||||
with self.assertRaises(wire.DataError):
|
||||
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__':
|
||||
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