Skip to content

Instantly share code, notes, and snippets.

Last active April 3, 2023 20:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save AdamISZ/a41d92e73c7dcb02762fac34d4c414a0 to your computer and use it in GitHub Desktop.
Save AdamISZ/a41d92e73c7dcb02762fac34d4c414a0 to your computer and use it in GitHub Desktop.
Offchain Joinmarket fees with adaptors

Joinmarket fees over Lightning using encrypted signatures

Fees inside Joinmarket coinjoins are one of (arguably, the principal) "metadata" fingerprints that damage the quality of the privacy generated by such coinjoins. At minimum, they force a lot more rounds of coinjoin in order to get a meaningful anonymity set (and realistically, more complex behaviour and a lot more time). It should be noted that there is no claim that removing these fingerprints are a panacea.

But let's consider how off-chain fees could work. It's clearly possible to do it with centralized servers. The more advanced way to use servers would be a Chaumian e-cash server as described by chris-belcher here. However this short note is intended to explain that the same goal can be achieved trustlessly.

First, remember that either with Schnorr or with ECDSA, we can construct "signature adaptors" or preferably "otVES" - one-time verifiably encrypted signatures, in Fournier's parlance. For now we'll use "adaptors". In brief:

Create adaptor:

Input: point T, message m, pubkey P. Output: adaptor a. a is effectively an encrypted signature.

Verify adaptor:

Input: a, m, P, T. Output: true/false

Decrypt adaptor:

Input: t, a. Output: s = signature on m with P.

This primitive lets us embed a secret in a signature encryption such that publishing the signature perforce reveals the secret.

Plan: we make atomic: (the Joinmarket coinjoin itself), and (a payment from taker to maker off chain).

The offchain payment over Lightning can be using the idea of a HODL invoice, which will require the sender to reveal a secret value (32 bytes) in order to claim (settle) the payment.

How to make them atomic

Thomas the Taker and Mandy the maker (only 1 to keep things simple here).

  • Thomas uses the HODL invoice primitive to create an off chain payment that is encrypted to secret t (i.e. preimage is just t). Mandy quits if this is not "corresponding" to T. [1]

  • Then the Joinmarket negotiation flow is as per usual, except that in the !sig message that Mandy sends to Thomas, Thomas not only does the usual verification of valid utxo, but also verifies that actual signature is a valid adaptor to secret t (i.e. it's a signature encrypted with the same key as his earlier one).

  • Then, since Thomas knows t, he decrypts that signature and broadcasts the coinjoin.

  • Then Mandy can settle the HODL invoice using the secret t, thus claiming the fee for the coinjoin liquidity, atomically.

Technical addenda

  1. The first bullet point above is what I'm most unsure on: if we use PTLC, it seems to make perfect sense. But I fear that in current LN that cannot be done unless there is some fancy footwork, because we use hash functions. Would love to hear opinions.

  2. Currrent Joinmarket means ECDSA, this only complicates things a small amount: we need to attach a PoDLE to create the kind of adaptor/otVES we need, see my earlier blog on this for details. This needn't affect the previous point, though, in itself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment