[BIP proposal] Private Payments

[BIP proposal] Private Payments
2022-06-27 20:20 ` Bryan Bishop
                   ` (3 more replies)
  
From: Alfred Hodler @ 2022-06-27 18:17 UTC (permalink / raw)
  To: bitcoin-dev

Hi,

There have been attempts to create static payment codes that function as a way for transacting parties to create "private" addresses, where private stands for "known only to transacting parties". BIP47 was one such standard.

The standard suffered from a number of problems:

1. The standard promised extensibility through versioning but it never used that capability to follow innovations in the Bitcoin protocol. It was designed around the idea that legacy p2pkh addresses would always be the primary and only way to transact. As new standard script types started to emerge (Segwit v0, Taproot), the creators dealt with the problem by stating that implementing wallets should scan for all existing standard scripts. The inability of payment codes to explicitly state which address types they derive places a burden on more resource constrained wallets.

2. The standard relied on a notification mechanism in order to connect a sender with a recipient, which included either offchain technology (Bitmessage), or so called "notification addresses" which a) left a footprint b) created toxic change. That type of footprint is particularly harmful because it makes it obvious that a particular recipient is going to receive private transactions. If the notifying party performs this process with coins linked to its identity (i.e. tainted or non-anonymized inputs), it forever becomes visible that Alice connected with Bob despite the fact that her payment code was blinded. While future transactions and their amounts aren't visible, this metadata makes it possible to build a social graph.

3. The standard was implemented only by an entity that disavowed the BIP process and didn't wish to use it to keep the standard up to date. Further updates did take place but only outside the BIP process, creating a lack of clarity as to what the real specification is. Ultimately the standard was abandoned.

I propose to build on the idea of payment codes under a new BIP with the following principal differences:

1. The new standard will allocate a 2-byte bitflag array that will signal address/script types that the receiver is deriving. Since the vast majority of scripts are p2pkh (47.3%) and p2wpkh (26.2%), bits 0 and 1 will be used for those respectively. Bit 2 will be p2tr. The remaining 13 bits are reserved for future standard script types.

2. Notification transactions still exist but no longer leave a privacy footprint on the blockchain. Instead, a notification transaction is simply a single OP_RETURN containing a value that only Alice and Bob can calculate. If Alice's notification transaction uses UTXOs not associated with her identity, there is never a footprint showing that either her or Bob are using private payments. If Alice uses tainted coins, only she is exposed as a user of Private Payments but Bob still isn't.

3. Payment code versioning is no longer done because it creates the potential for fragmentation and disparate standard updates by different parties that don't follow the BIP process (BIP47 is a good example of that).

4. Relying on static compressed pubkeys as opposed to extended keys means shorter payment codes.

==Proposed Payment Code Structure==

bytes 0-1: - enabled (watched) address types (16 possible address types)
bytes 2-35: - compressed public key P

==Encoding==

A payment code is encoded in base58check and the version byte produces "S" for the first character. A code might look like "SwLUHs3UfMUXq956aXLTUPPfow7a8gDfSUUAtafwqHcobf6mKcMbJk".

==Pubkey Derivation==

Recipient's payment code pubkey `P` is derived from a master key using the following path: `m/purpose'/coin_type'/account'`. `purpose` will be defined once a BIP number is assigned. Its corresponding private key is `p`.

Notifier/sender's pubkey `N` is derived using the following derivation path: `m/purpose'/coin_type'/account'/*`, where each recipient gets a new index. This way send-side privacy is always preserved. Its corresponding private key is `n`.

==Notifications==

Alice wants to notify Bob that he will receive future payments from her. Alice selects any UTXO in her wallet (preferably not associated with her) and `n_Alice`. Alice selects the public key contained in Bob's payment code `P_Bob`. Alice performs the following process (`*` and `+` are EC operations):

notification = SHA256(n_Alice * P_Bob)

Alice then constructs a 72-byte OP_RETURN output whose value is set to `BIPXXXX + notification + N_Alice` (`+` is concat) and sends it in a transaction containing no other outputs (XXXX to be replaced once a BIP number is assigned). Alice MUST now keep track of `n_Alice` or its derivation path as it will be used in future transactions exclusively with Bob (not for spending but to calculate secret addresses).

Bob's wallet receives whole blocks but doesn't need to waste resources on decoding them if the environment is resource constrained. Bob simply needs find the string BIPXXXX in the binary blob that represents an undecoded block. Once found, Bob extracts the subsequent 32 bytes (`notification`) and the subsequent 33 bytes (`N_Alice`). The benefit of this approach is that Bob doesn't have to decode blocks and extract pubkeys from scriptsigs.

