#32966 Silent Payments: Receiving

full analysis

https://github.com/bitcoin/bitcoin/pull/32966 · Eunovo · +18954/-165 in 94 files, 41 commits · labels: Needs rebase · draft

Goal

  • Enables Bitcoin Core wallet to receive BIP 352 Silent Payments
  • Lets recipients publish a single static address without compromising privacy through address reuse

This pull request introduces BIP 352 Silent Payments receiving capabilities to the Bitcoin Core wallet. It adds an `sp()` descriptor implementation, a dedicated `SilentPaymentDescriptorScriptPubKeyMan`, full block scanning logic for silent payment outputs, and automatic silent payments change type selection. It also includes the required libsecp256k1 BIP 352 module and tests.

Problem: Traditional Bitcoin addresses cannot be safely reused without severely compromising user privacy and transaction graph unlinkability. Silent payments solve this by allowing recipients to publish a single static address while payers derive unique one-time output keys on-chain.

Category: Utilities (logging, arguments, libraries) (#54 of 66)

P3 · new feature

  • P3 because subtree modifications should be maintained and merged upstream in libsecp256k1 first
  • Adds cryptographic primitives and benchmark tooling needed for BIP 352

Adds BIP 352 elliptic curve cryptographic primitives and benchmark tooling into the codebase. It ranks P3 in utils because subtree modifications are expected to be maintained and merged upstream in libsecp256k1 first.

Membership: Includes an in-tree squashed secp256k1 silentpayments module subtree and adds cryptographic helpers in src/common/bip352.cpp.

Factors: security/stability 1, bug 0, performance 1, user value 2, leverage 1

Category: Wallet (#15 of 84)

P2 · new feature

  • P2 because it provides a high-demand privacy upgrade that prevents address reuse
  • Lays the foundational receiving architecture for Bitcoin Core silent payments support

P2 because BIP 352 receiving is a high-demand privacy upgrade allowing users to receive payments without address reuse. Eunovo stated this PR 'Adds a Silent Payments descriptor implementation', 'Adds a SilentPaymentsDescriptorScriptPubKeyMan', and 'Implements Silent Payments scanning for the wallet', laying the foundational receiving architecture for Core's silent payment roadmap.

Membership: Implements the SilentPaymentDescriptorScriptPubKeyMan, sp() descriptor parsing, block scanning, and wallet change derivation for BIP 352.

Factors: security/stability 1, bug 0, performance 1, user value 3, leverage 2

Reviewability: Stale: Needs rebase

  • Needs rebase, has merge conflicts, and author has been silent for months
  • Review #35301 first and wait for upstream libsecp256k1 support

The PR has merge conflicts with 17 open pull requests, is marked draft, and depends on unmerged base PRs #35301 and upstream libsecp256k1 issue #1799. The author has also been silent for over 120 days.

Author status: silent since 2026-05-16, awaiting upstream libsecp256k1 resolution

Open concerns:

  • Blocked upstream by libsecp256k1 issue #1799 to standardize and release BIP 352 primitives.
  • Fast rescans are disabled for silent payment wallets because block filter indexes cannot predetermine one-time scriptPubKeys.
  • Functional test suggestions regarding descriptor checksum helpers and cleanups need addressing.

Resolved concerns:

  • Simplified key handling by separating the scan private key out of the standard signing provider flow.
  • Handled fallback change output logic when creating transactions from silent-payment-only wallets.
  • Restricted sp() descriptors to single path and added GUI dropdown support for receiving.

Agreement: Strong

  • Strong concept consensus on adding silent payment receiving to the wallet
  • Iteratively tested wallet creation and rescanning across revisions (Sjors)
  • Architectural feedback on key derivation and descriptor structures (josibake)
  • Contributed review feedback on tests (rkrux)

Strong concept consensus with active design collaboration from Sjors and josibake, awaiting upstream dependencies

Multiple domain contributors strongly endorse integrating BIP 352 receiving into the wallet and have iteratively reviewed and tested wallet creation, change generation, and watch-only importing.

  • Sjors tested wallet creation and rescanning across multiple revisions and provided GUI and descriptor integration suggestions.
  • josibake provided detailed architectural feedback on key derivation, provider interfaces, and descriptor structures.
  • rkrux contributed test review comments.

Review verdicts (DrahtBot): 0

Dependencies

Depends on: #35301, #35302

Enables:

  • BIP 352 Silent Payments recipient labels and complete silent payment wallet support

Files

3676 lines under test/bench/ci.

  • src/secp256k1/src/modules/silentpayments/bip352_send_and_receive_test_vectors.json +5729/-0
  • src/secp256k1/src/modules/silentpayments/vectors.h +4550/-0
  • src/test/data/bip352_send_and_receive_vectors.json +2760/-0
  • src/secp256k1/src/modules/silentpayments/tests_impl.h +844/-0
  • src/secp256k1/src/modules/silentpayments/main_impl.h +782/-0
  • src/secp256k1/examples/silentpayments.c +463/-0
  • src/secp256k1/include/secp256k1_silentpayments.h +400/-0
  • test/functional/wallet_silentpayments_receiving.py +391/-0
  • src/common/bip352.cpp +372/-0
  • src/secp256k1/tools/tests_silentpayments_generate.py +301/-0
  • src/wallet/scriptpubkeyman.cpp +249/-2
  • src/wallet/spend.cpp +213/-34
  • src/secp256k1/src/modules/silentpayments/bench_impl.h +227/-0
  • src/test/bip352_tests.cpp +202/-0
  • test/functional/wallet_silentpayments_sending.py +201/-0
  • src/wallet/wallet.cpp +170/-19
  • src/script/descriptor.cpp +175/-2
  • src/common/bip352.h +161/-0
  • src/secp256k1/src/ctime_tests.c +78/-0
  • src/secp256k1/src/bench.c +47/-17
  • src/wallet/walletutil.cpp +53/-11
  • src/wallet/scriptpubkeyman.h +55/-5
  • src/test/descriptor_tests.cpp +52/-0
  • src/key_io.cpp +45/-3
  • src/secp256k1/.github/workflows/ci.yml +28/-18
  • src/wallet/rpc/spend.cpp +29/-1
  • src/wallet/walletdb.cpp +27/-0
  • src/secp256k1/Makefile.am +25/-0
  • src/addresstype.h +20/-1
  • src/wallet/test/wallet_tests.cpp +21/-0
  • src/wallet/wallet.h +14/-7
  • src/key.h +19/-0
  • src/node/interfaces.cpp +13/-3
  • src/secp256k1/configure.ac +14/-0
  • src/validation.cpp +9/-3
  • src/key.cpp +10/-1
  • src/qt/forms/createwalletdialog.ui +10/-0
  • src/test/fuzz/script.cpp +9/-1
  • src/interfaces/chain.h +8/-1
  • src/qt/createwalletdialog.cpp +9/-0
  • src/script/descriptor.h +9/-0
  • src/secp256k1/src/CMakeLists.txt +9/-0
  • src/wallet/rpc/wallet.cpp +8/-1
  • src/wallet/types.h +6/-2
  • src/wallet/walletutil.h +7/-1
  • src/rpc/util.cpp +7/-0
  • src/secp256k1/src/tests.c +7/-0
  • src/secp256k1/src/bench.h +3/-3
  • src/secp256k1/src/modules/musig/session_impl.h +2/-4
  • src/test/policyestimator_tests.cpp +3/-3
  • src/validationinterface.cpp +3/-3
  • src/wallet/rpc/backup.cpp +5/-1
  • test/functional/wallet_fast_rescan.py +6/-0
  • src/addresstype.cpp +5/-0
  • src/kernel/chainparams.cpp +5/-0
  • src/outputtype.cpp +5/-0
  • src/secp256k1/src/modules/silentpayments/Makefile.am.include +5/-0
  • src/test/fuzz/util.cpp +5/-0
  • src/validationinterface.h +3/-2
  • src/secp256k1/examples/CMakeLists.txt +4/-0
  • src/secp256k1/src/secp256k1.c +4/-0
  • src/test/fuzz/package_eval.cpp +2/-2
  • src/test/transaction_tests.cpp +2/-2
  • src/wallet/coincontrol.h +3/-1
  • src/wallet/interfaces.cpp +4/-0
  • src/interfaces/wallet.h +3/-0
  • src/qt/receivecoinsdialog.cpp +3/-0
  • src/qt/walletcontroller.cpp +3/-0
  • src/secp256k1/ci/ci.sh +2/-1
  • src/test/fuzz/util/wallet.h +2/-1
  • src/wallet/rpc/addresses.cpp +2/-1
  • src/wallet/walletdb.h +3/-0
  • src/kernel/chainparams.h +2/-0
  • src/outputtype.h +2/-0
  • src/policy/fees/block_policy_estimator.cpp +1/-1
  • src/policy/fees/block_policy_estimator.h +1/-1
  • src/secp256k1/CMakeLists.txt +2/-0
  • src/secp256k1/README.md +2/-0
  • src/secp256k1/ci/linux-debian.Dockerfile +1/-1
  • src/test/CMakeLists.txt +2/-0
  • src/test/fuzz/tx_pool.cpp +1/-1
  • src/wallet/spend.h +2/-0
  • src/zmq/zmqnotificationinterface.cpp +1/-1
  • src/zmq/zmqnotificationinterface.h +1/-1
  • test/functional/rpc_getdescriptorinfo.py +2/-0
  • test/functional/test_runner.py +2/-0
  • test/functional/wallet_anchor.py +1/-1
  • src/CMakeLists.txt +1/-0
  • src/bech32.h +1/-0
  • src/pubkey.cpp +0/-1
  • src/qt/createwalletdialog.h +1/-0
  • src/rpc/client.cpp +1/-0
  • src/secp256k1/.gitignore +1/-0
  • src/wallet/test/util.cpp +1/-0

Uncertainties

  • Whether the secp256k1 subtree commits will be separated cleanly into an upstream dependency bump prior to rebasing this PR.

Card

This pull request implements BIP 352 Silent Payments receiving for the Bitcoin Core wallet. It introduces the sp() descriptor, a dedicated ScriptPubKeyMan to manage keys and tweaks, full block scanning routines, and automated silent payments change handling. This represents a significant user privacy enhancement by eliminating address reuse for incoming transactions. Review is currently blocked by merge conflicts and upstream libsecp256k1 dependency work in issue #1799.

Data

dossier JSON · extract JSON · model openrouter/google/gemini-3.8-flash, generated 2026-09-17T15:49, confidence high, input hash 4a9588831aa09450