You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
trezor-firmware/core/src/apps/bitcoin/verify_message.py

73 lines
2.1 KiB

from trezor import wire
from trezor.crypto.curve import secp256k1
from trezor.enums import InputScriptType
from trezor.messages import Success
from trezor.ui.layouts import confirm_signverify
from apps.common import coins
from apps.common.signverify import decode_message, message_digest
from .addresses import (
address_p2wpkh,
address_p2wpkh_in_p2sh,
address_pkh,
address_short,
address_to_cashaddr,
)
if False:
from trezor.messages import VerifyMessage
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),
)
return Success(message="Message verified")