lnpbp-0018
1
LNPBP: 0018
2
Layer: OSI Transport (i4)
3
Vertical: Lightning network protocol
4
Title: LNP native message framing protocol (BOLT-8 extract)
5
Author: BOLT-8 protocol authors
6
Comments-URI: n/a
7
Status: Proposal
8
Type: Standards Track
9
Created: 2020-14-05
10
License: CC0-1.0
Copied!

LNP native message framing protocol

Abstract

Table of Contents

Background

Motivation

Design

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:
1
+-------------------------------
2
|2-byte encrypted message length|
3
+-------------------------------
4
| 16-byte MAC of the encrypted |
5
| message length |
6
+-------------------------------
7
| |
8
| |
9
| encrypted Lightning |
10
| message |
11
| |
12
+-------------------------------
13
| 16-byte MAC of the |
14
| Lightning message |
15
+-------------------------------
Copied!
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.

Encrypting and Sending Messages

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:
    1.
    Let l = len(m).
      where len obtains the length in bytes of the Lightning message
    2.
    Serialize l into 2 bytes encoded as a big-endian integer.
    3.
    Encrypt l (using ChaChaPoly-1305, sn, and sk), to obtain lc
    (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.
      A zero-length byte slice is to be passed as the AD (associated data).
    4.
    Finally, encrypt the message itself (m) using the same procedure used to
    encrypt the length prefix. Let encrypted ciphertext be known as c.
      The nonce sn MUST be incremented after this step.
    5.
    Send lc || c over the network buffer.

Receiving and Decrypting Messages

In order to decrypt the next message in the network stream, the following steps are completed:
    1.
    Read exactly 18 bytes from the network buffer.
    2.
    Let the encrypted length prefix be known as lc.
    3.
    Decrypt lc (using ChaCha20-Poly1305, rn, and rk), to obtain the size of
    the encrypted packet l.
      A zero-length byte slice is to be passed as the AD (associated data).
      The nonce rn MUST be incremented after this step.
    4.
    Read exactly l+16 bytes from the network buffer, and let the bytes be
    known as c.
    5.
    Decrypt c (using ChaCha20-Poly1305, rn, and rk), to obtain decrypted
    plaintext packet p.
      The nonce rn MUST be incremented after this step.

Compatibility

Rationale

Reference implementation

Acknowledgements

References

    1.
    BOLT-8: Encrypted and Authenticated Transport. Version 1.
This document is licensed under the Creative Commons CC0 1.0 Universal license.

Test vectors

Last modified 3mo ago