diff --git a/book.toml b/book.toml index 6087acc..b611417 100644 --- a/book.toml +++ b/book.toml @@ -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" diff --git a/collaborative_txn_privacy.md b/collaborative_txn_privacy.md index ace8c1c..3054abb 100644 --- a/collaborative_txn_privacy.md +++ b/collaborative_txn_privacy.md @@ -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. +
+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. +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. +
+ +*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. diff --git a/contrib/figures.py b/contrib/figures.py new file mode 100644 index 0000000..f79141a --- /dev/null +++ b/contrib/figures.py @@ -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() diff --git a/src/figures/figure-32-dark.svg b/src/figures/figure-32-dark.svg new file mode 100644 index 0000000..cd671f6 --- /dev/null +++ b/src/figures/figure-32-dark.svg @@ -0,0 +1,1492 @@ + + + + + + +No small cut separates Alice's output from her candidate origins +32 → 31 → 30 → 29 → 28 → 27 → 26 → 25 → 24 → 23 → 22 candidate wallets, one lost per strike, thirty-one in all to reach one + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +One coin separates Alice's output from half her candidate origins +32 → 16 → 8 → 4 → 2 → 1 candidate wallet, exhausted after five + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +still a candidate +confirmed origin +struck off +never a candidate +Alice +Frank +Erin +Dave +Carol +Bob +wallet 32 +Alice +Frank +Erin +Dave +Carol +Bob +wallet 32 +round 1 +round 2 +round 3 +round 4 +round 5 +round 6 +round 7 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 + \ No newline at end of file diff --git a/src/figures/figure-32-light.svg b/src/figures/figure-32-light.svg new file mode 100644 index 0000000..cf9e015 --- /dev/null +++ b/src/figures/figure-32-light.svg @@ -0,0 +1,1492 @@ + + + + + + +No small cut separates Alice's output from her candidate origins +32 → 31 → 30 → 29 → 28 → 27 → 26 → 25 → 24 → 23 → 22 candidate wallets, one lost per strike, thirty-one in all to reach one + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +One coin separates Alice's output from half her candidate origins +32 → 16 → 8 → 4 → 2 → 1 candidate wallet, exhausted after five + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +still a candidate +confirmed origin +struck off +never a candidate +Alice +Frank +Erin +Dave +Carol +Bob +wallet 32 +Alice +Frank +Erin +Dave +Carol +Bob +wallet 32 +round 1 +round 2 +round 3 +round 4 +round 5 +round 6 +round 7 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 + \ No newline at end of file diff --git a/theme/diagrams.css b/theme/diagrams.css index bb71486..3a913ff 100644 --- a/theme/diagrams.css +++ b/theme/diagrams.css @@ -3,7 +3,8 @@ once per theme and swapped here; graphviz keeps whatever its .dot source asks for, with only graphviz's own defaults lifted for the dark themes. */ .mdbook-graphviz-output, -.mermaid { +.mermaid, +.chart-src { overflow-x: auto; margin: 1rem 0; } @@ -11,7 +12,8 @@ /* Scale wide graphs down to the content column instead of clipping them; the svg viewBox keeps them sharp at any size. */ .mdbook-graphviz-output svg, -.mermaid svg { +.mermaid svg, +.chart-src img { display: block; max-width: 100%; height: auto; @@ -23,14 +25,16 @@ only just overflow still fit without scrolling. */ @media (max-width: 700px) { .mdbook-graphviz-output, - .mermaid { + .mermaid, + .chart-src { margin-left: calc(-1 * var(--page-padding, 15px)); margin-right: calc(-1 * var(--page-padding, 15px)); padding: 0 var(--page-padding, 15px); } .mdbook-graphviz-output svg, - .mermaid svg { + .mermaid svg, + .chart-src img { max-width: none; } } @@ -67,3 +71,26 @@ html:is(.coal, .navy, .ayu) .mdbook-graphviz-output [fill="black"] { html:is(.coal, .navy, .ayu) .mdbook-graphviz-output text:not([fill]) { fill: #b7b7b7; } + +/* Each chart has a light and a dark file, marked for GitHub by its URL + fragment; book themes select one the same way. */ +.chart-src img[src$="#gh-dark-mode-only"] { + display: none; +} + +@media screen { + html:is(.coal, .navy, .ayu) .chart-src img[src$="#gh-dark-mode-only"] { + display: block; + } + + html:is(.coal, .navy, .ayu) .chart-src img[src$="#gh-light-mode-only"] { + display: none; + } +} + +/* Print the light palette even when the reader selected a dark book theme. */ +@media print { + .chart-src { + break-inside: avoid; + } +}