Skip to content

Commit 095ff3d

Browse files
sangbidarustyrussell
authored andcommitted
wallet/hsmd: fix signmessagewithkey for BIP86 wallets
The signmessagewithkey RPC was failing for BIP86 (mnemonic-based) wallets because: 1. The wallet RPC was iterating through BIP32-derived addresses only, so it couldn't find BIP86-derived addresses. 2. The HSM's handle_bip137_sign_message always used bitcoin_key() (BIP32 derivation) regardless of wallet type.
1 parent 54f4ceb commit 095ff3d

3 files changed

Lines changed: 18 additions & 27 deletions

File tree

hsmd/libhsmd.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -767,8 +767,12 @@ static u8 *handle_bip137_sign_message(struct hsmd_client *c, const u8 *msg_in)
767767
sha256_update(&sctx, msg, msg_len);
768768
sha256_double_done(&sctx, &shad);
769769

770-
/* get the private key BIP32 */
771-
bitcoin_key(&privkey, &pubkey, keyidx);
770+
/* Get the private key using appropriate derivation method */
771+
if (use_bip86_derivation(tal_bytelen(secretstuff.bip32_seed))) {
772+
bip86_key(&privkey, &pubkey, keyidx);
773+
} else {
774+
bitcoin_key(&privkey, &pubkey, keyidx);
775+
}
772776

773777
if (!secp256k1_ecdsa_sign_recoverable(
774778
secp256k1_ctx, &rsig, shad.sha.u.u8, privkey.secret.data, NULL,

wallet/test/run-wallet.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,7 @@ static struct wallet *create_test_wallet(struct lightningd *ld, const tal_t *ctx
911911
w->ld = ld;
912912
ld->wallet = w;
913913

914+
ld->bip86_base = NULL;
914915
ld->bip32_base = tal(ld, struct ext_key);
915916
CHECK(bip32_key_from_seed(badseed, sizeof(badseed),
916917
BIP32_VER_TEST_PRIVATE, 0,

wallet/walletrpc.c

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,38 +1282,24 @@ json_signmessagewithkey(struct command *cmd, const char *buffer,
12821282
"HSM does not support signing BIP137 signing.");
12831283
}
12841284

1285-
const u32 bip32_max_index =
1286-
db_get_intvar(cmd->ld->wallet->db, "bip32_max_index", 0);
1287-
bool match_found = false;
12881285
u32 keyidx;
1289-
enum addrtype addrtype;
1286+
enum addrtype addrtype;
12901287

1291-
/* loop over all generated keys, find a matching key */
1292-
for (keyidx = 1; keyidx <= bip32_max_index; keyidx++) {
1293-
bip32_pubkey(cmd->ld, &pubkey, keyidx);
1294-
u8 *redeemscript_p2wpkh;
1295-
char *out_p2wpkh = encode_pubkey_to_addr(
1296-
cmd, &pubkey, ADDR_BECH32, &redeemscript_p2wpkh);
1297-
if (!out_p2wpkh) {
1298-
abort();
1299-
}
1300-
/* wallet_get_addrtype fails for entries prior to v24.11, all
1301-
* address types are assumed in that case. */
1302-
if (!wallet_get_addrtype(cmd->ld->wallet, keyidx, &addrtype))
1303-
addrtype = ADDR_ALL;
1304-
if (streq(addr, out_p2wpkh) &&
1305-
(addrtype == ADDR_BECH32 || addrtype == ADDR_ALL)) {
1306-
match_found = true;
1307-
break;
1308-
}
1309-
}
1310-
1311-
if (!match_found) {
1288+
/* Use wallet_can_spend which handles both BIP32 and BIP86 addresses */
1289+
if (!wallet_can_spend(cmd->ld->wallet, scriptpubkey, script_len,
1290+
&keyidx, &addrtype)) {
13121291
return command_fail(
13131292
cmd, JSONRPC2_INVALID_PARAMS,
13141293
"Address is not found in the wallet's database");
13151294
}
13161295

1296+
/* Derive the pubkey for the found key index */
1297+
if (cmd->ld->bip86_base) {
1298+
bip86_pubkey(cmd->ld, &pubkey, keyidx);
1299+
} else {
1300+
bip32_pubkey(cmd->ld, &pubkey, keyidx);
1301+
}
1302+
13171303
/* wire to hsmd a sign request */
13181304
u8 *msg = towire_hsmd_bip137_sign_message(
13191305
cmd, tal_dup_arr(tmpctx, u8, (u8 *)message, strlen(message), 0),

0 commit comments

Comments
 (0)