Skip to content

Commit 92553fb

Browse files
committed
BOLT 4: add minitramp support.
We use the same "encrypted blob inside onion" trick as blinded paths, but using TLV 1, so it's ignored for backward compatibility. In this case, we need to tell the trampoline the `payment_secret` (and optional `payment_metadata`) to put in the onion, which gives it the possibility of probing, or even underpaying amountless invoices. However, if the final hop *does* support TLV 1, it can detect interference and refuse attempts to pay that same invoice (since there's a dishonest trampoline), providing *some* honesty incentive. Signed-off-by: Rusty Russell <[email protected]>
1 parent 14272b1 commit 92553fb

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed

04-onion-routing.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,10 @@ This is formatted according to the Type-Length-Value format defined in [BOLT #1]
189189

190190
1. `tlv_stream`: `payload`
191191
2. types:
192+
1. type: 1 (`minitramp`)
193+
2. data:
194+
* [`pubkey`:`trampkey`]
195+
* [`...*byte`:`encrypted_trampinfo`]
192196
1. type: 2 (`amt_to_forward`)
193197
2. data:
194198
* [`tu64`:`amt_to_forward`]
@@ -635,6 +639,127 @@ sender, containing instructions for the node on how to handle the message (it ca
635639
in both payment onions and onion messages onions. See [Route Blinding](#route-blinding).
636640

637641

642+
# Minitrampoline Support
643+
644+
This allows outsourcing routing, with limited privacy protections. The destination notes the `encrypted_trampinfo` field in the onion payload, and decrypts it to find `trampinfo` tlv stream, which indicates the next recipient, and a `encrypted_trampinfo` for that recipient (which may be the final recipient).
645+
646+
We share the encryption scheme used by the onion, except the key is explicitly given in the `trampkey` tlv field.
647+
648+
The `trampinfo` can contain another `encrypted_trampinfo` to allow for chaining minitrampolines. It is odd, so if the final recipient does not support `option_minitrampoline` it will ignore it: in this case the `payment_secret` and `payment_metadata` fields must be the correct ones for the payment, thus trusting the final minitrampoline node in the case of amountless bolt11 invoices.
649+
650+
Encryption is done using the same scheme as `encrypted_recipient_data`, with `trampkey` as `E`:
651+
- $`ss = SHA256(k * E)`$ (standard ECDH)
652+
- $`rho = HMAC256(\text{"rho"}, ss)`$
653+
- Use $`rho`$ as a key with ChaCha20-Poly1305 and an all-zero nonce key.
654+
655+
If the final destination does not support `encrypted_trampinfo` it will ignore the `minitramp` field, so in this case the `payment_secret` and `payment_metadata` have to be correct for the payment: if the payment is not for a specified amount, this may allow the final trampoline to try forwarding less than the full amount. However, if the final destination does understand `encrypted_trampinfo` then it will ensure the amounts, `payment_secret` and `payment_metadata` are correct, and it will never accept future attempts to pay this invoice if it detects a discrepancy. This unknown helps keep the trampoline nodes honest while the network transitions.
656+
657+
658+
1. `tlv_stream`: `minitramp_payload`
659+
2. types:
660+
1. type: 1 (`minitramp`)
661+
2. data:
662+
* [`pubkey`:`trampkey`]
663+
* [`...*byte`:`encrypted_trampinfo`]
664+
1. type: 2 (`amount_to_send`)
665+
2. data:
666+
* [`tu64`:`amount`]
667+
1. type: 4 (`next_cltv_value`)
668+
2. data:
669+
* [`tu32`:`next_cltv_value`]
670+
1. type: 6 (`next_node`)
671+
2. data:
672+
* [`publey`:`next`]
673+
1. type: 8 (`incoming_payment_secret`)
674+
2. data:
675+
* [`32*byte`:`payment_secret`]
676+
1. type: 10 (`incoming_payment_metadata`)
677+
2. data:
678+
* [`...*byte`:`payment_metadata`]
679+
1. type: 12 (`incoming_amount_msat`)
680+
2. data:
681+
* [`tu64`:`msat`]
682+
1. type: 14 (`incoming_ctlv`)
683+
2. data:
684+
* [`tu32`:`ctlv`]
685+
1. type: 16 (`outgoing_payment_secret`)
686+
2. data:
687+
* [`32*byte`:`payment_secret`]
688+
1. type: 18 (`outgoing_payment_metadata`)
689+
2. data:
690+
* [`...*byte`:`payment_metadata`]
691+
1. type: 20 (`blinded_paths`)
692+
2. data:
693+
* [`...*blinded_path`:`paths`]
694+
1. type: 22 (`blinded_payinfo`)
695+
2. data:
696+
* [`...*blinded_payinfo`:`payinfo`]
697+
698+
## Requirements
699+
700+
The initial sender of a "minitramp" payment builds it backwards from final destination:
701+
- MUST create a `trampinfo` (#1) for the payment destination:
702+
- MUST NOT set `amount_to_send`, `next_cltv_value`, `next_node`, `blinded_paths`, `blinded_payinfo` or `minitramp`.
703+
- MUST set `outgoing_payment_secret`, `outgoing_payment_metadata`, `total_amount_msat` to the values which would normally set in the final `payload`.
704+
- If the payment destination is known to support `option_minitrampoline`:
705+
- SHOULD set `incoming_payment_secret` and `incoming_payment_metadata` to random data (16 bytes in the case of `incoming_payment_metadata`).
706+
- Otherwise:
707+
- MUST set `incoming_payment_secret` and `incoming_payment_metadata` to `outgoing_payment_secret` and `outgoing_payment_metadata`.
708+
- MAY use `padding` to disguise that this is the final destination.
709+
- MUST create a `trampinfo` (#2) for the previous trampoline:
710+
- MUST set `minitramp`.`trampkey` to the public key of a random secret.
711+
- MUST set `minitramp`.`encrypted_trampinfo` to the encrypted `trampinfo` created for the payment destination.
712+
- MUST set `outgoing_payment_secret` to `incoming_payment_secret` in `trampinfo` #1.
713+
- MUST set `outgoing_payment_metadata` to `incoming_payment_metadata` in `trampinfo` #1.
714+
- MUST set `amount_to_send` and `next_cltv_value` to the values expected by the payment destination.
715+
- MUST set `blinded_paths` and `blinded_payinfo` as supplied by the invoice.
716+
- If it sets `blinded_paths`:
717+
- MUST NOT set `next_node`.
718+
- Otherwise:
719+
- MUST set `next_node` to the node id of the payment destination.
720+
- MUST set `incoming_amount_msat` and `incoming_ctlv` to the values expected at this destination.
721+
- MUST set `total_amount_msat` to the `incoming_amount_msat` of `trampinfo` #1
722+
- MUST set `next_cltv_value` to the `incoming_ctlv` of `trampinfo` #1
723+
- SHOULD set `incoming_payment_secret` and `incoming_payment_metadata` to random data (16 bytes in the case of `incoming_payment_metadata`).
724+
- If it creates another `trampinfo` (#3 onwards);
725+
- MUST set `minitramp`.`trampkey` to the public key of a random secret.
726+
- MUST set `minitramp`.`encrypted_trampinfo` to the encrypted previous `trampinfo`
727+
- MUST set `outgoing_payment_secret` to `incoming_payment_secret` in the previous `trampinfo`.
728+
- MUST set `outgoing_payment_metadata` to `incoming_payment_metadata` in the previous `trampinfo`.
729+
- SHOULD set `incoming_payment_secret` and `incoming_payment_metadata` to random data (16 bytes in the case of `incoming_payment_metadata`).
730+
- MUST set `total_amount_msat` to the `incoming_amount_msat` of the previous `trampinfo`
731+
- MUST set `next_cltv_value` to the `incoming_ctlv` of the previous `trampinfo`
732+
- MUST set `next_node` to the node id of the next trampoline
733+
- MUST create a payment to the first trampoline node:
734+
- MUST put the last-produced `minitramp` into the final `payload` for each payment part.
735+
- MUST set `payment_secret` and `payment_metadata` to the `incoming_payment_secret` and `incoming_payment_metadata` of the last-produced `trampinfo`.
736+
737+
The recipient:
738+
- MUST process all parts of the payment as normal.
739+
- If this is the final node (no more onion to unwrap), and `minitramp` is present:
740+
- If `encrypted_trampinfo` does not decrypt into a valid `trampinfo`:
741+
- Return an error (FIXME)
742+
- If `trampinfo`.`incoming_amount_msat` or `trampinfo`.`incoming_ctlv` are not equal to the incoming HTLC
743+
- Reject payment
744+
- If neither `node_id` nor `blinded_paths` are present (we are the final destination):
745+
- If `payment_secret` in `payload` is not equal to `trampinfo`.`incoming_payment_secret`:
746+
- Don't ever accept payment of this invoice
747+
- Reject payment
748+
- If `payment_metadata` in `payload` is not equal to `trampinfo`.`incoming_payment_metadata`:
749+
- Don't ever accept payment of this invoice
750+
- Reject payment
751+
- Otherwise: (forwarding):
752+
- If both `next_node` and `blinded_paths` are present:
753+
- Reject
754+
- Determine a route to `next_node` or `blinded_paths` for `amount_to_send` using `next_cltv_value`.
755+
- If the incoming amount or cltv is insufficient:
756+
- Don't ever accept payment of this invoice
757+
- Reject payment
758+
- If the number of `blinded_paths` and `blinded_payinfo` do not match:
759+
- Reject
760+
- MUST include `trampinfo`.`minitramp`, `outgoing_payment_secret` (as `payment_secret`) and `outgoing_payment_info` (as `payment_metadata`) in the inner `payload` of the payment onion.
761+
762+
638763
# Accepting and Forwarding a Payment
639764

640765
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.

09-features.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ The Context column decodes as follows:
5454
| 48/49 | `option_payment_metadata` | Payment metadata in tlv record | 9 | | [BOLT #11](11-payment-encoding.md#tagged-fields) |
5555
| 50/51 | `option_zeroconf` | Understands zeroconf channel types | INT | `option_scid_alias` | [BOLT #2][bolt02-channel-ready] |
5656
| 60/61 | `option_simple_close` | Simplified closing negotiation | IN | `option_shutdown_anysegwit` | [BOLT #2][bolt02-simple-close] |
57+
| 58/59 | `option_minitrampoline` | Will forward payments via encrypted instructions | IN | | [BOLT #4][bolt04-minitramp] |
5758

5859
## Requirements
5960

@@ -107,5 +108,6 @@ This work is licensed under a [Creative Commons Attribution 4.0 International Li
107108
[bolt07-sync]: 07-routing-gossip.md#initial-sync
108109
[bolt07-query]: 07-routing-gossip.md#query-messages
109110
[bolt04-mpp]: 04-onion-routing.md#basic-multi-part-payments
111+
[bolt04-minitramp]: 04-onion-routing.md#minitrampoline-support
110112
[bolt04-route-blinding]: 04-onion-routing.md#route-blinding
111113
[ml-sighash-single-harmful]: https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-September/002796.html

0 commit comments

Comments
 (0)