((("Lightning encrypted transport protocol", id="ix_14_encrypted_transport-asciidoc0", range="startofrange")))In this chapter we will review the Lightning Network's _encrypted message
transport_, sometimes referred to as the ((("Brontide Protocol")))_Brontide Protocol_, which allows peers to
establish end-to-end encrypted communication, authentication, and integrity
Part of this chapter includes some highly technical detail about the encryption protocol and encryption algorithms used in the Lightning encrypted transport. You may decide to skip that section if you are not interested in those details.
=== Encrypted Transport in the Lightning Protocol Suite
((("Lightning encrypted transport protocol","Lightning Protocol Suite and")))The transport component of the Lightning Network and its several components are shown in the leftmost part of the network connection layer in <<LN_protocol_encrypted_transport_highlight>>.
public key is used to end-to-end encrypt _all_ communication within the
network. Encryption by default at the lowest level of the protocol ensures that
all messages are authenticated, are immune to man-in-the-middle (MITM) attacks and snooping by third parties, and ensures privacy at the fundamental transport
level. In this chapter, we'll learn about the encryption protocol used by the
Lightning Network in detail. Upon completion of this chapter, the reader will
be familiar with the state of the art in encrypted messaging protocols, as well
as the various properties such a protocol provides to the network. It's worth
mentioning that the core of the encrypted message transport is _agnostic_ to
its usage within the context of the Lightning Network. As a result, the
((("channel graph","decentralized public key infrastructure")))((("Lightning encrypted transport protocol","channel graph as decentralized public key infrastructure")))((("PKI (public key infrastructure)")))((("public key infrastructure (PKI)")))As we learned in <<routing>>, every node has a long-term
Lightning Network is able to significantly simplify its encrypted transport
protocol as it doesn't need to deal with all the complexities that come along
with TLS, the Transport Layer Security protocol.
=== Why Not TLS?
((("Lightning encrypted transport protocol","TLS vulnerabilities/limitations")))((("TLS (Transport Layer Security protocol)")))((("Transport Layer Security protocol (TLS)")))Readers familiar with the TLS system may be wondering at this point: why wasn't
TLS used in spite of the drawbacks of the existing PKI system? It is indeed a
simplified protocol that retains all the added benefits of TLS.
=== The Noise Protocol Framework
((("Lightning encrypted transport protocol","Noise Protocol Framework")))((("Noise Protocol Framework","encrypted message transport and")))The Noise Protocol Framework is a modern, extensible, and flexible message
encryption protocol designed by the creators of the Signal Protocol. The Signal Protocol is one of the most widely used message encryption protocols in the
world. It's used by both Signal and Whatsapp, which cumulatively are used by
over a billion people around the world. The Noise framework is the result of
as Brontide. A _brontide_ is a low billowing noise, similar to what one would
hear during a thunderstorm when very far away.
=== Lightning Encrypted Transport in Detail
((("Lightning encrypted transport protocol","elements of", id="ix_14_encrypted_transport-asciidoc1", range="startofrange")))In this section we will break down the Lightning encrypted transport protocol and delve into the details of the cryptographic algorithms and protocol used to establish encrypted, authenticated, and integrity-assured communications between peers. Feel free to skip this section if you find this level of detail daunting.
((("Lightning encrypted transport protocol","Noise XK")))((("Noise Protocol Framework","Noise XK")))((("Noise_XK")))The Noise Protocol is extremely flexible in that it advertises several
handshakes, each with different security and privacy properties for a would-be
protocol implementer to select from. A deep exploration of each of the
handshakes and their various trade-offs is out of the scope of this chapter.
With that said, the Lightning Network uses a specific handshake referred to as
`Noise_XK`. ((("identity hiding")))The unique property provided by this handshake is __identity hiding__: in order for a node to initiate a connection with another node, it
must first know its public key. Mechanically, this means that the public key
of the responder is actually never transmitted during the context of the
handshake. Instead, a clever series of Elliptic Curve Diffie–Hellman (ECDH) and
message authentication code (MAC) checks are used to authenticate the
responder.
==== Handshake Notation and Protocol Flow
((("handshake","notation and protocol flow")))((("Lightning encrypted transport protocol","handshake notation and protocol flow")))((("Noise_XK","handshake notation and protocol flow")))Each handshake typically consists of several steps. At each step some
(possibly) encrypted material is sent to the opposite party, an ECDH (or
several) is performed, with the result of the handshake being "mixed" into a
protocol _transcript_. This transcript serves to authenticate each step of the
protocol and helps thwart a flavor of man-in-the-middle attacks. At the
end of the handshake, two keys, `ck` and `k`, are produced which are used to
encrypt messages (`k`) and rotate keys (`ck`) throughout the lifetime of
the session.
In the context of a handshake, `s` is usually a long-term static public key.
In our case, the public key crypto system used is an elliptic curve one,
instantiated with the `secp256k1` curve, which is used elsewhere in Bitcoin.
Several ephemeral keys are generated throughout the handshake. We use `e` to
refer to a new ephemeral key. ECDH operations between two keys are notated as
the concatenation of two keys. As an example, `ee` represents an ECDH operation
between two ephemeral keys.
==== High-Level Overview
((("Lightning encrypted transport protocol","high-level overview")))((("Noise_XK","high-level overview")))Using the notation laid out earlier, we can succinctly describe the `Noise_XK`
as follows:
```
Noise_XK(s, rs):
<- rs
...
-> e, e(rs)
<- e, ee
-> s, se
```
The protocol begins with the "pretransmission" of the responder's static key
(`rs`) to the initiator. Before executing the handshake, the initiator is to
generate its own static key (`s`). During each step of the handshake, all
material sent across the wire and the keys sent/used are incrementally
hashed into a _handshake digest_, `h`. This digest is never sent across the
wire during the handshake, and is instead used as the "associated data" when
AEAD (authenticated encryption with associated data) is sent across the wire.
((("AD (associated data)")))((("associated data (AD)")))_Associated data_ (AD) allows an encryption protocol to authenticate additional
information alongside a cipher text packet. In other domains, the AD may be a
domain name, or plain-text portion of the packet.
The existence of `h` ensures that if a portion of a transmitted handshake
message is replaced, then the other side will notice. At each step, a MAC
digest is checked. If the MAC check succeeds, then the receiving party knows
that the handshake has been successful up until that point. Otherwise, if a MAC
check ever fails, then the handshake process has failed, and the connection
should be terminated.
The protocol also adds a new piece of data to each handshake message: a protocol
version. The initial protocol version is `0`. At the time of writing, no new
choice, `secp256k1` as the elliptic curve, and `ChaChaPoly-130` as the AEAD
(symmetric encryption) construction.
Each variant of the Noise Protocol has a unique ASCII string used to refer to it. To ensure that two parties are using the same protocol
variant, the ASCII string is hashed into a digest, which is used to initialize
the starting handshake state. In the context of the Lightning Network, the ASCII
string describing the protocol is `Noise_XK_secp256k1_ChaChaPoly_SHA256`.
==== Handshake in Three Acts
((("Lightning encrypted transport protocol","handshake in three acts", id="ix_14_encrypted_transport-asciidoc2", range="startofrange")))((("Noise_XK","handshake in three acts", id="ix_14_encrypted_transport-asciidoc3", range="startofrange")))The handshake portion can be separated into three distinct "acts."
The entire handshake takes 1.5 round trips between the initiator and responder.
At each act, a single message is sent between both parties. The handshake
message is a fixed-size payload prefixed by the protocol version.
The Noise Protocol uses an object-oriented inspired notation to describe the
protocol at each step. During setup of the handshake state, each side will
initialize the following 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.
Where the object returned by `generateKey` has two attributes:`.pub`, which returns an abstract object representing the public key; and `.priv`, which represents the private key used to generate the public key
`a || b`:: This denotes the concatenation of two byte strings `a` and `b`.
===== Handshake session state initialization
((("handshake","session state initialization")))((("Lightning encrypted transport protocol","handshake session state initialization")))((("Noise_XK","handshake session state initialization")))Before starting the handshake process, both sides need to initialize the
starting state that they'll use to advance the handshake process. To start,
both sides need to construct the initial handshake digest `h`.
((("handshake","acts", id="ix_14_encrypted_transport-asciidoc4", range="startofrange")))((("Lightning encrypted transport protocol","handshake acts", id="ix_14_encrypted_transport-asciidoc5", range="startofrange")))((("Noise_XK","handshake acts", id="ix_14_encrypted_transport-asciidoc6", range="startofrange")))After the initial handshake initialization, we can begin the actual execution
of the handshake process. The handshake is composed of a series of
three messages sent between the initiator and responder, henceforth referred to as
"acts." Because each act is a single message sent between the parties, a handshake
is completed in a total of 1.5 round trips (0.5 for each act).
((("Diffie-Hellman Key Exchange (DHKE)")))The first act completes the initial portion of the incremental triple Diffie–Hellman (DH) key exchange (using a new ephemeral key generated by the initiator)
and also ensures that the initiator actually knows the long-term public key of
the responder. During the second act, the responder transmits the ephemeral key
they wish to use for the session to the initiator, and once again incrementally
mixes this new key into the triple DH handshake. During the third and final
act, the initiator transmits their long-term static public key to the
responder and executes the final DH operation to mix that into the final
resulting shared secret.
====== Act One
```
-> e, es
```
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.
The handshake message is _exactly_ 50 bytes: 1 byte for the handshake
version, 33 bytes for the compressed ephemeral public key of the initiator,
The sending and receiving nonces are initialized to 0.(((range="endofrange", startref="ix_14_encrypted_transport-asciidoc6")))(((range="endofrange", startref="ix_14_encrypted_transport-asciidoc5")))(((range="endofrange", startref="ix_14_encrypted_transport-asciidoc4")))
((("Lightning encrypted transport protocol","transport message encryption")))((("Noise_XK","transport message encryption")))At the conclusion of Act Three, both sides have derived the encryption keys, which
will be used to encrypt and decrypt messages for the remainder of the
session.
The actual Lightning Protocol messages are encapsulated within AEAD ciphertexts.
Each message is prefixed with another AEAD ciphertext, which encodes the total
length of the following Lightning message (not including its MAC).
((("Lightning encrypted transport protocol","Lightning message key rotation")))((("Noise_XK","Lightning message key rotation")))Changing keys regularly and forgetting previous keys is useful to prevent the
decryption of old messages, in the case of later key leakage (i.e., backward
secrecy).
Key rotation is performed for _each_ key (`sk` and `rk`) _individually_. A key
is to be rotated after a party encrypts or decrypts 1,000 times with it (i.e.,
every 500 messages). This can be properly accounted for by rotating the key
once the nonce dedicated to it exceeds 1,000.
Key rotation for a key `k` is performed according to the following steps(((range="endofrange", startref="ix_14_encrypted_transport-asciidoc3")))(((range="endofrange", startref="ix_14_encrypted_transport-asciidoc2"))):(((range="endofrange", startref="ix_14_encrypted_transport-asciidoc1")))
1. Let `ck` be the chaining key obtained at the end of Act Three.
2. `ck', k' = HKDF(ck, k)`
3. Reset the nonce for the key to `n = 0`.
4. `k = k'`
5. `ck = ck'`
=== Conclusion
Lightning's underlying transport encryption is based on the Noise Protocol and offers strong security guarantees of privacy, authenticity, and integrity for all communications between Lightning peers.
Unlike Bitcoin where peers often communicate "in the clear" (without encryption), all Lightning communications are encrypted peer-to-peer. In addition to transport encryption (peer-to-peer), in the Lightning Network, payments are _also_ encrypted into onion packets (hop-to-hop) and payment details are sent out-of-band between the sender and recipient (end-to-end). The combination of all these security mechanisms is cumulative and provides a layered defense against de-anonymization, man-in-the-middle attacks, and network surveillance.
Of course, no security is perfect and we will see in <<security_and_privacy>> that these properties can be degraded and attacked. However, the Lightning Network significantly improves upon the privacy of Bitcoin.(((range="endofrange", startref="ix_14_encrypted_transport-asciidoc0")))