mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 18:11:28 +01:00
ccff3ac437
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>
259 lines
8.5 KiB
C
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;
|
|
}
|