@@ -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,49 @@ 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+ /* Raw message signing with provided key using electrum's standard
707+ * signature = base64(SigRec(SHA256(SHA256(
708+ * "\x18Bitcoin Signed Message:\n" + var_int(len(message)) + message
709+ * )))) */
710+ static u8 * handle_sign_message_with_key (struct hsmd_client * c , const u8 * msg_in )
711+ {
712+ u8 * msg ;
713+ u32 keyidx ;
714+ struct sha256_ctx sctx = SHA256_INIT ;
715+ struct sha256_double shad ;
716+ secp256k1_ecdsa_recoverable_signature rsig ;
717+ struct privkey privkey ;
718+ struct pubkey pubkey ;
719+
720+ if (!fromwire_hsmd_sign_message_with_key (tmpctx , msg_in , & msg , & keyidx ))
721+ return hsmd_status_malformed_request (c , msg_in );
722+
723+ /* double sha256 the message */
724+ const char header [] = "\x18"
725+ "Bitcoin Signed Message:\n" ;
726+ sha256_update (& sctx , (const u8 * )header , strlen (header ));
727+
728+ u8 vt [VARINT_MAX_LEN ];
729+ size_t msg_len = tal_count (msg );
730+ size_t vtlen = varint_put (vt , msg_len );
731+ sha256_update (& sctx , vt , vtlen );
732+
733+ sha256_update (& sctx , msg , msg_len );
734+ sha256_double_done (& sctx , & shad );
735+
736+ /* get the private key BIP32 */
737+ bitcoin_key (& privkey , & pubkey , keyidx );
738+
739+ if (!secp256k1_ecdsa_sign_recoverable (
740+ secp256k1_ctx , & rsig , shad .sha .u .u8 , privkey .secret .data , NULL ,
741+ NULL )) {
742+ return hsmd_status_bad_request (c , msg_in ,
743+ "Failed to sign message" );
744+ }
745+
746+ return towire_hsmd_sign_message_with_key_reply (NULL , & rsig );
747+ }
748+
704749/*~ lightningd asks us to sign a liquidity ad offer */
705750static u8 * handle_sign_option_will_fund_offer (struct hsmd_client * c ,
706751 const u8 * msg_in )
@@ -2167,6 +2212,8 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
21672212 return handle_preapprove_keysend (client , msg );
21682213 case WIRE_HSMD_SIGN_MESSAGE :
21692214 return handle_sign_message (client , msg );
2215+ case WIRE_HSMD_SIGN_MESSAGE_WITH_KEY :
2216+ return handle_sign_message_with_key (client , msg );
21702217 case WIRE_HSMD_GET_CHANNEL_BASEPOINTS :
21712218 return handle_get_channel_basepoints (client , msg );
21722219 case WIRE_HSMD_CANNOUNCEMENT_SIG_REQ :
@@ -2249,6 +2296,7 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
22492296 case WIRE_HSMD_GET_CHANNEL_BASEPOINTS_REPLY :
22502297 case WIRE_HSMD_DEV_MEMLEAK_REPLY :
22512298 case WIRE_HSMD_SIGN_MESSAGE_REPLY :
2299+ case WIRE_HSMD_SIGN_MESSAGE_WITH_KEY_REPLY :
22522300 case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY_REPLY :
22532301 case WIRE_HSMD_SIGN_BOLT12_REPLY :
22542302 case WIRE_HSMD_SIGN_BOLT12_2_REPLY :
0 commit comments