-
Notifications
You must be signed in to change notification settings - Fork 5.9k
BIP375: Add test vectors + validator #2046
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
Changes from all commits
a8aa5ed
eedb7f9
e705101
8b46bd6
fc9918d
66053ae
6a91f88
ab30224
fb105b7
cf7a16a
7b4f1d6
9536c86
6295a70
897455d
b217897
8c0a9bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,7 @@ | |
| Assigned: 2025-01-08 | ||
| License: BSD-2-Clause | ||
| Discussion: https://groups.google.com/g/bitcoindev/c/5G5wzqUXyk4 | ||
| Version: 0.1.1 | ||
| Requires: 352, 370, 374 | ||
| </pre> | ||
|
|
||
|
|
@@ -177,7 +178,7 @@ 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 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. | ||
| * Compute and set an ECDH share and DLEQ proof for each eligible 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. | ||
|
|
||
|
|
@@ -235,7 +236,7 @@ Using [https://github.com/bitcoin/bips/blob/master/bip-0374.mediawiki#dleq-proof | |
|
|
||
| ====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·B<sub>scan</sub>'' 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. | ||
| 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·B<sub>scan</sub>'' with the PSBT_GLOBAL_SP_ECDH_SHARE for that scan key if available, or the sum of all PSBT_IN_SP_ECDH_SHAREs from eligible inputs 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. | ||
|
|
||
|
|
@@ -249,7 +250,163 @@ Silent payment capable PSBTs are backwards compatible with PSBTv2 once all outpu | |
|
|
||
| ==Test Vectors== | ||
|
|
||
| Todo | ||
| A [[bip-0375/bip375_test_vectors.json|collection of test vectors in JSON format]] is provided. Each test vector contains a base64-encoded PSBT string, which alone can be used to verify sending Silent Payments with PSBTs. | ||
|
macgyver13 marked this conversation as resolved.
|
||
| Validation is performed in 4 sequential checks. This [[bip-0375/validator/validate_psbt.py|Python implementation]] demonstrates the validation logic for each: | ||
|
|
||
| # '''PSBT Structure''' - Verify BIP375 field requirements | ||
| # '''ECDH Coverage''' - Verify ECDH share presence and correctness using BIP374 DLEQ | ||
| # '''Input Eligibility''' - Verify input constraints when silent payment outputs are present | ||
| # '''Output Scripts''' - Verify output scripts match silent payment derivation | ||
|
|
||
| Valid PSBTs are organized into 2 categories: | ||
| # '''Can Finalize''' - Signed and ready to finalize | ||
| # '''In Progress''' - Incomplete but valid | ||
|
|
||
| Use the provided [[bip-0375/test_runner.py|test runner]] to validate each test vector. See the [[bip-0375/README.md|README]] for more details. | ||
|
|
||
| ===Invalid PSBTs=== | ||
|
|
||
| {| | ||
| ! Category | ||
| ! Description | ||
| |- | ||
| | PSBT Structure | ||
| | missing PSBT_OUT_SP_V0_INFO field when PSBT_OUT_SP_V0_LABEL set | ||
| |- | ||
| | PSBT Structure | ||
| | incorrect byte length for PSBT_OUT_SP_V0_INFO field | ||
| |- | ||
| | PSBT Structure | ||
| | incorrect byte length for PSBT_IN_SP_ECDH_SHARE field | ||
| |- | ||
| | PSBT Structure | ||
| | incorrect byte length for PSBT_IN_SP_DLEQ field | ||
| |- | ||
| | PSBT Structure | ||
| | PSBT_GLOBAL_TX_MODIFIABLE field is non-zero when PSBT_OUT_SCRIPT set for sp output | ||
| |- | ||
| | PSBT Structure | ||
| | missing PSBT_OUT_SCRIPT field when sending to non-sp output | ||
| |- | ||
| | ECDH Coverage | ||
| | only one ineligible P2SH multisig input when PSBT_OUT_SCRIPT set for sp output | ||
| |- | ||
| | ECDH Coverage | ||
| | missing PSBT_IN_SP_ECDH_SHARE field for input 0 when PSBT_OUT_SCRIPT set for sp output | ||
| |- | ||
| | ECDH Coverage | ||
| | missing PSBT_IN_SP_DLEQ field for input when PSBT_IN_SP_ECDH_SHARE set | ||
| |- | ||
| | ECDH Coverage | ||
| | missing PSBT_GLOBAL_SP_DLEQ field when PSBT_GLOBAL_SP_ECDH_SHARE set | ||
| |- | ||
| | ECDH Coverage | ||
| | invalid proof in PSBT_IN_SP_DLEQ field | ||
| |- | ||
| | ECDH Coverage | ||
| | invalid proof in PSBT_GLOBAL_SP_DLEQ field | ||
| |- | ||
| | ECDH Coverage | ||
| | missing PSBT_IN_BIP32_DERIVATION field for input when PSBT_IN_SP_DLEQ set | ||
| |- | ||
| | ECDH Coverage | ||
| | output 1 missing ECDH share for scan key with one input / three sp outputs (different scan keys) | ||
| |- | ||
| | ECDH Coverage | ||
| | input 1 missing ECDH share for output 1 with two inputs / two sp outputs (different scan keys) | ||
| |- | ||
| | ECDH Coverage | ||
| | input 1 missing ECDH share for scan key with two inputs / one sp output | ||
| |- | ||
| | Input Eligibility | ||
| | segwit version greater than 1 in transaction inputs with sp output | ||
| |- | ||
| | Input Eligibility | ||
| | non-SIGHASH_ALL signature on input with sp output | ||
| |- | ||
| | Output Scripts | ||
| | P2TR input with NUMS internal key cannot derive sp output | ||
| |- | ||
| | Output Scripts | ||
| | PSBT_OUT_SCRIPT does not match derived sp output | ||
| |- | ||
| | Output Scripts | ||
| | two sp outputs (same scan / different spend keys) not sorted lexicographically by spend key | ||
| |- | ||
| | Output Scripts | ||
| | k values assigned to wrong output indices with three sp outputs (same scan / spend keys) | ||
| |} | ||
|
|
||
| ===Valid PSBTs=== | ||
|
|
||
| {| | ||
| ! State | ||
| ! Description | ||
| |- | ||
| | Can Finalize | ||
| | one P2PKH input single-signer | ||
| |- | ||
| | Can Finalize | ||
| | two inputs single-signer using global ECDH share | ||
| |- | ||
| | Can Finalize | ||
| | two inputs single-signer using per-input ECDH shares | ||
| |- | ||
| | Can Finalize | ||
| | two inputs / two sp outputs with mixed global and per-input ECDH shares | ||
| |- | ||
| | Can Finalize | ||
| | one input / one sp output with both global and per-input ECDH shares | ||
| |- | ||
| | Can Finalize | ||
| | three sp outputs (different scan keys) with multiple global ECDH shares | ||
| |- | ||
| | Can Finalize | ||
| | one P2WPKH input / two mixed outputs - labeled sp output and BIP 32 change | ||
| |- | ||
| | Can Finalize | ||
| | one input / two sp outputs - output 0 has no label / output 1 uses label=0 convention for sp change | ||
| |- | ||
| | Can Finalize | ||
| | two sp outputs - output 0 uses label=3 / output 1 uses label=1 | ||
| |- | ||
| | Can Finalize | ||
| | two inputs using per-input ECDH shares - only eligible inputs contribute shares (P2SH excluded) | ||
| |- | ||
| | Can Finalize | ||
| | two inputs using global ECDH share - only eligible inputs contribute shares (P2SH excluded) | ||
| |- | ||
| | Can Finalize | ||
| | two mixed input types - only eligible inputs contribute ECDH shares (NUMS internal key excluded) | ||
| |- | ||
| | Can Finalize | ||
| | three sp outputs (same scan key) - each output has distinct k value | ||
| |- | ||
| | Can Finalize | ||
| | three sp outputs (same scan key) / two regular outputs - k values assigned independently of output index | ||
| |- | ||
| | In Progress | ||
| | two P2TR inputs, neither is signed | ||
| |- | ||
| | In Progress | ||
| | one P2TR input / one sp output with no ECDH shares when PSBT_OUT_SCRIPT field is not set | ||
| |- | ||
| | In Progress | ||
| | two inputs / one sp output, input 1 missing ECDH share when PSBT_OUT_SCRIPT field is not set | ||
| |- | ||
| | In Progress | ||
| | one input / two sp outputs, input 0 missing ECDH share for output 0 when PSBT_OUT_SCRIPT field is not set | ||
| |- | ||
| | In Progress | ||
| | large PSBT with nine mixed inputs / six outputs - some inputs signed | ||
| |} | ||
|
|
||
| == Changelog == | ||
|
|
||
| * '''0.1.1''' (2026-04-16): | ||
| ** Add test vectors and reference for validating Sending Silent Payments with PSBTs. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are also updates to the BIP about eligible inputs / restrictions. Should that be mentioned?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit (not a blocker for this already substantial and BIP author approved improvement): Referencing the above comment as well as https://github.com/bitcoin/bips/pull/2046/changes#r3089267494, it seems to me that those updates, along with the new addition of the Valid PSBTs section, might suggest incrementing a minor, rather than patch, version (e.g., to 0.2.0), if the specification is considered to be modified/extended (in a backward-compatible way). (Both of these comments can be handled in a follow-up PR.)
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I read the addition of "eligible" as a simple clarification, because only some inputs are relevant to Silent Payments. |
||
| * '''0.1.0''' (2025-01-13): | ||
| ** Initial version, merged as BIP-375. | ||
|
|
||
| ==Rationale== | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # BIP-375 Validation Reference | ||
|
|
||
| A reference validation implementation for BIP-375: Sending Silent Payments with PSBTs. | ||
|
|
||
| ## Core Files | ||
| - **`validator/bip352_crypto.py`** - Silent payment output script derivation | ||
| - **`validator/inputs.py`** - PSBT input utility functions | ||
| - **`validator/psbt_bip375.py`** - BIP-375 specific PSBT/PSBTMap extensions | ||
| - **`validator/validate_psbt.py`** - Main BIP-375 validation functions | ||
| - **`test_runner.py`** - Test infrastructure (executable) | ||
|
|
||
| ## Dependencies | ||
| - **`deps/bitcoin_test/psbt.py`** - Bitcoin test framework PSBT module - [PR #21283](https://github.com/bitcoin/bitcoin/pull/21283) | ||
| - **`deps/bitcoin_test/messages.py`** - Bitcoin test framework primitives and message structures | ||
| - **`deps/dleq.py`** - Reference DLEQ implementation from BIP-374 | ||
| - **`deps/secp256k1lab/`** - vendored copy of [secp256k1lab](https://github.com/secp256k1lab/secp256k1lab/commit/44dc4bd893b8f03e621585e3bf255253e0e0fbfb) library at version 1.0.0 | ||
|
|
||
| ## Testing | ||
|
|
||
| ### Run Tests | ||
|
|
||
| ```bash | ||
| python test_runner.py # Run all tests | ||
| python test_runner.py -v # Verbose mode with detailed validation status | ||
| python test_runner.py -vv # More verbose with validation check failure reason | ||
|
|
||
| python test_runner.py -f vectors.json # Use custom test vector file | ||
| ``` | ||
|
|
||
| ### Generating Test Vectors | ||
|
|
||
| Test vectors were generated using [test_generator.py](https://github.com/macgyver13/bip375-test-generator/) |
Uh oh!
There was an error while loading. Please reload this page.