@@ -135,6 +135,7 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
135135 case WIRE_HSMD_GET_CHANNEL_BASEPOINTS :
136136 case WIRE_HSMD_DEV_MEMLEAK :
137137 case WIRE_HSMD_SIGN_MESSAGE :
138+ case WIRE_HSMD_SIGN_MESSAGE_WITH_KEY :
138139 case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY :
139140 case WIRE_HSMD_SIGN_BOLT12 :
140141 case WIRE_HSMD_SIGN_BOLT12_2 :
@@ -181,6 +182,7 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
181182 case WIRE_HSMD_GET_CHANNEL_BASEPOINTS_REPLY :
182183 case WIRE_HSMD_DEV_MEMLEAK_REPLY :
183184 case WIRE_HSMD_SIGN_MESSAGE_REPLY :
185+ case WIRE_HSMD_SIGN_MESSAGE_WITH_KEY_REPLY :
184186 case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY_REPLY :
185187 case WIRE_HSMD_SIGN_BOLT12_REPLY :
186188 case WIRE_HSMD_SIGN_BOLT12_2_REPLY :
@@ -701,6 +703,51 @@ static u8 *handle_sign_message(struct hsmd_client *c, const u8 *msg_in)
701703 return towire_hsmd_sign_message_reply (NULL , & rsig );
702704}
703705
706+ /* FIXME: implement BIP0322 signature scheme so that we can support any type of
707+ * address. */
708+ /* Sign a message with a private key (see BIP137):
709+ * signature = base64(SigRec(SHA256(SHA256(
710+ * "\x18Bitcoin Signed Message:\n" + var_int(len(message)) + message
711+ * )))) */
712+ static u8 * handle_sign_message_with_key (struct hsmd_client * c , const u8 * msg_in )
713+ {
714+ u8 * msg ;
715+ u32 keyidx ;
716+ struct sha256_ctx sctx = SHA256_INIT ;
717+ struct sha256_double shad ;
718+ secp256k1_ecdsa_recoverable_signature rsig ;
719+ struct privkey privkey ;
720+ struct pubkey pubkey ;
721+
722+ if (!fromwire_hsmd_sign_message_with_key (tmpctx , msg_in , & msg , & keyidx ))
723+ return hsmd_status_malformed_request (c , msg_in );
724+
725+ /* double sha256 the message */
726+ const char header [] = "\x18"
727+ "Bitcoin Signed Message:\n" ;
728+ sha256_update (& sctx , (const u8 * )header , strlen (header ));
729+
730+ u8 vt [VARINT_MAX_LEN ];
731+ size_t msg_len = tal_count (msg );
732+ size_t vtlen = varint_put (vt , msg_len );
733+ sha256_update (& sctx , vt , vtlen );
734+
735+ sha256_update (& sctx , msg , msg_len );
736+ sha256_double_done (& sctx , & shad );
737+
738+ /* get the private key BIP32 */
739+ bitcoin_key (& privkey , & pubkey , keyidx );
740+
741+ if (!secp256k1_ecdsa_sign_recoverable (
742+ secp256k1_ctx , & rsig , shad .sha .u .u8 , privkey .secret .data , NULL ,
743+ NULL )) {
744+ return hsmd_status_bad_request (c , msg_in ,
745+ "Failed to sign message" );
746+ }
747+
748+ return towire_hsmd_sign_message_with_key_reply (NULL , & rsig );
749+ }
750+
704751/*~ lightningd asks us to sign a liquidity ad offer */
705752static u8 * handle_sign_option_will_fund_offer (struct hsmd_client * c ,
706753 const u8 * msg_in )
@@ -2167,6 +2214,8 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
21672214 return handle_preapprove_keysend (client , msg );
21682215 case WIRE_HSMD_SIGN_MESSAGE :
21692216 return handle_sign_message (client , msg );
2217+ case WIRE_HSMD_SIGN_MESSAGE_WITH_KEY :
2218+ return handle_sign_message_with_key (client , msg );
21702219 case WIRE_HSMD_GET_CHANNEL_BASEPOINTS :
21712220 return handle_get_channel_basepoints (client , msg );
21722221 case WIRE_HSMD_CANNOUNCEMENT_SIG_REQ :
@@ -2249,6 +2298,7 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
22492298 case WIRE_HSMD_GET_CHANNEL_BASEPOINTS_REPLY :
22502299 case WIRE_HSMD_DEV_MEMLEAK_REPLY :
22512300 case WIRE_HSMD_SIGN_MESSAGE_REPLY :
2301+ case WIRE_HSMD_SIGN_MESSAGE_WITH_KEY_REPLY :
22522302 case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY_REPLY :
22532303 case WIRE_HSMD_SIGN_BOLT12_REPLY :
22542304 case WIRE_HSMD_SIGN_BOLT12_2_REPLY :
0 commit comments