From 40165ba6d57e3908d51a9986c2bdefb3374184ae Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Wed, 14 Jun 2017 10:29:10 +0200 Subject: [PATCH] script: Use pkh to construct p2pkh output scripts So far we always needed to know the public key, which was not the case for addresses that we don't own. Moving the hashing outside of the script construction allows us to send to arbitrary addresses. I also added the hash computation to the pubkey primitives. --- bitcoin/pubkey.c | 10 ++++++++++ bitcoin/pubkey.h | 7 +++++++ bitcoin/script.c | 6 ++---- bitcoin/script.h | 2 +- lightningd/test/run-funding_tx.c | 5 ++++- 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/bitcoin/pubkey.c b/bitcoin/pubkey.c index 499814b92..122e6bca5 100644 --- a/bitcoin/pubkey.c +++ b/bitcoin/pubkey.c @@ -99,3 +99,13 @@ static char *privkey_to_hexstr(const tal_t *ctx, const struct privkey *secret) } REGISTER_TYPE_TO_STRING(privkey, privkey_to_hexstr); REGISTER_TYPE_TO_HEXSTR(secret); + +void pubkey_to_hash160(const struct pubkey *pk, struct ripemd160 *hash) +{ + u8 der[PUBKEY_DER_LEN]; + struct sha256 h; + + pubkey_to_der(der, pk); + sha256(&h, der, sizeof(der)); + ripemd160(hash, h.u.u8, sizeof(h)); +} diff --git a/bitcoin/pubkey.h b/bitcoin/pubkey.h index af8bfe9b0..7b830d195 100644 --- a/bitcoin/pubkey.h +++ b/bitcoin/pubkey.h @@ -1,6 +1,8 @@ #ifndef LIGHTNING_BITCOIN_PUBKEY_H #define LIGHTNING_BITCOIN_PUBKEY_H #include "config.h" +#include +#include #include #include #include @@ -38,4 +40,9 @@ bool pubkey_eq(const struct pubkey *a, const struct pubkey *b); /* Compare the keys `a` and `b`. Return <0 if `a`<`b`, 0 if equal and >0 otherwise */ int pubkey_cmp(const struct pubkey *a, const struct pubkey *b); + +/** + * pubkey_to_hash160 - Get the hash for p2pkh payments for a given pubkey + */ +void pubkey_to_hash160(const struct pubkey *pk, struct ripemd160 *hash); #endif /* LIGHTNING_PUBKEY_H */ diff --git a/bitcoin/script.c b/bitcoin/script.c index 0d08507cb..d190dd1e3 100644 --- a/bitcoin/script.c +++ b/bitcoin/script.c @@ -212,15 +212,13 @@ u8 *scriptpubkey_p2sh(const tal_t *ctx, const u8 *redeemscript) } /* Create an output script using p2pkh */ -u8 *scriptpubkey_p2pkh(const tal_t *ctx, const struct pubkey *pubkey) +u8 *scriptpubkey_p2pkh(const tal_t *ctx, const struct bitcoin_address *addr) { - struct bitcoin_address addr; u8 *script = tal_arr(ctx, u8, 0); - hash160_key(&addr.addr, pubkey); add_op(&script, OP_DUP); add_op(&script, OP_HASH160); - add_push_bytes(&script, &addr.addr, sizeof(addr.addr)); + add_push_bytes(&script, &addr->addr, sizeof(addr->addr)); add_op(&script, OP_EQUALVERIFY); add_op(&script, OP_CHECKSIG); return script; diff --git a/bitcoin/script.h b/bitcoin/script.h index f29cde442..378389685 100644 --- a/bitcoin/script.h +++ b/bitcoin/script.h @@ -35,7 +35,7 @@ u8 *bitcoin_redeem_secret_or_delay(const tal_t *ctx, u8 *scriptpubkey_p2sh(const tal_t *ctx, const u8 *redeemscript); /* Create an output script using p2pkh */ -u8 *scriptpubkey_p2pkh(const tal_t *ctx, const struct pubkey *pubkey); +u8 *scriptpubkey_p2pkh(const tal_t *ctx, const struct bitcoin_address *addr); /* Create an input script which spends p2pkh */ u8 *bitcoin_redeem_p2pkh(const tal_t *ctx, const struct pubkey *pubkey, diff --git a/lightningd/test/run-funding_tx.c b/lightningd/test/run-funding_tx.c index 4143c4508..8a761b6fc 100644 --- a/lightningd/test/run-funding_tx.c +++ b/lightningd/test/run-funding_tx.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -52,6 +53,7 @@ int main(void) u16 funding_outnum; u8 *subscript; secp256k1_ecdsa_signature sig; + struct bitcoin_address addr; secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN); @@ -118,7 +120,8 @@ int main(void) printf("funding output: %u\n", funding_outnum); - subscript = scriptpubkey_p2pkh(funding, &inputkey); + pubkey_to_hash160(&inputkey, &addr.addr); + subscript = scriptpubkey_p2pkh(funding, &addr); sign_tx_input(funding, 0, subscript, NULL, &input_privkey, &inputkey, &sig);