# BIP-352 Silent Payments -- independent verification log # CypherpunkGuide (cypherpunkguide.com). Reproduced 2026-07-09. # # We implemented BIP-352's core derivation ourselves (Python 3.12 + # coincurve / libsecp256k1) and checked it against the official # bitcoin/bips test vectors. No wallet, no network -- pure derivation. # # Reproduce: # pip install coincurve # curl -sL https://cdn.jsdelivr.net/gh/bitcoin/bips@master/bip-0352/send_and_receive_test_vectors.json -o bip352_test_vectors.json # python bip352_verify.py # all official test vectors # python bip352_trace.py # one payment, traced by hand + the privacy demo # ============================ VERIFY (test vectors) ============================ [27] Maximum per-group recipient limit K_max is exceeded (2324 ma === BIP-352 self-implementation vs official vectors === sending sub-cases : 28/28 pass receiving sub-cases: 29/29 pass total wall time: 179.1 ms (coincurve/libsecp256k1, pure derivation) ============================ TRACE (one payment) ============================= ======================================================================== BIP-352 Silent Payments -- reproduced from scratch (coincurve/libsecp256k1) Key material: public BIP-352 test vectors. No network, no wallet. ======================================================================== One published address (never changes, safe to post in bio/README): sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv (116 chars) ------------------------------------------------------------------------ SENDER A derives a unique on-chain output (BIP-352 sender algorithm): a (sum of input priv keys) = 7ed265a6dac7aba8508a32d6d6b84c7f1dbd0a0941dd01088d69e8d556345f86 A (sum of input pub keys) = 032562c1ab2d6bd45d7ca4d78f569999e5333dffd3ac5263924fd00d00dedc4bee input_hash = H(outpoint||A) = 5bfe5321d759e01a2ac9292f0f396ff9c3d8b58d89ccb21a6922e84bb7ad0668 ecdh = input_hash*a*B_scan = 028158aff7d61ea66b2fa7f555bc3c5937d1debbde16423d630f9aa7943e14d80d t0 = H(ecdh||0) = f438b40179a3c4262de12986c0e6cce0634007cdc79c1dcd3e20b9ebc2e7eef6 OUTPUT = B_spend + t0*G = 3e9fce73d4e77a4809908e3c3a2e54ee147b9312dc5044a193d1fc85de46e3c1 -> receiver scan finds it: True (spend tweak f438b40179a3c426...) ------------------------------------------------------------------------ SENDER B -- a different person, paying the SAME published address: A (sum of input pub keys) = 03f028892bad7ed57d2fb57bf33081d5cfcf6f9ed3d3d7f159c2e2fff579dc341a ecdh = input_hash*a*B_scan = 0328d18895577666a5bbedb5e4174c3b6040b719b26d5b3738dc98fe2ea3100125 OUTPUT = B_spend + t0*G = 3f1dd702e5c3d5f252d2fd32a65270fe2ad6fe17b3acb53dc1053b19879b98ad -> receiver scan finds it: True (spend tweak 190ffb9be135b396...) ======================================================================== THE PRIVACY PROPERTY (verify it yourself above): Same address, two payers. On-chain outputs: A -> 3e9fce73d4e77a4809908e3c3a2e54ee147b9312dc5044a193d1fc85de46e3c1 B -> 3f1dd702e5c3d5f252d2fd32a65270fe2ad6fe17b3acb53dc1053b19879b98ad Identical? False Any shared address on-chain? None. An observer watching the chain sees two unrelated Taproot outputs. Only the holder of scan_priv can link them back to one address. ========================================================================