Re: [Lightning-dev] Eltoo, anyprevout and chaperone signatures

2019-05-16 Thread Anthony Towns
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 

Re: [Lightning-dev] Eltoo, anyprevout and chaperone signatures

2019-05-16 Thread Bastien TEINTURIER
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