mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-17 01:52:02 +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):
|
for j in range(0, 8):
|
||||||
ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31]
|
ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31]
|
||||||
return "".join(ret)
|
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 apps.common.paths import address_n_to_str, validate_path
|
||||||
|
|
||||||
from . import addresses
|
from . import addresses
|
||||||
|
from .common import get_xpub_magic
|
||||||
from .keychain import (
|
from .keychain import (
|
||||||
address_n_to_name_or_unknown,
|
address_n_to_name_or_unknown,
|
||||||
validate_path_against_script_type,
|
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
|
address_case_sensitive = False # cashaddr address
|
||||||
|
|
||||||
mac: bytes | None = None
|
mac: bytes | None = None
|
||||||
multisig_xpub_magic = coin.xpub_magic
|
if not multisig:
|
||||||
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:
|
|
||||||
# Attach a MAC for single-sig addresses, but only if the path is standard
|
# Attach a MAC for single-sig addresses, but only if the path is standard
|
||||||
# or if the user explicitly confirms a non-standard path.
|
# or if the user explicitly confirms a non-standard path.
|
||||||
if msg.show_display or (
|
if msg.show_display or (
|
||||||
@ -97,6 +85,10 @@ async def get_address(msg: GetAddress, keychain: Keychain, coin: CoinInfo) -> Ad
|
|||||||
if msg.show_display:
|
if msg.show_display:
|
||||||
path = address_n_to_str(address_n)
|
path = address_n_to_str(address_n)
|
||||||
if multisig:
|
if multisig:
|
||||||
|
multisig_xpub_magic = get_xpub_magic(
|
||||||
|
coin, script_type, msg.ignore_xpub_magic, is_multisig=True
|
||||||
|
)
|
||||||
|
|
||||||
if multisig.nodes:
|
if multisig.nodes:
|
||||||
pubnodes = multisig.nodes
|
pubnodes = multisig.nodes
|
||||||
else:
|
else:
|
||||||
|
@ -10,20 +10,20 @@ if TYPE_CHECKING:
|
|||||||
async def get_public_key(
|
async def get_public_key(
|
||||||
msg: GetPublicKey, auth_msg: MessageType | None = None
|
msg: GetPublicKey, auth_msg: MessageType | None = None
|
||||||
) -> PublicKey:
|
) -> PublicKey:
|
||||||
from trezor import TR, wire
|
from trezor import TR
|
||||||
from trezor.enums import InputScriptType
|
from trezor.enums import InputScriptType
|
||||||
from trezor.messages import HDNodeType, PublicKey, UnlockPath
|
from trezor.messages import HDNodeType, PublicKey, UnlockPath
|
||||||
|
|
||||||
from apps.common import coininfo, paths
|
from apps.common import coininfo, paths
|
||||||
from apps.common.keychain import FORBIDDEN_KEY_PATH, get_keychain
|
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"
|
coin_name = msg.coin_name or "Bitcoin"
|
||||||
script_type = msg.script_type or InputScriptType.SPENDADDRESS
|
script_type = msg.script_type or InputScriptType.SPENDADDRESS
|
||||||
coin = coininfo.by_name(coin_name)
|
coin = coininfo.by_name(coin_name)
|
||||||
curve_name = msg.ecdsa_curve_name or coin.curve_name
|
curve_name = msg.ecdsa_curve_name or coin.curve_name
|
||||||
address_n = msg.address_n # local_cache_attribute
|
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:
|
if address_n and address_n[0] == paths.SLIP25_PURPOSE:
|
||||||
# UnlockPath is required to access SLIP25 paths.
|
# UnlockPath is required to access SLIP25 paths.
|
||||||
@ -38,36 +38,13 @@ async def get_public_key(
|
|||||||
|
|
||||||
node = keychain.derive(address_n)
|
node = keychain.derive(address_n)
|
||||||
|
|
||||||
if (
|
sanitize_input_script_type(coin, script_type)
|
||||||
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
|
|
||||||
node_xpub = node.serialize_public(
|
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()
|
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.
|
# 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,
|
public_key=pubkey,
|
||||||
)
|
)
|
||||||
descriptor = _xpub_descriptor(
|
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:
|
if msg.show_display:
|
||||||
|
Loading…
Reference in New Issue
Block a user