payjoin / rust-payjoin

Supercharged payment batching to save you fees and preserve your privacy
https://payjoindevkit.org
86 stars 37 forks source link

Stabilize URI encoding for payjoin params pj subdirectory and ohttp #231

Closed DanGould closed 6 months ago

DanGould commented 7 months ago

Both the session public key and ohttp Key Configuration are included in the payjoin version 2 bitcoin URI. An early version of this protocol used base64url encoding since that's a dense binary to text encoding that's already available in rust-bitcoin.

Bitcoin URIs are often QR encoded, and base64Url breaks QR Alphanumeric Encoding and leads to QR codes with a much higher density that are more difficult to scan. Some other options have been proposed.

UR Encoding

UR Encoding was suggested since it encodes tagged fields and includes a checksum without breaking QR alphanumeric encoding. However, the payjoin subdirectory has no tagged fields since it's just a single key, and the OHTTP KeyConfig already has tagged fields in its binary encoding.

bytewords

Bytewords is basically UR minus the tagged fields. However it's less dense than some of the following suggestions. Setting aside the checksum, it is as dense as base16 or hexadecimal encoding.

Bech32m

Bech32 includes a human readable prefix and a checksum over a base32 encoding scheme. It's relatively dense and the checksum and prefix help it not be mistaken for other data. This encoding is used for segwit address types. Bech32m is a later version used for segwit v1+ addresses that fixed an issue with checksum malleability.

base45

Base45 RFC 9285 is the character set used for QR Alphanumeric Encoding, so that's about as dense as is appropriate for this application but does not include a checksum. The checksum is critical for the address where funds end up but less critical for public key exchange to facilitate secure transport. This might be the way to go, but it adds a dependency.

DanGould commented 6 months ago

URIs can't make much use of QR Alphanumeric Encoding because they already use the '?' and '=' characters which are outside of the character set. For this reason I continue to believe base64Url is the most appropriate encoding for subdirectory and ohttp keys in a BIP21 URI.