BIP375: check SegWit versions in non-witness UTXOs #2310

pull zjubiology wants to merge 1 commits into bitcoin:master from zjubiology:master changing 3 files +26 −7
  1. zjubiology commented at 1:07 PM on September 26, 2026: none

    BIP375 requires constructors and signers to reject PSBTs that combine silent payment outputs with inputs spending SegWit v2+ outputs.

    The reference validator currently performs this check only when the prevout is provided through PSBT_IN_WITNESS_UTXO. BIP174 also permits SegWit inputs to provide the full previous transaction through PSBT_IN_NON_WITNESS_UTXO, so an input containing only that field can currently bypass the SegWit-version check.

    Reuse the existing _script_pubkey_from_psbt_input() helper when validating input eligibility. This extracts the referenced scriptPubKey from either UTXO field.

    Also add an invalid test vector containing:

    • a silent payment output;
    • a SegWit v2 prevout supplied only through PSBT_IN_NON_WITNESS_UTXO;
    • a matching previous transaction ID and output index.
  2. yenimillet835-crypto commented at 12:55 AM on September 27, 2026: none

    🤩🤩

  3. zjubiology commented at 5:36 AM on September 28, 2026: none

    @achow101 @andrewtoth Could you please take a look when you have a chance? Thanks!

  4. fametrano commented at 7:53 PM on October 3, 2026: contributor

    The validator change holds: at ea1192c98800f3157fa6b22307e608362a07b7d2, master (927b6de) accepts the new vector under input_eligibility, this branch rejects it with "Input 0 uses segwit version > 1 with silent payments", and all 43 vectors pass.

    The vector's PSBT_IN_PREVIOUS_TXID is byte-reversed. The field holds 9630266b…0c73c9; the double-SHA256 of the PSBT_IN_NON_WITNESS_UTXO transaction is c9730c1b…263096. BIP 174 requires the two to match ("its hash must match the hash specified in the prevout"), and the six existing vectors with a non-witness UTXO store the hash as computed, so a parser that checks this rejects the PSBT for the wrong reason. Reversing the 32 bytes of PSBT_IN_PREVIOUS_TXID, and of prevout_txid in supplementary to match the other vectors, fixes it.

  5. BIP375: check SegWit versions in non-witness UTXOs
    Signed-off-by: zjubiology <zjubiology@outlook.com>
    242bfbe9cb
  6. in bip-0375/bip375_test_vectors.json:389 in ea1192c988
     383 | @@ -384,6 +384,25 @@
     384 |          "input_eligibility"
     385 |        ]
     386 |      },
     387 | +    {
     388 | +      "description": "input eligibility: segwit version greater than 1 supplied via PSBT_IN_NON_WITNESS_UTXO with sp output",
     389 | +      "psbt": "cHNidP8B+wQCAAAAAQIEAgAAAAEEAQEBBQEBAQYBAAABDiCWMCZrG0dm0WcLF8uVyI6AOAwflR+auv+KO1+SGwxzyQEPBAAAAAAiAgLIF7t1Ia/DXqlvO/snDm61Dd/6VWBie5Yf7ADymWUIv0cwRAIgcvN4hS+4Q3JgcvJQdvDndWDtTC4EcWbuamJsdb/bOdYCICEqrl8JV040H1iG9f/zL1cW6rkDCkpTeeYBa2pNQtwkAQEDBAEAAAAiBgLIF7t1Ia/DXqlvO/snDm61Dd/6VWBie5Yf7ADymWUIvwgAAACAAAAAAAEQBP7///8iHQJ6SH/Bn7dph3uHQtbqGBGPPE5yseqMbeYCp61KQdvgaCED7KT/Ebco4uD2DOYiKUOm/1W52V9ie/mpnQhLyHLVClsiHgJ6SH/Bn7dph3uHQtbqGBGPPE5yseqMbeYCp61KQdvgaECKE7OYVUX3K9bolxSuuQmz41SoQqm7i1bNDt7SHfihmVmLMSKKSeC9fpXOEFP3xbKKy1Q6aHB2AOPOiYIu4yAhAQBSAgAAAAH0whLVrtHn9v9jPyzgnGR8V77dkwMU2Y3ndQPVjpQLMwAAAAAA/////wGghgEAAAAAABZSFCKactNKZFvTSWu79Qu7gckGP0+UAAAAAAABAwgYcwEAAAAAAAEEIlEgMm31D+Cge3rLcgcL6ztjLrmtFbppXMHlqmqgB7YUb9gBCUICekh/wZ+3aYd7h0LW6hgRjzxOcrHqjG3mAqetSkHb4GgDYeGx6d5eQssgB/fKVLng1X7ROTj61W0/GeV1E6j84DkA",
    


    fametrano commented at 7:53 PM on October 3, 2026:
          "psbt": "cHNidP8B+wQCAAAAAQIEAgAAAAEEAQEBBQEBAQYBAAABDiDJcwwbkl87iv+6mh+VHww4gI7IlcsXC2fRZkcbayYwlgEPBAAAAAAiAgLIF7t1Ia/DXqlvO/snDm61Dd/6VWBie5Yf7ADymWUIv0cwRAIgcvN4hS+4Q3JgcvJQdvDndWDtTC4EcWbuamJsdb/bOdYCICEqrl8JV040H1iG9f/zL1cW6rkDCkpTeeYBa2pNQtwkAQEDBAEAAAAiBgLIF7t1Ia/DXqlvO/snDm61Dd/6VWBie5Yf7ADymWUIvwgAAACAAAAAAAEQBP7///8iHQJ6SH/Bn7dph3uHQtbqGBGPPE5yseqMbeYCp61KQdvgaCED7KT/Ebco4uD2DOYiKUOm/1W52V9ie/mpnQhLyHLVClsiHgJ6SH/Bn7dph3uHQtbqGBGPPE5yseqMbeYCp61KQdvgaECKE7OYVUX3K9bolxSuuQmz41SoQqm7i1bNDt7SHfihmVmLMSKKSeC9fpXOEFP3xbKKy1Q6aHB2AOPOiYIu4yAhAQBSAgAAAAH0whLVrtHn9v9jPyzgnGR8V77dkwMU2Y3ndQPVjpQLMwAAAAAA/////wGghgEAAAAAABZSFCKactNKZFvTSWu79Qu7gckGP0+UAAAAAAABAwgYcwEAAAAAAAEEIlEgMm31D+Cge3rLcgcL6ztjLrmtFbppXMHlqmqgB7YUb9gBCUICekh/wZ+3aYd7h0LW6hgRjzxOcrHqjG3mAqetSkHb4GgDYeGx6d5eQssgB/fKVLng1X7ROTj61W0/GeV1E6j84DkA",
    

    zjubiology commented at 10:34 PM on October 3, 2026:

    Thanks, good catch. I had written the human-readable txid byte order directly into PSBT_IN_PREVIOUS_TXID.

    I updated the field to use the raw double-SHA256 byte order and changed the supplementary prevout_txid accordingly. I also checked all seven vectors containing PSBT_IN_NON_WITNESS_UTXO; their previous transaction hashes now match their PSBT_IN_PREVIOUS_TXID fields.

    The corrected vector is still rejected by input eligibility with:

    Input 0 uses segwit version > 1 with silent payments

  7. in bip-0375/bip375_test_vectors.json:394 in ea1192c988
     389 | +      "psbt": "cHNidP8B+wQCAAAAAQIEAgAAAAEEAQEBBQEBAQYBAAABDiCWMCZrG0dm0WcLF8uVyI6AOAwflR+auv+KO1+SGwxzyQEPBAAAAAAiAgLIF7t1Ia/DXqlvO/snDm61Dd/6VWBie5Yf7ADymWUIv0cwRAIgcvN4hS+4Q3JgcvJQdvDndWDtTC4EcWbuamJsdb/bOdYCICEqrl8JV040H1iG9f/zL1cW6rkDCkpTeeYBa2pNQtwkAQEDBAEAAAAiBgLIF7t1Ia/DXqlvO/snDm61Dd/6VWBie5Yf7ADymWUIvwgAAACAAAAAAAEQBP7///8iHQJ6SH/Bn7dph3uHQtbqGBGPPE5yseqMbeYCp61KQdvgaCED7KT/Ebco4uD2DOYiKUOm/1W52V9ie/mpnQhLyHLVClsiHgJ6SH/Bn7dph3uHQtbqGBGPPE5yseqMbeYCp61KQdvgaECKE7OYVUX3K9bolxSuuQmz41SoQqm7i1bNDt7SHfihmVmLMSKKSeC9fpXOEFP3xbKKy1Q6aHB2AOPOiYIu4yAhAQBSAgAAAAH0whLVrtHn9v9jPyzgnGR8V77dkwMU2Y3ndQPVjpQLMwAAAAAA/////wGghgEAAAAAABZSFCKactNKZFvTSWu79Qu7gckGP0+UAAAAAAABAwgYcwEAAAAAAAEEIlEgMm31D+Cge3rLcgcL6ztjLrmtFbppXMHlqmqgB7YUb9gBCUICekh/wZ+3aYd7h0LW6hgRjzxOcrHqjG3mAqetSkHb4GgDYeGx6d5eQssgB/fKVLng1X7ROTj61W0/GeV1E6j84DkA",
     390 | +      "supplementary": {
     391 | +        "inputs": [
     392 | +          {
     393 | +            "input_index": 0,
     394 | +            "prevout_txid": "9630266b1b4766d1670b17cb95c88e80380c1f951f9abaff8a3b5f921b0c73c9",
    


    fametrano commented at 7:53 PM on October 3, 2026:
                "prevout_txid": "c9730c1b925f3b8affba9a1f951f0c38808ec895cb170b67d166471b6b263096",
    

    zjubiology commented at 10:35 PM on October 3, 2026:

    Updated the supplementary prevout_txid to match the serialized hash as well. Please review it again.

  8. zjubiology force-pushed on Oct 3, 2026
  9. fametrano commented at 7:19 AM on October 4, 2026: contributor

    ACK 242bfbe9cb2011733c16aea82de2227ba6fb2bc7

    The new vector's PSBT_IN_PREVIOUS_TXID now matches its non-witness UTXO, the test runner passes 43/43, and the vector is still rejected for the segwit version.

  10. zjubiology commented at 11:10 PM on October 4, 2026: none

    ACK 242bfbe

    The new vector's PSBT_IN_PREVIOUS_TXID now matches its non-witness UTXO, the test runner passes 43/43, and the vector is still rejected for the segwit version.

    Thanks for the review and ACK!

  11. zjubiology commented at 12:15 AM on October 10, 2026: none

    @fametrano Thanks for your review! If there's anything need I to do, please feel free to let me know.


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bips. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-10-14 03:10 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me