Skip to content

Conversation

@macgyver13
Copy link
Contributor

@macgyver13 macgyver13 commented Nov 26, 2025

This PR adds the test runner test_runner.py and test_vectors.json for demonstrating BIP 375 behavior.
Care was taken to minimize dependencies required to evaluate the test vectors.

Dependencies are referenced at runtime from bip-0374 instead of cloning locally.

Test generation tools moved to external repo

Feedback welcome @andrewtoth @achow101 @josibake

Test runner output

Invalid test cases: 13
=== Running Invalid Test Cases ===
Test 1: Missing DLEQ proof for ECDH share
Test 2: Invalid DLEQ proof
Test 3: Non-SIGHASH_ALL signature with silent payments
Test 4: Mixed segwit versions with silent payments
Test 5: Silent payment outputs but no ECDH shares
Test 6: Global ECDH share without DLEQ proof
Test 7: Wrong SP_V0_INFO field size
Test 8: Mixed eligible and ineligible input types
Test 9: Wrong ECDH share size
Test 10: Wrong DLEQ proof size
Test 11: Label without SP_V0_INFO
Test 12: Address mismatch
Test 13: Both global and per-input ECDH shares

=== Running Valid Test Cases ===
Test 14: Single signer with global ECDH share
Test 15: Multi-party with per-input ECDH shares
Test 16: P2WPKH to silent payment with change detection
Test 17: Silent payment to recipient with SP change (label=0)
Test 18: Multiple silent payment outputs to same scan key

@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
- Add constants.py with BIP 375 PSBT field type definitions
- Add parser.py with PSBT v2 structure parsing functions
- Add minimal test_runner.py for basic structure validation
- Validates PSBT magic bytes and parse-ability
- All 17 test vectors pass basic structure checks
- - Basic structure validation complete: 4 passed, 13 failed
- Add inputs.py with input type validation helpers
- Add dependencies from previous work
- - deps/bip352_utils.py
- - deps/secp256k1_374.py
- Validate eligible input types (P2PKH, P2WPKH, P2TR, P2SH-P2WPKH)
- Check segwit version restrictions (v0-v1 only)
- Verify P2SH inputs are P2SH-P2WPKH
- Update test_runner.py to validate inputs
Input validation complete: 6 passed, 11 failed
- Add dleq.py with DLEQ proof validation functions
- Extract public keys from BIP32 derivation fields
- Validate global and per-input DLEQ proofs using BIP-374
- Verify scan key consistency between ECDH and DLEQ fields
- Prevent conflicting global/per-input ECDH for same scan key
- Check ECDH shares exist for silent payment outputs
- Update test_runner.py with comprehensive DLEQ validation
DLEQ validation complete: 14 passed, 3 failed
- Add validator.py with comprehensive BIP-375 validation
- Validate output field requirements (SCRIPT or SP_V0_INFO)
- Check SP_V0_INFO field size (66 bytes)
- Validate SP_V0_LABEL requires SP_V0_INFO
- Enforce SIGHASH_ALL requirement for silent payments
- Integrate all previous validation (inputs, DLEQ, ECDH)
- Simplify test_runner.py to use validator module
- Validation complete: 16 passed, 1 failed
- Add validate_bip352_outputs() for output script verification
- Support both global and per-input ECDH share modes
- Update test_runner.py to pass test material to validator
- Details core files and dependencies
- Link to test_generator.py for vector generation
- Provide usage instructions for test_runner.py
…l=0)"

Fix compute output script ‘k’ bug - now increments for each output sharing the same scan key
@macgyver13 macgyver13 force-pushed the bip375-reference-testvectors-pr branch from 88dec03 to 4510632 Compare January 8, 2026 00:38
Comment on lines 35 to 37
# Check magic bytes
if len(psbt_data) < 5 or psbt_data[:5] != b"psbt\xff":
return False, "Invalid PSBT magic"
Copy link
Contributor

Choose a reason for hiding this comment

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

This check is also in parse_psbt_structure. I would keep it only in one of both places.


# Extract field type and handle key-value pairs
if key_data:
field_type = key_data[0]
Copy link
Contributor

Choose a reason for hiding this comment

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

The extraction of field_type from key_data is odd. I would use de-structure assignment to keep them separated when assigning key_data, and also use the names stated in BIP 174, e.g.:

key_type, *key_data = data[offset : offset + key_len]

return False, f"Input {i} uses segwit version > 1 with silent payments"

# Eligible input type requirement
# When silent payment outputs exist, ALL inputs must be eligible types
Copy link
Contributor

@nymius nymius Jan 14, 2026

Choose a reason for hiding this comment

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

What does ALL inputs must be eligible types mean in this context?
This is checking all inputs are valid for shared secret derivation, which is not a condition all inputs must fulfill in order to create a silent payment transaction.

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.

3 participants