Commit graph

79 commits

Author SHA1 Message Date
Valentine Wallace
3184393df2
Reverse (BlindedPath, BlindedPayInfo) tuple order in offers invoice.
To make it uniform with PaymentParameters' Payee::Blinded::route_hints.
2023-06-16 11:14:53 -04:00
Jeffrey Czyz
ecd283ea23
Include signature check in BOLT 12 signature test
The BOLT 12 test vectors had inadvertently left out a signature, but it
has since been added. Include a signature check in the corresponding
test for completeness.
2023-06-07 16:57:24 -05:00
Jeffrey Czyz
8540985351
Update BOLT 12 test vectors
The previous test vectors contained recurrences and older TLV types, and
therefore couldn't be parsed. Update the tests with the latest test
vectors from the spec and stop ignoring the tests.
2023-06-07 16:56:56 -05:00
Jeffrey Czyz
0970f3f63f
Remove custom blinded path test vector
These were added to help debug an encoding issue. However, the encoding
code was moved to the blinded_path module. Additionally, the test vector
used an old TLV encoding.
2023-06-07 16:55:09 -05:00
Jeffrey Czyz
b6bb32ce14
Remove duplicate BOLT 12 test vector 2023-06-02 14:20:30 -05:00
Arik Sosman
6cb9919f0c
Move keysinterface.rs to a directory-level module called sign. 2023-05-02 21:48:08 -07:00
Matt Corallo
28e16aedd2 [bindings] Disable BOLT12 builders which require move semantics 2023-04-25 22:51:18 +00:00
Matt Corallo
607727fae7
Merge pull request #2146 from valentinewallace/2023-03-blinded-pathfinding-groundwork
Blinded pathfinding groundwork
2023-04-24 16:46:15 +00:00
Valentine Wallace
ed4348f08a
Update PaymentParameters::route_hints for blinded paths 2023-04-20 10:14:17 -04:00
Valentine Wallace
efed905a4f
Move blinded_path and its utils into a new module 2023-04-20 10:14:15 -04:00
Jeffrey Czyz
42a772d675
Expose description from Invoice's offer/refund
This will allow clients like VLS to check the description for an invoice
as part of verification.
2023-04-20 08:41:07 -05:00
Jeffrey Czyz
8afe694020
DRY up InvoiceFields construction 2023-04-19 21:31:08 -05:00
Jeffrey Czyz
c8a847ae11
Support responding to refunds with transient keys 2023-04-19 21:31:07 -05:00
Jeffrey Czyz
e1a6bc3cad
Extract keys from Offer::metadata to sign Invoice
For offers where the signing pubkey is derived, the keys need to be
extracted from the Offer::metadata in order to sign an invoice.
Parameterize InvoiceBuilder such that a build_and_sign method is
available for this situation.
2023-04-19 21:31:07 -05:00
Jeffrey Czyz
259aa9aac3
DRY up verification of invreq TLV records 2023-04-19 21:31:07 -05:00
Jeffrey Czyz
2298af4d0b
Stateless verification of Invoice for Refund
Stateless verification of Invoice for Offer

Verify that an Invoice was produced from a Refund constructed by the
payer using the payer metadata reflected in the Invoice. The payer
metadata consists of a 128-bit encrypted nonce and possibly a 256-bit
HMAC over the nonce and Refund TLV records (excluding the payer id)
using an ExpandedKey.

Thus, the HMAC can be reproduced from the refund bytes using the nonce
and the original ExpandedKey, and then checked against the metadata. If
metadata does not contain an HMAC, then the reproduced HMAC was used to
form the signing keys, and thus can be checked against the payer id.
2023-04-19 21:31:07 -05:00
Jeffrey Czyz
1a7540f2c9
Refund metadata and payer id derivation
Add support for deriving a transient payer id for each Refund from an
ExpandedKey and a nonce. This facilitates payer privacy by not tying any
Refund to any other nor to the payer's node id.

Additionally, support stateless Invoice verification by setting payer
metadata using an HMAC over the nonce and the remaining TLV records,
which will be later verified when receiving an Invoice response.
2023-04-19 21:31:07 -05:00
Jeffrey Czyz
022eadc4db
Stateless verification of Invoice for Offer
Verify that an Invoice was produced from an InvoiceRequest constructed
by the payer using the payer metadata reflected in the Invoice. The
payer metadata consists of a 128-bit encrypted nonce and possibly a
256-bit HMAC over the nonce and InvoiceRequest TLV records (excluding
the payer id) using an ExpandedKey.

Thus, the HMAC can be reproduced from the invoice request bytes using
the nonce and the original ExpandedKey, and then checked against the
metadata. If metadata does not contain an HMAC, then the reproduced HMAC
was used to form the signing keys, and thus can be checked against the
payer id.
2023-04-19 21:31:07 -05:00
Jeffrey Czyz
9bd43e077f
Fix builder docs in offers module 2023-04-19 21:31:06 -05:00
Jeffrey Czyz
3880e69237
InvoiceRequest metadata and payer id derivation
Add support for deriving a transient payer id for each InvoiceRequest
from an ExpandedKey and a nonce. This facilitates payer privacy by not
tying any InvoiceRequest to any other nor to the payer's node id.

