In this commit, we reduce the total number of allocations that a
brontide session will incur over its lifetime. Profiling on one of my
nodes showed that we were generating a lot of garbage due to
re-creating a 65KB buffer to read the next message each time the
ReadMessage method was called.
To reduce the total number of memory allocations, we’ll now simply
re-use a buffer for both the cipher text header, and the cipher text
itself.
This commit modifies the NewBrontideMachine constructor to allow a
caller to specify exactly _how_ new ephemeral private keys for the
crypto handshake are generated. This allows callers a bit more
flexibility when using brontide, and also allow test cases to insert
specific public keys for use within the hand shake.
This commit adds some additional detail to the error message
encountered when the first byte of an act is an invalid handshake
version byte. This commit is meant to aide in tracking down a
re-occurring bug that has been encountered by early testers of the
software.
This commit adds a new message to the brontide.Conn struct which allows
callers to read an _entire_ message from the stream. As defined now,
brontide is a message crypto messaging protocol. Previously the only
method that allowed callers to read attempted to hide this feature with
a stream-like abstraction. However, having this as the sole interface
is at odds with the message oriented Lightning wire protocol, and isn’t
sufficient to allow parsing messages that have been padded as is
allowed by the protocol.
This new ReadNextMessage is intended to be used by higher level systems
which implement the Lightning p2p protocol.
This commit replaces aead’s chacha20 library with the official golang
implementation. We should see a bit of a performance increase on amd64
as the assembly for the library uses the SIMD AVX2 instructions in the
inner loop. In the future assembly will be written for other platforms,
so we’ll see a performance increase across the board.
Fixes#146.
This commit removes all instances of the fastsha256 library and
replaces it with the sha256 library in the standard library. This
change should see a number of performance improvements as the standard
library has highly optimized assembly instructions with use vectorized
instructions as the platform supports.
This commit modifies the `ecdh` function within the `brontide` package
to refer directly to the global curve params object in the `bcec`
package rather than reference it from the target public key. This
changes fixes a class of panics that have been uncovered recently but
*doesn’t* yet fix the root cause.
This commit modifies our key rotation slightly to match the test
vectors within the BOLT08 specifications. Before this commit, we were
rotating one message before the rest of the implementers. This
implementation divergence was possibly due to the section of the spec
describing the rotations being a bit ambiguous.
A future PR to the lightning-rfc repo will make the spec more explicit
to avoid situations like this in the future.
Pervasively we would include the length of the MAC in the length prefix
for cipher text packets. As a result, the MAC would eat into the total
payload size. To remedy this, we now exclude the MAC from the length
prefix for cipher text packets, and instead account for the length of
the MAC on the packet when reading messages.
This commit fixes a bug in our key derivation for the final step of the
key exchange. In our code we were swapping the order of the salt and
input keyeing material to the HKDF function. This was triggered by the
argument order of the golang implementation we’re currently using has
the “secret” of IKM argument first, instead of second as defined within
rfc5869.
To fix this, we simply need to swap function arguments in two places:
within the split() function and during key rotation.
This bug was discovered by Rusty Russell, thanks!
This commit modifies the opening brontide handshake to use
libsecp256k1's public ECDH API throughout the handshake rather than the
current method which just returns the x-coordinate of the generated
point.
This change was made in order to align the current spec draft with the
aforementioned library since it’s very popular within the pace and
strives to only expose safe API’s to end users.
This commit modifies the current implementation to more closely match
what’s currently specified within the spec.
The encrypted+MAC’d packet length is no longer included as the
associated data for the encryption/decryption of transport messages.
This isn’t required as if an active attacker swaps out the encrypted
length in the byte string, the decryption+MAC check will simply fail as
the nonce won’t be in proper sequence.
This commit implements key rotation for brontide as-per the current
draft of the LN p2p crypto spec. Key rotation is currently performed
every 1000 messages encrypted/decrypted with a cipherState object. Key
rotation is performed by evaluating the HKDF (extracting exactly 64
bytes) with the current chaining key, and cipher key. The key rotation
is to attempted after each nonce increment making implementation easy
as the current nonce value will already be within the local scope.
This commit modifies the current implementation of the p2p crypto
protocol to further constrain the max allowed payload size. With this
change we now use 16-bits (2-bytes) for the maximum payload length.
This change puts us closer to strict adherence of the Noise spec, and
simplifies the memory management w.r.t implementing the current version
of our scheme.
Note that this doesn’t restrict the size of messages that are able to
be sent over the wire within the LN p2p protocol. Larger message can
safely be encapsulated within the crypt messages via fragmentation that
will detected take place if a larger message is detected.
This commit introduces Brontide: an authenticated key agreement
protocol in three acts. Brontide is the successor to lndc within lnd,
and ultimately within the greater Lighting Network. Brontide uses the
Noise_XK handshake for initial key agreement, then implements an AEAD
scheme which encrypts+authenticates both packets, and the lengths of
the packets on the wire. The initial authentication handshake preserves
the responder’s identity by never transmitting it to the initiator and
performing mutual authentication via an incremental Triple-DH based on
ECDH of secp256k1 and an HKDF which uses SHA-256.
Bronzed isn’t yet integrated within the wider daemon yet. Full
integration will land in a future pull request.