mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-07 15:18:08 +00:00
WIP feat(legacy): send BIP-380 descriptor in GetPublicKey response
[skip_ci]
This commit is contained in:
parent
8d1ee10619
commit
fb240bf48a
@ -42,3 +42,11 @@ size_t strlcat(char *dst, const char *src, size_t size) {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
char *itoa(int i, char *dest, int base) {
|
||||
if (base != 10) {
|
||||
return dest;
|
||||
}
|
||||
int n = sprintf(dest, "%d", i);
|
||||
return dest + n;
|
||||
}
|
||||
|
@ -27,4 +27,6 @@ size_t strlcpy(char *dst, const char *src, size_t size);
|
||||
size_t strlcat(char *dst, const char *src, size_t size);
|
||||
#endif
|
||||
|
||||
char *itoa(int i, char *dest, int base) {
|
||||
|
||||
#endif
|
||||
|
@ -81,6 +81,56 @@ void fsm_msgGetPublicKey(const GetPublicKey *msg) {
|
||||
resp->node.public_key.bytes[0] = 0;
|
||||
}
|
||||
|
||||
bool descriptor = true;
|
||||
size_t descriptor_len = 0;
|
||||
|
||||
if (script_type == InputScriptType_SPENDADDRESS) {
|
||||
strlcpy(resp->descriptor, "pkh([", sizeof(resp->descriptor));
|
||||
descriptor_len += 5;
|
||||
} else if (script_type == InputScriptType_SPENDP2SHWITNESS) {
|
||||
strlcpy(resp->descriptor, "sh(wpkh([", sizeof(resp->descriptor));
|
||||
descriptor_len += 9;
|
||||
} else if (script_type == InputScriptType_SPENDWITNESS) {
|
||||
strlcpy(resp->descriptor, "wpkh([", sizeof(resp->descriptor));
|
||||
descriptor_len += 6;
|
||||
} else if (script_type == InputScriptType_SPENDTAPROOT) {
|
||||
strlcpy(resp->descriptor, "tr([", sizeof(resp->descriptor));
|
||||
descriptor_len += 4;
|
||||
} else {
|
||||
descriptor = false;
|
||||
}
|
||||
if (descriptor) {
|
||||
// FIXME this needs to be lowercase
|
||||
uint32hex(root_fingerprint, resp->descriptor + descriptor_len);
|
||||
descriptor_len += 8;
|
||||
|
||||
for (size_t i = 0; i < msg->address_n_count; i++) {
|
||||
strlcpy(resp->descriptor + descriptor_len, "/",
|
||||
sizeof(resp->descriptor) - descriptor_len);
|
||||
descriptor_len++;
|
||||
|
||||
uint32_t unhardened = msg->address_n[i] & PATH_UNHARDEN_MASK;
|
||||
|
||||
if (descriptor_len + 17 > sizeof(resp->descriptor)) {
|
||||
descriptor = false;
|
||||
break;
|
||||
}
|
||||
|
||||
char *result = itoa(unhardened, resp->descriptor + descriptor_len, 10);
|
||||
descriptor_len += result - (resp->descriptor + descriptor_len);
|
||||
|
||||
if (msg->address_n[i] & PATH_HARDENED) {
|
||||
strlcpy(resp->descriptor + descriptor_len, "'",
|
||||
sizeof(resp->descriptor) - descriptor_len);
|
||||
descriptor_len++;
|
||||
}
|
||||
}
|
||||
|
||||
strlcpy(resp->descriptor + descriptor_len, "]",
|
||||
sizeof(resp->descriptor) - descriptor_len);
|
||||
descriptor_len++;
|
||||
}
|
||||
|
||||
if (coin->xpub_magic && (script_type == InputScriptType_SPENDADDRESS ||
|
||||
script_type == InputScriptType_SPENDMULTISIG)) {
|
||||
hdnode_serialize_public(node, fingerprint, coin->xpub_magic, resp->xpub,
|
||||
@ -113,9 +163,37 @@ void fsm_msgGetPublicKey(const GetPublicKey *msg) {
|
||||
layoutHome();
|
||||
return;
|
||||
}
|
||||
if (descriptor) {
|
||||
if (coin->xpub_magic) {
|
||||
char tmp[XPUB_MAXLEN] = {0};
|
||||
hdnode_serialize_public(node, fingerprint, coin->xpub_magic, tmp,
|
||||
sizeof(tmp));
|
||||
strlcpy(resp->descriptor + descriptor_len, tmp,
|
||||
sizeof(resp->descriptor) - descriptor_len);
|
||||
descriptor_len += strlen(tmp);
|
||||
|
||||
strlcpy(resp->descriptor + descriptor_len, "/<0;1>/*)",
|
||||
sizeof(resp->descriptor) - descriptor_len);
|
||||
descriptor_len += 9;
|
||||
|
||||
if (script_type == InputScriptType_SPENDP2SHWITNESS) {
|
||||
strlcpy(resp->descriptor + descriptor_len, ")",
|
||||
sizeof(resp->descriptor) - descriptor_len);
|
||||
descriptor_len++;
|
||||
}
|
||||
|
||||
strlcpy(resp->descriptor + descriptor_len, "#00000000",
|
||||
sizeof(resp->descriptor) - descriptor_len);
|
||||
descriptor_len += 9;
|
||||
} else {
|
||||
descriptor = false;
|
||||
}
|
||||
}
|
||||
resp->has_descriptor = descriptor;
|
||||
|
||||
if (msg->has_show_display && msg->show_display) {
|
||||
for (int page = 0; page < 2; page++) {
|
||||
// TODO show descriptor
|
||||
layoutXPUB(resp->xpub, page);
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_PublicKey, true)) {
|
||||
memzero(resp, sizeof(PublicKey));
|
||||
|
@ -3,7 +3,7 @@ GetPublicKey.ecdsa_curve_name max_size:32
|
||||
GetPublicKey.coin_name max_size:21
|
||||
|
||||
PublicKey.xpub max_size:113
|
||||
PublicKey.descriptor type:FT_IGNORE
|
||||
PublicKey.descriptor max_size:180
|
||||
|
||||
GetAddress.address_n max_count:8
|
||||
GetAddress.coin_name max_size:21
|
||||
|
@ -161,14 +161,14 @@ def _address_n(purpose, coin, account, script_type):
|
||||
return res
|
||||
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
@pytest.mark.parametrize(
|
||||
"coin, account, purpose, script_type, descriptors", VECTORS_DESCRIPTORS
|
||||
)
|
||||
def test_descriptors(client: Client, coin, account, purpose, script_type, descriptors):
|
||||
with client:
|
||||
IF = InputFlowShowXpubQRCode(client)
|
||||
client.set_input_flow(IF.get())
|
||||
if client.model != models.T1B1:
|
||||
IF = InputFlowShowXpubQRCode(client)
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
address_n = _address_n(purpose, coin, account, script_type)
|
||||
res = btc.get_public_node(
|
||||
|
Loading…
Reference in New Issue
Block a user