From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 219FAC0032 for ; Tue, 22 Aug 2023 19:22:35 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id DCB8F400D2 for ; Tue, 22 Aug 2023 19:22:34 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org DCB8F400D2 Authentication-Results: smtp2.osuosl.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20221208 header.b=sjHGR6f1 X-Virus-Scanned: amavisd-new at osuosl.org X-Spam-Flag: NO X-Spam-Score: -1.848 X-Spam-Level: X-Spam-Status: No, score=-1.848 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_ENVFROM_END_DIGIT=0.25, 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 d28pKYYZkSNB for ; Tue, 22 Aug 2023 19:22:33 +0000 (UTC) Received: from mail-ej1-x631.google.com (mail-ej1-x631.google.com [IPv6:2a00:1450:4864:20::631]) by smtp2.osuosl.org (Postfix) with ESMTPS id 80688403AC for ; Tue, 22 Aug 2023 19:22:32 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 80688403AC Received: by mail-ej1-x631.google.com with SMTP id a640c23a62f3a-99d937b83efso625737566b.3 for ; Tue, 22 Aug 2023 12:22:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1692732150; x=1693336950; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=bK3rC03CR/qEtj1XiYfcjt4dPDj3XCRGYaCNNwVO8aM=; b=sjHGR6f1TeQREn7FfzBPdcy/OhEExxyjucUZQty4bcUeQIvInJroaCJq9AQUeM1ZoF TSpPsJHUur1pHZ718nQcV85Q6AT0xc2FczF1+OMufYFnGDt3uuPtJkI7zJ+jqjPr2JSi 26iDE8NqRbaAyST43jLl+6Xb3FPGSQLdovUdE4hpMItAyDsGrsV3BiddYK+gQSYM1/wu RbVIOa+4+PihmIKzxhc+ZDZyS6ZgdAeSq3MlxfmZ+M2F9x9L7q2GMp+Lz+7OYMf3ILcH UZmPO4K+thAgxL8pbf0Cmq6DNyQG9sfS8ENWVyycM2YJOKitSZ0iaZKUpwOdbddnffd2 TAOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692732150; x=1693336950; h=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=bK3rC03CR/qEtj1XiYfcjt4dPDj3XCRGYaCNNwVO8aM=; b=QX5t58RtOWVGACYiczGXJ+4LtDIpHBda8NDCY8+qLRIiOhpi2U4nUohh77CTtIoIWP Oh8zbbqntQHI9GCWX54svXAPfJBxhlGp+PQLku8IKcYMSptO1/vOxPUFDsj/PAv+6bbx WfUGvOtu1j6rmc3Kffpd/WY2v3i0OCnk/zMWpndlH1t0C2UiTF5LrzbMBHvysqJOiEAr phUgaE8ojsJJPNJwldGzhGHQCERgQ/Rs8Q3VHerxOV9F0WurEul086GLpNbp6q+1RS8n ZQhd1GVeZmTTvf4cgTWpgkVEopOXsWkD68U3S+ehhQJyVRlMPJi2bSrL0oWJeAMKhdXS vLOQ== X-Gm-Message-State: AOJu0Yzwt3KdPaWP1gjIuefSs/VFb1sJQdqH9IHGw27/vBexfKo50Imy nrN6j0fB6Y/PYOP12D2fXzBuckiOBqNRpZ/xl9H6z/+GVkY= X-Google-Smtp-Source: AGHT+IEwcWzkIfdC1Iz6hfBGUV64znAGURduckkuHHz6XL97qKWqCSRrFTecZwwpL0qLtIErWnjhlpaTSgd6eOtmfBQ= X-Received: by 2002:a17:906:cc2:b0:99d:f560:5d3c with SMTP id l2-20020a1709060cc200b0099df5605d3cmr9026417ejh.23.1692732150151; Tue, 22 Aug 2023 12:22:30 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Greg Sanders Date: Tue, 22 Aug 2023 15:22:18 -0400 Message-ID: To: Brandon Black , Bitcoin Protocol Discussion Content-Type: multipart/alternative; boundary="000000000000828034060387ea10" Subject: Re: [bitcoin-dev] Combined CTV+APO to minimal TXHASH+CSFS 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: Tue, 22 Aug 2023 19:22:35 -0000 --000000000000828034060387ea10 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Brandon, Not going to dive too deep here, just adding a bit of color. > * If the top item on the stack is not a minimally encoded `OP_0`, `OP_1`, or `OP_2`; succeed immediately[^2]. I presume this was supposed to go to OP_4 now. > ### How does the efficiency compare to [bip118][]? Just noting BIP118 also allows pubkey of "1" to stand in for the taproot inner pubkey, which would be a common use-case. "simply" adding an opcode ala OP_INNER_PUBKEY could also have the same effect of course. Also, BIP118 also opens the door for non-APO signatures to have a sighash digest that commits to additional data, closing a couple of taproot malleability bugs. See https://github.com/bitcoin-inquisition/bitcoin/issues/19 for more discussion along those lines. These aren't make or break, but would be nice to clean up if possible Best, Greg On Tue, Aug 22, 2023 at 3:04=E2=80=AFPM Brandon Black via bitcoin-dev < bitcoin-dev@lists.linuxfoundation.org> wrote: > Hi list, > > https://gist.github.com/reardencode/2aa98700b720174598d21989dd46e781 > > I'm seeking feedback on this proposal to provide the functionality > requested by those advocating for bip118 and bip119 in a combined way > that retains the low risk associated with each of those separate > proposals. At least part of the reason for creating this is similar to > my reason for creating bips PR#1472, and my covenant comparo > spreadsheet, i.e. to help further the discussion of these proposals and > make more clear the similarities and differences between them. > > https://github.com/bitcoin/bips/pull/1472 > > https://docs.google.com/spreadsheets/d/1YL5ttNb6-SHS6-C8-1tHwao1_19zNQ-31= YWPAHDZgfo/edit > > It's become clear to me that in large part the separation between > advocates of these two proposals stems from a lack of full understanding > of their properties. My hope is that this work helps to clarify our > thinking about them individually and together, and potentially move > toward consensus on a path toward enabling better lightning, vaults, and > likely other amazing ways to use bitcoin in the future. > > ----------------------- > > # Abstract > > This proposal is an alternative to [bip119][] and [bip118][], providing t= he > functionality of both proposals with no additional overhead in [many > cases](#compared-to-non-tapscript-ctv), while clearing certain objections > to > both, and opening clear upgrade paths. > > This is, in essence, an initially constrained version of Russel O'Connor'= s > [OP_TXHASH+OP_CSFS proposal][]. > > We define three new Tapscript-only opcodes. Replacing `OP_SUCCESS80`, > `OP_SUCCESS187`, and `OP_SUCCESS188` with `OP_TXHASH`, > `OP_CHECKSIGFROMSTACK`, > and `OP_CHECKSIGFROMSTACKVERIFY` respectively. > > # Summary > > For `OP_TXHASH`, we define exactly 5 methods of hashing the transaction > depending > on a minimally encoded numeric argument popped from the stack: > > argument | behavior > -------- | ----------------- > 0 | as in [bip119][] > 1 | as in [bip118][] with sighash flag `0x41` > 2 | as in [bip118][] with sighash flag `0xc1` > 3 | as in [bip118][] with sighash flag `0x43` > 4 | as in [bip118][] with sighash flag `0xc3` > > `OP_CHECKSIGFROMSTACK(VERIFY)` is defined similarly to the [implementatio= n > in > the Elements project][OP_CHECKSIGFROMSTACK in elements], but does not > internally SHA256 hash the data argument. As [bip340][] defines signature= s > on > arbitrary length messages, and these `OP_CHECKSIGFROMSTACK(VERIFY)` are > defined only in Tapscript, the internal hashing is unnecessarily > restrictive. > Users may wish to use pre-hashed values as in this proposal, or non-SHA25= 6 > hashes available in script. > > # Motivation > > Much ink has been spilled on the discussion of what is next for bitcoin > scipt > development. The two proposals nearest to consensus are [bip118][] and > [bip119][], but the proponents of each disagree about the relative priori= ty > and the merrits of the other. Here, we'll briefly outline some of the > objections to each and demonstrate how this proposal reduces those > objections. > We will not discuss the concerns about the introduction of covenants or > recursive covenants generally. > > ## [CTV][bip119] Objections > > * Not general enough > * Inefficient when otherwise validating the hash (e.g. when combined with > `OP_CHECKSIGFROMSTACK`) > * Uses `OP_NOPx` extension semantics even though `OP_SUCCESSx` is availab= le > > ## [APO][bip118] Objections > > * Not general enough > * Accidentally enables inefficient, hard to use covenants > * Uses new Tapscript key version to avoid accidents > > ## Solutions > > * By providing the behavior of both [bip118][] and [bip119][], this > proposal > is more general than either of those proposals. It also provides explic= it > upgrade hooks for further generality (e.g. to > [full OP_TXHASH][OP_TXHASH+OP_CSFS proposal]). > * By splitting the hashing from the validation of [bip119], the hash can = be > used in ways other than `OP_EQUALVERIFY`. > * We use `OP_SUCCESSx` upgrade semantics. > * We explicitly enable some of the sighash-based covenants accidentally > enabled by [bip118][]. > * By using new signature checking opcodes, we do not require the safety o= f > a > new Tapscript key version. > > # Specification > > ## `OP_TXHASH` > > When validating Tapscript, the behavior of `OP_SUCCESS80` is modified as > follows: > * If there is not at least one item on the stack, fail[^1]. > * If the top item on the stack is not a minimally encoded `OP_0`, `OP_1`, > or > `OP_2`; succeed immediately[^2]. > * Pop the top item from the stack, and name it `hash_mode` > * If `hash_mode` is 0: > * Hash the transaction as defined in [bip119][] > * Push the resulting hash to the stack > * If `hash_mode` is 1: > * Hash the transaction as defined in [bip118][] using > `sighash_type=3D0x41` > * Push the resulting hash to the stack > * If `hash_mode` is 2: > * Hash the transaction as defined in [bip118][] using > `sighash_type=3D0xc1` > * Push the resulting hash to the stack > * If `hash_mode` is 3: > * Hash the transaction as defined in [bip118][] using > `sighash_type=3D0x43` > * Push the resulting hash to the stack > * If `hash_mode` is 4: > * Hash the transaction as defined in [bip118][] using > `sighash_type=3D0xc3` > * Push the resulting hash to the stack > > ## `OP_CHECKSIGFROMSTACK(VERIFY)` > > When validating Tapscript, the behavior of `OP_SUCCESS187` and > `OP_SUCCESS188` > are modified as follows: > * If there are not at least 3 items on the stack, fail[^1]. > * If the top-minus-0 stack item's length is not 32, succeed > immediately[^2]. > * If the top-minus-2 stack item's length is not 64, fail[^3]. > * Pop the top 3 stack items as `pubkey`, `msg`, and `sig` respectively. > * Let `result` equal the result of verifying `sig` against `msg` and > `pubkey` according to [bip340][]. > * Push `true` if `result` otherwise `false` to the stack. > * If validating `OP_CHECKSIGFROMSTACKVERIFY` > * Pop the top item from the stack as `check`. > * If `check` is not `true`, fail. > > # Discussion > > ### How does the efficiency compare to [bip118][]? > > `SIGHASH_ANYPREVOUT`: > ``` > <64-byte signature>||<1-byte sighash type> <33-byte pubkey> > OP_CHECKSIG(VERIFY) > with pushes: 64+1+1 + 33+1 + 1 =3D 101 witness bytes (25.25vBytes) > ``` > > This proposal: > ``` > <64-byte signature> <1-byte argument> OP_TXHASH <32-byte pubkey> > OP_CHECKSIGFROMSTACK(VERIFY) > with pushes: 64+1 + 1 + 1 + 32+1 + 1 =3D 101 witness bytes (25.25vBytes) > ``` > > ### How does the efficiency compare to [bip119][]? > > #### Both in Tapscript > > `OP_CHECKTEMPLATEVERIFY` alone: > ``` > <32-byte hash> OP_CHECKTEMPLATEVERIFY OP_DROP OP_TRUE > with pushes: 32+1 + 1 + 1 + 1 =3D 36 witness bytes (9vBytes) > ``` > > `OP_CHECKTEMPLATEVERIFY` with a subsequent check: > ``` > <32-byte hash> OP_CHECKTEMPLATEVERIFY OP_DROP <...> > with pushes: 32+1 + 1 + 1 =3D 35 witness bytes (8.75vBytes) > ``` > > This proposal: > ``` > <1-byte argument> OP_TXHASH <32-byte hash> OP_EQUAL(VERIFY) > with pushes: 1 + 1 + 32+1 + 1 =3D 36 witness bytes (9 vBytes) > ``` > > #### Compared to non-Tapscript CTV > > Bare `OP_CHECKTEMPLATEVERIFY`: > ``` > Lock: <32-byte hash> OP_CHECKTEMPLATEVERIFY OP_DROP OP_TRUE > with pushes: 32+1 + 1 + 1 + 1 =3D 36 bytes (36vBytes) > > Unlock: > > Total: 36 + 0 =3D 36vBytes > ``` > > Witness v0 CTV: > ``` > Lock: OP_0 <32-byte hash> > with pushes: 1 + 32+1 =3D 34 bytes (34 vBytes) > > Unlock: > <36-byte witness script> > with sizes: 36+1 =3D 37 witness bytes (9.25vBytes) > > Total: 34 + 9.25 =3D 43.25vBytes > ``` > > This proposal: > ``` > Lock: OP_1 <32-byte pubkey> > with pushes: 1 + 32+1 =3D 34 bytes (34 vBytes) > > Unlock: > <36-byte leaf script> <33-byte control block> > with sizes: 36+1 + 33+1 =3D 71 witness bytes (17.75vBytes) > > Total: 34 + 17.75 =3D 51.75vBytes > ``` > > Compared to bare CTV, this proposal is 15.75vBytes more costly. If CTV us= e > cases gain popularity, a separate upgrade for bare CTV may be warranted, > either as specified in [bip119][], as its own witness version, or some > alternative. > > Bearing in mind the risks mentioned in [bip119][], fee sensitive users ca= n > add > `OP_RIPEMD160` to save 2.75 vBytes when using `OP_TXHASH` with > `OP_EQUAL(VERIFY)`. This brings the excess cost relative to bare CTV down > to > 13vBytes. > > ### Why not include modes for [bip118][] sighash_types 0x42 and 0xc2?[^4] > > Possibly due to a lack of imagination, we are unable to see a use for > signing > none of the inputs and none of the outputs (or a single input script and > none > of the outputs). > > ### Can this be used in ln-symmetry? > > Yes, this is fully compatible with ln-symmetry. It uses a different scrip= t, > but has the same size and behavior as [bip118][] for this purpose. > > ### Can this be used in PTLCs? > > Yes, this is fully compatible with PTLCs. It uses a different script, but > has > the same size and behavior as [bip118][] for this purpose. > > ### Can this be used with OP_VAULT? > > Yes, this is fully compatible with OP_VAULT. It uses a different script, > but > has the same size and behavior as [bip119][] for this purpose. > > # What is hashed? > > | field \ mode | CTV(0) | APO/ALL(1) | APOAS/ALL(2= ) > | APO/SINGLE(3) | APOAS/SINGLE(4) | > | ----------------------------------- | ------ | ---------- | -----------= - > | ------------- | --------------- | > | hash_type | | x | x > | x | x | > | version/locktime | x | x | x > | x | x | > | this input UTXO | | | > | | | > | other input UTXOs | | | > | | | > | this script pubkey/amount | | x | > | x | | > | other script pubkeys/amounts | | | > | | | > | this script sig | x | | > | | | > | other script sig | x | | > | | | > | the number of inputs | x | | > | | | > | this input sequence | x | x | x > | x | x | > | other input sequences | x | | > | | | > | this input spend type/annex | | x | x > | x | x | > | other input spend types/annexes | | | > | | | > | corresponding output script/amount | x | x | x > | x | x | > | other output scripts/amounts | x | x | x > | | | > | the number of outputs | x | | > | | | > > # Notes > > [^1]: We fail on invalid stack lengths to ensure that attackers cannot sk= ip > validation. > [^2]: We succeed on unspecified txhash modes or pubkey lengths to allow > future > extensions. > [^3]: We fail on invalid signature lengths _after_ the pubkey length chec= k, > thus allowing only 64-byte signatures for 32-byte keys, but allowing > future > key types to potentially also have different signature lengths. > [^4]: As far as we know there is no use for sighash types other than thos= e > defined in [bip118][] with this proposal, as the other types either > reduce > to `OP_CHECKSIG(VERIFY)` or create infinite hash loops. > > [bip118]: https://github.com/bitcoin/bips/blob/master/bip-0118.mediawiki > [bip119 > = ]: > https://github.com/bitcoin/bips/blob/master/bip-0119.mediawiki > [bip340 > = ]: > https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki > [OP_TXHASH+OP_CSFS proposal]: > https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/0198= 13.html > [OP_CHECKSIGFROMSTACK in elements]: > https://github.com/ElementsProject/elements/blob/f08447909101bfbbcaf89e38= 2f55c87b2086198a/src/script/interpreter.cpp#L1399 > [proposed ln-symmetry scripts]: > https://github.com/instagibbs/bolts/blob/eltoo_draft/XX-eltoo-transaction= s.md > > ----------------------- > > Best, > > --Brandon > _______________________________________________ > bitcoin-dev mailing list > bitcoin-dev@lists.linuxfoundation.org > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev > --000000000000828034060387ea10 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi Brandon,

