commit d67f1fe11add3c1c7eb626456f53751989787176
parent 1e25805c232b4cfb5e024ab3fcc5eb38fbdea8e4
Author: William Casarin <jb55@jb55.com>
Date: Sun, 9 Jan 2022 17:08:53 -0800
more stuff
Diffstat:
A | .gitmodules | | | 3 | +++ |
M | Makefile | | | 22 | +++++++++++++++++++--- |
A | deps/secp256k1 | | | 1 | + |
A | handshake.h | | | 107 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | netln.c | | | 76 | ++-------------------------------------------------------------------------- |
5 files changed, 132 insertions(+), 77 deletions(-)
diff --git a/.gitmodules b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "deps/secp256k1"]
+ path = deps/secp256k1
+ url = https://github.com/bitcoin-core/secp256k1
diff --git a/Makefile b/Makefile
@@ -1,12 +1,28 @@
-CFLAGS=-Wall -g -Og
+CFLAGS=-Wall -g -Og -Ideps/secp256k1
+
+LDFLAGS=
all: netln
-netln: netln.c
- $(CC) $(CFLAGS) $^ -o $@
+deps/secp256k1/src/libsecp256k1-config.h: deps/secp256k1/configure
+ ./configure
+
+deps/secp256k1/configure:
+ cd deps/secp256k1; \
+ ./autogen.sh
+
+deps/secp256k1/.libs/libsecp256k1.a: deps/secp256k1/configure
+ cd deps/secp256k1; \
+ make -j2 libsecp256k1.la
+
+netln: netln.c deps/secp256k1/.libs/libsecp256k1.a
+ $(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@
clean: fake
rm -f netln
+ cd deps/secp256k1; \
+ make clean
+
.PHONY: fake
diff --git a/deps/secp256k1 b/deps/secp256k1
@@ -0,0 +1 @@
+Subproject commit a1102b12196ea27f44d6201de4d25926a2ae9640
diff --git a/handshake.h b/handshake.h
@@ -0,0 +1,107 @@
+
+#ifndef LNLINK_HANDSHAKE_H
+#define LNLINK_HANDSHAKE_H
+
+#include <secp256k1/>
+
+struct pubkey {
+ /* Unpacked pubkey (as used by libsecp256k1 internally) */
+ secp256k1_pubkey pubkey;
+};
+
+/* BOLT #8:
+ *
+ * Act One is sent from initiator to responder. During Act One, the
+ * initiator attempts to satisfy an implicit challenge by the responder. To
+ * complete this challenge, the initiator must know the static public key of
+ * the responder.
+ */
+struct act_one {
+ u8 v;
+ u8 pubkey[PUBKEY_CMPR_LEN];
+ u8 tag[crypto_aead_chacha20poly1305_ietf_ABYTES];
+};
+
+/* BOLT #8:
+ *
+ * Act Two is sent from the responder to the initiator. Act Two will
+ * _only_ take place if Act One was successful. Act One was successful if
+ * the responder was able to properly decrypt and check the MAC of the tag
+ * sent at the end of Act One.
+ */
+struct act_two {
+ u8 v;
+ u8 pubkey[PUBKEY_CMPR_LEN];
+ u8 tag[crypto_aead_chacha20poly1305_ietf_ABYTES];
+};
+
+/* BOLT #8:
+ *
+ * Act Three is the final phase in the authenticated key agreement described
+ * in this section. This act is sent from the initiator to the responder as a
+ * concluding step. Act Three is executed _if and only if_ Act Two was
+ * successful. During Act Three, the initiator transports its static public
+ * key to the responder encrypted with _strong_ forward secrecy, using the
+ * accumulated `HKDF` derived secret key at this point of the handshake.
+ */
+struct act_three {
+ u8 v;
+ u8 ciphertext[PUBKEY_CMPR_LEN + crypto_aead_chacha20poly1305_ietf_ABYTES];
+ u8 tag[crypto_aead_chacha20poly1305_ietf_ABYTES];
+};
+
+/* BOLT #8:
+ *
+ * Throughout the handshake process, each side maintains these variables:
+ *
+ * * `ck`: the **chaining key**. This value is the accumulated hash of all
+ * previous ECDH outputs. At the end of the handshake, `ck` is used to derive
+ * the encryption keys for Lightning messages.
+ *
+ * * `h`: the **handshake hash**. This value is the accumulated hash of _all_
+ * handshake data that has been sent and received so far during the handshake
+ * process.
+ *
+ * * `temp_k1`, `temp_k2`, `temp_k3`: the **intermediate keys**. These are used to
+ * encrypt and decrypt the zero-length AEAD payloads at the end of each handshake
+ * message.
+ *
+ * * `e`: a party's **ephemeral keypair**. For each session, a node MUST generate a
+ * new ephemeral key with strong cryptographic randomness.
+ *
+ * * `s`: a party's **static keypair** (`ls` for local, `rs` for remote)
+ */
+struct handshake {
+ struct secret ck;
+ struct secret temp_k;
+ struct sha256 h;
+ struct keypair e;
+ struct secret *ss;
+
+ /* Used between the Acts */
+ struct pubkey re;
+ struct act_one act1;
+ struct act_two act2;
+ struct act_three act3;
+
+ /* Where is connection from/to */
+ struct wireaddr_internal addr;
+
+ /* Who we are */
+ struct pubkey my_id;
+ /* Who they are: set already if we're initiator. */
+ struct pubkey their_id;
+
+ /* Are we initiator or responder. */
+ enum bolt8_side side;
+
+ /* Function to call once handshake complete. */
+ struct io_plan *(*cb)(struct io_conn *conn,
+ const struct pubkey *their_id,
+ const struct wireaddr_internal *wireaddr,
+ struct crypto_state *cs,
+ void *cbarg);
+ void *cbarg;
+};
+
+#endif /* LNLINK_HANDSHAKE_H */
diff --git a/netln.c b/netln.c
@@ -8,6 +8,8 @@
#include <string.h>
#include <errno.h>
+#include "handshake.h"
+
#define array_len(x) (sizeof(x)/sizeof(x[0]))
struct netln {
@@ -15,80 +17,6 @@ struct netln {
int num_errors;
};
-
-struct pubkey {
- /* Unpacked pubkey (as used by libsecp256k1 internally) */
- secp256k1_pubkey pubkey;
-};
-
-/* BOLT #8:
- *
- * Act One is sent from initiator to responder. During Act One, the
- * initiator attempts to satisfy an implicit challenge by the responder. To
- * complete this challenge, the initiator must know the static public key of
- * the responder.
- */
-struct act_one {
- u8 v;
- u8 pubkey[PUBKEY_CMPR_LEN];
- u8 tag[crypto_aead_chacha20poly1305_ietf_ABYTES];
-};
-
-/* BOLT #8:
- *
- * Throughout the handshake process, each side maintains these variables:
- *
- * * `ck`: the **chaining key**. This value is the accumulated hash of all
- * previous ECDH outputs. At the end of the handshake, `ck` is used to derive
- * the encryption keys for Lightning messages.
- *
- * * `h`: the **handshake hash**. This value is the accumulated hash of _all_
- * handshake data that has been sent and received so far during the handshake
- * process.
- *
- * * `temp_k1`, `temp_k2`, `temp_k3`: the **intermediate keys**. These are used to
- * encrypt and decrypt the zero-length AEAD payloads at the end of each handshake
- * message.
- *
- * * `e`: a party's **ephemeral keypair**. For each session, a node MUST generate a
- * new ephemeral key with strong cryptographic randomness.
- *
- * * `s`: a party's **static keypair** (`ls` for local, `rs` for remote)
- */
-struct handshake {
- struct secret ck;
- struct secret temp_k;
- struct sha256 h;
- struct keypair e;
- struct secret *ss;
-
- /* Used between the Acts */
- struct pubkey re;
- struct act_one act1;
- struct act_two act2;
- struct act_three act3;
-
- /* Where is connection from/to */
- struct wireaddr_internal addr;
-
- /* Who we are */
- struct pubkey my_id;
- /* Who they are: set already if we're initiator. */
- struct pubkey their_id;
-
- /* Are we initiator or responder. */
- enum bolt8_side side;
-
- /* Function to call once handshake complete. */
- struct io_plan *(*cb)(struct io_conn *conn,
- const struct pubkey *their_id,
- const struct wireaddr_internal *wireaddr,
- struct crypto_state *cs,
- void *cbarg);
- void *cbarg;
-};
-
-
static void push_error(struct netln *netln, const char *err)
{
if (netln->num_errors >= array_len(netln->errors)) {