I have found this mixer proposal https://hackmd.io/@HWeNw8hNRimMm2m2GH56Cw/rJj9hEJTN?type=view
I'm is interested in this topic, but from my point of view with a current ethereum state it won't work. Let me share my view
Below i described my understanding mixer implementation in Ethereum and possible weaknesses.
General mixer description: Address A make a deposit to a mixer contract M. Address B sends to contract M prof that he made a deposit, but the proof doesn't reveal that he was A when he did it, and asks to withdraw his deposit to address C. As soon as there is no connection between A and C mixer successfully does what we expected. We investigated two possible implementation of such mixer: zk-SNARKs mixer Ring signature mixer zk-SNARKs - when A deposits money he also add a proof (a leaf) to a merkle tree inside the contact. When B wants to withdraw he send a proof that his leaf exists in the tree and a proof that he has never sent such request before( double spending protection) Issues with this approach - merkle tree will constantly grow, BarryWhiteHat who investigated this mixer said that he faced problem with amount of computations, for 1.5M (number of leaves) tree it takes 7 minutes to create a proof. We didn't check how much gas it takes to check the proof, but the problem is the merkle tree will grow and grow, and proof generation will became very hard. As I know for now we don't have solution to this problem.
Ring signature mixer - when B wants to withdraw he sends to the mixer a list of public keys (PKs) and proof that he has a private key of one of them, it is impossible to say which public key belongs to B. As soon as the mixer knows public keys which were used for deposit it can confirm that this person can withdraw money, also it makes double spend check.
The main issues with this approach is - the check is quite expensive, to check 5 PKs the contract spends ~1M GAS, so if you want to withdraw money with let say 1% probability that A and B is the same person, you have to withdraw with 10 PKs ring 1-10 times, if you have a public key in a ring which withdraw money from the mixer before it should be replaced with the ring it took money from, so if you are lucky you can get much better probability then a ring size and you will pay 2M - 20M GAS + (some gas to deposit money). This method doesn't have problem with accumulation of deposits, computation depends only on size of ring not number of people who made deposits. But flat ring computation is expensive.
Also we have general Ethereum mixer issue - when B send a withdraw request he must pay for this transaction, and for this he has to have money. It mean that it is impossible to just create a random account and send withdraw request from it. Even if a link between A and C doesn't exist there is a clear link between B and C, if an adversary is able to find a link between A and B he will define that A and C is the same person. As we said before B needs money to use the mixer so A needs some safe way to send this money to B, if A has this way he doesn't need the mixer he can send money to C without mixer. We can create some off chain services to send money to B or play role of B, but it will create a centralization/failure point. There is a improvement suggestion for ETH2.0 which will let contracts pay for transactions, in this case C can send a transaction to the mixer and the mixer will pay for it. If this suggestion become real the problem with gas trace will be solved.
Combination of problems described above makes mixer implementation in the current version of Ethereum very questionable. By my opinion the fundamental issue is gas traceability. It converts our task from hide from/to to implement hidden/safe gas supply for random accounts. To solve "create hidden transactions" task, we have to have hidden transactions. A snake bites its own tail.
Does anybody knows a good approach which will let us solve these problems and help to convert a mixer to a real application?