Re: [Lightning-dev] eltoo: A Simplified update Mechanism for Lightning and Off-Chain Contracts

2018-05-01 Thread ZmnSCPxj via Lightning-dev
Hi Christian,

Let me know if I have summarized the paper accurately below:

1.  SIGHASH_NOINPUT removes all inputs of the transaction copy before 
signing/verifying.

2.  SIGHASH_NOINPUT can be combined with SIGHASH_SINGLE.  It is dangerous to 
combine it with SIGHASH_NONE (as this also deletes all outputs of the 
transaction copy, so the signature only commits to nLockTime) and possibly 
pointless to combine it with SIGHASH_ANYONECANPAY (which deletes other inputs, 
but since there are no inputs after SIGHASH_NOINPUT, there is nothing else to 
delete).  The BIP only mentions combining it with SIGHASH_SINGLE, in any case.

3.  We have these kinds transactions: (1) funding transaction paying out to an 
ordinary N-of-N multisig (confirmed onchain); (2) offchain trigger transaction 
spending a funding transaction and paying out to the "update transaction 
script"; (3) offchain update transaction spending a trigger or update 
transaction and paying out to the "update transaction script" (the same script 
template as in trigger transaction); (4) offchain settlement transaction 
spending a trigger or update transaction and paying out to the counterparties 
according to the final agreed distribution of funds.  Update and settlement 
transactions are signed with SIGHASH_NOINPUT flags.

4.  The update transaction script has two branches: a CSV-encumbered N-of-N 
"settlement" branch, and a CLTV-encumbered N-of-N "update" branch.  Crucially, 
we use past Unix timestamps for the CLTV encumberance on the update.  The 
CLTV-encumberance starts with a minimum time value on the trigger transaction, 
and increments by 1 for every update transaction.

5.  The CLTV-encumberance ensures that if a past update transaction is 
confirmed, we can spend it using any later update transaction, since CLTV uses 
`stackTop <= nLockTime`.  The actual `nLockTime` we use is a past Unix 
timestamp so they are not actually time-encumbered, but the `OP_CLTV` still 
ensures that any later update transaction can be used to spend from any earlier 
update transaction, but not vice versa.  This is actually quite clever.

6.  The pubkeys on the settlement branch of each update transaction are 
different, and are derived using any hierarchical derivation method (trivially 
we can simply use the CLTV-encumberance value as the derivation index).  This 
ensures that each settlement transaction can only spend a particular update 
transaction.  Or in other words: There is a one-to-one correspondence between 
update and settlement transaction, and a settlement transaction can only 
confirm if the corresponding update transaction can be confirmed deeply enough 
without having its output re-spent.

7.  The pubkeys on the update branch are all the same in all update 
transactions.  This lets any update transaction replace any other update 
transaction, as long as the CLTV-encumberance (which is used for ordering 
rather than actual absolute locktime) is respected; together they mean that any 
later update transaction can replace any earlier update transaction.

8.  If an old update transaction is confirmed, the settlement transaction 
corresponding to it is still encumbered by CSV and cannot be confirmed 
immediately.  During this time, a later update transaction can spend it and be 
confirmed.  If that update transaction is still not the latest available, it 
can be further replaced with any, later transaction (since the 
CLTV-encumberance and the `nLockTime` increase in lockstep with each other) 
until the latest update transaction is confirmed.

9.  When the latest update transaction gets confirmed, no other update 
transaction can successfully spend its "update" branch (as their `nLockTime` is 
less than the CLTV-encumberance on that branch).  This lets the CSV-encumbered 
settlement transaction be confirmable after some blocks.

10.  Update transactions pay no fees!  Instead, for update transactions (but 
not settlement transactions) we additionally give SIGHASH_SINGLE: thus, no 
matter what transaction they end up in, the signatures for the update 
transaction will always be verified against only the update transaction output 
that pays out to the update transaction script.  We join update transactions 
with a spend of some onchain UTXO we control, which pays for the fees of the 
joined the update transactions, and may have a second output that is the 
remainder of the fund after paying the fees.

11.  Settlement transactions can carry contracts (in much the same way that 
Poon-Dryja commitment transactions); however contracts that contain absolute 
timelock components will be affected by the CSV-encumberance of the settlement 
transaction.

