Good morning list,

I would like to initiate some discussion on how Lightning could be updated to 
take advantage of the upcoming taproot update to the base layer.

For now, I am assuming the continued use of the existing Poon-Dryja update 
mechanism.
Decker-Russell-Osuntokun requires `SIGHASH_NOINPUT`/`SIGHASH_ANYPREVOUT`, and 
its details seem less settled for now than taproot details.

* [ ] We could update the current Poon-Dryja mechanism to use Schnorr 
signatures.
* [ ] Or we could just keep the current Poon-Dryja mechanism with SegWit v0 
only, and only update to Schnorr / SegWit v1 when we can implement 
Decker-Russell-Osuntokun.
  * This brings up the question as to whether we will allow Poon-Dryja to host 
pointlocked-timelocked contracts (i.e. the Scriptless Script replacement of 
HTLCs that uses payment points+scalars).
    * [ ] We could constrain Poon-Dryja channels to only HTLCs.
      * This might be simpler for implementations: implementations could have a 
completely new module that implements Decker-Russell-Osuntokun with HTLCs and 
PTLCs, and not touch existing modules for Poon-Dryja with HTLCs only.
      * We could "retire" Poon-Dryja constructions at some point and only add 
new features to Decker-Russell-Osuntokun channels.
    * [ ] We could allow hosting PTLCs as well on Poon-Dryja channels, as 
nothing in the base layer prevents a transaction from providing both SegWit v0 
and SegWit v1 outputs anyway.

Poon-Dryja with Schnorr
-----------------------

If we decide to update the current Poon-Dryja mechanism to use Schnorr, there 
are some wrinkles:

* [ ] We could just drop-in replace the signing algorithm with Schnorr.
  * We would define a NUMS point to be used as Taproot internal key, and use a 
single tapscript that is simply the current script template.
  * This is arguably not really taking advantage of the Schnorr and Taproot 
features, however.
* [ ] Or we could use some sort of MuSig between the two channel participants.

The latter option is probably what we want to use, as it potentially allows a 
channel close to be indistinguishable from an ordinary SegWit v1 spend of a 
UTXO.
Even for channels that have been published via gossip, it moves the onus of 
storing historical data about historically-published channels from base layer 
fullnodes to nodes that want to surveill the network.

### Digression: 2-of-2 is Obviously Lightning

Existing 2-of-2 outputs have a very high probability of being Lightning Network 
channels.
Thus, someone who wishes to surveill the Lightning Network can simply query any 
archive fullnode for historical 2-of-2 outputs and have a good chance that 
those are Lightning Network channels.

Consider the adage: Never go to sea with two chronometers; take one or three.
https://en.wikipedia.org/wiki/Dual_modular_redundancy
This implies that ordinary HODL usage of transaction outputs will either use 
1-of-1, or 2-of-3.

Offchain techniques, on the other hand, are only safe (trustless) if they are 
n-of-n, and are only usefully multi-participant if n > 1.
https://zmnscpxj.github.io/offchain/safety.html
Thus any n-of-n is likely to be an offchain protocol, with the most likely 
being the most widespread offchain protocol, Lightning Network.

Thus, the hyperbole "2-of-2 is Obviously Lightning".

However, we can "hide" 2-of-2 in a 2-of-3, which can be done by generating a 
third point from a NUMS point plus a random tweak generated by both 
participants.
Better yet, MuSig allows hiding any n-of-n among 1-of-1; we expect 1-of-1 use 
to dominate in the foreseeable future, thus MuSig usage maximizes our anonymity 
set.

### End Digression

A potential issue with MuSig is the increased number of communication rounds 
needed to generate signatures.

In the current Poon-Dryja setup we have, in order to completely sign the 
commitment transaction held by one participant, we only require sending a 
completed signature from the remote participant via `commitment_signed`.
Then the local participant issues a `revoke_and_ack` to reassure the remote 
side that the previous commitment it held is now revoked.
Thus, the signing itself requires only 0.5 round trips.

MuSig requires three rounds to complete the signing protocol.
Since Poon-Dryja only require the complete set of signatures for any particular 
commitment transaction to be owned by only one participant (i.e. Poon-Dryja 
commitment transactions are asymmetrical), MuSig only requires 2.5 round trips 
to sign a Poon-Dryja commitment.

Reducing the round trips is desirable when considering latency, which affects 
the experienced speed of forwarding, as well as the backwards propagation of 
failures (but not of successful payments).
Currently, latency on the network is known to be very low, but I observe that 
most Lightning Network participants today have excellent Internet connectivity, 
which might not be true in the foreseeable future.

We can reduce the round trips to 1.5 per commitment, except for the initial 
commitment transaction, by sending the `R` precommitments (the first phase of 
MuSig) of the *next* signing session while sending the `s` for the *current* 
signing session.

