1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-24 07:18:09 +00:00

fix(core/bitcoin): display descriptors for taproot XPUBs

This commit is contained in:
Martin Milata 2024-01-30 01:54:02 +01:00
parent 1a9bb11806
commit bb29c1e5f8
5 changed files with 87 additions and 13 deletions

View File

@ -0,0 +1 @@
Display descriptors for BTC Taproot public keys.

View File

@ -212,3 +212,49 @@ def format_fee_rate(
shortcut = ""
return f"{fee_rate_formatted} sat{shortcut}/{'v' if coin.segwit else ''}B"
# function copied from python/src/trezorlib/tools.py
def descriptor_checksum(desc: str) -> str:
def _polymod(c: int, val: int) -> int:
c0 = c >> 35
c = ((c & 0x7FFFFFFFF) << 5) ^ val
if c0 & 1:
c ^= 0xF5DEE51989
if c0 & 2:
c ^= 0xA9FDCA3312
if c0 & 4:
c ^= 0x1BAB10E32D
if c0 & 8:
c ^= 0x3706B1677A
if c0 & 16:
c ^= 0x644D626FFD
return c
INPUT_CHARSET = "0123456789()[],'/*abcdefgh@:$%{}IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~ijklmnopqrstuvwxyzABCDEFGH`#\"\\ "
CHECKSUM_CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
c = 1
cls = 0
clscount = 0
for ch in desc:
pos = INPUT_CHARSET.find(ch)
if pos == -1:
return ""
c = _polymod(c, pos & 31)
cls = cls * 3 + (pos >> 5)
clscount += 1
if clscount == 3:
c = _polymod(c, cls)
cls = 0
clscount = 0
if clscount > 0:
c = _polymod(c, cls)
for j in range(0, 8):
c = _polymod(c, 0)
c ^= 1
ret = [""] * 8
for j in range(0, 8):
ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31]
return "".join(ret)

View File

