public inbox for bitcoindev@googlegroups.com
 help / color / mirror / Atom feed
From: ZmnSCPxj <ZmnSCPxj@protonmail.com>
To: Tejaswi Nadahalli <nadahalli@gmail.com>
Cc: Matan Yehieli <matany@campus.technion.ac.il>,
	Bitcoin Protocol Discussion
	<bitcoin-dev@lists.linuxfoundation.org>,
	Itay Tsabary <sitay@campus.technion.ac.il>
Subject: Re: [bitcoin-dev] MAD-HTLC
Date: Thu, 02 Jul 2020 16:06:04 +0000	[thread overview]
Message-ID: <YhzMZ419vB1BY4Opd3lwfSSJ6_4AIQUDDtZPPhyB2HgskDZv0DKCQlEOAFklskLp1mj5AZrI43VPXOslX25MO-3Fijl9pBWrWYlYiaERr70=@protonmail.com> (raw)
In-Reply-To: <CAAifmARxvG+_Wo3zba6MCd=jxwesb2JhWAwRErq6QPVTe1AQEA@mail.gmail.com>

Good morning Tejaswi,

> > So it looks to me that scorched-earth is a possible mitigation against this attack.
>
> I don't follow this. We show that a reasonable value of fees and timelock are enough to avoid the attack. Why scorch the earth?

Because your model only considers that a block might have only 0 or 1 transactions, and there is no such thing as a mempool containing alternative, fee-paying transactions that the miner could include *instead*.

In reality, what a miner can earn from adding Alice transaction is the *difference* between the Alice transaction fee and the transaction that *just* misses getting included in the block because of feerate.

Thus, the f will not, in fact, *quite* be the Alice fee, but instead less than that.

Indeed if the Alice transaction fee is lower than the top 4 Mweight transactions in the mempool, the miner would be *losing* funds by including the Alice transaction.

My understanding is that we expect mempools to eventually never empty, as the block subsidy reduces over time, thus the payoff f for including the Alice transaction *instead of* some other transaction will be less than the Alice fee.


This effect also holds for Bob, but we can probably expect, all things being equal, that approximately the same value will be deducted from both the Bob bribe and Alice fee by the mempool effect.
Thus the ratio should really be (f - x) / (b - x), where x is the fee-of-transaction-that-just-misses-the-block.
At fee spikes, this x will go higher, and thus (f - x) / (b - x) will be far smaller than f / b and might even become negative, in which case the Alice transaction will not be confirmed even by myopic miners, because the Alice transaction will be below the top 4Mweight transactions in the mempool.


So it seems to me reasonable to use a *gradual* scorched earth policy, as it is not only resilient against this attack, but also to fee spikes.
Alice starts at the 1% reserve, then for every block that goes by, bumps up the fee.
Then Alice will settle at an (f - x) / (b - x) level that achieves the least weak miner that is known to run the myopic strategy.


I believe this is also better for UX --- people already accept that during high fee spikes, they end up paying more for onchain activities.
But boosting up `to_self_delay` is bad because it makes honest unilateral closes take longer, and we already get frownie faces from users about this parameter.
By using a gradual scorched-earth strategy we can start at the reserve level, and if we are not under attack and there is no fee spike, do not lose anything other than the reserve funds of the thief (which is not ours, but is instead that of the thief).
But if an attack happens during a fee spike, then even though we retain our current default `to_self_delay` of 144, we still have the ability to gradually and automatically move to higher fee regions until our transaction confirms, and we have a good excuse for it to present to users: "a fee spike was happening at the time, so you had to pay some extra miner fees".


----

And since you and your paper openly discusses it anyway, I would like to reveal that the MAD-HTLC argument does not apply to *just* HTLCs.
You make recommendations about `to_self_delay` and `channel_reserve_satoshis`, which are not parameters of Lightning HTLCs (those are stuff like `cltv_delta` and `final_cltv`), but are channel parameters.

The MAD-HTLC argument applies just as well to channel mechanisms themselves, ***independently of*** any HTLCs they transport.

The MAD-HTLC paper has the following core argument:

* We currently assume that currently-valid transactions will inevitably supersede alternate transactions that are valid at a later block height, simply because of the time advantage.
  * However, the owner of a later-block-height transaction can bribe miners to defer confirmation of currently-valid transactions, until its later-block-height transaction is valid and confirms.

