-
Notifications
You must be signed in to change notification settings - Fork 5.7k
bip174: add global xpub field #784
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
+1 would implement |
Just to clarify
Should means that it's a recommendation and I still can use non-hardened derivation index, right? If so, +1 from my side. |
Yes. It is a recommendation, not a requirement. |
This is a somewhat confusing sentence. At a minimum, the word highest seems ambiguous. Perhaps an example could also be provided to clarify? |
I think we're going to need a different 'key' for this field. Here are three xpub's with the same fingerprint, and if BIP45 was being used, they would all have the same derivation (
[Aside: All share As for a better key value to use, I think an index (32-bits, ascending) would be enough, or we could use the public key (33 bytes, compressed only). IMHO, the key derivation path is not useful information since I cannot verify it, but maybe it's useful to detect innocent errors between the global section and paths in the ins/outs. In conclusion, I propose we switch from using the (extended key fingerprint + key path) to just an (index + key path). Must start at zero, no gaps and so on. |
I don't think requiring it to start at 0 and increment is really needed. We just need some fixed sized nonce that makes it unique. Also, I think it would be worth keeping the extended key fingerprint as that would allow for efficient lookups in the case where fingerprints don't collide. So the key would be nonce + fingerprint + path. I would prefer something else that can be used for uniqueness that would be known from the child pubkey, although I can't think of one right now. |
|
We could use the fingerprint of the key itself as a nonce. It's a bit redundant as it can be calculated from the xpub, but sometimes people don't know the root fingerprint and use the fingerprint of the last hardened key instead. So it may help to do quick lookups in such cases. |
I don't understand the reasoning. Because If |
It is not specific to multisig wallets actually. In general the wallet Also, what if the attacker replace the xpubof |
I can only comment on the Coldcard. We will support out-of-band methods to setup the xpubs involved in a multisig wallet, and also support the PSBT globals section. However there is a setting, called "Trust PSBT" with values:
When the XPUB data is not provided in the PSBT, regardless of the above, we require the appropriate multisig wallet to already exist on the Coldcard. Default is to 'Offer' unless a multisig wallet already exists, otherwise 'Verify'. |
Stop me if I miss something, but if Coldcard does not know the xpubs out of band, then what prevent the attacker to put his own xpub in the PSBT global section? I don't understand how this proposal fix the problem it is aiming to solve. |
In my opinion, hardware wallets must track the M/N and xpubs for multisig wallets with which they are involved or else, yes, they will be vulnerable to changes to the PSBT. How that is stored/setup is out of scope for BIP-174 (IMHO) but with this addition to the PSBT format, HW wallets can implement a "trust on first use" model, which has proven to be very useful security model (example: SSH server pub keys). |
@peter-conalgo good point. I think that @achow101 should clearly clarify this. The "trust on first use" is the only reason for this global xpub field. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only reason to use this global xpub field is for trust on first use
scenario where one wants to initialize the multisig wallet by signing the first PSBT. Else this field must be disregarded, as an attacker could very well put his own xpub.
@peter-conalgo I think that this global xpub is not even useful in trust on first use scenario. Because you can't even know about |
@NicolasDorier Coldcard takes M/N from the first multisig input of the associated transaction. |
@NicolasDorier, why is it the only reason? |
@stepansnigirev because the attacker E can put his own xpub in this global field, and the HW has no way to know. |
I like @peter-conalgo approach as this technique can be used as a very good UX to initialize wallets with more complex scripts without changing or adding PSBT fields later. |
So there is an xpub E from the attacker, it is not in the input but it is in the output => the address is not a change address and we need to show to the user that keys are different. Can you describe the attack you are thinking of in more details? I don't understand. |
|
A see that A and B are in input 1 => OK |
@stepansnigirev I don't believe about a stateless wallet which can't save in its memory the multi sig xpubs and |
I am not against this BIP, but I think it is created for the wrong reason. And if HW wallet use this feature the wrong way here the problems:
|
@NicolasDorier , change address is a change address if ALL keys in inputs and change output are the same. As (A,B) != (A,E) the second output is not a change address => HW will show it as spending output. Software that doesn't use xpubs will be able to use hardware wallets with single keys (without multisig) or with multisig but the change address will be shown to the user as a normal spending address if the hardware wallet doesn't store the xpubs. It HW stores xpubs - no problem, HW can ignore this field. At the moment the fact that we are missing xpubs field in the standard makes PSBT incompatible with Trezor wallet. They don't use PSBT but they rely on xpubs. |
@stepansnigirev so in this case it means:
|
@stepansnigirev if the HW does not understand PSBT natively like coldcard does, then the responsibility to tell what is the change or not goes to the component interfacing with the HW (like HWI). This component should pass some hints to the HW to tell which input and output to sign explicitly, which can be done outside of the PSBT spec. (this make sense because which input and output to sign for a wallet is not known by the PSBT creator) |
Datapoint: Coldcard will reject any redeem script that doesn't have sorted public keys (per BIP-67), inputs or outputs. Aside: We are putting the finishing touches on Coldcard's multisig support (see branch 'multisig'), and we already support the global XPUB field as originally proposed (with 32bit-nonce addition). Also, psbt_dump will parse and display them. @achow101 Could you add the nonce from upthread into the diff which we are discussing? My comment as a hardware wallet maker: to be safe the Coldcard has to understand precisely what we are signing. Therefore, duplicating any value that can be derived from the transaction itself is not helpful. It just becomes another value that we have to double-check. I like the original proposal as it provides just the information we need and no more. The proposal is sufficient for multisig, and IMHO, other transaction types, like Coinjoin, can add additional metadata to appropriate PSBT sections when we understand what they need to be safely signed. |
Ok then if you insist on making this global xpub field, at list, in the BIP, describe how a HW should behave precisely, if I understand:
|
I think that is completely out of scope for this BIP. It is not a specification of how hardware wallets should behave, it is a description of a data structure and the abstract workflow around it. |
@peter-conalgo I don't really like the nonce idea. Do you really think that collisions will really be a problem? The probability of having a master key fingerprint colliding within a PSBT is very low and in many other places, the master fingerprint is being used for uniqueness. |
Collisions with a 32-bit truncated-hash can be legit---it's only mildly bad luck by my standards. I don't see any other spots in BIP-174 where BIP32 path is the key, so I think this is the only area with this potential problem. Of course the various implementations will still fall over, but that's not a concern when defining the file format. We just have to make it possible to create a conforming implementation that handles all cases. Alternatives to the 32-bit nonce idea:
The problem I see with (1) and (2) is they won't get implemented, since they only happen in this special case. Most coders are happy with "works most of the time"... The nonce idea, and (3) force implementations to do it right. |
I prefer a solution forcing implementation to do it right. Else we will end up with people having money locked unexpectedly (unless they are wizards). |
What if we flip key and value? Having xpub as a key and derivation path as a value would prevent collisions. It's harder to do lookups though. |
I've updated the changes as was discussed at Breaking Bitcoin. The key is changed to be the xpub and the value is the derivation path. The depth of the provided derivation path must match the depth specified in the xpub. I've also added a section on how change detection would work with this. |
Looks good to me. |
Love it.
|
bip-0174.mediawiki
Outdated
|
||
For outputs involving multiple keys, a signer can first examine the inputs that it is signing. It should determine the general pattern of the script. | ||
For example, it can observe the redeemScript or witnessScript and determine whether it is multisig. | ||
If it is multisig, it should determine how many keys there are, in what position they are, and how many signers are needed in order for the input to be valid. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure the pub keys are ordered (BIP-67) else there will be problems of changes not detected by the wallet software.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. Enforcing multisig rules is out of scope for PSBT. This section is just to clarify how xpubs can be used for change detection. It isn't a description of what must be done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then remove in what position they are
because it assumes there is no ordering...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you specify in what position they are
it means that if there is an input with 2 PubA PubB MULTISIG
, then a change with 2 PubB' PubA' MULTISIG
should not be considered a change. Which mean that BIP67 would be incompatible with what you are saying, not merely out of scope, but incompatible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Position matters in some cases. We could add an example:
If A
, B
and C
are xpubs, ai
, bi
, ci
are keys derived from them and input uses a spending script with condition (a1 or b1) and c1
then output with condition (a2 or b2) and c2
or (b2 or a2) and c2
can be considered as change, but (a2 or c2) and b2
should not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stepansnigirev no, if you follow BIP67, then (a2 or c2) and b2
SHOULD be considered as change and not (b2 or a2) and c2
.
@stepansnigirev I am concerned only about multi sigs expressions. in the form of 2 A B 2 MULTISIG
@achow101 please remove the in what position they are
this will really cause problem in the future. Either you force implementer to check BIP67, or you don't imply they can check the order.
If you say they can check the order, and that they do, we will have bunch of incompatibilities accross HW and wallet interfaces. This is an disincentive to use BIP67, which is bad: people using BIP67 will be incompatible with HW which check the order.
The whole point of PSBT is to nail down incompatibilities, not add more of them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@NicolasDorier The BIP is not saying anything about what signers must check. That whole section is about constructing the policy represented by a script, i.e. the descriptor. Public key order is something that can be part of such constructions. At no point does it say that signers must check that or that public key order must be part of the policy.
Incompatibilities between signers is to be expected because they will all probably have different signing policies. Specifying those signing policies is out of scope for this BIP. PSBT is an interchange format, not a description of how a wallet should work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At no point does it say that signers must check that or that public key order must be part of the policy.
I agree, but it does, and that's my problem! it says that the public key order must be part of the policy:
If it is multisig, it should determine how many keys there are, in what position they are
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about you read and review the current text instead of an outdated one? It no longer says that!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed! The updated one seems OK to me.
@luke-jr This looks to be RTM. |
@luke-jr This can be merged. |
@achow101 do you have a test vector somewhere? |
Here is what I get:
|
So, after properly reading this entire thread, I've come to realize that Cold-card is trying to implement a feature similar to my other global data point proposal #801 However, instead of internalizing the whitelist data (via an HW internal state combined with Trust on First Seen) my proposal is to create a signature with a specific private key of the HW seed, and have that signature passed in through the PSBT... meaning the wallet does not need an internal state. My proposal also seems to deal with a few of @NicolasDorier concerns... (though some are still existing) |
… xpub fields 8152117 Merge global xpubs in joinpsbts and combinepsbts (Andrew Chow) d8043dd Add global xpub test vectors from BIP (Andrew Chow) 35670df Add global_xpubs to decodepsbt (Andrew Chow) 9038485 Implement serializations for PSBT_GLOBAL_XPUB (Andrew Chow) c5c63b8 Implement operator< for KeyOriginInfo and CExtPubKey (Andrew Chow) d3dbb16 Separate individual HD Keypath serialization into separate functions (Andrew Chow) a69332f Store version bytes and be able to serialize them in CExtPubKey (Andrew Chow) 5fdaf6a moveonly: Move (Un)Serialize(To/From)Vector, (De)SerializeHDKeypaths to psbt module (Andrew Chow) 94065cc Test for proprietary field (Andrew Chow) a4cf810 Output proprietary type info in decodepsbt (Andrew Chow) aebe758 Implement PSBT proprietary type (Andrew Chow) 10ba0b5 Output psbt version in decodepsbt (Andrew Chow) df84fa9 Add GetVersion helper to PSBT (Andrew Chow) c3eb416 Implement PSBT versions (Andrew Chow) 3235847 Types are compact size uints (Andrew Chow) Pull request description: Implements the changes to BIP 174 proposed in bitcoin/bips#849 and bitcoin/bips#784 Implements `PSBT_GLOBAL_VERSION`, `PSBT_GLOBAL_PROPRIETARY`, `PSBT_IN_PROPRIETARY`, `PSBT_OUT_PROPRIETARY`, and `PSBT_GLOBAL_XPUB`. The `PSBT_GLOBAL_XPUB` changes are merged in from #16463. Also includes the test vectors added to BIP 174 for these fields. A number of additional changes to keypath and xpub serialization are made to support `PSBT_GLOBAL_XPUB`. ACKs for top commit: laanwj: Code review ACK 8152117 Tree-SHA512: bd71c3f26030fc23824e76a30d3d346a753e1db224ecee163d6813348feb52d3f4cf4e739a4699e2cff381197ce2a7ea4a92a054f2c3e1db579e91e92a0945e0
…elds 8152117 Merge global xpubs in joinpsbts and combinepsbts (Andrew Chow) d8043dd Add global xpub test vectors from BIP (Andrew Chow) 35670df Add global_xpubs to decodepsbt (Andrew Chow) 9038485 Implement serializations for PSBT_GLOBAL_XPUB (Andrew Chow) c5c63b8 Implement operator< for KeyOriginInfo and CExtPubKey (Andrew Chow) d3dbb16 Separate individual HD Keypath serialization into separate functions (Andrew Chow) a69332f Store version bytes and be able to serialize them in CExtPubKey (Andrew Chow) 5fdaf6a moveonly: Move (Un)Serialize(To/From)Vector, (De)SerializeHDKeypaths to psbt module (Andrew Chow) 94065cc Test for proprietary field (Andrew Chow) a4cf810 Output proprietary type info in decodepsbt (Andrew Chow) aebe758 Implement PSBT proprietary type (Andrew Chow) 10ba0b5 Output psbt version in decodepsbt (Andrew Chow) df84fa9 Add GetVersion helper to PSBT (Andrew Chow) c3eb416 Implement PSBT versions (Andrew Chow) 3235847 Types are compact size uints (Andrew Chow) Pull request description: Implements the changes to BIP 174 proposed in bitcoin/bips#849 and bitcoin/bips#784 Implements `PSBT_GLOBAL_VERSION`, `PSBT_GLOBAL_PROPRIETARY`, `PSBT_IN_PROPRIETARY`, `PSBT_OUT_PROPRIETARY`, and `PSBT_GLOBAL_XPUB`. The `PSBT_GLOBAL_XPUB` changes are merged in from bitcoin#16463. Also includes the test vectors added to BIP 174 for these fields. A number of additional changes to keypath and xpub serialization are made to support `PSBT_GLOBAL_XPUB`. ACKs for top commit: laanwj: Code review ACK 8152117 Tree-SHA512: bd71c3f26030fc23824e76a30d3d346a753e1db224ecee163d6813348feb52d3f4cf4e739a4699e2cff381197ce2a7ea4a92a054f2c3e1db579e91e92a0945e0
… xpub fields 4ca1ec3 Merge global xpubs in joinpsbts and combinepsbts (Andrew Chow) fed4bd5 Add global xpub test vectors from BIP (Andrew Chow) 958a2f7 Add global_xpubs to decodepsbt (Andrew Chow) feb2cae Implement serializations for PSBT_GLOBAL_XPUB (Andrew Chow) 9a017e8 Implement operator< for KeyOriginInfo and CExtPubKey (Andrew Chow) ff65018 Separate individual HD Keypath serialization into separate functions (Andrew Chow) 7e14f42 Store version bytes and be able to serialize them in CExtPubKey (Andrew Chow) ddd0620 moveonly: Move (Un)Serialize(To/From)Vector, (De)SerializeHDKeypaths to psbt module (Andrew Chow) e436636 Test for proprietary field (Andrew Chow) 624cd15 Output proprietary type info in decodepsbt (Andrew Chow) eafafc3 Implement PSBT proprietary type (Andrew Chow) 736907a Output psbt version in decodepsbt (Andrew Chow) 742a811 Add GetVersion helper to PSBT (Andrew Chow) 3355928 Implement PSBT versions (Andrew Chow) 6a76e80 Types are compact size uints (Andrew Chow) Pull request description: Implements the changes to BIP 174 proposed in bitcoin/bips#849 and bitcoin/bips#784 Implements `PSBT_GLOBAL_VERSION`, `PSBT_GLOBAL_PROPRIETARY`, `PSBT_IN_PROPRIETARY`, `PSBT_OUT_PROPRIETARY`, and `PSBT_GLOBAL_XPUB`. The `PSBT_GLOBAL_XPUB` changes are merged in from #16463. Also includes the test vectors added to BIP 174 for these fields. A number of additional changes to keypath and xpub serialization are made to support `PSBT_GLOBAL_XPUB`. ACKs for top commit: laanwj: Code review ACK 4ca1ec3 Tree-SHA512: bd71c3f26030fc23824e76a30d3d346a753e1db224ecee163d6813348feb52d3f4cf4e739a4699e2cff381197ce2a7ea4a92a054f2c3e1db579e91e92a0945e0
… xpub fields 8152117 Merge global xpubs in joinpsbts and combinepsbts (Andrew Chow) d8043dd Add global xpub test vectors from BIP (Andrew Chow) 35670df Add global_xpubs to decodepsbt (Andrew Chow) 9038485 Implement serializations for PSBT_GLOBAL_XPUB (Andrew Chow) c5c63b8 Implement operator< for KeyOriginInfo and CExtPubKey (Andrew Chow) d3dbb16 Separate individual HD Keypath serialization into separate functions (Andrew Chow) a69332f Store version bytes and be able to serialize them in CExtPubKey (Andrew Chow) 5fdaf6a moveonly: Move (Un)Serialize(To/From)Vector, (De)SerializeHDKeypaths to psbt module (Andrew Chow) 94065cc Test for proprietary field (Andrew Chow) a4cf810 Output proprietary type info in decodepsbt (Andrew Chow) aebe758 Implement PSBT proprietary type (Andrew Chow) 10ba0b5 Output psbt version in decodepsbt (Andrew Chow) df84fa9 Add GetVersion helper to PSBT (Andrew Chow) c3eb416 Implement PSBT versions (Andrew Chow) 3235847 Types are compact size uints (Andrew Chow) Pull request description: Implements the changes to BIP 174 proposed in bitcoin/bips#849 and bitcoin/bips#784 Implements `PSBT_GLOBAL_VERSION`, `PSBT_GLOBAL_PROPRIETARY`, `PSBT_IN_PROPRIETARY`, `PSBT_OUT_PROPRIETARY`, and `PSBT_GLOBAL_XPUB`. The `PSBT_GLOBAL_XPUB` changes are merged in from #16463. Also includes the test vectors added to BIP 174 for these fields. A number of additional changes to keypath and xpub serialization are made to support `PSBT_GLOBAL_XPUB`. ACKs for top commit: laanwj: Code review ACK 8152117 Tree-SHA512: bd71c3f26030fc23824e76a30d3d346a753e1db224ecee163d6813348feb52d3f4cf4e739a4699e2cff381197ce2a7ea4a92a054f2c3e1db579e91e92a0945e0
Adds a global type for xpubs as discussed on the bitcoin-dev mailing list: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-April/016894.html