Finally, we can consider to reduce the use of MuSig via various techniques.
One technique is the use of fast forwards: 
https://lists.linuxfoundation.org/pipermail/lightning-dev/2019-April/001986.html

The other involves using Taproot.
The taproot internal pubkey is the MuSig of both participants, but we also add 
an explicit 2-of-2 as a tapscript (or hide the 2-of-2 in a 2-of-3), i.e. `<A> 
OP_CHECKSIGVERIFY <B> OP_CHECKSIG` in a tapscript.
This allows commitment transactions to use the tapscript path and have separate 
signatures for both participants.
Then, mutual close uses the MuSig keypath spend.
This reduces the changes relative to the current Poon-Dryja implementation: we 
can continue to use `commitment_signed` messages (or equivalent new ones for 
Taproot-based Poon-Dryja channels), and only the mutual close ritual needs to 
be modified to use MuSig.

Thus the options are below, but ***please do not select an option yet***, 
because further sections greatly affect the tradeoffs of the options below.

* [ ] Latency is not an issue (even in the foreseeable future), just use the 
2.5 round trips for MuSig and MuSig-sign every commitment.
* [ ] Pre-send the `R` commitments with the previous `s`.
  * This increases the needed storage requirements of both nodes, and possibly 
complexity of node software, but reduces the round trips to 1.5.
  * This usage may need to have larger bounds than what may be naively 
expected, if we decide to use Multi-`R` composable MuSig (see later section).
  * Even *without* this option, at the minimum we still need to store `R` 
commitments and `R`, at least in memory, until we complete the MuSig ritual.
* [ ] Use fast-forwards.
  * This removes the latency of commitment transaction signing from the 
forwarding and failure-reporting paths.
    * *Improved* forwarding and failure-reporting latency compared to today 
(revocation and signature not needed for forwarding/failure-reporting).
  * Latency is still high for commitment transaction signing, but this is less 
of an issue as it is no longer in the forwarding/failure-reporting path.
* [ ] Explicit 2-of-2 for commitment, MuSig for mutual close.
  * No degradation in latency compared to today (0.5 round trips for signature, 
additional 1 round trip for signalling and revocation).
  * No improvement (or degradation) of privacy for unilateral closes compared 
to today, but improved privacy for mutual closes.
    * An argument *for* this option is that unilateral closes (commitment 
transactions) have special scripts on their outputs anyway, thus still leak 
their privacy, but see later sections for how Taproot may help reduce the 
uniqueness of those outputs, thus *not* taking this option may still improve 
privacy for unilateral closes.

Composable MuSig
----------------

As I describe here: 
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-November/017493.html

In that write-up, I mention the use-case of nodelets.
Another use-case is for redundant hardware signers: 
https://lists.ozlabs.org/pipermail/c-lightning/2019-December/000172.html

We have the option of allowing for a composable MuSig, probably my multi-`R` 
proposal, where each participant may send one or more `R` commitments and 
subsequent `R`s.

* [ ] Not use composable MuSig of any kind, at least for now.
  * Possibly we could defer the use of a composable MuSig when a better 
composable MuSig (with security proofs) has been derived.
* [ ] Use Multi-`R` composable MuSig.
  * We need to probably impose some limit on the number of `R` commitments that 
can be sent: _____ `R`s maximum.

The latter option above affects the previous choice regarding whether to 
pre-send `R` commitments with the previous `s` sending, as this increases the 
maximal storage requirement for the pre-sent `R` commitment(s).

Pointlocked Timelocked Contracts
--------------------------------

I would have preferred to keep this in a separate discussion thread, however 
the exact details of PTLCs may affect our decision on how to sign commitment 
transactions.

PTLCs are necessary to switch the Lightning Network to payment point+scalar, 
and indeed one can argue that the entire point of enabling Schnorr and Taproot 
at the base layer is to allow us to use payment point+scalar at the Lightning 
layer.

First, I will discuss how to create a certain kind of PTLCs, which I call 
"purely scriptless" PTLCs.
In particular, I would like to point out that we *actually* use in current 
Poon-Dryja Lightning Network channels is *revocable* HTLCs, thus we need to 
have *revocable* PTLCs to replace them.

* First, we must have a sender A, who is buying a secret scalar, and knows the 
point equivalent to that scalar.
* Second, we have a receiver B, who knows this secret scalar (or can somehow 
learn this secret scalar).
* A and B agree on the specifications of the PTLC: the point, the future 
absolute timelock, the value.
* A creates (but *does not* sign or broadcast) a transaction that pays to a 
MuSig of A and B and shares the txid and output number with the relevant MuSig 
output.
* A and B create a backout transaction.
  * This backout has an `nLockTime` equal to the agreed absolute timelock.
  * It spends the above MuSig output (this input must enable `nLockTime`, e.g. 
by setting `nSequence` to `0xFFFFFFFE`).
  * It creates an output that is solely controlled by A.
