-
Notifications
You must be signed in to change notification settings - Fork 37.7k
[Draft/POC] Add secp256k1-based HPKE (Hybrid Public Key Encryption) For Payjoin v2 #32617
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code Coverage & BenchmarksFor details see: https://corecheck.dev/bitcoin/bitcoin/pulls/32617. ReviewsSee the guideline for information on the review process. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
65acaaa
to
9183a8e
Compare
🚧 At least one of the CI tasks failed. HintsTry to run the tests locally, according to the documentation. However, a CI failure may still
Leave a comment here, if you need help tracking down a confusing failure. |
This comment was marked as abuse.
This comment was marked as abuse.
The main reason for the Bitcoin Core wallet to support payjoin directly is to reduce the number of necessary dependencies for those already using the core wallet. In particular rust-payjoin requires TLS (which is optional for the protocol) and rust implementations of cryptographic primatives that core could avoid with a bespoke implementation. |
Fore more context to reviewers, could add a link to BIP 77 in the PR description, particularly to the cryptography part: https://github.com/bitcoin/bips/blob/master/bip-0077.md#secp256k1-hybrid-public-key-encryption
Do we need all of the four modes for Payjoin v2 support? Didn't look in-depth yet, but at least BIP77 contains only the two modes "Base" and "Auth" explicitly (and no mentions of "PSK"): |
Good catch. I still need to verify whether |
I can confirm that neither BIP 77 nor the rust-payjoin implementations depend on the PSK functionality. There are ideas for future extensions that might make use of that, but they are only ideas at this point and would not be a part of BIP 77 itself. |
🐙 This pull request conflicts with the target branch and needs rebase. |
This PR introduces an implementation of Hybrid Public Key Encryption (HPKE) using a secp256k1-based Diffie-Hellman KEM (per RFC 9180 and "secp256k1-based DHKEM for HPKE" specification). It provides the core cryptographic component needed to enable the Payjoin v2 protocol.
This is an exploratory PR intended to kickstart discussion on adding Payjoin v2 support to Bitcoin Core – feedback and reviews are very welcome.
Payjoin v2 makes use of a protocol called Oblivious HTTP (OHTTP) to strip client-identifying metadata from the request. This protocol use a binary-encoded HTTP message encapsulated through HPKE.
The core implementation is contained in the new files
src/dhkem_secp256k1.h
andsrc/dhkem_secp256k1.cpp
:Base
,PSK
,Auth
, andAuthPSK
.Encap()
andDecap()
functions perform the base mode KEM (ephemeral ECDH using the receiver’s public key), whileAuthEncap()
andAuthDecap()
extend this to authenticated mode (including the sender’s static key in the shared secret derivation). Internally, the shared secret is derived as specified by HPKE using HKDF (SHA256) extraction and expansion.encryption key
,base nonce
, andexporter secret
. It follows RFC 9180 §7.1, hashing theinfo
andpsk_id
contexts and deriving the AEAD key and nonce. Per-message nonces are computed by XOR-ing the base nonce with a message sequence number as specified in RFC 9180 §5.2.ChaCha20-Poly1305
as the authenticated encryption scheme. The code providesSeal()
andOpen()
functions to encrypt and decrypt data using the derived context key and a given nonce. It uses Bitcoin Core’s existing ChaCha20Poly1305 implementation.The test file validates all the functions mentioned above: Encapsulation/Decapsulation, Encryption/Decryption, Nonce and Key Schedule Logic. This uses the PDK (Payjoin Dev Kit) test vectors. The tests also show how to use the HPKE functions.
This implementation only uses HKDF-SHA256 as Key Derivation Functions and ChaCha20-Poly1305 as AEAD, since these already exist in the Bitcoin Core codebase. It does not support other KDFs (such as HKDF-SHA384 and HKDF-SHA512) or other AEADs (such as AES-128-GCM and AES-256-GCM).
To run the tests:
build/bin/test_bitcoin --log_level=all --run_test=dhkem_secp256k1_tests