From 445f56d387471d6d6c99fa01c8d5e22b6a21868e Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Fri, 15 May 2020 18:35:09 +0000 Subject: [PATCH] core/bitcoin: finalize bitcoin refactor - core/bitcoin: move common files to the app's root - core/bitcoin: use require_confirm instead of confirm - core: move bitcoin unrelated functions from 'bitcoin' to a new 'misc' app - core/bitcoin: use relative imports inside the app - core: rename wallet app to bitcoin - core/wallet: replace SigningErrors and the other exception classes with wire.Errors --- core/SConscript.firmware | 15 ++-- core/SConscript.unix | 15 ++-- core/src/apps/{wallet => bitcoin}/__init__.py | 4 - .../{wallet/sign_tx => bitcoin}/addresses.py | 82 ++++--------------- core/src/apps/bitcoin/common.py | 42 ++++++++++ .../apps/{wallet => bitcoin}/get_address.py | 4 +- .../{wallet => bitcoin}/get_public_key.py | 0 core/src/apps/{wallet => bitcoin}/keychain.py | 0 .../{wallet/sign_tx => bitcoin}/multisig.py | 14 ++-- .../{wallet/sign_tx => bitcoin}/scripts.py | 46 +++++------ .../apps/{wallet => bitcoin}/sign_message.py | 2 +- .../{wallet => bitcoin}/sign_tx/__init__.py | 19 +---- .../{wallet => bitcoin}/sign_tx/bitcoin.py | 75 ++++++----------- .../sign_tx/bitcoinlike.py | 16 ++-- .../{wallet => bitcoin}/sign_tx/decred.py | 25 +++--- .../{wallet => bitcoin}/sign_tx/helpers.py | 78 ++++++------------ .../{wallet => bitcoin}/sign_tx/layout.py | 40 ++++----- .../{wallet => bitcoin}/sign_tx/matchcheck.py | 9 +- .../apps/{wallet => bitcoin}/sign_tx/omni.py | 0 .../{wallet => bitcoin}/sign_tx/progress.py | 0 .../{wallet => bitcoin}/sign_tx/tx_weight.py | 0 .../apps/{wallet => bitcoin}/sign_tx/zcash.py | 36 +++----- .../{wallet => bitcoin}/verify_message.py | 7 +- .../{wallet/sign_tx => bitcoin}/writers.py | 0 core/src/apps/common/signverify.py | 2 +- core/src/apps/lisk/sign_message.py | 2 +- core/src/apps/misc/__init__.py | 9 ++ .../apps/{wallet => misc}/cipher_key_value.py | 0 .../{wallet => misc}/get_ecdh_session_key.py | 6 +- core/src/apps/{wallet => misc}/get_entropy.py | 0 .../apps/{wallet => misc}/sign_identity.py | 0 core/src/apps/wallet/sign_tx/common.py | 12 --- core/src/main.py | 6 +- ...ddress.py => test_apps.bitcoin.address.py} | 10 +-- ...rs.py => test_apps.bitcoin.address_grs.py} | 4 +- ...ps.bitcoin.segwit.bip143.native_p2wpkh.py} | 6 +- ...s.bitcoin.segwit.bip143.p2wpkh_in_p2sh.py} | 6 +- ...ps.bitcoin.segwit.signtx.native_p2wpkh.py} | 8 +- ...itcoin.segwit.signtx.native_p2wpkh_grs.py} | 4 +- ...s.bitcoin.segwit.signtx.p2wpkh_in_p2sh.py} | 9 +- ...tcoin.segwit.signtx.p2wpkh_in_p2sh_grs.py} | 4 +- ...y => test_apps.bitcoin.sign_tx.writers.py} | 3 +- ...test_apps.bitcoin.signtx.fee_threshold.py} | 2 +- ...ni.py => test_apps.bitcoin.signtx.omni.py} | 2 +- ....signtx.py => test_apps.bitcoin.signtx.py} | 4 +- ...grs.py => test_apps.bitcoin.signtx_grs.py} | 4 +- ...eight.py => test_apps.bitcoin.txweight.py} | 4 +- ...3.py => test_apps.bitcoin.zcash.zip143.py} | 4 +- ...3.py => test_apps.bitcoin.zcash.zip243.py} | 4 +- core/tests/test_apps.common.seed.py | 4 +- core/tests/test_apps.wallet.keychain.py | 2 +- docs/core/src/apps.md | 4 +- 52 files changed, 275 insertions(+), 379 deletions(-) rename core/src/apps/{wallet => bitcoin}/__init__.py (59%) rename core/src/apps/{wallet/sign_tx => bitcoin}/addresses.py (77%) create mode 100644 core/src/apps/bitcoin/common.py rename core/src/apps/{wallet => bitcoin}/get_address.py (97%) rename core/src/apps/{wallet => bitcoin}/get_public_key.py (100%) rename core/src/apps/{wallet => bitcoin}/keychain.py (100%) rename core/src/apps/{wallet/sign_tx => bitcoin}/multisig.py (85%) rename core/src/apps/{wallet/sign_tx => bitcoin}/scripts.py (90%) rename core/src/apps/{wallet => bitcoin}/sign_message.py (95%) rename core/src/apps/{wallet => bitcoin}/sign_tx/__init__.py (82%) rename core/src/apps/{wallet => bitcoin}/sign_tx/bitcoin.py (89%) rename core/src/apps/{wallet => bitcoin}/sign_tx/bitcoinlike.py (87%) rename core/src/apps/{wallet => bitcoin}/sign_tx/decred.py (89%) rename core/src/apps/{wallet => bitcoin}/sign_tx/helpers.py (78%) rename core/src/apps/{wallet => bitcoin}/sign_tx/layout.py (73%) rename core/src/apps/{wallet => bitcoin}/sign_tx/matchcheck.py (93%) rename core/src/apps/{wallet => bitcoin}/sign_tx/omni.py (100%) rename core/src/apps/{wallet => bitcoin}/sign_tx/progress.py (100%) rename core/src/apps/{wallet => bitcoin}/sign_tx/tx_weight.py (100%) rename core/src/apps/{wallet => bitcoin}/sign_tx/zcash.py (83%) rename core/src/apps/{wallet => bitcoin}/verify_message.py (97%) rename core/src/apps/{wallet/sign_tx => bitcoin}/writers.py (100%) create mode 100644 core/src/apps/misc/__init__.py rename core/src/apps/{wallet => misc}/cipher_key_value.py (100%) rename core/src/apps/{wallet => misc}/get_ecdh_session_key.py (95%) rename core/src/apps/{wallet => misc}/get_entropy.py (100%) rename core/src/apps/{wallet => misc}/sign_identity.py (100%) delete mode 100644 core/src/apps/wallet/sign_tx/common.py rename core/tests/{test_apps.wallet.address.py => test_apps.bitcoin.address.py} (98%) rename core/tests/{test_apps.wallet.address_grs.py => test_apps.bitcoin.address_grs.py} (97%) rename core/tests/{test_apps.wallet.segwit.bip143.native_p2wpkh.py => test_apps.bitcoin.segwit.bip143.native_p2wpkh.py} (96%) rename core/tests/{test_apps.wallet.segwit.bip143.p2wpkh_in_p2sh.py => test_apps.bitcoin.segwit.bip143.p2wpkh_in_p2sh.py} (95%) rename core/tests/{test_apps.wallet.segwit.signtx.native_p2wpkh.py => test_apps.bitcoin.segwit.signtx.native_p2wpkh.py} (98%) rename core/tests/{test_apps.wallet.segwit.signtx.native_p2wpkh_grs.py => test_apps.bitcoin.segwit.signtx.native_p2wpkh_grs.py} (98%) rename core/tests/{test_apps.wallet.segwit.signtx.p2wpkh_in_p2sh.py => test_apps.bitcoin.segwit.signtx.p2wpkh_in_p2sh.py} (98%) rename core/tests/{test_apps.wallet.segwit.signtx.p2wpkh_in_p2sh_grs.py => test_apps.bitcoin.segwit.signtx.p2wpkh_in_p2sh_grs.py} (99%) rename core/tests/{test_apps.wallet.sign_tx.writers.py => test_apps.bitcoin.sign_tx.writers.py} (95%) rename core/tests/{test_apps.wallet.signtx.fee_threshold.py => test_apps.bitcoin.signtx.fee_threshold.py} (99%) rename core/tests/{test_apps.wallet.signtx.omni.py => test_apps.bitcoin.signtx.omni.py} (95%) rename core/tests/{test_apps.wallet.signtx.py => test_apps.bitcoin.signtx.py} (98%) rename core/tests/{test_apps.wallet.signtx_grs.py => test_apps.bitcoin.signtx_grs.py} (98%) rename core/tests/{test_apps.wallet.txweight.py => test_apps.bitcoin.txweight.py} (97%) rename core/tests/{test_apps.wallet.zcash.zip143.py => test_apps.bitcoin.zcash.zip143.py} (98%) rename core/tests/{test_apps.wallet.zcash.zip243.py => test_apps.bitcoin.zcash.zip243.py} (98%) diff --git a/core/SConscript.firmware b/core/SConscript.firmware index 7019b46ec..4e16a0f62 100644 --- a/core/SConscript.firmware +++ b/core/SConscript.firmware @@ -492,11 +492,13 @@ if FROZEN: SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/homescreen/*.py')) SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/management/*.py')) SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/management/*/*.py')) - SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/wallet/*.py')) - SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/wallet/*/*.py', + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/misc/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/*/*.py', exclude=[ - SOURCE_PY_DIR + 'apps/wallet/sign_tx/decred.py', - SOURCE_PY_DIR + 'apps/wallet/sign_tx/zcash.py', + SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/decred.py', + SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/bitcoinlike.py', + SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/zcash.py', ]) ) @@ -540,8 +542,9 @@ if FROZEN: SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/webauthn/*.py')) - SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/wallet/sign_tx/decred.py')) - SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/wallet/sign_tx/zcash.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/decred.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/bitcoinlike.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/zcash.py')) source_mpy = env.FrozenModule(source=SOURCE_PY, source_dir=SOURCE_PY_DIR, bitcoin_only=BITCOIN_ONLY) diff --git a/core/SConscript.unix b/core/SConscript.unix index 377aba361..0c998d90f 100644 --- a/core/SConscript.unix +++ b/core/SConscript.unix @@ -460,11 +460,13 @@ if FROZEN: SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/homescreen/*.py')) SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/management/*.py')) SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/management/*/*.py')) - SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/wallet/*.py')) - SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/wallet/*/*.py', + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/misc/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/*.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/*/*.py', exclude=[ - SOURCE_PY_DIR + 'apps/wallet/sign_tx/decred.py', - SOURCE_PY_DIR + 'apps/wallet/sign_tx/zcash.py', + SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/decred.py', + SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/bitcoinlike.py', + SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/zcash.py', ]) ) @@ -508,8 +510,9 @@ if FROZEN: SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/webauthn/*.py')) - SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/wallet/sign_tx/decred.py')) - SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/wallet/sign_tx/zcash.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/decred.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/bitcoinlike.py')) + SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/zcash.py')) source_mpy = env.FrozenModule(source=SOURCE_PY, source_dir=SOURCE_PY_DIR, bitcoin_only=BITCOIN_ONLY) diff --git a/core/src/apps/wallet/__init__.py b/core/src/apps/bitcoin/__init__.py similarity index 59% rename from core/src/apps/wallet/__init__.py rename to core/src/apps/bitcoin/__init__.py index 6d15518bd..5377055ad 100644 --- a/core/src/apps/wallet/__init__.py +++ b/core/src/apps/bitcoin/__init__.py @@ -5,10 +5,6 @@ from trezor.messages import MessageType def boot() -> None: wire.add(MessageType.GetPublicKey, __name__, "get_public_key") wire.add(MessageType.GetAddress, __name__, "get_address") - wire.add(MessageType.GetEntropy, __name__, "get_entropy") wire.add(MessageType.SignTx, __name__, "sign_tx") wire.add(MessageType.SignMessage, __name__, "sign_message") wire.add(MessageType.VerifyMessage, __name__, "verify_message") - wire.add(MessageType.SignIdentity, __name__, "sign_identity") - wire.add(MessageType.GetECDHSessionKey, __name__, "get_ecdh_session_key") - wire.add(MessageType.CipherKeyValue, __name__, "cipher_key_value") diff --git a/core/src/apps/wallet/sign_tx/addresses.py b/core/src/apps/bitcoin/addresses.py similarity index 77% rename from core/src/apps/wallet/sign_tx/addresses.py rename to core/src/apps/bitcoin/addresses.py index 522611ceb..a7b173bff 100644 --- a/core/src/apps/wallet/sign_tx/addresses.py +++ b/core/src/apps/bitcoin/addresses.py @@ -1,31 +1,21 @@ -from micropython import const - -from trezor.crypto import base58, bech32, cashaddr +from trezor import wire +from trezor.crypto import base58, cashaddr from trezor.crypto.hashlib import sha256 -from trezor.messages import FailureType, InputScriptType +from trezor.messages import InputScriptType from trezor.messages.MultisigRedeemScriptType import MultisigRedeemScriptType -from trezor.utils import ensure + +from .common import ecdsa_hash_pubkey, encode_bech32_address +from .multisig import multisig_get_pubkeys, multisig_pubkey_index +from .scripts import output_script_multisig, output_script_native_p2wpkh_or_p2wsh from apps.common import HARDENED, address_type, paths from apps.common.coininfo import CoinInfo -from apps.wallet.sign_tx.multisig import multisig_get_pubkeys, multisig_pubkey_index -from apps.wallet.sign_tx.scripts import ( - output_script_multisig, - output_script_native_p2wpkh_or_p2wsh, -) if False: from typing import List from trezor.crypto import bip32 from trezor.messages.TxInputType import EnumTypeInputScriptType -# supported witness version for bech32 addresses -_BECH32_WITVER = const(0x00) - - -class AddressError(Exception): - pass - def get_address( script_type: EnumTypeInputScriptType, @@ -42,11 +32,9 @@ def get_address( pubkey = node.public_key() index = multisig_pubkey_index(multisig, pubkey) if index is None: - raise AddressError(FailureType.ProcessError, "Public key not found") + raise wire.ProcessError("Public key not found") if coin.address_type_p2sh is None: - raise AddressError( - FailureType.ProcessError, "Multisig not enabled on this coin" - ) + raise wire.ProcessError("Multisig not enabled on this coin") pubkeys = multisig_get_pubkeys(multisig) address = address_multisig_p2sh(pubkeys, multisig.m, coin) @@ -54,7 +42,7 @@ def get_address( address = address_to_cashaddr(address, coin) return address if script_type == InputScriptType.SPENDMULTISIG: - raise AddressError(FailureType.ProcessError, "Multisig details required") + raise wire.ProcessError("Multisig details required") # p2pkh address = node.address(coin.address_type) @@ -64,9 +52,7 @@ def get_address( elif script_type == InputScriptType.SPENDWITNESS: # native p2wpkh or native p2wsh if not coin.segwit or not coin.bech32_prefix: - raise AddressError( - FailureType.ProcessError, "Segwit not enabled on this coin" - ) + raise wire.ProcessError("Segwit not enabled on this coin") # native p2wsh multisig if multisig is not None: pubkeys = multisig_get_pubkeys(multisig) @@ -79,9 +65,7 @@ def get_address( script_type == InputScriptType.SPENDP2SHWITNESS ): # p2wpkh or p2wsh nested in p2sh if not coin.segwit or coin.address_type_p2sh is None: - raise AddressError( - FailureType.ProcessError, "Segwit not enabled on this coin" - ) + raise wire.ProcessError("Segwit not enabled on this coin") # p2wsh multisig nested in p2sh if multisig is not None: pubkeys = multisig_get_pubkeys(multisig) @@ -91,14 +75,12 @@ def get_address( return address_p2wpkh_in_p2sh(node.public_key(), coin) else: - raise AddressError(FailureType.ProcessError, "Invalid script type") + raise wire.ProcessError("Invalid script type") def address_multisig_p2sh(pubkeys: List[bytes], m: int, coin: CoinInfo) -> str: if coin.address_type_p2sh is None: - raise AddressError( - FailureType.ProcessError, "Multisig not enabled on this coin" - ) + raise wire.ProcessError("Multisig not enabled on this coin") redeem_script = output_script_multisig(pubkeys, m) redeem_script_hash = coin.script_hash(redeem_script) return address_p2sh(redeem_script_hash, coin) @@ -106,9 +88,7 @@ def address_multisig_p2sh(pubkeys: List[bytes], m: int, coin: CoinInfo) -> str: def address_multisig_p2wsh_in_p2sh(pubkeys: List[bytes], m: int, coin: CoinInfo) -> str: if coin.address_type_p2sh is None: - raise AddressError( - FailureType.ProcessError, "Multisig not enabled on this coin" - ) + raise wire.ProcessError("Multisig not enabled on this coin") witness_script = output_script_multisig(pubkeys, m) witness_script_hash = sha256(witness_script).digest() return address_p2wsh_in_p2sh(witness_script_hash, coin) @@ -116,9 +96,7 @@ def address_multisig_p2wsh_in_p2sh(pubkeys: List[bytes], m: int, coin: CoinInfo) def address_multisig_p2wsh(pubkeys: List[bytes], m: int, hrp: str) -> str: if not hrp: - raise AddressError( - FailureType.ProcessError, "Multisig not enabled on this coin" - ) + raise wire.ProcessError("Multisig not enabled on this coin") witness_script = output_script_multisig(pubkeys, m) witness_script_hash = sha256(witness_script).digest() return address_p2wsh(witness_script_hash, hrp) @@ -149,24 +127,11 @@ def address_p2wsh_in_p2sh(witness_script_hash: bytes, coin: CoinInfo) -> str: def address_p2wpkh(pubkey: bytes, coin: CoinInfo) -> str: pubkeyhash = ecdsa_hash_pubkey(pubkey, coin) - address = bech32.encode(coin.bech32_prefix, _BECH32_WITVER, pubkeyhash) - if address is None: - raise AddressError(FailureType.ProcessError, "Invalid address") - return address + return encode_bech32_address(coin.bech32_prefix, pubkeyhash) def address_p2wsh(witness_script_hash: bytes, hrp: str) -> str: - address = bech32.encode(hrp, _BECH32_WITVER, witness_script_hash) - if address is None: - raise AddressError(FailureType.ProcessError, "Invalid address") - return address - - -def decode_bech32_address(prefix: str, address: str) -> bytes: - witver, raw = bech32.decode(prefix, address) - if witver != _BECH32_WITVER: - raise AddressError(FailureType.ProcessError, "Invalid address witness program") - return bytes(raw) + return encode_bech32_address(hrp, witness_script_hash) def address_to_cashaddr(address: str, coin: CoinInfo) -> str: @@ -181,17 +146,6 @@ def address_to_cashaddr(address: str, coin: CoinInfo) -> str: return cashaddr.encode(coin.cashaddr_prefix, version, data) -def ecdsa_hash_pubkey(pubkey: bytes, coin: CoinInfo) -> bytes: - if pubkey[0] == 0x04: - ensure(len(pubkey) == 65) # uncompressed format - elif pubkey[0] == 0x00: - ensure(len(pubkey) == 1) # point at infinity - else: - ensure(len(pubkey) == 33) # compresssed format - - return coin.script_hash(pubkey) - - def address_short(coin: CoinInfo, address: str) -> str: if coin.cashaddr_prefix is not None and address.startswith( coin.cashaddr_prefix + ":" diff --git a/core/src/apps/bitcoin/common.py b/core/src/apps/bitcoin/common.py new file mode 100644 index 000000000..e1c88b536 --- /dev/null +++ b/core/src/apps/bitcoin/common.py @@ -0,0 +1,42 @@ +from micropython import const + +from trezor import wire +from trezor.crypto import bech32, bip32, der +from trezor.crypto.curve import secp256k1 +from trezor.utils import ensure + +from apps.common.coininfo import CoinInfo + +# supported witness version for bech32 addresses +_BECH32_WITVER = const(0x00) + + +def ecdsa_sign(node: bip32.HDNode, digest: bytes) -> bytes: + sig = secp256k1.sign(node.private_key(), digest) + sigder = der.encode_seq((sig[1:33], sig[33:65])) + return sigder + + +def ecdsa_hash_pubkey(pubkey: bytes, coin: CoinInfo) -> bytes: + if pubkey[0] == 0x04: + ensure(len(pubkey) == 65) # uncompressed format + elif pubkey[0] == 0x00: + ensure(len(pubkey) == 1) # point at infinity + else: + ensure(len(pubkey) == 33) # compresssed format + + return coin.script_hash(pubkey) + + +def encode_bech32_address(prefix: str, script: bytes) -> bytes: + address = bech32.encode(prefix, _BECH32_WITVER, script) + if address is None: + raise wire.ProcessError("Invalid address") + return address + + +def decode_bech32_address(prefix: str, address: str) -> bytes: + witver, raw = bech32.decode(prefix, address) + if witver != _BECH32_WITVER: + raise wire.ProcessError("Invalid address witness program") + return bytes(raw) diff --git a/core/src/apps/wallet/get_address.py b/core/src/apps/bitcoin/get_address.py similarity index 97% rename from core/src/apps/wallet/get_address.py rename to core/src/apps/bitcoin/get_address.py index a63b90839..2724a4a41 100644 --- a/core/src/apps/wallet/get_address.py +++ b/core/src/apps/bitcoin/get_address.py @@ -2,9 +2,9 @@ from trezor.crypto import bip32 from trezor.messages import InputScriptType from trezor.messages.Address import Address +from . import addresses from .keychain import with_keychain -from .sign_tx import addresses -from .sign_tx.multisig import multisig_pubkey_index +from .multisig import multisig_pubkey_index from apps.common.layout import address_n_to_str, show_address, show_qr, show_xpub from apps.common.paths import validate_path diff --git a/core/src/apps/wallet/get_public_key.py b/core/src/apps/bitcoin/get_public_key.py similarity index 100% rename from core/src/apps/wallet/get_public_key.py rename to core/src/apps/bitcoin/get_public_key.py diff --git a/core/src/apps/wallet/keychain.py b/core/src/apps/bitcoin/keychain.py similarity index 100% rename from core/src/apps/wallet/keychain.py rename to core/src/apps/bitcoin/keychain.py diff --git a/core/src/apps/wallet/sign_tx/multisig.py b/core/src/apps/bitcoin/multisig.py similarity index 85% rename from core/src/apps/wallet/sign_tx/multisig.py rename to core/src/apps/bitcoin/multisig.py index 15f94a3d2..65919fc4a 100644 --- a/core/src/apps/wallet/sign_tx/multisig.py +++ b/core/src/apps/bitcoin/multisig.py @@ -1,20 +1,16 @@ +from trezor import wire from trezor.crypto import bip32 from trezor.crypto.hashlib import sha256 -from trezor.messages import FailureType from trezor.messages.HDNodeType import HDNodeType from trezor.messages.MultisigRedeemScriptType import MultisigRedeemScriptType from trezor.utils import HashWriter -from apps.wallet.sign_tx.writers import write_bytes_fixed, write_uint32 +from .writers import write_bytes_fixed, write_uint32 if False: from typing import List -class MultisigError(ValueError): - pass - - def multisig_fingerprint(multisig: MultisigRedeemScriptType) -> bytes: if multisig.nodes: pubnodes = multisig.nodes @@ -24,11 +20,11 @@ def multisig_fingerprint(multisig: MultisigRedeemScriptType) -> bytes: n = len(pubnodes) if n < 1 or n > 15 or m < 1 or m > 15: - raise MultisigError(FailureType.DataError, "Invalid multisig parameters") + raise wire.DataError("Invalid multisig parameters") for d in pubnodes: if len(d.public_key) != 33 or len(d.chain_code) != 32: - raise MultisigError(FailureType.DataError, "Invalid multisig parameters") + raise wire.DataError("Invalid multisig parameters") # casting to bytes(), sorting on bytearray() is not supported in MicroPython pubnodes = sorted(pubnodes, key=lambda n: bytes(n.public_key)) @@ -55,7 +51,7 @@ def multisig_pubkey_index(multisig: MultisigRedeemScriptType, pubkey: bytes) -> for i, hd in enumerate(multisig.pubkeys): if multisig_get_pubkey(hd.node, hd.address_n) == pubkey: return i - raise MultisigError(FailureType.DataError, "Pubkey not found in multisig script") + raise wire.DataError("Pubkey not found in multisig script") def multisig_get_pubkey(n: HDNodeType, p: list) -> bytes: diff --git a/core/src/apps/wallet/sign_tx/scripts.py b/core/src/apps/bitcoin/scripts.py similarity index 90% rename from core/src/apps/wallet/sign_tx/scripts.py rename to core/src/apps/bitcoin/scripts.py index 2c2df11f5..451f1b75a 100644 --- a/core/src/apps/wallet/sign_tx/scripts.py +++ b/core/src/apps/bitcoin/scripts.py @@ -1,34 +1,30 @@ -from trezor import utils +from trezor import utils, wire from trezor.crypto import base58, cashaddr from trezor.crypto.hashlib import sha256 -from trezor.messages import FailureType, InputScriptType, OutputScriptType +from trezor.messages import InputScriptType, OutputScriptType from trezor.messages.MultisigRedeemScriptType import MultisigRedeemScriptType from trezor.messages.TxInputType import TxInputType from trezor.messages.TxOutputType import TxOutputType from apps.common import address_type from apps.common.coininfo import CoinInfo -from apps.common.writers import empty_bytearray -from apps.wallet.sign_tx import addresses -from apps.wallet.sign_tx.multisig import ( +from apps.common.writers import empty_bytearray, write_bitcoin_varint + +from . import common +from .multisig import ( multisig_get_pubkey_count, multisig_get_pubkeys, multisig_pubkey_index, ) -from apps.wallet.sign_tx.writers import ( +from .writers import ( write_bytes_fixed, write_bytes_unchecked, write_op_push, - write_varint, ) if False: from typing import List, Optional - from apps.wallet.sign_tx.writers import Writer - - -class ScriptsError(ValueError): - pass + from .writers import Writer def input_derive_script( @@ -54,7 +50,7 @@ def input_derive_script( return input_script_p2wsh_in_p2sh(witness_script_hash) # p2wpkh in p2sh - return input_script_p2wpkh_in_p2sh(addresses.ecdsa_hash_pubkey(pubkey, coin)) + return input_script_p2wpkh_in_p2sh(common.ecdsa_hash_pubkey(pubkey, coin)) elif txi.script_type == InputScriptType.SPENDWITNESS: # native p2wpkh or p2wsh return input_script_native_p2wpkh_or_p2wsh() @@ -65,7 +61,7 @@ def input_derive_script( txi.multisig, signature, signature_index, hash_type, coin ) else: - raise ScriptsError(FailureType.ProcessError, "Invalid script type") + raise wire.ProcessError("Invalid script type") def output_derive_script(txo: TxOutputType, coin: CoinInfo) -> bytes: @@ -74,7 +70,7 @@ def output_derive_script(txo: TxOutputType, coin: CoinInfo) -> bytes: if coin.bech32_prefix and txo.address.startswith(coin.bech32_prefix): # p2wpkh or p2wsh - witprog = addresses.decode_bech32_address(coin.bech32_prefix, txo.address) + witprog = common.decode_bech32_address(coin.bech32_prefix, txo.address) return output_script_native_p2wpkh_or_p2wsh(witprog) if ( @@ -89,13 +85,13 @@ def output_derive_script(txo: TxOutputType, coin: CoinInfo) -> bytes: elif version == cashaddr.ADDRESS_TYPE_P2SH: version = coin.address_type_p2sh else: - raise ScriptsError("Unknown cashaddr address type") + raise wire.DataError("Unknown cashaddr address type") raw_address = bytes([version]) + data else: try: raw_address = base58.decode_check(txo.address, coin.b58_hash) except ValueError: - raise ScriptsError(FailureType.DataError, "Invalid address") + raise wire.DataError("Invalid address") if address_type.check(coin.address_type, raw_address): # p2pkh @@ -108,7 +104,7 @@ def output_derive_script(txo: TxOutputType, coin: CoinInfo) -> bytes: script = output_script_p2sh(scripthash) return script - raise ScriptsError(FailureType.DataError, "Invalid address type") + raise wire.DataError("Invalid address type") # see https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#specification @@ -131,9 +127,7 @@ def bip143_derive_script_code(txi: TxInputType, pubkeyhash: bytes) -> bytearray: return output_script_p2pkh(pubkeyhash) else: - raise ScriptsError( - FailureType.DataError, "Unknown input script type for bip143 script code", - ) + raise wire.DataError("Unknown input script type for bip143 script code") # P2PKH, P2SH @@ -238,7 +232,7 @@ def input_script_p2wsh_in_p2sh(script_hash: bytes) -> bytearray: # Signature is moved to the witness. if len(script_hash) != 32: - raise ScriptsError("Redeem script hash should be 32 bytes long") + raise wire.DataError("Redeem script hash should be 32 bytes long") w = empty_bytearray(3 + len(script_hash)) w.append(0x22) # length of the data @@ -272,7 +266,7 @@ def witness_p2wsh( ) # fill in our signature if signatures[signature_index]: - raise ScriptsError("Invalid multisig parameters") + raise wire.DataError("Invalid multisig parameters") signatures[signature_index] = signature # filter empty @@ -324,7 +318,7 @@ def input_script_multisig( ) -> bytearray: signatures = multisig.signatures # other signatures if len(signatures[signature_index]) > 0: - raise ScriptsError("Invalid multisig parameters") + raise wire.DataError("Invalid multisig parameters") signatures[signature_index] = signature # our signature # length of the redeem script @@ -367,10 +361,10 @@ def output_script_multisig(pubkeys: List[bytes], m: int) -> bytearray: def write_output_script_multisig(w: Writer, pubkeys: List[bytes], m: int) -> None: n = len(pubkeys) if n < 1 or n > 15 or m < 1 or m > 15 or m > n: - raise ScriptsError("Invalid multisig parameters") + raise wire.DataError("Invalid multisig parameters") for pubkey in pubkeys: if len(pubkey) != 33: - raise ScriptsError("Invalid multisig parameters") + raise wire.DataError("Invalid multisig parameters") w.append(0x50 + m) # numbers 1 to 16 are pushed as 0x50 + value for p in pubkeys: diff --git a/core/src/apps/wallet/sign_message.py b/core/src/apps/bitcoin/sign_message.py similarity index 95% rename from core/src/apps/wallet/sign_message.py rename to core/src/apps/bitcoin/sign_message.py index f75038487..e64dbddae 100644 --- a/core/src/apps/wallet/sign_message.py +++ b/core/src/apps/bitcoin/sign_message.py @@ -3,8 +3,8 @@ from trezor.crypto.curve import secp256k1 from trezor.messages.InputScriptType import SPENDADDRESS, SPENDP2SHWITNESS, SPENDWITNESS from trezor.messages.MessageSignature import MessageSignature +from .addresses import get_address, validate_full_path from .keychain import with_keychain -from .sign_tx.addresses import get_address, validate_full_path from apps.common.paths import validate_path from apps.common.signverify import message_digest, require_confirm_sign_message diff --git a/core/src/apps/wallet/sign_tx/__init__.py b/core/src/apps/bitcoin/sign_tx/__init__.py similarity index 82% rename from core/src/apps/wallet/sign_tx/__init__.py rename to core/src/apps/bitcoin/sign_tx/__init__.py index 50b5a7514..99502f818 100644 --- a/core/src/apps/wallet/sign_tx/__init__.py +++ b/core/src/apps/bitcoin/sign_tx/__init__.py @@ -5,12 +5,12 @@ from trezor.messages.TxAck import TxAck from trezor.messages.TxRequest import TxRequest from ..keychain import with_keychain -from . import addresses, bitcoin, common, helpers, layout, multisig, progress, scripts +from . import bitcoin, helpers, layout, progress from apps.common import coininfo, paths, seed if not utils.BITCOIN_ONLY: - from apps.wallet.sign_tx import bitcoinlike, decred, zcash + from . import bitcoinlike, decred, zcash if False: from typing import Type, Union @@ -36,22 +36,11 @@ async def sign_tx( else: signer_class = bitcoin.Bitcoin - try: - signer = signer_class(msg, keychain, coin).signer() - except common.SigningError as e: - raise wire.Error(*e.args) + signer = signer_class(msg, keychain, coin).signer() res = None # type: Union[TxAck, bool, None] while True: - try: - req = signer.send(res) - except ( - common.SigningError, - multisig.MultisigError, - addresses.AddressError, - scripts.ScriptsError, - ) as e: - raise wire.Error(*e.args) + req = signer.send(res) if isinstance(req, TxRequest): if req.request_type == TXFINISHED: break diff --git a/core/src/apps/wallet/sign_tx/bitcoin.py b/core/src/apps/bitcoin/sign_tx/bitcoin.py similarity index 89% rename from core/src/apps/wallet/sign_tx/bitcoin.py rename to core/src/apps/bitcoin/sign_tx/bitcoin.py index 38df36a41..8480cceee 100644 --- a/core/src/apps/wallet/sign_tx/bitcoin.py +++ b/core/src/apps/bitcoin/sign_tx/bitcoin.py @@ -1,8 +1,9 @@ import gc from micropython import const +from trezor import wire from trezor.crypto.hashlib import sha256 -from trezor.messages import FailureType, InputScriptType +from trezor.messages import InputScriptType from trezor.messages.SignTx import SignTx from trezor.messages.TransactionType import TransactionType from trezor.messages.TxInputType import TxInputType @@ -14,17 +15,12 @@ from trezor.messages.TxRequestSerializedType import TxRequestSerializedType from trezor.utils import HashWriter, ensure from apps.common import coininfo, seed -from apps.wallet.sign_tx import ( - addresses, - helpers, - multisig, - progress, - scripts, - tx_weight, - writers, -) -from apps.wallet.sign_tx.common import SigningError, ecdsa_sign -from apps.wallet.sign_tx.matchcheck import MultisigFingerprintChecker, WalletPathChecker +from apps.common.writers import write_bitcoin_varint + +from .. import addresses, multisig, scripts, writers +from ..common import ecdsa_hash_pubkey, ecdsa_sign +from . import helpers, progress, tx_weight +from .matchcheck import MultisigFingerprintChecker, WalletPathChecker if False: from typing import Set, Tuple, Union @@ -136,17 +132,10 @@ class Bitcoin: # fee > (coin.maxfee per byte * tx size) if fee > (self.coin.maxfee_kb / 1000) * (self.weight.get_total() / 4): - if not await helpers.confirm_feeoverthreshold(fee, self.coin): - raise SigningError(FailureType.ActionCancelled, "Signing cancelled") - + await helpers.confirm_feeoverthreshold(fee, self.coin) if self.tx.lock_time > 0: - if not await helpers.confirm_nondefault_locktime(self.tx.lock_time): - raise SigningError(FailureType.ActionCancelled, "Locktime cancelled") - - if not await helpers.confirm_total( - self.total_in - self.change_out, fee, self.coin - ): - raise SigningError(FailureType.ActionCancelled, "Total cancelled") + await helpers.confirm_nondefault_locktime(self.tx.lock_time) + await helpers.confirm_total(self.total_in - self.change_out, fee, self.coin) async def step4_serialize_inputs(self) -> None: self.write_tx_header(self.serialized_tx, self.tx, bool(self.segwit)) @@ -193,7 +182,7 @@ class Bitcoin: elif input_is_nonsegwit(txi): await self.process_nonsegwit_input(txi) else: - raise SigningError(FailureType.DataError, "Wrong input script type") + raise wire.DataError("Wrong input script type") async def process_segwit_input(self, txi: TxInputType) -> None: await self.process_bip143_input(txi) @@ -205,7 +194,7 @@ class Bitcoin: async def process_bip143_input(self, txi: TxInputType) -> None: if not txi.amount: - raise SigningError(FailureType.DataError, "Expected input with amount") + raise wire.DataError("Expected input with amount") self.bip143_in += txi.amount self.total_in += txi.amount @@ -213,24 +202,22 @@ class Bitcoin: if self.change_out == 0 and self.output_is_change(txo): # output is change and does not need confirmation self.change_out = txo.amount - elif not await helpers.confirm_output(txo, self.coin): - raise SigningError(FailureType.ActionCancelled, "Output cancelled") + else: + await helpers.confirm_output(txo, self.coin) self.write_tx_output(self.h_confirmed, txo, script_pubkey) self.hash143_add_output(txo, script_pubkey) self.total_out += txo.amount def on_negative_fee(self) -> None: - raise SigningError(FailureType.NotEnoughFunds, "Not enough funds") + raise wire.NotEnoughFunds("Not enough funds") async def serialize_segwit_input(self, i: int) -> None: # STAGE_REQUEST_SEGWIT_INPUT in legacy txi = await helpers.request_tx_input(self.tx_req, i, self.coin) if not input_is_segwit(txi): - raise SigningError( - FailureType.ProcessError, "Transaction has changed during signing" - ) + raise wire.ProcessError("Transaction has changed during signing") self.wallet_path.check_input(txi) # NOTE: No need to check the multisig fingerprint, because we won't be signing # the script here. Signatures are produced in STAGE_REQUEST_SEGWIT_WITNESS. @@ -245,15 +232,13 @@ class Bitcoin: self.multisig_fingerprint.check_input(txi) if txi.amount > self.bip143_in: - raise SigningError( - FailureType.ProcessError, "Transaction has changed during signing" - ) + raise wire.ProcessError("Transaction has changed during signing") self.bip143_in -= txi.amount node = self.keychain.derive(txi.address_n) public_key = node.public_key() hash143_hash = self.hash143_preimage_hash( - txi, addresses.ecdsa_hash_pubkey(public_key, self.coin) + txi, ecdsa_hash_pubkey(public_key, self.coin) ) signature = ecdsa_sign(node, hash143_hash) @@ -265,9 +250,7 @@ class Bitcoin: txi = await helpers.request_tx_input(self.tx_req, i, self.coin) if not input_is_segwit(txi): - raise SigningError( - FailureType.ProcessError, "Transaction has changed during signing" - ) + raise wire.ProcessError("Transaction has changed during signing") public_key, signature = self.sign_bip143_input(txi) @@ -318,9 +301,7 @@ class Bitcoin: addresses.ecdsa_hash_pubkey(key_sign_pub, self.coin) ) else: - raise SigningError( - FailureType.ProcessError, "Unknown transaction type" - ) + raise wire.ProcessError("Unknown transaction type") txi_sign = txi else: script_pubkey = bytes() @@ -340,9 +321,7 @@ class Bitcoin: # check the control digests if self.h_confirmed.get_digest() != h_check.get_digest(): - raise SigningError( - FailureType.ProcessError, "Transaction has changed during signing" - ) + raise wire.ProcessError("Transaction has changed during signing") # compute the signature from the tx digest signature = ecdsa_sign( @@ -368,9 +347,7 @@ class Bitcoin: tx = await helpers.request_tx_meta(self.tx_req, self.coin, prev_hash) if tx.outputs_cnt <= prev_index: - raise SigningError( - FailureType.ProcessError, "Not enough outputs in previous transaction." - ) + raise wire.ProcessError("Not enough outputs in previous transaction.") txh = self.create_hash_writer() @@ -401,9 +378,7 @@ class Bitcoin: writers.get_tx_hash(txh, double=self.coin.sign_hash_double, reverse=True) != prev_hash ): - raise SigningError( - FailureType.ProcessError, "Encountered invalid prev_hash" - ) + raise wire.ProcessError("Encountered invalid prev_hash") return amount_out @@ -469,7 +444,7 @@ class Bitcoin: txo.script_type ] except KeyError: - raise SigningError(FailureType.DataError, "Invalid script type") + raise wire.DataError("Invalid script type") node = self.keychain.derive(txo.address_n) txo.address = addresses.get_address( input_script_type, self.coin, node, txo.multisig diff --git a/core/src/apps/wallet/sign_tx/bitcoinlike.py b/core/src/apps/bitcoin/sign_tx/bitcoinlike.py similarity index 87% rename from core/src/apps/wallet/sign_tx/bitcoinlike.py rename to core/src/apps/bitcoin/sign_tx/bitcoinlike.py index a49bd43a0..18ddea23f 100644 --- a/core/src/apps/wallet/sign_tx/bitcoinlike.py +++ b/core/src/apps/bitcoin/sign_tx/bitcoinlike.py @@ -1,14 +1,16 @@ import gc from micropython import const -from trezor.messages import FailureType +from trezor import wire from trezor.messages.SignTx import SignTx from trezor.messages.TransactionType import TransactionType from trezor.messages.TxInputType import TxInputType -from apps.wallet.sign_tx import helpers, multisig, writers -from apps.wallet.sign_tx.bitcoin import Bitcoin, input_is_nonsegwit -from apps.wallet.sign_tx.common import SigningError +from .. import multisig, writers +from . import helpers +from .bitcoin import Bitcoin, input_is_nonsegwit + +from apps.common.writers import write_bitcoin_varint if False: from typing import Union @@ -19,7 +21,7 @@ _SIGHASH_FORKID = const(0x40) class Bitcoinlike(Bitcoin): async def process_segwit_input(self, txi: TxInputType) -> None: if not self.coin.segwit: - raise SigningError(FailureType.DataError, "Segwit not enabled on this coin") + raise wire.DataError("Segwit not enabled on this coin") await super().process_segwit_input(txi) async def process_nonsegwit_input(self, txi: TxInputType) -> None: @@ -32,9 +34,7 @@ class Bitcoinlike(Bitcoin): txi = await helpers.request_tx_input(self.tx_req, i_sign, self.coin) if not input_is_nonsegwit(txi): - raise SigningError( - FailureType.ProcessError, "Transaction has changed during signing" - ) + raise wire.ProcessError("Transaction has changed during signing") public_key, signature = self.sign_bip143_input(txi) # if multisig, do a sanity check to ensure we are signing with a key that is included in the multisig diff --git a/core/src/apps/wallet/sign_tx/decred.py b/core/src/apps/bitcoin/sign_tx/decred.py similarity index 89% rename from core/src/apps/wallet/sign_tx/decred.py rename to core/src/apps/bitcoin/sign_tx/decred.py index 9084c939f..aefd140d2 100644 --- a/core/src/apps/wallet/sign_tx/decred.py +++ b/core/src/apps/bitcoin/sign_tx/decred.py @@ -1,8 +1,9 @@ import gc from micropython import const +from trezor import wire from trezor.crypto.hashlib import blake256 -from trezor.messages import FailureType, InputScriptType +from trezor.messages import InputScriptType from trezor.messages.SignTx import SignTx from trezor.messages.TransactionType import TransactionType from trezor.messages.TxInputType import TxInputType @@ -11,9 +12,11 @@ from trezor.messages.TxOutputType import TxOutputType from trezor.utils import HashWriter, ensure from apps.common import coininfo, seed -from apps.wallet.sign_tx import addresses, helpers, multisig, progress, scripts, writers -from apps.wallet.sign_tx.bitcoin import Bitcoin -from apps.wallet.sign_tx.common import SigningError, ecdsa_sign + +from .. import multisig, scripts, writers +from ..common import ecdsa_hash_pubkey, ecdsa_sign +from . import helpers, progress +from .bitcoin import Bitcoin DECRED_SERIALIZE_FULL = const(0 << 16) DECRED_SERIALIZE_NO_WITNESS = const(1 << 16) @@ -60,10 +63,7 @@ class Decred(Bitcoin): async def confirm_output(self, txo: TxOutputType, script_pubkey: bytes) -> None: if txo.decred_script_version != 0: - raise SigningError( - FailureType.ActionCancelled, - "Cannot send to output with script version != 0", - ) + raise wire.ActionCancelled("Cannot send to output with script version != 0") await super().confirm_output(txo, script_pubkey) self.write_tx_output(self.serialized_tx, txo, script_pubkey) @@ -90,10 +90,10 @@ class Decred(Bitcoin): ) elif txi_sign.script_type == InputScriptType.SPENDADDRESS: prev_pkscript = scripts.output_script_p2pkh( - addresses.ecdsa_hash_pubkey(key_sign_pub, self.coin) + ecdsa_hash_pubkey(key_sign_pub, self.coin) ) else: - raise SigningError("Unsupported input script type") + raise wire.DataError("Unsupported input script type") h_witness = self.create_hash_writer() writers.write_uint32( @@ -138,10 +138,7 @@ class Decred(Bitcoin): def check_prevtx_output(self, txo_bin: TxOutputBinType) -> None: if txo_bin.decred_script_version != 0: - raise SigningError( - FailureType.ProcessError, - "Cannot use utxo that has script_version != 0", - ) + raise wire.ProcessError("Cannot use utxo that has script_version != 0") def hash143_add_input(self, txi: TxInputType) -> None: writers.write_tx_input_decred(self.h_prefix, txi) diff --git a/core/src/apps/wallet/sign_tx/helpers.py b/core/src/apps/bitcoin/sign_tx/helpers.py similarity index 78% rename from core/src/apps/wallet/sign_tx/helpers.py rename to core/src/apps/bitcoin/sign_tx/helpers.py index 0b0072f60..d2bece2f7 100644 --- a/core/src/apps/wallet/sign_tx/helpers.py +++ b/core/src/apps/bitcoin/sign_tx/helpers.py @@ -1,7 +1,7 @@ import gc -from trezor import utils -from trezor.messages import FailureType, InputScriptType, OutputScriptType +from trezor import utils, wire +from trezor.messages import InputScriptType, OutputScriptType from trezor.messages.RequestType import ( TXEXTRADATA, TXFINISHED, @@ -16,8 +16,7 @@ from trezor.messages.TxOutputBinType import TxOutputBinType from trezor.messages.TxOutputType import TxOutputType from trezor.messages.TxRequest import TxRequest -from .common import SigningError -from .writers import TX_HASH_SIZE +from ..writers import TX_HASH_SIZE from apps.common.coininfo import CoinInfo @@ -195,11 +194,11 @@ def sanitize_sign_tx(tx: SignTx, coin: CoinInfo) -> SignTx: if coin.decred or coin.overwintered: tx.expiry = tx.expiry if tx.expiry is not None else 0 elif tx.expiry: - raise SigningError(FailureType.DataError, "Expiry not enabled on this coin.") + raise wire.DataError("Expiry not enabled on this coin.") if coin.timestamp and not tx.timestamp: - raise SigningError(FailureType.DataError, "Timestamp must be set.") + raise wire.DataError("Timestamp must be set.") elif not coin.timestamp and tx.timestamp: - raise SigningError(FailureType.DataError, "Timestamp not enabled on this coin.") + raise wire.DataError("Timestamp not enabled on this coin.") return tx @@ -211,17 +210,15 @@ def sanitize_tx_meta(tx: TransactionType, coin: CoinInfo) -> TransactionType: if coin.extra_data: tx.extra_data_len = tx.extra_data_len if tx.extra_data_len is not None else 0 elif tx.extra_data_len: - raise SigningError( - FailureType.DataError, "Extra data not enabled on this coin." - ) + raise wire.DataError("Extra data not enabled on this coin.") if coin.decred or coin.overwintered: tx.expiry = tx.expiry if tx.expiry is not None else 0 elif tx.expiry: - raise SigningError(FailureType.DataError, "Expiry not enabled on this coin.") + raise wire.DataError("Expiry not enabled on this coin.") if coin.timestamp and not tx.timestamp: - raise SigningError(FailureType.DataError, "Timestamp must be set.") + raise wire.DataError("Timestamp must be set.") elif not coin.timestamp and tx.timestamp: - raise SigningError(FailureType.DataError, "Timestamp not enabled on this coin.") + raise wire.DataError("Timestamp not enabled on this coin.") return tx @@ -232,29 +229,18 @@ def sanitize_tx_input(tx: TransactionType, coin: CoinInfo) -> TxInputType: if txi.sequence is None: txi.sequence = 0xFFFFFFFF if txi.prev_hash is None or len(txi.prev_hash) != TX_HASH_SIZE: - raise SigningError(FailureType.DataError, "Provided prev_hash is invalid.") + raise wire.DataError("Provided prev_hash is invalid.") if txi.multisig and txi.script_type not in MULTISIG_INPUT_SCRIPT_TYPES: - raise SigningError( - FailureType.DataError, "Multisig field provided but not expected.", - ) + raise wire.DataError("Multisig field provided but not expected.") if txi.address_n and txi.script_type not in INTERNAL_INPUT_SCRIPT_TYPES: - raise SigningError( - FailureType.DataError, "Input's address_n provided but not expected.", - ) + raise wire.DataError("Input's address_n provided but not expected.") if not coin.decred and txi.decred_tree is not None: - raise SigningError( - FailureType.DataError, - "Decred details provided but Decred coin not specified.", - ) + raise wire.DataError("Decred details provided but Decred coin not specified.") if txi.script_type in SEGWIT_INPUT_SCRIPT_TYPES: if not coin.segwit: - raise SigningError( - FailureType.DataError, "Segwit not enabled on this coin", - ) + raise wire.DataError("Segwit not enabled on this coin") if txi.amount is None: - raise SigningError( - FailureType.DataError, "Segwit input without amount", - ) + raise wire.DataError("Segwit input without amount") _sanitize_decred(txi, coin) return txi @@ -263,35 +249,24 @@ def sanitize_tx_input(tx: TransactionType, coin: CoinInfo) -> TxInputType: def sanitize_tx_output(tx: TransactionType, coin: CoinInfo) -> TxOutputType: txo = tx.outputs[0] if txo.multisig and txo.script_type not in MULTISIG_OUTPUT_SCRIPT_TYPES: - raise SigningError( - FailureType.DataError, "Multisig field provided but not expected.", - ) + raise wire.DataError("Multisig field provided but not expected.") if txo.address_n and txo.script_type not in CHANGE_OUTPUT_SCRIPT_TYPES: - raise SigningError( - FailureType.DataError, "Output's address_n provided but not expected.", - ) + raise wire.DataError("Output's address_n provided but not expected.") if txo.script_type == OutputScriptType.PAYTOOPRETURN: # op_return output if txo.amount != 0: - raise SigningError( - FailureType.DataError, "OP_RETURN output with non-zero amount" - ) + raise wire.DataError("OP_RETURN output with non-zero amount") if txo.address or txo.address_n or txo.multisig: - raise SigningError( - FailureType.DataError, "OP_RETURN output with address or multisig" - ) + raise wire.DataError("OP_RETURN output with address or multisig") else: if txo.op_return_data: - raise SigningError( - FailureType.DataError, - "OP RETURN data provided but not OP RETURN script type.", + raise wire.DataError( + "OP RETURN data provided but not OP RETURN script type." ) if txo.address_n and txo.address: - raise SigningError( - FailureType.DataError, "Both address and address_n provided." - ) + raise wire.DataError("Both address and address_n provided.") if not txo.address_n and not txo.address: - raise SigningError(FailureType.DataError, "Missing address") + raise wire.DataError("Missing address") _sanitize_decred(txo, coin) @@ -312,7 +287,6 @@ def _sanitize_decred( tx.decred_script_version = 0 else: if tx.decred_script_version is not None: - raise SigningError( - FailureType.DataError, - "Decred details provided but Decred coin not specified.", + raise wire.DataError( + "Decred details provided but Decred coin not specified." ) diff --git a/core/src/apps/wallet/sign_tx/layout.py b/core/src/apps/bitcoin/sign_tx/layout.py similarity index 73% rename from core/src/apps/wallet/sign_tx/layout.py rename to core/src/apps/bitcoin/sign_tx/layout.py index 6974971ce..fdfd8ea7b 100644 --- a/core/src/apps/wallet/sign_tx/layout.py +++ b/core/src/apps/bitcoin/sign_tx/layout.py @@ -10,7 +10,7 @@ from trezor.utils import chunks from apps.common import coininfo if False: - from typing import Iterator, List + from typing import Iterator from trezor import wire _LOCKTIME_TIMESTAMP_MIN_VALUE = const(500000000) @@ -30,10 +30,11 @@ def split_op_return(data: str) -> Iterator[str]: async def confirm_output( ctx: wire.Context, output: TxOutputType, coin: coininfo.CoinInfo -) -> bool: +) -> None: from trezor.ui.text import Text - from apps.common.confirm import confirm - from apps.wallet.sign_tx import addresses, omni + from apps.common.confirm import require_confirm + from . import omni + from .. import addresses if output.script_type == OutputScriptType.PAYTOOPRETURN: data = output.op_return_data @@ -54,50 +55,39 @@ async def confirm_output( text = Text("Confirm sending", ui.ICON_SEND, ui.GREEN) text.normal(format_coin_amount(output.amount, coin) + " to") text.mono(*split_address(address_short)) - return await confirm(ctx, text, ButtonRequestType.ConfirmOutput) + await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput) async def confirm_total( ctx: wire.Context, spending: int, fee: int, coin: coininfo.CoinInfo -) -> bool: +) -> None: from trezor.ui.text import Text - from apps.common.confirm import hold_to_confirm + from apps.common.confirm import require_hold_to_confirm text = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN) text.normal("Total amount:") text.bold(format_coin_amount(spending, coin)) text.normal("including fee:") text.bold(format_coin_amount(fee, coin)) - return await hold_to_confirm(ctx, text, ButtonRequestType.SignTx) + await require_hold_to_confirm(ctx, text, ButtonRequestType.SignTx) async def confirm_feeoverthreshold( ctx: wire.Context, fee: int, coin: coininfo.CoinInfo -) -> bool: +) -> None: from trezor.ui.text import Text - from apps.common.confirm import confirm + from apps.common.confirm import require_confirm text = Text("High fee", ui.ICON_SEND, ui.GREEN) text.normal("The fee of") text.bold(format_coin_amount(fee, coin)) text.normal("is unexpectedly high.", "Continue?") - return await confirm(ctx, text, ButtonRequestType.FeeOverThreshold) + await require_confirm(ctx, text, ButtonRequestType.FeeOverThreshold) -async def confirm_foreign_address( - ctx: wire.Context, address_n: List[int], coin: coininfo.CoinInfo -) -> bool: +async def confirm_nondefault_locktime(ctx: wire.Context, lock_time: int) -> None: from trezor.ui.text import Text - from apps.common.confirm import confirm - - text = Text("Confirm sending", ui.ICON_SEND, ui.RED) - text.normal("Trying to spend", "coins from another chain.", "Continue?") - return await confirm(ctx, text, ButtonRequestType.SignTx) - - -async def confirm_nondefault_locktime(ctx: wire.Context, lock_time: int) -> bool: - from trezor.ui.text import Text - from apps.common.confirm import confirm + from apps.common.confirm import require_confirm text = Text("Confirm locktime", ui.ICON_SEND, ui.GREEN) text.normal("Locktime for this transaction is set to") @@ -107,4 +97,4 @@ async def confirm_nondefault_locktime(ctx: wire.Context, lock_time: int) -> bool text.normal("timestamp:") text.bold(str(lock_time)) text.normal("Continue?") - return await confirm(ctx, text, ButtonRequestType.SignTx) + await require_confirm(ctx, text, ButtonRequestType.SignTx) diff --git a/core/src/apps/wallet/sign_tx/matchcheck.py b/core/src/apps/bitcoin/sign_tx/matchcheck.py similarity index 93% rename from core/src/apps/wallet/sign_tx/matchcheck.py rename to core/src/apps/bitcoin/sign_tx/matchcheck.py index b813a43bb..336296b12 100644 --- a/core/src/apps/wallet/sign_tx/matchcheck.py +++ b/core/src/apps/bitcoin/sign_tx/matchcheck.py @@ -1,12 +1,11 @@ from micropython import const -from trezor.messages import FailureType +from trezor import wire from trezor.messages.TxInputType import TxInputType from trezor.messages.TxOutputType import TxOutputType from trezor.utils import ensure -from apps.wallet.sign_tx import multisig -from apps.wallet.sign_tx.common import SigningError +from .. import multisig if False: from typing import Any, Union @@ -71,9 +70,7 @@ class MatchChecker: # All added inputs had a matching attribute, allowing a change-output. # Ensure that this input still has the same attribute. if self.attribute != self.attribute_from_tx(txi): - raise SigningError( - FailureType.ProcessError, "Transaction has changed during signing" - ) + raise wire.ProcessError("Transaction has changed during signing") def output_matches(self, txo: TxOutputType) -> bool: self.read_only = True diff --git a/core/src/apps/wallet/sign_tx/omni.py b/core/src/apps/bitcoin/sign_tx/omni.py similarity index 100% rename from core/src/apps/wallet/sign_tx/omni.py rename to core/src/apps/bitcoin/sign_tx/omni.py diff --git a/core/src/apps/wallet/sign_tx/progress.py b/core/src/apps/bitcoin/sign_tx/progress.py similarity index 100% rename from core/src/apps/wallet/sign_tx/progress.py rename to core/src/apps/bitcoin/sign_tx/progress.py diff --git a/core/src/apps/wallet/sign_tx/tx_weight.py b/core/src/apps/bitcoin/sign_tx/tx_weight.py similarity index 100% rename from core/src/apps/wallet/sign_tx/tx_weight.py rename to core/src/apps/bitcoin/sign_tx/tx_weight.py diff --git a/core/src/apps/wallet/sign_tx/zcash.py b/core/src/apps/bitcoin/sign_tx/zcash.py similarity index 83% rename from core/src/apps/wallet/sign_tx/zcash.py rename to core/src/apps/bitcoin/sign_tx/zcash.py index ec10ca7a0..95c7c9906 100644 --- a/core/src/apps/wallet/sign_tx/zcash.py +++ b/core/src/apps/bitcoin/sign_tx/zcash.py @@ -1,8 +1,9 @@ import ustruct as struct from micropython import const +from trezor import wire from trezor.crypto.hashlib import blake2b -from trezor.messages import FailureType, InputScriptType +from trezor.messages import InputScriptType from trezor.messages.SignTx import SignTx from trezor.messages.TransactionType import TransactionType from trezor.messages.TxInputType import TxInputType @@ -10,12 +11,10 @@ from trezor.utils import HashWriter, ensure from apps.common.coininfo import CoinInfo from apps.common.seed import Keychain -from apps.wallet.sign_tx import helpers -from apps.wallet.sign_tx.bitcoinlike import Bitcoinlike -from apps.wallet.sign_tx.common import SigningError -from apps.wallet.sign_tx.multisig import multisig_get_pubkeys -from apps.wallet.sign_tx.scripts import output_script_multisig, output_script_p2pkh -from apps.wallet.sign_tx.writers import ( + +from ..multisig import multisig_get_pubkeys +from ..scripts import output_script_multisig, output_script_p2pkh +from ..writers import ( TX_HASH_SIZE, get_tx_hash, write_bytes_fixed, @@ -25,10 +24,12 @@ from apps.wallet.sign_tx.writers import ( write_uint64, write_varint, ) +from . import helpers +from .bitcoinlike import Bitcoinlike if False: from typing import Union - from apps.wallet.sign_tx.writers import Writer + from .writers import Writer OVERWINTERED = const(0x80000000) @@ -45,10 +46,7 @@ class Overwintered(Bitcoinlike): if not self.tx.branch_id: self.tx.branch_id = 0x76B809BB # Sapling else: - raise SigningError( - FailureType.DataError, - "Unsupported version for overwintered transaction", - ) + raise wire.DataError("Unsupported version for overwintered transaction") async def step7_finish(self) -> None: self.write_tx_footer(self.serialized_tx, self.tx) @@ -63,10 +61,7 @@ class Overwintered(Bitcoinlike): write_varint(self.serialized_tx, 0) # nShieldedOutput write_varint(self.serialized_tx, 0) # nJoinSplit else: - raise SigningError( - FailureType.DataError, - "Unsupported version for overwintered transaction", - ) + raise wire.DataError("Unsupported version for overwintered transaction") await helpers.request_tx_finish(self.tx_req) @@ -136,10 +131,7 @@ class Overwintered(Bitcoinlike): # 12. nHashType write_uint32(h_preimage, self.get_hash_type()) else: - raise SigningError( - FailureType.DataError, - "Unsupported version for overwintered transaction", - ) + raise wire.DataError("Unsupported version for overwintered transaction") # 10a /13a. outpoint write_bytes_reversed(h_preimage, txi.prev_hash, TX_HASH_SIZE) @@ -170,6 +162,4 @@ def derive_script_code(txi: TxInputType, pubkeyhash: bytes) -> bytearray: return output_script_p2pkh(pubkeyhash) else: - raise SigningError( - FailureType.DataError, "Unknown input script type for zip143 script code" - ) + raise wire.DataError("Unknown input script type for zip143 script code") diff --git a/core/src/apps/wallet/verify_message.py b/core/src/apps/bitcoin/verify_message.py similarity index 97% rename from core/src/apps/wallet/verify_message.py rename to core/src/apps/bitcoin/verify_message.py index 03bd7f949..c2889fbcb 100644 --- a/core/src/apps/wallet/verify_message.py +++ b/core/src/apps/bitcoin/verify_message.py @@ -3,9 +3,7 @@ from trezor.crypto.curve import secp256k1 from trezor.messages.InputScriptType import SPENDADDRESS, SPENDP2SHWITNESS, SPENDWITNESS from trezor.messages.Success import Success -from apps.common import coins -from apps.common.signverify import message_digest, require_confirm_verify_message -from apps.wallet.sign_tx.addresses import ( +from .addresses import ( address_p2wpkh, address_p2wpkh_in_p2sh, address_pkh, @@ -13,6 +11,9 @@ from apps.wallet.sign_tx.addresses import ( address_to_cashaddr, ) +from apps.common import coins +from apps.common.signverify import message_digest, require_confirm_verify_message + async def verify_message(ctx, msg): message = msg.message diff --git a/core/src/apps/wallet/sign_tx/writers.py b/core/src/apps/bitcoin/writers.py similarity index 100% rename from core/src/apps/wallet/sign_tx/writers.py rename to core/src/apps/bitcoin/writers.py diff --git a/core/src/apps/common/signverify.py b/core/src/apps/common/signverify.py index da208473c..57c3e0390 100644 --- a/core/src/apps/common/signverify.py +++ b/core/src/apps/common/signverify.py @@ -4,9 +4,9 @@ from trezor import utils, wire from trezor.crypto.hashlib import blake256, sha256 from trezor.ui.text import Text +from apps.bitcoin.writers import write_varint from apps.common.confirm import require_confirm from apps.common.layout import split_address -from apps.wallet.sign_tx.writers import write_varint if False: from typing import List diff --git a/core/src/apps/lisk/sign_message.py b/core/src/apps/lisk/sign_message.py index 7d2abac03..105b50956 100644 --- a/core/src/apps/lisk/sign_message.py +++ b/core/src/apps/lisk/sign_message.py @@ -3,12 +3,12 @@ from trezor.crypto.hashlib import sha256 from trezor.messages.LiskMessageSignature import LiskMessageSignature from trezor.utils import HashWriter +from apps.bitcoin.sign_tx.writers import write_varint from apps.common import paths from apps.common.seed import with_slip44_keychain from apps.common.signverify import require_confirm_sign_message from apps.lisk import CURVE, SLIP44_ID from apps.lisk.helpers import validate_full_path -from apps.wallet.sign_tx.writers import write_varint def message_digest(message): diff --git a/core/src/apps/misc/__init__.py b/core/src/apps/misc/__init__.py new file mode 100644 index 000000000..a086c6f53 --- /dev/null +++ b/core/src/apps/misc/__init__.py @@ -0,0 +1,9 @@ +from trezor import wire +from trezor.messages import MessageType + + +def boot() -> None: + wire.add(MessageType.GetEntropy, __name__, "get_entropy") + wire.add(MessageType.SignIdentity, __name__, "sign_identity") + wire.add(MessageType.GetECDHSessionKey, __name__, "get_ecdh_session_key") + wire.add(MessageType.CipherKeyValue, __name__, "cipher_key_value") diff --git a/core/src/apps/wallet/cipher_key_value.py b/core/src/apps/misc/cipher_key_value.py similarity index 100% rename from core/src/apps/wallet/cipher_key_value.py rename to core/src/apps/misc/cipher_key_value.py diff --git a/core/src/apps/wallet/get_ecdh_session_key.py b/core/src/apps/misc/get_ecdh_session_key.py similarity index 95% rename from core/src/apps/wallet/get_ecdh_session_key.py rename to core/src/apps/misc/get_ecdh_session_key.py index 52d5fa598..df53c36b7 100644 --- a/core/src/apps/wallet/get_ecdh_session_key.py +++ b/core/src/apps/misc/get_ecdh_session_key.py @@ -6,13 +6,11 @@ from trezor.messages.ECDHSessionKey import ECDHSessionKey from trezor.ui.text import Text from trezor.utils import chunks +from .sign_identity import serialize_identity, serialize_identity_without_proto + from apps.common import HARDENED from apps.common.confirm import require_confirm from apps.common.seed import get_keychain -from apps.wallet.sign_identity import ( - serialize_identity, - serialize_identity_without_proto, -) async def get_ecdh_session_key(ctx, msg): diff --git a/core/src/apps/wallet/get_entropy.py b/core/src/apps/misc/get_entropy.py similarity index 100% rename from core/src/apps/wallet/get_entropy.py rename to core/src/apps/misc/get_entropy.py diff --git a/core/src/apps/wallet/sign_identity.py b/core/src/apps/misc/sign_identity.py similarity index 100% rename from core/src/apps/wallet/sign_identity.py rename to core/src/apps/misc/sign_identity.py diff --git a/core/src/apps/wallet/sign_tx/common.py b/core/src/apps/wallet/sign_tx/common.py deleted file mode 100644 index 4b8b685a1..000000000 --- a/core/src/apps/wallet/sign_tx/common.py +++ /dev/null @@ -1,12 +0,0 @@ -from trezor.crypto import bip32, der -from trezor.crypto.curve import secp256k1 - - -class SigningError(ValueError): - pass - - -def ecdsa_sign(node: bip32.HDNode, digest: bytes) -> bytes: - sig = secp256k1.sign(node.private_key(), digest) - sigder = der.encode_seq((sig[1:33], sig[33:65])) - return sigder diff --git a/core/src/main.py b/core/src/main.py index 8c5480d94..e7b44b3c0 100644 --- a/core/src/main.py +++ b/core/src/main.py @@ -17,7 +17,8 @@ def _boot_apps() -> None: # load applications import apps.homescreen import apps.management - import apps.wallet + import apps.bitcoin + import apps.misc if not utils.BITCOIN_ONLY: import apps.ethereum @@ -38,7 +39,8 @@ def _boot_apps() -> None: # boot applications apps.homescreen.boot() apps.management.boot() - apps.wallet.boot() + apps.bitcoin.boot() + apps.misc.boot() if not utils.BITCOIN_ONLY: apps.ethereum.boot() apps.lisk.boot() diff --git a/core/tests/test_apps.wallet.address.py b/core/tests/test_apps.bitcoin.address.py similarity index 98% rename from core/tests/test_apps.wallet.address.py rename to core/tests/test_apps.bitcoin.address.py index d2f3cc236..f83845bf6 100644 --- a/core/tests/test_apps.wallet.address.py +++ b/core/tests/test_apps.bitcoin.address.py @@ -2,12 +2,12 @@ from common import * from trezor.crypto import bip32, bip39 from trezor.utils import HashWriter -from apps.wallet.sign_tx.addresses import validate_full_path, validate_path_for_bitcoin_public_key +from apps.bitcoin.addresses import validate_full_path, validate_path_for_bitcoin_public_key from apps.common.paths import HARDENED from apps.common import coins -from apps.wallet.sign_tx import scripts -from apps.wallet.sign_tx.addresses import * -from apps.wallet.sign_tx.writers import * +from apps.bitcoin import scripts +from apps.bitcoin.addresses import * +from apps.bitcoin.writers import * def node_derive(root, path): @@ -111,7 +111,7 @@ class TestAddress(unittest.TestCase): self.assertEqual(address, '39bgKC7RFbpoCRbtD5KEdkYKtNyhpsNa3Z') for invalid_m in (-1, 0, len(pubkeys) + 1, 16): - with self.assertRaises(scripts.ScriptsError): + with self.assertRaises(wire.DataError): address_multisig_p2sh(pubkeys, invalid_m, coin) def test_multisig_address_p2wsh_in_p2sh(self): diff --git a/core/tests/test_apps.wallet.address_grs.py b/core/tests/test_apps.bitcoin.address_grs.py similarity index 97% rename from core/tests/test_apps.wallet.address_grs.py rename to core/tests/test_apps.bitcoin.address_grs.py index 2b8584680..35a1e94f7 100644 --- a/core/tests/test_apps.wallet.address_grs.py +++ b/core/tests/test_apps.bitcoin.address_grs.py @@ -1,7 +1,7 @@ from common import * -from apps.wallet.sign_tx.common import * -from apps.wallet.sign_tx.addresses import * +from apps.bitcoin.common import * +from apps.bitcoin.addresses import * from apps.common import coins from trezor.crypto import bip32, bip39 diff --git a/core/tests/test_apps.wallet.segwit.bip143.native_p2wpkh.py b/core/tests/test_apps.bitcoin.segwit.bip143.native_p2wpkh.py similarity index 96% rename from core/tests/test_apps.wallet.segwit.bip143.native_p2wpkh.py rename to core/tests/test_apps.bitcoin.segwit.bip143.native_p2wpkh.py index 1223cf7a3..fa8f413ba 100644 --- a/core/tests/test_apps.wallet.segwit.bip143.native_p2wpkh.py +++ b/core/tests/test_apps.bitcoin.segwit.bip143.native_p2wpkh.py @@ -1,8 +1,8 @@ from common import * -from apps.wallet.sign_tx.scripts import output_derive_script -from apps.wallet.sign_tx.bitcoin import Bitcoin -from apps.wallet.sign_tx.writers import get_tx_hash +from apps.bitcoin.scripts import output_derive_script +from apps.bitcoin.sign_tx.bitcoin import Bitcoin +from apps.bitcoin.writers import get_tx_hash from apps.common import coins from trezor.messages.SignTx import SignTx from trezor.messages.TxInputType import TxInputType diff --git a/core/tests/test_apps.wallet.segwit.bip143.p2wpkh_in_p2sh.py b/core/tests/test_apps.bitcoin.segwit.bip143.p2wpkh_in_p2sh.py similarity index 95% rename from core/tests/test_apps.wallet.segwit.bip143.p2wpkh_in_p2sh.py rename to core/tests/test_apps.bitcoin.segwit.bip143.p2wpkh_in_p2sh.py index cbc8510fb..9cd71444a 100644 --- a/core/tests/test_apps.wallet.segwit.bip143.p2wpkh_in_p2sh.py +++ b/core/tests/test_apps.bitcoin.segwit.bip143.p2wpkh_in_p2sh.py @@ -1,8 +1,8 @@ from common import * -from apps.wallet.sign_tx.scripts import output_derive_script -from apps.wallet.sign_tx.bitcoin import Bitcoin -from apps.wallet.sign_tx.writers import get_tx_hash +from apps.bitcoin.scripts import output_derive_script +from apps.bitcoin.sign_tx.bitcoin import Bitcoin +from apps.bitcoin.writers import get_tx_hash from apps.common import coins from trezor.messages.SignTx import SignTx from trezor.messages.TxInputType import TxInputType diff --git a/core/tests/test_apps.wallet.segwit.signtx.native_p2wpkh.py b/core/tests/test_apps.bitcoin.segwit.signtx.native_p2wpkh.py similarity index 98% rename from core/tests/test_apps.wallet.segwit.signtx.native_p2wpkh.py rename to core/tests/test_apps.bitcoin.segwit.signtx.native_p2wpkh.py index f571f682f..a20853ef7 100644 --- a/core/tests/test_apps.wallet.segwit.signtx.native_p2wpkh.py +++ b/core/tests/test_apps.bitcoin.segwit.signtx.native_p2wpkh.py @@ -13,12 +13,12 @@ from trezor.messages.TxRequestDetailsType import TxRequestDetailsType from trezor.messages.TxRequestSerializedType import TxRequestSerializedType from trezor.messages import InputScriptType from trezor.messages import OutputScriptType +from trezor import wire from apps.common import coins from apps.common.seed import Keychain -from apps.wallet.keychain import get_namespaces_for_coin -from apps.wallet.sign_tx import helpers, bitcoin -from apps.wallet.sign_tx.scripts import ScriptsError +from apps.bitcoin.keychain import get_namespaces_for_coin +from apps.bitcoin.sign_tx import helpers, bitcoin EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray()) @@ -272,7 +272,7 @@ class TestSignSegwitTxNativeP2WPKH(unittest.TestCase): signer = bitcoin.Bitcoin(tx, keychain, coin).signer() for request, response in chunks(messages, 2): if response is None: - with self.assertRaises(ScriptsError): + with self.assertRaises(wire.DataError): signer.send(request) else: self.assertEqual(signer.send(request), response) diff --git a/core/tests/test_apps.wallet.segwit.signtx.native_p2wpkh_grs.py b/core/tests/test_apps.bitcoin.segwit.signtx.native_p2wpkh_grs.py similarity index 98% rename from core/tests/test_apps.wallet.segwit.signtx.native_p2wpkh_grs.py rename to core/tests/test_apps.bitcoin.segwit.signtx.native_p2wpkh_grs.py index 1ec161968..e2b025125 100644 --- a/core/tests/test_apps.wallet.segwit.signtx.native_p2wpkh_grs.py +++ b/core/tests/test_apps.bitcoin.segwit.signtx.native_p2wpkh_grs.py @@ -16,8 +16,8 @@ from trezor.messages import OutputScriptType from apps.common import coins from apps.common.seed import Keychain -from apps.wallet.keychain import get_namespaces_for_coin -from apps.wallet.sign_tx import bitcoinlike, helpers +from apps.bitcoin.keychain import get_namespaces_for_coin +from apps.bitcoin.sign_tx import bitcoinlike, helpers EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray()) diff --git a/core/tests/test_apps.wallet.segwit.signtx.p2wpkh_in_p2sh.py b/core/tests/test_apps.bitcoin.segwit.signtx.p2wpkh_in_p2sh.py similarity index 98% rename from core/tests/test_apps.wallet.segwit.signtx.p2wpkh_in_p2sh.py rename to core/tests/test_apps.bitcoin.segwit.signtx.p2wpkh_in_p2sh.py index f8c1b5a81..7f9881672 100644 --- a/core/tests/test_apps.wallet.segwit.signtx.p2wpkh_in_p2sh.py +++ b/core/tests/test_apps.bitcoin.segwit.signtx.p2wpkh_in_p2sh.py @@ -13,11 +13,12 @@ from trezor.messages.TxRequestDetailsType import TxRequestDetailsType from trezor.messages.TxRequestSerializedType import TxRequestSerializedType from trezor.messages import InputScriptType from trezor.messages import OutputScriptType +from trezor import wire from apps.common import coins from apps.common.seed import Keychain -from apps.wallet.keychain import get_namespaces_for_coin -from apps.wallet.sign_tx import bitcoin, common, helpers +from apps.bitcoin.keychain import get_namespaces_for_coin +from apps.bitcoin.sign_tx import bitcoin, helpers EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray()) @@ -341,8 +342,8 @@ class TestSignSegwitTxP2WPKHInP2SH(unittest.TestCase): i = 0 messages_count = int(len(messages) / 2) for request, response in chunks(messages, 2): - if i == messages_count - 1: # last message should throw SigningError - self.assertRaises(common.SigningError, signer.send, request) + if i == messages_count - 1: # last message should throw wire.Error + self.assertRaises(wire.ProcessError, signer.send, request) else: self.assertEqual(signer.send(request), response) i += 1 diff --git a/core/tests/test_apps.wallet.segwit.signtx.p2wpkh_in_p2sh_grs.py b/core/tests/test_apps.bitcoin.segwit.signtx.p2wpkh_in_p2sh_grs.py similarity index 99% rename from core/tests/test_apps.wallet.segwit.signtx.p2wpkh_in_p2sh_grs.py rename to core/tests/test_apps.bitcoin.segwit.signtx.p2wpkh_in_p2sh_grs.py index e00fb33d2..8a1e71fb0 100644 --- a/core/tests/test_apps.wallet.segwit.signtx.p2wpkh_in_p2sh_grs.py +++ b/core/tests/test_apps.bitcoin.segwit.signtx.p2wpkh_in_p2sh_grs.py @@ -16,8 +16,8 @@ from trezor.messages import OutputScriptType from apps.common import coins from apps.common.seed import Keychain -from apps.wallet.keychain import get_namespaces_for_coin -from apps.wallet.sign_tx import bitcoinlike, helpers +from apps.bitcoin.keychain import get_namespaces_for_coin +from apps.bitcoin.sign_tx import bitcoinlike, helpers EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray()) diff --git a/core/tests/test_apps.wallet.sign_tx.writers.py b/core/tests/test_apps.bitcoin.sign_tx.writers.py similarity index 95% rename from core/tests/test_apps.wallet.sign_tx.writers.py rename to core/tests/test_apps.bitcoin.sign_tx.writers.py index 9134333bb..488cd603c 100644 --- a/core/tests/test_apps.wallet.sign_tx.writers.py +++ b/core/tests/test_apps.bitcoin.sign_tx.writers.py @@ -3,8 +3,7 @@ from common import * from trezor.messages.TxInputType import TxInputType from trezor.messages import InputScriptType -from apps.common import coins -from apps.wallet.sign_tx import writers +from apps.bitcoin import writers class TestWriters(unittest.TestCase): diff --git a/core/tests/test_apps.wallet.signtx.fee_threshold.py b/core/tests/test_apps.bitcoin.signtx.fee_threshold.py similarity index 99% rename from core/tests/test_apps.wallet.signtx.fee_threshold.py rename to core/tests/test_apps.bitcoin.signtx.fee_threshold.py index d0d8120f4..6bcfc3835 100644 --- a/core/tests/test_apps.wallet.signtx.fee_threshold.py +++ b/core/tests/test_apps.bitcoin.signtx.fee_threshold.py @@ -16,7 +16,7 @@ from trezor.messages import OutputScriptType from apps.common import coins from apps.common.seed import Keychain -from apps.wallet.sign_tx import bitcoin, helpers +from apps.bitcoin.sign_tx import bitcoin, helpers EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray()) diff --git a/core/tests/test_apps.wallet.signtx.omni.py b/core/tests/test_apps.bitcoin.signtx.omni.py similarity index 95% rename from core/tests/test_apps.wallet.signtx.omni.py rename to core/tests/test_apps.bitcoin.signtx.omni.py index a48c96f3b..3f02d6de7 100644 --- a/core/tests/test_apps.wallet.signtx.omni.py +++ b/core/tests/test_apps.bitcoin.signtx.omni.py @@ -1,6 +1,6 @@ from common import * -from apps.wallet.sign_tx.omni import is_valid, parse +from apps.bitcoin.sign_tx.omni import is_valid, parse class TestSignTxOmni(unittest.TestCase): diff --git a/core/tests/test_apps.wallet.signtx.py b/core/tests/test_apps.bitcoin.signtx.py similarity index 98% rename from core/tests/test_apps.wallet.signtx.py rename to core/tests/test_apps.bitcoin.signtx.py index d183a6e55..4fad0d0d3 100644 --- a/core/tests/test_apps.wallet.signtx.py +++ b/core/tests/test_apps.bitcoin.signtx.py @@ -16,8 +16,8 @@ from trezor.messages import OutputScriptType from apps.common import coins from apps.common.seed import Keychain -from apps.wallet.keychain import get_namespaces_for_coin -from apps.wallet.sign_tx import bitcoin, helpers +from apps.bitcoin.keychain import get_namespaces_for_coin +from apps.bitcoin.sign_tx import bitcoin, helpers EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray()) diff --git a/core/tests/test_apps.wallet.signtx_grs.py b/core/tests/test_apps.bitcoin.signtx_grs.py similarity index 98% rename from core/tests/test_apps.wallet.signtx_grs.py rename to core/tests/test_apps.bitcoin.signtx_grs.py index 946bb262c..1ea30e281 100644 --- a/core/tests/test_apps.wallet.signtx_grs.py +++ b/core/tests/test_apps.bitcoin.signtx_grs.py @@ -16,8 +16,8 @@ from trezor.messages import OutputScriptType from apps.common import coins from apps.common.seed import Keychain -from apps.wallet.keychain import get_namespaces_for_coin -from apps.wallet.sign_tx import bitcoinlike, helpers +from apps.bitcoin.keychain import get_namespaces_for_coin +from apps.bitcoin.sign_tx import bitcoinlike, helpers EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray()) diff --git a/core/tests/test_apps.wallet.txweight.py b/core/tests/test_apps.bitcoin.txweight.py similarity index 97% rename from core/tests/test_apps.wallet.txweight.py rename to core/tests/test_apps.bitcoin.txweight.py index 4d81a7705..3a4ec73ca 100644 --- a/core/tests/test_apps.wallet.txweight.py +++ b/core/tests/test_apps.bitcoin.txweight.py @@ -6,8 +6,8 @@ from trezor.messages import OutputScriptType from trezor.crypto import bip32, bip39 from apps.common import coins -from apps.wallet.sign_tx.tx_weight import * -from apps.wallet.sign_tx.scripts import output_derive_script +from apps.bitcoin.sign_tx.tx_weight import * +from apps.bitcoin.scripts import output_derive_script class TestCalculateTxWeight(unittest.TestCase): diff --git a/core/tests/test_apps.wallet.zcash.zip143.py b/core/tests/test_apps.bitcoin.zcash.zip143.py similarity index 98% rename from core/tests/test_apps.wallet.zcash.zip143.py rename to core/tests/test_apps.bitcoin.zcash.zip143.py index da84be85e..31612cf0e 100644 --- a/core/tests/test_apps.wallet.zcash.zip143.py +++ b/core/tests/test_apps.bitcoin.zcash.zip143.py @@ -5,10 +5,10 @@ from trezor.messages.TxInputType import TxInputType from trezor.messages.TxOutputBinType import TxOutputBinType from apps.common import coins -from apps.wallet.sign_tx.writers import get_tx_hash +from apps.bitcoin.writers import get_tx_hash if not utils.BITCOIN_ONLY: - from apps.wallet.sign_tx.zcash import Overwintered + from apps.bitcoin.sign_tx.zcash import Overwintered # test vectors inspired from https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/zip_0143.py diff --git a/core/tests/test_apps.wallet.zcash.zip243.py b/core/tests/test_apps.bitcoin.zcash.zip243.py similarity index 98% rename from core/tests/test_apps.wallet.zcash.zip243.py rename to core/tests/test_apps.bitcoin.zcash.zip243.py index 01aa0a2ef..9cd2bf30d 100644 --- a/core/tests/test_apps.wallet.zcash.zip243.py +++ b/core/tests/test_apps.bitcoin.zcash.zip243.py @@ -5,10 +5,10 @@ from trezor.messages.TxInputType import TxInputType from trezor.messages.TxOutputBinType import TxOutputBinType from apps.common import coins -from apps.wallet.sign_tx.writers import get_tx_hash +from apps.bitcoin.writers import get_tx_hash if not utils.BITCOIN_ONLY: - from apps.wallet.sign_tx.zcash import Overwintered + from apps.bitcoin.sign_tx.zcash import Overwintered # test vectors inspired from https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/zip_0243.py diff --git a/core/tests/test_apps.common.seed.py b/core/tests/test_apps.common.seed.py index 37e8e2bae..cee415652 100644 --- a/core/tests/test_apps.common.seed.py +++ b/core/tests/test_apps.common.seed.py @@ -1,12 +1,10 @@ from common import * from storage import cache -from apps.common import HARDENED, coins +from apps.common import 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 -from trezor.crypto.curve import secp256k1 class TestKeychain(unittest.TestCase): diff --git a/core/tests/test_apps.wallet.keychain.py b/core/tests/test_apps.wallet.keychain.py index 10d117425..e5f020cc0 100644 --- a/core/tests/test_apps.wallet.keychain.py +++ b/core/tests/test_apps.wallet.keychain.py @@ -4,7 +4,7 @@ from trezor import wire from trezor.crypto import bip39 from apps.common.paths import HARDENED -from apps.wallet.keychain import get_keychain_for_coin +from apps.bitcoin.keychain import get_keychain_for_coin class TestBitcoinKeychain(unittest.TestCase): diff --git a/docs/core/src/apps.md b/docs/core/src/apps.md index 987b8f76b..a6804298f 100644 --- a/docs/core/src/apps.md +++ b/docs/core/src/apps.md @@ -6,11 +6,11 @@ Each app has a `boot()` function in the module's \_\_init\_\_ file. This functio ## Example -This binds the message GetAddress to function `get_address` inside the `apps.wallet` module. +This binds the message GetAddress to function `get_address` inside the `apps.bitcoin` module. ```python from trezor import wire from trezor.messages import MessageType -wire.add(MessageType.GetAddress, apps.wallet, "get_address") +wire.add(MessageType.GetAddress, apps.bitcoin, "get_address") ```