Not going to div= e too deep here, just adding a bit of color.

> = * If the top item on the stack is not a minimally encoded `OP_0`, `OP_1`, o= r
=C2=A0 `OP_2`; succeed immediately[^2].

I pre= sume this was supposed to go to OP_4 now.

> ### How do= es the efficiency compare to [bip118][]?

Just noting BIP= 118 also allows pubkey of "1" to stand in for the taproot inner p= ubkey, which would be a common use-case. "simply" adding an opcod= e ala OP_INNER_PUBKEY could also have the same effect of course.
<= div>
Also, BIP118 also opens the door for non-APO signatures = to have a sighash digest that commits to additional data, closing a couple = of taproot malleability bugs. See=C2=A0https://github.com/bitcoin-inquisition/bit= coin/issues/19 for more discussion along those lines. These aren't = make or break, but would be nice to clean up if possible

Best,
Greg

On Tue, Aug 22, 2023 at 3:04=E2=80= =AFPM Brandon Black via bitcoin-dev <bitcoin-dev@lists.linuxfoundation.org> wrote:<= br>
Hi list,

https://gist.github.com/reardenc= ode/2aa98700b720174598d21989dd46e781

I'm seeking feedback on this proposal to provide the functionality
requested by those advocating for bip118 and bip119 in a combined way
that retains the low risk associated with each of those separate
proposals. At least part of the reason for creating this is similar to
my reason for creating bips PR#1472, and my covenant comparo
spreadsheet, i.e. to help further the discussion of these proposals and
make more clear the similarities and differences between them.

