From e2adb50e77562b513d98b730a36168f32ce3ec3e Mon Sep 17 00:00:00 2001 From: Andrew Toth Date: Sat, 19 Oct 2024 11:28:39 -0400 Subject: [PATCH 01/10] Bip Draft: Sending Silent Payments in PSBTs --- bip-PSBT-SP.mediawiki | 187 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 bip-PSBT-SP.mediawiki diff --git a/bip-PSBT-SP.mediawiki b/bip-PSBT-SP.mediawiki new file mode 100644 index 0000000000..6920a60801 --- /dev/null +++ b/bip-PSBT-SP.mediawiki @@ -0,0 +1,187 @@ +
+  BIP: ?
+  Layer: Applications
+  Title: Sending Silent Payments with PSBTs
+  Author: Andrew Toth 
+          Ava Chow 
+          josibake 
+  Comments-Summary: No comments yet.
+  Comments-URI: TBD
+  Status: Draft
+  Type: Standards Track
+  Created: 2024-05-14
+  License: BSD-2-Clause
+
+ +==Introduction== + +===Abstract=== + +This document proposes additional fields and updated role responsibilities for BIP 370 PSBTv2 +which adds support for sending to silent payments as described in BIP352. + +===Copyright=== + +This BIP is licensed under the 2-clause BSD license. + +===Motivation=== + +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. +Also, any inputs that the Signer has the private keys for must be signed with SIGHASH_ALL and all inputs must not have any scriptPubKeys with Segwit version > 1. +Additionally, the silent payment outputs computed by a signer must be verifiable to other entities. +Therefore, new fields and role responsibilities must be added to carry, compute, and verify the silent payment data. + +==Specification== + +This document specifies new fields and new field inclusion/exclusion requirements. + +PSBT_OUT_SCRIPT is modified to be optional for outputs in silent payments capable PSBTs. If this field is not included in the output, then the field PSBT_OUT_SP_V0_INFO must be included. + +The new global types are defined as follows: + +{| +! Name +! +! +! Description +! +! Description +! Versions Requiring Inclusion +! Versions Requiring Exclusion +! Versions Allowing Inclusion +|- +| Silent Payment Global ECDH Share +| PSBT_GLOBAL_SP_ECDH_SHARE = 0x07 +| <33 byte scan key> <36 byte outpoint>* +| The scan key and a list of outpoints corresponding to the prevouts of the inputs that this ECDH share is for. The outpoints are composed of a 32 byte txid followed by a 32-bit little endian uint. +| <32 byte share> +| An ECDH share for a scan key, followed by a list of outpoints. The ECDH shared is computed with ''a * B_scan'', where ''a'' is the sum of all private keys of the inputs matching the list of outpoints, and ''B_scan'' is the scan key of a recipient. +| +| 0 +| 2 +|- +| Silent Payment Global DLEQ Proof +| PSBT_GLOBAL_SP_DLEQ = 0x08 +| <33 byte scan key> <36 byte outpoint>* +| The scan key and a list of outpoints corresponding to the prevouts of the inputs that this proof covers. The outpoints are composed of a 32 byte txid followed by a 32-bit little endian uint. +| <64-byte proof> +| A DLEQ proof computed for the matching ECDH share. +| +| 0 +| 2 +|} + +One new per-output type is defined as follows: + +{| +! Name +! +! +! Description +! +! Description +! Versions Requiring Inclusion +! Versions Requiring Exclusion +! Versions Allowing Inclusion +|- +| Silent Payment Data +| PSBT_OUT_SP_V0_INFO = 0x08 +| None +| No key data +| <33 byte scan key> <33 byte spend key> +| The scan and spend public keys from the silent payments address. +| +| 0 +| 2 +|} + +===Unique Identification=== + +Silent payment capable PSBTs can be uniquely identified the same way as PSBTv2s, except when including silent payment outputs. For silent payment capable PSBTs, all silent payment outputs must use the PSBT_OUT_SP_V0_INFO instead of PSBT_OUT_SCRIPT as the output script when creating the unsigned transaction used for unique identification. + +==Roles== + +This document modifies some existing roles. + +===Constructor=== + +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_SP_V0_INFO, or both, set. + +Additionally to PSBTv2, the Constructor must also follow additional rules: + +Inputs spending an output with script using Segwit version > 1 may only be added if there are no outputs with PSBT_OUT_SP_V0_INFO set. +Outputs with PSBT_OUT_SP_V0_INFO set may only be added if there are no inputs spending an output script using Segwit version > 1. + +===Signer=== + +All rules must be followed from PSBTv2 for this role. If there are any outputs with PSBT_OUT_SP_V0_INFO set, then the following additional rules must also be adhered to: + +If any input is spending an output with script using Segwit version > 1, the Signer must fail. + +For all outputs with PSBT_OUT_SP_V0_INFO set, the Signer should: + - Compute and set an ECDH share and DLEQ proof using all inputs it has the private key for. + - Verify the DLEQ proofs for all inputs it does not have the private keys for. + - If all eligible inputs have an ECDH share, compute and set the PSBT_OUT_SCRIPT. + +If the Signer sets any missing PSBT_OUT_SCRIPTs, it must set the Inputs Modifiable flag to False. + +If any output does not have PSBT_OUT_SCRIPT set, the Signer must not yet add a signature. + +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 provided and there are silent payment outputs present, the signer must fail if the sighash type is not SIGHASH_ALL. +If a sighash type is not provided and there are silent payment outputs present, the signer must sign using SIGHASH_ALL. + +====Computing the DLEQ Proof==== + +For each output with PSBT_OUT_SP_V0_INFO set, the Signer may generate a proof for other entities to generate the output scripts and verify that the output scripts were generated correctly. + +Generate a global ECDH share for each scan key ''Bscan'' and all eligible inputs the Signer has private keys for as follows: + +Using the notation from [https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki#specification BIP352] + +* Let ''An'' be the sum of the public keys ''A'' of all eligible inputs +* Let ''an'' be the sum of the private keys ''a'' of all eligible inputs +* Let ''C = an·Bscan'' + +Use a key ''Bscan'' followed by a list of the outpoints of all eligible inputs. + +Set the value for the key of PSBT_GLOBAL_SP_ECDH_SHARE to ''C''. + +Compute the DLEQ proof for ''C'' using ''an'' and ''Bscan''. +Set the value for the key of PSBT_GLOBAL_SP_DLEQ to the proof. + +====Verifying the DLEQ Proof==== + +For each output with PSBT_OUT_SP_V0_INFO set, 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. + +====Computing the Output Scripts==== + +Compute the PSBT_OUT_SCRIPT using the procedure in [https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki#user-content-Creating_outputs BIP352] but substituting ''a·Bscan'' with the sum of all PSBT_GLOBAL_SP_ECDH_SHAREs for that scan key. +If there are multiple silent payment codes with the same scan key, sort the codes lexicographically in ascending order to determine the ordering of the ''k'' value. +If there are multiple silent payment codes with both the same scan and spend keys, sort the subgroup by output index in ascending order. + +====Change Detection==== + +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. + +===Transaction Extractor=== + +For silent payment capable PSBTs, the transaction extractor should compute all output scripts for silent payment codes and verify they are correct using the ECDH shares and DLEQ proofs, otherwise fail. + +==Backwards Compatibility== + +Silent payment capable PSBTs are backwards compatible with PSBTv2 once all outputs have PSBT_OUT_SCRIPT set. Otherwise they are not backwards compatible. + +==Test Vectors== + +Todo + +==Rationale== + + + +==Reference implementation== + +Todo \ No newline at end of file From 7472ffb9939a634d2496202474167db2294f6346 Mon Sep 17 00:00:00 2001 From: Andrew Toth Date: Mon, 9 Dec 2024 14:22:47 -0500 Subject: [PATCH 02/10] Update bip-PSBT-SP.mediawiki Co-authored-by: Yuval Kogman --- bip-PSBT-SP.mediawiki | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bip-PSBT-SP.mediawiki b/bip-PSBT-SP.mediawiki index 6920a60801..17866b7585 100644 --- a/bip-PSBT-SP.mediawiki +++ b/bip-PSBT-SP.mediawiki @@ -120,9 +120,9 @@ All rules must be followed from PSBTv2 for this role. If there are any outputs w If any input is spending an output with script using Segwit version > 1, the Signer must fail. For all outputs with PSBT_OUT_SP_V0_INFO set, the Signer should: - - Compute and set an ECDH share and DLEQ proof using all inputs it has the private key for. - - Verify the DLEQ proofs for all inputs it does not have the private keys for. - - If all eligible inputs have an ECDH share, compute and set the PSBT_OUT_SCRIPT. +* Compute and set an ECDH share and DLEQ proof using all inputs it has the private key for. +* Verify the DLEQ proofs for all inputs it does not have the private keys for. +* If all eligible inputs have an ECDH share, compute and set the PSBT_OUT_SCRIPT. If the Signer sets any missing PSBT_OUT_SCRIPTs, it must set the Inputs Modifiable flag to False. From f21fc5c512588a4d2a74649a638558a668eb821b Mon Sep 17 00:00:00 2001 From: Andrew Toth Date: Tue, 10 Dec 2024 19:19:24 -0500 Subject: [PATCH 03/10] Update size of ECDH share and unify spacing --- bip-PSBT-SP.mediawiki | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bip-PSBT-SP.mediawiki b/bip-PSBT-SP.mediawiki index 17866b7585..07380fb12a 100644 --- a/bip-PSBT-SP.mediawiki +++ b/bip-PSBT-SP.mediawiki @@ -17,7 +17,7 @@ ===Abstract=== -This document proposes additional fields and updated role responsibilities for BIP 370 PSBTv2 +This document proposes additional fields and updated role responsibilities for BIP370 PSBTv2 which adds support for sending to silent payments as described in BIP352. ===Copyright=== @@ -26,7 +26,7 @@ This BIP is licensed under the 2-clause BSD license. ===Motivation=== -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. +Partially Signed Bitcoin Transaction Version 2 as described in BIP370 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. Also, any inputs that the Signer has the private keys for must be signed with SIGHASH_ALL and all inputs must not have any scriptPubKeys with Segwit version > 1. Additionally, the silent payment outputs computed by a signer must be verifiable to other entities. Therefore, new fields and role responsibilities must be added to carry, compute, and verify the silent payment data. @@ -54,7 +54,7 @@ The new global types are defined as follows: | PSBT_GLOBAL_SP_ECDH_SHARE = 0x07 | <33 byte scan key> <36 byte outpoint>* | The scan key and a list of outpoints corresponding to the prevouts of the inputs that this ECDH share is for. The outpoints are composed of a 32 byte txid followed by a 32-bit little endian uint. -| <32 byte share> +| <33 byte share> | An ECDH share for a scan key, followed by a list of outpoints. The ECDH shared is computed with ''a * B_scan'', where ''a'' is the sum of all private keys of the inputs matching the list of outpoints, and ''B_scan'' is the scan key of a recipient. | | 0 From f2ef71ea5bbcc106637de798079bdaa44634c088 Mon Sep 17 00:00:00 2001 From: Andrew Toth Date: Mon, 23 Dec 2024 20:16:59 -0500 Subject: [PATCH 04/10] Add post history and BIP dependencies --- bip-PSBT-SP.mediawiki | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bip-PSBT-SP.mediawiki b/bip-PSBT-SP.mediawiki index 07380fb12a..14eb82be89 100644 --- a/bip-PSBT-SP.mediawiki +++ b/bip-PSBT-SP.mediawiki @@ -11,6 +11,8 @@ Type: Standards Track Created: 2024-05-14 License: BSD-2-Clause + Post-History: https://groups.google.com/g/bitcoindev/c/5G5wzqUXyk4 + Requires: 352, 370 ==Introduction== From 22f2313f2df3d54822711196836bba9af34ec8c4 Mon Sep 17 00:00:00 2001 From: Andrew Toth Date: Mon, 23 Dec 2024 20:17:26 -0500 Subject: [PATCH 05/10] Clarify motivation --- bip-PSBT-SP.mediawiki | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bip-PSBT-SP.mediawiki b/bip-PSBT-SP.mediawiki index 14eb82be89..4db57e1092 100644 --- a/bip-PSBT-SP.mediawiki +++ b/bip-PSBT-SP.mediawiki @@ -28,9 +28,9 @@ This BIP is licensed under the 2-clause BSD license. ===Motivation=== -Partially Signed Bitcoin Transaction Version 2 as described in BIP370 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. -Also, any inputs that the Signer has the private keys for must be signed with SIGHASH_ALL and all inputs must not have any scriptPubKeys with Segwit version > 1. -Additionally, the silent payment outputs computed by a signer must be verifiable to other entities. +Partially Signed Bitcoin Transaction Version 2 as described in BIP370 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. +Additionally, the silent payment outputs computed by a signer must be verifiable by other entities, otherwise funds could be sent to an incorrect output script. Therefore, new fields and role responsibilities must be added to carry, compute, and verify the silent payment data. ==Specification== From 2dbc11a925f4087a5aa1755b201a71b89ac0fb34 Mon Sep 17 00:00:00 2001 From: Andrew Toth Date: Mon, 23 Dec 2024 20:17:47 -0500 Subject: [PATCH 06/10] Move updater to before signer --- bip-PSBT-SP.mediawiki | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bip-PSBT-SP.mediawiki b/bip-PSBT-SP.mediawiki index 4db57e1092..b1c176d431 100644 --- a/bip-PSBT-SP.mediawiki +++ b/bip-PSBT-SP.mediawiki @@ -115,6 +115,12 @@ Additionally to PSBTv2, the Constructor must also follow additional rules: Inputs spending an output with script using Segwit version > 1 may only be added if there are no outputs with PSBT_OUT_SP_V0_INFO set. Outputs with PSBT_OUT_SP_V0_INFO set may only be added if there are no inputs spending an output script using Segwit version > 1. +===Updater=== + +====Change Detection==== + +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. + ===Signer=== All rules must be followed from PSBTv2 for this role. If there are any outputs with PSBT_OUT_SP_V0_INFO set, then the following additional rules must also be adhered to: @@ -164,10 +170,6 @@ Compute the PSBT_OUT_SCRIPT using the procedure in [https://github.com/bitcoin/b If there are multiple silent payment codes with the same scan key, sort the codes lexicographically in ascending order to determine the ordering of the ''k'' value. If there are multiple silent payment codes with both the same scan and spend keys, sort the subgroup by output index in ascending order. -====Change Detection==== - -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. - ===Transaction Extractor=== For silent payment capable PSBTs, the transaction extractor should compute all output scripts for silent payment codes and verify they are correct using the ECDH shares and DLEQ proofs, otherwise fail. From fa5d3f82f16353b24062650a967edf4a94c2a136 Mon Sep 17 00:00:00 2001 From: Andrew Toth Date: Mon, 23 Dec 2024 20:18:46 -0500 Subject: [PATCH 07/10] Clarify output script and sp info mutual exclusion and unique id --- bip-PSBT-SP.mediawiki | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/bip-PSBT-SP.mediawiki b/bip-PSBT-SP.mediawiki index b1c176d431..8c4886b360 100644 --- a/bip-PSBT-SP.mediawiki +++ b/bip-PSBT-SP.mediawiki @@ -37,8 +37,6 @@ Therefore, new fields and role responsibilities must be added to carry, compute, This document specifies new fields and new field inclusion/exclusion requirements. -PSBT_OUT_SCRIPT is modified to be optional for outputs in silent payments capable PSBTs. If this field is not included in the output, then the field PSBT_OUT_SP_V0_INFO must be included. - The new global types are defined as follows: {| @@ -97,9 +95,16 @@ One new per-output type is defined as follows: | 2 |} +PSBT_OUT_SCRIPT is modified to be optional for outputs in silent payments capable PSBTs. If this field is not included in the output, then the field PSBT_OUT_SP_V0_INFO must be included. +If a PSBT_OUT_SCRIPT is not present for an output, then that output is being sent to a silent payment address represented by PSBT_OUT_SP_V0_INFO but the script has not yet been computed. +If both PSBT_OUT_SCRIPT and PSBT_OUT_SP_V0_INFO are present for an output, then the PSBT_OUT_SCRIPT is the computed output script corresponding to the silent payment address in PSBT_OUT_SP_V0_INFO. +If only PSBT_OUT_SCRIPT is present for an output, then the output is not being sent to a silent payment address. + ===Unique Identification=== -Silent payment capable PSBTs can be uniquely identified the same way as PSBTv2s, except when including silent payment outputs. For silent payment capable PSBTs, all silent payment outputs must use the PSBT_OUT_SP_V0_INFO instead of PSBT_OUT_SCRIPT as the output script when creating the unsigned transaction used for unique identification. +Silent payment capable PSBTs can be uniquely identified the same way as PSBTv2s, except when including silent payment outputs. If an output contains the the PSBT_OUT_SP_V0_INFO field, it must use that field instead of PSBT_OUT_SCRIPT as the output script when creating the unsigned transaction used for unique identification. ''' Why use PSBT_OUT_SP_V0_INFO when serializing for a unique identifier?''' Since the same silent payment capable PSBT is valid whether or not a PSBT_OUT_SCRIPT is included in an output that has PSBT_OUT_SP_V0_INFO set, using the PSBT_OUT_SCRIPT if present for the unique identifier will cause malleability. The identifier will be different depending on whether PSBT_OUT_SCRIPT is present, so always using PSBT_OUT_SP_V0_INFO if it exists makes sure the PSBT is always identified uniquely. +The PSBT_OUT_SP_V0_INFO should be serialized as a zero byte for the version, followed by the 33 bytes of the scan key and then 33 bytes for the spend key. + ==Roles== From f05353b7ecc1a4f5c2fa660c6a76a43e906e99d5 Mon Sep 17 00:00:00 2001 From: Andrew Toth Date: Mon, 23 Dec 2024 20:19:01 -0500 Subject: [PATCH 08/10] Add newline --- bip-PSBT-SP.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-PSBT-SP.mediawiki b/bip-PSBT-SP.mediawiki index 8c4886b360..d250f8a65d 100644 --- a/bip-PSBT-SP.mediawiki +++ b/bip-PSBT-SP.mediawiki @@ -193,4 +193,4 @@ Todo ==Reference implementation== -Todo \ No newline at end of file +Todo From c9589c588bdc7e265ca2a73ba54e0df1c1c95c7f Mon Sep 17 00:00:00 2001 From: Andrew Toth Date: Mon, 23 Dec 2024 20:19:20 -0500 Subject: [PATCH 09/10] Add ref for why sighash_all is required --- bip-PSBT-SP.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-PSBT-SP.mediawiki b/bip-PSBT-SP.mediawiki index d250f8a65d..c59f8a0aaf 100644 --- a/bip-PSBT-SP.mediawiki +++ b/bip-PSBT-SP.mediawiki @@ -144,7 +144,7 @@ If any output does not have PSBT_OUT_SCRIPT set, the Signer must not yet add a s 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 provided and there are silent payment outputs present, the signer must fail if the sighash type is not SIGHASH_ALL. -If a sighash type is not provided and there are silent payment outputs present, the signer must sign using SIGHASH_ALL. +If a sighash type is not provided and there are silent payment outputs present, the signer must sign using SIGHASH_ALL. ''' Why use only SIGHASH_ALL?''' BIP352 allows signing with SIGHASH_NONE and SIGHASH_SINGLE. However, silent payment capable PSBTs compute the output scripts deterministically based on the number and position of silent payment codes with the same scan key. SIGHASH_NONE and SIGHASH_SINGLE allow changing the amount or position of silent payment codes with the same scan and spend keys, which would invalidate computed output scripts. ====Computing the DLEQ Proof==== From 3bfecc3d5d37b1dc77bbd6a139d61adeb1da1664 Mon Sep 17 00:00:00 2001 From: Andrew Toth Date: Tue, 31 Dec 2024 15:41:11 -0500 Subject: [PATCH 10/10] Split up shares and proofs into global or per input fields --- bip-PSBT-SP.mediawiki | 110 +++++++++++++++++++++++++++++++++--------- 1 file changed, 88 insertions(+), 22 deletions(-) diff --git a/bip-PSBT-SP.mediawiki b/bip-PSBT-SP.mediawiki index c59f8a0aaf..ebbc4d41b9 100644 --- a/bip-PSBT-SP.mediawiki +++ b/bip-PSBT-SP.mediawiki @@ -12,7 +12,7 @@ Created: 2024-05-14 License: BSD-2-Clause Post-History: https://groups.google.com/g/bitcoindev/c/5G5wzqUXyk4 - Requires: 352, 370 + Requires: 352, 370, 374 ==Introduction== @@ -52,20 +52,54 @@ The new global types are defined as follows: |- | Silent Payment Global ECDH Share | PSBT_GLOBAL_SP_ECDH_SHARE = 0x07 -| <33 byte scan key> <36 byte outpoint>* -| The scan key and a list of outpoints corresponding to the prevouts of the inputs that this ECDH share is for. The outpoints are composed of a 32 byte txid followed by a 32-bit little endian uint. +| <33 byte scan key> +| The scan key that this ECDH share is for. | <33 byte share> -| An ECDH share for a scan key, followed by a list of outpoints. The ECDH shared is computed with ''a * B_scan'', where ''a'' is the sum of all private keys of the inputs matching the list of outpoints, and ''B_scan'' is the scan key of a recipient. +| An ECDH share for a scan key. The ECDH shared is computed with ''a * B_scan'', where ''a'' is the sum of all private keys of all eligible inputs, and ''B_scan'' is the scan key of a recipient. | | 0 | 2 |- | Silent Payment Global DLEQ Proof | PSBT_GLOBAL_SP_DLEQ = 0x08 -| <33 byte scan key> <36 byte outpoint>* -| The scan key and a list of outpoints corresponding to the prevouts of the inputs that this proof covers. The outpoints are composed of a 32 byte txid followed by a 32-bit little endian uint. +| <33 byte scan key> +| The scan key that this proof covers. | <64-byte proof> -| A DLEQ proof computed for the matching ECDH share. +| A BIP374 DLEQ proof computed for the matching ECDH share. +| +| 0 +| 2 +|} + +The new per-input types are defined as follows: + +{| +! Name +! +! +! Description +! +! Description +! Versions Requiring Inclusion +! Versions Requiring Exclusion +! Versions Allowing Inclusion +|- +| Silent Payment Input ECDH Share +| PSBT_IN_SP_ECDH_SHARE = 0x1d +| <33 byte scan key> +| The scan key that this ECDH share is for. +| <33 byte share> +| An ECDH share for a scan key. The ECDH shared is computed with ''a * B_scan'', where ''a'' is the private key of the corresponding prevout public key, and ''B_scan'' is the scan key of a recipient. +| +| 0 +| 2 +|- +| Silent Payment Input DLEQ Proof +| PSBT_IN_SP_DLEQ = 0x1e +| <33 byte scan key> +| The scan key that this proof covers. +| <64-byte proof> +| A BIP374 DLEQ proof computed for the matching ECDH share. | | 0 | 2 @@ -85,7 +119,7 @@ One new per-output type is defined as follows: ! Versions Allowing Inclusion |- | Silent Payment Data -| PSBT_OUT_SP_V0_INFO = 0x08 +| PSBT_OUT_SP_V0_INFO = 0x09 | None | No key data | <33 byte scan key> <33 byte spend key> @@ -93,6 +127,16 @@ One new per-output type is defined as follows: | | 0 | 2 +|- +| Silent Payment Label +| PSBT_OUT_SP_V0_LABEL = 0x10 +| None +| No key data +| <32-bit little endian uint label> +| The label to use to compute the spend key of the silent payments address to verify change. +| +| 0 +| 2 |} PSBT_OUT_SCRIPT is modified to be optional for outputs in silent payments capable PSBTs. If this field is not included in the output, then the field PSBT_OUT_SP_V0_INFO must be included. @@ -122,9 +166,11 @@ Outputs with PSBT_OUT_SP_V0_INFO set may only be added if there are no inputs sp ===Updater=== +The updater should add a PSBT_IN_BIP32_DERIVATION for any p2wpkh, p2sh-p2wpkh, or p2pkh input so the public key is available for creating the ecdh_shared_secret when the private key is not known. If the updater does not want to reveal the fingerprint or derivation path, it can set the value of the field to zero. + ====Change Detection==== -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. +Updaters may add two PSBT_OUT_BIP32_DERIVATION key-value-pairs with the corresponding derivation path of both the scan and spend keys. A label can be specified in PSBT_OUT_SP_V0_LABEL. The Signer can then use these fields to verify that the silent payment code is change. ===Signer=== @@ -132,12 +178,12 @@ All rules must be followed from PSBTv2 for this role. If there are any outputs w If any input is spending an output with script using Segwit version > 1, the Signer must fail. -For all outputs with PSBT_OUT_SP_V0_INFO set, the Signer should: -* Compute and set an ECDH share and DLEQ proof using all inputs it has the private key for. -* Verify the DLEQ proofs for all inputs it does not have the private keys for. -* If all eligible inputs have an ECDH share, compute and set the PSBT_OUT_SCRIPT. +For each output with PSBT_OUT_SP_V0_INFO set, the Signer should: +* Compute and set an ECDH share and DLEQ proof for each input it has the private key for, or set a global ECDH share and DLEQ proof if it has private keys for all eligible inputs. +* Verify the DLEQ proofs for all inputs it does not have the private keys for, or the global DLEQ proof if it is set. +* If all eligible inputs have an ECDH share or the global ECDH share is set, compute and set the PSBT_OUT_SCRIPT. -If the Signer sets any missing PSBT_OUT_SCRIPTs, it must set the Inputs Modifiable flag to False. +If the Signer sets any missing PSBT_OUT_SCRIPTs, it must set the Inputs Modifiable and Outputs Modifiable flags to False. If any output does not have PSBT_OUT_SCRIPT set, the Signer must not yet add a signature. @@ -146,32 +192,52 @@ The Signer should additionally compute the silent payment addresses, optionally If a sighash type is provided and there are silent payment outputs present, the signer must fail if the sighash type is not SIGHASH_ALL. If a sighash type is not provided and there are silent payment outputs present, the signer must sign using SIGHASH_ALL. ''' Why use only SIGHASH_ALL?''' BIP352 allows signing with SIGHASH_NONE and SIGHASH_SINGLE. However, silent payment capable PSBTs compute the output scripts deterministically based on the number and position of silent payment codes with the same scan key. SIGHASH_NONE and SIGHASH_SINGLE allow changing the amount or position of silent payment codes with the same scan and spend keys, which would invalidate computed output scripts. -====Computing the DLEQ Proof==== +====Computing the ECDH Shares and DLEQ Proofs==== For each output with PSBT_OUT_SP_V0_INFO set, the Signer may generate a proof for other entities to generate the output scripts and verify that the output scripts were generated correctly. -Generate a global ECDH share for each scan key ''Bscan'' and all eligible inputs the Signer has private keys for as follows: +If the Signer has the private keys for all eligible inputs, the Signer should generate a global ECDH share for each scan key ''Bscan'' as follows: Using the notation from [https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki#specification BIP352] -* Let ''An'' be the sum of the public keys ''A'' of all eligible inputs * Let ''an'' be the sum of the private keys ''a'' of all eligible inputs * Let ''C = an·Bscan'' -Use a key ''Bscan'' followed by a list of the outpoints of all eligible inputs. +Set the key as ''Bscan'' and the value as ''C'' for the PSBT_GLOBAL_SP_ECDH_SHARE field. + +Compute the DLEQ proof for ''C'' using [https://github.com/bitcoin/bips/blob/master/bip-0374.mediawiki#user-content-DLEQ_Proof_Generation BIP374 GenerateProof] and passing ''an'' as ''a'' and ''Bscan'' as ''B''. +Set the key as ''Bscan'' and the value as the proof for the PSBT_GLOBAL_SP_DLEQ field. -Set the value for the key of PSBT_GLOBAL_SP_ECDH_SHARE to ''C''. +If the Signer has the private keys for some eligible inputs or does not want to create a global ECDH share, the Signer should generate a per-input ECDH share for each scan key ''Bscan'' as follows: -Compute the DLEQ proof for ''C'' using ''an'' and ''Bscan''. -Set the value for the key of PSBT_GLOBAL_SP_DLEQ to the proof. +Using the notation from [https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki#specification BIP352], for each eligible input: + +* Let ''a'' be the private key of the input +* Let ''C = a·Bscan'' + +Set the key as ''Bscan'' and the value as ''C'' for the PSBT_IN_SP_ECDH_SHARE field of the input. + +Compute the DLEQ proof for ''C'' using [https://github.com/bitcoin/bips/blob/master/bip-0374.mediawiki#user-content-DLEQ_Proof_Generation BIP374 GenerateProof] and passing ''Bscan'' as ''B''. +Set the key as ''Bscan'' and the value as the proof for the PSBT_IN_SP_DLEQ field of the input. ====Verifying the DLEQ Proof==== For each output with PSBT_OUT_SP_V0_INFO set, 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. +If PSBT_GLOBAL_SP_ECDH_SHARE and PSBT_GLOBAL_SP_DLEQ are set, verify as follows: + +* Let ''An'' be the sum of the public keys ''A'' of all eligible inputs + +Using [https://github.com/bitcoin/bips/blob/master/bip-0374.mediawiki#dleq-proof-verification BIP374 VerifyProof] and passing ''A'' as ''An'', ''B'' as ''Bscan'', ''C'' as the value of PSBT_GLOBAL_SP_ECDH_SHARE, and ''proof'' as the value of PSBT_GLOBAL_SP_DLEQ. + +If PSBT_IN_SP_ECDH_SHARE and PSBT_IN_SP_DLEQ are set for a particular input, verify as follows: + +Using [https://github.com/bitcoin/bips/blob/master/bip-0374.mediawiki#dleq-proof-verification BIP374 VerifyProof] and passing ''A'' as the public key of the input, ''B'' as ''Bscan'', ''C'' as the value of PSBT_IN_SP_ECDH_SHARE, and ''proof'' as the value of PSBT_IN_SP_DLEQ. + + ====Computing the Output Scripts==== -Compute the PSBT_OUT_SCRIPT using the procedure in [https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki#user-content-Creating_outputs BIP352] but substituting ''a·Bscan'' with the sum of all PSBT_GLOBAL_SP_ECDH_SHAREs for that scan key. +Compute the PSBT_OUT_SCRIPT using the procedure in [https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki#user-content-Creating_outputs BIP352] but substituting ''a·Bscan'' with the PSBT_GLOBAL_SP_ECDH_SHARE for that scan key if available, or the sum of all PSBT_IN_SP_ECDH_SHAREs for that scan key. If there are multiple silent payment codes with the same scan key, sort the codes lexicographically in ascending order to determine the ordering of the ''k'' value. If there are multiple silent payment codes with both the same scan and spend keys, sort the subgroup by output index in ascending order.