Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Churning using random amounts is unnecessary at best, but mostly harmful #4

Open
jeffro256 opened this issue Jan 26, 2025 · 1 comment

Comments

@jeffro256
Copy link

A random amount of XMR (within the amuRange range) is selected and transferred to the newly created account using the Monero transfer method via a RPC call.

This is a bad strategy on so many levels. Let's start of with why it's useless: RingCT. As you're probably aware, RingCT hides the amounts of inputs and outputs from external observers. Only those who send/receive can see the amounts transferred. So from an external observer's viewpoint, the amount makes absolutely zero difference in the transaction graph. There is a whole realm of discussion to be had about quantizing amounts when you transfer XMR to other people, but that is out of scope for an automatic churner.

Now why's it's actively harmful to privacy. Let's say that you start with 10 XMR, and you need to pay for something that is 7 XMR. Scenario A) you don't bother churning a random amount and use the 10 XMR TXO as an input in your 1-in transfer transaction. Scenario B) you try churning and split your TXO worth 10 XMR into two TXOs, worth 4 and 6. Then to spend 7 XMR, you create a 2-in transfer transaction where each ring contains 1 member from the churn transaction. An external observer can detect that the funds for the transfer transaction originated from the churn transaction with higher probability.

In general, you should not be thinking about amounts at all when churning in Monero post-RingCT, you should be thinking about TXOs. If you want to add anonymity to the spend of a specific TXO, you should churn that TXO, not group multiple together to spend some random arbitrary amount. In my humble opinion, you should get yourself familiar with some of the research that's already out there on this topic, instead of trying to wing it. For example: https://github.com/cypherstack/churn

@antichainalysis
Copy link
Owner

antichainalysis commented Jan 26, 2025

Hello, thank you for your feedback. I believe you are overlooking a few nuances that could still justify the use of a random amount churn strategy within specific bounds. Before we get into it please keep in mind I designed moneroc in a way that is as user-friendly as possible (you will understand what I mean later on in this writing).

Yes, you're obviously correct that amounts are hidden via RingCT, randomizing the amounts doesn't add any meaningful privacy benefit because the amounts can't be seen anyway.

I agree to an extent, but you overlook the broader context. While RingCT does indeed hide amounts from external observers on the blockchain, there are other factors that can make transferring the same amount repeatedly detectable. I do explain in the README.md and other markdown files that the real privacy gain from randomizing amounts comes from reducing pattern recognition and statistical analysis mainly from Chainalysis (yes, they're very good at it.). Chainalysis can still make probabilistic guesses about which inputs and outputs belong to the same person based on transaction size (if it's always the same), timing, and other metadata that could be exposed when you sign the same transfer size repeatedly. Chainalysis runs a lot of Monero nodes I plan to push my writing on this in writeup.md by tomorrow or the day after.

Regarding your point on TXOs vs. Amounts in Churning I hope you read this example of moneroc process, but if not I will explain more clearly.

Your concern does NOT apply to moneroc. In this example, moneroc distributes the 100 XMR in Account 0 into 10 NEW accounts. In chunks of 10 XMR each. Obviously this is just an example, for SIMPLICITY purposes, since in moneroc production this is actually happening:

A random amount of XMR (within the amuRange range) is selected and transferred to the newly created account using the Monero transfer method via a RPC call.

The key here in the example is that 10 separate transactions create distinct TXOs that belong to individual accounts. The 10 XMR per account remains intact and is not split in the process. After distribution process from Account 0 happens, the churning process begins, when those accounts created in the distribution process churn their 10 XMR each into new accounts (11-20), each of those TXOs is still intact and not split up. The amount and identity of the transaction are kept discrete across different accounts. This process creates a new TXO for each account, and there is no splitting of funds into smaller chunks like in your example (where 10 XMR becomes 4 XMR and 6 XMR). This significantly reduces the chance of linking transactions.

My point is, moneroc keeps EVERYTHING segregated and are independent transactions. Each of the distribution and churning process also have a random 30-60 minute range delay between them. That also takes advantage of RingCT. There is no combination of smaller chunks in the same transaction. It is not creating a transaction with multiple inputs from different churns (which could potentially raise flags if they came from the same source). Rather, each account is transferring a single TXO to a new account in a seperate transaction. This means that external observers would see 10 separate transfers happening over time (MULTIPLE hours apart where by then Ring 16 is in full affect, if not mostly.), which is far harder to link back to a single source.

There is no risk of TXO reuse as long as the user who uses moneroc does not end up combining all the churn outputs together into a single wallet (account) right after churning process. It's all up to the user. Monero is a tool just like moneroc and tools are meant to be used CORRECTLY.

Even though, the example markdown file is simplified, the core logic behind the random amount within the amuRange still follows the same process, segregated and independent transactions. Your concern is about splitting TXOs and the risks of detecable patterns emerging when doing so. So regarding the amuRange strategy, I will break it down:

How the amuRange works:

  • moneroc is selecting a random amount within the amuRange range and sending it to a new account.
  • The amount varies between transactions, which means that instead of always sending a fixed 10 XMR, you could be sending something between, say, 5 and 15 XMR.
  • This randomness may seem like it could result in splitting TXOs, since it changes the amount of XMR being sent each time, creating a different size for each transfer.

moneroc prevents and avoids all your concerns, it's amuRange is used to generate diverse, randomized amounts across each churn, it adds a layer of complexity and randomness that helps obfuscate the flow of funds. moneroc doesn’t reuse TXOs across accounts or combine them. There's no static pattern for the amount of XMR distributed, thus mitigating the risk of it looking like an exchange's behaviour. Which I do also briefly explain here.

The main point to emphasize here is that TXOs are handled in isolation, and their amounts are randomized within a range to avoid patterns, while the churn process ensures that funds are moved across accounts and never recombined. This strategy makes it more difficult to link churned funds back to the original source, maintaining privacy throughout the process. I also want to further emphasize how the delay range between transactions and the use of RingCT also contributes to making it harder for external observers to link transactions, as this strengthens the overall anonymity of the system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants