Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 150 additions & 1 deletion bip-0375.mediawiki
Original file line number Diff line number Diff line change
Expand Up @@ -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==

Expand Down
32 changes: 32 additions & 0 deletions bip-0375/README.md
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/)
Loading