ZmnSCPxj [ARCHIVE] on Nostr: 📅 Original date posted:2019-12-17 📝 Original message: Good morning, > On Sun, ...
📅 Original date posted:2019-12-17
📝 Original message:
Good morning,
> On Sun, Dec 15, 2019 at 03:43:07PM +0000, ZmnSCPxj via Lightning-dev wrote:
>
> > 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.
>
> Supporting PTLCs instead of HTLCs is a global upgrade in that you need
> all nodes along your payment path to support it; moving from Poon-Dryja
> to Decker-Russell-Osuntokun is only relevant to individual peers. So I
> think it makes sense to do PTLCs first if the required features aren't
> both enabled at the same time.
Indeed.
The question is then do we upgrade Poon-Dryja to *at least* use a MuSig on mutual close (for the privacy boost of mutual closes), or do we just keep Poon-Dryja as is now, and add PTLCs from them.
>
> > Poon-Dryja with Schnorr
> >
> > ------------------------
>
> I think MuSig between the two pairs is always superior to a NUMS point
> for the taproot internal key; you definitely want to calculate a point
> rather than use a constant, or you're giving away that it's lightning,
> and if you're calculating you might as well calculate something that can
> be used for a cooperative key path spend if you ever want to.
I am uncertain why a NUMS point would be used here, except if you wanted to simulate an explicit 2-of-3 from your explicit 2-of-2, which while interesting is really a foolish idea and I will now lurk forever (for some definition of "forever") because of ever suggesting it.
>
> > A potential issue with MuSig is the increased number of communication rounds needed to generate signatures.
>
> I think you can reduce this via an alternative script path. In
> particular, if you want a script that the other guy can spend if they
> reveal the discrete log of point X, with musig you do:
Not quite the correct section?
This section is discussing the Poon-Dryja updateable mechanism, not the PTLCs, and it is the the "PTLC" which requires discrete log of a point.
But in any case....
>
> P = H(H(A,B),1)*A + H(H(A,B),2)*B
> [exchange H(RA),H(RB),RA,RB]
>
> [send X]
>
> sb = rb + H(RA+RB+X,P,m)*H(H(A,B),2)*b
>
> [wait for sb]
>
> sa = ra + H(RA+RB+X,P,m)*H(H(A,B),1)*a
>
> [store RA+RB+X, sa+sb, supply sa, watch for sig]
>
> sig = (RA+RB+X, sa+sb+x)
>
> So the 1.5 round trips are "I want to do a PTLC for X", "okay here's
> sb", "great, here's sa".
>
> But with taproot you can have a script path as well, so you could have a
> script:
>
> A CHECKSIGVERIFY B CHECKSIG
>
> and supply a partial signature:
>
> R+X,s,X where s = r + H(R+X,A,m)*a
>
> to allow them to satisfy "A CHECKSIGVERIFY" if they know the discrete
> log of X, and of course they can sign with B at any time. This is only
> half a round trip, and can be done at the same time as sending the "I
> want to do a PTLC for X" message to setup the (ultimately cheaper) MuSig
> spend. It's an extra signature on the sender's side and an extra verification
> on the receiver's side, but I think it works out fine.
Ah, so I suppose you are saying that it is possible to create an adaptor signature for what is effectively a 1-of-1 Schnorr pubkey, and that can implement the pointlocked branch?
Just to be clear, in the above:
* A is the payer (and wants to pay if and only if it can learn the payment).
* B is the payee (and knows the secret).
So A gives a pointlock condition to the payee by providing an adaptor signature for its pubkey A, which cannot be used to validate, but B can simply add the secret `x` that is the discrete log of `X`.
And since A knows the above adaptor signature which it generated, once the completed signature for A is given by B, A can simply subtract it with the stored adaptor signature to learn the secret.
However, we still need a branch for the timelock, and if the output is revocable, some more additional conditions and/or scripts need to be made.
We could use the same script for a revocable timelocked transaction going back to A, but A would have to get the signature from B for this revocable timelocked transaction *before* it hands over the adaptor signature (else B can just keep the adaptor signature forever and not claim the funds until its own convenience, possibly beyond the time that the scalar is useful).
This may mean adding one more round trip.
>
> > Pointlocked Timelocked Contracts
> >
> > ---------------------------------
> >
> > 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.
>
> (I think it makes more sense to provide "r + H(R+T, P, m)*b" instead of
> "r+t + H(R,P,m)*b" -- you might not know "t" at the point you need to
> start the signature exchange)
Ah, so basically the signature that appears onchain would be `(R + T, r + t + h(R + T | P | m) * p)`?
>
> I think the setup can be similar to BOLT-3:
>
> Funding TX output: MuSig(A,B)
>
> Commitment Tx Held by A:
> - locktime: obscured commitment number
> - input: funding tx
> - outputs:
> balance A
> balance B
> PTLC paying to A
> PTLC paying to B
> [etc]
Just to be clear, "PTLC paying to A" means the pointlock branch pays to A, the timelock branch pays to B, right?
>
> balance B can pay directly to B
>
> balance A pays to MuSig(Rn,B) -- where Rn is the revocation key for the
> nth commitment, and A holds a presigned tx by B with relative locktime
> set, paying the funds to A.
>
> PTLCs also pay to MuSig(Rn,B) --
>
> for the one paying to A, A holds a tx
> partially presigned by B that needs the point's discrete log added to x
> with relative timelock; for the one paying to B, A holds a presigned tx
> by B that has absolute locktime set and pays to MuSig(Rn,B) for which
> A has another presigned tx by B that has relative locktime set.
>
> HTLC's also pay to MuSig(Rn,B) but they're tweaked by a script -- if
> they're paying to B, A just holds the same timelocked presigned tx's as
> for PTLCs; if they're paying to A, A will use a "HASH160 X EQUALVERIFY
> A CHECKSIGVERIFY delay CSV" script path instead.
>
> B has a similar commitment Tx; and A holds pre-signed tx's for the
> PTLC's there, except without the relative timelock txs.
>
> This adds up to B needing to provide A with signatures for:
>
> the funding tx
> A's balance
> each PTLC/HTLC paying/refunding to A from A's commitment and the sub tx for each of those
> each PTLC/HTLC paying/refunding to B from B's commitment
>
> and each of those signatures need to be updated every commitment update.
>
> Note that you need to receive all the partial signatures to spend the
> commitment tx before you provide your partial signature over the funding
> tx to authorise the commitment tx. So yet more rounds of communication.
Yes, this looks like it needs some more fleshing out.
>
> I think this approach would let you upgrade existing channels to support
> PTLCs without closing/reopening, though.
I believe so as well, as of course the base layer allows transactions to have a mix of SegWit v0 (HTLCs) and SegWit v1 (PTLCs) outputs.
>
> I think you could do something eltoo-ish to simplify watchtowers:
>
> Funding TX output: MuSig(A,B)
>
> Commitment Tx Held by A:
> - locktime: obscured commitment number
> - inputs: funding tx
> - outputs: MuSig(Rn,B)
>
> Settlement Tx Held by A:
> - nsequence: to_self_delay
> - input: commitment tx held by A
> - outputs:
> balance A
> balance B
> PTLC paying to A
> PTLC paying to B
>
> Secondary Settlement Tx Held by B:
> - no abs/relative locktime
> - input: commitment tx held by A
> - outputs:
> balance A
> balance B
> PTLC paying to A
> PTLC paying to B
>
> in which case once the commitment is revoked, B only needs to do a single
> signature of MuSig(Rn,B) to claim all the funds if A publishes the
> old commitment, without having to worry about any HTLC/PTLC info? The
> settlement tx can be a bit simplified I think too. Maybe the edge case
> when the absolute locktime is close to the relative locktime makes this
> painful, though I think it would make eltoo painful then too? Not sure
> if I'm missing something here.
Indeed, having the relative locktime affect the absolute locktime is a pain, and I hope to have moved away from pathfinding before Decker-Russell-Osuntokun arrives and makes it a headache to find paths.
The issue is that the relative locktime for Decker-Russell-Osuntokun must be combined over each step of the route via the "max" function instead of the "`+`" function, and all existing pathfinding algos assume costs are combined via "`+`".
I suppose this is doable by annotating each node with the current max-csv, and if the node under evaluation has a higher csv requirement than the max-csv of the node it is arriving from, treat that edge as having a higher cost, but bleah.
>
> (Note that this gives symmetric delays: if A unilaterally closes the
> channel by publishing the commitment tx, and B wants their funds, B can
> either immediately claim all the funds via the revocation secret if A
> was cheating, or has to publish the settlement tx first, at which point
> A can get all A's funds immediately as well)
>
> > Revocable Outputs and PTLCs
> >
> > ----------------------------
> >
> > - No wallet uses relative-timelock for ordinary spends, unlike abolute-locktime where Bitcoin Core always uses absolute-locktime `nLockTime` for ordinary spends.
>
> I think the fact lightning relative timelocks will be "round" numbers,
> and the timelocked tx will be published as soon as possible will make
> it relatively easy to distinguish them from other spends anyway. Doing
> it scriptlessly is cheaper on chain though.
>
> Anyway, my picks are:
>
> - [x] Poon-Dryja PTLCs prior to eltoo
> - [x] scriptless revocation via MuSig(Rn,B) internal keys
> - [x] support HTLCs via taproot
> - [x] (optionally) allow use of script paths to minimise round trip
> delay
>
> Cheers,
> aj
>
Thank you for your considered opinion as well as the new adaptor constructions.
Regards,
ZmnSCPxj
📝 Original message:
Good morning,
> On Sun, Dec 15, 2019 at 03:43:07PM +0000, ZmnSCPxj via Lightning-dev wrote:
>
> > 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.
>
> Supporting PTLCs instead of HTLCs is a global upgrade in that you need
> all nodes along your payment path to support it; moving from Poon-Dryja
> to Decker-Russell-Osuntokun is only relevant to individual peers. So I
> think it makes sense to do PTLCs first if the required features aren't
> both enabled at the same time.
Indeed.
The question is then do we upgrade Poon-Dryja to *at least* use a MuSig on mutual close (for the privacy boost of mutual closes), or do we just keep Poon-Dryja as is now, and add PTLCs from them.
>
> > Poon-Dryja with Schnorr
> >
> > ------------------------
>
> I think MuSig between the two pairs is always superior to a NUMS point
> for the taproot internal key; you definitely want to calculate a point
> rather than use a constant, or you're giving away that it's lightning,
> and if you're calculating you might as well calculate something that can
> be used for a cooperative key path spend if you ever want to.
I am uncertain why a NUMS point would be used here, except if you wanted to simulate an explicit 2-of-3 from your explicit 2-of-2, which while interesting is really a foolish idea and I will now lurk forever (for some definition of "forever") because of ever suggesting it.
>
> > A potential issue with MuSig is the increased number of communication rounds needed to generate signatures.
>
> I think you can reduce this via an alternative script path. In
> particular, if you want a script that the other guy can spend if they
> reveal the discrete log of point X, with musig you do:
Not quite the correct section?
This section is discussing the Poon-Dryja updateable mechanism, not the PTLCs, and it is the the "PTLC" which requires discrete log of a point.
But in any case....
>
> P = H(H(A,B),1)*A + H(H(A,B),2)*B
> [exchange H(RA),H(RB),RA,RB]
>
> [send X]
>
> sb = rb + H(RA+RB+X,P,m)*H(H(A,B),2)*b
>
> [wait for sb]
>
> sa = ra + H(RA+RB+X,P,m)*H(H(A,B),1)*a
>
> [store RA+RB+X, sa+sb, supply sa, watch for sig]
>
> sig = (RA+RB+X, sa+sb+x)
>
> So the 1.5 round trips are "I want to do a PTLC for X", "okay here's
> sb", "great, here's sa".
>
> But with taproot you can have a script path as well, so you could have a
> script:
>
> A CHECKSIGVERIFY B CHECKSIG
>
> and supply a partial signature:
>
> R+X,s,X where s = r + H(R+X,A,m)*a
>
> to allow them to satisfy "A CHECKSIGVERIFY" if they know the discrete
> log of X, and of course they can sign with B at any time. This is only
> half a round trip, and can be done at the same time as sending the "I
> want to do a PTLC for X" message to setup the (ultimately cheaper) MuSig
> spend. It's an extra signature on the sender's side and an extra verification
> on the receiver's side, but I think it works out fine.
Ah, so I suppose you are saying that it is possible to create an adaptor signature for what is effectively a 1-of-1 Schnorr pubkey, and that can implement the pointlocked branch?
Just to be clear, in the above:
* A is the payer (and wants to pay if and only if it can learn the payment).
* B is the payee (and knows the secret).
So A gives a pointlock condition to the payee by providing an adaptor signature for its pubkey A, which cannot be used to validate, but B can simply add the secret `x` that is the discrete log of `X`.
And since A knows the above adaptor signature which it generated, once the completed signature for A is given by B, A can simply subtract it with the stored adaptor signature to learn the secret.
However, we still need a branch for the timelock, and if the output is revocable, some more additional conditions and/or scripts need to be made.
We could use the same script for a revocable timelocked transaction going back to A, but A would have to get the signature from B for this revocable timelocked transaction *before* it hands over the adaptor signature (else B can just keep the adaptor signature forever and not claim the funds until its own convenience, possibly beyond the time that the scalar is useful).
This may mean adding one more round trip.
>
> > Pointlocked Timelocked Contracts
> >
> > ---------------------------------
> >
> > 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.
>
> (I think it makes more sense to provide "r + H(R+T, P, m)*b" instead of
> "r+t + H(R,P,m)*b" -- you might not know "t" at the point you need to
> start the signature exchange)
Ah, so basically the signature that appears onchain would be `(R + T, r + t + h(R + T | P | m) * p)`?
>
> I think the setup can be similar to BOLT-3:
>
> Funding TX output: MuSig(A,B)
>
> Commitment Tx Held by A:
> - locktime: obscured commitment number
> - input: funding tx
> - outputs:
> balance A
> balance B
> PTLC paying to A
> PTLC paying to B
> [etc]
Just to be clear, "PTLC paying to A" means the pointlock branch pays to A, the timelock branch pays to B, right?
>
> balance B can pay directly to B
>
> balance A pays to MuSig(Rn,B) -- where Rn is the revocation key for the
> nth commitment, and A holds a presigned tx by B with relative locktime
> set, paying the funds to A.
>
> PTLCs also pay to MuSig(Rn,B) --
>
> for the one paying to A, A holds a tx
> partially presigned by B that needs the point's discrete log added to x
> with relative timelock; for the one paying to B, A holds a presigned tx
> by B that has absolute locktime set and pays to MuSig(Rn,B) for which
> A has another presigned tx by B that has relative locktime set.
>
> HTLC's also pay to MuSig(Rn,B) but they're tweaked by a script -- if
> they're paying to B, A just holds the same timelocked presigned tx's as
> for PTLCs; if they're paying to A, A will use a "HASH160 X EQUALVERIFY
> A CHECKSIGVERIFY delay CSV" script path instead.
>
> B has a similar commitment Tx; and A holds pre-signed tx's for the
> PTLC's there, except without the relative timelock txs.
>
> This adds up to B needing to provide A with signatures for:
>
> the funding tx
> A's balance
> each PTLC/HTLC paying/refunding to A from A's commitment and the sub tx for each of those
> each PTLC/HTLC paying/refunding to B from B's commitment
>
> and each of those signatures need to be updated every commitment update.
>
> Note that you need to receive all the partial signatures to spend the
> commitment tx before you provide your partial signature over the funding
> tx to authorise the commitment tx. So yet more rounds of communication.
Yes, this looks like it needs some more fleshing out.
>
> I think this approach would let you upgrade existing channels to support
> PTLCs without closing/reopening, though.
I believe so as well, as of course the base layer allows transactions to have a mix of SegWit v0 (HTLCs) and SegWit v1 (PTLCs) outputs.
>
> I think you could do something eltoo-ish to simplify watchtowers:
>
> Funding TX output: MuSig(A,B)
>
> Commitment Tx Held by A:
> - locktime: obscured commitment number
> - inputs: funding tx
> - outputs: MuSig(Rn,B)
>
> Settlement Tx Held by A:
> - nsequence: to_self_delay
> - input: commitment tx held by A
> - outputs:
> balance A
> balance B
> PTLC paying to A
> PTLC paying to B
>
> Secondary Settlement Tx Held by B:
> - no abs/relative locktime
> - input: commitment tx held by A
> - outputs:
> balance A
> balance B
> PTLC paying to A
> PTLC paying to B
>
> in which case once the commitment is revoked, B only needs to do a single
> signature of MuSig(Rn,B) to claim all the funds if A publishes the
> old commitment, without having to worry about any HTLC/PTLC info? The
> settlement tx can be a bit simplified I think too. Maybe the edge case
> when the absolute locktime is close to the relative locktime makes this
> painful, though I think it would make eltoo painful then too? Not sure
> if I'm missing something here.
Indeed, having the relative locktime affect the absolute locktime is a pain, and I hope to have moved away from pathfinding before Decker-Russell-Osuntokun arrives and makes it a headache to find paths.
The issue is that the relative locktime for Decker-Russell-Osuntokun must be combined over each step of the route via the "max" function instead of the "`+`" function, and all existing pathfinding algos assume costs are combined via "`+`".
I suppose this is doable by annotating each node with the current max-csv, and if the node under evaluation has a higher csv requirement than the max-csv of the node it is arriving from, treat that edge as having a higher cost, but bleah.
>
> (Note that this gives symmetric delays: if A unilaterally closes the
> channel by publishing the commitment tx, and B wants their funds, B can
> either immediately claim all the funds via the revocation secret if A
> was cheating, or has to publish the settlement tx first, at which point
> A can get all A's funds immediately as well)
>
> > Revocable Outputs and PTLCs
> >
> > ----------------------------
> >
> > - No wallet uses relative-timelock for ordinary spends, unlike abolute-locktime where Bitcoin Core always uses absolute-locktime `nLockTime` for ordinary spends.
>
> I think the fact lightning relative timelocks will be "round" numbers,
> and the timelocked tx will be published as soon as possible will make
> it relatively easy to distinguish them from other spends anyway. Doing
> it scriptlessly is cheaper on chain though.
>
> Anyway, my picks are:
>
> - [x] Poon-Dryja PTLCs prior to eltoo
> - [x] scriptless revocation via MuSig(Rn,B) internal keys
> - [x] support HTLCs via taproot
> - [x] (optionally) allow use of script paths to minimise round trip
> delay
>
> Cheers,
> aj
>
Thank you for your considered opinion as well as the new adaptor constructions.
Regards,
ZmnSCPxj