* A and B perform a MuSig ritual to sign the backout transaction.
* A now signs and broadcast the first transaction, the one that has an output 
that represents the PTLC.
* A and B wait for the above transaction to confirm deeply.
  This completes the setup phase for the PTLC.
* After this point, if the agreed-upon locktime is reached, A broadcasts the 
backout transaction and aborts the ritual.
* A and B create a claim transaction.
  * This has an `nLockTime` of 0, or a present or past blockheight, or disabled 
`nLockTime`.
  * This spends the above MuSig output.
  * This creates an output that is solely controlled by B.
* A and B generate an adaptor signature for the claim transaction, which 
reveals the agreed scalar.
  * This is almost entirely a MuSig ritual, except at `s` exchange, B provides 
`t + r + h(R | MuSig(A,B) | m) * MuSigTweak(A, B, B) * b` first, then demands 
`r + h(R | MuSig(A,B) | m) * MuSigTweak(A, B, A) * a` from A, then reveals `r + 
h(R | MuSig(A,B) | m) * MuSigTweak(A, B, B) * b` (or the completed signature, 
by publishing onchain), revealing the secret scalar `t` to A.
* A is able to learn the secret scalar from the above adaptor signature 
followed by the full signature, completing the ritual.

Note that the above ritual is "purely scriptless".
It is possible to take advantage of taproot to create a tapscript equivalent to 
`<agreed locktime> OP_CHECKLOCKTIMEVERIFY OP_DROP <A> OP_CHECKSIG`.
This removes the need to perform a MuSig ritual to sign a backout transaction: 
A can generate the backout transaction all by itself.
This use is not purely scriptless, as the timelocked branch is controlled by a 
tapscript that is hidden in the pointlocked branch, meaning that taking the 
timelocked branch reveals the contract.

The tradeoff is that if we use "purely scriptless" PTLCs:

* If we have purely scriptless PTLCs, then even the timelock branch is 
potentially indistinguishable from ordinary spends.
  * We should note that Bitcoin Core itself already uses the current 
blockheight plus 1 for `nLockTime` when spending, instead of a 0 or disabled 
`nLockTime`.
  * If the above habit were more widespread (i.e. if all wallets implemented 
the use of a current `nLockTime` for ordinary onchain spends) then the timelock 
branch has an anonymity set equal to all Schnorr keypath spends, as the 
`nLockTime` is always used anyway.
  * Other kinds of offchain protocols may also utilize this technique, slightly 
increasing the anonymity set as well.
    Thus, the use of the current blockheight plus 1 for `nLockTime` should be 
recommended for improved privacy in Bitcoin anyway.
* However, purely scriptless PTLCs require a complete MuSig ritual (2.5 to 3 
round trips!) to sign the timelocked branch (the initial backout transaction); 
this increases the latency of adding new PTLCs.
  * Of note is that in the case of Lightning, we may need to add a new PTLC 
while another PTLC is *still* in-flight; on the new commitment transaction, we 
need to redo the MuSig rituals to create new backouts and new adaptor signtures 
for each PTLC.
    * This can be amortized such that we redo all the rituals for all existing 
PTLCs in parallel.
      * The use of multi-`R` composable MuSig greatly increases the storage 
requirements as well!
  * Further, the privacy gained in the timelock path is degraded or lost when 
we consider revocable PTLCs and revocable outputs.
  * It is not clear to me as fo now if the MuSig ritual for the backout 
transaction must complete in full before the MuSig ritual for the claim 
transaction (the pointlocked branch, which includes sharing an adaptor 
signature during `s` exchange).
    * If we can do these two rituals in parallel, this reduces the latency 
disadvantage of the purely scriptless PTLC to just 1 round trip compared to the 
tapscripted timelock branch PTLC.
    * Possibly the adaptor signature ritual could stop until B provides the 
adaptor signature, then full `s` exchange is deferred to after the PTLC 2-of-2 
is instantiated onchain/reified in a commitment transaction.

Thus our options are the below, but again, you should defer deciding on the 
best option until you understand about revocable PTLCs.

* [ ] We can use a purely scriptless PTLC construction.
  * Better privacy, but increased latency.
* [ ] We can use a tapscripted timelock branch and a keypath pointlocked branch 
for the PTLC.
  * Lower latency, but possibly reduced privacy advantage in the timelock 
branch (privacy advantage still exists in the pointlocked branch, which we hope 
is more common anyway).

Revocable Outputs and PTLCs
---------------------------

Poon-Dryja mechanism is based on revocation of contracts instantiated from 
previous states.
Thus, all outputs of Poon-Dryja must be made revocable.

At a high-enough level, this only requires the addition of a 
`(revocation_secret && remote_secret) || (CSV && L)` to the top-level logic 
(`L`) of a contract.
Of course, the details have the devil.

