hsmd: add BIP86 wire scaffolding (derive/check), no behavior yet
What changed, and why it matters
This commit only adds placeholder message types and stubs for a future BIP86 key-derivation feature. The new wire messages return an explicit 'not implemented yet' error and perform no actual key derivation, signing, or secret handling. There is no active security issue in this patch itself.
No immediate action required. Monitor follow-up commits that implement the actual BIP86 derivation and CHECK logic for correct hardened derivation, xpub neutering, and verification of unhardened derivations.
Security signals we found
New HSM wire messages added but not implemented
Stub handlers explicitly reject requests with 'not implemented yet'
No secret derivation, signing, or memory handling of key material in this patch
No existing behavior modified
Evidence from the diff
The change introduces four new HSM wire protocol messages (DERIVE_BIP86_KEY, CHECK_BIP86_PUBKEY and their replies), registers them in the client capability list and dispatch tables, and adds stub handlers that immediately fail with hsmd_status_bad_request_fmt(‘not implemented yet’). No cryptographic code, secret derivation, or state mutation is implemented. The commit message describes the intended future architecture but explicitly notes ‘no behavior yet’.
Changed components
hsmd/hsmd.chsmd/hsmd_wire.csvhsmd/libhsmd.cInspect captured patch +34 / −0
diff --git a/hsmd/hsmd.c b/hsmd/hsmd.c
index 0d7de8b..63cbc0f 100644
--- a/hsmd/hsmd.c
+++ b/hsmd/hsmd.c
@@ -750,6 +750,8 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
case WIRE_HSMD_SIGN_REMOTE_HTLC_TO_US:
case WIRE_HSMD_SIGN_DELAYED_PAYMENT_TO_US:
case WIRE_HSMD_CHECK_PUBKEY:
+ case WIRE_HSMD_DERIVE_BIP86_KEY:
+ case WIRE_HSMD_CHECK_BIP86_PUBKEY:
case WIRE_HSMD_SIGN_ANY_PENALTY_TO_US:
case WIRE_HSMD_SIGN_ANY_DELAYED_PAYMENT_TO_US:
case WIRE_HSMD_SIGN_ANY_REMOTE_HTLC_TO_US:
@@ -797,6 +799,8 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
case WIRE_HSMD_PREAPPROVE_INVOICE_CHECK_REPLY:
case WIRE_HSMD_PREAPPROVE_KEYSEND_CHECK_REPLY:
case WIRE_HSMD_CHECK_PUBKEY_REPLY:
+ case WIRE_HSMD_DERIVE_BIP86_KEY_REPLY:
+ case WIRE_HSMD_CHECK_BIP86_PUBKEY_REPLY:
case WIRE_HSMD_SIGN_ANCHORSPEND_REPLY:
case WIRE_HSMD_SIGN_HTLC_TX_MINGLE_REPLY:
case WIRE_HSMD_SIGN_ANY_CANNOUNCEMENT_REPLY:
diff --git a/hsmd/hsmd_wire.csv b/hsmd/hsmd_wire.csv
index cfca1e6..95ef50d 100644
--- a/hsmd/hsmd_wire.csv
+++ b/hsmd/hsmd_wire.csv
@@ -196,6 +196,14 @@ msgdata,hsmd_preapprove_keysend_check,check_only,bool,
msgtype,hsmd_preapprove_keysend_check_reply,152
msgdata,hsmd_preapprove_keysend_check_reply,approved,bool,
+# Derive BIP86 key using path m/86'/0'/0'/change/address_index
+msgtype,hsmd_derive_bip86_key,54
+msgdata,hsmd_derive_bip86_key,index,u32,
+msgdata,hsmd_derive_bip86_key,is_change,bool,
+
+msgtype,hsmd_derive_bip86_key_reply,154
+msgdata,hsmd_derive_bip86_key_reply,bip86_base,ext_key,
+
# Give me ECDH(node-id-secret,point)
msgtype,hsmd_ecdh_req,1
msgdata,hsmd_ecdh_req,point,pubkey,
@@ -447,6 +455,14 @@ msgdata,hsmd_check_pubkey,pubkey,pubkey,
msgtype,hsmd_check_pubkey_reply,128
msgdata,hsmd_check_pubkey_reply,ok,bool,
+# Sanity check this BIP86 pubkey derivation is correct (unhardened only)
+msgtype,hsmd_check_bip86_pubkey,56
+msgdata,hsmd_check_bip86_pubkey,index,u32,
+msgdata,hsmd_check_bip86_pubkey,pubkey,pubkey,
+
+msgtype,hsmd_check_bip86_pubkey_reply,156
+msgdata,hsmd_check_bip86_pubkey_reply,ok,bool,
+
msgtype,hsmd_sign_anchorspend,147
msgdata,hsmd_sign_anchorspend,peerid,node_id,
msgdata,hsmd_sign_anchorspend,channel_dbid,u64,
diff --git a/hsmd/libhsmd.c b/hsmd/libhsmd.c
index 2adeed1..51cb238 100644
--- a/hsmd/libhsmd.c
+++ b/hsmd/libhsmd.c
@@ -154,6 +154,8 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
case WIRE_HSMD_PREAPPROVE_KEYSEND_CHECK:
case WIRE_HSMD_DERIVE_SECRET:
case WIRE_HSMD_CHECK_PUBKEY:
+ case WIRE_HSMD_DERIVE_BIP86_KEY:
+ case WIRE_HSMD_CHECK_BIP86_PUBKEY:
case WIRE_HSMD_SIGN_ANY_PENALTY_TO_US:
case WIRE_HSMD_SIGN_ANY_DELAYED_PAYMENT_TO_US:
case WIRE_HSMD_SIGN_ANY_REMOTE_HTLC_TO_US:
@@ -202,6 +204,8 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
case WIRE_HSMD_PREAPPROVE_KEYSEND_CHECK_REPLY:
case WIRE_HSMD_DERIVE_SECRET_REPLY:
case WIRE_HSMD_CHECK_PUBKEY_REPLY:
+ case WIRE_HSMD_DERIVE_BIP86_KEY_REPLY:
+ case WIRE_HSMD_CHECK_BIP86_PUBKEY_REPLY:
case WIRE_HSMD_SIGN_ANCHORSPEND_REPLY:
case WIRE_HSMD_SIGN_HTLC_TX_MINGLE_REPLY:
case WIRE_HSMD_SIGN_ANY_CANNOUNCEMENT_REPLY:
@@ -2283,6 +2287,13 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
return handle_derive_secret(client, msg);
case WIRE_HSMD_CHECK_PUBKEY:
return handle_check_pubkey(client, msg);
+ case WIRE_HSMD_DERIVE_BIP86_KEY:
+ case WIRE_HSMD_CHECK_BIP86_PUBKEY:
+ /* Not implemented yet */
+ return hsmd_status_bad_request_fmt(
+ client, msg,
+ "Message of type %s not implemented yet",
+ hsmd_wire_name(fromwire_peektype(msg)));
case WIRE_HSMD_SIGN_ANY_DELAYED_PAYMENT_TO_US:
return handle_sign_any_delayed_payment_to_us(client, msg);
case WIRE_HSMD_SIGN_ANY_REMOTE_HTLC_TO_US:
@@ -2332,7 +2343,9 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
case WIRE_HSMD_PREAPPROVE_KEYSEND_REPLY:
case WIRE_HSMD_PREAPPROVE_INVOICE_CHECK_REPLY:
case WIRE_HSMD_PREAPPROVE_KEYSEND_CHECK_REPLY:
+ case WIRE_HSMD_DERIVE_BIP86_KEY_REPLY:
case WIRE_HSMD_CHECK_PUBKEY_REPLY:
+ case WIRE_HSMD_CHECK_BIP86_PUBKEY_REPLY:
case WIRE_HSMD_SIGN_ANCHORSPEND_REPLY:
case WIRE_HSMD_SIGN_HTLC_TX_MINGLE_REPLY:
case WIRE_HSMD_SIGN_ANY_CANNOUNCEMENT_REPLY:
@@ -2351,6 +2364,7 @@ u8 *hsmd_init(const u8 *secret_data, size_t secret_len, const u64 hsmd_version,
struct node_id node_id;
static const u32 capabilities[] = {
WIRE_HSMD_CHECK_PUBKEY,
+ WIRE_HSMD_CHECK_BIP86_PUBKEY,
WIRE_HSMD_SIGN_ANY_DELAYED_PAYMENT_TO_US,
WIRE_HSMD_SIGN_ANCHORSPEND,
WIRE_HSMD_SIGN_HTLC_TX_MINGLE,
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.