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
|
#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);
|
size_t strlcat(char *dst, const char *src, size_t size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
char *itoa(int i, char *dest, int base) {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -81,6 +81,56 @@ void fsm_msgGetPublicKey(const GetPublicKey *msg) {
|
|||||||
resp->node.public_key.bytes[0] = 0;
|
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 ||
|
if (coin->xpub_magic && (script_type == InputScriptType_SPENDADDRESS ||
|
||||||
script_type == InputScriptType_SPENDMULTISIG)) {
|
script_type == InputScriptType_SPENDMULTISIG)) {
|
||||||
hdnode_serialize_public(node, fingerprint, coin->xpub_magic, resp->xpub,
|
hdnode_serialize_public(node, fingerprint, coin->xpub_magic, resp->xpub,
|
||||||
@ -113,9 +163,37 @@ void fsm_msgGetPublicKey(const GetPublicKey *msg) {
|
|||||||
layoutHome();
|
layoutHome();
|
||||||
return;
|
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) {
|
if (msg->has_show_display && msg->show_display) {
|
||||||
for (int page = 0; page < 2; page++) {
|
for (int page = 0; page < 2; page++) {
|
||||||
|
// TODO show descriptor
|
||||||
layoutXPUB(resp->xpub, page);
|
layoutXPUB(resp->xpub, page);
|
||||||
if (!protectButton(ButtonRequestType_ButtonRequest_PublicKey, true)) {
|
if (!protectButton(ButtonRequestType_ButtonRequest_PublicKey, true)) {
|
||||||
memzero(resp, sizeof(PublicKey));
|
memzero(resp, sizeof(PublicKey));
|
||||||
|
@ -3,7 +3,7 @@ GetPublicKey.ecdsa_curve_name max_size:32
|
|||||||
GetPublicKey.coin_name max_size:21
|
GetPublicKey.coin_name max_size:21
|
||||||
|
|
||||||
PublicKey.xpub max_size:113
|
PublicKey.xpub max_size:113
|
||||||
PublicKey.descriptor type:FT_IGNORE
|
PublicKey.descriptor max_size:180
|
||||||
|
|
||||||
GetAddress.address_n max_count:8
|
GetAddress.address_n max_count:8
|
||||||
GetAddress.coin_name max_size:21
|
GetAddress.coin_name max_size:21
|
||||||
|
@ -161,14 +161,14 @@ def _address_n(purpose, coin, account, script_type):
|
|||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip_t1
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"coin, account, purpose, script_type, descriptors", VECTORS_DESCRIPTORS
|
"coin, account, purpose, script_type, descriptors", VECTORS_DESCRIPTORS
|
||||||
)
|
)
|
||||||
def test_descriptors(client: Client, coin, account, purpose, script_type, descriptors):
|
def test_descriptors(client: Client, coin, account, purpose, script_type, descriptors):
|
||||||
with client:
|
with client:
|
||||||
IF = InputFlowShowXpubQRCode(client)
|
if client.model != models.T1B1:
|
||||||
client.set_input_flow(IF.get())
|
IF = InputFlowShowXpubQRCode(client)
|
||||||
|
client.set_input_flow(IF.get())
|
||||||
|
|
||||||
address_n = _address_n(purpose, coin, account, script_type)
|
address_n = _address_n(purpose, coin, account, script_type)
|
||||||
res = btc.get_public_node(
|
res = btc.get_public_node(
|
||||||
|
Loading…
Reference in New Issue
Block a user