hsmd: find correct P2TR key for utxo
In the case where we receive a taproot utxo we want to be able to tell if it was derived using a BIP32 seed or a BIP86 seed. Considering we will only be supporting BI86 type wallet addresses for mnemonics we can check if the out secret is 64 bytes long and if it is we can use our BIP86 for the withdrawal.
This commit is contained in:
committed by
Rusty Russell
parent
618d4f3377
commit
1b3e881d5a
@@ -696,7 +696,7 @@ static struct io_plan *handle_derive_bip86_key(struct io_conn *conn,
|
||||
return bad_req(conn, c, msg_in);
|
||||
|
||||
/* Check if we have a mnemonic-based HSM secret */
|
||||
if (hsm_secret_size(&hsm_secret) != 64) {
|
||||
if (!use_bip86_derivation(hsm_secret_size(&hsm_secret))) {
|
||||
return bad_req_fmt(conn, c, msg_in,
|
||||
"BIP86 derivation requires mnemonic-based HSM secret");
|
||||
}
|
||||
@@ -724,7 +724,7 @@ static struct io_plan *handle_check_bip86_pubkey(struct io_conn *conn,
|
||||
return bad_req(conn, c, msg_in);
|
||||
|
||||
/* Check if we have a mnemonic-based HSM secret */
|
||||
if (hsm_secret_size(&hsm_secret) != 64) {
|
||||
if (!use_bip86_derivation(hsm_secret_size(&hsm_secret))) {
|
||||
return bad_req_fmt(conn, c, msg_in,
|
||||
"BIP86 derivation requires mnemonic-based HSM secret");
|
||||
}
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
#include <bitcoin/script.h>
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <ccan/crypto/hkdf_sha256/hkdf_sha256.h>
|
||||
#include <ccan/mem/mem.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/bolt12_id.h>
|
||||
#include <common/bolt12_merkle.h>
|
||||
#include <common/hash_u5.h>
|
||||
#include <common/hsm_secret.h>
|
||||
#include <common/key_derive.h>
|
||||
#include <common/lease_rates.h>
|
||||
#include <common/memleak.h>
|
||||
@@ -542,8 +544,32 @@ static void hsm_key_for_utxo(struct privkey *privkey, struct pubkey *pubkey,
|
||||
hsmd_status_debug("Derived public key %s from unilateral close",
|
||||
fmt_pubkey(tmpctx, pubkey));
|
||||
} else {
|
||||
/* Simple case: just get derive via HD-derivation */
|
||||
bitcoin_key(privkey, pubkey, utxo->keyindex);
|
||||
/* Check if this is a BIP86 UTXO by examining the scriptPubkey */
|
||||
const size_t script_len = tal_bytelen(utxo->scriptPubkey);
|
||||
bool is_bip86 = false;
|
||||
|
||||
/* For P2TR scripts, we need to determine if it's BIP86 or regular P2TR
|
||||
* But BIP86 derivation requires mnemonic-based secrets */
|
||||
if (is_p2tr(utxo->scriptPubkey, script_len, NULL) &&
|
||||
use_bip86_derivation(secretstuff.bip32_seed_len)) {
|
||||
/* Try BIP86 derivation first and see if it matches */
|
||||
struct pubkey test_pubkey;
|
||||
bip86_key(NULL, &test_pubkey, utxo->keyindex);
|
||||
|
||||
/* Create P2TR scriptpubkey from BIP86 key and compare */
|
||||
const u8 *bip86_script = scriptpubkey_p2tr(tmpctx, &test_pubkey);
|
||||
if (memeq(utxo->scriptPubkey, script_len, bip86_script, tal_bytelen(bip86_script))) {
|
||||
is_bip86 = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_bip86) {
|
||||
/* Use BIP86 derivation */
|
||||
bip86_key(privkey, pubkey, utxo->keyindex);
|
||||
} else {
|
||||
/* Simple case: just get derive via HD-derivation */
|
||||
bitcoin_key(privkey, pubkey, utxo->keyindex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user