mirror of
https://github.com/bitcoin/bips.git
synced 2025-10-10 04:44:17 +02:00
directory -> mailbox
This commit is contained in:
@@ -19,10 +19,10 @@
|
||||
This document proposes a backwards-compatible second version of the Payjoin protocol described in
|
||||
[[bip-0078.mediawiki|BIP 78]], allowing complete Payjoin receiver functionality, including payment output
|
||||
substitution, without requiring a receiver to host a secure public endpoint. This requirement is replaced with an
|
||||
untrusted third-party directory accessed via HTTP clients that communicate using an asynchronous protocol
|
||||
untrusted third-party "mailroom" server accessed via HTTP clients that communicate using an asynchronous protocol
|
||||
and authenticated, encrypted payloads. Authenticated encryption depends only on cryptographic primitives
|
||||
available in Bitcoin Core. Requests use [[https://www.ietf.org/rfc/rfc9458.html| Oblivious HTTP]] to prevent
|
||||
the directory and Payjoin peers from linking requests to client IP addresses.
|
||||
the mailroom and Payjoin peers from linking requests to client IP addresses.
|
||||
|
||||
==Copyright==
|
||||
|
||||
@@ -64,13 +64,13 @@ URIs. Because BIP 78 messages relayed over an unsecured server are neither end-t
|
||||
encrypted between sender and receiver, a malicious unsecured Payjoin server is able to modify the Proposal
|
||||
PSBT in flight, thus requiring payment output substitution to be disabled. Output substitution is useful for
|
||||
a number of block space optimizations, including payment batching and transaction cut-through. This proposal
|
||||
introduces authentication and encryption to secure output substitution by using a directory server without
|
||||
introduces authentication and encryption which secure output substitution while relying on a mailbox server without
|
||||
compromising sender or receiver privacy.
|
||||
|
||||
Although unsecured Payjoin server separation is mentioned in BIP 78, no known specification or implementation
|
||||
exists. This document specifies a way to use the Payjoin directory as an unsecured backwards compatible server
|
||||
exists. This document specifies a mailbox server as an unsecured backwards compatible server
|
||||
for version 1 senders. Receivers responding to version 1 senders must disable output substitution, since their
|
||||
payloads are saved in plaintext, so that they may payjoin without the risk of the directory, acting as a
|
||||
payloads are saved in plaintext, so that they may payjoin without the risk of the mailbox server, acting as a
|
||||
version 1 unsecured Payjoin server, stealing funds.
|
||||
|
||||
The protocols in this document reuse BIP 78's BIP 21 URI parameters. An "Original PSBT" timeout parameter is
|
||||
@@ -80,8 +80,8 @@ introduced which may also help coordinate the synchronous version 1 protocol.
|
||||
|
||||
[[https://docs.samourai.io/en/spend-tools#stowaway| Stowaway]] was a Payjoin coordination mechanism that
|
||||
depended on Tor, a third-party relay, and the [[https://paynym.is| PayNym]] [[https://github.com/bitcoin/bips/
|
||||
blob/master/bip-0047.mediawiki| BIP 47]] "payment codes" directory for subdirectory identification and
|
||||
encryption. The Payjoin version 2 protocol uses per-request public keys for relay subdirectory identification,
|
||||
blob/master/bip-0047.mediawiki| BIP 47]] "payment codes" server for peer identification and
|
||||
encryption. The Payjoin version 2 protocol uses per-request public keys for peer identification,
|
||||
authentication, and encryption instead of BIP 47 public keys derived from a wallet. Payjoin version 2 also
|
||||
supports asynchronous messaging, in contrast to Stowaway's synchronous messaging. Offline Stowaway depends on
|
||||
manual message passing rather than an asynchronous network protocol. Successful Stowaway execution results in
|
||||
@@ -92,46 +92,45 @@ manual message passing rather than an asynchronous network protocol. Successful
|
||||
===Overview===
|
||||
|
||||
Payjoin requests are made using familiar BIP 21 URIs. Instead of a public HTTP endpoint, this scheme allows
|
||||
an HTTP client to initiate a Payjoin Session at a store-and-forward directory server to send and receive
|
||||
Payjoin messages. Directories may optionally require an authorization credential before allocating resources
|
||||
in order to prevent DoS attacks. Sender and receiver payloads are buffered at the directory to support
|
||||
asynchronous interaction. Authenticated encryption prevents the directory from snooping on message contents
|
||||
an HTTP client to initiate a Payjoin Session at a store-and-forward mailroom server to send and receive
|
||||
Payjoin messages. Mailrooms may optionally require an authorization credential before allocating resources
|
||||
in order to prevent DoS attacks. Sender and receiver payloads are buffered at the mailroom to support
|
||||
asynchronous interaction. Authenticated encryption prevents the mailroom from snooping on message contents
|
||||
or forging messages by way of HPKE. Oblivious HTTP is required for version 2 interactions in order to separate
|
||||
client IP addresses from the directory to prevent metadata attacks. Aside from application layer authenticated
|
||||
client IP addresses from the mailroom to prevent metadata attacks. Aside from application layer authenticated
|
||||
encryption and relayed asynchronous networking, version 2 messaging takes much the same form as the existing
|
||||
BIP 78 specification.
|
||||
|
||||
===Basic scheme===
|
||||
|
||||
The receiver first generates a 256-bit keypair. This key will be the basis of end-to-end authenticated
|
||||
encryption and identification of a particular payjoin over the directory.
|
||||
encryption and identification of a particular mailbox in the mailroom.
|
||||
|
||||
Rather than hosting a public server itself, the receiver specifies a Payjoin Session associated with their
|
||||
keypair's public key. This public key, compressed, hashed, truncated to 8 bytes, and bech32 encoded without a
|
||||
checksum [[#short-id| short ID]], is used to identify a store-and-forward Session subdirectory on the Payjoin
|
||||
Directory server and establishes end-to-end encryption. As long as a Session is active, the receiver long
|
||||
polls GET requests to this subdirectory to await a payjoin request to a Payjoin Session from the sender. Out
|
||||
checksum [[#short-id| short ID]], is used to identify a store-and-forward mailbox on the
|
||||
mailroom server and establish end-to-end encryption. As long as a Session is active, the receiver long
|
||||
polls GET requests to this mailbox to await a message from the sender. Out
|
||||
of band, the receiver shares a [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP 21]]
|
||||
Payjoin URI including the subdirectory endpoint in the <code>pj=</code> query parameter and a new Oblivious
|
||||
HTTP <code>ohttp=</code> fragment parameter including the Payjoin Directory's [[https://www.ietf.org/rfc/
|
||||
Payjoin URI including the mailbox endpoint in the <code>pj=</code> query parameter and a new Oblivious
|
||||
HTTP <code>ohttp=</code> fragment parameter including the Payjoin Mailroom's [[https://www.ietf.org/rfc/
|
||||
rfc9458.html#name-key-configuration| OHTTP Key Configuration]].
|
||||
|
||||
The sender constructs an [[https://www.rfc-editor.org/rfc/rfc9180.html#name-authentication-using-an-asy| HPKE
|
||||
Auth mode]] payload containing a PSBT and optional parameters similar to BIP 78. The resulting ciphertext
|
||||
ensures message secrecy and integrity when passed to the receiver using the subdirectory <code>pj=</code>
|
||||
ensures message secrecy and integrity when passed to the receiver using the mailbox <code>pj=</code>
|
||||
endpoint.
|
||||
|
||||
The receiver augments the Sender's PSBT with new inputs and outputs, and may adjust the fee. The receiver then
|
||||
encrypts the resulting PSBT and sends it back to the sender by POSTing it to a new subdirectory derived from
|
||||
encrypts the resulting PSBT and sends it back to the sender by POSTing it to a new mailbox derived from
|
||||
the sender's reply key shared in their payload along with their original PSBT.
|
||||
|
||||
The sender will be long polling this second subdirectory for a response from the receiver. Upon receipt, the
|
||||
The sender will be long polling this second mailbox for a response from the receiver. Upon receipt, the
|
||||
sender validates the receiver's Proposal PSBT, and if satisfied, signs its inputs and broadcasts the
|
||||
transaction to the Bitcoin network.
|
||||
|
||||
Messages are secured by symmetric cipher rather than TLS or Onion routing session key. Sender and receiver may
|
||||
experience network interruption and proceed with the protocol since their request and response are buffered at
|
||||
the Payjoin Directory.
|
||||
experience network interruption and proceed with the protocol since their request and response are buffered in the mailroom.
|
||||
|
||||
====Sequence Diagram====
|
||||
|
||||
@@ -140,13 +139,12 @@ Key:
|
||||
|-----> Single transmission
|
||||
|- - -> Polled transmission
|
||||
|
||||
+----------+ +-----------+ +--------+ +---------+
|
||||
| Receiver | | Directory | | Sender | | Network |
|
||||
+----------+ +-----------+ +--------+ +---------+
|
||||
+----------+ +----------+ +--------+ +---------+
|
||||
| Receiver | | Mailroom | | Sender | | Network |
|
||||
+----------+ +----------+ +--------+ +---------+
|
||||
| | | |
|
||||
| | | |
|
||||
| destination (address, | | |
|
||||
| subdirectory) | | |
|
||||
| destination (address, mailbox) | | |
|
||||
+---------------------------------------------------->| |
|
||||
| | | |
|
||||
| GET Request Original PSBT | | |
|
||||
@@ -179,26 +177,26 @@ The Payjoin version 2 protocol takes the following steps:
|
||||
The <code>pj</code> URL path ends with the [[#short-id| short ID]], [[https://datatracker.ietf.org/doc/html/
|
||||
rfc4648#section-5| base64url-encoded]] followed by the [[#receiver-fragment-parameters| receiver fragment
|
||||
parameters]].
|
||||
* To support version 1 senders, the directory acts as an unsecured Payjoin server, so <code>pjos=0</code>
|
||||
* To support version 1 senders, the mailroom acts as an unsecured Payjoin server, so <code>pjos=0</code>
|
||||
must be specified in the URI. Version 2 senders may safely allow output substitution regardless.
|
||||
* The sender creates a valid version 0 PSBT satisfying the [[https://github.com/bitcoin/bips/blob/master/bip-
|
||||
0078.mediawiki#receivers-original-psbt-checklist| the receiver checklist]]. We call this the <code>Original
|
||||
PSBT</code>. This <code>Original PSBT</code>, and optional sender parameters, are wrapped in HPKE authenticated
|
||||
encryption, including a sender session public key as associated data, and encapsulates it all as OHTTP. This
|
||||
[[#send-messaging| Original PSBT Request send message]] is made to the directory's OHTTP Gateway. The request
|
||||
is stored in the receiver subdirectory.
|
||||
* The sender polls GET requests to the subdirectory defined by the sender's Payjoin Session public key short
|
||||
ID in order to await a response from the directory containing a <code>Proposal PSBT</code>. It stops polling
|
||||
[[#send-messaging| Original PSBT Request send message]] is made to the mailroom's OHTTP Gateway. The request
|
||||
is stored in the receiver mailbox.
|
||||
* The sender polls GET requests to the mailbox defined by the sender's Payjoin Session public key short
|
||||
ID in order to await a response from the mailroom containing a <code>Proposal PSBT</code>. It stops polling
|
||||
after expiry.
|
||||
* Once the receiver is online, it sends <code>GET</code> requests [[#receive-messaging| to the receiver
|
||||
subdirectory]] requests to the subdirectory. The receiver decrypts and authenticates the response, which it
|
||||
mailbox]] requests to the mailbox. The receiver decrypts and authenticates the response, which it
|
||||
checks according to [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-
|
||||
checklist| the receiver checklist]]. The receiver updates the Original PSBT to include new signed inputs and
|
||||
outputs, invalidating sender signatures, and may adjust the fee. The result is called the <code>Proposal
|
||||
PSBT</code>.
|
||||
* The <code>Proposal PSBT</code> and HPKE keys are encrypted, authenticated, encapsulated in OHTTP, and POSTed
|
||||
to the sender's subdirectory via the directory's OHTTP Gateway.
|
||||
* The directory awaits a GET request from the sender. Upon request, the directory relays the encrypted
|
||||
to the sender's mailbox via the mailroom's OHTTP Gateway.
|
||||
* The mailroom awaits a GET request from the sender. Upon request, the mailroom relays the encrypted
|
||||
<code>Proposal PSBT</code>.
|
||||
* The sender validates the <code>Proposal PSBT</code> according to [[#senders-proposal-psbt-checklist|the
|
||||
sender checklist]], signs its inputs and broadcasts the transaction to the Bitcoin network.
|
||||
@@ -235,14 +233,14 @@ The Proposal PSBT MUST NOT:
|
||||
Sessions between senders and receivers are established out of band when a receiver shares a Payjoin URI
|
||||
containing its Payjoin Session public key with a sender.
|
||||
|
||||
A receiver must first discover the directory's OHTTP Gateway Key Configuration via an authenticated bootstrap
|
||||
A receiver must first discover the mailroom's OHTTP Gateway Key Configuration via an authenticated bootstrap
|
||||
mechanism before it can initialize a Session to receive payjoin requests. This mechanism may vary by
|
||||
implementation but must follow [[https://datatracker.ietf.org/doc/html/draft-ietf-privacypass-key-consistency-
|
||||
01| OHTTP Consistency Requirements]] and should not reveal a receiver IP address to the directory. Some
|
||||
01| OHTTP Consistency Requirements]] and should not reveal a receiver IP address to the mailroom. Some
|
||||
examples of suitable mechanisms include fetching over a VPN, using keys included with an application binary,
|
||||
https-in-http CONNECT method, https-in-WebSocket, or a Tor hidden service.
|
||||
|
||||
If a directory is subject to denial of service attacks, it may require [[https://datatracker.ietf.org/doc/html/
|
||||
If a mailroom is subject to denial of service attacks, it may require [[https://datatracker.ietf.org/doc/html/
|
||||
rfc6750| RFC 6750]] authorization and otherwise respond with <code>401</code> unauthorized responses to
|
||||
requests. Authorization tokens must be unlinkable to preserve client privacy. A specific unlinkable
|
||||
authorization token mechanism is out of the scope of this proposal.
|
||||
@@ -251,25 +249,25 @@ authorization token mechanism is out of the scope of this proposal.
|
||||
|
||||
The Original PSBT is serialized in base64, followed by the query parameter string on a new line. This plaintext
|
||||
string is encrypted according to HPKE using a shared secret derived from the sender's Payjoin Session public
|
||||
key combined with the receiver's subdirectory Payjoin Session public key. The resulting HPKE payload body is
|
||||
then encapsulated according to Oblivious HTTP as a POST request to the directory's OHTTP Gateway to the
|
||||
receiver's payjoin session subdirectory.
|
||||
key combined with the receiver's mailbox Payjoin Session public key. The resulting HPKE payload body is
|
||||
then encapsulated according to Oblivious HTTP as a POST request to the mailroom's OHTTP Gateway to the
|
||||
receiver's mailbox.
|
||||
|
||||
Upon receipt, the directory's OHTTP Gateway decapsulates the OHTTP request and handles the inner POST request
|
||||
at the receiver's Payjoin Session subdirectory endpoint, which stores the HPKE encrypted payload to be
|
||||
Upon receipt, the mailroom's OHTTP Gateway decapsulates the OHTTP request and handles the inner POST request
|
||||
at the receiver's Payjoin Session mailbox endpoint, which stores the HPKE encrypted payload to be
|
||||
forwarded to the receiver.
|
||||
|
||||
The sender then polls GET requests to the sender's Payjoin Session subdirectory endpoint in order to await a
|
||||
response from the directory containing a <code>Proposal PSBT</code>. It stops polling after expiry.
|
||||
The sender then polls GET requests to the sender's Payjoin Session mailbox endpoint in order to await a
|
||||
response from the mailroom containing a <code>Proposal PSBT</code>. It stops polling after expiry.
|
||||
|
||||
====Receive Messaging====
|
||||
|
||||
After sharing the Payjoin URI with the sender, the receiver sends a GET request to the path of the receiver's
|
||||
Payjoin Session subdirectory. This request is encapsulated in OHTTP. It continues to poll by sending a new
|
||||
OHTTP request after receiving an encapsulated 202 ACCEPTED response notifying the receiver that the directory
|
||||
Payjoin Session mailbox. This request is encapsulated in OHTTP. It continues to poll by sending a new
|
||||
OHTTP request after receiving an encapsulated 202 ACCEPTED response notifying the receiver that the mailroom
|
||||
has not yet received a request from the sender.
|
||||
|
||||
Upon receiving OHTTP response from the directory encapsulating a request from the sender with status code 200
|
||||
Upon receiving OHTTP response from the mailroom encapsulating a request from the sender with status code 200
|
||||
OK, the receiver decrypts the payload and checks the <code>Proposal PSBT</code> according to the [[#receivers-
|
||||
proposal-psbt-checklist|checklist]].
|
||||
|
||||
@@ -281,8 +279,8 @@ keypair from which it derives a shared secret with the sender's Payjoin Session
|
||||
It generates a nonce from sufficient randomness, and constructs a ciphertext containing the Proposal PSBT and
|
||||
serialized receiver ephemeral key <code>e</code>'s public key as associated data using ChaCha20Poly1305. A
|
||||
payload is constructed by concatenating the ephemeral public key, the nonce, and the ciphertext. This Proposal
|
||||
PSBT payload is then sent as a POST message to the directory in an OHTTP request encapsulating the binary
|
||||
payload to the sender's Payjoin Session subdirectory.
|
||||
PSBT payload is then sent as a POST message to the mailroom in an OHTTP request encapsulating the binary
|
||||
payload to the sender's Payjoin Session mailbox.
|
||||
|
||||
===Receiver's Original PSBT checklist===
|
||||
|
||||
@@ -298,24 +296,24 @@ script types are allowed, and it expects all UTXO data to be filled in. BIP 78 r
|
||||
to be excluded from the PSBT, which has caused many issues, as it required the sender to add them back to the
|
||||
Payjoin proposal PSBT. Version 2 has no such requirement.
|
||||
|
||||
===Directory interactions===
|
||||
===Mailroom interactions===
|
||||
|
||||
The Payjoin Directory provides a rendezvous point for sender and receiver to meet. The directory stores Payjoin
|
||||
payloads to support asynchronous communication. The directory must only accept OHTTP requests with an OHTTP
|
||||
Gateway for Payjoin version 2, accepting encrypted payloads. The directory may optionally accept HTTP/1.1 POST
|
||||
requests without OHTTP to Payjoin Session subdirectories for backwards compatibility with Payjoin version 1 requests.
|
||||
The Payjoin Mailroom provides a rendezvous point for sender and receiver to meet. The mailroom stores Payjoin
|
||||
payloads to support asynchronous communication. The mailroom must only accept OHTTP requests with an OHTTP
|
||||
Gateway for Payjoin version 2, accepting encrypted payloads. The mailroom may optionally accept HTTP/1.1 POST
|
||||
requests without OHTTP to mailbox URLs for backwards compatibility with Payjoin version 1 requests.
|
||||
|
||||
===Subdirectories===
|
||||
===Mailboxes===
|
||||
|
||||
Each Payjoin Session subdirectory allocated on the directory has one buffer for a PSBT payload. The buffer
|
||||
Each Payjoin Session mailbox allocated in the mailroom has one buffer for a PSBT payload. The buffer
|
||||
updates listeners through awaitable events so that updates are immediately apparent upon client request.
|
||||
|
||||
====Short ID====
|
||||
|
||||
Short IDs are an 8-byte identifier for a Payjoin Session subdirectory. They are generated by hashing a
|
||||
Short IDs are an 8-byte identifier for a Payjoin Session mailbox. They are generated by hashing a
|
||||
compressed secp256k1 public key with Sha256, truncating it to 8 bytes, and encoding it in bech32 with the HRP
|
||||
"ID". The Short ID HRP prefix (including the '1' separator) "ID1" is stripped from the bech32 encoded uppercase
|
||||
string before it is used as the subdirectory identifier.
|
||||
string before it is used as the mailbox identifier.
|
||||
|
||||
64 bits are sufficient to make the probability of experiencing a random collisions negligible. As of writing,
|
||||
the UTXO set has ~2^28 elements. This is a very loose upper bound for the number of concurrent (non-spam)
|
||||
@@ -334,9 +332,9 @@ Instead of defining new [[https://github.com/bitcoin/bips/blob/master/bip-0021.m
|
||||
parameters, Payjoin version 2 encodes parameters in the [[https://datatracker.ietf.org/doc/html/rfc3986#section-
|
||||
3.5| fragment]] of the URL following the <code>pj=</code> parameter in the BIP 21 URI. They follow the
|
||||
<code>#</code> as bech32 parameters separated by a <code>+</code> character. In order to simplify parsing and
|
||||
allow QR encoders to use alphanumeric QR mode wherever possible, the <code>pj</code> parameter subdirectory and
|
||||
allow QR encoders to use alphanumeric QR mode wherever possible, the <code>pj</code> parameter mailbox and
|
||||
fragment that follows must be uppercased and should come as the last parameter of the URI. Since URLs are case
|
||||
sensitive, path elements of a payjoin-directory may be lowercased but SHOULD be configured to be uppercased.
|
||||
sensitive, path elements of a mailroom URL may be lowercased but SHOULD be configured to be uppercased.
|
||||
|
||||
The '#' fragment separator character must be [[https://datatracker.ietf.org/doc/html/rfc3986| RFC 3986]]
|
||||
percent-encoded as '%23' according to BIP 21.
|
||||
@@ -346,8 +344,8 @@ according to their role:
|
||||
|
||||
* <code>RK</code>: represents the receiver's Payjoin Session public key. This is a compressed public key of the
|
||||
receiver's Payjoin Session. Senders will initiate HPKE with the receiver using this key.
|
||||
* <code>OH</code>: represents the OHTTP Key Configuration of the directory. This is a compressed public key of
|
||||
the directory's OHTTP Gateway, prefixed by the 2-byte Key Identifier, from which the [[https://www.ietf.org/rfc/
|
||||
* <code>OH</code>: represents the OHTTP Key Configuration of the mailroom. This is a compressed public key of
|
||||
the mailroom's OHTTP Gateway, prefixed by the 2-byte Key Identifier, from which the [[https://www.ietf.org/rfc/
|
||||
rfc9458.html#section-3.1| RFC 9458 Key Configuration can be constructed]]. This parameter is required for Payjoin
|
||||
version 2 URIs.
|
||||
* <code>EX</code>: represents a request expiration in [[https://pubs.opengroup.org/onlinepubs/9699919799/
|
||||
@@ -376,7 +374,7 @@ BIP 78's optional query parameters are also valid as version 2 parameters.
|
||||
|
||||
===Request expiration & Original PSBT===
|
||||
|
||||
The directory may hold a request for an offline payjoin peer until that peer comes online. However, the BIP 78
|
||||
The mailroom may hold a request for an offline payjoin peer until that peer comes online. However, the BIP 78
|
||||
spec [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receiver-does-not-need-to-be-a-full-node|
|
||||
recommends]] broadcasting Original PSBTs in the case of an offline counterparty. Doing so exposes a naïve,
|
||||
surveillance-vulnerable transaction which Payjoin intends to avoid.
|
||||
@@ -394,8 +392,8 @@ WebSockets protocol, plain HTTP can benefit from metadata protection by using Ob
|
||||
|
||||
===Oblivious HTTP===
|
||||
|
||||
OHTTP protects sender and receiver IP addresses both from one another and from the directory. This makes it
|
||||
more difficult for a directory to correlate many payjoin transactions with specific IP addresses by
|
||||
OHTTP protects sender and receiver IP addresses both from one another and from the mailroom. This makes it
|
||||
more difficult for a mailroom to correlate many payjoin transactions with specific IP addresses by
|
||||
intersection.
|
||||
|
||||
OHTTP relays can be run as basic HTTP proxies from wallet providers or third parties.
|
||||
@@ -406,7 +404,7 @@ OHTTP relays can be run as basic HTTP proxies from wallet providers or third par
|
||||
|
||||
===Uniform Payloads===
|
||||
|
||||
Encapsulated OHTTP payloads and messages seen by the Payjoin Directory are constructed to be uniform so that
|
||||
Encapsulated OHTTP payloads and messages seen by the mailroom are constructed to be uniform so that
|
||||
the third-party services are unable to distinguish between them based on payload size or by distinguishing
|
||||
them from random bytes. However, the Encapsulated OHTTP message includes an uncompressed key for the DHKEM
|
||||
which is distinguishable from random bytes but uniform across different encapsulated requests.
|
||||
@@ -414,13 +412,13 @@ which is distinguishable from random bytes but uniform across different encapsul
|
||||
OHTTP messages are padded to 8192 bytes.
|
||||
|
||||
HPKE message payloads are padded to 7168 bytes. Elligator swift is used to encode encapsulated HPKE public keys
|
||||
prepended to the HPKE ciphertext so that the payjoin directory can't distinguish between key material, the
|
||||
ciphertext, and randomness, so that the directory may accommodate new protocols in the future without
|
||||
prepended to the HPKE ciphertext so that the mailroom can't distinguish between key material, the
|
||||
ciphertext, and randomness, so that the mailroom may accommodate new protocols in the future without
|
||||
discrimination.
|
||||
|
||||
This is sufficient size for most PSBTs without exceeding the [[https://www.geekersdigest.com/max-http-request-
|
||||
header-size-server-comparison/| 8KB limit]] of many HTTP/1.1 web servers. 8KB is also too small for image
|
||||
sharing, making misuse of the Payjoin Directory impractical.
|
||||
sharing, making misuse of the mailroom impractical.
|
||||
|
||||
====Message Byte Representations====
|
||||
|
||||
@@ -472,7 +470,7 @@ noiseprotocol.org/noise.html#zero-rtt-and-noise-protocols| zero-RTT]] version of
|
||||
org/noise.html| Noise Framework]] [[https://noiseexplorer.com/patterns/IK/| IK]] pattern. A receiver shares its
|
||||
public key out of band in the BIP 21 URI. Static keys shared in URIs must only be used for a single Payjoin
|
||||
Session. The key is encoded in [[https://datatracker.ietf.org/doc/html/rfc4648#section-5| base64url]] encoding
|
||||
as a Payjoin Directory subdirectory in the <code>pj=</code> parameter.
|
||||
as a mailbox URL fragment in the <code>pj=</code> parameter.
|
||||
|
||||
====Secp256k1-based DHKEM====
|
||||
|
||||
@@ -497,9 +495,9 @@ SHA-256 is considered secure and is necessarily available in bitcoin contexts.
|
||||
In addition to the attack vectors and mitigations in [[https://github.com/bitcoin/bips/blob/master/bip-0078.
|
||||
mediawiki#attack-vectors| BIP 78 Payjoin version 1]], Payjoin version 2 has the following attack vectors.
|
||||
|
||||
Since directories store arbitrary encrypted payloads they are vulnerable to the tragedy of the commons and
|
||||
denial of service attacks. To mitigate such attacks, directory operators may impose an authentication
|
||||
requirement before they allocate a Payjoin Session subdirectory to receivers.
|
||||
Since each mailbox stores arbitrary encrypted payloads they are vulnerable to the tragedy of the commons and
|
||||
denial of service attacks. To mitigate such attacks, mailroom operators may impose an authentication
|
||||
requirement before they allocate a Payjoin Session mailbox to receivers.
|
||||
|
||||
Since we make use of 0-RTT HPKE, the first message containing the sender's Original PSBT has minimal forward
|
||||
secrecy. If the receiver's key is compromised, this message containing the Original PSBT could be read by the
|
||||
@@ -513,14 +511,14 @@ norm, so falling back to them is no worse than typical bitcoin transaction behav
|
||||
|
||||
===Network privacy===
|
||||
|
||||
Oblivious HTTP must be used to protect the IP addresses of both sender and receiver from the directory. This
|
||||
requires an OHTTP Key Configuration to be shared in the BIP 21 URI and for the directory to support Oblivious
|
||||
Oblivious HTTP must be used to protect the IP addresses of both sender and receiver from the mailroom. This
|
||||
requires an OHTTP Key Configuration to be shared in the BIP 21 URI and for the mailroom to support Oblivious
|
||||
HTTP. A secp256k1 HPKE OHTTP configuration should be used to leverage the cryptography already available in
|
||||
bitcoin contexts.
|
||||
|
||||
Unlike BIP 78 implementations, sender and receiver peers will only see the IP address of the directory and not
|
||||
that of their peers. Directories may additionally be made available via Tor hidden services to allow either of
|
||||
the peers to protect their IP from the directory without OHTTP.
|
||||
Unlike BIP 78 implementations, sender and receiver peers will only see the IP address of the mailroom and not
|
||||
that of their peers. A mailroom may additionally be made available via Tor hidden service to allow either of
|
||||
the peers to protect their IP from the mailroom without OHTTP.
|
||||
|
||||
==Backwards compatibility==
|
||||
|
||||
@@ -535,16 +533,16 @@ MUST consider the entire URI invalid per BIP 21.
|
||||
Receivers may choose to support version 1 payloads. Payjoin version 2 URIs for backwards compatible receivers
|
||||
MUST enable <code>pjos=0</code> so that these version 1 senders disable output substitution. Since the version
|
||||
1 messages are neither encrypted nor authenticated, they would otherwise be at risk for man-in-the-middle
|
||||
attacks. The directory protocol should carry on as normal, responding to payjoin requests instead with this
|
||||
attacks. The mailroom protocol should carry on as normal, responding to payjoin requests instead with this
|
||||
version 1 request as [[https://www.rfc-editor.org/v3test/htmlredo/rfc9292.html| BHTTP]] in an OHTTP response. The receiver should POST Payjoin version 1 Proposal PSBTs to the same
|
||||
subdirectory as in version 2 to respond to these version 1 senders within 30 seconds. If no response is
|
||||
received within 30 seconds, the directory should respond with an <code>unavailable</code> error code as
|
||||
mailbox as in version 2 to respond to these version 1 senders within 30 seconds. If no response is
|
||||
received within 30 seconds, the mailroom should respond with an <code>unavailable</code> error code as
|
||||
[[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-well-known-errors| defined in BIP
|
||||
78]].
|
||||
|
||||
==Reference implementation==
|
||||
|
||||
An production reference implementation client can be found at [[https://crates.io/crates/payjoin-cli]]. Source
|
||||
code for the clients, the Payjoin Directory, and development kit may be found here: [[https://github.com/payjoin/
|
||||
code for the clients, the mailroom, and development kit may be found here: [[https://github.com/payjoin/
|
||||
rust-payjoin]]. Source code for an Oblivious HTTP relay implementation may be found here [[https://github.com/
|
||||
payjoin/ohttp-relay]].
|
||||
|
Reference in New Issue
Block a user