diff --git a/.aspell.en.pws b/.aspell.en.pws
index c9e3a0206..d247edfa7 100644
--- a/.aspell.en.pws
+++ b/.aspell.en.pws
@@ -386,3 +386,4 @@ csv
CHECKSIGVERIFY
IFDUP
sats
+onionmsg
diff --git a/01-messaging.md b/01-messaging.md
index 678393e1b..7f030d7d3 100644
--- a/01-messaging.md
+++ b/01-messaging.md
@@ -49,7 +49,7 @@ The messages are grouped logically into five groups, ordered by the most signifi
- Setup & Control (types `0`-`31`): messages related to connection setup, control, supported features, and error reporting (described below)
- Channel (types `32`-`127`): messages used to setup and tear down micropayment channels (described in [BOLT #2](02-peer-protocol.md))
- Commitment (types `128`-`255`): messages related to updating the current commitment transaction, which includes adding, revoking, and settling HTLCs as well as updating fees and exchanging signatures (described in [BOLT #2](02-peer-protocol.md))
- - Routing (types `256`-`511`): messages containing node and channel announcements, as well as any active route exploration (described in [BOLT #7](07-routing-gossip.md))
+ - Routing (types `256`-`511`): messages containing node and channel announcements, as well as any active route exploration or messaging (described in [BOLT #7](07-routing-gossip.md))
- Custom (types `32768`-`65535`): experimental and application-specific messages
The size of the message is required by the transport layer to fit into a 2-byte unsigned int; therefore, the maximum possible size is 65535 bytes.
diff --git a/04-onion-routing.md b/04-onion-routing.md
index 5677a1427..1ecfbec60 100644
--- a/04-onion-routing.md
+++ b/04-onion-routing.md
@@ -51,6 +51,7 @@ A node:
* [Legacy HopData Payload Format](#legacy-hop_data-payload-format)
* [TLV Payload Format](#tlv_payload-format)
* [Basic Multi-Part Payments](#basic-multi-part-payments)
+ * [Onion Messages](#onion-messages)
* [Accepting and Forwarding a Payment](#accepting-and-forwarding-a-payment)
* [Payload for the Last Node](#payload-for-the-last-node)
* [Non-strict Forwarding](#non-strict-forwarding)
@@ -367,6 +368,86 @@ otherwise meets the amount criterion (eg. some other failure, or
invoice timeout), however if it were to fulfill only some of them,
intermediary nodes could simply claim the remaining ones.
+### Onion Messages
+
+Onion messages have an onion with an alternate `hop_payload`
+format: a `bigsize` followed by a `onionmsg_payload`. Note that there
+is no legacy format, thus a `bigsize` of 0 means no payload.
+
+1. tlvs: `onionmsg_payload`
+2. types:
+ 1. type: 4 (`next_node_id`)
+ 2. data:
+ * [`point`:`node_id`]
+ 1. type: 6 (`next_short_channel_id`)
+ 2. data:
+ * [`short_channel_id`:`short_channel_id`]
+ 1. type: 8 (`reply_path`)
+ 2. data:
+ * [`point`:`blinding`]
+ * [`...*onionmsg_path`:`path`]
+ 1. type: 10 (`enctlv`)
+ 2. data:
+ * [`...*byte`:`enctlv`]
+ 1. type: 12 (`blinding`)
+ 2. data:
+ * [`point`:`blinding`]
+
+1. tlvs: `encmsg_tlvs`
+2. types:
+ 1. type: 4 (`next_node_id`)
+ 2. data:
+ * [`point`:`node_id`]
+ 1. type: 6 (`next_short_channel_id`)
+ 2. data:
+ * [`short_channel_id`:`short_channel_id`]
+
+1. subtype: `onionmsg_path`
+2. data:
+ * [`point`:`node_id`]
+ * [`u16`:`enclen`]
+ * [`enclen*byte`:`enctlv`]
+
+#### Requirements
+
+The writer:
+- For the non-final nodes' `onionmsg_payload`:
+ - MUST include exactly one of `next_short_channel_id`, `next_node_id`
+ or `enctlv` indicating the next node.
+- For the final node's `onionmsg_payload`:
+ - if the final node is permitted to reply:
+ - MUST set `reply_path` `blinding` to the initial blinding factor for the `next_node_id`
+ - For the first `reply_path` `path`:
+ - MUST set `node_id` to the first node in the reply path.
+ - For the remaining `reply_path` `path`:
+ - MUST set `node_id` to the blinded node id to encrypt the onion hop for.
+ - Within `reply_path` `path`:
+ - MUST encrypt `enctlv` as detailed in (FIXME: reference to t-bast's blinded path section:
+ `ChaChaPoly-1305` encryption using an all-zero nonce).
+ - MUST set `enctlv` to a valid `encmsg_tlvs` containing exactly one of either
+ `next_node_id` or `next_short_channel_id`.
+ - otherwise:
+ - MUST NOT set `reply_path`.
+
+The reader:
+- if `enctlv` is present:
+ - MUST extract the shared secret from the given `blinding` parameter and decrypt `enctlv`.
+ - MUST drop the message if `enctlv` is not a valid TLV.
+ - MUST use `next_short_channel_id` or `next_node_id` from `enctlv`.
+- Otherwise:
+ - MUST use `next_short_channel_id` or `next_node_id` from `onionmsg_payload`.
+
+- if it is not the final node according to the onion encryption:
+ - if `next_short_channel_id` or `next_node_id` is found:
+ - SHOULD forward the message using `onion_message` to the indicated peer if possible.
+
+- otherwise:
+ - if it wants to send a reply:
+ - MUST create an onion encoding using `reply_path`.
+ - MUST send the reply via `onion_message` to the node indicated by
+ the first element of `reply_path` `path` using `reply_path` `blinding`.
+
+
# Accepting and Forwarding a Payment
Once a node has decoded the payload it either accepts the payment locally, or forwards it to the peer indicated as the next hop in the payload.
diff --git a/07-routing-gossip.md b/07-routing-gossip.md
index b89c3d222..10eee0690 100644
--- a/07-routing-gossip.md
+++ b/07-routing-gossip.md
@@ -1,4 +1,4 @@
-# BOLT #7: P2P Node and Channel Discovery
+# BOLT #7: P2P Node and Channel Discovery and Onion Messages
This specification describes simple node discovery, channel discovery, and channel update mechanisms that do not rely on a third-party to disseminate the information.
@@ -33,6 +33,7 @@ To support channel and node discovery, three *gossip messages* are supported:
* [HTLC Fees](#htlc-fees)
* [Pruning the Network View](#pruning-the-network-view)
* [Recommendations for Routing](#recommendations-for-routing)
+ * [Onion Messages](#onion-messages)
* [References](#references)
## Definition of `short_channel_id`
@@ -1119,7 +1120,58 @@ A->D's `update_add_htlc` message would be:
And D->C's `update_add_htlc` would again be the same as B->C's direct payment
above.
-## References
+# Onion Messages
+
+Onion messages allow peers to use existing connections to query for
+invoices (see [BOLT 12](12-offer-encoding.md)). Like gossip messages,
+they are not associated with a particular local channel. Like HTLCs,
+they use [BOLT 4](04-onion-routing.md#onion-messages) protocol for
+end-to-end encryption.
+
+Onion messages are unreliable: in particular, they are designed to
+be cheap to process and require no storage to forward. As a result,
+there is no error returned from intermediary nodes.
+
+To enable messaging via blinded paths, there is an optional `blinding`
+parameter which allows decryption of the `enctlv` field inside the
+`onionmsg`'s `onionmsg_payload`.
+
+## The `onion_message` Message
+
+1. type: 385 (`onion_message`) (`option_onion_messages`)
+2. data:
+ * [`u16`:`len`]
+ * [`len*byte`:`onionmsg`]
+ * [`onion_message_tlvs`:`onion_message_tlvs`]
+
+1. tlvs: `onion_message_tlvs`
+2. types:
+ 1. type: 2 (`blinding`)
+ 2. data:
+ * [`point`:`blinding`]
+
+## Requirements
+
+The writer:
+- MUST populate the per-hop payloads as described in [BOLT 4](04-onion-routing.md#onion-messages).
+- SHOULD retry via a different route if it expects a response and
+ doesn't receive one after a reasonable period.
+- SHOULD set `len` to 1366 or 32834.
+
+The reader:
+- MUST handle the per-hop payloads as described in [BOLT 4](04-onion-routing.md#onion-messages).
+- SHOULD accept onion messages from peers without an established channel.
+- MAY rate-limit messages by dropping them.
+
+## Rationale
+
+`len` allows larger messages to be sent than the standard 1300 bytes
+allowed for an HTLC onion, but this should be used sparingly as it is
+reduces anonymity set, hence the recommendation that it either look
+like an HTLC onion, or if larger, be a fixed size.
+
+
+# References
1. [RFC 1950 "ZLIB Compressed Data Format Specification version 3.3](https://www.ietf.org/rfc/rfc1950.txt)
2. [Maximum Compression Factor](https://zlib.net/zlib_tech.html)
diff --git a/09-features.md b/09-features.md
index ea37b8b5e..a9b0d1ed5 100644
--- a/09-features.md
+++ b/09-features.md
@@ -40,6 +40,7 @@ The Context column decodes as follows:
| 18/19 | `option_support_large_channel` | Can create large channels | IN | | [BOLT #2](02-peer-protocol.md#the-open_channel-message) |
| 20/21 | `option_anchor_outputs` | Anchor outputs | IN | `option_static_remotekey` | [BOLT #3](03-transactions.md) |
| 22/23 | `option_anchors_zero_fee_htlc_tx` | Anchor commitment type with zero fee HTLC transactions | IN | | [BOLT #3][bolt03-htlc-tx], [lightning-dev][ml-sighash-single-harmful]|
+| 102/103 | `option_onion_messages` | Can forward onion messages | IN9 | | [BOLT #7](07-routing-gossip.md#onion-messages) |
## Requirements