Return-Path: Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 3BB69C0032; Thu, 2 Nov 2023 05:24:54 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 0153D43338; Thu, 2 Nov 2023 05:24:54 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 0153D43338 Authentication-Results: smtp2.osuosl.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=XAPvAVqo X-Virus-Scanned: amavisd-new at osuosl.org X-Spam-Flag: NO X-Spam-Score: -2.098 X-Spam-Level: X-Spam-Status: No, score=-2.098 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 3rcI6NqccpVN; Thu, 2 Nov 2023 05:24:49 +0000 (UTC) Received: from mail-io1-xd29.google.com (mail-io1-xd29.google.com [IPv6:2607:f8b0:4864:20::d29]) by smtp2.osuosl.org (Postfix) with ESMTPS id 905C84002B; Thu, 2 Nov 2023 05:24:48 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 905C84002B Received: by mail-io1-xd29.google.com with SMTP id ca18e2360f4ac-7a692658181so23871839f.1; Wed, 01 Nov 2023 22:24:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1698902687; x=1699507487; darn=lists.linuxfoundation.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=0z7cCoFGP+WHqlolC7EhWhDMMSF/3/0Oja9xuwx1VKo=; b=XAPvAVqoiGUOJcPW0dIDzUvXJGQ1hxu6mi8vMQkK/65SWHc4eu+cemsJsQEYMpRjvJ uV24Th4D2ccUsd0KKkrbsQMzZfH/SVvqitLXRPeuAMDcoVP9GuSLieGbqi7VXflYLoJk cKXQymOf92WOxldxCKvj+iy7dee1Y4Hbh8vJNB3dAyOqG2zVor1NlW40+Conj7D2k7nl X3kGbPKsDJl1+o5y/4vuTjqeIFHXjs6oRt0izutUAncT8kVLVwsb0KDwoleO833lvX9c 3Ze3YSuADhBO8CjJTM0i/IPs2bogkATkd0ZCsmqJi+Z2P0QpCYFw8CMdRaljuWdfHtiM 5J8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698902687; x=1699507487; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=0z7cCoFGP+WHqlolC7EhWhDMMSF/3/0Oja9xuwx1VKo=; b=OI/vRl2FcOFTABOwLFFNwr5YImkI7ihtS4Mvh7fw3C1Q9jjj5nytVK1pSECqnV6VK4 HwHm57tZa82nWM8Poug7ZVjvoMtFcfSjptPIFc0cJwaPnu+43sGBLBIC2cEq+9+8/y9u ZHInyeT8URTbjJHSgRWi2kGUTEmRhcrIRfxT4g7EfZ0jApQk9impdoAGpAB1kjf3file 8vemLj/YdapXzopvkYQn16oA9uodYy8D4YNnAdkybgrzmxRIV+ypGl8vUf7XEeh3LNbz w5CCfRJtU0wCzIo8dhp8IXEsO++hZ0pRCps/SvJto8AR79M9NJL4yM6b712fL9227ptm 13bQ== X-Gm-Message-State: AOJu0YxttkpnCVXBkc/CxiqMygYltG1IzyaPWf+btgoEHTcArRdeHpXP IDdk0KgmaJGDZsZzS8wZu+ZF5L+gPW1J2md72Ns= X-Google-Smtp-Source: AGHT+IGtB0hBDV1zDky3uUEOpgqnP+cBwHI5uFNsDBlxJ9gFYi9+Q1jp88R/fItizS3UWu31iUlO2HRuKQ4DMF2mojI= X-Received: by 2002:a05:6602:2e95:b0:7a9:96aa:e019 with SMTP id m21-20020a0566022e9500b007a996aae019mr21287725iow.13.1698902687376; Wed, 01 Nov 2023 22:24:47 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Antoine Riard Date: Thu, 2 Nov 2023 05:24:36 +0000 Message-ID: To: Peter Todd Content-Type: multipart/alternative; boundary="000000000000306b130609249bf0" X-Mailman-Approved-At: Thu, 02 Nov 2023 11:36:06 +0000 Cc: Bitcoin Protocol Discussion , security@ariard.me, "lightning-dev\\\\@lists.linuxfoundation.org" Subject: Re: [bitcoin-dev] OP_Expire and Coinbase-Like Behavior: Making HTLCs Safer by Letting Transactions Expire Safely X-BeenThere: bitcoin-dev@lists.linuxfoundation.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Bitcoin Protocol Discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 02 Nov 2023 05:24:54 -0000 --000000000000306b130609249bf0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Peter, > So, why can't we make the HTLC-preimage path expire? Traditionally, we've tried > to ensure that transactions - once valid - remain valid forever. We do this > because we don't want transactions to become impossible to mine in the event of > a large reorganization. I don't know if reverse time-lock where a lightning spending path becomes invalid after a block height or epoch point solves the more advanced replacement cycling attacks, where a malicious commitment transaction itself replaces out a honest commitment transaction, and the child-pay-for-parent of this malicious transaction is itself replaced out by the attacker, leading to the automatic trimming of the malicious commitment transaction. I think this attack scenario is exposed here: https://github.com/ariard/bitcoin/commits/2023-10-test-mempool-2 If this scenario is correct, there is not only a need for a solution that expires the htlc-preimage spending path, but also channel commitment ones. I think you have a difficulty as both channel commitments can be legitimately valid under lightning protocol semantics, where both counterparties cannot trust the other one to broadcast a commitment state in a timely fashion, to subsequently claim time-sensitive HTLCs. Of course, one might come with the observation that the time-sensitive HTLCs might be safeguarded under the new reverse time-lock semantic, though I think you're just switching the security risk from one counterparty to the other one. Now, the forwarding node might receive the preimage off-chain from the payee, and then block any attempt of the payee to broadcast its commitment transaction to claim the inbound HTLC, before the reverse time-lock kicks out. I believe another line of solution could to remove any counterparty malleability in the setting of a package total fees and have fee-bumping reserves pre-committed, though intuitively this sounds to come with the downside of a high-level of total reserve for each channel. Best, Antoine Le sam. 21 oct. 2023 =C3=A0 01:09, Peter Todd a =C3=A9= crit : > On Mon, Oct 16, 2023 at 05:57:36PM +0100, Antoine Riard via bitcoin-dev > wrote: > > Here enter a replacement cycling attack. A malicious channel counterpar= ty > > can broadcast its HTLC-preimage transaction with a higher absolute fee > and > > higher feerate than the honest HTLC-timeout of the victim lightning nod= e > > and triggers a replacement. Both for legacy and anchor output channels,= a > > HTLC-preimage on a counterparty commitment transaction is malleable, i.= e > > additional inputs or outputs can be added. The HTLC-preimage spends an > > unconfirmed and unrelated to the channel parent transaction M and > conflicts > > its child. > > The basic problem here is after the HTLC-timeout path becomes spendable, > the > HTLC-preimage path remains spendable. That's bad, because in this case we > want > spending the HTLC-preimage - if possible - to have an urgency attached to > it to > ensure that it happens before the previous HTLC-timeout is mined. > > So, why can't we make the HTLC-preimage path expire? Traditionally, we've > tried > to ensure that transactions - once valid - remain valid forever. We do th= is > because we don't want transactions to become impossible to mine in the > event of > a large reorganization. > > A notable example of this design philosophy is seen in Bitcoin's rules > around > coinbase outputs: they only become spendable after 100 more blocks have > been > found; a 100 block reorg is quite unlikely. > > Enter the OP_Expire and the Coinbase Bit soft-fork upgrade. > > > # Coinbase Bit > > By redefining a bit of the nVersion field, eg the most significant bit, w= e > can > apply coinbase-like txout handling to arbitrary transactions. Such a > transaction's outputs would be treated similarly to a coinbase > transaction, and > would be spendable only after 100 more blocks had been mined. Due to this > requirement, these transactions will pose no greater risk to reorg safety > than > the existing hazard of coinbase transactions themselves becoming invalid. > > Note how such a transaction is non-standard right now, ensuring > compatibility > with existing nodes in a soft-fork upgrade. > > > # OP_Expire > > Redefining an existing OP_Nop opcode, OP_Expire would terminate script > evaluation with an error if: > > 1) the Coinbase Bit was not set; or > 2) the stack is empty; or > 3) the top item on the stack was >=3D the block height of the containing > block > > This is conceptually an AntiCheckLockTimeVerify: where CLTV _allows_ a > txout to > become spendable in a particular way in the future, Expire _prevents_ a > txout > from being spent in a particular way. > > Since OP_Expire requires the Coinbase Bit to be set, the reorg security o= f > OP_Expire-using transactions is no worse than transactions spending miner > coinbases. > > > # How HTLC's Would Use OP_Expire > > Whenever revealing the preimage on-chain is necessary to the secure > functioning > of the HTLC-using protocol, we simply add an appropriate OP_Expire to the > pre-image branch of the script along the lines of: > > If > Expire Drop > Hash EqualVerify > CheckSig > ElseIf > # HTLC Expiration conditions > ... > EndIf > > Now the party receiving the pre-image has a deadline. Either they get a > transaction spending the preimage mined, notifying the other party via th= e > blockchain itself, or they fail to get the preimage mined in time, > reverting > control to the other party who can spend the HTLC output at their leisure= , > without strict time constraints. > > Since the HTLC-expired branch does *not* execute OP_Expire, the transacti= on > spending the HTLC-expired branch does *not* need to set the Coinbase Bit. > Thus > it can be spent in a perfectly normal transaction, without restrictions. > > > # Delta Encoding Expiration > > Rather than having a specific Coinbase Bit, it may also be feasible to > encode > the expiration height as a delta against a block-height nLockTime. In thi= s > variant, OP_Expire would work similarly to OP_CheckLockTimeVerify, by > checking > that the absolute expiration height was <=3D the requested expiration, > allowing > multiple HTLC preimage outputs to be spent in one transaction. > > If the top 16-bits were used, the maximum period a transaction could be > valid > would be: > > 2^16 blocks / 144 blocks/day =3D 455 days > > In this variant, a non-zero expiration delta would enable expiration > behavior, > as well as the coinbase-like output spending restriction. The remaining > 16-bits > of nVersion would remain available for other meanings. > > Similar to how CLTV and CSV verified nLockTime and nSequence respectively= , > verifying an expiration height encoded in the nVersion has the advantage = of > making an expiration height easy to detect without validating scripts. > > While Lightning's HTLC-success transactions currently use nLockTime=3D0, > AFAIK > there is no reason why they could not set nLockTime to be valid in the ne= xt > block, allowing delta encoding to be used. > > > ## Reusing Time-Based nLockTime > > Reusing time-based nLockTime's prior to some pre-2009 genesis point for > expiration is another possibility (similar to how Lightning makes use of > time-based nLockTime for signalling). However I believe this is not as > desirable as delta encoding or a coinbase bit, as it would prevent > transactions > from using block nLockTime and expiration at the same time. It would also > still > require a coinbase bit or nVersion increase to ensure expiration-using > transactions are non-standard. > > > # Mempool Behavior > > Obviously, mempool logic will need to handle transactions that can expire > differently than non-expiring transactions. One notable consideration is > that > nodes should require higher minimum relay fees for transactions close to > their > expiration height to ensure we don't waste bandwidth on transactions that > have > no potential to be mined. Considering the primary use-case, it is probabl= y > acceptable to always require a fee rate high enough to be mined in the ne= xt > block. > > -- > https://petertodd.org 'peter'[:-1]@petertodd.org > --000000000000306b130609249bf0 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi Peter,

