From d09547fec3c921fa01429b9f43df08b37c6094b4 Mon Sep 17 00:00:00 2001 From: Yura Pakhuchiy Date: Sun, 1 Jul 2018 23:47:43 +0700 Subject: [PATCH] Introduce coininfo.b58_hash --- src/apps/common/coininfo.py | 4 +++ src/apps/wallet/sign_tx/addresses.py | 40 ++++++++++++++-------------- src/apps/wallet/sign_tx/signing.py | 2 +- src/apps/wallet/verify_message.py | 4 +-- src/trezor/crypto/base58.py | 9 ++++--- src/trezor/crypto/hashlib.py | 2 +- 6 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/apps/common/coininfo.py b/src/apps/common/coininfo.py index e85b20f389..b30d2668d8 100644 --- a/src/apps/common/coininfo.py +++ b/src/apps/common/coininfo.py @@ -1,3 +1,5 @@ +from trezor.crypto.base58 import groestl512d_32, sha256d_32 + class CoinInfo: def __init__( @@ -36,8 +38,10 @@ class CoinInfo: self.bip115 = bip115 self.curve_name = curve_name if curve_name == 'secp256k1-groestl': + self.b58_hash = groestl512d_32 self.sign_hash_double = False else: + self.b58_hash = sha256d_32 self.sign_hash_double = True diff --git a/src/apps/wallet/sign_tx/addresses.py b/src/apps/wallet/sign_tx/addresses.py index f5929a1bcc..077885b646 100644 --- a/src/apps/wallet/sign_tx/addresses.py +++ b/src/apps/wallet/sign_tx/addresses.py @@ -34,7 +34,7 @@ def get_address(script_type: InputScriptType, coin: CoinInfo, node, multisig=Non 'Multisig not enabled on this coin') pubkeys = multisig_get_pubkeys(multisig) - address = address_multisig_p2sh(pubkeys, multisig.m, coin.address_type_p2sh) + address = address_multisig_p2sh(pubkeys, multisig.m, coin) if coin.cashaddr_prefix is not None: address = address_to_cashaddr(address, coin) return address @@ -67,32 +67,32 @@ def get_address(script_type: InputScriptType, coin: CoinInfo, node, multisig=Non # p2wsh multisig nested in p2sh if multisig is not None: pubkeys = multisig_get_pubkeys(multisig) - return address_multisig_p2wsh_in_p2sh(pubkeys, multisig.m, coin.address_type_p2sh) + return address_multisig_p2wsh_in_p2sh(pubkeys, multisig.m, coin) # p2wpkh nested in p2sh - return address_p2wpkh_in_p2sh(node.public_key(), coin.address_type_p2sh) + return address_p2wpkh_in_p2sh(node.public_key(), coin) else: raise AddressError(FailureType.ProcessError, 'Invalid script type') -def address_multisig_p2sh(pubkeys: bytes, m: int, addrtype: int): - if addrtype is None: +def address_multisig_p2sh(pubkeys: bytes, m: int, coin: CoinInfo): + if coin.address_type_p2sh is None: raise AddressError(FailureType.ProcessError, 'Multisig not enabled on this coin') redeem_script = output_script_multisig(pubkeys, m) redeem_script_hash = sha256_ripemd160_digest(redeem_script) - return address_p2sh(redeem_script_hash, addrtype) + return address_p2sh(redeem_script_hash, coin) -def address_multisig_p2wsh_in_p2sh(pubkeys: bytes, m: int, addrtype: int): - if addrtype is None: +def address_multisig_p2wsh_in_p2sh(pubkeys: bytes, m: int, coin: CoinInfo): + if coin.address_type_p2sh is None: raise AddressError(FailureType.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, addrtype) + return address_p2wsh_in_p2sh(witness_script_hash, coin) def address_multisig_p2wsh(pubkeys: bytes, m: int, hrp: str): @@ -104,27 +104,27 @@ def address_multisig_p2wsh(pubkeys: bytes, m: int, hrp: str): return address_p2wsh(witness_script_hash, hrp) -def address_pkh(pubkey: bytes, addrtype: int) -> str: - s = addrtype_bytes(addrtype) + sha256_ripemd160_digest(pubkey) - return base58.encode_check(bytes(s)) +def address_pkh(pubkey: bytes, coin: CoinInfo) -> str: + s = addrtype_bytes(coin.address_type) + sha256_ripemd160_digest(pubkey) + return base58.encode_check(bytes(s), coin.b58_hash) -def address_p2sh(redeem_script_hash: bytes, addrtype: int) -> str: - s = addrtype_bytes(addrtype) + redeem_script_hash - return base58.encode_check(bytes(s)) +def address_p2sh(redeem_script_hash: bytes, coin: CoinInfo) -> str: + s = addrtype_bytes(coin.address_type_p2sh) + redeem_script_hash + return base58.encode_check(bytes(s), coin.b58_hash) -def address_p2wpkh_in_p2sh(pubkey: bytes, addrtype: int) -> str: +def address_p2wpkh_in_p2sh(pubkey: bytes, coin: CoinInfo) -> str: pubkey_hash = ecdsa_hash_pubkey(pubkey) redeem_script = output_script_native_p2wpkh_or_p2wsh(pubkey_hash) redeem_script_hash = sha256_ripemd160_digest(redeem_script) - return address_p2sh(redeem_script_hash, addrtype) + return address_p2sh(redeem_script_hash, coin) -def address_p2wsh_in_p2sh(witness_script_hash: bytes, addrtype: int) -> str: +def address_p2wsh_in_p2sh(witness_script_hash: bytes, coin: CoinInfo) -> str: redeem_script = output_script_native_p2wpkh_or_p2wsh(witness_script_hash) redeem_script_hash = sha256_ripemd160_digest(redeem_script) - return address_p2sh(redeem_script_hash, addrtype) + return address_p2sh(redeem_script_hash, coin) def address_p2wpkh(pubkey: bytes, hrp: str) -> str: @@ -153,7 +153,7 @@ def decode_bech32_address(prefix: str, address: str) -> bytes: def address_to_cashaddr(address: str, coin: CoinInfo) -> str: - raw = base58.decode_check(address) + raw = base58.decode_check(address, coin.b58_hash) version, data = raw[0], raw[1:] if version == coin.address_type: version = cashaddr.ADDRESS_TYPE_P2KH diff --git a/src/apps/wallet/sign_tx/signing.py b/src/apps/wallet/sign_tx/signing.py index 0c69254ac7..3fd5cc2060 100644 --- a/src/apps/wallet/sign_tx/signing.py +++ b/src/apps/wallet/sign_tx/signing.py @@ -509,7 +509,7 @@ def output_derive_script(o: TxOutputType, coin: CoinInfo, root: bip32.HDNode) -> raise ValueError('Unknown cashaddr address type') raw_address = bytes([version]) + data else: - raw_address = base58.decode_check(o.address) + raw_address = base58.decode_check(o.address, coin.b58_hash) if address_type.check(coin.address_type, raw_address): # p2pkh diff --git a/src/apps/wallet/verify_message.py b/src/apps/wallet/verify_message.py index 571c3a1d25..88ebce5187 100644 --- a/src/apps/wallet/verify_message.py +++ b/src/apps/wallet/verify_message.py @@ -38,11 +38,11 @@ async def verify_message(ctx, msg): raise wire.ProcessError('Invalid signature') if script_type == SPENDADDRESS: - addr = address_pkh(pubkey, coin.address_type) + addr = address_pkh(pubkey, coin) if coin.cashaddr_prefix is not None: addr = address_to_cashaddr(addr, coin) elif script_type == SPENDP2SHWITNESS: - addr = address_p2wpkh_in_p2sh(pubkey, coin.address_type_p2sh) + addr = address_p2wpkh_in_p2sh(pubkey, coin) elif script_type == SPENDWITNESS: addr = address_p2wpkh(pubkey, coin.bech32_prefix) else: diff --git a/src/trezor/crypto/base58.py b/src/trezor/crypto/base58.py index c3624af0b3..f4c36cd0b1 100644 --- a/src/trezor/crypto/base58.py +++ b/src/trezor/crypto/base58.py @@ -59,19 +59,22 @@ def decode(string: str) -> bytes: return bytes((b for b in reversed(result + [0] * (origlen - newlen)))) -def _dsha256_32(data: bytes) -> bytes: +def sha256d_32(data: bytes) -> bytes: from .hashlib import sha256 return sha256(sha256(data).digest()).digest()[:4] +def groestl512d_32(data: bytes) -> bytes: + from .hashlib import groestl512 + return groestl512(groestl512(data).digest()).digest()[:4] -def encode_check(data: bytes, digestfunc=_dsha256_32) -> str: +def encode_check(data: bytes, digestfunc=sha256d_32) -> str: ''' Convert bytes to base58 encoded string, append checksum. ''' return encode(data + digestfunc(data)) -def decode_check(string: str, digestfunc=_dsha256_32) -> bytes: +def decode_check(string: str, digestfunc=sha256d_32) -> bytes: ''' Convert base58 encoded string to bytes and verify checksum. ''' diff --git a/src/trezor/crypto/hashlib.py b/src/trezor/crypto/hashlib.py index 14ea76d666..526adfd7a4 100644 --- a/src/trezor/crypto/hashlib.py +++ b/src/trezor/crypto/hashlib.py @@ -1 +1 @@ -from trezorcrypto import blake256, blake2b, blake2s, ripemd160, sha1, sha256, sha512, sha3_256, sha3_512 # noqa: F401 +from trezorcrypto import blake256, blake2b, blake2s, groestl512, ripemd160, sha1, sha256, sha512, sha3_256, sha3_512 # noqa: F401