---

Some pros and cons relative to Poon-Dryja (LN-penalty) channels:

- Requires more transactions in the worst-case: trigger, update, settlement.  
Compare to Poon-Dryja: commitment, claim.  Decker-Russell-Osuntokun channels 
can be trigger-settlement but only in the degenerate case where the channel was 
never 

Re: [Lightning-dev] eltoo: A Simplified update Mechanism for Lightning and Off-Chain Contracts

2018-05-01 Thread Christian Decker
ZmnSCPxj  writes:
> Good morning Christian,
>
> This is very interesting indeed!
>
> I have started skimming through the paper.
>
> I am uncertain if the below text is correct?
>
>> Throughout this paper we will use the terms *input script* to refer to 
>> `witnessProgram` and `scriptPubKey`, and *output script* to refer to the 
>> `witness` or `scriptSig`.
>
> Figure 2 contains to what looks to me like a `witnessProgram`, 
> `scriptPubKey`, or `redeemScript` but refers to it as an "output script":
>
>>OP_IF
>>10 OP_CSV
>>2 As Bs 2 OP_CHECKMULTISIGVERIFY
>>OP_ELSE
>>2 Au Bu 2 OP_CHECKMULTISIGVERIFY
>>OP_ENDIF
>>
>> Figure 2: The output script used by the on-chain update transactions.
>
> Regards,
> ZmnSCPxj

Darn last minute changes! Yes, you are right, I seem to have flipped the
two definitions. I'll fix that up and push a new version.
___
Lightning-dev mailing list
Lightning-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev


Re: [Lightning-dev] eltoo: A Simplified update Mechanism for Lightning and Off-Chain Contracts

2018-05-01 Thread Christian Decker
Excellent summary ZmnSCPxj, I'll try to address the points inline (if
there is anything to add that is):

ZmnSCPxj  writes:
> Hi Christian,
>
> Let me know if I have summarized the paper accurately below:
>
> 1.  SIGHASH_NOINPUT removes all inputs of the transaction copy before
> signing/verifying.

It sets them to a known constant, in this case we just blank
them. Removing could entail more costly serialization depending on the
implementation. bitcoind serializes into a hash accumulator so it'd not
make a difference there, but others may do it differently.

> 2.  SIGHASH_NOINPUT can be combined with SIGHASH_SINGLE.  It is
> dangerous to combine it with SIGHASH_NONE (as this also deletes all
> outputs of the transaction copy, so the signature only commits to
> nLockTime) and possibly pointless to combine it with
> SIGHASH_ANYONECANPAY (which deletes other inputs, but since there are
> no inputs after SIGHASH_NOINPUT, there is nothing else to delete).
> The BIP only mentions combining it with SIGHASH_SINGLE, in any case.

`SIGHASH_SINGLE` really is only singled out (no pun intended) because it
is usefull for the fee feature that Rusty came up with. It's not our
intention to exclude other uses, but you're right, it's hard to come up
with a use-case for `SIGHASH_NOINPUT` in combination with
`SIGHASH_NONE` or `SIGHASH_ANYONECANPAY` :-)

In particular we don't want to exclude potential future sighash types,
but those will have to be dealt with when they come up.

> 3.  We have these kinds transactions: (1) funding transaction paying
> out to an ordinary N-of-N multisig (confirmed onchain); (2) offchain
> trigger transaction spending a funding transaction and paying out to
> the "update transaction script"; (3) offchain update transaction
> spending a trigger or update transaction and paying out to the "update
> transaction script" (the same script template as in trigger
> transaction); (4) offchain settlement transaction spending a trigger
> or update transaction and paying out to the counterparties according
> to the final agreed distribution of funds.  Update and settlement
> transactions are signed with SIGHASH_NOINPUT flags.
>
> 4.  The update transaction script has two branches: a CSV-encumbered
> N-of-N "settlement" branch, and a CLTV-encumbered N-of-N "update"
> branch.  Crucially, we use past Unix timestamps for the CLTV
> encumberance on the update.  The CLTV-encumberance starts with a
> minimum time value on the trigger transaction, and increments by 1 for
> every update transaction.

Really any monotonically increasing sequence of increments will work,
but incrementing by 1 maximizes the number of updates we can perform,
yes.

