bips icon indicating copy to clipboard operation
bips copied to clipboard

[BIP174] Add PSBT_GLOBAL_XPUB_SIGNATURE to BIP

Open junderw opened this issue 5 years ago • 16 comments

As discussed on the mailing list: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-June/thread.html#start Search the page for the following subject: BIP174 extension proposal (Global Type: PSBT_GLOBAL_XPUB_SIGNATURE)

  • POR_COMMITMENT is also a separate BIP, but the encoding spec is listed here, so I am following suit.
  • Maybe there could be a way to offload the encoding descriptions into a "this key will represent the BIP number" etc. but for now no such spec exists. I may create a new BIP to cover the usage of this data for wallets to implement a whitelist for output verification.

Here is the description of the imagined use case:

  1. Securely verify the xpub of the warm / hot wallet.
  2. Using the airgap signing tool, sign the xpub with all cold keys.
  3. Upload the signature/xpub pairs to the online unsigned transaction generator.
  4. Include one keyval pair per coldkey/xpub pairing.
  5. When offline signing, if the wallet detects there is a global keyval XPUB_SIGNATURE with its pubkey in the key, it must verify that all outputs have BIP32_DERIVATION and that it can verify the outputs through the derivation, to the xpub, and to the signature.

The 0x01 global xpub entry allows HW wallet to verify change outputs.

This 0x02 global xpub signature will allow HW wallet to "verify" a whitelisted xpub that it has previously signed. Which is useful if HW wallets create some way for users to exchange xpubs securely. Instead of having to do the secure exchange every time, they would only need to do it once, then refer to the whitelist signature.

I was thinking of adding some extra data for a label which would also be signed, that way Trezor could say "Are you sure you want to pay Cindy?" instead of address verification.

Reducing address reuse is a two pronged motion of encouraging change address rotation (0x01) and encouraging people use new addresses every time (0x02 facilitates features that remove some friction)

Any comments are welcome.

Thanks.

junderw avatar Jul 10 '19 06:07 junderw

I should make a separate BIP for the signing scheme and how wallets should implement the verification of these signatures.

I will write up a draft and submit to the mailing list for review sometime in the next month or two.

junderw avatar Jul 23 '19 05:07 junderw

@achow101

luke-jr avatar Jul 23 '19 14:07 luke-jr

I was thinking of adding some extra data for a label which would also be signed, that way Trezor could say "Are you sure you want to pay Cindy?" instead of address verification.

I like the idea. All participants will need to agree on the labels, before the signing. The labels can also be used as/include 'serial numbers' or 'epoch words', as a way for xpub revocations - if the signing person sees that the label includes an old serial number or 'epoch word', she will refuse to sign.

dgpv avatar Jul 24 '19 12:07 dgpv

m/2042083607'/959190427'/1400854130'/990526201' (Magic number, randomly picked only for low likelyhood of overlapping).

Why not use 174' as the root for this path, using the number of this BIP, in accordance to BIP43 ? for example: m/174'/2' where 2 is the type of PSBT_GLOBAL_XPUB_SIGNATURE

If all subsequent fields, when there's a need to derive some keys, would use the same scheme m/174'/<field_code>'/... then there should be no overlaps

dgpv avatar Jul 24 '19 12:07 dgpv

As noted in the discussions about the global xpub field (0x01), the use of only 32 bits as the unique identifier is not necessarily unique enough due to collisions. Since this signature is really just for the offline signer to prove to itself that it has approved these keys for use in outputs, I think it would be better to use the full public key (not the xpub) to avoid collisions and make it easier for the signer to identify which signature is his.

One thing I'm not really a fan of is just specifying the keys and only sticking to single or multisig outputs. I would much rather this be more generic with the use of miniscript and output descriptors, but I suppose that would require miniscript to actually be finalized. That way you could have any arbitrary script for the outputs (or nested within the outputs as p2sh/p2wsh) and be effectively committing to the script directly instead of just the keys.

achow101 avatar Jul 25 '19 16:07 achow101

Since this signature is really just for the offline signer to prove to itself that it has approved these keys for use in outputs, I think it would be better to use the full public key (not the xpub) to avoid collisions and make it easier for the signer to identify which signature is his.

The signer can just ignore the entry if the signature does not match, and if there's no entries with matching signatures, give an error 'no matching signatures found' or something like that.