https://github.com/bitcoin/bips/pull/1472
https://docs= .google.com/spreadsheets/d/1YL5ttNb6-SHS6-C8-1tHwao1_19zNQ-31YWPAHDZgfo/edi= t

It's become clear to me that in large part the separation between
advocates of these two proposals stems from a lack of full understanding of their properties. My hope is that this work helps to clarify our
thinking about them individually and together, and potentially move
toward consensus on a path toward enabling better lightning, vaults, and likely other amazing ways to use bitcoin in the future.

-----------------------

# Abstract

This proposal is an alternative to [bip119][] and [bip118][], providing the=
functionality of both proposals with no additional overhead in [many
cases](#compared-to-non-tapscript-ctv), while clearing certain objections t= o
both, and opening clear upgrade paths.

This is, in essence, an initially constrained version of Russel O'Conno= r's
[OP_TXHASH+OP_CSFS proposal][].

We define three new Tapscript-only opcodes. Replacing `OP_SUCCESS80`,
`OP_SUCCESS187`, and `OP_SUCCESS188` with `OP_TXHASH`, `OP_CHECKSIGFROMSTAC= K`,
and `OP_CHECKSIGFROMSTACKVERIFY` respectively.

# Summary

For `OP_TXHASH`, we define exactly 5 methods of hashing the transaction dep= ending
on a minimally encoded numeric argument popped from the stack:

argument | behavior
-------- | -----------------
=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0| as in [bip119][]
=C2=A0 =C2=A01=C2=A0 =C2=A0 =C2=A0| as in [bip118][] with sighash flag `0x4= 1`
=C2=A0 =C2=A02=C2=A0 =C2=A0 =C2=A0| as in [bip118][] with sighash flag `0xc= 1`
=C2=A0 =C2=A03=C2=A0 =C2=A0 =C2=A0| as in [bip118][] with sighash flag `0x4= 3`
=C2=A0 =C2=A04=C2=A0 =C2=A0 =C2=A0| as in [bip118][] with sighash flag `0xc= 3`

`OP_CHECKSIGFROMSTACK(VERIFY)` is defined similarly to the [implementation = in
the Elements project][OP_CHECKSIGFROMSTACK in elements], but does not
internally SHA256 hash the data argument. As [bip340][] defines signatures = on
arbitrary length messages, and these `OP_CHECKSIGFROMSTACK(VERIFY)` are
defined only in Tapscript, the internal hashing is unnecessarily restrictiv= e.
Users may wish to use pre-hashed values as in this proposal, or non-SHA256<= br> hashes available in script.

# Motivation

Much ink has been spilled on the discussion of what is next for bitcoin sci= pt
development. The two proposals nearest to consensus are [bip118][] and
[bip119][], but the proponents of each disagree about the relative priority=
and the merrits of the other. Here, we'll briefly outline some of the objections to each and demonstrate how this proposal reduces those objectio= ns.
We will not discuss the concerns about the introduction of covenants or
recursive covenants generally.

## [CTV][bip119] Objections

* Not general enough
* Inefficient when otherwise validating the hash (e.g. when combined with =C2=A0 `OP_CHECKSIGFROMSTACK`)
* Uses `OP_NOPx` extension semantics even though `OP_SUCCESSx` is available=

## [APO][bip118] Objections

* Not general enough
* Accidentally enables inefficient, hard to use covenants
* Uses new Tapscript key version to avoid accidents

## Solutions

* By providing the behavior of both [bip118][] and [bip119][], this proposa= l
=C2=A0 is more general than either of those proposals. It also provides exp= licit
=C2=A0 upgrade hooks for further generality (e.g. to
=C2=A0 [full OP_TXHASH][OP_TXHASH+OP_CSFS proposal]).
* By splitting the hashing from the validation of [bip119], the hash can be=
=C2=A0 used in ways other than `OP_EQUALVERIFY`.
* We use `OP_SUCCESSx` upgrade semantics.
* We explicitly enable some of the sighash-based covenants accidentally
=C2=A0 enabled by [bip118][].
* By using new signature checking opcodes, we do not require the safety of = a
=C2=A0 new Tapscript key version.

# Specification

## `OP_TXHASH`

When validating Tapscript, the behavior of `OP_SUCCESS80` is modified as follows:
* If there is not at least one item on the stack, fail[^1].
* If the top item on the stack is not a minimally encoded `OP_0`, `OP_1`, o= r
=C2=A0 `OP_2`; succeed immediately[^2].
* Pop the top item from the stack, and name it `hash_mode`
* If `hash_mode` is 0:
=C2=A0 =C2=A0 * Hash the transaction as defined in [bip119][]
=C2=A0 =C2=A0 * Push the resulting hash to the stack
* If `hash_mode` is 1:
=C2=A0 =C2=A0 * Hash the transaction as defined in [bip118][] using `sighas= h_type=3D0x41`
=C2=A0 =C2=A0 * Push the resulting hash to the stack
* If `hash_mode` is 2:
=C2=A0 =C2=A0 * Hash the transaction as defined in [bip118][] using `sighas= h_type=3D0xc1`
=C2=A0 =C2=A0 * Push the resulting hash to the stack
* If `hash_mode` is 3:
=C2=A0 =C2=A0 * Hash the transaction as defined in [bip118][] using `sighas= h_type=3D0x43`
=C2=A0 =C2=A0 * Push the resulting hash to the stack
* If `hash_mode` is 4:
=C2=A0 =C2=A0 * Hash the transaction as defined in [bip118][] using `sighas= h_type=3D0xc3`
=C2=A0 =C2=A0 * Push the resulting hash to the stack

## `OP_CHECKSIGFROMSTACK(VERIFY)`

When validating Tapscript, the behavior of `OP_SUCCESS187` and `OP_SUCCESS1= 88`
are modified as follows:
* If there are not at least 3 items on the stack, fail[^1].
* If the top-minus-0 stack item's length is not 32, succeed immediately= [^2].
* If the top-minus-2 stack item's length is not 64, fail[^3].
* Pop the top 3 stack items as `pubkey`, `msg`, and `sig` respectively.
* Let `result` equal the result of verifying `sig` against `msg` and `pubke= y` according to [bip340][].
* Push `true` if `result` otherwise `false` to the stack.
* If validating `OP_CHECKSIGFROMSTACKVERIFY`
=C2=A0 =C2=A0 * Pop the top item from the stack as `check`.
=C2=A0 =C2=A0 * If `check` is not `true`, fail.

# Discussion

### How does the efficiency compare to [bip118][]?

`SIGHASH_ANYPREVOUT`:
```
<64-byte signature>||<1-byte sighash type> <33-byte pubkey&g= t; OP_CHECKSIG(VERIFY)
with pushes: 64+1+1 + 33+1 + 1 =3D 101 witness bytes (25.25vBytes)
```

This proposal:
```
<64-byte signature> <1-byte argument> OP_TXHASH <32-byte pub= key> OP_CHECKSIGFROMSTACK(VERIFY)
with pushes: 64+1 + 1 + 1 + 32+1 + 1 =3D 101 witness bytes (25.25vBytes) ```

### How does the efficiency compare to [bip119][]?

#### Both in Tapscript

`OP_CHECKTEMPLATEVERIFY` alone:
```
<32-byte hash> OP_CHECKTEMPLATEVERIFY OP_DROP OP_TRUE
with pushes: 32+1 + 1 + 1 + 1 =3D 36 witness bytes (9vBytes)
```

`OP_CHECKTEMPLATEVERIFY` with a subsequent check:
```
<32-byte hash> OP_CHECKTEMPLATEVERIFY OP_DROP <...>
with pushes: 32+1 + 1 + 1 =3D 35 witness bytes (8.75vBytes)
```

This proposal:
```
<1-byte argument> OP_TXHASH <32-byte hash> OP_EQUAL(VERIFY)
with pushes: 1 + 1 + 32+1 + 1 =3D 36 witness bytes (9 vBytes)
```

#### Compared to non-Tapscript CTV

Bare `OP_CHECKTEMPLATEVERIFY`:
```
Lock: <32-byte hash> OP_CHECKTEMPLATEVERIFY OP_DROP OP_TRUE
with pushes: 32+1 + 1 + 1 + 1 =3D 36 bytes (36vBytes)

Unlock: <empty>

Total: 36 + 0 =3D 36vBytes
```

Witness v0 CTV:
```
Lock: OP_0 <32-byte hash>
with pushes: 1 + 32+1 =3D 34 bytes (34 vBytes)

Unlock:
<36-byte witness script>
with sizes: 36+1 =3D 37 witness bytes (9.25vBytes)

Total: 34 + 9.25 =3D 43.25vBytes
```

This proposal:
```
Lock: OP_1 <32-byte pubkey>
with pushes: 1 + 32+1 =3D 34 bytes (34 vBytes)

Unlock:
<36-byte leaf script> <33-byte control block>
with sizes: 36+1 + 33+1 =3D 71 witness bytes (17.75vBytes)

Total: 34 + 17.75 =3D 51.75vBytes
```

Compared to bare CTV, this proposal is 15.75vBytes more costly. If CTV use<= br> cases gain popularity, a separate upgrade for bare CTV may be warranted, either as specified in [bip119][], as its own witness version, or some
alternative.

Bearing in mind the risks mentioned in [bip119][], fee sensitive users can = add
`OP_RIPEMD160` to save 2.75 vBytes when using `OP_TXHASH` with
`OP_EQUAL(VERIFY)`. This brings the excess cost relative to bare CTV down t= o
13vBytes.

### Why not include modes for [bip118][] sighash_types 0x42 and 0xc2?[^4]
Possibly due to a lack of imagination, we are unable to see a use for signi= ng
none of the inputs and none of the outputs (or a single input script and no= ne
of the outputs).

### Can this be used in ln-symmetry?

Yes, this is fully compatible with ln-symmetry. It uses a different script,=
but has the same size and behavior as [bip118][] for this purpose.

### Can this be used in PTLCs?

Yes, this is fully compatible with PTLCs. It uses a different script, but h= as
the same size and behavior as [bip118][] for this purpose.

### Can this be used with OP_VAULT?

Yes, this is fully compatible with OP_VAULT. It uses a different script, bu= t
has the same size and behavior as [bip119][] for this purpose.

# What is hashed?

| field \ mode=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 | CTV(0) | APO/ALL(1) | APOAS/ALL(2) | APO/SINGLE(= 3) | APOAS/SINGLE(4) |
| ----------------------------------- | ------ | ---------- | ------------ = | ------------- | --------------- |
| hash_type=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2=A0 =C2=A0 =C2=A0 | x=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 | x=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | = x=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0| x=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|
| version/locktime=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 | x=C2=A0 =C2=A0 =C2=A0 | x=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= | x=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | x=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0| x=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0|
| this input UTXO=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|
| other input UTXOs=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0|=C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|
| this script pubkey/amount=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0= =C2=A0 =C2=A0 =C2=A0 | x=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | x=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0|=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0|
| other script pubkeys/amounts=C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A0 = =C2=A0 =C2=A0 |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0|=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0|
| this script sig=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0| x=C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|
| other script sig=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 | x=C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0|
| the number of inputs=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 | x=C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0|
| this input sequence=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0| x=C2=A0 =C2=A0 =C2=A0 | x=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | x= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | x=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0| x=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0|
| other input sequences=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0| x=C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0|
| this input spend type/annex=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2= =A0 =C2=A0 =C2=A0 | x=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | x=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 | x=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0| x=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|
| other input spend types/annexes=C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2=A0 =C2=A0 = =C2=A0 |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0|=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|
| corresponding output script/amount=C2=A0 | x=C2=A0 =C2=A0 =C2=A0 | x=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | x=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 | x=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0| x=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|
| other output scripts/amounts=C2=A0 =C2=A0 =C2=A0 =C2=A0 | x=C2=A0 =C2=A0 = =C2=A0 | x=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | x=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|
| the number of outputs=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0| x=C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0|

# Notes

[^1]: We fail on invalid stack lengths to ensure that attackers cannot skip=
=C2=A0 validation.
[^2]: We succeed on unspecified txhash modes or pubkey lengths to allow fut= ure
=C2=A0 extensions.
[^3]: We fail on invalid signature lengths _after_ the pubkey length check,=
=C2=A0 thus allowing only 64-byte signatures for 32-byte keys, but allowing= future
=C2=A0 key types to potentially also have different signature lengths.
[^4]: As far as we know there is no use for sighash types other than those<= br> =C2=A0 defined in [bip118][] with this proposal, as the other types either = reduce
=C2=A0 to `OP_CHECKSIG(VERIFY)` or create infinite hash loops.

[bip118]: https://github.com/= bitcoin/bips/blob/master/bip-0118.mediawiki
[bip119
]: https://github.= com/bitcoin/bips/blob/master/bip-0119.mediawiki
[bip340
]: https://github.com/bitco= in/bips/blob/master/bip-0340.mediawiki
[OP_TXHASH+OP_CSFS proposal]: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-Ja= nuary/019813.html
[OP_CHECKSIGFROMSTACK in elements]: https://github.co= m/ElementsProject/elements/blob/f08447909101bfbbcaf89e382f55c87b2086198a/sr= c/script/interpreter.cpp#L1399
[proposed ln-symmetry scripts]: https://github.com/instagibbs/bolts/blob/eltoo_draft/XX-eltoo-tran= sactions.md

-----------------------

Best,

--Brandon
_______________________________________________
bitcoin-dev mailing list
= bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mail= man/listinfo/bitcoin-dev
--000000000000828034060387ea10--