pull down to refresh

82 sats \ 6 replies \ @Kruw 9 Jul
Suppose every overt and covert tagging vector above were closed. A malicious coordinator still decides who participates. It can drop or "lose" messages to fail out every input except the ones it wants to track, then fill the rest of the round with its own inputs — an isolation attack that shrinks a victim's anonymity set at only mining-fee and liquidity cost, and amplifies the statistical tagging attacks by leaving fewer real targets.

This is incorrect. Users can submit multiple inputs, which would allow them to detect if any specific input is being targeted.

reply

Hi Kruw! I was trying to contact you privately but didn't find a way to. If you want to talk you can choose how to contact me from the options at https://sgn.space

Anyway, to your point. First of all even if a user could do that (which I agree they probably could) it's not checked automatically by the client. Which means that "regular" users would never notice.

The second part is that even if someone did, they wouldn't really be able to conclude that the coordinator is evil. Maybe Tor was flaky with that one stream? Maybe it's not even the coordinator itself but Cloudflare or the VPS provider that drops that particular connection. Very hard to escape this problem.

But anyway the elephant in the room is the tagging attacks mentioned before that. Attacks that the coordinator can currently perform probably unnoticeably and, even if detected, without a way to prove the cheating.

reply
But anyway the elephant in the room is the tagging attacks mentioned before that. Attacks that the coordinator can currently perform probably unnoticeably and, even if detected, without a way to prove the cheating.

Coordinators publish their round IDs and phase timeouts publicly, so even the most tinfoil hat skeptic can verify everything: https://coinjoin.kruw.io/wabisabi/human-monitor

There's a PR for making this check happen in the client automatically in the background: https://github.com/WalletWasabi/WalletWasabi/pull/14333

It's also worth noting that Yuval's assumptions were incorrect since Taproot's BIP322 signing commits to the scriptpubkey, so these proofs can't be forged.

reply
Coordinators publish their round IDs and phase timeouts publicly, so even the most tinfoil hat skeptic can verify everything: https://coinjoin.kruw.io/wabisabi/human-monitor

I guess it's better than nothing, but definitely not enough. BlameOf is not there and is not part of the round ID either. So the tree attack mentioned in the gist still works even for someone manually checking this. Apart from the trust/centralization problem. This is just one more observer (and in this case served by the same infrastructure).

There's a PR for making this check happen in the client automatically in the background: https://github.com/WalletWasabi/WalletWasabi/pull/14333

This would be very nice. Still not perfect as already mentioned (missing committing to all round parameters). But definitely an improvement. And BTW it's mentioned in the gist as part of the solution.

But I'm really skeptical about it getting merged anytime soon. The flaw it fixes was already known before the release. And there have been other PRs fixing it that where never merged. Maybe this time is different?

It's also worth noting that Yuval's assumptions were incorrect since Taproot's BIP322 signing commits to the scriptpubkey, so these proofs can't be forged.

Maybe "forge" was the wrong term. You can't forge the signature, but you can forge the key. You won't be able to fool a full node that can check if that address has the expected unspent UTXO. But the tagging attack doesn't touch ownership proofs at all. It's per-client KVAC issuer keys -> per-client round IDs. My proof commits to my own round ID, and the coordinator links by which issuer key my re-randomized credentials verify under. BIP-322 committing to the scriptpubkey changes nothing there.

And for the Sybil, signature "forgery" isn't needed either. A malicious coordinator fills the round with its own coins (perfectly valid proofs, its own made up keys), and a light client verifies peers' proofs against scriptpubkeys the coordinator relays, with no UTXO set to check they're real, unspent, and not the coordinator's.

Or did you mean something else?

reply
119 sats \ 2 replies \ @Kruw 10 Jul
BlameOf is not there and is not part of the round ID either. So the tree attack mentioned in the gist still works even for someone manually checking this.

