Safety of committing only to transaction outputs

Safety of committing only to transaction outputs
2019-05-24 20:59 ` Jeremy
  
From: Johnson Lau @ 2019-05-23 20:54 UTC (permalink / raw)
  To: bitcoin-dev

[-- Attachment #1: Type: text/plain, Size: 2842 bytes --]

This is a meta-discussion for any approach that allows the witness committing to only transaction outputs, but not inputs.

We can already do the following things with the existing bitcoin script system:
* commit to both inputs and outputs: SIGHASH_ALL or SIGHASH_SINGLE, with optional SIGHASH_ANYONECANPAY
* commit to only inputs but not outputs: SIGHASH_NONE with optional SIGHASH_ANYONECANPAY
* not commit to any input nor output: not using any sigop; using a trivial private key; using the SIGHASH_SINGLE bug in legacy script

The last one is clearly unsafe as any relay/mining node may redirect the payment to any output it chooses. The witness/scriptSig is also replayable, so any future payment to this script will likely be swept immediately

SIGHASH_NONE with ANYONECANPAY also allows redirection of payment, but the signature is not replayable

But it’s quite obvious that not committing to outputs are inherently insecure

The existing system doesn’t allow committing only to outputs, and we now have 3 active proposals for this function:

1. CAT and CHECKSIGFROMSTACK (CSFS): https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-May/016946.html <https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-May/016946.html>
2. ANYPREVOUT (aka NOINPUT): https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-May/016929.html <https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-May/016929.html>
3. CHECKOUTPUTSHASHVERIFY (COHV): https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-May/016934.html <https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-May/016934.html>

With outputs committed, redirecting payment is not possible. On the other hand, not committing to any input means the witness is replayable without the consent of address owner. Whether replayability is acceptable is subject to controversy, but the ANYPREVOUT proposal fixes this by requiring a chaperone signature that commits to input. However, if the rationale for chaperone signature stands, it should be applicable to all proposals listed above.

A more generic approach is to always require a “safe" signature that commits to at least one input. However, this interacts poorly with the "unknown public key type” upgrade path described in bip-tapscript (https://github.com/sipa/bips/blob/bip-schnorr/bip-tapscript.mediawiki <https://github.com/sipa/bips/blob/bip-schnorr/bip-tapscript.mediawiki>), since it’d be a hardfork to turn an “unknown type sig” into a “safe sig”. But we could still use a new “leaf version” every time we introduce new sighash types, so we could have a new definition for “safe sig”. I expect this would be a rare event and it won’t consume more than a couple leaf versions. By the way, customised sighash policies could be done with CAT/CSFS.

[-- Attachment #2: Type: text/html, Size: 3626 bytes --]

 permalink raw reply	[|nested]
2019-05-23 20:54 [bitcoin-dev] Safety of committing only to transaction outputs Johnson Lau

  2019-05-25  7:53   ` Johnson Lau
  
From: Jeremy @ 2019-05-24 20:59 UTC (permalink / raw)
  To: Johnson Lau, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 4151 bytes --]

Hi Johnson,

As noted on the other thread, witness replay-ability can be helped by
salting the taproot key or the taproot leaf script at the last stage of a
congestion control tree.

I also think that chaperone signatures should be opt-in; there are cases
where we may not want them. OP_COSHV is compatible with an additional
checksig operation.

There are also other mechanisms that can improve the safety. Proposed below:

OP_CHECKINPUTSHASHVERIFY -- allow checking that the hash of the inputs is a
particular value. The top-level of a congestion control tree can check that
the inputs match the desired inputs for that spend, and default to
requiring N of N otherwise. This is replay proof! This is useful for other
applications too.

OP_CHECKFEEVERIFY -- allowing an explicit commitment to the exact amount of
fee limits replay to txns which were funded with the exact amount of the
prior. If there's a mismatch, an alternative branch can be used. This is a
generally useful mechanism, but means that transactions using it must have
all inputs/outputs set.

Best,

Jeremy
--
@JeremyRubin <https://twitter.com/JeremyRubin>
<https://twitter.com/JeremyRubin>


On Fri, May 24, 2019 at 7:40 AM Johnson Lau via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> This is a meta-discussion for any approach that allows the witness
> committing to only transaction outputs, but not inputs.
>
> We can already do the following things with the existing bitcoin script
> system:
> * commit to both inputs and outputs: SIGHASH_ALL or SIGHASH_SINGLE, with
> optional SIGHASH_ANYONECANPAY
> * commit to only inputs but not outputs: SIGHASH_NONE with optional
> SIGHASH_ANYONECANPAY
> * not commit to any input nor output: not using any sigop; using a trivial
> private key; using the SIGHASH_SINGLE bug in legacy script
>
> The last one is clearly unsafe as any relay/mining node may redirect the
> payment to any output it chooses. The witness/scriptSig is also replayable,
> so any future payment to this script will likely be swept immediately
>
> SIGHASH_NONE with ANYONECANPAY also allows redirection of payment, but the
> signature is not replayable
>
> But it’s quite obvious that not committing to outputs are inherently
> insecure
>
> The existing system doesn’t allow committing only to outputs, and we now
> have 3 active proposals for this function:
>
> 1. CAT and CHECKSIGFROMSTACK (CSFS):
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-May/016946.html
> 2. ANYPREVOUT (aka NOINPUT):
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-May/016929.html
> 3. CHECKOUTPUTSHASHVERIFY (COHV):
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-May/016934.html
>
> With outputs committed, redirecting payment is not possible. On the other
> hand, not committing to any input means the witness is replayable without
> the consent of address owner. Whether replayability is acceptable is
> subject to controversy, but the ANYPREVOUT proposal fixes this by requiring
> a chaperone signature that commits to input. However, if the rationale for
> chaperone signature stands, it should be applicable to all proposals listed
> above.
>
> A more generic approach is to always require a “safe" signature that
> commits to at least one input. However, this interacts poorly with the
> "unknown public key type” upgrade path described in bip-tapscript (
> https://github.com/sipa/bips/blob/bip-schnorr/bip-tapscript.mediawiki),
> since it’d be a hardfork to turn an “unknown type sig” into a “safe sig”.
> But we could still use a new “leaf version” every time we introduce new
> sighash types, so we could have a new definition for “safe sig”. I expect
> this would be a rare event and it won’t consume more than a couple leaf
> versions. By the way, customised sighash policies could be done with
> CAT/CSFS.
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>

[-- Attachment #2: Type: text/html, Size: 7027 bytes --]

 permalink raw reply	[|nested]
2019-05-24 20:59 ` Jeremy

  
From: Johnson Lau @ 2019-05-25  7:53 UTC ( / )
  To: Jeremy;  bitcoin-dev





> On 25 May 2019, at 4:59 AM, Jeremy <jlrubin@mit•edu> wrote:
> 
> Hi Johnson,
> 
> As noted on the other thread, witness replay-ability can be helped by salting the taproot key or the taproot leaf script at the last stage of a congestion control tree.
> 

The salt will be published when it is first spent. Salting won’t help if the address is reused.

> I also think that chaperone signatures should be opt-in; there are cases where we may not want them. OP_COSHV is compatible with an additional checksig operation.
> 
> There are also other mechanisms that can improve the safety. Proposed below:
> 
> OP_CHECKINPUTSHASHVERIFY -- allow checking that the hash of the inputs is a particular value. The top-level of a congestion control tree can check that the inputs match the desired inputs for that spend, and default to requiring N of N otherwise. This is replay proof! This is useful for other applications too.

It is circular dependent: the script has to commit to the txid, and the txid is a function of script


> 
> OP_CHECKFEEVERIFY -- allowing an explicit commitment to the exact amount of fee limits replay to txns which were funded with the exact amount of the prior. If there's a mismatch, an alternative branch can be used. This is a generally useful mechanism, but means that transactions using it must have all inputs/outputs set.
> 

This restricts replayability to input with same value, but is still replay-able, just like ANYPREVOUT committing to the input value


> Best,
> 
> Jeremy
> --
> @JeremyRubin <https://twitter.com/JeremyRubin> <https://twitter.com/JeremyRubin>