From 597402eab8741eee71cce2b5727b509fa27539f5 Mon Sep 17 00:00:00 2001 From: gabrielkerekes Date: Wed, 14 Apr 2021 09:40:28 +0200 Subject: [PATCH] refactor(core/cardano): decouple address parameters validation --- .../cardano/get_enterprise_address.json | 2 - .../fixtures/cardano/sign_tx.failed.json | 4 +- core/src/apps/cardano/address.py | 120 ++++++++---- core/src/apps/cardano/auxiliary_data.py | 24 +-- core/src/apps/cardano/certificates.py | 7 +- core/src/apps/cardano/get_address.py | 3 +- core/src/apps/cardano/helpers/__init__.py | 4 +- core/src/apps/cardano/sign_tx.py | 19 +- core/tests/test_apps.cardano.address.py | 179 +++++++----------- 9 files changed, 176 insertions(+), 186 deletions(-) diff --git a/common/tests/fixtures/cardano/get_enterprise_address.json b/common/tests/fixtures/cardano/get_enterprise_address.json index 4d5eee415..3b9a8c6de 100644 --- a/common/tests/fixtures/cardano/get_enterprise_address.json +++ b/common/tests/fixtures/cardano/get_enterprise_address.json @@ -8,7 +8,6 @@ "parameters": { "path": "m/1852'/1815'/0'/0/0", "address_type": "enterprise", - "staking_key_hash": "1bc428e4720702ebd5dab4fb175324c192dc9bb76cc5da956e3c8dff", "network_id": 1, "protocol_magic": 764824073 }, @@ -20,7 +19,6 @@ "parameters": { "path": "m/1852'/1815'/0'/0/0", "address_type": "enterprise", - "staking_key_hash": "1bc428e4720702ebd5dab4fb175324c192dc9bb76cc5da956e3c8dff", "network_id": 0, "protocol_magic": 42 }, diff --git a/common/tests/fixtures/cardano/sign_tx.failed.json b/common/tests/fixtures/cardano/sign_tx.failed.json index afc2367d2..355dbcf6a 100644 --- a/common/tests/fixtures/cardano/sign_tx.failed.json +++ b/common/tests/fixtures/cardano/sign_tx.failed.json @@ -230,7 +230,7 @@ ] }, "result": { - "error_message": "Output address network mismatch!" + "error_message": "Output address network mismatch" } }, { @@ -258,7 +258,7 @@ ] }, "result": { - "error_message": "Output address network mismatch!" + "error_message": "Output address network mismatch" } }, { diff --git a/core/src/apps/cardano/address.py b/core/src/apps/cardano/address.py index 5cf2b88ca..2445c1d97 100644 --- a/core/src/apps/cardano/address.py +++ b/core/src/apps/cardano/address.py @@ -1,9 +1,15 @@ -from trezor import wire from trezor.crypto import base58, hashlib from trezor.enums import CardanoAddressType from .byron_address import derive_byron_address, validate_byron_address -from .helpers import INVALID_ADDRESS, NETWORK_MISMATCH, bech32, network_ids +from .helpers import ( + ADDRESS_KEY_HASH_SIZE, + INVALID_ADDRESS, + INVALID_ADDRESS_PARAMETERS, + NETWORK_MISMATCH, + bech32, + network_ids, +) from .helpers.paths import SCHEMA_STAKING_ANY_ACCOUNT from .helpers.utils import derive_public_key, variable_length_encode from .seed import is_byron_path, is_shelley_path @@ -31,6 +37,70 @@ MIN_ADDRESS_BYTES_LENGTH = 29 MAX_ADDRESS_BYTES_LENGTH = 65 +def validate_address_parameters(parameters: CardanoAddressParametersType) -> None: + _validate_address_parameters_structure(parameters) + + if parameters.address_type == CardanoAddressType.BYRON: + if not is_byron_path(parameters.address_n): + raise INVALID_ADDRESS_PARAMETERS + elif parameters.address_type in ADDRESS_TYPES_SHELLEY: + if not is_shelley_path(parameters.address_n): + raise INVALID_ADDRESS_PARAMETERS + + if parameters.address_type == CardanoAddressType.BASE: + _validate_base_address_staking_info( + parameters.address_n_staking, parameters.staking_key_hash + ) + elif parameters.address_type == CardanoAddressType.POINTER: + if parameters.certificate_pointer is None: + raise INVALID_ADDRESS_PARAMETERS + elif parameters.address_type == CardanoAddressType.REWARD: + if not SCHEMA_STAKING_ANY_ACCOUNT.match(parameters.address_n): + raise INVALID_ADDRESS_PARAMETERS + else: + raise INVALID_ADDRESS_PARAMETERS + + +def _validate_address_parameters_structure( + parameters: CardanoAddressParametersType, +) -> None: + address_n_staking = parameters.address_n_staking + staking_key_hash = parameters.staking_key_hash + certificate_pointer = parameters.certificate_pointer + + fields_to_be_empty: tuple = () + if parameters.address_type in ( + CardanoAddressType.BYRON, + CardanoAddressType.REWARD, + CardanoAddressType.ENTERPRISE, + ): + fields_to_be_empty = (address_n_staking, staking_key_hash, certificate_pointer) + elif parameters.address_type == CardanoAddressType.BASE: + fields_to_be_empty = (certificate_pointer,) + elif parameters.address_type == CardanoAddressType.POINTER: + fields_to_be_empty = (address_n_staking, staking_key_hash) + + if any(fields_to_be_empty): + raise INVALID_ADDRESS_PARAMETERS + + +def _validate_base_address_staking_info( + staking_path: list[int], + staking_key_hash: bytes | None, +) -> None: + if staking_key_hash and staking_path: + raise INVALID_ADDRESS_PARAMETERS + + if staking_key_hash: + if len(staking_key_hash) != ADDRESS_KEY_HASH_SIZE: + raise INVALID_ADDRESS_PARAMETERS + elif staking_path: + if not SCHEMA_STAKING_ANY_ACCOUNT.match(staking_path): + raise INVALID_ADDRESS_PARAMETERS + else: + raise INVALID_ADDRESS_PARAMETERS + + def _validate_address_and_get_type( address: str, protocol_magic: int, network_id: int ) -> int: @@ -142,7 +212,7 @@ def _get_address_network_id(address: bytes) -> int: def get_public_key_hash(keychain: seed.Keychain, path: list[int]) -> bytes: public_key = derive_public_key(keychain, path) - return hashlib.blake2b(data=public_key, outlen=28).digest() + return hashlib.blake2b(data=public_key, outlen=ADDRESS_KEY_HASH_SIZE).digest() def derive_human_readable_address( @@ -180,31 +250,18 @@ def derive_address_bytes( is_byron_address = parameters.address_type == CardanoAddressType.BYRON if is_byron_address: - address = _derive_byron_address(keychain, parameters.address_n, protocol_magic) + address = derive_byron_address(keychain, parameters.address_n, protocol_magic) else: address = _derive_shelley_address(keychain, parameters, network_id) return address -def _derive_byron_address( - keychain: seed.Keychain, path: list[int], protocol_magic: int -) -> bytes: - if not is_byron_path(path): - raise wire.DataError("Invalid path for byron address!") - - address = derive_byron_address(keychain, path, protocol_magic) - return address - - def _derive_shelley_address( keychain: seed.Keychain, parameters: CardanoAddressParametersType, network_id: int, ) -> bytes: - if not is_shelley_path(parameters.address_n): - raise wire.DataError("Invalid path for shelley address!") - if parameters.address_type == CardanoAddressType.BASE: address = _derive_base_address( keychain, @@ -213,21 +270,22 @@ def _derive_shelley_address( parameters.staking_key_hash, network_id, ) - elif parameters.address_type == CardanoAddressType.ENTERPRISE: - address = _derive_enterprise_address(keychain, parameters.address_n, network_id) elif parameters.address_type == CardanoAddressType.POINTER: - if parameters.certificate_pointer is None: - raise wire.DataError("Certificate pointer data missing!") + # ensured by validate_address_parameters + assert parameters.certificate_pointer is not None + address = _derive_pointer_address( keychain, parameters.address_n, parameters.certificate_pointer, network_id, ) + elif parameters.address_type == CardanoAddressType.ENTERPRISE: + address = _derive_enterprise_address(keychain, parameters.address_n, network_id) elif parameters.address_type == CardanoAddressType.REWARD: address = _derive_reward_address(keychain, parameters.address_n, network_id) else: - raise wire.DataError("Invalid address type!") + raise INVALID_ADDRESS_PARAMETERS return address @@ -247,27 +305,12 @@ def _derive_base_address( header = _create_address_header(CardanoAddressType.BASE, network_id) spending_key_hash = get_public_key_hash(keychain, path) - _validate_base_address_staking_info(staking_path, staking_key_hash) - if staking_key_hash is None: staking_key_hash = get_public_key_hash(keychain, staking_path) return header + spending_key_hash + staking_key_hash -def _validate_base_address_staking_info( - staking_path: list[int], - staking_key_hash: bytes | None, -) -> None: - if (staking_key_hash is None) == (not staking_path): - raise wire.DataError( - "Base address needs either a staking path or a staking key hash!" - ) - - if staking_key_hash is None and not SCHEMA_STAKING_ANY_ACCOUNT.match(staking_path): - raise wire.DataError("Invalid staking path!") - - def _derive_pointer_address( keychain: seed.Keychain, path: list[int], @@ -305,9 +348,6 @@ def _derive_reward_address( path: list[int], network_id: int, ) -> bytes: - if not SCHEMA_STAKING_ANY_ACCOUNT.match(path): - raise wire.DataError("Invalid path for reward address!") - staking_key_hash = get_public_key_hash(keychain, path) return pack_reward_address_bytes(staking_key_hash, network_id) diff --git a/core/src/apps/cardano/auxiliary_data.py b/core/src/apps/cardano/auxiliary_data.py index da0379e16..3c12a8bb6 100644 --- a/core/src/apps/cardano/auxiliary_data.py +++ b/core/src/apps/cardano/auxiliary_data.py @@ -4,7 +4,11 @@ from trezor.enums import CardanoAddressType from apps.common import cbor -from .address import derive_address_bytes, derive_human_readable_address +from .address import ( + derive_address_bytes, + derive_human_readable_address, + validate_address_parameters, +) from .helpers import INVALID_AUXILIARY_DATA, bech32 from .helpers.bech32 import HRP_JORMUN_PUBLIC_KEY from .helpers.paths import SCHEMA_STAKING_ANY_ACCOUNT @@ -36,12 +40,7 @@ METADATA_KEY_CATALYST_REGISTRATION = 61284 METADATA_KEY_CATALYST_REGISTRATION_SIGNATURE = 61285 -def validate_auxiliary_data( - keychain: seed.Keychain, - auxiliary_data: CardanoTxAuxiliaryDataType | None, - protocol_magic: int, - network_id: int, -) -> None: +def validate_auxiliary_data(auxiliary_data: CardanoTxAuxiliaryDataType | None) -> None: if not auxiliary_data: return @@ -52,10 +51,7 @@ def validate_auxiliary_data( if auxiliary_data.catalyst_registration_parameters: fields_provided += 1 _validate_catalyst_registration_parameters( - keychain, - auxiliary_data.catalyst_registration_parameters, - protocol_magic, - network_id, + auxiliary_data.catalyst_registration_parameters ) if fields_provided != 1: @@ -72,10 +68,7 @@ def _validate_auxiliary_data_blob(auxiliary_data_blob: bytes) -> None: def _validate_catalyst_registration_parameters( - keychain: seed.Keychain, catalyst_registration_parameters: CardanoCatalystRegistrationParametersType, - protocol_magic: int, - network_id: int, ) -> None: if ( len(catalyst_registration_parameters.voting_public_key) @@ -92,8 +85,7 @@ def _validate_catalyst_registration_parameters( if address_parameters.address_type == CardanoAddressType.BYRON: raise INVALID_AUXILIARY_DATA - # try to derive the address to validate it - derive_address_bytes(keychain, address_parameters, protocol_magic, network_id) + validate_address_parameters(address_parameters) async def show_auxiliary_data( diff --git a/core/src/apps/cardano/certificates.py b/core/src/apps/cardano/certificates.py index caea2ac1a..8860481a7 100644 --- a/core/src/apps/cardano/certificates.py +++ b/core/src/apps/cardano/certificates.py @@ -7,7 +7,7 @@ from .address import ( get_public_key_hash, validate_reward_address, ) -from .helpers import INVALID_CERTIFICATE, LOVELACE_MAX_SUPPLY +from .helpers import ADDRESS_KEY_HASH_SIZE, INVALID_CERTIFICATE, LOVELACE_MAX_SUPPLY from .helpers.paths import SCHEMA_STAKING_ANY_ACCOUNT if False: @@ -26,7 +26,6 @@ if False: POOL_HASH_SIZE = 28 VRF_KEY_HASH_SIZE = 32 POOL_METADATA_HASH_SIZE = 32 -PUBLIC_KEY_HASH_SIZE = 28 IPV4_ADDRESS_SIZE = 4 IPV6_ADDRESS_SIZE = 16 @@ -140,7 +139,9 @@ def _validate_pool_owners(owners: list[CardanoPoolOwnerType]) -> None: owner.staking_key_hash is not None or owner.staking_key_path is not None ) if owner.staking_key_hash is not None: - assert_certificate_cond(len(owner.staking_key_hash) == PUBLIC_KEY_HASH_SIZE) + assert_certificate_cond( + len(owner.staking_key_hash) == ADDRESS_KEY_HASH_SIZE + ) if owner.staking_key_path: assert_certificate_cond( SCHEMA_STAKING_ANY_ACCOUNT.match(owner.staking_key_path) diff --git a/core/src/apps/cardano/get_address.py b/core/src/apps/cardano/get_address.py index eee172c41..3891c6450 100644 --- a/core/src/apps/cardano/get_address.py +++ b/core/src/apps/cardano/get_address.py @@ -5,7 +5,7 @@ from apps.common import paths from apps.common.layout import address_n_to_str, show_qr from . import seed -from .address import derive_human_readable_address +from .address import derive_human_readable_address, validate_address_parameters from .helpers import protocol_magics, staking_use_cases from .helpers.paths import SCHEMA_ADDRESS from .helpers.utils import to_account_path @@ -38,6 +38,7 @@ async def get_address( ) validate_network_info(msg.network_id, msg.protocol_magic) + validate_address_parameters(address_parameters) try: address = derive_human_readable_address( diff --git a/core/src/apps/cardano/helpers/__init__.py b/core/src/apps/cardano/helpers/__init__.py index 31b6b11c3..ef27610cc 100644 --- a/core/src/apps/cardano/helpers/__init__.py +++ b/core/src/apps/cardano/helpers/__init__.py @@ -1,7 +1,8 @@ from trezor import wire INVALID_ADDRESS = wire.ProcessError("Invalid address") -NETWORK_MISMATCH = wire.ProcessError("Output address network mismatch!") +INVALID_ADDRESS_PARAMETERS = wire.ProcessError("Invalid address parameters") +NETWORK_MISMATCH = wire.ProcessError("Output address network mismatch") INVALID_CERTIFICATE = wire.ProcessError("Invalid certificate") INVALID_WITHDRAWAL = wire.ProcessError("Invalid withdrawal") INVALID_TOKEN_BUNDLE_OUTPUT = wire.ProcessError("Invalid token bundle in output") @@ -14,3 +15,4 @@ INVALID_STAKEPOOL_REGISTRATION_TX_INPUTS = wire.ProcessError( ) LOVELACE_MAX_SUPPLY = 45_000_000_000 * 1_000_000 +ADDRESS_KEY_HASH_SIZE = 28 diff --git a/core/src/apps/cardano/sign_tx.py b/core/src/apps/cardano/sign_tx.py index c50d71bc8..3b0bcc6b0 100644 --- a/core/src/apps/cardano/sign_tx.py +++ b/core/src/apps/cardano/sign_tx.py @@ -17,6 +17,7 @@ from .address import ( derive_address_bytes, derive_human_readable_address, get_address_bytes_unsafe, + validate_address_parameters, validate_output_address, ) from .auxiliary_data import ( @@ -135,12 +136,10 @@ async def _sign_ordinary_tx( ctx, keychain, i.address_n, SCHEMA_ADDRESS.match(i.address_n) ) - _validate_outputs(keychain, msg.outputs, msg.protocol_magic, msg.network_id) + _validate_outputs(msg.outputs, msg.protocol_magic, msg.network_id) _validate_certificates(msg.certificates, msg.protocol_magic, msg.network_id) _validate_withdrawals(msg.withdrawals) - validate_auxiliary_data( - keychain, msg.auxiliary_data, msg.protocol_magic, msg.network_id - ) + validate_auxiliary_data(msg.auxiliary_data) # display the transaction in UI await _show_standard_tx(ctx, keychain, msg) @@ -166,11 +165,9 @@ async def _sign_stake_pool_registration_tx( _validate_stake_pool_registration_tx_structure(msg) _ensure_no_signing_inputs(msg.inputs) - _validate_outputs(keychain, msg.outputs, msg.protocol_magic, msg.network_id) + _validate_outputs(msg.outputs, msg.protocol_magic, msg.network_id) _validate_certificates(msg.certificates, msg.protocol_magic, msg.network_id) - validate_auxiliary_data( - keychain, msg.auxiliary_data, msg.protocol_magic, msg.network_id - ) + validate_auxiliary_data(msg.auxiliary_data) await _show_stake_pool_registration_tx(ctx, keychain, msg) @@ -209,7 +206,6 @@ def _validate_stake_pool_registration_tx_structure(msg: CardanoSignTx) -> None: def _validate_outputs( - keychain: seed.Keychain, outputs: list[CardanoTxOutputType], protocol_magic: int, network_id: int, @@ -218,10 +214,7 @@ def _validate_outputs( for output in outputs: total_amount += output.amount if output.address_parameters: - # try to derive the address to validate it - derive_address_bytes( - keychain, output.address_parameters, protocol_magic, network_id - ) + validate_address_parameters(output.address_parameters) elif output.address is not None: validate_output_address(output.address, protocol_magic, network_id) else: diff --git a/core/tests/test_apps.cardano.address.py b/core/tests/test_apps.cardano.address.py index 863cffb0e..574c692d2 100644 --- a/core/tests/test_apps.cardano.address.py +++ b/core/tests/test_apps.cardano.address.py @@ -8,7 +8,7 @@ from trezor.messages import CardanoBlockchainPointerType from apps.common import HARDENED, seed if not utils.BITCOIN_ONLY: - from apps.cardano.address import derive_human_readable_address + from apps.cardano.address import derive_human_readable_address, validate_address_parameters from apps.cardano.byron_address import _address_hash from apps.cardano.helpers import network_ids, protocol_magics from apps.cardano.seed import Keychain @@ -335,32 +335,6 @@ class TestCardanoAddress(unittest.TestCase): self.assertEqual(actual_address, expected_address) - def test_base_address_with_invalid_parameters(self): - mnemonic = "test walk nut penalty hip pave soap entry language right filter choice" - passphrase = "" - node = bip32.from_mnemonic_cardano(mnemonic, passphrase) - keychain = Keychain(node) - - # both address_n_staking and staking_key_hash are None - with self.assertRaises(wire.DataError): - address_parameters = CardanoAddressParametersType( - address_type=CardanoAddressType.BASE, - address_n=[1852 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0], - address_n_staking=None, - staking_key_hash=None, - ) - derive_human_readable_address(keychain, address_parameters, 0, 0) - - # address_n_staking is not a staking path - with self.assertRaises(wire.DataError): - address_parameters = CardanoAddressParametersType( - address_type=CardanoAddressType.BASE, - address_n=[1852 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0], - address_n_staking=[1852 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0], - staking_key_hash=None, - ) - derive_human_readable_address(keychain, address_parameters, 0, 0) - def test_enterprise_address(self): mnemonic = "test walk nut penalty hip pave soap entry language right filter choice" passphrase = "" @@ -404,21 +378,6 @@ class TestCardanoAddress(unittest.TestCase): self.assertEqual(actual_address, expected_address) - def test_pointer_address_invalid_pointers(self): - mnemonic = "test walk nut penalty hip pave soap entry language right filter choice" - passphrase = "" - node = bip32.from_mnemonic_cardano(mnemonic, passphrase) - keychain = Keychain(node) - - # pointer is None - with self.assertRaises(wire.DataError): - address_parameters = CardanoAddressParametersType( - address_type=CardanoAddressType.POINTER, - address_n=[1852 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0], - certificate_pointer=None, - ) - derive_human_readable_address(keychain, address_parameters, 0, 0) - def test_reward_address(self): mnemonic = "test walk nut penalty hip pave soap entry language right filter choice" passphrase = "" @@ -440,95 +399,99 @@ class TestCardanoAddress(unittest.TestCase): self.assertEqual(actual_address, expected_address) - def test_reward_address_with_non_staking_path(self): - mnemonic = "test walk nut penalty hip pave soap entry language right filter choice" + def test_testnet_byron_address(self): + mnemonic = "all all all all all all all all all all all all" passphrase = "" node = bip32.from_mnemonic_cardano(mnemonic, passphrase) keychain = Keychain(node) - with self.assertRaises(wire.DataError): + addresses = [ + "2657WMsDfac5F3zbgs9BwNWx3dhGAJERkAL93gPa68NJ2i8mbCHm2pLUHWSj8Mfea", + "2657WMsDfac6ezKWszxLFqJjSUgpg9NgxKc1koqi24sVpRaPhiwMaExk4useKn5HA", + "2657WMsDfac7hr1ioJGr6g7r6JRx4r1My8Rj91tcPTeVjJDpfBYKURrPG2zVLx2Sq", + ] + + for i, expected in enumerate(addresses): + # 44'/1815'/0'/0/i' address_parameters = CardanoAddressParametersType( - address_type=CardanoAddressType.REWARD, - address_n=[44 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0] + address_type=CardanoAddressType.BYRON, + address_n=[0x80000000 | 44, 0x80000000 | 1815, 0x80000000, 0, i], ) - derive_human_readable_address(keychain, address_parameters, 0, 0) + address = derive_human_readable_address(keychain, address_parameters, protocol_magics.TESTNET, 0) + self.assertEqual(expected, address) - def test_shelley_address_with_byron_namespace(self): - """ - It shouldn't be possible to derive Shelley addresses - (Base, Pointer, Enterprise, Reward) with a Byron namespace (44') - """ - mnemonic = "test walk nut penalty hip pave soap entry language right filter choice" - passphrase = "" - node = bip32.from_mnemonic_cardano(mnemonic, passphrase) - keychain = Keychain(node) + def test_validate_address_parameters(self): + test_vectors = [ + # base address - both address_n_staking and staking_key_hash are None + CardanoAddressParametersType( + address_type=CardanoAddressType.BASE, + address_n=[1852 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0], + address_n_staking=None, + staking_key_hash=None, + ), + # base address - both address_n_staking and staking_key_hash are set + CardanoAddressParametersType( + address_type=CardanoAddressType.BASE, + address_n=[1852 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0], + address_n_staking=[1852 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 2, 0], + staking_key_hash=unhexlify("1bc428e4720702ebd5dab4fb175324c192dc9bb76cc5da956e3c8dff"), + ), + # base address - staking_key_hash is too short + CardanoAddressParametersType( + address_type=CardanoAddressType.BASE, + address_n=[1852 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0], + address_n_staking=None, + staking_key_hash=unhexlify("1bc428e4720702ebd5dab4fb175324c192dc9bb76cc5da956e3c8d"), + ), + # base address - address_n_staking is not a staking path + CardanoAddressParametersType( + address_type=CardanoAddressType.BASE, + address_n=[1852 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0], + address_n_staking=[1852 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0], + staking_key_hash=None, + ), + # pointer address - pointer is None + CardanoAddressParametersType( + address_type=CardanoAddressType.POINTER, + address_n=[1852 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0], + certificate_pointer=None, + ), + # reward address - non staking path + CardanoAddressParametersType( + address_type=CardanoAddressType.REWARD, + address_n=[1852 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0] + ), - with self.assertRaises(wire.DataError): - address_parameters = CardanoAddressParametersType( + # Shelley addresses with Byron namespace + CardanoAddressParametersType( address_type=CardanoAddressType.BASE, address_n=[44 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0] - ) - derive_human_readable_address(keychain, address_parameters, 0, 0) - - with self.assertRaises(wire.DataError): - address_parameters = CardanoAddressParametersType( + ), + CardanoAddressParametersType( address_type=CardanoAddressType.POINTER, address_n=[44 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0], certificate_pointer=CardanoBlockchainPointerType(block_index=0, tx_index=0, certificate_index=0) - ) - derive_human_readable_address(keychain, address_parameters, 0, 0) - - with self.assertRaises(wire.DataError): - address_parameters = CardanoAddressParametersType( + ), + CardanoAddressParametersType( address_type=CardanoAddressType.ENTERPRISE, address_n=[44 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0], - ) - derive_human_readable_address(keychain, address_parameters, 0, 0) - - with self.assertRaises(wire.DataError): - address_parameters = CardanoAddressParametersType( + ), + CardanoAddressParametersType( address_type=CardanoAddressType.REWARD, address_n=[44 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0], - ) - derive_human_readable_address(keychain, address_parameters, 0, 0) - - def test_byron_address_with_shelley_namespace(self): - """ - It shouldn't be possible to derive Byron addresses - with a Shelley namespace (1852') - """ - mnemonic = "all all all all all all all all all all all all" - passphrase = "" - node = bip32.from_mnemonic_cardano(mnemonic, passphrase) - keychain = Keychain(node) + ), - with self.assertRaises(wire.DataError): - address_parameters = CardanoAddressParametersType( + # Byron address with Shelley namespace + CardanoAddressParametersType( address_type=CardanoAddressType.BYRON, address_n=[1852 | HARDENED, 1815 | HARDENED, 0 | HARDENED, 0, 0], ) - derive_human_readable_address(keychain, address_parameters, 0, 0) - - def test_testnet_byron_address(self): - mnemonic = "all all all all all all all all all all all all" - passphrase = "" - node = bip32.from_mnemonic_cardano(mnemonic, passphrase) - keychain = Keychain(node) - - addresses = [ - "2657WMsDfac5F3zbgs9BwNWx3dhGAJERkAL93gPa68NJ2i8mbCHm2pLUHWSj8Mfea", - "2657WMsDfac6ezKWszxLFqJjSUgpg9NgxKc1koqi24sVpRaPhiwMaExk4useKn5HA", - "2657WMsDfac7hr1ioJGr6g7r6JRx4r1My8Rj91tcPTeVjJDpfBYKURrPG2zVLx2Sq", ] - for i, expected in enumerate(addresses): - # 44'/1815'/0'/0/i' - address_parameters = CardanoAddressParametersType( - address_type=CardanoAddressType.BYRON, - address_n=[0x80000000 | 44, 0x80000000 | 1815, 0x80000000, 0, i], - ) - address = derive_human_readable_address(keychain, address_parameters, protocol_magics.TESTNET, 0) - self.assertEqual(expected, address) + for address_parameters in test_vectors: + with self.assertRaises(wire.ProcessError): + validate_address_parameters(address_parameters) + if __name__ == '__main__': unittest.main()