BIP-341: Committing to all scriptPubKeys in the signature message

BIP-341: Committing to all scriptPubKeys in the signature message
2020-05-01  6:57 ` Jeremy
                   ` (3 more replies)
  
From: Andrew Kozlik @ 2020-04-29 14:57 UTC (permalink / raw)
  To: Bitcoin Protocol Discussion

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

Hi everyone,

In the current draft of BIP-0341 [1] the signature message commits to the
scriptPubKey of the output being spent by the input. I propose that the
signature message should commit to the scriptPubKeys of *all* transaction
inputs.

In certain applications like CoinJoin, a wallet has to deal with
transactions containing external inputs. To calculate the actual amount
that the user is spending, the wallet needs to reliably determine for each
input whether it belongs to the wallet or not. Without such a mechanism an
adversary can fool the wallet into displaying incorrect information about
the amount being spent, which can result in theft of user funds [2].

In order to ascertain non-ownership of an input which is claimed to be
external, the wallet needs the scriptPubKey of the previous output spent by
this input. It must acquire the full transaction being spent and verify its
hash against that which is given in the outpoint. This is an obstacle in
the implementation of lightweight air-gapped wallets and hardware wallets
in general. If the signature message would commit to the scriptPubKeys of
all transaction inputs, then the wallet would only need to acquire the
scriptPubKey of the output being spent without having to acquire and verify
the hash of the entire previous transaction. If an attacker would provide
an incorrect scriptPubKey, then that would cause the wallet to generate an
invalid signature message.

Note that committing only to the scriptPubKey of the output being spent is
insufficient for this application, because the scriptPubKeys which are
needed to ascertain non-ownership of external inputs are precisely the ones
that would not be included in any of the signature messages produced by the
wallet.

The obvious way to implement this is to add another hash to the signature
message:
sha_scriptPubKeys (32): the SHA256 of the serialization of all
scriptPubKeys of the previous outputs spent by this transaction.

Cheers,
Andrew Kozlik

[1]
https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#common-signature-message
[2]
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-August/014843.html

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

 permalink raw reply	[|nested]
2020-05-01  6:57 ` 
                   ` 
  
From: Andrew Kozlik @ 2020-04-29 14:57 UTC (permalink / raw)
  To: Bitcoin Protocol Discussion

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

Hi everyone,

In the current draft of BIP-0341 [1] the signature message commits to the
scriptPubKey of the output being spent by the input. I propose that the
signature message should commit to the scriptPubKeys of *all* transaction
inputs.

In certain applications like CoinJoin, a wallet has to deal with
transactions containing external inputs. To calculate the actual amount
that the user is spending, the wallet needs to reliably determine for each
input whether it belongs to the wallet or not. Without such a mechanism an
adversary can fool the wallet into displaying incorrect information about
the amount being spent, which can result in theft of user funds [2].

In order to ascertain non-ownership of an input which is claimed to be
external, the wallet needs the scriptPubKey of the previous output spent by
this input. It must acquire the full transaction being spent and verify its
hash against that which is given in the outpoint. This is an obstacle in
the implementation of lightweight air-gapped wallets and hardware wallets
in general. If the signature message would commit to the scriptPubKeys of
all transaction inputs, then the wallet would only need to acquire the
scriptPubKey of the output being spent without having to acquire and verify
the hash of the entire previous transaction. If an attacker would provide
an incorrect scriptPubKey, then that would cause the wallet to generate an
invalid signature message.

Note that committing only to the scriptPubKey of the output being spent is
insufficient for this application, because the scriptPubKeys which are
needed to ascertain non-ownership of external inputs are precisely the ones
that would not be included in any of the signature messages produced by the
wallet.

The obvious way to implement this is to add another hash to the signature
message:
sha_scriptPubKeys (32): the SHA256 of the serialization of all
scriptPubKeys of the previous outputs spent by this transaction.

Cheers,
Andrew Kozlik

[1]
https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#common-signature-message
[2]
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-August/014843.html

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

 permalink raw reply	[|nested]
