Skip to content

BIP-376: Silent Payment input signing behavior#2139

Open
lucia-w wants to merge 6 commits intobitcoin:masterfrom
lucia-w:bip-0376
Open

BIP-376: Silent Payment input signing behavior#2139
lucia-w wants to merge 6 commits intobitcoin:masterfrom
lucia-w:bip-0376

Conversation

@lucia-w
Copy link
Copy Markdown

@lucia-w lucia-w commented Apr 12, 2026

  • This PR adds a reference implementation and test vectors for Silent Payment input signing behavior.

@murchandamus murchandamus added Proposed BIP modification PR by non-owner to update BIP content Pending acceptance This BIP modification requires sign-off by the champion of the BIP being modified labels Apr 12, 2026
@murchandamus
Copy link
Copy Markdown
Member

Thanks for your submission. cc'ing the author @nymius for review.

Copy link
Copy Markdown
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.

Approach NACK 8c38c9e

Thanks for working on this.
Although your changes are exercising the behavior of the signer role, my expectations for the test cases are inclined to what we already have in BIP 174 or is currently being worked on for BIP 375 (#2046)
There we have full serialized PSBT tests.
As this BIP is focused towards PSBTs, I think that's the way to proceed.

Comment thread bip-0376/reference.py
@@ -0,0 +1,223 @@
#!/usr/bin/env python3
"""BIP-0376 reference implementation and test vector runner.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I recommend you to follow the approach taken in #2087 and #2046 , use secp256k1lab and the components from bitcoin_test that you need. That would focus the review process on BIP 376.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Makes sense, thank you

Comment thread bip-0376/test-vectors.json Outdated
"tweak": "ac7b0d0420f0d4a567d9abcb8a52e02cfae21690fd8d2d5934370dcc5aaee221",
"output_pubkey": "528b75296fa646acecf3fcb7c7697f92f7645ea0e41e6ee8a66554739d2da028"
},
"error_substr": "spend key out of range"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

These are unnecessary and constraint the implementation, I would remove them.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done, could you please review again

@jonatack jonatack added the PR Author action required Needs updates, has unaddressed review comments, or is otherwise waiting for PR author label Apr 14, 2026
@murchandamus murchandamus removed the PR Author action required Needs updates, has unaddressed review comments, or is otherwise waiting for PR author label Apr 27, 2026
@murchandamus murchandamus requested a review from nymius April 27, 2026 17:41
Copy link
Copy Markdown
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.

Thanks for the update. Let me explain this better:

I would create a dependencies or deps dir with the secp256k1lab@1.0.0 source code and the code from bitcoin core test framework like BIP 375 does: https://github.com/bitcoin/bips/tree/master/bip-0375

And I recommend you to do it with git subtree add --prefix=bip-0352/secp256k1lab --squash https://github.com/secp256k1lab/secp256k1lab v1.0.0 command, like in: #2087, it is redundant, but is self contained.

For the test implementation, I don't think the spend seckey checks belong here, because they are in the domain of BIP 340.

The test cases I have in mind for now are:

  • Updater adds PSBT_IN_SP_TWEAK.
  • Updater adds PSBT_IN_SP_TWEAK and PSBT_IN_SP_SPEND_BIP32_DERIVATION.
  • Signer sets the PSBT_IN_TAP_KEY_SIG with expected signature for input with PSBT_IN_SP_TWEAK set using PSBT_IN_SP_SPEND_BIP32_DERIVATION.
  • Signer sets the PSBT_IN_TAP_KEY_SIG with expected signature for input with PSBT_IN_SP_TWEAK without PSBT_IN_SP_SPEND_BIP32_DERIVATION field.
  • Signer sets the PSBT_IN_TAP_KEY_SIG with expected signature with d.G odd, for input with PSBT_IN_SP_TWEAK set.
  • Signer fails if the x-coordinate of d.G does not equal the output key in the P2TR output script.
  • Input finalizer fails to verify PSBT_IN_TAP_KEY_SIG for PSBT_IN_SP_TWEAK (i.e., wrong signature).
  • Input finalizer removes PSBT_IN_SP_TWEAK, PSBT_IN_SP_SPEND_BIP32_DERIVATION, PSBT_IN_TAP_KEY_SIG, and PSBT_IN_WITNESS_UTXO fields for an input where PSBT_IN_SP_TWEAK is set, and the PSBT_IN_FINAL_SCRIPTWITNESS is present.

I have been thinking in a way to standarize the PSBT test vectors, following BIP 375 approach, and this is the structure I came up with:

{
  "description": "string", // BIP 376 test vectors
  "version": "string", // "0.1.0"
  "notes": [],
  "cases": [
    {
      "description": "string",
      "psbt": {
        "hex": "string",
        "base64": "string"
      },
      "supplementary": { // Supplementary can hold multiple optional fields, which depend of the case you are testing, I've added the ones already required for signing
        "spend_seckey": "string",
        "message": "string",
        "aux_rand": "string" // I'm not sure about this one, we can do like BIP 340 reference and derive one each time using incremental numbers
        "task": "string", // This is required, but to keep compatibility with BIP 375 test vectors I placed it here. It can be one of [fail, fail_sign, update, finalize]
      }
    }
  ]
}

Comment thread bip-0376/reference.py
import sys
from pathlib import Path

BIP375_DIR = Path(__file__).resolve().parents[1] / "bip-0375"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is brittle, I would do exactly what bip-0375 does and copy the whole secp256k1lab source code in this directory, and then do the Path magic.

Comment thread bip-0376/psbt_bip376.py
assert PSBT_GLOBAL_INPUT_COUNT in self.g.map
assert PSBT_GLOBAL_OUTPUT_COUNT in self.g.map
self.version = struct.unpack("<I", self.g.map[PSBT_GLOBAL_VERSION])[0]
assert self.version in [0, 2]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

BIP 376 is backwards compatible with PSBTv2. It isn't compatible with PSBTv0, as the new fields are marked as excluded.

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 PR by non-owner to update BIP content

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants