OpenBitcoinPrivacyProject / rfc

OBPP Request for Comments (RFC) Documentation
19 stars 8 forks source link

Feedback on OBPP-5: Reusable Payment Codes v3 #6

Closed craigraw closed 3 years ago

craigraw commented 3 years ago

Hi,

I'm lead maintainer of Sparrow Wallet. I'm interesting in supporting the reusable payment codes specification, but I've run into an issue (that might be a misunderstanding on my part) regarding payment output scripts:

The BIP47 specification (payment code versions 1 & 2) supports receiving at P2PKH addresses only. This is simple enough, but by now this legacy script is discouraged by most wallet software as being fee inefficient.

For version 3, a much wider range of script types is allowed, including P2WPKH and P2WSH (Off-topic: I'm not sure what the P2WSH script would look like here given multisig is not supported. Additionally, P2PK is recommended which seems anachronistic? What about P2SH-P2WPKH?)

The issue however is this: Some wallet software, like Samourai, supports multiple script types behind the scenes based off a seed. Others, like Sparrow, configure a user's wallet with a specific script type. While it's technically possible for Sparrow to listen for payments to other script types based off the ephemeral public key, it has no place in the UI to display payments to these script types. It just doesn't fit the UI model, which aims to provide visibility into the Bitcoin protocol rather than abstracting these details from the user.

A related problem is that the receiving wallet must support listening to a wide and loosely defined variety of script types, which increases the server-side burden considerably given that a reasonable lookahead must be supported for all of the 'payment channels' that have been established.

As a remedy, I propose that the v3 payment code includes information on the script type it supports receiving on, from the following list:

  1. P2PKH
  2. P2SH-P2WPKH
  3. P2WPKH

This could be encoded into the v3 payment code at the cost of an extra byte, making it much safer to support receiving BIP47 style payments across a wide variety of wallet software, and in addition reducing the risk of losing access to funds when moving from one to another.

justusranvier commented 3 years ago

The issue with scripts are that 20 bytes hashes aren't as secure as we would like them to be in the specific situation of derived keys.

If your script type includes a 20 byte hash (P2PKH, P2WPKH, P2SH, P2WSH) then the sender can generate a colliding hash with only 80 bits of work on average and reclaim the payment.

80 bits of work is still a lot and it's probably not worth giving up on 20 byte hash scripts entirely, but original though was that end users never see raw scripts anyway so it shouldn't matter if the script is swapped out for P2PK behind the scenes for added security. It's interesting that your wallet does display those details by default, but I'm hesitant to change a wallet-agnostic protocol based on a particular ui design decision that is not common to multiple implementation.

The point about server side burden only applies to wallets that use a server backend, which is again not common to all implementations. Payment codes can be implemented with BIP-157 client-side filters which eliminates the server backend load issue.

I am open to revising the list of scripts though.

On chains with excessive fees, then P2WPKH is probably the best choice since if the user is concerned about the security of high-value payments they can sweep receive funds to non-derived keys.

If we're going to modify the list entirely then I can see dropping P2WSH since it's kinda pointless and was only listed for the sake of consistency. P2PK has to stay since it would be the preferred, most secure, script type. P2PKH is also kinda pointless because in situations where you don't want to use P2PK then you should use P2WPKH.

P2SH-P2WPKH is also pointless because if a sender wallet has to be taught the payment protocol anyway they it can just be taught to send native P2WPKH, and what receiving wallet that would be implementing v3 payment codes doesn't already support native segwit by now?

Regarding adding a byte - we can't. The improvements to the notification protocol are only possible if a payment code is 33 bytes payload + 1 byte version.

We can define more than one version though.

If there is a wallet that absolutely can't support receiving to P2PK for some reason that could be defined as version 4, whereas version 3 is implied to accept either P2PK or P2WPKH.

justusranvier commented 3 years ago

Metier Wallet addresses this by watching all plausible script types so adding or removing a few is no big deal at this stage.

craigraw commented 3 years ago

Thanks for the detailed consideration. I'm starting from the point of view that BIP47 (or it's descendants) is good for the Bitcoin ecosystem and should be implemented in as many wallets as possible. Given this, I don't think that a requirement to support receiving on multiple script types is a good idea for the reasons I've stated above:

  1. We can't assume the the UI and underlying code will handle it easily or at all (most wallets configure a specific script type)
  2. We can't assume the server implementation will handle it easily or at all (most wallets use a server backend AFAIK - BIP157 is not widely used)

Could you elaborate on why 20 bytes hashes aren't as secure in the context of derived keys - surely all public keys are derived? I have another two concerns around using P2PK:

  1. It's almost entirely unused currently, which makes it much more visible to blockchain analytics - this is a significant privacy concern and I can't see privacy focused wallets using it for this reason
  2. There is no way to derive an address from a P2PK script, which makes it more difficult to work with these outputs generally (outside of the context of this proposal)

I would like to request if version 4 could support receiving to P2WPKH only. This way, P2PKH wallets can use version 1 or 2, and P2WPKH wallets can use version 4. I think this would see a much higher chance of adoption given the significantly simpler implementation requirements, and avoidance of the privacy issue above.

(Actually, I'd like to see version 3 support P2SH-P2WPKH (wrapped segwit) only, and version 4 P2WPKH only, to cover all common single sig script types, but I'd gladly take the above as a compromise).

justusranvier commented 3 years ago

Let's move this conversation to the PR thread so the discussion ends with something actionable:

https://github.com/OpenBitcoinPrivacyProject/rfc/pull/7