> So, why can't we mak= e the HTLC-preimage path expire? Traditionally, we've tried
> to = ensure that transactions - once valid - remain valid forever. We do this> because we don't want transactions to become impossible to mine i= n the event of
> a large reorganization.

I don't know if reverse time-lock where a lightning spending path beco= mes invalid after a block height or epoch point solves the more advanced re= placement cycling attacks, where a malicious commitment transaction itself = replaces out a honest commitment transaction, and the child-pay-for-parent = of this malicious transaction is itself replaced out by the attacker, leadi= ng to the automatic trimming of the malicious commitment transaction.
=

I think this attack scenario is exposed here:
https://github.com/ariard/bitcoin/commits/2023-10-test-mempool-2
=

If this scenario is correct, there is not only a = need for a solution that expires the htlc-preimage spending path, but also = channel commitment ones. I think you have a difficulty=C2=A0as both channel= commitments can be legitimately valid under lightning protocol semantics, = where both counterparties cannot trust the other one to broadcast a commitm= ent state in a timely fashion, to subsequently claim time-sensitive HTLCs.<= /div>

Of course, one might come with the observation tha= t the time-sensitive HTLCs might be safeguarded under the new reverse time-= lock semantic, though I think you're just switching the security risk f= rom one counterparty to the other one. Now, the forwarding node might recei= ve the preimage off-chain from the payee, and then block any attempt of the= payee to broadcast its commitment transaction to claim the inbound HTLC, b= efore the reverse time-lock kicks out.