> 5.  The CLTV-encumberance ensures that if a past update transaction is
> confirmed, we can spend it using any later update transaction, since
> CLTV uses `stackTop <= nLockTime`.  The actual `nLockTime` we use is a
> past Unix timestamp so they are not actually time-encumbered, but the
> `OP_CLTV` still ensures that any later update transaction can be used
> to spend from any earlier update transaction, but not vice versa.
> This is actually quite clever.

Correct, the only reason to use `nLocktime` here is that we need the
signature of the update transaction to commit to the state number, so we
can't put it in the script itself.

> 6.  The pubkeys on the settlement branch of each update transaction
> are different, and are derived using any hierarchical derivation
> method (trivially we can simply use the CLTV-encumberance value as the
> derivation index).  This ensures that each settlement transaction can
> only spend a particular update transaction.  Or in other words: There
> is a one-to-one correspondence between update and settlement
> transaction, and a settlement transaction can only confirm if the
> corresponding update transaction can be confirmed deeply enough
> without having its output re-spent.

Other bindings are possible, e.g., compare the `nLocktime` again, but
binding through pubkeys minimizes the script size.

> 7.  The pubkeys on the update branch are all the same in all update
> transactions.  This lets any update transaction replace any other
> update transaction, as long as the CLTV-encumberance (which is used
> for ordering rather than actual absolute locktime) is respected;
> together they mean that any later update transaction can replace any
> earlier update transaction.
>
> 8.  If an old update transaction is confirmed, the settlement
> transaction corresponding to it is still encumbered by CSV and cannot
> be confirmed immediately.  During this time, a later update
> transaction can spend it and be confirmed.  If that update transaction
> is still not the latest available, it can be further replaced with
> any, later transaction (since the CLTV-encumberance and the
> `nLockTime` increase in lockstep with each other) until the latest
> update transaction is confirmed.

Notice that the update transactions are actually paying their keep,
i.e., th

Re: [Lightning-dev] eltoo: A Simplified update Mechanism for Lightning and Off-Chain Contracts

2018-05-01 Thread ZmnSCPxj via Lightning-dev
Good morning Christian,

Thank you very much!

> > Hi Christian,
> > 
> > Let me know if I have summarized the paper accurately below:
> > 
> > 1.  SIGHASH_NOINPUT removes all inputs of the transaction copy before
> > 
> > signing/verifying.
> > 
> 
> It sets them to a known constant, in this case we just blank
> 
> them. Removing could entail more costly serialization depending on the
> 
> implementation. bitcoind serializes into a hash accumulator so it'd not
> 
> make a difference there, but others may do it differently.

Does this then mean that if the transaction has two inputs, we are still 
committing to the fact that there are two inputs?  If so, it is probably 
useable together with SIGHASH_ANYONECANPAY.

In fact, it seems, if we are using this to provide additional fees to update 
transactions, we should also use SIGHASH_ANYONECANPAY on the update UTXO path 
so that we can add new inputs to the transaction that will pay for the fee.

> > Some pros and cons relative to Poon-Dryja (LN-penalty) channels:
> > 
> > -   Requires more transactions in the worst-case: trigger, update,
> > 
> > settlement. Compare to Poon-Dryja: commitment, claim.
> > 
> > Decker-Russell-Osuntokun channels can be trigger-settlement but only
> > 
> > in the degenerate case where the channel was never updated (indeed for
> > 
> > implementation simplicity we might rather prefer to make an initial
> > 
> > update transaction at the start, instead of starting with a
> > 
> > trigger-settlement).
> > 
> 
> Actually the trigger can also be replaced in the cooperative case,
> 
> meaning that the settlement in that case is just a single transaction,
> 
> identical to LN-penalty.

Yes, but the intent of this second list is to contrast it to 
Poon-Dryja/LN-penalty channels, so I skipped over similarities (well there is 
the onchannel reserve vs the onchain fee-paying reserve, but I would argue they 
are congruent and not exactly identical).  One can argue that any viable 
channel-update-mechanism should be cooperatively collapsible to a single 
transaction on top of the funding transaction (because neither side has a good 
chance of contesting what has been agreed on, and collapsing them all to a 
single closing transaction is always an improvement due to having less data hit 
the blockchain), so if you did your job right in eltoo (and it looks to me like 
you all have) then that is already a given.