including a pubkey will make error messages more clear and debugging a little easier, at the price of some extra data included in PSBT.

On the other hand, this is not per-input/per-output field, so the savings will not be big. Including the pubkey makes sense in this case, in my opinion.

dgpv avatar Jul 25 '19 17:07 dgpv

I would much rather this be more generic with the use of miniscript and output descriptors

With pre-defined set of scripts in the signer configuration, the signer can process non-standard scripts, and can assign script-specific meaning for each key in the set.

That would require for the xpubs to be ordered by their script-specific meaning, and not alphabetically, or have some sort of tags that the signer can match against a script template. Pubkeys might play the role of these tags.

the signer would have a template like [op1, op2], <pubkey1>, [op3, op4], <pubkey2> [op5 ... opN], <pubkeyX> where ops are the opcodes(1) of the script and <pubkeyN> are the pubkeys of the xpubs. Signer, after it checked that xpub package + script template is signed with trusted key, and that the pubkeys in the script template match pubkeys of the xpubs, can replace the pubkeys in the template with the derived versions, and then check the result against the output scripts.

I am not sure if would be good to put this script template in PSBT itself, and complicate the processing for those who are not concerned with such cases. Most likely each particular usecase would have very few non-standard scripts, and the signers can be made to take those script templates as a configuration. If it is desireable to put the script templates inside PSBT, it can be put after a signature - if the signature field is larger than 64 bytes, then there's a script template there.

(1) actually, for the signer these opcodes would be just bytes, it does not necessary need to interpret them in any way

dgpv avatar Jul 25 '19 17:07 dgpv

I am not sure if would be good to put this script template in PSBT itself, and complicate the processing for those who are not concerned with such cases. Most likely each particular usecase would have very few non-standard scripts, and the signers can be made to take those script templates as a configuration. If it is desireable to put the script templates inside PSBT, it can be put after a signature - if the signature field is larger than 64 bytes, then there's a script template there.

This proposal is, in effect, already adding script templates. By specifying a m for multisigs or single key, we are already using some form of a template, albeit a very limited one. Since the signature should be committing to the script(s) being used, we should specify the script template that is being signed.

achow101 avatar Jul 25 '19 17:07 achow101

The idea is that to authorize a specific script, you don't need to specify full semantics of the script, you only need the positions of the pubkeys and the values of the bytes around the pubkeys.

You will not be able to specify other parameters of the script beside the pubkeys (1), but just the ability to match/substitute pubkeys would give a lot of flexibility.

(1) otherwise the parsing of the data will get overly complex, IMO - while xpubs have natural 'labels' -- their pubkeys, specifying other things like numbers would require assigning labels to them, etc.

dgpv avatar Jul 25 '19 17:07 dgpv

m=0 can mean that there's a script template after the signature. m=1 can mean that the script is standard single-sig (and no data after the signature) 1 < m <= 15 can mean the script is standard multi-sig (and no data after the signature) the (less-common) case of single-sig p2sh can be encoded with m=0 and a script template.

dgpv avatar Jul 25 '19 17:07 dgpv

Putting the script template after a signature will mean certain duplication (duplicating the pubkeys of xpubs), and also would prevent having different scripts with the same xpub set, within one PSBT (convoluted case, but consievable)

The script template can also be put into the field key itself.

The key would be

{0x02}|{signing_pubkey_fingerprint}|{script_template_including_xpubs}

script_template_inluding_xpubs would consist of a chunks of a script with embedded xpubs.

For example, for standard 2-of-3 multisig, it might consist of

<1>[0x02] 0x00 <xpub1_len>[xpub1] 0x00 <xpub2_len>[xpub2] 0x00 <xpub3_len>[xpub3] <2>[0x03, 0xAC]

where values in angle brackets are varints, values in square brackets are bytes of data (0xAC would be OP_CHECKMULTISIG). 0x00 is a marker indicating that the next chunk is xpub.

The checking code would parse this template into two array of data chunks - the script raw bytes, and xpubs.

data chunks of script raw bytes would be:

[0x02], [], [], [0x03, 0xAC] where [] are empty data chunks

and the xpubs would be [xpub1], [xpub2], [xpub3]

