async def sign_message(ctx, msg, keychain, coin): message = msg.message address_n = msg.address_n script_type = msg.script_type or 0 await require_confirm_sign_message(ctx, "Sign message", message) await validate_path( ctx, validate_full_path, keychain, msg.address_n, coin.curve_name, coin=coin, script_type=msg.script_type, validate_script_type=False, ) 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 == SPENDADDRESS: pass elif script_type == SPENDP2SHWITNESS: signature = bytes([signature[0] + 4]) + signature[1:] elif script_type == 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: 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): message = msg.message address_n = msg.address_n coin_name = msg.coin_name or 'Bitcoin' script_type = msg.script_type or 0 coin = coins.by_name(coin_name) await require_confirm_sign_message(ctx, message) node = await seed.derive_node(ctx, 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 == SPENDADDRESS: pass elif script_type == SPENDP2SHWITNESS: signature = bytes([signature[0] + 4]) + signature[1:] elif script_type == SPENDWITNESS: signature = bytes([signature[0] + 8]) + signature[1:] else: raise wire.ProcessError('Unsupported script type') return MessageSignature(address=address, signature=signature)
def sign_challenge( seckey: bytes, challenge_hidden: bytes, challenge_visual: str, sigtype: Union[str, coininfo.CoinInfo], curve: str, ) -> bytes: from trezor.crypto.hashlib import sha256 if curve == "secp256k1": from trezor.crypto.curve import secp256k1 elif curve == "nist256p1": from trezor.crypto.curve import nist256p1 elif curve == "ed25519": from trezor.crypto.curve import ed25519 from apps.common.signverify import message_digest if sigtype == "gpg": data = challenge_hidden elif sigtype == "signify": if curve != "ed25519": raise wire.DataError("Unsupported curve") data = challenge_hidden elif sigtype == "ssh": if curve != "ed25519": data = sha256(challenge_hidden).digest() else: data = challenge_hidden elif isinstance(sigtype, coininfo.CoinInfo): # sigtype is coin challenge = ( sha256(challenge_hidden).digest() + sha256(challenge_visual.encode()).digest() ) data = message_digest(sigtype, challenge) else: raise wire.DataError("Unsupported sigtype") if curve == "secp256k1": signature = secp256k1.sign(seckey, data) elif curve == "nist256p1": signature = nist256p1.sign(seckey, data) elif curve == "ed25519": signature = ed25519.sign(seckey, data) else: raise wire.DataError("Unknown curve") if curve == "ed25519": signature = b"\x00" + signature elif sigtype == "gpg" or sigtype == "ssh": signature = b"\x00" + signature[1:] return 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 sign_message(ctx, msg): message = msg.message address_n = msg.address_n coin_name = msg.coin_name or 'Bitcoin' coin = coins.by_name(coin_name) await confirm_sign_message(ctx, message) node = await seed.derive_node(ctx, address_n) seckey = node.private_key() address = node.address(coin.address_type) digest = message_digest(coin, message) signature = secp256k1.sign(seckey, digest) return MessageSignature(address=address, signature=signature)
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')
def sign_challenge(seckey: bytes, challenge_hidden: bytes, challenge_visual: str, sigtype, curve: str) -> bytes: from trezor.crypto.hashlib import sha256 if curve == "secp256k1": from trezor.crypto.curve import secp256k1 elif curve == "nist256p1": from trezor.crypto.curve import nist256p1 elif curve == "ed25519": from trezor.crypto.curve import ed25519 from apps.common.signverify import message_digest if sigtype == "gpg": data = challenge_hidden elif sigtype == "ssh": if curve != "ed25519": data = sha256(challenge_hidden).digest() else: data = challenge_hidden else: # sigtype is coin challenge = (sha256(challenge_hidden).digest() + sha256(challenge_visual).digest()) data = message_digest(sigtype, challenge) if curve == "secp256k1": signature = secp256k1.sign(seckey, data) elif curve == "nist256p1": signature = nist256p1.sign(seckey, data) elif curve == "ed25519": signature = ed25519.sign(seckey, data) else: raise ValueError("Unknown curve") if curve == "ed25519": signature = b"\x00" + signature elif sigtype == "gpg" or sigtype == "ssh": signature = b"\x00" + signature[1:] return signature
def sign_challenge(seckey: bytes, challenge_hidden: bytes, challenge_visual: str, sigtype, curve: str) -> bytes: from trezor.crypto.hashlib import sha256 if curve == 'secp256k1': from trezor.crypto.curve import secp256k1 elif curve == 'nist256p1': from trezor.crypto.curve import nist256p1 elif curve == 'ed25519': from trezor.crypto.curve import ed25519 from apps.common.signverify import message_digest if sigtype == 'gpg': data = challenge_hidden elif sigtype == 'ssh': if curve != 'ed25519': data = sha256(challenge_hidden).digest() else: data = challenge_hidden else: # sigtype is coin challenge = sha256(challenge_hidden).digest() + sha256( challenge_visual).digest() data = message_digest(sigtype, challenge) if curve == 'secp256k1': signature = secp256k1.sign(seckey, data) elif curve == 'nist256p1': signature = nist256p1.sign(seckey, data) elif curve == 'ed25519': signature = ed25519.sign(seckey, data) else: raise ValueError('Unknown curve') if curve == 'ed25519': signature = b'\x00' + signature elif sigtype == 'gpg' or sigtype == 'ssh': signature = b'\x00' + signature[1:] return signature
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)
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')