I believe a= nother line of solution could to remove any counterparty malleability in th= e setting of a package total fees and have fee-bumping reserves pre-committ= ed, though intuitively this sounds to come with the downside of a high-leve= l of total reserve for each channel.

Best,
Antoine

Le=C2=A0sam. 21 oct. 2023 =C3=A0=C2=A001:09, Peter Todd <= ;pete@petertodd.org> a =C3=A9c= rit=C2=A0:
On Mon, Oct 16, 2023 at 05:57:36PM +01= 00, Antoine Riard via bitcoin-dev wrote:
> Here enter a replacement cycling attack. A malicious channel counterpa= rty
> can broadcast its HTLC-preimage transaction with a higher absolute fee= and
> higher feerate than the honest HTLC-timeout of the victim lightning no= de
> and triggers a replacement. Both for legacy and anchor output channels= , a
> HTLC-preimage on a counterparty commitment transaction is malleable, i= .e
> additional inputs or outputs can be added. The HTLC-preimage spends an=
> unconfirmed and unrelated to the channel parent transaction M and conf= licts
> its child.

The basic problem here is after the HTLC-timeout path becomes spendable, th= e
HTLC-preimage path remains spendable. That's bad, because in this case = we want
spending the HTLC-preimage - if possible - to have an urgency attached to i= t to
ensure that it happens before the previous HTLC-timeout is mined.