The checker will derive a pubkey from each xpub, yeliding [pub1],[pub2],[pub3], and then combine the data chunks and the derived pubkeys in-order, placing one pubkey after each script data chunk (includng the empty chunks):

[0x02], [pub1], [], [pub2], [], [pub3] [0x03, 0xAC]

After joining these chunks into a single byte array, the checker will get a data blob that should match the output's redeem/witness script.

This won't work for pubkey hashes - p2pkh and p2wpkh. They would need to be special-cased - for example, when the template consists of a single xpub, that would mean this is a special pubkey-hash case.

dgpv avatar Jul 25 '19 22:07 dgpv

  1. miniscript extended to include xpub awareness, a way to denote pubkey sorting, etc. could work.
  2. pubkey instead of fingerprint seems fine

However, one thing I do fear with using miniscript is that miniscript itself would probably need some work and discussion to include it here, and it does increase the scope of this modification significantly.

junderw avatar Jul 26 '19 01:07 junderw

However, one thing I do fear with using miniscript is that miniscript itself would probably need some work and discussion to include it here, and it does increase the scope of this modification significantly.

I agree. I'm not sure it's the right place to integrate it either (checking whether something is change or not doesn't really require understanding the script - perhaps a more level template matching is enough?).

sipa avatar Jul 26 '19 01:07 sipa

checking whether something is change

Just to clarify... this is not meant just for change. This is meant for a whitelist feature for airgapped / HW wallets to verify addresses so humans don't have to.

(ie. We send from cold to warm / hot all the time, but in order to make address verification easier we had to designate one address of each warm and hot as "the deposit address" even though both warm and hot were HD... since it made human verification of the send-to address easier... the solution we came up with was to have the cold keys sign a message saying "I trust this xpub in this configuration as our hot wallet" and before signing our offline signer will verify the signature and will not send unless it can verify the output script is derived from a whitelisted xpub/config... this way our cold -> warm and cold -> hot transactions don't gather in one address like most exchanges do.)

We also think if this type of whitelist feature is implemented into wallets like Trezor etc. Exchanges could offer a pairing feature which will give the user a "deposit xpub" and their wallet could just save the xpub internally in insecure storage (Dropbox integration in MyTrezor etc) and the HW wallet can verify the xpub each signature.

Overall, I think this sort of integration will be more successful and less wasteful than other types of pairing (ie BIP47) in the long run.

junderw avatar Jul 26 '19 01:07 junderw

(Although it could be used for change verification for multisig, since verifying from your xpub alone does not tell the airgapped machine whether a hacker replaced the other keys.)

junderw avatar Jul 26 '19 01:07 junderw

a way to denote pubkey sorting

for a simple byte-level-replace template presented above, bip67-style pubkey sorting is not applicable - in the general case, the script can have sorted pubkeys in one place, and some special pubkeys that are not sorted in another place (timelocked keys). To support sorting, the byte-level-replace template need to allow to express the notion of a 'list of pubkeys'. A bit more complicated, but not by much. If a varint after 0x00 is some small number that cannot be the length of xpub (less than 78, the data length of xpub including version bytes), it can be interpreted as the number of xpubs in a subsequent list. Having xpub lists would mean there's no need for the notion of 'empty data chunks' in the replacement logic that was presented above.

dgpv avatar Jul 26 '19 06:07 dgpv

@junderw are you still working on this and plan to update in response to BIP author feedback?

As there has been no activity in the past five years, let's close this for inactivity on or after 8 May 2024 if no further progress is seen.

jonatack avatar Apr 24 '24 15:04 jonatack

Since 174 is final, I think any new fields should be defined in separate BIPs that also provide test vectors and recommendations on the usage of the field. 174's table can be updated to list the fields, but the full specs of them should live in a separate BIP. At least this is the process that I've been using when adding new fields.

achow101 avatar Apr 24 '24 15:04 achow101

@junderw are you still working on this and plan to update in response to BIP author feedback?

As there has been no activity in the past five years, let's close this for inactivity on or after 8 May 2024 if no further progress is seen.

Nope. We ended up going with a proprietary standard that we use internally. I would be willing to participate on discussions in future related proposals.

junderw avatar Apr 24 '24 16:04 junderw

Thanks @junderw!

jonatack avatar Apr 24 '24 18:04 jonatack