2020-05-01  6:57 ` Jeremy

  
From: Andrew Kozlik @ 2020-05-01  8:48 UTC (permalink / raw)
  To: Jeremy;  Bitcoin Protocol Discussion

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

Hi Jeremy,

What you are saying is correct and I am not disputing that there is
sufficient cryptographic commitment in the signature message. As I tried to
explain, my proposal is about avoiding the need for the metadata protocol
you speak of. Avoiding such a protocol has been a design goal in both
BIP-143 [1, 2] and BIP-341 [3, 4], because having to acquire each of the
transactions being spent in their entirety places a significant burden on
offline signing devices.

Cheers,
Andrew

[1]
https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#motivation
[2] https://bitcointalk.org/index.php?topic=181734.0
[3]
https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#cite_note-16
[4]
https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#cite_note-17

On Fri, May 1, 2020 at 8:56 AM Jeremy <jlrubin@mit•edu> wrote:

> Hi Andrew,
>
> If you use SIGHASH_ALL it shall sign the COutPoints of all inputs which
> commit to the scriptPubKeys of the txn.
>
> Thus the 341 hash doesn't need to sign any additional data.
>
> As a metadata protocol you can provide all input transactions to check the
> scriptPubKeys.
>
> Best,
>
> Jeremy
> --
> @JeremyRubin <https://twitter.com/JeremyRubin>
>
>
> On Thu, Apr 30, 2020 at 1:22 AM Andrew Kozlik via bitcoin-dev <
> bitcoin-dev@lists•linuxfoundation.org> wrote:
>
>> Hi everyone,
>>
>> In the current draft of BIP-0341 [1] the signature message commits to the
>> scriptPubKey of the output being spent by the input. I propose that the
>> signature message should commit to the scriptPubKeys of *all* transaction
>> inputs.
>>
>> In certain applications like CoinJoin, a wallet has to deal with
>> transactions containing external inputs. To calculate the actual amount
>> that the user is spending, the wallet needs to reliably determine for each
>> input whether it belongs to the wallet or not. Without such a mechanism an
>> adversary can fool the wallet into displaying incorrect information about
>> the amount being spent, which can result in theft of user funds [2].
>>
>> In order to ascertain non-ownership of an input which is claimed to be
>> external, the wallet needs the scriptPubKey of the previous output spent by
>> this input. It must acquire the full transaction being spent and verify its
>> hash against that which is given in the outpoint. This is an obstacle in
>> the implementation of lightweight air-gapped wallets and hardware wallets
>> in general. If the signature message would commit to the scriptPubKeys of
>> all transaction inputs, then the wallet would only need to acquire the
>> scriptPubKey of the output being spent without having to acquire and verify
>> the hash of the entire previous transaction. If an attacker would provide
>> an incorrect scriptPubKey, then that would cause the wallet to generate an
>> invalid signature message.
>>
>> Note that committing only to the scriptPubKey of the output being spent
>> is insufficient for this application, because the scriptPubKeys which are
>> needed to ascertain non-ownership of external inputs are precisely the ones
>> that would not be included in any of the signature messages produced by the
>> wallet.
>>
>> The obvious way to implement this is to add another hash to the signature
>> message:
>> sha_scriptPubKeys (32): the SHA256 of the serialization of all
>> scriptPubKeys of the previous outputs spent by this transaction.
>>
>> Cheers,
>> Andrew Kozlik
>>
>> [1]
>> https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#common-signature-message
>> [2]
>> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-August/014843.html
>> _______________________________________________
>> bitcoin-dev mailing list
>> bitcoin-dev@lists•linuxfoundation.org
>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>>
>

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

 permalink raw reply	[|nested]
* 
  2020-04-29 14:57 [bitcoin-dev] BIP-341: Committing to all scriptPubKeys in the signature message Andrew Kozlik

  2020-05-01  8:48   ` Andrew Kozlik
  2020-05-01 12:23 ` 
                   ` 
  3 siblings, 1 reply; 13+ messages in thread
From: Jeremy @ 2020-05-01  6:57 UTC (permalink / raw)
  To: Andrew Kozlik, Bitcoin Protocol Discussion

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

Hi Andrew,

If you use SIGHASH_ALL it shall sign the COutPoints of all inputs which
commit to the scriptPubKeys of the txn.

Thus the 341 hash doesn't need to sign any additional data.

As a metadata protocol you can provide all input transactions to check the
scriptPubKeys.

Best,

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


On Thu, Apr 30, 2020 at 1:22 AM Andrew Kozlik via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> Hi everyone,
>
> In the current draft of BIP-0341 [1] the signature message commits to the
> scriptPubKey of the output being spent by the input. I propose that the
> signature message should commit to the scriptPubKeys of *all* transaction
> inputs.
>
> In certain applications like CoinJoin, a wallet has to deal with
> transactions containing external inputs. To calculate the actual amount
> that the user is spending, the wallet needs to reliably determine for each
> input whether it belongs to the wallet or not. Without such a mechanism an
> adversary can fool the wallet into displaying incorrect information about
> the amount being spent, which can result in theft of user funds [2].
>
> In order to ascertain non-ownership of an input which is claimed to be
> external, the wallet needs the scriptPubKey of the previous output spent by
> this input. It must acquire the full transaction being spent and verify its
> hash against that which is given in the outpoint. This is an obstacle in
> the implementation of lightweight air-gapped wallets and hardware wallets
> in general. If the signature message would commit to the scriptPubKeys of
> all transaction inputs, then the wallet would only need to acquire the
> scriptPubKey of the output being spent without having to acquire and verify
> the hash of the entire previous transaction. If an attacker would provide
> an incorrect scriptPubKey, then that would cause the wallet to generate an
> invalid signature message.
>
> Note that committing only to the scriptPubKey of the output being spent is
> insufficient for this application, because the scriptPubKeys which are
> needed to ascertain non-ownership of external inputs are precisely the ones
> that would not be included in any of the signature messages produced by the
> wallet.
>
> The obvious way to implement this is to add another hash to the signature
> message:
> sha_scriptPubKeys (32): the SHA256 of the serialization of all
> scriptPubKeys of the previous outputs spent by this transaction.
>
> Cheers,
> Andrew Kozlik
>
> [1]
> https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#common-signature-message
> [2]
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-August/014843.html
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>

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