@ -1,6 +1,7 @@
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from trezor.enums import InputScriptType
from trezor.messages import GetPublicKey, PublicKey
from trezor.protobuf import MessageType
@ -96,8 +97,13 @@ async def get_public_key(
account = coin.coin_shortcut
else:
account = f"{coin.coin_shortcut} {account_name}"
show_xpub = node_xpub
if script_type == InputScriptType.SPENDTAPROOT:
show_xpub = _xpub_descriptor(
node_xpub, address_n, script_type, node.fingerprint()
)
await show_pubkey(
node_xpub,
show_xpub,
"XPUB",
account=account,
path=path,
@ -110,3 +116,23 @@ async def get_public_key(
xpub=node_xpub,
root_fingerprint=keychain.root_fingerprint(),
)
def _xpub_descriptor(
node_xpub: str,
address_n: list[int],
script_type: InputScriptType,
fingerprint: int,
) -> str:
from trezor.enums import InputScriptType
from apps.common import paths
from .common import descriptor_checksum
if script_type != InputScriptType.SPENDTAPROOT:
raise ValueError("Unsupported script type.")
path = paths.address_n_to_str(address_n)
descriptor = f"tr([{fingerprint:08x}{path[1:]}]{node_xpub}/<0;1>/*)"
checksum = descriptor_checksum(descriptor)
return f"{descriptor}#{checksum}"

View File

@ -479,6 +479,7 @@ class InputFlowShowXpubQRCode(InputFlowBase):
# Go through details and back
self.debug.press_right(wait=True)
self.debug.press_right(wait=True)
self.debug.press_right(wait=True)
self.debug.press_left(wait=True)
self.debug.press_left(wait=True)
assert br.pages is not None

View File

@ -809,24 +809,24 @@
"TR_bitcoin-test_bcash.py::test_send_bch_multisig_wrongchange": "fa268b2481cce18a041c8f8bf773f16cbfed6ad372a89c7d7220a2de3aa9042e",
"TR_bitcoin-test_bcash.py::test_send_bch_nochange": "395635f081e0c9bdf3f6de9a1540d9211c3a1d68665d8ac13ffb8c236add0a3b",
"TR_bitcoin-test_bcash.py::test_send_bch_oldaddr": "3957efb1b584f974d8b32523eadb4c18596956b38dec2c85005e7e4f0bf85593",
"TR_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-0-10025-InputScriptType.SPENDTAPROOT--301d7568": "7fb7f797b6fb89460beab4df5fbd5f61cbdcd2931349b8c2bae696bf45195b7c",
"TR_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-0-10025-InputScriptType.SPENDTAPROOT--301d7568": "70524243a1d093df71ce94251a1bdfe8ff82b7ee84c2b13b71c09908be89dbc4",
"TR_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-0-44-InputScriptType.SPENDADDRESS-pkh-a1b0211f": "ad9329ebacf27f00e736d1d3d8a33a539512a23fd134806ddfe6da4e4b517d1a",
"TR_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-0-49-InputScriptType.SPENDP2SHWITNESS-75f8d49f": "cb4cea77c61cafeece033128c8c050060cba7c64e4ef255dc59b235324bcf213",
"TR_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-0-84-InputScriptType.SPENDWITNESS-wpk-cee65569": "0ffab62bd4c51d042e77c23f5569b9b9a46d9aae102f55edf20d7894dc75b17d",
"TR_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-0-86-InputScriptType.SPENDTAPROOT-tr(-6b548a1a": "7d3ad845c22d4b74965e62437e8090a2359ddedd528604e3295cab2527b1f877",
"TR_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-0-86-InputScriptType.SPENDTAPROOT-tr(-6b548a1a": "17a198a8b24035578345b5e85ec307ec8d800a2f343d051a1820ca3121dba696",
"TR_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-1-44-InputScriptType.SPENDADDRESS-pkh-37215d1b": "bad6123462cf0f8c9d938ca92ac9841b53221e5152f27bc92959e870d4108f1e",
"TR_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-1-49-InputScriptType.SPENDP2SHWITNESS-3ccd985b": "c66f3f30c1a6c809fb8c99a9773c9a9ebea29207c4383f8507db751ba59eb11f",
"TR_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-1-84-InputScriptType.SPENDWITNESS-wpk-21c3fa4c": "ab012153490f26746ff9a1b5388f2418bf7c9d98b127217babbeab339245d8f7",
"TR_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-1-86-InputScriptType.SPENDTAPROOT-tr(-3a85f3dd": "d37242f2ae1be0a8a9bb3e2eea693e3cf989062d953b44d90f3563c1b21f3bc9",
"TR_bitcoin-test_descriptors.py::test_descriptors[Testnet-0-10025-InputScriptType.SPENDTAPROOT--591134d6": "fd8f0b4079d5ae46955439d95df5c75877670b93634dc71661beaa54bc1b2ae3",
"TR_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-1-86-InputScriptType.SPENDTAPROOT-tr(-3a85f3dd": "695853ac56e78df434995eeb457f7d4b466f66c9af560fb103f6a4fba717e0fb",
"TR_bitcoin-test_descriptors.py::test_descriptors[Testnet-0-10025-InputScriptType.SPENDTAPROOT--591134d6": "c3519859e757af09f9fed46739e484845fdee3d3aa4fb84ee89e7df63d3ccf95",
"TR_bitcoin-test_descriptors.py::test_descriptors[Testnet-0-44-InputScriptType.SPENDADDRESS-pkh-b7612f41": "482a7d3ce0d25e9b940cb3571201b35a856187ed2215f12ce05b06b32e5ebcc1",
"TR_bitcoin-test_descriptors.py::test_descriptors[Testnet-0-49-InputScriptType.SPENDP2SHWITNESS-4408e6b6": "442a787c067f35af606eb27a2a585a15272bb920af01070f408a402603572b39",
"TR_bitcoin-test_descriptors.py::test_descriptors[Testnet-0-84-InputScriptType.SPENDWITNESS-wpk-49d5549d": "d53ebc2f1c866b3d5920b13d9ac909fc81d4ca943a0625801b5dc533f2fe6ef5",
"TR_bitcoin-test_descriptors.py::test_descriptors[Testnet-0-86-InputScriptType.SPENDTAPROOT-tr(-51c6f7dc": "ad765a86ca402de45b89ec4ac839d8ea720df2751243c4bef60a7a2877146562",
"TR_bitcoin-test_descriptors.py::test_descriptors[Testnet-0-86-InputScriptType.SPENDTAPROOT-tr(-51c6f7dc": "7798b65e874be333b51ce443ccb26713bb0a17565217f09bd89eff635ddff8a6",
"TR_bitcoin-test_descriptors.py::test_descriptors[Testnet-1-44-InputScriptType.SPENDADDRESS-pkh-671fabde": "b42ab862d2d45bb9e0509fc4ba4d68405acde83fda935c5dafd44d9e48cb29d3",
"TR_bitcoin-test_descriptors.py::test_descriptors[Testnet-1-49-InputScriptType.SPENDP2SHWITNESS-6a0c7b09": "6b7c12363fc566de9d35013be5156c970e9fba33c2ed73b4a7e9b06e0974e867",
"TR_bitcoin-test_descriptors.py::test_descriptors[Testnet-1-84-InputScriptType.SPENDWITNESS-wpk-7c651f2d": "7714578913a2a1e573193ac78cddc20c2df6c2856ad8c50d447906bfee41e4f6",
"TR_bitcoin-test_descriptors.py::test_descriptors[Testnet-1-86-InputScriptType.SPENDTAPROOT-tr(-b37d77de": "094264a5b04a8042806562f315c71c9edecb2018af6db957a001fcdc31b0296d",
"TR_bitcoin-test_descriptors.py::test_descriptors[Testnet-1-86-InputScriptType.SPENDTAPROOT-tr(-b37d77de": "67b86cfe9f4ab3b54a829e70565061d80304a3f75ea70a4fbd92c22a643737ef",
"TR_bitcoin-test_firo.py::test_spend_lelantus": "aff133d149549783adbdaa9563cb990af6cc5f8fafba3f50d82bbbd2765bb4ff",
"TR_bitcoin-test_fujicoin.py::test_send_p2tr": "6ab906b521bb73e0725c3d0f3eb5a6ecf9f582853f4cd71672f73190f15fb917",
"TR_bitcoin-test_getaddress.py::test_address_mac": "8c801bd0142e5c1ad4aad50b34c7debb1b8f17a2e0a87eb7f95531b9fd15e095",
@ -2181,24 +2181,24 @@
"TT_bitcoin-test_decred.py::test_send_decred": "7e8b1532772cf7695fbcf3460d179d08f22c410687c057ff128882e32d923c92",
"TT_bitcoin-test_decred.py::test_send_decred_change": "d28de2959972fb3ef29bb267fa8bf6b96ac9c7d9ef4550538db5235a5b45307d",
"TT_bitcoin-test_decred.py::test_spend_from_stake_generation_and_revocation_decred": "d4657fa66b4d9e90d99de7bf5ad3123d74fec9c528a819f691bc565b521257f3",
"TT_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-0-10025-InputScriptType.SPENDTAPROOT--301d7568": "b38ee9ea74d82cf94bcd1db9a70e673d3d515aa9995787bff2f0188371201fab",
"TT_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-0-10025-InputScriptType.SPENDTAPROOT--301d7568": "75cf40b6d916ab5107d5241143ba1edd408d359076edcfdfd6ebef4f6202598f",
"TT_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-0-44-InputScriptType.SPENDADDRESS-pkh-a1b0211f": "7dd16059ade8769aca12649b7b2523ac52718fb7bb9eb416fa13a5cb747be1b2",
"TT_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-0-49-InputScriptType.SPENDP2SHWITNESS-75f8d49f": "8b434c5de0caf71301bd6b21481bb1944d4b43dd596a7ecb9acb921c8083e955",
"TT_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-0-84-InputScriptType.SPENDWITNESS-wpk-cee65569": "e8628d184603bceaad9c5ae5b9f51460054e7b5622ea9c1a3dc84f84034808bc",
"TT_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-0-86-InputScriptType.SPENDTAPROOT-tr(-6b548a1a": "0e5a8b8f71fe27225eb8fa35dd338eebee9dcd265aed2f0b925fb3c23a34ddea",
"TT_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-0-86-InputScriptType.SPENDTAPROOT-tr(-6b548a1a": "d9e035a4407e3fbbeaad3726c1c19c32d45a788a943187e909b0f2787aad7486",
"TT_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-1-44-InputScriptType.SPENDADDRESS-pkh-37215d1b": "a8f46662c3d14e2defdd5aa2ff4486aeac3f566facf086916da7ddc7e0185130",
"TT_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-1-49-InputScriptType.SPENDP2SHWITNESS-3ccd985b": "013171ff086e4565db1bc4f8a0d466a0fa7c6449ee58a3d27b27f073bfb74d63",
"TT_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-1-84-InputScriptType.SPENDWITNESS-wpk-21c3fa4c": "3941cd14f74e1d7ea919cb32cbd7c5954c412d845305e4f0e495378c7701a53b",
"TT_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-1-86-InputScriptType.SPENDTAPROOT-tr(-3a85f3dd": "9f228b072051500d298b3386082208b858521667424b0de352e1501e0912e2d2",
"TT_bitcoin-test_descriptors.py::test_descriptors[Testnet-0-10025-InputScriptType.SPENDTAPROOT--591134d6": "1651987f970c1bfcaf3906b3185a37709dc940289493272cef36357d810edb9d",
"TT_bitcoin-test_descriptors.py::test_descriptors[Bitcoin-1-86-InputScriptType.SPENDTAPROOT-tr(-3a85f3dd": "2b38959aba5f6a57365ebee67831eaeb9fd3276f9ca0d6c6d99e6b46e97998bc",
"TT_bitcoin-test_descriptors.py::test_descriptors[Testnet-0-10025-InputScriptType.SPENDTAPROOT--591134d6": "9db02ff67c8b507a62ab3bca79b4a6d5cd3f3da7136f7bc0b237fde382b50739",
"TT_bitcoin-test_descriptors.py::test_descriptors[Testnet-0-44-InputScriptType.SPENDADDRESS-pkh-b7612f41": "d8e95f6a14ddabd6db4944802f847ccddd8161eed28559f35dc095b568461df7",
"TT_bitcoin-test_descriptors.py::test_descriptors[Testnet-0-49-InputScriptType.SPENDP2SHWITNESS-4408e6b6": "6ac0059ce935707618eefe9c23d403ff30807df3c3ec23b8615a50b648bbba75",
"TT_bitcoin-test_descriptors.py::test_descriptors[Testnet-0-84-InputScriptType.SPENDWITNESS-wpk-49d5549d": "b8e44bea2eb0d3ac672a41ebf83683adbb0e02a622cbafe2fb02283117bd4c4a",
"TT_bitcoin-test_descriptors.py::test_descriptors[Testnet-0-86-InputScriptType.SPENDTAPROOT-tr(-51c6f7dc": "fc9c8773c1cc4d8c4a455e29e3b916992bb4b3114a9e322cd809c19c21cde4f2",
"TT_bitcoin-test_descriptors.py::test_descriptors[Testnet-0-86-InputScriptType.SPENDTAPROOT-tr(-51c6f7dc": "eae032ac90ebf7d44b84eb6f06c43f67140de7adef88906d98c1759ffd4995cd",
"TT_bitcoin-test_descriptors.py::test_descriptors[Testnet-1-44-InputScriptType.SPENDADDRESS-pkh-671fabde": "4795ab245421deef1f7ebdb6568165a64c7066054747a84c4e30a78085c71e22",
"TT_bitcoin-test_descriptors.py::test_descriptors[Testnet-1-49-InputScriptType.SPENDP2SHWITNESS-6a0c7b09": "284b98fb9d745aae6f552999e1652300d84d4863c3b29452615ae5b691d7b266",
"TT_bitcoin-test_descriptors.py::test_descriptors[Testnet-1-84-InputScriptType.SPENDWITNESS-wpk-7c651f2d": "660130572e80e9161d733f3ebc465a5f2a9859a79eecd7201c7ebf955173df23",
"TT_bitcoin-test_descriptors.py::test_descriptors[Testnet-1-86-InputScriptType.SPENDTAPROOT-tr(-b37d77de": "f83fb40390de5ee5fca1cece2d24ec9c57c376ac4d294b1bede62b04ef0bb0fa",
"TT_bitcoin-test_descriptors.py::test_descriptors[Testnet-1-86-InputScriptType.SPENDTAPROOT-tr(-b37d77de": "35e60de9968a7c5bb296dc554970a16878165e062bb8480a5c8428f73a3cf921",
"TT_bitcoin-test_firo.py::test_spend_lelantus": "213ced04e2b337576abe1861c11ef69352eb5542f2bef720e50d54cea031f9db",
"TT_bitcoin-test_fujicoin.py::test_send_p2tr": "6104cd021625791fc9141ca802c3c18fb50815459acae06b2eeb05da432352f7",
"TT_bitcoin-test_getaddress.py::test_address_mac": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",