Additionally, support stateless Invoice verification by setting payer
metadata using an HMAC over the nonce and the remaining TLV records,
which will be later verified when receiving an Invoice response.
2023-04-19 21:31:06 -05:00
Jeffrey Czyz
e15044b889
Refactor InvoiceRequestContents fields into a sub-struct
InvoiceRequestBuilder has a field containing InvoiceRequestContents.
When deriving the payer_id from the remaining fields, a struct is needed
without payer_id as it not optional. Refactor InvoiceRequestContents to
have an inner struct without the payer_id such that
InvoiceRequestBuilder can use it instead.
2023-04-19 21:31:06 -05:00
Jeffrey Czyz
dd2ccd2322
Stateless verification of InvoiceRequest
Verify that an InvoiceRequest was produced from an Offer constructed by
the recipient using the Offer metadata reflected in the InvoiceRequest.
The Offer metadata consists of a 128-bit encrypted nonce and possibly a
256-bit HMAC over the nonce and Offer TLV records (excluding the signing
pubkey) using an ExpandedKey.

Thus, the HMAC can be reproduced from the offer bytes using the nonce
and the original ExpandedKey, and then checked against the metadata. If
metadata does not contain an HMAC, then the reproduced HMAC was used to
form the signing keys, and thus can be checked against the signing
pubkey.
2023-04-19 21:30:40 -05:00
Jeffrey Czyz
b2e87ff25b
TlvStream range iterator
Add an iterator that yields TlvRecords over a range of a TlvStream.
Useful for verifying that, e.g., an InvoiceRequest was sent in response
to an Offer constructed by the intended recipient.
2023-04-19 21:08:05 -05:00
Jeffrey Czyz
1cad430e14
Offer metadata and signing pubkey derivation
Add support for deriving a transient signing pubkey for each Offer from
an ExpandedKey and a nonce. This facilitates recipient privacy by not
tying any Offer to any other nor to the recipient's node id.