^ permalink raw reply	[|nested] 13+ messages in thread
2020-05-01 12:23 ` Russell O'Connor

  2020-05-02  4:35     ` Jeremy
  2020-05-02 14:26   ` Anthony Towns
  
From: Greg Sanders @ 2020-05-01 12:25 UTC (permalink / raw)
  To: Russell O'Connor, Bitcoin Protocol Discussion
  Cc: jonasd.nick, Pieter Wuille

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

For what it's worth this measure had been discussed as a lightweight way of
informing offline signers if inputs were segwit or not for malleability
analysis reasons. So there's at least a couple direct use-cases it seems.

On Fri, May 1, 2020, 8:23 AM Russell O'Connor via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> While I'm not entirely convinced yet that accertaining non-ownership of an
> input is a robust method of solving the problem here, I also see little
> reason not to amend BIP-341 as proposed. The ScriptPubKeys in question is
> already indirectly covered through the outpoints, so it is just a matter of
> optimization.  Furthermore in the consensus code, the ScriptPubKeys are
> part of the UTXO data set, and it is already being retrieved as part of the
> transaction checking process, so it is readily available.
>
> I'm not sure how much my opinion on the topic matters, but I did include
> this kind of functionality in my design for Simplicity on Elements, and I
> have been leaning towards adding this kind of functionality in my Bitcoin
> demo application of Simplicity.
>
> Regarding specifics, I personally think it would be better to keep the
> hashes of the ScriptPubKeys separate from the hashes of the input values.
> This way anyone only interested in input values does not need to wade
> through what are, in principle, arbitrarily long ScriptPubKeys in order to
> check the input values (which each fixed size).  To that end, I would also
> (and independently) propose separating the hashing of the output values
> from the output ScriptPubKeys in `sha_outputs` so again, applications
> interested only in summing the values of the outputs (for instance to
> compute fees) do not have to wade through those arbitrarily long
> ScriptPubKeys in the outputs.
>
> On Thu, Apr 30, 2020 at 4:22 AM Andrew Kozlik via bitcoin-dev <
> bitcoin-dev@lists•linuxfoundation.org> wrote:
>
>> Hi everyone,
>>
>> In the current draft of BIP-0341 [1] the signature message commits to the
>> scriptPubKey of the output being spent by the input. I propose that the
>> signature message should commit to the scriptPubKeys of *all* transaction
>> inputs.
>>
>> In certain applications like CoinJoin, a wallet has to deal with
>> transactions containing external inputs. To calculate the actual amount
>> that the user is spending, the wallet needs to reliably determine for each
>> input whether it belongs to the wallet or not. Without such a mechanism an
>> adversary can fool the wallet into displaying incorrect information about
>> the amount being spent, which can result in theft of user funds [2].
>>
>> In order to ascertain non-ownership of an input which is claimed to be
>> external, the wallet needs the scriptPubKey of the previous output spent by
>> this input. It must acquire the full transaction being spent and verify its
>> hash against that which is given in the outpoint. This is an obstacle in
>> the implementation of lightweight air-gapped wallets and hardware wallets
>> in general. If the signature message would commit to the scriptPubKeys of
>> all transaction inputs, then the wallet would only need to acquire the
>> scriptPubKey of the output being spent without having to acquire and verify
>> the hash of the entire previous transaction. If an attacker would provide
>> an incorrect scriptPubKey, then that would cause the wallet to generate an
>> invalid signature message.
>>
>> Note that committing only to the scriptPubKey of the output being spent
>> is insufficient for this application, because the scriptPubKeys which are
>> needed to ascertain non-ownership of external inputs are precisely the ones
>> that would not be included in any of the signature messages produced by the
>> wallet.
>>
>> The obvious way to implement this is to add another hash to the signature
>> message:
>> sha_scriptPubKeys (32): the SHA256 of the serialization of all
>> scriptPubKeys of the previous outputs spent by this transaction.
>>
>> Cheers,
>> Andrew Kozlik
>>
>> [1]
>> https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#common-signature-message
>> [2]
>> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-August/014843.html
>> _______________________________________________
>> bitcoin-dev mailing list
>> bitcoin-dev@lists•linuxfoundation.org
>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>>
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>

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

 permalink raw reply	[|nested]
2020-05-01 12:25   ` Greg Sanders

  
From: Jeremy @ 2020-05-02  4:35 UTC (permalink / raw)
  To: Greg Sanders, Bitcoin Protocol Discussion;  jonasd.nick, Pieter Wuille

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

