Skip to content

Commit 2489627

Browse files
committed
descriptor: add support for tr(k)
1 parent 33b4d39 commit 2489627

File tree

1 file changed

+51
-1
lines changed

1 file changed

+51
-1
lines changed

src/descriptor.c

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
#define KIND_DESCRIPTOR_ADDR (0x00040000 | KIND_DESCRIPTOR)
8888
#define KIND_DESCRIPTOR_RAW (0x00050000 | KIND_DESCRIPTOR)
8989
#define KIND_DESCRIPTOR_RAW_TR (0x00100000 | KIND_DESCRIPTOR)
90+
#define KIND_DESCRIPTOR_TR (0x00200000 | KIND_DESCRIPTOR)
9091

9192
/* miniscript */
9293
#define KIND_MINISCRIPT_PK (0x00000100 | KIND_MINISCRIPT)
@@ -702,6 +703,18 @@ static int verify_raw_tr(ms_ctx *ctx, ms_node *node)
702703
return WALLY_OK;
703704
}
704705

706+
static int verify_tr(ms_ctx *ctx, ms_node *node)
707+
{
708+
const uint32_t child_count = node_get_child_count(node);
709+
if (child_count != 1u)
710+
return WALLY_EINVAL; /* FIXME: Support script paths */
711+
if (node->child->builtin || !(node->child->kind & KIND_KEY) ||
712+
node_has_uncompressed_key(ctx, node))
713+
return WALLY_EINVAL;
714+
node->type_properties = builtin_get(node)->type_properties;
715+
return WALLY_OK;
716+
}
717+
705718
static int verify_delay(ms_ctx *ctx, ms_node *node)
706719
{
707720
(void)ctx;
@@ -1404,6 +1417,35 @@ static int generate_raw_tr(ms_ctx *ctx, ms_node *node,
14041417
return ret;
14051418
}
14061419

1420+
static int generate_tr(ms_ctx *ctx, ms_node *node,
1421+
unsigned char *script, size_t script_len, size_t *written)
1422+
{
1423+
unsigned char tweaked[EC_PUBLIC_KEY_LEN];
1424+
unsigned char pubkey[EC_PUBLIC_KEY_UNCOMPRESSED_LEN + 1];
1425+
size_t pubkey_len;
1426+
int ret;
1427+
1428+
/* Generate a push of the x-only public key of our child */
1429+
const bool force_xonly = true;
1430+
ret = generate_pk_k_impl(ctx, node, pubkey, sizeof(pubkey), force_xonly, &pubkey_len);
1431+
if (pubkey_len != EC_XONLY_PUBLIC_KEY_LEN + 1)
1432+
return WALLY_EINVAL; /* Should be PUSH_32 [x-only pubkey] */
1433+
1434+
/* Tweak it into a compressed pubkey */
1435+
ret = wally_ec_public_key_bip341_tweak(pubkey + 1, pubkey_len - 1,
1436+
NULL, 0, 0, /* FIXME: Support script path */
1437+
tweaked, sizeof(tweaked));
1438+
1439+
if (ret == WALLY_OK && script_len >= WALLY_SCRIPTPUBKEY_P2TR_LEN) {
1440+
/* Generate the script using the x-only part of the tweaked key */
1441+
script[0] = OP_1;
1442+
script[1] = sizeof(tweaked) - 1;
1443+
memcpy(script + 2, tweaked + 1, sizeof(tweaked) - 1);
1444+
}
1445+
*written = WALLY_SCRIPTPUBKEY_P2TR_LEN;
1446+
return ret;
1447+
}
1448+
14071449
static int generate_delay(ms_ctx *ctx, ms_node *node,
14081450
unsigned char *script, size_t script_len, size_t *written)
14091451
{
@@ -1817,6 +1859,11 @@ static const struct ms_builtin_t g_builtins[] = {
18171859
KIND_DESCRIPTOR_RAW_TR,
18181860
TYPE_NONE,
18191861
1, verify_raw_tr, generate_raw_tr
1862+
}, {
1863+
I_NAME("tr"),
1864+
KIND_DESCRIPTOR_TR,
1865+
TYPE_NONE,
1866+
0xffffffff, verify_tr, generate_tr
18201867
},
18211868
/* miniscript */
18221869
{
@@ -2087,7 +2134,9 @@ static int analyze_pubkey_hex(ms_ctx *ctx, ms_node *node,
20872134
wally_ec_xonly_public_key_verify(pubkey, pubkey_len) != WALLY_OK)
20882135
return WALLY_OK; /* Not a valid pubkey */
20892136

2090-
make_xonly = node->parent && (node->parent->kind == KIND_DESCRIPTOR_RAW_TR);
2137+
make_xonly = node->parent &&
2138+
(node->parent->kind == KIND_DESCRIPTOR_RAW_TR ||
2139+
node->parent->kind == KIND_DESCRIPTOR_TR);
20912140
allow_xonly = make_xonly || flags & WALLY_MINISCRIPT_TAPSCRIPT;
20922141
if (pubkey_len == EC_PUBLIC_KEY_UNCOMPRESSED_LEN && allow_xonly)
20932142
return WALLY_OK; /* Uncompressed key not allowed here */
@@ -2502,6 +2551,7 @@ static int node_generation_size(const ms_node *node, size_t *total)
25022551
/* No-op */
25032552
break;
25042553
case KIND_DESCRIPTOR_RAW_TR:
2554+
case KIND_DESCRIPTOR_TR:
25052555
*total += WALLY_SCRIPTPUBKEY_P2TR_LEN;
25062556
break;
25072557
case KIND_MINISCRIPT_PK_K:

0 commit comments

Comments
 (0)