core-lightning/lightningd/key_derive.c
Rusty Russell ccff3ac437 lightningd/funding_tx: fill in scriptsigs for p2sh UTXOs.
This is a bit tricky: for our signing code, we don't want scriptsigs,
but to calculate the txid, we need them.  For most transactions in lightning,
they're pure segwit so it doesn't matter, but funding transactions can
have P2SH-wrapped P2WPKH inputs.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-03-07 11:31:55 +10:30

259 lines
8.5 KiB
C

#include <bitcoin/privkey.h>
#include <bitcoin/pubkey.h>
#include <ccan/crypto/sha256/sha256.h>
#include <lightningd/key_derive.h>
#include <utils.h>
#include <wally_bip32.h>
/* BOLT #3:
*
* ### `localkey`, `remotekey`, `local-delayedkey` and `remote-delayedkey` Derivation
*
* These keys are simply generated by addition from their base points:
*
* pubkey = basepoint + SHA256(per-commitment-point || basepoint)*G
*
* The `localkey` uses the local node's `payment-basepoint`, `remotekey`
* uses the remote node's `payment-basepoint`, the `local-delayedkey`
* uses the local node's `delayed-payment-basepoint`, and the
* `remote-delayedkey` uses the remote node's
* `delayed-payment-basepoint`.
*/
bool derive_simple_key(const struct pubkey *basepoint,
const struct pubkey *per_commitment_point,
struct pubkey *key)
{
struct sha256 sha;
unsigned char der_keys[PUBKEY_DER_LEN * 2];
pubkey_to_der(der_keys, per_commitment_point);
pubkey_to_der(der_keys + PUBKEY_DER_LEN, basepoint);
sha256(&sha, der_keys, sizeof(der_keys));
#ifdef SUPERVERBOSE
printf("# SHA256(per-commitment-point || basepoint)\n");
printf("# => SHA256(0x%s || 0x%s)\n",
tal_hexstr(tmpctx, der_keys, PUBKEY_DER_LEN),
tal_hexstr(tmpctx, der_keys + PUBKEY_DER_LEN, PUBKEY_DER_LEN));
printf("# = 0x%s\n",
tal_hexstr(tmpctx, &sha, sizeof(sha)));
#endif
*key = *basepoint;
if (secp256k1_ec_pubkey_tweak_add(secp256k1_ctx,
&key->pubkey, sha.u.u8) != 1)
return false;
#ifdef SUPERVERBOSE
printf("# + basepoint (0x%s)\n",
type_to_string(tmpctx, struct pubkey, basepoint));
printf("# = 0x%s\n",
type_to_string(tmpctx, struct pubkey, key));
#endif
return true;
}
/* BOLT #3:
*
* The corresponding private keys can be derived similarly if the basepoint
* secrets are known (i.e., `localkey` and `local-delayedkey` only):
*
* secretkey = basepoint-secret + SHA256(per-commitment-point || basepoint)
*/
bool derive_simple_privkey(const struct privkey *base_secret,
const struct pubkey *basepoint,
const struct pubkey *per_commitment_point,
struct privkey *key)
{
struct sha256 sha;
unsigned char der_keys[PUBKEY_DER_LEN * 2];
pubkey_to_der(der_keys, per_commitment_point);
pubkey_to_der(der_keys + PUBKEY_DER_LEN, basepoint);
sha256(&sha, der_keys, sizeof(der_keys));
#ifdef SUPERVERBOSE
printf("# SHA256(per-commitment-point || basepoint)\n");
printf("# => SHA256(0x%s || 0x%s)\n",
tal_hexstr(tmpctx, der_keys, PUBKEY_DER_LEN),
tal_hexstr(tmpctx, der_keys + PUBKEY_DER_LEN, PUBKEY_DER_LEN));
printf("# = 0x%s\n", tal_hexstr(tmpctx, &sha, sizeof(sha)));
#endif
*key = *base_secret;
if (secp256k1_ec_privkey_tweak_add(secp256k1_ctx, key->secret,
sha.u.u8) != 1)
return false;
#ifdef SUPERVERBOSE
printf("# + basepoint_secret (0x%s)\n",
tal_hexstr(tmpctx, base_secret, sizeof(*base_secret)));
printf("# = 0x%s\n",
tal_hexstr(tmpctx, key, sizeof(*key)));
#endif
return true;
}
/* BOLT #3:
*
* The revocationkey is a blinded key: the remote node provides the base,
* and the local node provides the blinding factor which it later
* reveals, so the remote node can use the secret revocationkey for a
* penalty transaction.
*
* The `per-commitment-point` is generated using EC multiplication:
*
* per-commitment-point = per-commitment-secret * G
*
* And this is used to derive the revocation key from the remote node's
* `revocation-basepoint`:
*
* revocationkey = revocation-basepoint * SHA256(revocation-basepoint || per-commitment-point) + per-commitment-point*SHA256(per-commitment-point || revocation-basepoint)
*/
bool derive_revocation_key(const struct pubkey *basepoint,
const struct pubkey *per_commitment_point,
struct pubkey *key)
{
struct sha256 sha;
unsigned char der_keys[PUBKEY_DER_LEN * 2];
secp256k1_pubkey add[2];
const secp256k1_pubkey *args[2];
pubkey_to_der(der_keys, basepoint);
pubkey_to_der(der_keys + PUBKEY_DER_LEN, per_commitment_point);
sha256(&sha, der_keys, sizeof(der_keys));
#ifdef SUPERVERBOSE
printf("# SHA256(revocation-basepoint || per-commitment-point)\n");
printf("# => SHA256(0x%s || 0x%s)\n",
tal_hexstr(tmpctx, der_keys, PUBKEY_DER_LEN),
tal_hexstr(tmpctx, der_keys + PUBKEY_DER_LEN, PUBKEY_DER_LEN));
printf("# = 0x%s\n", tal_hexstr(tmpctx, sha.u.u8, sizeof(sha.u.u8))),
#endif
add[0] = basepoint->pubkey;
if (secp256k1_ec_pubkey_tweak_mul(secp256k1_ctx, &add[0], sha.u.u8) != 1)
return false;
#ifdef SUPERVERBOSE
printf("# x revocation-basepoint = 0x%s\n",
type_to_string(tmpctx, secp256k1_pubkey, &add[0]));
#endif
pubkey_to_der(der_keys, per_commitment_point);
pubkey_to_der(der_keys + PUBKEY_DER_LEN, basepoint);
sha256(&sha, der_keys, sizeof(der_keys));
#ifdef SUPERVERBOSE
printf("# SHA256(per-commitment-point || revocation-basepoint)\n");
printf("# => SHA256(0x%s || 0x%s)\n",
tal_hexstr(tmpctx, der_keys, PUBKEY_DER_LEN),
tal_hexstr(tmpctx, der_keys + PUBKEY_DER_LEN, PUBKEY_DER_LEN));
printf("# = 0x%s\n", tal_hexstr(tmpctx, sha.u.u8, sizeof(sha.u.u8))),
#endif
add[1] = per_commitment_point->pubkey;
if (secp256k1_ec_pubkey_tweak_mul(secp256k1_ctx, &add[1], sha.u.u8) != 1)
return false;
#ifdef SUPERVERBOSE
printf("# x per-commitment-point = 0x%s\n",
type_to_string(tmpctx, secp256k1_pubkey, &add[1]));
#endif
args[0] = &add[0];
args[1] = &add[1];
if (secp256k1_ec_pubkey_combine(secp256k1_ctx, &key->pubkey, args, 2)
!= 1)
return false;
#ifdef SUPERVERBOSE
printf("# 0x%s + 0x%s => 0x%s\n",
type_to_string(tmpctx, secp256k1_pubkey, args[0]),
type_to_string(tmpctx, secp256k1_pubkey, args[1]),
type_to_string(tmpctx, struct pubkey, key));
#endif
return true;
}
/* BOLT #3:
*
* The corresponding private key can be derived once the `per-commitment-secret`
* is known:
*
* revocationsecretkey = revocation-basepoint-secret * SHA256(revocation-basepoint || per-commitment-point) + per-commitment-secret*SHA256(per-commitment-point || revocation-basepoint)
*/
bool derive_revocation_privkey(const struct privkey *base_secret,
const struct privkey *per_commitment_secret,
const struct pubkey *basepoint,
const struct pubkey *per_commitment_point,
struct privkey *key)
{
struct sha256 sha;
unsigned char der_keys[PUBKEY_DER_LEN * 2];
struct privkey part2;
pubkey_to_der(der_keys, basepoint);
pubkey_to_der(der_keys + PUBKEY_DER_LEN, per_commitment_point);
sha256(&sha, der_keys, sizeof(der_keys));
#ifdef SUPERVERBOSE
printf("# SHA256(revocation-basepoint || per-commitment-point)\n");
printf("# => SHA256(0x%s || 0x%s)\n",
tal_hexstr(tmpctx, der_keys, PUBKEY_DER_LEN),
tal_hexstr(tmpctx, der_keys + PUBKEY_DER_LEN, PUBKEY_DER_LEN));
printf("# = 0x%s\n", tal_hexstr(tmpctx, sha.u.u8, sizeof(sha.u.u8))),
#endif
*key = *base_secret;
if (secp256k1_ec_privkey_tweak_mul(secp256k1_ctx, key->secret, sha.u.u8)
!= 1)
return false;
#ifdef SUPERVERBOSE
printf("# * revocation-basepoint-secret (0x%s)",
tal_hexstr(tmpctx, base_secret, sizeof(*base_secret))),
printf("# = 0x%s\n", tal_hexstr(tmpctx, key, sizeof(*key))),
#endif
pubkey_to_der(der_keys, per_commitment_point);
pubkey_to_der(der_keys + PUBKEY_DER_LEN, basepoint);
sha256(&sha, der_keys, sizeof(der_keys));
#ifdef SUPERVERBOSE
printf("# SHA256(per-commitment-point || revocation-basepoint)\n");
printf("# => SHA256(0x%s || 0x%s)\n",
tal_hexstr(tmpctx, der_keys, PUBKEY_DER_LEN),
tal_hexstr(tmpctx, der_keys + PUBKEY_DER_LEN, PUBKEY_DER_LEN));
printf("# = 0x%s\n", tal_hexstr(tmpctx, sha.u.u8, sizeof(sha.u.u8))),
#endif
part2 = *per_commitment_secret;
if (secp256k1_ec_privkey_tweak_mul(secp256k1_ctx, part2.secret,
sha.u.u8) != 1)
return false;
#ifdef SUPERVERBOSE
printf("# * per-commitment-secret (0x%s)",
tal_hexstr(tmpctx, per_commitment_secret,
sizeof(*per_commitment_secret))),
printf("# = 0x%s\n", tal_hexstr(tmpctx, &part2, sizeof(part2)));
#endif
if (secp256k1_ec_privkey_tweak_add(secp256k1_ctx, key->secret,
part2.secret) != 1)
return false;
#ifdef SUPERVERBOSE
printf("# => 0x%s\n", tal_hexstr(tmpctx, key, sizeof(*key)));
#endif
return true;
}
bool bip32_pubkey(const struct ext_key *bip32_base,
struct pubkey *pubkey, u32 index)
{
struct ext_key ext;
if (index >= BIP32_INITIAL_HARDENED_CHILD)
return false;
if (bip32_key_from_parent(bip32_base, index,
BIP32_FLAG_KEY_PUBLIC, &ext) != WALLY_OK)
return false;
if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &pubkey->pubkey,
ext.pub_key, sizeof(ext.pub_key)))
return false;
return true;
}