mirror of
https://github.com/lightning/blips.git
synced 2024-11-19 00:50:02 +01:00
Merge pull request #39 from ellemouton/bolt11-blinded-path
blip-0039: BOLT 11 Invoice Blinded Path Tagged Field
This commit is contained in:
commit
9a1bd0a90d
13
blip-0002.md
13
blip-0002.md
@ -45,12 +45,13 @@ Custom feature bits used in the `I` [Bolt 11](https://github.com/lightning/bolts
|
||||
|
||||
bLIPs may reserve feature bits by adding them to the following table:
|
||||
|
||||
| Bits | Name | Description | Context | Dependencies | Link |
|
||||
| --------- | ---------------------- | ----------------------------------------------------------- | ---------------- | -------------------------------- | -------------------------------- |
|
||||
| 54/55 | `keysend` | A form of spontaneous payment | N | `var_onion_optin` | [bLIP 3](./blip-0003.md) |
|
||||
| 256/257 | `hosted_channels` | This node accepts requests for hosted channels | IN | | [bLIP 17](./blip-0017.md) |
|
||||
| 258/259 | `dns_resolver` | This node accepts DNSSEC proof requests | N | | [bLIP 32](./blip-0032.md) |
|
||||
| 260/261 | `htlc_endorsement` | This node forwards experimental htlc endorsement signals | N | | [bLIP 4](./blip-004.md) |
|
||||
| Bits | Name | Description | Context | Dependencies | Link |
|
||||
|---------|-----------------------|------------------------------------------------------------|---------|-------------------------|---------------------------|
|
||||
| 54/55 | `keysend` | A form of spontaneous payment | N | `var_onion_optin` | [bLIP 3](./blip-0003.md) |
|
||||
| 256/257 | `hosted_channels` | This node accepts requests for hosted channels | IN | | [bLIP 17](./blip-0017.md) |
|
||||
| 258/259 | `dns_resolver` | This node accepts DNSSEC proof requests | N | | [bLIP 32](./blip-0032.md) |
|
||||
| 260/261 | `htlc_endorsement` | This node forwards experimental htlc endorsement signals | N | | [bLIP 4](./blip-004.md) |
|
||||
| 262/263 | `bolt11_blinded_path` | This invoice may contain a new blinded path tagged field | I | `option_route_blinding` | [bLIP 39](./blip-0039.md) |
|
||||
|
||||
### Messages
|
||||
|
||||
|
307
blip-0039.md
Normal file
307
blip-0039.md
Normal file
@ -0,0 +1,307 @@
|
||||
```
|
||||
bLIP: 39
|
||||
Title: BOLT 11 Invoice Blinded Path Tagged Field
|
||||
Author: Elle Mouton <elle.mouton@gmail.com>
|
||||
Status: Draft
|
||||
Created: 2024-07-08
|
||||
* Post-History: 2024-06-26: https://delvingbitcoin.org/t/blip-bolt-11-invoice-blinded-path-tagged-field/991
|
||||
License: CC0
|
||||
```
|
||||
|
||||
## Abstract
|
||||
|
||||
This bLIP defines a new [tagged field][tagged-fields] for the payment invoice
|
||||
encoding described by [BOLT 11][bolt11] which can be used to communicate
|
||||
encoded blinded path information to the payer of the invoice.
|
||||
|
||||
## Copyright
|
||||
|
||||
This bLIP is licensed under the CC0 license.
|
||||
|
||||
## Rational
|
||||
|
||||
Blinded paths have been included in the [BOLT 4 specification][blinded-paths]
|
||||
and using them in the context of receiving payments is natively supported in
|
||||
the [BOLT 12 Offers proposal][offers]. However, the Offers proposal also
|
||||
includes various other dependencies such as onion messaging and various new
|
||||
protocol message all of which will require a network wide upgrade before full
|
||||
advantage can be taken of the new protocol. Blinded paths themselves are a
|
||||
useful tool for privacy and potentially more reliable payment delivery due to
|
||||
receiver being able to select paths it knows to be more reliable. This document
|
||||
proposes a carve-out to the existing [BOLT 11][bolt11] invoice format so that
|
||||
testing of blinded paths can be done in implementations that have not yet
|
||||
implemented the full Offers specification. This will be done by adding a new
|
||||
tagged-field type to the BOLT 11 invoice specification that will encode a
|
||||
blinded payment path. With this bLIP, the sender and the receiver of a payment
|
||||
will need to be aware of the new tagged-field and the receiver will need to
|
||||
support route blinding and ideally have direct channel peers who also support
|
||||
route blinding in order to start widening their anonymity set.
|
||||
|
||||
## Specification
|
||||
|
||||
### Feature Bit
|
||||
|
||||
A new feature bit, `bolt11_blinded_path`, for the `I` context will be added
|
||||
using bits from the experimental range. This is required because the BOLT 11
|
||||
tagged-fields pre-date the TLV format and so nodes parsing the invoice will just
|
||||
skip fields they don't know as there is no concept of "It's OK to be odd". This
|
||||
feature bit thus allows nodes to fail fast if they do not yet understand the new
|
||||
tagged field.
|
||||
|
||||
### Tagged Field
|
||||
|
||||
The proposal is to add the following new [tagged field][tagged-fields] to the
|
||||
set defined in [BOLT 11][bolt11]:
|
||||
|
||||
- `b` (20): `data_length` variable. One or more entries each containing a
|
||||
blinded payment path for a private route; there may be more than one `b`
|
||||
field. The field uses the `blinded_payinfo` type described below which draws
|
||||
heavily on the proposed encoding of the `blinded_payinfo` subtype defined in
|
||||
the [Offers proposal][offers].
|
||||
|
||||
1. subtype: `blinded_payinfo`
|
||||
2. data:
|
||||
* [`u32`:`fee_base_msat`]
|
||||
* [`u32`:`fee_proportional_millionths`]
|
||||
* [`u16`:`cltv_expiry_delta`]
|
||||
* [`u64`:`htlc_minimum_msat`]
|
||||
* [`u64`:`htlc_maximum_msat`]
|
||||
* [`u16`:`flen`]
|
||||
* [`flen*byte`:`features`]
|
||||
* [`33*byte`:`first_ephemeral_blinding_point`]
|
||||
* [`byte`:`num_hops`]
|
||||
* [`num_hops*blinded_hop`:`blinded_hops`]
|
||||
|
||||
1. subtype: `blinded_hop`
|
||||
2. data:
|
||||
* [`33*byte`:`blinded_node_pubkey`]
|
||||
* [`bigsize`: `cipher_text_length`]
|
||||
* [`cipher_text_length*byte`:`cipher_text`]
|
||||
|
||||
The `blinded_node_pubkey` of the first `blinded_hop` in a `blinded_payinfo` is
|
||||
the real public key of the blinded path's introduction node. This encoding was
|
||||
chosen so that `num_hops` accurately reflects the true number of hops including
|
||||
the introduction node while keeping the number of bytes required for the
|
||||
encoding to a minimum. The `cipher_text` is the `encrypted_recipient_data` as
|
||||
defined in [BOLT 4 TLV payload][bolt4-payload].
|
||||
|
||||
The `fee_base_msat`, `fee_proportional_millionths` and `cltv_expiry_delta` are
|
||||
the accumulated blinded route policy values as defined in [BOLT 4][bolt4-relay].
|
||||
`features` is the set of features for the path, `first_ephemeral_blinding_point`
|
||||
is the blinding point that must be communicated to the introduction node via the
|
||||
`blinding` field of the [`payload`][bolt4-payload] type.
|
||||
|
||||
** Note: see discussion section for question around communicating
|
||||
`max_cltv_expiry` **
|
||||
|
||||
### Requirements
|
||||
|
||||
An invoice containing the `b` field type:
|
||||
- MUST not contain the `r` field type.
|
||||
- MUST not contain the `s` field type since a payment address in the context of
|
||||
blinded payments does not make sense since the recipient is able to use the
|
||||
`path_id` in the `encrypted_recipient_data` for the same purpose.
|
||||
- SHOULD sign the invoice with a private key that is not the same as their
|
||||
public node ID and should not set the destination node (`n` field).
|
||||
- Each `blinded_path` must fit within the `data_length` size limit. This places
|
||||
an upper limit of approximately 7 `blinded_hops` on each path. See the
|
||||
appendix for the estimation calculation.
|
||||
- If the invoice will be displayed in QR form, then this also places an upper
|
||||
limit on the number of `blinded_path` fields that can be added to the
|
||||
invoice.
|
||||
- The existing `c` field (`min_final_cltv_expiry_delta`) is meaningless for an
|
||||
invoice containing the `b` field since this value is expected to be accounted
|
||||
for in each path's accumulated `cltv_expiry_delta`.
|
||||
- The existing invoice `expiry` field along with the `timestamp` field
|
||||
should be used to communicate the `max_cltv_expiry` of the blinded paths in
|
||||
the invoice. The reader should use the 10-minutes-per-block assumption to
|
||||
calculate an estimation of the `max_cltv_exipiry` value.
|
||||
|
||||
## Universality
|
||||
|
||||
This proposal is a temporary measure that will allow users to start making use
|
||||
of blinded paths in the context of payments and thereby take advantage of the
|
||||
potential privacy and payment success rate benefits that they will in theory
|
||||
provide. Once the Offers protocol along with its new invoice format has been
|
||||
widely deployed, then there will be no use for this BOLT 11 carve-out. Due to
|
||||
the forcasted temporary use of the new field, it makes sense to be in bLIP form
|
||||
rather than adding this in a more temporary way to the spec via a BOLT update
|
||||
proposal. The intent is that this will be used mostly for testing of blinded
|
||||
paths in implementations that have not yet implemented the full Offers spec.
|
||||
|
||||
## Backwards Compatibility
|
||||
|
||||
BOLT 11 states that the reader of an invoice "MUST skip over unknown fields".
|
||||
This means that an un-updated reader of an invoice that includes the new tagged
|
||||
field would skip it when parsing the invoice. The proposal also adds a new
|
||||
feature bit to the invoice feature bit vector and so this gives nodes an
|
||||
indication that the invoice includes something they do not yet understand.
|
||||
Even if un-upgraded senders did not check the feature bit vector, they would not
|
||||
be able to use the invoice as, without knowledge of the blinded path field, it
|
||||
does not contain enough information to attempt a payment since no routing hints
|
||||
will be included and the invoice will be signed with a random ephemeral key
|
||||
meaning that the derived destination node would not correspond to a real node
|
||||
in the graph.
|
||||
|
||||
## Reference Implementations
|
||||
|
||||
The proposed encoding of the new BOLT 11 tagged-field is added to the LND
|
||||
implementation in [this PR][impl].
|
||||
|
||||
## Appendix
|
||||
|
||||
### Test Vector
|
||||
|
||||
The following string is an example of a BOLT11 invoice containing 2 blinded
|
||||
paths, one with 1 hop and one with 3 hops.
|
||||
|
||||
```
|
||||
lnbc20m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4js5fdqqqqq2qqqqqpgqyzqqqqqqqqqqqqyqqqqqqqqqqqvsqqqqlnxy0ffrlt2y2jgtzw89kgr3zg4dlwtlfycn3yuek8x5eucnuchqps82xf0m2u6sx5wnjw7xxgnxz5kf09quqsv5zvkgj7d5kpzttp4qz7q5qsyqcyq5pzq2feycsemrh7wvendc4kw3tsmkt25a36ev6kfehrv7ecfkrp5zs9q5zqxqspqtr4avek5quzjn427asptzews5wrczfhychr2sq6ue9phmn35tjqcrspqgpsgpgxquyqjzstpsxsu59zqqqqqpqqqqqqyqq2qqqqqqqqqqqqqqqqqqqqqqqqpgqqqqk8t6endgpc99824amqzk9japgu8synwf3wx4qp4ej2r0h8rghypsqsygpf8ynzr8vwleenxdhzke69wrwed2nk8t9n2e8xudnm8pxcvxs2q5qsyqcyq5y4rdlhtf84f8rgdj34275juwls2ftxtcfh035863q3p9k6s94hpxhdmzfn5gxpsazdznxs56j4vt3fdhe00g9v2l3szher50hp4xlggqkxf77f
|
||||
```
|
||||
|
||||
Breakdown:
|
||||
|
||||
This invoice was signed with `priv_key`=`e126f68f7eafcc8b74f54d269fe206be715000f94dac067d1c04a8ca3b2db734`.
|
||||
It does _not_ contain a payment secret.
|
||||
|
||||
* `lnbc`: prefix, Lightning on Bitcoin mainnet
|
||||
* `20m`: amount (20 milli-bitcoin)
|
||||
* `1`: Bech32 separator
|
||||
* `pvjluez`: timestamp (1496314658)
|
||||
* `p`: payment hash (0001020304050607080900010203040506070809000102030405060708090102)
|
||||
* `d`: description: '1 cup coffee'
|
||||
* `b`: blinded path:
|
||||
* `fee_base_msat`: 40
|
||||
* `fee_proportional_millionths`: 20
|
||||
* `cltv_expiry_delta`: 130
|
||||
* `htlc_minimum_msat`: 2
|
||||
* `htlc_maximum_msat`: 100
|
||||
* `flen`: 0
|
||||
* `first_ephemeral_blinding_point`: 03f3311e948feb5115242c4e396c81c448ab7ee5fd24c4e24e66c73533cc4f98b8
|
||||
* `num_hops`: 3
|
||||
* `blinded_hops`:
|
||||
* `blinded_node_pubkey`: 03a8c97ed5cd40d474e4ef18c899854b25e5070106504cb225e6d2c112d61a805e
|
||||
* `cipher_text`: 0102030405
|
||||
* `blinded_node_pubkey`: 0220293926219d8efe733336e2b674570dd96aa763acb3564e6e367b384d861a0a
|
||||
* `cipher_text`: 0504030201
|
||||
* `blinded_node_pubkey`: 02c75eb336a038294eaaf760158b2e851c3c0937262e35401ae64a1bee71a2e40c
|
||||
* `cipher_text`: 0102030405060708090a0b0c0d0e
|
||||
* `b`: blinded path:
|
||||
* `fee_base_msat`: 4
|
||||
* `fee_proportional_millionths`: 2
|
||||
* `cltv_expiry_delta`: 10
|
||||
* `htlc_minimum_msat`: 0
|
||||
* `htlc_maximum_msat`: 10
|
||||
* `flen`: 0
|
||||
* `first_ephemeral_blinding_point`: 02c75eb336a038294eaaf760158b2e851c3c0937262e35401ae64a1bee71a2e40c
|
||||
* `num_hops`: 1
|
||||
* `blinded_hops`:
|
||||
* `blinded_node_pubkey`: 0220293926219d8efe733336e2b674570dd96aa763acb3564e6e367b384d861a0a
|
||||
* `cipher_text`: 0102030405
|
||||
|
||||
### Size Restrictions
|
||||
|
||||
#### `data_length` Limit
|
||||
|
||||
In order to conform to any existing BOLT 11 invoice parser, each new tagged
|
||||
field must use the `data_length` encoding defined there. This means that the
|
||||
maximum size of any _single_ encoded blinded path is 639 bytes.
|
||||
|
||||
What follows is a rough estimation of the maximum number of hops we can include
|
||||
in a single blinded path. It assumes that each hop's cipher text is the same
|
||||
length.
|
||||
|
||||
##### Cipher Text Size Estimation
|
||||
|
||||
First, a rough estimation of the average cipher text length is required. A
|
||||
forwarding node in a blinded path will receive a cipher text payload containing
|
||||
the following data:
|
||||
|
||||
- `padding`: optional
|
||||
- `short_channel_id` of 8 bytes
|
||||
- `payment_relay`:
|
||||
* 2 byte `cltv_expiry_delta`
|
||||
* 4 byte `fee_proportional_millionths`
|
||||
* 4 byte `fee_base_msat`
|
||||
- `payment_constraints`:
|
||||
* 4 byte `max_cltv_expiry`
|
||||
* 8 byte `htlc_minimum_msat`
|
||||
- `allowed_features`: optional
|
||||
|
||||
If we [assume that the `allowed_features` vector is not
|
||||
set][empty-allowed-features], then this comes to a total of 30 mandatory bytes.
|
||||
|
||||
For the recipient node, it will receive a cipher text payload containing:
|
||||
|
||||
- `padding`: optional
|
||||
- `path_id`: let's assume that this is 32 bytes like the existing payment
|
||||
address.
|
||||
- `payment_constraints`:
|
||||
* 4 byte `max_cltv_expiry`
|
||||
* 8 byte `htlc_minimum_msat`
|
||||
|
||||
This comes to a total of 44 bytes for the recipient's cipher text.
|
||||
|
||||
The padding field should be used by recipients to pad cipher text blobs so that
|
||||
all are the same size. Since the calculated recipient cipher text blob size (44)
|
||||
is larger than that of the forwarding nodes (30), we can assume that all the
|
||||
cipher text blobs will have a size of around 44 bytes.
|
||||
|
||||
##### `blinded_hop` Size Estimation
|
||||
|
||||
The total number of bytes required for a single `blinded_hop` is:
|
||||
|
||||
= 33+bigsize_len(cipher_text)+len(cipher_text)
|
||||
|
||||
If we use the estimated `cipher_text` size of 44 bytes, then
|
||||
`bigsize_len(cipher_text)` is 1 and so this comes to 78 bytes for a single
|
||||
`blinded_hop`.
|
||||
|
||||
##### `blinded_payinfo` Size Estimation
|
||||
|
||||
The total number of bytes required for the encoding of a single
|
||||
`blinded_payinfo` entry is:
|
||||
|
||||
= 4+4+2+8+8+2+len(features)+33+1+(num_hops*len(blinded_hop))
|
||||
= 68+len(features)+(num_hops*len(blinded_hop))
|
||||
|
||||
If we take the estimate of 78 bytes per `blinded_hop` and if we assume an empty
|
||||
feature vector then this comes to:
|
||||
|
||||
= 68+(num_hops*78)
|
||||
|
||||
The maximum number of hops in a single blinded path can then be calculated to
|
||||
be:
|
||||
|
||||
639 = 68+(num_hops*78)
|
||||
num_hops = 7
|
||||
|
||||
#### QR code limit
|
||||
|
||||
Another soft maximum value to keep in mind is the maximum number of bytes that
|
||||
can fit into a [QR code][qr] which is 2,953 bytes. This is a soft maximum
|
||||
because this only applies if the invoice is in fact being transmitted via QR
|
||||
code. This limit does not apply if the invoice is being transmitted via other
|
||||
protocols such as LNURL. In the cases where the limit does apply, then two
|
||||
variables will be at play:
|
||||
|
||||
- The number of blinded paths
|
||||
- The number of blinded hops within each path (which will always also be
|
||||
restricted by the `data_length` maximum).
|
||||
|
||||
The exact limit on the number of blinded paths that can be included depends on
|
||||
the size of other fields in the invoice. It is worth noting that an invoice with
|
||||
a blinded path should not contain any `r` (route hint) fields.
|
||||
|
||||
[tagged-fields]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md#tagged-fields
|
||||
[bolt11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
|
||||
[bolt4-payload]: https://github.com/lightning/bolts/blob/master/04-onion-routing.md#payload-format
|
||||
[bolt4-relay]: https://github.com/lightning/bolts/blob/master/04-onion-routing.md#requirements
|
||||
[blinded-paths]: https://github.com/lightning/bolts/blob/master/04-onion-routing.md#route-blinding
|
||||
[offers]: https://github.com/lightning/bolts/pull/798
|
||||
[impl]: https://github.com/lightningnetwork/lnd/pull/8752
|
||||
[qr]: https://en.wikipedia.org/wiki/QR_code#Information_capacity
|
||||
[lnurl]: https://github.com/lnurl/luds
|
||||
[rb-proposal]: https://github.com/lightning/bolts/blob/c562d91ace0e95bec3c6f8758969eaf3627f23c8/proposals/route-blinding.md?plain=1#L274
|
||||
[max_cltv_expiry]: https://github.com/lightning/bolts/pull/798/files#r1053000804
|
||||
[empty-allowed-features]: https://github.com/lightning/bolts/blob/c562d91ace0e95bec3c6f8758969eaf3627f23c8/04-onion-routing.md?plain=1#L253
|
Loading…
Reference in New Issue
Block a user