BIP 77: Payjoin Version 2 — Async Payjoin #1483

pull DanGould wants to merge 42 commits into bitcoin:master from DanGould:pjv2 changing 3 files +287 −0
  1. DanGould commented at 9:10 pm on August 12, 2023: contributor

    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.

  2. DanGould force-pushed on Dec 14, 2023
  3. DanGould marked this as ready for review on Dec 14, 2023
  4. luke-jr added the label New BIP on Dec 26, 2023
  5. luke-jr commented at 7:14 pm on December 26, 2023: member
    Let’s call this BIP 77
  6. luke-jr renamed this:
    BIP for Payjoin Version 2: Serverless Payjoin
    BIP 77: Payjoin Version 2: Serverless Payjoin
    on Dec 26, 2023
  7. DanGould force-pushed on Mar 6, 2024
  8. murchandamus commented at 6:50 pm on May 1, 2024: 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.
  9. in bip-0077.mediawiki:26 in 37f74d8226 outdated
    21+
    22+==Motivation==
    23+
    24+Payjoin solves the sole privacy problem left open in the bitcoin paper, that transactions with multiple inputs "necessarily reveal that their inputs were owned by the same owner." Breaking that common-input ownership assumption and others requires input from multiple owners. Cooperative transaction construction also increases transaction throughput by providing new opportunity for payment batching and transaction cut-through.
    25+
    26+Version 1 coordinates payjoins over a public server endpoint secured by either TLS or Tor hidden service hosted by the receiver. Version 1 is synchronous, requiring both sender and reciever 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 develoepers [[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-January/018358.html|regard]] these as limits to payjoin adoption.
    


    spacebear21 commented at 9:21 pm on May 2, 2024:
    0Version 1 coordinates payjoins over a public server endpoint secured by either TLS or Tor hidden service hosted by the receiver. Version 1 is 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.
    
  10. in bip-0077.mediawiki:34 in 37f74d8226 outdated
    29+
    30+===Relation to BIP 78 (Payjoin version 1)===
    31+
    32+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.
    33+
    34+The BIP 78 standard allows for an [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#unsecured-payjoin-server|unsecured payjoin server|]] to operate separately from the so-called "payment server" responsible for generating [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki|BIP 21]] request URIs. Because BIP 78 messages relayed over an unsecured server are neither end-to-end authenticated nor encrypted between sender and receiver, a malicious unsecured payjoin server is able to modify the Payjoin PSBT in flight, thus requiring payment output substitition to be disabled. Output substitition is useful for a number of block space optimizations, including payment batching and transaction cut-through. This proposal introduces authentication and encryption to secure output substition while using a directory relay without compromising sender or receiver privacy.
    


    spacebear21 commented at 9:23 pm on May 2, 2024:
    0The BIP 78 standard allows for an [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#unsecured-payjoin-server|unsecured payjoin server|]] to operate separately from the so-called "payment server" responsible for generating [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki|BIP 21]] request URIs. Because BIP 78 messages relayed over an unsecured server are neither end-to-end authenticated nor encrypted between sender and receiver, a malicious unsecured payjoin server is able to modify the Payjoin PSBT in flight, thus requiring payment output substitution to be disabled. Output substitution is useful for a number of block space optimizations, including payment batching and transaction cut-through. This proposal introduces authentication and encryption to secure output substitution while using a directory relay without compromising sender or receiver privacy.
    
  11. in bip-0077.mediawiki:42 in 37f74d8226 outdated
    37+
    38+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.
    39+
    40+===Relation to Stowaway===
    41+
    42+[[https://code.samourai.io/wallet/ExtLibJ/-/blob/develop/doc/cahoots/STOWAWAY.md|Stowaway]] is a payjoin coordination mechanism which depends on Tor, a third-party relay, and the [[https://samouraiwallet.com/paynym|PayNym]] [[https://github.com/bitcoin/bips/blob/master/bip-0047.mediawiki|BIP 47]] Payment codes directory for subdirectory identification and encryption. The payjoin version 2 protocol uses per-request public keys for relay subdirectory identification, authentication, and encryption instead of BIP 47 public keys derived from a wallet. Payjoin version 2 also supports asynchronous messaging, in contrast to Stowaway's synchronous messaging. Offline stowaway depends on manual message passing rather than an asynchronous network protocol. Successful Stowaway execution results in 2-output transactions, while BIP 78, and this work may produce batched transactions with many outputs.
    


    spacebear21 commented at 9:24 pm on May 2, 2024:
    0[[https://code.samourai.io/wallet/ExtLibJ/-/blob/develop/doc/cahoots/STOWAWAY.md|Stowaway]] is a payjoin coordination mechanism which depends on Tor, a third-party relay, and the [[https://samouraiwallet.com/paynym|PayNym]] [[https://github.com/bitcoin/bips/blob/master/bip-0047.mediawiki|BIP 47]] Payment codes directory for subdirectory identification and encryption. The payjoin version 2 protocol uses per-request public keys for relay subdirectory identification, authentication, and encryption instead of BIP 47 public keys derived from a wallet. Payjoin version 2 also supports asynchronous messaging, in contrast to Stowaway's synchronous messaging. Offline Stowaway depends on manual message passing rather than an asynchronous network protocol. Successful Stowaway execution results in 2-output transactions, while BIP 78, and this work may produce batched transactions with many outputs.
    
  12. in bip-0077.mediawiki:48 in 37f74d8226 outdated
    43+
    44+==Specification==
    45+
    46+===Overview===
    47+
    48+Payjoin requests are made using familiar BIP 21 URIs. Instead of a public HTTP endpoint, this scheme allows an HTTP client to enroll with a store-and-forward directory server to receive payjoin. Directories may optionally require an authorization credential before allocating resources in order to prevent DoS attacks. Sender and receiver payloads are buffered at the directory to support asynchronous interaction. Authenticated encryption prevents the directory from snooping on message contents or forging messages by way of HPKE. Oblivious HTTP is required for version 2 interactions in order to separate client IP addresses from the directory to prevent metadata attacks. Aside from a application layer authenticated encryption and relayed asynchronus networking, the version 2 messaging takes much the same form as the existing BIP 78 specification.
    


    spacebear21 commented at 9:25 pm on May 2, 2024:
    0Payjoin requests are made using familiar BIP 21 URIs. Instead of a public HTTP endpoint, this scheme allows an HTTP client to enroll with a store-and-forward directory server to receive payjoin. Directories may optionally require an authorization credential before allocating resources in order to prevent DoS attacks. Sender and receiver payloads are buffered at the directory to support asynchronous interaction. Authenticated encryption prevents the directory from snooping on message contents or forging messages by way of HPKE. Oblivious HTTP is required for version 2 interactions in order to separate client IP addresses from the directory to prevent metadata attacks. Aside from a application layer authenticated encryption and relayed asynchronous networking, the version 2 messaging takes much the same form as the existing BIP 78 specification.
    
  13. in bip-0077.mediawiki:74 in 37f74d8226 outdated
    69+- The sender continues to replay this request in order to await a response from the directory containing a <code>Payjoin PSBT</code>. It stops after expiry.
    70+- The request is stored in the subdirectory.
    71+- Once the receiver is online, it sends <code>/receive</code>requests to await updates from the subdirectory. The receiver decrypts and authenticates the response which it checks according to [[https://github.com/bitcoin/bips/blob/master/bip-0078#receivers-original-psbt-checklist|the receiver checklist]]. It updates the Original PSBT to include new signed inputs and outputs, invalidating sender signatures, and may adjust the fee. The result is called the <code>Payjoin PSBT</code>.
    72+- The <code>Payjoin PSBT</code> and HPKE keys are encrypted, authenticated, encapsulated in OHTTP, and sent to the directory's OHTTP Gateway.
    73+- The directory awaits a request from the sender if it goes offline. Upon request, it relays the encrypted <code>Payjoin PSBT</code>.
    74+- The sender validates the <code>Payjoin PSBT</code> according to [[#senders-payjoin-psbt-checklist|the sender checklist]], signs its inputs and broadcasts the transaction to the Bitcoin network.
    


    spacebear21 commented at 9:41 pm on May 2, 2024:

    For some reason these Markdown lists aren’t rendering properly on the GitHub file view.

    0* The recipient sends their payjoin pubkey and optional authentication credential according to [[#directory-enrollment|receiver directory enrollment]] protocol to receive a subdirectory allocation. It may go offline and replay enrollment to come back online.
    1* Out of band, the receiver of the payment, shares a bitcoin URI with the sender including a <code>pj=</code> query parameter including the subdirectory as a base64URL encoded pubkey. To support version 1 senders the directory acts as an unsecured payjoin server so <code>pjos=0</code> must be specified in the URI. Version 2 senders may safely allow output substitution regardless. An <code>ohttp=</code> parameter containing the directory's base64URL Key Config should also be provided.
    2* The sender creates a valid version 2 PSBT satisfying the [[https://github.com/bitcoin/bips/blob/master/bip-0078#receivers-original-psbt-checklist|the receiver checklist]]. We call this the <code>Original PSBT</code>. This <code>Original PSBT</code>, optional sender parameters, and HPKE keys are encrypted and authenticated, and encapsulated in OHTTP. This [[#original-psbt-request|Original PSBT Request]] is sent to the directory's OHTTP Gateway.
    3* The sender continues to replay this request in order to await a response from the directory containing a <code>Payjoin PSBT</code>. It stops after expiry.
    4* The request is stored in the subdirectory.
    5* Once the receiver is online, it sends <code>/receive</code>requests to await updates from the subdirectory. The receiver decrypts and authenticates the response which it checks according to [[https://github.com/bitcoin/bips/blob/master/bip-0078#receivers-original-psbt-checklist|the receiver checklist]]. It updates the Original PSBT to include new signed inputs and outputs, invalidating sender signatures, and may adjust the fee. The result is called the <code>Payjoin PSBT</code>.
    6* The <code>Payjoin PSBT</code> and HPKE keys are encrypted, authenticated, encapsulated in OHTTP, and sent to the directory's OHTTP Gateway.
    7* The directory awaits a request from the sender if it goes offline. Upon request, it relays the encrypted <code>Payjoin PSBT</code>.
    8* The sender validates the <code>Payjoin PSBT</code> according to [[#senders-payjoin-psbt-checklist|the sender checklist]], signs its inputs and broadcasts the transaction to the Bitcoin network.
    
  14. in bip-0077.mediawiki:82 in 37f74d8226 outdated
    77+
    78+- Include complete UTXO data.
    79+- Be signed.
    80+- Exclude unnecessary fields such as global xpubs or keypath information. <!-- I believe PSBTv2 obviates this requirement -->
    81+- Set input and output Transaction Modifiable Flags to 1
    82+- Be broadcastable.
    


    spacebear21 commented at 9:41 pm on May 2, 2024:
    0* Include complete UTXO data.
    1* Be signed.
    2* Exclude unnecessary fields such as global xpubs or keypath information. <!-- I believe PSBTv2 obviates this requirement -->
    3* Set input and output Transaction Modifiable Flags to 1
    4* Be broadcastable.
    
  15. in bip-0077.mediawiki:87 in 37f74d8226 outdated
    82+- Be broadcastable.
    83+
    84+The Original PSBT MAY:
    85+
    86+- Include outputs unrelated to the sender-receiver transfer for batching purposes.
    87+- Set SIGHASH_SINGLE Transaction Modifiable Flags flags to 1
    


    spacebear21 commented at 9:42 pm on May 2, 2024:
    0* Include outputs unrelated to the sender-receiver transfer for batching purposes.
    1* Set SIGHASH_SINGLE Transaction Modifiable Flags flags to 1
    
  16. in bip-0077.mediawiki:93 in 37f74d8226 outdated
    88+
    89+The Payjoin PSBT MUST:
    90+
    91+- Include all inputs from the Original PSBT.
    92+- Include all outputs which do not belong to the receiver from the Original PSBT.
    93+- Include complete UTXO data.
    


    spacebear21 commented at 9:43 pm on May 2, 2024:
    0* Include all inputs from the Original PSBT.
    1* Include all outputs which do not belong to the receiver from the Original PSBT.
    2* Include complete UTXO data.
    
  17. in bip-0077.mediawiki:97 in 37f74d8226 outdated
    92+- Include all outputs which do not belong to the receiver from the Original PSBT.
    93+- Include complete UTXO data.
    94+
    95+The Payjoin PSBT sender MAY:
    96+
    97+- Add, remove or modify Original PSBT outputs under the control of the receiver (i.e. not sender change).
    


    spacebear21 commented at 9:43 pm on May 2, 2024:
    0* Add, remove or modify Original PSBT outputs under the control of the receiver (i.e. not sender change).
    
  18. in bip-0077.mediawiki:102 in 37f74d8226 outdated
     97+- Add, remove or modify Original PSBT outputs under the control of the receiver (i.e. not sender change).
     98+
     99+The Payjoin PSBT MUST NOT:
    100+
    101+- Shuffle the order of inputs or outputs; the additional outputs or additional inputs must be inserted at a random index.
    102+- Decrease the absolute fee of the original transaction.
    


    spacebear21 commented at 9:43 pm on May 2, 2024:
    0* Shuffle the order of inputs or outputs; the additional outputs or additional inputs must be inserted at a random index.
    1* Decrease the absolute fee of the original transaction.
    
  19. in bip-0077.mediawiki:106 in 37f74d8226 outdated
    101+- Shuffle the order of inputs or outputs; the additional outputs or additional inputs must be inserted at a random index.
    102+- Decrease the absolute fee of the original transaction.
    103+
    104+====Enroll Messaging====
    105+
    106+Receivers must enroll with a directory to a subdirectory allocated. 
    


    spacebear21 commented at 9:49 pm on May 2, 2024:
    This sentence seems malformed. Did you mean “to get a subdirectory allocated”?

    DanGould commented at 3:09 am on May 3, 2024:
    Yes.
  20. in bip-0077.mediawiki:151 in 37f74d8226 outdated
    146+A major benefit of BIP 78 payjoin over other coordination mechanisms is its compatibility with the universal BIP 21 bitcoin URI standard.
    147+
    148+This proposal defines the following new [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki|BIP 21 URI]] parameters:
    149+
    150+- <code>ohttp</code> represents the OHTTP Key Configuration of the directory server. This is a base64URL encoded public key of the directory server's OHTTP Gateway. This parameter is required for version 2 payjoin URIs.
    151+- <code>exp</code>: represents a request expiration after which the receiver reserves the right to broadcast the transaction extracted from the Original PSBT and ignore requests. This is only necessary for receivers who only support synchonous execution of the protocol, like automated payment processors.
    


    spacebear21 commented at 10:02 pm on May 2, 2024:
    0* <code>ohttp</code> represents the OHTTP Key Configuration of the directory server. This is a base64URL encoded public key of the directory server's OHTTP Gateway. This parameter is required for version 2 payjoin URIs.
    1* <code>exp</code>: represents a request expiration after which the receiver reserves the right to broadcast the transaction extracted from the Original PSBT and ignore requests. This is only necessary for receivers who only support synchronous execution of the protocol, like automated payment processors.
    
  21. in bip-0077.mediawiki:157 in 37f74d8226 outdated
    152+
    153+===Optional sender parameters===
    154+
    155+When the payjoin sender posts the original PSBT to the receiver, it can optionally specify the following HTTP query string parameters:
    156+
    157+- <code>v</code>: represents the version number of the payjoin protocol that the sender is using. This version is <code>2</code>.
    


    spacebear21 commented at 10:02 pm on May 2, 2024:
    0* <code>v</code>: represents the version number of the payjoin protocol that the sender is using. This version is <code>2</code>.
    
  22. in bip-0077.mediawiki:185 in 37f74d8226 outdated
    180+
    181+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.
    182+
    183+===Secp256k1 Hybrid Public Key Encryption===
    184+
    185+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 appication specific configuration to use DHKEM(Secp256k1, HKDF-SHA256) and ChaCha20Poly1305 AEAD.
    


    spacebear21 commented at 10:08 pm on May 2, 2024:
    0Hybrid 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.
    
  23. in bip-0077.mediawiki:217 in 37f74d8226 outdated
    212+
    213+===Network privacy=== 
    214+
    215+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.
    216+
    217+Unlike BIP 78 implementations, sender and receiver peers will only see the IP address of the directory, not their peers. Directories may aditionally be made available via Tor hidden service to allow either of the peers to protect their IP from the directory with without OHTTP.
    


    spacebear21 commented at 10:13 pm on May 2, 2024:
    0Unlike BIP 78 implementations, sender and receiver peers will only see the IP address of the directory, not their peers. Directories may additionally be made available via Tor hidden service to allow either of the peers to protect their IP from the directory with without OHTTP.
    
  24. in bip-0077.mediawiki:8 in 37f74d8226 outdated
    0@@ -0,0 +1,237 @@
    1+<pre>
    2+  BIP: 77
    3+  Layer: Applications
    4+  Title: Payjoin Version 2: Serverless Payjoin
    5+  Author: Dan Gould <d@ngould.dev>
    6+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0077
    7+  Status: Draft
    8+  Replaces: 78
    


    spacebear21 commented at 10:30 pm on May 2, 2024:
    I don’t think this really replaces BIP78 since it’s intended to be backwards-compatible?
  25. DanGould marked this as a draft on May 3, 2024
  26. Draft payjoin v2 BIP 5e2f2aad1c
  27. Include mailing list feedback 3df3f51bf2
  28. Include TABConf feedback 936d0e7fd9
  29. Include padding 4069db51ba
  30. Include production reference implementation 45daed4ef1
  31. Adopt BIP-77 for payjoin v2 b593c457c9
  32. Distinguish payjoin directory from OHTTP Relay 6becb34a5e
  33. Detail OHTTP Key Configuration mechanism 754e287d46
  34. Fix punctuation 80b8bacfd0
  35. Make base64URL references consistent b5353b59b0
  36. Reference standardized Secp256k1 DHKEM for HPKE 9e8b4d7ee7
  37. Add Comments-URI 3c1629bb23
  38. DanGould force-pushed on May 3, 2024
  39. DanGould force-pushed on May 3, 2024
  40. DanGould commented at 3:14 am on May 3, 2024: contributor

    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.

  41. in bip-0077.mediawiki:47 in 7e74783a7f outdated
    42+
    43+==Specification==
    44+
    45+===Overview===
    46+
    47+Payjoin requests are made using familiar BIP 21 URIs. Instead of a public HTTP endpoint, this scheme allows an HTTP client to enroll with a store-and-forward directory server to receive payjoin. Directories may optionally require an authorization credential before allocating resources in order to prevent DoS attacks. Sender and receiver payloads are buffered at the directory to support asynchronous interaction. Authenticated encryption prevents the directory from snooping on message contents or forging messages by way of HPKE. Oblivious HTTP is required for version 2 interactions in order to separate client IP addresses from the directory to prevent metadata attacks. Aside from a application layer authenticated encryption and relayed asynchronous networking, the version 2 messaging takes much the same form as the existing BIP 78 specification.
    


    thebrandonlucas commented at 1:41 am on May 6, 2024:

    Grammar error?

    0Payjoin requests are made using familiar BIP 21 URIs. Instead of a public HTTP endpoint, this scheme allows an HTTP client to enroll with a store-and-forward directory server to receive payjoin. Directories may optionally require an authorization credential before allocating resources in order to prevent DoS attacks. Sender and receiver payloads are buffered at the directory to support asynchronous interaction. Authenticated encryption prevents the directory from snooping on message contents or forging messages by way of HPKE. Oblivious HTTP is required for version 2 interactions in order to separate client IP addresses from the directory to prevent metadata attacks. Aside from application layer authenticated encryption and relayed asynchronous networking, version 2 messaging takes much the same form as the existing BIP 78 specification.
    
  42. in bip-0077.mediawiki:179 in 7e74783a7f outdated
    174+
    175+The version 2 sender's checklist is largely the same as the [[https://github.com/bitcoin/bips/blob/master/bip-0078#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 headaches since it required the sender to add them back to the Payjoin proposal PSBT. Version 2 has no such requirement.
    176+
    177+===Directory interactions===
    178+
    179+The Payjoin Directory provides a rendezvous point for sender and receiver to meet. It stores Payjoin payloads to support asynchronous communication. It must only accept OHTTP requests with an OHTTP Gateway for Payjoin version 2, accepting encrypted payloads. It may optionally accept HTTP/1.1 POST requests without HTTP to enrolled subdirectories to support backwards compatible Payjoin version 1 requests.
    


    thebrandonlucas commented at 1:51 am on May 6, 2024:
    At different times, “directory”, “directory server”, and “payjoin directory” (sometimes capitalized) are used to refer to the same thing. It may be useful to standardize the usage of this terminology throughout for clarity, or use an acronym where the term is defined.

    DanGould commented at 10:04 pm on May 6, 2024:

    I’ve changed this to use either “directory” as shorthand or " and only once “payjoin directory server” to introduce the fact that it is in fact a server. Un-capitalized to be consistent.

    If you think this is still too varied, please let me know.

  43. in bip-0077.mediawiki:175 in 7e74783a7f outdated
    170+
    171+Other than requiring PSBTv2 the receiver checklist is the same as the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist|the BIP 78 receiver checklist]]
    172+
    173+===Sender's Payjoin PSBT checklist===
    174+
    175+The version 2 sender's checklist is largely the same as the [[https://github.com/bitcoin/bips/blob/master/bip-0078#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 headaches since it required the sender to add them back to the Payjoin proposal PSBT. Version 2 has no such requirement.
    


    thebrandonlucas commented at 2:05 am on May 6, 2024:

    Link leads to 404. I think this was meant to lead here?

    0The 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 sender 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 headaches since it required the sender to add them back to the Payjoin proposal PSBT. Version 2 has no such requirement.
    

    DanGould commented at 10:02 pm on May 6, 2024:
    It turned out bar is used for links inside the repo and spaces should be used for external links. So I’ve adjusted them all accordingly. Nice catches.
  44. in bip-0077.mediawiki:107 in 7e74783a7f outdated
    102+
    103+Payjoin v2 messages use [[https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki|BIP 370 PSBT v2]] format to fascilitate PSBT mutation.
    104+
    105+The payjoin version 2 protocol takes the following steps:
    106+
    107+* The recipient sends their payjoin pubkey and optional authentication credential according to [[#directory-enrollment|receiver directory enrollment]] protocol to receive a subdirectory allocation. It may go offline and replay enrollment to come back online.
    


    thebrandonlucas commented at 2:12 am on May 6, 2024:
    Where is “receiver directory enrollment” supposed to link to? here?
  45. in bip-0077.mediawiki:109 in 7e74783a7f outdated
    104+
    105+The payjoin version 2 protocol takes the following steps:
    106+
    107+* The recipient sends their payjoin pubkey and optional authentication credential according to [[#directory-enrollment|receiver directory enrollment]] protocol to receive a subdirectory allocation. It may go offline and replay enrollment to come back online.
    108+* Out of band, the receiver of the payment, shares a bitcoin URI with the sender including a <code>pj=</code> query parameter including the subdirectory as a base64URL encoded pubkey. To support version 1 senders the directory acts as an unsecured payjoin server so <code>pjos=0</code> must be specified in the URI. Version 2 senders may safely allow output substitution regardless. An <code>ohttp=</code> parameter containing the directory's base64URL Key Config should also be provided.
    109+* The sender creates a valid version 2 PSBT satisfying the [[https://github.com/bitcoin/bips/blob/master/bip-0078#receivers-original-psbt-checklist|the receiver checklist]]. We call this the <code>Original PSBT</code>. This <code>Original PSBT</code>, optional sender parameters, and HPKE keys are encrypted and authenticated, and encapsulated in OHTTP. This [[#original-psbt-request|Original PSBT Request]] is sent to the directory's OHTTP Gateway.
    


    thebrandonlucas commented at 2:19 am on May 6, 2024:
    Where is “Original PSBT Request” supposed to link to?
  46. in bip-0077.mediawiki:103 in 7e74783a7f outdated
     98+|- - -> Polled transmission
     99+</pre>
    100+
    101+===Payjoin version 2 messaging===
    102+
    103+Payjoin v2 messages use [[https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki|BIP 370 PSBT v2]] format to fascilitate PSBT mutation.
    


    thebrandonlucas commented at 2:20 am on May 6, 2024:
    0Payjoin v2 messages use [[https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki|BIP 370 PSBT v2]] format to facilitate PSBT mutation.
    
  47. in bip-0077.mediawiki:143 in 7e74783a7f outdated
    138+* Add, remove or modify Original PSBT outputs under the control of the receiver (i.e. not sender change).
    139+
    140+The Payjoin PSBT MUST NOT:
    141+
    142+* Shuffle the order of inputs or outputs; the additional outputs or additional inputs must be inserted at a random index.
    143+* Decrease the absolute fee of the original transaction.
    


    thebrandonlucas commented at 2:21 am on May 6, 2024:

    We’re referring to the Original PSBT here, yes?

    0* Decrease the absolute fee of the Original PSBT.
    
  48. in bip-0077.mediawiki:263 in 7e74783a7f outdated
    258+
    259+===Network privacy===
    260+
    261+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.
    262+
    263+Unlike BIP 78 implementations, sender and receiver peers will only see the IP address of the directory, not their peers. Directories may additionally be made available via Tor hidden service to allow either of the peers to protect their IP from the directory with without OHTTP.
    


    thebrandonlucas commented at 2:21 am on May 6, 2024:
    0Unlike BIP 78 implementations, sender and receiver peers will only see the IP address of the directory, not their peers. Directories may additionally be made available via Tor hidden service to allow either of the peers to protect their IP from the directory without OHTTP.
    
  49. fixup: Format and spell check
    Co-authored-by: spacebear <144076611+grizznaut@users.noreply.github.com>
    a0d3654471
  50. Add BIP 77 to README b758311ba6
  51. Add Payjoin V2 overview diagram 95a3b14b81
  52. Add Oblivious HTTP Sequence Diagram 6646e9908c
  53. DanGould force-pushed on May 6, 2024
  54. Correct links and spelling
    Co-authored-by: thebrandonlucas <38222767+thebrandonlucas@users.noreply.github.com>
    5ff5b7ae77
  55. DanGould force-pushed on May 6, 2024
  56. in bip-0077.mediawiki:112 in 5ff5b7ae77 outdated
    107+* The recipient sends their payjoin pubkey and optional authentication credential according to the [[#enroll-messaging|enroll messaging]] protocol to receive a subdirectory allocation. It may go offline and replay enrollment to come back online.
    108+* Out of band, the receiver of the payment, shares a bitcoin URI with the sender including a <code>pj=</code> query parameter including the subdirectory as a base64URL encoded pubkey. To support version 1 senders the directory acts as an unsecured payjoin server so <code>pjos=0</code> must be specified in the URI. Version 2 senders may safely allow output substitution regardless. An <code>ohttp=</code> parameter containing the directory's base64URL Key Config should also be provided.
    109+* The sender creates a valid version 2 PSBT satisfying the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist the receiver checklist]]. We call this the <code>Original PSBT</code>. This <code>Original PSBT</code>, optional sender parameters, and HPKE keys are encrypted and authenticated, and encapsulated in OHTTP. This [[#send-messaging|Original PSBT Request send message]] is sent to the directory's OHTTP Gateway.
    110+* The sender continues to replay this request in order to await a response from the directory containing a <code>Payjoin PSBT</code>. It stops after expiry.
    111+* The request is stored in the subdirectory.
    112+* Once the receiver is online, it sends <code>/receive</code>requests to await updates from the subdirectory. The receiver decrypts and authenticates the response which it checks according to [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist the receiver checklist]]. It updates the Original PSBT to include new signed inputs and outputs, invalidating sender signatures, and may adjust the fee. The result is called the <code>Payjoin PSBT</code>.
    


    spacebear21 commented at 1:42 am on May 7, 2024:
    0* Once the receiver is online, it sends <code>/receive</code> requests to await updates from the subdirectory. The receiver decrypts and authenticates the response which it checks according to [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist the receiver checklist]]. It updates the Original PSBT to include new signed inputs and outputs, invalidating sender signatures, and may adjust the fee. The result is called the <code>Payjoin PSBT</code>.
    
  57. in bip-0077.mediawiki:165 in 5ff5b7ae77 outdated
    160+
    161+The directory's OHTTP Gateway decapsulates the OHTTP request, decrypts the payload, and forwards the BHTTP POST request to the receiver's internal subdirectory endpoint which stores the HPKE encrypted payload to be forwarded to the receiver. The directory's OHTTP Gateway then awaits a response from the receiver's subdirectory endpoint, encapsulates it, and responds according to OHTTP.
    162+
    163+====Receive Messaging====
    164+
    165+The receiver sends a GET request to the path of the subdirectory followed by `/receive`. This request is encapsulated in OHTTP. It awaits an OHTTP response from the directory containing the BHTTP request from the sender with status code 200 OK, or sends a new OHTTP request after receiving 202 ACCEPTED notifying the receiver that the directory has not yet received an request from the sender.
    


    spacebear21 commented at 1:42 am on May 7, 2024:
    0The receiver sends a GET request to the path of the subdirectory followed by <code>/receive</code>. This request is encapsulated in OHTTP. It awaits an OHTTP response from the directory containing the BHTTP request from the sender with status code 200 OK, or sends a new OHTTP request after receiving 202 ACCEPTED notifying the receiver that the directory has not yet received an request from the sender.
    
  58. in bip-0077.mediawiki:167 in 5ff5b7ae77 outdated
    162+
    163+====Receive Messaging====
    164+
    165+The receiver sends a GET request to the path of the subdirectory followed by `/receive`. This request is encapsulated in OHTTP. It awaits an OHTTP response from the directory containing the BHTTP request from the sender with status code 200 OK, or sends a new OHTTP request after receiving 202 ACCEPTED notifying the receiver that the directory has not yet received an request from the sender.
    166+
    167+Once an Original PSBT Payload is decrypted and checked according to the list, the receiver may respond with a Payjoin PSBT. The receiver encrypts the PSBT according to the HPKE protocol, generating an ephemeral keypair `e` from which it derives a shared secret `ee` with the sender's key `e` from the payload. It generates a nonce from sufficient randomness, and constructs a ciphertext containing the Payjoin PSBT and serialized receiver ephemeral key `e`'s pubkey as associated data using ChaCha20Poly1305. A payload is constructed by concatenating the ephemeral pubkey, the nonce, and the ciphertext. This payload is then sent to the directory in an OHTTP request encapsulating the binary payload as a POST message to the subdirectory followed by `/receive`.
    


    spacebear21 commented at 1:43 am on May 7, 2024:
    0Once an Original PSBT Payload is decrypted and checked according to the list, the receiver may respond with a Payjoin PSBT. The receiver encrypts the PSBT according to the HPKE protocol, generating an ephemeral keypair `e` from which it derives a shared secret `ee` with the sender's key `e` from the payload. It generates a nonce from sufficient randomness, and constructs a ciphertext containing the Payjoin PSBT and serialized receiver ephemeral key `e`'s pubkey as associated data using ChaCha20Poly1305. A payload is constructed by concatenating the ephemeral pubkey, the nonce, and the ciphertext. This payload is then sent to the directory in an OHTTP request encapsulating the binary payload as a POST message to the subdirectory followed by <code>/receive</code>.
    
  59. in bip-0077.mediawiki:53 in 5ff5b7ae77 outdated
    48+
    49+===Basic scheme===
    50+
    51+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.
    52+
    53+Rather than hosting a public server, they start a session to receive messages and allocate a subdirectory from which to relay messages. The first message must include their pubkey to be enrolled as a subdirectory identifier. The next message from the directory to sender includes the enrolled subdirectory payjoin endpoint with the pubkey as identifying subdirectory. After enrollment, they await 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 <code>ohttp=</code> parameter including the payjoin directory's [[https://www.ietf.org/rfc/rfc9458.html#name-key-configuration OHTTP Key Configuration]].
    


    spacebear21 commented at 1:47 am on May 7, 2024:

    The next message from the directory to sender includes the enrolled subdirectory payjoin endpoint

    Should this say “from the directory to receiver”? IIUC the sender is not involved yet at this stage


    DanGould commented at 8:28 pm on May 7, 2024:
    yes
  60. in bip-0077.mediawiki:41 in 5ff5b7ae77 outdated
    36+
    37+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.
    38+
    39+===Relation to Stowaway===
    40+
    41+[[https://code.samourai.io/wallet/ExtLibJ/-/blob/develop/doc/cahoots/STOWAWAY.md Stowaway]] is a payjoin coordination mechanism which depends on Tor, a third-party relay, and the [[https://samouraiwallet.com/paynym PayNym]] [[https://github.com/bitcoin/bips/blob/master/bip-0047.mediawiki BIP 47]] Payment codes directory for subdirectory identification and encryption. The payjoin version 2 protocol uses per-request public keys for relay subdirectory identification, authentication, and encryption instead of BIP 47 public keys derived from a wallet. Payjoin version 2 also supports asynchronous messaging, in contrast to Stowaway's synchronous messaging. Offline Stowaway depends on manual message passing rather than an asynchronous network protocol. Successful Stowaway execution results in 2-output transactions, while BIP 78, and this work may produce batched transactions with many outputs.
    


    spacebear21 commented at 1:53 am on May 7, 2024:
    The samourai links are dead :/
  61. Wrap <code> blocks ce66047ded
  62. Fix basic scheme actors 07db553668
  63. Fix dead samourai links b693fb9a2e
  64. Orient motivation around a problem f9b4b911ed
  65. fix links bc3123e1da
  66. in bip-0077.mediawiki:27 in bc3123e1da outdated
    22+
    23+Payjoin is the simplest case of interactive bitcoin batching, allowing two participants to combine their transaction intents. It solves the sole privacy problem left open in the bitcoin paper, that transactions with multiple inputs "necessarily reveal that their inputs were owned by the same owner," by enabling two owners to provide input in a transaction.
    24+
    25+The payjoin protocols automate cooperative transaction construction to break that common-input assumption. The increased the opportunity to batch payments and and execute transaction cut-through increases intent throughput, since multiple intents combined take up fewer bytes than independent transactions.
    26+
    27+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.linuxfuihjknhoundation.org/pipermail/bitcoin-dev/2021-January/018358.html| regard]] these as limits to payjoin adoption.
    


    thebrandonlucas commented at 0:55 am on May 13, 2024:
    0Version 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.
    
  67. in bip-0077.mediawiki:25 in bc3123e1da outdated
    20+
    21+==Motivation==
    22+
    23+Payjoin is the simplest case of interactive bitcoin batching, allowing two participants to combine their transaction intents. It solves the sole privacy problem left open in the bitcoin paper, that transactions with multiple inputs "necessarily reveal that their inputs were owned by the same owner," by enabling two owners to provide input in a transaction.
    24+
    25+The payjoin protocols automate cooperative transaction construction to break that common-input assumption. The increased the opportunity to batch payments and and execute transaction cut-through increases intent throughput, since multiple intents combined take up fewer bytes than independent transactions.
    


    thebrandonlucas commented at 0:55 am on May 13, 2024:
    0The 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.
    
  68. in bip-0077.mediawiki:110 in bc3123e1da outdated
    105+Payjoin v2 messages use [[https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki| BIP 370 PSBT v2]] format to facilitate PSBT mutation.
    106+
    107+The payjoin version 2 protocol takes the following steps:
    108+
    109+* The recipient sends their payjoin pubkey and optional authentication credential according to the [[#enroll-messaging|enroll messaging]] protocol to receive a subdirectory allocation. It may go offline and replay enrollment to come back online.
    110+* Out of band, the receiver of the payment, shares a bitcoin URI with the sender including a <code>pj=</code> query parameter including the subdirectory as a base64URL encoded pubkey. To support version 1 senders the directory acts as an unsecured payjoin server so <code>pjos=0</code> must be specified in the URI. Version 2 senders may safely allow output substitution regardless. An <code>ohttp=</code> parameter containing the directory's base64URL Key Config should also be provided.
    


    thebrandonlucas commented at 0:56 am on May 13, 2024:
    0* Out of band, the receiver of the payment shares a bitcoin URI with the sender, including a <code>pj=</code> query parameter with the subdirectory as a base64URL encoded pubkey. To support version 1 senders the directory acts as an unsecured payjoin server so <code>pjos=0</code> must be specified in the URI. Version 2 senders may safely allow output substitution regardless. An <code>ohttp=</code> parameter containing the directory's base64URL Key Config should also be provided.
    

    DanGould commented at 3:24 pm on May 21, 2024:
    I rewrote the sentence and believe I fixed the core issue
  69. thebrandonlucas changes_requested
  70. Keyconfig s/should/must/ be provided 35ebad8ea2
  71. Fix typos
    Co-authored-by: thebrandonlucas <38222767+thebrandonlucas@users.noreply.github.com>
    224208c270
  72. s/pubkey/public key d7ffad81e6
  73. in bip-0077.mediawiki:15 in d7ffad81e6 outdated
    10+  License: BSD-2-Clause
    11+</pre>
    12+
    13+==Abstract==
    14+
    15+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.
    


    jonatack commented at 9:27 pm on May 22, 2024:

    (“which” is followed by a comma; “that” is not)

    0This 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.
    

    DanGould commented at 4:51 am on May 23, 2024:
    TIL about restrictive vs non-restrictive clauses
  74. in bip-0077.mediawiki:27 in d7ffad81e6 outdated
    22+
    23+Payjoin is the simplest case of interactive bitcoin batching, allowing two participants to combine their transaction intents. It solves the sole privacy problem left open in the bitcoin paper, that transactions with multiple inputs "necessarily reveal that their inputs were owned by the same owner," by enabling two owners to provide input in a transaction.
    24+
    25+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.
    26+
    27+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.
    


    jonatack commented at 9:33 pm on May 22, 2024:
    0Payjoin 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.
    
  75. in bip-0077.mediawiki:29 in d7ffad81e6 outdated
    24+
    25+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.
    26+
    27+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.
    28+
    29+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.
    


    jonatack commented at 9:49 pm on May 22, 2024:
    0The 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.
    
  76. in bip-0077.mediawiki:33 in d7ffad81e6 outdated
    28+
    29+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.
    30+
    31+===Relation to BIP 78 (Payjoin version 1)===
    32+
    33+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.
    


    jonatack commented at 10:41 pm on May 22, 2024:
    0The 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.

  77. in bip-0077.mediawiki:39 in d7ffad81e6 outdated
    34+
    35+The BIP 78 standard allows for an [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#unsecured-payjoin-server| unsecured payjoin server|]] to operate separately from the so-called "payment server" responsible for generating [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP 21]] request URIs. Because BIP 78 messages relayed over an unsecured server are neither end-to-end authenticated nor encrypted between sender and receiver, a malicious unsecured payjoin server is able to modify the Payjoin PSBT in flight, thus requiring payment output substitution to be disabled. Output substitution is useful for a number of block space optimizations, including payment batching and transaction cut-through. This proposal introduces authentication and encryption to secure output substitution while using a directory relay without compromising sender or receiver privacy.
    36+
    37+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.
    38+
    39+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.
    


    jonatack commented at 10:47 pm on May 22, 2024:
    0The 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.
    
  78. in bip-0077.mediawiki:43 in d7ffad81e6 outdated
    38+
    39+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.
    40+
    41+===Relation to Stowaway===
    42+
    43+[[https://docs.samourai.io/en/spend-tools#stowaway| Stowaway]] was a payjoin coordination mechanism which depends on Tor, a third-party relay, and the [[https://paynym.is| PayNym]] [[https://github.com/bitcoin/bips/blob/master/bip-0047.mediawiki| BIP 47]] Payment codes directory for subdirectory identification and encryption. The payjoin version 2 protocol uses per-request public keys for relay subdirectory identification, authentication, and encryption instead of BIP 47 public keys derived from a wallet. Payjoin version 2 also supports asynchronous messaging, in contrast to Stowaway's synchronous messaging. Offline Stowaway depends on manual message passing rather than an asynchronous network protocol. Successful Stowaway execution results in 2-output transactions, while BIP 78, and this work may produce batched transactions with many outputs.
    


    jonatack commented at 11:08 pm on May 22, 2024:
    0[[https://docs.samourai.io/en/spend-tools#stowaway| Stowaway]] was a payjoin coordination mechanism that depended on Tor, a third-party relay, and the [[https://paynym.is| PayNym]] [[https://github.com/bitcoin/bips/blob/master/bip-0047.mediawiki| BIP 47]] "payment codes" directory for subdirectory identification and encryption. The payjoin version 2 protocol uses per-request public keys for relay subdirectory identification, authentication, and encryption instead of BIP 47 public keys derived from a wallet. Payjoin version 2 also supports asynchronous messaging, in contrast to Stowaway's synchronous messaging. Offline Stowaway depends on manual message passing rather than an asynchronous network protocol. Successful Stowaway execution results in 2-output transactions, while BIP 78 and this work may produce batched transactions with many outputs.
    
  79. in bip-0077.mediawiki:55 in d7ffad81e6 outdated
    50+
    51+===Basic scheme===
    52+
    53+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.
    54+
    55+Rather than hosting a public server, they start a session to receive messages and allocate a subdirectory from which to relay messages. The first message must include their public key to be enrolled as a subdirectory identifier. The response message from the directory to receiver includes the newly enrolled subdirectory payjoin endpoint with the public key as identifying subdirectory. After enrollment, they await 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 <code>ohttp=</code> parameter including the payjoin directory's [[https://www.ietf.org/rfc/rfc9458.html#name-key-configuration| OHTTP Key Configuration]].
    


    jonatack commented at 11:17 pm on May 22, 2024:

    Suggest prefixing the first mention of ohttp in this document with Oblivious HTTP. Some other suggestions:

    0Rather 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]].
    
  80. in bip-0077.mediawiki:57 in d7ffad81e6 outdated
    52+
    53+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.
    54+
    55+Rather than hosting a public server, they start a session to receive messages and allocate a subdirectory from which to relay messages. The first message must include their public key to be enrolled as a subdirectory identifier. The response message from the directory to receiver includes the newly enrolled subdirectory payjoin endpoint with the public key as identifying subdirectory. After enrollment, they await 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 <code>ohttp=</code> parameter including the payjoin directory's [[https://www.ietf.org/rfc/rfc9458.html#name-key-configuration| OHTTP Key Configuration]].
    56+
    57+The sender constructs an encrypted and authenticated payload containing a PSBT and optional parameters similar to BIP 78. The resulting ciphertext ensures message secrecy and integrity when passed to the recipient by the subdirectory <code>pj=</code> endpoint.
    


    jonatack commented at 11:18 pm on May 22, 2024:

    Consistent naming

    0The sender constructs an encrypted and authenticated payload containing a PSBT and optional parameters similar to BIP 78. The resulting ciphertext ensures message secrecy and integrity when passed to the receiver by the subdirectory <code>pj=</code> endpoint.
    
  81. in bip-0077.mediawiki:105 in d7ffad81e6 outdated
    100+|- - -> Polled transmission
    101+</pre>
    102+
    103+===Payjoin version 2 messaging===
    104+
    105+Payjoin v2 messages use [[https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki| BIP 370 PSBT v2]] format to facilitate PSBT mutation.
    


    jonatack commented at 11:22 pm on May 22, 2024:
    “PSBT mutation” -> it may be helpful to link here to the PSBT Version 2 section below.
  82. in bip-0077.mediawiki:109 in d7ffad81e6 outdated
    104+
    105+Payjoin v2 messages use [[https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki| BIP 370 PSBT v2]] format to facilitate PSBT mutation.
    106+
    107+The payjoin version 2 protocol takes the following steps:
    108+
    109+* The recipient sends their payjoin public key and optional authentication credential according to the [[#enroll-messaging|enroll messaging]] protocol to receive a subdirectory allocation. It may go offline and replay enrollment to come back online.
    


    jonatack commented at 11:23 pm on May 22, 2024:

    “It may go offline” -> can you clarify what “It” is (the receiver)?

    0* The receiver sends their payjoin public key and optional authentication credential according to the [[#enroll-messaging|enroll messaging]] protocol to receive a subdirectory allocation. It may go offline and replay enrollment to come back online.
    
  83. in bip-0077.mediawiki:110 in d7ffad81e6 outdated
    105+Payjoin v2 messages use [[https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki| BIP 370 PSBT v2]] format to facilitate PSBT mutation.
    106+
    107+The payjoin version 2 protocol takes the following steps:
    108+
    109+* The recipient sends their payjoin public key and optional authentication credential according to the [[#enroll-messaging|enroll messaging]] protocol to receive a subdirectory allocation. It may go offline and replay enrollment to come back online.
    110+* Out of band, the receiver of the payment shares a bitcoin URI with the sender including a <code>pj=</code> query parameter where the subdirectory is a base64URL encoded public key. To support version 1 senders the directory acts as an unsecured payjoin server so <code>pjos=0</code> must be specified in the URI. Version 2 senders may safely allow output substitution regardless. An <code>ohttp=</code> parameter containing the directory's base64URL Key Config must also be provided.
    


    jonatack commented at 11:32 pm on May 22, 2024:

    Suggest adding the explanatory link for base64url encoding here, as it is the first time it is used, in addition to line 235 below: The key is encoded in [[https://datatracker.ietf.org/doc/html/rfc4648#section-5| base64URL]] encoding

    Also (nit) suggest writing each instance of it as base64url, as done in RFC4648.

    A few further suggestions here:

    0* Out of band, the receiver shares a bitcoin URI with the sender, including a <code>pj=</code> query parameter where the subdirectory is a base64url encoded public key. To support version 1 senders, the directory acts as an unsecured payjoin server, so <code>pjos=0</code> must be specified in the URI. Version 2 senders may safely allow output substitution regardless. An <code>ohttp=</code> parameter containing the directory's base64url "Key Config" must also be provided.
    
  84. in bip-0077.mediawiki:114 in d7ffad81e6 outdated
    109+* The recipient sends their payjoin public key and optional authentication credential according to the [[#enroll-messaging|enroll messaging]] protocol to receive a subdirectory allocation. It may go offline and replay enrollment to come back online.
    110+* Out of band, the receiver of the payment shares a bitcoin URI with the sender including a <code>pj=</code> query parameter where the subdirectory is a base64URL encoded public key. To support version 1 senders the directory acts as an unsecured payjoin server so <code>pjos=0</code> must be specified in the URI. Version 2 senders may safely allow output substitution regardless. An <code>ohttp=</code> parameter containing the directory's base64URL Key Config must also be provided.
    111+* The sender creates a valid version 2 PSBT satisfying the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the receiver checklist]]. We call this the <code>Original PSBT</code>. This <code>Original PSBT</code>, optional sender parameters, and HPKE keys are encrypted and authenticated, and encapsulated in OHTTP. This [[#send-messaging|Original PSBT Request send message]] is sent to the directory's OHTTP Gateway.
    112+* The sender continues to replay this request in order to await a response from the directory containing a <code>Payjoin PSBT</code>. It stops after expiry.
    113+* The request is stored in the subdirectory.
    114+* Once the receiver is online, it sends <code>/receive</code> requests to await updates from the subdirectory. The receiver decrypts and authenticates the response which it checks according to [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the receiver checklist]]. It updates the Original PSBT to include new signed inputs and outputs, invalidating sender signatures, and may adjust the fee. The result is called the <code>Payjoin PSBT</code>.
    


    jonatack commented at 11:47 pm on May 22, 2024:
    • Maybe link /receive to the Receive Messaging section below.

    • “which” needs to be followed by a comma

    0* Once the receiver is online, it sends <code>/receive</code> requests to await updates from the subdirectory. The receiver decrypts and authenticates the response, which it checks according to [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the receiver checklist]]. It updates the Original PSBT to include new signed inputs and outputs, invalidating sender signatures, and may adjust the fee. The result is called the <code>Payjoin PSBT</code>.
    
  85. in bip-0077.mediawiki:116 in d7ffad81e6 outdated
    111+* The sender creates a valid version 2 PSBT satisfying the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the receiver checklist]]. We call this the <code>Original PSBT</code>. This <code>Original PSBT</code>, optional sender parameters, and HPKE keys are encrypted and authenticated, and encapsulated in OHTTP. This [[#send-messaging|Original PSBT Request send message]] is sent to the directory's OHTTP Gateway.
    112+* The sender continues to replay this request in order to await a response from the directory containing a <code>Payjoin PSBT</code>. It stops after expiry.
    113+* The request is stored in the subdirectory.
    114+* Once the receiver is online, it sends <code>/receive</code> requests to await updates from the subdirectory. The receiver decrypts and authenticates the response which it checks according to [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the receiver checklist]]. It updates the Original PSBT to include new signed inputs and outputs, invalidating sender signatures, and may adjust the fee. The result is called the <code>Payjoin PSBT</code>.
    115+* The <code>Payjoin PSBT</code> and HPKE keys are encrypted, authenticated, encapsulated in OHTTP, and sent to the directory's OHTTP Gateway.
    116+* The directory awaits a request from the sender if it goes offline. Upon request, it relays the encrypted <code>Payjoin PSBT</code>.
    


    jonatack commented at 11:50 pm on May 22, 2024:
    Do both words “it” here mean the same thing (what)?
  86. in bip-0077.mediawiki:124 in d7ffad81e6 outdated
    119+The Original PSBT MUST:
    120+
    121+* Include complete UTXO data.
    122+* Be signed.
    123+* Exclude unnecessary fields such as global xpubs or keypath information. <!-* I believe PSBTv2 obviates this requirement -->
    124+* Set input and output Transaction Modifiable Flags to 1
    


    jonatack commented at 11:51 pm on May 22, 2024:

    Here and line 130, to be like the other entries.

    0* Set input and output Transaction Modifiable Flags to 1.
    
  87. in bip-0077.mediawiki:123 in d7ffad81e6 outdated
    118+
    119+The Original PSBT MUST:
    120+
    121+* Include complete UTXO data.
    122+* Be signed.
    123+* Exclude unnecessary fields such as global xpubs or keypath information. <!-* I believe PSBTv2 obviates this requirement -->
    


    jonatack commented at 11:51 pm on May 22, 2024:
    Should this line be removed, per your comment?

    DanGould commented at 6:23 pm on June 2, 2024:
    Because PSBTv2 support is not yet merged in even bitcoin core, I plan to revert this BIP to using PSBTv0 in order to be compatible with wallets of today, as is done in the reference implementation, so I’ll leave the comment until either the reference implementation uses PSBTv2 or the entire doc is reverted to PSBTv0
  88. in bip-0077.mediawiki:149 in d7ffad81e6 outdated
    144+* Shuffle the order of inputs or outputs; the additional outputs or additional inputs must be inserted at a random index.
    145+* Decrease the absolute fee of the original PSBT.
    146+
    147+====Enroll Messaging====
    148+
    149+Receivers must enroll with a directory to have a subdirectory allocated to them as follows.
    


    jonatack commented at 11:53 pm on May 22, 2024:
    0Receivers must enroll with a directory to have a subdirectory allocated to them, as follows:
    
  89. in bip-0077.mediawiki:155 in d7ffad81e6 outdated
    150+
    151+A receiver must first discover the directory's OHTTP gateway key configuration via an authenticated bootstrap mechanism before it can enroll to receive payjoin requests. This mechanism may vary by implementation but must follow [[https://datatracker.ietf.org/doc/html/draft-ietf-privacypass-key-consistency-01| OHTTP Consistency Requirements]] and should not reveal a receiver IP address to the directory. Some examples of suitable mechanisms include fetching over a VPN, using keys included with an application binary, https-in-http CONNECT method, https-in-WebSocket, or a Tor hidden service.
    152+
    153+Payjoin sessions begin by having a receiver send the static public key to the directory via OHTTP, receiving their subdirectory in a base64URL encoded directory url as response. Enrollment may be replayed in case the receiver goes offline and should result in the same response.
    154+
    155+Optionally, before returning the uri the receiver may request an authentication token by presenting a message containing only the word <code>Authenticate: <description></code> after which the receiver is required to submit an <code>Authenticate: <token></code> including the token from the directory out of band. If authentication fails an error is returned.
    


    jonatack commented at 11:57 pm on May 22, 2024:
    0Optionally, before returning the uri, the receiver may request an authentication token by presenting a message containing only the word <code>Authenticate: <description></code>, after which the receiver is required to submit an <code>Authenticate: <token></code> including the token from the directory out of band. If authentication fails, an error is returned.
    
  90. in bip-0077.mediawiki:157 in d7ffad81e6 outdated
    152+
    153+Payjoin sessions begin by having a receiver send the static public key to the directory via OHTTP, receiving their subdirectory in a base64URL encoded directory url as response. Enrollment may be replayed in case the receiver goes offline and should result in the same response.
    154+
    155+Optionally, before returning the uri the receiver may request an authentication token by presenting a message containing only the word <code>Authenticate: <description></code> after which the receiver is required to submit an <code>Authenticate: <token></code> including the token from the directory out of band. If authentication fails an error is returned.
    156+
    157+In the case a directory is operated by an exchange, it may give out authentication tokens for users of its app, or may require some proof of work out of band. Tokens should be anonymous credentials from the directory describing the parameters of their authorization. Specific credentialing is out of the scope of this proposal.
    


    jonatack commented at 11:58 pm on May 22, 2024:
    0If a directory is operated by an exchange, it may give out authentication tokens for users of its app, or may require some proof of work out of band. Tokens should be anonymous credentials from the directory describing the parameters of their authorization. Specific credentialing is out of the scope of this proposal.
    
  91. in bip-0077.mediawiki:161 in d7ffad81e6 outdated
    156+
    157+In the case a directory is operated by an exchange, it may give out authentication tokens for users of its app, or may require some proof of work out of band. Tokens should be anonymous credentials from the directory describing the parameters of their authorization. Specific credentialing is out of the scope of this proposal.
    158+
    159+====Send Messaging====
    160+
    161+The version 2 Original PSBT is placed in an HTTP POST request body as binary before being encoded into BHTTP and encrypted according to the HPKE protocol. This Original PSBT BHTTP Request is then encrypted according to the HPKE, generating an ephemeral keypair <code>e</code> from which it derives a shared secret <code>es</code> with the receiver's key <code>s</code>. It generates a nonce from sufficient randomness, and constructs a ciphertext containing the Original PSBT BHTTP Request and serialized ephemeral key <code>e</code>'s public key as associated data using ChaCha20Poly1305. A payload is constructed by concatenating the ephemeral public key, the nonce, and the ciphertext. This payload is then sent to the directory in an OHTTP request encapsulating the binary payload.
    


    jonatack commented at 0:00 am on May 23, 2024:
    “it” and “It” in this paragraph would be clearer if replaced by the actual subject.
  92. in bip-0077.mediawiki:163 in d7ffad81e6 outdated
    158+
    159+====Send Messaging====
    160+
    161+The version 2 Original PSBT is placed in an HTTP POST request body as binary before being encoded into BHTTP and encrypted according to the HPKE protocol. This Original PSBT BHTTP Request is then encrypted according to the HPKE, generating an ephemeral keypair <code>e</code> from which it derives a shared secret <code>es</code> with the receiver's key <code>s</code>. It generates a nonce from sufficient randomness, and constructs a ciphertext containing the Original PSBT BHTTP Request and serialized ephemeral key <code>e</code>'s public key as associated data using ChaCha20Poly1305. A payload is constructed by concatenating the ephemeral public key, the nonce, and the ciphertext. This payload is then sent to the directory in an OHTTP request encapsulating the binary payload.
    162+
    163+The directory's OHTTP Gateway decapsulates the OHTTP request, decrypts the payload, and forwards the BHTTP POST request to the receiver's internal subdirectory endpoint which stores the HPKE encrypted payload to be forwarded to the receiver. The directory's OHTTP Gateway then awaits a response from the receiver's subdirectory endpoint, encapsulates it, and responds according to OHTTP.
    


    jonatack commented at 0:01 am on May 23, 2024:
    0The directory's OHTTP Gateway decapsulates the OHTTP request, decrypts the payload, and forwards the BHTTP POST request to the receiver's internal subdirectory endpoint, which stores the HPKE encrypted payload to be forwarded to the receiver. The directory's OHTTP Gateway then awaits a response from the receiver's subdirectory endpoint, encapsulates it, and responds according to OHTTP.
    
  93. in bip-0077.mediawiki:167 in d7ffad81e6 outdated
    162+
    163+The directory's OHTTP Gateway decapsulates the OHTTP request, decrypts the payload, and forwards the BHTTP POST request to the receiver's internal subdirectory endpoint which stores the HPKE encrypted payload to be forwarded to the receiver. The directory's OHTTP Gateway then awaits a response from the receiver's subdirectory endpoint, encapsulates it, and responds according to OHTTP.
    164+
    165+====Receive Messaging====
    166+
    167+The receiver sends a GET request to the path of the subdirectory followed by <code>/receive</code>. This request is encapsulated in OHTTP. It awaits an OHTTP response from the directory containing the BHTTP request from the sender with status code 200 OK, or sends a new OHTTP request after receiving 202 ACCEPTED notifying the receiver that the directory has not yet received an request from the sender.
    


    jonatack commented at 0:02 am on May 23, 2024:
    0The receiver sends a GET request to the path of the subdirectory followed by <code>/receive</code>. This request is encapsulated in OHTTP. It awaits an OHTTP response from the directory containing the BHTTP request from the sender with status code 200 OK, or sends a new OHTTP request after receiving 202 ACCEPTED notifying the receiver that the directory has not yet received a request from the sender.
    
  94. in bip-0077.mediawiki:169 in d7ffad81e6 outdated
    164+
    165+====Receive Messaging====
    166+
    167+The receiver sends a GET request to the path of the subdirectory followed by <code>/receive</code>. This request is encapsulated in OHTTP. It awaits an OHTTP response from the directory containing the BHTTP request from the sender with status code 200 OK, or sends a new OHTTP request after receiving 202 ACCEPTED notifying the receiver that the directory has not yet received an request from the sender.
    168+
    169+Once an Original PSBT Payload is decrypted and checked according to the list, the receiver may respond with a Payjoin PSBT. The receiver encrypts the PSBT according to the HPKE protocol, generating an ephemeral keypair <code>e</code> from which it derives a shared secret <code>ee</code> with the sender's key <code>e</code> from the payload. It generates a nonce from sufficient randomness, and constructs a ciphertext containing the Payjoin PSBT and serialized receiver ephemeral key <code>e</code>'s public key as associated data using ChaCha20Poly1305. A payload is constructed by concatenating the ephemeral public key, the nonce, and the ciphertext. This payload is then sent to the directory in an OHTTP request encapsulating the binary payload as a POST message to the subdirectory followed by <code>/receive</code>.
    


    jonatack commented at 0:03 am on May 23, 2024:
    “it” and “It” in this paragraph would be clearer if replaced by the actual subject.
  95. in bip-0077.mediawiki:173 in d7ffad81e6 outdated
    168+
    169+Once an Original PSBT Payload is decrypted and checked according to the list, the receiver may respond with a Payjoin PSBT. The receiver encrypts the PSBT according to the HPKE protocol, generating an ephemeral keypair <code>e</code> from which it derives a shared secret <code>ee</code> with the sender's key <code>e</code> from the payload. It generates a nonce from sufficient randomness, and constructs a ciphertext containing the Payjoin PSBT and serialized receiver ephemeral key <code>e</code>'s public key as associated data using ChaCha20Poly1305. A payload is constructed by concatenating the ephemeral public key, the nonce, and the ciphertext. This payload is then sent to the directory in an OHTTP request encapsulating the binary payload as a POST message to the subdirectory followed by <code>/receive</code>.
    170+
    171+===Receiver's Payjoin PSBT checklist===
    172+
    173+Other than requiring PSBTv2 the receiver checklist is the same as the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the BIP 78 receiver checklist]]
    


    jonatack commented at 0:03 am on May 23, 2024:
    0Other than requiring PSBTv2, the receiver checklist is the same as the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the BIP 78 receiver checklist]]
    
  96. in bip-0077.mediawiki:177 in d7ffad81e6 outdated
    172+
    173+Other than requiring PSBTv2 the receiver checklist is the same as the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the BIP 78 receiver checklist]]
    174+
    175+===Sender's Payjoin PSBT checklist===
    176+
    177+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 headaches since it required the sender to add them back to the Payjoin proposal PSBT. Version 2 has no such requirement.
    


    jonatack commented at 0:05 am on May 23, 2024:
    0The 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 caused issues, as it required the sender to add them back to the Payjoin proposal PSBT. Version 2 has no such requirement.
    
  97. in bip-0077.mediawiki:181 in d7ffad81e6 outdated
    176+
    177+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 headaches since it required the sender to add them back to the Payjoin proposal PSBT. Version 2 has no such requirement.
    178+
    179+===Directory interactions===
    180+
    181+The payjoin directory provides a rendezvous point for sender and receiver to meet. It stores Payjoin payloads to support asynchronous communication. It must only accept OHTTP requests with an OHTTP Gateway for Payjoin version 2, accepting encrypted payloads. It may optionally accept HTTP/1.1 POST requests without HTTP to enrolled subdirectories to support backwards compatible Payjoin version 1 requests.
    


    jonatack commented at 0:08 am on May 23, 2024:
    Perhaps replace the 3 “it” words in this paragraph with the actual subject.
  98. in bip-0077.mediawiki:185 in d7ffad81e6 outdated
    180+
    181+The payjoin directory provides a rendezvous point for sender and receiver to meet. It stores Payjoin payloads to support asynchronous communication. It must only accept OHTTP requests with an OHTTP Gateway for Payjoin version 2, accepting encrypted payloads. It may optionally accept HTTP/1.1 POST requests without HTTP to enrolled subdirectories to support backwards compatible Payjoin version 1 requests.
    182+
    183+===Subdirectories===
    184+
    185+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.
    


    jonatack commented at 0:08 am on May 23, 2024:
    0Each 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.
    
  99. in bip-0077.mediawiki:198 in d7ffad81e6 outdated
    193+* <code>ohttp</code> represents the OHTTP Key Configuration of the directory. This is a base64URL encoded public key of the directory's OHTTP Gateway. This parameter is required for version 2 payjoin URIs.
    194+* <code>exp</code>: represents a request expiration after which the receiver reserves the right to broadcast the transaction extracted from the Original PSBT and ignore requests. This is only necessary for receivers who only support synchonous execution of the protocol, like automated payment processors.
    195+
    196+===Optional sender parameters===
    197+
    198+When the payjoin sender posts the original PSBT to the receiver, it can optionally specify the following HTTP query string parameters:
    


    jonatack commented at 0:09 am on May 23, 2024:
    0When the payjoin sender posts the original PSBT to the receiver, the sender can optionally specify the following HTTP query string parameters:
    
  100. in bip-0077.mediawiki:210 in d7ffad81e6 outdated
    205+
    206+===Request expiration & Original PSBT===
    207+
    208+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.
    209+
    210+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 -->
    


    jonatack commented at 0:12 am on May 23, 2024:
    0The 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 -->
    
  101. in bip-0077.mediawiki:214 in d7ffad81e6 outdated
    209+
    210+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 -->
    211+
    212+===HTTP===
    213+
    214+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.
    


    jonatack commented at 0:13 am on May 23, 2024:

    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.

    0HTTP 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.
    
  102. in bip-0077.mediawiki:218 in d7ffad81e6 outdated
    213+
    214+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.
    215+
    216+===Oblivious HTTP===
    217+
    218+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.
    


    jonatack commented at 0:17 am on May 23, 2024:

    Either “with specific IP addresses”, or “with a specific IP address”

    0OHTTP 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.
    
  103. jonatack commented at 0:23 am on May 23, 2024: member
    Midway through a first (non-technical) review pass. Once at the end, will read through BIP78 and then do a more technical review.
  104. Incorporate jonatack's suggestions 3b863a402e
  105. DanGould commented at 6:38 pm on June 2, 2024: contributor

    @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
  106. in bip-0077.mediawiki:161 in 3b863a402e outdated
    156+
    157+If a directory is operated by an exchange, it may give out authentication tokens for users of its app, or may require some proof of work out of band. Tokens should be anonymous credentials from the directory describing the parameters of their authorization. Specific credentialing is out of the scope of this proposal.
    158+
    159+====Send Messaging====
    160+
    161+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.
    


    jonatack commented at 9:53 pm on June 18, 2024:
    0The 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,

  107. in bip-0077.mediawiki:168 in 3b863a402e outdated
    163+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.
    164+
    165+====Receive Messaging====
    166+
    167+The receiver sends a GET request to the path of the subdirectory followed by <code>/receive</code>. This request is encapsulated in OHTTP. 
    168+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.
    


    jonatack commented at 9:57 pm on June 18, 2024:
    0The 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.
    
  108. in bip-0077.mediawiki:163 in 3b863a402e outdated
    158+
    159+====Send Messaging====
    160+
    161+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.
    162+
    163+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.
    


    jonatack commented at 10:00 pm on June 18, 2024:
    0The 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.)

  109. in bip-0077.mediawiki:178 in 3b863a402e outdated
    173+
    174+Other than requiring PSBTv2, the receiver checklist is the same as the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the BIP 78 receiver checklist]]
    175+
    176+===Sender's Payjoin PSBT checklist===
    177+
    178+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.
    


    jonatack commented at 10:08 pm on June 18, 2024:
    0The 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.
    
  110. jonatack commented at 10:15 pm on June 18, 2024: member

    Review pass of the latest changes in 3b863a402e0250658985f08a455a6cd103e269e5.

    Note to self: continue original review pass from line 180 to the end.

  111. in bip-0077.mediawiki:201 in 3b863a402e outdated
    196+
    197+===Optional sender parameters===
    198+
    199+When the payjoin sender posts the original PSBT to the receiver, the sender should specify the following HTTP query string parameters:
    200+
    201+* <code>v</code>: represents the version number of the payjoin protocol that the sender is using. This version is <code>2</code>.
    


    jonatack commented at 10:53 pm on June 18, 2024:
    Suggest writing all 3 params (2 receiver, 1 sender) either followed by a colon, or by no colon.
  112. in bip-0077.mediawiki:209 in 3b863a402e outdated
    204+
    205+==Rationale==
    206+
    207+===Request expiration & Original PSBT===
    208+
    209+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.
    


    jonatack commented at 11:00 pm on June 18, 2024:
    Suggestion: link here to where BIP 78 recommends this.

    satsie commented at 7:38 pm on July 4, 2024:
    Are the “request PSBTs” the same as Original PSBTs? If so, I prefer the “Orignial PSBT” terminology since it is the same term that is used in the sequence diagram.
  113. in bip-0077.mediawiki:211 in 3b863a402e outdated
    206+
    207+===Request expiration & Original PSBT===
    208+
    209+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.
    210+
    211+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 -->
    


    jonatack commented at 11:01 pm on June 18, 2024:
    “I also like to for timeout” -> unclear
  114. in bip-0077.mediawiki:236 in 3b863a402e outdated
    231+
    232+===Secp256k1 Hybrid Public Key Encryption===
    233+
    234+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.
    235+
    236+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.
    


    jonatack commented at 11:05 pm on June 18, 2024:
    0The 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)

  115. in bip-0077.mediawiki:234 in 3b863a402e outdated
    229+
    230+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.
    231+
    232+===Secp256k1 Hybrid Public Key Encryption===
    233+
    234+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.
    


    jonatack commented at 11:09 pm on June 18, 2024:
    0Hybrid 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.
    
  116. in bip-0077.mediawiki:244 in 3b863a402e outdated
    239+
    240+[[https://www.ietf.org/archive/id/draft-wahby-cfrg-hpke-kem-secp256k1-01.html| Secp256k1-based DHKEM for HPKE]] is most appropriate because of secp256k1's availability in bitcoin contexts.
    241+
    242+====ChaCha20Poly1305 AEAD====
    243+
    244+This authenticated encryption with additional data [[https://en.wikipedia.org/wiki/ChaCha20-Poly1305| algorithm]] is standardized in [[https://www.rfc-editor.org/rfc/rfc8439| RFC 8439]] and has high performance. ChaCha20Poly1305 AEAD seems to be making its way into bitcoin by way of [[https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki| BIP 324]] as well. The protocol has widespread support in browsers, OpenSSL and libsodium. AES-GCM is more widespread but is both older, slower, and not necessarily already a dependency in bitcoin software.
    


    jonatack commented at 11:10 pm on June 18, 2024:
    0This authenticated encryption with additional data (AEAD) [[https://en.wikipedia.org/wiki/ChaCha20-Poly1305| algorithm]] is standardized in [[https://www.rfc-editor.org/rfc/rfc8439| RFC 8439]] and has high performance. ChaCha20Poly1305 AEAD has been implemented in Bitcoin Core [optionally could link here to https://github.com/bitcoin/bitcoin/pull/15649] as specified in [[https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki| BIP 324]] as well. The protocol has widespread support in browsers, OpenSSL and libsodium. AES-GCM is more widespread but is both older, slower, and not necessarily already a dependency in bitcoin software.
    
  117. in bip-0077.mediawiki:252 in 3b863a402e outdated
    247+
    248+SHA-256 is considered secure and is necessarily available in bitcoin contexts.
    249+
    250+===PSBT Version 2===
    251+
    252+The PSBT version 1 protocol was replaced because it was not designed to have inputs and outputs be mutated. Payjoin mutates the PSBT, so BIP 78 uses a hack where a new PSBT is created by the receiver instead of mutating it. This can cause some strange behaviors from signers who don't know where to look to find the scripts that they are accountable for. PSBT version 2 makes mutating a PSBT's inputs and outputs trivial. It also eliminates the transaction finalization step. Receivers who do not understand PSBT version 1 may choose to reject Payjoin version 1 requests and only support PSBT version 2.
    


    jonatack commented at 11:16 pm on June 18, 2024:
    0The PSBT version 1 protocol was replaced because it was not designed to have inputs and outputs be mutated. Payjoin mutates the PSBT, so BIP 78 uses a workaround where a new PSBT is created by the receiver instead of mutating it. This can cause strange behaviors from signers who don't know where to look to find the scripts that they are accountable for. PSBT version 2 makes mutating a PSBT's inputs and outputs trivial. It also eliminates the transaction finalization step. Receivers who do not understand PSBT version 1 may choose to reject Payjoin version 1 requests and only support PSBT version 2.
    
  118. in bip-0077.mediawiki:256 in 3b863a402e outdated
    251+
    252+The PSBT version 1 protocol was replaced because it was not designed to have inputs and outputs be mutated. Payjoin mutates the PSBT, so BIP 78 uses a hack where a new PSBT is created by the receiver instead of mutating it. This can cause some strange behaviors from signers who don't know where to look to find the scripts that they are accountable for. PSBT version 2 makes mutating a PSBT's inputs and outputs trivial. It also eliminates the transaction finalization step. Receivers who do not understand PSBT version 1 may choose to reject Payjoin version 1 requests and only support PSBT version 2.
    253+
    254+===Attack vectors===
    255+
    256+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.
    


    jonatack commented at 11:17 pm on June 18, 2024:

    Perhaps explain further how/why these attacks are possible.

    0Since directories store arbitrary encrypted payloads, they are vulnerable to the tragedy of the commons and denial of service attacks. To mitigate such attacks, directory operators may impose an authentication requirement before they allocate a subdirectory to receivers.
    
  119. in bip-0077.mediawiki:260 in 3b863a402e outdated
    255+
    256+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.
    257+
    258+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.
    259+
    260+Since the Original PSBT is valid, even where <code>exp=</code> is specified, the receiver may broadcast it and lose out on savings from payment batching and  privacy protection from payjoin structure at any time. Though unfortunate, this failure mode is the typical bitcoin transaction flow today anyhow.
    


    jonatack commented at 11:21 pm on June 18, 2024:

    I think this paragraph could be clearer/better written.

    0Since the Original PSBT is valid, even where <code>exp=</code> is specified, the receiver may broadcast it and lose out on savings from payment batching and privacy protection from payjoin structure at any time. Though unfortunate, this failure mode is the typical bitcoin transaction flow today anyhow.
    
  120. in bip-0077.mediawiki:264 in 3b863a402e outdated
    259+
    260+Since the Original PSBT is valid, even where <code>exp=</code> is specified, the receiver may broadcast it and lose out on savings from payment batching and  privacy protection from payjoin structure at any time. Though unfortunate, this failure mode is the typical bitcoin transaction flow today anyhow.
    261+
    262+===Network privacy===
    263+
    264+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.
    


    jonatack commented at 11:22 pm on June 18, 2024:
    0Oblivious 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 BIP 21 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.
    

    satsie commented at 8:05 pm on July 4, 2024:
    0Oblivious 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 :laughing:

  121. in bip-0077.mediawiki:266 in 3b863a402e outdated
    261+
    262+===Network privacy===
    263+
    264+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.
    265+
    266+Unlike BIP 78 implementations, sender and receiver peers will only see the IP address of the directory, not their peers. Directories may additionally be made available via Tor hidden service to allow either of the peers to protect their IP from the directory without OHTTP.
    


    jonatack commented at 11:23 pm on June 18, 2024:
    0Unlike BIP 78 implementations, sender and receiver peers will only see the IP address of the directory and not that of their peers. Directories may additionally be made available via Tor hidden services to allow either of the peers to protect their IP from the directory without OHTTP.
    
  122. in bip-0077.mediawiki:270 in 3b863a402e outdated
    265+
    266+Unlike BIP 78 implementations, sender and receiver peers will only see the IP address of the directory, not their peers. Directories may additionally be made available via Tor hidden service to allow either of the peers to protect their IP from the directory without OHTTP.
    267+
    268+==Backwards compatibility==
    269+
    270+The receivers advertise payjoin capabilities through [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP21's URI Scheme]].
    


    jonatack commented at 11:24 pm on June 18, 2024:
    0The receivers advertise payjoin capabilities through [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP 21's URI Scheme]].
    
  123. in bip-0077.mediawiki:272 in 3b863a402e outdated
    267+
    268+==Backwards compatibility==
    269+
    270+The receivers advertise payjoin capabilities through [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP21's URI Scheme]].
    271+
    272+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. 
    


    jonatack commented at 11:27 pm on June 18, 2024:
    0Senders 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.

  124. in bip-0077.mediawiki:274 in 3b863a402e outdated
    269+
    270+The receivers advertise payjoin capabilities through [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP21's URI Scheme]].
    271+
    272+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. 
    273+
    274+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.
    


    jonatack commented at 11:39 pm on June 18, 2024:
    0Receivers 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.
  125. in bip-0077.mediawiki:278 in 3b863a402e outdated
    273+
    274+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.
    275+
    276+==Reference implementation==
    277+
    278+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:
    


    jonatack commented at 11:41 pm on June 18, 2024:
    0A 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.


    DanGould commented at 4:30 pm on July 6, 2024:
    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.
  126. in bip-0077.mediawiki:286 in 3b863a402e outdated
    281+
    282+Independent Oblivious HTTP relays are run by Obscura VPN at https://ohttp-relay.obscuravpn.io/payjoin and by BOB Spaces at https://pj.bobspacebkk.com.
    283+
    284+==Acknowledgements==
    285+
    286+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.
    


    jonatack commented at 11:51 pm on June 18, 2024:
    0Thank 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.


    murchandamus commented at 1:05 pm on July 1, 2024:
    Just Murch is fine with me.

    satsie commented at 1:57 am on July 4, 2024:
    EDIT: after reading the rest of the paragraph, I like the consistency and am fine staying as “Satsie” :)
  127. jonatack commented at 11:55 pm on June 18, 2024: member

    continue original review pass from line 180 to the end

    Done (for the initial proofreading pass)

  128. 5twelve approved
  129. in bip-0077.mediawiki:27 in 3b863a402e outdated
    22+
    23+Payjoin is the simplest case of interactive bitcoin batching, allowing two participants to combine their transaction intents. It solves the sole privacy problem left open in the bitcoin paper, that transactions with multiple inputs "necessarily reveal that their inputs were owned by the same owner," by enabling two owners to provide input in a transaction.
    24+
    25+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.
    26+
    27+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.
    


    satsie commented at 3:07 pm on July 4, 2024:
    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”.
  130. in bip-0077.mediawiki:55 in 3b863a402e outdated
    50+
    51+===Basic scheme===
    52+
    53+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.
    54+
    55+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]].
    


    satsie commented at 5:45 pm on July 4, 2024:
    0Rather 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.


    satsie commented at 5:51 pm on July 4, 2024:
    0Rather 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.


    satsie commented at 6:05 pm on July 4, 2024:

    This part reads a little strange. Would either of these suggestions be an improvement?

    0Rather 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]].
    
    0Rather 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]].
    

    satsie commented at 7:59 pm on July 4, 2024:
    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.
  131. in bip-0077.mediawiki:78 in 3b863a402e outdated
    73+|                                  |                  |                |
    74+|      destination (address,       |                  |                |
    75+|        subdirectory)             |                  |                |
    76++---------------------------------------------------->|                |
    77+|                                  |                  |                |
    78+|      Request Original PSBT       |                  |                |
    


    satsie commented at 6:11 pm on July 4, 2024:
    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

    DanGould commented at 6:11 pm on July 6, 2024:

    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.


    satsie commented at 6:58 pm on July 6, 2024:

    Ok cool. No I don’t have any suggestions :laughing:. 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.

  132. in bip-0077.mediawiki:105 in 3b863a402e outdated
    100+|- - -> Polled transmission
    101+</pre>
    102+
    103+===Payjoin version 2 messaging===
    104+
    105+Payjoin V2 messages use [[https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki| BIP 370 PSBT V2]] format to facilitate [[#psbt-version-2|PSBT mutation]].
    


    satsie commented at 6:24 pm on July 4, 2024:
    nit : Another example of mixed “V2” / “version 2” usage. I personally lean towards V2, but it I think this doc favors “version 2”.

    DanGould commented at 6:13 pm on July 6, 2024:
    The document is titled PSBT Version 2 so I’ll put “BIP 370: PSBT Version 2 (PSBTv2)” to enable the latter usage elsewhere
  133. in bip-0077.mediawiki:219 in 3b863a402e outdated
    214+
    215+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.
    216+
    217+===Oblivious HTTP===
    218+
    219+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.
    


    satsie commented at 6:28 pm on July 4, 2024:
    0OHTTP protects sender and receiver IP addresses both from one another and from the directory. This makes it more difficult for a directory to correlate many payjoin transactions with specific IP addresses by intersection.
    

    nit: moving the word “from” allows the two phrases “from one another” and “from the directory” to match/be consistent with the usage of “from”

  134. in bip-0077.mediawiki:153 in 3b863a402e outdated
    148+
    149+Receivers must enroll with a directory to have a subdirectory allocated to them, as follows:
    150+
    151+A receiver must first discover the directory's OHTTP gateway key configuration via an authenticated bootstrap mechanism before it can enroll to receive payjoin requests. This mechanism may vary by implementation but must follow [[https://datatracker.ietf.org/doc/html/draft-ietf-privacypass-key-consistency-01| OHTTP Consistency Requirements]] and should not reveal a receiver IP address to the directory. Some examples of suitable mechanisms include fetching over a VPN, using keys included with an application binary, https-in-http CONNECT method, https-in-WebSocket, or a Tor hidden service.
    152+
    153+Payjoin sessions begin by having a receiver send the static public key to the directory via OHTTP, receiving their subdirectory in a base64url encoded directory url as response. Enrollment may be replayed in case the receiver goes offline and should result in the same response.
    


    satsie commented at 6:43 pm on July 4, 2024:
    Re: the last sentence, so enrollment is idempotent, right? Not sure if adding that that term would be helpful or confusing to readers :smile:

    satsie commented at 6:45 pm on July 4, 2024:
    0Payjoin sessions begin by having a receiver send the static public key to the directory via OHTTP, receiving their subdirectory in a base64url encoded directory URL as response. Enrollment may be replayed in case the receiver goes offline and should result in the same response.
    

    nit: Do you want “url” to be lowercase or all caps? This is the only occurence of it by itself (as opposed to “base64url”). At first I wasn’t going to mention anything but I saw that “URI” was capitalized throughout the doc.

  135. in bip-0077.mediawiki:110 in 3b863a402e outdated
    105+Payjoin V2 messages use [[https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki| BIP 370 PSBT V2]] format to facilitate [[#psbt-version-2|PSBT mutation]].
    106+
    107+The payjoin version 2 protocol takes the following steps:
    108+
    109+* The receiver sends their payjoin public key and optional authentication credential according to the [[#enroll-messaging|enroll messaging]] protocol to receive a subdirectory allocation. The receiver may go offline and replay enrollment to come back online.
    110+* Out of band, the receiver shares a bitcoin URI with the sender, including a <code>pj=</code> query parameter where the subdirectory is the session public key. The key is encoded in [[https://datatracker.ietf.org/doc/html/rfc4648#section-5| base64url]] encoding. To support version 1 senders, the directory acts as an unsecured payjoin server, so <code>pjos=0</code> must be specified in the URI. Version 2 senders may safely allow output substitution regardless. An <code>ohttp=</code> parameter containing the directory's base64url encoded [[https://www.ietf.org/rfc/rfc9458.html#name-key-configuration| Oblivious HTTP Key Configuration]] must also be provided.
    


    satsie commented at 7:06 pm on July 4, 2024:
    Is the “session public key” the same as the public key being referred to in the previous bullet point? (Line 109)

    DanGould commented at 6:16 pm on July 6, 2024:
    yes, I’ll clarify.
  136. in bip-0077.mediawiki:90 in 3b863a402e outdated
    85+|<---------------------------------|                  |                |
    86+|                                  |                  |                |
    87+|                                  |                  |                |
    88+|             Payjoin PSBT         |                  |                |
    89++--------------------------------->|                  |                |
    90+|                                  |   Payjoin PSBT   |                |
    


    satsie commented at 7:19 pm on July 4, 2024:
    Does the sender poll for the Payjoin PSBT?

    DanGould commented at 6:16 pm on July 6, 2024:
    It does poll for the Payjoin PSBT by sending a payload containing the Original PSBT

    satsie commented at 7:02 pm on July 6, 2024:
    Got it. I might consider adding a footnote for that. The way the diagram is, it looks like the directory pushes a Payjoin PSBT to the sender. But I also think you are quite limited by what you can do with this format so instead of complicating the diagram, it may just be something that could be mentioned at the bottom.
  137. in bip-0077.mediawiki:174 in 3b863a402e outdated
    169+
    170+Once an Original PSBT Payload is decrypted and checked according to the [[#receivers-payjoin-psbt-checklist|checklist]], the receiver should respond with a Payjoin PSBT or an error. The receiver encrypts the PSBT according to the HPKE protocol, generating an ephemeral keypair <code>e</code> from which it derives a shared secret <code>ee</code> with the sender's key <code>e</code> from the payload. It generates a nonce from sufficient randomness, and constructs a ciphertext containing the Payjoin PSBT and serialized receiver ephemeral key <code>e</code>'s public key as associated data using ChaCha20Poly1305. A payload is constructed by concatenating the ephemeral public key, the nonce, and the ciphertext. This payload is then sent to the directory in an OHTTP request encapsulating the binary payload as a POST message to the subdirectory followed by <code>/receive</code>.
    171+
    172+===Receiver's Payjoin PSBT checklist===
    173+
    174+Other than requiring PSBTv2, the receiver checklist is the same as the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the BIP 78 receiver checklist]]
    


    satsie commented at 7:26 pm on July 4, 2024:

    nit: the rest of the doc refers to it as “PSBT version 2” (and not PSBTv2)

    I saw your comment about changing this BIP to use “PSBTv0”, is that what it is called? Or is it PSBT version 1?


    DanGould commented at 6:17 pm on July 6, 2024:
    PSBTv0 == BIP 174. There is no version 1 because an upgrade from version 0 to version 1 was considered too confusing.
  138. in bip-0077.mediawiki:182 in 3b863a402e outdated
    177+
    178+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.
    179+
    180+===Directory interactions===
    181+
    182+The payjoin directory provides a rendezvous point for sender and receiver to meet. The directory stores Payjoin payloads to support asynchronous communication. The directory must only accept OHTTP requests with an OHTTP Gateway for Payjoin version 2, accepting encrypted payloads. The directory may optionally accept HTTP/1.1 POST requests without HTTP to enrolled subdirectories to support backwards compatible Payjoin version 1 requests.
    


    satsie commented at 7:32 pm on July 4, 2024:
    What are the rules for capitalizing “Payjoin” and leaving it lowercase? One thing I noticed is “Payjoin PSBT” is capitalized since it’s treated like proper noun so by that reasoning I understand why “Payjoin payloads” is capitalized. Not sure about something like “Payjoin version 2” since it is lowercase in other parts of this doc.

    DanGould commented at 6:28 pm on July 6, 2024:
    I’m making anywhere Payjoin x is used as a proper noun capitalized, and anywhere it serves as a single transaction or adjective or verb lowercase.
  139. in bip-0077/oblivious-http-sequence.png:1 in 3b863a402e


    satsie commented at 7:43 pm on July 4, 2024:

    How easy is it for you to update this diagram? If it’s within reason I’d consider doing the following:

    • Use an italic, bold, or underline font for “Relay Request”, “Gateway Request”, “Gateway Response”, and “Relay Response” so that it is clear these are titles of the messages.

    For consistency,

    • Add “TO: Relay IP” to the Gateway Response
    • Add “TO: Client IP” to the Relay Response
  140. in bip-0077.mediawiki:230 in 3b863a402e outdated
    225+<img src=bip-0077/oblivious-http-sequence.png></img>
    226+
    227+
    228+===Message Padding===
    229+
    230+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.
    


    satsie commented at 7:46 pm on July 4, 2024:
    Is “transaction PSBTs” redundant? Or does “transaction” not refer to a Bitcoin transaction?

    satsie commented at 7:47 pm on July 4, 2024:
    Are you able to provide a link to where the 7168 number comes from?
  141. in bip-0077.mediawiki:258 in 3b863a402e outdated
    253+
    254+===Attack vectors===
    255+
    256+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.
    257+
    258+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.
    


    satsie commented at 8:02 pm on July 4, 2024:
    0Since 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.
    
  142. satsie commented at 8:22 pm on July 4, 2024: contributor
    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.
  143. Incorporate more jonatack suggestions f86fe4150b
  144. Incorporate satsie's suggesetions 5c65c2120e
  145. murchandamus added the label PR Author action required on Jul 8, 2024
  146. DanGould renamed this:
    BIP 77: Payjoin Version 2: Serverless Payjoin
    BIP 77: Payjoin Version 2 — Async Payjoin
    on Jul 15, 2024
  147. Rename "Async Payjoin" b701adea50
  148. Replace BIP21 params with fragment params 93b1e60d8a
  149. Revise document to describe Payjoin Sessions
    Enrollment was a less clear than sessions
    7e7b3b4bac
  150. Revise Sequence Diagram df3bd5239b
  151. DanGould force-pushed on Jul 15, 2024
  152. in bip-0077.mediawiki:151 in df3bd5239b outdated
    146+
    147+====Session Initiation====
    148+
    149+Receivers must initialize a Payjoin Session on a directory to have a Session subdirectory allocated to them, as follows:
    150+
    151+A receiver must first discover the directory's OHTTP Gateway Key Configuration via an authenticated bootstrap mechanism before it can initialilze a Session to receive payjoin requests. This mechanism may vary by implementation but must follow [[https://datatracker.ietf.org/doc/html/draft-ietf-privacypass-key-consistency-01| OHTTP Consistency Requirements]] and should not reveal a receiver IP address to the directory. Some examples of suitable mechanisms include fetching over a VPN, using keys included with an application binary, https-in-http CONNECT method, https-in-WebSocket, or a Tor hidden service.
    


    thebrandonlucas commented at 11:26 pm on August 19, 2024:
    0A receiver must first discover the directory's OHTTP Gateway Key Configuration via an authenticated bootstrap mechanism before it can initialize a Session to receive payjoin requests. This mechanism may vary by implementation but must follow [[https://datatracker.ietf.org/doc/html/draft-ietf-privacypass-key-consistency-01| OHTTP Consistency Requirements]] and should not reveal a receiver IP address to the directory. Some examples of suitable mechanisms include fetching over a VPN, using keys included with an application binary, https-in-http CONNECT method, https-in-WebSocket, or a Tor hidden service.
    
  153. jonatack commented at 3:42 pm on September 25, 2024: member
    Hi @DanGould, want to update here?
  154. DanGould commented at 6:29 pm on September 26, 2024: contributor

    Hi @DanGould, want to update here?

    Since the last review I have made breaking changes, which I’ll apply with an update now. I think we’re at the point where each design decision I’m aware of is deliberate. I’ll take it out of draft once the new update is pushed.

  155. Spell initialize dc4a975734
  156. Update the bip to represent the stable protocol 87f892dce6
  157. Spell according to Type Checks's job 11b1b83db6
  158. Mention the format of the ohttp fragment e44f748f6a
  159. DanGould commented at 9:05 pm on September 26, 2024: contributor

    The main changes from the last review are that

    • HTTP request methods (POST, GET, PUT) control the flow of the protocol rather than further path subdiretories
    • bip21 parameters (pj subdirectory and ohttp key config) serialize as compressed public keys to shorten the URI
    • Use PSBTv0 since PSBTv2 support is still very limited
    • explicitly mention the format of the ohttp KeyConfiguration URL fragment
  160. DanGould marked this as ready for review on Sep 26, 2024
  161. Reference BIP 78 attack vectors f7a5d25b52
  162. Remove straggling text 3b7be8cf18
  163. in bip-0077.mediawiki:258 in e44f748f6a outdated
    253+
    254+Since directories store arbitrary encrypted payloads they are vulnerable to the tragedy of the commons and denial of service attacks. To mitigate such attacks, directory operators may impose an authentication requirement before they allocate a Payjoin Session subdirectory to receivers.
    255+
    256+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.
    257+
    258+Receivers may break spec by ignoring the <code>exp=</code> without financial consequence since the sender payload contains a valid transaction that may be broadcast at any time. There is no mechanism to enforce penalties if a receiver fails to construct a Payjoin PSBT and wait for a signature once a Payjoin PSBT is returned to a sender. However, such basic transactions that comply with the common-input assumption are the norm, so falling back to them is no worse than typical bitcoin transaction behavior.
    


    1440000bytes commented at 11:09 pm on October 7, 2024:
    Can add a link to attack vectors shared in BIP 78 as they apply to BIP 77 as well and mention that it should not be used for accepting donations: https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#attack-vectors

    DanGould commented at 4:19 am on October 8, 2024:

    I’ve now referenced the BIP 78 attack vectors thanks to your recommendation.

    Why not use Payjoin to accept donations?


    jonatack commented at 6:10 pm on October 8, 2024:

    mention that it should not be used for accepting donations

    for the benefit of users

    I think that would need a rationale to be helpful to users.

  164. 1440000bytes changes_requested
  165. 1440000bytes commented at 6:19 pm on October 8, 2024: contributor

    NACK

    This BIP is bad for privacy and lacks details in “attack vectors” section. Please be careful while implementing.

  166. jonatack commented at 6:26 pm on October 8, 2024: member

    NACK

    This BIP is bad for privacy

    Can you provide the reasoning, please?

  167. 1440000bytes commented at 6:35 pm on October 8, 2024: contributor

    NACK

    This BIP is bad for privacy

    Can you provide the reasoning, please?

    Risks with accepting donations using payjoin:

    • Probing: Already mentioned in BIP 78
    • Small donations: Best form of attack in which FBI donates some sats to support their work and know all the UTXOs in the wallet
  168. 1440000bytes commented at 6:37 pm on October 8, 2024: contributor
  169. thebrandonlucas commented at 7:04 pm on October 8, 2024: none

    Risks with accepting donations using payjoin:

    • Probing: Already mentioned in BIP 78 but BIP 77 author too emotional to accept it
    • Small donations: Best form of attack in which FBI donates some sats to support their work and know all the UTXOs in the wallet @1440000bytes Your first point has already been addressed and he has added a link to the attack vectors section on BIP-78. No one is “not accepting” anything. Are you asking that the full explanation given on probing attacks in BIP-78 be redundantly added here? What exactly is your criticism?

    Your second point has already been addressed in BIP-78, here is what the link that you suggested be added says:

    0While we cannot prevent this type of attack entirely, we implemented the following mitigations:
    1
    2- When the receiver detects an original transaction being broadcast, or if the receiver detects that the original transaction has been double spent, then they will reuse the UTXO that was exposed for the next payjoin.
    3- While the exposed UTXO will be reused in priority to not leak other UTXOs, there is no strong guarantee about it. This prevents the attacker from detecting with certainty the next payjoin of the merchant to another peer.
    

    BIP-78 already explains what can be done to mitigate this, and fully acknowledges this tradeoff. Can you explain, in terms of probing attacks, how BIP-77 would be worse for privacy than the already accepted BIP-78?

  170. in bip-0077.mediawiki:153 in 3b7be8cf18 outdated
    148+
    149+Payjoin Sessions begin by having a receiver send the static public key to the directory via OHTTP, receiving their subdirectory in a base64url encoded directory URL as response. Initiation may be replayed in case the receiver goes offline and should result in the same response, i.e. it Is idempotent.
    150+
    151+Optionally, before returning the URI, the receiver may request an authentication token by presenting a message containing only the word <code>Authenticate: <description></code>, after which the receiver is required to submit an <code>Authenticate: <token></code> including the token from the directory out of band. If authentication fails, an error is returned.
    152+
    153+If a directory is operated by an exchange, it may give out authentication tokens for users of its app, or may require some proof of work out of band. Tokens should be anonymous credentials from the directory describing the parameters of their authorization. Specific credentialing is out of the scope of this proposal.
    


    nothingmuch commented at 10:48 pm on October 8, 2024:
    1. shouldn’t the directory indicate to the receiver that authorization is required using a 401 response?

    2. wouldn’t an Authorization header be more appropriate? Specifically RFC 6750? the wording “required to submit an Authenticate: <token>” doesn’t indicate how it’s to be submitted (seems to imply that it’s as a header but closest is WWW-Authenticate which is a response header used in 40{1,7} responses)

    3. instead of “should be anonymous credentials”, if a token is used maybe it’s better to specify that it “must be unlinkable”?


    DanGould commented at 4:44 am on October 9, 2024:
    • shouldn’t the directory indicate to the receiver that authorization is required using a 401 response?

    Yes, that’s proper HTTP semantics

    • wouldn’t an Authorization header be more appropriate? Specifically RFC 6750? the wording “required to submit an Authenticate: <token>” doesn’t indicate how it’s to be submitted (seems to imply that it’s as a header but closest is WWW-Authenticate which is a response header used in 40{1,7} responses)

    Yes

    • instead of “should be anonymous credentials”, if a token is used maybe it’s better to specify that it “must be unlinkable”?

    Yes

    TODO

  171. nothingmuch commented at 1:47 am on October 9, 2024: none

    The sender could first register an additional session subdirectory for the response, and include the associated public key along with the original PSBT when posting to the receiver’s subdirectory. The sender would then respond in the sender’s subdirectory.

    Eliminating the request/response distinction would avoid a metadata leak, namely whether or not the payjoin flow was completed, since requests and responses would be indistinguishable.

    A followup suggestion would be removing explicit session initialization. Incidentally in the reference directory it appears that since post_session is stateless, calling it before other operations is indeed not enforced. GET & POST handlers do appear to validate the id path component, but if they did then the first successful request would indicate to either party that the subdirectory ID is valid (or perhaps arbitrary IDs were allowed by design?)

    Timing analysis of subdirectory polling could still leak information about which payjoin requests were responded to, but aggressive clients could mitigate this by maintaining a pool of pre-allocated and randomly polled subdirectories ahead of time, and by responding to themselves in some of them with dummy payloads to generate random cover traffic.

  172. DanGould commented at 4:14 am on October 9, 2024: contributor

    @nothingmuch I’ll write up your suggestions to simplify the protocol. It makes the directory implementation simpler, requires fewer protocol message types, and even reduces bandwidth. wowza

    The sender could first register an additional session subdirectory … and include the associated public key along with the original PSBT

    HPKE E2EE deployed in this application in Authenticated mode (akin to Noise Framework’s IK model) already requires the sender to include their session public key as associated data, so this is an pretty darn easy change to make. The change not only simplifies the protocol messaging, but as you say eliminates a metadata leak. I’m a big fan.

    A followup suggestion would be removing explicit session initialization

    This makes sense too. Creating separate subdirectory resources for either sender or receiver on POST then GETting updates to replace the repeated sender POST polling reduces bandwidth too, since the GET request doesn’t contain that repeat POST body.

    Even without aggressive client mitigation of the remaining client leaks subject to timing analysis assuming this suggestion is put in place, your new design deletes complexity and improves efficiency.

    I’ll update the BIP to the best of my understanding based on your comment and link it to a rust-payjoin issue to implement. This spec has already made some breaking changes since the last directory release, so it’s a good time for another one since we won’t break production implementations other than our own.

    Edit: Is there a potential authorization issue now that the sender POSTs first? In the current design of the protocol, only the receiver might need authorization from the directory in order to initialize a session subdirectory, and having knowledge of a session public key was sufficient for the sender to use an initialized subdirectory. Now, the sender would also need to obtain authorization somehow, since the directory doesn’t yet know about the session the receiver has implicitly initiated by communicating directly with the sender, out of band from the directory. We’ll have to work out how this might affect the expiration mechanic as well.

  173. Specify authorization mechanism
    The specifics of a credential issuance are left out, however
    66457a0111
  174. Use implicit session initialization c917eab7e8
  175. jonatack removed the label PR Author action required on Oct 11, 2024
  176. in bip-0077.mediawiki:236 in c917eab7e8 outdated
    231+
    232+===Secp256k1 Hybrid Public Key Encryption===
    233+
    234+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 version 2 application specific configuration to use DHKEM(Secp256k1, HKDF-SHA256) and ChaCha20Poly1305 AEAD.
    235+
    236+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 used for a single Payjoin Session. The key is encoded in [[https://datatracker.ietf.org/doc/html/rfc4648#section-5| base64url]] encoding as a Payjoin Directory subdirectory in the <code>pj=</code> parameter.
    


    nothingmuch commented at 6:35 pm on October 16, 2024:
    0The 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/IK/| IK]] pattern. A receiver shares its public key out of band in the BIP 21 URI. Static keys shared in URIs must only be used for a single Payjoin Session. The key is encoded in [[https://datatracker.ietf.org/doc/html/rfc4648#section-5| base64url]] encoding as a Payjoin Directory subdirectory in the <code>pj=</code> parameter.
    
  177. Specify cryptographic handshake based on Noise IK
    Co-authored-by: Yuval Kogman <nothingmuch@woobling.org>
    3046520eba
  178. in bip-0077.mediawiki:154 in 3046520eba outdated
    149+
    150+The Original PSBT is serialized in base64, followed by the query parameter string on a new line. This plaintext string is encrypted according to HPKE using a shared secret derived from the sender's Payjoin Session public key combined with the receiver's subdirectory Payjoin Session public key. The resulting HPKE payload body is then encapsulated according to Oblivious HTTP as a POST request to the directory's OHTTP Gateway to the receiver's payjoin session subdirectory.
    151+
    152+Upon receipt, the directory's OHTTP Gateway decapsulates the OHTTP request and handles the inner POST request at the receiver's Payjoin Session subdirectory endpoint, which stores the HPKE encrypted payload to be forwarded to the receiver.
    153+
    154+The sender then polls GET requests to the receiver's Payjoin Session subdirectory endpoint in order to await a response from the directory containing a <code>Payjoin PSBT</code>. It stops polling after expiry.
    


    spacebear21 commented at 1:56 am on October 17, 2024:
    0The sender then polls GET requests to the receiver's Payjoin Session subdirectory endpoint in order to await a response from the directory containing a <code>Proposal PSBT</code>. It stops polling after expiry.
    

    spacebear21 commented at 10:10 pm on October 17, 2024:

    IIUC the sender should poll GET requests to their own subdirectory here, not the receiver’s.

    0The sender then polls GET requests to the sender's Payjoin Session subdirectory endpoint in order to await a response from the directory containing a <code>Payjoin PSBT</code>. It stops polling after expiry.
    
  179. in bip-0077.mediawiki:160 in 3046520eba outdated
    155+
    156+====Receive Messaging====
    157+
    158+After sharing the Payjoin URI with the sender, the receiver sends a GET request to the path of the receiver's Payjoin Session subdirectory. This request is encapsulated in OHTTP. It continues to poll by sending a new OHTTP request after receiving an encapsulated 202 ACCEPTED response notifying the receiver that the directory has not yet received a request from the sender.
    159+
    160+Upon receiving OHTTP response from the directory encapsulating a request from the sender with status code 200 OK, the receiver decrypts the payload and checks the <code>Payjoin PSBT</code> according to the [[#receivers-payjoin-psbt-checklist|checklist]].
    


    spacebear21 commented at 1:56 am on October 17, 2024:
    0Upon receiving OHTTP response from the directory encapsulating a request from the sender with status code 200 OK, the receiver decrypts the payload and checks the <code>Original PSBT</code> according to the [[#receivers-payjoin-psbt-checklist|checklist]].
    
  180. in bip-0077.mediawiki:162 in 3046520eba outdated
    157+
    158+After sharing the Payjoin URI with the sender, the receiver sends a GET request to the path of the receiver's Payjoin Session subdirectory. This request is encapsulated in OHTTP. It continues to poll by sending a new OHTTP request after receiving an encapsulated 202 ACCEPTED response notifying the receiver that the directory has not yet received a request from the sender.
    159+
    160+Upon receiving OHTTP response from the directory encapsulating a request from the sender with status code 200 OK, the receiver decrypts the payload and checks the <code>Payjoin PSBT</code> according to the [[#receivers-payjoin-psbt-checklist|checklist]].
    161+
    162+The receiver then updates the <code>Original PSBT</code> to include new signed inputs and outputs, invalidating sender signatures, and may adjust the fee. The result is called the <code>Payjoin PSBT</code>.
    


    spacebear21 commented at 1:57 am on October 17, 2024:
    0The receiver then updates the <code>Original PSBT</code> to include new signed inputs and outputs, invalidating sender signatures, and may adjust the fee. The result is called the <code>Proposal PSBT</code>.
    
  181. in bip-0077.mediawiki:164 in 3046520eba outdated
    159+
    160+Upon receiving OHTTP response from the directory encapsulating a request from the sender with status code 200 OK, the receiver decrypts the payload and checks the <code>Payjoin PSBT</code> according to the [[#receivers-payjoin-psbt-checklist|checklist]].
    161+
    162+The receiver then updates the <code>Original PSBT</code> to include new signed inputs and outputs, invalidating sender signatures, and may adjust the fee. The result is called the <code>Payjoin PSBT</code>.
    163+
    164+The receiver encrypts the <code>Payjoin PSBT</code> according to the HPKE protocol, generating an ephemeral keypair from which it derives a shared secret with the sender's Payjoin Session public key from the payload. It generates a nonce from sufficient randomness, and constructs a ciphertext containing the Payjoin PSBT and serialized receiver ephemeral key <code>e</code>'s public key as associated data using ChaCha20Poly1305. A payload is constructed by concatenating the ephemeral public key, the nonce, and the ciphertext. This Payjoin PSBT payload is then sent as a POST message to the directory in an OHTTP request encapsulating the binary payload to the sender's Payjoin Session subdirectory.
    


    spacebear21 commented at 1:58 am on October 17, 2024:
    0The receiver encrypts the <code>Proposal PSBT</code> according to the HPKE protocol, generating an ephemeral keypair from which it derives a shared secret with the sender's Payjoin Session public key from the payload. It generates a nonce from sufficient randomness, and constructs a ciphertext containing the Proposal PSBT and serialized receiver ephemeral key <code>e</code>'s public key as associated data using ChaCha20Poly1305. A payload is constructed by concatenating the ephemeral public key, the nonce, and the ciphertext. This Proposal PSBT payload is then sent as a POST message to the directory in an OHTTP request encapsulating the binary payload to the sender's Payjoin Session subdirectory.
    

    DanGould commented at 1:40 am on October 21, 2024:
    Consistency is key
  182. spacebear21 commented at 2:02 am on October 17, 2024: none
    Some minor clarifications following the “original”/“proposal” payjoin PSBT terminology established in BIP78.
  183. in bip-0077.mediawiki:104 in 3046520eba outdated
     99+
    100+The Payjoin version 2 protocol takes the following steps:
    101+
    102+* The receiver generates a Payjoin Session public key.
    103+* Out of band, the receiver shares a bitcoin URI with the sender, including a <code>pj=</code> query parameter where the subdirectory is the compressed Payjoin Session public key. The key is encoded in [[https://datatracker.ietf.org/doc/html/rfc4648#section-5| base64url]] encoding. To support version 1 senders, the directory acts as an unsecured Payjoin server, so <code>pjos=0</code> must be specified in the URI. Version 2 senders may safely allow output substitution regardless. An <code>ohttp=</code> fragment parameter containing the directory's base64url encoded [[https://www.ietf.org/rfc/rfc9458.html#name-key-configuration| Oblivious HTTP Key Configuration]] must also be provided. It should also include an <code>exp=</code> parameter with a Unix timestamp after which the receiver will broadcast the Original PSBT and stop polling the session.
    104+* The sender creates a valid version 0 PSBT satisfying the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the receiver checklist]]. We call this the <code>Original PSBT</code>. This <code>Original PSBT</code>, and optional sender parameters, are wrapped in HPKE authenticated encryption, including a sender session public key as associated data, and encapsulats it all as OHTTP. This [[#send-messaging|Original PSBT Request send message]] is made to the directory's OHTTP Gateway.
    


    spacebear21 commented at 2:13 am on October 17, 2024:
    0* The sender creates a valid version 0 PSBT satisfying the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the receiver checklist]]. We call this the <code>Original PSBT</code>. This <code>Original PSBT</code>, and optional sender parameters, are wrapped in HPKE authenticated encryption, including a sender session public key as associated data, and encapsulates it all as OHTTP. This [[#send-messaging|Original PSBT Request send message]] is made to the directory's OHTTP Gateway.
    
  184. in bip-0077.mediawiki:103 in 3046520eba outdated
     98+===Payjoin version 2 messaging===
     99+
    100+The Payjoin version 2 protocol takes the following steps:
    101+
    102+* The receiver generates a Payjoin Session public key.
    103+* Out of band, the receiver shares a bitcoin URI with the sender, including a <code>pj=</code> query parameter where the subdirectory is the compressed Payjoin Session public key. The key is encoded in [[https://datatracker.ietf.org/doc/html/rfc4648#section-5| base64url]] encoding. To support version 1 senders, the directory acts as an unsecured Payjoin server, so <code>pjos=0</code> must be specified in the URI. Version 2 senders may safely allow output substitution regardless. An <code>ohttp=</code> fragment parameter containing the directory's base64url encoded [[https://www.ietf.org/rfc/rfc9458.html#name-key-configuration| Oblivious HTTP Key Configuration]] must also be provided. It should also include an <code>exp=</code> parameter with a Unix timestamp after which the receiver will broadcast the Original PSBT and stop polling the session.
    


    spacebear21 commented at 10:05 pm on October 17, 2024:

    This bullet point is a bit overloaded, it could instead link to existing parts of the documentation that describe the parameters in more detail.

    0* Out of band, the receiver shares a bitcoin URI with the sender, including a <code>pj=</code> query parameter. The <code>pj</code> URL contains the compressed Payjoin Session public key, [[https://datatracker.ietf.org/doc/html/rfc4648#section-5| base64url-encoded]] followed by the [[#receiver-fragment-parameters|receiver fragment parameters]] .
    1  * To support version 1 senders, the directory acts as an unsecured Payjoin server, so <code>pjos=0</code> must be specified in the URI. Version 2 senders may safely allow output substitution regardless.
    
  185. in bip-0077.mediawiki:106 in 3046520eba outdated
    101+
    102+* The receiver generates a Payjoin Session public key.
    103+* Out of band, the receiver shares a bitcoin URI with the sender, including a <code>pj=</code> query parameter where the subdirectory is the compressed Payjoin Session public key. The key is encoded in [[https://datatracker.ietf.org/doc/html/rfc4648#section-5| base64url]] encoding. To support version 1 senders, the directory acts as an unsecured Payjoin server, so <code>pjos=0</code> must be specified in the URI. Version 2 senders may safely allow output substitution regardless. An <code>ohttp=</code> fragment parameter containing the directory's base64url encoded [[https://www.ietf.org/rfc/rfc9458.html#name-key-configuration| Oblivious HTTP Key Configuration]] must also be provided. It should also include an <code>exp=</code> parameter with a Unix timestamp after which the receiver will broadcast the Original PSBT and stop polling the session.
    104+* The sender creates a valid version 0 PSBT satisfying the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the receiver checklist]]. We call this the <code>Original PSBT</code>. This <code>Original PSBT</code>, and optional sender parameters, are wrapped in HPKE authenticated encryption, including a sender session public key as associated data, and encapsulats it all as OHTTP. This [[#send-messaging|Original PSBT Request send message]] is made to the directory's OHTTP Gateway.
    105+* The sender polls GET requests to the subdirectory defined by the sender's Payjoin Session public key in order to await a response from the directory containing a <code>Payjoin PSBT</code>. It stops polling after expiry.
    106+* The request is stored in the subdirectory.
    


    spacebear21 commented at 10:15 pm on October 17, 2024:

    Remove an unnecessary bullet point and indicate which subdirectory the request is stored in in the POST step.

    0* The sender creates a valid version 0 PSBT satisfying the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the receiver checklist]]. We call this the <code>Original PSBT</code>. This <code>Original PSBT</code>, and optional sender parameters, are wrapped in HPKE authenticated encryption, including a sender session public key as associated data, and encapsulates it all as OHTTP. This [[#send-messaging|Original PSBT Request send message]] is made to the directory's OHTTP Gateway. The request is stored in the receiver subdirectory.
    1* The sender polls GET requests to the subdirectory defined by the sender's Payjoin Session public key in order to await a response from the directory containing a <code>Payjoin PSBT</code>. It stops polling after expiry.
    
  186. in bip-0077.mediawiki:107 in 3046520eba outdated
    102+* The receiver generates a Payjoin Session public key.
    103+* Out of band, the receiver shares a bitcoin URI with the sender, including a <code>pj=</code> query parameter where the subdirectory is the compressed Payjoin Session public key. The key is encoded in [[https://datatracker.ietf.org/doc/html/rfc4648#section-5| base64url]] encoding. To support version 1 senders, the directory acts as an unsecured Payjoin server, so <code>pjos=0</code> must be specified in the URI. Version 2 senders may safely allow output substitution regardless. An <code>ohttp=</code> fragment parameter containing the directory's base64url encoded [[https://www.ietf.org/rfc/rfc9458.html#name-key-configuration| Oblivious HTTP Key Configuration]] must also be provided. It should also include an <code>exp=</code> parameter with a Unix timestamp after which the receiver will broadcast the Original PSBT and stop polling the session.
    104+* The sender creates a valid version 0 PSBT satisfying the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the receiver checklist]]. We call this the <code>Original PSBT</code>. This <code>Original PSBT</code>, and optional sender parameters, are wrapped in HPKE authenticated encryption, including a sender session public key as associated data, and encapsulats it all as OHTTP. This [[#send-messaging|Original PSBT Request send message]] is made to the directory's OHTTP Gateway.
    105+* The sender polls GET requests to the subdirectory defined by the sender's Payjoin Session public key in order to await a response from the directory containing a <code>Payjoin PSBT</code>. It stops polling after expiry.
    106+* The request is stored in the subdirectory.
    107+* Once the receiver is online, it sends [[#receive-messaging|<code>GET</code>]] requests to the subdirectory. The receiver decrypts and authenticates the response, which it checks according to [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the receiver checklist]]. The receiver updates the Original PSBT to include new signed inputs and outputs, invalidating sender signatures, and may adjust the fee. The result is called the <code>Payjoin PSBT</code>.
    


    spacebear21 commented at 10:17 pm on October 17, 2024:
    0* Once the receiver is online, it sends <code>GET</code> requests [[#receive-messaging|to the receiver subdirectory]]. The receiver decrypts and authenticates the response, which it checks according to [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the receiver checklist]]. The receiver updates the Original PSBT to include new signed inputs and outputs, invalidating sender signatures, and may adjust the fee. The result is called the <code>Payjoin PSBT</code>.
    
  187. in bip-0077.mediawiki:109 in 3046520eba outdated
    104+* The sender creates a valid version 0 PSBT satisfying the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the receiver checklist]]. We call this the <code>Original PSBT</code>. This <code>Original PSBT</code>, and optional sender parameters, are wrapped in HPKE authenticated encryption, including a sender session public key as associated data, and encapsulats it all as OHTTP. This [[#send-messaging|Original PSBT Request send message]] is made to the directory's OHTTP Gateway.
    105+* The sender polls GET requests to the subdirectory defined by the sender's Payjoin Session public key in order to await a response from the directory containing a <code>Payjoin PSBT</code>. It stops polling after expiry.
    106+* The request is stored in the subdirectory.
    107+* Once the receiver is online, it sends [[#receive-messaging|<code>GET</code>]] requests to the subdirectory. The receiver decrypts and authenticates the response, which it checks according to [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the receiver checklist]]. The receiver updates the Original PSBT to include new signed inputs and outputs, invalidating sender signatures, and may adjust the fee. The result is called the <code>Payjoin PSBT</code>.
    108+* The <code>Payjoin PSBT</code> and HPKE keys are encrypted, authenticated, encapsulated in OHTTP, and POSTed to the directory's OHTTP Gateway.
    109+* The directory awaits a request from the sender if it goes offline. Upon request, the directory relays the encrypted <code>Payjoin PSBT</code>.
    


    spacebear21 commented at 10:18 pm on October 17, 2024:
    0* The directory awaits a GET request from the sender. Upon request, the directory relays the encrypted <code>Payjoin PSBT</code>.
    
  188. spacebear21 commented at 10:22 pm on October 17, 2024: none
    I struggled a bit to grok the new messaging flow. After reading through the implementation I think I get it now and left some corrections/clarification suggestions throughout.
  189. DanGould force-pushed on Oct 21, 2024
  190. Add Spacebear's clarifications
    Co-authored-by: spacebear <git@spacebear.dev>
    28f064b98a
  191. in bip-0077.mediawiki:168 in 28f064b98a
    163+
    164+The receiver encrypts the <code>Proposal PSBT</code> according to the HPKE protocol, generating an ephemeral keypair from which it derives a shared secret with the sender's Payjoin Session public key from the payload. It generates a nonce from sufficient randomness, and constructs a ciphertext containing the Proposal PSBT and serialized receiver ephemeral key <code>e</code>'s public key as associated data using ChaCha20Poly1305. A payload is constructed by concatenating the ephemeral public key, the nonce, and the ciphertext. This Proposal PSBT payload is then sent as a POST message to the directory in an OHTTP request encapsulating the binary payload to the sender's Payjoin Session subdirectory.
    165+
    166+===Receiver's Proposal PSBT checklist===
    167+
    168+The receiver checklist is the same as the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the BIP 78 receiver checklist]], except for the "Verify that the payjoin proposal did not introduce mixed input's type" step, which may be ignored.
    


    spacebear21 commented at 3:03 pm on October 21, 2024:
    0===Receiver's Original PSBT checklist===
    1
    2The receiver checklist is the same as the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the BIP 78 receiver checklist]], except for the "If the sender's inputs are all from the same scriptPubKey type, the receiver must match the same type" step, which may be ignored.
    

    murchandamus commented at 6:29 pm on November 13, 2024:
    Maybe use “output script” instead of “scriptPubKey” since this document also uses “input script” elsewhere.
  192. in bip-0077.mediawiki:35 in 28f064b98a
    30+
    31+===Relation to BIP 78 (Payjoin version 1)===
    32+
    33+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.
    34+
    35+The BIP 78 standard allows for an [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#unsecured-payjoin-server| unsecured Payjoin server|]] to operate separately from the so-called "payment server" responsible for generating [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP 21]] request URIs. Because BIP 78 messages relayed over an unsecured server are neither end-to-end authenticated nor encrypted between sender and receiver, a malicious unsecured Payjoin server is able to modify the Proposal PSBT in flight, thus requiring payment output substitution to be disabled. Output substitution is useful for a number of block space optimizations, including payment batching and transaction cut-through. This proposal introduces authentication and encryption to secure output substitution by using a directory server without compromising sender or receiver privacy.
    


    murchandamus commented at 6:02 pm on November 13, 2024:

    This extraneous pipe character doesn’t seem to show up anywhere, but still seems to be a syntax error.

    0The BIP 78 standard allows for an [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#unsecured-payjoin-server| unsecured Payjoin server]] to operate separately from the so-called "payment server" responsible for generating [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP 21]] request URIs. Because BIP 78 messages relayed over an unsecured server are neither end-to-end authenticated nor encrypted between sender and receiver, a malicious unsecured Payjoin server is able to modify the Proposal PSBT in flight, thus requiring payment output substitution to be disabled. Output substitution is useful for a number of block space optimizations, including payment batching and transaction cut-through. This proposal introduces authentication and encryption to secure output substitution by using a directory server without compromising sender or receiver privacy.
    
  193. in bip-0077.mediawiki:10 in 28f064b98a
     5+  Author: Dan Gould <d@ngould.dev>
     6+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0077
     7+  Status: Draft
     8+  Type: Standards Track
     9+  Created: 2023-08-08
    10+  License: BSD-2-Clause
    


    murchandamus commented at 6:06 pm on November 13, 2024:

    It sounds like this proposal builds on BIP 21 URI Scheme, BIP 174 PSBT, and expands on BIP 78, so perhaps those should be listed as requirements:

    0  License: BSD-2-Clause
    1  Requires: 21, 78, 174
    

    or even replacement:

    0  License: BSD-2-Clause
    1  Requires: 21, 174
    2  Replaces: 78
    

    murchandamus commented at 7:25 pm on November 13, 2024:
    Please also link to all relevant mailing list threads via the Post-History header.
  194. in bip-0077.mediawiki:119 in 28f064b98a
    114+* Include complete UTXO data.
    115+* Be signed.
    116+* Exclude unnecessary fields such as global xpubs or keypath information.
    117+* Be broadcastable.
    118+
    119+The Original PSBT MAY:
    


    murchandamus commented at 6:17 pm on November 13, 2024:
    Just wondering, is this proposal only compatible with PSBT v0, or also PSBT v2? Perhaps it would make sense for this proposal to consider whether this proposal will be compatible with the efforts in “Bip Draft: Sending Silent Payments in PSBTs #1687” to ensure that it will be possible in the future to create Silent Payments-based Payjoins?

    nothingmuch commented at 10:14 pm on November 15, 2024:

    From the point of view of the BIP 77 Sender & Receiver roles, there are three relevant settings we might consider, whether the receiver knows b_scan or only B_scan (relevant for cut-through payments when the receiver’s intended recipient is a 3rd party), or whether the sender knows B_scan at the time of sending the original PSBT.

    When the receiver only knows B_scan, they they know the corresponding a values of their inputs, but since the BIP 77 sender does not necessarily know B_scan yet, this requires another round of communication. The receiver can provide the ECDH_SHARE values a*B_scan for their inputs, and SP_V0_INFO values for their outputs as per BIP-PSBT-SP. Unfortunately, although the sender can complete compute the output scripts, they cannot sign for the receiver’s inputs, nor can the receiver sign before the sender’s ECDH_SHARE values are given because their output scripts are not finalized, which deviates from BIP 77.

    Conversely, since BIP 77 specifies that the receiver modify the Original PSBT, which is already signed, the proposal PSBT can’t be considered “the same” in line with BIP 370, as that requires that inputs and outputs no longer be modifiable to ensure signatures are invalidated, and BIP 352 requires that signatures commit to the input set to ensure output scripts are spendable. Therefore for BIP-PSBT-SP to be compatible with this use case it would need to relax BIP 370’s rules for input/output modifiability as well, and introduce non-monotonicity to the Signer and Combiner roles.

    However, the other two settings don’t require any modifications for compatibility:

    When the receiver knows b_scan, they can use the Original PSBT’s witnesses to compute A as per BIP 352, adjust it to account for their own inputs, and use b_scan to derive their own output addresses before sending the proposal PSBT back to the sender, and the sender doesn’t need to support silent payments in any way (also compatible with BIP 78 if output substitution is not disallowed). This allows a BIP 352 aware BIP 77 receiver receiver to statelessly avoid address reuse, and does not require state or growing the BIP 44 address gap limit even if BIP 77 sessions fail, so potentially quite valuable.

    Secondly, the case where the sender knows B_scan a priori (e.g. from the BIP 21 URI) is also independently interesting, but does not require any changes WRT the BIP-PSBT-SP.

    If silent payments transactions are hypothetically used for sender initiated BIP 77 compatible payjoins (arguably topic of a separate BIP than BIP 77 anyway), the receiver can reply with a proposal PSBT as in BIP 77, with the silent payments transaction taking the place of the original PSBT. The sender’s reply public key can be implicit, e.g. the BIP 352 A point (or arguably better yet, the sum of the R points?). This sort of assumes payjoin/rust-payjoin#364. If also assuming payjoin/rust-payjoin#386, the BIP 352 ECDH shared secret could be used to derive a tweak for the HPKE reply key, precluding the directory from censoring payjoins associated with a specific SP transaction.

    In this situation, the sender already provided their ECDH secrets, which allows the receiver to dividing out the original PSBT’s input set hash, add their own private keys, and the input hash of the modified input set, only requiring the sender to provide new signatures for the proposal PSBT.

    Unfortunately this final variant is not as useful as it might appears, because it assumes the sender won’t do another round of input addition, which implies the transaction replacement will leak information about the payment amount and potentially violate the unnecessary input heuristics if the additional round of communication is to be avoided. If the sender is allowed to reply to the receiver, then it would need to provide ECDH_SHARE values as per BIP-PSBT-SP, in line with the case where receiver only knowing B_scan.

  195. in bip-0077.mediawiki:127 in 28f064b98a
    122+
    123+The Proposal PSBT MUST:
    124+
    125+* Include all inputs from the Original PSBT.
    126+* Include all outputs which do not belong to the receiver from the Original PSBT.
    127+* Include complete UTXO data.
    


    murchandamus commented at 6:21 pm on November 13, 2024:
    0* Include complete UTXO data.
    1* Insert additional outputs or additional inputs at random indices while retaining the order of existing inputs and outputs.
    
  196. in bip-0077.mediawiki:135 in 28f064b98a
    130+
    131+* Add, remove or modify Original PSBT outputs under the control of the receiver (i.e. not sender change).
    132+
    133+The Proposal PSBT MUST NOT:
    134+
    135+* Shuffle the order of inputs or outputs; the additional outputs or additional inputs must be inserted at a random index.
    


    murchandamus commented at 6:23 pm on November 13, 2024:

    It seems to me that the latter should also be mentioned in the “MUST” block above (see above) and then this could be reduced to the MUST NOT part:

    0* Shuffle the order of existing inputs or outputs.
    
  197. in bip-0077.mediawiki:172 in 28f064b98a
    167+
    168+The receiver checklist is the same as the [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist| the BIP 78 receiver checklist]], except for the "Verify that the payjoin proposal did not introduce mixed input's type" step, which may be ignored.
    169+
    170+===Sender's Proposal PSBT checklist===
    171+
    172+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 mixed input script types are allowed, and 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.
    


    murchandamus commented at 6:31 pm on November 13, 2024:

    inputs ⇒ input?

    0The 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 mixed input script types are allowed, and it expects all UTXO data to be filled in. BIP 78 required sender input 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.
    
  198. in bip-0077.mediawiki:27 in 28f064b98a
    22+
    23+Payjoin is the simplest case of interactive bitcoin batching, allowing two participants to combine their transaction intents. It solves the sole privacy problem left open in the bitcoin paper, that transactions with multiple inputs "necessarily reveal that their inputs were owned by the same owner," by enabling two owners to provide input in a transaction.
    24+
    25+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.
    26+
    27+Payjoin version 1's requirements have proven to be an obstacle to adoption. Version 1 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.
    


    murchandamus commented at 6:34 pm on November 13, 2024:
    BIP 78 is titled “A Simple Payjoin Proposal”, so maybe just to make the context abundantly clear, it may be useful to formally introduce “Payjoin version 1” as a moniker for BIP 78 Payjoins before the first use thereof (it’s only introduced implicitly in line 31).
  199. in bip-0077.mediawiki:176 in 28f064b98a
    171+
    172+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 mixed input script types are allowed, and 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.
    173+
    174+===Directory interactions===
    175+
    176+The Payjoin Directory provides a rendezvous point for sender and receiver to meet. The directory stores Payjoin payloads to support asynchronous communication. The directory must only accept OHTTP requests with an OHTTP Gateway for Payjoin version 2, accepting encrypted payloads. The directory may optionally accept HTTP/1.1 POST requests without OHTTP to Payjoin Session subdirectories to support backwards compatible Payjoin version 1 requests.
    


    murchandamus commented at 6:45 pm on November 13, 2024:

    FWIU, it’s the directory that is backwards compatible, not the Payjoin version 1 request

    0The Payjoin Directory provides a rendezvous point for sender and receiver to meet. The directory stores Payjoin payloads to support asynchronous communication. The directory must only accept OHTTP requests with an OHTTP Gateway for Payjoin version 2, accepting encrypted payloads. The directory may optionally accept HTTP/1.1 POST requests without OHTTP to Payjoin Session subdirectories for backwards compatibility with Payjoin version 1 requests.
    
  200. in bip-0077.mediawiki:184 in 28f064b98a
    179+
    180+Each Payjoin Session subdirectory allocated on the directory has one buffer for a PSBT payload. The buffer updates listeners through awaitable events so that updates are immediately apparent upon client request.
    181+
    182+===Receiver fragment parameters===
    183+
    184+A major benefit of BIP 78 Payjoin over other coordination mechanisms is its compatibility with the universal BIP 21 bitcoin URI standard.
    


    murchandamus commented at 6:47 pm on November 13, 2024:
    I noticed that “BIP 78 Payjoin” or “Payjoin version 1” appear to be used synonymously. Please only use one term to refer to the same concept throughout the document. If synonyms should be mentioned, please state them along the introduction of the term.
  201. in bip-0077.mediawiki:188 in 28f064b98a
    183+
    184+A major benefit of BIP 78 Payjoin over other coordination mechanisms is its compatibility with the universal BIP 21 bitcoin URI standard.
    185+
    186+Instead of defining new [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP 21 URI]] parameters, Payjoin version 2 encodes parameters in the [[https://datatracker.ietf.org/doc/html/rfc3986#section-3.5| fragment]] of the URL following the <code>pj=</code> parameter in the BIP 21 URI. They follow the <code>#</code> character and follow the semantics of the [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki#abnf-grammar| BIP 21 "otherparam" grammar]], being separated by an <code>&</code> character.
    187+
    188+* <code>ohttp</code>: represents the OHTTP Key Configuration of the directory. This is a base64url encoded compressed public key of the directory's OHTTP Gateway, prefixed by the one byte Key Identifier, from which the [[https://www.ietf.org/rfc/rfc9458.html#section-3.1| RFC 9458 Key Configuration can be constructed]]. This parameter is required for version 2 Payjoin URIs.
    


    murchandamus commented at 6:52 pm on November 13, 2024:

    “Payjoin version 2” vs “version 2 Payjoin”:

    0* <code>ohttp</code>: represents the OHTTP Key Configuration of the directory. This is a base64url encoded compressed public key of the directory's OHTTP Gateway, prefixed by the one byte Key Identifier, from which the [[https://www.ietf.org/rfc/rfc9458.html#section-3.1| RFC 9458 Key Configuration can be constructed]]. This parameter is required for Payjoin version 2 URIs.
    
  202. in bip-0077.mediawiki:219 in 28f064b98a
    214+
    215+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.
    216+
    217+===Oblivious HTTP===
    218+
    219+OHTTP protects sender and receiver IP addresses both from one another and from the directory. This makes it more difficult for a directory to correlate many payjoin transactions with specific IP addresses by intersection.
    


    murchandamus commented at 6:56 pm on November 13, 2024:

    It seems that we may be referring to the agent behind the directory rather than the directory itself?

    0OHTTP protects sender and receiver IP addresses both from one another and from the directory provider. This makes it more difficult for a directory provider to correlate many payjoin transactions with specific IP addresses by intersection.
    
  203. in bip-0077.mediawiki:225 in 28f064b98a
    220+
    221+OHTTP relays can be run as basic HTTP proxies from wallet providers or third parties.
    222+
    223+====OHTTP Sequence Diagram====
    224+
    225+<img src=bip-0077/oblivious-http-sequence.png></img>
    


    murchandamus commented at 6:57 pm on November 13, 2024:
    I’m surprised that the sequence diagram above was drawn in ASCII, while this is an image. Perhaps both should be provided in the same style.
  204. in bip-0077.mediawiki:272 in 28f064b98a
    267+
    268+The receivers advertise Payjoin capabilities through [[https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki| BIP 21's URI Scheme]].
    269+
    270+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. If a sender intending to pay such a URI containing <code>req-pj=</code> does not support Payjoin, it MUST consider the entire URI invalid per BIP 21.
    271+
    272+Receivers may choose to support version 1 payloads. Version 2 Payjoin URIs for backwards compatible receivers MUST enable <code>pjos=0</code> so that these version 1 senders disable output substitution. Since the version 1 messages are neither encrypted nor authenticated, they would otherwise be at risk for man-in-the-middle attacks. The directory protocol should carry on as normal, responding to payjoin requests instead with this version 1 request as BHTTP in an OHTTP response. The receiver should POST version 1 Proposal PSBTs to the same subdirectory as in version 2 to respond to these version 1 senders within 30 seconds. If no response is received within 30 seconds, the directory should respond with an <code>unavailable</code> error code as [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-well-known-errors| defined in BIP 78]].
    


    murchandamus commented at 7:08 pm on November 13, 2024:

    Consistency nit:

    0Receivers may choose to support Payjoin version 1 payloads. Payjoin version 2  URIs for backwards compatible receivers MUST enable <code>pjos=0</code> so that these version 1 senders disable output substitution. Since the version 1 messages are neither encrypted nor authenticated, they would otherwise be at risk for man-in-the-middle attacks. The directory protocol should carry on as normal, responding to payjoin requests instead with this version 1 request as BHTTP in an OHTTP response. The receiver should POST version 1 Proposal PSBTs to the same subdirectory as in version 2 to respond to these version 1 senders within 30 seconds. If no response is received within 30 seconds, the directory should respond with an <code>unavailable</code> error code as [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-well-known-errors| defined in BIP 78]].
    

    murchandamus commented at 7:10 pm on November 13, 2024:
    What is BHTTP? I don’t think that was introduced in this document.

    murchandamus commented at 7:11 pm on November 13, 2024:

    Luckily there is no PSBT v1, otherwise “version 1 Proposal PSBTs” may be confusing. Either way, I think it would be better to use “Payjoin version 1” consistently instead of abbreviating.

    0Receivers may choose to support version 1 payloads. Version 2 Payjoin URIs for backwards compatible receivers MUST enable <code>pjos=0</code> so that these version 1 senders disable output substitution. Since the version 1 messages are neither encrypted nor authenticated, they would otherwise be at risk for man-in-the-middle attacks. The directory protocol should carry on as normal, responding to payjoin requests instead with this version 1 request as BHTTP in an OHTTP response. The receiver should POST Payjoin version 1 Proposal PSBTs to the same subdirectory as in version 2 to respond to these version 1 senders within 30 seconds. If no response is received within 30 seconds, the directory should respond with an <code>unavailable</code> error code as [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-well-known-errors| defined in BIP 78]].
    
  205. in bip-0077.mediawiki:276 in 28f064b98a
    271+
    272+Receivers may choose to support version 1 payloads. Version 2 Payjoin URIs for backwards compatible receivers MUST enable <code>pjos=0</code> so that these version 1 senders disable output substitution. Since the version 1 messages are neither encrypted nor authenticated, they would otherwise be at risk for man-in-the-middle attacks. The directory protocol should carry on as normal, responding to payjoin requests instead with this version 1 request as BHTTP in an OHTTP response. The receiver should POST version 1 Proposal PSBTs to the same subdirectory as in version 2 to respond to these version 1 senders within 30 seconds. If no response is received within 30 seconds, the directory should respond with an <code>unavailable</code> error code as [[https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-well-known-errors| defined in BIP 78]].
    273+
    274+==Reference implementation==
    275+
    276+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 may be configured to the following independent production relays as of 24/09/26:
    


    murchandamus commented at 7:12 pm on November 13, 2024:

    Typo:

    0An 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 Oblivious HTTP relay implementation may be found here [[https://github.com/payjoin/ohttp-relay]]. The reference implementation may be configured to the following independent production relays as of 24/09/26:
    

    murchandamus commented at 7:19 pm on November 13, 2024:

    I’m not sure whether specifying “production relays” in the BIP makes sense as that information will almost inevitably outdate.

    I also think that “production relays” synonymously refers to what was previously called “Payjoin Directory”. Please do not use synonyms but settle on one term.

    image via https://courses.lumenlearning.com/olemiss-technicalwriting/chapter/unit-3-using-appropiate-language-and-tone-avoiding-confusing-terms-lecture-2/

  206. in bip-0077.mediawiki:15 in 28f064b98a
    10+  License: BSD-2-Clause
    11+</pre>
    12+
    13+==Abstract==
    14+
    15+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.
    


    murchandamus commented at 7:23 pm on November 13, 2024:

    It is clearer to repeat the active agent by name:

    0This 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 the receiver to host a secure public endpoint. This requirement is replaced with an untrusted third-party directory accessed via HTTP clients that communicate using an asynchronous protocol 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.
    
  207. in bip-0077.mediawiki:4 in 28f064b98a
    0@@ -0,0 +1,280 @@
    1+<pre>
    2+  BIP: 77
    3+  Layer: Applications
    4+  Title: Payjoin Version 2 — Async Payjoin
    


    murchandamus commented at 7:32 pm on November 13, 2024:

    Many visitors of the BIPs repository may first become aware of this proposal per the title. Does writing out “version 2” provide the biggest bang for the buck?

    What do you think about:

    0  Title: Payjoin v2—Async Payjoin
    

    Or even:

    0  Title: Async Payjoin
    
  208. murchandamus commented at 7:40 pm on November 13, 2024: contributor

    This is looking great. I did not notice any blocking formatting issues, and it appears to fulfill all formal criteria to get merged. Please let me know when you have concluded addressing the outstanding review comments and are ready for it to get merged.

    Would it be viable to provide test vectors for this proposal? If so, I would suggest that some be added before this proposal is advanced to “Proposed”.


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bips. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-11-21 12:10 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me