So, why can't we make the HTLC-preimage path expire? Traditionally, we&= #39;ve tried
to ensure that transactions - once valid - remain valid forever. We do this=
because we don't want transactions to become impossible to mine in the = event of
a large reorganization.

A notable example of this design philosophy is seen in Bitcoin's rules = around
coinbase outputs: they only become spendable after 100 more blocks have bee= n
found; a 100 block reorg is quite unlikely.

Enter the OP_Expire and the Coinbase Bit soft-fork upgrade.


# Coinbase Bit

By redefining a bit of the nVersion field, eg the most significant bit, we = can
apply coinbase-like txout handling to arbitrary transactions. Such a
transaction's outputs would be treated similarly to a coinbase transact= ion, and
would be spendable only after 100 more blocks had been mined. Due to this requirement, these transactions will pose no greater risk to reorg safety t= han
the existing hazard of coinbase transactions themselves becoming invalid.
Note how such a transaction is non-standard right now, ensuring compatibili= ty
with existing nodes in a soft-fork upgrade.


# OP_Expire

Redefining an existing OP_Nop opcode, OP_Expire would terminate script
evaluation with an error if:

1) the Coinbase Bit was not set; or
2) the stack is empty; or
3) the top item on the stack was >=3D the block height of the containing= block

This is conceptually an AntiCheckLockTimeVerify: where CLTV _allows_ a txou= t to
become spendable in a particular way in the future, Expire _prevents_ a txo= ut
from being spent in a particular way.

