From ZmnSCPxj at protonmail.com Tue Jun 11 03:47:26 2019 From: ZmnSCPxj at protonmail.com (ZmnSCPxj) Date: Tue, 11 Jun 2019 03:47:26 +0000 Subject: [Lightning-dev] ECDH for spontaneous payments and offline vending machines In-Reply-To: References: Message-ID: 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