Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions book.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ after = ["links", "graphviz"]
command = "mdbook-katex"
after = ["links"]

[preprocessor.figures]
command = "python3 contrib/figures.py"
after = ["links", "graphviz", "mermaid", "katex"]

[output.html]
additional-css = ["theme/diagrams.css"]
git-repository-url = "https://github.com/fungi-protocol/docs"
6 changes: 6 additions & 0 deletions collaborative_txn_privacy.md
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,12 @@ For example, a chain analysis vendor with KYC information may already be able to
If the CoinJoin graph is *robustly connected*[^flow], then no small cut separates any output from the mass of its candidate origin coins. Stated differently, every output is connected to its candidate origins by multiple disjoint paths.

This redundancy forestalls the cliff of exponential decay, where privacy becomes much more brittle, extending the duration of the linear decay regime by requiring the adversary to deanonymize a much larger proportion of users before divide-and-conquer tactics start coming into play.
<div class="chart-src f32">
<img src="src/figures/figure-32-light.svg#gh-light-mode-only" loading="lazy" alt="Two CoinJoin graphs of thirty-two wallets under the same ten deanonymizations: mixing sheds one candidate per strike; merges through a single coin collapse to one.">
<img src="src/figures/figure-32-dark.svg#gh-dark-mode-only" loading="lazy" alt="Two CoinJoin graphs of thirty-two wallets under the same ten deanonymizations: mixing sheds one candidate per strike; merges through a single coin collapse to one.">
</div>

*The same ten peers, deanonymized in the same order, in both graphs.*

But when two post-CoinJoin outputs are linked, on-chain or otherwise, this makes **intersection attacks**[^goldfeder][^scroll-intersection] possible. In such attacks, we take the candidate origins of these now-linked coins and check for any overlaps.

Expand Down
24 changes: 24 additions & 0 deletions contrib/figures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env python3
"""Point chart images at the book's copy; the source keeps repository paths for GitHub."""
import json
import sys


def walk(items):
for item in items:
chapter = item.get('Chapter') if isinstance(item, dict) else None
if chapter:
chapter['content'] = chapter['content'].replace('src="src/figures/', 'src="figures/')
walk(chapter['sub_items'])


def main():
if len(sys.argv) > 1 and sys.argv[1] == 'supports':
sys.exit(0 if len(sys.argv) > 2 and sys.argv[2] == 'html' else 1)
context, book = json.load(sys.stdin)
walk(book.get('items', book.get('sections', [])))
json.dump(book, sys.stdout)


if __name__ == '__main__':
main()
Loading
Loading