[Lightning-dev] Proposal: Lightning Pre-Image Encryption Standard

Nadav Kohen nadav at suredbits.com
Tue Jun 25 16:54:23 UTC 2019


Hi all,


There are many applications that sell some form of data to users (e.g. a
blog post, a game, live data, etc.) monetizing with Lightning. This data
transfer can (and often should) be made atomic with the payment for that
data using the payment pre-image. This basically entails responding to any
request for data with an invoice and data that is encrypted with that
invoice's payment pre-image; thus ensuring that the user gets the data if
and only if they successfully pay that invoice over the lightning network.
This scheme is already in use in real applications and will likely be
further adopted as more lapps emerge. It would be beneficial to have an
industry standard that would allow for the creation of uniform libraries
for standard ln-encryption and ln-decryption.

We propose the use of AES encryption in CFB mode with no padding to
plaintext. AES encryption is a widely used standard that has libraries
available for most platforms and languages. CFB mode allows the encryption
of arbitrary sized plaintexts, allowing us to avoid any logic for
padding/unpadding. Note that with AES in CFB mode you need to provide an
initialization vector (IV), and this IV must be random for every encrypted
plaintext.

A data provider should respond to requests for data over a secure channel
(e.g. HTTPS) with the requested data encrypted by the payment pre-image
using AES in CFB mode. Encrypting with the pre-image ensures that the user
only receives the data they pay for and sending over a secure channel
ensures no one else who knows the pre-image receives the data.

When encrypting with the preimage, any pre-image that is 16, 24 or 32 bytes
will work.

After encrypting the desired data with the payment pre-image, serialize the
encrypted data by prepending the IV to the encrypted data, and then convert
the sequence of bytes to a base64 string. This final base64-encoded string
can be sent over the wire to the user (securly). Since the IV is a
fixed-length 16 byte prefix, deserializing the base64 string is simply a
matter of converting the base64 string to a sequence of bytes, setting the
IV to the first 16 bytes and the ciphertext to the rest.

Optimizations:

Once the payment has been received by the data provider, they may offer the
payment preimage directly to the data recipient if there is a communication
channel to the user (say over a websocket). The data provider can also
simply make the payment pre-image publicly available, e.g. via a public
API. This is done to provide for a better user experience by reducing
latency as well as reducing the amount of communication a lapp client must
have with a lightning node.

Reference implementations:

   -

   JavaScript, using the Crypto-JS library:
   https://gist.github.com/torkelrogstad/4611d73567cdcbc40d1da144169c9b03
   -

   Python, using the Pycrypto library:
   https://gist.github.com/torkelrogstad/9f57c9ec2f14322a9c1ce0a863f4ad50
   -

   Java/Scala:
   https://github.com/torkelrogstad/bitcoin-s/blob/21f69158de361349a3ef1abe6f94f042af144ea9/core/src/main/scala/org/bitcoins/core/crypto/AesCrypt.scala


Acknowledgments:

   -

   Thank you to Alex Bosworth for sharing this idea with us and having a
   working implementation of this scheme at yalls.org <http://www.yalls.org>
   -

   Thank you to Torkel Rogstad for the encryption details and reference
   implementations


Best,
Nadav
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linuxfoundation.org/pipermail/lightning-dev/attachments/20190625/91bd241a/attachment-0001.html>


More information about the Lightning-dev mailing list