Now, in Poon-Dryja, each side of the channel has its own commitment transaction.
Thus, contracts on the commitment transaction refer to a "local side" and a 
"remote side".
The "local side" is whoever is holding the completely-signed commitment 
transaction, while the "remote side" is the other side.

Revocable outputs always have a CSV-requirement before the output can be spent 
by whoever "should" own the output, according to the contract details.
The revocation secret is known by the local side, and then when a *new* 
commitment transaction has been signed, the revocation secret is given by the 
local side to the remote side, allowing all outputs to be spent directly by the 
remote side if an old, revoked commitment transaction is published onchain.

There are many ways to implement revocable outputs.
The core idea of revocable outputs, however, is that there must exist some 
relative-locktime branch on each output that goes to the local side.
This relative-locktime branch can be implemented as "purely scriptless" by 
using a 2-of-2 of both the local and remote sides, with a relative-locktime 
`nSequence`, using the same technique as described in the previous section.

However, unlike the absolute-locktime `nLockTime` for the timelock branches of 
PTLCs, ***there is no current wallet software that uses 
activated-relative-locktime `nSequence` for ordinary spends***.
Thus, any use of the relative-locktime branch does *not* have a privacy 
advantage under purely scriptless.

Thus the tradeoffs here are different, and definitely in favor of the 
tapscripted-relative-locktime technique.

* There is no current wallet software that uses relative locktimes.
  * Bitcoin Core uses absolute locktimes with the current blockheight plus 1, 
and we can hide the use of absolute locktimes by imitating this Bitcoin Core 
behavior.
  * Any use of relative locktimes is a strong signal of some kind of 
complicated offchain updateable mechanism.
    We can note as well that Decker-Russell-Osuntokun also uses relative 
locktimes.
* The relative-locktime branch in revocable outputs is the **desirable** case, 
because taking the relative locktime means that the commitment transaction 
published *was not* a revoked transaction (i.e. it was the latest transaction 
version).
  * Thus, it would be nice if this had good privacy.
  * However, this *cannot* have good privacy since there is no current common 
use of activated relative locktimes for ordinary spends.

The latter point above also biases us towards rejecting purely-scriptless in 
the *previous* section, in particular:

* The absolute-locktime branch in the PTLC is the **undesirable** case, where 
the payee B somehow stops responding to A.
  * In particular, propagating failure backwards is done by simply deleting 
PTLCs, thus the absolute-locktime branch does not come into play during payment 
failure.
  * Thus, the privacy increase of hiding absolute-locktime branches is minor, 
and the privacy breach of revocable outputs (i.e. it leaks the use of 
relative-locktime, and nearly all uses of relative locktime will be offchain 
updateable cryptocurrency mechanisms, such as Poon-Dryja or 
Decker-Russell-Osuntokun) is arguably much larger than the privacy increase of 
purely-scriptless absolute-locktime.

Of particular not is that if a PTLC is instantiated on the commitment 
transaction of the payer A, then the absolute-locktime backout transaction must 
*not* pay to A only, but instead pays to a *revocable output* that will 
eventually pay to A after the relative locktime.
Thus, the privacy boost of the purely-scriptless backout transaction would be 
lost by the later revelation of the use of a relative locktime after the 
revocable output is reclaimed by A.
Again, that use of relative locktime (whether enforced by script, or by 
scriptless use of a 2-of-2 that is spent with an activated relative-locktime 
`nSequence`) is a strong indicator of the use of Poon-Dryja or 
Decker-Russell-Osuntokun or even Decker-Wattenhofer mechanisms, and the logic 
is that since Lightning Network is the most widespread offchain mechanism, it 
probably indicates the use of LN.

Thus the decision in the previous section is affected by this reality that we 
in fact need *revocable* PTLCs, not plain PTLCs, thus the advantage of 
purely-scriptless backout transactions in the previous section is reduced by 
the need to make outputs revocable.

Thus:

* Revocable outputs require a relative-timelock branch.
* That branch is the **desirable** branch, i.e. the latest commitment 
transaction is the one that got published and thus is *not* revoked.
  * We thus expect this relative-timelock branch to be the *common* branch.
* No wallet uses relative-timelock for ordinary spends, unlike abolute-locktime 
where Bitcoin Core always uses absolute-locktime `nLockTime` for ordinary 
spends.
  * Thus, using purely scriptless for the relative-timelock branch of revocable 
outputs does not in fact hide that we are doing something special.

Conclusion
----------

Others may find further issues or alternative options for the above points.
Further discussion may be warranted before we actually select particular 
options to implement and evaluate in alpha software.

Regards,
ZmnSCPxj

_______________________________________________
Lightning-dev mailing list
Lightning-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev

Reply via email to