-
Notifications
You must be signed in to change notification settings - Fork 5.3k
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 — Async Payjoin #1483
base: master
Are you sure you want to change the base?
Conversation
Let's call this BIP 77 |
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. |
Co-authored-by: thebrandonlucas <[email protected]>
Co-authored-by: thebrandonlucas <[email protected]>
There was a problem hiding this 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.
@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:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review pass of the latest changes in 3b863a4.
Note to self: continue original review pass from line 180 to the end.
bip-0077.mediawiki
Outdated
|
||
====Send Messaging==== | ||
|
||
The version 2 Original PSBT is serialized in base64 followed by the query parameter string on a new line. This plaintext string encrypted according to the HPKE using a shared secret derived from a newly generated session keypair public key combined with the receiver's subdirectory 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The version 2 Original PSBT is serialized in base64 followed by the query parameter string on a new line. This plaintext string encrypted according to the HPKE using a shared secret derived from a newly generated session keypair public key combined with the receiver's subdirectory 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. | |
The version 2 Original PSBT is serialized in base64 followed by the query parameter string on a new line. This plaintext string is encrypted according to the HPKE using a shared secret derived from a newly generated session keypair public key combined with the receiver's subdirectory 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. |
-
missing verb? (i.e. "is")
-
"on a new line" applies to the quary param only? If yes, consider
s/base64/base64,
bip-0077.mediawiki
Outdated
====Receive Messaging==== | ||
|
||
The receiver sends a GET request to the path of the subdirectory followed by <code>/receive</code>. This request is encapsulated in OHTTP. | ||
The recver then awaits an OHTTP response from the directory encapsulating a request from the sender with status code 200 OK, or sends a new OHTTP request after receiving an encapsulated 202 ACCEPTED response notifying the receiver that the directory has not yet received a request from the sender. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The recver then awaits an OHTTP response from the directory encapsulating a request from the sender with status code 200 OK, or sends a new OHTTP request after receiving an encapsulated 202 ACCEPTED response notifying the receiver that the directory has not yet received a request from the sender. | |
The receiver then awaits an OHTTP response from the directory encapsulating a request from the sender with status code 200 OK, or sends a new OHTTP request after receiving an encapsulated 202 ACCEPTED response notifying the receiver that the directory has not yet received a request from the sender. |
bip-0077.mediawiki
Outdated
|
||
The version 2 Original PSBT is serialized in base64 followed by the query parameter string on a new line. This plaintext string encrypted according to the HPKE using a shared secret derived from a newly generated session keypair public key combined with the receiver's subdirectory 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. | ||
|
||
The directory's OHTTP Gateway decapsulates the OHTTP request, handles the POST request at the receiver's internal subdirectory endpoint, which stores the HPKE encrypted payload to be forwarded to the receiver. The directory's awaits a request from the receiver's to the subdirectory endpoint, encapsulates to responds with the HPKE encrypted Original PSBT payload acording to OHTTP. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The directory's OHTTP Gateway decapsulates the OHTTP request, handles the POST request at the receiver's internal subdirectory endpoint, which stores the HPKE encrypted payload to be forwarded to the receiver. The directory's awaits a request from the receiver's to the subdirectory endpoint, encapsulates to responds with the HPKE encrypted Original PSBT payload acording to OHTTP. | |
The directory's OHTTP Gateway decapsulates the OHTTP request and handles the POST request at the receiver's internal subdirectory endpoint, which stores the HPKE encrypted payload to be forwarded to the receiver. The directory's OHTTP Gateway awaits a request from the receiver to the subdirectory endpoint and responds with the HPKE encrypted Original PSBT payload acording to OHTTP. |
(Not sure what the latest version of this sentence intends to say; it is a bit confusing, so my suggested edits are likely to be incorrect.)
bip-0077.mediawiki
Outdated
|
||
===Sender's Payjoin PSBT checklist=== | ||
|
||
The version 2 sender's checklist is largely the same as the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#senders-payjoin-proposal-checklist| the BIP 78 checklist]], with the exception that it expects all UTXO data to be filled in. BIP 78 required sender inputs UTXO data 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The version 2 sender's checklist is largely the same as the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#senders-payjoin-proposal-checklist| the BIP 78 checklist]], with the exception that it expects all UTXO data to be filled in. BIP 78 required sender inputs UTXO data 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. | |
The version 2 sender's checklist is largely the same as the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#senders-payjoin-proposal-checklist| the BIP 78 checklist]], with the exception that it expects all UTXO data to be filled in. BIP 78 required sender inputs UTXO data 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
continue original review pass from line 180 to the end
Done (for the initial proofreading pass)
bip-0077.mediawiki
Outdated
|
||
When the payjoin sender posts the original PSBT to the receiver, the sender should specify the following HTTP query string parameters: | ||
|
||
* <code>v</code>: represents the version number of the payjoin protocol that the sender is using. This version is <code>2</code>. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest writing all 3 params (2 receiver, 1 sender) either followed by a colon, or by no colon.
bip-0077.mediawiki
Outdated
|
||
===Request expiration & Original PSBT=== | ||
|
||
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: link here to where BIP 78 recommends this.
bip-0077.mediawiki
Outdated
|
||
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 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 --> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"I also like to for timeout" -> unclear
bip-0077.mediawiki
Outdated
|
||
Hybrid Public Key Encryption is a modern web standard for secure message exchange without TLS. Since client and server agree on a configuration out of band, we can pre-define the payjoin v2 application specific configuration to use DHKEM(Secp256k1, HKDF-SHA256) and ChaCha20Poly1305 AEAD. | ||
|
||
The cryptographic handshake is conducted in parallel to the payjoin messaging inspired by the [[http:https://www.noiseprotocol.org/noise.html#zero-rtt-and-noise-protocols| zero-RTT]] version of the [[http:https://www.noiseprotocol.org/noise.html| Noise Framework]] [[https://noiseexplorer.com/patterns/NKpsk0/| IK]] pattern. A receiver shares its public key out of band in the BIP21 URI. Static keys shared in URIs must only for a single 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cryptographic handshake is conducted in parallel to the payjoin messaging inspired by the [[http://www.noiseprotocol.org/noise.html#zero-rtt-and-noise-protocols| zero-RTT]] version of the [[http://www.noiseprotocol.org/noise.html| Noise Framework]] [[https://noiseexplorer.com/patterns/NKpsk0/| IK]] pattern. A receiver shares its public key out of band in the BIP21 URI. Static keys shared in URIs must only for a single 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. | |
The cryptographic handshake is conducted in parallel to the payjoin messaging inspired by the [[http://www.noiseprotocol.org/noise.html#zero-rtt-and-noise-protocols| zero-RTT]] version of the [[http://www.noiseprotocol.org/noise.html| Noise Framework]] [[https://noiseexplorer.com/patterns/NKpsk0/| IK]] pattern. A receiver shares its public key out of band in the BIP 21 URI. Static keys shared in URIs must only [be valid? be used?] for a single 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. |
-
"Static keys shared in URIs must only for a single session" -> missing verb
-
(no strong opinion about "BIP21", but you wrote "BIP 21" with a space throughout this draft)
bip-0077.mediawiki
Outdated
|
||
===Secp256k1 Hybrid Public Key Encryption=== | ||
|
||
Hybrid Public Key Encryption is a modern web standard for secure message exchange without TLS. Since client and server agree on a configuration out of band, we can pre-define the payjoin v2 application specific configuration to use DHKEM(Secp256k1, HKDF-SHA256) and ChaCha20Poly1305 AEAD. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hybrid Public Key Encryption is a modern web standard for secure message exchange without TLS. Since client and server agree on a configuration out of band, we can pre-define the payjoin v2 application specific configuration to use DHKEM(Secp256k1, HKDF-SHA256) and ChaCha20Poly1305 AEAD. | |
Hybrid Public Key Encryption (HPKE) is a modern web standard for secure message exchange without TLS. Since client and server agree on a configuration out of band, we can pre-define the payjoin v2 application specific configuration to use DHKEM(Secp256k1, HKDF-SHA256) and ChaCha20Poly1305 AEAD. |
bip-0077.mediawiki
Outdated
|
||
==Backwards compatibility== | ||
|
||
The receivers advertise payjoin capabilities through [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP21's URI Scheme]]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The receivers advertise payjoin capabilities through [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP21's URI Scheme]]. | |
The receivers advertise payjoin capabilities through [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP 21's URI Scheme]]. |
bip-0077.mediawiki
Outdated
|
||
The receivers advertise payjoin capabilities through [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP21's URI Scheme]]. | ||
|
||
Senders not supporting payjoin will just ignore the <code>pj=</code> parameter and proceed to typical address-based transaction flows. <code>req-pj=</code> may be used to compel payjoin. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Senders not supporting payjoin will just ignore the <code>pj=</code> parameter and proceed to typical address-based transaction flows. <code>req-pj=</code> may be used to compel payjoin. | |
Senders not supporting payjoin will just ignore the <code>pj=</code> parameter and proceed to typical address-based transaction flows. A <code>req-pj=</code> parameter, as specified in BIP 21, may be advertised to compel payjoin. |
What must occur if req-pj
is advertised by the receiver, but the sender doesn't support payjoin? Perhaps confirm here if it "MUST consider the entire URI invalid" per BIP 21, if that is the case.
bip-0077.mediawiki
Outdated
|
||
Senders not supporting payjoin will just ignore the <code>pj=</code> parameter and proceed to typical address-based transaction flows. <code>req-pj=</code> may be used to compel payjoin. | ||
|
||
Receivers may choose to support version 1 payloads. Version 2 payjoin URIs should enable <code>pjos=0</code> so that these v1 senders disable output substitution since the v1 messages are neither encrypted nor authenticated, putting them at risk for man-in-the-middle attacks otherwise. The directory protocol should carry on as normal, responding to payjoin requests instead with this version 1 request as BHTTP in an OHTTP response. The receiver should POST version 1 Payjoin PSBTs to the same subdirectory as in version 2 to respond to these version 1 senders within 30 seconds to respond to the sender's request. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Receivers may choose to support version 1 payloads. Version 2 payjoin URIs should enable <code>pjos=0</code> so that these v1 senders disable output substitution since the v1 messages are neither encrypted nor authenticated, putting them at risk for man-in-the-middle attacks otherwise. The directory protocol should carry on as normal, responding to payjoin requests instead with this version 1 request as BHTTP in an OHTTP response. The receiver should POST version 1 Payjoin PSBTs to the same subdirectory as in version 2 to respond to these version 1 senders within 30 seconds to respond to the sender's request. | |
Receivers may choose to support version 1 payloads. Version 2 payjoin URIs should enable <code>pjos=0</code> so that these v1 senders disable output substitution (since the v1 messages are neither encrypted nor authenticated, putting them at risk for man-in-the-middle attacks, otherwise). The directory protocol should carry on as normal, responding to payjoin requests instead with this version 1 request as BHTTP in an OHTTP response. The receiver should POST version 1 Payjoin PSBTs to the same subdirectory as in version 2 to respond to these version 1 senders within 30 seconds. |
- break up the long run-on sentence
- "to respond to the sender's request" at the end seems a little redundant.
bip-0077.mediawiki
Outdated
|
||
==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/rust-payjoin. Source code for an Oblivous HTTP relay implementation may be found here https://github.com/payjoin/ohttp-relay. The reference implementation implements an asynchronous payment flow using HTTP using PSBTv1 with encryption and Oblivious HTTP and may be configured to the following independent production relays: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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/rust-payjoin. Source code for an Oblivous HTTP relay implementation may be found here https://github.com/payjoin/ohttp-relay. The reference implementation implements an asynchronous payment flow using HTTP using PSBTv1 with encryption and Oblivious HTTP and may be configured to the following independent production relays: | |
A production reference implementation client can be found at [https://crates.io/crates/payjoin-cli](https://crates.io/crates/payjoin-cli). Source code for the clients, the payjoin directory, and the development kit may be found here: [https://github.com/payjoin/rust-payjoin](https://github.com/payjoin/rust-payjoin). Source code for an Oblivous HTTP relay implementation may be found here [https://github.com/payjoin/ohttp-relay](https://github.com/payjoin/ohttp-relay). The reference implementation implements an asynchronous payment flow using HTTP and PSBTv1 with encryption and Oblivious HTTP and may be configured to the following independent production relays: |
There may be a more idiomatic way to do it, but it seems best to remove the trailing .
from each link so that they function.
Idem for the two links afterward and the other links in this BIP that otherwise would contain a trailing period.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh, I thought they were working in the previewer. I think the idiomatic way to do it is to surround links with double square brackets [[ ]]
so I'll do that.
bip-0077.mediawiki
Outdated
|
||
==Acknowledgements== | ||
|
||
Thank you to OpenSats for funding this pursuit, to Human Rights Foundation for putting a bounty on it and funding invaluable BOB Space support, who I owe a thank you to as well. Thank you to Ethan Heilman, Nicolas Dorier, Kukks, nopara73, Kristaps Kaupe, Kixunil, /dev/fd0/, Craig Raw, Mike Schmidt, Murch, Dávid Molnár, Lucas Ontiviero, Waxwing, Christopher Allen, Symphonic, Steve Meyers, Sjors Provost, Ava Chow, jbesraa, and countless plebs for feedback that has turned this idea from concept into draft, to Mike Jarmuz for suggesting that I write a BIP, and to Satsie for writing the "All About BIPS" zine which I've referenced a number of times in the drafting process. Thanks to Armin Sabouri, Ron Stoner, and Johns Beharry for hacking on the first iOS Payjoin receiver and uncovering the problem that this solves in the first place. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you to OpenSats for funding this pursuit, to Human Rights Foundation for putting a bounty on it and funding invaluable BOB Space support, who I owe a thank you to as well. Thank you to Ethan Heilman, Nicolas Dorier, Kukks, nopara73, Kristaps Kaupe, Kixunil, /dev/fd0/, Craig Raw, Mike Schmidt, Murch, Dávid Molnár, Lucas Ontiviero, Waxwing, Christopher Allen, Symphonic, Steve Meyers, Sjors Provost, Ava Chow, jbesraa, and countless plebs for feedback that has turned this idea from concept into draft, to Mike Jarmuz for suggesting that I write a BIP, and to Satsie for writing the "All About BIPS" zine which I've referenced a number of times in the drafting process. Thanks to Armin Sabouri, Ron Stoner, and Johns Beharry for hacking on the first iOS Payjoin receiver and uncovering the problem that this solves in the first place. | |
Thank you to OpenSats for funding this pursuit, to the Human Rights Foundation for putting a bounty on it and funding invaluable BOB Space support, who I owe a thank you to as well. Thank you to Ethan Heilman, Nicolas Dorier, Kukks, nopara73, Kristaps Kaupe, Kixunil, /dev/fd0/, Craig Raw, Mike Schmidt, Murch, Dávid Molnár, Lucas Ontiviero, Waxwing, Christopher Allen, Symphonic, Steve Meyers, Sjors Provost, Ava Chow, jbesraa, and countless plebs for feedback that has turned this idea from concept into draft, to Mike Jarmuz for suggesting that I write a BIP, and to Satsie (Stacy Waleyko) for writing the "All About BIPS" zine which I've referenced a number of times in the drafting process. Thanks to Armin Sabouri, Ron Stoner, and Johns Beharry for hacking on the first iOS Payjoin receiver and uncovering the problem that this solves in the first place. |
I don't know if people like Murch, Waxwing, and Stacie would prefer to have their real names written in addition to their nickname, e.g. Mark "Murch" Erhardt, Waxwing (Adam Gibson), Satsie (Stacie Waleyko), etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just Murch is fine with me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EDIT: after reading the rest of the paragraph, I like the consistency and am fine staying as "Satsie" :)
bip-0077.mediawiki
Outdated
|
||
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. | ||
|
||
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 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: there is a mix of "V1" and "version 1" phrasing used, specifically in this paragraph, but I have seen it in other parts of the doc. "version 1" seems to be favored. This also applies to a few instances of "V2"/"version 2".
bip-0077.mediawiki
Outdated
|
||
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. | ||
|
||
Rather than hosting a public server, the receiver starts a session to receive messages and allocates a subdirectory from which to relay messages. The first message must include the receiver's public key to be enrolled as a subdirectory identifier. The response message from the directory to the receiver includes the newly enrolled subdirectory payjoin endpoint with the public key as identifying subdirectory. After enrollment, the receiver awaits a payjoin request on a session identified by the subdirectory. Out of band, the receiver shares a [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP 21]] payjoin URI including the directory endpoint in the <code>pj=</code> query parameter and a new Oblivious HTTP <code>ohttp=</code> parameter including the payjoin directory's [[https://www.ietf.org/rfc/rfc9458.html#name-key-configuration| OHTTP Key Configuration]]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than hosting a public server, the receiver starts a session to receive messages and allocates a subdirectory from which to relay messages. The first message must include the receiver's public key to be enrolled as a subdirectory identifier. The response message from the directory to the receiver includes the newly enrolled subdirectory payjoin endpoint with the public key as identifying subdirectory. After enrollment, the receiver awaits a payjoin request on a session identified by the subdirectory. Out of band, the receiver shares a [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP 21]] payjoin URI including the directory endpoint in the <code>pj=</code> query parameter and a new Oblivious HTTP <code>ohttp=</code> parameter including the payjoin directory's [[https://www.ietf.org/rfc/rfc9458.html#name-key-configuration| OHTTP Key Configuration]]. | |
Rather than hosting a public server, the receiver starts an HTTP client session with the directory server to receive messages and allocates a subdirectory from which to relay messages. The first message must include the receiver's public key to be enrolled as a subdirectory identifier. The response message from the directory to the receiver includes the newly enrolled subdirectory payjoin endpoint with the public key as identifying subdirectory. After enrollment, the receiver awaits a payjoin request on a session identified by the subdirectory. Out of band, the receiver shares a [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP 21]] payjoin URI including the directory endpoint in the <code>pj=</code> query parameter and a new Oblivious HTTP <code>ohttp=</code> parameter including the payjoin directory's [[https://www.ietf.org/rfc/rfc9458.html#name-key-configuration| OHTTP Key Configuration]]. |
It might be helpful to specify a bit more about the session, since that can be a pretty general term. I'm not sure if my suggestion here is the best, but you get the idea.
bip-0077.mediawiki
Outdated
|
||
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. | ||
|
||
Rather than hosting a public server, the receiver starts a session to receive messages and allocates a subdirectory from which to relay messages. The first message must include the receiver's public key to be enrolled as a subdirectory identifier. The response message from the directory to the receiver includes the newly enrolled subdirectory payjoin endpoint with the public key as identifying subdirectory. After enrollment, the receiver awaits a payjoin request on a session identified by the subdirectory. Out of band, the receiver shares a [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP 21]] payjoin URI including the directory endpoint in the <code>pj=</code> query parameter and a new Oblivious HTTP <code>ohttp=</code> parameter including the payjoin directory's [[https://www.ietf.org/rfc/rfc9458.html#name-key-configuration| OHTTP Key Configuration]]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than hosting a public server, the receiver starts a session to receive messages and allocates a subdirectory from which to relay messages. The first message must include the receiver's public key to be enrolled as a subdirectory identifier. The response message from the directory to the receiver includes the newly enrolled subdirectory payjoin endpoint with the public key as identifying subdirectory. After enrollment, the receiver awaits a payjoin request on a session identified by the subdirectory. Out of band, the receiver shares a [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP 21]] payjoin URI including the directory endpoint in the <code>pj=</code> query parameter and a new Oblivious HTTP <code>ohttp=</code> parameter including the payjoin directory's [[https://www.ietf.org/rfc/rfc9458.html#name-key-configuration| OHTTP Key Configuration]]. | |
Rather than hosting a public server, the receiver starts a session to receive messages and allocate a subdirectory from which to relay messages. The first message must include the receiver's public key to be enrolled as a subdirectory identifier. The response message from the directory to the receiver includes the newly enrolled subdirectory payjoin endpoint with the public key as identifying subdirectory. After enrollment, the receiver awaits a payjoin request on a session identified by the subdirectory. Out of band, the receiver shares a [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP 21]] payjoin URI including the directory endpoint in the <code>pj=</code> query parameter and a new Oblivious HTTP <code>ohttp=</code> parameter including the payjoin directory's [[https://www.ietf.org/rfc/rfc9458.html#name-key-configuration| OHTTP Key Configuration]]. |
This suggestion is kind of related to my previous comment. I read it as you start a session because you plan to receive messages, as well as allocate your subdirectory. However, when I initially read this sentence I questioned if the subdirectory was something local because I thought allocating the subdirectory was a separate, unrelated action from receiving messages. Since the session is to the directory server (specifying that is what my previous comment suggests), changing "allocates" to "allocate" (so that it matches the tense of "receive") allows the sentence to imply that the subdirectory is indeed part of the directory server.
bip-0077.mediawiki
Outdated
|
||
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. | ||
|
||
Rather than hosting a public server, the receiver starts a session to receive messages and allocates a subdirectory from which to relay messages. The first message must include the receiver's public key to be enrolled as a subdirectory identifier. The response message from the directory to the receiver includes the newly enrolled subdirectory payjoin endpoint with the public key as identifying subdirectory. After enrollment, the receiver awaits a payjoin request on a session identified by the subdirectory. Out of band, the receiver shares a [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP 21]] payjoin URI including the directory endpoint in the <code>pj=</code> query parameter and a new Oblivious HTTP <code>ohttp=</code> parameter including the payjoin directory's [[https://www.ietf.org/rfc/rfc9458.html#name-key-configuration| OHTTP Key Configuration]]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part reads a little strange. Would either of these suggestions be an improvement?
Rather than hosting a public server, the receiver starts a session to receive messages and allocates a subdirectory from which to relay messages. The first message must include the receiver's public key to be enrolled as a subdirectory identifier. The response message from the directory to the receiver includes the newly enrolled subdirectory payjoin endpoint with the public key as identifying subdirectory. After enrollment, the receiver awaits a payjoin request on a session identified by the subdirectory. Out of band, the receiver shares a [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP 21]] payjoin URI including the directory endpoint in the <code>pj=</code> query parameter and a new Oblivious HTTP <code>ohttp=</code> parameter including the payjoin directory's [[https://www.ietf.org/rfc/rfc9458.html#name-key-configuration| OHTTP Key Configuration]]. | |
Rather than hosting a public server, the receiver starts a session to receive messages and allocates a subdirectory from which to relay messages. The first message must include the receiver's public key to be enrolled as a subdirectory identifier. The response message from the directory to the receiver includes the newly enrolled subdirectory payjoin endpoint with the public key as the subdirectory identifier. After enrollment, the receiver awaits a payjoin request on a session identified by the subdirectory. Out of band, the receiver shares a [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP 21]] payjoin URI including the directory endpoint in the <code>pj=</code> query parameter and a new Oblivious HTTP <code>ohttp=</code> parameter including the payjoin directory's [[https://www.ietf.org/rfc/rfc9458.html#name-key-configuration| OHTTP Key Configuration]]. |
Rather than hosting a public server, the receiver starts a session to receive messages and allocates a subdirectory from which to relay messages. The first message must include the receiver's public key to be enrolled as a subdirectory identifier. The response message from the directory to the receiver includes the newly enrolled subdirectory payjoin endpoint with the public key as identifying subdirectory. After enrollment, the receiver awaits a payjoin request on a session identified by the subdirectory. Out of band, the receiver shares a [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP 21]] payjoin URI including the directory endpoint in the <code>pj=</code> query parameter and a new Oblivious HTTP <code>ohttp=</code> parameter including the payjoin directory's [[https://www.ietf.org/rfc/rfc9458.html#name-key-configuration| OHTTP Key Configuration]]. | |
Rather than hosting a public server, the receiver starts a session to receive messages and allocates a subdirectory from which to relay messages. The first message must include the receiver's public key to be enrolled as a subdirectory identifier. The response message from the directory to the receiver includes the newly enrolled subdirectory payjoin endpoint with the public key identifying the subdirectory. After enrollment, the receiver awaits a payjoin request on a session identified by the subdirectory. Out of band, the receiver shares a [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP 21]] payjoin URI including the directory endpoint in the <code>pj=</code> query parameter and a new Oblivious HTTP <code>ohttp=</code> parameter including the payjoin directory's [[https://www.ietf.org/rfc/rfc9458.html#name-key-configuration| OHTTP Key Configuration]]. |
| subdirectory) | | | | ||
+---------------------------------------------------->| | | ||
| | | | | ||
| Request Original PSBT | | | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Want to make sure I'm reading this correctly, this is when the requester starts polling for the Original PSBT, right? Before I saw the key down below for the line types, I got confused that the sender had not yet posted the original PSBT
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes indeed. If you think there might be a better way to express such a diagram I am open to suggestions.
I can put the key on the top to help.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok cool. No I don't have any suggestions 😆. If this were something richer than an ASCII diagram I'd suggest making the two types of lines more obviously different but I'm not sure if there's much you can do about it in this format.
I think it's normal/fine to leave the key at the bottom.
bip-0077.mediawiki
Outdated
|
||
===Message Padding=== | ||
|
||
All cyphertexts should be padded to the same length of 7168 bytes to prevent traffic analysis. This is sufficient size for most transaction PSBTs without exceeding the 8KB limit of many HTTP/1.1 web servers. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is "transaction PSBTs" redundant? Or does "transaction" not refer to a Bitcoin transaction?
bip-0077.mediawiki
Outdated
|
||
===Message Padding=== | ||
|
||
All cyphertexts should be padded to the same length of 7168 bytes to prevent traffic analysis. This is sufficient size for most transaction PSBTs without exceeding the 8KB limit of many HTTP/1.1 web servers. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you able to provide a link to where the 7168 number comes from?
bip-0077.mediawiki
Outdated
|
||
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. | ||
|
||
Rather than hosting a public server, the receiver starts a session to receive messages and allocates a subdirectory from which to relay messages. The first message must include the receiver's public key to be enrolled as a subdirectory identifier. The response message from the directory to the receiver includes the newly enrolled subdirectory payjoin endpoint with the public key as identifying subdirectory. After enrollment, the receiver awaits a payjoin request on a session identified by the subdirectory. Out of band, the receiver shares a [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP 21]] payjoin URI including the directory endpoint in the <code>pj=</code> query parameter and a new Oblivious HTTP <code>ohttp=</code> parameter including the payjoin directory's [[https://www.ietf.org/rfc/rfc9458.html#name-key-configuration| OHTTP Key Configuration]]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After reading the full BIP I've come to understand that the public key is specific to a session. It might be worth mentioning this up here at the top of the doc so that later when "public key" and "session public key" are used, there isn't a question on if these are separate things.
bip-0077.mediawiki
Outdated
|
||
Since directories store arbitrary encrypted payloads they are vulnerable to the tragedy of the commons and denial of service attacks. Directory operators may impose an authentication requirement before they allocate a subdirectory to receivers to mitigate such attacks. | ||
|
||
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 compromiser. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 compromiser. | |
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 compromiser. |
bip-0077.mediawiki
Outdated
|
||
===Network privacy=== | ||
|
||
Oblivious HTTP must be used to protect the IP address of both sender and receiver from the directory. This requires an additional key configuration to be shared in the bip21 URI and for the directory to support Oblivious HTTP. A secp256k1 HPKE OHTTP configuration should be used to leverage the cryptography already available in bitcoin contexts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oblivious HTTP must be used to protect the IP address of both sender and receiver from the directory. This requires an additional key configuration to be shared in the bip21 URI and for the directory to support Oblivious HTTP. A secp256k1 HPKE OHTTP configuration should be used to leverage the cryptography already available in bitcoin contexts. | |
Oblivious HTTP must be used to protect the IP addresses of both sender and receiver from the directory. This requires an additional key configuration to be shared in the bip21 URI and for the directory to support Oblivious HTTP. A secp256k1 HPKE OHTTP configuration should be used to leverage the cryptography already available in bitcoin contexts. |
I'm only 80% sure of this grammar correction 😆
I really enjoyed reading this :) Well done! Dropped some comments on mainly nit related suggestions, but there were a few places where I left comments seeking clarification. |
Enrollment was a less clear than sessions
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.