At the end of the day I don't really care that much I just prefer something
that doesn't throw taproot in for another review cycle.

A side effect of this proposal is it would seem to make it not possible to
produce a signature for a transaction without having access to the inputs.
This is limiting for a number of cases where you don't care about that
data. There are a litany of use cases where you don't want to have
SIGHASH_ALL behavior, and having to sign the scriptpubkeys breaks that. So
at the very least it should respect other flags.

I also don't really understand the exact attack. So you submit a
transaction to the wallet asking them to sign input 10. They sign. They've
committed to the signature being bound to the specific COutpoint and input
index, so I don't see how they wouldn't be required to sign a second
signature with the other output too? Is there an attack you can describe
end-to-end relying on this behavior?

If you look at the TXID hash the vouts are one of the last fields
serialized. this makes it possible (at least, I think) to do a midstate
proof so that all you are providing is the hash midstate, and the relevant
transaction output,  the siblings after, and the locktime. So you get to
skip all the input data, the witness data, and most of the output data.

This sort of data can easily go into the proprietary use (maybe becoming
well defined if there's a standardization push) area in PSBT, so that
hardware devices can get easy access to it. All they have to do to verify
is to finalize the hash against that buffer and match to the correct input.


As an alternative proposal, I think you can just make a separate BIP for
some new sigash flags that can be reviewed separately from taproot. There's
a lot of value in investing in figuring out more granular controls over
what the signature hash is you sign, which may have some exciting
contracting implications!
--
@JeremyRubin <https://twitter.com/JeremyRubin>
<https://twitter.com/JeremyRubin>


On Fri, May 1, 2020 at 5:26 AM Greg Sanders via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> For what it's worth this measure had been discussed as a lightweight way
> of informing offline signers if inputs were segwit or not for malleability
> analysis reasons. So there's at least a couple direct use-cases it seems.
>
> On Fri, May 1, 2020, 8:23 AM Russell O'Connor via bitcoin-dev <
> bitcoin-dev@lists•linuxfoundation.org> wrote:
>
>> While I'm not entirely convinced yet that accertaining non-ownership of
>> an input is a robust method of solving the problem here, I also see little
>> reason not to amend BIP-341 as proposed. The ScriptPubKeys in question is
>> already indirectly covered through the outpoints, so it is just a matter of
>> optimization.  Furthermore in the consensus code, the ScriptPubKeys are
>> part of the UTXO data set, and it is already being retrieved as part of the
>> transaction checking process, so it is readily available.
>>
>> I'm not sure how much my opinion on the topic matters, but I did include
>> this kind of functionality in my design for Simplicity on Elements, and I
>> have been leaning towards adding this kind of functionality in my Bitcoin
>> demo application of Simplicity.
>>
>> Regarding specifics, I personally think it would be better to keep the
>> hashes of the ScriptPubKeys separate from the hashes of the input values.
>> This way anyone only interested in input values does not need to wade
>> through what are, in principle, arbitrarily long ScriptPubKeys in order to
>> check the input values (which each fixed size).  To that end, I would also
>> (and independently) propose separating the hashing of the output values
>> from the output ScriptPubKeys in `sha_outputs` so again, applications
>> interested only in summing the values of the outputs (for instance to
>> compute fees) do not have to wade through those arbitrarily long
>> ScriptPubKeys in the outputs.
>>
>> On Thu, Apr 30, 2020 at 4:22 AM Andrew Kozlik via bitcoin-dev <
>> bitcoin-dev@lists•linuxfoundation.org> wrote:
>>
>>> Hi everyone,
>>>
>>> In the current draft of BIP-0341 [1] the signature message commits to
>>> the scriptPubKey of the output being spent by the input. I propose that the
>>> signature message should commit to the scriptPubKeys of *all* transaction
>>> inputs.
>>>
>>> In certain applications like CoinJoin, a wallet has to deal with
>>> transactions containing external inputs. To calculate the actual amount
>>> that the user is spending, the wallet needs to reliably determine for each
>>> input whether it belongs to the wallet or not. Without such a mechanism an
>>> adversary can fool the wallet into displaying incorrect information about
>>> the amount being spent, which can result in theft of user funds [2].
>>>
>>> In order to ascertain non-ownership of an input which is claimed to be
>>> external, the wallet needs the scriptPubKey of the previous output spent by
>>> this input. It must acquire the full transaction being spent and verify its
>>> hash against that which is given in the outpoint. This is an obstacle in
>>> the implementation of lightweight air-gapped wallets and hardware wallets
>>> in general. If the signature message would commit to the scriptPubKeys of
>>> all transaction inputs, then the wallet would only need to acquire the
>>> scriptPubKey of the output being spent without having to acquire and verify
>>> the hash of the entire previous transaction. If an attacker would provide
>>> an incorrect scriptPubKey, then that would cause the wallet to generate an
>>> invalid signature message.
>>>
>>> Note that committing only to the scriptPubKey of the output being spent
>>> is insufficient for this application, because the scriptPubKeys which are
>>> needed to ascertain non-ownership of external inputs are precisely the ones
>>> that would not be included in any of the signature messages produced by the
>>> wallet.
>>>
>>> The obvious way to implement this is to add another hash to the
>>> signature message:
>>> sha_scriptPubKeys (32): the SHA256 of the serialization of all
>>> scriptPubKeys of the previous outputs spent by this transaction.
>>>
>>> Cheers,
>>> Andrew Kozlik
>>>
>>> [1]
>>> https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#common-signature-message
>>> [2]
>>> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-August/014843.html
>>> _______________________________________________
>>> bitcoin-dev mailing list
>>> bitcoin-dev@lists•linuxfoundation.org
>>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>>>
>> _______________________________________________
>> bitcoin-dev mailing list
>> bitcoin-dev@lists•linuxfoundation.org
>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>>
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>

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

 permalink raw reply	[|nested]
2020-04-29 14:57 [bitcoin-dev] BIP-341: Committing to all scriptPubKeys in the signature message Andrew Kozlik
  2020-05-01  6:57 ` Jeremy
  2020-05-01 12:23 ` Russell O'Connor

  2020-05-05 10:20 ` Jonas Nick
  
From: David A. Harding @ 2020-05-02 12:53 UTC (permalink / raw)
  To: Andrew Kozlik, Bitcoin Protocol Discussion

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

On Wed, Apr 29, 2020 at 04:57:46PM +0200, Andrew Kozlik via bitcoin-dev wrote:
> In order to ascertain non-ownership of an input which is claimed to be
> external, the wallet needs the scriptPubKey of the previous output spent by
> this input.

A wallet can easily check whether a scriptPubKey contais a specific
pubkey (as in P2PK/P2TR), but I think it's impractical for most wallets
to check whether a scriptPubKey contains any of the possible ~two
billion keys available in a specific BIP32 derivation path (and many
wallets natively support multiple paths).

It would seem to me that checking a list of scriptPubKeys for wallet
matches would require obtaining the BIP32 derivation paths for the
corresponding keys, which would have to be provided by a trusted data
source.  If you trust that source, you could just trust them to tell you
that none of the other inputs belong to your wallet.

Alternatively, there's the scheme described in the email you linked by
Greg Saunders (with the scheme co-attributed to Andrew Poelstra), which
seems reasonable to me.[1]  It's only downside (AFAICT) is that it
requires an extra one-way communication from a signing device to a
coordinator.  For a true offline signer, that can be annoying, but for
an automated hardware wallet participating in coinjoins or LN, that
doesn't seem too burdensome to me.

-Dave

[1] The scheme could be trivially tweaked to be compatible with BIP322
    generic signed messages, which is something that could become widely
    adopted (I hope) and so make supporting the scheme easier.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

 permalink raw reply	[|nested]
2020-05-01 12:23 ` Russell O'Connor
  2020-05-01 12:25   ` Greg Sanders

  2020-05-02 14:43     ` Russell O'Connor
  2020-05-02 21:15     ` Russell O'Connor
  
From: Anthony Towns @ 2020-05-02 14:26 UTC (permalink / raw)
  To: Russell O'Connor
  Cc: jonasd.nick, Bitcoin Protocol Discussion, Pieter Wuille

On Fri, May 01, 2020 at 08:23:07AM -0400, Russell O'Connor wrote:
> Regarding specifics, I personally think it would be better to keep the
> hashes of the ScriptPubKeys separate from the hashes of the input values.

I think Andrew's original suggestion achieves this:

>> The obvious way to implement this is to add another hash to the
>> signature message:
>>   sha_scriptPubKeys (32): the SHA256 of the serialization of all
>>   scriptPubKeys of the previous outputs spent by this
>>   transaction.

presumably with sha_scriptPubKeys' inclusion being conditional on
hash_type not matching ANYONECANPAY.

We could possibly also make the "scriptPubKey" field dependent on
hash_type matching ANYONECANPAY, making this not cost any more
in serialised bytes per signature.

This would basically mean we're committing to each component of the
UTXOs being spent:

  without ANYONECANPAY:
    sha_prevouts commits to the txid hashes and vout indexes (COutPoint)
    sha_amounts commits to the nValues (Coin.CTxOut.nValue)
    sha_scriptpubkeys commits to the scriptPubKey (Coin.CTxOut.scriptPubKey)

  with ANYONECANPAY it's the same but just for this input's prevout:
    outpoint
    amount
    scriptPubKey

except that we'd arguably still be missing:

    is this a coinbase output? (Coin.fCoinBase)
    what was the height of the coin? (Coin.nHeight)

Maybe committing to the coinbase flag would have some use, but committing
to the height would make it hard to chain unconfirmed spends, so at
least that part doesn't seem worth adding.

> I would also (and independently) propose
> separating the hashing of the output values from the output ScriptPubKeys in
> `sha_outputs` so again, applications interested only in summing the values of
> the outputs (for instance to compute fees) do not have to wade through those
> arbitrarily long ScriptPubKeys in the outputs.

If you didn't verify the output scriptPubKeys, you would *only* be able
to care about fees since you couldn't verify where any of the funds went?
And you'd only be able to say fees are "at least x", since they could be
more if one of the scriptPubKeys turned out to be OP_TRUE eg. That might
almost make sense for a transaction accelerator that's trying to increase
the fees; but only if you were doing it for someone else's transaction
(since otherwise you'd care about the output addresses) and only if you
were happy to not receive any change? Seems like a pretty weird use case?

There's some prior discussion on this topic at:

http://www.erisian.com.au/taproot-bip-review/log-2020-03-04.html
http://www.erisian.com.au/taproot-bip-review/log-2020-03-05.html

Cheers,
aj



 permalink raw reply	[|nested]
2020-05-02 14:26   ` Anthony Towns

  2020-05-02 21:15     ` Russell O'Connor
  
From: Russell O'Connor @ 2020-05-02 14:43 UTC (permalink / raw)
  To: Anthony Towns;  jonasd.nick, Bitcoin Protocol Discussion, Pieter Wuille

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

> If you didn't verify the output scriptPubKeys, you would *only* be able
> to care about fees since you couldn't verify where any of the funds went?
> And you'd only be able to say fees are "at least x", since they could be
> more if one of the scriptPubKeys turned out to be OP_TRUE eg. That might
> almost make sense for a transaction accelerator that's trying to increase
> the fees; but only if you were doing it for someone else's transaction
> (since otherwise you'd care about the output addresses) and only if you
> were happy to not receive any change? Seems like a pretty weird use case?
>

You are right of course.  I was thinking of cases where you only care about
where some of the outputs go but not all.  But of course, even in that case
you will need to wade through all of the output ScriptPubKeys anyways.
The current design shares the hashOuputs value with the one computed with
BIP-143, and that is a somewhat valuable property to keep.

Thanks for setting me straight.

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

 permalink raw reply	[|nested]
2020-05-02 14:26   ` Anthony Towns
  2020-05-02 14:43     ` Russell O'Connor

  2020-05-04 15:48       ` Andrew Kozlik
  
From: Russell O'Connor @ 2020-05-02 21:15 UTC (permalink / raw)
  To: Anthony Towns;  jonasd.nick, Bitcoin Protocol Discussion, Pieter Wuille

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

On Sat, May 2, 2020 at 10:26 AM Anthony Towns <aj@erisian•com.au> wrote:

>
> except that we'd arguably still be missing:
>
>     is this a coinbase output? (Coin.fCoinBase)
>     what was the height of the coin? (Coin.nHeight)
>
> Maybe committing to the coinbase flag would have some use, but committing
> to the height would make it hard to chain unconfirmed spends, so at
> least that part doesn't seem worth adding.
>

To add to this point, the height of the coin is something that is *not*
currently covered by any signature mode and including it would constitute a
change of an entirely different  caliber; a change that I would strongly
caution against for your above reason and more.

The coinbase output flag is currently covered by the signature as the
outpoint hash has the required information (its prevout index of 0xFFFFFFFF
is only legal in a coinbase transaction).  While I'm not particularly
enthusiastic about making it easier to distinguish coinbase outputs from
other outputs, and I worry a little about alternative designs for
implementing the Bitcoin protocol where this information is not so readily
available, I suppose I won't really oppose adding it.  However, I don't
think anyone is seriously proposing it.
-

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

 permalink raw reply	[|nested]
2020-05-02 21:15     ` Russell O'Connor

  
From: Andrew Kozlik @ 2020-05-04 15:48 UTC (permalink / raw)
  To: Russell O'Connor
  Cc: jonasd.nick, Bitcoin Protocol Discussion, Pieter Wuille

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

>
> A side effect of this proposal is it would seem to make it not possible to
> produce a signature for a transaction without having access to the inputs.
> This is limiting for a number of cases where you don't care about that
> data. There are a litany of use cases where you don't want to have
> SIGHASH_ALL behavior, and having to sign the scriptpubkeys breaks that. So
> at the very least it should respect other flags.
>

I agree, sha_scriptPubKeys should be included only if hash_type does not
match SIGHASH_ANYONECANPAY. I am also sympathetic to aj's idea of making
the scriptPubKey field dependent on hash_type matching SIGHASH_ANYONECANPAY.

I also don't really understand the exact attack. So you submit a
> transaction to the wallet asking them to sign input 10. They sign. They've
> committed to the signature being bound to the specific COutpoint and input
> index, so I don't see how they wouldn't be required to sign a second
> signature with the other output too? Is there an attack you can describe
> end-to-end relying on this behavior?
>

For example, in a CoinJoin transaction the attacker can construct a
transaction with two inputs (in1, in2) of identical value and two outputs
of identical value, one belonging to the user (user_out) and another
belonging to the attacker (attacker_out). If such a transaction is sent to
the hardware wallet twice with in1 marked as external the first time and
in2 marked as external the second time, then the hardware wallet will
display two signing requests to the user with spending amounts of in2 -
user_out and in1 - user_out respectively. The user will think that they are
signing two different CoinJoin transactions, while in reality they are
signing two different inputs to a single transaction and sending half of
the amount to the attacker.

As an alternative proposal, I think you can just make a separate BIP for
> some new sigash flags that can be reviewed separately from taproot. There's
> a lot of value in investing in figuring out more granular controls over
> what the signature hash is you sign, which may have some exciting
> contracting implications!
>

The proposal of adding sha_scriptPubKeys is just an optimization which is
not intended to change what the signature message is committing to. Thus I
don't see it as warranting a new sigash flag.

Alternatively, there's the scheme described in the email you linked by Greg
> Saunders (with the scheme co-attributed to Andrew Poelstra), which seems
> reasonable to me.[1]  It's only downside (AFAICT) is that it requires an
> extra one-way communication from a signing device to a coordinator.  For a
> true offline signer, that can be annoying, but for an automated hardware
> wallet participating in coinjoins or LN, that doesn't seem too burdensome
> to me.
>

Yes, I see this as the correct direction forward. Whatever the exact format
of the ownership proof will be, the proof will need to be signed by the
owner of the UTXO using BIP-0322 or something along those lines. So the
scriptPubKey is needed to verify that signature.

Cheers,
Andrew Kozlik

On Sat, May 2, 2020 at 11:16 PM Russell O'Connor <roconnor@blockstream•com>
wrote:

> On Sat, May 2, 2020 at 10:26 AM Anthony Towns <aj@erisian•com.au> wrote:
>
>>
>> except that we'd arguably still be missing:
>>
>>     is this a coinbase output? (Coin.fCoinBase)
>>     what was the height of the coin? (Coin.nHeight)
>>
>> Maybe committing to the coinbase flag would have some use, but committing
>> to the height would make it hard to chain unconfirmed spends, so at
>> least that part doesn't seem worth adding.
>>
>
> To add to this point, the height of the coin is something that is *not*
> currently covered by any signature mode and including it would constitute a
> change of an entirely different  caliber; a change that I would strongly
> caution against for your above reason and more.
>
> The coinbase output flag is currently covered by the signature as the
> outpoint hash has the required information (its prevout index of 0xFFFFFFFF
> is only legal in a coinbase transaction).  While I'm not particularly
> enthusiastic about making it easier to distinguish coinbase outputs from
> other outputs, and I worry a little about alternative designs for
> implementing the Bitcoin protocol where this information is not so readily
> available, I suppose I won't really oppose adding it.  However, I don't
> think anyone is seriously proposing it.
>
>    -
>
>

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

 permalink raw reply	[|nested]
2020-04-29 14:57 [bitcoin-dev] BIP-341: Committing to all scriptPubKeys in the signature message Andrew Kozlik
                   ` (2 preceding siblings ...)
  2020-05-02 12:53 ` David A. Harding

  2020-05-11 22:12   ` Pieter Wuille
  
From: Jonas Nick @ 2020-05-05 10:20 UTC (permalink / raw)
  To: bitcoin-dev

This is a reasonable suggestion. Committing to every spent scriptPubKey and
therefore every element of the TxOut instead of just the amount makes sense
conceptually. And it would be a small diff (~4 lines + rationale) compared to
the current bip-taproot version.

As far aas I understand, coinjoin with offline signers would be substantially
harder without this proposal. There is a WIP "SLIP" that helped me understand
how the Proof of Ownership would work [0]. For every input, the offline signing
device verifies a signature against the corresponding scriptPubKey. In order to
obtain the correct scriptPubKey, sending the whole input transaction to the
signing device is prohibitive when the available bandwidth is low (QR codes).
The idea of only sending the transaction midstate along with the rest of
to-be-hashed transaction data is an improvement, but still results in a lot of
data (whole vout and witness stacks). Adding a new sighash flag that marks
coinjoin transactions would be a step backwards fungibility-wise.

Thus, the same reasoning for for committing to the input values in the
transaction digest to allow compact fee proofs would similarly apply the
scriptPubKeys - with the only difference that coinjoins with offline signers are
less common.

The downsides of this proposal seem to be limited. It requires additional
review, but the BIP is only in the draft stage and should incorporate reasonable
feedback. It does not invite further scope creep because the full TxOut would be
already included. The costs to verifiers is only slightly increased using
Anthony Town's suggested sighash change. Availability of the scriptPubKeys for
signing devices does not seem to be an issue because the input amounts are
already required. And if all inputs belong to the signing device, there's no
additional data sent to the device.

[0] https://github.com/satoshilabs/slips/blob/slips-19-20-coinjoin-proofs/slip-0019.md


On 4/29/20 2:57 PM, Andrew Kozlik via bitcoin-dev wrote:
> Hi everyone,
> 
> In the current draft of BIP-0341 [1] the signature message commits to the
> scriptPubKey of the output being spent by the input. I propose that the
> signature message should commit to the scriptPubKeys of *all* transaction
> inputs.
> 
> In certain applications like CoinJoin, a wallet has to deal with
> transactions containing external inputs. To calculate the actual amount
> that the user is spending, the wallet needs to reliably determine for each
> input whether it belongs to the wallet or not. Without such a mechanism an
> adversary can fool the wallet into displaying incorrect information about
> the amount being spent, which can result in theft of user funds [2].
> 
> In order to ascertain non-ownership of an input which is claimed to be
> external, the wallet needs the scriptPubKey of the previous output spent by
> this input. It must acquire the full transaction being spent and verify its
> hash against that which is given in the outpoint. This is an obstacle in
> the implementation of lightweight air-gapped wallets and hardware wallets
> in general. If the signature message would commit to the scriptPubKeys of
> all transaction inputs, then the wallet would only need to acquire the
> scriptPubKey of the output being spent without having to acquire and verify
> the hash of the entire previous transaction. If an attacker would provide
> an incorrect scriptPubKey, then that would cause the wallet to generate an
> invalid signature message.
> 
> Note that committing only to the scriptPubKey of the output being spent is
> insufficient for this application, because the scriptPubKeys which are
> needed to ascertain non-ownership of external inputs are precisely the ones
> that would not be included in any of the signature messages produced by the
> wallet.
> 
> The obvious way to implement this is to add another hash to the signature
> message:
> sha_scriptPubKeys (32): the SHA256 of the serialization of all
> scriptPubKeys of the previous outputs spent by this transaction.
> 
> Cheers,
> Andrew Kozlik
> 
> [1]
> https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#common-signature-message
> [2]
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-August/014843.html
> 
> 
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
> 


 permalink raw reply	[|nested]
2020-05-05 10:20 ` Jonas Nick

  
From: Pieter Wuille @ 2020-05-11 22:12 UTC ( / )
  To: Bitcoin Protocol Discussion

Hi all,

On Tuesday, May 5, 2020 3:20 AM, Jonas Nick via bitcoin-dev <bitcoin-dev@lists•linuxfoundation.org> wrote:

> This is a reasonable suggestion. Committing to every spent scriptPubKey and
> therefore every element of the TxOut instead of just the amount makes sense
> conceptually. And it would be a small diff (~4 lines + rationale) compared to
> the current bip-taproot version.

I agree.

There have been several steps so far towards making it possible for signers to determine whether they can safely sign with just O(1) information per input. This was initially attempted in BIP141 (by committing to spent input, to thwart the ability to lie about fees to ofline signers), and is improved in the current BIP341.

I think the CoinJoin + offline signer model indeed shows that is still incomplete, as it is yet another example where a signer may need to be provided with the entire creating transaction, which would be very unfortunate.

It's also counter to the model proposed by BIP147 (PSBT) workflows: the assumption is effectively already that it is sufficient to provide signers with just amount + scriptPubKey of the spent outputs. It feels very natural that signatures then indeed also need to commit to all that data; otherwise there should be ways that this information can be undetectably wrong.

AJ's approach seems great. It means not increasing the per-signature hashing, while retaining the ability to cache information across BIP141/BIP341.

As for coinbaseness and height: these are indeed also things currently kept track of in the UTXO set, but I don't think any signer is using this information to determine whether to sign or not (which I think is the minimum requirement for it to be included in a signature hash, see above). Signing height would cripple the ability to spend unconfirmed outputs, or force signers to reveal they're doing so (if done through a separate sighash flag) - both of which would be undesirable. That leaves coinbaseness, but I think the utility is very low.

The only downside is that this potentially slows down review, but I agree with earlier comments that it's hard to see how this would hurt. I also think it's important to get these things right from the start. Many things inside BIP341/BIP342 are extensible with future softforks, but signature hashes for key-path spends is not one of them (the set of potential signature hash semantics must be committed to directly by the output, so changing them requires a new output type - which would be highly unfortunate for fungibility reasons).

Thus, unless there are objections, I'd like to go through with this and make the suggested changes.

Thoughts?

--
Pieter