diff --git a/anchor.c b/anchor.c index 90f87693c..8e636c911 100644 --- a/anchor.c +++ b/anchor.c @@ -4,6 +4,7 @@ #include "pkt.h" #include "permute_tx.h" #include "bitcoin_script.h" +#include "pubkey.h" #include struct bitcoin_tx *anchor_tx_create(const tal_t *ctx, @@ -15,6 +16,7 @@ struct bitcoin_tx *anchor_tx_create(const tal_t *ctx, struct bitcoin_tx *tx; u8 *redeemscript; size_t *inmap, *outmap; + struct pubkey key1, key2; if (add_overflows_size_t(o1->anchor->n_inputs, o2->anchor->n_inputs)) return NULL; @@ -49,9 +51,13 @@ struct bitcoin_tx *anchor_tx_create(const tal_t *ctx, if (add_overflows_u64(o1->anchor->total, o2->anchor->total)) return tal_free(tx); + /* Pubkeys both valid, right? */ + if (!proto_to_pubkey(o1->anchor->pubkey, &key1) + || !proto_to_pubkey(o2->anchor->pubkey, &key2)) + return tal_free(tx); + /* Make the 2 of 2 payment for the commitment txs. */ - redeemscript = bitcoin_redeem_2of2(tx, o1->anchor->pubkey, - o2->anchor->pubkey); + redeemscript = bitcoin_redeem_2of2(tx, &key1, &key2); tx->output[0].amount = o1->anchor->total + o2->anchor->total; tx->output[0].script = scriptpubkey_p2sh(tx, redeemscript); tx->output[0].script_length = tal_count(tx->output[0].script); diff --git a/bitcoin_script.c b/bitcoin_script.c index c496b1994..321cad60a 100644 --- a/bitcoin_script.c +++ b/bitcoin_script.c @@ -2,6 +2,7 @@ #include "bitcoin_address.h" #include "pkt.h" #include "signature.h" +#include "pubkey.h" #include #include #include @@ -60,6 +61,11 @@ static void add_push_bytes(u8 **scriptp, const void *mem, size_t len) add(scriptp, mem, len); } +static void add_push_key(u8 **scriptp, const struct pubkey *key) +{ + add_push_bytes(scriptp, key->key, pubkey_len(key)); +} + /* Bitcoin wants DER encoding. */ static void add_push_sig(u8 **scriptp, const struct signature *sig) { @@ -81,39 +87,28 @@ static void add_push_sig(u8 **scriptp, const struct signature *sig) /* FIXME: permute? */ /* Is a < b? (If equal we don't care) */ -static bool key_less(const BitcoinPubkey *a, const BitcoinPubkey *b) +static bool key_less(const struct pubkey *a, const struct pubkey *b) { - size_t len; - int cmp; + /* Shorter one wins. */ + if (pubkey_len(a) != pubkey_len(b)) + return pubkey_len(a) < pubkey_len(b); - if (a->key.len < b->key.len) - len = a->key.len; - else - len = b->key.len; - - cmp = memcmp(a->key.data, b->key.data, len); - if (cmp < 0) - return true; - else if (cmp > 0) - return false; - - /* Corner case: if it's shorter, it's less. */ - return a->key.len < b->key.len; + return memcmp(a->key, b->key, pubkey_len(a)) < 0; } /* tal_count() gives the length of the script. */ u8 *bitcoin_redeem_2of2(const tal_t *ctx, - const BitcoinPubkey *key1, - const BitcoinPubkey *key2) + const struct pubkey *key1, + const struct pubkey *key2) { u8 *script = tal_arr(ctx, u8, 0); add_op(&script, OP_LITERAL(2)); if (key_less(key1, key2)) { - add_push_bytes(&script, key1->key.data, key1->key.len); - add_push_bytes(&script, key2->key.data, key2->key.len); + add_push_key(&script, key1); + add_push_key(&script, key2); } else { - add_push_bytes(&script, key2->key.data, key2->key.len); - add_push_bytes(&script, key1->key.data, key1->key.len); + add_push_key(&script, key2); + add_push_key(&script, key1); } add_op(&script, OP_LITERAL(2)); add_op(&script, OP_CHECKMULTISIG); @@ -121,10 +116,10 @@ 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 u8 *key, size_t keylen) +u8 *bitcoin_redeem_single(const tal_t *ctx, const struct pubkey *key) { u8 *script = tal_arr(ctx, u8, 0); - add_push_bytes(&script, key, keylen); + add_push_key(&script, key); add_op(&script, OP_CHECKSIG); return script; } @@ -193,9 +188,9 @@ bool is_pay_to_pubkey_hash(const ProtobufCBinaryData *script) * mysig and relative locktime passed, OR * theirsig and hash preimage. */ u8 *bitcoin_redeem_revocable(const tal_t *ctx, - const BitcoinPubkey *mykey, + const struct pubkey *mykey, u32 locktime, - const BitcoinPubkey *theirkey, + const struct pubkey *theirkey, const Sha256Hash *revocation_hash) { u8 *script = tal_arr(ctx, u8, 0); @@ -221,7 +216,7 @@ u8 *bitcoin_redeem_revocable(const tal_t *ctx, add_op(&script, OP_HASH160); add_push_bytes(&script, rhash_ripemd, sizeof(rhash_ripemd)); add_op(&script, OP_EQUALVERIFY); - add_push_bytes(&script, theirkey->key.data, theirkey->key.len); + add_push_key(&script, theirkey); add_op(&script, OP_CHECKSIG); /* Otherwise, it should be both our sigs. */ @@ -236,11 +231,11 @@ u8 *bitcoin_redeem_revocable(const tal_t *ctx, add_op(&script, OP_LITERAL(2)); /* This obscures whose key is whose. Probably unnecessary? */ if (key_less(mykey, theirkey)) { - add_push_bytes(&script, mykey->key.data, mykey->key.len); - add_push_bytes(&script, theirkey->key.data, theirkey->key.len); + add_push_key(&script, mykey); + add_push_key(&script, theirkey); } else { - add_push_bytes(&script, theirkey->key.data, theirkey->key.len); - add_push_bytes(&script, mykey->key.data, mykey->key.len); + add_push_key(&script, theirkey); + add_push_key(&script, mykey); } add_op(&script, OP_LITERAL(2)); add_op(&script, OP_CHECKMULTISIG); @@ -250,7 +245,7 @@ u8 *bitcoin_redeem_revocable(const tal_t *ctx, add_op(&script, OP_ELSE); add_push_bytes(&script, &locktime_le, sizeof(locktime_le)); add_op(&script, OP_CHECKSEQUENCEVERIFY); - add_push_bytes(&script, mykey->key.data, mykey->key.len); + add_push_key(&script, mykey); add_op(&script, OP_CHECKSIG); add_op(&script, OP_ENDIF); diff --git a/bitcoin_script.h b/bitcoin_script.h index f71b745d8..2465cc0e9 100644 --- a/bitcoin_script.h +++ b/bitcoin_script.h @@ -5,25 +5,25 @@ #include "lightning.pb-c.h" struct bitcoin_address; -struct bitcoin_compressed_pubkey; +struct pubkey; struct signature; /* tal_count() gives the length of the script. */ u8 *bitcoin_redeem_2of2(const tal_t *ctx, - const BitcoinPubkey *key1, - const BitcoinPubkey *key2); + 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 u8 *key, size_t keylen); +u8 *bitcoin_redeem_single(const tal_t *ctx, const struct pubkey *key); /* One of: * mysig and theirsig, OR * mysig and relative locktime passed, OR * theirsig and hash preimage. */ u8 *bitcoin_redeem_revocable(const tal_t *ctx, - const BitcoinPubkey *mykey, + const struct pubkey *mykey, u32 locktime, - const BitcoinPubkey *theirkey, + const struct pubkey *theirkey, const Sha256Hash *revocation_hash); /* Create an output script using p2sh for this redeem script. */ diff --git a/commit_tx.c b/commit_tx.c index 153f6403f..e5b8ab9c5 100644 --- a/commit_tx.c +++ b/commit_tx.c @@ -3,6 +3,7 @@ #include "bitcoin_tx.h" #include "bitcoin_script.h" #include "permute_tx.h" +#include "pubkey.h" struct bitcoin_tx *create_commit_tx(const tal_t *ctx, OpenChannel *ours, @@ -12,6 +13,7 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx, { struct bitcoin_tx *tx; const u8 *redeemscript; + struct pubkey ourkey, theirkey; /* Now create commitment tx: one input, two outputs. */ tx = bitcoin_tx(ctx, 1, 2); @@ -20,10 +22,15 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx, tx->input[0].txid = *anchor_txid; tx->input[0].index = anchor_output; + if (!proto_to_pubkey(ours->anchor->pubkey, &ourkey)) + return tal_free(tx); + if (!proto_to_pubkey(theirs->anchor->pubkey, &theirkey)) + return tal_free(tx); + /* First output is a P2SH to a complex redeem script (usu. for me) */ - redeemscript = bitcoin_redeem_revocable(tx, ours->anchor->pubkey, + redeemscript = bitcoin_redeem_revocable(tx, &ourkey, ours->locktime_seconds, - theirs->anchor->pubkey, + &theirkey, ours->revocation_hash); tx->output[0].script = scriptpubkey_p2sh(tx, redeemscript); tx->output[0].script_length = tal_count(tx->output[0].script);