> It is true that we've split the unilateral
> 
> commitment from LN-penalty into two transactions, but we removed the
> 
> need for a claim transaction, since funds directly go to the recipient
> 
> and we have no our_unilateral/to_us or their_unilateral/to_them delay
> 
> that needs to be sweeped (technically also not necessary, but all
> 
> implementation do that if I'm not mistaken). Even if funds are not
> 
> sweeped, the UTXO state is larger due to the bigger script that our
> 
> simple outputs for the settlement.

Ah, that is another difference I had not noticed, thank you.

> > -   The CSV-encumberance on settlement transactions, which are the ones
> > 
> > which carry the contracts in the channel, affects all
> > 
> > absolute-timelocked contracts transported on the channel. Compare to
> > 
> > Poon-Dryja, where commitment transactions themselves are unencumbered
> > 
> > by CSV, and we simply insert the revocation to spends of the contracts
> > 
> > being transported (i.e. the reason why we have HTLC-success and
> > 
> > HTLC-timeout transactions in BOLT spec).
> > 
> 
> True, but as I argued in another mail, this is a fixed offset, that is
> 
> in the same range as today's CLTV deltas for some nodes. So for the
> 
> network of today using eltoo is roughly equivalent of adding another hop
> 
> to our path :-)

This may complicate routing decisions, however, in a mixed network where some 
channels are Poon-Dryja and some channels are Decker-Russell-Osuntokun; and if 
we deploy this as a back-compatible extension to the Lightning Network rather 
than a completely new network (and we should) then we will have such a mixed 
network.

A payer routing through such a network finding two routes with identical fees 
and cltv-deltas, but one going through only Poon-Dryja channels and the other 
with one channel going through Decker-Russell-Osuntokun (and the rest still 
Poon-Dryja) would prefer the purely Poon-Dryja one, which does not have any 
additional csv-delta to impose on the route.

Further, once a payer can find no purely Poon-Dryja routes, then it no longer 
matters how many Decker-Russell-Osuntokun channels a route hops, because 
csv-deltas are not additive.  Unfortunately most standard routing I know of 
assume additive costs, meaning we would either have a two-phase routing (first 
we try to find only purely Poon-Dryja routes, then if there are none we accept 
Decker-Russell-Osuntokun channels) or hack around 

Re: [Lightning-dev] eltoo: A Simplified update Mechanism for Lightning and Off-Chain Contracts

2018-05-01 Thread ZmnSCPxj via Lightning-dev
Good morning Christian,

It seems to me we can remove the trigger transaction.

The observation is that `nSequence`-encumbered transactions are only settlement 
transactions and not any update transactions.

Thus, it is not needed for a trigger transaction to exist, if we can make 
update transactions behave as the trigger transaction for its settlement 
transaction or any later update transaction.

So, let me propose, that the funding transaction outpoint could have the below 
SCRIPT:

OP_IF
# Settlement branch
OP_FALSE
OP_ELSE
# Update branch. 500,000,000 is the minimum state number under 
Decker-Russell-Osuntokun.
5 OP_CHECKLOCKTIMEVERIFY
2 Au Bu 2 OP_CHECKMULTISIGVERIFY
OP_ENDIF

Thus, the funding outpoint can be spent directly by any update transaction, 
which has `  OP_FALSE` at its `witness` script.

When creating a mutual close transaction, we simply use the update branch of 
the funding transaction above, again signing with `  OP_FALSE`.  
This does have the drawback that the mutual close transaction can be RBFed away 
by an update transaction (requiring more code to handle this case); but the 
latest update transaction can still be published in that case and we simply 
devolve down to the usual unilateral close branch.

The drawback is that the mutual close transaction increases by 1 weight unit 
(the `OP_FALSE` in the `witness` script) plus the size of the more complicated 
funding transaction SCRIPT, which is no longer a regular 2-of-2 P2WSH and 
indelibly marking it as a Decker-Russel-Osuntokun mutual close.  Taproot would 
help there by implicitly including a plain 2-of-2 fallback.

Finally, we could argue that the mutual close transaction is expected to be the 
more common case, so increasing its size by even a small amount may outweigh 
the size reduction in the much rarer unilateral close case.

