Skip to content
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

BIP 77: Payjoin Version 2: Serverless Payjoin #1483

Draft
wants to merge 26 commits into
base: master
Choose a base branch
from

Conversation

DanGould
Copy link

@DanGould DanGould commented Aug 12, 2023

This document proposes an asynchronous, backwards-compatible second version of the payjoin protocol described in BIP 78, enabling complete payjoin receiver functionality including payment output substitution with only an HTTP client rather than server. The former requirement for receivers to run HTTP servers is replaced with an untrusted third-party "payjoin directory" store-and-forward server accessed by polling clients which communicate using an asynchronous protocol and authenticated, encrypted payloads. It was originally proposed to the mailing list here.

The protocol design has received rounds of review elsewhere on the bitcoin-dev mailing list as well.

Feedback from that list post has been incorporated into this draft.

Proposing this as an Standards Track BIP to ensure wallets across the ecosystem can come to rough consensus on a single asynchronous payjoin standard and correctly implement it widely.

@luke-jr
Copy link
Member

luke-jr commented Dec 26, 2023

Let's call this BIP 77

@murchandamus
Copy link
Contributor

Hi @DanGould, the first comment on this PR seems to indicate that this proposal is still WIP. Is that an accurate understanding? If this PR is not yet ready to be merged, perhaps it should be changed to "Draft". If I misunderstood the status of this PR, please respond below so someone may review to assess whether this is ready for merge.

bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
@DanGould DanGould marked this pull request as draft May 3, 2024 02:50
@DanGould DanGould force-pushed the pjv2 branch 2 times, most recently from 51bb8c0 to 9f4624e Compare May 3, 2024 03:13
@DanGould
Copy link
Author

DanGould commented May 3, 2024

Converted to draft until we have some more experience with the implementations in the wild.

Still seeking review especially on the soundness of the network privacy, choice of cryptosystem, and bip21 parameter encoding.

bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
Co-authored-by: thebrandonlucas <38222767+thebrandonlucas@users.noreply.github.com>
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
bip-0077.mediawiki Outdated Show resolved Hide resolved
DanGould and others added 3 commits May 21, 2024 11:17
Co-authored-by: thebrandonlucas <38222767+thebrandonlucas@users.noreply.github.com>
Copy link
Contributor

@jonatack jonatack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Midway through a first (non-technical) review pass. Once at the end, will read through BIP78 and then do a more technical review.


==Abstract==

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 one to host a secure public endpoint. This requirement is replaced with an untrusted third-party directory accessed via HTTP clients which 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.
Copy link
Contributor

@jonatack jonatack May 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

("which" is followed by a comma; "that" is not)

Suggested change
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 one to host a secure public endpoint. This requirement is replaced with an untrusted third-party directory accessed via HTTP clients which 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.
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 one 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 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.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL about restrictive vs non-restrictive clauses


The payjoin protocols automate cooperative transaction construction to break that common-input assumption. The increased opportunity to batch payments and execute transaction cut-through increases intent throughput, since multiple intents combined take up fewer bytes than independent transactions.

Version 1's requirements have proven to be an obstacle to adoption. V1 coordinates payjoins over a public server endpoint secured by either TLS or Tor hidden service hosted by the receiver. Version 1 is also synchronous, requiring both sender and receiver to be online simultaneously to payjoin. Both requirements present significant barriers for all but sophisticated server operators or those wallets with complex Tor integration. Wallet developers [[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-January/018358.html| regard]] these as limits to payjoin adoption.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Version 1's requirements have proven to be an obstacle to adoption. V1 coordinates payjoins over a public server endpoint secured by either TLS or Tor hidden service hosted by the receiver. Version 1 is also synchronous, requiring both sender and receiver to be online simultaneously to payjoin. Both requirements present significant barriers for all but sophisticated server operators or those wallets with complex Tor integration. Wallet developers [[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-January/018358.html| regard]] these as limits to payjoin adoption.
Payjoin V1's requirements have proven to be an obstacle to adoption. V1 coordinates payjoins over a public server endpoint secured by either TLS or a Tor hidden service hosted by the receiver. Version 1 is also synchronous, requiring both sender and receiver to be online simultaneously to payjoin. Both requirements present significant barriers for all but sophisticated server operators or those wallets with complex Tor integration. Wallet developers [[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-January/018358.html| regard]] these as limits to payjoin adoption.


