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!

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?

  • Thank you. So in order to achieve what I want, which is having an address to receive a lot of transactions and still be able to spend all those outputs, I would simply share my wallet's public address, right? Also, wouldn't a stealth address become a vulnerability if an attacker paid a higher fee so he could get his small transaction to the stealth address confirmed before the bigger transaction in order to burn the bigger transaction? Could this ever happen? – David Lopez May 4 '17 at 17:16
  • 2
    Sender makes a random brand new one-time public key each time he sends to some address. It "belongs" to the address but the address itself never appears on the blockchain! So what you seek is already achieved by normal use. Even if someone would purposefully craft a TX to send to some one-time key again (and there could be placed safeguards against this, if needed), it can hardly be used as an attack considering you could choose from which one to spend! If you had already spent, and someone later sent to the same one, it's effectively burned at the moment of sending. – JollyMort May 4 '17 at 19:14
  • Great, that resolves my doubts fully. – David Lopez May 6 '17 at 0:25
  • Doesn't this mean that any attacker can delete Monero on the network, just by reusing a stealth address? – rubdos Dec 1 '17 at 6:50
  • @rubdos It's not deleted, as in the total amount of XMR doesn't decrease, those XMRs entering an spent stealth address would simply become unspendable but still count towards the total amount of XMR in the network. Similar to burn addresses in Ethereum or Bitcoin – David Lopez Sep 21 at 21:49

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.

  • This makes a lot of sense. I understand one-time public keys and addresses in Monero now. Thank you! Do all cryptocurrencies based on cryptonote work this way? For instance, does Bytecoin's cryptonight work like this too? Or are these one-time public keys specific to Monero? Which other currencies operate this way? – David Lopez May 6 '17 at 0:34
  • Cool! Yeah, all CryptoNote currencies use this. See here for some additional details if you're interested. – JollyMort May 6 '17 at 10:27

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.

  • I believe he's referring to P's, ie P=H_s(rA||i)G + B, ie one-time keys aka outputs. Someone could craft another TX a same P as in some past TX, even if r is different, although I don't see a feasible way of doing that if we want A and B to be the same. If we just copy the P, then interesting thing is, that the wallet knows x for this P as well (based on past TX actually directed to it) and it could theoretically spend it in place of the older one, but it won't ever detect it by normal means because by def. it's testing P == (P' = H(aR||i)G + B) and it won't be matching due to different R. – JollyMort May 4 '17 at 19:21

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.