m2049r / xmrwallet

monerujo: An Android Monero Wallet
https://www.monerujo.io/
Apache License 2.0
617 stars 273 forks source link

On PocketChange; warnings, suggestions and improvements #907

Open dnaleor opened 1 year ago

dnaleor commented 1 year ago

In general, it's the best for privacy and fungibility to always have 2 outputs and a maximum of 2 inputs. That is a standard transaction. All other transactions stand out and can lead to clustering.


It seems that PocketChange isn't implemented in a privacy conscious way.

The main problem is that the software tries to fill every pocket on every transaction, which often results in an transaction with 3 outputs. This hurts privacy and enables clustering. This article from back in the day on the issues that XWallet had, is relevant: https://weuse.cash/2018/01/18/software-implementation-matters/

So please, at least only fill the pockets when there is only 1 pocket left, don't refill every time. That would already improve privacy a lot


Then, on the implementation, I would suggest to fully use the maximum amount of outputs, which is 16. This minimizes the amount of transactions with more than 2 outputs as the interval between these transactions with 16 outputs would be further apart


My 3rd suggestion is to use exponentially increasing pockets with powers of 2. So you'd usually only use a single pocket as an input. Using multiple pockets will probably lead to clustering. Once a wallet needs to use 2 pockets/inputs for a transaction, you can refill the pockets. Maybe give the user the option to chose the base amount to start the exponential ladder of pockets. Maybe 2^16 is a bit too big, so you could use 2 duplicate "ladders" of pockets. This would be ideal for a standard wallet of 3 XMR: when you create the pockets, you have 15 additional outputs to fill pockets. You could do it in this way: 0.01 - 0.02 - 0.04 - 0.08 - 0.16 - 0.32 - 0.64 - payment 0.01 - 0.02 - 0.04 - 0.08 - 0.16 - 0.32 - 0.64 - change

This would probably be close to optimal and avoid using 2 or more pockets in one transaction. Maybe consider a "suggested base amount" (in this example 0.01) based on the wallet balance


But the main problem is that more than 2 outputs is bad for privacy, so a totally different suggestion would be a "BalanceSplit" feature: you could put a "warning" in the wallet that you only have one output. If you click it, automatically your wallet balance will be send to yourself, but in 2 equal outputs (both just spit in half). These 2 "pockets" would usually be enough, it enables the user to create 2 transactions in a 10 minute time span.

You could also add a toggle to "AutoSplit" that just automatically creates a transaction when the wallet is active that splits the balance whenever there is just one txo in the wallet. If people keep their wallet open in the background, they wouldn't even need to sign this "split transaction", it would just happen in the background.


Please consider these suggestions and I'd recommend deactivating the current implementation of PocketChange as it really hurts the privacy of Monerujo. As a sidenote: it also makes some decoys worthless. If some wallet selects a txo from a clustered Monerujo-wallet, this decoy is useless.

chaserene commented 7 months ago

PocketChange v2 included many improvements:

https://twitter.com/monerujowallet/status/1696517171537748116

https://libreddit.projectsegfau.lt/r/Monerujo/comments/164tklr/weve_released_an_updated_version_of_monerujo_on/

among the outstanding issues left, and within the confines of what's feasible (both in the technological and the UX sense), I'd very much like to see a mechanism that maintains a set of enotes with various different amounts (as @dnaleor outlined above). this would reduce the amount of inputs of a transaction in general, and reduce the chance of linking multiple PocketChange outputs in particular.

for posterity, here are ofrnxmr's ideas about this topic on how to evolve PocketChange (beginning with this Matrix message:

Random is almost as bad. Needs to produce 1/16 or 1/2 transactions. < fingerprint = gone.. not "reduced".

setting a minimum so it only makes change when necessary (less than 6) was good 👍. Does it make sure to select the largest output? (to avoid making small change)

The idea here is to hide amongst "natural" transactions.

Its more of a workaround for a UX issue (frequent spending), with as little tradeoffs as possible. Solving would imply mandating via consensus rules that only 2 and 16 out tx are possible, Ie padding transactions to 16 out if > 2 outputs. *

Having the wallet software emulate that mandate is the "workaround"

. * there is talk of mandating 2/4/6/8/16, but my view is that, because 2 and 16 cover the vast majority of all transactions, anything outside of those 2 are a "new tx type" and poison rings of real spends

if a non-pocketchange user has a bunch of ring members with 3-15 outs when spending at a merchant, makes it pretty clear that the true spend is not any of the 3-15 outs (lowering effective ring size)

In addition to "mandate 2 and 16", it was also important to

  1. Remove/segregate coinbase decoys (pr done by jeffro)
  2. Keep the ring member distribution to ~ eleven 2's and five 16's (assuming ring size of 16)

to look at it from another perspective, If someone wants to spam the network to mess with privacy in a way that a casual observer can notice, by decreasing the effective ring size, they need only spam 3-15 output tx. Spamming 2 and 16 are only(?) valuable knowledge for the person who owns the outputs (the spammer) / 2 and 16 arent easily distinguishable from real tx by anyone but the spammer if all wallets behaved like pocketchange (what would typically be a 2 out tx may be 6-15), then you end up with a private pool of real tx in those ranges. (2's would become less prevalent as a consequence). But thats rather spammy to the network / bloated. So.. as an "opt in" tool, it should only do 16 outs