Since ECDH dictates that SHA256(n_Alice * P_Bob) == SHA256(N_Alice * p_Bob), Bob calculates the expected notification value and checks if it matches the first value in the payload. If so, Bob found a notification transaction addressed to himself and stores `N_Alice` in order to be able to detect and spend future payments from Alice. The added benefit of this approach over BIP47 is that Bob doesn't learn Alice's payment code, so Alice can pay Bob without revealing her identity. To take advantage of these privacy benefits, Alice simply has to engage in coin control on her end. A real world scenario where this might be useful is anonymous donations to a party whose wallet may be seized in the future. Seizing such a wallet won't reveal who Alice is (as long as she engages in coin control), whereas BIP47 would by default leak her identity even if her coins as anonymized.

If this process fails for any reason, Bob assumes a spurious notification or one not addressed to himself and gives up.

==Transacting==

Now that they are connected, Alice can send transactions to Bob. Alice needs to keep track of her transaction count toward Bob; let's name that counter `X`. This process is similar to what BIP47 does.

Alice calculates a secret point:

S = n_Alice * P_Bob

Alice calculates a shared secret:

s = SHA256(S, X)

Alice calculates Bob's ephemeral public key and its associated address where the funds will be sent:

P_Bob' = P_Bob + s*G

When Bob detects a payment to `P_Bob'`, he can spend such coins by calculating the shared secret `s` in the same manner using `N_Alice` and `p_Bob` and performing:

p_bob' = p_bob + s

The fact that Alice and Bob are using a shared counter means we can do away with chain codes and make payment codes much smaller. Bob simply needs to derive a number of addresses to watch with respect to some gap limit (which can be as low as 1 in practice).

==Anti-spam==

While DoS hasn't been a problem with BIP47, it is possible to build anti-spam measures into payment codes. The owner of a code could simply demand that a notification transaction meets some minimum miner fee or a multiple of some trailing average. This would help prevent spam notifications that might otherwise overwhelm a payment code with addresses to watch. But that is purely optional.

Looking forward to hearing thoughts and ideas.

Alfred



 permalink raw reply	[|nested]
2022-06-27 20:20 ` 
                   ` 
  
From: Alfred Hodler @ 2022-06-27 18:17 UTC (permalink / raw)
  To: bitcoin-dev

Hi,

There have been attempts to create static payment codes that function as a way for transacting parties to create "private" addresses, where private stands for "known only to transacting parties". BIP47 was one such standard.

The standard suffered from a number of problems:

1. The standard promised extensibility through versioning but it never used that capability to follow innovations in the Bitcoin protocol. It was designed around the idea that legacy p2pkh addresses would always be the primary and only way to transact. As new standard script types started to emerge (Segwit v0, Taproot), the creators dealt with the problem by stating that implementing wallets should scan for all existing standard scripts. The inability of payment codes to explicitly state which address types they derive places a burden on more resource constrained wallets.

2. The standard relied on a notification mechanism in order to connect a sender with a recipient, which included either offchain technology (Bitmessage), or so called "notification addresses" which a) left a footprint b) created toxic change. That type of footprint is particularly harmful because it makes it obvious that a particular recipient is going to receive private transactions. If the notifying party performs this process with coins linked to its identity (i.e. tainted or non-anonymized inputs), it forever becomes visible that Alice connected with Bob despite the fact that her payment code was blinded. While future transactions and their amounts aren't visible, this metadata makes it possible to build a social graph.

3. The standard was implemented only by an entity that disavowed the BIP process and didn't wish to use it to keep the standard up to date. Further updates did take place but only outside the BIP process, creating a lack of clarity as to what the real specification is. Ultimately the standard was abandoned.

I propose to build on the idea of payment codes under a new BIP with the following principal differences:

1. The new standard will allocate a 2-byte bitflag array that will signal address/script types that the receiver is deriving. Since the vast majority of scripts are p2pkh (47.3%) and p2wpkh (26.2%), bits 0 and 1 will be used for those respectively. Bit 2 will be p2tr. The remaining 13 bits are reserved for future standard script types.

2. Notification transactions still exist but no longer leave a privacy footprint on the blockchain. Instead, a notification transaction is simply a single OP_RETURN containing a value that only Alice and Bob can calculate. If Alice's notification transaction uses UTXOs not associated with her identity, there is never a footprint showing that either her or Bob are using private payments. If Alice uses tainted coins, only she is exposed as a user of Private Payments but Bob still isn't.

3. Payment code versioning is no longer done because it creates the potential for fragmentation and disparate standard updates by different parties that don't follow the BIP process (BIP47 is a good example of that).

4. Relying on static compressed pubkeys as opposed to extended keys means shorter payment codes.

