BIP: TBD Layer: Applications Title: PSBT Version 3 Author: Andrew Toth <andrewstoth@gmail.com> josibake <josibake@protonmail.com> Comments-Summary: No comments yet. Comments-URI: TBD Status: Draft Type: Standards Track Created: 2024-05-14 License: BSD-2-Clause
This document proposes a third version of the Partially Signed Bitcoin Transaction format described in BIP 174 and BIP 370 which adds support for sending to silent payments as described in BIP352.
This BIP is licensed under the 2-clause BSD license.
Partially Signed Bitcoin Transaction Version 2 as described in BIP 370 is not compatible with sending to silent payments as described in BIP352. In particular, the output script of a silent payment cannot be computed until after all transaction inputs have been added. There also must not be any inputs that use SIGHASH_ANYONECANPAY or have a scriptPubKey with Segwit version > 1. PSBT Version 3 is intended to rectify this problem.
PSBT Version 3 (PSBTv3) specifies new fields, new field inclusion/exclusion requirements, and additional bits in an existing bitfield field.
PSBT_GLOBAL_TX_MODIFIABLE may be included in PSBTv3, in which case the following bits are used: Bit 3 is the Silent Payments Modifiable Flag, set to 1 to indicate whether silent payment outputs may be added. Bit 4 is the Has Silent Payments Flag, set to 1 to indicate if any silent payment outputs have been added. Bit 4 indicates that the Constructor may not add any inputs either with SIGHASH_ANYONECANPAY or spending an output with Segwit version > 1 (TODO: How does constructor know this?).
PSBT_OUT_SCRIPT is modified to be optional for outputs in PSBT Version 3. If this field is not included in the output, then the field PSBT_OUT_SILENT_PAYMENT_CODE must be included.
The new per-output types for PSBT Version 3 are defined as follows:
Name | <keytype> | <keydata> | <keydata> Description | <valuedata> | <valuedata> Description | Versions Requiring Inclusion | Versions Requiring Exclusion | Versions Allowing Inclusion |
---|---|---|---|---|---|---|---|---|
Silent Payment Data | PSBT_OUT_SILENT_PAYMENT_CODE = 0x08 | None | No key data | <67-byte data> | 67 bytes representing the Silent Payment Code. The first byte is the silent payment version. The next 33 bytes are the scan public key, and the following 33 bytes are the spend public key. | 0, 2 | 3 | |
Silent Payment DLEQ Proof | PSBT_OUT_SILENT_PAYMENT_DLEQ_PROOF = 0x09 | <compact size uint number of indexes> <32-bit little endian uint index>* | The set of indexes of the inputs that this proof covers. | <967-byte proof> | A proof generated by a Signer used by other entities to generate and verify the output script for the silent payment code. Used by entities which don't have access to all private keys used in the shared secret deriviation. | 0, 2 | 3 |
PSBTv3s can be uniquely identified the same way as PSBTv2s, except when including silent payment outputs. For PSBTv3, all silent payment outputs must use the PSBT_OUT_SILENT_PAYMENT_CODE instead of PSBT_OUT_SCRIPT as the output script when creating the unsigned transaction used for unique identification.
PSBTv3 modifies some existing roles.
The Creator must do everything that is done in PSBTv2, except that the PSBT version is set to 3.
Additionally to PSBTv2, the Creator must also set the Silent Payments Modifiable and Has Silent Payments flags appropriately.
All rules must be followed from PSBTv2 for this role, with the following exception: When an output is added, it must have either PSBT_OUT_SCRIPT or PSBT_OUT_SILENT_PAYMENT_CODE set.
Additionally to PSBTv2, the Constructor must also follow the following rules:
Inputs spending an output with Segwit version > 1 (TODO: How does constructor know this?) may only be added if the Has Silent Payments flag is False. Outputs with PSBT_OUT_SILENT_PAYMENT_CODE set may only be added if the Silent Payments Modifiable flag is True.
If an input is added that spends an output with Segwit version > 1 (TODO: How does constructor know this?), the Silent Payments Modifiable Flag must be set to False. If an output is added with PSBT_OUT_SILENT_PAYMENT_CODE, the Has Silent Payments Flag must be set to True.
For PSBTv3, the Updater must follow these additional rules: The PSBT_IN_SIGHASH_TYPE for an input may only add the sighash type SIGHASH_ANYONECANPAY if the Has Silent Payments flag is False. If the sighash type SIGHASH_ANYONECANPAY is added to an input, the Silent Payments Modifiable flag must be set to False.
All rules must be followed from PSBTv2 for this role, in addition to the following:
The Signer should compute a DLEQ proof for each output that has PSBT_OUT_SILENT_PAYMENT_CODE using all inputs it has the private key for. The Signer should compute and set all missing PSBT_OUT_SCRIPT using its own private keys and all PSBT_OUT_SILENT_PAYMENT_DLEQ_PROOFs. If the Signer adds any DLEQ proofs or sets any missing PSBT_OUT_SCRIPTs, it must set the Inputs Modifiable flag to False.
If signing a SIGHASH_SINGLE input and the corresponding output does not have PSBT_OUT_SCRIPT set, the Signer must fail. If signing an input that is not SIGHASH_NONE or SIGHASH_SINGLE and any output does not have PSBT_OUT_SCRIPT set, the Signer must fail. If signing an input that is SIGHASH_SINGLE and the output corresponding to the input has PSBT_OUT_SILENT_PAYMENT_CODE set, the Signer should verify the PSBT_OUT_SCRIPT using all PSBT_OUT_SILENT_PAYMENT_DLEQ_PROOFs for that output. If signing an input that is not SIGHASH_NONE or SIGHASH_SINGLE, the Signer should verify the PSBT_OUT_SCRIPT using all PSBT_OUT_SILENT_PAYMENT_DLEQ_PROOFs for all outputs.
The Signer should additionally compute the silent payment addresses, optionally showing this data to the user instead of the computed segwit v1 addresses.
If a sighash type is not provided and the Silent Payments Modifiable flag is set to True, the Signer may not sign with the sighash type SIGHASH_ANYONECANPAY. If a sighash type is not provided and the Signer signs with SIGHASH_ANYONECANPAY, the Silent Payments Modifiable flag must be set to False.
For each output, the Signer may generate a proof for other entities to generate the output scripts and verify that the output scripts were generated correctly.
Using the notation from BIP352
- Let An be the sum of the public keys A of all eligible inputs the Signer has the private keys for
- Let an be the sum of the private keys a of all eligible inputs the Signer has
- Let C = an·Bscan
- Let r be a 32-byte random nonce generated by the Signer
- Let R1 = r·G
- Let R2 = r·Bscan
- Let e = SHA256(serP(R1) || serP(R2) || serP(An) || serP(C))
- Let s = r + e·an
For each output, the Signer should verify the ECDH shares for all eligible inputs it does not have the private key for using the proofs provided by other Signers.
Using the notation from BIP352
- Let An be the sum of the public keys A of all inputs covered by the proof
- Let proof be the data in PSBT_OUT_SILENT_PAYMENT_DLEQ_PROOF
- Let C = proof[0:33]
- Let e = proof[33:65]
- Let s = proof[65:97]
- Let R1 = s·G - e·An
- Let R2 = s·Bscan - e·C
Compute the PSBT_OUT_SCRIPT using the procedure in BIP352 but substituting a·Bscan with the sum of all Cs for all proofs covering all eligible inputs for that output. If the proofs for any output do not cover all inputs exactly once with no overlap, fail computing the output scripts.
Updaters may add two PSBT_OUT_BIP32_DERIVATION key-value-pairs with the corresponding derivation path of both the scan and spend keys. The Signer can then use these fields to verify that the silent payment code is change.
For PSBTv3s, the transaction extractor should verify all output scripts computed by silent payment codes are correct using the DLEQ proofs, otherwise fail.
PSBTv3 is backwards compatible with PSBTv2 if the Has Silent Payments flag is set to False or PSBT_GLOBAL_TX_MODIFIABLE is not present and no silent payment outputs have been added. Otherwise it is not backwards compatible.
Todo
Todo
Hi, I took a brief look at the DLEQ proof. Some minor comments: