mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-20 23:54:22 +01:00
pubkey: don't carry around DER encoding.
We just wrap the libsecp256k1 structure, and convert to DER on demand. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
2
Makefile
2
Makefile
@@ -282,7 +282,7 @@ secp256k1/libsecp256k1.la:
|
||||
lightning.pb-c.c lightning.pb-c.h: lightning.proto
|
||||
$(PROTOCC) lightning.proto --c_out=.
|
||||
|
||||
$(TEST_PROGRAMS): % : %.o $(BITCOIN_OBJS) $(CCAN_OBJS) version.o libsecp256k1.a
|
||||
$(TEST_PROGRAMS): % : %.o $(BITCOIN_OBJS) $(CCAN_OBJS) utils.o version.o libsecp256k1.a
|
||||
|
||||
ccan/config.h: ccan/tools/configurator/configurator
|
||||
if $< > $@.new; then mv $@.new $@; else rm $@.new; exit 1; fi
|
||||
|
||||
@@ -1,39 +1,44 @@
|
||||
#include "privkey.h"
|
||||
#include "pubkey.h"
|
||||
#include "utils.h"
|
||||
#include <assert.h>
|
||||
#include <ccan/mem/mem.h>
|
||||
#include <ccan/str/hex/hex.h>
|
||||
#include <ccan/structeq/structeq.h>
|
||||
|
||||
bool pubkey_from_der(secp256k1_context *secpctx,
|
||||
const u8 *der, size_t len,
|
||||
struct pubkey *key)
|
||||
{
|
||||
if (len != sizeof(key->der))
|
||||
if (len != PUBKEY_DER_LEN)
|
||||
return false;
|
||||
|
||||
memcpy(key->der, memcheck(der, sizeof(key->der)), sizeof(key->der));
|
||||
if (!secp256k1_ec_pubkey_parse(secpctx, &key->pubkey, key->der,
|
||||
sizeof(key->der)))
|
||||
if (!secp256k1_ec_pubkey_parse(secpctx, &key->pubkey,
|
||||
memcheck(der, len), len))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void pubkey_to_der(secp256k1_context *secpctx, u8 der[PUBKEY_DER_LEN],
|
||||
const struct pubkey *key)
|
||||
{
|
||||
size_t outlen = PUBKEY_DER_LEN;
|
||||
if (!secp256k1_ec_pubkey_serialize(secpctx, der, &outlen,
|
||||
&key->pubkey,
|
||||
SECP256K1_EC_COMPRESSED))
|
||||
abort();
|
||||
assert(outlen == PUBKEY_DER_LEN);
|
||||
}
|
||||
|
||||
/* Pubkey from privkey */
|
||||
bool pubkey_from_privkey(secp256k1_context *secpctx,
|
||||
const struct privkey *privkey,
|
||||
struct pubkey *key,
|
||||
unsigned int compressed_flags)
|
||||
{
|
||||
size_t outlen;
|
||||
|
||||
if (!secp256k1_ec_pubkey_create(secpctx, &key->pubkey, privkey->secret))
|
||||
return false;
|
||||
|
||||
if (!secp256k1_ec_pubkey_serialize(secpctx, key->der, &outlen,
|
||||
&key->pubkey, compressed_flags))
|
||||
return false;
|
||||
assert(outlen == sizeof(key->der));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -41,7 +46,7 @@ bool pubkey_from_hexstr(secp256k1_context *secpctx,
|
||||
const char *derstr, size_t slen, struct pubkey *key)
|
||||
{
|
||||
size_t dlen;
|
||||
unsigned char der[sizeof(key->der)];
|
||||
unsigned char der[PUBKEY_DER_LEN];
|
||||
|
||||
dlen = hex_data_size(slen);
|
||||
if (dlen != sizeof(der))
|
||||
@@ -53,7 +58,16 @@ bool pubkey_from_hexstr(secp256k1_context *secpctx,
|
||||
return pubkey_from_der(secpctx, der, dlen, key);
|
||||
}
|
||||
|
||||
char *pubkey_to_hexstr(const tal_t *ctx, secp256k1_context *secpctx,
|
||||
const struct pubkey *key)
|
||||
{
|
||||
unsigned char der[PUBKEY_DER_LEN];
|
||||
|
||||
pubkey_to_der(secpctx, der, key);
|
||||
return tal_hexstr(ctx, der, sizeof(der));
|
||||
}
|
||||
|
||||
bool pubkey_eq(const struct pubkey *a, const struct pubkey *b)
|
||||
{
|
||||
return memcmp(a->der, b->der, sizeof(a->der)) == 0;
|
||||
return structeq(&a->pubkey, &b->pubkey);
|
||||
}
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
|
||||
struct privkey;
|
||||
|
||||
#define PUBKEY_DER_LEN 33
|
||||
|
||||
struct pubkey {
|
||||
/* DER-encoded key (as hashed by bitcoin, for addresses) */
|
||||
u8 der[33];
|
||||
/* Unpacked pubkey (as used by libsecp256k1 internally) */
|
||||
secp256k1_pubkey pubkey;
|
||||
};
|
||||
@@ -18,6 +18,10 @@ struct pubkey {
|
||||
bool pubkey_from_hexstr(secp256k1_context *secpctx,
|
||||
const char *derstr, size_t derlen, struct pubkey *key);
|
||||
|
||||
/* Convert from hex string of DER (scriptPubKey from validateaddress) */
|
||||
char *pubkey_to_hexstr(const tal_t *ctx, secp256k1_context *secpctx,
|
||||
const struct pubkey *key);
|
||||
|
||||
/* Pubkey from privkey */
|
||||
bool pubkey_from_privkey(secp256k1_context *secpctx,
|
||||
const struct privkey *privkey,
|
||||
@@ -28,6 +32,10 @@ bool pubkey_from_privkey(secp256k1_context *secpctx,
|
||||
bool pubkey_from_der(secp256k1_context *secpctx,
|
||||
const u8 *der, size_t len, struct pubkey *key);
|
||||
|
||||
/* Pubkey to DER encoding: must be valid pubkey. */
|
||||
void pubkey_to_der(secp256k1_context *secpctx, u8 der[PUBKEY_DER_LEN],
|
||||
const struct pubkey *key);
|
||||
|
||||
/* Are these keys equal? */
|
||||
bool pubkey_eq(const struct pubkey *a, const struct pubkey *b);
|
||||
#endif /* LIGHTNING_PUBKEY_H */
|
||||
|
||||
@@ -110,14 +110,24 @@ static void add_number(u8 **script, u32 num)
|
||||
}
|
||||
}
|
||||
|
||||
static void add_push_key(u8 **scriptp, const struct pubkey *key)
|
||||
static void add_push_key(u8 **scriptp,
|
||||
secp256k1_context *secpctx,
|
||||
const struct pubkey *key)
|
||||
{
|
||||
add_push_bytes(scriptp, key->der, sizeof(key->der));
|
||||
u8 der[PUBKEY_DER_LEN];
|
||||
pubkey_to_der(secpctx, der, key);
|
||||
|
||||
add_push_bytes(scriptp, der, sizeof(der));
|
||||
}
|
||||
|
||||
static u8 *stack_key(const tal_t *ctx, const struct pubkey *key)
|
||||
static u8 *stack_key(const tal_t *ctx,
|
||||
secp256k1_context *secpctx,
|
||||
const struct pubkey *key)
|
||||
{
|
||||
return tal_dup_arr(ctx, u8, key->der, sizeof(key->der), 0);
|
||||
u8 der[PUBKEY_DER_LEN];
|
||||
pubkey_to_der(secpctx, der, key);
|
||||
|
||||
return tal_dup_arr(ctx, u8, der, sizeof(der), 0);
|
||||
}
|
||||
|
||||
/* Bitcoin wants DER encoding. */
|
||||
@@ -151,26 +161,31 @@ static u8 *stack_number(const tal_t *ctx, unsigned int num)
|
||||
return tal_dup_arr(ctx, u8, &val, 1, 0);
|
||||
}
|
||||
|
||||
/* FIXME: permute? */
|
||||
/* Is a < b? (If equal we don't care) */
|
||||
static bool key_less(const struct pubkey *a, const struct pubkey *b)
|
||||
static bool key_less(secp256k1_context *secpctx,
|
||||
const struct pubkey *a, const struct pubkey *b)
|
||||
{
|
||||
return memcmp(a->der, b->der, sizeof(a->der)) < 0;
|
||||
u8 a_der[PUBKEY_DER_LEN], b_der[PUBKEY_DER_LEN];
|
||||
pubkey_to_der(secpctx, a_der, a);
|
||||
pubkey_to_der(secpctx, b_der, b);
|
||||
|
||||
return memcmp(a_der, b_der, sizeof(a_der)) < 0;
|
||||
}
|
||||
|
||||
/* tal_count() gives the length of the script. */
|
||||
u8 *bitcoin_redeem_2of2(const tal_t *ctx,
|
||||
secp256k1_context *secpctx,
|
||||
const struct pubkey *key1,
|
||||
const struct pubkey *key2)
|
||||
{
|
||||
u8 *script = tal_arr(ctx, u8, 0);
|
||||
add_number(&script, 2);
|
||||
if (key_less(key1, key2)) {
|
||||
add_push_key(&script, key1);
|
||||
add_push_key(&script, key2);
|
||||
if (key_less(secpctx, key1, key2)) {
|
||||
add_push_key(&script, secpctx, key1);
|
||||
add_push_key(&script, secpctx, key2);
|
||||
} else {
|
||||
add_push_key(&script, key2);
|
||||
add_push_key(&script, key1);
|
||||
add_push_key(&script, secpctx, key2);
|
||||
add_push_key(&script, secpctx, key1);
|
||||
}
|
||||
add_number(&script, 2);
|
||||
add_op(&script, OP_CHECKMULTISIG);
|
||||
@@ -178,10 +193,12 @@ u8 *bitcoin_redeem_2of2(const tal_t *ctx,
|
||||
}
|
||||
|
||||
/* tal_count() gives the length of the script. */
|
||||
u8 *bitcoin_redeem_single(const tal_t *ctx, const struct pubkey *key)
|
||||
u8 *bitcoin_redeem_single(const tal_t *ctx,
|
||||
secp256k1_context *secpctx,
|
||||
const struct pubkey *key)
|
||||
{
|
||||
u8 *script = tal_arr(ctx, u8, 0);
|
||||
add_push_key(&script, key);
|
||||
add_push_key(&script, secpctx, key);
|
||||
add_op(&script, OP_CHECKSIG);
|
||||
return script;
|
||||
}
|
||||
@@ -200,15 +217,19 @@ u8 *scriptpubkey_p2sh(const tal_t *ctx, const u8 *redeemscript)
|
||||
}
|
||||
|
||||
/* Create the redeemscript for a P2SH + P2WPKH (for signing tx) */
|
||||
u8 *bitcoin_redeem_p2wpkh(const tal_t *ctx, const struct pubkey *key)
|
||||
u8 *bitcoin_redeem_p2wpkh(const tal_t *ctx,
|
||||
secp256k1_context *secpctx,
|
||||
const struct pubkey *key)
|
||||
{
|
||||
struct ripemd160 keyhash;
|
||||
u8 der[PUBKEY_DER_LEN];
|
||||
u8 *script = tal_arr(ctx, u8, 0);
|
||||
|
||||
/* BIP141: BIP16 redeemScript pushed in the scriptSig is exactly a
|
||||
* push of a version byte plus a push of a witness program. */
|
||||
add_number(&script, 0);
|
||||
hash160(&keyhash, key->der, sizeof(key->der));
|
||||
pubkey_to_der(secpctx, der, key);
|
||||
hash160(&keyhash, der, sizeof(der));
|
||||
add_push_bytes(&script, &keyhash, sizeof(keyhash));
|
||||
return script;
|
||||
}
|
||||
@@ -220,7 +241,7 @@ void bitcoin_witness_p2sh_p2wpkh(const tal_t *ctx,
|
||||
const struct bitcoin_signature *sig,
|
||||
const struct pubkey *key)
|
||||
{
|
||||
u8 *redeemscript = bitcoin_redeem_p2wpkh(ctx, key);
|
||||
u8 *redeemscript = bitcoin_redeem_p2wpkh(ctx, secpctx, key);
|
||||
|
||||
/* BIP141: The scriptSig must be exactly a push of the BIP16 redeemScript
|
||||
* or validation fails. */
|
||||
@@ -233,7 +254,7 @@ void bitcoin_witness_p2sh_p2wpkh(const tal_t *ctx,
|
||||
* a public key. */
|
||||
input->witness = tal_arr(ctx, u8 *, 2);
|
||||
input->witness[0] = stack_sig(input->witness, secpctx, sig);
|
||||
input->witness[1] = stack_key(input->witness, key);
|
||||
input->witness[1] = stack_key(input->witness, secpctx, key);
|
||||
}
|
||||
|
||||
/* Create an output script for a 32-byte witness. */
|
||||
@@ -249,13 +270,17 @@ u8 *scriptpubkey_p2wsh(const tal_t *ctx, const u8 *witnessscript)
|
||||
}
|
||||
|
||||
/* Create an output script for a 20-byte witness. */
|
||||
u8 *scriptpubkey_p2wpkh(const tal_t *ctx, const struct pubkey *key)
|
||||
u8 *scriptpubkey_p2wpkh(const tal_t *ctx,
|
||||
secp256k1_context *secpctx,
|
||||
const struct pubkey *key)
|
||||
{
|
||||
struct ripemd160 h;
|
||||
u8 der[PUBKEY_DER_LEN];
|
||||
u8 *script = tal_arr(ctx, u8, 0);
|
||||
|
||||
add_op(&script, OP_0);
|
||||
hash160(&h, key->der, sizeof(key->der));
|
||||
pubkey_to_der(secpctx, der, key);
|
||||
hash160(&h, der, sizeof(der));
|
||||
add_push_bytes(&script, &h, sizeof(h));
|
||||
return script;
|
||||
}
|
||||
@@ -274,7 +299,7 @@ u8 **bitcoin_witness_2of2(const tal_t *ctx,
|
||||
witness[0] = stack_number(witness, 0);
|
||||
|
||||
/* sig order should match key order. */
|
||||
if (key_less(key1, key2)) {
|
||||
if (key_less(secpctx, key1, key2)) {
|
||||
witness[1] = stack_sig(witness, secpctx, sig1);
|
||||
witness[2] = stack_sig(witness, secpctx, sig2);
|
||||
} else {
|
||||
@@ -282,12 +307,13 @@ u8 **bitcoin_witness_2of2(const tal_t *ctx,
|
||||
witness[2] = stack_sig(witness, secpctx, sig1);
|
||||
}
|
||||
|
||||
witness[3] = bitcoin_redeem_2of2(witness, key1, key2);
|
||||
witness[3] = bitcoin_redeem_2of2(witness, secpctx, key1, key2);
|
||||
return witness;
|
||||
}
|
||||
|
||||
/* Create a script for our HTLC output: sending. */
|
||||
u8 *bitcoin_redeem_htlc_send(const tal_t *ctx,
|
||||
secp256k1_context *secpctx,
|
||||
const struct pubkey *ourkey,
|
||||
const struct pubkey *theirkey,
|
||||
const struct abs_locktime *htlc_abstimeout,
|
||||
@@ -321,7 +347,7 @@ u8 *bitcoin_redeem_htlc_send(const tal_t *ctx,
|
||||
|
||||
/* If either matched... */
|
||||
add_op(&script, OP_IF);
|
||||
add_push_key(&script, theirkey);
|
||||
add_push_key(&script, secpctx, theirkey);
|
||||
|
||||
add_op(&script, OP_ELSE);
|
||||
|
||||
@@ -331,7 +357,7 @@ u8 *bitcoin_redeem_htlc_send(const tal_t *ctx,
|
||||
add_number(&script, locktime->locktime);
|
||||
add_op(&script, OP_CHECKSEQUENCEVERIFY);
|
||||
add_op(&script, OP_2DROP);
|
||||
add_push_key(&script, ourkey);
|
||||
add_push_key(&script, secpctx, ourkey);
|
||||
|
||||
add_op(&script, OP_ENDIF);
|
||||
add_op(&script, OP_CHECKSIG);
|
||||
@@ -341,6 +367,7 @@ u8 *bitcoin_redeem_htlc_send(const tal_t *ctx,
|
||||
|
||||
/* Create a script for our HTLC output: receiving. */
|
||||
u8 *bitcoin_redeem_htlc_recv(const tal_t *ctx,
|
||||
secp256k1_context *secpctx,
|
||||
const struct pubkey *ourkey,
|
||||
const struct pubkey *theirkey,
|
||||
const struct abs_locktime *htlc_abstimeout,
|
||||
@@ -372,7 +399,7 @@ u8 *bitcoin_redeem_htlc_recv(const tal_t *ctx,
|
||||
/* Drop extra hash as well as locktime. */
|
||||
add_op(&script, OP_2DROP);
|
||||
|
||||
add_push_key(&script, ourkey);
|
||||
add_push_key(&script, secpctx, ourkey);
|
||||
|
||||
add_op(&script, OP_ELSE);
|
||||
|
||||
@@ -389,7 +416,7 @@ u8 *bitcoin_redeem_htlc_recv(const tal_t *ctx,
|
||||
add_op(&script, OP_DROP);
|
||||
add_op(&script, OP_ENDIF);
|
||||
|
||||
add_push_key(&script, theirkey);
|
||||
add_push_key(&script, secpctx, theirkey);
|
||||
|
||||
add_op(&script, OP_ENDIF);
|
||||
add_op(&script, OP_CHECKSIG);
|
||||
@@ -398,13 +425,17 @@ u8 *bitcoin_redeem_htlc_recv(const tal_t *ctx,
|
||||
}
|
||||
|
||||
/* Create scriptcode (fake witness, basically) for P2WPKH */
|
||||
u8 *p2wpkh_scriptcode(const tal_t *ctx, const struct pubkey *key)
|
||||
u8 *p2wpkh_scriptcode(const tal_t *ctx,
|
||||
secp256k1_context *secpctx,
|
||||
const struct pubkey *key)
|
||||
{
|
||||
struct sha256 h;
|
||||
struct ripemd160 pkhash;
|
||||
u8 der[PUBKEY_DER_LEN];
|
||||
u8 *script = tal_arr(ctx, u8, 0);
|
||||
|
||||
sha256(&h, key->der, sizeof(key->der));
|
||||
pubkey_to_der(secpctx, der, key);
|
||||
sha256(&h, der, sizeof(der));
|
||||
ripemd160(&pkhash, h.u.u8, sizeof(h));
|
||||
/* BIP143:
|
||||
*
|
||||
@@ -439,6 +470,7 @@ bool is_p2sh(const u8 *script, size_t script_len)
|
||||
/* A common script pattern: A can have it with secret, or B can have
|
||||
* it after delay. */
|
||||
u8 *bitcoin_redeem_secret_or_delay(const tal_t *ctx,
|
||||
secp256k1_context *secpctx,
|
||||
const struct pubkey *delayed_key,
|
||||
const struct rel_locktime *locktime,
|
||||
const struct pubkey *key_if_secret_known,
|
||||
@@ -456,7 +488,7 @@ u8 *bitcoin_redeem_secret_or_delay(const tal_t *ctx,
|
||||
add_op(&script, OP_IF);
|
||||
|
||||
/* They can collect the funds. */
|
||||
add_push_key(&script, key_if_secret_known);
|
||||
add_push_key(&script, secpctx, key_if_secret_known);
|
||||
|
||||
add_op(&script, OP_ELSE);
|
||||
|
||||
@@ -464,7 +496,7 @@ u8 *bitcoin_redeem_secret_or_delay(const tal_t *ctx,
|
||||
add_number(&script, locktime->locktime);
|
||||
add_op(&script, OP_CHECKSEQUENCEVERIFY);
|
||||
add_op(&script, OP_DROP);
|
||||
add_push_key(&script, delayed_key);
|
||||
add_push_key(&script, secpctx, delayed_key);
|
||||
|
||||
add_op(&script, OP_ENDIF);
|
||||
add_op(&script, OP_CHECKSIG);
|
||||
|
||||
@@ -21,15 +21,19 @@ struct bitcoin_signature {
|
||||
|
||||
/* tal_count() gives the length of the script. */
|
||||
u8 *bitcoin_redeem_2of2(const tal_t *ctx,
|
||||
secp256k1_context *secpctx,
|
||||
const struct pubkey *key1,
|
||||
const struct pubkey *key2);
|
||||
|
||||
/* tal_count() gives the length of the script. */
|
||||
u8 *bitcoin_redeem_single(const tal_t *ctx, const struct pubkey *key);
|
||||
u8 *bitcoin_redeem_single(const tal_t *ctx,
|
||||
secp256k1_context *secpctx,
|
||||
const struct pubkey *key);
|
||||
|
||||
/* A common script pattern: A can have it with secret, or B can have
|
||||
* it after delay. */
|
||||
u8 *bitcoin_redeem_secret_or_delay(const tal_t *ctx,
|
||||
secp256k1_context *secpctx,
|
||||
const struct pubkey *delayed_key,
|
||||
const struct rel_locktime *locktime,
|
||||
const struct pubkey *key_if_secret_known,
|
||||
@@ -39,7 +43,9 @@ u8 *bitcoin_redeem_secret_or_delay(const tal_t *ctx,
|
||||
u8 *scriptpubkey_p2sh(const tal_t *ctx, const u8 *redeemscript);
|
||||
|
||||
/* Create the redeemscript for a P2SH + P2WPKH. */
|
||||
u8 *bitcoin_redeem_p2wpkh(const tal_t *ctx, const struct pubkey *key);
|
||||
u8 *bitcoin_redeem_p2wpkh(const tal_t *ctx,
|
||||
secp256k1_context *secpctx,
|
||||
const struct pubkey *key);
|
||||
|
||||
/* Create a witness which spends the 2of2. */
|
||||
void bitcoin_witness_p2sh_p2wpkh(const tal_t *ctx,
|
||||
@@ -49,10 +55,13 @@ void bitcoin_witness_p2sh_p2wpkh(const tal_t *ctx,
|
||||
const struct pubkey *key);
|
||||
|
||||
/* Create scriptcode (fake witness, basically) for P2WPKH */
|
||||
u8 *p2wpkh_scriptcode(const tal_t *ctx, const struct pubkey *key);
|
||||
u8 *p2wpkh_scriptcode(const tal_t *ctx,
|
||||
secp256k1_context *secpctx,
|
||||
const struct pubkey *key);
|
||||
|
||||
/* Create a script for our HTLC output: sending. */
|
||||
u8 *bitcoin_redeem_htlc_send(const tal_t *ctx,
|
||||
secp256k1_context *secpctx,
|
||||
const struct pubkey *ourkey,
|
||||
const struct pubkey *theirkey,
|
||||
const struct abs_locktime *htlc_abstimeout,
|
||||
@@ -62,6 +71,7 @@ u8 *bitcoin_redeem_htlc_send(const tal_t *ctx,
|
||||
|
||||
/* Create a script for our HTLC output: receiving. */
|
||||
u8 *bitcoin_redeem_htlc_recv(const tal_t *ctx,
|
||||
secp256k1_context *secpctx,
|
||||
const struct pubkey *ourkey,
|
||||
const struct pubkey *theirkey,
|
||||
const struct abs_locktime *htlc_abstimeout,
|
||||
@@ -73,7 +83,9 @@ u8 *bitcoin_redeem_htlc_recv(const tal_t *ctx,
|
||||
u8 *scriptpubkey_p2wsh(const tal_t *ctx, const u8 *witnessscript);
|
||||
|
||||
/* Create an output script for a 20-byte witness program. */
|
||||
u8 *scriptpubkey_p2wpkh(const tal_t *ctx, const struct pubkey *key);
|
||||
u8 *scriptpubkey_p2wpkh(const tal_t *ctx,
|
||||
secp256k1_context *secpctx,
|
||||
const struct pubkey *key);
|
||||
|
||||
/* Create a witness which spends the 2of2. */
|
||||
u8 **bitcoin_witness_2of2(const tal_t *ctx,
|
||||
|
||||
13
commit_tx.c
13
commit_tx.c
@@ -11,12 +11,14 @@
|
||||
#include <assert.h>
|
||||
|
||||
static bool add_htlc(struct bitcoin_tx *tx, size_t n,
|
||||
secp256k1_context *secpctx,
|
||||
const struct htlc *h,
|
||||
const struct pubkey *ourkey,
|
||||
const struct pubkey *theirkey,
|
||||
const struct sha256 *rhash,
|
||||
const struct rel_locktime *locktime,
|
||||
u8 *(*scriptpubkeyfn)(const tal_t *,
|
||||
secp256k1_context *,
|
||||
const struct pubkey *,
|
||||
const struct pubkey *,
|
||||
const struct abs_locktime *,
|
||||
@@ -27,7 +29,7 @@ static bool add_htlc(struct bitcoin_tx *tx, size_t n,
|
||||
assert(!tx->output[n].script);
|
||||
|
||||
tx->output[n].script = scriptpubkey_p2wsh(tx,
|
||||
scriptpubkeyfn(tx, ourkey, theirkey,
|
||||
scriptpubkeyfn(tx, secpctx, ourkey, theirkey,
|
||||
&h->expiry, locktime, rhash,
|
||||
&h->rhash));
|
||||
tx->output[n].script_length = tal_count(tx->output[n].script);
|
||||
@@ -36,6 +38,7 @@ static bool add_htlc(struct bitcoin_tx *tx, size_t n,
|
||||
}
|
||||
|
||||
struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
|
||||
secp256k1_context *secpctx,
|
||||
const struct pubkey *our_final,
|
||||
const struct pubkey *their_final,
|
||||
const struct rel_locktime *our_locktime,
|
||||
@@ -77,7 +80,7 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
|
||||
|
||||
/* First output is a P2WSH to a complex redeem script
|
||||
* (usu. for this side) */
|
||||
redeemscript = bitcoin_redeem_secret_or_delay(tx, self,
|
||||
redeemscript = bitcoin_redeem_secret_or_delay(tx, secpctx, self,
|
||||
locktime,
|
||||
other,
|
||||
rhash);
|
||||
@@ -86,7 +89,7 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
|
||||
tx->output[0].amount = cstate->side[side].pay_msat / 1000;
|
||||
|
||||
/* Second output is a P2WPKH payment to other side. */
|
||||
tx->output[1].script = scriptpubkey_p2wpkh(tx, other);
|
||||
tx->output[1].script = scriptpubkey_p2wpkh(tx, secpctx, other);
|
||||
tx->output[1].script_length = tal_count(tx->output[1].script);
|
||||
tx->output[1].amount = cstate->side[!side].pay_msat / 1000;
|
||||
|
||||
@@ -96,7 +99,7 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
|
||||
|
||||
/* HTLCs this side sent. */
|
||||
for (i = 0; i < tal_count(cstate->side[side].htlcs); i++) {
|
||||
if (!add_htlc(tx, num, cstate->side[side].htlcs[i],
|
||||
if (!add_htlc(tx, num, secpctx, cstate->side[side].htlcs[i],
|
||||
self, other, rhash, locktime,
|
||||
bitcoin_redeem_htlc_send))
|
||||
return tal_free(tx);
|
||||
@@ -104,7 +107,7 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
|
||||
}
|
||||
/* HTLCs this side has received. */
|
||||
for (i = 0; i < tal_count(cstate->side[!side].htlcs); i++) {
|
||||
if (!add_htlc(tx, num, cstate->side[!side].htlcs[i],
|
||||
if (!add_htlc(tx, num, secpctx, cstate->side[!side].htlcs[i],
|
||||
self, other, rhash, locktime,
|
||||
bitcoin_redeem_htlc_recv))
|
||||
return tal_free(tx);
|
||||
|
||||
@@ -12,6 +12,7 @@ struct rel_locktime;
|
||||
/* Create commitment tx to spend the anchor tx output; doesn't fill in
|
||||
* input scriptsig. */
|
||||
struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
|
||||
secp256k1_context *secpctx,
|
||||
const struct pubkey *our_final,
|
||||
const struct pubkey *their_final,
|
||||
const struct rel_locktime *our_locktime,
|
||||
|
||||
15
daemon/log.c
15
daemon/log.c
@@ -274,12 +274,13 @@ void log_add(struct log *log, const char *fmt, ...)
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
#define to_string(ctx, structtype, ptr) \
|
||||
to_string_((ctx), stringify(structtype), \
|
||||
#define to_string(ctx, lr, structtype, ptr) \
|
||||
to_string_((ctx), lr, stringify(structtype), \
|
||||
((void)sizeof((ptr) == (structtype *)NULL), \
|
||||
((union loggable_structs)((const structtype *)ptr))))
|
||||
|
||||
static char *to_string_(const tal_t *ctx,
|
||||
struct log_record *lr,
|
||||
const char *structname,
|
||||
union loggable_structs u)
|
||||
{
|
||||
@@ -287,7 +288,7 @@ static char *to_string_(const tal_t *ctx,
|
||||
|
||||
/* GCC checks we're one of these, so we should be. */
|
||||
if (streq(structname, "struct pubkey"))
|
||||
s = tal_hexstr(ctx, u.pubkey->der, sizeof(u.pubkey->der));
|
||||
s = pubkey_to_hexstr(ctx, lr->dstate->secpctx, u.pubkey);
|
||||
else if (streq(structname, "struct sha256_double"))
|
||||
s = tal_hexstr(ctx, u.sha256_double, sizeof(*u.sha256_double));
|
||||
else if (streq(structname, "struct sha256"))
|
||||
@@ -318,11 +319,11 @@ static char *to_string_(const tal_t *ctx,
|
||||
" rval=%s"
|
||||
" src=%s }",
|
||||
h->id, h->msatoshis,
|
||||
to_string(ctx, struct abs_locktime, &h->expiry),
|
||||
to_string(ctx, struct sha256, &h->rhash),
|
||||
to_string(ctx, lr, struct abs_locktime, &h->expiry),
|
||||
to_string(ctx, lr, struct sha256, &h->rhash),
|
||||
h->r ? tal_hexstr(ctx, h->r, sizeof(*h->r))
|
||||
: "UNKNOWN",
|
||||
h->src ? to_string(ctx, struct pubkey,
|
||||
h->src ? to_string(ctx, lr, struct pubkey,
|
||||
&h->src->peer->id)
|
||||
: "local");
|
||||
}
|
||||
@@ -345,7 +346,7 @@ void log_struct_(struct log *log, int level,
|
||||
va_end(ap);
|
||||
|
||||
/* GCC checks we're one of these, so we should be. */
|
||||
s = to_string_(ctx, structname, u);
|
||||
s = to_string_(ctx, log->lr, structname, u);
|
||||
if (!s)
|
||||
fatal("Logging unknown type %s", structname);
|
||||
|
||||
|
||||
@@ -22,20 +22,6 @@
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#define FIXME_STUB(peer) do { log_broken((peer)->dstate->base_log, "%s:%u: Implement %s!", __FILE__, __LINE__, __func__); abort(); } while(0)
|
||||
|
||||
static void dump_tx(const char *str, const struct bitcoin_tx *tx)
|
||||
{
|
||||
u8 *linear = linearize_tx(NULL, tx);
|
||||
printf("%s:%s\n", str, tal_hexstr(linear, linear, tal_count(linear)));
|
||||
tal_free(linear);
|
||||
}
|
||||
|
||||
static void dump_key(const char *str, const struct pubkey *key)
|
||||
{
|
||||
printf("%s:%s\n", str, tal_hexstr(NULL, key->der, sizeof(key->der)));
|
||||
}
|
||||
|
||||
/* Wrap (and own!) member inside Pkt */
|
||||
static Pkt *make_pkt(const tal_t *ctx, Pkt__PktCase type, const void *msg)
|
||||
{
|
||||
@@ -150,8 +136,10 @@ void queue_pkt_open_commit_sig(struct peer *peer)
|
||||
|
||||
open_commit_sig__init(s);
|
||||
|
||||
dump_tx("Creating sig for:", peer->remote.commit->tx);
|
||||
dump_key("Using key:", &peer->local.commitkey);
|
||||
log_debug_struct(peer->log, "Creating sig for %s",
|
||||
struct bitcoin_tx, peer->remote.commit->tx);
|
||||
log_add_struct(peer->log, " using key %s",
|
||||
struct pubkey, &peer->local.commitkey);
|
||||
|
||||
peer->remote.commit->sig = tal(peer->remote.commit,
|
||||
struct bitcoin_signature);
|
||||
@@ -281,7 +269,7 @@ void queue_pkt_commit(struct peer *peer)
|
||||
* changes except unacked fee changes to the remote commitment
|
||||
* before generating `sig`. */
|
||||
ci->cstate = copy_cstate(ci, peer->remote.staging_cstate);
|
||||
ci->tx = create_commit_tx(ci,
|
||||
ci->tx = create_commit_tx(ci, peer->dstate->secpctx,
|
||||
&peer->local.finalkey,
|
||||
&peer->remote.finalkey,
|
||||
&peer->local.locktime,
|
||||
@@ -445,7 +433,8 @@ void queue_pkt_close_clearing(struct peer *peer)
|
||||
CloseClearing *c = tal(peer, CloseClearing);
|
||||
|
||||
close_clearing__init(c);
|
||||
redeemscript = bitcoin_redeem_single(c, &peer->local.finalkey);
|
||||
redeemscript = bitcoin_redeem_single(c, peer->dstate->secpctx,
|
||||
&peer->local.finalkey);
|
||||
peer->closing.our_script = scriptpubkey_p2sh(peer, redeemscript);
|
||||
|
||||
c->scriptpubkey.data = tal_dup_arr(c, u8,
|
||||
@@ -526,7 +515,8 @@ Pkt *accept_pkt_open(struct peer *peer, const Pkt *pkt)
|
||||
|
||||
/* Witness script for anchor. */
|
||||
peer->anchor.witnessscript
|
||||
= bitcoin_redeem_2of2(peer, &peer->local.commitkey,
|
||||
= bitcoin_redeem_2of2(peer, peer->dstate->secpctx,
|
||||
&peer->local.commitkey,
|
||||
&peer->remote.commitkey);
|
||||
return NULL;
|
||||
}
|
||||
@@ -769,7 +759,7 @@ Pkt *accept_pkt_commit(struct peer *peer, const Pkt *pkt)
|
||||
*/
|
||||
/* (We already applied them to staging_cstate as we went) */
|
||||
ci->cstate = copy_cstate(ci, peer->local.staging_cstate);
|
||||
ci->tx = create_commit_tx(ci,
|
||||
ci->tx = create_commit_tx(ci, peer->dstate->secpctx,
|
||||
&peer->local.finalkey,
|
||||
&peer->remote.finalkey,
|
||||
&peer->local.locktime,
|
||||
|
||||
@@ -416,6 +416,7 @@ static void peer_start_clearing(struct peer *peer)
|
||||
/* If they started close, we might not have sent ours. */
|
||||
if (!peer->closing.our_script) {
|
||||
u8 *redeemscript = bitcoin_redeem_single(peer,
|
||||
peer->dstate->secpctx,
|
||||
&peer->local.finalkey);
|
||||
|
||||
peer->closing.our_script = scriptpubkey_p2sh(peer, redeemscript);
|
||||
@@ -586,6 +587,7 @@ static const struct bitcoin_tx *htlc_fulfill_tx(const struct peer *peer,
|
||||
assert(htlc->r);
|
||||
|
||||
wscript = bitcoin_redeem_htlc_recv(peer,
|
||||
peer->dstate->secpctx,
|
||||
&peer->local.finalkey,
|
||||
&peer->remote.finalkey,
|
||||
&htlc->expiry,
|
||||
@@ -602,7 +604,9 @@ static const struct bitcoin_tx *htlc_fulfill_tx(const struct peer *peer,
|
||||
/* Using a new output address here would be useless: they can tell
|
||||
* it's their HTLC, and that we collected it via rval. */
|
||||
tx->output[0].script = scriptpubkey_p2sh(tx,
|
||||
bitcoin_redeem_single(tx, &peer->local.finalkey));
|
||||
bitcoin_redeem_single(tx,
|
||||
peer->dstate->secpctx,
|
||||
&peer->local.finalkey));
|
||||
tx->output[0].script_length = tal_count(tx->output[0].script);
|
||||
|
||||
log_debug(peer->log, "Pre-witness txlen = %zu\n",
|
||||
@@ -1404,6 +1408,7 @@ static const struct bitcoin_tx *htlc_timeout_tx(const struct peer *peer,
|
||||
htlc = htlc_by_index(ci, i);
|
||||
|
||||
wscript = bitcoin_redeem_htlc_send(peer,
|
||||
peer->dstate->secpctx,
|
||||
&peer->local.finalkey,
|
||||
&peer->remote.finalkey,
|
||||
&htlc->expiry,
|
||||
@@ -1422,7 +1427,9 @@ static const struct bitcoin_tx *htlc_timeout_tx(const struct peer *peer,
|
||||
/* Using a new output address here would be useless: they can tell
|
||||
* it's our HTLC, and that we collected it via timeout. */
|
||||
tx->output[0].script = scriptpubkey_p2sh(tx,
|
||||
bitcoin_redeem_single(tx, &peer->local.finalkey));
|
||||
bitcoin_redeem_single(tx,
|
||||
peer->dstate->secpctx,
|
||||
&peer->local.finalkey));
|
||||
tx->output[0].script_length = tal_count(tx->output[0].script);
|
||||
|
||||
log_unusual(peer->log, "Pre-witness txlen = %zu\n",
|
||||
@@ -1550,6 +1557,7 @@ static void resolve_cheating(struct peer *peer)
|
||||
peer->closing_onchain.resolved[0] = steal_tx;
|
||||
wscripts[n++]
|
||||
= bitcoin_redeem_secret_or_delay(wscripts,
|
||||
peer->dstate->secpctx,
|
||||
&peer->remote.finalkey,
|
||||
&peer->local.locktime,
|
||||
&peer->local.finalkey,
|
||||
@@ -1570,6 +1578,7 @@ static void resolve_cheating(struct peer *peer)
|
||||
if (!htlc_is_ours(ci, i)) {
|
||||
wscripts[n]
|
||||
= bitcoin_redeem_htlc_send(wscripts,
|
||||
peer->dstate->secpctx,
|
||||
&peer->remote.finalkey,
|
||||
&peer->local.finalkey,
|
||||
&h->expiry,
|
||||
@@ -1579,6 +1588,7 @@ static void resolve_cheating(struct peer *peer)
|
||||
} else {
|
||||
wscripts[n]
|
||||
= bitcoin_redeem_htlc_recv(wscripts,
|
||||
peer->dstate->secpctx,
|
||||
&peer->remote.finalkey,
|
||||
&peer->local.finalkey,
|
||||
&h->expiry,
|
||||
@@ -2291,14 +2301,12 @@ struct bitcoin_tx *peer_create_close_tx(struct peer *peer, u64 fee)
|
||||
}
|
||||
|
||||
log_debug(peer->log,
|
||||
"creating close-tx with fee %"PRIu64": to %02x%02x%02x%02x/%02x%02x%02x%02x, amounts %u/%u",
|
||||
"creating close-tx with fee %"PRIu64" amounts %u/%u to ",
|
||||
fee,
|
||||
peer->local.finalkey.der[0], peer->local.finalkey.der[1],
|
||||
peer->local.finalkey.der[2], peer->local.finalkey.der[3],
|
||||
peer->remote.finalkey.der[0], peer->remote.finalkey.der[1],
|
||||
peer->remote.finalkey.der[2], peer->remote.finalkey.der[3],
|
||||
cstate.side[OURS].pay_msat / 1000,
|
||||
cstate.side[THEIRS].pay_msat / 1000);
|
||||
log_add_struct(peer->log, "%s", struct pubkey, &peer->local.finalkey);
|
||||
log_add_struct(peer->log, "/%s", struct pubkey, &peer->remote.finalkey);
|
||||
|
||||
return create_close_tx(peer->dstate->secpctx, peer,
|
||||
peer->closing.our_script,
|
||||
@@ -2396,6 +2404,7 @@ const struct bitcoin_tx *bitcoin_spend_ours(struct peer *peer)
|
||||
|
||||
/* The redeemscript for a commit tx is fairly complex. */
|
||||
witnessscript = bitcoin_redeem_secret_or_delay(peer,
|
||||
peer->dstate->secpctx,
|
||||
&peer->local.finalkey,
|
||||
&peer->remote.locktime,
|
||||
&peer->remote.finalkey,
|
||||
@@ -2411,7 +2420,9 @@ const struct bitcoin_tx *bitcoin_spend_ours(struct peer *peer)
|
||||
&commit->output[p2wsh_out].amount);
|
||||
|
||||
tx->output[0].script = scriptpubkey_p2sh(tx,
|
||||
bitcoin_redeem_single(tx, &peer->local.finalkey));
|
||||
bitcoin_redeem_single(tx,
|
||||
peer->dstate->secpctx,
|
||||
&peer->local.finalkey));
|
||||
tx->output[0].script_length = tal_count(tx->output[0].script);
|
||||
|
||||
/* Witness length can vary, due to DER encoding of sigs, but we
|
||||
@@ -2787,6 +2798,7 @@ bool setup_first_commit(struct peer *peer)
|
||||
return false;
|
||||
|
||||
peer->local.commit->tx = create_commit_tx(peer->local.commit,
|
||||
peer->dstate->secpctx,
|
||||
&peer->local.finalkey,
|
||||
&peer->remote.finalkey,
|
||||
&peer->local.locktime,
|
||||
@@ -2800,6 +2812,7 @@ bool setup_first_commit(struct peer *peer)
|
||||
&peer->local.commit->map);
|
||||
|
||||
peer->remote.commit->tx = create_commit_tx(peer->remote.commit,
|
||||
peer->dstate->secpctx,
|
||||
&peer->local.finalkey,
|
||||
&peer->remote.finalkey,
|
||||
&peer->local.locktime,
|
||||
@@ -2830,6 +2843,17 @@ static void json_add_abstime(struct json_result *response,
|
||||
json_object_end(response);
|
||||
}
|
||||
|
||||
static void json_add_pubkey(struct json_result *response,
|
||||
secp256k1_context *secpctx,
|
||||
const char *id,
|
||||
const struct pubkey *key)
|
||||
{
|
||||
u8 der[PUBKEY_DER_LEN];
|
||||
|
||||
pubkey_to_der(secpctx, der, key);
|
||||
json_add_hex(response, id, der, sizeof(der));
|
||||
}
|
||||
|
||||
static void json_add_htlcs(struct json_result *response,
|
||||
const char *id,
|
||||
const struct channel_oneside *side)
|
||||
@@ -2869,8 +2893,8 @@ static void json_getpeers(struct command *cmd,
|
||||
|
||||
/* This is only valid after crypto setup. */
|
||||
if (p->state != STATE_INIT)
|
||||
json_add_hex(response, "peerid",
|
||||
p->id.der, sizeof(p->id.der));
|
||||
json_add_pubkey(response, cmd->dstate->secpctx,
|
||||
"peerid", &p->id);
|
||||
|
||||
json_add_bool(response, "connected", p->conn && !p->fake_close);
|
||||
|
||||
|
||||
@@ -40,12 +40,13 @@ void wallet_add_signed_input(struct lightningd_state *dstate,
|
||||
struct bitcoin_signature sig;
|
||||
assert(input_num < tx->input_count);
|
||||
|
||||
redeemscript = bitcoin_redeem_p2wpkh(tx, &w->pubkey);
|
||||
redeemscript = bitcoin_redeem_p2wpkh(tx, dstate->secpctx, &w->pubkey);
|
||||
|
||||
sig.stype = SIGHASH_ALL;
|
||||
sign_tx_input(dstate->secpctx, tx, input_num,
|
||||
redeemscript, tal_count(redeemscript),
|
||||
p2wpkh_scriptcode(redeemscript, &w->pubkey),
|
||||
p2wpkh_scriptcode(redeemscript, dstate->secpctx,
|
||||
&w->pubkey),
|
||||
&w->privkey,
|
||||
&w->pubkey,
|
||||
&sig.sig);
|
||||
@@ -83,7 +84,8 @@ static void json_newaddr(struct command *cmd,
|
||||
struct sha256 h;
|
||||
|
||||
new_keypair(cmd->dstate, &w->privkey, &w->pubkey);
|
||||
redeemscript = bitcoin_redeem_p2wpkh(cmd, &w->pubkey);
|
||||
redeemscript = bitcoin_redeem_p2wpkh(cmd, cmd->dstate->secpctx,
|
||||
&w->pubkey);
|
||||
sha256(&h, redeemscript, tal_count(redeemscript));
|
||||
ripemd160(&w->p2sh, h.u.u8, sizeof(h));
|
||||
|
||||
|
||||
@@ -48,14 +48,12 @@ BitcoinPubkey *pubkey_to_proto(const tal_t *ctx,
|
||||
const struct pubkey *key)
|
||||
{
|
||||
BitcoinPubkey *p = tal(ctx, BitcoinPubkey);
|
||||
struct pubkey check;
|
||||
|
||||
bitcoin_pubkey__init(p);
|
||||
p->key.len = sizeof(key->der);
|
||||
p->key.data = tal_dup_arr(p, u8, key->der, p->key.len, 0);
|
||||
p->key.len = PUBKEY_DER_LEN;
|
||||
p->key.data = tal_arr(p, u8, p->key.len);
|
||||
|
||||
assert(pubkey_from_der(secpctx, p->key.data, p->key.len, &check));
|
||||
assert(pubkey_eq(&check, key));
|
||||
pubkey_to_der(secpctx, p->key.data, key);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user