From 2c003052f5c0fd02f3928887d9fb9e68f01faa1c Mon Sep 17 00:00:00 2001 From: Andrew Kozlik Date: Fri, 19 Mar 2021 21:26:52 +0100 Subject: [PATCH] refactor(core/bitcoin): Change CoinInfo.script_hash to be a HashContext. --- core/src/apps/binance/helpers.py | 4 ++-- core/src/apps/bitcoin/addresses.py | 6 +++--- core/src/apps/bitcoin/common.py | 2 +- core/src/apps/bitcoin/verification.py | 6 +++--- core/src/apps/common/coininfo.py | 12 ++++++------ core/src/apps/common/coininfo.py.mako | 12 ++++++------ core/src/trezor/crypto/scripts.py | 14 ++++++-------- core/src/trezor/utils.py | 3 +++ 8 files changed, 30 insertions(+), 29 deletions(-) diff --git a/core/src/apps/binance/helpers.py b/core/src/apps/binance/helpers.py index dad3fe4962..d718f44792 100644 --- a/core/src/apps/binance/helpers.py +++ b/core/src/apps/binance/helpers.py @@ -1,7 +1,7 @@ from micropython import const from trezor.crypto import bech32 -from trezor.crypto.scripts import sha256_ripemd160_digest +from trezor.crypto.scripts import sha256_ripemd160 from trezor.messages import ( BinanceCancelMsg, BinanceInputOutput, @@ -86,7 +86,7 @@ def address_from_public_key(pubkey: bytes, hrp: str) -> str: HRP - bnb for productions, tbnb for tests """ - h = sha256_ripemd160_digest(pubkey) + h = sha256_ripemd160(pubkey).digest() convertedbits = bech32.convertbits(h, 8, 5, False) diff --git a/core/src/apps/bitcoin/addresses.py b/core/src/apps/bitcoin/addresses.py index de7a400eb8..84845e08e2 100644 --- a/core/src/apps/bitcoin/addresses.py +++ b/core/src/apps/bitcoin/addresses.py @@ -97,7 +97,7 @@ def address_multisig_p2wsh(pubkeys: list[bytes], m: int, hrp: str) -> str: def address_pkh(pubkey: bytes, coin: CoinInfo) -> str: - s = address_type.tobytes(coin.address_type) + coin.script_hash(pubkey) + s = address_type.tobytes(coin.address_type) + coin.script_hash(pubkey).digest() return base58.encode_check(bytes(s), coin.b58_hash) @@ -109,13 +109,13 @@ def address_p2sh(redeem_script_hash: bytes, coin: CoinInfo) -> str: def address_p2wpkh_in_p2sh(pubkey: bytes, coin: CoinInfo) -> str: pubkey_hash = ecdsa_hash_pubkey(pubkey, coin) redeem_script = output_script_native_p2wpkh_or_p2wsh(pubkey_hash) - redeem_script_hash = coin.script_hash(redeem_script) + redeem_script_hash = coin.script_hash(redeem_script).digest() return address_p2sh(redeem_script_hash, coin) 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 = coin.script_hash(redeem_script) + redeem_script_hash = coin.script_hash(redeem_script).digest() return address_p2sh(redeem_script_hash, coin) diff --git a/core/src/apps/bitcoin/common.py b/core/src/apps/bitcoin/common.py index cc81c220f9..8a8a529497 100644 --- a/core/src/apps/bitcoin/common.py +++ b/core/src/apps/bitcoin/common.py @@ -73,7 +73,7 @@ def ecdsa_hash_pubkey(pubkey: bytes, coin: CoinInfo) -> bytes: else: ensure(len(pubkey) == 33) # compresssed format - return coin.script_hash(pubkey) + return coin.script_hash(pubkey).digest() def encode_bech32_address(prefix: str, script: bytes) -> str: diff --git a/core/src/apps/bitcoin/verification.py b/core/src/apps/bitcoin/verification.py index c00f9e45fb..944b729e61 100644 --- a/core/src/apps/bitcoin/verification.py +++ b/core/src/apps/bitcoin/verification.py @@ -60,7 +60,7 @@ class SignatureVerifier: write_input_script_p2wpkh_in_p2sh(w, pubkey_hash) if w != script_sig: raise wire.DataError("Invalid public key hash") - script_hash = coin.script_hash(script_sig[1:]) + script_hash = coin.script_hash(script_sig[1:]).digest() if output_script_p2sh(script_hash) != script_pubkey: raise wire.DataError("Invalid script hash") self.public_keys = [public_key] @@ -72,7 +72,7 @@ class SignatureVerifier: write_input_script_p2wsh_in_p2sh(w, script_hash) if w != script_sig: raise wire.DataError("Invalid script hash") - script_hash = coin.script_hash(script_sig[1:]) + script_hash = coin.script_hash(script_sig[1:]).digest() if output_script_p2sh(script_hash) != script_pubkey: raise wire.DataError("Invalid script hash") self.public_keys, self.threshold = parse_output_script_multisig(script) @@ -88,7 +88,7 @@ class SignatureVerifier: self.signatures = [(signature, hash_type)] elif len(script_pubkey) == 23: # P2SH script, self.signatures = parse_input_script_multisig(script_sig) - script_hash = coin.script_hash(script) + script_hash = coin.script_hash(script).digest() if output_script_p2sh(script_hash) != script_pubkey: raise wire.DataError("Invalid script hash") self.public_keys, self.threshold = parse_output_script_multisig(script) diff --git a/core/src/apps/common/coininfo.py b/core/src/apps/common/coininfo.py index 620adc8aa6..969cb1866a 100644 --- a/core/src/apps/common/coininfo.py +++ b/core/src/apps/common/coininfo.py @@ -2,10 +2,10 @@ # do not edit manually! from trezor import utils from trezor.crypto.base58 import blake256d_32, groestl512d_32, keccak_32, sha256d_32 -from trezor.crypto.scripts import blake256_ripemd160_digest, sha256_ripemd160_digest +from trezor.crypto.scripts import blake256_ripemd160, sha256_ripemd160 if False: - from typing import Any + from typing import Any, Type # flake8: noqa @@ -67,19 +67,19 @@ class CoinInfo: if curve_name == "secp256k1-groestl": self.b58_hash = groestl512d_32 self.sign_hash_double = False - self.script_hash = sha256_ripemd160_digest + self.script_hash: Type[utils.HashContext] = sha256_ripemd160 elif curve_name == "secp256k1-decred": self.b58_hash = blake256d_32 self.sign_hash_double = False - self.script_hash = blake256_ripemd160_digest + self.script_hash = blake256_ripemd160 elif curve_name == "secp256k1-smart": self.b58_hash = keccak_32 self.sign_hash_double = False - self.script_hash = sha256_ripemd160_digest + self.script_hash = sha256_ripemd160 else: self.b58_hash = sha256d_32 self.sign_hash_double = True - self.script_hash = sha256_ripemd160_digest + self.script_hash = sha256_ripemd160 def __eq__(self, other: Any) -> bool: if not isinstance(other, CoinInfo): diff --git a/core/src/apps/common/coininfo.py.mako b/core/src/apps/common/coininfo.py.mako index eb73ae9395..bd88e2df14 100644 --- a/core/src/apps/common/coininfo.py.mako +++ b/core/src/apps/common/coininfo.py.mako @@ -2,10 +2,10 @@ # do not edit manually! from trezor import utils from trezor.crypto.base58 import blake256d_32, groestl512d_32, keccak_32, sha256d_32 -from trezor.crypto.scripts import blake256_ripemd160_digest, sha256_ripemd160_digest +from trezor.crypto.scripts import blake256_ripemd160, sha256_ripemd160 if False: - from typing import Any + from typing import Any, Type # flake8: noqa @@ -67,19 +67,19 @@ class CoinInfo: if curve_name == "secp256k1-groestl": self.b58_hash = groestl512d_32 self.sign_hash_double = False - self.script_hash = sha256_ripemd160_digest + self.script_hash: Type[utils.HashContext] = sha256_ripemd160 elif curve_name == "secp256k1-decred": self.b58_hash = blake256d_32 self.sign_hash_double = False - self.script_hash = blake256_ripemd160_digest + self.script_hash = blake256_ripemd160 elif curve_name == "secp256k1-smart": self.b58_hash = keccak_32 self.sign_hash_double = False - self.script_hash = sha256_ripemd160_digest + self.script_hash = sha256_ripemd160 else: self.b58_hash = sha256d_32 self.sign_hash_double = True - self.script_hash = sha256_ripemd160_digest + self.script_hash = sha256_ripemd160 def __eq__(self, other: Any) -> bool: if not isinstance(other, CoinInfo): diff --git a/core/src/trezor/crypto/scripts.py b/core/src/trezor/crypto/scripts.py index 4944bdab1b..b98257b2ec 100644 --- a/core/src/trezor/crypto/scripts.py +++ b/core/src/trezor/crypto/scripts.py @@ -1,13 +1,11 @@ from trezor.crypto.hashlib import blake256, ripemd160, sha256 -def sha256_ripemd160_digest(b: bytes) -> bytes: - h = sha256(b).digest() - h = ripemd160(h).digest() - return h +class sha256_ripemd160(sha256): + def digest(self) -> bytes: + return ripemd160(super().digest()).digest() -def blake256_ripemd160_digest(b: bytes) -> bytes: - h = blake256(b).digest() - h = ripemd160(h).digest() - return h +class blake256_ripemd160(blake256): + def digest(self) -> bytes: + return ripemd160(super().digest()).digest() diff --git a/core/src/trezor/utils.py b/core/src/trezor/utils.py index 7bc6d95acb..43aaea2932 100644 --- a/core/src/trezor/utils.py +++ b/core/src/trezor/utils.py @@ -146,6 +146,9 @@ def chunks_intersperse( if False: class HashContext(Protocol): + def __init__(self, data: bytes = None) -> None: + ... + def update(self, buf: bytes) -> None: ...