I agree BlameOf should be added to the hashed parameters (I've been making a list here - https://github.com/WalletWasabi/WalletWasabi/issues/11118#issuecomment-4783803398).

However, this attack vector can be prevented by the client without the coordinator needing to commit to anything: A blame round should never contain new inputs that were not present in the original round. I don't know if the client currently checks for this or not, but it's a simple fix.

This is just one more observer (and in this case served by the same infrastructure).

No, publicly posting the round status allows for an infinite number of more observers. Additionally, it lets anyone observe previous rounds and future rounds, not just the one a user intends to participate in.

And BTW it's mentioned in the gist as part of the solution.

Yes, sorry for repeating things you already mentioned in your writeups, I just want to make it visible for SN commenters.

But I'm really skeptical about it getting merged anytime soon. The flaw it fixes was already known before the release. And there have been other PRs fixing it that where never merged. Maybe this time is different?

Wasabi's maintainer has been focused on making the app stable and resilient since zkSNACKS shut down (with absolutely no funding from Opensats, HRF, Spiral, etc). Now that P2P support for compact filters is done, there's time to focus on patching up the remaining problems with coinjoins.

And for the Sybil, signature "forgery" isn't needed either. A malicious coordinator fills the round with its own coins (perfectly valid proofs, its own made up keys), and a light client verifies peers' proofs against scriptpubkeys the coordinator relays, with no UTXO set to check they're real, unspent, and not the coordinator's.

Right, but spending coins that don't exist would create an invalid transaction, and nodes would reject it.

reply
This is just one more observer (and in this case served by the same infrastructure).
No, publicly posting the round status allows for an infinite number of more observers. Additionally, it lets anyone observe previous rounds and future rounds, not just the one a user intends to participate in.
And BTW it's mentioned in the gist as part of the solution.
Yes, sorry for repeating things you already mentioned in your writeups, I just want to make it visible for SN commenters.
But I'm really skeptical about it getting merged anytime soon. The flaw it fixes was already known before the release. And there have been other PRs fixing it that where never merged. Maybe this time is different?
Wasabi's maintainer has been focused on making the app stable and resilient since zkSNACKS shut down (with absolutely no funding from Opensats, HRF, Spiral, etc). Now that P2P support for compact filters is done, there's time to focus on patching up the remaining problems with coinjoins.
And for the Sybil, signature "forgery" isn't needed either. A malicious coordinator fills the round with its own coins (perfectly valid proofs, its own made up keys), and a light client verifies peers' proofs against scriptpubkeys the coordinator relays, with no UTXO set to check they're real, unspent, and not the coordinator's.
Right, but spending coins that don't exist would create an invalid transaction, and nodes would reject it.

On BlameOf / the tree attack: The "no new inputs in a blame round" check helps, but it doesn't close it. The coordinator doesn't add inputs, it splits the honest set into per-victim subsets (each passes a subset check) and re-keys each branch, and the "original round" is just whatever it showed you anyway. Hashing BlameOf plus polling over separate circuits is what catches it; and only a signed commitment makes it provable.

On publishing the round status: Fair. It does add observers and past/future visibility. The nuance I'd keep: a public feed only leaks round metadata, not the input to output map (still just the coordinator/CDN/VPS). And you can get non-equivocation by signing the params for participants, without posting every round publicly.

On Sybil / invalid tx: That only bites if the fake coins have to be spent. But (1) the coordinator can just Sybil with its own real coins, valid tx, nothing to reject, and your whole anon set is the coordinator; and (2) with fake inputs the link is already recovered at output registration, before signing, then it aborts, so no tx is ever broadcast. That would be enough for an evil coordinator to link inputs together or know what payment you were trying to do (amount and destination).

reply
On BlameOf / the tree attack: The "no new inputs in a blame round" check helps, but it doesn't close it. The coordinator doesn't add inputs, it splits the honest set into per-victim subsets (each passes a subset check) and re-keys each branch, and the "original round" is just whatever it showed you anyway. Hashing BlameOf plus polling over separate circuits is what catches it; and only a signed commitment makes it provable.

Maybe I'm misunderstanding, but I think the BlameOf commitment is for preventing the coordinator from covertly merging tagged rounds:

  • Alice, Bob, and Charlie open satoshi connections to the coordinator to listen for round updates
  • The malicious coordinator feeds each connection different round IDs
  • Alice registers to fake round A, Bob registers to fake round B, Charlies registers to fake round C, and the coordinator inserts enough faked inputs in each round to trigger the signing phase
  • The coordinator fails rounds A, B, and C, then creates legitimate round D
  • Alice, Bob, and Charlie's tagged coins all join round D (since it does not commit to any specific A, B or C round)
  • Round D succeeds: Alice, Bob, and Charlie's outputs gain anonymity score, but the coordinator knows the links between their inputs

This would be prevented by the "no new inputs" check since the participants in round D would recognize that multiple blame rounds are being merged together. It would also be detected by a cautious user that checks the publicly posted round ID.

Is there a different attack you have in mind?

The nuance I'd keep: a public feed only leaks round metadata, not the input to output map

The input to output map should be fixed by increasing the gap limit, but this was NACKed by the maintainer in favor of deriving coinjoin outputs via silent payments. I don't know any details on how this would be implemented.

But (1) the coordinator can just Sybil with its own real coins

WabiSabi is uniquely resilient against Sybil attacks. Users choose their own rounds, the coordinator does not choose rounds for users:

Users can submit multiple inputs, which would allow them to detect if any specific input is being targeted.

This means a malicious coordinator would need to have 100x more liquidity and pay 100x more mining fees compared to the target, while the target (and every non-target participant who gets rejected) is able to detect this attack. This 100x cost is a lower bound, since a convincing Sybil attack would also require extra idle liquidity and pay fees in previous/future txs.

(2) with fake inputs the link is already recovered at output registration, before signing, then it aborts, so no tx is ever broadcast. That would be enough for an evil coordinator to link inputs together or know what payment you were trying to do (amount and destination).

I'm not sure what the solution to this is, maybe some sort of sanity check on the maximum number of concurrent rounds? There was a coordinator that tried to fabricate activity: https://bitcointalk.org/index.php?topic=5498650.msg66122296#msg66122296

reply