LNPBP: 0018
Layer: OSI Transport (i4)
Vertical: Lightning network protocol
Title: LNP native message framing protocol (BOLT-8 extract)
Author: BOLT-8 protocol authors
Comments-URI: n/a
Status: Proposal
Type: Standards Track
Created: 2020-14-05
License: CC0-1.0
- Abstract
- Background
- Motivation
- Design
- Specification
- Compatibility
- Rationale
- Reference implementation
- Acknowledgements
- References
- Copyright
- Test vectors
At the conclusion of Act Three of LNPBP-15, 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).
The maximum size of any Lightning message MUST NOT exceed 65535
bytes. A
maximum size of 65535
simplifies testing, makes memory management easier, and
helps mitigate memory-exhaustion attacks.
In order to make traffic analysis more difficult, the length prefix for all
encrypted Lightning messages is also encrypted. Additionally a 16-byte
Poly-1305
tag is added to the encrypted length prefix in order to ensure that
the packet length hasn't been modified when in-flight and also to avoid creating
a decryption oracle.
The structure of packets on the wire resembles the following:
+-------------------------------
|2-byte encrypted message length|
+-------------------------------
| 16-byte MAC of the encrypted |
| message length |
+-------------------------------
| |
| |
| encrypted Lightning |
| message |
| |
+-------------------------------
| 16-byte MAC of the |
| Lightning message |
+-------------------------------
The prefixed message length is encoded as a 2-byte big-endian integer, for a
total maximum packet length of 2 + 16 + 65535 + 16
= 65569
bytes.
In order to encrypt and send a Lightning message (m
) to the network stream,
given a sending key (sk
) and a nonce (sn
), the following steps are
completed:
- Let
l = len(m)
.- where
len
obtains the length in bytes of the Lightning message
- where
- Serialize
l
into 2 bytes encoded as a big-endian integer. - Encrypt
l
(usingChaChaPoly-1305
,sn
, andsk
), to obtainlc
(18 bytes)- The nonce
sn
is encoded as a 96-bit little-endian number. As the decoded nonce is 64 bits, the 96-bit nonce is encoded as: 32 bits of leading 0s followed by a 64-bit value.- The nonce
sn
MUST be incremented after this step.
- The nonce
- A zero-length byte slice is to be passed as the AD (associated data).
- The nonce
- Finally, encrypt the message itself (
m
) using the same procedure used to encrypt the length prefix. Let encrypted ciphertext be known asc
.- The nonce
sn
MUST be incremented after this step.
- The nonce
- Send
lc || c
over the network buffer.
In order to decrypt the next message in the network stream, the following steps are completed:
- Read exactly 18 bytes from the network buffer.
- Let the encrypted length prefix be known as
lc
. - Decrypt
lc
(usingChaCha20-Poly1305
,rn
, andrk
), to obtain the size of the encrypted packetl
.- A zero-length byte slice is to be passed as the AD (associated data).
- The nonce
rn
MUST be incremented after this step.
- Read exactly
l+16
bytes from the network buffer, and let the bytes be known asc
. - Decrypt
c
(usingChaCha20-Poly1305
,rn
, andrk
), to obtain decrypted plaintext packetp
.- The nonce
rn
MUST be incremented after this step.
- The nonce
- BOLT-8: Encrypted and Authenticated Transport. Version 1. https://github.com/lightningnetwork/lightning-rfc/blob/v1.0/08-transport.md
This document is licensed under the Creative Commons CC0 1.0 Universal license.