async def verify_message(ctx: Context, msg: EthereumVerifyMessage) -> Success: digest = message_digest(msg.message) if len(msg.signature) != 65: raise wire.DataError("Invalid signature") sig = bytearray([msg.signature[64]]) + msg.signature[:64] pubkey = secp256k1.verify_recover(sig, digest) if not pubkey: raise wire.DataError("Invalid signature") pkh = sha3_256(pubkey[1:], keccak=True).digest()[-20:] address_bytes = bytes_from_address(msg.address) if address_bytes != pkh: raise wire.DataError("Invalid signature") address = address_from_bytes(address_bytes) await confirm_signverify(ctx, "ETH", decode_message(msg.message), address=address, verify=True) return Success(message="Message verified")
async def ethereum_verify_message(ctx, msg): from .sign_message import message_digest from trezor.crypto.curve import secp256k1 from trezor.crypto.hashlib import sha3_256 from trezor import ui from trezor.messages.Success import Success digest = message_digest(msg.message) sig = bytearray([msg.signature[64]]) + msg.signature[:64] pubkey = secp256k1.verify_recover(sig, digest) if not pubkey: raise ValueError('Invalid signature') pkh = sha3_256(pubkey[1:]).digest(True)[-20:] if msg.address != pkh: raise ValueError('Invalid signature') ui.display.clear() ui.display.text(10, 30, 'Verifying message', ui.BOLD, ui.LIGHT_GREEN, ui.BG) ui.display.text(10, 60, msg.message, ui.MONO, ui.FG, ui.BG) ui.display.text(10, 80, msg.address, ui.MONO, ui.FG, ui.BG) return Success(message='Message verified')
async def layout_verify_message(ctx, msg): from trezor.messages.Success import Success from trezor.crypto.curve import secp256k1 from trezor.crypto.hashlib import ripemd160, sha256 from trezor.crypto import base58 from ..common import address_type from ..common import coins from ..common.signverify import message_digest coin_name = msg.coin_name or 'Bitcoin' coin = coins.by_name(coin_name) digest = message_digest(coin, msg.message) pubkey = secp256k1.verify_recover(msg.signature, digest) if not pubkey: raise ValueError('Invalid signature') raw_address = base58.decode_check(msg.address) at, pkh = address_type.split(coin, raw_address) pkh2 = ripemd160(sha256(pubkey).digest()).digest() if pkh != pkh2: raise ValueError('Invalid signature') ui.display.clear() ui.display.text(10, 30, 'Verifying message', ui.BOLD, ui.LIGHT_GREEN, ui.BG) ui.display.text(10, 60, msg.message, ui.MONO, ui.FG, ui.BG) ui.display.text(10, 80, msg.address, ui.MONO, ui.FG, ui.BG) return Success(message='Message verified')
async def verify_message(ctx, msg): digest = message_digest(msg.message) if len(msg.signature) != 65: raise wire.DataError("Invalid signature") sig = bytearray([msg.signature[64]]) + msg.signature[:64] try: pubkey = secp256k1.verify_recover(sig, digest) except ValueError: raise wire.DataError("Invalid signature") if not pubkey: raise wire.DataError("Invalid signature") pkh = sha3_256(pubkey[1:], keccak=True).digest()[-20:] address_bytes = bytes_from_address(msg.address) if address_bytes != pkh: raise wire.DataError("Invalid signature") address = address_from_bytes(address_bytes) await require_confirm_verify_message(ctx, address, msg.message) return Success(message="Message verified")
def test_verify_recover(self): for compressed in [False, True]: for _ in range(100): sk = secp256k1.generate_secret() pk = secp256k1.publickey(sk, compressed) dig = random.bytes(32) sig = secp256k1.sign(sk, dig, compressed) pk2 = secp256k1.verify_recover(sig, dig) self.assertEqual(pk, pk2)
async def verify_message(ctx: wire.Context, msg: VerifyMessage) -> Success: message = msg.message address = msg.address signature = msg.signature coin_name = msg.coin_name or "Bitcoin" coin = coins.by_name(coin_name) digest = message_digest(coin, message) recid = signature[0] if 27 <= recid <= 34: # p2pkh script_type = InputScriptType.SPENDADDRESS elif 35 <= recid <= 38: # segwit-in-p2sh script_type = InputScriptType.SPENDP2SHWITNESS signature = bytes([signature[0] - 4]) + signature[1:] elif 39 <= recid <= 42: # native segwit script_type = InputScriptType.SPENDWITNESS signature = bytes([signature[0] - 8]) + signature[1:] else: raise wire.ProcessError("Invalid signature") pubkey = secp256k1.verify_recover(signature, digest) if not pubkey: raise wire.ProcessError("Invalid signature") if script_type == InputScriptType.SPENDADDRESS: addr = address_pkh(pubkey, coin) if coin.cashaddr_prefix is not None: addr = address_to_cashaddr(addr, coin) elif script_type == InputScriptType.SPENDP2SHWITNESS: addr = address_p2wpkh_in_p2sh(pubkey, coin) elif script_type == InputScriptType.SPENDWITNESS: addr = address_p2wpkh(pubkey, coin) else: raise wire.ProcessError("Invalid signature") if addr != address: raise wire.ProcessError("Invalid signature") await confirm_signverify( ctx, coin.coin_shortcut, decode_message(message), address=address_short(coin, address), verify=True, ) return Success(message="Message verified")
async def verify_message(ctx, msg): message = msg.message address = msg.address signature = msg.signature coin_name = msg.coin_name or 'Bitcoin' coin = coins.by_name(coin_name) digest = message_digest(coin, message) script_type = None recid = signature[0] if recid >= 27 and recid <= 34: script_type = SPENDADDRESS # p2pkh elif recid >= 35 and recid <= 38: script_type = SPENDP2SHWITNESS # segwit-in-p2sh signature = bytes([signature[0] - 4]) + signature[1:] elif recid >= 39 and recid <= 42: script_type = SPENDWITNESS # native segwit signature = bytes([signature[0] - 8]) + signature[1:] else: raise wire.ProcessError('Invalid signature') pubkey = secp256k1.verify_recover(signature, digest) if not pubkey: raise wire.ProcessError('Invalid signature') if script_type == SPENDADDRESS: addr = address_pkh(pubkey, coin.address_type) 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) elif script_type == SPENDWITNESS: addr = address_p2wpkh(pubkey, coin.bech32_prefix) else: raise wire.ProcessError('Invalid signature') if addr != address: raise wire.ProcessError('Invalid signature') address_short = address[len(coin.cashaddr_prefix) + 1:] if coin.cashaddr_prefix is not None else address await require_confirm_verify_message(ctx, address_short, message) return Success(message='Message verified')
async def verify_message(ctx, msg): digest = message_digest(msg.message) sig = bytearray([msg.signature[64]]) + msg.signature[:64] pubkey = secp256k1.verify_recover(sig, digest) if not pubkey: raise ValueError("Invalid signature") pkh = sha3_256(pubkey[1:], keccak=True).digest()[-20:] if msg.address != pkh: raise ValueError("Invalid signature") address = "0x" + hexlify(msg.address).decode() await require_confirm_verify_message(ctx, address, msg.message) return Success(message="Message verified")
async def ethereum_verify_message(ctx, msg): digest = message_digest(msg.message) sig = bytearray([msg.signature[64]]) + msg.signature[:64] pubkey = secp256k1.verify_recover(sig, digest) if not pubkey: raise ValueError('Invalid signature') pkh = sha3_256(pubkey[1:]).digest(True)[-20:] if msg.address != pkh: raise ValueError('Invalid signature') address = '0x' + hexlify(msg.address).decode() await require_confirm_verify_message(ctx, address, msg.message) return Success(message='Message verified')
async def verify_message(ctx, msg): message = msg.message address = msg.address signature = msg.signature coin_name = msg.coin_name or 'Bitcoin' coin = coins.by_name(coin_name) await confirm_verify_message(ctx, message) digest = message_digest(coin, message) pubkey = secp256k1.verify_recover(signature, digest) if not pubkey: raise wire.FailureError(ProcessError, 'Invalid signature') raw_address = base58.decode_check(address) _, pkh = address_type.split(coin, raw_address) pkh2 = ripemd160(sha256(pubkey).digest()).digest() if pkh != pkh2: raise wire.FailureError(ProcessError, 'Invalid signature') return Success(message='Message verified')