Regards,
ZmnSCPxj
___
Lightning-dev mailing list
Lightning-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev


[Lightning-dev] Mitigations for loop attacks

2018-05-01 Thread Jim Posen
I have been thinking a lot lately about attacks on lightning routing nodes,
the worst of which is the so-called Loop Attack [1]. See the mailing list
thread for more details, but the basic idea is that a sender and receiver
collude to create a long circuit and refuse to settle or fail the HTLC at
the end until the last possible moment. The attack is particularly
insidious for a few reasons. Firstly, an attack on a multi-hop route gives
the attacker leverage, so that their funds locked in one channel cause
funds to be locked up in every channel on the route. Second, the onion
routing makes it difficult to attribute blame to a single node and defend
against a repeated attack.

First, I'll note that the case where a sender and recipient collude is a
more active variant on an attack that any node in a route can perform. Even
if a node does not initiate the payment, it can just accept offered HTLCs
in the route, not forward them, and wait until the offered HTLC almost
expires before failing. As noted above, the prior node in the route cannot
determine whether the attacking node is at fault or one downstream from it.
Even the sender may not be able to determine where in the route the payment
failed because of the issue where the obfuscated error reason is not MAC'ed
on every hop.

There are two directions of solutions I have heard: 1) protocol support for
decrypting the onion route if the HTLC is kept in-flight for too long 2)
requiring fees even if the payment fails as a cost to the attacker 3) some
sort of reputation system for nodes.

Option 1 I'm afraid may be quite complex. Say this mechanism kicks in and
all nodes in the circuit deobfuscate the route and are able to see the
delays at each hop. The outcome we hope for is that there is one node
clearly to blame and the prior hop in the route fails all channels with
them. However, the attacker can of course control multiple successive hops
in the route, one that looks innocent in front of one that looks guilty,
then keep the channel alive and try again. So then all nodes need to keep a
record of the full circuits and iteratively shift blame up the chain if bad
HTLCs keep going through those channels.

Option 2 is also problematic because it only protects against the case
where the sender is colluding with the receiver, and not where a routing
node is opportunistically delaying payments. This would, however, likely be
successful against nodes being annoying and sending tons of payments with
randomly generated payment hashes in order to "ping" a circuit.

Option 3 has become my preferred solution. The idea is that that for each
node that one has channels with, it only forwards payments through them if
they have a good history, otherwise it fails the payment. Notably, we
ignore whether the downstream hop is directly responsible for delaying a
payment or whether they are simply willing to forward to another node that
is intentionally delaying -- both should be considered bad behavior. In my
opinion, this type of solution fits best into the Lightning model of
independent, linked channels where each node has private contracts with its
direct peers. It also is the simplest in the context of onion routing
because if you are offered an HTLC to route, the only decision you can make
is whether to forward it or fail it based on the amount, previous hop, and
next hop. When I refer to "reputation" hereafter, I do not mean a global
reputation that is gossiped about -- just a local view of a peer's history.

For a Sybil-resistant reputation system, we can use money as a way of
measuring reputation. Fees collected through routing payments across
channels raise the reputation of the channel peer. You lose reputation by
accepting an HTLC and not failing or fulfilling it quickly, proportional to
the value of the HTLC and time to respond. What this essentially means is
that if an attacker wants people to send them HTLCs to delay, they pay a
certain amount in fees over time. So each node will track for each peer 1)
total fees collected from forwarding on routes where that peer is the prior
hop 2) total fees collect from forwarding on routes where that peer is the
next hop 3) total value times time of money locked in offered HTLCs on
channels to the peer. To track the third, as soon as an offered HTLC is
locked in by the peer, the node starts a timer. When the HTLC is settled or
failed or handled on-chain, the timer stops and the node registers the
total elapsed time multiplied by the value of the HTLC.

A very simple strategy would be to have two factors, R_inbound and
R_outbound and calculate reputation per peer as R_inbound * total inbound
fees + R_outbound * total outbound fees - total Bitcoin-seconds locked in
an HTLC. When forwarding a payment, you calculate the worst case reputation
loss, HTLC value * (CLTV - current block height) * 10 min / block, and fail
the payment if that value is greater than their current score. Effectively,
reputation scores are the maximum number of