Since OP_Expire requires the Coinbase Bit to be set, the reorg security of<= br> OP_Expire-using transactions is no worse than transactions spending miner coinbases.


# How HTLC's Would Use OP_Expire

Whenever revealing the preimage on-chain is necessary to the secure functio= ning
of the HTLC-using protocol, we simply add an appropriate OP_Expire to the pre-image branch of the script along the lines of:

=C2=A0 =C2=A0 If
=C2=A0 =C2=A0 =C2=A0 =C2=A0 <expiry height> Expire Drop
=C2=A0 =C2=A0 =C2=A0 =C2=A0 Hash <digest> EqualVerify
=C2=A0 =C2=A0 =C2=A0 =C2=A0 <pubkey> CheckSig
=C2=A0 =C2=A0 ElseIf
=C2=A0 =C2=A0 =C2=A0 =C2=A0 # HTLC Expiration conditions
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ...
=C2=A0 =C2=A0 EndIf

Now the party receiving the pre-image has a deadline. Either they get a
transaction spending the preimage mined, notifying the other party via the<= br> blockchain itself, or they fail to get the preimage mined in time, revertin= g
control to the other party who can spend the HTLC output at their leisure,<= br> without strict time constraints.

Since the HTLC-expired branch does *not* execute OP_Expire, the transaction=
spending the HTLC-expired branch does *not* need to set the Coinbase Bit. T= hus
it can be spent in a perfectly normal transaction, without restrictions.

# Delta Encoding Expiration

Rather than having a specific Coinbase Bit, it may also be feasible to enco= de
the expiration height as a delta against a block-height nLockTime. In this<= br> variant, OP_Expire would work similarly to OP_CheckLockTimeVerify, by check= ing
that the absolute expiration height was <=3D the requested expiration, a= llowing
multiple HTLC preimage outputs to be spent in one transaction.

If the top 16-bits were used, the maximum period a transaction could be val= id
would be:

=C2=A0 =C2=A0 2^16 blocks / 144 blocks/day =3D 455 days

In this variant, a non-zero expiration delta would enable expiration behavi= or,
as well as the coinbase-like output spending restriction. The remaining 16-= bits
of nVersion would remain available for other meanings.

Similar to how CLTV and CSV verified nLockTime and nSequence respectively,<= br> verifying an expiration height encoded in the nVersion has the advantage of=
making an expiration height easy to detect without validating scripts.

While Lightning's HTLC-success transactions currently use nLockTime=3D0= , AFAIK
there is no reason why they could not set nLockTime to be valid in the next=
block, allowing delta encoding to be used.


## Reusing Time-Based nLockTime

Reusing time-based nLockTime's prior to some pre-2009 genesis point for=
expiration is another possibility (similar to how Lightning makes use of time-based nLockTime for signalling). However I believe this is not as
desirable as delta encoding or a coinbase bit, as it would prevent transact= ions
from using block nLockTime and expiration at the same time. It would also s= till
require a coinbase bit or nVersion increase to ensure expiration-using
transactions are non-standard.


# Mempool Behavior

Obviously, mempool logic will need to handle transactions that can expire differently than non-expiring transactions. One notable consideration is th= at
nodes should require higher minimum relay fees for transactions close to th= eir
expiration height to ensure we don't waste bandwidth on transactions th= at have
no potential to be mined. Considering the primary use-case, it is probably<= br> acceptable to always require a fee rate high enough to be mined in the next=
block.

--
http= s://petertodd.org 'peter'[:-1]@petertodd.org
--000000000000306b130609249bf0--