Re: [Lightning-dev] Eltoo, anyprevout and chaperone signatures
On Thu, May 16, 2019 at 09:55:57AM +0200, Bastien TEINTURIER wrote: > Thanks for your answers and links, the previous discussions probably happened > before I joined this list so I'll go dig into the archive ;) The discussion was on a different list anyway, I think, this might be the middle of the thread: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-March/016777.html > > Specifically we can't make make use of the collaborative path where > > we override an `update_tx` with a newer one in taproot as far as I can > > see, since the `update_tx` needs to be signed with noinput (for > > rebindability) but there is no way for us to specify the chaperone key > > since we're not revealing the committed script. > Can you expand on that? Why do we need to "make use of the collaborative path" > (maybe it's unclear to me what you mean by collaborative path here)? I think Christian means the "key path" per the terminology in the taproot bip. That's the path that just provides a signature, rather than providing an internal key, a script, and signatures etc for the script. > I feel like there will be a few other optimizations that are unlocked by > taproot/tapscript, it will be interesting to dig into that. I had a go at drafting up scripts, and passed them around privately to some of the people on this list already. They're more "thought bubble" than even "draft" yet, but for the sake of discussion: --- FWIW, the eltoo scripts I'm imaginging with this spec are roughly: UPDATE TX n: nlocktime: 500e6+n nsequence: 0 output 0: P = muSig(A,B) scripts = [ "OP_1 CHECKSIGVERIFY X CHECKSIGVERIFY 500e6+n+1 CLTV" ] witness: sig(P,hash_type=SINGLE|ANYPREVOUTANYSCRIPT=0xc3) sig(X,hash_type=0) SETTLEMENT TX n: nlocktime: 500e6+n+1 nsequence: [delay] output 0: A output 1: B output n: (HTLC) P = muSig(A,B) scripts = [ "OP_1 CHECKSIGVERIFY X CHECKSIG" "A CHECKSIGVERIFY CLTV" ] witness: sig(P,hash_type=ALL|ANYPREVOUT=0x41) sig(X,hash_type=0) HTLC CLAIM (reveal secp256k1 preimage R): witness: hash-of-alternative-script sig(P,hash_type=SINGLE|ANYPREVOUT,reveal R) sig(X,hash_type=0) HTLC REFUND (timeout): witness: hash-of-alternative-script sig(A,hash_type=ALL) Because "n" changes for each UPDATE tx, each ANYPREVOUT signature (for the SETTLEMENT tx) commits to a specific UPDATE tx via both the scriptPubKey commitment and the tapleaf_hash commitment. So the witness data for both txs involve revealing: 33 byte control block 43 byte redeem script 65 byte anyprevout sig 64 byte sighash all sig Compared to a 65 byte key path spend (if ANYPREVOUT worked for key paths), that's an extra 143 WU or 35.75 vbytes, so about 217% more expensive. The update tx script proposed in eltoo.pdf is (roughly): "IF 2 Asi Bsi ELSE <500e6+n+1> CLTV DROP 2 Au Bu ENDIF 2 OP_CHECKMULTISIG" 148 byte redeem script 65 byte anyprevout sig by them 64 byte sighash all sig by us "1" or "0" to control the IF which I think would be about 282 WU total, or an extra 216 WU/54 vbytes over a 65 byte key path spend, so about 327% more expensive. So at least we're a lot better than where we were with BIP 118, ECDSA and p2wsh. Depending on if you can afford generating a bunch more signatures you could also have a SIGHASH_ALL key path spend for the common unilateral case where only a single UPDATE TX is published. UPDATE TX n (alt): input: FUNDING TX witness: sig(P,hash_type=0) output 0: P = muSig(A,B) scripts = [ "OP_1 CHECKSIGVERIFY X CHECKSIGVERIFY 500e6+n+1 CLTV" ] SETTLEMENT TX n (alt): nsequence: [delay] input: UPDATE TX n (alt) witness: sig(P+H(P||scripts)*G,hash_type=0) outputs: [as above] (This approach can either use the same ANYPREVOUT sigs for the HTLC claims, or could include an additional sig for each active HTLC for each channel update to allow HTLC claims via SIGHASH_ALL scriptless scripts...) Despite using SIGHASH_SINGLE, I don't think you can combine two UPDATE txs generally, because the nlocktime won't match (this could possibly be fixed in a future soft-fork by using the annex to support per-input absolute locktimes). You can't combine SETTLEMENT tx, because the ANYPREVOUT signature needs to commit to multiple outputs (one for my balance, one for yours, one for each active HTLC). Combining HTLC refunds is kind-of easy, but only possible in the first place if you've got a bunch expiring at the same time, which might not be that likely. Combining HTLC claims should be easy enough since they just need scriptless-script signatures. For fees, because of ALL|ANYPREVOUT, you can add a new input and new change output to bring-your-own-fees for the UPDATE tx; and while you can't do that for the SETTLEMENT tx, you can immediately spend your channel-balance output to add fees via CPFP. As far as "X" goes, calculating the private key as a HD key using ECDH between the peers t
Re: [Lightning-dev] Eltoo, anyprevout and chaperone signatures
Thanks for your answers and links, the previous discussions probably happened before I joined this list so I'll go dig into the archive ;) > I think it makes sense for us to consider both variants, one committing > to the script and the other not committing to the script, but I think it > applies rather to the `update_tx` <-> `settlement_tx` link and less to > the `funding_tx` <-> `update_tx` link and `update_tx` <-> `update_tx` > link. The reason is that the `settlement_tx` needs to be limited to be > bindable only to the matching `update_tx` (`anyprevout`), while > `update_tx` need to be bindable to the `funding_tx` as well as any prior > `update_tx` which differ in the script by at least the state number > (hence `anyprevoutanyscript`). > Like AJ pointed out in another thread, the use of an explicit trigger > transaction is not really needed since any `update_tx` can act as a > trigger transaction (i.e., start the relative timeouts to tick). Thanks for confirming, that was how I understood it too. > Specifically we can't make make use of the collaborative path where > we override an `update_tx` with a newer one in taproot as far as I can > see, since the `update_tx` needs to be signed with noinput (for > rebindability) but there is no way for us to specify the chaperone key > since we're not revealing the committed script. Can you expand on that? Why do we need to "make use of the collaborative path" (maybe it's unclear to me what you mean by collaborative path here)? When we override an `update_tx` we use a new state number and we derive the new keys for that state independently of the keys of the previous state right? So we would derive new settlement keys and potentially chaperone keys, and re-create a merkle tree and taproot from scratch. I don't see where taproot interacts in a negative way with noinput there... > For that matter the `OP_CHECKMULTISIG`/`OP_CHECKSIGADD` could be reduced by using MuSig on the two participants. > Further, there is no need for an explicit `OP_CHECKSEQUENCEVERIFY` or even separate keys for state and update paths. Thanks for the suggestions, these are good optimizations. I feel like there will be a few other optimizations that are unlocked by taproot/tapscript, it will be interesting to dig into that. Thanks, Bastien Le jeu. 16 mai 2019 à 03:48, ZmnSCPxj a écrit : > Good morning, > > > > > > We could collapse those 1-of-2 multisigs into a single-sig if we just > > collaboratively create a shared private key that is specific to the > > instance of the protocol upon setup. That minimizes the extra space > > needed. > > For that matter the `OP_CHECKMULTISIG`/`OP_CHECKSIGADD` could be reduced > by using MuSig on the two participants. > Further, there is no need for an explicit `OP_CHECKSEQUENCEVERIFY` or even > separate keys for state and update paths. > xref. > https://lists.linuxfoundation.org/pipermail/lightning-dev/2019-March/001933.html > > The proposal that does not include `OP_CODESEPARATOR` is: > > OP_CHECKLOCKTIMEVERIFY OP_DROP > OP_CHECKSIG OP_CHECKSIG > > Where `C` is the common key that Christian described above, and `index` is > the update number index. > > For update transactions, `nSequence` is 0. > For state transactions, `nSequence` is non-0. > Both of them will have `nLockTime` equal to the required index. > The `nSequence` is enforced by the participants refusing to sign invalid > `nSequence`. > > The above seems quite optimized. > > > > (I ommitted the tapscript changes, ie moving to OP_CHECKSIGADD, to > > > highlight only the chaperone changes) > > > When updating the channel, Alice and Bob would exchange their > > > anyprevoutanyscript signatures (for the 2-of-2 multisig). > > > The chaperone signature can be provided by either Alice or Bob at > > > transaction broadcast time (so that it commits to a specific input > > > transaction). > > > It seems to me that using the same key for both signatures (the > chaperone > > > one and the anyprevoutanyscript one) is safe here, but if someone knows > > > better I'm interested. > > > If that's unsafe, we simply need to introduce another key-pair > (chaperone > > > key). > > > Is that how you guys understand it too? Do you have other ideas on how > to > > > comply with the need for a chaperone signature? > > > Note that as Anthony said himself, the BIP isn't final and we don't > know > > > yet if chaperone signatures will eventually be needed, but I think it's > > > useful to make sure that Eltoo could support it. > > > > I quite like the chaperone idea, however it doesn't really play nice > > with taproot collaborative spends that require anyprevout / > > anyprevoutanyscript / noinput, which would make our transactions stand > > out quite a bit. Then again this is only the case for the unhappy, > > unilateral close, path of the protocol, which (hopfully) should happen > > rarely. > > The mere use of any `SIGHASH` that is not `SIGHASH_ALL` already stands out. > So I think this is not a sign