7

If I understand correctly, every new payment will ideally have a different one-time public key for increased privacy. However, could a one-time public key receive Monero more than once (as in thousands of times)? What would be the drawbacks of doing this?.

I am thinking that using a one-time public key would be more convenient. Similar to using a public address in Bitcoin for many transactions related to one thing.

Thank you in advance!

David Lopez
  • 181
  • 4

3 Answers3

6

However, could a one-time public key receive Monero more than once (as in thousands of times)

Yes, but it is certainly not practical. There are basically two reasons as two why. First, sending Monero to the same one-time public key (stealth address) will be detrimental to unlinkability, i.e., it will create linkability between payments. In addition, sending to the same stealth address is basically similar to a stealth address collision. From Luigi1111's article:

The chance of a collision (two stealth addresses being the same) is cryptographically negligible. Using the Birthday Paradox we can roughly estimate it would take sqrt(l), or about 2^126, stealth addresses being created before having a 50% chance of a collision. The result would be that the colliding addresses become publicly linkable to each other, but not to any others.

Secondly, and this is even worse in my opinion, sending to the same stealth address will "burn" all outputs except one. More specifically, an output is accompanied by a key image (I = xHp(P)), where I = the key image, x = a private key, Hp = a hash to point function, and P = one-time public key. As you can see from aforementioned function, sending Monero to the same stealth address will result in multiple key images that are exactly the same. Note that the network will reject a key image if it's already present in the blockchain, because it will be seen as an attempt to double spend. Thus, you will only be able to spend from this stealth address once and the remainder of the outputs will be unspendable.

More practically speaking, let's say you sent 1 XMR twice to P1 and 2 XMR twice to P2. Subsequently, you create a transaction that combines P1 and P2 and broadcast it to the network. Now, if you want to create another transaction that again combines P1 and P2, it will be rejected by the network, because the key images are already present in the blockchain and it will be seen as a double spend attempt. Thus, effectively you burned 1+2 = 3 XMR by sending to the same stealth address.

Some more information:

What is a key image?

What are the "ingredients" of a key image?

Constructing a Stealth Monero Address?

dEBRUYNE
  • 15,417
  • 18
  • 60
  • 114
4

If I understand correctly, every new payment will ideally have a different one-time public key for increased privacy.

That's right. It's practically guaranteed due to the way one-time public keys are constructed. It's also important to note that it's the sender who makes those. I will recap how it works, although there are many good reads about it in other Q&As here.

  1. You give your wallet address to the sender. Note that it's comprised of 2 public keys A and B (a and b being their private counterparts).

  2. Your sender starts to construct a transaction, and first creates a TX "header" by choosing a random value r which he keeps to himself, and uses it to create a public TX key R = r*G, where * is EC multiplication. This key can be seen by anyone reading the blockchain. This is known as "sender's random data" which is a key ingredient in what happens after.

  3. Your sender makes as many one-time keys (P) as he likes, one even to himself - for the change. The ingredients for making an one-time key are: destination wallet address (your A and B), the private TX key r, and output index in the TX (i=0, 1 ... n). Use of r here practically guarantees that you won't see two Ps which are the same, because r is a 256-bit number so collision is improbable. Formally, if you're interested in technicalities: P=H_s(r*A||i)*G + B. This is EC, so first we make EC multiplication rA, then append the index i, then hash everything together and multiply with EC basepoint G. Finally, we add the B. Adding B makes sure only the recipient can spend the one-time key, so it's called a public spend key. Using rA makes sure only the recipient can recognize the output, and A is called a public view key. Both A and B are wallet-specific and are encoded in your address. Those are really just special instructions to the sender. See rather simplified mechanics of it here.

  4. The sender has to sign a TX. By signing, the sender will "burn" some of his one-time keys (by publishing and signing with the key images as well) on the input side of the TX which gives him the right to create new one-time keys of the same value on the output side. I will not go into details of the signing, although it's worth mentioning that the actual one-time key getting burned is hidden in the ring signature but it's guaranteed that the same one can't be burned twice - thanks to key images.

  5. Your wallet scans the blockchain. First it reads the R. Then, it uses it in attempt to reconstruct each of the Ps using your wallet's private keys a and b. Even though it doesn't know the r, it can construct a match by performing P'=H_s(a*R||i)*G + B. Familiar? Sender did P=H_s(r*A||i)*G + B. If they are the same, it's your public key! This works because aR = rA, and this piece of information is called a shared secret. Only you and the sender know this information, and the one-time key will look completely random to the rest of the world with no way of it being associated to your wallet! This is called ECDH, ie Elliptic Curve Diffie-Helmann key exchange. See here and here for more info.

However, could a one-time public key receive Monero more than once (as in thousands of times)? What would be the drawbacks of doing this?

Looking at the above, it could. Some sender would have to use same r, send to the same address and put the destination one-time key at the same index as before. This would result in 2 TX-es with the same R, and I'm not sure of the implications or whether the protocol guards against this. There's nothing fundamentally wrong with it, but doing this would effectively burn the funds because each one-time key can be spent only once, and here you have 2 of them but can spend only one.

I am thinking that using a one-time public key would be more convenient. Similar to using a public address in Bitcoin for many transactions related to one thing.

Your wallet address serves that purpose already. Unlike Bitcoin, your address is not where the money is. The address in Monero is just an instruction to the sender, who generates public keys for the recipient following that instruction but all the money resides on those public keys. Your balance is comprised of all individual public keys added together which you didn't spend already.

JollyMort
  • 20,004
  • 3
  • 49
  • 105
0

DH exchanged tx key (r). This needs to be unique. DH is not secure if you know two Rs were generated from the same r.

Fireice UK
  • 232
  • 1
  • 3