diff --git a/hsmd/hsmd.c b/hsmd/hsmd.c index 26b3fb75b..0c5c58ef6 100644 --- a/hsmd/hsmd.c +++ b/hsmd/hsmd.c @@ -350,31 +350,6 @@ static void node_key(struct privkey *node_privkey, struct pubkey *node_id) #endif } -/*~ This returns the secret and/or public x-only key for this node. */ -static void node_schnorrkey(secp256k1_keypair *node_keypair, - struct pubkey32 *node_id32) -{ - secp256k1_keypair unused_kp; - struct privkey node_privkey; - - if (!node_keypair) - node_keypair = &unused_kp; - - node_key(&node_privkey, NULL); - if (secp256k1_keypair_create(secp256k1_ctx, node_keypair, - node_privkey.secret.data) != 1) - status_failed(STATUS_FAIL_INTERNAL_ERROR, - "Failed to derive keypair"); - - if (node_id32) { - if (secp256k1_keypair_xonly_pub(secp256k1_ctx, - &node_id32->pubkey, - NULL, node_keypair) != 1) - status_failed(STATUS_FAIL_INTERNAL_ERROR, - "Failed to derive xonly pub"); - } -} - /*~ This secret is the basis for all per-channel secrets: the per-channel seeds * will be generated by mixing in the dbid and the peer node_id. */ static void hsm_channel_secret_base(struct secret *channel_seed_base) @@ -1803,61 +1778,6 @@ static struct io_plan *handle_sign_node_announcement(struct io_conn *conn, return req_reply(conn, c, take(reply)); } - -/*~ lightningd asks us to sign a bolt12 (e.g. offer). */ -static struct io_plan *handle_sign_bolt12(struct io_conn *conn, - struct client *c, - const u8 *msg_in) -{ - char *messagename, *fieldname; - struct sha256 merkle, sha; - struct bip340sig sig; - secp256k1_keypair kp; - u8 *publictweak; - - if (!fromwire_hsmd_sign_bolt12(tmpctx, msg_in, - &messagename, &fieldname, &merkle, - &publictweak)) - return bad_req(conn, c, msg_in); - - sighash_from_merkle(messagename, fieldname, &merkle, &sha); - - if (!publictweak) { - node_schnorrkey(&kp, NULL); - } else { - /* If we're tweaking key, we use bolt12 key */ - struct pubkey32 bolt12; - struct sha256 tweak; - - if (secp256k1_keypair_xonly_pub(secp256k1_ctx, - &bolt12.pubkey, NULL, - &secretstuff.bolt12) != 1) - status_failed(STATUS_FAIL_INTERNAL_ERROR, - "Could not derive bolt12 public key."); - payer_key_tweak(&bolt12, publictweak, tal_bytelen(publictweak), - &tweak); - - kp = secretstuff.bolt12; - - if (secp256k1_keypair_xonly_tweak_add(secp256k1_ctx, - &kp, - tweak.u.u8) != 1) { - return bad_req_fmt(conn, c, msg_in, - "Failed to get tweak key"); - } - } - - if (!secp256k1_schnorrsig_sign(secp256k1_ctx, sig.u8, - sha.u.u8, - &kp, - NULL, NULL)) { - return bad_req_fmt(conn, c, msg_in, "Failed to sign bolt12"); - } - - return req_reply(conn, c, - take(towire_hsmd_sign_bolt12_reply(NULL, &sig))); -} - #if DEVELOPER static struct io_plan *handle_memleak(struct io_conn *conn, struct client *c, @@ -2009,13 +1929,12 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c) return handle_sign_mutual_close_tx(conn, c, c->msg_in); case WIRE_HSMD_SIGN_MESSAGE: + case WIRE_HSMD_SIGN_BOLT12: /* Hand off to libhsmd for processing */ return req_reply(conn, c, take(hsmd_handle_client_message( tmpctx, c->hsmd_client, c->msg_in))); - case WIRE_HSMD_SIGN_BOLT12: - return handle_sign_bolt12(conn, c, c->msg_in); #if DEVELOPER case WIRE_HSMD_DEV_MEMLEAK: return handle_memleak(conn, c, c->msg_in); diff --git a/hsmd/libhsmd.c b/hsmd/libhsmd.c index 4f3deee31..918bf9cc3 100644 --- a/hsmd/libhsmd.c +++ b/hsmd/libhsmd.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -188,6 +189,31 @@ static void node_key(struct privkey *node_privkey, struct pubkey *node_id) #endif } +/*~ This returns the secret and/or public x-only key for this node. */ +static void node_schnorrkey(secp256k1_keypair *node_keypair, + struct pubkey32 *node_id32) +{ + secp256k1_keypair unused_kp; + struct privkey node_privkey; + + if (!node_keypair) + node_keypair = &unused_kp; + + node_key(&node_privkey, NULL); + if (secp256k1_keypair_create(secp256k1_ctx, node_keypair, + node_privkey.secret.data) != 1) + hsmd_status_failed(STATUS_FAIL_INTERNAL_ERROR, + "Failed to derive keypair"); + + if (node_id32) { + if (secp256k1_keypair_xonly_pub(secp256k1_ctx, + &node_id32->pubkey, + NULL, node_keypair) != 1) + hsmd_status_failed(STATUS_FAIL_INTERNAL_ERROR, + "Failed to derive xonly pub"); + } +} + /*~ lightningd asks us to sign a message. I tweeted the spec * in https://twitter.com/rusty_twit/status/1182102005914800128: * @@ -227,6 +253,59 @@ static u8 *handle_sign_message(struct hsmd_client *c, const u8 *msg_in) return towire_hsmd_sign_message_reply(NULL, &rsig); } +/*~ lightningd asks us to sign a bolt12 (e.g. offer). */ +static u8 *handle_sign_bolt12(struct hsmd_client *c, const u8 *msg_in) +{ + char *messagename, *fieldname; + struct sha256 merkle, sha; + struct bip340sig sig; + secp256k1_keypair kp; + u8 *publictweak; + + if (!fromwire_hsmd_sign_bolt12(tmpctx, msg_in, + &messagename, &fieldname, &merkle, + &publictweak)) + return hsmd_status_malformed_request(c, msg_in); + + sighash_from_merkle(messagename, fieldname, &merkle, &sha); + + if (!publictweak) { + node_schnorrkey(&kp, NULL); + } else { + /* If we're tweaking key, we use bolt12 key */ + struct pubkey32 bolt12; + struct sha256 tweak; + + if (secp256k1_keypair_xonly_pub(secp256k1_ctx, + &bolt12.pubkey, NULL, + &secretstuff.bolt12) != 1) + hsmd_status_failed( + STATUS_FAIL_INTERNAL_ERROR, + "Could not derive bolt12 public key."); + payer_key_tweak(&bolt12, publictweak, tal_bytelen(publictweak), + &tweak); + + kp = secretstuff.bolt12; + + if (secp256k1_keypair_xonly_tweak_add(secp256k1_ctx, + &kp, + tweak.u.u8) != 1) { + return hsmd_status_bad_request_fmt( + c, msg_in, "Failed to get tweak key"); + } + } + + if (!secp256k1_schnorrsig_sign(secp256k1_ctx, sig.u8, + sha.u.u8, + &kp, + NULL, NULL)) { + return hsmd_status_bad_request_fmt(c, msg_in, + "Failed to sign bolt12"); + } + + return towire_hsmd_sign_bolt12_reply(NULL, &sig); +} + u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client, const u8 *msg) { @@ -271,10 +350,11 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client, case WIRE_HSMD_SIGN_REMOTE_COMMITMENT_TX: case WIRE_HSMD_SIGN_REMOTE_HTLC_TX: case WIRE_HSMD_SIGN_MUTUAL_CLOSE_TX: - case WIRE_HSMD_SIGN_BOLT12: /* Not implemented yet. Should not have been passed here yet. */ return hsmd_status_bad_request_fmt(client, msg, "Not implemented yet."); + case WIRE_HSMD_SIGN_BOLT12: + return handle_sign_bolt12(client, msg); case WIRE_HSMD_SIGN_MESSAGE: return handle_sign_message(client, msg);