Browse Source

struct secret: use everywhere.

We alternated between using a sha256 and using a privkey, but there are
numerous places where we have a random 32 bytes which are neither.

This fixes many of them (plus, struct privkey is now defined in terms of
struct secret).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 8 years ago
parent
commit
b99c5620ef
  1. 6
      bitcoin/base58.c
  2. 7
      bitcoin/privkey.h
  3. 3
      bitcoin/pubkey.c
  4. 2
      bitcoin/signature.c
  5. 2
      daemon/lightningd.h
  6. 7
      daemon/peer.c
  7. 24
      daemon/secrets.c
  8. 2
      daemon/sphinx.c
  9. 3
      daemon/wallet.c
  10. 5
      lightningd/channel/channel.c
  11. 2
      lightningd/channel/channel_wire.csv
  12. 36
      lightningd/cryptomsg.c
  13. 6
      lightningd/cryptomsg.h
  14. 6
      lightningd/derive_basepoints.c
  15. 6
      lightningd/derive_basepoints.h
  16. 2
      lightningd/dev_newhtlc.c
  17. 50
      lightningd/handshake/handshake.c
  18. 22
      lightningd/handshake/test/run-handshake.c
  19. 2
      lightningd/hsm/client.c
  20. 4
      lightningd/hsm/client.h
  21. 24
      lightningd/hsm/hsm.c
  22. 4
      lightningd/hsm/hsm_client_wire_csv
  23. 4
      lightningd/hsm/hsm_wire.csv
  24. 4
      lightningd/htlc_end.h
  25. 23
      lightningd/key_derive.c
  26. 7
      lightningd/key_derive.h
  27. 2
      lightningd/lightningd.h
  28. 2
      lightningd/pay.c
  29. 13
      lightningd/peer_control.c
  30. 22
      lightningd/sphinx.c
  31. 11
      lightningd/sphinx.h
  32. 70
      lightningd/test/run-commit_tx.c
  33. 16
      lightningd/test/run-cryptomsg.c
  34. 23
      lightningd/test/run-key_derive.c
  35. 26
      test/test_sphinx.c
  36. 1
      type_to_string.h
  37. 7
      wire/fromwire.c
  38. 7
      wire/towire.c
  39. 2
      wire/wire.h

6
bitcoin/base58.c

@ -114,7 +114,7 @@ char *key_to_base58(const tal_t *ctx, bool test_net, const struct privkey *key)
u8 version = test_net ? 239 : 128;
size_t outlen = sizeof(out);
memcpy(buf, key->secret, sizeof(key->secret));
memcpy(buf, key->secret.data, sizeof(key->secret.data));
/* Mark this as a compressed key. */
buf[32] = 1;
@ -148,9 +148,9 @@ bool key_from_base58(const char *base58, size_t base58_len,
return false;
/* Copy out secret. */
memcpy(priv->secret, keybuf + 1, sizeof(priv->secret));
memcpy(priv->secret.data, keybuf + 1, sizeof(priv->secret.data));
if (!secp256k1_ec_seckey_verify(secp256k1_ctx, priv->secret))
if (!secp256k1_ec_seckey_verify(secp256k1_ctx, priv->secret.data))
return false;
/* Get public key, too. */

7
bitcoin/privkey.h

@ -3,8 +3,13 @@
#include "config.h"
#include <ccan/short_types/short_types.h>
/* General 256-bit secret, which must be private. Used in various places. */
struct secret {
u8 data[32];
};
/* This is a private key. Keep it secret. */
struct privkey {
u8 secret[32];
struct secret secret;
};
#endif /* LIGHTNING_BITCOIN_PRIVKEY_H */

3
bitcoin/pubkey.c

@ -34,7 +34,7 @@ bool pubkey_from_privkey(const struct privkey *privkey,
struct pubkey *key)
{
if (!secp256k1_ec_pubkey_create(secp256k1_ctx,
&key->pubkey, privkey->secret))
&key->pubkey, privkey->secret.data))
return false;
return true;
}
@ -98,3 +98,4 @@ static char *privkey_to_hexstr(const tal_t *ctx, const struct privkey *secret)
return str;
}
REGISTER_TYPE_TO_STRING(privkey, privkey_to_hexstr);
REGISTER_TYPE_TO_HEXSTR(secret);

2
bitcoin/signature.c

@ -83,7 +83,7 @@ void sign_hash(const struct privkey *privkey,
ok = secp256k1_ecdsa_sign(secp256k1_ctx,
s,
h->sha.u.u8,
privkey->secret, NULL, NULL);
privkey->secret.data, NULL, NULL);
assert(ok);
}

2
daemon/lightningd.h

