diff --git a/README.mediawiki b/README.mediawiki index 7700c8b0..f7e00c59 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -428,6 +428,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Standard | Final |- +| [[bip-0077.md|77]] +| Applications +| Async Payjoin +| Dan Gould, Yuval Kogman +| Standard +| Draft +|- | [[bip-0078.mediawiki|78]] | Applications | A Simple Payjoin Proposal diff --git a/bip-0077.md b/bip-0077.md new file mode 100644 index 00000000..3c08788f --- /dev/null +++ b/bip-0077.md @@ -0,0 +1,737 @@ +``` + BIP: 77 + Layer: Applications + Title: Async Payjoin + Author: Dan Gould + Yuval Kogman + Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0077 + Post-History: https://github.com/bitcoin/bips/pull/1483 + https://gnusha.org/pi/bitcoindev/7B11AE34-27A7-46ED-95BF-66CA13BA26F3@ngould.dev/#t + https://gnusha.org/pi/bitcoindev/3C0A6E4C-444E-4E75-829C-1A21D8EE40E0@ngould.dev/#t + Status: Draft + Type: Standards Track + Created: 2023-08-08 + License: BSD-2-Clause + Requires: 21, 78, 173, 174 +``` + +## Copyright + +This BIP is licensed under the 2-clause BSD license. + +## Abstract + +Payjoin lets Bitcoin senders and receivers interact to make batched +transactions. + +This document proposes a second, backwards-compatible, asynchronous version of +the Payjoin protocol ("Version 2") relative to and described in [BIP 78](bip-0078.mediawiki) ("Version 1"). An untrusted +third-party "directory server" replaces the requirement +for a receiver to host a secure public endpoint for interactions. HTTP clients +access the directory server using an asynchronous protocol and authenticated, +encrypted payloads. The design preserves complete Payjoin receiver +functionality, including payment +output substitution. Authenticated encryption depends only on cryptographic +primitives available in Bitcoin Core. Requests use [Oblivious +HTTP](https://www.ietf.org/rfc/rfc9458.html) (OHTTP) to +prevent the directory and other Payjoin clients from linking requests to client +IP addresses. + +## Motivation + +Satoshi Nakamoto pointed out one specific privacy risk in the +[whitepaper](https://bitcoin.org/en/bitcoin-paper), +that transactions with multiple inputs "necessarily reveal that +their inputs were owned by the same owner." +Payjoin addresses that risk, the _common-input-ownership heuristic_, +by making it practical to spend inputs owned by multiple parties +in one transaction. + +While addressing Bitcoin's primal privacy risk, Payjoin *input* batching +also improves on the widespread non-interactive *output* batching practice +deployed by exchanges. When combined, the same movement of funds can use +less block weight and save fees. + +A natural application of Payjoin would be to combine +getting paid with consolidating UTXOs into one transaction. But Payjoin +can also secure [transaction +cut-through](https://bitcointalk.org/index.php?topic=281848.0), +allowing a sender to transfer funds to a receiver who also transfers +funds to a third party in the same transaction. For example, deposits to an +exchange may "cut through" in a single transaction that also satisfies +withdrawals instead of with a second transaction that spends the deposited +funds. Payjoin enables more blockspace-efficient transactions that +reduce fees while addressing privacy risks. + +However, BIP 78's requirements for Payjoin Version 1 have proven to be an +obstacle to adoption. Version 1 receivers must host a secured +public-facing HTTP server. Mobile and web environments limit the ability +to fulfil such a requirement. Version 1 also requires synchronous +communication. Both sender and receiver must be online simultaneously. +Wallet developers [ +regard](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-January/018358.html) +these requirements as barriers to Payjoin adoption. + +To address these limitations, our goal is to specify a practical +coordination mechanism suitable for widespread implementation. This proposal +leverages mature solutions to common problems, building on established web +standards and proven Bitcoin primitives. + +## Overview + +A Payjoin *sender* and *receiver* interact so that they may both contribute to a +transaction. In this proposal, they exchange asynchronous end-to-end +encrypted messages by relaying them to a store-and-forward *directory* server +using OHTTP. + +Before initiating the protocol, the receiver must secure communications with +the directory by [bootstrapping](#ohttp-bootstrapping). + +- The receiver [initiates a Payjoin Session](#session-initiation) + by sharing a [Payjoin URI](#payjoin-uri) that includes the URL of an + ephemeral mailbox hosted on the directory, where it can receive a message + from the sender. +- The sender [posts a message](#sender-original-psbt-messaging) + containing a fully signed fallback transaction, known as the *Original PSBT*, + to the mailbox. +- The receiver gets this message and + [posts a message containing a *Proposal + PSBT*](#receiver-proposal-psbt-messaging) + to the sender's ephemeral mailbox, by updating the Original PSBT with + appropriate inputs and/or outputs. +- The sender gets the Proposal PSBT, [checks it, signs, and + broadcasts](#sender-signing-and-broadcast) the final transaction. + +At any point, either party may choose to broadcast the +fallback transaction described by the Original PSBT instead of proceeding. +Because the Original PSBT and Proposal PSBT spend the same input(s) they are +mutually exclusive and only one can be confirmed. + +Messages are buffered in the directory, allowing both parties to tolerate +temporary disconnections and resume communication by polling. + +### Sequence Diagram + +```mermaid +sequenceDiagram + title Async Payjoin Sequence Diagram + participant R as Receiver + participant D as Directory + participant S as Sender + participant N as Network + + R-)S: Payjoin URI (BIP 21) out of band + + R-->>D: Poll GET Requests
for Original PSBT + activate D  + S->>D: POST Request
Original PSBT + D->>R: GET Response
Original PSBT + deactivate D + + S-->>D: Poll GET Requests
for Proposal PSBT + activate D + R->>D: POST Request
Proposal PSBT + D->>S: GET Response
Proposal PSBT + deactivate D + + S->>N: Broadcast Payjoin +``` + +## Specification + +### OHTTP Bootstrapping + +Before initiating a Payjoin Session a receiver must first discover the +directory's +[OHTTP Key Configuration](https://www.ietf.org/rfc/rfc9458.html#section-3.1), +via an authenticated +bootstrap mechanism. The key configuration contains information to establish +[Hybrid Public Key Encryption](#secp256k1-hybrid-public-key-encryption) (HPKE) in order to secure communications between the client and the directory in +lieu of TLS. + +The bootstrap mechanism may vary by implementation but must +follow [OHTTP Consistency +Requirements](https://datatracker.ietf.org/doc/html/draft-ietf-privacypass-key-consistency-01) +and should not reveal a receiver IP address to the directory. Some +examples of suitable mechanisms include getting a key configuration +from a Payjoin URI, a trusted application binary, or fetching using https-in-http +CONNECT method, https-in-WebSocket, Tor, or a VPN. + +Directory OHTTP Gateways MUST support [RFC 9540 Key Configuration +Fetching](https://www.rfc-editor.org/rfc/rfc9540.html#name-key-configuration-fetching) +via GET request. RFC 9540 defines the +gateway location as `/.well-known/ohttp-gateway`. + +### Session Initiation + +A receiver initiates a session by sharing a Payjoin URI. Because a URI +contains sensitive information, such as a receiver address, it should be shared +over a confidential channel. + +#### Payjoin URI + +Bitcoin URIs ([BIP +21](https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki) +or [BIP +321](https://github.com/bitcoin/bips/blob/master/bip-0321.mediawiki)) +are a standard way to request bitcoin. + +A Payjoin URI is a Bitcoin URI that contains a `pj` parameter. The `pj` +parameter value is a URL in both BIP 78 and BIP 77. + +Senders that understand Bitcoin URI but don't support Payjoin will just +ignore the `pj` parameter and proceed to typical address-based +transaction flows. + +A `req-pj` parameter may be used as a [BIP 21 forwards compatibility `reqparam`](https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki#forward-compatibility) instead of +`pj` to signal that Payjoin is required. +`pj` to signal that Payjoin is required. + +The parameter value must be [uppercased and the parameter should be placed last in the URI](#uppercase-url). + +Since BIP 78 payloads are neither encrypted nor authenticated, +a directory used for backwards-compatible payloads is known +as an ["unsecured payjoin server" in BIP 78 +parlance](https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#unsecured-payjoin-server). +Backwards-compatible receivers MUST disable output substitution +by setting `pjos=0` to prevent modification by a malicious directory. + +##### Mailbox endpoint + +In this proposal the URL in the `pj` parameter value is the mailbox +endpoint URL. Mailboxes are shared HTTP resources hosted by the +directory and serve as OHTTP Target Resources. Clients use these endpoints +to relay encrypted messages. They `POST` messages to and `GET` messages from +mailbox endpoints via OHTTP. + +Senders that support BIP 78 but not this proposal may POST messages directly to +mailbox endpoints for [backwards compatibility](#backwards-compatibility). + +###### Short ID + +A Short ID identifies a mailbox based on its associated public key. The Short +ID is the path component of the mailbox endpoint. One is derived by hashing the +33-byte compressed public key encoding with SHA-256, truncating it to +[8 bytes (64 bits)](#64-bit-short-id-length), and encoding it in +[uppercase](#uppercase-url) using the bech32 character set (like a bech32 string without the HRP, separator and checksum). + +##### Receiver fragment parameters + +This proposal introduces session-specific parameters which the +receiver shares encoded in the URI. + +Instead of defining new Bitcoin URI parameters, the session-specific +parameters are encoded in the [ +fragment](https://datatracker.ietf.org/doc/html/rfc3986#section-3.5) +of the the mailbox endpoint URL. + +The `#` fragment separator character must be [RFC 3986 +percent-encoded](https://datatracker.ietf.org/doc/html/rfc3986#section-2.1) +as `%23`, because it separates the +fragment of the mailbox endpoint URL included in the `pj` parameter, not the +fragment of the Bitcoin URI. + +These session-specific parameters use a bech32-inspired encoding. +The HRP is used as the parameter key, followed by the '1' separator, +followed by the parameter value encoded using the bech32 character set in +[uppercase](#uppercase-url). No checksum is used. Parameters are separated +by a `+` character. + +The following parameters are defined, and must be provided in reverse +lexicographical order: + +- `RK`: encodes the *receiver key* as a 33-byte compressed public key. + Senders will initiate HPKE with the receiver using this key. +- `OH`: encodes an alternate format of the OHTTP Key Configuration of + the directory. It consists of a 33-byte compressed public key of the + directory's OHTTP Gateway, prefixed by the 2-byte Key Identifier. A [ + RFC 9458 Key + Configuration](https://www.ietf.org/rfc/rfc9458.html#section-3.1) + is reconstructed by assuming the HPKE KEM ID and Symmetric Algorithms + are [fixed](#secp256k1-hybrid-public-key-encryption). +- `EX`: specifies a [session + expiration](#session-expiration) in [unix + time](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_16). + +For example, a properly encoded endpoint Bitcoin URI looks like this +`bitcoin:tb1q6q6de88mj8qkg0q5lupmpfexwnqjsr4d2gvx2p?amount=0.00666666&pjos=0&pj=HTTPS://PAYJO.IN/TXJCGKTKXLUUZ%23RK1Q0DJS3VVDXWQQTLQ8022QGXSX7ML9PHZ6EDSF6AKEWQG758JPS2EV+OH1QYPM59NK2LXXS4890SUAXXYT25Z2VAPHP0X7YEYCJXGWAG6UG9ZU6NQ+EX1WKV8CEC` + +### Sender Original PSBT Messaging + +The sender constructs the fallback transaction, a typical transaction +spending funds to the receiver's address specified in the Payjoin URI. +This transaction is serialized as a BIP 174 PSBTv0, satisfying +[the receiver checklist](#receivers-original-psbt-checklist). + +The Original PSBT MUST: + +- Include complete UTXO data. +- Be fully signed. +- Exclude unnecessary fields such as global xpubs or keypath + information. +- Be broadcastable. + +The Original PSBT MAY: + +- Include outputs unrelated to the sender-receiver transfer for batching + purposes. + +This *Original PSBT* is encoded as base64, followed by the query +parameter string on a new line containing [optional sender +parameters](#optional-sender-parameters). + +The sender generates an ephemeral mailbox key. The corresponding public key is +known as the *reply key*, and it is prepended to the base64 plaintext string, +serialized in compressed form as 33 bytes. + +This plaintext string is encrypted to the receiver key according to [HPKE Base +mode](https://www.rfc-editor.org/rfc/rfc9180.html#name-encryption-to-a-public-key). +The HPKE `info` string, used for domain separation, is `PjV2MsgA`. The +ciphertext ensures message secrecy and integrity when passed to the receiver +using the mailbox endpoint. The 16-byte authentication tag is appended to the +ciphertext. + +RFC 9180 [does not +specify](https://www.rfc-editor.org/rfc/rfc9180.html#section-10) the wire format +encoding of HPKE messages. To construct an HPKE payload, the secp256k1 public +key from the DHKEM is encoded using ElligatorSwift in 64 bytes. Note that +ElligatorSwift is only the wire format; when deriving shared secrets, the curve +point is re-serialized in uncompressed form. + +``` +PjV2MsgA Byte Representation (7168 bytes total) ++---------------------------------------------------------------------------------------+ +| ElligatorSwift | Ciphertext | +| (64 bytes) | (7104 bytes) | +| +-----------------------+---------------------------------+------------+ +| | Reply Key | Padded Plaintext | AEAD Tag | +| | (33 bytes) | (7055 bytes = 7168-64-33-16) | (16 bytes) | ++---------------------------------------------------------------------------------------+ +``` + +The resulting HPKE payload is the body of a POST request to the +receiver's mailbox. This request is then [ +encapsulated](#client-directory-interactions) according to +Oblivious HTTP to the directory's OHTTP Gateway. OHTTP serializes the +inner request as BHTTP, and provides another layer of HPKE encryption, +between the client and directory. + +Upon receipt, the directory's OHTTP Gateway decapsulates the OHTTP +request and handles the inner POST request at the receiver's mailbox +endpoint, which stores the HPKE encrypted payload to be forwarded to the +receiver. + +The sender then polls OHTTP encapsulated GET requests to the sender's +mailbox endpoint until it receives a response from the directory +containing the receiver's *Proposal PSBT*, and proceeds to +[sign and broadcast](#sender-signing-and-broadcast). +It stops polling after expiration. + +#### Optional sender parameters + +[BIP 78's optional sender parameters](https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#optional-parameters) +may be used in this proposal, but must be included in +the body as part of the ciphertext rather than as a query string. + +HPKE binds ciphertexts to application-specific `info` strings. Because +of this domain separation, BIP 78's `v` parameter is redundant and +should be omitted for this proposal. + +### Receiver Proposal PSBT Messaging + +After sharing the Payjoin URI with the sender, the receiver polls via +OHTTP encapsulated GET requests to the receiver's mailbox endpoint. So +long as the mailbox contains no message, the directory responds with +status 202 ACCEPTED. Once a mailbox contains a message, the directory +returns it in the response body with status 200 OK. + +Upon receiving an encapsulated 200 OK response, the receiver decrypts +the payload and checks the *Original PSBT* therein according to the +[receiver checklist](#receivers-original-psbt-checklist). + +The receiver then updates the *Original PSBT* to include new signed +inputs and outputs, invalidating the sender's signature(s). The receiver +may also adjust the transaction fee. The result, called the *Proposal +PSBT*, must satisfy the [sender checklist](#senders-proposal-psbt-checklist) + +The Proposal PSBT MUST: + +- Include complete UTXO data. +- Include all inputs from the Original PSBT. +- Include all outputs which do not belong to the receiver from the + Original PSBT. +- Use a random index if additional inputs or outputs are added. + +The Proposal PSBT sender MAY: + +- Add inputs at random indices. +- Add outputs at random indices. +- Remove or modify Original PSBT outputs under the control of the + receiver (i.e. not sender change). + +The Proposal PSBT MUST NOT: + +- Shuffle the order of inputs or outputs contained in the Original PSBT. +- Decrease the absolute fee of the Original PSBT. + +The receiver encrypts the *Proposal PSBT* to the sender's reply key according to +[HPKE Auth +mode](https://www.rfc-editor.org/rfc/rfc9180.html#name-authentication-using-an-asy), +using the receiver's key for authentication. The HPKE `info` string is +`PjV2MsgB`. The HPKE wire format is the same as in the [sender's +message](#sender-original-psbt-messaging). + +``` +PjV2MsgB Byte Representation (7168 bytes total) ++---------------------------------------------------------------------------------------+ +| ElligatorSwift | Ciphertext | +| (64 bytes) | (7104 bytes) | +| +---------------------------------------------------------+------------+ +| | Padded Plaintext | AEAD Tag | +| | (7088 bytes = 7168-64-16) | (16 bytes) | ++---------------------------------------------------------------------------------------+ +``` + +The receiver makes the resulting HPKE payload the body of a POST request to the +sender's mailbox whose Short ID is derived from the sender's reply key. This request is then [ +encapsulated](#client-directory-interactions) according to +Oblivious HTTP to the directory's OHTTP Gateway. OHTTP serializes the +inner request as BHTTP, and provides another layer of HPKE encryption, +between the client and directory. + +Once the receiver makes this request, they wait for either transaction from the +Original PSBT or Proposal PSBT to be broadcast to the Bitcoin network. + +#### Receiver's Original PSBT checklist + +The receiver checklist is the same as [the BIP 78 receiver +checklist](https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist). + +### Sender signing and broadcast + +The sender validates the *Proposal PSBT* it receives against a +checklist. If the checks pass, it may sign and broadcast the resulting +Payjoin transaction. + +#### Sender's Proposal PSBT checklist + +This proposal's sender checklist is the same as [the BIP 78 sender +checklist](https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#senders-payjoin-proposal-checklist). + +### Client/Directory interactions + +The Payjoin Directory provides a rendezvous point for senders and +receivers to exchange messages. The directory stores Payjoin payloads to +support asynchronous communication. Async Payjoin requests must be +submitted as encapsulated messages to the directory's OHTTP Gateway. + +The wire format OHTTP request is specified in [RFC +9458](https://www.ietf.org/rfc/rfc9458.html#name-hpke-encapsulation). HPKE +requires the directory's OHTTP key configuration. The plaintext is a binary +encoded HTTP request ([RFC 9292](https://www.rfc-editor.org/rfc/rfc9292.html)) +intended for the OHTTP target resource, usually a mailbox endpoint, padded to +8104 bytes with [random data](#random-padding). + +``` +OHTTP Encapsulated Request Byte Representation (8192 bytes total) ++--------------+-------------------------+------------------------------------------+ +| OHTTP Header | HPKE KEM | Ciphertext | +| (7 bytes) | Uncompressed Public Key | (8120 bytes = 8192-65-7) + +| | (65 bytes) +-----------------------------+------------+ +| | | Padded BHTTP Request | AEAD Tag | +| | | (8104 bytes = 8192-65-16-7) | (16 bytes) | ++--------------+-------------------------+------------------------------------------+ +``` + +Response encryption uses the Export functionality of the request HPKE context to +establish a shared secret, and therefore consists of a 32 byte nonce followed by +the AEAD ciphertext and tag. + +``` +OHTTP Encapsulated Response Byte Representation (8192 bytes total) ++---------------------+------------------------------------------+ +| Nonce | Ciphertext | +| (32 bytes) | (8160 bytes = 8192-32) + +| +-----------------------------+------------+ +| | Padded BHTTP Response | AEAD Tag | +| | (8144 bytes = 8192-32-16) | (16 bytes) | ++---------------------+------------------------------------------+ +``` + +GET requests on an empty mailbox should block until a message is posted +or a timeout occurs. The timeout should be 30 seconds because that will +not exceed the default timeout for most HTTP clients. + +The directory may optionally accept HTTP/1.1 POST requests without OHTTP +to mailbox endpoint URLs for backwards compatibility with BIP 78 senders. + +#### OHTTP Sequence Diagram + +```mermaid +sequenceDiagram + title OHTTP Sequence Diagram + participant C as Client + participant R as OHTTP Relay + + box PaleVioletRed Payjoin Directory + participant G as OHTTP Gateway + participant D as HTTP Resource + end + + C->>R: Relay Request
FROM: Client IP
[+ Encapsulated Request] + R->>G: Gateway Request
FROM: Relay IP
[+ Encapsulated Request] + G->>D: Request + D->>G: Response + G->>R: Gateway Response
TO: Relay IP
[+ Encapsulated Response] + R->>C: Relay Response
TO: Client IP
[+ Encapsulated Response] +``` + +### Relay/Directory interactions + +RFC 9458 requires each OHTTP Relay to be configured to forward requests +to exactly one OHTTP Gateway. This requirement prevents receivers from +being able to choose any directory, and senders from choosing relays +independently. Without addressing this limitation, senders would have to +know which relays are appropriate to use for each directory, creating a +tendency for one directory and its affiliated relays to monopolize the +protocol. + +In order to allow OHTTP Relays to be used with any directory, a +directory's OHTTP Gateway may advertise this allowed purpose. This +advertisement prevents OHTTP Relays from acting as open internet proxies, +which would otherwise allow anonymized access to arbitrary resources and +expose them to denial-of-service attacks, as well as other forms of abuse. +When the directory receives a GET request to the `/.well-known/ohttp-gateway` +path with an `allowed_purposes` query parameter, its response body +should contain a magic string in the same format as a TLS ALPN protocol +list (a U16BE length encoded list of U8 length encoded strings). The +magic string is `BIP77 454403bb-9f7b-4385-b31f-acd2dae20b7e`, offering +an unambiguous signal to relays that this OHTTP Gateway will accept +requests associated with this purpose from any relay. + +By supporting this `allowed_purposes` parameter, the directory signals +to OHTTP Relays that it is willing to handle requests related to BIP 77, +removing the RFC 9458's requirement that relays and +Gateways be configured in a one-to-one relationship. + +## Rationale + +### Uppercase URL + +In order to simplify parsing and allow QR encoders to use [Alphanumeric +QR +mode](https://www.rfc-editor.org/rfc/rfc9285.html#name-the-alphabet-used-in-base45), +which is more compact than Byte mode, the mailbox endpoint URL, +including the fragment parameters, is encoded in uppercase. + +Unlike Bitcoin URI parameters, which require switching back to Byte +mode, the use of the URL fragment for session-specific parameters makes +it possible to stay in Alphanumeric mode. + +### Parameter Ordering + +The order of fragment parameters, Bitcoin URI parameters, as well as in the +sender's optional parameters have no defined meaning. + +In the BIP 21 URI, the `pj` parameter mailbox endpoint URL SHOULD be the last +parameter to avoid QR mode switching. + +Since variations might create a fingerprint for particular wallet software, +this document requires that fragment parameters MUST appear in reverse +lexicographical order. + +### Session Expiration + +The directory may hold a message for an offline Payjoin client until that +client comes online. However, the BIP 78 spec [ +recommends](https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receiver-does-not-need-to-be-a-full-node) +broadcasting Original PSBTs in the case of an offline counterparty. +Doing so exposes a naïve, surveillance-vulnerable transaction, which +Payjoin intends to avoid. + +Because BIP 78 is a synchronous protocol without a standard expiration +mechanism, and automated receivers are vulnerable to probing attacks, +BIP 78 encourages receivers to broadcast the Original PSBT after some +undefined expiration time. + +Because BIP 77 is an asynchronous protocol, it requires an explicit [ +session-specific fragment +parameter](#receiver-fragment-parameters), `EX`, to +communicate this expiration time to the sender. + +There is no way for a sender to prevent a receiver from broadcasting the +fallback transaction extracted from the Original PSBT before the +receiver-specified expiration time. + +### 64-bit Short ID Length + +64 bits are sufficient to make the probability of experiencing a random +collision 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) +sessions, for which the probability of a random collision will be less +than 1%. The actual number of sessions will of course be (orders of +magnitudes) lower given that sessions are short-lived. With ~2^21 +sessions (a loose bound on number of transactions that can be confirmed +in 24 hours) the probability is less than 1e-6. These figures bound the +probability of a collision existing anywhere in the entire set, whereas +the probability for an individual session to experience a collision is +\<\< 1e-10 in either case. + +### Complete UTXO Data + +Complete UTXO data is required because this information is required for +signing and calculating fees for some input types. + +### HTTP + +HTTP is ubiquitous. Using simple HTTP polling allows even Bitcoin Core +to consider an implementation. Unlike a WebSockets protocol, plain HTTP +can benefit from metadata protection by using Oblivious HTTP. + +### 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. + +OHTTP relays can be run as basic HTTP proxies from wallet providers or +third parties. + +### Uniform Payloads + +Encapsulated OHTTP payloads seen by the relay and directory, and +encrypted messages seen by the directory, are constructed to be uniform +so that these third-party services are unable to distinguish between +them. + +Encapsulated OHTTP messages are 8192 bytes long, and begin with a +cleartext OHTTP header and an uncompressed key which is distinguishable +from random bytes but uniform across different encapsulated requests. + +End-to-end encrypted messages are 7168 bytes long, and should be +indistinguishable from uniformly random bytes. +[ElligatorSwift as defined in BIP 324](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki#elligatorswift-encoding-of-curve-x-coordinates) +is used to encode encapsulated HPKE public keys prepended to the HPKE ciphertext +so that the directory can't distinguish between key material, the +ciphertext, and randomness. This ensures the two different protocol +messages are indistinguishable from each other as well as any protocol +extensions. + +These padded sizes are sufficient for most PSBTs without exceeding the [ +8KB +limit](https://www.geekersdigest.com/max-http-request-header-size-server-comparison/) +of many HTTP/1.1 web servers. 8KB is also too small for image sharing, +making misuse of the directory impractical. + +#### Random Padding + +The typical [zero padding recommended by the BHTTP +specification](https://www.rfc-editor.org/rfc/rfc9292.html#name-padding-and-truncation) +would make future use of [multi-hop OHTTP inspired by the Sphinx mix +format](https://github.com/orgs/payjoin/discussions/582) detectable from the +point of view of the directory. Random padding is allowed so long as the BHTTP +encoded request is not truncated. + +By randomly padding OHTTP messages, any future use of such techniques would be +indistinguishable from clients that only implement standardized OHTTP. Since +this would limit a malicious directory's ability to censor any such requests in +the future, and such requests significantly bolster the privacy threat model +against malicious OHTTP relays or traffic analysis by a global passive +adversary, it is desirable to do so for standard OHTTP requests as well. + +### Secp256k1 Hybrid Public Key Encryption + +[RFC 9180 Hybrid Public Key +Encryption](https://www.rfc-editor.org/rfc/rfc9180.html) +(HPKE) is a modern IETF standard for secure +message exchange without TLS, since TLS is not available in Bitcoin Core. + +This proposal uses `DHKEM(Secp256k1, HKDF-SHA256)` and +`ChaCha20Poly1305` AEAD for both OHTTP encapsulation and for end-to-end +encryption between the sender and receiver. + +The receiver transmits its receiver key in [receiver fragment +parameters](#receiver-fragment-parameters). The sender shares +its reply key along with the Original PSBT. These keys are ephemeral and +must only be used for a single Payjoin Session. + +#### Secp256k1-based DHKEM + +[Secp256k1-based DHKEM for +HPKE](https://www.ietf.org/archive/id/draft-wahby-cfrg-hpke-kem-secp256k1-01.html) +is most appropriate because of secp256k1's availability in bitcoin +contexts. + +#### ChaCha20Poly1305 AEAD + +This authenticated encryption with additional data [ +algorithm](https://en.wikipedia.org/wiki/ChaCha20-Poly1305) +is standardized in [RFC +8439](https://www.rfc-editor.org/rfc/rfc8439) and has high +performance. ChaCha20Poly1305 AEAD has been implemented [in Bitcoin +Core](https://github.com/bitcoin/bitcoin/pull/15649) for [ +BIP 324 Encrypted +Transport](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki) +as well. This has widespread support in browsers and common +cryptographic libraries. AES-GCM is more widespread but slower without +hardware support and not typically already a dependency in bitcoin software. + +#### HKDF-SHA256 + +SHA-256 is necessarily available in bitcoin contexts. + +## Attack vectors + +In addition to the attack vectors and mitigations in +[BIP 78](https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#attack-vectors), +this proposal has the following attack vectors. + +### Directory Denial of Service + +Since each mailbox stores arbitrary encrypted payloads, directories are +vulnerable to flooding. To mitigate such denial of service attacks, +directory operators may respond with `401` unauthorized unless an +authorization token is provided. Authorization tokens must be unlinkable +to preserve client privacy. A specific unlinkable authorization token +mechanism is out of the scope of this proposal. + +### 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 Payjoin URI and for the directory to +support Oblivious HTTP. + +Unlike BIP 78 implementations, sender and receiver clients will only see +the IP address of the directory and not that of the client they are +interacting with. + +Senders that submit requests directly to the directory, without using +an OHTTP Relay, may reveal their IP address to the receiver since that +receiver also specifies the directory. + +## Backwards compatibility + +Senders not supporting Payjoin will just ignore the `pj` parameter and +proceed to typical address-based transaction flows. + +All Payjoin versions use [Bitcoin URIs](#payjoin-uri). +Receivers may choose to accept BIP 78 payloads at their discretion. + +A BIP 78 sender posts their request to the directory, which stores +and forwards it to the BIP 77 receiver. A backwards-compatible +receiver proceeds with the BIP 78 checks if the encapsulated response +body is UTF-8 plaintext, signifying BIP 78. In order to service the +request, a BIP 78 response must be returned to the sender within 30 +seconds or else the directory should respond with an `unavailable` JSON +error code as [defined in BIP +78](https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-well-known-errors). + +## Reference implementation + +A production reference implementation client can be found at +. Source code for the clients, the +directory, and development kit may be found here: +. Source code for an Oblivious +HTTP relay implementation may be found here: +.