Version 1's requirements have proven to be an obstacle to adoption. V1 coordinates payjoins over a public server endpoint secured by either TLS or Tor hidden service hosted by the receiver. Version 1 is also synchronous, requiring both sender and receiver to be online simultaneously to payjoin. Both requirements present significant barriers for all but sophisticated server operators or those wallets with complex Tor integration. Wallet developers [[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-January/018358.html| regard]] these as limits to payjoin adoption.

The primary goal of this proposal is to provide a practical coordination mechanism viable to implement in a majority of bitcoin software environments. This is realized as a simple protocol built on bitcoin URI requests, web standards, common crypto, and minimal dependencies.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The primary goal of this proposal is to provide a practical coordination mechanism viable to implement in a majority of bitcoin software environments. This is realized as a simple protocol built on bitcoin URI requests, web standards, common crypto, and minimal dependencies.
The primary goal of this proposal is to provide a practical coordination mechanism that can be implemented in a majority of bitcoin software environments. This is done here using a simple protocol built on bitcoin URI requests, web standards, common cryptography, and minimal dependencies.


===Relation to BIP 78 (Payjoin version 1)===

The message payloads in this version parallel those used in BIP 78 while being encapsulated in authenticated encryption. TLS and Tor security, which depend on third-party authorities, are replaced with Hybrid Public Key Encryption ([[https://www.rfc-editor.org/rfc/rfc9180| HPKE]]). The synchronous HTTP client-server model is replaced with an asynchronous store-and-forward mechanism. This protocol also upgrades to PSBT version 2 to simplify transaction construction.
Copy link
Contributor

@jonatack jonatack May 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The message payloads in this version parallel those used in BIP 78 while being encapsulated in authenticated encryption. TLS and Tor security, which depend on third-party authorities, are replaced with Hybrid Public Key Encryption ([[https://www.rfc-editor.org/rfc/rfc9180| HPKE]]). The synchronous HTTP client-server model is replaced with an asynchronous store-and-forward mechanism. This protocol also upgrades to PSBT version 2 to simplify transaction construction.
The message payloads in this version parallel those used in BIP 78, while being encapsulated in authenticated encryption. TLS and Tor security, which depend on third-party authorities, are replaced with Hybrid Public Key Encryption ([[https://www.rfc-editor.org/rfc/rfc9180| HPKE]]). The synchronous HTTP client-server model is replaced with an asynchronous store-and-forward mechanism. This protocol also upgrades to PSBT version 2 to simplify transaction construction.

Also, perhaps mention/link to BIP 370 here when mentioning PSBT v2 for the first time in the document.


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 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 stealing funds.

The protocols in this document reuse BIP 78's BIP 21 URI parameters. A Original PSBT timeout parameter is introduced which may also help coordinate the synchronous version 1 protocol.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The protocols in this document reuse BIP 78's BIP 21 URI parameters. A Original PSBT timeout parameter is introduced which may also help coordinate the synchronous version 1 protocol.
The protocols in this document reuse BIP 78's BIP 21 URI parameters. An "Original PSBT" timeout parameter is introduced which may also help coordinate the synchronous version 1 protocol.


===Subdirectories===

Each receiver subdirectory allocated on the directory has a buffer for requests and one for responses. Each buffer updates listeners through awaitable events so that updates are immediately apparent upon client request.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Each receiver subdirectory allocated on the directory has a buffer for requests and one for responses. Each buffer updates listeners through awaitable events so that updates are immediately apparent upon client request.
Each receiver subdirectory allocated on the directory has one buffer for requests and one for responses. Each buffer updates listeners through awaitable events so that updates are immediately apparent upon client request.


===Optional sender parameters===

When the payjoin sender posts the original PSBT to the receiver, it can optionally specify the following HTTP query string parameters:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
When the payjoin sender posts the original PSBT to the receiver, it can optionally specify the following HTTP query string parameters:
When the payjoin sender posts the original PSBT to the receiver, the sender can optionally specify the following HTTP query string parameters:


The directory may hold a request for an offline payjoin peer until that peer comes online. However, the BIP 78 spec recommends broadcasting request PSBTs in the case of an offline counterparty. Doing so exposes a naïve, surveillance-vulnerable transaction which payjoin intends to avoid.

The existing BIP 78 protocol has to be synchronous only for automated endpoints which may be vulnerable to probing attacks. It can cover this tradeoff by demanding Original PSBT from which a valid payment transaction may be extracted that would not preserve privacy the same way as a payjoin. BIP 21 URI can communicate a request expiration to alleviate both of these problems. Receivers may specify a deadline after which they will broadcast this original with a new expiration parameter <code>exp=</code>. <!-- I also like to for timeout, but it's hard to coordinate in an asynchronous way -->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The existing BIP 78 protocol has to be synchronous only for automated endpoints which may be vulnerable to probing attacks. It can cover this tradeoff by demanding Original PSBT from which a valid payment transaction may be extracted that would not preserve privacy the same way as a payjoin. BIP 21 URI can communicate a request expiration to alleviate both of these problems. Receivers may specify a deadline after which they will broadcast this original with a new expiration parameter <code>exp=</code>. <!-- I also like to for timeout, but it's hard to coordinate in an asynchronous way -->
The existing BIP 78 protocol has to be synchronous only for automated endpoints, which may be vulnerable to probing attacks. It can cover this tradeoff by demanding an Original PSBT, from which a valid payment transaction may be extracted that would not preserve privacy the same way as a payjoin. BIP 21 URIs can communicate a request expiration to alleviate both of these problems. Receivers may specify a deadline after which they will broadcast this original with a new expiration parameter <code>exp=</code>. <!-- I also like to for timeout, but it's hard to coordinate in an asynchronous way -->


===HTTP===

HTTP is ubiquitous. Using simple HTTP polling allows even Bitcoin Core to consider an implementation. Unlike a WebSockets protocol, plain HTTP is eligible to enjoy metadata protection from Oblivious HTTP.
Copy link
Contributor

@jonatack jonatack May 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand your meaning correctly; protection from Oblivious HTTP seems odd here, as the latter is providing protection and not causing the need for it.

Suggested change
HTTP is ubiquitous. Using simple HTTP polling allows even Bitcoin Core to consider an implementation. Unlike a WebSockets protocol, plain HTTP is eligible to enjoy metadata protection from Oblivious 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 from both one another and from the directory. This makes it more difficult for a directory to correlate many payjoin transactions with a specific IP addresses by intersection.
Copy link
Contributor

@jonatack jonatack May 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either "with specific IP addresses", or "with a specific IP address"

Suggested change
OHTTP protects sender and receiver IP addresses from both one another and from the directory. This makes it more difficult for a directory to correlate many payjoin transactions with a specific IP addresses by intersection.
OHTTP protects sender and receiver IP addresses from both one another and from the directory. This makes it more difficult for a directory to correlate many payjoin transactions with specific IP addresses by intersection.

@DanGould
Copy link
Author

DanGould commented Jun 2, 2024

@jonatack Thank you for the review and implicit advice about how to clarify technical specifications such as this one with even small changes like using explicit subjects. Your patient, thorough contribution moves the needle toward production readiness and helps me reflect on the parts of the spec that are most lacking to correct them.

In incorporating your fresh perspective, I see a few issues remaining that I'll outline as a note for myself to correct:

  • Revise document to describe Payjoin "sessions" instead of directory "enrollment". e.g.: "The payjoin version 2 protocol uses per-[session] public keys"
  • Replacethe Authenticate: <token> messaging with a mask on eligible OHTTP relay addresses that start with "pay" domains. Avoid using identifying protocols like authentication tokens to preserve privacy. The goal is to make free access to these servers while by limiting their capability to preventing DoS vectors or misuse.
  • Either include PSBTv2 in the reference implementation or remove it from the bip77 spec

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
6 participants