==Proposed Payment Code Structure==

bytes 0-1: - enabled (watched) address types (16 possible address types)
bytes 2-35: - compressed public key P

==Encoding==

A payment code is encoded in base58check and the version byte produces "S" for the first character. A code might look like "SwLUHs3UfMUXq956aXLTUPPfow7a8gDfSUUAtafwqHcobf6mKcMbJk".

==Pubkey Derivation==

Recipient's payment code pubkey `P` is derived from a master key using the following path: `m/purpose'/coin_type'/account'`. `purpose` will be defined once a BIP number is assigned. Its corresponding private key is `p`.

Notifier/sender's pubkey `N` is derived using the following derivation path: `m/purpose'/coin_type'/account'/*`, where each recipient gets a new index. This way send-side privacy is always preserved. Its corresponding private key is `n`.

==Notifications==

Alice wants to notify Bob that he will receive future payments from her. Alice selects any UTXO in her wallet (preferably not associated with her) and `n_Alice`. Alice selects the public key contained in Bob's payment code `P_Bob`. Alice performs the following process (`*` and `+` are EC operations):

notification = SHA256(n_Alice * P_Bob)

Alice then constructs a 72-byte OP_RETURN output whose value is set to `BIPXXXX + notification + N_Alice` (`+` is concat) and sends it in a transaction containing no other outputs (XXXX to be replaced once a BIP number is assigned). Alice MUST now keep track of `n_Alice` or its derivation path as it will be used in future transactions exclusively with Bob (not for spending but to calculate secret addresses).

Bob's wallet receives whole blocks but doesn't need to waste resources on decoding them if the environment is resource constrained. Bob simply needs find the string BIPXXXX in the binary blob that represents an undecoded block. Once found, Bob extracts the subsequent 32 bytes (`notification`) and the subsequent 33 bytes (`N_Alice`). The benefit of this approach is that Bob doesn't have to decode blocks and extract pubkeys from scriptsigs.

Since ECDH dictates that SHA256(n_Alice * P_Bob) == SHA256(N_Alice * p_Bob), Bob calculates the expected notification value and checks if it matches the first value in the payload. If so, Bob found a notification transaction addressed to himself and stores `N_Alice` in order to be able to detect and spend future payments from Alice. The added benefit of this approach over BIP47 is that Bob doesn't learn Alice's payment code, so Alice can pay Bob without revealing her identity. To take advantage of these privacy benefits, Alice simply has to engage in coin control on her end. A real world scenario where this might be useful is anonymous donations to a party whose wallet may be seized in the future. Seizing such a wallet won't reveal who Alice is (as long as she engages in coin control), whereas BIP47 would by default leak her identity even if her coins as anonymized.

If this process fails for any reason, Bob assumes a spurious notification or one not addressed to himself and gives up.

==Transacting==

Now that they are connected, Alice can send transactions to Bob. Alice needs to keep track of her transaction count toward Bob; let's name that counter `X`. This process is similar to what BIP47 does.

Alice calculates a secret point:

S = n_Alice * P_Bob

Alice calculates a shared secret:

s = SHA256(S, X)

Alice calculates Bob's ephemeral public key and its associated address where the funds will be sent:

P_Bob' = P_Bob + s*G

When Bob detects a payment to `P_Bob'`, he can spend such coins by calculating the shared secret `s` in the same manner using `N_Alice` and `p_Bob` and performing:

p_bob' = p_bob + s

The fact that Alice and Bob are using a shared counter means we can do away with chain codes and make payment codes much smaller. Bob simply needs to derive a number of addresses to watch with respect to some gap limit (which can be as low as 1 in practice).

==Anti-spam==

While DoS hasn't been a problem with BIP47, it is possible to build anti-spam measures into payment codes. The owner of a code could simply demand that a notification transaction meets some minimum miner fee or a multiple of some trailing average. This would help prevent spam notifications that might otherwise overwhelm a payment code with addresses to watch. But that is purely optional.

Looking forward to hearing thoughts and ideas.

Alfred



 permalink raw reply	[|nested]
* 
  2022-06-27 18:17 [bitcoin-dev] [BIP proposal] Private Payments Alfred Hodler

  2022-06-27 20:35   ` Ruben Somsen
  2022-06-28 12:40   ` Alfred Hodler
  2022-06-27 20:30 ` 
                   ` 
  3 siblings, 2 replies; 12+ messages in thread
From: Bryan Bishop @ 2022-06-27 20:20 UTC (permalink / raw)
  To: Alfred Hodler, Bitcoin Protocol Discussion, Bryan Bishop

