mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
hsm: sign funding transactions.
The main daemon gives it to us to sign the inputs. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
891a915e0f
commit
f66445c1d1
@ -1,5 +1,7 @@
|
||||
#include <bitcoin/privkey.h>
|
||||
#include <bitcoin/pubkey.h>
|
||||
#include <bitcoin/script.h>
|
||||
#include <bitcoin/tx.h>
|
||||
#include <ccan/breakpoint/breakpoint.h>
|
||||
#include <ccan/container_of/container_of.h>
|
||||
#include <ccan/crypto/hkdf_sha256/hkdf_sha256.h>
|
||||
@ -8,6 +10,7 @@
|
||||
#include <ccan/io/fdpass/fdpass.h>
|
||||
#include <ccan/io/io.h>
|
||||
#include <ccan/noerr/noerr.h>
|
||||
#include <ccan/ptrint/ptrint.h>
|
||||
#include <ccan/read_write_all/read_write_all.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
@ -16,6 +19,7 @@
|
||||
#include <lightningd/hsm/gen_hsm_client_wire.h>
|
||||
#include <lightningd/hsm/gen_hsm_control_wire.h>
|
||||
#include <lightningd/hsm/gen_hsm_status_wire.h>
|
||||
#include <permute_tx.h>
|
||||
#include <secp256k1_ecdh.h>
|
||||
#include <sodium/randombytes.h>
|
||||
#include <status.h>
|
||||
@ -198,7 +202,7 @@ static void populate_secretstuff(void)
|
||||
"Can't derive private bip32 key");
|
||||
}
|
||||
|
||||
static inline void bitcoin_pubkey(struct pubkey *pubkey, u32 index)
|
||||
static void bitcoin_pubkey(struct pubkey *pubkey, u32 index)
|
||||
{
|
||||
struct ext_key ext;
|
||||
|
||||
@ -217,9 +221,9 @@ static inline void bitcoin_pubkey(struct pubkey *pubkey, u32 index)
|
||||
"Parse of BIP32 child %u pubkey failed", index);
|
||||
}
|
||||
|
||||
static inline void bitcoin_keypair(struct privkey *privkey,
|
||||
struct pubkey *pubkey,
|
||||
u32 index)
|
||||
static void bitcoin_keypair(struct privkey *privkey,
|
||||
struct pubkey *pubkey,
|
||||
u32 index)
|
||||
{
|
||||
struct ext_key ext;
|
||||
|
||||
@ -340,6 +344,82 @@ static u8 *pass_hsmfd_ecdh(struct io_conn *conn,
|
||||
return towire_hsmctl_hsmfd_fd_response(control);
|
||||
}
|
||||
|
||||
/* Note that it's the main daemon that asks for the funding signature so it
|
||||
* can broadcast it. */
|
||||
static u8 *sign_funding_tx(const tal_t *ctx, const u8 *data)
|
||||
{
|
||||
const tal_t *tmpctx = tal_tmpctx(ctx);
|
||||
u64 satoshi_out, change_out;
|
||||
u32 change_keyindex;
|
||||
struct privkey local_privkey;
|
||||
struct pubkey local_pubkey, remote_pubkey;
|
||||
struct utxo *inputs;
|
||||
struct bitcoin_tx *tx;
|
||||
u8 *wscript, *msg_out;
|
||||
secp256k1_ecdsa_signature *sig;
|
||||
const void **inmap;
|
||||
size_t i;
|
||||
|
||||
/* FIXME: Check fee is "reasonable" */
|
||||
if (!fromwire_hsmctl_sign_funding(tmpctx, data, NULL,
|
||||
&satoshi_out, &change_out,
|
||||
&change_keyindex, &local_privkey,
|
||||
&local_pubkey, &inputs))
|
||||
status_failed(WIRE_HSMSTATUS_BAD_REQUEST, "Bad SIGN_FUNDING");
|
||||
|
||||
if (!secp256k1_ec_pubkey_create(secp256k1_ctx,
|
||||
&local_pubkey.pubkey,
|
||||
local_privkey.secret))
|
||||
status_failed(WIRE_HSMSTATUS_BAD_REQUEST,
|
||||
"Bad SIGN_FUNDING privkey");
|
||||
|
||||
tx = bitcoin_tx(tmpctx, tal_count(inputs), 1 + !!change_out);
|
||||
inmap = tal_arr(tmpctx, const void *, tal_count(inputs));
|
||||
for (i = 0; i < tal_count(inputs); i++) {
|
||||
tx->input[i].txid = inputs[i].txid;
|
||||
tx->input[i].index = inputs[i].outnum;
|
||||
tx->input[i].amount = tal_dup(tx->input, u64, &inputs[i].amount);
|
||||
inmap[i] = int2ptr(i);
|
||||
}
|
||||
tx->output[0].amount = satoshi_out;
|
||||
wscript = bitcoin_redeem_2of2(tx, &local_pubkey, &remote_pubkey);
|
||||
tx->output[0].script = scriptpubkey_p2wsh(tx, wscript);
|
||||
if (change_out) {
|
||||
struct pubkey changekey;
|
||||
bitcoin_pubkey(&changekey, change_keyindex);
|
||||
|
||||
tx->output[1].amount = change_out;
|
||||
tx->output[1].script = scriptpubkey_p2wpkh(tx, &changekey);
|
||||
}
|
||||
|
||||
/* Now permute. */
|
||||
permute_outputs(tx->output, tal_count(tx->output), NULL);
|
||||
permute_inputs(tx->input, tal_count(tx->input), inmap);
|
||||
|
||||
/* Now generate signatures. */
|
||||
sig = tal_arr(tmpctx, secp256k1_ecdsa_signature, tal_count(inputs));
|
||||
for (i = 0; i < tal_count(inputs); i++) {
|
||||
struct pubkey inkey;
|
||||
struct privkey inprivkey;
|
||||
const struct utxo *in = &inputs[ptr2int(inmap[i])];
|
||||
u8 *subscript;
|
||||
|
||||
bitcoin_keypair(&inprivkey, &inkey, in->keyindex);
|
||||
if (in->is_p2sh)
|
||||
subscript = bitcoin_redeem_p2wpkh(tmpctx, &inkey);
|
||||
else
|
||||
subscript = NULL;
|
||||
wscript = p2wpkh_scriptcode(tmpctx, &inkey);
|
||||
|
||||
sign_tx_input(tx, i, subscript, wscript,
|
||||
&inprivkey, &inkey, &sig[i]);
|
||||
}
|
||||
|
||||
msg_out = towire_hsmctl_sign_funding_response(ctx, sig);
|
||||
tal_free(tmpctx);
|
||||
return msg_out;
|
||||
}
|
||||
|
||||
static struct io_plan *control_received_req(struct io_conn *conn,
|
||||
struct conn_info *control)
|
||||
{
|
||||
@ -359,9 +439,13 @@ static struct io_plan *control_received_req(struct io_conn *conn,
|
||||
control->out = pass_hsmfd_ecdh(conn, control, control->in,
|
||||
&control->out_fd);
|
||||
goto send_out;
|
||||
case WIRE_HSMCTL_SIGN_FUNDING:
|
||||
control->out = sign_funding_tx(control, control->in);
|
||||
goto send_out;
|
||||
|
||||
case WIRE_HSMCTL_INIT_RESPONSE:
|
||||
case WIRE_HSMCTL_HSMFD_FD_RESPONSE:
|
||||
case WIRE_HSMCTL_SIGN_FUNDING_RESPONSE:
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -11,5 +11,21 @@ hsmctl_init_response,35,bip32_seed,bip32_len*1,u8
|
||||
hsmctl_hsmfd_ecdh,3
|
||||
hsmctl_hsmfd_ecdh,0,unique_id,8
|
||||
|
||||
# Return signature for a funding tx.
|
||||
#include <lightningd/utxo.h>
|
||||
# FIXME: This should also take their commit sig & details, to verify.
|
||||
hsmctl_sign_funding,4
|
||||
hsmctl_sign_funding,0,satoshi_out,8
|
||||
hsmctl_sign_funding,8,change_out,8
|
||||
hsmctl_sign_funding,16,change_keyindex,4
|
||||
hsmctl_sign_funding,20,our_privkey,32,struct privkey
|
||||
hsmctl_sign_funding,52,their_pubkey,33
|
||||
hsmctl_sign_funding,85,num_inputs,2
|
||||
hsmctl_sign_funding,87,inputs,num_inputs*49,struct utxo
|
||||
|
||||
hsmctl_sign_funding_response,104
|
||||
hsmctl_sign_funding_response,0,num_sigs,2
|
||||
hsmctl_sign_funding_response,0,sig,num_sigs*64,secp256k1_ecdsa_signature
|
||||
|
||||
# No message, just an fd.
|
||||
hsmctl_hsmfd_fd_response,103
|
||||
|
Loading…
Reference in New Issue
Block a user