The above core argument is presented as applying to HTLCs.

However, the same argument actually **also** applies to all current offchain multiparticipant cryptocurrency systems (i.e. "channel mechanisms").

* Spilman
* Poon-Dryja (what we currently use in Lightning)
* Decker-Wattenhofer decrementing-`nSequence`
* Decker-Russell-Osuntokun

The [Khabbazian-Nadahalli-Wattenhofer "Timelocked Bribing" paper](https://eprint.iacr.org/2020/774.pdf) mentions the use of revoked transactions in a Poon-Dryja mechanism, but seems to imply that the issue is with the HTLC instantiated inside the revoked transaction.
But note that the paper describes recommendations for the `to_self_delay` parameter and also analyzes the `channel_reserve_satoshis` parameter, which are parameters of the ***Poon-Dryja*** mechanism, and **not** of the HTLCs instantiated inside it.

So, to be very clear, the MAD-HTLC argument applies to all the above mechanisms *even if HTLCs are not used at all*.
Or put another way, if you use a modern offchain updateable cryptocurrency system at all, you are still vulnerable to the MAD-HTLC argument even if you never instantiate HTLCs inside the offchain system.

Thus, other proposed systems that (could) use any of the channel mechanisms, but do ***not*** necessarily use HTLCs, such as CoinPools, channel factories, and statechains, are also vulnerable to the MAD-HTLC argument.

In particular, if the MAD-HTLC argument holds, we should take note that e.g. Lightning channels have to be at least as large as any HTLC they contain, and since the MAD-HTLC argument applies to the channel itself (in addition to any HTLCs they contain), the application of that argument implies greater loss, as it is the entire channel that is at risk, not just any HTLCs it might contain.

Spilman
=======

A Spilman channel is a unidirectional single-funded channel.

The overall idea was presented pre-SegWit, and needed `OP_CHECKLOCKTIMEVERIFY` to be malleation-safe.
I will describe here a modernized version that uses SegWit (and thus is malleation safe) instead.

Suppose Bob wishes to make a Spilman channel to Alice.
The setup is as follows:

* Bob creates but does *NOT* sign a funding transaction, paying out to a 2-of-2 between Alice and Bob, and hands over this txid and the output number to Alice.
* Alice creates a timeout transaction, `nLockTime`d to a pre-agreed locktime, spending the above txout, and returning the funds to Bob, and signs this transaction and hands over the signature and tx to Bob.
* Bob signs the funding transaction and broadcasts it.
* Alice and Bob wait for deep confirmation of the funding tx.

At each payment from Bob to Alice, Bob signs a non-`nLockTime`d (or one with current blockheight) transaction that spends the funding txout and assigns more of the fund to Alice, then sends the signature and tx to Alice.

At any time, Alice can unilaterally close the channel using any of the signatures given by Bob.
Rationally, it will publish the one that gives it the most money, which is the latest such transaction, thus leading to the unidirectional nature of Spilman channels.
Alice needs to perform this unilateral close far before the pre-agreed locktime.

Under the MAD-HTLC argument, Bob can bribe miners to ignore the Alice unilateral close transaction, and the initial timeout transaction by Bob gets confirmed even if within the channel mechanism Alice is supposed to own most or all of the funds.

Poon-Dryja
==========

A Poon-Dryja channel is a modern two-participant bidirectional channel.

The core of security of Poon-Dryja involves "revocable outputs".
A revocable output is an output that, when published onchain, is owned by one entity (the owner), but that entity may reveal a secret, the revocation secret, to another entity (the revoker).
Once that other entity knows the revocation secret, if the output is ever published onchain, it can revoke the output and claim its value.

Poon-Dryja uses this building block to implement an updateable state.
All states are represented by commitment transactions that have revocable outputs.
In order to advance to a new state, the revocable outputs of previous states are revoked by exchanging revocation secrets.
Thus, the security of Poon-Dryja is dependent on the correct operation of revocation.

Revocable outputs are implemented by imposing a relative locktime on the owner of the output, and requiring knowledge of two secrets from the revoker.

Thus, a revocable output has two branches:

* Revocation branch: with the revoker privkey and knowledge of a revocaation secret, the revoker can claim the fund immediately.
* Claim branch: with the owner privkey and a relative locktime, the owner can claim the fund after a pre-agreed number of blocks (`to_self_delay` in Lightning) since the output is confirmed onchain.

Under the MAD-HTLC argument, the owner of the revoked output can bribe miners to ignore attempts by the revoker to claim the funds until the claim branch is valid and confirmable.
Thus, a thief can publish old state, then apply the MAD-HTLC argument to get miners to ignore the revoker of the old state.

Decker-Wattenhofer decrementing-`nSequence`
===========================================

Decker-Wattenhofer ("Duplex Micropayment Channels") is a modern multi-participant (N >= 2) offchain updateable cryptocurrency mechanism.

Decker-Wattenhofer chains together two different mechanisms, embedding them one inside the other, in order to balance the tradeoffs of one with the tradeoffs of the other.

* One or more decrementing-`nSequence` mechanisms, chained one inside the other.
* Two ("duplex") unidirectional Spilman variants, using a relative locktime instead of an absolute locktime, one in both directions of the channel, inside the innermost decrementing-`nSequence` mechanism.

The decrementing-`nSequence` mechanisms by themselves are multiparticipant (N >= 2), and if we focus only on having one or more of these mechanisms chained together, we can consider Decker-Wattenhofer as multiparticipant.

In the decrementing-`nSequence` mechanism, there is a kickoff transaction which spends from the n-of-n funding outpoint, and sends it to yet another n-of-n output between the participants.
Then, the second n-of-n is spent by a transaction with a relative-locktime `nSequence` transaction, which then distributes the money among various participants.

When a new state is created, the participants create and sign a new relative-locktime `nSequence` transaction spending the kickoff n-of-n outpoint.
The new state transaction has a lower `nSequence` than the most previous state transaction, hence decrementing-`nSequence`.
Once the latest state transaction has a 0-block relative locktime, a newer state can no longer be added to the mechanism.

The kickoff n-of-n outpoint thus has multiple branches, one for each created state.
The most recent state is assumed to supersede previous states, because it has the smallest relative locktime among all states.

Under the MAD-HTLC argument, a participant which prefers an older state can bribe miners to defer confirmation of all more recent states.
Thus, that participant can publish the kickoff and bribe miners to defer more recent states until its preferred state is confirmable onchain.

Decker-Russell-Osuntokun
========================

Decker-Russell-Osuntokun ("eltoo") is a futuristic multiparticipant (N >= 2) offchain updateable cryptocurrency system.

Decker-Russell-Osuntokun uses a proposed new `SIGHASH_NOINPUT` flag, which does not commit to the specific output being spent, allowing a signature that signs using `SIGHASH_NOINPUT` to be used to spend a different transaction outpoint, as long as the same pubkey is used for that outpoint.

As is typical for channel mechanisms, a funding outpoint is created, which is an n-of-n of all participants.
The funding outpoint is spent by an update transaction with a single output, which has the following branches:

* Update branch: can be spent by the same n-of-n pubkeys as the funding outpoint, as long as the spending transaction has a higher `nLockTime` than the update transaction.
* State branch: can be spent by a different n-of-n pubkeys from the same participants, after a relative locktime.
  * Each update transaction has its own unique set of n-of-n pubkeys for the state branch, given by the same participant set.

Of note is that the `nLockTime` used in Decker-Russell-Osuntokun are always past `nLockTime`s, so that the update branch is always confirmable at the current tip, from now until forever.
Only the state branch has an actual timelock that could prevent immediate confirmation of a transaction spending that branch.

Update transactions (awesomely mis)use `nLockTime` as a sequence number; the first update transaction has the lowest `nLockTime`, then each succeeding update transaction has a higher `nLockTime`, until they reach the present time.

Update transactions are signed with `SIGHASH_NOINPUT`.
This allows the update transaction to not only spend the funding outpoint itself, but also to spend any previous update transaction.

Thus, if an old update transaction is published onchain, its output can be re-spent by any newer update transaction before the state transaction for that update can come into play.
Any other participant who notices this event can simply publish the newest update transaction it knows, as that would supersede the state transaction, which can only be confirmed after a time delay.

Under the MAD-HTLC argument, a participant who prefers an older state can publish the update transaction for the older state, then bribe miners to defer confirmation of newer update transactions, until the state transaction for that update transaction can be confirmed.

Conclusion
==========

All the above mechanisms use a timelock, and implicitly have the assumption that "a transaction, that can be confirmed now, supersedes any transaction that has a timelock that forces it to be confirmed later".

It seems likely to me that even future mechanisms will use the same assumption as well.

In particular, many proposed mechanisms for non-federated sidechains often include some kind of delay between when a sidechain coin is burned and the corresponding mainchain coin is released (i.e. side-to-main peg).
Often, this delay exists in order to allow showing of a counterproof that the supposed side-to-main transfer did not actually exist in the sidechain (or was later reorged out, or whatever).
It seems to me that the MAD-HTLC argument would also apply to such mechanisms (if anyone still wants to go push sidechains, anyway).

Thus, we really need to carefully investigate the MAD-HTLC argument.

My current analysis suggests that in practice, the MAD-HTLC argument does not apply at all (else I would not be revealing that all channel mechanisms are broken **if** the MAD-HTLC argument *does* apply), since the myopic strategy seems to be pretty much inevitably dominant at stable states.
But it would still be best to investigate further until we are fully convinced that the MAD-HTLC argument ("'earlier supersedes later' might be falsified by bribery") does not apply.



Regards,
ZmnSCPxj


  reply	other threads:[~2020-07-02 16:06 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CABT1wW=X35HRVGuP-BHUhDrkBEw27+-iDkNnHWjRU-1mRkn0JQ@mail.gmail.com>
2020-06-23  6:41 ` [bitcoin-dev] MAD-HTLC Stanga
2020-06-23  9:48   ` ZmnSCPxj
2020-06-23 12:47     ` Stanga
2020-06-23 13:18       ` Stanga
2020-06-25  1:38         ` ZmnSCPxj
2020-06-25  3:26           ` Nadav Ivgi
2020-06-25  4:04             ` ZmnSCPxj
2020-06-25  4:35               ` Nadav Ivgi
2020-06-25 13:12                 ` Bastien TEINTURIER
2020-06-28 16:41       ` David A. Harding
2020-07-04 21:05         ` ZmnSCPxj
2020-06-28 12:15   ` David A. Harding
2020-06-29 11:57     ` Tejaswi Nadahalli
2020-06-29 18:05     ` ZmnSCPxj
2020-06-30  6:28       ` Stanga
2020-06-30  6:45       ` Tejaswi Nadahalli
2020-07-01 16:58         ` ZmnSCPxj
2020-07-02 12:22           ` Tejaswi Nadahalli
2020-07-02 16:06             ` ZmnSCPxj [this message]
2020-07-03  9:43               ` Tejaswi Nadahalli
2020-07-03 10:16                 ` ZmnSCPxj
2020-07-03 10:44                   ` Tejaswi Nadahalli
     [not found]                     ` <CAF-fr9Z7Xo8JmwtuQ7LE3k1=er+p7s9zPjH_8MNPwbxAfT1z7Q@mail.gmail.com>
2020-07-03 12:38                       ` ZmnSCPxj
     [not found]                         ` <CAF-fr9YhiOFD4n8rGF-MBkWeZmzBWfOJz+p8ggfLuDpioVRvyQ@mail.gmail.com>
2020-07-04 20:58                           ` ZmnSCPxj
2020-07-05  9:03                         ` Stanga
2020-07-06 11:13                       ` Tejaswi Nadahalli
2020-07-02 12:39           ` Tejaswi Nadahalli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='YhzMZ419vB1BY4Opd3lwfSSJ6_4AIQUDDtZPPhyB2HgskDZv0DKCQlEOAFklskLp1mj5AZrI43VPXOslX25MO-3Fijl9pBWrWYlYiaERr70=@protonmail.com' \
    --to=zmnscpxj@protonmail.com \
    --cc=bitcoin-dev@lists.linuxfoundation.org \
    --cc=matany@campus.technion.ac.il \
    --cc=nadahalli@gmail.com \
    --cc=sitay@campus.technion.ac.il \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox