|
| 1 | +/// The payload of an onion message. |
| 2 | +struct Payload { |
| 3 | + /// Onion message payloads contain an encrypted TLV stream, containing both "control" TLVs and |
| 4 | + /// sometimes user-provided custom "data" TLVs. See [`EncryptedTlvs`] for more information. |
| 5 | + encrypted_tlvs: EncryptedTlvs, |
| 6 | + // Coming soon: |
| 7 | + // message: Message |
| 8 | + |
| 9 | + // Coming soon: custom TLVs |
| 10 | + |
| 11 | + // Coming soon: |
| 12 | + // reply_path: BlindedRoute, |
| 13 | +} |
| 14 | + |
| 15 | +impl Writeable for Payload { |
| 16 | + fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> { |
| 17 | + // calls: |
| 18 | + // * ChaCha20Poly1305RFC::encrypt_in_place |
| 19 | + } |
| 20 | +} |
| 21 | + |
| 22 | +// Coming soon: |
| 23 | +// enum Message { |
| 24 | +// InvoiceRequest(InvoiceRequest), |
| 25 | +// Invoice(Invoice), |
| 26 | +// InvoiceError(InvoiceError), |
| 27 | + |
| 28 | +/// Onion messages contain an encrypted TLV stream. This can be supplied by someone else, in the |
| 29 | +/// case that we're sending to a blinded route, or created by us if we're constructing payloads for |
| 30 | +/// unblinded hops in the onion message's path. |
| 31 | +enum EncryptedTlvs { |
| 32 | + /// If we're sending to a blinded route, the node that constructed the blinded route has provided |
| 33 | + /// our onion message's `EncryptedTlvs`, already encrypted and encoded into bytes. |
| 34 | + Blinded(Vec<u8>), |
| 35 | + /// If we're receiving an onion message or constructing an onion message to send through any |
| 36 | + /// unblinded nodes, we'll need to construct the onion message's `EncryptedTlvs` in their |
| 37 | + /// unblinded state to avoid encoding them into an intermediate `Vec`. |
| 38 | + // Below will later have an additional Vec<CustomTlv> |
| 39 | + Unblinded(ControlTlvs, SharedSecret), |
| 40 | +} |
| 41 | + |
| 42 | +/// Onion messages have "control" TLVs and "data" TLVs. Control TLVs are used to control the |
| 43 | +/// direction and routing of an onion message from hop to hop, whereas data TLVs contain the onion |
| 44 | +/// message content itself. |
| 45 | +enum ControlTlvs { |
| 46 | + /// Control TLVs for the final recipient of an onion message. |
| 47 | + Receive { |
| 48 | + /// If `path_id` is `Some`, it is used to identify the blinded route that this onion message is |
| 49 | + /// sending to. This is useful for receivers to check that said blinded route is being used in |
| 50 | + /// the right context. |
| 51 | + path_id: Option<[u8; 32]> |
| 52 | + }, |
| 53 | + /// Control TLVs for an intermediate forwarder of an onion message. |
| 54 | + Forward { |
| 55 | + /// The node id of the next hop in the onion message's path. |
| 56 | + next_node_id: PublicKey, |
| 57 | + /// Senders of onion messages have the option of specifying an overriding [`blinding_point`] |
| 58 | + /// for forwarding nodes along the path. If this field is absent, forwarding nodes will |
| 59 | + /// calculate the next hop's blinding point by multiplying the blinding point that they |
| 60 | + /// received by a blinding factor. |
| 61 | + /// |
| 62 | + /// [`blinding_point`]: crate::ln::msgs::OnionMessage::blinding_point |
| 63 | + next_blinding_override: Option<PublicKey>, |
| 64 | + } |
| 65 | +} |
| 66 | + |
1 | 67 | /// Used to construct the blinded hops portion of a blinded route. These hops cannot be identified
|
2 | 68 | /// by outside observers and thus can be used to hide the identity of the recipient.
|
3 | 69 | pub struct BlindedNode {
|
4 | 70 | /// The blinded node id of this hop in a blinded route.
|
5 | 71 | pub blinded_node_id: PublicKey,
|
6 | 72 | /// The encrypted payload intended for this hop in a blinded route.
|
| 73 | + // If we're sending to this blinded route, this payload will later be encoded into the |
| 74 | + // [`EncryptedTlvs`] for the hop when constructing the onion packet for sending. |
| 75 | + // |
| 76 | + // [`EncryptedTlvs`]: EncryptedTlvs |
7 | 77 | pub encrypted_payload: Vec<u8>,
|
8 | 78 | }
|
9 | 79 |
|
@@ -74,14 +144,36 @@ impl<Signer: Sign, K: Deref> OnionMessager<Signer, K>
|
74 | 144 |
|
75 | 145 | /// Send an empty onion message to `recipient`, routing it through `intermediate_nodes`.
|
76 | 146 | // NOTE: sending custom TLVs and reply paths aren't included atm
|
77 |
| - pub fn send_onion_message(&self, recipient: Destination, intermediate_nodes: Vec<PublicKey>) -> Result<(), APIError> {} |
| 147 | + pub fn send_onion_message(&self, recipient: Destination, intermediate_nodes: Vec<PublicKey>) -> Result<(), APIError> { |
| 148 | + // calls: |
| 149 | + // * construct_path_keys |
| 150 | + // * build_payloads |
| 151 | + // * onion_utils::construct_onion_message_packet |
| 152 | + } |
78 | 153 | }
|
79 | 154 |
|
80 | 155 | impl OnionMessageHandler for OnionMessager {
|
81 | 156 | fn handle_onion_message(&self, peer_node_id: &PublicKey, msg: &msgs::OnionMessage) {
|
82 | 157 | }
|
83 | 158 | }
|
84 | 159 |
|
| 160 | +/// Construct keys for sending an onion message along the given `path`. |
| 161 | +/// |
| 162 | +/// Returns: `(encrypted_tlvs_keys, onion_packet_keys, blinded_node_ids)` |
| 163 | +/// where the encrypted tlvs keys are used to encrypt the `EncryptedTlvs` of the onion message, the |
| 164 | +/// onion packet keys are used to encrypt the onion packet, and the blinded node ids are used to set |
| 165 | +/// the [`blinded_node_id`]s if we're constructing a [`BlindedRoute`]. |
| 166 | +/// |
| 167 | +/// [`blinded_node_id`]: BlindedNode::blinded_node_id |
| 168 | +/// [`BlindedRoute`]: BlindedRoute |
| 169 | +fn construct_path_keys<T: secp256k1::Signing + secp256k1::Verification>( |
| 170 | + secp_ctx: &Secp256k1<T>, unblinded_hops: Vec<PublicKey>, blinded_hops: Vec<PublicKey>, |
| 171 | + session_priv: &SecretKey) |
| 172 | +-> Result<(Vec<SharedSecret>, Vec<onion_utils::OnionKeys>, Vec<PublicKey>), secp256k1::Error> {} |
| 173 | + |
| 174 | +/// Build an onion message's payloads for encoding in the onion packet. |
| 175 | +fn build_payloads(blinding_secret: SecretKey, intermediate_nodes: Vec<PublicKey>, destination: Destination, encrypted_data_keys: Vec<SharedSecret>) -> Vec<Payload> {} |
| 176 | + |
85 | 177 | /// Useful for simplifying the parameters of [`SimpleArcChannelManager`] and
|
86 | 178 | /// [`SimpleArcPeerManager`]. See their docs for more details.
|
87 | 179 | pub type SimpleArcOnionMessager = OnionMessager<Arc<KeysManager>>;
|
|
0 commit comments