BIP375: require DLEQ proof for every per-input ECDH share #2321

pull gophersg wants to merge 1 commits into bitcoin:master from gophersg:bip375-in-progress-dleq changing 3 files +50 −7
  1. gophersg commented at 3:05 AM on October 2, 2026: none

    BIP375 pairs an ECDH share with a DLEQ proof: a signer must "compute and set an ECDH share and DLEQ proof for each eligible input", and the invalid PSBT table already lists "missing PSBT_IN_SP_DLEQ field for input when PSBT_IN_SP_ECDH_SHARE set" without qualifying it on PSBT_OUT_SCRIPT.

    The reference validator does not enforce that pairing for in-progress PSBTs. Its per-input DLEQ presence check sits inside the scan_key_has_computed_output branch, so as soon as PSBT_OUT_SCRIPT is absent the branch is skipped entirely and a PSBT carrying PSBT_IN_SP_ECDH_SHARE without PSBT_IN_SP_DLEQ passes validation:

    $ python3 test_runner.py     # before
    Summary: 43 passed, 1 failed

    The global path does not have this hole: a global ECDH share always requires PSBT_GLOBAL_SP_DLEQ, whether or not the output script has been computed.

    This moves the share/proof pairing check out of the computed-output branch so it applies to every ECDH share, while the branch keeps doing only what its name says - checking coverage of eligible inputs. It also adds the corresponding invalid test vector (the existing one sets PSBT_OUT_SCRIPT, so it never exercised the skipped path), the matching row in the invalid PSBT table, and a changelog entry.

    $ python3 test_runner.py     # after
    Summary: 44 passed, 0 failed

    To run the tests:

    cd bip-0375
    python3 test_runner.py
  2. jonatack added the label Proposed BIP modification on Oct 2, 2026
  3. jonatack added the label Pending acceptance on Oct 2, 2026
  4. fametrano commented at 8:00 PM on October 3, 2026: contributor

    The check is right and the hole is real: master (927b6de) passes the new vector with all checks, 706853a9eb8303838f550f76a76c5e466559c89a rejects it with "Input 0 ECDH share missing DLEQ proof", and all 44 vectors pass.

    The vector marks input 0 "signed": true and carries a PSBT_IN_PARTIAL_SIG, but output 0 has no PSBT_OUT_SCRIPT, so there is no signature hash for a SIGHASH_ALL signature to commit to; the signature bytes are the ones the psbt-structure vectors carry. The three in-progress vectors without PSBT_OUT_SCRIPT have no partial signature and "signed": false; this one should match them.

  5. in bip-0375/bip375_test_vectors.json:136 in 706853a9eb outdated
     130 | @@ -131,6 +131,34 @@
     131 |          ]
     132 |        }
     133 |      },
     134 | +    {
     135 | +      "description": "ecdh coverage: missing PSBT_IN_SP_DLEQ field for input when PSBT_IN_SP_ECDH_SHARE set and PSBT_OUT_SCRIPT not set",
     136 | +      "psbt": "cHNidP8B+wQCAAAAAQIEAgAAAAEEAQEBBQEBAQYBAAABDiAYpxdmOwurFLEqGncTI/8eQHndUy5d0T4o6hCBxwCYSgEPBAAAAAABAR+ghgEAAAAAABYAFCKactNKZFvTSWu79Qu7gckGP0+UIgICyBe7dSGvw16pbzv7Jw5utQ3f+lVgYnuWH+wA8pllCL9HMEQCIAkHemqmSsFK56GqT+aMAqziBsnqxyNJBhrnYDkAuSJuAiBvFDKlePjjMK8LkAJWdGvJ9OUqoujMeQKdyOdqPClLBgEBAwQBAAAAIgYCyBe7dSGvw16pbzv7Jw5utQ3f+lVgYnuWH+wA8pllCL8IAAAAgAAAAAABEAT+////Ih0Cekh/wZ+3aYd7h0LW6hgRjzxOcrHqjG3mAqetSkHb4GghA+yk/xG3KOLg9gzmIilDpv9VudlfYnv5qZ0IS8hy1QpbAAEDCBhzAQAAAAAAAQlCAnpIf8Gft2mHe4dC1uoYEY88TnKx6oxt5gKnrUpB2+BoA2HhseneXkLLIAf3ylS54NV+0Tk4+tVtPxnldROo/OA5AA==",
    


    fametrano commented at 8:00 PM on October 3, 2026:
          "psbt": "cHNidP8B+wQCAAAAAQIEAgAAAAEEAQEBBQEBAQYBAAABDiAYpxdmOwurFLEqGncTI/8eQHndUy5d0T4o6hCBxwCYSgEPBAAAAAABAR+ghgEAAAAAABYAFCKactNKZFvTSWu79Qu7gckGP0+UAQMEAQAAACIGAsgXu3Uhr8NeqW87+ycObrUN3/pVYGJ7lh/sAPKZZQi/CAAAAIAAAAAAARAE/v///yIdAnpIf8Gft2mHe4dC1uoYEY88TnKx6oxt5gKnrUpB2+BoIQPspP8Rtyji4PYM5iIpQ6b/VbnZX2J7+amdCEvIctUKWwABAwgYcwEAAAAAAAEJQgJ6SH/Bn7dph3uHQtbqGBGPPE5yseqMbeYCp61KQdvgaANh4bHp3l5CyyAH98pUueDVftE5OPrVbT8Z5XUTqPzgOQA=",
    
  6. in bip-0375/bip375_test_vectors.json:149 in 706853a9eb
     144 | +            "prevout_index": 0,
     145 | +            "prevout_scriptpubkey": "0014229a72d34a645bd3496bbbf50bbb81c9063f4f94",
     146 | +            "amount": 100000,
     147 | +            "witness_utxo": "a086010000000000160014229a72d34a645bd3496bbbf50bbb81c9063f4f94",
     148 | +            "sequence": 4294967294,
     149 | +            "signed": true
    


    fametrano commented at 8:00 PM on October 3, 2026:
                "signed": false
    
  7. gophersg force-pushed on Oct 8, 2026
  8. gophersg commented at 2:51 PM on October 8, 2026: none

    The check is right and the hole is real: master (927b6de) passes the new vector with all checks, 706853a rejects it with "Input 0 ECDH share missing DLEQ proof", and all 44 vectors pass.

    The vector marks input 0 "signed": true and carries a PSBT_IN_PARTIAL_SIG, but output 0 has no PSBT_OUT_SCRIPT, so there is no signature hash for a SIGHASH_ALL signature to commit to; the signature bytes are the ones the psbt-structure vectors carry. The three in-progress vectors without PSBT_OUT_SCRIPT have no partial signature and "signed": false; this one should match them. @fametrano Thanks, fixed. I changed the vector’s signed field to false to match the other in-progress vectors without PSBT_OUT_SCRIPT, and force-pushed the update as a single commit.

  9. fametrano commented at 7:13 PM on October 8, 2026: contributor

    Thanks @gophersg. One thing is left: input 0 of the vector's PSBT still carries a partial signature, which doesn't match "signed": false. The first suggestion is the same PSBT without it, and with that PSBT the vector is still rejected for the missing DLEQ proof. I'm not a BIP owner or maintainer, so this is only one reviewer's view: ACK once the partial signature is removed.

  10. gophersg force-pushed on Oct 8, 2026
  11. gophersg commented at 9:06 PM on October 8, 2026: none

    Thanks @gophersg. One thing is left: input 0 of the vector's PSBT still carries a partial signature, which doesn't match "signed": false. The first suggestion is the same PSBT without it, and with that PSBT the vector is still rejected for the missing DLEQ proof. I'm not a BIP owner or maintainer, so this is only one reviewer's view: ACK once the partial signature is removed. @fametrano Thanks, you’re right.

    I removed the partial signature from input 0 and kept "signed": false. The vector still exercises the missing DLEQ proof case. I’ve force-pushed the update as a single commit

  12. fametrano commented at 5:40 AM on October 9, 2026: contributor

    ACK bb0e65b08183ed2f02f631190eb8b709e733df58

    The partial signature is gone, and the vector's PSBT is now the one I suggested. The runner passes 44/44, and with master's validator it fails only the new vector.

    Nit: the preamble still says Version: 0.1.2, while the changelog adds 0.1.3.

  13. BIP375: require DLEQ proof for every per-input ECDH share
    Signed-off-by: gophersg <gopher@2980.com>
    4599942870
  14. gophersg force-pushed on Oct 10, 2026
  15. gophersg force-pushed on Oct 10, 2026
  16. gophersg force-pushed on Oct 10, 2026
  17. gophersg commented at 12:09 AM on October 10, 2026: none

    ACK bb0e65b

    The partial signature is gone, and the vector's PSBT is now the one I suggested. The runner passes 44/44, and with master's validator it fails only the new vector.

    Nit: the preamble still says Version: 0.1.2, while the changelog adds 0.1.3. @fametrano Thanks! Modified!

    <img width="669" height="291" alt="image" src="https://github.com/user-attachments/assets/796a0cec-fa2d-4625-a40b-4fe765a53142" />

  18. fametrano commented at 9:28 AM on October 10, 2026: contributor

    ACK 4599942870c031d8f19abb09fde29e9e378be7e7

    The only change since bb0e65b is the preamble's Version: 0.1.3, so my earlier checks still hold.


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-11 23:10 UTC

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