Skip to content

Commit b6388c7

Browse files
Lagrang3rustyrussell
authored andcommitted
HSMD: add new wire BIP137 sign message API
Changelog-Added: HSMD: add new wire API to sign messages with bitcoin wallet keys according to BIP137. Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
1 parent 49bcc94 commit b6388c7

File tree

4 files changed

+64
-1
lines changed

4 files changed

+64
-1
lines changed

common/hsm_version.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
* v6 no secret from get_per_commitment_point: 0cad1790beb3473d64355f4cb4f64daa80c28c8a241998b7ef0223385d7ffff9
2929
* v6 with sign_bolt12_2 (tweak using node id): 8fcb731279a10af3f95aeb8be1da6b2ced76a1984afa18c5f46a03515d70ea0e
3030
* v6 with dev_warn_on_overgrind: a273b68e19336073e551c01a78bcd1e1f8cc510da7d0dde3afc45e249f9830cc
31-
*/
31+
* v6 with bip137_sign_message: 4bfe28b02e92aae276b8eca2228e32f32d5dee8d5381639e7364939fa2fa1370
32+
*/
3233
#define HSM_MIN_VERSION 5
3334
#define HSM_MAX_VERSION 6
3435
#endif /* LIGHTNING_COMMON_HSM_VERSION_H */

hsmd/hsmd.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,7 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
692692
case WIRE_HSMD_GET_CHANNEL_BASEPOINTS:
693693
case WIRE_HSMD_SIGN_INVOICE:
694694
case WIRE_HSMD_SIGN_MESSAGE:
695+
case WIRE_HSMD_BIP137_SIGN_MESSAGE:
695696
case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER:
696697
case WIRE_HSMD_SIGN_BOLT12:
697698
case WIRE_HSMD_SIGN_BOLT12_2:
@@ -748,6 +749,7 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
748749
case WIRE_HSMD_GET_CHANNEL_BASEPOINTS_REPLY:
749750
case WIRE_HSMD_DEV_MEMLEAK_REPLY:
750751
case WIRE_HSMD_SIGN_MESSAGE_REPLY:
752+
case WIRE_HSMD_BIP137_SIGN_MESSAGE_REPLY:
751753
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY_REPLY:
752754
case WIRE_HSMD_SIGN_BOLT12_REPLY:
753755
case WIRE_HSMD_SIGN_BOLT12_2_REPLY:

hsmd/hsmd_wire.csv

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,15 @@ msgdata,hsmd_sign_message,msg,u8,len
364364
msgtype,hsmd_sign_message_reply,123
365365
msgdata,hsmd_sign_message_reply,sig,secp256k1_ecdsa_recoverable_signature,
366366

367+
# sign a raw message with a derived key
368+
msgtype,hsmd_bip137_sign_message,45
369+
msgdata,hsmd_bip137_sign_message,len,u16,
370+
msgdata,hsmd_bip137_sign_message,msg,u8,len
371+
msgdata,hsmd_bip137_sign_message,keyidx,u32,
372+
373+
msgtype,hsmd_bip137_sign_message_reply,145
374+
msgdata,hsmd_bip137_sign_message_reply,sig,secp256k1_ecdsa_recoverable_signature,
375+
367376
# lightningd needs to get a scriptPubkey for a utxo with closeinfo
368377
msgtype,hsmd_get_output_scriptpubkey,24
369378
msgdata,hsmd_get_output_scriptpubkey,channel_id,u64,

hsmd/libhsmd.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
136136
case WIRE_HSMD_GET_CHANNEL_BASEPOINTS:
137137
case WIRE_HSMD_DEV_MEMLEAK:
138138
case WIRE_HSMD_SIGN_MESSAGE:
139+
case WIRE_HSMD_BIP137_SIGN_MESSAGE:
139140
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY:
140141
case WIRE_HSMD_SIGN_BOLT12:
141142
case WIRE_HSMD_SIGN_BOLT12_2:
@@ -182,6 +183,7 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
182183
case WIRE_HSMD_GET_CHANNEL_BASEPOINTS_REPLY:
183184
case WIRE_HSMD_DEV_MEMLEAK_REPLY:
184185
case WIRE_HSMD_SIGN_MESSAGE_REPLY:
186+
case WIRE_HSMD_BIP137_SIGN_MESSAGE_REPLY:
185187
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY_REPLY:
186188
case WIRE_HSMD_SIGN_BOLT12_REPLY:
187189
case WIRE_HSMD_SIGN_BOLT12_2_REPLY:
@@ -715,6 +717,51 @@ static u8 *handle_sign_message(struct hsmd_client *c, const u8 *msg_in)
715717
return towire_hsmd_sign_message_reply(NULL, &rsig);
716718
}
717719

