Re: [bitcoin-dev] Continuing the discussion about noinput / anyprevout
On Thu, Oct 03, 2019 at 01:08:29PM +0200, Christian Decker wrote: > > * anyprevout signatures make the address you're signing for less safe, > >which may cause you to lose funds when additional coins are sent to > >the same address; this can be avoided if handled with care (or if you > >don't care about losing funds in the event of address reuse) > Excellent points, I had missed the hidden nature of the opt-in via > pubkey prefix while reading your proposal. I'm starting to like that > option more and more. In that case we'd only ever be revealing that we > opted into anyprevout when we're revealing the entire script anyway, at > which point all fungibility concerns go out the window anyway. > > Would this scheme be extendable to opt into all sighash flags the > outpoint would like to allow (e.g., adding opt-in for sighash_none and > sighash_anyonecanpay as well)? That way the pubkey prefix could act as a > mask for the sighash flags and fail verification if they don't match. For me, the thing that distinguishes ANYPREVOUT/NOINPUT as warranting an opt-in step is that it affects the security of potentially many UTXOs at once; whereas all the other combinations (ALL,SINGLE,NONE cross ALL,ANYONECANPAY) still commit to the specific UTXO being spent, so at most you only risk somehow losing the funds from the specific UTXO you're working with (apart from the SINGLE bug, which taproot doesn't support anyway). Having a meaningful prefix on the taproot scriptpubkey (ie paying to "[SIGHASH_SINGLE][32B pubkey]") seems like it would make it a bit easier to distinguish wallets, which taproot otherwise avoids -- "oh this address is going to be a SIGHASH_SINGLE? probably some hacker, let's ban it". > > I think it might be good to have a public testnet (based on Richard Myers > > et al's signet2 work?) where we have some fake exchanges/merchants/etc > > and scheduled reorgs, and demo every weird noinput/anyprevout case anyone > > can think of, and just work out if we need any extra code/tagging/whatever > > to keep those fake exchanges/merchants from losing money (and write up > > the weird cases we've found in a wiki or a paper so people can easily > > tell if we missed something obvious). > That'd be great, however even that will not ensure that every possible > corner case is handled [...] Well, sure. I'm thinking of it more as a *necessary* step than a *sufficient* one, though. If we can't demonstrate that we can deal with the theoretical attacks people have dreamt up in a "laboratory" setting, then it doesn't make much sense to deploy things in a real world setting, does it? I think if it turns out that we can handle every case we can think of easily, that will be good evidence that output tagging and the like isn't necessary; and conversely if it turns out we can't handle them easily, it at least gives us a chance to see how output tagging (or chaperone sigs, or whatever else) would actually work, and if they'd provide any meaningful protection at all. At the moment the best we've got is ideas and handwaving... Cheers, aj ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Re: [bitcoin-dev] Continuing the discussion about noinput / anyprevout
Anthony Towns writes: > On Mon, Sep 30, 2019 at 03:23:56PM +0200, Christian Decker via bitcoin-dev > wrote: >> With the recently renewed interest in eltoo, a proof-of-concept >> implementation >> [1], and the discussions regarding clean abstractions for off-chain protocols >> [2,3], I thought it might be time to revisit the `sighash_noinput` proposal >> (BIP-118 [4]), and AJ's `bip-anyprevout` proposal [5]. > > Hey Christian, thanks for the write up! > >> ## Open questions >> The questions that remain to be addressed are the following: >> 1. General agreement on the usefulness of noinput / anyprevoutanyscript / >> anyprevout[?] >> 2. Is there strong support or opposition to the chaperone signatures[?] >> 3. The same for output tagging / explicit opt-in[?] >> 4. Shall we merge BIP-118 and bip-anyprevout. This would likely reduce the >> confusion and make for simpler discussions in the end. > > I think there's an important open question you missed from this list: > (1.5) do we really understand what the dangers of noinput/anyprevout-style > constructions actually are? > > My impression on the first 3.5 q's is: (1) yes, (1.5) not really, > (2) weak opposition for requiring chaperone sigs, (3) mixed (weak) > support/opposition for output tagging. > > My thinking at the moment (subject to change!) is: > > * anyprevout signatures make the address you're signing for less safe, >which may cause you to lose funds when additional coins are sent to >the same address; this can be avoided if handled with care (or if you >don't care about losing funds in the event of address reuse) > > * being able to guarantee that an address can never be signed for with >an anyprevout signature is therefore valuable; so having it be opt-in >at the tapscript level, rather than a sighash flag available for >key-path spends is valuable (I call this "opt-in", but it's hidden >until use via taproot rather than "explicit" as output tagging >would be) > > * receiving funds spent via an anyprevout signature does not involve any >qualitatively new double-spending/malleability risks. > >(eltoo is unavoidably malleable if there are multiple update >transactions (and chaperone signatures aren't used or are used with >well known keys), but while it is better to avoid this where possible, >it's something that's already easily dealt with simply by waiting >for confirmations, and whether a transaction is malleable is always >under the control of the sender not the receiver) > > * as such, output tagging is also unnecessary, and there is also no >need for users to mark anyprevout spends as "tainted" in order to >wait for more confirmations than normal before considering those funds >"safe" Excellent points, I had missed the hidden nature of the opt-in via pubkey prefix while reading your proposal. I'm starting to like that option more and more. In that case we'd only ever be revealing that we opted into anyprevout when we're revealing the entire script anyway, at which point all fungibility concerns go out the window anyway. Would this scheme be extendable to opt into all sighash flags the outpoint would like to allow (e.g., adding opt-in for sighash_none and sighash_anyonecanpay as well)? That way the pubkey prefix could act as a mask for the sighash flags and fail verification if they don't match. > I think it might be good to have a public testnet (based on Richard Myers > et al's signet2 work?) where we have some fake exchanges/merchants/etc > and scheduled reorgs, and demo every weird noinput/anyprevout case anyone > can think of, and just work out if we need any extra code/tagging/whatever > to keep those fake exchanges/merchants from losing money (and write up > the weird cases we've found in a wiki or a paper so people can easily > tell if we missed something obvious). That'd be great, however even that will not ensure that every possible corner case is handled and from experience it seems that people are unwilling to invest a lot of time testing on a network unless their money is on the line. That's not to say that we shouldn't try, we absolutely should, I'm just not sure it alone is enough to dispell all remaining doubts :-) Cheers, Christian ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Re: [bitcoin-dev] Continuing the discussion about noinput / anyprevout
ZmnSCPxj writes: >> That is very much how I was planning to implement it anyway, using a >> trigger transaction to separate timeout start and the actual >> update/settlement pairs (cfr. eltoo paper Section 4.2). So for eltoo >> there shouldn't be an issue here :-) > > My understanding is that a trigger transaction is not in fact > necessary for Decker-Russell-Osuntokun: any update transaction could > spend the funding transaction output directly, and thereby start the > relative timelock. At least, if we could arrange the funding > transaction output to be spendable directly using `SIGHASH_NOINPUT` or > variants thereof. This is the case in which we don't have a pre-signed settlement transaction (or in this case refund transaction) that uses a relative timelock. In order to have a refund transaction we would need to have the first update and settlement pair be signed before funding (otherwise the funder isn't sure she is getting her funds back). Since that first update and settlement pair do not need to be rebound (they can only ever be bound to the funding transaction) they can be signed without noinput/anyprevoutanyscript. If we use output tagging we would mandate that this first update must be published, so that the funding output is indistinguishable from a normal output, and the first update switches from non-noinput/anyprevoutanyscript to enabling it. Collaborative closes are still indistinguishable, unilateral closes require the switch, but then would be identifiable anyway. The one downside I can see is that we now mandate that unilateral closes also publish the first update, which is a bit annoying. >> While I do agree that we should keep outputs as unidentifiable as >> possible, I am starting to question whether that is possible for >> off-chain payment networks since we are gossiping about the existence of >> channels and binding them to outpoints to prove their existence anyway. > > * Lightning supports unpublished channels, so we do not gossip some outpoints > even though they are in fact channels underneath. > * I confess the existence of unpublished channels in the spec fails to > summon any reaction other than incredulity from me, but they exist > nonetheless, my incredulity notwithstanding. That is true, we do however selectively tell others about the channel's existence (in invoices, our peers, ...) so I wouldn't consider that to be the most secret information :-) As for why they exist: nodes need to have the option of not announcing their channels to reduce the noise in the network with channels that are unlikely to be useable in order to forward payments. If every node were to announce their channels we'd have a much larger routing table, mostly consisting of unusable channels going to leafs in the network. Furthermore, the sheer threat that there might be unannounced channels adds uncertainty for attackers trying to profile nodes: "I see only my channel with my peer, but he might have unannounced channels, so I can't really tell whether the payment I forwarded to it is destined for it or one of its unannounced peers". > * Historical channels that have been cooperatively closed are no longer > normally gossiped, so the fact that they used to be channels is no longer > widely broadcast, and may eventually be forgotten by most or all of the > network. > * This means anyone who wants to record the historical use of Lightning > will have to retain the information themselves, rather than delegating it to > fullnodes everywhere. Good point, it requires storing the ephemeral data from gossip, that's not all that hard, but I agree that it puts up a small barrier for newcomers. ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Re: [bitcoin-dev] Continuing the discussion about noinput / anyprevout
Good morning lists, Let me propose the below radical idea: * `SIGHASH` flags attached to signatures are a misdesign, sadly retained from the original BitCoin 0.1.0 Alpha for Windows design, on par with: * 1 RETURN * higher-`nSequence` replacement * DER-encoded pubkeys * unrestricted `scriptPubKey` * Payee-security-paid-by-payer (i.e. lack of P2SH) * `OP_CAT` and `OP_MULT` and `OP_ADD` and friends * transaction malleability * probably many more So let me propose the more radical excision, starting with SegWit v1: * Remove `SIGHASH` from signatures. * Put `SIGHASH` on public keys. Public keys are now encoded as either 33-bytes (implicit `SIGHASH_ALL`) or 34-bytes (`SIGHASH` byte, followed by pubkey type, followed by pubkey coordinate). `OP_CHECKSIG` and friends then look at the *public key* to determine sighash algorithm rather than the signature. As we expect public keys to be indirectly committed to on every output `scriptPubKey`, this is automatically output tagging to allow particular `SIGHASH`. However, we can then utilize the many many ways to hide public keys away until they are needed, exemplified in MAST-inside-Taproot. I propose also the addition of the opcode: OP_SETPUBKEYSIGHASH * `sighash` must be one byte. * `pubkey` may be the special byte `0x1`, meaning "just use the Taproot internal pubkey". * `pubkey` may be 33-byte public key, in which case the `sighash` byte is just prepended to it. * `pubkey` may be 34-byte public key with sighash, in which case the first byte is replaced with `sighash` byte. * If `sighash` is `0x00` then the result is a 33-byte public key (the sighash byte is removed) i.e. `SIGHASH_ALL` implicit. This retains the old feature where the sighash is selected at time-of-spending rather than time-of-payment. This is done by using the script: OP_SETPUBKEYSIGHASH OP_CHECKSIG Then the sighash can be put in the witness stack after the signature, letting the `SIGHASH` flag be selected at time-of-signing, but only if the SCRIPT specifically is formed to do so. This is malleability-safe as the signature still commits to the `SIGHASH` it was created for. However, by default, public keys will not have an attached `SIGHASH` byte, implying `SIGHASH_ALL` (and disallowing-by-default non-`SIGHASH_ALL`). This removes the problems with `SIGHASH_NONE` `SIGHASH_SINGLE`, as they are allowed only if the output specifically says they are allowed. Would this not be a superior solution? Regards, ZmnSCPxj ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Re: [bitcoin-dev] Continuing the discussion about noinput / anyprevout
On Mon, Sep 30, 2019 at 03:23:56PM +0200, Christian Decker via bitcoin-dev wrote: > With the recently renewed interest in eltoo, a proof-of-concept implementation > [1], and the discussions regarding clean abstractions for off-chain protocols > [2,3], I thought it might be time to revisit the `sighash_noinput` proposal > (BIP-118 [4]), and AJ's `bip-anyprevout` proposal [5]. Hey Christian, thanks for the write up! > ## Open questions > The questions that remain to be addressed are the following: > 1. General agreement on the usefulness of noinput / anyprevoutanyscript / > anyprevout[?] > 2. Is there strong support or opposition to the chaperone signatures[?] > 3. The same for output tagging / explicit opt-in[?] > 4. Shall we merge BIP-118 and bip-anyprevout. This would likely reduce the > confusion and make for simpler discussions in the end. I think there's an important open question you missed from this list: (1.5) do we really understand what the dangers of noinput/anyprevout-style constructions actually are? My impression on the first 3.5 q's is: (1) yes, (1.5) not really, (2) weak opposition for requiring chaperone sigs, (3) mixed (weak) support/opposition for output tagging. My thinking at the moment (subject to change!) is: * anyprevout signatures make the address you're signing for less safe, which may cause you to lose funds when additional coins are sent to the same address; this can be avoided if handled with care (or if you don't care about losing funds in the event of address reuse) * being able to guarantee that an address can never be signed for with an anyprevout signature is therefore valuable; so having it be opt-in at the tapscript level, rather than a sighash flag available for key-path spends is valuable (I call this "opt-in", but it's hidden until use via taproot rather than "explicit" as output tagging would be) * receiving funds spent via an anyprevout signature does not involve any qualitatively new double-spending/malleability risks. (eltoo is unavoidably malleable if there are multiple update transactions (and chaperone signatures aren't used or are used with well known keys), but while it is better to avoid this where possible, it's something that's already easily dealt with simply by waiting for confirmations, and whether a transaction is malleable is always under the control of the sender not the receiver) * as such, output tagging is also unnecessary, and there is also no need for users to mark anyprevout spends as "tainted" in order to wait for more confirmations than normal before considering those funds "safe" I think it might be good to have a public testnet (based on Richard Myers et al's signet2 work?) where we have some fake exchanges/merchants/etc and scheduled reorgs, and demo every weird noinput/anyprevout case anyone can think of, and just work out if we need any extra code/tagging/whatever to keep those fake exchanges/merchants from losing money (and write up the weird cases we've found in a wiki or a paper so people can easily tell if we missed something obvious). Cheers, aj ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Re: [bitcoin-dev] Continuing the discussion about noinput / anyprevout
Good morning aj, > On Mon, Sep 30, 2019 at 11:28:43PM +, ZmnSCPxj via bitcoin-dev wrote: > > > Suppose rather than `SIGHASH_NOINPUT`, we created a new opcode, > > `OP_CHECKSIG_WITHOUT_INPUT`. > > I don't think there's any meaningful difference between making a new > opcode and making a new tapscript public key type; the difference is > just one of encoding: > > 3301AC [CHECKSIG of public key type 0x01] > 32B3 [CHECKSIG_WITHOUT_INPUT (replacing NOP4) of key] > > > This new opcode ignores any `SIGHASH` flags, if present, on a signature, > > (How sighash flags are treated can be redefined by new public key types; > if that's not obvious already) Thank you for this thought, I believe under tapscript v0 we can give `OP_1` as the public key to `OP_CHECKSIG` to mean to reuse the internal Taproot pubkey, would it be possible to have some similar mechanism here, to copy the internal Taproot pubkey but also to enable new `SIGHASH` flag for this particular script only? This seems fine, as then a Decker-Russell-Osuntokun funding tx output between nodes A, B, and C would have: * Taproot internal key: `P = MuSig(A, B, C)` * Script 1: leaf version 0, ` OP_CHECKSIG` Then, update transactions could use `MuSig(A,B,C)` for signing along the "update" path, with unique "state" keys. And cooperative closes would sign using `P + h(P | MAST( OPCHECKSIG)) * G`, not revealing the fact that this was in fact a Decker-Russell-Osuntokun output. Regards, ZmnSCPxj ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Re: [bitcoin-dev] Continuing the discussion about noinput / anyprevout
Good morning Christian, > > - A standard MuSig 2-of-2 bip-schnorr SegWit v1 Funding Transaction > > Output, confirmed onchain > > - A "translator transaction" spending the above and paying out to a > > SegWit v16 output-tagged output, kept offchain. > > - Decker-Russell-Osuntokun update transaction, signed with > > `SIGHASH_NOINPUT` spending the translator transaction output. > > - Decker-Russell-Osuntokun state transaction, signed with > > `SIGHASH_NOINPUT` spending the update transaction output. > > That is very much how I was planning to implement it anyway, using a > trigger transaction to separate timeout start and the actual > update/settlement pairs (cfr. eltoo paper Section 4.2). So for eltoo > there shouldn't be an issue here :-) My understanding is that a trigger transaction is not in fact necessary for Decker-Russell-Osuntokun: any update transaction could spend the funding transaction output directly, and thereby start the relative timelock. At least, if we could arrange the funding transaction output to be spendable directly using `SIGHASH_NOINPUT` or variants thereof. > > Again, the more important point is that special blockchain > > constructions should only be used in the "bad" unilateral close case. > > In the cooperative case, we want to use simple plain > > bip-schnorr-signed outputs getting spent to further bip-schnor/Taproot > > SegWit v1 addresses, to increase the anonymity set of all uses of > > Decker-Russell-Osuntokun and other applications that might use > > `SIGHASH_NOINPUT` in some edge case (but which resolve down to simple > > bip-schnorr-signed n-of-n cases when the protocol is completed > > successfully by all participants). > > While I do agree that we should keep outputs as unidentifiable as > possible, I am starting to question whether that is possible for > off-chain payment networks since we are gossiping about the existence of > channels and binding them to outpoints to prove their existence anyway. * Lightning supports unpublished channels, so we do not gossip some outpoints even though they are in fact channels underneath. * I confess the existence of unpublished channels in the spec fails to summon any reaction other than incredulity from me, but they exist nonetheless, my incredulity notwithstanding. * Historical channels that have been cooperatively closed are no longer normally gossiped, so the fact that they used to be channels is no longer widely broadcast, and may eventually be forgotten by most or all of the network. * This means anyone who wants to record the historical use of Lightning will have to retain the information themselves, rather than delegating it to fullnodes everywhere. > > Not the strongest argument I know, but there's little point in talking > ideal cases when we need to weaken that later again. The point of ideal cases is to strive to approach them, not necessarily achieve them. Just as a completely unbiased rational reasoner is almost impossible to achieve, does not mean we should give up all attempts to reduce bias. Outpoints that used to be channels, but have now been closed using cooperative closes, will potentially no longer be widely gossiped as having once been channels, thus it may happen that they will eventually be forgotten by most of the network as once having been channels. But if the outpoints of those channels are specially marked, then that cannot be forgotten, as the initial block download thereafter will have that history indelibly etched forevermore. Regards, ZmnSCPxj ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Re: [bitcoin-dev] Continuing the discussion about noinput / anyprevout
On Mon, Sep 30, 2019 at 11:28:43PM +, ZmnSCPxj via bitcoin-dev wrote: > Suppose rather than `SIGHASH_NOINPUT`, we created a new opcode, > `OP_CHECKSIG_WITHOUT_INPUT`. I don't think there's any meaningful difference between making a new opcode and making a new tapscript public key type; the difference is just one of encoding: 3301AC [CHECKSIG of public key type 0x01] 32B3 [CHECKSIG_WITHOUT_INPUT (replacing NOP4) of key] > This new opcode ignores any `SIGHASH` flags, if present, on a signature, (How sighash flags are treated can be redefined by new public key types; if that's not obvious already) Cheers, aj ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Re: [bitcoin-dev] Continuing the discussion about noinput / anyprevout
I do have some concerns about SIGHASH_NOINPUT, mainly that it does introduce another footgun into the bitcoin protocol with address reuse. It's common practice for bitcoin businesses to re-use addresses. Many exchanges [1] reuse addresses for cold storage with very large sums of money that is stored in these addreses. It is my understanding with this part of BIP118 >Using NOINPUT the input containing the signature no longer references a specific output. Any participant can take a transaction and rewrite it by changing the hash reference to the previous output, without invalidating the signatures. This allows transactions to be bound to any output that matches the value committed to in the witness and whose witnessProgram, combined with the spending transaction's witness returns true. if an exchange were to once produce a digital signature from that cold storage address with a SIGHASH_NOINPUT signature, that signature can be replayed again and again on the blockchain until their wallet is drained. This might be able to mitigated since the signatures commit to outputs, which may be small in value for the transaction that SIGHASH_NOINPUT was used. This means that an exchange could move coins from the address with a larger transaction that spends money to a new output (and presumably pays a higher fee than the smaller transactions). ### Why does this matter? It seems that SIGHASH_NOINPUT will be an extremely useful tool for offchain protocols like Lightning. This gives us the building blocks for enforcing specific offchain states to end up onchain [2]. Since this tool is useful, we can presume that it will be integrated into the signing path of large economic entities in bitcoin -- namely exchanges. Many exchanges have specific signing procedures for transactions that are leaving an exchange that is custom software. Now -- presuming wide adoption of off chain protocols -- they will need to have a _second unique signing path that uses SIGHASH_NOINPUT_. It is imperative that this second signing path -- which uses SIGHASH_NOINPUT -- does NOT get mixed up with the first signing path that controls an exchanges onchain funds. If this were to happen, fund lost could occur if the exchange is reusing address, which seems to be common practice. This is stated here in BIP118: >This also means that particular care has to be taken in order to avoid unintentionally enabling this rebinding mechanism. NOINPUT MUST NOT be used, unless it is explicitly needed for the application, e.g., it MUST NOT be a default signing flag in a wallet implementation. Rebinding is only possible when the outputs the transaction may bind to all use the same public keys. Any public key that is used in a NOINPUT signature MUST only be used for outputs that the input may bind to, and they MUST NOT be used for transactions that the input may not bind to. For example an application SHOULD generate a new key-pair for the application instance using NOINPUT signatures and MUST NOT reuse them afterwards. This means we need to encourage onchain hot wallet signing procedures to be kept separate from offchain hot wallet signing procedures, which introduces more complexity for key management (two keychains). One (of the few) upsides of the current Lightning penalty mechanism is that fund loss can be contained to balance of the channel. You cannot do something in the current protocol that will effect your funds outside of that channel. With SIGHASH_NOINPUT, that property changes. ### A side note In general, i think we should start disallowing uses of the SIGHASH protocols that have unexpected behavior. The classic example of this is SIGHASH_SINGLE [3]. I get uneasy about adding more footguns to the protocol, which with current network behavior (address re-use) SIGHASH_NOINPUT would be a big one. [1] - https://bitinfocharts.com/top-100-richest-bitcoin-addresses.html [2] - https://lists.linuxfoundation.org/pipermail/lightning-dev/2019-September/002136.html [3] - https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-May/016048.html On Mon, Sep 30, 2019 at 9:24 AM Christian Decker via bitcoin-dev < bitcoin-dev@lists.linuxfoundation.org> wrote: > With the recently renewed interest in eltoo, a proof-of-concept > implementation > [1], and the discussions regarding clean abstractions for off-chain > protocols > [2,3], I thought it might be time to revisit the `sighash_noinput` proposal > (BIP-118 [4]), and AJ's `bip-anyprevout` proposal [5]. > > (sorry for the long e-mail. I wanted to give enough context and describe > the > various tradeoffs so people don't have to stitch them together from > memory. If > you're impatient there are a couple of open questions at the bottom) > > Both proposals are ways to allow rebinding of transactions to new outputs, > by > adding a sighash flag that excludes the output when signing. This allows > the > transaction to be bound to any output, without needing a new signature, as > long as output script and input
Re: [bitcoin-dev] Continuing the discussion about noinput / anyprevout
ZmnSCPxj writes: > To elucidate further --- > > Suppose rather than `SIGHASH_NOINPUT`, we created a new opcode, > `OP_CHECKSIG_WITHOUT_INPUT`. > > This new opcode ignores any `SIGHASH` flags, if present, on a > signature, but instead hashes the current transaction without the > input references, then checks that hash to the signature. > > This is equivalent to `SIGHASH_NOINPUT`. > > Yet as an opcode, it would be possible to embed in a Taproot script. > > For example, a Decker-Russell-Osuntokun would have an internal Taproot > point be a 2-of-2, then have a script `OP_1 > OP_CHECKSIG_WITHOUT_INPUT`. Unilateral closes would expose the hidden > script, but cooperative closes would use the 2-of-2 directly. > > Of note, is that any special SCRIPT would already be supportable by Taproot. > This includes SCRIPTs that may potentially lose funds for the user. > Yet such SCRIPTs are already targetable by a Taproot address. > > If we are so concerned about `SIGHASH_NOINPUT` abuse, why are we not > so concerned about Taproot abuse? That would certainly be another possibility, which I have not explored in detail so far. Due to the similarity between the various signature checking op-codes it felt that it should be a sighash flag, and it neatly slotted into the already existing flags. If we go for a separate opcode we might end up reinventing the wheel, and to be honest I feared that proposing a new opcode would get us into bikeshedding territory (which I apparently failed to avoid with the sighash flag anyway...). The advantage would be that with the sighash flag the spender is in charge of specifying the flags, whereas with an opcode the output dictates the signature verification modalities. The downside is the increased design space. What do others think? Would this be an acceptable opt-in mechanism that addresses the main concerns? Cheers, Christian ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
[bitcoin-dev] Continuing the discussion about noinput / anyprevout
With the recently renewed interest in eltoo, a proof-of-concept implementation [1], and the discussions regarding clean abstractions for off-chain protocols [2,3], I thought it might be time to revisit the `sighash_noinput` proposal (BIP-118 [4]), and AJ's `bip-anyprevout` proposal [5]. (sorry for the long e-mail. I wanted to give enough context and describe the various tradeoffs so people don't have to stitch them together from memory. If you're impatient there are a couple of open questions at the bottom) Both proposals are ways to allow rebinding of transactions to new outputs, by adding a sighash flag that excludes the output when signing. This allows the transaction to be bound to any output, without needing a new signature, as long as output script and input script are compatible, e.g., the signature matches the public key specified in the output. BIP-118 is limited to explaining the details of signature verification, and omits anything related to deployment and dependency on other proposals. This was done in order not to depend on bip-taproot which is also in draft-phase currently, and to allow deployment alongside the next version of segwit script. `bip-anyprevout` builds on top of BIP-118, adding integration with `bip-taproot`, chaperone signatures, limits the use of the sighash flag to script path spends, as well as a new pubkey serialization which uses the first byte to signal opt-in. I'd like to stress that both proposals are complementary and not competing, which is something that I've heard a couple of times. There remain a couple of unclear points which I hope we can address in the coming days, to get this thing moving again, and hopefully get a new tool in our toolbox soon(ish). In the following I will quote a couple of things that were discussed during the CoreDev meeting earlier this year, but not everybody could join, and it is important that we engage the wider community, to get a better picture, and I think not everybody is up-to-date about the current state. ## Dangers of `sighash_noinput` An argument I have heard against noinput is that it is slightly less complex or compute intensive than `sighash_all` signatures, which may encourage wallet creators to only implement the noinput variant, and use it indiscrimi- nately. This is certainly a good argument, and indeed we have seen at least one developer proposing to use noinput for all transactions to discourage address reuse. This was also mentioned at CoreDev [6]: > When [...] said he wanted to write a wallet that only used SIGHASH\_NOINPUT, > that was pause for concern. Some people might want to use SIGHASH\_NOINPUT as > a > way to cheapen or reduce the complexity of making a wallet > implementation. SIGHASH\_NOINPUT is from a purely procedural point of view > easier than doing a SIGHASH\_ALL, that's all I'm saying. So you're hashing > less. It's way faster. That concern has been brought to my attention and it's > something I can see. Do we want to avoid people being stupid and shooting > themselves and their customers in the foot? Or do we treat this as a special > case where you mark we're aware of how it should be used and we just try to > get that awareness out? Another issue that is sometimes brought up is that an external user may attempt to send funds to a script that was really part of a higher-level protocol. This leads to those funds becoming inaccessible unless you gather all the participants and sign off on those funds. I don't believe this is anything new, and if users really want to shoot themselves in the foot and send funds to random addresses they fish out of a blockexplorer there's little we can do. What we could do is make the scripts used internally in our protocols unaddressable (see output tagging below), removing this issue altogether. ## Chaperone signatures Chaperone signatures are signatures that ensure that there is no third-party malleability of transactions. The idea is to have an additional signature, that doesn't use noinput, or any of its variants, and therefore needs to be authored by one of the pubkeys in the output script, i.e., one or more of the participants of the contract the transaction belongs to. Concretely in eltoo we'd be using a shared key known to all participants in the eltoo instance, so any participant can sign an update to rebind it to the desired output. Chaperone signatures have a number of downsides however: - Additional size: both the public key and the signature actually need to be stored along with the real noinput signature, resulting in transfer, computational and storage overhead. We can't reuse the same pubkey from the noinput signature since that'd require access to the matching privkey which is what we want to get rid of using noinput in the first place. - Protocols can still simply use a globally known privkey, voiding the benefit of chaperone signatures, since third-parties can sign again. I argue that third-party