diff --git a/bip-0375.mediawiki b/bip-0375.mediawiki index 7d6089a4..28c0a3cf 100644 --- a/bip-0375.mediawiki +++ b/bip-0375.mediawiki @@ -10,7 +10,7 @@ Assigned: 2025-01-08 License: BSD-2-Clause Discussion: https://groups.google.com/g/bitcoindev/c/5G5wzqUXyk4 - Version: 0.1.1 + Version: 0.1.2 Requires: 352, 370, 374 @@ -27,7 +27,7 @@ This BIP is licensed under the 2-clause BSD license. ===Motivation=== -Partially Signed Bitcoin Transaction Version 2 as described in BIP370 is not compatible with sending to silent payments as described in BIP352. +Partially Signed Bitcoin Transaction Version 2 as described in BIP370 is not compatible with sending to silent payments as described in BIP352. In particular, the output script of a silent payment cannot be computed until after all transaction inputs have been added. Additionally, the silent payment outputs computed by a signer must be verifiable by other entities, otherwise funds could be sent to an incorrect output script. Therefore, new fields and role responsibilities must be added to carry, compute, and verify the silent payment data. @@ -274,6 +274,9 @@ Use the provided [[bip-0375/test_runner.py|test runner]] to validate each test v | missing PSBT_OUT_SP_V0_INFO field when PSBT_OUT_SP_V0_LABEL set |- | PSBT Structure +| incorrect byte length for PSBT_OUT_SP_V0_LABEL field +|- +| PSBT Structure | incorrect byte length for PSBT_OUT_SP_V0_INFO field |- | PSBT Structure @@ -403,6 +406,8 @@ Use the provided [[bip-0375/test_runner.py|test runner]] to validate each test v == Changelog == +* '''0.1.2''' (2026-09-27): +** Validate PSBT_OUT_SP_V0_LABEL is exactly 4 bytes; add invalid test vector for wrong length. * '''0.1.1''' (2026-04-16): ** Add test vectors and reference for validating Sending Silent Payments with PSBTs. * '''0.1.0''' (2025-01-13): diff --git a/bip-0375/bip375_test_vectors.json b/bip-0375/bip375_test_vectors.json index 38511f65..d08d943e 100644 --- a/bip-0375/bip375_test_vectors.json +++ b/bip-0375/bip375_test_vectors.json @@ -13,6 +13,11 @@ "psbt": "cHNidP8B+wQCAAAAAQIEAgAAAAEEAQEBBQEBAQYBAAABDiAYpxdmOwurFLEqGncTI/8eQHndUy5d0T4o6hCBxwCYSgEPBAAAAAABAR+ghgEAAAAAABYAFCKactNKZFvTSWu79Qu7gckGP0+UIgICyBe7dSGvw16pbzv7Jw5utQ3f+lVgYnuWH+wA8pllCL9HMEQCIAkHemqmSsFK56GqT+aMAqziBsnqxyNJBhrnYDkAuSJuAiBvFDKlePjjMK8LkAJWdGvJ9OUqoujMeQKdyOdqPClLBgEBAwQBAAAAIgYCyBe7dSGvw16pbzv7Jw5utQ3f+lVgYnuWH+wA8pllCL8IAAAAgAAAAAABEAT+////Ih0Cekh/wZ+3aYd7h0LW6hgRjzxOcrHqjG3mAqetSkHb4GghA+yk/xG3KOLg9gzmIilDpv9VudlfYnv5qZ0IS8hy1QpbIh4Cekh/wZ+3aYd7h0LW6hgRjzxOcrHqjG3mAqetSkHb4GhAihOzmFVF9yvW6JcUrrkJs+NUqEKpu4tWzQ7e0h34oZlZizEiikngvX6VzhBT98WyistUOmhwdgDjzomCLuMgIQABAwgYcwEAAAAAAAEEIlEgImjPUplZ8wrI96VHHKTGdTalHw5bForwPu1HFe3McuABCgQBAAAAAA==", "supplementary": {} }, + { + "description": "psbt structure: incorrect byte length for PSBT_OUT_SP_V0_LABEL field", + "psbt": "cHNidP8B+wQCAAAAAQIEAgAAAAEEAQEBBQECAQYBAAABDiAYpxdmOwurFLEqGncTI/8eQHndUy5d0T4o6hCBxwCYSgEPBAAAAAABAR8goQcAAAAAABYAFCKactNKZFvTSWu79Qu7gckGP0+UIgICyBe7dSGvw16pbzv7Jw5utQ3f+lVgYnuWH+wA8pllCL9IMEUCIQCspcmETsmSLIHmcIF+My2i3RXSxdOpRiq21l5TtoKJXgIgTfMs6jgucsQ8BYQE/a5wWVHmuj3jPYM8g6lbsBg4CscBAQMEAQAAACIGAsgXu3Uhr8NeqW87+ycObrUN3/pVYGJ7lh/sAPKZZQi/CAAAAIAAAAAAARAE/v///yIdAnpIf8Gft2mHe4dC1uoYEY88TnKx6oxt5gKnrUpB2+BoIQPspP8Rtyji4PYM5iIpQ6b/VbnZX2J7+amdCEvIctUKWyIeAnpIf8Gft2mHe4dC1uoYEY88TnKx6oxt5gKnrUpB2+BoQIoTs5hVRfcr1uiXFK65CbPjVKhCqbuLVs0O3tId+KGZWYsxIopJ4L1+lc4QU/fFsorLVDpocHYA486Jgi7jICEAAQMIoIYBAAAAAAABBCJRICJoz1KZWfMKyPelRxykxnU2pR8OWxaK8D7tRxXtzHLgAQlCAnpIf8Gft2mHe4dC1uoYEY88TnKx6oxt5gKnrUpB2+BoA+qPIovitxbaze/LKBAHKHTwCkdvXAe9BRkXEmzGSz3vAQoBAQABAwhw8wUAAAAAAAEEFgAUOMGPNd2AY+OApw/+tPmP9O80gXciAgLIF7t1Ia/DXqlvO/snDm61Dd/6VWBie5Yf7ADymWUIvwwAAAAAAAAAAAAAAAEA", + "supplementary": {} + }, { "description": "psbt structure: incorrect byte length for PSBT_OUT_SP_V0_INFO field", "psbt": "cHNidP8B+wQCAAAAAQIEAgAAAAEEAQEBBQEBAQYBAAABDiAYpxdmOwurFLEqGncTI/8eQHndUy5d0T4o6hCBxwCYSgEPBAAAAAABAR+ghgEAAAAAABYAFCKactNKZFvTSWu79Qu7gckGP0+UIgICyBe7dSGvw16pbzv7Jw5utQ3f+lVgYnuWH+wA8pllCL9HMEQCIAkHemqmSsFK56GqT+aMAqziBsnqxyNJBhrnYDkAuSJuAiBvFDKlePjjMK8LkAJWdGvJ9OUqoujMeQKdyOdqPClLBgEBAwQBAAAAIgYCyBe7dSGvw16pbzv7Jw5utQ3f+lVgYnuWH+wA8pllCL8IAAAAgAAAAAABEAT+////Ih0Cekh/wZ+3aYd7h0LW6hgRjzxOcrHqjG3mAqetSkHb4GghA+yk/xG3KOLg9gzmIilDpv9VudlfYnv5qZ0IS8hy1QpbIh4Cekh/wZ+3aYd7h0LW6hgRjzxOcrHqjG3mAqetSkHb4GhAihOzmFVF9yvW6JcUrrkJs+NUqEKpu4tWzQ7e0h34oZlZizEiikngvX6VzhBT98WyistUOmhwdgDjzomCLuMgIQABAwgYcwEAAAAAAAEEIlEgMm31D+Cge3rLcgcL6ztjLrmtFbppXMHlqmqgB7YUb9gBCUECekh/wZ+3aYd7h0LW6hgRjzxOcrHqjG3mAqetSkHb4GgDYeGx6d5eQssgB/fKVLng1X7ROTj61W0/GeV1E6j84AA=", diff --git a/bip-0375/validator/validate_psbt.py b/bip-0375/validator/validate_psbt.py index bc5c1d44..054f4fd6 100644 --- a/bip-0375/validator/validate_psbt.py +++ b/bip-0375/validator/validate_psbt.py @@ -46,6 +46,7 @@ def validate_psbt_structure(psbt: PSBT) -> Tuple[bool, str]: Checks: - Each output must have PSBT_OUT_SCRIPT or PSBT_OUT_SP_V0_INFO - PSBT_OUT_SP_V0_LABEL requires PSBT_OUT_SP_V0_INFO + - SP_V0_LABEL must be 4 bytes (32-bit little-endian uint) - SP_V0_INFO must be 66 bytes (33-byte scan key + 33-byte spend key) - ECDH shares must be 33 bytes - DLEQ proofs must be 64 bytes @@ -73,6 +74,15 @@ def validate_psbt_structure(psbt: PSBT) -> Tuple[bool, str]: f"Output {i} has PSBT_OUT_SP_V0_LABEL but missing PSBT_OUT_SP_V0_INFO", ) + # Validate SP_V0_LABEL field length + if has_sp_label: + sp_label = output_map[PSBT_OUT_SP_V0_LABEL] + if len(sp_label) != 4: + return ( + False, + f"Output {i} PSBT_OUT_SP_V0_LABEL has wrong length ({len(sp_label)} bytes, expected 4)", + ) + # Validate SP_V0_INFO field length if has_sp_info: sp_info = output_map[PSBT_OUT_SP_V0_INFO]