720+
/* FIXME: implement BIP0322 signature scheme so that we can support any type of
721+
* address. */
722+
/* Sign a message with a private key (see BIP137):
723+
* signature = base64(SigRec(SHA256(SHA256(
724+
* "\x18Bitcoin Signed Message:\n" + var_int(len(message)) + message
725+
* )))) */
726+
static u8 *handle_bip137_sign_message(struct hsmd_client *c, const u8 *msg_in)
727+
{
728+
u8 *msg;
729+
u32 keyidx;
730+
struct sha256_ctx sctx = SHA256_INIT;
731+
struct sha256_double shad;
732+
secp256k1_ecdsa_recoverable_signature rsig;
733+
struct privkey privkey;
734+
struct pubkey pubkey;
735+
736+
if (!fromwire_hsmd_bip137_sign_message(tmpctx, msg_in, &msg, &keyidx))
737+
return hsmd_status_malformed_request(c, msg_in);
738+
739+
/* double sha256 the message */
740+
const char header[] = "\x18"
741+
"Bitcoin Signed Message:\n";
742+
sha256_update(&sctx, (const u8 *)header, strlen(header));
743+
744+
u8 vt[VARINT_MAX_LEN];
745+
size_t msg_len = tal_count(msg);
746+
size_t vtlen = varint_put(vt, msg_len);
747+
sha256_update(&sctx, vt, vtlen);
748+
749+
sha256_update(&sctx, msg, msg_len);
750+
sha256_double_done(&sctx, &shad);
751+
752+
/* get the private key BIP32 */
753+
bitcoin_key(&privkey, &pubkey, keyidx);
754+
755+
if (!secp256k1_ecdsa_sign_recoverable(
756+
secp256k1_ctx, &rsig, shad.sha.u.u8, privkey.secret.data, NULL,
757+
NULL)) {
758+
return hsmd_status_bad_request(c, msg_in,
759+
"Failed to sign message");
760+
}
761+
762+
return towire_hsmd_bip137_sign_message_reply(NULL, &rsig);
763+
}
764+
718765
/*~ lightningd asks us to sign a liquidity ad offer */
719766
static u8 *handle_sign_option_will_fund_offer(struct hsmd_client *c,
720767
const u8 *msg_in)
@@ -2181,6 +2228,8 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
21812228
return handle_preapprove_keysend(client, msg);
21822229
case WIRE_HSMD_SIGN_MESSAGE:
21832230
return handle_sign_message(client, msg);
2231+
case WIRE_HSMD_BIP137_SIGN_MESSAGE:
2232+
return handle_bip137_sign_message(client, msg);
21842233
case WIRE_HSMD_GET_CHANNEL_BASEPOINTS:
21852234
return handle_get_channel_basepoints(client, msg);
21862235
case WIRE_HSMD_CANNOUNCEMENT_SIG_REQ:
@@ -2263,6 +2312,7 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
22632312
case WIRE_HSMD_GET_CHANNEL_BASEPOINTS_REPLY:
22642313
case WIRE_HSMD_DEV_MEMLEAK_REPLY:
22652314
case WIRE_HSMD_SIGN_MESSAGE_REPLY:
2315+
case WIRE_HSMD_BIP137_SIGN_MESSAGE_REPLY:
22662316
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY_REPLY:
22672317
case WIRE_HSMD_SIGN_BOLT12_REPLY:
22682318
case WIRE_HSMD_SIGN_BOLT12_2_REPLY:
@@ -2297,6 +2347,7 @@ u8 *hsmd_init(struct secret hsm_secret, const u64 hsmd_version,
22972347
WIRE_HSMD_FORGET_CHANNEL,
22982348
WIRE_HSMD_REVOKE_COMMITMENT_TX,
22992349
WIRE_HSMD_SIGN_BOLT12_2,
2350+
WIRE_HSMD_BIP137_SIGN_MESSAGE,
23002351
WIRE_HSMD_PREAPPROVE_INVOICE_CHECK,
23012352
WIRE_HSMD_PREAPPROVE_KEYSEND_CHECK,
23022353
};

0 commit comments

Comments
 (0)