[-- Attachment #1: Type: text/plain, Size: 873 bytes --]

Hi,

On Mon, Jun 27, 2022 at 2:14 PM Alfred Hodler via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> 2. Notification transactions still exist but no longer leave a privacy
> footprint on the blockchain. Instead, a notification transaction is simply
> a single OP_RETURN containing a value that only Alice and Bob can
> calculate. If Alice's notification transaction uses UTXOs not associated
> with her identity, there is never a footprint showing that either her or
> Bob are using private payments. If Alice uses tainted coins, only she is
> exposed as a user of Private Payments but Bob still isn't.
>

That's a neat trick. What about not using OP_RETURN at all, and just
publishing on a tor hidden service that other wallets check?  Alice
wouldn't have to expose on-chain that she is a sender of a private payment.

- Bryan
https://twitter.com/kanzure

[-- Attachment #2: Type: text/html, Size: 1347 bytes --]

^ permalink raw reply	[|nested] 12+ messages in thread
2022-06-27 20:20 ` Bryan Bishop

  2022-06-28 12:40   ` Alfred Hodler
  
From: Ruben Somsen @ 2022-06-27 20:35 UTC (permalink / raw)
  To: Bryan Bishop, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 1464 bytes --]

Hi Bryan,

>just publishing on a tor hidden service that other wallets check

The problem is that this data is critical to access the funds. By putting
it on-chain you're guaranteeing that it's always available when you restore
your funds from backup.

Cheers,
Ruben

On Mon, Jun 27, 2022 at 10:21 PM Bryan Bishop via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> Hi,
>
> On Mon, Jun 27, 2022 at 2:14 PM Alfred Hodler via bitcoin-dev <
> bitcoin-dev@lists•linuxfoundation.org> wrote:
>
>> 2. Notification transactions still exist but no longer leave a privacy
>> footprint on the blockchain. Instead, a notification transaction is simply
>> a single OP_RETURN containing a value that only Alice and Bob can
>> calculate. If Alice's notification transaction uses UTXOs not associated
>> with her identity, there is never a footprint showing that either her or
>> Bob are using private payments. If Alice uses tainted coins, only she is
>> exposed as a user of Private Payments but Bob still isn't.
>>
>
> That's a neat trick. What about not using OP_RETURN at all, and just
> publishing on a tor hidden service that other wallets check?  Alice
> wouldn't have to expose on-chain that she is a sender of a private payment.
>
> - Bryan
> https://twitter.com/kanzure
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>

[-- Attachment #2: Type: text/html, Size: 2488 bytes --]

 permalink raw reply	[|nested]
2022-06-27 20:30 ` Ruben Somsen

       [not found]     ` <PS2P216MB10894F1EE83AFA648003C6339DBF9@PS2P216MB1089.KORP216.PROD.OUTLOOK.COM>
  2022-06-28 23:33   ` Peter Todd
  
From: Alfred Hodler @ 2022-06-28 12:35 UTC (permalink / raw)
  To: Ruben Somsen;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 2415 bytes --]

Hi Ruben,

Good to see your input here.

>I agree it's not as efficient as it could be, but how big is this problem in practice? Expecting payments on more addresses doesn't seem like a huge overhead. Or are you talking about the hassle of having to support spending from all these address types?

My worry is that once the number of standard scripts becomes significant, wallets will have to watch all of them. This could create a performance hit eventually, though I don't know what that would be in practice. Maybe someone else can offer more insight. It's possible to mitigate that using a tighter gap limit. But we still have the problem of wallets not supporting certain scripts. For example, Bob's wallet may not support wrapped segwit but Alice could accidentally send funds there assuming Bob can spend them.

SP proposes to use Taproot-only (as we've been discussing elsewhere), but I still don't think it's the right solution to lock down the BIP to a single script type, for the sake of future proofing if nothing else. Having address type flags solves these issues at the expense having a couple of extra bytes.

>but it does make it rather difficult to support light clients.

That's correct. This can't take advantage of compact block filters. Doing so would require having a notification address again. The scanning scheme is lighter and a bit simpler to implement than the one proposed by SP but it still presumes a full node.

>The basic idea is that everyone publishes a single pubkey on-chain,

It even seems to me that Bob doesn't even have to publish his key on-chain unless he intends on sending funds. Only senders would have to do so, and pure recipients (if there would be any such entities) would just have to publish their codes off-chain (e.g. website donation address). The downside is that Alice now has to publish her pubkey on-chain, which creates a footprint. She's now a confirmed user of stealth addresses. She can mitigate that by publishing an ephemeral pubkey for each recipient, but this might spiral out of control fast if the standard gains wider acceptance.

>Note that this mechanism is not safe against miners, as they can pay themselves arbitrarily high fees with no downside.

Good point. Perhaps the solution is to require an OP_RETURN burn instead. I thought it's better to benefit the ecosystem by sending coins back to miners, but burning is also possible.

Alfred

[-- Attachment #2: Type: text/html, Size: 3455 bytes --]

 permalink raw reply	[|nested]
2022-06-27 20:20 ` Bryan Bishop
  2022-06-27 20:35   ` Ruben Somsen

  
From: Alfred Hodler @ 2022-06-28 12:40 UTC (permalink / raw)
  To: Bryan Bishop;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 463 bytes --]

Hi Bryan,

Thanks for your input.

>That's a neat trick. What about not using OP_RETURN at all, and just publishing on a tor hidden service that other wallets check? Alice wouldn't have to expose on-chain that she is a sender of a private payment.

This can be done (Tor keys can even be derived from master keys) but it's an off-chain solution, not very different from Bitmessage notifications in BIP47. As Ruben said, it won't work in an offline regime.

Alfred

[-- Attachment #2: Type: text/html, Size: 1264 bytes --]

 permalink raw reply	[|nested]
2022-06-27 20:30 ` Ruben Somsen
  2022-06-28 12:35   ` Alfred Hodler

  
From: Peter Todd @ 2022-06-28 23:33 UTC (permalink / raw)
  To: Ruben Somsen, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 497 bytes --]

On Mon, Jun 27, 2022 at 10:30:39PM +0200, Ruben Somsen via bitcoin-dev wrote:
> >demand that a notification transaction meets some minimum miner fee
> 
> Note that this mechanism is not safe against miners, as they can pay
> themselves arbitrarily high fees with no downside.

Block space is relatively expensive, so maybe it's enough that the spammer has
to publish at all.

You could also do a timelocked sacrifice with OP_CSV.

-- 
https://petertodd.org 'peter'[:-1]@petertodd.org

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

 permalink raw reply	[|nested]
2022-06-27 18:17 [bitcoin-dev] [BIP proposal] Private Payments Alfred Hodler
  2022-06-27 20:20 ` Bryan Bishop
  2022-06-27 20:30 ` Ruben Somsen

  2022-07-01 12:41   ` Alfred Hodler
  2022-07-11 10:28 ` Alfred Hodler
  
From: Clark Moody @ 2022-06-29 22:33 UTC (permalink / raw)
  To: Bitcoin Protocol Discussion

Alfred,

Thanks for the proposal. This is really interesting, especially the
additional on-chain privacy improvements over BIP47: ephemeral
notifier/sender keys and shielding of the sender key(s) against
seizure of the recipient's wallet.

> A payment code is encoded in base58check and the version byte produces "S" for the first character.

This is a bit under-specified, but let me bike-shed here and suggest
going with a Bech32m encoding. We gain more compact QR codes as well
as error detection/correction.

Alternate proposal:

- Bech32m human-readable part = "pay"
- Data payload is [watched address type bytes (2), compressed pubkey (33)]

Example:

- Address type bytes = c000
- Pubkey 03b54543fbed9d17d9300b508c55769bc4c8385620626730b4d52e5f3e30d9a6c1
- Published payment code:
pay1cqqq8d29g0a7m8ghmycqk5yv24mfh3xg8ptzqcn8xz6d2tjl8ccdnfkpjl7p84

> The owner of a code could simply demand that a notification transaction meets some minimum miner fee or a multiple of some trailing average.

I don't see how this would work, and others have pointed out that the
cost of block space is itself an anti-spam measure.

== Notification Service Idea ==

A third-party service could offer to publish OP_RETURN notification
payloads in the blockchain for a fee, paid over Lightning Network.
This completely de-links Alice's notification from her wallet, while
accepting the less-known privacy implications of a Lightning payment.
The service would remain ignorant of Bob's identity in any event. Such
a service would also be incentivized to charge market rates for the
potential privacy boost and for block space.

== Data Service Idea ==

Another service could publish only the OP_RETURN data pertaining to
this BIP, which is easy to obtain due to the clear tagging scheme.
Light wallets would check in with this service on a regular basis,
performing the ECDH filtering steps on each output. Upon further
request, the service furnishes transaction proofs for the full
transaction containing the OP_RETURN. Care would need to be taken to
avoid leaking too much information to the service, and techniques such
as using separate Tor circuits or requesting tx proofs on a bulk set
of transactions could help obfuscate the exact transaction of
interest. These concerns are similar to those found in BIP157
client-side block filtering (Neutrino filters).

Alternatively, the service publishes the block height along with the
notification data contained within that block. Light clients could
download relevant blocks over the p2p network and perform full
validation.


-Clark

On Mon, Jun 27, 2022 at 2:14 PM Alfred Hodler via bitcoin-dev
<bitcoin-dev@lists•linuxfoundation.org> wrote:
>
> Hi,
>
> There have been attempts to create static payment codes that function as a way for transacting parties to create "private" addresses, where private stands for "known only to transacting parties". BIP47 was one such standard.
>
> The standard suffered from a number of problems:
>
> 1. The standard promised extensibility through versioning but it never used that capability to follow innovations in the Bitcoin protocol. It was designed around the idea that legacy p2pkh addresses would always be the primary and only way to transact. As new standard script types started to emerge (Segwit v0, Taproot), the creators dealt with the problem by stating that implementing wallets should scan for all existing standard scripts. The inability of payment codes to explicitly state which address types they derive places a burden on more resource constrained wallets.
>
> 2. The standard relied on a notification mechanism in order to connect a sender with a recipient, which included either offchain technology (Bitmessage), or so called "notification addresses" which a) left a footprint b) created toxic change. That type of footprint is particularly harmful because it makes it obvious that a particular recipient is going to receive private transactions. If the notifying party performs this process with coins linked to its identity (i.e. tainted or non-anonymized inputs), it forever becomes visible that Alice connected with Bob despite the fact that her payment code was blinded. While future transactions and their amounts aren't visible, this metadata makes it possible to build a social graph.
>
> 3. The standard was implemented only by an entity that disavowed the BIP process and didn't wish to use it to keep the standard up to date. Further updates did take place but only outside the BIP process, creating a lack of clarity as to what the real specification is. Ultimately the standard was abandoned.
>
> I propose to build on the idea of payment codes under a new BIP with the following principal differences:
>
> 1. The new standard will allocate a 2-byte bitflag array that will signal address/script types that the receiver is deriving. Since the vast majority of scripts are p2pkh (47.3%) and p2wpkh (26.2%), bits 0 and 1 will be used for those respectively. Bit 2 will be p2tr. The remaining 13 bits are reserved for future standard script types.
>
> 2. Notification transactions still exist but no longer leave a privacy footprint on the blockchain. Instead, a notification transaction is simply a single OP_RETURN containing a value that only Alice and Bob can calculate. If Alice's notification transaction uses UTXOs not associated with her identity, there is never a footprint showing that either her or Bob are using private payments. If Alice uses tainted coins, only she is exposed as a user of Private Payments but Bob still isn't.
>
> 3. Payment code versioning is no longer done because it creates the potential for fragmentation and disparate standard updates by different parties that don't follow the BIP process (BIP47 is a good example of that).
>
> 4. Relying on static compressed pubkeys as opposed to extended keys means shorter payment codes.
>
> ==Proposed Payment Code Structure==
>
> bytes 0-1: - enabled (watched) address types (16 possible address types)
> bytes 2-35: - compressed public key P
>
> ==Encoding==
>
> A payment code is encoded in base58check and the version byte produces "S" for the first character. A code might look like "SwLUHs3UfMUXq956aXLTUPPfow7a8gDfSUUAtafwqHcobf6mKcMbJk".
>
> ==Pubkey Derivation==
>
> Recipient's payment code pubkey `P` is derived from a master key using the following path: `m/purpose'/coin_type'/account'`. `purpose` will be defined once a BIP number is assigned. Its corresponding private key is `p`.
>
> Notifier/sender's pubkey `N` is derived using the following derivation path: `m/purpose'/coin_type'/account'/*`, where each recipient gets a new index. This way send-side privacy is always preserved. Its corresponding private key is `n`.
>
> ==Notifications==
>
> Alice wants to notify Bob that he will receive future payments from her. Alice selects any UTXO in her wallet (preferably not associated with her) and `n_Alice`. Alice selects the public key contained in Bob's payment code `P_Bob`. Alice performs the following process (`*` and `+` are EC operations):
>
> notification = SHA256(n_Alice * P_Bob)
>
> Alice then constructs a 72-byte OP_RETURN output whose value is set to `BIPXXXX + notification + N_Alice` (`+` is concat) and sends it in a transaction containing no other outputs (XXXX to be replaced once a BIP number is assigned). Alice MUST now keep track of `n_Alice` or its derivation path as it will be used in future transactions exclusively with Bob (not for spending but to calculate secret addresses).
>
> Bob's wallet receives whole blocks but doesn't need to waste resources on decoding them if the environment is resource constrained. Bob simply needs find the string BIPXXXX in the binary blob that represents an undecoded block. Once found, Bob extracts the subsequent 32 bytes (`notification`) and the subsequent 33 bytes (`N_Alice`). The benefit of this approach is that Bob doesn't have to decode blocks and extract pubkeys from scriptsigs.
>
> Since ECDH dictates that SHA256(n_Alice * P_Bob) == SHA256(N_Alice * p_Bob), Bob calculates the expected notification value and checks if it matches the first value in the payload. If so, Bob found a notification transaction addressed to himself and stores `N_Alice` in order to be able to detect and spend future payments from Alice. The added benefit of this approach over BIP47 is that Bob doesn't learn Alice's payment code, so Alice can pay Bob without revealing her identity. To take advantage of these privacy benefits, Alice simply has to engage in coin control on her end. A real world scenario where this might be useful is anonymous donations to a party whose wallet may be seized in the future. Seizing such a wallet won't reveal who Alice is (as long as she engages in coin control), whereas BIP47 would by default leak her identity even if her coins as anonymized.
>
> If this process fails for any reason, Bob assumes a spurious notification or one not addressed to himself and gives up.
>
> ==Transacting==
>
> Now that they are connected, Alice can send transactions to Bob. Alice needs to keep track of her transaction count toward Bob; let's name that counter `X`. This process is similar to what BIP47 does.
>
> Alice calculates a secret point:
>
> S = n_Alice * P_Bob
>
> Alice calculates a shared secret:
>
> s = SHA256(S, X)
>
> Alice calculates Bob's ephemeral public key and its associated address where the funds will be sent:
>
> P_Bob' = P_Bob + s*G
>
> When Bob detects a payment to `P_Bob'`, he can spend such coins by calculating the shared secret `s` in the same manner using `N_Alice` and `p_Bob` and performing:
>
> p_bob' = p_bob + s
>
> The fact that Alice and Bob are using a shared counter means we can do away with chain codes and make payment codes much smaller. Bob simply needs to derive a number of addresses to watch with respect to some gap limit (which can be as low as 1 in practice).
>
> ==Anti-spam==
>
> While DoS hasn't been a problem with BIP47, it is possible to build anti-spam measures into payment codes. The owner of a code could simply demand that a notification transaction meets some minimum miner fee or a multiple of some trailing average. This would help prevent spam notifications that might otherwise overwhelm a payment code with addresses to watch. But that is purely optional.
>
> Looking forward to hearing thoughts and ideas.
>
> Alfred
>
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev


 permalink raw reply	[|nested]
2022-06-29 22:33 ` Clark Moody

  2022-07-01 17:37     ` Christopher Allen
  
From: Alfred Hodler @ 2022-07-01 12:41 UTC (permalink / raw)
  To: Bitcoin Protocol Discussion

Hi Clark,

Thanks for your input.

I agree with your proposal to use bech32 instead of base58. It looks sound to me and as you said, the standard would benefit from more compact QR codes. The `pay1` prefix is fairly recognizable.

> I don't see how this would work, and others have pointed out that the
> cost of block space is itself an anti-spam measure.

I agree.

> A third-party service could offer to publish OP_RETURN notification
> payloads in the blockchain for a fee, paid over Lightning Network.
> This completely de-links Alice's notification from her wallet, while
> accepting the less-known privacy implications of a Lightning payment.
> The service would remain ignorant of Bob's identity in any event. Such
> a service would also be incentivized to charge market rates for the
> potential privacy boost and for block space.

The manner of publishing or outsourcing notifications cannot be enforced by the standard but we can add this as a recommendation. We can also release such a service in tandem with the BIP in order to encourage its use. The fact that the service would use its own coins would be beneficial to notifiers since they wouldn't have to engage in coin control on their end.

I'm not too familiar with the innerworkings of Lightning, but it is my understanding that a message can be embedded in each payment. The message in this case can be the OP_RETURN payload. That way both the payment and the notification payload are sent out in one go. Please correct me if I'm wrong.

The downside is that this isn't as censorship resistant as direct notifications but that's probably not going to be a big problem in reality. If these services ever go down, users should still be able to notify from their own wallets.

> Alternatively, the service publishes the block height along with the
> notification data contained within that block. Light clients could
> download relevant blocks over the p2p network and perform full
> validation.

This sounds better than requesting transaction data, both from the standpoint of simplicity and privacy. The danger is that the service drops notifications, either on purpose or by accident, eventually causing clients to miss notifications. Two possible solutions: a) the service publishes Merkle Trees b) each client subscribes to more than one service.

Alfred



 permalink raw reply	[|nested]
2022-07-01 12:41   ` Alfred Hodler

  
From: Christopher Allen @ 2022-07-01 17:37 UTC (permalink / raw)
  To: Alfred Hodler, Bitcoin Protocol Discussion;  Wolf McNally

[-- Attachment #1: Type: text/plain, Size: 2132 bytes --]

On Fri, Jul 1, 2022 at 5:43 AM Alfred Hodler via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> I agree with your proposal to use bech32 instead of base58. It looks sound
> to me and as you said, the standard would benefit from more compact QR
> codes.


The most important thing to get more compact QR codes is to not use
lowercase letters, and certain other characters, as if you can avoid them
the QRs will auto-compress.

It happens that the core of bech32 works if all caps, and you are careful
with the human readable portion.

See
https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-003-uri-binary-compatibility.md
for more details, but a big offender is base64 which not only doesn’t
auto-compress but also can trigger binary mode that almost doubled the size
of the QR.

We have a number of standards & libraries focused on bitcoin QRs, including
support of animated QRs for things like PSBTs, but if you care about QR
size you should take a look at the techniques we use our swift library
https://github.com/BlockchainCommons/QRCodeGenerator which are also in
https://www.nayuki.io/page/qr-code-generator-library.

Basically both of these libraries support “optimal encoding using segments”
that if they encounter a set of characters that must be encoded in binary
(In particularly $ % * + / :) that would in most default platform QR
implementations  cause the entire QR to double in size. Instead will only
encode the small segment as binary, letting the rest of the QR leverage
auto-compression.

If your are interested in our other Airgap QR and TorGap UR efforts, see
our video from last year:
https://youtu.be/RYgOFSdUqWY We have much more on the way, including NFC
encrypted Airgap & crypto-request/response flows.

I’d love to see proposals for various payment and invoice QRs that leverage
these wallet interoperability standards we have been offering. Let us know
if you are interested, or join discussions at
https://github.com/BlockchainCommons/Airgapped-Wallet-Community

— Christopher Allen, Blockchain Commons

>

[-- Attachment #2: Type: text/html, Size: 3442 bytes --]

 permalink raw reply	[|nested]
[not found]     ` <PS2P216MB10894F1EE83AFA648003C6339DBF9@PS2P216MB1089.KORP216.PROD.OUTLOOK.COM>

  
From: Alfred Hodler @ 2022-07-05  9:38 UTC (permalink / raw)
  To: KING JAMES HRMH;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 1208 bytes --]

Hi Damian,

Which specific part of the proposal do you think affects the legibility of the blockchain and the fungibility of UTXOs? Please point out the relevant section so that we can address your concerns.
Alfred

------- Original Message -------
On Sunday, July 3rd, 2022 at 3:17 PM, KING JAMES HRMH <willtech@live•com.au> wrote:

> Good Afternoon,
>
> In regard to Private Payments, the blockchain is indelible record and it isn't a record unless it is legible so that someone could check the validity of any UTXO and it is enough that Bitcoin is Fungible and the only reason Bitcoin is Fungible is because it is a wallet that makes use of the Blockchain so the concept is
> NACK
>
> KING JAMES HRMH
> Great British Empire
>
> Regards,
> The Australian
> LORD HIS EXCELLENCY JAMES HRMH (& HMRH)
> of Hougun Manor & Glencoe & British Empire
> MR. Damian A. James Williamson
> Professor
> Wills
>
> et al.
>
> Willtech
> www.willtech.com.au
> www.go-overt.com
> duigco.org DUIGCO API
> and other projects
>
> m. 0487135719
> f. +61261470192
>
> This email does not constitute a general advice. Please disregard this email if misdelivered.
>
> ---------------------------------------------------------------

[-- Attachment #2: Type: text/html, Size: 2981 bytes --]

 permalink raw reply	[|nested]
2022-06-27 18:17 [bitcoin-dev] [BIP proposal] Private Payments Alfred Hodler
                   ` (2 preceding siblings ...)
  2022-06-29 22:33 ` Clark Moody

  
From: Alfred Hodler @ 2022-07-11 10:28 UTC (permalink / raw)
  To: bitcoin-dev

Update: Bob doesn't have to watch all address types he's advertising. When notifying Bob, Alice will pick one address type out of the ones Bob is advertising and include it in the notification. That way even if Bob's wallet accepts many address types, he still doesn't have to watch all of them for each Alice.

The previous spec reads:

> Alice then constructs a 72-byte OP_RETURN output whose value is set to `BIPXXXX + notification + N_Alice` (`+` is concat) and sends it in a transaction containing no other outputs (XXXX to be replaced once a BIP number is assigned).

We can extended the payload to 73 bytes and define it as: `BIPXXXX + notification + N_Alice + address_type`, where `address_type` is a single byte containing the desired address type index (1 out of 16, limited by Bob's payment code). If Alice ever wants to start sending to a different address type, she can simply re-notify Bob and Bob will switch to a new address type in the case of Alice.

Alfred



 permalink raw reply	[|nested]