Derive BIP86 public key from the base key */
| 267 | |
| 268 | /* Derive BIP86 public key from the base key */ |
| 269 | void bip86_pubkey(struct lightningd *ld, struct pubkey *pubkey, u32 index) |
| 270 | { |
| 271 | const uint32_t flags = BIP32_FLAG_KEY_PUBLIC | BIP32_FLAG_SKIP_HASH; |
| 272 | struct ext_key ext; |
| 273 | u32 path[2]; |
| 274 | |
| 275 | if (index >= BIP32_INITIAL_HARDENED_CHILD) |
| 276 | fatal("Can't derive key %u (too large!)", index); |
| 277 | |
| 278 | /* BIP86 path: m/86'/0'/0'/0/index */ |
| 279 | path[0] = 0; /* change (0 for receive) */ |
| 280 | path[1] = index; /* address_index */ |
| 281 | |
| 282 | assert(ld->bip86_base != NULL); |
| 283 | |
| 284 | if (bip32_key_from_parent_path(ld->bip86_base, path, 2, flags, &ext) != WALLY_OK) |
| 285 | fatal("Can't derive key %u", index); |
| 286 | |
| 287 | if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &pubkey->pubkey, |
| 288 | ext.pub_key, sizeof(ext.pub_key))) |
| 289 | fatal("Can't parse derived key %u", index); |
| 290 | |
| 291 | /* Don't assume hsmd supports it! */ |
| 292 | if (hsm_capable(ld, WIRE_HSMD_CHECK_BIP86_PUBKEY)) { |
| 293 | bool ok; |
| 294 | const u8 *msg = towire_hsmd_check_bip86_pubkey(NULL, index, pubkey); |
| 295 | msg = hsm_sync_req(tmpctx, ld, take(msg)); |
| 296 | if (!fromwire_hsmd_check_bip86_pubkey_reply(msg, &ok)) |
| 297 | fatal("Invalid check_bip86_pubkey_reply from hsm"); |
| 298 | |
| 299 | if (!ok) |
| 300 | fatal("HSM said BIP86 key derivation of %u != %s", |
| 301 | index, fmt_pubkey(tmpctx, pubkey)); |
| 302 | } |
| 303 | } |
| 304 | |
| 305 | const u8 *hsm_sync_req(const tal_t *ctx, struct lightningd *ld, const u8 *msg) |
| 306 | { |
no test coverage detected