mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 23:48:12 +00:00
feat(core): Support multisig_xpub_magic in GetPublicKey.
This commit is contained in:
parent
4287d2b377
commit
6568c36a83
1
core/.changelog.d/2658.added
Normal file
1
core/.changelog.d/2658.added
Normal file
@ -0,0 +1 @@
|
||||
Add multisig_xpub_magic option to GetPublicKey.
|
@ -271,3 +271,30 @@ def descriptor_checksum(desc: str) -> str:
|
||||
for j in range(0, 8):
|
||||
ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31]
|
||||
return "".join(ret)
|
||||
|
||||
|
||||
def get_xpub_magic(
|
||||
coin: CoinInfo,
|
||||
script_type: InputScriptType,
|
||||
ignore_xpub_magic: bool | None,
|
||||
is_multisig: bool | None,
|
||||
) -> int:
|
||||
from trezor.enums import InputScriptType
|
||||
|
||||
xpub_magic = None
|
||||
if not ignore_xpub_magic:
|
||||
# Handle SegWit v0 script types.
|
||||
# When coin.segwit is true, cointool.py guarantees that the corresponding xpub_magic_* attributes not None.
|
||||
if not is_multisig:
|
||||
if script_type == InputScriptType.SPENDP2SHWITNESS:
|
||||
xpub_magic = coin.xpub_magic_segwit_p2sh
|
||||
elif script_type == InputScriptType.SPENDWITNESS:
|
||||
xpub_magic = coin.xpub_magic_segwit_native
|
||||
else:
|
||||
if script_type == InputScriptType.SPENDWITNESS:
|
||||
xpub_magic = coin.xpub_magic_multisig_segwit_native
|
||||
elif script_type == InputScriptType.SPENDP2SHWITNESS:
|
||||
xpub_magic = coin.xpub_magic_multisig_segwit_p2sh
|
||||
|
||||
# SPENDADDRESS, SPENDMULTISIG, SPENDTAPROOT, ignore_xpub_magic or fallback.
|
||||
return xpub_magic or coin.xpub_magic
|
||||
|
@ -39,6 +39,7 @@ async def get_address(msg: GetAddress, keychain: Keychain, coin: CoinInfo) -> Ad
|
||||
from apps.common.paths import address_n_to_str, validate_path
|
||||
|
||||
from . import addresses
|
||||
from .common import get_xpub_magic
|
||||
from .keychain import (
|
||||
address_n_to_name_or_unknown,
|
||||
validate_path_against_script_type,
|
||||
@ -72,20 +73,7 @@ async def get_address(msg: GetAddress, keychain: Keychain, coin: CoinInfo) -> Ad
|
||||
address_case_sensitive = False # cashaddr address
|
||||
|
||||
mac: bytes | None = None
|
||||
multisig_xpub_magic = coin.xpub_magic
|
||||
if multisig:
|
||||
if coin.segwit and not msg.ignore_xpub_magic:
|
||||
if (
|
||||
script_type == InputScriptType.SPENDWITNESS
|
||||
and coin.xpub_magic_multisig_segwit_native is not None
|
||||
):
|
||||
multisig_xpub_magic = coin.xpub_magic_multisig_segwit_native
|
||||
elif (
|
||||
script_type == InputScriptType.SPENDP2SHWITNESS
|
||||
and coin.xpub_magic_multisig_segwit_p2sh is not None
|
||||
):
|
||||
multisig_xpub_magic = coin.xpub_magic_multisig_segwit_p2sh
|
||||
else:
|
||||
if not multisig:
|
||||
# Attach a MAC for single-sig addresses, but only if the path is standard
|
||||
# or if the user explicitly confirms a non-standard path.
|
||||
if msg.show_display or (
|
||||
@ -97,6 +85,10 @@ async def get_address(msg: GetAddress, keychain: Keychain, coin: CoinInfo) -> Ad
|
||||
if msg.show_display:
|
||||
path = address_n_to_str(address_n)
|
||||
if multisig:
|
||||
multisig_xpub_magic = get_xpub_magic(
|
||||
coin, script_type, msg.ignore_xpub_magic, is_multisig=True
|
||||
)
|
||||
|
||||
if multisig.nodes:
|
||||
pubnodes = multisig.nodes
|
||||
else:
|
||||
|
@ -10,20 +10,20 @@ if TYPE_CHECKING:
|
||||
async def get_public_key(
|
||||
msg: GetPublicKey, auth_msg: MessageType | None = None
|
||||
) -> PublicKey:
|
||||
from trezor import TR, wire
|
||||
from trezor import TR
|
||||
from trezor.enums import InputScriptType
|
||||
from trezor.messages import HDNodeType, PublicKey, UnlockPath
|
||||
|
||||
from apps.common import coininfo, paths
|
||||
from apps.common.keychain import FORBIDDEN_KEY_PATH, get_keychain
|
||||
|
||||
from .common import get_xpub_magic, sanitize_input_script_type
|
||||
|
||||
coin_name = msg.coin_name or "Bitcoin"
|
||||
script_type = msg.script_type or InputScriptType.SPENDADDRESS
|
||||
coin = coininfo.by_name(coin_name)
|
||||
curve_name = msg.ecdsa_curve_name or coin.curve_name
|
||||
address_n = msg.address_n # local_cache_attribute
|
||||
ignore_xpub_magic = msg.ignore_xpub_magic # local_cache_attribute
|
||||
xpub_magic = coin.xpub_magic # local_cache_attribute
|
||||
|
||||
if address_n and address_n[0] == paths.SLIP25_PURPOSE:
|
||||
# UnlockPath is required to access SLIP25 paths.
|
||||
@ -38,36 +38,13 @@ async def get_public_key(
|
||||
|
||||
node = keychain.derive(address_n)
|
||||
|
||||
if (
|
||||
script_type
|
||||
in (
|
||||
InputScriptType.SPENDADDRESS,
|
||||
InputScriptType.SPENDMULTISIG,
|
||||
InputScriptType.SPENDTAPROOT,
|
||||
)
|
||||
and xpub_magic is not None
|
||||
):
|
||||
node_xpub = node.serialize_public(xpub_magic)
|
||||
elif (
|
||||
coin.segwit
|
||||
and script_type == InputScriptType.SPENDP2SHWITNESS
|
||||
and (ignore_xpub_magic or coin.xpub_magic_segwit_p2sh is not None)
|
||||
):
|
||||
assert coin.xpub_magic_segwit_p2sh is not None
|
||||
sanitize_input_script_type(coin, script_type)
|
||||
|
||||
node_xpub = node.serialize_public(
|
||||
xpub_magic if ignore_xpub_magic else coin.xpub_magic_segwit_p2sh
|
||||
get_xpub_magic(
|
||||
coin, script_type, msg.ignore_xpub_magic, msg.multisig_xpub_magic
|
||||
)
|
||||
elif (
|
||||
coin.segwit
|
||||
and script_type == InputScriptType.SPENDWITNESS
|
||||
and (ignore_xpub_magic or coin.xpub_magic_segwit_native is not None)
|
||||
):
|
||||
assert coin.xpub_magic_segwit_native is not None
|
||||
node_xpub = node.serialize_public(
|
||||
xpub_magic if ignore_xpub_magic else coin.xpub_magic_segwit_native
|
||||
)
|
||||
else:
|
||||
raise wire.DataError("Invalid combination of coin and script_type")
|
||||
|
||||
pubkey = node.public_key()
|
||||
# For curve25519 and ed25519, the public key has the prefix 0x00, as specified by SLIP-10. However, since this prefix is non-standard, it may be removed in the future.
|
||||
@ -79,7 +56,7 @@ async def get_public_key(
|
||||
public_key=pubkey,
|
||||
)
|
||||
descriptor = _xpub_descriptor(
|
||||
node, xpub_magic, address_n, script_type, keychain.root_fingerprint()
|
||||
node, coin.xpub_magic, address_n, script_type, keychain.root_fingerprint()
|
||||
)
|
||||
|
||||
if msg.show_display:
|
||||
|
Loading…
Reference in New Issue
Block a user