BOLT 4: Onion Routing Protocol
## Overview This document describes the construction of an onion routed packet that is used to route a payment from an _origin node_ to a _final node_. The packet is routed through a number of intermediate nodes, called _hops_. The routing schema is based on the [Sphinx][sphinx] construction and is extended with a per-hop payload. Intermediate nodes forwarding the message can verify the integri
No reviewsSpecification
BOLT #4: Onion Routing Protocol
Overview
This document describes the construction of an onion routed packet that is used to route a payment from an origin node to a final node. The packet is routed through a number of intermediate nodes, called hops.
The routing schema is based on the [Sphinx][sphinx] construction and is extended with a per-hop payload.
Intermediate nodes forwarding the message can verify the integrity of the packet and can learn which node they should forward the packet to. They cannot learn which other nodes, besides their predecessor or successor, are part of the packet's route; nor can they learn the length of the route or their position within it. The packet is obfuscated at each hop, to ensure that a network-level attacker cannot associate packets belonging to the same route (i.e. packets belonging to the same route do not share any correlating information). Notice that this does not preclude the possibility of packet association by an attacker via traffic analysis.
The route is constructed by the origin node, which knows the public keys of each intermediate node and of the final node. Knowing each node's public key allows the origin node to create a shared secret (using ECDH) for each intermediate node and for the final node. The shared secret is then used to generate a pseudo-random stream of bytes (which is used to obfuscate the packet) and a number of keys (which are used to encrypt the payload and compute the HMACs). The HMACs are then in turn used to ensure the integrity of the packet at each hop.
Each hop along the route only sees an ephemeral key for the origin node, in order to hide the sender's identity. The ephemeral key is blinded by each intermediate hop before forwarding to the next, making the onions unlinkable along the route.
This specification describes version 0 of the packet format and routing mechanism.
A node:
- upon receiving a higher version packet than it implements:
- MUST report a route failure to the origin node.
- MUST discard the packet.
Table of Contents
- Conventions
- Key Generation
- Pseudo Random Byte Stream
- Packet Structure
- Route Blinding
- Accepting and Forwarding a Payment
- Shared Secret
- Blinding Ephemeral Onion Keys
- Packet Construction
- Onion Decryption
- Filler Generation
- Returning Errors
- Onion Messages
max_htlc_cltvSelection- Test Vector
- References
- Authors
Conventions
There are a number of conventions adhered to throughout this document:
- HMAC: the integrity verification of the packet is based on Keyed-Hash
Message Authentication Code, as defined by the [FIPS 198
Standard][fips198]/[RFC 2104][RFC2104], and using a
SHA256hashing algorithm. - Elliptic curve: for all computations involving elliptic curves, the Bitcoin
curve is used, as specified in [
secp256k1][sec2] - Pseudo-random stream: [
ChaCha20][rfc8439] is used to generate a pseudo-random byte stream. For its generation, a fixed 96-bit null-nonce (0x000000000000000000000000) is used, along with a key derived from a shared secret and with a0x00-byte stream of the desired output size as the message. - The terms origin node and final node refer to the initial packet sender and the final packet recipient, respectively.
- The terms hop and node are sometimes used interchangeably, but a hop usually refers to an intermediate node in the route rather than an end node. origin node --> hop --> ... --> hop --> final node
- The term processing node refers to the specific node along the route that is currently processing the forwarded packet.
- The term peers refers only to hops that are direct neighbors (in the overlay network): more specifically, sending peers forward packets to receiving peers.
- Each hop in the route has a variable length
hop_payload.- The variable length
hop_payloadis prefixed with abigsizeencoding the length in bytes, excluding the prefix and the trailing HMAC.
- The variable length
Key Generation
A number of encryption and verification keys are derived from the shared secret:
- rho: used as key when generating the pseudo-random byte stream that is used to obfuscate the per-hop information
- mu: used during the HMAC generation
- um: used during error reporting
- pad: use to generate random filler bytes for the starting mix-header packet
The key generation function takes a key-type (rho=0x72686F, mu=0x6d75,
um=0x756d, or pad=0x706164) and a 32-byte secret as inputs and returns
a 32-byte key.
Keys are generated by computing an HMAC (with SHA256 as hashing algorithm)
using the appropriate key-type (i.e. rho, mu, um, or pad) as HMAC-key
and the 32-byte shared secret as the message. The resulting HMAC is then
returned as the key.
Notice that the key-type does not include a C-style 0x00-termination-byte,
e.g. the length of the rho key-type is 3 bytes, not 4.
Pseudo Random Byte Stream
The pseudo-random byte stream is used to obfuscate the packet at each hop of the
path, so that each hop may only recover the address and HMAC of the next hop.
The pseudo-random byte stream is generated by encrypting (using ChaCha20) a
0x00-byte stream, of the required length, which is initialized with a key
derived from the shared secret and a 96-bit zero-nonce (0x000000000000000000000000).
The use of a fixed nonce is safe, since the keys are never reused.
Packet Structure
The packet consists of four sections:
- a
versionbyte - a 33-byte compressed
secp256k1public_key, used during the shared secret generation - a 1300-byte
hop_payloadsconsisting of multiple, variable length,hop_payloadpayloads - a 32-byte
hmac, used to verify the packet's integrity
The network format of the packet consists of the individual sections serialized into one contiguous byte-stream and then transferred to the packet recipient. Due to the fixed size of the packet, it need not be prefixed by its length when transferred over a connection.
The overall structure of the packet is as follows:
- type:
onion_packet - data:
- [
byte:version] - [
point:public_key] - [
1300*byte:hop_payloads] - [
32*byte:hmac]
- [
For this specification (version 0), version has a constant value of 0x00.
The hop_payloads field is a structure that holds obfuscated routing information, and associated HMAC.
It is 1300 bytes long and has the following structure:
- type:
hop_payloads - data:
- [
bigsize:length] - [
length*byte:payload] - [
32*byte:hmac] - ...
filler
- [
Where, the length, payload, and hmac are repeated for each hop;
and where, filler consists of obfuscated, deterministically-generated padding, as detailed in Filler Generation.
Additionally, hop_payloads is incrementally obfuscated at each hop.
Using the payload field, the origin node is able to specify the path and structure of the HTLCs forwarded at each hop.
As the payload is protected under the packet-wide HMAC, the information it contains is fully authenticated with each pair-wise relationship between the HTLC sender (origin node) and each hop in the path.
Using this end-to-end authentication, each hop is able to cross-check the HTLC
parameters with the payload's specified values and to ensure that the
sending peer hasn't forwarded an ill-crafted HTLC.
Since no payload TLV value can ever be shorter than 2 bytes, length values of 0 and 1 are reserved. (0 indicated a legacy format no longer supported, and 1 is reserved for future use).
payload format
This is formatted according to the Type-Length-Value format defined in BOLT #1.
tlv_stream:payload- types:
- type: 2 (
amt_to_forward) - data:
- [
tu64:amt_to_forward]
- [
- type: 4 (
outgoing_cltv_value) - data:
- [
tu32:outgoing_cltv_value]
- [
- type: 6 (
short_channel_id) - data:
- [
short_channel_id:short_channel_id]
- [
- type: 8 (
payment_data) - data:
- [
32*byte:payment_secret] - [
tu64:total_msat]
- [
- type: 10 (
encrypted_recipient_data) - data:
- [
...*byte:encrypted_recipient_data]
- [
- type: 12 (
current_path_key) - data:
- [
point:path_key]
- [
- type: 16 (
payment_metadata) - data:
- [
...*byte:payment_metadata]
- [
- type: 18 (
total_amount_msat) - data:
- [
tu64:total_msat]
- [
- type: 2 (
short_channel_id is the ID of the outgoing channel used to route the
message; the receiving peer should operate the other end of this channel.
amt_to_forward is the amount, in millisatoshis, to forward to the
next receiving peer specified within the routing information, or for
the final destination.
For non-final nodes, this includes the origin node's computed fee for the receiving peer, calculated according to the receiving peer's advertised fee schema (as described in BOLT #7).
outgoing_cltv_value is the CLTV value that the outgoing HTLC
carrying the packet should have. Inclusion of this field allows a hop
to both authenticate the information specified by the origin node, and
the parameters of the HTLC forwarded, and ensure the origin node is
using the current cltv_expiry_delta value.
If the values don't correspond, this indicates that either a
forwarding node has tampered with the intended HTLC values or that the
origin node has an obsolete cltv_expiry_delta value.
The requirements ensure consistency in responding to an unexpected
outgoing_cltv_value, whether it is the final node or not, to avoid
leaking its position in the route.
Requirements
The creator of encrypted_recipient_data (usually, the recipient of payment):
- MUST create
encrypted_data_tlvfor each node in the blinded route (including itself). - MUST include
encrypted_data_tlv.payment_relayfor each non-final node. - MUST include exactly one of
encrypted_data_tlv.short_channel_idorencrypted_data_tlv.next_node_idfor each non-final node. - MUST set
encrypted_data_tlv.payment_constraintsfor each non-final node and MAY set it for the final node:max_cltv_expiryto the largest block height at which the route is allowed to be used, starting from the final node's chosenmax_cltv_expiryheight at which the route should expire, adding the final node'smin_final_cltv_expiry_deltaand then addingencrypted_data_tlv.payment_relay.cltv_expiry_deltaat each hop.htlc_minimum_msatto the largest minimum HTLC value the nodes will allow.
- If it sets
encrypted_data_tlv.allowed_features:- MUST set it to an empty array.
- MUST compute the total fees and CLTV delta of the route as follows and communicate them to the sender:
total_fee_base_msat(n+1) = (fee_base_msat(n+1) * 1000000 + total_fee_base_msat(n) * (1000000 + fee_proportional_millionths(n+1)) + 1000000 - 1) / 1000000total_fee_proportional_millionths(n+1) = ((total_fee_proportional_millionths(n) + fee_proportional_millionths(n+1)) * 1000000 + total_fee_proportional_millionths(n) * fee_proportional_millionths(n+1) + 1000000 - 1) / 1000000total_cltv_delta = cltv_delta(0) + cltv_delta(1) + ... + cltv_delta(n) + min_final_cltv_expiry_delta
- MUST create the
encrypted_recipient_datafrom theencrypted_data_tlvas required in Route Blinding.
The writer of the TLV payload:
- For every node inside a blinded route:
- MUST include the
encrypted_recipient_dataprovided by the recipient - For the first node in the blinded route:
- MUST include the
path_keyprovided by the recipient incurrent_path_key
- MUST include the
- If it is the final node:
- MUST include
amt_to_forward,outgoing_cltv_valueandtotal_amount_msat. - The value set for
outgoing_cltv_value:- MUST use the current block height as a baseline value.
- if a random offset was added to improve privacy:
- SHOULD add the offset to the baseline value.
- MUST include
- MUST NOT include any other tlv field.
- MUST include the
- For every node outside of a blinded route:
- MUST include
amt_to_forwardandoutgoing_cltv_value. - For every non-final node:
- MUST include
short_channel_id - MUST NOT include
payment_data
- MUST include
- For the final node:
- MUST NOT include
short_channel_id - if the recipient provided
payment_secret:- MUST include
payment_data - MUST set
payment_secretto the one provided - MUST set
total_msatto the total amount it will send
- MUST include
- if the recipient provided
payment_metadata:- MUST include
payment_metadatawith every HTLC - MUST not apply any limits to the size of
payment_metadataexcept the limits implied by the fixed onion size
- MUST include
- MUST NOT include
- MUST include
The reader:
- If
encrypted_recipient_datais present:- If
path_keyis set in the incomingupdate_add_htlc:- MUST return an error if
current_path_keyis present. - MUST use that
path_keyaspath_keyfor decryption.
- MUST return an error if
- Otherwise:
- MUST return an error if
current_path_keyis not present. - MUST use that
current_path_keyas thepath_keyfor decryption. - SHOULD add a random delay before returning errors.
- MUST return an error if
- MUST return an error if
encrypted_recipient_datadoes not decrypt using thepath_keyas described in Route Blinding. - If
payment_constraintsis present:- MUST return an error if:
- the expiry is greater than
encrypted_recipient_data.payment_constraints.max_cltv_expiry. - the amount is below
encrypted_recipient_data.payment_constraints.htlc_minimum_msat.
- the expiry is greater than
- MUST return an error if:
- If
allowed_featuresis missing:- MUST process the message as if it were present and contained an empty array.
- MUST return an error if:
- `encrypted_
- If
[Content truncated — view full spec at source]
Discussion (0 threads)
No discussion yet. Be the first to comment.