Additionally, support stateless Offer verification by setting its
metadata using an HMAC over the nonce and the remaining TLV records,
which will be later verified when receiving an InvoiceRequest.
2023-04-19 21:06:37 -05:00
Jeffrey Czyz
fd426a0018
Add missing UnknownRequiredFeatures tests 2023-04-18 13:30:32 -05:00
Jeffrey Czyz
ce7a02d1e0
Common offers test_utils module
Move utility functions used across all offers modules into a common
module. Avoids duplicating larger utilities such as payment_path across
more than one module.
2023-04-18 13:30:10 -05:00
Jeffrey Czyz
39befa16b4
Expose a BOLT 12 Invoice's signable_hash
This is useful as an identifier for downstream clients like VLS.
2023-04-06 23:15:31 -05:00
Jeffrey Czyz
9c2a3d090b
Fix amount overflow in Invoice building
An overflow can occur when multiplying the offer amount by the requested
quantity when no amount is given in the request. Return an error instead
of overflowing.
2023-02-23 18:25:50 -06:00
Jeffrey Czyz
32ed69a2bd
Fix amount overflow in Offer parsing and building
An overflow can occur when multiplying the offer amount by the requested
quantity when checking if the given amount is enough. Return an error
instead of overflowing.
2023-02-23 18:25:50 -06:00
Jeffrey Czyz
56a01de61d
Expose Bech32Encode trait for fuzzing
In order to fuzz test Bech32Encode parsing independent of the underlying
message deserialization, the trait needs to be exposed. Conditionally
expose it only for fuzzing.
2023-02-23 18:25:49 -06:00
Jeffrey Czyz
e049e97993
Fuzz test for parsing InvoiceRequest
An invoice request is serialized as a TLV stream and encoded as bytes.
Add a fuzz test that parses the TLV stream and deserializes the
underlying InvoiceRequest. Then compare the original bytes with those
obtained by re-serializing the InvoiceRequest.
2023-02-23 18:24:41 -06:00
Jeffrey Czyz
9a65709239
Derive traits for InvoiceRequest and Invoice
Offer and Refund derive Debug, Clone, and PartialEq. For consistency,
derive these traits for InvoiceRequest and Invoice as well.
2023-02-21 14:07:51 -06:00
Jeffrey Czyz
0001260f74
Fuzz test for parsing Refund
A refund is serialized as a TLV stream and encoded in bech32 without a
checksum. Add a fuzz test that parses the unencoded TLV stream and
deserializes the underlying Refund. Then compare the original bytes with
those obtained by re-serializing the Refund.
2023-02-08 19:02:17 -06:00
Jeffrey Czyz
fcb67434d9
Make BlindedPayInfo fields public
BlindedPayInfo fields need to be public in order to construct one for
fuzz tests. Typically, they would be constructed from ChannelUpdateInfo
for public channels and ChannelDetails for unannounced channels. For
now, make the fields public so they can be constructed manually.
2023-02-08 18:56:40 -06:00
Jeffrey Czyz
53d2d47360
Fuzz test for parsing Offer
An offer is serialized as a TLV stream and encoded in bech32 without a
checksum. Add a fuzz test that parses the unencoded TLV stream and
deserializes the underlying Offer. Then compare the original bytes with
those obtained by re-serializing the Offer.
2023-02-08 18:47:48 -06:00
Jeffrey Czyz
153d831ccc
Make offers module public
This is needed in order to fuzz test BOLT 12 message deserialization.
2023-02-03 15:23:43 -06:00
Jeffrey Czyz
6388c9a3e5
Add test for requesting invoice from expired offer 2023-02-03 15:23:43 -06:00
Jeffrey Czyz
4763612131
Make separate no-std version for invoice response
Both Refund::respond_with and InvoiceRequest::respond_with take a
created_at since the Unix epoch Duration in no-std. However, this can
cause problems if two downstream dependencies want to use the lightning
crate with different feature flags set. Instead, define
respond_with_no_std versions of each method in addition to a
respond_with version in std.
2023-02-03 15:23:33 -06:00
Jeffrey Czyz
3302f25e9f
Fix BOLT 12 invoice doctests to work with no-std 2023-02-03 15:14:58 -06:00
Jeffrey Czyz
22ea505348
Update docs regarding payment path privacy 2023-01-30 15:44:39 -06:00
Jeffrey Czyz
2d44dbe013
Disallow offer_metadata in Refund
The offer_metadata was optional but is redundant with invreq_metadata
(i.e., payer_metadata) for refunds. It is now disallowed in the spec and
was already unsupported by RefundBuilder.
2023-01-30 15:44:39 -06:00
Jeffrey Czyz
6236e0d472
Allow quantity in Refund
The spec always allowed this but the reason was unclear. It's useful if
the refund is for an invoice paid for offer where a quantity was given
in the request. The description in the refund would be from the offer,
which may have given a unit for each item. So allowing a quantity makes
it clear how many items the refund is for.
2023-01-30 15:44:39 -06:00
Jeffrey Czyz
4059677e8e
Support explicit quantity_max = 1 in Offer
The spec was modified to allow setting offer_quantity_max explicitly to
one. This is to support a use case where more than one item is supported
but only one item is left in the inventory. Introduce a Quantity::One
variant to replace Quantity::Bounded(1) so the later can be used for the
explicit setting.
2023-01-30 15:44:39 -06:00
Jeffrey Czyz
a452551480
Invoice parsing tests
Tests for checking invoice semantics when parsing invoice bytes as
defined by BOLT 12.
2023-01-20 16:04:39 -06:00
Jeffrey Czyz
bf1147f23f
Invoice building tests
Tests for checking invoice message semantics when building an invoice as
defined by BOLT 12.
2023-01-20 16:04:39 -06:00
Jeffrey Czyz
fe83aede0c
Expand invoice module docs and include an example 2023-01-20 16:04:38 -06:00
Jeffrey Czyz
7f52d26e6e
Use SystemTime::now() for Invoice creation time
For std builds, Invoice::created_at can be automatically set upon
construction using SystemTime::now() offset by SystemTime::UNIX_EPOCH.
Change InvoiceRequest::respond_with and Refund::respond_with to only
take a created_at parameter in no-std builds.
2023-01-20 16:04:38 -06:00
Jeffrey Czyz
f779bc066f
Builder for creating invoices for refunds
Add a builder for creating invoices for a refund and required fields.
Other settings are optional and duplicative settings will override
previous settings. Building produces a semantically valid `invoice`
message for the refund, which then can be signed with the key associated
with the provided signing pubkey.
2023-01-20 16:04:38 -06:00
Jeffrey Czyz
88c5197e44
Builder for creating invoices for offers
Add a builder for creating invoices for an offer from a given request
and required fields. Other settings are optional and duplicative
settings will override previous settings. Building produces a
semantically valid `invoice` message for the offer, which then can be
signed with the key associated with the offer's signing pubkey.
2023-01-20 16:04:37 -06:00
Jeffrey Czyz
e1aa18aed8
Invoice encoding and parsing
Define an interface for BOLT 12 `invoice` messages. The underlying
format consists of the original bytes and the parsed contents.

The bytes are later needed for serialization. This is because it must
mirror all the `offer` and `invoice_request` TLV records, including
unknown ones, which aren't represented in the contents.

Invoices may be created for an Offer (from an InvoiceRequest) or for a
Refund. The primary difference is how the signing pubkey is given -- by
the writer of the offer or the reader of the refund.
2023-01-20 16:04:37 -06:00