Good morning Stepan, > # Offline invoice generation > > Some time ago there was a discussion about offline vending machines, the idea > was to pre-load a vending machine with invoices, display invoices to the user > and ask for the preimage as a payment confirmation. When all invoices are > used or expired we refill it with the new ones. It is great but it doesn't > work if the payment amount is variable (pay for volume or time). > > An alternative could be to share the node private key with the vending > machines to generate invoices on the fly, but it is a security hole. There is > a trick though how generate invoices that our online node could claim without > exposing any secrets to the vending machine. > > Vending machine generates an ephemeral key `k` and corresponding ephemeral > node id `K`. It generates an invoice signed with this key. It also includes a > routing information that the payment should go through our online node `N`. > As a preimage we use `hmac-sha256(x, amount)` where `x` is a secret key from > ECDH(K, N) - (x-coordinate of `k * N`). We also put the amount into the > 8-byte short channel id in the routing information to ensure that the node > can calculate the preimage even if the user is willing to pay a tip and > increases the amount of the htlc. > > When our online node is asked to route a payment to an unknown node `K` it > tries to generate the preimage. It calculates the ECDH secret `x` > (x-coordinate of `n * K` where `n` is a private key corresponding to its node > id) and calculates the preimage from the amount encoded in the short channel > id and the secret x. If the preimage matches the payment hash it can claim > the money (also checking that htlc amount is greater or equal the amount > encoded in the channel id).
Reviewing BOLT #4, sadly it seems not to work...? > 1. type: `per_hop` (for `realm` 0) > 2. data: > * [`8`:`short_channel_id`] > * [`8`:`amt_to_forward`] > * [`4`:`outgoing_cltv_value`] > * [`12`:`padding`] There is no way to inform your online node what `K` is, since what is in the `per_hop` does not include `K`. Instead, the `short_channel_id` is intended to inform the forwarding node which is the next hop, using only 8 bytes; presumably the forwarding node has a table mapping short channel IDs to actual peers it has. The online node in your proposal is unable to extract `K`, a the next-node-ID is never transmitted. For the donation case, it seems possible, as the donator is the sender and can arrange to use the shared secret as the preimage. But for the invoice-generation case, the invoice-generator is not the sender, and the sender might not know how to properly inform the shared secret. Maybe later, when we use "rendezvous routing" (and provide hooks into BOLT #11 for it), it may become possible to perform this trick (as we will use node IDs in rendezvous routing, rather than `short_channel_id`). Then the online node can, if unable to rendezvous-forward to a node on its routemap, check if the "next node ID" in the rendezvous routing sub-route can be used as to compute a shared secret that is the preimage. https://github.com/lightningnetwork/lightning-rfc/pull/611 Regards, ZmnSCPxj _______________________________________________ Lightning-dev mailing list Lightning-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev