lnsocket

A minimal C library for connecting to the lightning network
git clone git://jb55.com/lnsocket
Log | Files | Refs | Submodules | README | LICENSE

commit 7a5cf9f51c5d7c2f82dfd1de03efd8bae4580618
parent ba5e344f0adc2dd9cce774a970d64b27176b0b47
Author: William Casarin <jb55@jb55.com>
Date:   Sun, 16 Jan 2022 08:48:09 -0800

handshake_success to initialize final crypto state

Diffstat:
Acrypto.h | 40++++++++++++++++++++++++++++++++++++++++
Mhandshake.c | 29++++++++++++++++++++++++++++-
Mhandshake.h | 24+-----------------------
Mlnsocket_internal.h | 8+++++++-
4 files changed, 76 insertions(+), 25 deletions(-)

diff --git a/crypto.h b/crypto.h @@ -0,0 +1,40 @@ + +#ifndef LNSOCKET_CRYPTO_H +#define LNSOCKET_CRYPTO_H + +#include <secp256k1.h> + +#define PUBKEY_CMPR_LEN 33 + +struct secret { + u8 data[32]; +}; + +struct node_id { + u8 k[PUBKEY_CMPR_LEN]; +}; + +struct pubkey { + secp256k1_pubkey pubkey; +}; + +struct privkey { + struct secret secret; +}; + +struct keypair { + struct pubkey pub; + struct privkey priv; +}; + +struct crypto_state { + /* Received and sent nonces. */ + u64 rn, sn; + /* Sending and receiving keys. */ + struct secret sk, rk; + /* Chaining key for re-keying */ + struct secret s_ck, r_ck; +}; + + +#endif /* LNSOCKET_CRYPTO_H */ diff --git a/handshake.c b/handshake.c @@ -218,6 +218,33 @@ static int decrypt(const struct secret *k, u64 nonce, return 1; } +static int handshake_success(struct lnsocket *ln, struct handshake *h) +{ + struct crypto_state *cs = &ln->crypto_state; + + /* BOLT #8: + * + * 9. `rk, sk = HKDF(ck, zero)` + * * where `zero` is a zero-length plaintext, `rk` is the key to + * be used by the responder to decrypt the messages sent by the + * initiator, and `sk` is the key to be used by the responder + * to encrypt messages to the initiator + * + * * The final encryption keys, to be used for sending and + * receiving messages for the duration of the session, are + * generated. + */ + if (h->side == RESPONDER) + hkdf_two_keys(&cs->rk, &cs->sk, &h->ck, NULL, 0); + else + hkdf_two_keys(&cs->sk, &cs->rk, &h->ck, NULL, 0); + + cs->rn = cs->sn = 0; + cs->r_ck = cs->s_ck = h->ck; + + return 1; +} + static int act_three_initiator(struct lnsocket *ln, struct handshake *h) { u8 spub[PUBKEY_CMPR_LEN]; @@ -274,7 +301,7 @@ static int act_three_initiator(struct lnsocket *ln, struct handshake *h) return note_error(&ln->errs, "handshake failed on initial send"); } - return note_error(&ln->errs, "handshake success!\n"); + return handshake_success(ln, h); } // act2: read the response to the message sent in act1 diff --git a/handshake.h b/handshake.h @@ -24,44 +24,22 @@ THE SOFTWARE. #include "typedefs.h" #include "sha256.h" +#include "crypto.h" #include <netdb.h> #include <sodium/crypto_aead_chacha20poly1305.h> #include <secp256k1_extrakeys.h> -#define PUBKEY_CMPR_LEN 33 - #define ACT_ONE_SIZE 50 #define ACT_TWO_SIZE 50 #define ACT_THREE_SIZE 66 -struct node_id { - u8 k[PUBKEY_CMPR_LEN]; -}; - enum bolt8_side { INITIATOR, RESPONDER }; -struct secret { - u8 data[32]; -}; - -struct pubkey { - secp256k1_pubkey pubkey; -}; - -struct privkey { - struct secret secret; -}; - -struct keypair { - struct pubkey pub; - struct privkey priv; -}; - /* BOLT #8: * * Act One is sent from initiator to responder. During Act One, the diff --git a/lnsocket_internal.h b/lnsocket_internal.h @@ -1,11 +1,17 @@ +#ifndef LNSOCKET_INTERNAL_H +#define LNSOCKET_INTERNAL_H + +#include "crypto.h" struct lnsocket { const char *errors[8]; struct cursor mem; struct errors errs; - int socket; int num_errors; + int socket; struct keypair key; + struct crypto_state crypto_state; secp256k1_context *secp; }; +#endif /* LNSOCKET_INTERNAL_H */