From cf7a16a5f960dc3b48938a6008f83b4cec1a1a18 Mon Sep 17 00:00:00 2001 From: macgyver13 <4712150+macgyver13@users.noreply.github.com> Date: Mon, 23 Feb 2026 11:18:30 -0500 Subject: [PATCH] BIP-375: update documentation Update Test Vectors section Add README.md to explain validation tooling and dependencies --- bip-0375.mediawiki | 151 ++++++++++++++++++++++++++++++++++++++++++++- bip-0375/README.md | 32 ++++++++++ 2 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 bip-0375/README.md diff --git a/bip-0375.mediawiki b/bip-0375.mediawiki index c50d62cc..2e743878 100644 --- a/bip-0375.mediawiki +++ b/bip-0375.mediawiki @@ -249,7 +249,156 @@ 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. +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 +|- +| PSBT Structure +| empty PSBT_OUT_SCRIPT field when sending to non-sp output +|- +| ECDH Coverage +| only one ineligible P2MS 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 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 mixed input types - only eligible inputs contribute ECDH 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 +|} ==Rationale== diff --git a/bip-0375/README.md b/bip-0375/README.md new file mode 100644 index 00000000..b9ce1119 --- /dev/null +++ b/bip-0375/README.md @@ -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/)