|
| 1 | +``` |
| 2 | +bLIP: 39 |
| 3 | +Title: BOLT 11 Invoice Blinded Path Tagged Field |
| 4 | +Author: Elle Mouton <[email protected]> |
| 5 | +Status: Draft |
| 6 | +Created: 2024-07-08 |
| 7 | +* Post-History: 2024-06-26: https://delvingbitcoin.org/t/blip-bolt-11-invoice-blinded-path-tagged-field/991 |
| 8 | +License: CC0 |
| 9 | +``` |
| 10 | + |
| 11 | +## Abstract |
| 12 | + |
| 13 | +This bLIP defines a new [tagged field][tagged-fields] for the payment invoice |
| 14 | +encoding described by [BOLT 11][bolt11] which can be used to communicate |
| 15 | +encoded blinded path information to the payer of the invoice. |
| 16 | + |
| 17 | +## Copyright |
| 18 | + |
| 19 | +This bLIP is licensed under the CC0 license. |
| 20 | + |
| 21 | +## Rational |
| 22 | + |
| 23 | +Blinded paths have been included in the [BOLT 4 specification][blinded-paths] |
| 24 | +and using them in the context of receiving payments is natively supported in |
| 25 | +the [BOLT 12 Offers proposal][offers]. However, the Offers proposal also |
| 26 | +includes various other dependencies such as onion messaging and various new |
| 27 | +protocol message all of which will require a network wide upgrade before full |
| 28 | +advantage can be taken of the new protocol. Blinded paths themselves are a |
| 29 | +useful tool for privacy and potentially more reliable payment delivery due to |
| 30 | +receiver being able to select paths it knows to be more reliable. This document |
| 31 | +proposes a carve-out to the existing [BOLT 11][bolt11] invoice format so that |
| 32 | +testing of blinded paths can be done in implementations that have not yet |
| 33 | +implemented the full Offers specification. This will be done by adding a new |
| 34 | +tagged-field type to the BOLT 11 invoice specification that will encode a |
| 35 | +blinded payment path. With this bLIP, the sender and the receiver of a payment |
| 36 | +will need to be aware of the new tagged-field and the receiver will need to |
| 37 | +support route blinding and ideally have direct channel peers who also support |
| 38 | +route blinding in order to start widening their anonymity set. |
| 39 | + |
| 40 | +## Specification |
| 41 | + |
| 42 | +### Feature Bit |
| 43 | + |
| 44 | +A new feature bit, `bolt11_blinded_path`, for the `I` context will be added |
| 45 | +using bits from the experimental range. This is required because the BOLT 11 |
| 46 | +tagged-fields pre-date the TLV format and so nodes parsing the invoice will just |
| 47 | +skip fields they don't know as there is no concept of "It's OK to be odd". This |
| 48 | +feature bit thus allows nodes to fail fast if they do not yet understand the new |
| 49 | +tagged field. |
| 50 | + |
| 51 | +### Tagged Field |
| 52 | + |
| 53 | +The proposal is to add the following new [tagged field][tagged-fields] to the |
| 54 | +set defined in [BOLT 11][bolt11]: |
| 55 | + |
| 56 | +- `b` (20): `data_length` variable. One or more entries each containing a |
| 57 | + blinded payment path for a private route; there may be more than one `b` |
| 58 | + field. The field uses the `blinded_payinfo` type described below which draws |
| 59 | + heavily on the proposed encoding of the `blinded_payinfo` subtype defined in |
| 60 | + the [Offers proposal][offers]. |
| 61 | + |
| 62 | +1. subtype: `blinded_payinfo` |
| 63 | +2. data: |
| 64 | + * [`u32`:`fee_base_msat`] |
| 65 | + * [`u32`:`fee_proportional_millionths`] |
| 66 | + * [`u16`:`cltv_expiry_delta`] |
| 67 | + * [`u64`:`htlc_minimum_msat`] |
| 68 | + * [`u64`:`htlc_maximum_msat`] |
| 69 | + * [`u16`:`flen`] |
| 70 | + * [`flen*byte`:`features`] |
| 71 | + * [`33*byte`:`first_ephemeral_blinding_point`] |
| 72 | + * [`byte`:`num_hops`] |
| 73 | + * [`num_hops*blinded_hop`:`blinded_hops`] |
| 74 | + |
| 75 | +1. subtype: `blinded_hop` |
| 76 | +2. data: |
| 77 | + * [`33*byte`:`blinded_node_pubkey`] |
| 78 | + * [`bigsize`: `cipher_text_length`] |
| 79 | + * [`cipher_text_length*byte`:`cipher_text`] |
| 80 | + |
| 81 | +The `blinded_node_pubkey` of the first `blinded_hop` in a `blinded_payinfo` is |
| 82 | +the real public key of the blinded path's introduction node. This encoding was |
| 83 | +chosen so that `num_hops` accurately reflects the true number of hops including |
| 84 | +the introduction node while keeping the number of bytes required for the |
| 85 | +encoding to a minimum. The `cipher_text` is the `encrypted_recipient_data` as |
| 86 | +defined in [BOLT 4 TLV payload][bolt4-payload]. |
| 87 | + |
| 88 | +The `fee_base_msat`, `fee_proportional_millionths` and `cltv_expiry_delta` are |
| 89 | +the accumulated blinded route policy values as defined in [BOLT 4][bolt4-relay]. |
| 90 | +`features` is the set of features for the path, `first_ephemeral_blinding_point` |
| 91 | +is the blinding point that must be communicated to the introduction node via the |
| 92 | +`blinding` field of the [`payload`][bolt4-payload] type. |
| 93 | + |
| 94 | +** Note: see discussion section for question around communicating |
| 95 | +`max_cltv_expiry` ** |
| 96 | + |
| 97 | +### Requirements |
| 98 | + |
| 99 | +An invoice containing the `b` field type: |
| 100 | +- MUST not contain the `r` field type. |
| 101 | +- MUST not contain the `s` field type since a payment address in the context of |
| 102 | + blinded payments does not make sense since the recipient is able to use the |
| 103 | + `path_id` in the `encrypted_recipient_data` for the same purpose. |
| 104 | +- SHOULD sign the invoice with a private key that is not the same as their |
| 105 | + public node ID and should not set the destination node (`n` field). |
| 106 | +- Each `blinded_path` must fit within the `data_length` size limit. This places |
| 107 | + an upper limit of approximately 7 `blinded_hops` on each path. See the |
| 108 | + appendix for the estimation calculation. |
| 109 | +- If the invoice will be displayed in QR form, then this also places an upper |
| 110 | + limit on the number of `blinded_path` fields that can be added to the |
| 111 | + invoice. |
| 112 | +- The existing `c` field (`min_final_cltv_expiry_delta`) is meaningless for an |
| 113 | + invoice containing the `b` field since this value is expected to be accounted |
| 114 | + for in each path's accumulated `cltv_expiry_delta`. |
| 115 | +- The existing invoice `expiry` field along with the `timestamp` field |
| 116 | + should be used to communicate the `max_cltv_expiry` of the blinded paths in |
| 117 | + the invoice. The reader should use the 10-minutes-per-block assumption to |
| 118 | + calculate an estimation of the `max_cltv_exipiry` value. |
| 119 | + |
| 120 | +## Universality |
| 121 | + |
| 122 | +This proposal is a temporary measure that will allow users to start making use |
| 123 | +of blinded paths in the context of payments and thereby take advantage of the |
| 124 | +potential privacy and payment success rate benefits that they will in theory |
| 125 | +provide. Once the Offers protocol along with its new invoice format has been |
| 126 | +widely deployed, then there will be no use for this BOLT 11 carve-out. Due to |
| 127 | +the forcasted temporary use of the new field, it makes sense to be in bLIP form |
| 128 | +rather than adding this in a more temporary way to the spec via a BOLT update |
| 129 | +proposal. The intent is that this will be used mostly for testing of blinded |
| 130 | +paths in implementations that have not yet implemented the full Offers spec. |
| 131 | + |
| 132 | +## Backwards Compatibility |
| 133 | + |
| 134 | +BOLT 11 states that the reader of an invoice "MUST skip over unknown fields". |
| 135 | +This means that an un-updated reader of an invoice that includes the new tagged |
| 136 | +field would skip it when parsing the invoice. The proposal also adds a new |
| 137 | +feature bit to the invoice feature bit vector and so this gives nodes an |
| 138 | +indication that the invoice includes something they do not yet understand. |
| 139 | +Even if un-upgraded senders did not check the feature bit vector, they would not |
| 140 | +be able to use the invoice as, without knowledge of the blinded path field, it |
| 141 | +does not contain enough information to attempt a payment since no routing hints |
| 142 | +will be included and the invoice will be signed with a random ephemeral key |
| 143 | +meaning that the derived destination node would not correspond to a real node |
| 144 | +in the graph. |
| 145 | + |
| 146 | +## Reference Implementations |
| 147 | + |
| 148 | +The proposed encoding of the new BOLT 11 tagged-field is added to the LND |
| 149 | +implementation in [this PR][impl]. |
| 150 | + |
| 151 | +## Appendix |
| 152 | + |
| 153 | +### Test Vector |
| 154 | + |
| 155 | +The following string is an example of a BOLT11 invoice containing 2 blinded |
| 156 | +paths, one with 1 hop and one with 3 hops. |
| 157 | + |
| 158 | +``` |
| 159 | +lnbc20m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4js5fdqqqqq2qqqqqpgqyzqqqqqqqqqqqqyqqqqqqqqqqqvsqqqqlnxy0ffrlt2y2jgtzw89kgr3zg4dlwtlfycn3yuek8x5eucnuchqps82xf0m2u6sx5wnjw7xxgnxz5kf09quqsv5zvkgj7d5kpzttp4qz7q5qsyqcyq5pzq2feycsemrh7wvendc4kw3tsmkt25a36ev6kfehrv7ecfkrp5zs9q5zqxqspqtr4avek5quzjn427asptzews5wrczfhychr2sq6ue9phmn35tjqcrspqgpsgpgxquyqjzstpsxsu59zqqqqqpqqqqqqyqq2qqqqqqqqqqqqqqqqqqqqqqqqpgqqqqk8t6endgpc99824amqzk9japgu8synwf3wx4qp4ej2r0h8rghypsqsygpf8ynzr8vwleenxdhzke69wrwed2nk8t9n2e8xudnm8pxcvxs2q5qsyqcyq5y4rdlhtf84f8rgdj34275juwls2ftxtcfh035863q3p9k6s94hpxhdmzfn5gxpsazdznxs56j4vt3fdhe00g9v2l3szher50hp4xlggqkxf77f |
| 160 | +``` |
| 161 | + |
| 162 | +Breakdown: |
| 163 | + |
| 164 | +This invoice was signed with `priv_key`=`e126f68f7eafcc8b74f54d269fe206be715000f94dac067d1c04a8ca3b2db734`. |
| 165 | +It does _not_ contain a payment secret. |
| 166 | + |
| 167 | +* `lnbc`: prefix, Lightning on Bitcoin mainnet |
| 168 | +* `20m`: amount (20 milli-bitcoin) |
| 169 | +* `1`: Bech32 separator |
| 170 | +* `pvjluez`: timestamp (1496314658) |
| 171 | +* `p`: payment hash (0001020304050607080900010203040506070809000102030405060708090102) |
| 172 | +* `d`: description: '1 cup coffee' |
| 173 | +* `b`: blinded path: |
| 174 | + * `fee_base_msat`: 40 |
| 175 | + * `fee_proportional_millionths`: 20 |
| 176 | + * `cltv_expiry_delta`: 130 |
| 177 | + * `htlc_minimum_msat`: 2 |
| 178 | + * `htlc_maximum_msat`: 100 |
| 179 | + * `flen`: 0 |
| 180 | + * `first_ephemeral_blinding_point`: 03f3311e948feb5115242c4e396c81c448ab7ee5fd24c4e24e66c73533cc4f98b8 |
| 181 | + * `num_hops`: 3 |
| 182 | + * `blinded_hops`: |
| 183 | + * `blinded_node_pubkey`: 03a8c97ed5cd40d474e4ef18c899854b25e5070106504cb225e6d2c112d61a805e |
| 184 | + * `cipher_text`: 0102030405 |
| 185 | + * `blinded_node_pubkey`: 0220293926219d8efe733336e2b674570dd96aa763acb3564e6e367b384d861a0a |
| 186 | + * `cipher_text`: 0504030201 |
| 187 | + * `blinded_node_pubkey`: 02c75eb336a038294eaaf760158b2e851c3c0937262e35401ae64a1bee71a2e40c |
| 188 | + * `cipher_text`: 0102030405060708090a0b0c0d0e |
| 189 | +* `b`: blinded path: |
| 190 | + * `fee_base_msat`: 4 |
| 191 | + * `fee_proportional_millionths`: 2 |
| 192 | + * `cltv_expiry_delta`: 10 |
| 193 | + * `htlc_minimum_msat`: 0 |
| 194 | + * `htlc_maximum_msat`: 10 |
| 195 | + * `flen`: 0 |
| 196 | + * `first_ephemeral_blinding_point`: 02c75eb336a038294eaaf760158b2e851c3c0937262e35401ae64a1bee71a2e40c |
| 197 | + * `num_hops`: 1 |
| 198 | + * `blinded_hops`: |
| 199 | + * `blinded_node_pubkey`: 0220293926219d8efe733336e2b674570dd96aa763acb3564e6e367b384d861a0a |
| 200 | + * `cipher_text`: 0102030405 |
| 201 | + |
| 202 | +### Size Restrictions |
| 203 | + |
| 204 | +#### `data_length` Limit |
| 205 | + |
| 206 | +In order to conform to any existing BOLT 11 invoice parser, each new tagged |
| 207 | +field must use the `data_length` encoding defined there. This means that the |
| 208 | +maximum size of any _single_ encoded blinded path is 639 bytes. |
| 209 | + |
| 210 | +What follows is a rough estimation of the maximum number of hops we can include |
| 211 | +in a single blinded path. It assumes that each hop's cipher text is the same |
| 212 | +length. |
| 213 | + |
| 214 | +##### Cipher Text Size Estimation |
| 215 | + |
| 216 | +First, a rough estimation of the average cipher text length is required. A |
| 217 | +forwarding node in a blinded path will receive a cipher text payload containing |
| 218 | +the following data: |
| 219 | + |
| 220 | +- `padding`: optional |
| 221 | +- `short_channel_id` of 8 bytes |
| 222 | +- `payment_relay`: |
| 223 | + * 2 byte `cltv_expiry_delta` |
| 224 | + * 4 byte `fee_proportional_millionths` |
| 225 | + * 4 byte `fee_base_msat` |
| 226 | +- `payment_constraints`: |
| 227 | + * 4 byte `max_cltv_expiry` |
| 228 | + * 8 byte `htlc_minimum_msat` |
| 229 | +- `allowed_features`: optional |
| 230 | + |
| 231 | +If we [assume that the `allowed_features` vector is not |
| 232 | +set][empty-allowed-features], then this comes to a total of 30 mandatory bytes. |
| 233 | + |
| 234 | +For the recipient node, it will receive a cipher text payload containing: |
| 235 | + |
| 236 | +- `padding`: optional |
| 237 | +- `path_id`: let's assume that this is 32 bytes like the existing payment |
| 238 | + address. |
| 239 | +- `payment_constraints`: |
| 240 | + * 4 byte `max_cltv_expiry` |
| 241 | + * 8 byte `htlc_minimum_msat` |
| 242 | + |
| 243 | +This comes to a total of 44 bytes for the recipient's cipher text. |
| 244 | + |
| 245 | +The padding field should be used by recipients to pad cipher text blobs so that |
| 246 | +all are the same size. Since the calculated recipient cipher text blob size (44) |
| 247 | +is larger than that of the forwarding nodes (30), we can assume that all the |
| 248 | +cipher text blobs will have a size of around 44 bytes. |
| 249 | + |
| 250 | +##### `blinded_hop` Size Estimation |
| 251 | + |
| 252 | +The total number of bytes required for a single `blinded_hop` is: |
| 253 | + |
| 254 | + = 33+bigsize_len(cipher_text)+len(cipher_text) |
| 255 | + |
| 256 | +If we use the estimated `cipher_text` size of 44 bytes, then |
| 257 | +`bigsize_len(cipher_text)` is 1 and so this comes to 78 bytes for a single |
| 258 | +`blinded_hop`. |
| 259 | + |
| 260 | +##### `blinded_payinfo` Size Estimation |
| 261 | + |
| 262 | +The total number of bytes required for the encoding of a single |
| 263 | +`blinded_payinfo` entry is: |
| 264 | + |
| 265 | + = 4+4+2+8+8+2+len(features)+33+1+(num_hops*len(blinded_hop)) |
| 266 | + = 68+len(features)+(num_hops*len(blinded_hop)) |
| 267 | + |
| 268 | +If we take the estimate of 78 bytes per `blinded_hop` and if we assume an empty |
| 269 | +feature vector then this comes to: |
| 270 | + |
| 271 | + = 68+(num_hops*78) |
| 272 | + |
| 273 | +The maximum number of hops in a single blinded path can then be calculated to |
| 274 | +be: |
| 275 | + |
| 276 | + 639 = 68+(num_hops*78) |
| 277 | + num_hops = 7 |
| 278 | + |
| 279 | +#### QR code limit |
| 280 | + |
| 281 | +Another soft maximum value to keep in mind is the maximum number of bytes that |
| 282 | +can fit into a [QR code][qr] which is 2,953 bytes. This is a soft maximum |
| 283 | +because this only applies if the invoice is in fact being transmitted via QR |
| 284 | +code. This limit does not apply if the invoice is being transmitted via other |
| 285 | +protocols such as LNURL. In the cases where the limit does apply, then two |
| 286 | +variables will be at play: |
| 287 | + |
| 288 | +- The number of blinded paths |
| 289 | +- The number of blinded hops within each path (which will always also be |
| 290 | + restricted by the `data_length` maximum). |
| 291 | + |
| 292 | +The exact limit on the number of blinded paths that can be included depends on |
| 293 | +the size of other fields in the invoice. It is worth noting that an invoice with |
| 294 | +a blinded path should not contain any `r` (route hint) fields. |
| 295 | + |
| 296 | +[tagged-fields]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md#tagged-fields |
| 297 | +[bolt11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md |
| 298 | +[bolt4-payload]: https://github.com/lightning/bolts/blob/master/04-onion-routing.md#payload-format |
| 299 | +[bolt4-relay]: https://github.com/lightning/bolts/blob/master/04-onion-routing.md#requirements |
| 300 | +[blinded-paths]: https://github.com/lightning/bolts/blob/master/04-onion-routing.md#route-blinding |
| 301 | +[offers]: https://github.com/lightning/bolts/pull/798 |
| 302 | +[impl]: https://github.com/lightningnetwork/lnd/pull/8752 |
| 303 | +[qr]: https://en.wikipedia.org/wiki/QR_code#Information_capacity |
| 304 | +[lnurl]: https://github.com/lnurl/luds |
| 305 | +[rb-proposal]: https://github.com/lightning/bolts/blob/c562d91ace0e95bec3c6f8758969eaf3627f23c8/proposals/route-blinding.md?plain=1#L274 |
| 306 | +[max_cltv_expiry]: https://github.com/lightning/bolts/pull/798/files#r1053000804 |
| 307 | +[empty-allowed-features]: https://github.com/lightning/bolts/blob/c562d91ace0e95bec3c6f8758969eaf3627f23c8/04-onion-routing.md?plain=1#L253 |
0 commit comments