@ -99,7 +99,7 @@ struct lightningd_state {
struct list_head pay_commands;
/* Our private key */
struct secret *secret;
struct privkey *privkey;
/* This is us. */
struct pubkey id;

7
daemon/peer.c

@ -878,7 +878,6 @@ static void their_htlc_added(struct peer *peer, struct htlc *htlc,
struct peer *only_dest)
{
struct invoice *invoice;
struct privkey pk;
struct onionpacket *packet;
struct route_step *step = NULL;
@ -909,15 +908,13 @@ static void their_htlc_added(struct peer *peer, struct htlc *htlc,
return;
}
//FIXME: dirty trick to retrieve unexported state
memcpy(&pk, peer->dstate->secret, sizeof(pk));
packet = parse_onionpacket(peer,
htlc->routing, tal_count(htlc->routing));
if (packet) {
u8 shared_secret[32];
if (onion_shared_secret(shared_secret, packet, &pk))
if (onion_shared_secret(shared_secret, packet,
peer->dstate->privkey))
step = process_onionpacket(packet, packet,
shared_secret,
htlc->rhash.u.u8,

24
daemon/secrets.c

@ -22,18 +22,13 @@
#include <sys/types.h>
#include <unistd.h>
struct secret {
/* Secret ID of our node; public is dstate->id. */
struct privkey privkey;
};
void privkey_sign(struct lightningd_state *dstate, const void *src, size_t len,
secp256k1_ecdsa_signature *sig)
{
struct sha256_double h;
sha256_double(&h, memcheck(src, len), len);
sign_hash(&dstate->secret->privkey, &h, sig);
sign_hash(dstate->privkey, &h, sig);
}
struct peer_secrets {
@ -142,7 +137,8 @@ static void new_keypair(struct lightningd_state *dstate,
struct privkey *privkey, struct pubkey *pubkey)
{
do {
randombytes_buf(privkey->secret, sizeof(privkey->secret));
randombytes_buf(privkey->secret.data,
sizeof(privkey->secret.data));
} while (!pubkey_from_privkey(privkey, pubkey));
}
@ -215,7 +211,7 @@ void secrets_init(struct lightningd_state *dstate)
{
int fd;
dstate->secret = tal(dstate, struct secret);
dstate->privkey = tal(dstate, struct privkey);
fd = open("privkey", O_RDONLY);
if (fd < 0) {
@ -223,14 +219,14 @@ void secrets_init(struct lightningd_state *dstate)
fatal("Failed to open privkey: %s", strerror(errno));
log_unusual(dstate->base_log, "Creating privkey file");
new_keypair(dstate, &dstate->secret->privkey, &dstate->id);
new_keypair(dstate, dstate->privkey, &dstate->id);
fd = open("privkey", O_CREAT|O_EXCL|O_WRONLY, 0400);
if (fd < 0)
fatal("Failed to create privkey file: %s",
strerror(errno));
if (!write_all(fd, dstate->secret->privkey.secret,
sizeof(dstate->secret->privkey.secret))) {
if (!write_all(fd, &dstate->privkey->secret,
sizeof(dstate->privkey->secret))) {
unlink_noerr("privkey");
fatal("Failed to write to privkey file: %s",
strerror(errno));
@ -244,11 +240,11 @@ void secrets_init(struct lightningd_state *dstate)
if (fd < 0)
fatal("Failed to reopen privkey: %s", strerror(errno));
}
if (!read_all(fd, dstate->secret->privkey.secret,
sizeof(dstate->secret->privkey.secret)))
if (!read_all(fd, &dstate->privkey->secret,
sizeof(dstate->privkey->secret)))
fatal("Failed to read privkey: %s", strerror(errno));
close(fd);
if (!pubkey_from_privkey(&dstate->secret->privkey, &dstate->id))
if (!pubkey_from_privkey(dstate->privkey, &dstate->id))
fatal("Invalid privkey");
log_info_struct(dstate->base_log, "ID: %s", struct pubkey, &dstate->id);

2
daemon/sphinx.c

@ -260,7 +260,7 @@ bool onion_shared_secret(
const struct privkey *privkey)
{
return create_shared_secret(secret, &packet->ephemeralkey,
privkey->secret);
privkey->secret.data);
}
void pubkey_hash160(

3
daemon/wallet.c

@ -45,7 +45,8 @@ bool restore_wallet_address(struct lightningd_state *dstate,
static void new_keypair(struct privkey *privkey, struct pubkey *pubkey)
{
do {
randombytes_buf(privkey->secret, sizeof(privkey->secret));
randombytes_buf(privkey->secret.data,
sizeof(privkey->secret.data));
} while (!pubkey_from_privkey(privkey, pubkey));
}

5
lightningd/channel/channel.c

@ -595,7 +595,8 @@ static void their_htlc_locked(const struct htlc *htlc, struct peer *peer)
u8 *msg;
struct onionpacket *op;
struct route_step *rs;
struct sha256 ss, bad_onion_sha;
struct sha256 bad_onion_sha;
struct secret ss;
enum onion_type failcode;
enum channel_remove_err rerr;
struct pubkey ephemeral;
@ -625,7 +626,7 @@ static void their_htlc_locked(const struct htlc *htlc, struct peer *peer)
goto bad_onion;
}
rs = process_onionpacket(tmpctx, op, ss.u.u8, htlc->rhash.u.u8,
rs = process_onionpacket(tmpctx, op, ss.data, htlc->rhash.u.u8,
sizeof(htlc->rhash));
if (!rs) {
failcode = WIRE_INVALID_ONION_HMAC;

2
lightningd/channel/channel_wire.csv

@ -88,7 +88,7 @@ channel_accepted_htlc,0,forward,bool
channel_accepted_htlc,0,amt_to_forward,u64
channel_accepted_htlc,0,outgoing_cltv_value,u32
channel_accepted_htlc,0,next_channel,struct short_channel_id
channel_accepted_htlc,0,shared_secret,32
channel_accepted_htlc,0,shared_secret,struct secret
# FIXME: Add code to commit current channel state!

Can't render this file because it has a wrong number of fields in line 2.

36
lightningd/cryptomsg.c

@ -14,9 +14,9 @@
#include <wire/wire.h>
#include <wire/wire_io.h>
static void hkdf_two_keys(struct sha256 *out1, struct sha256 *out2,
const struct sha256 *in1,
const struct sha256 *in2)
static void hkdf_two_keys(struct secret *out1, struct secret *out2,
const struct secret *in1,
const struct secret *in2)
{
/* BOLT #8:
*
@ -26,7 +26,7 @@ static void hkdf_two_keys(struct sha256 *out1, struct sha256 *out2,
* of cryptographic randomness using the extract-and-expand
* component of the `HKDF`.
*/
struct sha256 okm[2];
struct secret okm[2];
BUILD_ASSERT(sizeof(okm) == 64);
hkdf_sha256(okm, sizeof(okm), in1, sizeof(*in1), in2, sizeof(*in2),
@ -35,9 +35,9 @@ static void hkdf_two_keys(struct sha256 *out1, struct sha256 *out2,
*out2 = okm[1];
}
static void maybe_rotate_key(u64 *n, struct sha256 *k, struct sha256 *ck)
static void maybe_rotate_key(u64 *n, struct secret *k, struct secret *ck)
{
struct sha256 new_k, new_ck;
struct secret new_k, new_ck;
/* BOLT #8:
*
@ -113,7 +113,7 @@ u8 *cryptomsg_decrypt_body(const tal_t *ctx,
memcheck(in, inlen),
inlen,
NULL, 0,
npub, cs->rk.u.u8) != 0) {
npub, cs->rk.data) != 0) {
/* FIXME: Report error! */
return tal_free(decrypted);
}
@ -176,7 +176,7 @@ bool cryptomsg_decrypt_header(struct crypto_state *cs, u8 hdr[18], u16 *lenp)
&mlen, NULL,
memcheck(hdr, 18), 18,
NULL, 0,
npub, cs->rk.u.u8) != 0) {
npub, cs->rk.data) != 0) {
/* FIXME: Report error! */
return false;
}
@ -275,7 +275,7 @@ u8 *cryptomsg_encrypt_msg(const tal_t *ctx,
sizeof(l),
NULL, 0,
NULL, npub,
cs->sk.u.u8);
cs->sk.data);
assert(ret == 0);
assert(clen == sizeof(l) + 16);
#ifdef SUPERVERBOSE
@ -300,7 +300,7 @@ u8 *cryptomsg_encrypt_msg(const tal_t *ctx,
mlen,
NULL, 0,
NULL, npub,
cs->sk.u.u8);
cs->sk.data);
assert(ret == 0);
assert(clen == mlen + 16);
#ifdef SUPERVERBOSE
@ -346,18 +346,18 @@ void towire_crypto_state(u8 **ptr, const struct crypto_state *cs)
{
towire_u64(ptr, cs->rn);
towire_u64(ptr, cs->sn);
towire_sha256(ptr, &cs->sk);
towire_sha256(ptr, &cs->rk);
towire_sha256(ptr, &cs->s_ck);
towire_sha256(ptr, &cs->r_ck);
towire_secret(ptr, &cs->sk);
towire_secret(ptr, &cs->rk);
towire_secret(ptr, &cs->s_ck);
towire_secret(ptr, &cs->r_ck);
}
void fromwire_crypto_state(const u8 **ptr, size_t *max, struct crypto_state *cs)
{
cs->rn = fromwire_u64(ptr, max);
cs->sn = fromwire_u64(ptr, max);
fromwire_sha256(ptr, max, &cs->sk);
fromwire_sha256(ptr, max, &cs->rk);
fromwire_sha256(ptr, max, &cs->s_ck);
fromwire_sha256(ptr, max, &cs->r_ck);
fromwire_secret(ptr, max, &cs->sk);
fromwire_secret(ptr, max, &cs->rk);
fromwire_secret(ptr, max, &cs->s_ck);
fromwire_secret(ptr, max, &cs->r_ck);
}

6
lightningd/cryptomsg.h

@ -1,7 +1,7 @@
#ifndef LIGHTNING_LIGHTNINGD_CRYPTOMSG_H
#define LIGHTNING_LIGHTNINGD_CRYPTOMSG_H
#include "config.h"
#include <ccan/crypto/sha256/sha256.h>
#include <bitcoin/privkey.h>
#include <ccan/short_types/short_types.h>
#include <ccan/tal/tal.h>
@ -12,9 +12,9 @@ struct crypto_state {
/* Received and sent nonces. */
u64 rn, sn;
/* Sending and receiving keys. */
struct sha256 sk, rk;
struct secret sk, rk;
/* Chaining key for re-keying */
struct sha256 s_ck, r_ck;
struct secret s_ck, r_ck;
};
struct peer_crypto_state {

6
lightningd/derive_basepoints.c

@ -23,9 +23,9 @@ bool derive_basepoints(const struct privkey *seed,
"c-lightning", strlen("c-lightning"));
secrets->funding_privkey = keys.f;
secrets->revocation_basepoint_secret = keys.r;
secrets->payment_basepoint_secret = keys.p;
secrets->delayed_payment_basepoint_secret = keys.d;
secrets->revocation_basepoint_secret = keys.r.secret;
secrets->payment_basepoint_secret = keys.p.secret;
secrets->delayed_payment_basepoint_secret = keys.d.secret;
if (!pubkey_from_privkey(&keys.f, funding_pubkey)
|| !pubkey_from_privkey(&keys.r, &basepoints->revocation)

6
lightningd/derive_basepoints.h

@ -14,9 +14,9 @@ struct basepoints {
struct secrets {
struct privkey funding_privkey;
struct privkey revocation_basepoint_secret;
struct privkey payment_basepoint_secret;
struct privkey delayed_payment_basepoint_secret;
struct secret revocation_basepoint_secret;
struct secret payment_basepoint_secret;
struct secret delayed_payment_basepoint_secret;
};
bool derive_basepoints(const struct privkey *seed,

2
lightningd/dev_newhtlc.c

@ -62,7 +62,7 @@ static void json_dev_newhtlc(struct command *cmd,
u8 *onion;
struct htlc_end *hend;
struct pubkey *path = tal_arrz(cmd, struct pubkey, 1);
struct sha256 *shared_secrets;
struct secret *shared_secrets;
if (!json_get_params(buffer, params,
"peerid", &peeridtok,

50
lightningd/handshake/handshake.c

@ -25,12 +25,6 @@
#define REQ_FD STDIN_FILENO
/* Representing chacha keys and ecdh results we derive them from;
* even though it's not really an SHA */
struct secret {
struct sha256 s;
};
/* BOLT #8:
*
* * `generateKey()`
@ -51,9 +45,9 @@ static struct keypair generate_key(void)
struct keypair k;
do {
randombytes_buf(k.priv.secret, sizeof(k.priv.secret));
randombytes_buf(k.priv.secret.data, sizeof(k.priv.secret.data));
} while (!secp256k1_ec_pubkey_create(secp256k1_ctx,
&k.pub.pubkey, k.priv.secret));
&k.pub.pubkey, k.priv.secret.data));
return k;
}
@ -181,7 +175,7 @@ static void encrypt_ad(const struct secret *k, u64 nonce,
memcheck(plaintext, plaintext_len),
plaintext_len,
additional_data, additional_data_len,
NULL, npub, k->s.u.u8);
NULL, npub, k->data);
assert(ret == 0);
assert(clen == plaintext_len + crypto_aead_chacha20poly1305_ietf_ABYTES);
}
@ -213,7 +207,7 @@ static bool decrypt(const struct secret *k, u64 nonce,
memcheck(ciphertext, ciphertext_len),
ciphertext_len,
additional_data, additional_data_len,
npub, k->s.u.u8) != 0)
npub, k->data) != 0)
return false;
assert(mlen == ciphertext_len - crypto_aead_chacha20poly1305_ietf_ABYTES);
@ -337,10 +331,10 @@ static void act_one_initiator(struct handshake *h, int fd,
* * The initiator performs a `ECDH` between its newly generated
* ephemeral key with the remote node's static public key.
*/
if (!secp256k1_ecdh(secp256k1_ctx, h->ss.s.u.u8,
&their_id->pubkey, h->e.priv.secret))
if (!secp256k1_ecdh(secp256k1_ctx, h->ss.data,
&their_id->pubkey, h->e.priv.secret.data))
status_failed(WIRE_INITR_ACT1_BAD_ECDH_FOR_SS, "%s", "");
status_trace("# ss=0x%s", tal_hexstr(trc, &h->ss.s, sizeof(h->ss.s)));
status_trace("# ss=0x%s", tal_hexstr(trc, h->ss.data, sizeof(h->ss.data)));
/* BOLT #8:
*
@ -442,7 +436,7 @@ static void act_one_responder(struct handshake *h, int fd, struct pubkey *re)
* * The responder performs an `ECDH` between its static public
* key and the initiator's ephemeral public key.
*/
if (!hsm_do_ecdh(&h->ss.s, re))
if (!hsm_do_ecdh(&h->ss, re))
status_failed(WIRE_RESPR_ACT1_BAD_HSM_ECDH,
"re=%s",
type_to_string(trc, struct pubkey, re));
@ -547,12 +541,12 @@ static void act_two_responder(struct handshake *h, int fd,
* * where `re` is the ephemeral key of the initiator which was
* received during `ActOne`.
*/
if (!secp256k1_ecdh(secp256k1_ctx, h->ss.s.u.u8, &re->pubkey,
h->e.priv.secret))
if (!secp256k1_ecdh(secp256k1_ctx, h->ss.data, &re->pubkey,
h->e.priv.secret.data))
status_failed(WIRE_RESPR_ACT2_BAD_ECDH_FOR_SS, "re=%s e.priv=%s",
type_to_string(trc, struct pubkey, re),
tal_hexstr(trc, &h->e.priv, sizeof(h->e.priv)));
status_trace("# ss=0x%s", tal_hexstr(trc, &h->ss.s, sizeof(h->ss.s)));
status_trace("# ss=0x%s", tal_hexstr(trc, &h->ss, sizeof(h->ss)));
/* BOLT #8:
*
@ -652,8 +646,8 @@ static void act_two_initiator(struct handshake *h, int fd, struct pubkey *re)
*
* * `ss = ECDH(re, e.priv)`
*/
if (!secp256k1_ecdh(secp256k1_ctx, h->ss.s.u.u8, &re->pubkey,
h->e.priv.secret))
if (!secp256k1_ecdh(secp256k1_ctx, h->ss.data, &re->pubkey,
h->e.priv.secret.data))
status_failed(WIRE_INITR_ACT2_BAD_ECDH_FOR_SS, "re=%s e.priv=%s",
type_to_string(trc, struct pubkey, re),
tal_hexstr(trc, &h->e.priv, sizeof(h->e.priv)));
@ -757,7 +751,7 @@ static void act_three_initiator(struct handshake *h, int fd,
* * where `re` is the ephemeral public key of the responder.
*
*/
if (!hsm_do_ecdh(&h->ss.s, re))
if (!hsm_do_ecdh(&h->ss, re))
status_failed(WIRE_INITR_ACT3_BAD_HSM_ECDH,
"re=%s",
type_to_string(trc, struct pubkey, re));
@ -862,8 +856,8 @@ static void act_three_responder(struct handshake *h, int fd,
* * `ss = ECDH(rs, e.priv)`
* * where `e` is the responder's original ephemeral key
*/
if (!secp256k1_ecdh(secp256k1_ctx, h->ss.s.u.u8, &their_id->pubkey,
h->e.priv.secret))
if (!secp256k1_ecdh(secp256k1_ctx, h->ss.data, &their_id->pubkey,
h->e.priv.secret.data))
status_failed(WIRE_RESPR_ACT3_BAD_ECDH_FOR_SS, "rs=%s e.priv=%s",
type_to_string(trc, struct pubkey, their_id),
tal_hexstr(trc, &h->e.priv, sizeof(h->e.priv)));
@ -990,9 +984,9 @@ int main(int argc, char *argv[])
if (fromwire_handshake_responder(msg, NULL, &my_id)) {
responder(clientfd, &my_id, &their_id, &ck, &sk, &rk);
cs.rn = cs.sn = 0;
cs.sk = sk.s;
cs.rk = rk.s;
cs.r_ck = cs.s_ck = ck.s;
cs.sk = sk;
cs.rk = rk;
cs.r_ck = cs.s_ck = ck;
wire_sync_write(REQ_FD,
towire_handshake_responder_reply(msg,
&their_id,
@ -1001,9 +995,9 @@ int main(int argc, char *argv[])
&their_id)) {
initiator(clientfd, &my_id, &their_id, &ck, &sk, &rk);
cs.rn = cs.sn = 0;
cs.sk = sk.s;
cs.rk = rk.s;
cs.r_ck = cs.s_ck = ck.s;
cs.sk = sk;
cs.rk = rk;
cs.r_ck = cs.s_ck = ck;
wire_sync_write(REQ_FD,
towire_handshake_initiator_reply(msg, &cs));
} else

22
lightningd/handshake/test/run-handshake.c

@ -61,10 +61,10 @@ void hsm_setup(int fd)
{
}
bool hsm_do_ecdh(struct sha256 *ss, const struct pubkey *point)
bool hsm_do_ecdh(struct secret *ss, const struct pubkey *point)
{
return secp256k1_ecdh(secp256k1_ctx, ss->u.u8, &point->pubkey,
privkey.secret) == 1;
return secp256k1_ecdh(secp256k1_ctx, ss->data, &point->pubkey,
privkey.secret.data) == 1;
}
int main(void)
@ -80,11 +80,11 @@ int main(void)
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
| SECP256K1_CONTEXT_SIGN);
memset(responder_privkey.secret, 0x21,
sizeof(responder_privkey.secret));
memset(responder_privkey.secret.data, 0x21,
sizeof(responder_privkey.secret.data));
if (!secp256k1_ec_pubkey_create(secp256k1_ctx,
&responder_id.pubkey,
responder_privkey.secret))
responder_privkey.secret.data))
errx(1, "Keygen failed");
if (pipe(fds1) != 0 || pipe(fds2) != 0)
@ -104,7 +104,7 @@ int main(void)
privkey = responder_privkey;
status_prefix = "RESPR";
status_trace("ls.priv: 0x%s",
tal_hexstr(trc, responder_privkey.secret,
tal_hexstr(trc, &responder_privkey,
sizeof(responder_privkey)));
status_trace("ls.pub: 0x%s",
type_to_string(trc, struct pubkey, &responder_id));
@ -125,19 +125,19 @@ int main(void)
close(fds2[1]);
close(fds1[0]);
memset(initiator_privkey.secret, 0x11,
sizeof(initiator_privkey.secret));
memset(initiator_privkey.secret.data, 0x11,
sizeof(initiator_privkey.secret.data));
memset(e_priv, 0x12, sizeof(e_priv));
if (!secp256k1_ec_pubkey_create(secp256k1_ctx,
&initiator_id.pubkey,
initiator_privkey.secret))
initiator_privkey.secret.data))
errx(1, "Initiator keygen failed");
privkey = initiator_privkey;
status_prefix = "INITR";
status_trace("rs.pub: 0x%s",
type_to_string(trc, struct pubkey, &responder_id));
status_trace("ls.priv: 0x%s",
tal_hexstr(trc, initiator_privkey.secret,
tal_hexstr(trc, &initiator_privkey,
sizeof(initiator_privkey)));
status_trace("ls.pub: 0x%s",
type_to_string(trc, struct pubkey, &initiator_id));

2
lightningd/hsm/client.c

@ -9,7 +9,7 @@ void hsm_setup(int fd)
hsm_fd = fd;
}
bool hsm_do_ecdh(struct sha256 *ss, const struct pubkey *point)
bool hsm_do_ecdh(struct secret *ss, const struct pubkey *point)
{
u8 *req = towire_hsm_ecdh_req(NULL, point), *resp;
size_t len;

4
lightningd/hsm/client.h

@ -7,11 +7,11 @@
#include <stdbool.h>
struct pubkey;
struct sha256;
struct secret;
/* Setup communication to the HSM */
void hsm_setup(int fd);
/* Do ECDH using this node id secret. */
bool hsm_do_ecdh(struct sha256 *ss, const struct pubkey *point);
bool hsm_do_ecdh(struct secret *ss, const struct pubkey *point);
#endif /* LIGHTNING_LIGHTNINGD_HSM_H */

24
lightningd/hsm/hsm.c

@ -37,7 +37,7 @@
/* Nobody will ever find it here! */
static struct {
struct privkey hsm_secret;
struct secret hsm_secret;
struct ext_key bip32;
} secretstuff;
@ -49,26 +49,26 @@ struct client {
struct io_plan *(*handle)(struct io_conn *, struct daemon_conn *);
};
static void node_key(struct privkey *node_secret, struct pubkey *node_id)
static void node_key(struct privkey *node_privkey, struct pubkey *node_id)
{
u32 salt = 0;
struct privkey unused_s;
struct pubkey unused_k;
if (node_secret == NULL)
node_secret = &unused_s;
if (node_privkey == NULL)
node_privkey = &unused_s;
else if (node_id == NULL)
node_id = &unused_k;
do {
hkdf_sha256(node_secret, sizeof(*node_secret),
hkdf_sha256(node_privkey, sizeof(*node_privkey),
&salt, sizeof(salt),
&secretstuff.hsm_secret,
sizeof(secretstuff.hsm_secret),
"nodeid", 6);
salt++;
} while (!secp256k1_ec_pubkey_create(secp256k1_ctx, &node_id->pubkey,
node_secret->secret));
node_privkey->secret.data));
}
static struct client *new_client(struct daemon_conn *master,
@ -95,7 +95,7 @@ static struct io_plan *handle_ecdh(struct io_conn *conn, struct daemon_conn *dc)
struct client *c = container_of(dc, struct client, dc);
struct privkey privkey;
struct pubkey point;
struct sha256 ss;
struct secret ss;
if (!fromwire_hsm_ecdh_req(dc->msg_in, NULL, &point)) {
daemon_conn_send(c->master,
@ -106,8 +106,8 @@ static struct io_plan *handle_ecdh(struct io_conn *conn, struct daemon_conn *dc)
}
node_key(&privkey, NULL);
if (secp256k1_ecdh(secp256k1_ctx, ss.u.u8, &point.pubkey,
privkey.secret) != 1) {
if (secp256k1_ecdh(secp256k1_ctx, ss.data, &point.pubkey,
privkey.secret.data) != 1) {
status_trace("secp256k1_ecdh fail for client %"PRIu64, c->id);
daemon_conn_send(c->master,
take(towire_hsmstatus_client_bad_request(c,
@ -238,7 +238,7 @@ static struct io_plan *handle_channeld(struct io_conn *conn,
static void send_init_response(struct daemon_conn *master)
{
struct pubkey node_id;
struct privkey peer_seed;
struct secret peer_seed;
u8 *serialized_extkey = tal_arr(master, u8, BIP32_SERIALIZED_LEN), *msg;
hkdf_sha256(&peer_seed, sizeof(peer_seed), NULL, 0,
@ -343,9 +343,9 @@ static void bitcoin_keypair(struct privkey *privkey,
"BIP32 of %u failed", index);
/* libwally says: The private key with prefix byte 0 */
memcpy(privkey->secret, ext.priv_key+1, 32);
memcpy(privkey->secret.data, ext.priv_key+1, 32);
if (!secp256k1_ec_pubkey_create(secp256k1_ctx, &pubkey->pubkey,
privkey->secret))
privkey->secret.data))
status_failed(WIRE_HSMSTATUS_KEY_FAILED,
"BIP32 pubkey %u create failed", index);
}

4
lightningd/hsm/hsm_client_wire_csv

@ -1,8 +1,8 @@
# Give me ECDH(node-id-secret,point)
hsm_ecdh_req,1
hsm_ecdh_req,0,point,33
hsm_ecdh_req,0,point,struct pubkey
hsm_ecdh_resp,100
hsm_ecdh_resp,0,ss,32
hsm_ecdh_resp,0,ss,struct secret
hsm_cannouncement_sig_req,2
hsm_cannouncement_sig_req,0,bitcoin_id,struct pubkey

4
lightningd/hsm/hsm_wire.csv

@ -17,7 +17,7 @@ hsmctl_init,0,new,bool
hsmctl_init_reply,101
hsmctl_init_reply,0,node_id,33
hsmctl_init_reply,33,peer_seed,struct privkey
hsmctl_init_reply,33,peer_seed,struct secret
hsmctl_init_reply,65,bip32_len,2
hsmctl_init_reply,67,bip32_seed,bip32_len*u8
@ -49,4 +49,4 @@ hsmctl_hsmfd_channeld,5
hsmctl_hsmfd_channeld,0,unique_id,8
# Empty reply, just an fd
hsmctl_hsmfd_channeld_reply,105
hsmctl_hsmfd_channeld_reply,105

Can't render this file because it has a wrong number of fields in line 2.

4
lightningd/htlc_end.h

@ -31,11 +31,11 @@ struct htlc_end {
/* If we are forwarding, remember the shared secret for an
* eventual reply */
struct sha256 *shared_secret;
struct secret *shared_secret;
/* If we are the origin, remember all shared secrets, so we
* can unwrap an eventual reply */
struct sha256 *path_secrets;
struct secret *path_secrets;
};
static inline const struct htlc_end *keyof_htlc_end(const struct htlc_end *e)

23
lightningd/key_derive.c

@ -58,7 +58,7 @@ bool derive_simple_key(const struct pubkey *basepoint,
*
* secretkey = basepoint-secret + SHA256(per-commitment-point || basepoint)
*/
bool derive_simple_privkey(const struct privkey *base_secret,
bool derive_simple_privkey(const struct secret *base_secret,
const struct pubkey *basepoint,
const struct pubkey *per_commitment_point,
struct privkey *key)
@ -77,8 +77,8 @@ bool derive_simple_privkey(const struct privkey *base_secret,
printf("# = 0x%s\n", tal_hexstr(tmpctx, &sha, sizeof(sha)));
#endif
*key = *base_secret;
if (secp256k1_ec_privkey_tweak_add(secp256k1_ctx, key->secret,
key->secret = *base_secret;
if (secp256k1_ec_privkey_tweak_add(secp256k1_ctx, key->secret.data,
sha.u.u8) != 1)
return false;
#ifdef SUPERVERBOSE
@ -175,15 +175,15 @@ bool derive_revocation_key(const struct pubkey *basepoint,
*
* 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,
bool derive_revocation_privkey(const struct secret *base_secret,
const struct secret *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;
struct secret part2;
pubkey_to_der(der_keys, basepoint);
pubkey_to_der(der_keys + PUBKEY_DER_LEN, per_commitment_point);
@ -196,8 +196,9 @@ bool derive_revocation_privkey(const struct privkey *base_secret,
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)
key->secret = *base_secret;
if (secp256k1_ec_privkey_tweak_mul(secp256k1_ctx, key->secret.data,
sha.u.u8)
!= 1)
return false;
#ifdef SUPERVERBOSE
@ -218,7 +219,7 @@ bool derive_revocation_privkey(const struct privkey *base_secret,
#endif
part2 = *per_commitment_secret;
if (secp256k1_ec_privkey_tweak_mul(secp256k1_ctx, part2.secret,
if (secp256k1_ec_privkey_tweak_mul(secp256k1_ctx, part2.data,
sha.u.u8) != 1)
return false;
#ifdef SUPERVERBOSE
@ -228,8 +229,8 @@ bool derive_revocation_privkey(const struct privkey *base_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)
if (secp256k1_ec_privkey_tweak_add(secp256k1_ctx, key->secret.data,
part2.data) != 1)
return false;
#ifdef SUPERVERBOSE

7
lightningd/key_derive.h

@ -3,13 +3,14 @@
#include "config.h"
struct pubkey;
struct secret;
/* For `localkey`, `remotekey`, `local-delayedkey` and `remote-delayedkey` */
bool derive_simple_key(const struct pubkey *basepoint,
const struct pubkey *per_commitment_point,
struct pubkey *key);
bool derive_simple_privkey(const struct privkey *base_secret,
bool derive_simple_privkey(const struct secret *base_secret,
const struct pubkey *basepoint,
const struct pubkey *per_commitment_point,
struct privkey *key);
@ -19,8 +20,8 @@ bool derive_revocation_key(const struct pubkey *basepoint,
const struct pubkey *per_commitment_point,
struct pubkey *key);
bool derive_revocation_privkey(const struct privkey *base_secret,
const struct privkey *per_commitment_secret,
bool derive_revocation_privkey(const struct secret *base_secret,
const struct secret *per_commitment_secret,
const struct pubkey *basepoint,
const struct pubkey *per_commitment_point,
struct privkey *key);

2
lightningd/lightningd.h

@ -33,7 +33,7 @@ struct lightningd {
/* All peers we're tracking. */
struct list_head peers;
/* FIXME: This should stay in HSM */
struct privkey peer_seed;
struct secret peer_seed;
/* Used to give a unique seed to every peer. */
u64 peer_counter;

2
lightningd/pay.c

@ -163,7 +163,7 @@ static void json_sendpay(struct command *cmd,
u64 amount, lastamount;
struct onionpacket *packet;
u8 *msg;
struct sha256 *path_secrets;
struct secret *path_secrets;
if (!json_get_params(buffer, params,
"route", &routetok,

13
lightningd/peer_control.c

@ -641,12 +641,12 @@ struct decoding_htlc {
u32 cltv_expiry;
struct sha256 payment_hash;
u8 onion[TOTAL_PACKET_SIZE];
u8 shared_secret[32];
struct secret shared_secret;
};
static void fail_htlc(struct peer *peer, struct htlc_end *hend, const u8 *msg)
{
u8 *reply = wrap_onionreply(hend, hend->shared_secret->u.u8, msg);
u8 *reply = wrap_onionreply(hend, hend->shared_secret, msg);
subd_send_msg(peer->owner,
take(towire_channel_fail_htlc(peer, hend->htlc_id, reply)));
if (taken(msg))
@ -660,7 +660,7 @@ static void fail_local_htlc(struct peer *peer, struct htlc_end *hend, const u8 *
log_broken(peer->log, "failed htlc %"PRIu64" code 0x%04x (%s)",
hend->htlc_id, failcode, onion_type_name(failcode));
reply = create_onionreply(hend, hend->shared_secret->u.u8, msg);
reply = create_onionreply(hend, hend->shared_secret, msg);
fail_htlc(peer, hend, reply);
}
@ -1088,7 +1088,7 @@ static int peer_accepted_htlc(struct peer *peer, const u8 *msg)
u8 *req;
hend = tal(msg, struct htlc_end);
hend->shared_secret = tal(hend, struct sha256);
hend->shared_secret = tal(hend, struct secret);
if (!fromwire_channel_accepted_htlc(msg, NULL,
&hend->htlc_id, &hend->msatoshis,
&hend->cltv_expiry, &hend->payment_hash,
@ -1179,10 +1179,9 @@ static int peer_failed_htlc(struct peer *peer, const u8 *msg)
reason);
} else {
size_t numhops = tal_count(hend->path_secrets);
u8 **shared_secrets = tal_arr(hend, u8*, numhops);
struct secret *shared_secrets = tal_arr(hend, struct secret, numhops);
for (size_t i=0; i<numhops; i++) {
shared_secrets[i] = tal_arr(hend, u8, 32);
memcpy(shared_secrets[i], hend->path_secrets[i].u.u8, 32);
shared_secrets[i] = hend->path_secrets[i];
}
reply = unwrap_onionreply(msg, shared_secrets, numhops, reason);
failcode = fromwire_peektype(reply->msg);

22
lightningd/sphinx.c

@ -233,7 +233,7 @@ bool onion_shared_secret(
const struct privkey *privkey)
{
return create_shared_secret(secret, &packet->ephemeralkey,
privkey->secret);
privkey->secret.data);
}
void pubkey_hash160(
@ -363,7 +363,7 @@ struct onionpacket *create_onionpacket(
const u8 *sessionkey,
const u8 *assocdata,
const size_t assocdatalen,
struct sha256 **path_secrets
struct secret **path_secrets
)
{
struct onionpacket *packet = talz(ctx, struct onionpacket);
@ -373,7 +373,7 @@ struct onionpacket *create_onionpacket(
u8 nexthmac[SECURITY_PARAMETER];
u8 stream[ROUTING_INFO_SIZE];
struct hop_params *params = generate_hop_params(ctx, sessionkey, path);
struct sha256 *secrets = tal_arr(ctx, struct sha256, num_hops);
struct secret *secrets = tal_arr(ctx, struct secret, num_hops);
if (!params)
return NULL;
@ -470,7 +470,7 @@ struct route_step *process_onionpacket(
return step;
}
u8 *create_onionreply(const tal_t *ctx, const u8 *shared_secret,
u8 *create_onionreply(const tal_t *ctx, const struct secret *shared_secret,
const u8 *failure_msg)
{
size_t msglen = tal_len(failure_msg);
@ -485,7 +485,7 @@ u8 *create_onionreply(const tal_t *ctx, const u8 *shared_secret,
towire_pad(&payload, padlen);
assert(tal_len(payload) == ONION_REPLY_SIZE + 4);
generate_key(key, "um", 2, shared_secret);
generate_key(key, "um", 2, shared_secret->data);
compute_hmac(hmac, payload, tal_len(payload), key, KEY_LEN);
towire(&reply, hmac, sizeof(hmac));
@ -495,19 +495,21 @@ u8 *create_onionreply(const tal_t *ctx, const u8 *shared_secret,
return reply;
}
u8 *wrap_onionreply(const tal_t *ctx, const u8 *shared_secret, const u8 *reply)
u8 *wrap_onionreply(const tal_t *ctx,
const struct secret *shared_secret, const u8 *reply)
{
u8 key[KEY_LEN];
size_t streamlen = tal_len(reply);
u8 stream[streamlen];
u8 *result = tal_arr(ctx, u8, streamlen);
generate_key(key, "ammag", 5, shared_secret);
generate_key(key, "ammag", 5, shared_secret->data);
generate_cipher_stream(stream, key, streamlen);
xorbytes(result, stream, reply, streamlen);
return result;
}
struct onionreply *unwrap_onionreply(const tal_t *ctx, u8 **shared_secrets,
struct onionreply *unwrap_onionreply(const tal_t *ctx,
const struct secret *shared_secrets,
const int numhops, const u8 *reply)
{
tal_t *tmpctx = tal_tmpctx(ctx);
@ -528,11 +530,11 @@ struct onionreply *unwrap_onionreply(const tal_t *ctx, u8 **shared_secrets,
for (int i = 0; i < numhops; i++) {
/* Since the encryption is just XORing with the cipher
* stream encryption is identical to decryption */
msg = wrap_onionreply(tmpctx, shared_secrets[i], msg);
msg = wrap_onionreply(tmpctx, &shared_secrets[i], msg);
/* Check if the HMAC matches, this means that this is
* the origin */
generate_key(key, "um", 2, shared_secrets[i]);
generate_key(key, "um", 2, shared_secrets[i].data);
compute_hmac(hmac, msg + sizeof(hmac),
tal_len(msg) - sizeof(hmac), key, KEY_LEN);
if (memcmp(hmac, msg, sizeof(hmac)) == 0) {

11
lightningd/sphinx.h

@ -87,7 +87,7 @@ struct onionpacket *create_onionpacket(
const u8 * sessionkey,
const u8 *assocdata,
const size_t assocdatalen,
struct sha256 **path_secrets
struct secret **path_secrets
);
/**
@ -162,7 +162,8 @@ struct onionreply {
* HMAC
* @failure_msg: message (must support tal_len)
*/
u8 *create_onionreply(const tal_t *ctx, const u8 *shared_secret, const u8 *failure_msg);
u8 *create_onionreply(const tal_t *ctx, const struct secret *shared_secret,
const u8 *failure_msg);
/**
* wrap_onionreply - Add another encryption layer to the reply.
@ -172,7 +173,8 @@ u8 *create_onionreply(const tal_t *ctx, const u8 *shared_secret, const u8 *failu
* encryption.
* @reply: the reply to wrap
*/
u8 *wrap_onionreply(const tal_t *ctx, const u8 *shared_secret, const u8 *reply);
u8 *wrap_onionreply(const tal_t *ctx, const struct secret *shared_secret,
const u8 *reply);
/**
* unwrap_onionreply - Remove layers, check integrity and parse reply
@ -182,7 +184,8 @@ u8 *wrap_onionreply(const tal_t *ctx, const u8 *shared_secret, const u8 *reply);
* @numhops: path length and number of shared_secrets provided
* @reply: the incoming reply
*/
struct onionreply *unwrap_onionreply(const tal_t *ctx, u8 **shared_secrets,
struct onionreply *unwrap_onionreply(const tal_t *ctx,
const struct secret *shared_secrets,
const int numhops, const u8 *reply);
#endif /* LIGHTNING_DAEMON_SPHINX_H */

70
lightningd/test/run-commit_tx.c

@ -41,9 +41,9 @@ static struct sha256_double txid_from_hex(const char *hex)
return sha256;
}
static struct privkey privkey_from_hex(const char *hex)
static struct secret secret_from_hex(const char *hex)
{
struct privkey pk;
struct secret s;
size_t len;
if (strstarts(hex, "0x"))
hex += 2;
@ -56,9 +56,17 @@ static struct privkey privkey_from_hex(const char *hex)
*/
if (len == 66 && strends(hex, "01"))
len -= 2;
if (!hex_decode(hex, len, &pk, sizeof(pk)))
if (!hex_decode(hex, len, &s, sizeof(s)))
abort();
return pk;
return s;
}
static bool pubkey_from_secret(const struct secret *secret,
struct pubkey *key)
{
return secp256k1_ec_pubkey_create(secp256k1_ctx,
&key->pubkey,
secret->data);
}
static void tx_must_be_eq(const struct bitcoin_tx *a,
@ -420,10 +428,10 @@ int main(void)
u16 to_self_delay;
/* x_ prefix means internal vars we used to derive spec */
struct privkey local_funding_privkey, x_remote_funding_privkey;
struct privkey x_local_payment_basepoint_secret, x_remote_payment_basepoint_secret;
struct privkey x_local_per_commitment_secret;
struct privkey x_local_delayed_payment_basepoint_secret;
struct privkey x_remote_revocation_basepoint_secret;
struct secret x_local_payment_basepoint_secret, x_remote_payment_basepoint_secret;
struct secret x_local_per_commitment_secret;
struct secret x_local_delayed_payment_basepoint_secret;
struct secret x_remote_revocation_basepoint_secret;
struct privkey local_secretkey, x_remote_secretkey;
struct privkey x_local_delayed_secretkey;
struct pubkey local_funding_pubkey, remote_funding_pubkey;
@ -503,61 +511,61 @@ int main(void)
* # From local_delayed_payment_basepoint_secret, local_per_commitment_point and local_delayed_payment_basepoint
* INTERNAL: local_delayed_secretkey: adf3464ce9c2f230fd2582fda4c6965e4993ca5524e8c9580e3df0cf226981ad01
*/
local_funding_privkey = privkey_from_hex("30ff4956bbdd3222d44cc5e8a1261dab1e07957bdac5ae88fe3261ef321f374901");
x_remote_funding_privkey = privkey_from_hex("1552dfba4f6cf29a62a0af13c8d6981d36d0ef8d61ba10fb0fe90da7634d7e1301");
local_funding_privkey.secret = secret_from_hex("30ff4956bbdd3222d44cc5e8a1261dab1e07957bdac5ae88fe3261ef321f374901");
x_remote_funding_privkey.secret = secret_from_hex("1552dfba4f6cf29a62a0af13c8d6981d36d0ef8d61ba10fb0fe90da7634d7e1301");
SUPERVERBOSE("INTERNAL: remote_funding_privkey: %s01\n",
type_to_string(tmpctx, struct privkey,
&x_remote_funding_privkey));
x_local_payment_basepoint_secret = privkey_from_hex("1111111111111111111111111111111111111111111111111111111111111111");
x_local_payment_basepoint_secret = secret_from_hex("1111111111111111111111111111111111111111111111111111111111111111");
SUPERVERBOSE("INTERNAL: local_payment_basepoint_secret: %s\n",
type_to_string(tmpctx, struct privkey,
type_to_string(tmpctx, struct secret,
&x_local_payment_basepoint_secret));
x_remote_revocation_basepoint_secret = privkey_from_hex("2222222222222222222222222222222222222222222222222222222222222222");
x_remote_revocation_basepoint_secret = secret_from_hex("2222222222222222222222222222222222222222222222222222222222222222");
SUPERVERBOSE("INTERNAL: remote_revocation_basepoint_secret: %s\n",
type_to_string(tmpctx, struct privkey,
type_to_string(tmpctx, struct secret,
&x_remote_revocation_basepoint_secret));
x_local_delayed_payment_basepoint_secret = privkey_from_hex("3333333333333333333333333333333333333333333333333333333333333333");
x_local_delayed_payment_basepoint_secret = secret_from_hex("3333333333333333333333333333333333333333333333333333333333333333");
SUPERVERBOSE("INTERNAL: local_delayed_payment_basepoint_secret: %s\n",
type_to_string(tmpctx, struct privkey,
type_to_string(tmpctx, struct secret,
&x_local_delayed_payment_basepoint_secret));
x_remote_payment_basepoint_secret = privkey_from_hex("4444444444444444444444444444444444444444444444444444444444444444");
x_remote_payment_basepoint_secret = secret_from_hex("4444444444444444444444444444444444444444444444444444444444444444");
SUPERVERBOSE("INTERNAL: remote_payment_basepoint_secret: %s\n",
type_to_string(tmpctx, struct privkey,
type_to_string(tmpctx, struct secret,
&x_remote_payment_basepoint_secret));
x_local_per_commitment_secret = privkey_from_hex("0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100");
x_local_per_commitment_secret = secret_from_hex("0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100");
SUPERVERBOSE("x_local_per_commitment_secret: %s\n",
type_to_string(tmpctx, struct privkey,
type_to_string(tmpctx, struct secret,
&x_local_per_commitment_secret));
if (!pubkey_from_privkey(&x_remote_revocation_basepoint_secret,
&x_remote_revocation_basepoint))
abort();
if (!pubkey_from_secret(&x_remote_revocation_basepoint_secret,
&x_remote_revocation_basepoint))
abort();
SUPERVERBOSE("# From remote_revocation_basepoint_secret\n"
"INTERNAL: remote_revocation_basepoint: %s\n",
type_to_string(tmpctx, struct pubkey,
&x_remote_revocation_basepoint));
if (!pubkey_from_privkey(&x_local_delayed_payment_basepoint_secret,
&x_local_delayed_payment_basepoint))
if (!pubkey_from_secret(&x_local_delayed_payment_basepoint_secret,
&x_local_delayed_payment_basepoint))
abort();
SUPERVERBOSE("# From local_delayed_payment_basepoint_secret\n"
"INTERNAL: local_delayed_payment_basepoint: %s\n",
type_to_string(tmpctx, struct pubkey,
&x_local_delayed_payment_basepoint));
if (!pubkey_from_privkey(&x_local_per_commitment_secret,
&x_local_per_commitment_point))
if (!pubkey_from_secret(&x_local_per_commitment_secret,
&x_local_per_commitment_point))
abort();
SUPERVERBOSE("INTERNAL: local_per_commitment_point: %s\n",
type_to_string(tmpctx, struct pubkey,
&x_local_per_commitment_point));
if (!pubkey_from_privkey(&x_local_payment_basepoint_secret,
&local_payment_basepoint))
if (!pubkey_from_secret(&x_local_payment_basepoint_secret,
&local_payment_basepoint))
abort();
if (!pubkey_from_privkey(&x_remote_payment_basepoint_secret,
&remote_payment_basepoint))
if (!pubkey_from_secret(&x_remote_payment_basepoint_secret,
&remote_payment_basepoint))
abort();
if (!derive_simple_privkey(&x_remote_payment_basepoint_secret,

16
lightningd/test/run-cryptomsg.c

@ -59,20 +59,20 @@ static struct io_plan *check_msg_read(struct io_conn *conn, struct peer *peer,
return NULL;
}
static struct sha256 sha256_from_hex(const char *hex)
static struct secret secret_from_hex(const char *hex)
{
struct sha256 sha256;
struct secret secret;
hex += 2;
if (!hex_decode(hex, strlen(hex), &sha256, sizeof(sha256)))
if (!hex_decode(hex, strlen(hex), &secret, sizeof(secret)))
abort();
return sha256;
return secret;
}
int main(void)
{
tal_t *tmpctx = tal_tmpctx(NULL);
struct peer_crypto_state cs_out, cs_in;
struct sha256 sk, rk, ck;
struct secret sk, rk, ck;
const void *msg = tal_dup_arr(tmpctx, char, "hello", 5, 0);
size_t i;
@ -89,9 +89,9 @@ int main(void)
* # HKDF(0x919219dbb2920afa8db80f9a51787a840bcf111ed8d588caf9ab4be716e42b01,zero)
* output: sk,rk=0x969ab31b4d288cedf6218839b27a3e2140827047f2c0f01bf5c04435d43511a9,0xbb9020b8965f4df047e07f955f3c4b88418984aadc5cdb35096b9ea8fa5c3442
*/
ck = sha256_from_hex("0x919219dbb2920afa8db80f9a51787a840bcf111ed8d588caf9ab4be716e42b01");
sk = sha256_from_hex("0x969ab31b4d288cedf6218839b27a3e2140827047f2c0f01bf5c04435d43511a9");
rk = sha256_from_hex("0xbb9020b8965f4df047e07f955f3c4b88418984aadc5cdb35096b9ea8fa5c3442");
ck = secret_from_hex("0x919219dbb2920afa8db80f9a51787a840bcf111ed8d588caf9ab4be716e42b01");
sk = secret_from_hex("0x969ab31b4d288cedf6218839b27a3e2140827047f2c0f01bf5c04435d43511a9");
rk = secret_from_hex("0xbb9020b8965f4df047e07f955f3c4b88418984aadc5cdb35096b9ea8fa5c3442");
cs_out.cs.sn = cs_out.cs.rn = cs_in.cs.sn = cs_in.cs.rn = 0;
cs_out.cs.sk = cs_in.cs.rk = sk;

23
lightningd/test/run-key_derive.c

@ -10,35 +10,40 @@ static void *tmpctx;
#include <stdio.h>
#include <type_to_string.h>
static struct privkey privkey_from_hex(const char *hex)
static struct secret secret_from_hex(const char *hex)
{
struct privkey privkey;
struct secret s;
hex += 2;
if (!hex_decode(hex, strlen(hex), &privkey, sizeof(privkey)))
if (!hex_decode(hex, strlen(hex), &s, sizeof(s)))
abort();
return privkey;
return s;
}
int main(void)
{
struct privkey base_secret, per_commitment_secret, privkey;
struct privkey privkey;
struct secret base_secret, per_commitment_secret;
struct pubkey base_point, per_commitment_point, pubkey, pubkey2;
tmpctx = tal_tmpctx(NULL);
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
| SECP256K1_CONTEXT_SIGN);
base_secret = privkey_from_hex("0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f");
per_commitment_secret = privkey_from_hex("0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100");
base_secret = secret_from_hex("0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f");
per_commitment_secret = secret_from_hex("0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100");
printf("base_secret: 0x%s\n",
tal_hexstr(tmpctx, &base_secret, sizeof(base_secret)));
printf("per_commitment_secret: 0x%s\n",
tal_hexstr(tmpctx, &per_commitment_secret,
sizeof(per_commitment_secret)));
if (!pubkey_from_privkey(&per_commitment_secret, &per_commitment_point))
if (!secp256k1_ec_pubkey_create(secp256k1_ctx,
&per_commitment_point.pubkey,
per_commitment_secret.data))
abort();
if (!pubkey_from_privkey(&base_secret, &base_point))
if (!secp256k1_ec_pubkey_create(secp256k1_ctx,
&base_point.pubkey,
base_secret.data))
abort();
printf("base_point: 0x%s\n",
type_to_string(tmpctx, struct pubkey, &base_point));

26
test/test_sphinx.c

@ -14,6 +14,14 @@
secp256k1_context *secp256k1_ctx;
static struct secret secret_from_hex(const char *hex)
{
struct secret s;
if (!hex_decode(hex, strlen(hex), &s, sizeof(s)))
abort();
return s;
}
/* Create an onionreply with the test vector parameters and check that
* we match the test vectors and that we can also unwrap it. */
static void run_unit_tests(void)
@ -31,12 +39,12 @@ static void run_unit_tests(void)
"21e13c2d7cfe7e18836df50872466117a295783ab8aab0e7ecc8c725503ad02d",
"b5756b9b542727dbafc6765a49488b023a725d631af688fc031217e90770c328",
};
u8 *ss[] = {
tal_hexdata(tmpctx, secrets[0], 64),
tal_hexdata(tmpctx, secrets[1], 64),
tal_hexdata(tmpctx, secrets[2], 64),
tal_hexdata(tmpctx, secrets[3], 64),
tal_hexdata(tmpctx, secrets[4], 64),
struct secret ss[] = {
secret_from_hex(secrets[0]),
secret_from_hex(secrets[1]),
secret_from_hex(secrets[2]),
secret_from_hex(secrets[3]),
secret_from_hex(secrets[4])
};
int replylen = 164 * 2;
@ -90,10 +98,10 @@ static void run_unit_tests(void)
replylen),
};
reply = create_onionreply(tmpctx, ss[4], raw);
reply = create_onionreply(tmpctx, &ss[4], raw);
for (int i = 4; i >= 0; i--) {
printf("input_packet %s\n", tal_hex(tmpctx, reply));
reply = wrap_onionreply(tmpctx, ss[i], reply);
reply = wrap_onionreply(tmpctx, &ss[i], reply);
printf("obfuscated_packet %s\n", tal_hex(tmpctx, reply));
assert(memcmp(reply, intermediates[i], tal_len(reply)) == 0);
}
@ -140,7 +148,7 @@ int main(int argc, char **argv)
u8 privkeys[argc - 1][32];
u8 sessionkey[32];
struct hop_data hops_data[num_hops];
struct sha256 *shared_secrets;
struct secret *shared_secrets;
memset(&sessionkey, 'A', sizeof(sessionkey));

1
type_to_string.h

@ -21,6 +21,7 @@ union printable_types {
const secp256k1_pubkey *secp256k1_pubkey;
const struct channel_id *channel_id;
const struct short_channel_id *short_channel_id;
const struct secret *secret;
const struct privkey *privkey;
const secp256k1_ecdsa_signature *secp256k1_ecdsa_signature;
const struct channel *channel;

7
wire/fromwire.c

@ -106,9 +106,14 @@ void fromwire_pubkey(const u8 **cursor, size_t *max, struct pubkey *pubkey)
fail_pull(cursor, max);
}
void fromwire_secret(const u8 **cursor, size_t *max, struct secret *secret)
{
fromwire(cursor, max, secret->data, sizeof(secret->data));
}
void fromwire_privkey(const u8 **cursor, size_t *max, struct privkey *privkey)
{
fromwire(cursor, max, privkey->secret, sizeof(privkey->secret));
fromwire_secret(cursor, max, &privkey->secret);
}
void fromwire_secp256k1_ecdsa_signature(const u8 **cursor,

7
wire/towire.c

@ -58,9 +58,14 @@ void towire_pubkey(u8 **pptr, const struct pubkey *pubkey)
towire(pptr, output, outputlen);
}
void towire_secret(u8 **pptr, const struct secret *secret)
{
towire(pptr, secret->data, sizeof(secret->data));
}
void towire_privkey(u8 **pptr, const struct privkey *privkey)
{
towire(pptr, privkey->secret, sizeof(privkey->secret));
towire_secret(pptr, &privkey->secret);
}
void towire_secp256k1_ecdsa_signature(u8 **pptr,

2
wire/wire.h

@ -31,6 +31,7 @@ int fromwire_peektype(const u8 *cursor);
void towire(u8 **pptr, const void *data, size_t len);
void towire_pubkey(u8 **pptr, const struct pubkey *pubkey);
void towire_privkey(u8 **pptr, const struct privkey *privkey);
void towire_secret(u8 **pptr, const struct secret *secret);
void towire_secp256k1_ecdsa_signature(u8 **pptr,
const secp256k1_ecdsa_signature *signature);
void towire_channel_id(u8 **pptr, const struct channel_id *channel_id);
@ -55,6 +56,7 @@ u16 fromwire_u16(const u8 **cursor, size_t *max);
u32 fromwire_u32(const u8 **cursor, size_t *max);
u64 fromwire_u64(const u8 **cursor, size_t *max);
bool fromwire_bool(const u8 **cursor, size_t *max);
void fromwire_secret(const u8 **cursor, size_t *max, struct secret *secret);
void fromwire_privkey(const u8 **cursor, size_t *max, struct privkey *privkey);
void fromwire_pubkey(const u8 **cursor, size_t *max, struct pubkey *pubkey);
void fromwire_secp256k1_ecdsa_signature(const u8 **cursor, size_t *max,

Loading…
Cancel
Save