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 sign_message(ctx: wire.Context, msg: SignMessage, keychain: Keychain, coin: CoinInfo) -> MessageSignature: message = msg.message address_n = msg.address_n script_type = msg.script_type or InputScriptType.SPENDADDRESS await validate_path(ctx, keychain, address_n) await confirm_signverify(ctx, coin.coin_shortcut, decode_message(message)) node = keychain.derive(address_n) seckey = node.private_key() address = get_address(script_type, coin, node) digest = message_digest(coin, message) signature = secp256k1.sign(seckey, digest) if script_type == InputScriptType.SPENDADDRESS: pass elif script_type == InputScriptType.SPENDP2SHWITNESS: signature = bytes([signature[0] + 4]) + signature[1:] elif script_type == InputScriptType.SPENDWITNESS: signature = bytes([signature[0] + 8]) + signature[1:] else: raise wire.ProcessError("Unsupported script type") return MessageSignature(address=address, signature=signature)
async def sign_message(ctx, msg, keychain): await paths.validate_path(ctx, keychain, msg.address_n) await confirm_signverify(ctx, "Lisk", decode_message(msg.message)) node = keychain.derive(msg.address_n) seckey = node.private_key() pubkey = node.public_key() pubkey = pubkey[1:] # skip ed25519 pubkey marker signature = ed25519.sign(seckey, message_digest(msg.message)) return LiskMessageSignature(public_key=pubkey, signature=signature)
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): digest = message_digest(msg.message) verified = ed25519.verify(msg.public_key, msg.signature, digest) if not verified: raise wire.ProcessError("Invalid signature") address = get_address_from_public_key(msg.public_key) await confirm_signverify(ctx, "Lisk", decode_message(msg.message), address=address) return Success(message="Message verified")
async def sign_message(ctx, msg, keychain): await paths.validate_path(ctx, keychain, msg.address_n) await confirm_signverify(ctx, "ETH", decode_message(msg.message)) node = keychain.derive(msg.address_n) signature = secp256k1.sign( node.private_key(), message_digest(msg.message), False, secp256k1.CANONICAL_SIG_ETHEREUM, ) return EthereumMessageSignature( address=address.address_from_bytes(node.ethereum_pubkeyhash()), signature=signature[1:] + bytearray([signature[0]]), )
async def sign_message(ctx: wire.Context, msg: SignMessage, keychain: Keychain, coin: CoinInfo) -> MessageSignature: message = msg.message address_n = msg.address_n script_type = msg.script_type or InputScriptType.SPENDADDRESS await validate_path(ctx, keychain, address_n, validate_path_against_script_type(coin, msg)) node = keychain.derive(address_n) address = get_address(script_type, coin, node) await confirm_signverify( ctx, coin.coin_shortcut, decode_message(message), address_short(coin, address), verify=False, ) seckey = node.private_key() digest = message_digest(coin, message) signature = secp256k1.sign(seckey, digest) if script_type == InputScriptType.SPENDADDRESS: script_type_info = 0 elif script_type == InputScriptType.SPENDP2SHWITNESS: script_type_info = 4 elif script_type == InputScriptType.SPENDWITNESS: script_type_info = 8 else: raise wire.ProcessError("Unsupported script type") # Add script type information to the recovery byte. if script_type_info != 0 and not msg.no_script_type: signature = bytes([signature[0] + script_type_info]) + signature[1:] return MessageSignature(address=address, signature=signature)