Skip to content

BIP375: Add test vectors + validator#2046

Draft
macgyver13 wants to merge 10 commits intobitcoin:masterfrom
macgyver13:bip375-reference-testvectors-pr
Draft

BIP375: Add test vectors + validator#2046
macgyver13 wants to merge 10 commits intobitcoin:masterfrom
macgyver13:bip375-reference-testvectors-pr

Conversation

@macgyver13
Copy link
Contributor

@macgyver13 macgyver13 commented Nov 26, 2025

This PR provides bip-0375/bip375_test_vectors.json and a reference bip-0375/validator/validate_psbt.py for validating Sending Silent Payments with PSBTs.
PSBTs are validated against v2 requirements with BIP-375 rules (building on BIP-352 silent payment derivation and BIP-374 DLEQ proofs).

Changes since last force-push:

  • Add vendored dependencies in bip-0375/deps:
    • secp256k1lab (ECC operations)
    • bitcoin_test (PSBT parsing adapted from Bitcoin Core test framework)
  • Implement 4-stage sequential PSBT validation: structure, ECDH coverage + DLEQ correctness, input eligibility, and output script verification
  • Expanded test vector coverage:
    • mixed + ineligible inputs
    • output script validation with same scan key / spend key, same scan / different spend key, different scan key
    • introduce P2TR inputs
  • Add test vector version field (starting at 1.1)
  • Update BIP-0375 Test Vectors section

Open Questions:

  • BIP-375 allows PSBT_OUT_SCRIPT field to be optional if PSBT_OUT_SP_V0_INFO field is present for an output, should PSBT_OUT_SCRIPT field with empty value_data be considered valid? - I prefer invalid
  • Should BIP text be clarified for Computing the Output Scripts as follows? - added 'from eligible inputs'

Compute the PSBT_OUT_SCRIPT using the procedure in 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 from eligible inputs for that scan key.

Feedback welcome @andrewtoth @achow101 @theStack

Details

Test Runner Output

Description: BIP-375 Test Vectors
Version: 1.1

Invalid PSBTs: 23
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: 18
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

Summary: 41 passed, 0 failed

Test vector generator is available in an external repo

@jonatack jonatack added Proposed BIP modification Pending acceptance This BIP modification requires sign-off by the champion of the BIP being modified labels Nov 27, 2025
@macgyver13 macgyver13 force-pushed the bip375-reference-testvectors-pr branch 3 times, most recently from d540a48 to 88dec03 Compare December 5, 2025 19:54
@macgyver13 macgyver13 force-pushed the bip375-reference-testvectors-pr branch from 88dec03 to 4510632 Compare January 8, 2026 00:38
Copy link
Contributor

@nymius nymius left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cACK 4510632

  • I haven't been able to decode the PSBT's using bitcoin-cli decodepsbt in a per test basis. Did you have any issues?

  • I would consider copying the approach taken in #2084, and use secp256k1lab here.

  • As each PSBT change is reflected in BIP 174, maybe is worth moving the parsing, fields and PSBT validation logic to BIP 174 directory, and keep the role logic of each protocol on its own directory, like here.

@macgyver13
Copy link
Contributor Author

cACK 4510632

  • I haven't been able to decode the PSBT's using bitcoin-cli decodepsbt in a per test basis. Did you have any issues?

Details in comment above - PSBT v2 not supported

I agree that approach is better than the current bip-0374 import. The current import process would have to adapt to that change regardless. I'll put that on the list for the next revision.

  • As each PSBT change is reflected in BIP 174, maybe is worth moving the parsing, fields and PSBT validation logic to BIP 174 directory, and keep the role logic of each protocol on its own directory, like here.

Interesting idea. Are you suggesting a storage change for this PR or expand the scope of the PSBT parsing, fields and validation to v0 and other v2 fields and move to other BIPS directories?

@nymius
Copy link
Contributor

nymius commented Jan 16, 2026

Interesting idea. Are you suggesting a storage change for this PR or expand the scope of the PSBT parsing, fields and validation to v0 and other v2 fields and move to other BIPS directories?

I'm suggesting the second one, but as it seems to involve more components, I wouldn't pursue it in this PR.

@macgyver13
Copy link
Contributor Author

This PR depends on #2084.

Converting to draft while dependent work is evaluated. In parallel reworking a few test cases for better coverage of spec. ie. (ECDH share coverage and unique identification)

@macgyver13 macgyver13 marked this pull request as draft January 22, 2026 21:48
@murchandamus
Copy link
Member

@macgyver13: It looks like your dependency moved forward. Could you take another look whether this is ready for an update?

@macgyver13 macgyver13 changed the title BIP375: Add test vectors + runner BIP375: Add test vectors + validation runner Mar 9, 2026
@macgyver13 macgyver13 changed the title BIP375: Add test vectors + validation runner BIP375: Add test vectors + validator Mar 9, 2026
git-subtree-dir: bip-0375/deps/secp256k1lab
git-subtree-split: 44dc4bd893b8f03e621585e3bf255253e0e0fbfb
BIP375PSBT (a PSBT subclass that deserializes into BIP375PSBTMap instances)
BIP375PSBTMap (a PSBTMap subclass with BIP-375 field access helpers)
Implement psbt structure checks
Add validator/dleq.py (Adapted from bip-0374/reference.py)
Extract pubkey from PSBT inputs 
- PSBT_IN_BIP32_DERIVATION
- PSBT_IN_WITNESS_UTXO for P2TR
Add input helpers
- scriptPubKey helpers
- bip352 input eligibility helpers
Verify segwit version >1 not used if silent payment outputs present (bip352)
Verify SIGHASH_ALL requirement
Verify PSBT_GLOBAL_TX_MODIFIABLE is zero (unmodifiable) if PSBT_OUT_SCRIPT is set
Add support for computing bip352 output scripts
Add extract ECDH shares and public key from PSBT and aggregate both if necessary
Update Test Vectors section
Add README.md to explain validation tooling and dependencies
@macgyver13 macgyver13 force-pushed the bip375-reference-testvectors-pr branch from 4510632 to f2529c9 Compare March 18, 2026 02:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Pending acceptance This BIP modification requires sign-off by the champion of the BIP being modified Proposed BIP modification

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants