diff --git a/.gitignore b/.gitignore index 8dade17..11e0883 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ book/ result +.ipynb_checkpoints/ diff --git a/.typos.toml b/.typos.toml new file mode 100644 index 0000000..0210cca --- /dev/null +++ b/.typos.toml @@ -0,0 +1,11 @@ +[default.extend-identifiers] +# Mermaid class for Alice's cluster in the intersection diagram. +aci = "aci" +# Author of The Byzantine Generals Problem. +Pease = "Pease" +# Author of Asymmetric Distributed Trust. +Cachin = "Cachin" + +[default.extend-words] +# Groth16, the proof system named after Jens Groth. +Groth = "Groth" diff --git a/README.md b/README.md index 38856fe..5fd7a4f 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,52 @@ # Fungi -This repository contains documents that describe a family collaborative Bitcoin transaction construction protocols. The protocols form a progression towards decentralized and market based privacy preserving transactions. +Fungi is a protocol for collaborative transactions designed to make using Bitcoin more private. Participants can also pay each other interactively in these transactions, which helps not just privacy but also blockspace efficiency. + +A software development kit (SDK) is [in development](https://github.com/fungi-protocol/fungi). This repository contains the specifications and the analysis behind them. > [!NOTE] -> **Work in progress**: most chapters are still under review. See the [open pull requests](https://github.com/fungi-protocol/docs/pulls) for material being drafted. +> **Work in progress**: most chapters are drafts under review. See the [open pull requests](https://github.com/fungi-protocol/docs/pulls) for material being drafted. +> +> Chapters, sections or paragraphs marked with 🤖 are LLM output. They have been partly verified but have not yet been edited or rewritten as necessary, and should be considered a working draft. + +## Background + +Censorship resistance and fungibility are among Bitcoin's foundational properties. Without privacy, both can be undermined largely outside the protocol's rules, whether by targeting specific individuals or through chilling effects. + +Bitcoin transactions are public data, and they are connected in a graph structure. Chain analysis is the application of heuristics to this graph to infer which coins share an owner. While no heuristic is perfect, their effectiveness has been shown in numerous studies. Several heuristics can be combined for a more accurate analysis. Analysis might also draw on auxiliary information not recorded on the blockchain, such as which coins an exchange sent to which customer. + +CoinJoin transactions seek to undermine some of the heuristics used to cluster coins across the transaction graph. They combine several users' inputs and outputs in one transaction in order to obscure ownership links within it. Several CoinJoin implementations exist with different approaches to their transaction structure. -## Fungi protocol suite +## Problem statement -### Honest setting +Unfortunately, CoinJoin privacy is often stated in terms of the number of indistinguishable outputs in a transaction. This tacitly ignores the fact that those coins will go on to be spent. The information revealed by the spending transactions, which are themselves related to other transactions, can dramatically affect privacy, in some cases making the CoinJoin inputs linkable to the outputs. -The *honest* setting assumes all participants can be trusted in two ways: +Recurring relationships give rise to patterns too. Transacting with the same employers, shops and friends leaves a structure in the transaction graph, even if techniques like PayJoin might hide the individual amounts and confound some of the clustering heuristics. Obscuring this structure necessitates transacting with unrelated users, chosen at random, so users who don't know or trust each other need a way to find each other and agree on a transaction. Random selection must additionally be Sybil resistant, so that the cost of an $n-1$ deanonymization attack, where the adversary controls all of the other (apparent) participants, is a sufficient deterrent. -- not to disrupt the execution of the protocol -- with privacy, which means not revealing to the adversary, ideally forgetting, any information that may be revealed by participants in the course of the protocol's execution +In general, deanonymizing a single user always makes it easier to deanonymize the other users. But sometimes the adversary might progress not just by process of elimination, but more like divide and conquer. This happens when deanonymizing that one user splits the problem of deanonymizing the rest into several smaller problems, as opposed to merely making it incrementally smaller. -In this as well as subsequent protocol, trust never means giving up control over one's funds. Input signatures in transactions enforce this safety by letting each party ensure its , requiring unanimous consent by all parties. +The [problem definition](docs/collaborative_txn_privacy.md) chapter discusses these on-chain privacy leaks in depth, and describes a particular transaction graph structure that resists deanonymization more robustly. -### Semi-honest setting +## How Fungi works -In the *semi-honest* setting, also known as *honest-but-curious*, we no longer assume peers have to be trusted to keep a secret. Instead this relies on privacy preserving transports for the communication, that allow a peer to broadcast its messages anonymously to the other participants. Because Bitcoin transactions are transparent, privacy further demands a more careful approach to transaction construction, or the actions of a peer may be revealing even if not directly attributable. +A user first tells their wallet which payments they intend to make, and the wallet keeps these in a queue. Intents can vary in their time, privacy or cost sensitivity. Making a payment quickly, cheaply and privately is a balancing act, and improving one usually means compromising on another. The wallet's job is to construct transactions that make the queued payments, balancing these goals in line with the user's preferences. -The semi-honest setting can provide some degree of confidentiality, especially against 3rd party observers, through the construction of net settlement transactions. But not anonymity. Transactions between peers that are somehow related have inherent privacy issues because such relationships constitute a social network, exhibiting community structure. +The wallet schedules and batches payments, negotiating with other participants to find terms that suit the user's priorities. The more flexible a payment's timing, the more cost-effective it can be, because there is more time for compatible proposals to be combined, so that its cost can be shared with more participants. The protocol and the strategy are designed together, and the SDK implements both. -### Byzantine fault tolerant setting +Avoiding links between coins is central to the strategy. The input and output amounts can imply such links if there aren't enough possibilities for how to group inputs and outputs so their totals match. But as mentioned above, a partition of a transaction's coins can also be evaluated based on the surrounding context in the transaction graph, not just the amounts associated with that transaction. So the strategy must consider not just whether the transaction's internal structure is sufficiently ambiguous, but also how a transaction sits in the wider transaction graph. -Overcoming the community analysis concern requires a Sybil resistant, permissionless protocol where peers with no meaningful economic relationship can find each other. This involves an additional *coalition formation* protocol that sets up transaction construction using a market based mechanism. +In Fungi, a *co-spend proposal* sets out the terms for spending a set of coins together. Proposals are made automatically according to the privacy optimization strategy. The transaction-wide terms of a co-spend proposal are public, constraining things like the range of acceptable feerates or whether or not non-SegWit inputs can be used. Proposals can also include fees, which are kept confidential. A proposal involving three or more parties additionally hides which of them made the proposal. Once accepted by all parties, co-spend proposals are publicly broadcast. -While it is beneficial for privacy, interacting with strangers in a permissionless protocol invites disruption or attempts at surveillance. For honest peers to be able to reliably transact, especially with the unanimity requirement, demands a byzantine fault tolerance from the transaction construction protocol. +Any participant can collect fully accepted co-spend proposals from multiple parties, and then make a *coalition formation proposal* which aggregates them together, so long as the terms are compatible. If everyone accepts the coalition formation proposal, then a coalition has been formed, and the parties can proceed with collaborative transaction construction. Privacy is brittle in small transactions. A critical mass of participants is therefore necessary for privacy to be robust and cost-effective, and coalition formation is designed to facilitate such a critical mass forming. -In the course of a BFT interaction with untrusted peers, a participant may still use the other variants of the protocol to coordinate activity with the subset of peers they do know or trust, for instance by performing net-settlement within a larger BFT CoinJoin. +During collaborative transaction construction, participants add their intended inputs and outputs anonymously. This preserves the unlinkability of inputs and outputs so long as it isn't undermined in some other way (for example by reusing an output address). Interactive payments additionally provide privacy against the payment counterparty. In addition to hiding the payment amount from third parties, the sender and receiver do not learn about each other's coins. Since many interactive payments can be settled in one collaborative transaction, this creates the opportunity for blockspace savings. -## Motivation +In order to ensure funds are secure throughout, every participant retains control at all times and therefore signs their own inputs. Unfortunately, this means that as the number of participants grows, reliability will necessarily degrade. Even if the probability of any one participant causing a fault is low, that compounds when considering the probability that none of them will. Transaction construction is designed to be fault-tolerant, so that even when a valid transaction has not successfully been produced, participants have a basis to refine the coalition structure. Fault tolerance includes malicious disruption. -Wallet clustering is the broad term for a variety of techniques that can be used to deanonymize on chain activity. Clustering involves linking particular coins to one another, attributing their ownership to the same entity. Over the course of Bitcoin's existence many papers have been published on this subject, also about related privacy issues issues, such as Lightning network, or the transport layer. +## Compared to JoinMarket -This body of work has, time and again, shown that misconceptions about privacy invariably err on the side of optimism. Moreover, depending on individual users' threat models, their adversary may have access to comprehensive auxiliary information. Such auxiliary information doesn't even need to be about the target user, information about other users may be useful for deanonymization of the target user. In cryptography, rotating long lived keys or favoring ephemeral ones can limit the scope of a compromise, but an individual's identity is who they are. +Fungi could be described as a spiritual successor to JoinMarket (as implemented by [JoinMarket](https://github.com/JoinMarket-Org/joinmarket-clientserver) and [JoinMarket-NG](https://github.com/joinmarket-ng/joinmarket-ng)). Like JoinMarket, it is peer-to-peer and market-based, with no centralized coordinator, but differs substantially in how it approaches the order book mechanism as well as transaction construction. -The fungi protocol suite is designed to make arbitrary transactions possible between mutually consenting but distrusting peers. This means safety, liveness, and unlinkability of protocol messages. Within such a protocol peers are free to pursue whatever outcomes they desire. +JoinMarket distinguishes two roles: in each transaction, a user in the role of the taker selects several makers from the order book. Makers advertise their willingness to participate in CoinJoin transactions. Generally, the taker will pay the on-chain fees as well as any maker fees. The taker learns which coins belong to the makers it pays, so makers get no privacy from the taker. And because there is a single taker, a transaction can only include as many participants as one taker is willing to pay for. -Privacy does not simply emerge naturally from collaborative transactions. Peers must actively optimize for that. Optimization involves the use of a cost function, an extension or generalization of the kind used for coin selection. This repository makes specific recommendations with which the protocols are designed to be compatible. The recommended privacy related terms address Sybil resistance, the transaction structure (for example how output values are chosen in relation to others' input values) and the graph structure. +Fungi makes no distinction between the taker and maker roles. Instead, a participant can both send and accept proposals, and proposals involving multiple users can be aggregated, allowing a single transaction to be negotiated more as a group buy of blockspace. As the number of participants grows, the privacy benefits compound for everyone, which means each individual user needs to pay for proportionately less blockspace in order to meet their individual privacy requirements. Finally, the proposed transaction structure aims to address several deanonymization attacks that were not yet understood at the time JoinMarket's design was put in place. diff --git a/book.toml b/book.toml index 0b88649..caff386 100644 --- a/book.toml +++ b/book.toml @@ -6,6 +6,11 @@ src = "src" [build] create-missing = false +[preprocessor.jupyter] +command = "python3 contrib/jupyter_nb.py" +after = ["links"] +before = ["graphviz", "mermaid", "katex"] + [preprocessor.graphviz] command = "mdbook-graphviz" after = ["links"] @@ -17,8 +22,11 @@ after = ["links", "graphviz"] [preprocessor.katex] command = "mdbook-katex" after = ["links"] +# mdbook-graphviz re-serializes the markdown, escaping the TeX source. +before = ["graphviz"] [output.html] additional-css = ["theme/diagrams.css"] git-repository-url = "https://github.com/fungi-protocol/docs" -site-url = "/docs/" +site-url = "/docs-draft/" +additional-js = ["theme/nb-table.js"] diff --git a/contrib/book.py b/contrib/book.py index 1cf9b79..952da45 100644 --- a/contrib/book.py +++ b/contrib/book.py @@ -4,14 +4,19 @@ docs/index.md, the bundle's OKF index, states the chapter order: its headings become the parts of SUMMARY.md and its entries the chapters, without their descriptions, so an entry must name a chapter, by a path -relative to docs/, and every chapter must have an entry. The README is -the introduction, and the index, with its descriptions, is the contents -page. Frontmatter is checked and then dropped, as mdbook would render it -as text. The bundle's other files are copied as they are. +relative to docs/, and every chapter must have an entry. An entry +indented two spaces more than the entry above it is a sub-chapter of +that entry. The README is the introduction, and the index, with its +descriptions, is the contents page. Frontmatter is checked and then +dropped, as mdbook would render it as text. Chapters are markdown pages +and Jupyter notebooks, whose frontmatter is a raw cell that opens them. +The bundle's other files are copied as they are, except for Jupyter's +autosaves. python3 book.py ROOT """ import argparse +import json import posixpath import re import shutil @@ -21,7 +26,7 @@ import yaml FRONTMATTER = re.compile(r"\A---\n(.*?)\n---[ \t]*(?:\n+|\Z)", re.DOTALL) -ENTRY = re.compile(r"\* \[([^\]]+)\]\(([^)\s]+)\)(?: - .*)?") +ENTRY = re.compile(r"( *)\* \[([^\]]+)\]\(([^)\s]+)\)(?: - .*)?") DOCS = "docs" # As set in book.toml. SRC = "src" @@ -29,12 +34,35 @@ GENERATED = ("README.md", "SUMMARY.md", CONTENTS) STATUSES = ("draft", "stable", "deprecated") RESERVED = ("index.md", "log.md") +NOTEBOOK = ".ipynb" +CHECKPOINTS = ".ipynb_checkpoints" +# A sub-chapter's entry is indented this much more than its chapter's. +INDENT = " " def strip_frontmatter(text): return FRONTMATTER.sub("", text, count=1) +def notebook_frontmatter(text): + """A notebook's frontmatter, as a markdown page would have it, if a + raw cell holding nothing else opens it, and the notebook without it.""" + nb = json.loads(text) + cells = nb.get("cells", []) + if cells and cells[0].get("cell_type") == "raw": + head = "".join(cells[0].get("source", [])) + if FRONTMATTER.fullmatch(head): + nb["cells"] = cells[1:] + return head, json.dumps(nb, indent=1, ensure_ascii=False) + "\n" + return "", text + + +def body(name, text): + if name.endswith(NOTEBOOK): + return notebook_frontmatter(text)[1] + return strip_frontmatter(text) + + def frontmatter(text): m = FRONTMATTER.match(text) fields = yaml.safe_load(m.group(1)) if m else None @@ -47,6 +75,8 @@ def check(name, text): has passed is not checked, so that a build does not depend on when it runs.""" try: + if name.endswith(NOTEBOOK): + text = notebook_frontmatter(text)[0] fields = frontmatter(text) except (yaml.YAMLError, ValueError) as e: raise ValueError(f"{name}: {e}") from e @@ -71,20 +101,35 @@ def check(name, text): def summary(index, pages): """SUMMARY.md from an OKF index: `# Part` headings and `* [Title](file.md) - description` entries, naming each of `pages`, - the paths in docs/ of the pages the book is given.""" + the paths in docs/ of the pages the book is given. Indented entries + are nested under the entry above them.""" out = ["# Summary", "", "[Introduction](README.md)", f"[Contents]({CONTENTS})"] listed = set() + # The depth of the entry above, or -1 at the start of a part, where + # there is none to nest under. + above = -1 for line in strip_frontmatter(index).splitlines(): if line.startswith("# "): out += ["", line, ""] + above = -1 elif m := ENTRY.fullmatch(line): - chapter = posixpath.normpath(m.group(2)) + depth, odd = divmod(len(m.group(1)), len(INDENT)) + if odd: + raise ValueError(f"index entry has odd indentation: {line!r}") + if depth > above + 1: + if above < 0: + raise ValueError(f"index entry has no entry above: {line!r}") + raise ValueError( + f"index entry is nested more than one level deeper: {line!r}" + ) + above = depth + chapter = posixpath.normpath(m.group(3)) if chapter not in pages: raise ValueError(f"index entry is not a chapter: {line!r}") if chapter in listed: raise ValueError(f"index entry repeats a chapter: {line!r}") listed.add(chapter) - out.append(f"- [{m.group(1)}]({chapter})") + out.append(f"{INDENT * depth}- [{m.group(2)}]({chapter})") elif line.strip(): raise ValueError(f"unexpected line in index: {line!r}") if unlisted := sorted(set(pages) - listed): @@ -103,8 +148,8 @@ def assemble(root): docs, out = root / DOCS, root / SRC index = (docs / "index.md").read_text() pages = {} - for page in sorted(docs.rglob("*.md")): - if page.name not in RESERVED: + for page in sorted([*docs.rglob("*.md"), *docs.rglob("*" + NOTEBOOK)]): + if page.name not in RESERVED and CHECKPOINTS not in page.parts: name = page.relative_to(docs).as_posix() pages[name] = page.read_text() check(name, pages[name]) @@ -136,14 +181,14 @@ def assemble(root): shutil.copytree( docs, out, - ignore=shutil.ignore_patterns("*.md", ".gitignore"), + ignore=shutil.ignore_patterns("*.md", "*" + NOTEBOOK, CHECKPOINTS, ".gitignore"), dirs_exist_ok=True, ) for name, text in generated.items(): (out / name).write_text(text) for name, text in pages.items(): (out / name).parent.mkdir(parents=True, exist_ok=True) - (out / name).write_text(strip_frontmatter(text)) + (out / name).write_text(body(name, text)) def main(argv=None): diff --git a/contrib/jupyter_nb.py b/contrib/jupyter_nb.py new file mode 100755 index 0000000..a10bfb7 --- /dev/null +++ b/contrib/jupyter_nb.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python3 +"""mdbook preprocessor: render `.ipynb` chapters from their saved outputs. + +Any chapter whose source path ends in `.ipynb` is replaced with markdown +built from the notebook's cells. Nothing is executed: markdown cells pass +through verbatim and code-cell outputs (plots, tables, text) are emitted +from what the notebook already has saved, so the build needs no scientific +python stack. Images are inlined as data URIs, so no asset files are written. + +Input (code) cells are hidden by default -- the plotting boilerplate does +not aid understanding. Per-cell control follows the jupyter-book tag +convention via `metadata.tags`: + + remove-cell drop the cell entirely (no input, no output) + show-input force the source to be shown in a fenced block + remove-output drop the outputs + +Links to notebook chapters, `[text](notebook.ipynb#section)`, are pointed +at the chapter's `.md` path: mdbook rewrites `.md` links to the rendered +pages, on the print page too, but leaves `.ipynb` links as they are. + +Plots read on every mdbook theme when the notebook saves them transparent +with medium-lightness chrome (see the style cell in the notebook); a raster +cannot be recoloured by css the way inline svg can. +""" +import json +import posixpath +import re +import sys + +# The relative target of an inline link or a reference definition, if it +# ends in `.ipynb`, before any fragment. +NOTEBOOK_LINK = re.compile( + r"(\]\(\s*#?:]+)\.ipynb(?=[#>)\s]|$)", + re.M, +) + + +def cell_tags(cell): + return set(cell.get("metadata", {}).get("tags", [])) + + +def joined(value): + return "".join(value) if isinstance(value, list) else (value or "") + + +def fenced(code, lang=""): + return "\n```%s\n%s\n```\n" % (lang, code.rstrip("\n")) + + +def render_output(out): + kind = out.get("output_type") + if kind == "stream": + # stdout/stderr is noise (warnings, progress bars); drop it. + return "" + if kind == "error": + return fenced("\n".join(out.get("traceback", []))) + data = out.get("data", {}) + if "image/png" in data: + png = joined(data["image/png"]).replace("\n", "") + return '\n\n' % png + if "image/svg+xml" in data: + return '\n
\n%s\n
\n' % joined(data["image/svg+xml"]) + if "text/html" in data: + html = joined(data["text/html"]) + # Colab wraps tables in interactive widget markup (scripts, sort + # buttons) that is inert in a static book; keep just the table. + match = re.search(r"", html, re.S) + if match: + html = match.group(0) + return '\n
\n%s\n
\n' % html + if "text/plain" in data: + return fenced(joined(data["text/plain"])) + return "" + + +def render_notebook(nb): + parts = [] + for cell in nb.get("cells", []): + tags = cell_tags(cell) + if "remove-cell" in tags: + continue + kind = cell.get("cell_type") + if kind == "markdown": + parts.append(joined(cell.get("source"))) + elif kind == "code": + if "show-input" in tags: + parts.append(fenced(joined(cell.get("source")), "python")) + if "remove-output" not in tags: + for out in cell.get("outputs", []): + piece = render_output(out) + if piece: + parts.append(piece) + return "\n\n".join(p for p in parts if p.strip()) + + +def is_notebook(chapter): + for key in ("source_path", "path"): + p = chapter.get(key) + if isinstance(p, str) and p.endswith(".ipynb"): + return True + return False + + +def chapters(items): + # Separators are bare strings, part titles are `{"PartTitle": ...}`. + for item in items or []: + chapter = item.get("Chapter") if isinstance(item, dict) else None + if chapter: + yield chapter + yield from chapters(chapter.get("sub_items")) + + +def link_notebooks(chapter, notebooks): + """Point links that resolve to one of `notebooks` at its `.md` path.""" + here = posixpath.dirname(chapter.get("path") or "") + + def fix(m): + target = posixpath.normpath(posixpath.join(here, m.group(2) + ".ipynb")) + return m.group(1) + m.group(2) + ".md" if target in notebooks else m.group(0) + + chapter["content"] = NOTEBOOK_LINK.sub(fix, chapter.get("content", "")) + + +def main(): + if len(sys.argv) > 1 and sys.argv[1] == "supports": + sys.exit(0) + _context, book = json.load(sys.stdin) + # mdbook 0.5 renamed the top level key from `sections` to `items`. + items = book.get("items", book.get("sections")) + notebooks = set() + for chapter in chapters(items): + if is_notebook(chapter): + notebooks.add(posixpath.normpath(chapter.get("path") or chapter["source_path"])) + if chapter.get("content", "").strip(): + chapter["content"] = render_notebook(json.loads(chapter["content"])) + for chapter in chapters(items): + link_notebooks(chapter, notebooks) + json.dump(book, sys.stdout) + + +if __name__ == "__main__": + main() diff --git a/contrib/test_book.py b/contrib/test_book.py index 25f5c09..07f2c39 100644 --- a/contrib/test_book.py +++ b/contrib/test_book.py @@ -1,3 +1,4 @@ +import json import re import book @@ -13,6 +14,16 @@ * [Two](sub/two.md) - The second chapter. """ CHAPTERS = {"one.md", "sub/two.md"} +MARKDOWN_CELL = {"cell_type": "markdown", "metadata": {}, "source": ["# Three\n"]} + + +def notebook(*cells): + nb = {"cells": list(cells), "metadata": {}, "nbformat": 4, "nbformat_minor": 5} + return json.dumps(nb, indent=1, ensure_ascii=False) + "\n" + + +def raw_cell(text): + return {"cell_type": "raw", "metadata": {}, "source": text.splitlines(True)} def test_frontmatter_is_dropped_once(): @@ -44,6 +55,75 @@ def test_contents_keep_descriptions_under_one_title(): ) +NESTED = """# Part + +* [One](one.md) - The first chapter. + * [Two](sub/two.md) - Under the first. + * [Three](three.md) - Under the second. + + * [Four](four.md) - Under the first, after a blank line. +* [Five](five.md) - The last chapter. +""" +NESTED_CHAPTERS = {"one.md", "sub/two.md", "three.md", "four.md", "five.md"} + + +def test_summary_nests_indented_entries_under_the_entry_above(): + assert book.summary(NESTED, NESTED_CHAPTERS) == ( + "# Summary\n\n" + "[Introduction](README.md)\n" + "[Contents](contents.md)\n\n" + "# Part\n\n" + "- [One](one.md)\n" + " - [Two](sub/two.md)\n" + " - [Three](three.md)\n" + " - [Four](four.md)\n" + "- [Five](five.md)\n" + ) + + +def test_contents_keep_the_nesting(): + assert book.contents(NESTED) == ( + "# Contents\n\n" + "## Part\n\n" + "* [One](one.md) - The first chapter.\n" + " * [Two](sub/two.md) - Under the first.\n" + " * [Three](three.md) - Under the second.\n\n" + " * [Four](four.md) - Under the first, after a blank line.\n" + "* [Five](five.md) - The last chapter.\n" + ) + + +@pytest.mark.parametrize( + "index, error", + [ + ("# Part\n\n * [One](one.md)\n", "no entry above"), + (" * [One](one.md)\n", "no entry above"), + ("* [One](one.md)\n\n# Part\n\n * [Two](sub/two.md)\n", "no entry above"), + ("# Part\n\n* [One](one.md)\n * [Two](sub/two.md)\n", "more than one level"), + ("# Part\n\n* [One](one.md)\n * [Two](sub/two.md)\n", "odd indentation"), + ("# Part\n\n* [One](one.md)\n * [Two](sub/two.md)\n", "odd indentation"), + ("# Part\n\n* [One](one.md)\n\t* [Two](sub/two.md)\n", "unexpected line"), + ("# Part\n\n* [One](one.md)\n # Sub\n", "unexpected line"), + ], +) +def test_summary_rejects_entries_it_cannot_nest(index, error): + with pytest.raises(ValueError, match=error): + book.summary(index, CHAPTERS) + + +def test_summary_rejects_a_nested_chapter_listed_twice(): + with pytest.raises(ValueError, match="repeats a chapter"): + book.summary( + "# Part\n\n* [One](one.md)\n * [Two](sub/two.md)\n * [Again](one.md)\n", + CHAPTERS, + ) + + +def test_summary_rejects_a_nested_entry_that_is_not_a_chapter(): + with pytest.raises(ValueError, match="not a chapter"): + book.summary("# Part\n\n* [One](one.md)\n * [Gone](gone.md)\n", CHAPTERS) + + @pytest.mark.parametrize( "line, error", [ @@ -120,6 +200,31 @@ def test_check_rejects_a_page_without_a_type_status_or_stale_after(text, error): book.check("one.md", text) +def test_a_notebooks_frontmatter_is_the_raw_cell_that_opens_it(): + head = "---\ntype: Chapter\nstatus: stable\n---" + text = notebook(raw_cell(head), MARKDOWN_CELL) + assert book.notebook_frontmatter(text) == (head, notebook(MARKDOWN_CELL)) + book.check("three.ipynb", text) + + +@pytest.mark.parametrize( + "cells", + [ + [MARKDOWN_CELL], + [MARKDOWN_CELL, raw_cell("---\ntype: Chapter\nstatus: stable\n---")], + [raw_cell("---\ntype: Chapter\nstatus: stable\n---\n\nMore.\n"), MARKDOWN_CELL], + ], +) +def test_check_rejects_a_notebook_that_opens_without_frontmatter(cells): + with pytest.raises(ValueError, match="three.ipynb: no type"): + book.check("three.ipynb", notebook(*cells)) + + +def test_check_rejects_a_notebook_that_is_not_json(): + with pytest.raises(ValueError, match="three.ipynb: Expecting value"): + book.check("three.ipynb", "# Three\n") + + def test_assembly_skips_reserved_files_at_any_level(tmp_path): root, out = tmp_path / "root", tmp_path / "root" / "src" (root / "docs" / "sub").mkdir(parents=True) @@ -286,3 +391,19 @@ def fail(*args, **kwargs): with pytest.raises(OSError): book.assemble(root) assert (out / ".gitignore").read_text() == "*\n" + + +def test_assembly_makes_chapters_of_notebooks_without_their_frontmatter(tmp_path): + root, out = tmp_path / "root", tmp_path / "root" / "src" + (root / "docs" / ".ipynb_checkpoints").mkdir(parents=True) + (root / "README.md").write_text("# Intro\n") + (root / "docs" / "index.md").write_text("# Part\n\n* [Three](three.ipynb)\n") + head = "---\ntype: Chapter\nstatus: stable\n---" + (root / "docs" / "three.ipynb").write_text(notebook(raw_cell(head), MARKDOWN_CELL)) + # Jupyter's autosaves are neither chapters nor part of the book. + checkpoint = root / "docs" / ".ipynb_checkpoints" / "three-checkpoint.ipynb" + checkpoint.write_text(notebook(MARKDOWN_CELL)) + book.assemble(root) + assert (out / "three.ipynb").read_text() == notebook(MARKDOWN_CELL) + assert "- [Three](three.ipynb)\n" in (out / "SUMMARY.md").read_text() + assert not (out / ".ipynb_checkpoints").exists() diff --git a/contrib/test_jupyter_nb.py b/contrib/test_jupyter_nb.py new file mode 100644 index 0000000..002d171 --- /dev/null +++ b/contrib/test_jupyter_nb.py @@ -0,0 +1,33 @@ +import json + +import jupyter_nb + +NOTEBOOK = {"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# Nb\n"]}]} + + +def chapter(path, content, sub_items=()): + return {"Chapter": {"path": path, "source_path": path, "content": content, "sub_items": list(sub_items)}} + + +def test_chapters_skip_separators_and_part_titles(): + items = [ + {"PartTitle": "Part"}, + chapter("one.md", "", [chapter("sub/two.md", "")]), + "Separator", + chapter("three.md", ""), + ] + assert [c["path"] for c in jupyter_nb.chapters(items)] == ["one.md", "sub/two.md", "three.md"] + + +def test_links_to_notebook_chapters_point_at_their_md_path(monkeypatch, capsys): + items = [ + chapter("nb.ipynb", json.dumps(NOTEBOOK)), + "Separator", + chapter("sub/page.md", "[a](../nb.ipynb#x) [b](other.ipynb)\n\n[c]: ../nb.ipynb\n"), + ] + monkeypatch.setattr("sys.argv", ["jupyter_nb.py"]) + monkeypatch.setattr("sys.stdin", __import__("io").StringIO(json.dumps([{}, {"items": items}]))) + jupyter_nb.main() + out = json.loads(capsys.readouterr().out)["items"] + assert out[0]["Chapter"]["content"] == "# Nb\n" + assert out[2]["Chapter"]["content"] == "[a](../nb.md#x) [b](other.ipynb)\n\n[c]: ../nb.md\n" diff --git a/cspell.json b/cspell.json index c90a361..4032acd 100644 --- a/cspell.json +++ b/cspell.json @@ -20,10 +20,15 @@ "fonts", "python", "networking-terms", + "author-names", "bitcoin-privacy", "repo-tooling" ], "dictionaryDefinitions": [ + { + "name": "author-names", + "path": "./cspell/author-names.txt" + }, { "name": "bitcoin-privacy", "path": "./cspell/bitcoin-privacy.txt" diff --git a/cspell/author-names.txt b/cspell/author-names.txt new file mode 100644 index 0000000..9aa4a2d --- /dev/null +++ b/cspell/author-names.txt @@ -0,0 +1,51 @@ +# Author names +AdamISZ +Alpern +Androulaki +Capkun +Claessens +Danezis +Dorier +Dwork +Elkind +Ghesmati +Gierlichs +Goldfeder +Haslhofer +Havar +Judmayer +Kalodner +Kappos +Karame +Keidar +Kelen +Kleppmann +Kogias +Kogman +Kokoris +Levchenko +Maurer +Meiklejohn +Möser +Naor +Neudecker +Paverd +Pomarole +Poupko +Preneel +Reisman +Roeschlin +Rollet +Sabouri +Serjantov +Seys +Shmatikov +Stifter +Stockmeyer +Stütz +Syverson +Troncoso +Verbauwhede +Voelker +Weippl +Yousaf diff --git a/cspell/bitcoin-privacy.txt b/cspell/bitcoin-privacy.txt index 16c9b72..a842581 100644 --- a/cspell/bitcoin-privacy.txt +++ b/cspell/bitcoin-privacy.txt @@ -1,6 +1,7 @@ # Bitcoin and privacy vocabulary blockspace CoinJoin +CoinSwap deanonymization deanonymize CLTV @@ -13,18 +14,97 @@ HTLCs keytype locktime Merkle +Merklized MuSig Payjoin +permissioned permissionless preimages PSBT PSBTs pubkeys RIPEMD +Samourai scriptSig scriptWitness sighash +sneakernet taptree unlinkability +unlinkable UTXO xpub +backout +feerates +locktimes +# Cited journals +Academiae +Scientiarum +Hungaricae +# Network science +assortativity +deanonymizes +multiroute +superconcentrator +# Cited authors +Chekuri +Idleman +Karrer +Kishimoto +Maurer +Neudecker +Orlin +multiset +satisfice +satisficing +sumset +coindays +precomputation +Blocklace +CoinSwap +Merklized +permissioned +Samourai +sneakernet +unlinkable +deanonymizing +Bustapay +CIOH +counterfactually +entropist +fingerprintable +multigraph +NSNR +payjoins +KVACs +minrelayfee +multisignature +standardness +unaddressable +vbyte +vbytes +WabiSabi +wtxid +# Cryptography +HPKE +# Mathematics +elementwise +unioning +# Game theory +rivalrous + +# Concurrent PSBT construction +ANYONECANPAY +CRDT +globalseed +joinpsbts +keydata +kickstarter +nlocktime +psbtv +reserialization +txns +unioned +unrepresentable +unshuffled +valuedata diff --git a/cspell/tooling.txt b/cspell/tooling.txt index 32ceda8..7dc7a70 100644 --- a/cspell/tooling.txt +++ b/cspell/tooling.txt @@ -1,15 +1,21 @@ # Repository tools, identifiers, and upstream authors +ambs +atmd cacheprovider +capsys DejaVu devshell DNSSEC dontInstall dylanowen +encs fileset foldl fontconfig Graphviz +ipynb KaTeX +linkpred lzanini mdBook mmdc @@ -23,4 +29,5 @@ PyYAML stdenv svgs toplevel +txni unfetched diff --git a/docs/Denominations_and_gap_size_distributions.ipynb b/docs/Denominations_and_gap_size_distributions.ipynb new file mode 100644 index 0000000..6cdc8fa --- /dev/null +++ b/docs/Denominations_and_gap_size_distributions.ipynb @@ -0,0 +1,1537 @@ +{ + "cells": [ + { + "cell_type": "raw", + "metadata": {}, + "source": [ + "---\n", + "type: concept\n", + "title: Small Hamming Weight Denominations for CoinJoins\n", + "status: draft\n", + "stale_after: 2027-01-23T00:00:00Z\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Small Hamming Weight Denominations for CoinJoins\n", + "\n", + "Standardizing on a small set of denominations has advantages, among other use cases, for privacy in CoinJoin transactions. Instead of creating a single output for an arbitrary amount, a wallet can approximate the amount from below by a sum of standard denominations, and create one output for each denomination in the sum. Each of these outputs is less linkable to the input cluster that funded it.\n", + "\n", + "The fewer denominations there are to choose from, the more likely it is that more than one user chooses any given denomination, which improves privacy. The cost is that more outputs are needed to represent a given balance.\n", + "\n", + "With too few denominations, the approximations also get worse. This notebook quantifies that trade-off. It takes denominations with Hamming weight 1, meaning values with a single nonzero digit in some base, such as powers of 2. It then measures the gaps between consecutive sums of up to $k$ such denominations. There are only $O(\\log n)$ such values up to $n$ sats.\n", + "\n", + "## Sub-transaction model and implications for privacy\n", + "\n", + "In the sub-transaction model ([1](https://m.flrn.cc/academic/2017_CoinJoin.pdf), [2](https://medium.com/@laurentmt/introducing-boltzmann-85930984a159)), for every repeated value with multiplicity $m$ in the inputs or the outputs of a sub-transaction mapping as a whole, $m!$ equivalent mappings can be obtained by permutation. Permuting coins of equal value does not change the sum of any sub-transaction, so it preserves the defining property of a sub-transaction: that its inputs minus its outputs sum to (approximately) zero. Permutations within a single sub-transaction do not change which sub-transaction any coin is assigned to, so they yield no new mappings.\n", + "\n", + "In base 2, a value with multiplicity 2 within a single sub-transaction is exchangeable with the next denomination up from some other sub-transaction. Base 3 and 10 have somewhat more complex arithmetic relationships which imply yet more permutations of subsets of coins.\n", + "\n", + "If an arbitrary output value (i.e. with large Hamming weight) can be constructed -- or more generally than in Maurer et al, approximated -- by summing together $k$ distinct denominations, and each of which has multiplicity $m$ in the outputs of the sub-transaction mapping as a whole, then the number of equivalent mappings is $k \\times m!$. This counts permutations over sets of subsets of outputs, specifically when a subset of size $k$ is exchanged with a subset of size $1$.\n", + "\n", + "Although this preserves the nominal sum of the sub-transaction, its weight, and therefore its implied fee rate, will differ. A high variance in the implied fee rates of sub-transactions is less likely, so unlike 1:1 exchanges, k:1 exchanges are not perfectly symmetric. Here a sub-transaction's implied fee rate is the nominal sum of its inputs minus that of its outputs, divided by the weight of the sub-transaction. Users who attempt to recover every last sat are more susceptible to such analysis.\n", + "\n", + "A partition of the inputs and outputs is only a valid sub-transaction mapping if each part's outputs balance its inputs. When the coins form a dense subset sum instance, almost any group of inputs can be balanced by many groups of outputs, and vice versa. With multiplicities high enough that no single sub-transaction uses every copy of a denomination, the remaining coins stay dense after any one sub-transaction is set aside, so the same holds for the rest of the transaction. Every input and output therefore appears in many distinct sub-transactions across all non-derived mappings.\n", + "\n", + "## Radix CoinJoin\n", + "\n", + "It follows that a logarithmic (in the range of values) number of small Hamming weight values with non-trivial multiplicity, taken from a geometric progression, can provide cover for any number of arbitrary valued inputs and outputs. Larger Hamming weight values with multiplicity 1 can of course contribute to subset sum density, but a geometric progression with high multiplicity is much more robust and trivial to analyze.\n", + "\n", + "Ignoring any hypothetical UTXO sharing, the anonymity set size of a CoinJoin transaction is constrained by the number of inputs or the number of outputs (the smaller of the two). Even if the estimated number of distinct sub-transactions in which a coin appears is very large, this only means that the sub-transaction mappings will not be the limiting constraint on anonymity set size for this coin. Therefore even loose lower bounds on this value are sufficient in practice.\n", + "\n", + "## Mixed bases and preferred values\n", + "\n", + "If using only a single base, when a small fee cost is subtracted from a single denomination this will result in a remaining balance with a large Hamming weight in that base. To get around this to some extent, values from multiple bases can be used. Additionally, not all Hamming weight 1 values are required, a [preferred value series](https://en.wikipedia.org/wiki/Preferred_number) can approximate values well with a smaller number of denominations.\n", + "\n", + "Currency conversions often result in excessively precise bitcoin amounts. In some base $b$, a value $v$ will have expected weight $\\frac{(b-1) \\log_b v}{b}$. Values which have a small weight in one base usually have a large weight in another, in particular bases 2 and 3. The result of subtracting a value with weight 1 in base 3 from a value with a large weight in base 2 can often have a weight that is smaller by more than 1 (but it may also be higher).\n", + "\n", + "Concretely, the 1-2-5 series in base 10 is useful for representing values with a decimal bias. Base 2 and 3 are suitable for decomposing arbitrary values with a high decimal Hamming weight. They are also complementary to each other: the 1-2 series in base 3 has a high Hamming weight in base 2 and powers of 2 have a high Hamming weight in base 3. These additional values also improve the overall density, reducing the sizes of combinations required for good approximations. Beyond this, additional denominations provide diminishing returns.\n", + "\n", + "As we will see in detail, allowing more outputs improves the density of representable values. Coverage is denser in the interior of the range and becomes sparser towards the upper end, where combinations are limited by the largest available denomination. Raising this denomination limit can improve coverage in the upper region, but does not fill existing gaps between smaller values. With the parameters used here, some gaps still exceed the dust threshold even with six outputs.\n", + "\n", + "This python implementation is optimized for simplicity, not performance or memory use, and the nature of this problem lends itself to precomputation. In an optimized implementation it's possible to exhaustively enumerate all possibilities even as part of an online computation. This is worth noting because for privacy choosing uniformly at random between an unbiased selection of acceptable choices is better than always picking the best choice according to the cost function. A black box optimization approach may introduce such a bias depending on the cost function." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Parameters\n", + "\n", + "The minimal feerate can be controlled in order to vary the dust threshold." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "tags": [ + "show-input" + ] + }, + "outputs": [], + "source": [ + "# bitcoin network parameters\n", + "max_sats = 2099999997690000\n", + "dust_feerate = 3.0\n", + "expected_feerate = 10.0\n", + "min_vbytes = 98 # 294 sats @ 3 sat/vb for p2wpkh per https://bitcoin.stackexchange.com/a/41082\n", + "dust = int(min_vbytes * dust_feerate)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will generate denominations from the dust threshold to some maximum value. Setting a large `max_denom` smooths the gap distribution and emphasizes the gaps between the larger magnitude values, which tend to have smaller relative differences. `max_combination_value` cuts the sums off at a multiple of `max_denom`, because larger sums are less informative. A sum above $c$ times `max_denom` needs more than $c$ terms, since no term exceeds `max_denom`, so it effectively has fewer than $k$ free terms and the sumset is sparse there." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "tags": [ + "show-input" + ] + }, + "outputs": [], + "source": [ + "# denomination parameters\n", + "min_denom = dust\n", + "max_denom = int(1e8) # reducing this reveals some interesting structure in the plots below\n", + "max_combination_size = 6 # 7 is slow but doable, and consumes lots of ram for larger values of max_denom with this naive implementation. results are not very interesting, median gap size is 1 sat.\n", + "max_combination_value = max_denom * 2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The final parameters set a cutoff for the smallest gaps. The smallest possible gap is of size 1. Setting a higher cutoff omits negligible gaps (e.g. below `dust`) improving readability of the individual histograms with regard to larger gaps. Low values aid in comparing between sumset degrees." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "tags": [ + "show-input" + ] + }, + "outputs": [], + "source": [ + "# analysis parameters\n", + "min_diff = 2 # setting to dust hides small gaps, focusing on more significant ones\n", + "min_diff_ratio = 0 # 1e-4 is a basis point" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Generate denominations" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# import boilerplate\n", + "from math import comb, log, ceil\n", + "\n", + "from itertools import combinations_with_replacement, product\n", + "\n", + "import pandas as pd\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "import numpy as np\n", + "\n", + "# theme-neutral plot style: reads on light and dark mdbook themes\n", + "plt.rcParams.update({\n", + " \"savefig.transparent\": True,\n", + " \"figure.facecolor\": \"none\",\n", + " \"axes.facecolor\": \"none\",\n", + " \"savefig.facecolor\": \"none\",\n", + " \"text.color\": \"#888888\",\n", + " \"axes.labelcolor\": \"#888888\",\n", + " \"axes.edgecolor\": \"#888888\",\n", + " \"axes.titlecolor\": \"#888888\",\n", + " \"xtick.color\": \"#888888\",\n", + " \"ytick.color\": \"#888888\",\n", + " \"grid.color\": \"#888888\",\n", + " \"legend.labelcolor\": \"#888888\",\n", + " \"axes.spines.top\": False,\n", + " \"axes.spines.right\": False,\n", + " \"legend.frameon\": False,\n", + "})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Denominations are based on [preferred value series](https://en.wikipedia.org/wiki/Preferred_number) in base 2, 3, and 10." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "tags": [ + "show-input" + ] + }, + "outputs": [], + "source": [ + "# helper functions\n", + "def powers(b: int) -> set[int]:\n", + " \"\"\"\n", + " Generates the powers of the given base up to the maximum denomination.\n", + " Smaller powers are kept, since a multiple of one may still be large enough.\n", + " \"\"\"\n", + " return { b**i for i in range(int(log(max_denom)/log(b))+1) }\n", + "\n", + "def multiples(vs: set[int], cs: set[int]) -> set[int]:\n", + " \"\"\"\n", + " Computes the products of pairs of values from two sets.\n", + " \"\"\"\n", + " return { c*v for (c,v) in product(cs,vs) if c*v in range(min_denom, max_denom+1) }" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "tags": [ + "show-input" + ] + }, + "outputs": [], + "source": [ + "# denominations of different bases\n", + "binary = multiples(powers(2), {1})\n", + "ternary = multiples(powers(3), {1,2})\n", + "decimal = multiples(powers(10), {1,2,5})" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "tags": [ + "show-input" + ] + }, + "outputs": [], + "source": [ + "# these additional Hamming weight 2 values plug the proportionally largest gaps\n", + "# between the denominations. this has some impact on the decomposition of smaller\n", + "# values (max_denom <= 1e6 or so) and so seem appropriate for a future with a\n", + "# lower dust feerate, but marginal benefit today\n", + "\n", + "#binary = binary | multiples({3}, { 2**i for i in [ 10, 13, 15, 18 ]})\n", + "\n", + "# the addition of 3 * 2^n arguably over-represents base 2 values\n", + "# https://en.wikipedia.org/wiki/Preferred_number#Computer_engineering\n", + "\n", + "#binary = multiples(powers(2), {1,3})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The combined set of denominations is just a union of these Hamming weight 1 values in these 3 useful bases." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "tags": [ + "show-input" + ] + }, + "outputs": [], + "source": [ + "# combined denomination set\n", + "combined = binary | ternary | decimal" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "dark" + }, + "output_type": "display_data" + } + ], + "source": [ + "# denomination values\n", + "palette = {'binary': '#0072B2', 'ternary': '#E69F00', 'decimal': '#009E73', 'combined': '#D55E00'}\n", + "origin = { v: 'binary' for v in binary } | { v: 'ternary' for v in ternary } | { v: 'decimal' for v in decimal }\n", + "\n", + "combined_index = {value: index for index, value in enumerate(sorted(combined))}\n", + "\n", + "plt.figure(figsize=(8,3))\n", + "sns.scatterplot(data=pd.DataFrame([{'value': v, 'index': combined_index[v], 'set': origin[v]} for v in sorted(combined) ]), x='index', y='value', hue='set', palette=palette)\n", + "\n", + "plt.yscale('log')\n", + "plt.ylabel('sats')\n", + "plt.title('Denomination values')\n", + "plt.grid(True, which='both', alpha=0.25)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "dark" + }, + "output_type": "display_data" + } + ], + "source": [ + "# denomination set sizes\n", + "data = {\n", + " 'set': ['binary', 'ternary', 'decimal', 'combined'],\n", + " 'size': [len(binary), len(ternary), len(decimal), len(combined)],\n", + " 'color': [palette['binary'], palette['ternary'], palette['decimal'], palette['combined']]\n", + "}\n", + "df_sets = pd.DataFrame(data)\n", + "\n", + "plt.figure(figsize=(8, 2))\n", + "ax = sns.barplot(x='set', y='size', hue='set', data=df_sets, palette=palette, legend=False)\n", + "plt.xlabel('Base')\n", + "plt.ylabel('Number of denominations')\n", + "plt.title(f'Sizes of denomination base sets for values ≤ {max_denom/1e8} BTC')\n", + "\n", + "for container in ax.containers:\n", + " ax.bar_label(container, fmt='%.0f', label_type='center', color='black')\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
setvaluebinary (little endian)popcountweight (base 3)weight (base 10)
0ternary0.00000486011001111613
1decimal0.00000500001011111641
2binary0.000005120000000001143
3ternary0.000007291001101101613
4decimal0.000010000001011111641
5binary0.0000102400000000001163
6ternary0.0000145801001101101614
7decimal0.0000200000001011111641
8binary0.00002048000000000001163
9ternary0.00002187110100010001514
10binary0.000040960000000000001173
11ternary0.000043740110100010001514
12decimal0.000050000001000111001561
13ternary0.000065611000010110011614
14binary0.0000819200000000000001154
15decimal0.0001000000001000111001571
16ternary0.0001312201000010110011615
17binary0.00016384000000000000001185
18ternary0.00019683110001110011001815
19decimal0.00020000000001000111001551
20binary0.0003276800000000000000011105
21ternary0.000393660110001110011001815
22decimal0.000500000000101011000011691
23ternary0.000590491001010101100111914
24binary0.0006553600000000000000001175
25decimal0.0010000000000101011000011671
26ternary0.0011809801001010101100111915
27binary0.00131072000000000000000001195
28ternary0.001771471101111111001101011316
29decimal0.00200000000000101011000011671
30binary0.002621440000000000000000001196
31ternary0.0035429401101111111001101011316
32decimal0.0050000000000100100001011117111
33binary0.0052428800000000000000000001196
34ternary0.00531441100011111101100000011016
35decimal0.0100000000000010010000101111791
36binary0.010485760000000000000000000011106
37ternary0.010628820100011111101100000011016
38ternary0.015943231100101111001010000111117
39decimal0.020000000000000100100001011117101
40binary0.0209715200000000000000000000011116
41ternary0.0318864601100101111001010000111117
42binary0.04194304000000000000000000000011116
43ternary0.04782969100111101101111100010011417
44decimal0.0500000000000010110100100011001871
45binary0.08388608000000000000000000000001186
46ternary0.095659380100111101101111100010011417
47decimal0.10000000000000010110100100011001891
48ternary0.143489071101011001001111010110111517
49binary0.167772160000000000000000000000001198
50decimal0.2000000000000000101101001000110018121
51ternary0.2869781401101011001001111010110111518
52binary0.3355443200000000000000000000000001178
53ternary0.43046721100000101110101100001001011117
54decimal0.500000000000000100001111010111110112111
55binary0.671088640000000000000000000000000011127
56ternary0.860934420100000101110101100001001011117
57decimal1.0000000000000000100001111010111110112131
\n", + "
" + ], + "text/plain": [ + " set value binary (little endian) popcount \\\n", + "0 ternary 0.00000486 011001111 6 \n", + "1 decimal 0.00000500 001011111 6 \n", + "2 binary 0.00000512 0000000001 1 \n", + "3 ternary 0.00000729 1001101101 6 \n", + "4 decimal 0.00001000 0001011111 6 \n", + "5 binary 0.00001024 00000000001 1 \n", + "6 ternary 0.00001458 01001101101 6 \n", + "7 decimal 0.00002000 00001011111 6 \n", + "8 binary 0.00002048 000000000001 1 \n", + "9 ternary 0.00002187 110100010001 5 \n", + "10 binary 0.00004096 0000000000001 1 \n", + "11 ternary 0.00004374 0110100010001 5 \n", + "12 decimal 0.00005000 0001000111001 5 \n", + "13 ternary 0.00006561 1000010110011 6 \n", + "14 binary 0.00008192 00000000000001 1 \n", + "15 decimal 0.00010000 00001000111001 5 \n", + "16 ternary 0.00013122 01000010110011 6 \n", + "17 binary 0.00016384 000000000000001 1 \n", + "18 ternary 0.00019683 110001110011001 8 \n", + "19 decimal 0.00020000 000001000111001 5 \n", + "20 binary 0.00032768 0000000000000001 1 \n", + "21 ternary 0.00039366 0110001110011001 8 \n", + "22 decimal 0.00050000 0000101011000011 6 \n", + "23 ternary 0.00059049 1001010101100111 9 \n", + "24 binary 0.00065536 00000000000000001 1 \n", + "25 decimal 0.00100000 00000101011000011 6 \n", + "26 ternary 0.00118098 01001010101100111 9 \n", + "27 binary 0.00131072 000000000000000001 1 \n", + "28 ternary 0.00177147 110111111100110101 13 \n", + "29 decimal 0.00200000 000000101011000011 6 \n", + "30 binary 0.00262144 0000000000000000001 1 \n", + "31 ternary 0.00354294 0110111111100110101 13 \n", + "32 decimal 0.00500000 0000010010000101111 7 \n", + "33 binary 0.00524288 00000000000000000001 1 \n", + "34 ternary 0.00531441 10001111110110000001 10 \n", + "35 decimal 0.01000000 00000010010000101111 7 \n", + "36 binary 0.01048576 000000000000000000001 1 \n", + "37 ternary 0.01062882 010001111110110000001 10 \n", + "38 ternary 0.01594323 110010111100101000011 11 \n", + "39 decimal 0.02000000 000000010010000101111 7 \n", + "40 binary 0.02097152 0000000000000000000001 1 \n", + "41 ternary 0.03188646 0110010111100101000011 11 \n", + "42 binary 0.04194304 00000000000000000000001 1 \n", + "43 ternary 0.04782969 10011110110111110001001 14 \n", + "44 decimal 0.05000000 00000010110100100011001 8 \n", + "45 binary 0.08388608 000000000000000000000001 1 \n", + "46 ternary 0.09565938 010011110110111110001001 14 \n", + "47 decimal 0.10000000 000000010110100100011001 8 \n", + "48 ternary 0.14348907 110101100100111101011011 15 \n", + "49 binary 0.16777216 0000000000000000000000001 1 \n", + "50 decimal 0.20000000 0000000010110100100011001 8 \n", + "51 ternary 0.28697814 0110101100100111101011011 15 \n", + "52 binary 0.33554432 00000000000000000000000001 1 \n", + "53 ternary 0.43046721 10000010111010110000100101 11 \n", + "54 decimal 0.50000000 00000001000011110101111101 12 \n", + "55 binary 0.67108864 000000000000000000000000001 1 \n", + "56 ternary 0.86093442 010000010111010110000100101 11 \n", + "57 decimal 1.00000000 000000001000011110101111101 12 \n", + "\n", + " weight (base 3) weight (base 10) \n", + "0 1 3 \n", + "1 4 1 \n", + "2 4 3 \n", + "3 1 3 \n", + "4 4 1 \n", + "5 6 3 \n", + "6 1 4 \n", + "7 4 1 \n", + "8 6 3 \n", + "9 1 4 \n", + "10 7 3 \n", + "11 1 4 \n", + "12 6 1 \n", + "13 1 4 \n", + "14 5 4 \n", + "15 7 1 \n", + "16 1 5 \n", + "17 8 5 \n", + "18 1 5 \n", + "19 5 1 \n", + "20 10 5 \n", + "21 1 5 \n", + "22 9 1 \n", + "23 1 4 \n", + "24 7 5 \n", + "25 7 1 \n", + "26 1 5 \n", + "27 9 5 \n", + "28 1 6 \n", + "29 7 1 \n", + "30 9 6 \n", + "31 1 6 \n", + "32 11 1 \n", + "33 9 6 \n", + "34 1 6 \n", + "35 9 1 \n", + "36 10 6 \n", + "37 1 6 \n", + "38 1 7 \n", + "39 10 1 \n", + "40 11 6 \n", + "41 1 7 \n", + "42 11 6 \n", + "43 1 7 \n", + "44 7 1 \n", + "45 8 6 \n", + "46 1 7 \n", + "47 9 1 \n", + "48 1 7 \n", + "49 9 8 \n", + "50 12 1 \n", + "51 1 8 \n", + "52 7 8 \n", + "53 1 7 \n", + "54 11 1 \n", + "55 12 7 \n", + "56 1 7 \n", + "57 13 1 " + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# denominations table\n", + "\n", + "def hamming_weight(n, base):\n", + " \"\"\"Calculates the Hamming weight of n in a given base.\"\"\"\n", + " if n == 0:\n", + " return 0\n", + " weight = 0\n", + " while n > 0:\n", + " weight += n % base != 0\n", + " n //= base\n", + " return weight\n", + "\n", + "pd.DataFrame([{\n", + " 'set': origin[x],\n", + " 'value': \"{0:.8f}\".format(x/1e8),\n", + " 'binary (little endian)': \"{0:b}\".format(x)[::-1],\n", + " 'popcount': bin(x).count('1'),\n", + " 'weight (base 3)': hamming_weight(x, 3),\n", + " 'weight (base 10)': hamming_weight(x, 10)\n", + " } for x in sorted(combined) ])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Generate sumsets\n", + "\n", + "`{0}` is unioned with the denominations in order to obtain the sumsets from combinations of size $\\leq k$ as opposed to $=k$." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "tags": [ + "show-input" + ] + }, + "outputs": [], + "source": [ + "# compute sumsets naively\n", + "\n", + "sumsets = []\n", + "for k in range(1, max_combination_size+1):\n", + " subsets = combinations_with_replacement({0} | combined, k)\n", + " sumset = { s for s in map(sum, subsets) if s in range(1,max_combination_value+1) }\n", + " sumsets.append(np.array(sorted(sumset)))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "# (fail to) compute sumsets more efficiently\n", + "import numpy as np\n", + "from numpy.fft import fft, ifft\n", + "from math import log2\n", + "\n", + "def sumset_k_fft(nums, k):\n", + " \"\"\"\n", + " Compute sumset via FFT, same as above but supposedly faster\n", + " \"\"\"\n", + " nums = np.array(sorted(nums))\n", + " max_sum = np.max(nums) * k\n", + " poly = np.zeros(2**ceil(log2(max_sum)))\n", + " poly[nums] = 1\n", + " F = fft(poly)\n", + " Fk = F ** k\n", + " result = np.rint(ifft(Fk).real).astype(int)\n", + " sums = np.where(result > 0)[0]\n", + " sums = sums[(sums >= min_denom) & (sums <= max_combination_value)]\n", + " return sums\n", + "\n", + "# this is actually slower, so don't do it\n", + "#sumsets = [sumset_k_fft({0} | combined, k) for k in range(1, max_combination_size+1)]" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# compute gaps naively\n", + "# gaps = [np.array([ d for d in (b - a for a,b in zip(s, s[1:])) if min_diff <= d ]) for s in sumsets]" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "tags": [ + "show-input" + ] + }, + "outputs": [], + "source": [ + "# compute gaps efficiently\n", + "gaps = []\n", + "for s in sumsets:\n", + " diffs = np.diff(s)\n", + " gaps.append(diffs[diffs >= min_diff])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For the relative gap size, omit gaps below the dust threshold. These gaps are negligible and unrecoverable (since an additional output has a cost), and are therefore noise. To improve clarity of the plots they are filtered out of the relative differences." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "# compute normalized gaps naively\n", + "#relative_gaps = [np.array([ p for d, p in ((b-a, (b-a)/b) for a,b in zip(s, s[1:])) if dust <= d and min_diff_ratio <= p ]) for s in sumsets]" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "tags": [ + "show-input" + ] + }, + "outputs": [], + "source": [ + "# compute normalized gaps efficiently\n", + "\n", + "relative_gaps = []\n", + "for s in sumsets:\n", + " diffs = np.diff(s)\n", + " relative_diffs = diffs / s[1:]\n", + " mask = (diffs >= dust) & (relative_diffs >= min_diff_ratio)\n", + " relative_gaps.append(relative_diffs[mask])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Plots" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "# dataframe boilerplate\n", + "\n", + "all_gaps_data = np.concatenate(gaps)\n", + "all_gaps_k_values = np.concatenate([np.full(len(g_arr), i + 1) for i, g_arr in enumerate(gaps)])\n", + "df_gaps = pd.DataFrame({'d': all_gaps_data, 'k': all_gaps_k_values})\n", + "\n", + "all_rel_gaps_data = np.concatenate(relative_gaps)\n", + "all_rel_gaps_k_values = np.concatenate([np.full(len(rg_arr), i + 1) for i, rg_arr in enumerate(relative_gaps)])\n", + "df_rel_gaps = pd.DataFrame({'r': all_rel_gaps_data, 'k': all_rel_gaps_k_values})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Gaps" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Count and sizes\n", + "\n", + "Here we compare the gaps (ignoring gaps of size 1) of the sumsets of different degrees. As larger combinations are permitted the number of distinct sums grows and with them the number of gaps between these sums. Because these values are all in a fixed range, the sizes of the more numerous gaps of sumsets of higher degrees are of course smaller.\n", + "\n", + "Note that for $k \\in \\{1, 6\\}$ the scatterplots are a little misleading. For $k=1$ there aren't that many distinct values, so even though these values are smoothly distributed the quantile values aren't. For $k=6$ several quantiles of the sumset are entirely gaps of size 1. The plot omits those gaps, so its lowest several quantiles are 2 and the next several are 3. The spacings of these in the scatter plot are a visual artifact arising from plotting integer values." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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VIthwNJYJmm8934b59wnYZA2Plye267bs2rAq865swC89+cAcWCyc+7ycNlfgKOAH2EBxFHAS865P+Z24L0/BPjEe7868DlwKPBr59wj4foGLGhpVy6zFvrQe386FjQeXbC8H/Ab59z74X4vAv60kN3+BnjbOXdyeP9t7/06wKkFx/2MBYO9C733OwN7Af8tWP4JljXMhvsJsGDt8naOvSLwd+fcW+H9d9trZGE3UO/9P7GAbaNw0b5YEHtYLnvnvT8YmI4FwA+3t99KpEBNRERERKqCc+5T7/025IOy8d77A4HrwvsfANu01S2ym7xW0JYW7/0UrDtkzqTw59Lhzw2Abb3337axr1WAQUB/YELBfqd6799eWCO899sCfwTGAEtg5/QDvfdDnHO5oiOzckFa6IuCdrVlDeD5omX/KzpuLRac7gP8ABgQ3ooLnTxX1M1xAnCS977WOdfSxrHPA64I38tHgduK2v493vsjsCB384LgbQNgVWCG975w84HY611V1PVRRERERKqGc+4TLDvyARacPcOCQdonPXj44u542cJlBcFJTcHPe7GuhIW31YAngUhnG+C9Xwmrgvg6sCcWnBwTru63iLYu7HiRcJviZYVOwjJjf8O6W66LdfdcrG6FzrkEsDaQCvc70Xu/e3vbh8H6hVgm8tWCVTVY18x1i26rAzcuThvLQRk1EREREakqYXfHA7EgLefAHg7SuuIlLJjKOOeai1d679/DAqpNgI/DZUtigcUT7exzQ+wc/iTnXGv4mL27oa1vAbu0caxCWwJ3O+euD49bgwWdbxZtt0kb999tJ5sGgHPuHeAd4Hzv/U1YsZS7irfz3q8K3IEVMbmzaPVLWLbvK+fcN+0dq1ooUBMRERGRqhKOSbuuaPF1uTFr5WhTOy4GDgdu8t7/HStEsio2lupw59y33vsrgb+H3SgnYQU8Wheyz/exc/jfeu/vBTbHxpctrkuBE731GbwSy0QdFK7LZdreA/b03m8GTANOBEbz/UBtBe/9eeE+1wd+i2Xjvsd7PwgrqHI78CFWIGQjLBhra9t7seIsl3nvR+fWOee+xIqSnAzc7b3/EzbWb0Wsoubfe7BLbI9Q10cRERERqRpFhUM+wAKVXDfI8cXVIMvJOfc51r5arIvg68A/sUInuWDsZKwb5D3Y+Kynse577e3zFSxAcuH+DgBO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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "dark" + }, + "output_type": "display_data" + } + ], + "source": [ + "gap_sizes = list(map(len, gaps))\n", + "gap_sizes_larger_than_dust = list(map(lambda x: max(len(x),1), [ [x for x in s if dust <= x] for s in gaps ]))\n", + "ks = list(range(1, max_combination_size + 1))\n", + "\n", + "fig, ax1 = plt.subplots(figsize=(8, 4))\n", + "\n", + "ax1.set_xlabel('Combination Size (k)')\n", + "ax1.tick_params(axis='y')\n", + "ax1.set_xticks(ks)\n", + "ax1.grid(axis='y', alpha=0.25)\n", + "ax1.set_yscale(\"log\")\n", + "\n", + "ax1.plot(ks, gap_sizes, label=\"# gaps\")\n", + "ax1.plot(ks, gap_sizes_larger_than_dust, label=f\"# gaps ≥ dust ({dust})\")\n", + "\n", + "mean_gap_sizes = df_gaps.groupby('k')['d'].mean()\n", + "median_gap_sizes = df_gaps.groupby('k')['d'].median()\n", + "num_quantiles = 20\n", + "quantiles = df_gaps.groupby('k')['d'].quantile([i/num_quantiles for i in range(1, num_quantiles)])\n", + "\n", + "ax1.plot(ks, mean_gap_sizes.values, label='mean gap size')\n", + "\n", + "ax1.scatter(ks, median_gap_sizes.values, color='#888888', marker='x', label='median gap size')\n", + "\n", + "for i in range(1, num_quantiles):\n", + " if i == num_quantiles // 2: # skip median, plotted separately above\n", + " continue\n", + " quantile_values = quantiles.loc[(slice(None), i/num_quantiles)].values\n", + " ax1.scatter(ks, quantile_values, marker='.', color='#888888', alpha=0.2, label=f'i×{100 // num_quantiles}-th percentile' if i == 1 else None)\n", + "\n", + "fig.suptitle('Gaps by Combination Size', y=1.05)\n", + "fig.legend(loc=\"lower left\", bbox_to_anchor=(1,1), bbox_transform=ax1.transAxes)\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Gap sizes distribution\n", + "\n", + "The next two plots show the gaps in more detail, both their sizes and their sizes in relation to the next larger value. When decomposing into low Hamming weight values, the total balance being decomposed may fall in one of these gaps. The distribution of their sizes bounds the loss from the decomposition. Here too small integer values create visual artifacts, the empty bins for $k>3$ are empty because the populated bins interspersing them correspond to successive integer values." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "bins = 300" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "dark" + }, + "output_type": "display_data" + } + ], + "source": [ + "min_gap = df_gaps['d'].min()\n", + "gap_bins = np.logspace(np.log10(min_gap), np.log10(df_gaps['d'].max()), bins)\n", + "g_abs_hist_binned = sns.FacetGrid(df_gaps, col='k', col_wrap=1, height=1.7, aspect=6)\n", + "g_abs_hist_binned.map(plt.hist, 'd', bins=gap_bins)\n", + "g_abs_hist_binned.set(xscale=\"log\", yscale=\"log\")\n", + "g_abs_hist_binned.fig.suptitle(f'Gap sizes ≥ {min_gap} sats', y=1.05)\n", + "for i, ax in enumerate(g_abs_hist_binned.axes.flat):\n", + " k = i+1\n", + " ax.grid(True, which='both', alpha=0.25)\n", + " if min_diff < dust:\n", + " ax.axvline(x=dust, color='#888888', linestyle='--', label=f'dust ({dust} sats = {min_vbytes} vB × {dust_feerate} sat/vB)')\n", + " ax.axvline(x=k*dust, color='orange', linestyle='--', label='k × dust')\n", + " ax.axvline(x=k*(expected_feerate * min_vbytes), color='red', linestyle='--', label=f'k × {min_vbytes} vB × {expected_feerate} sat/vB')\n", + " if i == 0:\n", + " ax.legend()\n", + " ax.secondary_xaxis('top').spines['top'].set_visible(False)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Relative gap size\n", + "\n", + "The next plot displays gaps larger than the dust threshold as a fraction of the larger value. No quantization artifacts arise in this plot, but there is a cutoff imposed by dividing by values no larger than the maximum combination value." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "dark" + }, + "output_type": "display_data" + } + ], + "source": [ + "ratio_bins = np.logspace(np.log10(df_rel_gaps['r'].min()), np.log10(df_rel_gaps['r'].max()), bins)\n", + "g_ratio_hist_binned = sns.FacetGrid(df_rel_gaps, col='k', col_wrap=1, height=1.5, aspect=7)\n", + "g_ratio_hist_binned.map(plt.hist, 'r', bins=ratio_bins)\n", + "g_ratio_hist_binned.set(xscale=\"log\", yscale=\"log\")\n", + "g_ratio_hist_binned.fig.suptitle(f'Relative gap sizes (b-a)/b ≥ {min_diff_ratio} for gaps (a,b) where (b-a) ≥ {dust}', y=1.05)\n", + "for i, ax in enumerate(g_ratio_hist_binned.axes.flat):\n", + " ax.grid(True, which='both', alpha=0.25)\n", + " ax.axvline(x=1e-4, color='#888888', linestyle='--', label='1‱')\n", + " ax.axvline(x=1e-2, color='red', linestyle='--', label='1%')\n", + " if i == 0:\n", + " ax.legend()\n", + " ax.secondary_xaxis('top').spines['top'].set_visible(False)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Sums and combinations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Density of distinct sums\n", + "\n", + "The next plot shows the density of distinct sums in the integers. The previous plots show the gap sizes over the entire range, but not all balances decompose as readily, and towards the end of the range the density tapers off (see `max_combination_value` parameter). The initial ramp up is determined by the size of the smallest denomination (see also `dust_feerate` parameter).\n", + "\n", + "This plot gives a clearer indication of the expected loss as a function of the balance being decomposed into a sum of standard values. The distinct constructible sums are assigned into bins (ranges of natural numbers). To plot each bin, this number of distinct values is divided by the size of the bin (number of distinct values, or difference between smallest and largest values).\n", + "\n", + "A density of 1 implies every possible integer value in the bin can be constructed exactly, and a density $\\geq\\mathrm{dust}^{-1}$ means every value can be approximated from below with error smaller than the dust threshold.\n", + "\n", + "More intuitively, anything above the dashed line means values can be well approximated often enough that the loss is on average negligible (the cost of an additional output will be higher even at the minimum relay fee). The difference in costs will be linear in $k$, smaller combinations are more efficient representations of a given value but concrete efficiency depends on the feerate, and at higher feerates." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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zj3I8+cemNgVBrGvR2ZPYJXa9JjiZNtNik/bnYquM60k65ogCBvDet6S/gfgL4AngApwF9FS+y8Abx2da8JGcPPNN8+88Y1v3PuhD31o8dWvfnXupg579+7tFU6hXvziF3PrbTfnCjz22GP69a9//d4//MM/PDU7Oyt7EgmCIEwYdVvmKysXY61GKztxk+attMJgWodUXL3jWKg1Dc+jVipRdm5D39pupbYbhq2QcV0Q1ks0vmXrPaGb9exDfxr4Z0EQfA/wAqK3/H/n+/6nRu2cMF5uuOGG2Xe84x27b7nlllNXX311z1vD3XffnRtOEYbh3qmpqam88845Xvva1+593etet3LllVeG999//9YJghQEQdghhM7DWs155z/GY4+eR+i8HTEJ3AhCrblv725WVuucqlTwQJa9j5CujOvWoaVthW1CenzL1ntCmnXHMfu+/1fAX43Ql7ESBMEs8I/AH/m+/x8225/N5tZbb62cPHlSf/KTnzx51VVX9f3Gdtlll+UGK1arVWeMoXPTgzV+93d/11teXna/8Ru/sbx+jwVBEISNYHpKviWOmji2+vyZBfbNau6vPk1iq0dInHE9DiVQxnDayWJAYXuQHN917fHI3JxsvSd0MNCEPggCDbwW+FGiPegd8CDwx8DNvu9P8t3zrcDdm+3EpHD06NHwnnvuKd90002zV1555ZLuE083zJL7z372s/rLX/6ynp+f78j+/5KXvOSsH/3RH61//OMfPzVwBQRBEARhizGtGlS0fAkfB8mM63aDJ/Oh1u3JllAMCY8YjPb4lpTSQgaFh0UQBAr4BPBK4KvA1wAFPAu4iWiS/6qRezgCgiA4AjwTuBU4usnuTASHDx9uXn/99UvHjh07eM0113DjjTcu9ZIfZsn9ddddF7797W9vJ8I7fvy496pXvWr/Rz/60ade9KIXra8CgiAIwoZTtyWqVrNsFNPaTlSMvSBsBvFWddZFL0bWdmCQxINZdIVHOIc34StVkrHrgjCJDPKc57XAS4Hv9X3/08kTrXj6PwuC4Kd93//9QRwIguClwK8BLwTOA37E9/0/S8lc05I5D/gH4E2+739uADPXt8pfNYhv251nPetZ5s477zx57Nixg294wxvc+9///tzs88Msub/wwgupVCrN+O+5uTkHcMkllzQvuOAC+cQTBEHYAtRtmb9fOcxK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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "dark" + }, + "output_type": "display_data" + } + ], + "source": [ + "min_sum = min_denom\n", + "max_sum = max_combination_value\n", + "\n", + "log_bins = np.logspace(np.log10(min_sum), np.log10(max_sum), bins)\n", + "\n", + "plt.figure(figsize=(12, 5))\n", + "\n", + "colors = plt.cm.plasma(np.linspace(0, 1, max_combination_size))[::-1]\n", + "\n", + "# similar to density=True except there's no division by the total entry count,\n", + "# which allows comparing the relative densities of different combination sizes\n", + "for i in range(max_combination_size -1 , -1, -1):\n", + " k = i + 1\n", + " if len(log_bins) > 1:\n", + " counts, bin_edges = np.histogram(sumsets[i], bins=log_bins)\n", + " bin_widths = np.diff(bin_edges)\n", + " density = counts / bin_widths\n", + " plt.bar(bin_edges[:-1], density, width=bin_widths, color=colors[i], label=f'k = {k}', align='edge')\n", + " plt.stairs(density, bin_edges, color='#888888', linewidth=1)\n", + "\n", + "plt.xscale('log')\n", + "plt.yscale('log')\n", + "plt.ylim(1e-5, 1)\n", + "plt.xlabel('Binned sums (sats)')\n", + "plt.ylabel('Density per bin (count / bin width)')\n", + "plt.title(f'Density of distinct sums by combination size (k)')\n", + "plt.axhline(y=1/dust, color='#888888', linestyle='--', label=f'dust⁻¹ ({dust}⁻¹)')\n", + "\n", + "plt.axhspan(ymin=0, ymax=1/dust, facecolor='lightgrey', alpha=0.5)\n", + "\n", + "plt.legend(loc='lower left', frameon=True, facecolor='white', labelcolor='black')\n", + "plt.grid(True, which='both', alpha=0.25)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Distinct combinations vs. distinct sums\n", + "\n", + "The following plot displays the possible combinations (as opposed to the distinct sums of the previous plot), which gives an indication for how many ways of constructing a possible sum there are as the combination size increases." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "dark" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax1 = plt.subplots(figsize=(8, 5))\n", + "\n", + "ks = list(range(1, max_combination_size + 1))\n", + "# like the sumsets, count combinations of size <= k: multisets of size k drawn\n", + "# from the n denominations and 0, (n+k choose k), less the empty combination\n", + "num_combinations = [ comb(len(combined)+k, k) - 1 for k in ks ]\n", + "\n", + "\n", + "ax1.set_xlabel('Combination Size (k)', fontsize=11)\n", + "ax1.set_yscale(\"log\")\n", + "ax1.plot(ks, num_combinations, marker='.', label=f\"combinations of size ≤ k (({len(combined)}+k) choose k) − 1\")\n", + "ax1.plot(ks, list(map(len, sumsets)), marker='.', label=f\"distinct sums ≤ {max_combination_value/1e8} BTC\")\n", + "plt.axhline(y=max_combination_value, color='#888888', linestyle='--', label=f\"distinct integers ≤ {max_combination_value/1e8} BTC\")\n", + "ax1.legend()\n", + "for i, k in enumerate(ks):\n", + " ax1.text(k, num_combinations[i], f'{num_combinations[i]:,}', ha='right', va='bottom')\n", + " if k > 1:\n", + " ax1.text(k, len(sumsets[i]), f'{len(sumsets[i]):,}', ha='right', va='top')\n", + "\n", + "ax1.grid(True, which='both', alpha=0.25)\n", + "\n", + "\n", + "fig.suptitle(f'Combinations with replacement of denominations ≤ {max_denom/1e8} BTC')\n", + "\n", + "ax2 = ax1.twinx()\n", + "exponent = int(np.floor(np.log10(max_combination_value)))\n", + "mantissa = max_combination_value / (10**exponent)\n", + "def sup(n):\n", + " \"\"\"Converts an integer to a unicode superscript string.\"\"\"\n", + " superscript_map = {\n", + " '0': '⁰', '1': '¹', '2': '²', '3': '³', '4': '⁴', '5': '⁵', '6': '⁶',\n", + " '7': '⁷', '8': '⁸', '9': '⁹', '-': '⁻'\n", + " }\n", + " return ''.join(superscript_map.get(digit, digit) for digit in str(n))\n", + "ax2.set_ylabel(f'Density (y × ({mantissa:.1f} × 10{sup(exponent)}){sup(-1)})', fontsize=11)\n", + "ax2.set_yscale(\"log\")\n", + "# same scale as the left axis, divided by the size of the range\n", + "ax2.set_ylim(*(y / max_combination_value for y in ax1.get_ylim()))\n", + "\n", + "plt.show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.15" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/docs/block-dag.md b/docs/block-dag.md new file mode 100644 index 0000000..0cc2466 --- /dev/null +++ b/docs/block-dag.md @@ -0,0 +1,226 @@ +--- +type: Specification +title: Block DAG +description: The validator blocks both tracks share, with their objects, nonce commitments and equivocation evidence, genesis, causal order and frontiers. +status: draft +stale_after: 2027-04-23T00:00:00Z +--- + + + +# Block DAG + +🤖 Both tracks use the block DAG defined here. + +## Synchronizing protocol state + +The abstract state sharing requirements of [transaction construction](transaction-construction.md) can be realized by a family of related constructions. + +🤖 These constructions form a ladder of increasingly narrow special cases. Each step restricts the one before it, so every structure further down is still an instance of those above it: + +1. **Byzantine eventual consistency**: a hash-linked causal log of authenticated messages. +2. **A block DAG with cordiality**: a fixed set of validators, each block referring to $t$ blocks of the previous height. +3. **A threshold per track**: $t = n$ on the optimistic track, $t \lt n$ on the recovery track. +4. **One validator collecting**: the others acknowledge its blocks. This splits the workload within the same model, on either track. +5. **TEE attestations**: an optional extension to all blocks, which certain clients can choose to trust, even when they act as validators. + +### Byzantine eventual consistency + +The general starting point is Byzantine Eventual Consistency (BEC) by Martin Kleppmann and Heidi Howard.[^bec] In this model, messages, or transaction fragments as in our case, are committed to a [Merklized](https://en.wikipedia.org/wiki/Merkle_tree) causal log. For example, if Alice is adding an output, the output itself would be the payload of her message, and the envelope would contain references to Alice's last message, as well as the messages of other peers, referenced by hash. + +In the naive version of their protocol (they describe a more optimized version), whenever a message is received, if the receiving peer does not know what a hash in its references commits to, it will request the preimage from the peer which sent this message, and after a finite number of such recursive queries and round trips it will eventually reach a message it has already seen. Signatures on the messages authenticate their authorship, allowing messages to be relayed via intermediate peers, and for any equivocations to be detectable. If the payloads are subject to validity constraints and merging independently accepted updates preserves these constraints, as Kleppmann and Howard show, this is sufficient for *Byzantine* eventual consistency: loosely speaking, even in the presence of Byzantine nodes, honest peers will eventually converge on the same set of messages. + +For privacy-preserving transaction construction, the payload should be a list of transaction fragments delivered anonymously to the peer which constructs the message. In the general BEC construction, these messages form a directed acyclic graph (DAG), with each honest peer's messages forming a linked list which also links into the linked lists of other peers. BEC itself does not require the depths of these lists to be synchronized or bounded; the block DAG specializations below impose additional structure. + +Because in our setting they collect several state-related messages submitted by other participants, we'll call these messages blocks, in line with conventions in similar protocols. + +### Cordial miners inspired invariants + +Cordial miners[^cordial] is one of a family of so-called block DAG consensus protocols.[^dag-rider] In these protocols, a fixed set of participants, usually called validators, produce blocks that, similarly to BEC, refer to other validators' blocks, and the consensus protocol involves defining a deterministic function that produces a consistent priority order when blocks conflict, that all honest validators will agree on. The cordiality requirement is that for $n = 3f + 1$ validators, every block at height $h$ will have $t = n - f$ parent blocks with height $h - 1$. In addition to setting up the required thresholds for Byzantine fault-tolerant consistency, this also serves as a flood protection mechanism. + +By waiting to reconcile the set of fragments with neighboring peers before building a block, peers can adhere to the cordiality while minimizing the number of blocks sent overall, which is more appropriate for the goal of coming to consensus over a finite sequence of sets with minimal end-to-end latency, as opposed to maximizing throughput and minimizing confirmation latency, which is the more typical design goal for DAG consensus algorithms. + +Note that these restrictions on the structure still consist of a special case of Kleppmann and Howard's [hash-consed](https://en.wikipedia.org/wiki/Hash_consing) DAG; every block DAG structure is also a valid Byzantine eventual consistency causal log structure. Because of the validity proofs on transaction fragments, and the concurrent PSBT semantics we do not need an ordering but only a set union. + +In the optimistic track, borrowing the cordial structure and setting $t = n$ to fulfill the unanimity requirement means that under asynchrony eventual consistency is the best guarantee we could make. Under synchrony or partial synchrony, the more standard $t = 2f + 1$ lets responsive peers coordinate the recovery track. Note that in principle $t$ could be lowered further, for partition tolerance or recovery in the presence of a dishonest majority, but this is a substantial qualitative difference in guarantees and so it has not yet been explored. + +### Centralization spectrum and optional TEE-based liveness + +All participants can submit their transaction fragments to a designated validator, with all other validators' blocks simply acknowledging the designated validator's blocks. These acknowledgements can have empty payloads, concentrating collection and validation work on one peer. + +In principle, it is possible to decouple the validator role from the participant role, with one validator serving many transaction participants. That validator's blocks form a linked list. This instantiates a version of the protocol based on a trusted coordinator. Note that "trust" here is meant only with regard to liveness, not to privacy. If a coordinator is trusted with privacy, which is the norm for such services,[^trusted-coordinators] validity proofs and anonymous broadcast are little more than privacy theater. A centralized protocol where the server simply does not keep a permanent record would be strictly better because users would be informed and computational and bandwidth resources would not be pointlessly wasted, degrading reliability (which is itself a privacy concern). + +Note that centralizing the bulk of this communication and coordination work on one node does not require decoupling the validator and participant roles, nor does it confer any special privileges to this de-facto leader; on the DAG model participants which only acknowledge the blocks of a single peer, can make those acknowledgement in the form of blocks that echo the content bearing blocks with minimal communication complexity. No protocol modifications so long as this validator is still a participant in the transaction, and only the introduction of a validator that is not a participant would require these roles to be decoupled. + +Going further, a trusted execution environment (TEE) can shift trust assumptions from a participant to the hardware vendor on which the participant is running the protocol. Such a participant can produce attestations about exactly what code is being executed in the TEE enclave, which the other participants can verify. Clients could therefore accept its validation of the protocol state without trusting the operator to execute that code faithfully, instead trusting the vendor’s hardware isolation and attestation guarantees. + +The reason such an additional trust assumption may be desired in some circumstances is that it improves liveness and consistency under weaker quorum assumptions, while reducing clients’ validation work further. This does not relax the requirement for unanimous transaction signing, nor is the TEE trusted with protecting privacy; private allocations and spending authority remain with the participants and their messages must remain unlinkable. This provides an alternative path to liveness when clients are too constrained for scalable Byzantine fault tolerance, or when the conditions for Byzantine fault tolerance don't hold (for example a dishonest majority of validators). + +🤖 Peers need not make identical trust assumptions: one may accept a vendor's attestations while another validates independently. This is related to asymmetric distributed trust, which models each participant's assumptions about which combinations of peers may fail.[^asymmetric-trust] Flexible BFT provides a complementary precedent for interpreting a shared protocol transcript under different fault and timing assumptions.[^flexible-bft] These are relevant frameworks rather than proofs of this TEE construction; its guarantees depend on the chosen acceptance rules and trust assumptions. + +In other words, using essentially the same unmodified block DAG structure we can accommodate multiple communication models and trust assumptions, to accommodate a variety of client capabilities and circumstances. + +## 🤖 Objects {#objects} + +A construction instance identifies a fixed validator set and its permitted inputs. A phase identifies the interpretation and admission rules for contributions within that instance. Recovery proposals can establish successor instances with different membership. + +A **contribution** is an application message, such as a transaction fragment, proof, acknowledgement or coalition proposal. Anonymous submission prevents a validator's inclusion of a contribution from identifying its author. + +A **block** is a product type + +$$ +b=(M_b, B_b, s_b, R_b^{\mathrm{opt}}, R_b^{\mathrm{rec}}, \kappa_b, \phi_b, E_b), +$$ + +with the following components: + +| Component | Meaning | +| --- | --- | +| $M_b$ | Set of included messages; may be empty for an acknowledgement block. | +| $B_b$ | Set of parent blocks. | +| $s_b$ | Optional self-parent block, from the same validator. | +| $R_b^{\mathrm{opt}}$ | Nonce point committed for signing the validator's next optimistic block. | +| $R_b^{\mathrm{rec}}$ | Nonce point committed for signing the validator's next recovery block. | +| $\kappa_b$ | Block type: optimistic ($t=n$) or pessimistic recovery ($t + +# 🤖 Peer and broadcast channels + +Peer to group and peer to world messages are broadcast. Both are built by gossip over peer to peer channels, using the send and receive channels of the [abstract transport interfaces](transport-interfaces.md). A broadcast channel is itself a send channel and a receive channel, so protocol code that broadcasts sees only those two. + +* **Send** submits a message to the broadcast domain. The sender does not choose which peers the gossip reaches. +* **Receive** yields messages from the broadcast domain. It need not authenticate or distinguish anonymous senders. + +## Broadcast domains + +Gossip always happens within a namespace or topic, which names the broadcast domain. + +* A **group** namespace is ephemeral. It is derived from a shared secret with a tagged hash, as for a transaction construction session. A secret namespace restricts discovery, but it does not hide authorship, and it does not stop members from sharing it. +* A **world** namespace is well known, such as a public order book. + +If the namespace includes a block hash, message IDs can be short. + +A session's initiation message binds its namespace to the construction context, including the initial PSBT state and parameters. See [session initiation issue #61](https://github.com/fungi-protocol/fungi/issues/61). + +Gossip by itself does not provide reliable broadcast, agreement, a total order, or evidence that every participant has received a message. Those need protocol rules on top. For transaction construction, the [block DAG](block-dag.md) provides them. + +## Peer to world broadcast + +### Setup: BIP 322 gossip, online key enrollment + +Every spendable coin could potentially be spent in a multiparty transaction (although not all coins can be co-spent). To facilitate this, we require a gossip mechanism for BIP-322 ownership proofs, with a replacement and expiration mechanism for flood protection, committing to a public key referred to as the *online key* for the coin. + +The purpose of this online key is to authenticate the owner of the UTXO without requiring them to access the spending keys for communication. Anonymous authentication requires the use of ring signatures (and are therefore less likely to be supported by a HWW than BIP-322 proofs), and also simplify the mapping to just a single public key per UTXO, regardless of the complexity the `scriptPubKey` might have (complex multisig or ambiguity from multiple spend paths). + +Ownership proofs are also used to estimate input weights. For P2TR outputs, this indicates the spend path intended to be used in any collaborative transactions. Note, however, that this isn't enforceable. + +Each proof's endorsement of the online key has a validity interval specified in terms of Bitcoin block height or MTP (valid-after and valid-until). When multiple proofs by the same UTXO are nominally in effect, the one with the latest expiry time takes precedence. Ownership proofs commit to a block hash whose height or MTP is within some set interval of the valid-after field. + +#### Flood protection + +Online keys may need to be rotated. A rate limiting mechanism is needed for ownership proofs, and more generally for other protocol messages. + +Ownership proofs are tied to UTXOs that provides some degree of Sybil protection, since creating UTXOs incurs a cost. However, this is insufficient for flood protection, since there is no restriction on how many ownership proofs can be created. + +Note that Sybil resistance for flood protection is a separate concern from Sybil resistance in the context of CoinJoin $n-1$ deanonymization attacks on CoinJoins. The latter is assumed to be encoded of the cost function, and therefore out of scope for this protocol. + +To be accepted (and propagated through gossip) by a peer, any newly made proof associated with a coin must have a hash value (e.g. wtxid of the BIP 322 `to_sign` virtual transaction) numerically smaller than all the other proofs already associated with that output which are known to the peer. + +Because ownership proofs may be valid at disjoint time intervals, a peer should store up to $k$ proofs (in total, not per validity time interval) in its gossip set for each candidate UTXO, so long as the hashes of *all* of these are numerically smaller than $c_1 + 2^{(c_2 d k)}$, where $d$ is the total duration of all proofs, and $c_i$ are dynamically set policy values (similar to `minrelayfee`, based on local resource limits). + +#### Precedence ordering + +In addition to rudimentary flood protection for the ownership proof gossip, this defines a clear precedence order. This is so that with respect to a specific block tip, even without global consensus on the set of all ownership proofs, it's possible to efficiently arrive at the unambiguous mapping from a particular set of UTXOs to the same set of online keys by sharing with peers any relevant proofs they might be missing. + +If the online keys are generated by hash chain (similar to LN revocation keys), revealing the key can revoke a previous ownership proof, forcing a linear sequence of key updates, and providing a mechanism for efficient revocation. However, it's unclear at the time of writing whether revocation is required at all, and the proof of work approach to flood protection seems sufficient. + +Similarly, rate limiting could be done by restricting the rate of broadcast on the basis of the committed block hash, but on its own, this wouldn't establish a precedence order, and in the absence of consensus on the set of ownership proofs, it may result in ambiguities about which online key to use. + +### Listen advertisements + +Peers should only gossip [listen advertisements](coalition_formation.md) for currently active or soon-to-be-active online keys. The hash of the signature is used as a flood protection mechanism, similar to ownership proofs. + +### Flood protection for partially accepted proposals + +Partially accepted proposals can be communicated directly only between involved peers or gossipped to third parties. Gossip of partial proposals enables a single proposer to make many nuisance offers involving different sets of keys. Normally linkable ring signatures will protect their identity, which means that other nodes can only use a statistical approach to detect the culprit and may mistakenly penalize the UTXOs the attacker names, without their owners contributing to this flooding attack. "Normally" means the key image generator point is just be a hash to curve of the proposal data itself, allowing a practically unlimited number of ring signatures per UTXO (exponential in the size of the candidate UTXO set). + +To limit this behavior, the linkable ring signature key image base point can be time dependent (e.g. making use of a sufficiently buried block's hash as a randomness beacon) and include a truncated hash of the proposal when choosing the generator (by hashing to the curve). Truncating to 10 bits, for example, would allow up to 1,024 unrelated proposals to be accepted or made by a single UTXO equivocation per timestep, allowing flooding to be prevented. Note, however, that honest users may be restricted from accepting some honest proposals due to the birthday bound, but honest proposers with knowledge of other proposals can grind the proposal data to avoid collisions, and we of course assume attackers can do this without restriction). + +Additionally, it's possible to make use of a verifiable encryption scheme for the openings of the commitments, allowing verification of the proposal during gossip, but this doesn't prevent the broadcast of nuisance proposals that wouldn't be accepted despite being formally valid. + +In contrast, in a semi-honest setting, and if acceptors don't mind revealing whether they accept to the proposer, the linkable ring signatures can be shortcut entirely and MuSig2 negotiated directly, with the proposer collecting the nonces and partial signatures of all named parties. MuSig2 signing should still be initiated concurrently, even when linkable ring signatures are used to minimize the number of round trips. + +## Peer channels + +A broadcast channel uses two kinds of peer to peer channel: + +* **Neighbor channels** connect a peer to each of its gossip neighbors. They are bidirectional, and may be authenticated. A neighbor's authentication identifies the neighbor, not the author of a message it relays. +* **Submission channels** carry the peer's own messages into the broadcast domain. They are sender anonymous and message unlinkable. + +## Gossip messages + +These travel over neighbor channels. The minimal set suffices for the honest setting: + +* **announce** a message by its hash; +* **pull** a message by its hash; +* **push** a message that a neighbor pulled. + +The semi-honest and Byzantine settings add **unsolicited push**, used for anonymous broadcast. A peer that receives a new unsolicited message pushes it to one randomly selected neighbor, and announces it to its other neighbors. This is a candidate policy, not an established anonymity guarantee. + +🤖 Anonymous submission introduces a message into the broadcast domain. Once received, the message is disseminated by gossip or set reconciliation. The submission mechanism and the subsequent dissemination serve different purposes. + +## Anonymous submission + +1. The sender pushes its message, unsolicited, to a member of the broadcast domain over a submission channel. +2. That member handles it as any new unsolicited message. From then on it is an ordinary message in the synchronized set. A message that is not linked to its author can be relayed even on a channel that is not anonymous. +3. The sender keeps its own message out of its synchronized set until it receives the message through synchronization. It then processes and relays the message by the same rules as any other received message, without using its knowledge of authorship. Until it is satisfied that the message has been disseminated, it continues submitting anonymously. + +The broadcast's anonymity therefore rests on the submission channels, not on the neighbor channels. Removing an author field later cannot undo what the submission channel revealed. If a message is first announced by an identified peer, and then pulled from it, that peer is revealed as the first to hold it, even if later gossip hides the route. + +## Synchronization + +Convergence is the point of a transaction construction session. Each peer therefore synchronizes the set of all session messages with each of its neighbors. Order does not matter: the result is the union of the sets. This includes the blocklace, the session's block DAG. A peer's broadcast receive channel yields each message when it first enters the peer's set. + +Every message carries a state commitment: the Merkle roots of the sender's sets, with height and set sizes. Fetching an ever-growing set of sets is a resource exhaustion risk. Blocks are necessary for progress, and cordiality rate limits them. + +Honest peers should converge on the messages to include before producing blocks. A peer should be eager to gossip, but not too eager to produce blocks. + +The goal is that all participants, even those with asymmetric capabilities such as limited bandwidth, arrive at the same set of messages. This repeats over multiple epochs. + +## Dissemination methods + +**Epidemic gossip** is the minimal approach: announce new messages to neighbors, which pull the ones they lack. It works over simplex peer channels. It avoids write contention and multiple readers per destination, and the potential censorship these allow. It will likely win on latency. But announcements are sent for every message to every neighbor, and a peer may hear of the same message many times. + +**Set reconciliation** is a later improvement of blocklace dissemination efficiency. Two neighbors compare their sets and learn which messages each is missing. It throttles or suppresses announcements. Communication then grows with the difference between the sets, not with their size. It will likely win on communication complexity. Range based reconciliation and rateless invertible Bloom lookup tables (RIBLT) are candidates. Multiparty set reconciliation has not been studied as far as we know; recent work covers two parties. A peer can still reconcile with each neighbor in turn. See [peer set reconciliation](set-reconciliation.md). + +**Network coding**, such as algebraic gossip on top of the same structure, offers a whole spectrum of further possibilities, with some additional complications. + +The same building blocks may not suit both peer to world broadcast (coalition formation) and peer to group broadcast (transaction construction). Message counts and sizes also vary: small messages on the happy path, larger ones for validity proofs. + +## Topology + +* **Hub and spoke.** Some peers are better connected, and many others connect to them. +* **Clique.** Every peer is connected to every other peer, with no distinction between them. A transport that can send to any peer at any time, without a connection, behaves like this. +* **Gossip.** Two models apply, both described by Weaver (Unknown Participants, Changing Topologies, and Faulty Devices, PhD dissertation, Georgetown University, 2023, p. 69 and p. 155): + * In the **random phone call model**, also called the gossip model, each round a peer exchanges a bounded amount of information with one neighbor, picked at random. The graph is often assumed to be connected ([Karp et al. 2000](https://doi.org/10.1109/SFCS.2000.892324), [Boyd et al. 2006](https://doi.org/10.1109/TIT.2006.874516)). + * In the **LOCAL model**, each round a peer exchanges messages with all of its neighbors, and the topology has bounded degree ([Luby 1985](https://doi.org/10.1145/22145.22146), [Alon, Babai and Itai 1986](https://doi.org/10.1016/0196-6774%2886%2990019-2)). + + Fungi targets both models. + +Connection based channels limit a peer to a more or less static local topology, so a connection oriented transport scales well only in the LOCAL model. A transport that is connectionless end to end can send a message to any peer at any time. It matches the random phone call model, or a low capacity clique. + +## Candidate transports + +The specification relies only on the channel properties above. These candidate transports are not part of it. Gossip over any of them provides group and world broadcast. The table says what each provides directly. + +| Transport | Delivery | Broadcast domain | Sender anonymity | Topology | +| --- | --- | --- | --- | --- | +| BIP 77 mailbox | Store and forward | None, peer to peer | Message unlinkable towards the directory, if the OHTTP relay and the directory do not collude. Messages to one mailbox are linkable to each other by its ID. | Random phone call model: connectionless end to end, so a peer can reach any mailbox. The directory is a hub. | +| OHTTP pubsub | Store and forward, by topic | Group (secret topic) and world (well known topic) | As for the BIP 77 mailbox, for each publish and each read. | Independent servers, connected to each other or not, like nostr relays. Peers bridge between them. | +| Nostr with gift wrapping | Store and forward, by subscription | World | Each event is signed by a one-time key, so it does not name its author. The relay connection still identifies the client, and links the events sent on it. | Independent relays, connected to each other or not. Peers bridge between them. | +| Tor | Connection oriented, low latency | None, peer to peer | Connection unlinkable. With connection isolation, one message per connection is message unlinkable. | LOCAL model: connection oriented, so it scales well only with a bounded number of connections per peer. | +| Nym | Message based mixnet | None, peer to peer | Message unlinkable. Mixing delays and cover traffic resist timing correlation. | Random phone call model: connectionless end to end, so a peer can send to any peer at any time. | + +* **BIP 77 mailbox.** [BIP 77](https://github.com/bitcoin/bips/blob/master/bip-0077.md) payjoin already uses it, with directories reached through [OHTTP](https://www.rfc-editor.org/rfc/rfc9458) relays. It suits interactive payments and session initiation with a known peer: the receiver is identified by its mailbox, and the sender need not be. +* **OHTTP pubsub.** A specialized service, with topics in place of mailboxes. It would serve group broadcast, and global gossip as well. It runs on a set of independent servers, much like nostr relays. A broadcast domain can span several servers, or be sharded across them, as long as some peers bridge between the servers and keep the network connected. None exists yet. +* **Nostr with gift wrapping.** [Gift wrapping](https://github.com/nostr-protocol/nips/blob/master/59.md) hides the author in the event, not in the connection. Open gossip that is message unlinkable therefore needs one relay connection per message, over an anonymous channel. +* **Tor.** + * It has by far the most adoption, compared with Nym or OHTTP mailboxes. [Anonymity loves company](https://freehaven.net/doc/wupss04/usability.pdf), so Tor is likely the better privacy choice, even though its guarantees are weaker than Nym's. + * Its guarantees are stronger than OHTTP's, with three hops instead of two. Neither resists a global passive adversary doing traffic analysis. + * It is not usable from a web app or progressive web app (PWA). + * Being connection oriented, it suits neighbor channels, and submission channels that carry one message per connection, using [stream isolation](https://spec.torproject.org/proposals/171-separate-streams.html). + * A cold start is slow, because building circuits takes many round trips. Once circuits are built, a new connection costs about the circuit's end to end latency, plus the exit node's connection to the server. + * A phone waking up pays the cold start. This is the main reason to also support OHTTP: a request takes only a few round trips, because the OHTTP relay keeps its connection to the gateway open. Being request and response oriented, OHTTP also keeps a client's requests unlinked at the server, without a separate connection for each. +* **Nym.** [Nym](https://nym.com/docs) sends to any peer without a connection, so it suits the random phone call model. Mixing adds latency. diff --git a/docs/coalition_formation.md b/docs/coalition_formation.md index 20ee11a..f6502d9 100644 --- a/docs/coalition_formation.md +++ b/docs/coalition_formation.md @@ -1,10 +1,216 @@ --- -type: Stub -title: Market-based coalition formation for collaborative transaction construction +type: concept +title: Market-based coalition formation status: draft -stale_after: 2027-04-15T00:00:00Z +stale_after: 2027-01-23T00:00:00Z --- -# Market-based coalition formation for collaborative transaction construction +# Market-based coalition formation -This chapter is under review in [#18](https://github.com/fungi-protocol/docs/pull/18). Its draft is on [the pull request's branch](https://github.com/fungi-protocol/docs/blob/coalition-formation/coalition_formation.md). +## Problem definition + +In several existing market-based decentralized protocols involving collaborative transactions, a single party initiates and typically bears the costs — for example, JoinMarket or liquidity ads. + +Transactions meeting the demand of more than one "taker" can be more efficient, depending on their desired outcomes. CoinJoin privacy in particular is a non-rivalrous positive externality obtained by each participant from the other participants, and as such, it's an inherently positive sum. + +The following protocol aims to generalize the type of order matching JoinMarket supports, allowing multiple users' intents to be aggregated together. + +## Overview of proposed solution + +This document describes a permissionless, peer-to-peer protocol for negotiating the initiation of a collaborative transaction construction. This takes place over two primary phases: bilateral negotiation, followed by aggregation. Successful execution of the protocol results in a coalition of UTXO owners unanimously agreeing to build a transaction together. + +This isn't a transaction construction protocol, but a precursor to such a protocol. This protocol bootstraps a compatible transaction construction protocol by finding consensus on an initial set of UTXOs whose (honest) owners intend to spend them in a collaborative transaction. Refer to the last section for a brief discussion of such a protocol and how it composes with this one. + +### Bilateral negotiation + +A proposer, the owner of one or more UTXOs, selects UTXOs belonging to others from an "order book". The proposer initiates peer-to-peer bilateral negotiations with the owners of these coins by sending them a message that includes a *co-spend proposal*. This expresses an intent to cooperate to spend this set of coins together in a single Bitcoin transaction. + +Co-spend proposals are publicly verifiable, confidential adjustments to the effective values of the specified coins. These adjustments can represent arbitrary payoff structures. Whether a proposal takes effect (i.e. the adjustment is applied) is contingent on the constraints specified in the proposal being satisfied in a transaction construction session intended on spending the specified UTXOs. For example, a proposal may require that non-SegWit inputs be excluded for TxID stability, or that the feerate be within an acceptable range, among other constraints. + +Co-spend proposals rely on cryptography to keep each coin's adjustment hidden, except for that coin's owner and the proposer. The proposer's UTXO is indistinguishable from the other UTXOs. Before a proposal is unanimously accepted, it isn't known which UTXO owners have accepted the proposal. + +### Aggregation + +Co-spend proposals aren't exclusive. Many proposals can be aggregated together before collaboratively constructing a transaction in which the combination of all the aggregated proposals is in effect. The UTXOs specified in proposals that are aggregated together may overlap but don't need to; the main requirement is for the constraints to be compatible. + +Fully accepted proposals can be broadcast and then aggregated with other compatible proposals. Aggregation makes it possible for multiple participants to simultaneously optimize for their desired outcome according to their individual preferences. When they value privacy, or any other kind of positive sum interaction, aggregation generates surplus from which all participants may benefit. + +To aggregate, several proposals are bundled together with a *coalition formation proposal* that all parties must agree to. Unanimous acceptance of such a coalition formation proposal signals that everyone is ready to construct a transaction. + +Because transactions are only valid if all inputs are signed, multiparty transactions require unanimous agreement. A precondition for denial of service protection in privacy preserving multiparty transaction construction protocols is incentive compatibility for the honest participants. No honest participant should have a reason to withhold their signature. + +The primary purpose of this protocol is to construct an [imputation](https://en.wikipedia.org/wiki/Imputation_%28game_theory%29), which is a payoff distribution over the inputs. This aligns incentives for successful transaction construction while maintaining confidentiality of the individual payoffs. + +## Background + +### Hedonic games and games with transferable utility + +Coalition formation games, in game theory, typically refer to the cooperative game theory setting, where agreements are binding and can be enforced by some kind of mechanism. While Bitcoin can provide such a construct, analogously to the function of the court system, the current consensus rules require some kind of contract to be anchored in a confirmed transaction, i.e. binding agreements require creating new transactions and waiting for them to confirm.[^coinswap] In order to build transactions without having already built transactions, we must therefore assume the non-cooperative setting. Coalition formation in the non-cooperative setting can only rely on incentives. + +When preferences over the coalition structure are in play (the cost function), in so-called hedonic games, it is often very hard (also in an algorithmic sense) to find stable coalition structures, as the preferences of the participants may conflict. In their most general form, such game descriptions are enormous as the preferences are defined over a large combinatorial object. Even when many assumptions are made, like constraining the kinds of preferences the participants may have, it is still generally hard to find stable equilibria.[^hedonic] Complicating matters further, sharing the preferences would itself be a privacy leak, so we would prefer to limit that as much as possible, and certainly we cannot assume a mechanism that optimizes outcomes by just being able to read these preferences. + +Fortunately, some of these difficulties of hedonic games can be bypassed with the introduction of a transferable utility, and assigning the coalition itself a payoff, which can be redistributed. In our use case this payoff originates from any blockspace savings from net settlement, and the privacy benefits from collaboration. This surplus is not observable, it is the sum of subjective payoffs depending on individual participants' preferences (which in turn depend on their circumstances, privacy threat model, etc). While this does not guarantee stability, if a stable coalition structure exists, a transferable utility can make the process of finding one much easier by iterated bilateral negotiation. However much these benefits are worth to participants, if this surplus exists, then it can be voluntarily redistributed as sats among the participants (i.e. via a fee mechanism) aligning incentives for collaborative transaction construction, so that all coalition members stand to gain from participating. + +Coalition formation games output a partition over $N$ peers. Finding stable equilibria in such games is generally difficult. Depending on the structures in the preferences of the peers, many special cases described in the hedonic games literature are still hard. In the byzantine setting appropriate for Bitcoin protocols, no such structure can be assumed, which makes finding stable partitions intractable. + +Since the participants in the protocol unilaterally control independent UTXOs during the execution of this protocol, we're constrained to the non-cooperative setting, where agreements are non-binding and can't be enforced. Additionally, for privacy, the cost functions should remain hidden so that no mechanism can access the peers' preferences and globally optimize. Note that due to the nature of revealed preferences, the cost function can't be fully hidden. + +Fortunately, the introduction of a transferable utility greatly simplifies finding stable coalition structures, even under these assumptions. Bitcoin can approximate such a transferable utility. This makes it possible to simply assign payoffs to the coalitions and allow them to be distributed among the peers through bilateral negotiation. If Alice prefers not to co-spend with Bob, but Carol strongly favors both Alice's and Bob's participation, Carol is able to compensate Alice, so that as long as the coalition generates some surplus, all parties will be able to obtain a positive payoff. + +### Transaction construction liveness assumptions + +For a coalition of $n \leq N$ peers, $f$ of which are adversarial, liveness for transaction construction can be achieved (with privacy) by the honest subset of peers in $O(f)$ time. Any defection requires transaction construction to start over. Due to random network disruptions, necessarily some rate of (apparent) defection must be tolerated. + +Because exclusivity of spending attempts by inputs can't be enforced without global consensus, and because transaction replacement is desirable for fee market efficiency, we assume inputs are allowed to participate in concurrent sessions, which will result in conflicting transactions. Opt-in signalling can be used and obeyed as a courtesy, but this ultimately reduces to the same liveness model as transaction construction, potentially requiring additional attempts to recreate the transaction. + +### Cost functions + +This protocol is mostly agnostic to the cost function that describes the peers' preferences. + +Much like in the problem of coin selection (which this work aims to generalize), the cost function is denominated in sats, and it's the combination of objective terms (i.e. the fee cost) and subjective ones (any positive utility obtained from transacting, which by definition must dominate over the objective costs for a self-interested, not necessarily honest peer to agree to sign the transaction). + +Although out of scope for this specific document, privacy-related terms are assumed to quantify things like how much cover other peers' coins provide in Maurer et al's sub-transaction model, or an estimate of the cost to an adversary of an $n-1$ deanonymization attack (for instance, an adversary using older coins incurs a higher cost to do such an attack, as that liquidity must effectively be locked up to become old). + +A precondition for liveness is that any such cost function is monotonically decreasing in new information revealed during transaction construction. + +Concretely, this means that whenever the action of some peer is revealed (i.e. when an input or output is added), at worst, other peers should be indifferent to this, but they may also obtain positive utility. If this isn't the case, parties may rationally choose to defect. The purpose of the constraints in proposals is to allow the honest subset peers to avoid such non-malicious conflicts a priori. Since monotonicity is required for liveness, a peer that engages in the protocol without adhering to this restriction and refuses to sign is deviating from the protocol, and therefore by definition not a member of the honest subset. + +## Simplified example + +Note that this example omits many details discussed below. + +Alice, Bob, Carol, and Dave are owners of UTXOs $A$, $B$, $C$, and $D$, respectively. Alice wants to CoinJoin with Bob and Carol. She creates a co-spend proposal with UTXOs $\{ A, B, C \}$. In this proposal, she adjusts her UTXO $A$ down by 100 sats, and adjusts $B$ and $C$, perhaps up by 50 sats each, providing an incentive for Bob and Carol to accept. She sends this to Bob and Carol, who accept, after which the proposal is fully accepted and broadcast. + +For all Bob knows, either Carol or Alice made the proposal, and the same goes for Carol, not knowing if it was Alice or Bob. Bob only learns that he was offered 50 sats; he doesn't learn how much Carol (or whomever) was offered. All Bob knows is that the 50 sats, which he would receive if a transaction was constructed with this proposal in effect, would be paid for by one of the UTXOs $\{A, C\}$. + +Carol also wishes to CoinJoin with Alice and Dave. She creates a co-spend proposal with UTXOs $\{ A, C, D \}$, and adjusts $C$ down by 50 sats, $A$ up by 20, and $D$ up by 30. This too is unanimously accepted and broadcast. + +Dave then notices both proposals are compatible, and chooses to aggregate them together. He produces a coalition formation proposal, which depends on these two proposals. The coalition formation proposal chooses a specific feerate, among other things, combining the constraints of both previous proposals. It names $\{ A, B, C, D \}$ as the UTXOs. + +Once all parties accept Dave's proposal, consensus has been bootstrapped. Everyone can derive the same total adjustments: $A - 80$, $B + 50$, $C + 0$, $D + 30$. In general, only the owner of each coin knows their final adjustment, but in this example, Carol knows that Dave obtained $+30$ because her proposal is the only one that applies to his coin, and likewise Alice knows Bob obtained $+50$. + +All peers can then proceed to transaction construction, where each party is entitled to add up to their adjusted value's worth in outputs. They may add additional inputs and arbitrary outputs, so long as for each peer, the sum of the outputs' effective cost doesn't exceed the sum of the adjusted effective values of that peer's inputs. + +## Technical details + +### Setup: BIP 322 gossip, online key enrollment + +🤖 Ownership proofs and online keys are specified under [peer to world broadcast](channels.md), together with the gossip, flood protection and precedence ordering rules for them and for listen advertisements. + +### Negotiation: Listen advertisements and/or gossip of partially accepted proposals + +Short-lived listen advertisements may be signed by "makers" using their online keys to indicate that the owner of a UTXO is soliciting proposals pertaining to its spending over the named communication channel. + +"Takers" evaluate listening coins and can construct proposals (defined in the next section) over the specified communication channels. + +Alternatively, negotiation with listening but unaddressable UTXO owners can be made possible using an opt-in gossip layer. On this layer, it's permitted to broadcast partially accepted proposals. See below for a discussion of flood protection considerations in this setting. + +Listen advertisements can specify constraints for proposals being entertained, indicating that proposals outside of the constrained subspace (see coalition formation proposal details below for specifics) are unacceptable at any price. + +Finally, listen advertisements also indicate the owner's willingness to serve as a validator node in transaction construction, as either demanding to be a one, opting in at the aggregator's discretion, or declining. The aggregator has an incentive be a validator (and to do so honestly), but is not required to. + +### Co-Spend proposals + +Co-spend proposals specify a set of outpoints of coins intended to be spent together. Fully accepted proposals take effect contingent on the conditions they specify, such as the range of feerates the offer is valid under, `nLocktime` ranges, or whether or not txid stability is required (i.e. only SegWit inputs). The effect of a proposal is some confidential redistribution of the input funds, e.g. fees negotiated between the transacting parties. + +#### Making and ratifying co-spend proposals + +A proposal specifying $n$ UTXOs can have $1 \leq m \leq n$ linkable ring signatures by the associated online keys of the named UTXOs. + +While $m < n$, a proposal is only partially accepted. Which of the peers have accepted a partial proposal is kept hidden by the ring signatures. This includes keeping the proposer anonymous within this set of signers; technically, the proposer is just the first to accept, and at least one peer needs to accept for anti-Sybil flood protection reasons. + +If $m=n$ linkable ring signatures with distinct key images have been collected, then a proposal has been unanimously accepted. + +Finally, for a proposal to be fully accepted, the $n$ linkable ring signatures are replaced with a single Schnorr signature made by the MuSig2 aggregate key formed from the set of associated online keys of the UTXOs. This reduces the size, as well as the computational cost of verifying proposals. Because all parties have accepted, no single party can deny having signed. This makes a joint multisignature semantically equivalent to the $n$ individual linkable ring signatures. The deniability of linkable ring signatures only makes a difference during negotiations before all parties have accepted. + +Fully accepted proposals can then be broadcast for aggregation. A fully accepted proposal indicates that all owners of the specified UTXOs have some interest in this proposal being in effect. + +Individual proposals commit to a specific set of BIP 322 ownership proofs so that the signatures on them are verifiable. Proposals that refer to expired ownership proofs are still considered valid, and more generally, proposals that commit to different ownership proofs are potentially valid as long there is a non-expired ownership proof associated with the UTXO, which is also used for input weight estimations. See the coalition formation proposal section below for details. + +Co-spend proposals aren't updatable or revocable once fully accepted, but they do have an expiry (specified in block height, MTP, or UTC time). More than one signature on the same proposal should be considered a flooding attack by all participants, and honest parties should only sign (MuSig2) a proposal once. Again, see below for discussion of flood protection with respect to partially accepted proposals. + +However, co-spend proposals are able to explicitly include conflict hints for other proposals, indicating that (at least) the proposer of the conflicting proposal wouldn't accept a coalition formation proposal that depends on the excluded proposals. + +#### Effective value adjustments + +Proposals verifiably redistribute sats among the UTXOs by adjusting their effective values. Corresponding to each UTXO, a homomorphic value commitment to an adjustment term is included. This adjustment can implement fee payments between peers, and it may be positive or negative for every UTXO. + +The sum of all the adjustment value commitments in a proposal is a commitment to the sum of the adjustments. This value, the *surplus* of a proposal, is included in cleartext, and the sum commitment is proven to commit to it in a balance proof. This too may be positive or negative. + +When communicating a partial proposal, the proposer shares with each recipient the opening of the commitment associated with their UTXO. This payoff is denominated in sats, and it can be positive or negative. + +Each adjustment value commitment is also covered by a range proof certifying that the adjustment is a small positive or negative integer. Small means at least $\lfloor\frac{v}{log_2(v)}\rfloor$, where $v$ is the minimal effective value among all specified UTXOs. This minimum value is computed by taking the highest acceptable feerate in the proposal conditions and multiplying that by the input weights estimated from the ownership proofs. + +The sum of the adjustment commitments, when tweaked by the effective value of the UTXO according to the final feerate of the UTXO, must be a commitment to a positive number of sats. This is ensured by accounting for the maximum values in the range proofs, and by ensuring it doesn't overflow the effective value. + +Imposing a minimal range width size imposes a limit on how many proposals can be aggregated together, roughly logarithmic in the total value to be spent. Proposals can use wider range proofs than the minimum, which limits their ability to be aggregated and leaks information about the size of the adjustments. + +### Proposal aggregation and condition details + +A coalition formation proposal is a special kind of co-spend proposal that aggregates together a bundle of non-conflicting, fully accepted co-spend proposals. The coalition formation proposal is made by one of the peers, the aggregator, to *all* other peers implicated in the aggregation. The aggregator must also set specific values for any constrained parameters (e.g. a concrete feerate and not just a range). + +#### Making and ratifying coalition formation proposals + +Any peer may attempt to construct a coalition formation proposal by aggregating unanimously accepted co-spend proposals together, so long as it controls at least one of the online keys implicated in the aggregation. For rate limiting, the aggregator's key is made explicit, and the hash of this signature is used for flood control when gossipping the partially signed coalition formation proposal, much like the hash of ownership proofs. + +Unlike co-spend proposals, coalition formation proposals are accepted with a regular signature by the online key. This makes them tractable for aggregators to make coalition formation proposals that revise the payoff or omit peers who didn't accept. As discussed above, coalition formation proposals aren't mutually exclusive. If a peer rejects a coalition formation proposal due to the inclusion of a specific proposal, it may broadcast a counter final proposal of its own, so there's no mechanism for explicit rejection. + +A coalition formation proposal also specifies a concrete transaction construction protocol version, and commits to a specific set of listen advertisements associated with the specified UTXOs, which have either demanded or opted into serving as validators. These peers agree to allow other peers to connect to them and facilitate in gossip. Depending on the liveness requirements of byzantine agreement for the subsequent transaction construction protocol, the aggregator may specify validators at their discretion and named parties may accept or decline. + +#### Bootstrapping consensus for transaction construction + +Once a coalition formation proposal is fully accepted, a coalition has been formed, complete with a payoff imputation. The online keys are then used to initiate a consensus protocol to construct the full transaction. + +Since the coalition formation proposal addresses every UTXO, its ownership proof set commitment is authoritative. This determines the canonical online key set for the coalition, allowing a consensus protocol to be initialized. The aggregator should use [precedence ordering](channels.md) for symmetry breaking to minimize additional gossip and improve the chances of the coalition formation proposal being unanimously accepted, but there's no consensus state for this data at the time the coalition formation proposal is being authored. The purpose of coalition formation proposals is to bootstrap both the consensus protocol and incentive compatibility to make use of it. + +#### Coalition formation proposal structure + +🤖 The surplus of all included co-spend proposals belongs to the coalition. The aggregator proposes adjustments for each UTXO and an amount to allocate to mining fees. Some or all of the surplus may be allocated to mining fees, which must cover the shared transaction fields at the agreed feerate. These allocations take effect only if the coalition formation proposal is unanimously accepted. + +The logical conjunction of co-spend proposals implies the union of their adjusted UTXOs and the intersection of their conditions is in effect. The per-UTXO adjustments are collected for each outpoint. The total adjustment for each UTXO may not overflow its effective value, based on the range proof widths. + +Co-spend proposals therefore form a commutative semi-group, unioning the sets of UTXOs and summing the adjustments component wise. It's only a semi-group because proposals can't always be aggregated together. One reason for this is that the conditions might be mutually exclusive. Another is consensus rules (e.g. `OP_CLTV` making conflicting assertions). + +Conditions are intersected elementwise. The intersection of mutually exclusive conditions — for example, a time-based vs. a height-based nLocktime — is empty, precluding the combination of such proposals. + +The following are all numerical intervals under intersection: + +- Transaction consensus fields + - version + - individual flag bits (top is {0,1} then {0}, {1}, bottom is {}) + - nIns + - not included: nOuts, (min cannot be enforced and so can't be included, max is enforced indirectly by vbytes allocation see below) + - nSequence (constrains all nSequence fields) + - nLocktime +- Non-consensus parameters + - feerate + - max total vbytes per tx (divide by nIns and round down for allocation per input, nIns must be set accordingly to pass standardness or consensus limits) + +The following are sets under intersection: + +- Allowed input types (catchall "unknown" or "arbitrary" as one of the variants, variants for standard or well known output types) +- Allowed output types + +### Flood protection for partially accepted proposals + +🤖 Gossip of partially accepted proposals, and its flood protection, is specified under [peer to world broadcast](channels.md). + +### Post quantum security and privacy + +Apart from the BIP-322 ownership proofs, which are related to spending keys, the signatures used throughout don't require PQ security for privacy (assuming perfectly hiding commitments) or safety, but only for liveness. + +However, for privacy, it's important that any proofs of knowledge of openings of the commitments don't compromise the unconditional hiding of commitments, so as to avoid "harvest now, decrypt later" attacks on anonymity (although out of the scope of this document, this is also required for transaction construction). + +Secondly, in addition to the secp256k1 online key, a PQ key for end-to-end encrypted communication (e.g. the encrypted openings of commitments included in a proposal) can also be used. HPKE is an obvious choice for secp256k1-based encryption, and hybrid HPKE is specified using ML-KEM, which makes it a relatively simpler change. However, neither of these is verifiable without general purpose ZK, which is often costly for the prover or in proof size. Lattice-based schemes (without a symmetric cipher) seem potentially amenable to such verifiable encryption, but I have yet to look into that. Verifiable encryption is necessary for partial proposal gossip, as otherwise there's no guarantee that the proposal can even be accepted, as some parties may not learn the opening of the value commitments associated with their UTXOs. + +Finally, PQ privacy must of course also assume that metadata privacy at the transport layer is also preserved. + +### Transaction construction protocol + +🤖 The accepted coalition formation proposal specifies the initial inputs, their online keys, the negotiated adjustments and the parameters for [transaction construction](transaction-construction.md). It is the genesis of the construction instance. The initial state can be proven valid with respect to each UTXO's adjustment sum commitments, which enforces that the agreed imputation is in effect. When construction stalls, the [recovery track](recovery-track.md) turns the stall into a new coalition formation proposal among the responsive subset. + +🤖 Any participant can act as an aggregator. Assembling a proposal gives that participant no additional privileges during transaction construction. + +[^coinswap]: For example [CoinSwap](https://openswap.live/) is such a protocol which relies on atomic swap contracts, designed with privacy in mind. + +[^hedonic]: D. Peters and E. Elkind, [*Simple Causes of Complexity in Hedonic Games*](https://arxiv.org/abs/1507.03474) (2015). Shows how modest expressiveness in preferences can make deciding the existence of stable outcomes computationally hard. diff --git a/docs/collaborative_txn_privacy.md b/docs/collaborative_txn_privacy.md index 73367b7..06a318d 100644 --- a/docs/collaborative_txn_privacy.md +++ b/docs/collaborative_txn_privacy.md @@ -1,10 +1,1033 @@ --- -type: Stub +type: Problem Definition title: Collaborative transaction privacy +description: Challenges for privacy in multiparty transaction settings, from PayJoin to CoinJoin. status: draft -stale_after: 2027-04-15T00:00:00Z +stale_after: 2027-01-23T00:00:00Z --- # Collaborative transaction privacy -This chapter is under review in [#7](https://github.com/fungi-protocol/docs/pull/7). Its draft is on [the pull request's branch](https://github.com/fungi-protocol/docs/blob/problem-definition/collaborative_txn_privacy.md). +This document examines some challenges for privacy in a variety of multiparty transaction settings, from PayJoin to CoinJoin. + +## The Bitcoin transaction graph + +The Bitcoin transaction graph is a trace of the movement of funds between different users. + +The flows themselves can also be modeled as a graph where vertices represent users, and edges represent the relationships between the users, that is to say the edges describe how funds tend to flow between the users. Borrowing from the first study to describe this, we'll refer to it as the user network, and define it more precisely below. Deanonymization of Bitcoin transactions roughly corresponds to recovering (parts of) this underlying structure from the transaction graph recorded on-chain. + +Neither the user network nor the transaction graph is random. But they both have some randomness in them. The user network is a kind of social graph, specifically an economic network. An extensive literature on complex networks characterizes such graphs.[^newman] These networks behave very differently from random graphs, certain properties of these graphs can be predicted reliably. In the transaction graph, some of the details are obscured, primarily due to Bitcoin's reliance on the UTXO model (rather than say the account model) for transfers. However, because the transaction graph is a trace of transfers through the user network, and because the user network is highly structured, so is the transaction graph. And while the user network is not directly observable, it is one of the defining properties of Bitcoin that the complete transaction graph is observable by anyone. + +For the transaction graph to be privacy preserving, it must robustly obscure patterns originating from the user network. This is challenging because the user network constrains how the transaction graph is constructed. There are different ways of accomplishing this goal, but the approach assumed here is that of an overtly ambiguous graph, where the individual users' actions are sufficiently and randomly intertwined, necessitating additional information to disentangle. The central claim made here is that such a graph must be carefully and deliberately constructed. It does not emerge spontaneously, nor by naive attempts. But it *can* be constructed, even efficiently, and the guarantees it provides are relatively straightforward to understand and even to quantify. + +Unfortunately, common misconceptions about how on-chain privacy works and what attackers are capable of paint a much rosier picture than what the published literature has shown is actually possible. None of the attacks described here are novel, but some of the cited results of the privacy literature originated in a different setting than Bitcoin privacy. + +This document isn't concerned with providing empirical proof of the viability of different attacks, partly because some of the structures whose weaknesses are examined are still hypothetical, but mostly because of the lack of novelty; the cited works are generally supported by evidence and most are peer reviewed. It is on proponents of privacy to show why their technology can resist such attacks, rather than on critics to demonstrate how it can be broken for the same reasons as in cryptography but even more so because many of these attacks are substantially amplified by an adversary's access to auxiliary information such as labeling originating from KYC processes. + +Unlike in cryptography, where the burden of proof is both high and generally belongs to those making claims of security, in Bitcoin privacy various apologists and interested parties often promote the notion that the burden of proof is reversed, or that addressing these problems is trivial. That framing is misleading in minimizing the consequences. Misinformed users are needlessly exposed to risks to which they might not have given *informed* consent. + +This document *is* concerned with defining specific failure modes. Vendors of privacy-enhancing technologies, as is the norm in other industries, should be expected to address these widely understood attacks and argue for how their product maintains privacy in the face of adversaries that aren't assumed to be unreasonably weak. Specifically this document defines the problems that the Fungi protocol suite aims to address. And by extension a minimum bar for evaluating any claims about the on-chain privacy guarantees it tries to provide. + +In other words, the problem is that due to the economic network at the heart of Bitcoin, not only is it unreasonable to expect privacy or fungibility automatically, but the privacy guarantees that are currently available themselves often rely on unreasonable assumptions. By understanding these challenges we can describe the properties a transaction graph requires so that its resistance to analysis does not rest on fragile or unrealistic assumptions. + +## Unilateral transaction privacy + +Unilateral transactions are highly susceptible to deanonymization using clustering techniques. After address reuse, the most obvious way to cluster, or link a user's coins, is the **common-input-ownership heuristic** (CIOH): A transaction that spends several inputs is evidence that one entity owns all of them, since at the protocol level signing for all of them normally requires all of their keys.[^cioh-wp][^cioh-scroll] + +```mermaid +flowchart LR + classDef ac fill:#7993b6,stroke:#000,color:#111,rx:12,ry:12 + classDef bc fill:#e9a969,stroke:#000,color:#111,rx:12,ry:12 + classDef cc fill:#da817d,stroke:#000,color:#111,rx:12,ry:12 + classDef txn fill:#444,stroke:#000,color:#fff + a1("input 0.5"):::ac --> tx1["transaction 1"]:::txn + a2("input 0.3"):::ac --> tx1 + tx1 --> pay1("payment 0.6"):::bc + tx1 --> chg1("change 0.2"):::ac + chg1 --> tx2["transaction 2"]:::txn + a3("input 0.4"):::ac --> tx2 + tx2 --> pay2("payment 0.5"):::cc + tx2 --> chg2("change 0.1"):::ac +``` + +*CIOH links the inputs of each transaction, and change identification links the two transactions: All five blue coins merge into a single cluster.* + +Practical clustering combines heuristics beyond CIOH to build a **wallet cluster**: a set of addresses and coins inferred to share one owner.[^reid-harrigan][^ron-shamir][^androulaki][^meiklejohn][^nick][^harrigan-fretter][^scroll-history] + +## Collaborative transactions + +A transaction that spends inputs owned by more than one user falsifies CIOH by construction. Starting with just two parties, the observable structure can have (at least) two forms.[^forms] The on-chain transaction must be compatible with the actual allocation of inputs, outputs, and payments among the participants, but it might not reveal that allocation in its entirety. + +The first two-party form is a batched transaction, or a CoinJoin: two independent sub-transactions, both of which are balanced, aggregated into a single transaction. + +Here, a **sub-transaction** means some, but not all, of a transaction's inputs and outputs attributed to one participant's action. A more precise, probabilistic notion will be discussed below. Informally, a balanced sub-transaction is one whose balance, the difference of the sum of input values and the sum of the output values, is approximately zero. + +```mermaid +flowchart LR + classDef ac fill:#7993b6,stroke:#5778a4,color:#111,rx:12,ry:12 + classDef bc fill:#e9a969,stroke:#e49444,color:#111,rx:12,ry:12 + classDef payA fill:#da817d,stroke:#5778a4,stroke-width:3px,color:#111,rx:12,ry:12 + classDef payB fill:#9dc5c1,stroke:#e49444,stroke-width:3px,color:#111,rx:12,ry:12 + classDef txn fill:#444,stroke:#000,color:#fff + ai("Alice's input 0.9"):::ac --> tx["transaction"]:::txn + bi("Bob's input 0.3"):::bc --> tx + tx --> pa("payment 0.5"):::payA + tx --> cb("Bob's change 0.1"):::bc + tx --> pb("payment 0.2"):::payB + tx --> ca("Alice's change 0.4"):::ac + linkStyle 0,2,5 stroke:#5778a4,stroke-width:3px + linkStyle 1,3,4 stroke:#e49444,stroke-width:3px +``` + +*A batch: two independent spends aggregated, SharedCoin style. Each sub-transaction balances on its own (0.9 = 0.5 + 0.4 and 0.3 = 0.2 + 0.1).* + +In the example above, although CIOH is falsified, the amounts strongly suggest one way of partitioning the transaction, and CIOH still applies within each sub-transaction separately. We'll return to this form of collaborative transaction and its variations, as well as how the sub-transaction model generalizes CIOH, in later sections. + +## Two-party PayJoin + +The other main form a two-party transaction can take is a PayJoin.[^p2ep][^bip79][^bip78][^bip77] Unlike the independent, balanced sub-transactions in the preceding example, the sender's sub-transaction has a positive balance (a surplus) that covers the receiver's negative balance (a deficit). This imbalance between the two sub-transactions is the payment. + +The following illustrates a single payment from Alice to Bob, but Bob also contributes one of his own inputs alongside Alice's: + +```mermaid +flowchart LR + classDef alice fill:#7993b6,stroke:#000,color:#111,rx:12,ry:12 + classDef bob fill:#e9a969,stroke:#000,color:#111,rx:12,ry:12 + classDef txn fill:#444,stroke:#000,color:#fff + ai("Alice's input 0.9"):::alice + bi("Bob's input 0.6"):::bob + tx["transaction"]:::txn + pay("Bob's output 1.1"):::bob + chg("Alice's change 0.4"):::alice + ai --> tx + bi --> tx + tx --> pay + tx --> chg +``` + +*Here, Alice pays Bob 0.5: Bob's 0.6 input grows into a 1.1 output. The payment amount appears nowhere on-chain, and the ownership coloring is of course not part of the on-chain data either.* + +For privacy, a somewhat teleological but more general definition of PayJoin is a collaborative transaction that should be **indistinguishable from an ordinary single-party transaction**. The **unnecessary-input heuristics** flag an input when the remaining inputs could already fund the outputs and fees; such an input may reveal that another participant contributed it.[^uih-adamisz][^uih-ghesmati] If collaborative transactions were sufficiently common, naive application of CIOH would quickly lead to cluster collapse, forcing a more nuanced approach to clustering. + +CIOH, seeing two inputs, would wrongly attribute them to a single owner. There's no single unambiguous interpretation: Looking at a transaction like the example in isolation, an analyst cannot be sure which inputs are Alice's, which output is the real payment, or even that a PayJoin occurred at all rather than an ordinary two-input spend. + +With only two parties, there are only a few interpretations, namely the different ways of assigning inputs and outputs to sub-transactions attributed to Alice and Bob separately. The typical uncertainty is therefore on the order of a few bits to an external observer, even when looking only at the transaction in isolation and ignoring its context.[^payjoin-entropy] + +The next few sections discuss extensions to two-party PayJoin, but bear in mind that as they're more difficult to analyze, the same concerns apply even more to the two-party case. Additionally, a two-party PayJoin inherently cannot provide privacy from the counterparty. Each participant can eliminate their own inputs and outputs from consideration, which entails that everything else is attributable to the only other party. Privacy within a transaction requires three or more parties. + +## Many senders, one receiver (NS1R) + +A natural generalization is from one sender to many.[^ns1r] Several senders each contribute inputs to a single transaction that pays one common receiver, so it resembles an ordinary batched payout the receiver might have made by consolidating funds: + +```mermaid +flowchart LR + classDef s1c fill:#7993b6,stroke:#000,color:#111 + classDef s2c fill:#e9a969,stroke:#000,color:#111 + classDef s3c fill:#da817d,stroke:#000,color:#111 + classDef rc fill:#9dc5c1,stroke:#000,color:#111 + ls1(["Alice"]):::s1c -- "0.2" --> lr(["Dave"]):::rc + ls2(["Bob"]):::s2c -- "0.3" --> lr + ls3(["Carol"]):::s3c -- "0.7" --> lr +``` + +*The payment graph, which isn't observable on-chain.* + +```mermaid +flowchart LR + classDef s1c fill:#7993b6,stroke:#000,color:#111,rx:12,ry:12 + classDef s2c fill:#e9a969,stroke:#000,color:#111,rx:12,ry:12 + classDef s3c fill:#da817d,stroke:#000,color:#111,rx:12,ry:12 + classDef rc fill:#9dc5c1,stroke:#000,color:#111,rx:12,ry:12 + classDef txn fill:#444,stroke:#000,color:#fff + r1("Dave's input 0.4"):::rc + s1("Alice's input 0.5"):::s1c + s2("Bob's input 0.6"):::s2c + s3("Carol's input 0.9"):::s3c + tx["transaction"]:::txn + pay("Dave's output 1.6"):::rc + c1("Alice's change 0.3"):::s1c + c2("Bob's change 0.3"):::s2c + c3("Carol's change 0.2"):::s3c + r1 --> tx + s1 --> tx + s2 --> tx + s3 --> tx + tx --> c2 + tx --> pay + tx --> c3 + tx --> c1 +``` + +*Alice, Bob and Carol pay 0.2, 0.3 and 0.7 respectively; Dave consolidates the payments with a 0.4 input of his own. None of the payment amounts appear on-chain.* + +This allows more payments to be consolidated into a single receiver output, so it's cheaper than paying separately. + +Counterparty privacy depends on how the transaction is constructed. In the experimental NS1R implementation,[^ns1r] each sender supplied a pre-signed transaction to the receiver, revealing which inputs and change outputs belonged to that sender. If transaction construction conceals attribution, the receiver can still use its knowledge of each sender's payment amount to test possible input and change-output assignments. This can narrow the possibilities, and may identify a sender's change output, but does not by itself guarantee a unique assignment. + +This structure can't really hide much more than that: The change outputs will likely still link, and as the number of senders grows, the receiver must consolidate more aggressively to leverage the savings — which is itself a detectable fingerprint. Avoiding it means forgoing the fee savings and splitting the received funds into several outputs of a smaller magnitude to better match the distribution of the change outputs. Splitting the receiver's funds creates another hazard: Later spending those sibling outputs together, even in a multiparty transaction, is wasteful and potentially more indicative of common ownership than spending non-sibling outputs together. Two independent users participating in one transaction and then independently spending their respective outputs in the same subsequent transaction would arguably require more coincidences.[^siblings] + +## Many senders, many receivers (NSNR) + +The two sides can instead be made symmetric. Let $n = 2m$ be the number of participants, half spending and half receiving. The transaction consists of $m$ payments between the $n$ sub-transactions, pairing sub-transactions uniquely. + +```mermaid +flowchart LR + classDef s1c fill:#7993b6,stroke:#000,color:#111,rx:12,ry:12 + classDef s2c fill:#e9a969,stroke:#000,color:#111,rx:12,ry:12 + classDef s3c fill:#da817d,stroke:#000,color:#111,rx:12,ry:12 + classDef r1c fill:#9dc5c1,stroke:#000,color:#111,rx:12,ry:12 + classDef r2c fill:#88b279,stroke:#000,color:#111,rx:12,ry:12 + classDef r3c fill:#ecd580,stroke:#000,color:#111,rx:12,ry:12 + classDef txn fill:#444,stroke:#000,color:#fff + s1("Alice's input 0.9"):::s1c --> tx["transaction"]:::txn + r3("Frank's input 0.15"):::r3c --> tx + s2("Bob's input 0.4"):::s2c --> tx + r1("Dave's input 0.3"):::r1c --> tx + s3("Carol's input 0.45"):::s3c --> tx + r2("Erin's input 0.35"):::r2c --> tx + tx --> p2("Erin's output 0.85"):::r2c + tx --> c3("Carol's change 0.25"):::s3c + tx --> p1("Dave's output 0.5"):::r1c + tx --> c1("Alice's change 0.4"):::s1c + tx --> p3("Frank's output 0.45"):::r3c + tx --> c2("Bob's change 0.1"):::s2c +``` + +*A multiparty PayJoin transaction with three payments between six participants, with one input and one output per party.* + +```mermaid +flowchart LR + classDef s1c fill:#7993b6,stroke:#000,color:#111 + classDef s2c fill:#e9a969,stroke:#000,color:#111 + classDef s3c fill:#da817d,stroke:#000,color:#111 + classDef r1c fill:#9dc5c1,stroke:#000,color:#111 + classDef r2c fill:#88b279,stroke:#000,color:#111 + classDef r3c fill:#ecd580,stroke:#000,color:#111 + ls1(["Alice"]):::s1c -- "0.5" --> lr2(["Erin"]):::r2c + ls2(["Bob"]):::s2c -- "0.3" --> lr3(["Frank"]):::r3c + ls3(["Carol"]):::s3c -- "0.2" --> lr1(["Dave"]):::r1c +``` + +*The underlying payment graph, which isn't observable on-chain.* + +A different interpretation of the same transaction might swap the candidate ownership of Alice's 0.4 change and Erin's 0.85 output: + +```mermaid +flowchart LR + classDef s1c fill:#7993b6,stroke:#000,color:#111,rx:12,ry:12 + classDef s2c fill:#e9a969,stroke:#000,color:#111,rx:12,ry:12 + classDef s3c fill:#da817d,stroke:#000,color:#111,rx:12,ry:12 + classDef r1c fill:#9dc5c1,stroke:#000,color:#111,rx:12,ry:12 + classDef r2c fill:#88b279,stroke:#000,color:#111,rx:12,ry:12 + classDef r3c fill:#ecd580,stroke:#000,color:#111,rx:12,ry:12 + classDef txn fill:#444,stroke:#000,color:#fff + s1("Alice's input 0.9"):::s1c --> tx["transaction"]:::txn + r3("Frank's input 0.15"):::r3c --> tx + s2("Bob's input 0.4"):::s2c --> tx + r1("Dave's input 0.3"):::r1c --> tx + s3("Carol's input 0.45"):::s3c --> tx + r2("Erin's input 0.35"):::r2c --> tx + tx --> c1("Alice's change 0.85"):::s1c + tx --> c3("Carol's change 0.25"):::s3c + tx --> p1("Dave's output 0.5"):::r1c + tx --> p2("Erin's output 0.4"):::r2c + tx --> p3("Frank's output 0.45"):::r3c + tx --> c2("Bob's change 0.1"):::s2c +``` + +*Under this alternative assignment, Alice's 0.9 input leaves 0.85 in change, implying a payment of only 0.05 to Erin.* + +Because each participant only participates in exactly one payment, each hidden sub-transaction is related to only *one payment of one amount*. The amounts therefore still carry information. In the example above, the alternative 0.05 payment may seem less plausible than the original 0.5 payment if its magnitude is atypical relative to prior on-chain payments and auxiliary context such as exchange rates, timing, fees, and wallet fingerprints. This is essentially the same logic as the unnecessary input heuristics.[^uih-adamisz][^uih-ghesmati] And if the adversary happens to know that Alice's cluster contains a smaller UTXO than the 0.9 one which still suffices for a payment of 0.05, that would be rather strong evidence in favor of the payment amount being 0.5. + +## Net settlement with cycles + +Net settlement is the most general form of multiparty PayJoin. Where NSNR fixed $\frac{n}{2}$ payments among $n$ participants, net settlement allows odd $n$ and up to $\frac{n(n-1)}{2}$ net payments to be aggregated: Any participant may pay any other. + +Participants settle an arbitrary set of mutual obligations in a single transaction, including cycles (e.g. Alice pays Bob, Bob pays Carol, Carol pays Alice). A participant may both pay and receive payments in the same settlement. The number of participants $n$ is in general not observable from the transaction (though in some cases it can be statistically or directly inferred from its structure). + +```mermaid +flowchart LR + classDef ac fill:#7993b6,stroke:#000,color:#111,rx:12,ry:12 + classDef bc fill:#e9a969,stroke:#000,color:#111,rx:12,ry:12 + classDef cc fill:#da817d,stroke:#000,color:#111,rx:12,ry:12 + classDef txn fill:#444,stroke:#000,color:#fff + ia("Alice's input 0.6"):::ac --> tx["transaction"]:::txn + ib("Bob's input 0.2"):::bc --> tx + ic("Carol's input 0.5"):::cc --> tx + tx --> oc("Carol's output 0.4"):::cc + tx --> oa("Alice's output 0.5"):::ac + tx --> ob("Bob's output 0.4"):::bc +``` + +*A single settlement transaction. Under the ownership assignment shown, the balances are Alice +0.1, Bob −0.2, and Carol +0.1: inputs minus outputs, including fees. None of the individual obligation amounts appear on-chain.* + +```mermaid +flowchart LR + classDef ac fill:#7993b6,stroke:#000,color:#111 + classDef bc fill:#e9a969,stroke:#000,color:#111 + classDef cc fill:#da817d,stroke:#000,color:#111 + A(["Alice"]):::ac -- "0.5" --> B(["Bob"]):::bc + B -- "0.3" --> C(["Carol"]):::cc + C -- "0.4" --> A +``` + +*Three mutual obligations, including a cycle.* + +Once cycles are allowed, a participant's inferred balance can combine several payments sent and received, as well as their miner fee contribution. It is still a single amount, but its magnitude need not resemble that of any individual payment: Large payments in opposite directions can leave a small balance, including near zero. This weakens the amount-based analysis used in the preceding NSNR example. A small balance is no longer evidence of an implausibly small payment, because it may instead reflect the settlement of several larger obligations. + +Since net settlement is strictly more general, if it's supported in implementations, then *every* multiparty batch could in principle be a net settlement transaction, even if that's not actually the case. Conversely, if the only thing actually deployed is the restricted NSNR above, users are forced back into that weaker regime where amounts still leak. The strength of the defense depends on the general form being the norm, not the exception. + +Unfortunately, this isn't enough for privacy, because the resulting graph still has community structure. The adversary doesn't see only a single transaction; it sees the transaction graph and some clustering of it (which may be based just on the graph structure, or be based on blockchain-external information too). A settlement among counterparties is a slice of an economic network, and economic networks aren't featureless: They have recurring relationships, and the behaviors can often follow predictable patterns. + +### Sparse datasets + +Deanonymization of networks with exactly this kind of structure is a well studied problem. In 2008, Narayanan and Shmatikov showed that real-world high dimensional datasets are typically sparse — most records have no close neighbors in the feature space — and this sparseness makes deanonymization feasible with only a little auxiliary information, even when that information is noisy.[^ns-netflix][^ns-retro] + +Any observable pattern in a cluster is potentially useful for such an analysis. These divide into *statistical* features (fee-rate habits, activity timing and time zone, value distributions) and *topological* features (the shape a cluster carves through the graph and its links to other clusters). "Topological" is used to refer to the graph structure in order to distinguish it from the structure of transactions, which are more to do with wallet fingerprints. + +**Wallet (software) fingerprints** are a special case of the statistical kind: Signature grinding, fee-rate selection, script and address types, and `nSequence` and `nLockTime` conventions each vary from one wallet implementation to the next. While some wallets randomize these, and specific entities may use more than one piece of software, fingerprint-based clustering — both more generally[^moser-narayanan][^kappos], and also specifically in the context of PayJoin[^sabouri] — has thus far proven to be extremely powerful. This problem is pretty widespread. In principle, it can be mitigated by the Sisyphean task of making all wallets draw their observable behavior from similar enough distributions to render them indistinguishable. Note that these distributions need not be uniform, nor must every transaction look identical. + +Fortunately wallet fingerprints on their own do not have high enough dimensionality to satisfy the sparseness condition: while the software used to create certain transactions might be determined even with low uncertainty, that on its own does not distinguish one user of the software from another. It can nevertheless narrow the population within which other statistical and topological features distinguish a cluster. + +Unfortunately, that doesn't invalidate the general approach. And while minimizing fingerprint leaks is necessary for clustering resistance in a diverse wallet ecosystem, even if it comprehensively fixed that would not be sufficient for addressing these concerns they currently raise, since wallet fingerprints aren't the only dimensions along which clusters can be compared, and they remain useful when considering a model where sparseness does hold. + +### Social graphs + +Turning to the topological features, in subsequent work,[^ns-social] the same authors showed that the vertices of two social graphs can be matched iteratively, starting from a relatively small seed matching, which matches some of the vertices of one graph with those of the other. + +This builds on the sparseness assumption exploited by the previous work. Here, a "dimension" can be thought of roughly as whether some target vertex is related to some other specific vertex. In a social graph, most nodes will be readily identifiable based on the identities of their neighbors. The actual result in the paper is significantly stronger, requiring only a seed of relatively few matched nodes to iteratively propagate the matching along the graphs. Later work by Narayanan et al. generalized this further to link prediction on incomplete graphs.[^ns-linkpred] + +```mermaid +flowchart LR + classDef ac fill:#7993b6,stroke:#000,color:#111 + classDef bc fill:#e9a969,stroke:#000,color:#111 + classDef cc fill:#da817d,stroke:#000,color:#111 + classDef dc fill:#9dc5c1,stroke:#000,color:#111 + classDef enc fill:#88b279,stroke:#000,color:#111 + classDef acs fill:#7993b6,stroke:#ffe234,stroke-width:4px,color:#111 + classDef bcs fill:#e9a969,stroke:#ffe234,stroke-width:4px,color:#111 + classDef amb fill:#fafafa,stroke:#777,stroke-dasharray:4 3,color:#111 + classDef ambs fill:#fafafa,stroke:#ffe234,stroke-width:4px,color:#111 + subgraph aux["auxiliary graph"] + A(["Alice"]):::ac --- B(["Bob"]):::bc + A --- C(["Carol"]):::cc + B --- C + B --- D(["Dave"]):::dc + C --- E(["Erin"]):::enc + D --- E + end + subgraph anon["anonymized graph"] + v1(["Alice"]):::acs --- v2(["Bob"]):::bcs + v1 --- v3([" ? "]):::amb + v2 --- v3 + v2 --- v4([" ? "]):::amb + v3 --- v5([" ? "]):::amb + v4 --- v5 + v1 --- v6([" ? "]):::amb + end + A -.- v1 + B -.- v2 + style aux fill:none,stroke:#777 + style anon fill:none,stroke:#777 + linkStyle 13,14 stroke:#ffe234,stroke-width:3px +``` + +*The adversary holds two overlapping social graphs — one identified, one anonymized. The yellow correspondence edges mark the seed of confidently matched pairs, identifying their anonymous endpoints.* + +```mermaid +flowchart LR + classDef ac fill:#7993b6,stroke:#000,color:#111 + classDef bc fill:#e9a969,stroke:#000,color:#111 + classDef cc fill:#da817d,stroke:#000,color:#111 + classDef dc fill:#9dc5c1,stroke:#000,color:#111 + classDef enc fill:#88b279,stroke:#000,color:#111 + classDef acs fill:#7993b6,stroke:#ffe234,stroke-width:4px,color:#111 + classDef bcs fill:#e9a969,stroke:#ffe234,stroke-width:4px,color:#111 + classDef ccs fill:#da817d,stroke:#ffe234,stroke-width:4px,color:#111 + classDef amb fill:#fafafa,stroke:#777,stroke-dasharray:4 3,color:#111 + classDef ambs fill:#fafafa,stroke:#ffe234,stroke-width:4px,color:#111 + subgraph aux["auxiliary graph"] + A(["Alice"]):::ac --- B(["Bob"]):::bc + A --- C(["Carol"]):::cc + B --- C + B --- D(["Dave"]):::dc + C --- E(["Erin"]):::enc + D --- E + end + subgraph anon["anonymized graph"] + v1(["Alice"]):::acs --- v2(["Bob"]):::bcs + v1 --- v3(["Carol"]):::ccs + v2 --- v3 + v2 --- v4([" ? "]):::amb + v3 --- v5([" ? "]):::amb + v4 --- v5 + v1 --- v6([" ? "]):::amb + end + A -.- v1 + B -.- v2 + C -. "1" .- v3 + style aux fill:none,stroke:#777 + style anon fill:none,stroke:#777 + linkStyle 13,14,15 stroke:#ffe234,stroke-width:3px +``` + +*The only unidentified vertex adjacent to both seeds must be Carol's, so it's matched first.* + +```mermaid +flowchart LR + classDef ac fill:#7993b6,stroke:#000,color:#111 + classDef bc fill:#e9a969,stroke:#000,color:#111 + classDef cc fill:#da817d,stroke:#000,color:#111 + classDef dc fill:#9dc5c1,stroke:#000,color:#111 + classDef enc fill:#88b279,stroke:#000,color:#111 + classDef acs fill:#7993b6,stroke:#ffe234,stroke-width:4px,color:#111 + classDef bcs fill:#e9a969,stroke:#ffe234,stroke-width:4px,color:#111 + classDef ccs fill:#da817d,stroke:#ffe234,stroke-width:4px,color:#111 + classDef dcs fill:#9dc5c1,stroke:#ffe234,stroke-width:4px,color:#111 + classDef encs fill:#88b279,stroke:#ffe234,stroke-width:4px,color:#111 + classDef amb fill:#fafafa,stroke:#777,stroke-dasharray:4 3,color:#111 + classDef ambs fill:#fafafa,stroke:#ffe234,stroke-width:4px,color:#111 + subgraph aux["auxiliary graph"] + A(["Alice"]):::ac --- B(["Bob"]):::bc + A --- C(["Carol"]):::cc + B --- C + B --- D(["Dave"]):::dc + C --- E(["Erin"]):::enc + D --- E + end + subgraph anon["anonymized graph"] + v1(["Alice"]):::acs --- v2(["Bob"]):::bcs + v1 --- v3(["Carol"]):::ccs + v2 --- v3 + v2 --- v4(["Dave"]):::dcs + v3 --- v5(["Erin"]):::encs + v4 --- v5 + v1 --- v6([" ? "]):::amb + end + A -.- v1 + B -.- v2 + C -. "1" .- v3 + D -. "2" .- v4 + E -. "3" .- v5 + style aux fill:none,stroke:#777 + style anon fill:none,stroke:#777 + linkStyle 13,14,15,16,17 stroke:#ffe234,stroke-width:3px +``` + +*Each match extends the frontier: Dave's vertex is the remaining neighbor of Bob's, and Erin's is the remaining neighbor of Carol's. The graphs don't need to agree exactly — the vertex with no counterpart in the auxiliary graph simply remains unmatched.* + +Suppose the adversary starts with an incomplete clustering of Bitcoin transaction outputs. While the clusters do link together some outputs, because it's incomplete, there may be several clusters per actual user. So long as the adversary still hasn't collected enough evidence to conclude that several clusters belong to the same user, that user still enjoys pseudonymity. + +This adversary doesn't just apply CIOH blindly. When it's first observed, a transaction suspected to be a PayJoin, for example, will have four or more related clusters. Each entity will be represented by at least one input-side cluster and at least one output-side cluster. Naive CIOH would compel merging of all of the input clusters, and change identification may additionally link it to one of the outputs. Subsequent transactions will in turn link to those. The ensuing cluster collapse will of course be avoided by any competent adversary. + +Starting with the transaction graph, where coins are vertices, let clusters be represented by undirected edges connecting the linked coins. By edge contraction on these edges, a graph minor analogue[^minor-nitpick] can be obtained from a given clustering, where all of the coins of a particular cluster are fused into just one vertex representing the cluster itself. The residual edges of this multigraph correspond to transfers of Bitcoin between clusters, so those relationships remain available for analysis. + +Reid and Harrigan's paper[^reid-harrigan], in its discussion of clustering, introduced the notion of a user network, where vertices are users and edges represent the flows of Bitcoin between them. If the clustering is complete, and each user can be identified with just one node on the contracted graph, that is the user network. Otherwise, when the clustering is incomplete, this cluster graph is better thought of as a pseudonym graph rather than a user network. This is a social network per Shmatikov and Narayanan's definition.[^multigraph-nitpick] The statistical feature distributions of clusters reduce to attributes on the vertices, and both those and the topological features can inform the edge attributes used in their algorithm. + +Narayanan and Shmatikov's propagation algorithm starts with two graph views and a seed correspondence between some of their vertices. Contracting the entire coin graph gives us only one view. To obtain several, we could first partition the cluster-annotated coin graph, for example into epochs, and then contract each subgraph separately. Each resulting graph minor analogue would then present a view of the pseudonym graph over a different period. + +Existing clustering supplies the seed correspondence. If a coin in one epoch is already linked to a coin in another, their cluster vertices form a seed pair. Address reuse, heuristics applied to boundary transactions, or auxiliary information can supply such links. + +The more active a user is, the more data they expose. Consistent economic relationships can also make their neighborhood recognizable across epochs. Where the views preserve enough of this structure and the adversary has suitable seeds, Shmatikov and Narayanan's graph matching algorithm can propagate clustering information beyond local heuristics. A proliferation of pseudonyms may limit any one run of the propagation algorithm, but high-confidence matches can still inform other clustering heuristics, and the outputs of other clustering heuristics can be used as inputs to this algorithm. + +Epochs are also only one way to partition the coin graph. Another approach would place the boundaries at high-ambiguity regions, where many clusters seemingly connect to many others, as CoinJoins tend to produce. Excluding those densely connected regions can leave components in which each cluster has relatively few neighbors. The adversary can then compare components from different partitions. + +As a crude analogy, this is the “opposite” of expander decomposition, a technique that partitions a graph by making sparse cuts in order to decompose a graph into several components, while retaining strong connectivity within each component. Here, the adversary instead decomposes the graph along dense, high-ambiguity regions in order to obtain sparse components whose relationships are easier to match to one another. + +Some clustering must already have been produced by another technique for this to work, hence the starting assumption that the clustering is partial. It both supplies the annotations that make contraction possible in the first place and provides the seed correspondence from which graph matching can propagate. + +So, even when net settlements call amount-based analysis into question, and the number of parties complicates things further, the nature of social networks and of the transaction graph is that over time, a lot of structure will inevitably be revealed. There's an expression that illustrates this; I think it goes something like "show [the adversary] who your friends are, and [the adversary] will [successfully deanonymize you]." + +## Equal amount CoinJoin among arbitrary peers + +Every construction so far required its participants to be doing business with one another: a payment, a batch of payments, a settlement of mutual obligations. + +A CoinJoin doesn't have this limitation.[^maxwell] The participants of an equal amount CoinJoin transaction spend their inputs to produce outputs of the same amount and script type. Traditionally parties are assumed to not be related except in that they are participating in the same transaction, which implies there are no payments settled between them apart from any fees related to the transaction itself, which tend to be low. + +```mermaid +flowchart LR + classDef ac fill:#7993b6,stroke:#000,color:#111,rx:12,ry:12 + classDef bc fill:#e9a969,stroke:#000,color:#111,rx:12,ry:12 + classDef cc fill:#da817d,stroke:#000,color:#111,rx:12,ry:12 + classDef txn fill:#444,stroke:#000,color:#fff + classDef amb fill:#fafafa,stroke:#777,stroke-dasharray:4 3,color:#111,rx:12,ry:12 + a1("Alice's input 0.7"):::ac --> cj["CoinJoin"]:::txn + b1("Bob's input 0.25"):::bc --> cj + b2("Bob's input 0.15"):::bc --> cj + c1("Carol's input 0.55"):::cc --> cj + cj --> e1("output 0.3"):::amb + cj --> cb("Bob's change 0.1"):::bc + cj --> e2("output 0.3"):::amb + cj --> cc2("Carol's change 0.25"):::cc + cj --> e3("output 0.3"):::amb + cj --> ca("Alice's change 0.4"):::ac +``` + +*The equal outputs are interchangeable, but the change outputs remain linked to the inputs by their amounts, and Bob's two inputs are linked to each other by the consolidation forced by a minimum denomination requirement.* + +PayJoin transactions are made when one party intends to pay another, but in CoinJoin transactions no such relationship between the parties needs to exist. This means they can be chosen randomly from a broader population rather than be constrained by the structure of the real world user network and its economic relationships. While it may seem that this already confounds social-graph analysis, this type of CoinJoin is readily identifiable. A cautious adversary can decline to apply CIOH within it, leaving additional cluster pseudonyms, while still matching the implied user graphs on either side.[^ns-social] Observable flows between apparent clusters elsewhere in the graph can still expose recurring economic relationships and therefore community structure. + +What it can do is introduce uncertainty about the origins of a coin, limiting the ability to perform input-side clustering for any subsequent transactions as well. This slows the rate at which certainty can be gained about clustering structures, but it isn't a comprehensive or robust defense, and over time, such structures will generally be revealed.[^danezis][^troncoso] + +Unfortunately, linking inputs to one another is practically inherent in the equal-amount approach.[^tx0] Users generally cannot choose incoming payment amounts or outgoing-payment change to match a CoinJoin denomination, so reaching that denomination often requires combining inputs and almost always produces change. This change is also relatively easy to link to the input clusters, as discussed in the next section. + +Turning to the equal amount outputs, their order is presumed to be meaningless, so as long as they're unspent, they're interchangeable. But this doesn't last indefinitely. Any spending transactions of these outputs will reveal more information about an output's ownership through its timing, fingerprints, and other information that can be incorporated into the adversary's clustering model. + +Furthermore, even though such a transaction only spends a single output, any change left from the payment will, in general, not be of a specific denomination either. To avoid harming the privacy of the payment transaction, this change shouldn't be linkable to the spender's other on-chain activity, but even if spent into a CoinJoin, the equal amount approach necessitates consolidating multiple such coins together, which potentially links many "anonymous" transactions to each other, and to subsequent transactions via the change from the CoinJoin. + +For example, suppose Alice obtains two seemingly anonymous coins from two independent CoinJoins of the same denomination and spends each in its own payment: + +```mermaid +flowchart LR + classDef rc fill:#9dc5c1,stroke:#000,color:#111,rx:12,ry:12 + classDef r2c fill:#88b279,stroke:#000,color:#111,rx:12,ry:12 + classDef txn fill:#444,stroke:#000,color:#fff + classDef amb fill:#fafafa,stroke:#777,stroke-dasharray:4 3,color:#111,rx:12,ry:12 + cj1["CoinJoin 1"]:::txn + cj1 --> m2("output 0.1"):::amb + cj1 --> m3("output 0.1"):::amb + cj1 --> m1("output 0.1"):::amb + cj2["CoinJoin 2"]:::txn + cj2 --> n1("output 0.1"):::amb + cj2 --> n2("output 0.1"):::amb + cj2 --> n3("output 0.1"):::amb + m1 --> tx1["transaction"]:::txn + tx1 --> p1("payment 0.03"):::rc + tx1 --> g1("change 0.07"):::amb + n1 --> tx2["transaction"]:::txn + tx2 --> g2("change 0.04"):::amb + tx2 --> p2("payment 0.06"):::r2c +``` + +*Two mixed coins spent independently: Each payment is ambiguous, and nothing links the payments to the same user.* + +Later, wanting to CoinJoin again, she consolidates the two leftover change outputs: + +```mermaid +flowchart LR + classDef ac fill:#7993b6,stroke:#000,color:#111,rx:12,ry:12 + classDef bc fill:#e9a969,stroke:#000,color:#111,rx:12,ry:12 + classDef rc fill:#9dc5c1,stroke:#000,color:#111,rx:12,ry:12 + classDef r2c fill:#88b279,stroke:#000,color:#111,rx:12,ry:12 + classDef txn fill:#444,stroke:#000,color:#fff + classDef amb fill:#fafafa,stroke:#777,stroke-dasharray:4 3,color:#111,rx:12,ry:12 + classDef acg fill:#7993b6,stroke:#ffe234,stroke-width:5px,color:#111,rx:12,ry:12 + cj1["CoinJoin 1"]:::txn + cj1 --> m2("output 0.1"):::amb + cj1 --> m3("output 0.1"):::amb + cj1 --> m1("Alice's output 0.1"):::acg + cj2["CoinJoin 2"]:::txn + cj2 --> n1("Alice's output 0.1"):::acg + cj2 --> n2("output 0.1"):::amb + cj2 --> n3("output 0.1"):::amb + m1 --> tx1["transaction"]:::txn + tx1 --> p1("payment 0.03"):::rc + tx1 --> g1("Alice's change 0.07"):::acg + n1 --> tx2["transaction"]:::txn + tx2 --> g2("Alice's change 0.04"):::acg + tx2 --> p2("payment 0.06"):::r2c + g1 --> cj3["CoinJoin 3"]:::txn + g2 --> cj3 + b1("Bob's input 0.13"):::bc --> cj3 + cj3 --> q1("output 0.1"):::amb + cj3 --> q2("output 0.1"):::amb + cj3 --> q3("Alice's change 0.01"):::acg + cj3 --> q4("Bob's change 0.03"):::bc + linkStyle 6,8,9,10,12,13,17 stroke:#ffe234,stroke-width:4px +``` + +*The consolidating CoinJoin links the two change outputs, which links the two payments and retroactively identifies Alice's outputs in both of the original CoinJoins.* + +In other words, attempting to CoinJoin to recover the change and make it usable for private payments not only fails to achieve that goal, but also undoes the privacy of the previous transactions. + +## Arbitrary amount CoinJoin + +So strict adherence to the equal amount approach leaks information about linkage after the fact. Naive batching, which we glossed over, does too, even without considering the wider context of the graph.[^sudoku] + +The Boltzmann link probability matrix[^boltzmann] and Maurer et al.'s sub-transaction model[^maurer] are two similar models. They employ a combinatorial approach: Count all the ways the transaction could be partitioned, grouping together subsets of the inputs and outputs into sub-transactions, which are assumed to be the actions of a single party in a multiparty transaction. + +What exactly makes a partition a valid sub-transaction mapping is whether or not the sub-transaction is deemed plausible. In Maurer et al., the values of the inputs and the outputs must exactly cancel out, which isn't sufficiently general for real-world analyses. Boltzmann casts a wider net by allowing these to vary somewhat, accounting for fees (including JoinMarket maker fees). + +A large number of possible partitions does not by itself imply much privacy: Most of the probability may be concentrated on just a few of them. Entropy quantifies the uncertainty in this distribution, measured in bits.[^diaz][^serjantov-danezis][^syverson][^scroll-intersection] + +When a sub-transaction mapping is underdetermined, more than one assignment of inputs and outputs to separate sub-transactions remains possible. If several assignments have comparable probabilities, the adversary needs further information to distinguish them. The entropy of the distribution implies a lower bound on how much additional information is required. Output values can be deliberately chosen to create many possible assignments.[^radix] + +```mermaid +flowchart LR + classDef ac fill:#7993b6,stroke:#000,color:#111,rx:12,ry:12 + classDef bc fill:#e9a969,stroke:#000,color:#111,rx:12,ry:12 + classDef txn fill:#444,stroke:#000,color:#fff + b1("Bob's input 2"):::bc --> cj["Bad CoinJoin"]:::txn + a1("Alice's input 0.3"):::ac --> cj + b2("Bob's input 5"):::bc --> cj + a2("Alice's input 0.1"):::ac --> cj + cj --> o1("Alice's output 0.4"):::ac + cj --> o2("Bob's output 7"):::bc +``` + +*Carelessly chosen values are no better than a naive batch: The only sub-transaction mapping consistent with the amounts is 0.1 + 0.3 = 0.4 and 2 + 5 = 7, so a subset sum analysis fully partitions the transaction.* + +```mermaid +flowchart LR + classDef txn fill:#444,stroke:#000,color:#fff + classDef amb fill:#fafafa,stroke:#777,stroke-dasharray:4 3,color:#111,rx:12,ry:12 + b1("input 0.1"):::amb --> cj["CoinJoin"]:::txn + a2("input 0.4"):::amb --> cj + b2("input 0.2"):::amb --> cj + b3("input 0.5"):::amb --> cj + a1("input 0.3"):::amb --> cj + cj --> o1("output 0.7"):::amb + cj --> o2("output 0.8"):::amb +``` + +*With values chosen to be underdetermined, three distinct mappings balance: The 0.7 output can be funded by 0.3 + 0.4, by 0.2 + 0.5, or by 0.1 + 0.2 + 0.4, with the remaining inputs funding the 0.8 output. Across these readings — and the single-owner one — no input is linked to either output.* + +Alternatively, the assumption that each participant's sub-transaction is balanced (allowing for fees), can be invalidated. As discussed above, net settlement allows one participant's surplus to cover another's deficit while the transaction as a whole still balances. There's no technical reason why economically related users couldn't settle within a protocol that also admits strangers to the same transaction. This will also conceal their business relationships better than a purely net settlement transaction structure. + +The adversary can also incorporate statistical features, topological features of the surrounding graph, and auxiliary information into its sub-transaction analysis. These can change the plausibility of a mapping which only accounts for the amounts. Neither variant of the model, as originally described, incorporates these additional observables. For this reason, neither net settlement nor overtly ambiguous CoinJoins can offer a comprehensive solution to these problems. + +## Taking provenance into account + +Enumerating the possible points of origin of the funds of a particular coin is fairly intuitive based on the graph structure.[^kelen-seres] The entropy of the probability distribution of this candidate set can grow fairly quickly by CoinJoining, especially if an effort is made to diversify peer selection. + +However, it can also decay rather quickly. Suppose the adversary successfully deanonymizes some auxiliary user. This can have two very different outcomes: + +- The coins of that user are eliminated as linking candidates when attempting to deanonymize the target user. This is an additive decay of privacy. +- In addition, the eliminated coins form the boundary between regions of the transaction graph, fracturing it. This is a multiplicative decay of privacy, and the adversary can make progress at an exponential rate when this is the case. + +An entropy estimate based on on-chain observations measures uncertainty under the information available to that particular observer. It cannot represent the uncertainty remaining for an adversary with additional information, nor how quickly that uncertainty could shrink. + +For example, a chain analysis vendor with KYC information may already be able to separate regions of a graph that still appears highly ambiguous to an outside observer. Users therefore need a safety margin chosen for the auxiliary information their threat model allows the adversary to have. + +## Robust connectivity + +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. + +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. + +```mermaid +flowchart LR + classDef ac fill:#7993b6,stroke:#000,color:#111 + classDef bc fill:#e9a969,stroke:#000,color:#111 + classDef cc fill:#da817d,stroke:#000,color:#111 + classDef dc fill:#9dc5c1,stroke:#000,color:#111 + classDef enc fill:#88b279,stroke:#000,color:#111 + classDef txn fill:#444,stroke:#000,color:#fff + classDef amb1 fill:#fdf6ec,stroke:#777,stroke-dasharray:4 3,color:#111,rx:12,ry:12 + classDef amb2 fill:#edf5f5,stroke:#777,stroke-dasharray:4 3,color:#111,rx:12,ry:12 + B(["Bob's cluster"]):::bc --> cj1 + C(["Carol's cluster"]):::cc --> cj1 + A(["Alice's cluster"]):::ac --> cj1["CoinJoin 1"]:::txn + A --> cj2["CoinJoin 2"]:::txn + D(["Dave's cluster"]):::dc --> cj2 + E(["Erin's cluster"]):::enc --> cj2 + cj1 --> x1("Alice, Bob or Carol?"):::amb1 + cj1 --> x2("Alice, Bob or Carol?"):::amb1 + cj1 --> x3("Alice, Bob or Carol?"):::amb1 + cj2 --> y1("Alice, Dave or Erin?"):::amb2 + cj2 --> y2("Alice, Dave or Erin?"):::amb2 + cj2 --> y3("Alice, Dave or Erin?"):::amb2 +``` + +*The adversary's view while the CoinJoin outputs remain unspent: six outputs in two equivalence classes, each output ambiguous among its CoinJoin's participants.* + +```mermaid +flowchart LR + classDef txn fill:#444,stroke:#000,color:#fff + classDef amb fill:#fafafa,stroke:#777,stroke-dasharray:4 3,color:#111,rx:12,ry:12 + classDef aci fill:#7993b6,stroke:#e9a969,stroke-width:8px,color:#000,font-weight:bold + classDef bc1 fill:#e9a969,stroke:#ffe234,stroke-width:2px,color:#111 + classDef cc1 fill:#da817d,stroke:#ffe234,stroke-width:2px,color:#111 + classDef aco1 fill:#7993b6,stroke:#ffe234,stroke-width:3px,color:#111,rx:12,ry:12 + classDef dc2 fill:#9dc5c1,stroke:#ff7a76,stroke-width:2px,color:#111 + classDef enc2 fill:#88b279,stroke:#ff7a76,stroke-width:2px,color:#111 + classDef aco2 fill:#7993b6,stroke:#ff7a76,stroke-width:3px,color:#111,rx:12,ry:12 + B(["Bob's cluster"]):::bc1 --> cj1 + C(["Carol's cluster"]):::cc1 --> cj1 + A(["Alice's cluster"]):::aci --> cj1["CoinJoin 1"]:::txn + A --> cj2["CoinJoin 2"]:::txn + D(["Dave's cluster"]):::dc2 --> cj2 + E(["Erin's cluster"]):::enc2 --> cj2 + cj1 --> xo1("Bob or Carol?"):::amb + cj1 --> x("Alice's output"):::aco1 + cj1 --> xo2("Bob or Carol?"):::amb + cj2 --> y("Alice's output"):::aco2 + x --> sp["transaction"]:::txn + y --> sp + cj2 --> yo1("Dave or Erin?"):::amb + cj2 --> yo2("Dave or Erin?"):::amb + linkStyle 0,1 stroke:#ffe234,stroke-width:2px + linkStyle 2,7,10 stroke:#ffe234,stroke-width:5px + linkStyle 4,5 stroke:#ff7a76,stroke-width:2px + linkStyle 3,9,11 stroke:#ff7a76,stroke-width:5px +``` + +*Alice's spend links one output from each class. Tracing each input back — from spent output, through its creating CoinJoin, and to the pre-CoinJoin input clusters — gives the two antecessor sets, highlighted in yellow and red. These overlap only at Alice's cluster, highlighted as the one node belonging to both: The intersection identifies her, and by elimination also narrows the remaining outputs' candidate sets: CoinJoin 1's to Bob or Carol, CoinJoin 2's to Dave or Erin.* + +If each additional intersection reduces the remaining candidate set by a constant factor, its size falls exponentially with the number of observations. Starting from $n$ candidates, a process of elimination that rules out one candidate at a time will take $O(n)$ time to narrow down a single candidate, but if intersections are used to eliminate them then $O(\log n)$ observations may suffice for successful deanonymization. + +This holds unless the size of the symmetric difference between antecessor sets is bounded by a constant — i.e. the antecessor sets of linked coins are very similar — because then the size of the intersection is similar to the size of the intersected sets. This attack is powerful because that similarity is rare in practice: The intersection will usually be significantly smaller than the sets themselves. + +It's also important to bear in mind that the candidate origins aren't coins, but rather clusters, so the objects being intersected needn't be connected on the transaction graph for the adversary to notice an overlap. This is particularly concerning because the clusters being intersected are the pre-CoinJoin ones, where — presumably — privacy is inherently weak. It's also worth emphasizing that the change outputs of equal amount CoinJoins are part of these clusters as well. + +Next, consider an adversary who is also a counterparty — for example, an ATM in some remote location that sells coins to a user in exchange for cash, and later receives funds from descendants of those coins. Such a counterparty knows, from its own records, exactly which coins it paid out and can observe when descendants of those coins are sold back to it. Connectivity to a crowd of strangers over the internet does little against this, because none of those strangers are likely to have transacted with the ATM, and the CoinJoin doesn't sever the link from a coin to its past. By the same logic of intersection attacks, privacy loss arising from consolidation of more than one input doesn't just add up; it compounds. This is known as the **Eve-Alice-Eve** threat model. + +## Own-origin robustness + +The privileged counterparty knows one endpoint because it *is* the origin, so the property is stated relative to that origin. It demands that a coin have many plausible, counterfactual paths back to the user's own antecedent coins. + +Suppose Alice withdraws from that ATM, and that is her only means of obtaining Bitcoin. She then CoinJoins with Bob. If one of those coins is then returned to the ATM, its operator can conclude that it is likely Alice. + +```mermaid +flowchart LR + classDef ac fill:#7993b6,stroke:#000,color:#111,rx:12,ry:12 + classDef bc fill:#e9a969,stroke:#000,color:#111,rx:12,ry:12 + classDef ec fill:#b996b2,stroke:#000,color:#111,rx:12,ry:12 + classDef txn fill:#444,stroke:#000,color:#fff + classDef amb fill:#fafafa,stroke:#777,stroke-dasharray:4 3,color:#111,rx:12,ry:12 + atm(("ATM")):::ec -. "withdrawal" .-> a0("Alice's coin"):::ac + a0 --> cj["CoinJoin
Alice + Bob"]:::txn + b0("Bob's coin"):::bc --> cj + cj --> x1("Alice or Bob?"):::amb + cj --> x2("Alice or Bob?"):::amb + x1 --> deposit["deposit"]:::txn + deposit --> atmd("ATM's output"):::ec +``` + +*Taken in isolation, the deposited coin is ambiguous: It could be Alice's or Bob's.* + +```mermaid +flowchart LR + classDef ac fill:#7993b6,stroke:#000,color:#111,rx:12,ry:12 + classDef bc fill:#e9a969,stroke:#000,color:#111,rx:12,ry:12 + classDef ec fill:#b996b2,stroke:#000,color:#111,rx:12,ry:12 + classDef txn fill:#444,stroke:#000,color:#fff + classDef acg fill:#7993b6,stroke:#ffe234,stroke-width:5px,color:#111,rx:12,ry:12 + atm(("ATM")):::ec -. "withdrawal" .-> a0("Alice's coin"):::acg + a0 --> cj["CoinJoin
Alice + Bob"]:::txn + b0("Bob's coin"):::bc --> cj + cj --> x1("Alice's output"):::acg + cj --> x2("Bob's output"):::bc + x1 --> deposit["deposit"]:::txn + deposit --> atmd("ATM's output"):::ec + linkStyle 0,1,3,5,6 stroke:#ffe234,stroke-width:4px +``` + +*But in this minimal example, the ambiguity is thin. The ATM can conclude with reasonable certainty that the deposit is Alice's, because it's much more likely to get repeated business from her than it is for her to randomly interact with Bob just before Bob happens to use the ATM.* + +Consolidation makes the ATM's job easier still. Suppose Alice withdraws two coins, mixes each once with a different peer, and then spends the two mixed outputs together: + +```mermaid +flowchart LR + classDef ac fill:#7993b6,stroke:#000,color:#111,rx:12,ry:12 + classDef bc fill:#e9a969,stroke:#000,color:#111,rx:12,ry:12 + classDef cc fill:#da817d,stroke:#000,color:#111,rx:12,ry:12 + classDef ec fill:#b996b2,stroke:#000,color:#111,rx:12,ry:12 + classDef txn fill:#444,stroke:#000,color:#fff + classDef acg fill:#7993b6,stroke:#ffe234,stroke-width:5px,color:#111,rx:12,ry:12 + atm(("ATM")):::ec -. "withdrawal" .-> a0("Alice's coin"):::acg + atm -. "withdrawal" .-> a0b("Alice's other coin"):::acg + b0("Bob's coin"):::bc --> cj1 + a0 --> cj1["CoinJoin 1
Alice + Bob"]:::txn + cj1 --> o2("Bob's output"):::bc + cj1 --> o1("Alice's output"):::acg + a0b --> cj2["CoinJoin 2
Alice + Carol"]:::txn + c0("Carol's coin"):::cc --> cj2 + cj2 --> o3("Alice's output"):::acg + cj2 --> o4("Carol's output"):::cc + o1 --> deposit["deposit"]:::txn + o3 --> deposit + deposit --> atmd("ATM's output"):::ec + linkStyle 0,1,3,5,6,8,10,11,12 stroke:#ffe234,stroke-width:4px +``` + +*Each CoinJoin output on its own is ambiguous, but only Alice is consistent with both inputs of the consolidation, so the deposit identifies her. Additional inputs amplify the ATM's observing power exponentially.* + +Suppose instead that Bob CoinJoins with another user, Carol, and then Carol CoinJoins with Alice. + +If *Carol* were to use the ATM at that point, her coin would have inherited Alice's provenance, which may cause the ATM to incorrectly conclude that it is Alice who is using it. By symmetry, if it were Alice who did that, she gets some degree of plausible deniability. + +```mermaid +flowchart LR + classDef ac fill:#7993b6,stroke:#000,color:#111,rx:12,ry:12 + classDef bc fill:#e9a969,stroke:#000,color:#111,rx:12,ry:12 + classDef cc fill:#da817d,stroke:#000,color:#111,rx:12,ry:12 + classDef ec fill:#b996b2,stroke:#000,color:#111,rx:12,ry:12 + classDef txn fill:#444,stroke:#000,color:#fff + atm(("ATM")):::ec -. "withdrawal" .-> a0("Alice's coin"):::ac + a0 --> cj1["CoinJoin 1
Alice + Bob"]:::txn + b0("Bob's coin"):::bc --> cj1 + cj1 --> a1("Alice's output"):::ac + cj1 --> b1("Bob's output"):::bc + b1 --> cj2["CoinJoin
Bob + Carol"]:::txn + c0("Carol's coin"):::cc --> cj2 + cj2 --> c1("Carol's output"):::cc + cj2 --> b2("Bob's output"):::bc + a1 --> cj3["CoinJoin 3
Carol + Alice"]:::txn + c1 --> cj3 + cj3 --> o1("Alice's output"):::ac + cj3 --> o2("Carol's output"):::cc + o2 --> deposit["deposit"]:::txn + deposit --> atmd("ATM's output"):::ec +``` + +*In this scenario, it *is* actually Carol who deposits, and the funds were never in Alice's possession, but their history is interwoven with Alice's through the CoinJoins, which, by the same logic, would cause the adversary to mistakenly conclude that it is Alice.* + +```mermaid +flowchart LR + classDef ac fill:#7993b6,stroke:#000,color:#111,rx:12,ry:12 + classDef bc fill:#e9a969,stroke:#000,color:#111,rx:12,ry:12 + classDef cc fill:#da817d,stroke:#000,color:#111,rx:12,ry:12 + classDef ec fill:#b996b2,stroke:#000,color:#111,rx:12,ry:12 + classDef txn fill:#444,stroke:#000,color:#fff + classDef amb fill:#fafafa,stroke:#777,stroke-dasharray:4 3,color:#111,rx:12,ry:12 + atm(("ATM")):::ec -. "withdrawal" .-> a0("Alice's coin"):::ac + a0 --> cj1["CoinJoin 1
Alice + Bob"]:::txn + b0("Bob's coin"):::bc --> cj1 + cj1 --> a1("Alice or Bob?"):::amb + cj1 --> b1("Alice or Bob?"):::amb + b1 --> cj2["CoinJoin
Bob + Carol"]:::txn + c0("Carol's coin"):::cc --> cj2 + cj2 --> c1("Alice, Bob or Carol?"):::amb + cj2 --> b2("Alice, Bob or Carol?"):::amb + a1 --> cj3["CoinJoin 3
Carol or Bob + Alice"]:::txn + c1 --> cj3 + cj3 --> o1("Alice, Bob or Carol?"):::amb + cj3 --> o2("Alice, Bob or Carol?"):::amb + o2 --> deposit["deposit"]:::txn + deposit --> atmd("ATM's output"):::ec +``` + +*The same transactions from the ATM's point of view: After CoinJoin 3, the two outputs are equivalent — whichever one is deposited has plausible paths back to the dispensed coin, directly through CoinJoin 3 or via Bob through CoinJoins 1 and 2 — so the ATM cannot tell Alice returning from either Bob or Carol.* + +Repeated CoinJoins can spread Alice's coins' provenance-related features to other users' coins while spreading their features to hers. This allows her to build up to a quantifiable anonymity set. + +```mermaid +flowchart LR + classDef ac fill:#7993b6,stroke:#000,color:#111,rx:12,ry:12 + classDef bc fill:#e9a969,stroke:#000,color:#111,rx:12,ry:12 + classDef cc fill:#da817d,stroke:#000,color:#111,rx:12,ry:12 + classDef dc fill:#9dc5c1,stroke:#000,color:#111,rx:12,ry:12 + classDef enc fill:#88b279,stroke:#000,color:#111,rx:12,ry:12 + classDef fc fill:#ecd580,stroke:#000,color:#111,rx:12,ry:12 + classDef txn fill:#444,stroke:#000,color:#fff + classDef txni fill:#444,stroke:#5778a4,stroke-width:6px,color:#fff + classDef ai fill:#7993b6,stroke:#5778a4,stroke-width:6px,color:#111,rx:12,ry:12 + classDef bi fill:#e9a969,stroke:#5778a4,stroke-width:6px,color:#111,rx:12,ry:12 + classDef ci fill:#da817d,stroke:#5778a4,stroke-width:6px,color:#111,rx:12,ry:12 + classDef di fill:#9dc5c1,stroke:#5778a4,stroke-width:6px,color:#111,rx:12,ry:12 + a0("Alice's coin"):::ac --> cj1["CoinJoin
Alice + Bob"]:::txni + b0("Bob's coin"):::bc --> cj1 + cj1 --> a1("Alice's output"):::ai + cj1 --> b1("Bob's output"):::bi + b1 --> cj2["CoinJoin
Bob + Carol"]:::txni + c0("Carol's coin"):::cc --> cj2 + cj2 --> b2("Bob's output"):::bi + cj2 --> c1("Carol's output"):::ci + d0("Dave's coin"):::dc --> cjx1["CoinJoin
Dave + Erin"]:::txn + e0("Erin's coin"):::enc --> cjx1 + cjx1 --> d1("Dave's output"):::dc + cjx1 --> e1("Erin's output"):::enc + c1 --> cj3["CoinJoin
Carol + Dave"]:::txni + d1 --> cj3 + cj3 --> c2("Carol's output"):::ci + cj3 --> d2("Dave's output"):::di + e1 --> cjx2["CoinJoin
Erin + Frank"]:::txn + f0("Frank's coin"):::fc --> cjx2 + cjx2 --> e2("Erin's output"):::enc + cjx2 --> f1("Frank's output"):::fc + linkStyle 0,2,3,4,6,7,12,14,15 stroke:#5778a4,stroke-width:3px +``` + +*Coins are colored by their true owner; a thick blue border marks the coins descending from Alice's. Dave's coin picks up the fingerprint when mixing with Carol, for example.* + +As this set grows, Alice's chances of CoinJoining her actual funds with such a coin increase with time. If Alice participates in enough CoinJoins so that eventually inputs to the next CoinJoin are already descendants of her prior coin and many such counterfactual paths exist, that can provide privacy even against an adversarial counterparty, which by finding its own coins in the intersection is able to cluster much more reliably than a third-party observer relying on heuristics. + +```mermaid +flowchart LR + classDef ac fill:#7993b6,stroke:#000,color:#111,rx:12,ry:12 + classDef bc fill:#e9a969,stroke:#000,color:#111,rx:12,ry:12 + classDef cc fill:#da817d,stroke:#000,color:#111,rx:12,ry:12 + classDef dc fill:#9dc5c1,stroke:#000,color:#111,rx:12,ry:12 + classDef enc fill:#88b279,stroke:#000,color:#111,rx:12,ry:12 + classDef fc fill:#ecd580,stroke:#000,color:#111,rx:12,ry:12 + classDef gc fill:#b9a0d8,stroke:#000,color:#111,rx:12,ry:12 + classDef txn fill:#444,stroke:#000,color:#fff + classDef txni fill:#444,stroke:#5778a4,stroke-width:6px,color:#fff + classDef ai fill:#7993b6,stroke:#5778a4,stroke-width:6px,color:#111,rx:12,ry:12 + classDef bi fill:#e9a969,stroke:#5778a4,stroke-width:6px,color:#111,rx:12,ry:12 + classDef ci fill:#da817d,stroke:#5778a4,stroke-width:6px,color:#111,rx:12,ry:12 + classDef di fill:#9dc5c1,stroke:#5778a4,stroke-width:6px,color:#111,rx:12,ry:12 + classDef ei fill:#88b279,stroke:#5778a4,stroke-width:6px,color:#111,rx:12,ry:12 + classDef fi fill:#ecd580,stroke:#5778a4,stroke-width:6px,color:#111,rx:12,ry:12 + classDef gi fill:#b9a0d8,stroke:#5778a4,stroke-width:6px,color:#111,rx:12,ry:12 + + a0("Alice"):::ac --> cj1[" "]:::txni + b0("Bob"):::bc --> cj1 + cj1 --> a1("Alice"):::ai + cj1 --> b1("Bob"):::bi + a1 --> cj6[" "]:::txni + + b1 --> cj2[" "]:::txni + c0("Carol"):::cc --> cj2 + cj2 --> c1("Carol"):::ci + cj2 --> b2("Bob"):::bi + d0("Dave"):::dc --> cjx1[" "]:::txn + e0("Erin"):::enc --> cjx1 + cjx1 --> d1("Dave"):::dc + cjx1 --> e1("Erin"):::enc + c1 --> cj3[" "]:::txni + d1 --> cj3 + cj3 --> d2("Dave"):::di + cj3 --> c2("Carol"):::ci + e1 --> cjx2[" "]:::txn + f0("Frank"):::fc --> cjx2 + cjx2 --> e2("Erin"):::enc + cjx2 --> f1("Frank"):::fc + + b2 --> cj4[" "]:::txni + e2 --> cj4 + cj4 --> b3("Bob"):::bi + cj4 --> e3("Erin"):::ei + + d2 --> cj5[" "]:::txni + f1 --> cj5 + cj5 --> d3("Dave"):::di + cj5 --> f2("Frank"):::fi + + b3 --> cj6 + d3 --> cj6 + g0("Grace"):::gc --> cj6 + cj6 --> a2("Alice"):::ai + cj6 --> b4("Bob"):::bi + cj6 --> d4("Dave"):::di + cj6 --> g1("Grace"):::gi + + linkStyle 0,2,3,4,5,7,8,13,15,16,21,23,24,25,27,28,29,30,32,33,34,35 stroke:#5778a4,stroke-width:4px +``` + +*Continuing the preceding graph, Bob and Dave spend marked outputs along separate branches. As more marked outputs circulate, more branches can spread Alice's provenance features. In Alice's next four-input CoinJoin, Bob's and Dave's inputs also descend from her original coin; only Grace's does not.* + +When spending more than one coin, the similarity of these provenance features matters because it determines how much their antecessor sets overlap. + +To quantify an anonymity set size, Alice can count the inputs belonging to other users that already share her coins' provenance features,[^proximity] i.e. inputs that counterfactually trace back to her origin coins. Many such counterfactual paths imply that intersected candidate sets shrink only at a linear rate, because Alice's coins would also be in the intersections arising from post CoinJoin linking of coins that have nothing to do with her. + +This is the most conservative notion of on-chain privacy described in this document. CoinJoin transactions that have the topological properties discussed — where peers are chosen so as to satisfy these robustness properties — are required to frustrate a real-world deanonymization adversary. Without them, the information required to deanonymize is often revealed in the transaction graph itself, which is already very harmful for privacy, fungibility, and censorship resistance. And this is compounded — perhaps catastrophically — by many other privacy loss vectors outside the graph, such as blockchain indexing services for light clients, KYC information, leaks from data breaches, and transport level information like IP addresses. + +Note, however, that this still requires that the other ATM users also CoinJoin; otherwise, Alice's history will still be unique. Even if she tries to obscure this using "normal looking" transactions, the ATM could still distinguish Alice based on the fact that these transactions descend from the CoinJoin subgraph, simply because those of the other users do not. Determining whether she is the only such user is something that can be judged based on evidence like temporal patterns (correlations or periodic activity). Such patterns are more easily discernible when there are clearly delineated CoinJoin-using and non-CoinJoin-using populations in the transaction graph as a whole. + +The adversary can combine amount-based analysis, wallet fingerprints and other statistical features, graph matching, link prediction, intersection attacks, and auxiliary information. A link inferred from one source can change the interpretation of another. These analyses need not run as separate stages, and the auxiliary information may come from public observations, the adversary's own transactions, or private records. + +## Censorship resistance vs. privacy tradeoffs and complementarity + +The constructions discussed here form a spectrum: unilateral transactions, two-party PayJoins, many senders and receivers, net settlement, and market-based CoinJoin among strangers, constructed with increasing degrees of connectivity robustness. + +One end offers censorship resistance and generally weak privacy; the other offers stronger privacy guarantees at the cost of an overt fingerprint. + +Note that this doesn't refer to on-chain censorship resistance specifically; we must take for granted that at least some miners will include CoinJoin transactions for any of this to work. The relevant risk is censorship by businesses — an exchange or custodian that refuses, freezes, or discounts coins by their history, particularly if that history contains privacy-enhanced transactions.[^scam-exchanges] + +This isn't zero sum. The two ends then reinforce each other. The censorship-resistant end gains fungibility and can better resist clustering from being interwoven with the well-connected structure. The robust anonymity end gains censorship resistance by not being an insular sub-economy that rarely touches ordinary transactions. + +Multiparty transactions that don't overtly optimize for an underdetermined sub-transaction mapping can still provide ambiguity, with their susceptibility to censorship based on public information largely reduced to their proximity to the overtly privacy-enhancing ones. + +If this spectrum of transaction forms and topological properties is realized on-chain, the distribution of provenance features labeling a user's output has a better chance of matching the provenance feature distributions of more superficially similar but unrelated coins. Superficially similar coins are those with which it shares statistical features (like value distribution or wallet software fingerprints) or transaction layout features (e.g. size of the containing transaction). + +Recall that sparseness is a requirement for Narayanan and Shmatikov's results. In today's transaction graph, cluster features — both statistical, and more importantly, topological — are very likely to be unique because there doesn't exist any wallet software that deliberately blends the topological features. Wallet fingerprints and other statistical features of clusters might not be sparse on their own. But if the social network structure is recoverable from the transaction graph, that will be enough for the adversary to deanonymize most of the graph. Auxiliary information like KYC data might be the basis of such a seed, but just high degree nodes on the social graph, such as well-known mining pools, exchanges, and payment processors may suffice. + +Sufficiently ambiguous collaborative transactions would produce coins that share the *sum* of their inputs' provenance feature vectors, blending together their fingerprints. This undermines sparseness by construction. The more widely these sums spread, the less sparse the feature vectors of all coins become. For the transaction graph structure to actually be connected in this way requires deliberate effort, but there's no fundamental barrier to this occurring. + +This suggests that some of today's widely held — but often misleading — beliefs or intuitions about on-chain privacy and fungibility would be more accurate under two conditions: if such mixing of provenance features were pervasive, and if the boundary between such transactions and "normal" transactions were obscured by a network of covert transactions, none of them completely disconnected from the CoinJoin graph. + +In other words, imagine a world where some users CoinJoin and construct transaction graphs with sufficiently many disjoint counterfactual paths, as discussed above, and other users engage in net settlement transactions or two-party PayJoins. Crucially, all of these subgraphs are intertwined. In that world, the combinatorial explosion of graph-based features, which today can reveal a lot of information to the adversary, would be rendered mostly inert. By construction, such a transaction graph will not satisfy the sparseness conditions which are required for applying Shmatikov and Narayanan's approach. + +Until such time, be skeptical of claims that PayJoin or even CoinJoin provide privacy against a competent adversary — especially if it's well funded and is widely known to have access to a trove of high-quality auxiliary information. And even if this does become a reality, please remember that it wouldn't address the auxiliary information concern, nor thwart any as-of-yet undiscovered analyses that perhaps exploit some subtler leaks. And bear in mind that this depends not just on software, but a critical mass of adoption and assimilation of such privacy enhanced transaction graph structures into the rest of the Bitcoin ecosystem in order to have a meaningful impact on fungibility. + +[^newman]: M. E. J. Newman, [*The Structure and Function of Complex Networks*](https://arxiv.org/abs/cond-mat/0303516) + +[^cioh-wp]: The common-input-ownership observation appears in passing in the Bitcoin whitepaper: S. Nakamoto, [*Bitcoin: A Peer-to-Peer Electronic Cash System*](https://bitcoin.org/bitcoin.pdf) + +[^cioh-scroll]: For an informal introduction to wallet clustering, see [The Scroll #2, Wallet Clustering Basics](https://spiralbtc.substack.com/p/the-scroll-2-wallet-clustering-basics) + +[^forms]: The two-party case isn't exhaustive; the space of collaborative transaction forms is larger; in particular, lightning is probably the most widespread type of two-party transaction. See [The Scroll #5, The Many Faces of CoinJoins](https://spiralbtc.substack.com/p/the-scroll-5-the-many-faces-of-coinjoins) + +[^payjoin-entropy]: Roughly 1.58 bits is the best possible case for a two-input, two-output transaction, which is a rather typical shape. Counterintuitively, while additional inputs seem to suggest linear growth in entropy because of the combinatorics, input consolidation may result in a linear reduction in entropy due to consolidation as a function of the in-degree of the consolidation sub-transaction. See the discussion about intersection attacks below. + +[^reid-harrigan]: F. Reid and M. Harrigan, [*An Analysis of Anonymity in the Bitcoin System*](https://arxiv.org/abs/1107.4524) + +[^ron-shamir]: D. Ron and A. Shamir, [*Quantitative Analysis of the Full Bitcoin Transaction Graph*](https://eprint.iacr.org/2012/584) + +[^androulaki]: E. Androulaki, G. Karame, M. Roeschlin, T. Scherer, S. Capkun, [*Evaluating User Privacy in Bitcoin*](https://eprint.iacr.org/2012/596) + +[^meiklejohn]: S. Meiklejohn, M. Pomarole, G. Jordan, K. Levchenko, D. McCoy, G. M. Voelker, S. Savage, [*A Fistful of Bitcoins: Characterizing Payments Among Men with No Names*](https://cseweb.ucsd.edu/~smeiklejohn/files/imc13.pdf) + +[^nick]: J. Nick, [*Data-Driven De-Anonymization in Bitcoin*](https://jonasnick.github.io/papers/thesis.pdf) + +[^harrigan-fretter]: M. Harrigan and C. Fretter, [*The Unreasonable Effectiveness of Address Clustering*](https://arxiv.org/abs/1605.06369) + +[^moser-narayanan]: M. Möser and A. Narayanan, [*Resurrecting Address Clustering in Bitcoin*](https://arxiv.org/abs/2107.05749) +[^kappos]: G. Kappos, H. Yousaf, R. Stütz, S. Rollet, B. Haslhofer, S. Meiklejohn, [*How to Peel a Million: Validating and Expanding Bitcoin Clusters*](https://arxiv.org/abs/2205.13882) + +[^scroll-history]: For a narrative history of clustering techniques, see [The Scroll #3, A Brief History of Wallet Clustering](https://spiralbtc.substack.com/p/the-scroll-3-a-brief-history-of-wallet) + +[^p2ep]: [Pay-to-EndPoint (P2EP)](https://blockstream.com/2018/08/08/en-improving-privacy-using-pay-to-endpoint/) +[^bip79]: R. Havar, [BIP 79: *Bustapay :: a practical coinjoin protocol*](https://github.com/bitcoin/bips/blob/master/bip-0079.mediawiki) +[^bip78]: N. Dorier, [BIP 78: *A Simple Payjoin Proposal*](https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki) +[^bip77]: D. Gould and Y. Kogman, [BIP 77: *Async Payjoin*](https://github.com/bitcoin/bips/blob/master/bip-0077.md) + +[^uih-adamisz]: AdamISZ, [payjoin / unnecessary-input-heuristic writeup](https://gist.github.com/AdamISZ/4551b947789d3216bacfcb7af25e029e) + +[^uih-ghesmati]: S. Ghesmati, A. Kern, A. Judmayer, N. Stifter, and E. Weippl, [*Unnecessary Input Heuristics & PayJoin Transactions*](https://eprint.iacr.org/2022/589) + +[^boltzmann]: LaurentMT, [*Boltzmann*](https://gist.github.com/LaurentMT/d361bca6dc52868573a2), specifically the link-probability matrix. + +[^ns1r]: rust-payjoin, [PR #923 (removal of the experimental NS1R implementation, with status discussion)](https://github.com/payjoin/rust-payjoin/pull/923) + +[^siblings]: This concern is not entirely hypothetical; it applies to some CoinJoin capable wallets and Electrum's “multiple change addresses” mode. + +[^maxwell]: G. Maxwell, [*CoinJoin: Bitcoin privacy for the real world*](https://bitcointalk.org/index.php?topic=279249) + +[^maurer]: F. K. Maurer, T. Neudecker, M. Florian, [*Anonymous CoinJoin Transactions with Arbitrary Values*](https://www.comsys.rwth-aachen.de/publication/2017/2017_maurer_anonymous-coin-join-transactions-with/2017_maurer_anonymous-coin-join-transactions-with.pdf) + +[^ns-netflix]: A. Narayanan and V. Shmatikov, [*Robust De-anonymization of Large Sparse Datasets*](https://arxiv.org/abs/cs/0610105) (S&P 2008; the linked arXiv version is titled *How To Break Anonymity of the Netflix Prize Dataset*) + +[^ns-retro]: A. Narayanan and V. Shmatikov, [*Robust De-anonymization of Large Sparse Datasets: a Decade Later*](https://www.cs.princeton.edu/~arvindn/publications/de-anonymization-retrospective.pdf) + +[^ns-social]: A. Narayanan and V. Shmatikov, [*De-anonymizing Social Networks*](https://arxiv.org/abs/0903.3276) + +[^minor-nitpick]: This isn't really a graph minor since there are directed edges. In fact, it's not really a graph because it has both directed and undirected edges. + +[^multigraph-nitpick]: Strictly speaking, their model involves a directed graph, not a multigraph, but edges are labeled with arbitrary attributes so the information about the various payments can be collected into a rich set of attributes on a single edge representing the relationship between two clusters. + +[^ns-linkpred]: A. Narayanan, E. Shi, B. I. P. Rubinstein, [*Link Prediction by De-anonymization*](https://arxiv.org/abs/1102.4374) + +[^sabouri]: A. Sabouri, [*How Wallet Fingerprints Damage Payjoin Privacy*](https://payjoin.org/blog/2026/03/25/wallet-fingerprints-payjoin-privacy/) + +[^goldfeder]: S. Goldfeder, H. Kalodner, D. Reisman, A. Narayanan, [*When the Cookie Meets the Blockchain*](https://arxiv.org/abs/1708.04748) + +[^danezis]: G. Danezis, [*Statistical Disclosure Attacks*](https://www.freehaven.net/anonbib/cache/statistical-disclosure.pdf) + +[^troncoso]: C. Troncoso, B. Gierlichs, B. Preneel, I. Verbauwhede, [*Perfect Matching Disclosure Attacks*](https://www.freehaven.net/anonbib/cache/troncoso-pet2008.pdf) + +[^scroll-intersection]: For an accessible treatment of entropy and intersection attacks on coinjoin anonymity sets, see [The Scroll #4, Intersection Attacks](https://spiralbtc.substack.com/p/the-scroll-4-intersection-attacks) + +[^kelen-seres]: D. M. Kelen and I. A. Seres, [*Towards Measuring the Traceability of Cryptocurrencies*](https://arxiv.org/abs/2211.04259) + +[^flow]: Note that being connected doesn't just mean a path can be traced along the graph, but that the flow of funds along that path appears plausible. + +[^diaz]: C. Diaz, S. Seys, J. Claessens, B. Preneel, [*Towards Measuring Anonymity*](https://www.freehaven.net/anonbib/cache/Diaz02.pdf) + +[^serjantov-danezis]: A. Serjantov and G. Danezis, [*Towards an Information Theoretic Metric for Anonymity*](https://bib.mixnetworks.org/pdf/serjantov2002towards.pdf) + +[^tx0]: This gets worse if coins of a specific denomination are prepared before the CoinJoin, because that setup transaction is highly fingerprintable as a unilateral transaction. + +[^sudoku]: K. Atlas, [*Weak Privacy Guarantees for SharedCoin Mixing Service*](https://www.coinjoinsudoku.com/advisory/) (CoinJoin Sudoku) + +[^radix]: The [Radix CoinJoin Denominations](Denominations_and_gap_size_distributions.ipynb) chapter. + +[^syverson]: P. Syverson, [*Why I'm not an entropist*](https://www.freehaven.net/anonbib/cache/entropist.pdf) + +[^scam-exchanges]: Unsurprisingly, the most aggressive compliance posturing has historically often come from businesses that later collapsed, namely FTX, whose executives were convicted of fraud, and BlockFi, which settled SEC charges that included materially false statements before going under in FTX's wake. + +[^proximity]: Not exactly the same, since both temporal patterns and the number of hops make a difference. This can be addressed by ensuring the length of the actual path taken is consistent with the distribution of lengths of the counterfactual paths. diff --git a/docs/contacts.md b/docs/contacts.md new file mode 100644 index 0000000..ad45a15 --- /dev/null +++ b/docs/contacts.md @@ -0,0 +1,29 @@ +--- +type: Specification +title: Contacts and payment messaging +description: What interactive payments need from peer to peer messaging between payer and payee. +status: draft +stale_after: 2027-04-15T00:00:00Z +--- + +# Contacts and payment messaging + +🤖 Interactive payments need the payer and the payee to message each other. This chapter states what the protocol requires of that messaging. How an application manages contacts, identities and devices, and how it obtains a suitable channel, is up to the application. The protocol only uses the channel it is given, so it need not implement an identity system. + +## Requirements + +1. 🤖 **Reach the counterparty's device.** A peer can send authenticated [peer to peer messages](transport-interfaces.md#kinds-of-messaging) to a device acting for its counterparty. +2. 🤖 **Invite it into a collaborative transaction.** A payment is made by inviting the counterparty into a transaction construction session. The invitation binds the session's identity, its initial state and its broadcast namespace. An accepted invitation therefore cannot silently substitute a different session. Receiving an invitation is distinct from accepting the transaction's terms. +3. 🤖 **Message it during the critical section.** After output finalization and before input signing, the counterparties exchange payment confirmations. The messaging must remain available for this. + +🤖 The payment relationship can be honest or semi-honest, even when the construction session uses the Byzantine fault tolerant protocol. The confirmations below are how the counterparties check that the shared session satisfies their payment. + +Payment communication has different requirements, which also must be provided by the underlying transport. A sender must authenticate its receiver and obtain confirmation that the proposed transaction satisfies their agreement. However, this authentication can rely on a one-time code or pseudonym. The receiver doesn't need to authenticate the sender in order to be paid securely. Both counterparties know their payment amount, but need not disclose that relationship to the group or identify their transaction inputs and outputs to one another. + +## 🤖 Confirmation during construction {#confirmation-during-construction} + +Before signing its inputs, the payer needs the payee to confirm that the output set it will sign is consistent with the payee's claim that the funds reach their ultimate destination. The confirmation is with respect to the construction state, including payments settled through other participants. It is distinct from confirmation of a transaction on the Bitcoin chain. + +The [concurrent PSBT specification](psbt-concurrent.md#confirmation-of-successful-payment-prior-to-signing) defines who confirms to whom, in what order, and how cycles in the payment graph are broken. The confirmed construction state is bound to the protocol transcript's Merkle-set commitment, which is used as the deterministic sort seed. The transcript includes the applicable proofs as well as transaction contributions, so this commitment also binds those proofs. + +Counterparties exchange these confirmations after output finalization and before input signing, with respect to that finalized state. An earlier agreement on a payment or maker is not a substitute for this check. Each participant also checks the applicable proof obligations, while the construction protocol supplies its validity and phase-agreement rules. diff --git a/docs/cost_function_abstract.md b/docs/cost_function_abstract.md deleted file mode 100644 index cbac411..0000000 --- a/docs/cost_function_abstract.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -type: Stub -title: Cost function framework for Bitcoin wallets -status: draft -stale_after: 2027-04-15T00:00:00Z ---- - -# Cost function framework for Bitcoin wallets - -This chapter is under review in [#15](https://github.com/fungi-protocol/docs/pull/15). Its draft is on [the pull request's branch](https://github.com/fungi-protocol/docs/blob/cost-function-abstract/cost_function.md). diff --git a/docs/cost_function_concrete.md b/docs/cost_function_concrete.md new file mode 100644 index 0000000..505c852 --- /dev/null +++ b/docs/cost_function_concrete.md @@ -0,0 +1,76 @@ +--- +type: concept +title: Privacy liability terms +status: draft +stale_after: 2026-11-06T00:00:00Z +--- + +# 🤖 Privacy liability terms + +Privacy liabilities represent subjective losses of utility associated with outcomes that do not meet the user's privacy objectives. Each term evaluates a specified measure or proxy; evidence that the defined problem has been removed discharges the corresponding liability. The cost function combines these liabilities with objective costs and the utility of completing payments to guide the wallet's automated decisions. + +The liabilities collectively reduce a new privacy-problematic coin's subjective value by the budget fraction of its nominal value. The [Optimization framework](optimization_framework.md#global-privacy-budget) explains this valuation, and [Cost function structure](cost_function_structure.md#linear-combination) defines the accounting. The measures and their thresholds express objectives chosen for the user's threat model. Meeting them does not establish that the resulting outcome satisfies that threat model in every respect. This chapter describes the purpose and interactions of the terms; their definitions and justifications appear in the linked chapters. The measures computed from public data that the terms take as input are described in the [Privacy metrics](privacy_metrics.md) chapter. + +## Randomized selection + +An adversary who controls many of the coins a user co-spends with learns the user's coins by elimination. Randomizing which coins are co-spent makes that costly. + +- **Per input and pairwise preferences.** They randomize which coins are co-spent, with block hashes as a public randomness beacon. They only break ties, so they don't compete with the other terms. +- **Cardinality.** Everyone uses the same randomness, so the bias it leaves in a transaction's inputs can be observed afterwards, and bounds the size of the order book the inputs were selected from. + +Randomization also promotes a robustly connected transaction graph, which the [counterfactual paths](cost_function_counterfactual_paths.md) term measures. See the [Randomized selection](cost_function_randomized_selection.md) chapter for the terms, and the [Order book size estimation](sybil_resistance_index.md) chapter for the lower bound on the number of candidates. + +## 🤖 Sybil resistance + +The Sybil resistance term evaluates the cost of an adversary supplying the coins in a coin's history and the candidates from which they were selected. Observed resource requirements and estimates derived from selection bias are assessed against the user's threat model. The liability is zero when the attack cost is judged prohibitive under that model; otherwise, it represents a subjective loss scaled by the user's privacy budget. See the [Sybil resistance](cost_function_sybil_resistance.md) chapter. + +## Subset sum ambiguity + +Amounts are the most direct way to link a transaction's inputs to its outputs, and the inputs to each other. This term measures how well the other users' coins explain the user's amounts. + +- The more combinations of the user's outputs the subset sums of the other users' inputs cover, the more readings of the transaction remain, and the lower the liability. +- It measures the same for the user's own inputs. +- Once the transaction has been fully built, both are also checked against the subset sums of the other users' outputs. + +See the [Subset sum ambiguity](cost_function_subset_sum_ambiguity.md) chapter. The [Subset sum density](subset_sum_density.md) chapter covers the density it relies on, and how co-spend proposals and the aggregator raise it. + +## Counterfactual paths + +[Intersection attacks](collaborative_txn_privacy.md) compare the histories of coins across transactions, and what those histories have in common reveals the link. This term counts the disjoint routes a coin's amount could have taken from its origins. + +- Its main use is a label for each of the wallet's own coins, indicating how closely it meets the objective for counterfactual routes. +- The consolidation penalty uses these labels, together with subset-sum density, to evaluate spending coins together. + +See the [Counterfactual paths](cost_function_counterfactual_paths.md) chapter. + +## Consolidation + +The consolidation penalty accounts for the additional exposure to intersection attacks introduced by spending multiple wallet-owned inputs together. Its liability is deliberately unbounded: consolidation may leave the wallet worse off than its baseline, and the corresponding subjective loss may exceed the remaining privacy budget. An automated action is taken only when the cost-function evaluation predicts an improvement. Fees, batching, and reduced fragmentation may make more aggressive consolidation attractive in the best case, while the available evidence must support the decision. + +The penalty is attenuated jointly by subset-sum density and counterfactual routes, with the contribution of each depending on the other. Dense subset sums alone are insufficient, because comparing the ancestry of pairs of inputs narrows down an intersection efficiently. The route analysis considers each input against the combined set of coins through which the inputs' funds first entered the wallet. These pairwise flow measurements would contribute to a graded measure of absorption, whose aggregation and use in the liability remain to be specified. The consolidation chapter defines these quantities and their thresholds. The same penalty contributes to the evaluation of a wallet state by considering a hypothetical transaction spending all of its coins together, so that the wallet can arrange its state to minimize privacy damage if an emergency requires the user to spend those funds at short notice. + +See the [Consolidation penalty](cost_function_consolidation.md) chapter. + +## Siblings + +Spending outputs of the same transaction together is wasteful, and a strong sign of common ownership. Amounts can explain the values, but not two users spending outputs of one transaction together, so neither subset sums nor counterfactual routes relieve it. It's penalized heavily. + +See the [Sibling output penalty](cost_function_siblings.md) chapter. + +## UTXO pool diversity + +A wallet also values the diversity of its own UTXO pool: + +1. some radix denominations; +2. some coins with high Hamming weight; +3. a good size distribution, possibly adapted to the wallet's payment distribution. + +How to represent this mathematically is an open question. + +## Other ad hoc terms + +Other ad hoc terms, such as fingerprint avoidance, are yet to be specified. + +## In the decision tree + +Each liability either only falls as other users' coins are learned, or is fixed once the inputs are chosen or a coin confirms. That's what lets [bottom-up construction](bottom_up_construction.md#6-bracket-and-back-up-values) bracket every leaf between a best case and a worst case, cache what's fixed per coin, and [re-evaluate](tactics.md#re-evaluation) only when something changes. Once the transaction is fully constructed, the same cost function evaluates the complete state and determines the liabilities and privacy-budget accounting. Each term's chapter says how it behaves in the decision tree. diff --git a/docs/cost_function_consolidation.md b/docs/cost_function_consolidation.md new file mode 100644 index 0000000..a3be16d --- /dev/null +++ b/docs/cost_function_consolidation.md @@ -0,0 +1,135 @@ +--- +type: concept +title: Consolidation penalty +status: draft +stale_after: 2026-11-06T00:00:00Z +--- + +# 🤖 Consolidation penalty + +A privacy liability term of the [cost function](optimization_framework.md). Spending several own coins together adds exposure to [intersection attacks](collaborative_txn_privacy.md), which the term models as compounding with each additional coin. [Subset-sum density](subset_sum_density.md) and counterfactual routes jointly attenuate the penalty: the contribution of each depends on the other. The penalty is fully discharged when both meet their thresholds. + +- **Why unbounded.** Consolidation may leave the wallet worse off than its baseline, so the liability can exceed 1 and its associated reduction in subjective value can exceed the remaining privacy budget. Other terms may still outweigh this cost; the penalty does not categorically prohibit consolidation. +- Density alone isn't enough. Comparing the ancestor sets of pairs of inputs narrows down an intersection efficiently, even in a large transaction. + +Consolidation exposes the inputs' histories to comparison, so the route analysis considers their combined ancestry. Its measurements describe counterfactual connectivity between each input and the coins through which any of the consolidated funds first entered the wallet. Combining these measurements into a scalar would quantify how thoroughly the inputs' histories have become connected through other users' transactions. This measure of absorption would inform the consolidation liability alongside subset-sum density. The aggregation rule remains to be specified. + +The routes factor uses the route counts $k$ of the [Counterfactual paths](cost_function_counterfactual_paths.md) to [label](#labels) the wallet's coins, and the [combined ancestry](#combined-ancestry) of the inputs. + +## Definition + +The following parameterization uses per-coin route labels. Incorporating a joint measure of absorption into this parameterization remains an open question. + +- $I$: the own inputs of the transaction under consideration, each with a label $\iota(a) \in [0, 1]$, the degree to which $a$ meets the counterfactual-route objective. + - The labels are defined in [Labels](#labels). +- **Links.** $\nu_0 = |I| - 1$. +- **Linked count.** $\nu = \sum_{a \in I} (1 - \iota(a)) - \max_{a \in I} (1 - \iota(a))$. + - A single coin gives $\nu = 0$, and so does one coin below the route threshold spent with coins that meet it. +- **Routes.** $q = 1 - \nu / \nu_0$, and $q = 1$ for a single coin. +- **Density.** $\eta = \min_{a \in I} f_a$. + - $f_a$ is the covered fraction of the [subset sum ambiguity](cost_function_subset_sum_ambiguity.md#definition) term for own input $a$. + - While decisions are evaluated, it checks $\Sigma(I)$ against $\Sigma_{\le d}(X)$, the other users' inputs known so far. After the fact, it also checks it against $\Sigma_{\le d}(Y)$, the other users' outputs. + - $p = 1 - \text{clamp}(\log_2(\varphi_c / \eta) / \theta_c, 0, 1)$, with $\varphi_c$ well above that term's $\varphi$. + - $\theta_c$: the number of doublings of $\eta$ over which $p$ rises from 0 to 1. +- **Liability.** $\ell_c = (b^{\nu_0} - 1) \cdot (1 - p q)$, with $b > 1$ the factor per intersection. + - **Thresholds.** $p = 1$ once $\eta \ge \varphi_c$. $q = 1$ once every input but one has $\iota = 1$, i.e. $K$ routes. + - For more than one own input, it's 0 only when both meet their thresholds. + - The relief from each is proportional to the other: $\partial \ell_c / \partial p \propto -q$. With $q = 0$, density relieves nothing, and with $p = 0$, routes relieve nothing. + +## Labels + +For each own coin $c$: + +- **Origins.** $O(c)$ is the set of coins by which the wallet received the funds $c$ descends from. +- **Routes.** $k_c = \min_{o \in O(c)} k(o, \{c\})$, with the wallet's own edges omitted. +- **Label.** $\iota(c) \in [0, 1]$ rises with $k_c$ and reaches 1 at $K$, the chosen route threshold. For example, $\iota(c) = \min(1, k_c / K)$. +- **Use.** At $\iota(c) = 1$, $c$ adds nothing to the linked count $\nu$. + +Everything $k_c$ depends on exists once $c$ confirms: the coins between its origins and $c$, the other coins in their transactions, and their link probabilities. So $k_c$ is fixed from then on, and labels are cached per coin. + +### From bounds + +With the [bounds](cost_function_counterfactual_paths.md) $k^-$ and $k^+$: + +- $\iota$ uses $k^-$, so it's never overstated. +- If $k^- \ge K$, $c$ is impervious. +- If $k^+ \lt K$, it isn't, and more sampling won't change that. +- Otherwise, take more walks, or compute $k$ exactly on a pruned graph. + +## Combined ancestry + +Spending own coins $I$ together links them. An intersection attack then intersects their candidate origins. + +- **Union.** $U = \bigcup_{i \in I} O(i)$: every coin by which the wallet received funds that any of them descends from. +- **Routes matrix.** $M_{i,u} = k(u, \{i\})$, for each $i \in I$ and $u \in U$. + - It's a bipartite graph from $U$ to $I$, with each edge labelled by its routes, written as a matrix. + - Each entry is one max flow. Entries already computed for a coin's own origins carry over: $k_c$ is the minimum of row $c$ over $O(c)$. +- **Reading it.** Row $i$ shows which origins $i$ has many counterfactual routes from. When every row is high in almost every column, each input's candidate origins cover almost all of $U$. The sets the adversary can intersect then have a small symmetric difference, so intersecting them reveals little. + - "Almost every" is read off $M$, not fixed in advance. For example, the columns where one row is at least $K$ and another isn't are what an intersection of those two inputs can reveal. +- **Aggregation.** A [candidate absorption index](#candidate-absorption-index) aggregates shortfalls in pairwise connectivity. Its parameters and its mapping to the consolidation liability remain to be determined. +- **Counterfactual superconcentrator.** The graph of other users' edges only. + - Sources: the earliest ancestor coins, $U$. + - Sinks: the inputs under consideration for consolidation, $I$. + - The aim is $K$ counterfactual routes across it, making it a superconcentrator: for every $j$, any $j$ sources and any $j$ sinks are joined by $j$ disjoint paths. + +### Candidate absorption index + +One candidate aggregates the shortfall of each input–origin pair from a connectivity objective. For this purpose, use the unrounded flow ratio $r_{i,u} = F_{i,u}/d_{i,u}$, retaining fractional values rather than the integer route count $k$. Let $K > 0$ be the objective and $s_{i,u} = \min(r_{i,u}/K, 1)$ the degree to which a pair meets it. Saturation prevents additional flow for an already sufficient pair from providing further compensation for weak connectivity elsewhere. + +For nonnegative weights $w_{i,u}$ summing to 1 over the input–origin pairs, define + +$$ +A = 1 - \left(\sum_{i \in I,\,u \in U} w_{i,u}(1-s_{i,u})^\alpha\right)^{1/\alpha}, +\qquad \alpha > 1. +$$ + +At $\alpha = 2$, this is one minus the root-mean-square shortfall. Larger $\alpha$ gives weak pairs more influence; as $\alpha$ tends to infinity, $A$ approaches the weakest score with positive weight. Finite $\alpha$ permits strong coverage to compensate for incomplete coverage, while each improvement below saturation increases the index for a pair with positive weight. If a fraction $f$ of the weight has score 0 and the rest has score 1, then $A = 1-f^{1/\alpha}$. + +The weights must represent the exposure being evaluated, rather than the number of sampled paths. Their choice remains open, including how to prevent splitting funds or repeating observations from manufacturing credit. The index is a connectivity measure, not an attack-cost estimate. Incorporating Sybil resistance along the supporting paths remains to be specified: an adversary may create apparent alternatives through prior CoinJoins, and the expenditure supporting several pairs cannot be counted as a separate expenditure for each pair. + +A possible extension first computes a coverage score for each input across origins, and for each origin across inputs, using a power mean with exponent $0 < \beta < 1$. It then takes a power mean of those profiles' shortfalls, with exponent $\alpha > 1$, and subtracts it from 1. This distinguishes missing connections concentrated around one input or origin from missing connections spread across them, which the single mean does not. It adds a parameter and requires weights at both levels. Neither formulation by itself establishes that a high score makes a targeted intersection attack prohibitively expensive. + +## In the decision tree + +- It's a privacy-related term. +- **Fixed per coin.** Once a coin confirms, no later block adds to its ancestry. So $\iota$, and the entries of $M$ for confirmed inputs, are computed once and reused in every leaf. Over time, they're constant. +- **A leaf's inputs.** A leaf fixes the own inputs $I$, and with them $U$ and the rows of $M$. Nothing other users add to the transaction changes them, so the best and worst cases of the labels and $M$ are equal. +- **Outputs.** The transaction's own outputs get labels only after it confirms. +- **Order book coins.** The own inputs' coin edges are omitted, so routes from their origins into the transaction's own outputs enter only through other users' inputs. + - An order book coin that descends from those origins adds routes, so selecting it is valuable. + - A co-spend proposal from an own input that names such a coin links the two, unless such proposals are already common. An outcome may still prefer the selection, but the cost function should penalize proposals that leak the link this way. +- **Bounds.** Leaves use $\iota$ from $k^-$, the lower [bound](cost_function_counterfactual_paths.md). Tightening $k^-$, with more walks or an exact $k$ on a pruned graph, can run between iterations of the decision loop in the [Mixed strategy](mixed_strategy.md) chapter. It can only raise $\iota$. +- **Worst case:** $\eta$ checks only the other users' inputs known so far. Their outputs aren't known until the transaction has been fully built. +- **Best case:** $\ell_c = 0$, which is used for pruning. +- $\ell_c \ge 0$ is unbounded, so its associated reduction in subjective value can exceed the remaining budget. An automated action requires a predicted improvement under the full cost-function evaluation. Consolidation-heavy branches are pruned when that evaluation cannot justify them; evidence that improves the lower bound can reduce the penalty and change the decision. +- More aggressive consolidation can nevertheless have a better best-case evaluation because of feerates, batching opportunities, or reduced fragmentation. That best case alone does not justify execution under the current lower bound. +- It applies to every own output of the transaction. The reduction in subjective value scales with their total value, independently of the number of outputs. + +## After construction + +- Once the transaction is fully constructed, $\eta$ is computed from the complete sets and the same cost function is evaluated with that information. This determines the liabilities and the accounting for privacy-budget expenditure, as described in [Cost function structure](cost_function_structure.md#linear-combination). An explicit manual override resets liability accounting to the baseline. + +## Evaluating the wallet state + +- The term can evaluate a wallet state too. Imagine that an emergency forces the user to spend all of its coins rapidly in one unilateral transaction, and take that transaction's consolidation penalty. This favors arranging the wallet state to minimize the privacy damage if such a liquidation becomes necessary. +- That transaction's cost includes its objective costs, e.g. the fees for each coin, so this also prices a wallet split over many coins. +- It depends on the [open question](#open-questions) about transactions with only the wallet's own coins. Until that's settled, $p = 0$ there, and every state with more than one coin gets the full penalty. + +## Monotonicity + +- $\ell_c$ can only fall as $\eta$ rises, or as the labels rise. + +## Open questions + +- How should the absorption index determine the route factor? The [candidate shortfall mean and its grouped extension](#candidate-absorption-index) describe possible aggregation rules; their weights, parameters and resistance to manipulation remain to be evaluated. + +- Should siblings also count towards $\nu$? +- A transaction with only the wallet's own coins has no other users' coins, so $p = 0$ and the penalty can't be discharged. Which density applies there? For example, the [covered fraction](cost_function_subset_sum_ambiguity.md#definition) $f_o$ of the outputs that became the inputs, in the transactions that created them. +- How should $p$ and $q$ be scaled? +- What link probabilities apply to the transaction under construction? They must hold in every completion. +- Which term penalizes a co-spend proposal that leaks a link to an order book coin that adds routes, and how is "already common" measured? +- How is the routes factor computed: from each input's $\iota$, as the [definition](#definition) does now, or from the counterfactual superconcentrator condition? +- How is the counterfactual superconcentrator condition checked? It ranges over sets of sources and sinks of equal size, while $M$ holds only single pairs. +- Should $\iota$ ramp up to $K$, or switch from 0 to 1 at $K$? What should $K$ be? +- May $\iota$ use an estimate ($k^+$, the analytic estimate or Monte Carlo) when the randomization evidence is strong, or only $k^-$? +- What label does an own input get before it confirms, such as change from a transaction still in flight? diff --git a/docs/cost_function_counterfactual_paths.md b/docs/cost_function_counterfactual_paths.md new file mode 100644 index 0000000..a893c31 --- /dev/null +++ b/docs/cost_function_counterfactual_paths.md @@ -0,0 +1,222 @@ +--- +type: concept +title: Counterfactual paths +status: draft +stale_after: 2026-11-05T00:00:00Z +--- + +# 🤖 Counterfactual paths + +A counterfactual-connectivity measurement used by the [cost function](optimization_framework.md). It counts how many times the sink's amount could have travelled from a source coin to the sink coins, along disjoint counterfactual paths. This is the [problem definition](collaborative_txn_privacy.md)'s robust connectivity, measured with one max flow. + +The paths start at any coin linked to the source within its transactions, and end at any coin linked to the sinks. These links are what make more than one route possible. A source and a sink with nothing linked to them give at most one. + +The [Consolidation penalty](cost_function_consolidation.md) chapter uses it to label the wallet's coins, and to estimate when spending them together is safe from intersection attacks. + +## Network + +The transaction graph, with details that don't matter here, such as scripts, left out. Transactions are vertices and coins are edges, which works because an unspent coin can't carry flow along the DAG. Each max flow is from one source to its sinks, and every edge is labelled with its capacity for that pair. + +Edges follow the funds, from the transaction that creates a coin to the one that spends it. The source is the earlier coin, such as an origin of the wallet's coins, and the sinks are later coins, such as the wallet's own. Bitcoin's references point the other way, from each input to the coin it spends. Either direction gives the same result. Reversing every edge and swapping the source with the sinks turns each cut between them into a cut with the same capacity, so the max flow, and with it $k$, is unchanged. + +- **Coin edges.** Each coin $c$ is an edge from the transaction that creates it to the transaction that spends it, with capacity $v(c)$. +- **Flow edges.** The model is refined by replacing each transaction with a bipartite graph: an edge from each spent coin to each created coin. + - Capacity: $P_{I,O}(i, o) \cdot \min(v(i), v(o))$. + - $P_{I,O}(i, o)$ is the probability that $i$ and $o$ are in the same sub-transaction. + - Max flow works the same way on the refined graph, so the model with one vertex per transaction is without loss of generality. +- **Link edges.** These carry no flow. They only define the neighbourhoods below. + - Between the inputs of a transaction, with probability $P_{I,I}$. + - Between its outputs, with probability $P_{O,O}$. +- **Neighbourhoods.** The super-source of a coin $s$ connects to $s$ and to every coin linked to it on either side, with capacity equal to the link probability times that coin's value. The super-sink of the sink coins $T$ is built the same way. +- **Own edges.** When source and sink are both the wallet's coins, only counterfactual paths should remain. Two kinds of edges are omitted from the graph: + - flow edges between two of the wallet's coins in the same transaction; + - coin edges of the wallet's coins on the way from the source to the sink. + +## Definition + +For a single source coin $s$ and sink coins $T$: + +1. **Amount.** $d = \min(v(s), v(T))$, where $v(T)$ is the sum of the sinks' values. +2. **Caps.** Every coin edge and every flow edge is capped at $d$. + - Uncapped: the coin edges of the source and the sinks, and the super-source and super-sink edges. + - Coins linked to the source or the sinks are capped like any other, so each carries at most one route. +3. **Flow.** $F$ is the max flow from the super-source to the super-sink. +4. **Routes.** $k(s, T) = \lfloor F / d \rfloor$. + +For several sources, $k(S, T) = \min_{s \in S} k(s, T)$. + +- A single super-source over all of $S$ would add up the routes of different sources. Two linked coins with one route each would score 2, hiding the intersection. + +### Why this counts routes + +- **Theorem.** An acyclic flow of value $v$ in which no edge carries more than $v/k$ is a $k$-route flow.[^kishimoto][^aggarwal-orlin][^chekuri-idleman] + - That is, it's a sum of bundles. Each bundle is $k$ paths that share no edge, carrying equal amounts. +- **Guarantee.** With every capped edge at $d$ and $F \ge k d$, removing any $j \lt k$ capped edges still leaves a flow of at least $(k - j) d$. + - So no $k - 1$ capped edges cut the source off from the sinks. This is the problem definition's "no small cut". +- **Uncapped edges.** These behave like $k$ parallel copies, so routes may share them. + +### Split routes + +A route may be spread over several smaller coins, as long as no two routes share a capped edge. For example, two disjoint coins of $d/2$ each count as one route of $d$. + +The floor makes $k$ conservative. Three disjoint coins of $d/2$ give $k = 1$, yet any one of them can be removed and $d$ still gets through. + +### Max flow alone isn't enough + +- Without caps, a single large coin can carry all of $F$, so $F$ can't tell one route from several. +- Scaling the demand to $k d$ doesn't help, for the same reason. + +## Scope + +For one source and one sink, only the coins that descend from the source's neighbourhood and are ancestors of the sink's neighbourhood matter. These lie between the two confirmations. One pair never needs the full chain. + +### Pruning + +Any restriction of the transaction graph gives a lower bound on $k$, since removing coins or edges can't raise a max flow. Some examples: + +- the last $n$ blocks; +- only CoinJoins meeting some conditions; +- only the flow edges of specific coins in them, such as equal amount outputs. + +A lower bound is safe for [labels](cost_function_consolidation.md): a coin is never labelled impervious when it isn't. + +Restricting to CoinJoins undercounts, though: payments and PayJoins intertwined with CoinJoins also carry counterfactual routes. + +### Cost + +- One max flow per source. Sources are independent, so they parallelize. +- A transaction with $n$ inputs and $m$ outputs has $n m$ flow edges. + - Cache $P_{I,O}$ per transaction. It has a closed form for equal amounts, and needs subset sum enumeration otherwise. + - Leaving out edges with small $P_{I,O}$ gives a lower bound. +- A new block only adds coins and edges, so it never lowers $k$. + +## Approximation + +This avoids computing $k$ on the full graph. + +The approximation can't be strictly monotone. Bounding the resources spent on decision making is a client implementation decision. As long as a light client doesn't defect, i.e. it behaves as if its evaluation is monotone, it is still incentive compatible. + +### Data access + +How much of the chain a wallet sees depends on its constraints: + +- With limited bandwidth, it samples blocks. +- With limited storage, it fetches every block in a range, but keeps only a subgraph in a compact encoding. See [Pruning](#pruning). +- If it can only fetch transactions adjacent to ones it knows, it uses the [bounds](#bounds). + +### Layers + +The approximation estimates each layer of the network separately. Each layer depends only on the ones before it. + +1. **Topology.** Transactions, their numbers of inputs and outputs, and how long coins stay unspent. +2. **Amounts.** Coin values. Relative to $d$, they set each coin's capacity. +3. **Links.** $P_{I,O}$, $P_{I,I}$ and $P_{O,O}$, computed from the amounts within each transaction. They set the flow edges and the neighbourhoods. +4. **Knowledge.** The wallet's own edges. + +### Sampled blocks + +- Sample blocks, and estimate each layer's distributions from their transactions, separately. + - For the topology: the numbers of inputs and outputs per transaction, and the spend rate $p$, the fraction of unspent coins spent per block. +- Base the estimate on randomized selection, as in the [Randomized selection](cost_function_randomized_selection.md) chapter. When coins are selected at random from the candidates, the transaction graph can be treated as a random acyclic network with those degree distributions.[^karrer-newman-acyclic][^karrer-newman-models] +- **Observed paths.** Traversing backwards from a coin in the order book until reaching CoinJoins the wallet already knows, such as descendants of ones it participated in, establishes a flow route. This can be repeated several times, bounded to a block range. Even if only a few paths are found, they estimate the degree sequence of the random acyclic network, together with the [order book size estimation](sybil_resistance_index.md). + - The paths give the distributions of the numbers of inputs and outputs, from the transactions they pass through. + - The order book size estimation gives a median estimate $\hat{N}$ of the number of candidates. +- **Number of candidates $N$.** + - The order book size estimation gives $L$, a relatively conservative estimate of a lower bound on $N$. It scales the Sybil cost. + - The degree sequence uses $\hat{N}$, a median estimate of $N$. + - In the pool model below, no coins enter or leave the CoinJoin graph. There, doubling $N$ from 1000 to 2000 lowers $E[k]$ from 1.20 to 0.73 at $n = 4$, $R = 12$. + +### Time slices + +Every route crosses each block boundary on a coin that's unspent at that boundary. + +- A **slice** is the set of coins unspent at a boundary that descend from the source's neighbourhood and are ancestors of the sinks' neighbourhood, excluding the neighbourhoods themselves. +- Each slice is a cut, so $k$ is at most the smallest slice's capacity. +- In the prototype below, $k$ equals the smallest slice in 95% to 100% of runs. + +### Analytic estimate + +This covers the topology layer only: every coin's capacity is $d$, and every $P_{I,O}$ is 1. + +- **Growth.** $D_r$ is the number of unspent coins after block $r$ that descend from the source's neighbourhood. + - $D_{r+1} = (1 - p) D_r + \frac{p N \bar{o}}{\bar{\imath}} \left(1 - G(1 - D_r / N)\right)$. + - $\bar{\imath}$ and $\bar{o}$ are the mean numbers of inputs and outputs, and $G$ is the generating function of the number of inputs. The two numbers are assumed independent. + - Under random selection, a transaction joins the descendants with probability $1 - G(1 - D_r / N)$, the probability that any of its inputs is a descendant. + - $A_r$, the ancestors of the sinks' neighbourhood, grows the same way backwards from the sink, with inputs and outputs swapped. +- **Slices.** Under random selection, an unspent coin after block $r$ is an ancestor of the sinks with probability $A_r / N$, independently of whether it descends from the source. +- **Ends.** The slices next to the source and the sinks are the narrowest, and nearly independent of each other. + - $X \sim \text{Binomial}(n_s, A_0 / N)$, where $n_s$ is the number of coins the source's neighbourhood first reaches. + - $Y \sim \text{Binomial}(n_T, D_{R-1} / N)$, where $n_T$ is the number of coins that first reach the sinks' neighbourhood, and $R$ is the number of blocks between them. + - $k \approx \min(X, Y)$, so $P(k \ge K) \approx P(X \ge K) \cdot P(Y \ge K)$. +- Using only the single narrowest slice, $\text{Binomial}(D_r, A_r / N)$, overestimates $k$. + +The estimate is neither a lower nor an upper bound. + +### Monte Carlo + +- Generate transaction graphs from the estimated layers, in order: topology, amounts, links, knowledge. +- Compute $k$ on each with the max flow, restricted to the coins between source and sink. +- Estimate $P(k \ge K)$ from the results. +- Unlike the analytic estimate, this covers every layer. + +**Prototype, analytic and Monte Carlo.** A pool of $N$ candidate coins of equal value. In each block, a fraction $p = 0.2$ of the pool is selected at random into transactions of $n$ inputs and $n$ outputs. The source's neighbourhood is the inputs of a transaction in the first block, and the sinks' is the outputs of one $R$ blocks later. Each Monte Carlo row is 30 to 40 runs. + +| $n$ | $N$ | $R$ | $E[k]$, Monte Carlo | $E[k]$, analytic | $P(k \ge n/2)$, Monte Carlo | $P(k \ge n/2)$, analytic | +|---|---|---|---|---|---|---| +| 4 | 1000 | 8 | 0.23 | 0.11 | 0.03 | 0.00 | +| 4 | 1000 | 12 | 1.20 | 0.97 | 0.30 | 0.23 | +| 4 | 1000 | 20 | 3.08 | 3.20 | 0.97 | 0.99 | +| 8 | 2000 | 6 | 1.43 | 1.04 | 0.03 | 0.00 | +| 8 | 2000 | 8 | 2.83 | 2.90 | 0.30 | 0.30 | +| 8 | 2000 | 12 | 5.33 | 5.58 | 0.93 | 0.97 | + +Counting only whether the first coins at each end are spent or created in time predicts $E[k] = 2.8$ at $n = 4$, $R = 8$. The graph between the ends is what limits $k$ there. + +### Bounds + +- **Upper bound.** For $k^+$, merge every coin $r$ transactions away from the source into the super-sink, and compute $k$. Do the same from the sink backwards, and take the smaller of the two. + - Keep $d$ as computed from $s$ and $T$. Merged coins raise the sink's value, and recomputing $d$ from it would break the bound. + - Merging only adds capacity, so each is an upper bound. + - The cost depends on $r$ and the local degrees, not on the chain. +- **Lower bound.** For $k^-$, take random walks forward from the source's neighbourhood and backward from the sink's. Follow $f$ randomly chosen edges per step, up to the other end's confirmation height. Compute $k$ on their union. + - The union is a subgraph, so its $k$ is a lower bound. + - Walks that cross share edges, and the max flow counts a shared edge once. Overlapping paths aren't double counted. + +**Randomization.** With randomized selection, as in the [Randomized selection](cost_function_randomized_selection.md) chapter, in the prototype below, this puts the smallest cut next to one of the ends, so $k = k^+$. That isn't guaranteed in general. + +- The selection bias bounds the number of candidates from below. It doesn't show that both ends draw from the same candidates: two groups that never transact with each other can each select at random. +- The evidence that the ends are connected is $k^-$ itself, as it approaches $k^+$. + +**Prototype, bounds.** A layered model: 7 layers of 256 coins of equal value, joined by 6 rounds of transactions with 8 inputs and 8 outputs, 6 seeds each. + +- The source's neighbourhood is the 8 inputs of its transaction, and the sink's is the 8 outputs of its transaction. So 8 is the most $k$ can be. +- **Random selection:** $k = k^+ = 8$ in every seed, so no route was lost in between. With 4 walks branching 2 ways per step, $k^- = 8$ in every seed. +- **Two halves that never transact with each other:** $k = 0$, while $k^+ = 8$. +- **Two halves, 10% of transactions mixed:** $k = 8$ in 5 seeds, and 7 in the other. + +## Limitations + +- **Sub-transactions.** Flow relaxes sub-transaction mappings: it can split across them in ways no single mapping allows. +- **Unknown link probabilities.** Taking $P_{I,O} = 0$ when it's unknown is conservative. +- **Independent transactions.** Each transaction's probabilities are computed on their own. Intersections across transactions enter only through the minimum over sources and the [consolidation](cost_function_consolidation.md) condition. +- **What the adversary removes.** Routes are counted as disjoint in coins and flow edges, while an adversary deanonymizes users, removing all of a user's coins at once. +- **Timing and hops.** Route length and timing aren't modelled. + +## Open questions + +- With several sink coins, should each sink get its own share of $d$? +- Should a privileged counterparty's own coins also be omitted, since it knows where they went? +- **Known transactions.** The wallet already has the transactions next to its own coins. Should the estimates use those as they are, such as the actual $n_s$ and $n_T$, and model only the transactions it hasn't fetched? +- **Amounts and links in the analytic estimate.** Can they enter as expected capacities per coin, or only through Monte Carlo? +- How should competing spends of one coin be handled? +- **Entries and exits.** A smaller $N$ also means fewer vertices. Two counts depend on it: coins entering from transactions without randomized inputs, and outputs leaving the CoinJoin graph. Which way this moves $k$, and so whether $L$ or $\hat{N}$ is more conservative here, isn't known. + +[^kishimoto]: W. Kishimoto, [*A method for obtaining the maximum multiroute flows in a network*](https://doi.org/10.1002/(SICI)1097-0037(199607)27:4%3C279::AID-NET3%3E3.0.CO;2-D), Networks 27(4), 1996. + +[^aggarwal-orlin]: C. C. Aggarwal, J. B. Orlin, [*On multiroute maximum flows in networks*](https://doi.org/10.1002/net.10008), Networks 39(1), 2002. + +[^chekuri-idleman]: C. Chekuri, M. Idleman, [*Congestion Minimization for Multipath Routing via Multiroute Flows*](https://doi.org/10.4230/OASIcs.SOSA.2018.3), SOSA 2018, Theorem 1. + +[^karrer-newman-acyclic]: B. Karrer, M. E. J. Newman, [*Random acyclic networks*](https://arxiv.org/abs/0902.4013), 2009. + +[^karrer-newman-models]: B. Karrer, M. E. J. Newman, [*Random graph models for directed acyclic networks*](https://arxiv.org/abs/0907.4346), 2009. diff --git a/docs/cost_function_randomized_selection.md b/docs/cost_function_randomized_selection.md new file mode 100644 index 0000000..d4c0cb5 --- /dev/null +++ b/docs/cost_function_randomized_selection.md @@ -0,0 +1,75 @@ +--- +type: concept +title: Randomized selection +status: draft +stale_after: 2026-11-06T00:00:00Z +--- + +# Randomized selection + + + +Two terms of the [cost function](optimization_framework.md): weak preferences that randomize the choice of which UTXOs to co-spend with, using the blockchain as a randomness beacon. The [Sybil resistance](cost_function_sybil_resistance.md) term values coins by how well that randomization can be observed in their history. + +Together they: + +- make Sybil attacks more costly; +- promote a robustly connected transaction graph, with similarities to [interconnection networks](https://en.wikipedia.org/wiki/Multistage_interconnection_networks); +- establish a Schelling point among takers with regards to which makers to interact with; +- reduce temporal fingerprinting of makers' UTXOs' availability; +- provide useful information to light clients with limited access to the blockchain. + +They compose with arbitrary other terms. The setting is non-cooperative, so they are a component of a strategy, not a mechanism. If widely adopted by those paying for CoinJoin blockspace, privacy related payoffs are more strongly positive sum. + +Makers announce UTXOs in an order book, and takers propose to spend them in CoinJoin transactions, as in [coalition formation](coalition_formation.md). The roles are used loosely: a single participant may perform both. + +## Inputs + +- $t$: a block hash, e.g. 144 blocks from the best known chain tip. +- $I$: the outpoints being considered for spending in a possible transaction, with $n = |I|$. +- $x_i = H(t, i)$ for each $i \in I$, where $H$ is a tagged hash. Hash outputs are interpreted as rational numbers in $[0, 1]$. +- $f_1, f_2$: monotone scaling functions, e.g. log or sqrt, possibly with a bias. + +## Per input term + +$$ +f_1\left( \sum_{i \in I} x_i \right) +$$ + +- How "lucky" a maker's coin is at a point in time, with many leading 1's in the hash output being considered lucky. This is a total ordering over inputs. +- A weak preference: more than 0 but less than 1 sat, so it only breaks ties. +- It lets takers converge on the same makers' coins, especially when the number of active takers is small enough that a grand coalition can construct a single transaction. All else being equal, takers concentrate on the same subset of makers, reducing their shared costs. + +## Pairwise term + +$$ +f_2\left( \sum_{i,j \in I} x_i \oplus x_j \right) +$$ + +- An affinity between inputs, using the XOR metric. Valuing it promotes randomized assortativity between inputs. +- A weak preference, like the per input term. It scales quadratically in the number of inputs, which $f_2$ must account for. +- **Tipping point.** Due to the CoinJoin liveness model, success probability is roughly exponential in the number of inputs. This limits how far the total order of the per input term can be optimized. Where these interactivity costs dominate, this term dominates over the first, avoiding more rivalrous competition for lucky coins to all be spent in the same transaction. +- **Partitions.** When the candidate UTXO set is larger than the feasible transaction size, this term promotes partitioning of the candidate UTXO set, with each part being a reasonable estimator for its size. +- **Why XOR.** For uniform $x_i$, $x_i \oplus x_j$ is also uniform. Preferring small values also biases the $x_i$ themselves: a pair whose XOR has $b$ leading zero bits shares its $b$ most significant bits, so both lie in a random subinterval of size $2^{-b}$. This simplifies the density estimation. The Hamming distance or the arithmetic difference would change the distribution, and the scaling functions can simulate such effects. + +## 🤖 Order book size estimation {#cardinality} + +The [Order book size estimation](sybil_resistance_index.md) chapter gives a lower bound $L$ on the number of candidate coins $N$ the inputs were selected from, using the joint sums of the input hashes, with $P(L \gt N) \le \delta$ for every selection strategy. It also gives the proofs, the scan over block hashes, and measurements. + +## 🤖 In the decision tree {#in-the-decision-tree} + +- **Per input and pairwise terms** change during coalition formation, as candidates appear. + +## After confirmation + +This is the analysis that contributes privacy gains, and that uses the budget. + +- All inputs are known, but $t$ isn't. It can be guessed from the confirmation time, or the nLockTime. +- 🤖 $L$ is the maximum over the candidate block hashes mined after the inputs confirmed, each at $\delta / W$ for $W$ candidates. See [Finding the block hash](sybil_resistance_index.md#finding-the-block-hash). +- 🤖 The [Sybil resistance](cost_function_sybil_resistance.md) term of the transaction's outputs is then fixed. + +## 🤖 Open questions {#open-questions} + +- What should $\delta$ be? +- Can light clients estimate $L$ for transactions they only sample? + diff --git a/docs/cost_function_siblings.md b/docs/cost_function_siblings.md new file mode 100644 index 0000000..de50b16 --- /dev/null +++ b/docs/cost_function_siblings.md @@ -0,0 +1,34 @@ +--- +type: concept +title: Sibling output penalty +status: draft +stale_after: 2026-11-06T00:00:00Z +--- + +# 🤖 Sibling output penalty + +A privacy liability term of the [cost function](optimization_framework.md). Spending outputs of the same transaction together is wasteful, and more indicative of common ownership than spending unrelated coins together. It's penalized heavily. + +## Definition + +- $I$: the own inputs of the transaction under consideration. +- For each earlier transaction $T$, $j_T$ is the number of its outputs in $I$. +- **Liability.** $\ell_s = \sigma \sum_T \max(0, j_T - 1)$, with $\sigma$ large. +- Neither the labels from the [Consolidation penalty](cost_function_consolidation.md) chapter nor [subset sum density](subset_sum_density.md) reduce it. Amounts can explain the values, but not two users spending outputs of one transaction together. + +## In the decision tree + +- It's a privacy-related term. +- **Worst case:** $\ell_s$ as defined. It depends only on the own inputs. +- **Best case:** $\ell_s = 0$, which is used for pruning. +- $\ell_s \ge 0$ is unbounded, so it can exceed the remaining budget. The action is then taken only if other terms, e.g. a payment deadline, outweigh it. +- It applies to every own output of the transaction. The discount scales with value, not with the number of outputs. + +## After confirmation + +- $\ell_s$ is fixed once the inputs are chosen. +- Once the action is taken, the resulting coins' liability is capped at 1. + +## Open questions + +- Should $\ell_s$ extend to coins with a common ancestor further back? diff --git a/docs/cost_function_structure.md b/docs/cost_function_structure.md new file mode 100644 index 0000000..830acdd --- /dev/null +++ b/docs/cost_function_structure.md @@ -0,0 +1,64 @@ +--- +type: concept +title: Cost function structure +status: draft +stale_after: 2026-11-06T00:00:00Z +--- + +# 🤖 Cost function structure + +The evaluation of pure strategies is a family of cost functions, sharing the structure set out in the [Optimization framework](optimization_framework.md#preliminaries) chapter: a linear combination of terms, each labelled as privacy related or not, and each a piecewise linear function of time. This chapter describes that structure: how terms depend on time, how they are combined into a single amount in satoshis, and how incomplete information is handled by bracketing. The chapters that follow define the concrete terms. + +## Time dependence + +Every term of the cost function and every intent in the queue may depend on time, and how it does may depend on what is being evaluated. This time dependence is modeled as piecewise linear offsets to values computed independently of time, so the cost function returns a family of piecewise linear functions of time, one per term. Evaluating them at a given time is just a matter of indexing them and taking a sum, but treating them explicitly as piecewise linear functions makes it possible to solve for intercepts. + +## Linear combination + +The [global privacy budget](optimization_framework.md#global-privacy-budget), with its budget rate $p$ and remaining budget $B$, normalizes the privacy terms, so that all terms can be summed into a single amount in satoshis. + +Each coin has a *privacy liability* $\lambda$. Concrete privacy terms each start from their own notions, for example quantifying the entropy of a coin's anonymity set and how close it is to some threshold, potentially non-linearly, and are normalized into a single ensemble liability. All privacy liabilities collectively give a new privacy-problematic coin the baseline $\lambda = 1$; each term does not impose a separate baseline reduction. Coins received at external addresses start at this baseline, since the wallet has no prior knowledge about them. Change outputs of unilateral payments and privacy-problematic outputs of manual consolidations also start at the baseline. Evidence that the problems specified by the terms' definitions have been removed discharges the corresponding liabilities, reaching 0 when all have been discharged. This expresses the model's assessment of those problems, rather than a general privacy guarantee. $\lambda$ is stored per coin, but it is derived information. + +A coin's *subjective value* is its nominal value $x$ reduced by $\lambda p x$. At the baseline, the collective reduction in subjective value is therefore the budget fraction $p$ of the coin's nominal value. This turns abstract thresholds on privacy metrics into a penalty in satoshis, allowing subjective and objective costs to be summed and the wallet states predicted to result from different actions to be compared. Since the reduction in subjective value is computed per coin, this applies regardless of how many inputs and outputs a transaction has. + +A transaction spending coins with a total reduction in subjective value of $d_{in}$ and creating coins with a total reduction of $d_{out}$ at an objective cost of $y$ changes the wallet's total subjective value by + +$$(d_{in} - d_{out}) - y,$$ + +so on privacy grounds alone, an action is only worth taking if the decrease in liability costs dominates its objective cost. Privacy-motivated costs must also fit within the remaining budget. Other terms, such as the waste metric or the utility of completing a payment, also drive the decision. However, the utility of a payment is not part of the subjective value of the resulting state: a payment's utility rising over time doesn't mean that waiting longer to make it would leave the wallet with a higher subjective balance. + +For example, suppose Alice sets her budget rate to 1% and receives a coin of 100,100 sats, adding 1,001 sats to her remaining budget. The coin starts at the baseline, so its subjective value is 99,099 sats. The wallet considers CoinJoin transactions costing 100 sats in fees, each replacing it with a coin of 100,000 sats: + +| | nominal | $\lambda$ | reduction in subjective value | subjective value | change | +|---|---|---|---|---|---| +| before | 100,100 | 1 | 1,001 | 99,099 | | +| large improvement | 100,000 | 0.5 | 500 | 99,500 | +401 | +| small improvement | 100,000 | 0.8 | 800 | 99,200 | +101 | +| not worth it | 100,000 | 0.95 | 950 | 99,050 | −49 | + +Either of the first two outcomes is worth taking, and either leaves 901 sats in the remaining budget. The last reduces the liability cost by only 51 sats while costing 100, so the wallet would not make it. + +The same accounting applies when coins are split or consolidated. Splitting the same coin into two outputs whose liabilities improve by different amounts: + +| | nominal | $\lambda$ | reduction in subjective value | subjective value | +|---|---|---|---|---| +| input | 100,100 | 1 | 1,001 | 99,099 | +| output A | 60,000 | 0.5 | 300 | 59,700 | +| output B | 40,000 | 0.9 | 360 | 39,640 | +| outputs total | 100,000 | | 660 | 99,340 | + +The total reduction in subjective value falls by 341, which dominates the fee, for a net change of +241. Consolidating two coins of 60,000 and 40,100 sats, both at the baseline (reductions in subjective value of 600 and 401) into a single CoinJoin output of 100,000 sats with $\lambda = 0.5$ gives exactly the same result as the single coin, +401, since only the totals on each side matter. + +When evaluating a candidate action, the cost function may assign $\lambda > 1$ to the resulting coins. For example, if the privacy metrics assess the output of consolidating the same two coins without a CoinJoin, at the same fee, at $\lambda = 1.2$, its reduction in subjective value is 1,200 and its subjective value 98,800, a change of −299 before any other terms. Such an increase counts against the candidate in the full cost-function evaluation. An automated action is taken only when the cost-function evaluation predicts an improvement. This evaluation accounts for changes in the wallet's subjective balance, objective costs, the waste metric, and the utility of completing a payment. + +During decision-making, the cost function evaluates partial states with incomplete information. Once the transaction is fully constructed, the same function evaluates the complete state, including the other users' output values. This determines the liabilities and the accounting for privacy-budget expenditure. An explicit manual override resets the liability accounting for the resulting privacy-problematic coins to the baseline. This writes off the loss as an external adjustment authorized by the user, reflecting a valuation the cost function fails to capture. + +In general, a transaction which is worth taking on privacy grounds alone, spending coins of nominal value $x$ with a total reduction in subjective value of $d$ at a cost of $y$, results in coins whose subjective value is greater than $x - d$ and at most $x - y$ (when no liability remains). + +## Bracketing + +We model privacy liabilities as terms that only reduce the evaluation of a particular state, and can only be reduced as more information is revealed. This means that for every state we can derive a best case and worst case cost. The worst case is based on the information already available: it assumes that no other party contributes anything of value to the wallet, apart from the adjustments of any co-spend proposals in effect, which are guaranteed if the leaf materializes. The best case assumes they act optimally for the wallet, discharging all modeled privacy liabilities, and is obtained by simply omitting any privacy related penalties from the sum. Its use is pruning: a leaf whose best case is still unacceptable can be discarded, as in branch and bound. + +The most likely outcome lies in between, with other parties behaving the way they typically behave. An expected value for each leaf could in principle be estimated empirically, by comparing how a coalition was evaluated when the wallet committed to it with the actual wallet state, and the reduction in liabilities it generated, once it was finalized in a block. However, peers that consistently behave well could push the wallet towards optimism, and then exploit it in a coalition where they don't. How much risk to accept is up to the user, but this document only describes the pessimistic version, in which a leaf's expected value is its worst case. An expected value can always be introduced later as another term. + +During the critical section of transaction construction, i.e. after the inputs are revealed and before signatures are posted, knowledge of the other users' inputs may improve the worst case bracket. Preparing the decision tree ahead of time and computing these brackets makes it possible to respond to this new information efficiently, finalizing the decision of which outputs to add to the transaction in order to obtain better outcomes. diff --git a/docs/cost_function_subset_sum_ambiguity.md b/docs/cost_function_subset_sum_ambiguity.md new file mode 100644 index 0000000..cc34cac --- /dev/null +++ b/docs/cost_function_subset_sum_ambiguity.md @@ -0,0 +1,146 @@ +--- +type: concept +title: Subset sum ambiguity +status: draft +stale_after: 2026-11-05T00:00:00Z +--- + +# 🤖 Subset sum ambiguity + + + +A privacy liability term of the [cost function](optimization_framework.md). It applies the techniques of the [subset sum density](subset_sum_density.md) chapter to the user's own coins, for two measures: + +- **Inputs.** How well the sumset of the other users' inputs covers the sumset of the user's inputs. +- **Outputs.** How well the sumset of the other users' inputs covers the sumset of the user's outputs. + +Once the transaction has been fully built, both are also checked against the sumset of the other users' outputs. If both are well covered for every combination, the [sub-transaction](collaborative_txn_privacy.md) model is underdetermined. + +Given the wallet state and a transaction under consideration, it checks both for a proposed output decomposition, relative to the other users' inputs known so far. The other users' sumsets are bounded in degree, so they stay small, and the user's own are complete. It's cheap enough to evaluate for many decompositions. + +## Sub-transaction ambiguity + +A sub-transaction mapping, as in the models of Maurer et al. and LaurentMT described in [Collaborative transaction privacy](collaborative_txn_privacy.md), partitions a transaction's inputs and outputs into sub-transactions that each balance. Given one valid mapping, others can be reached by transformations that preserve that invariant. Ordered by generality, they break counting the mappings into a hierarchy of complexity: + +- **1:1 exchange.** If an output denomination has multiplicity $m$, the $m!$ permutations of the equal outputs all preserve the mapping. With one copy of the denomination per sub-transaction, quotienting by these permutations is trivial. +- **n:m exchange.** Substitute a set of inputs or outputs for another. With effective values and costs at an estimated feerate, this preserves the invariant in a model that admits non-zero fees. +- **Merge and re-partition.** The most general transformation that's still constructive. Merge some of the mapping's sub-transactions and partition them again, or make exchanges that break the invariant temporarily. It's a walk through the space of partitions and back into the sub-space of sub-transaction mappings. +- **Enumeration.** As in Maurer et al., the space can be enumerated by brute force. + +Multiplicity makes 1:1 exchange trivial, but that isn't enough for privacy. This term climbs only as high as n:m exchange, which reduces to subset sum. Subset sum density makes n:m exchange underdetermined as well, without the generality or the computational cost of the last two. The coverage checks below concern n:m exchange of the sums only the wallet knows: its own inputs and outputs. If those are sufficiently underdetermined, they give a lower bound on the number of sub-transaction mappings relevant to the wallet, and on the entropy of Maurer et al.'s link probabilities $p_{II}$, $p_{OO}$ and $p_{IO}$. + +## Notation + +For a multiset $Z$ of values: + +- $\Sigma(Z)$ is the set of its subset sums, over non-empty subsets. +- $\Sigma_{\le d}(Z)$ is the set of sums of at most $d$ of its elements. +- $A \sqsubseteq^{+}_\varepsilon B$: every $s \in A$ has some $t \in B$ with $s \le t \le s + \varepsilon$. +- $A \sqsubseteq^{-}_\varepsilon B$: every $s \in A$ has some $t \in B$ with $s - \varepsilon \le t \le s$. +- A single such $s$ is **covered**. + +## Inputs + +- $f$: the feerate of the [coalition formation proposal](coalition_formation.md). Effective values are [fixed](subset_sum_density.md#effective-values) at $f$. +- $X$: effective values of the other users' inputs known so far, positive values only. +- $Y$: effective costs of the other users' outputs. They're only known once the transaction has been fully built, though not necessarily signed. By then $O$ is fixed. While decisions are evaluated, $Y$ is empty. +- $I$: the own inputs, as effective values. +- $O$: the user's outputs, as effective costs. + - In the decision tree, a proposed decomposition. + - Once the transaction has been fully built, the complete multiset of the user's outputs. +- Parameters: + - $d$: the degree bound for the other users' sumsets, e.g. 2 or 3 for large transactions; + - $\varepsilon$: the slop; + - $\varphi$: the covered fraction at which the liability reaches 0; + - $\theta$: the number of doublings of $f_c$ over which the liability falls from 1 to 0. + +## Definition + +1. **Other users' sumsets.** $\Sigma_{\le d}(X)$, and $\Sigma_{\le d}(Y)$ once $Y$ is known. Either can be a bitmap, or count the subsets per sum. + - Whether coverage should require more than one subset per sum depends on the threat model, the computational resources and the value range. +2. **Own sumsets.** $\Sigma(I)$, and $\Sigma(O)$ once $O$ is proposed. +3. **Coverage.** Effective values are at least effective costs, so each check is one-sided. + - While decisions are evaluated, check $\Sigma(I) \sqsubseteq^{+}_\varepsilon \Sigma_{\le d}(X)$ and $\Sigma(O) \sqsubseteq^{+}_\varepsilon \Sigma_{\le d}(X)$. The other users' inputs can plausibly combine to the same balance as the user's coins, or slightly more. + - After the fact, also check $\Sigma(I) \sqsubseteq^{-}_\varepsilon \Sigma_{\le d}(Y)$. Sums of $Y$ are total effective costs, so they're at most the sums of $I$. + - And $\Sigma(O) \sqsubseteq^{-}_\varepsilon \Sigma_{\le d}(Y)$. A sum of $Y$ is a combination of the other users' outputs that could be interchanged with the user's outputs of that sum, so it's at most their actual sum. +4. **Covered fraction.** For each own coin $c$ in $I$ or $O$, $f_c$ is the fraction of the subsets of its side that contain $c$ and whose sums are covered. +5. **Liability.** $\ell(c) = \text{clamp}(\log_2(\varphi / f_c) / \theta, 0, 1)$. + - It's 0 once $f_c \ge \varphi$. + - It falls by $1/\theta$ per doubling of $f_c$. + +## Implementation + +### Tables + +Built once per transaction and shared by all decompositions: + +- $K_X$: for each sum up to the range, the smallest number of elements of $X$ that reach it, if at most $d$. + - Apply $K_X[i] \gets \min(K_X[i], K_X[i - a] + 1)$ per input $a$, from the top down. + - Counting per sum works the same way, with one layer per subset size. + - $\Sigma_{\le d}(X)$ has at most $\sum_{h \le d} \binom{|X|}{h}$ elements. Where that's far fewer than the range, enumerate it explicitly, or use a [sparse convolution](subset_sum_density.md#estimates-and-enumerators), and look sums up by binary search. +- $K_Y$: the same over $Y$, once it's known. +- $\Sigma(I)$: enumerated once per transaction. $\Sigma(O)$: enumerated per decomposition. Both are small. +- **Lookups:** a prefix count over the table answers whether the window $[s, s + \varepsilon]$ holds a sum, or $[s - \varepsilon, s]$ against $Y$. +- **Rounding:** the windows tolerate rounding, e.g. to multiples of 128 sats. Round in the direction that counts no implausible substitution. + - Against $X$, round the values of $X$ down and the own sums up. + - Against $Y$, round the values of $Y$ up and the own sums down. + - The window then widens by at most $d + 1$ rounding units. +- **Range:** from 0 to the largest own sum plus $\varepsilon$. Double it and rebuild if needed. Skip inputs that are too large to fit. + +### Updates + +- Each auxiliary input is one more pass over $K_X$. Once the transaction has been fully built, each of the other users' outputs is one more pass over $K_Y$. The order doesn't matter. +- Deduplicate inputs by outpoint and outputs by output id. +- Removing a value needs counts, or a rebuild. + +### Per decomposition + +- Look up each sum of $\Sigma(O)$. The results for $\Sigma(I)$ are shared by all decompositions. +- **Satisficing stops the work early:** + - a coin, once $\ell(c) = 0$; + - a decomposition, once all of its outputs have. + +### Radix denominations + +These are inputs with nominal value $c \cdot b^i$: + +- $b = 2$, $c = 1$; +- $b = 3$, $c \in \{1, 2\}$; +- $b = 10$, $c \in \{1, 2, 5\}$. + +They're grouped by effective value $v$, with multiplicity $m_v$. + +- **Multiplicity:** one pass per group, as a sliding window along each residue class mod $v$. +- **Contiguity:** sort the coins and keep a running sum $R$. Accept each next coin while it's $\le R + \varepsilon$, starting from a coin $\le \varepsilon$. + - Every sum $\le R$ is then covered without the tables. + - It may use any number of coins, so it only applies when $d$ is at least the number of coins accepted. + - Keeping $m_v - r$ coins per value gives robustness to $r$ removals per value. + +## In the decision tree + +- It's a privacy-related term. +- **Worst case:** only the inputs known so far count. $X$ is a lower bound, and auxiliary inputs are learned later. The other users' outputs aren't known until the transaction has been fully built, so only $\Sigma_{\le d}(X)$ is checked. +- **Best case:** $\ell(c) = 0$, which is used for pruning. +- Every participant, including the aggregator in that role, evaluates [co-spend proposals](subset_sum_density.md#co-spend-proposals) with this term, deciding whether to propose a generated one or to accept an incoming one. + - A generated proposal can carry density challenges, with a reward in the surplus. + - Perturbing a proposal adds values to the tables, one pass each. +- $\ell(c) \in [0, 1]$. + +## After confirmation + +This is the analysis that contributes privacy gains, and that uses the budget. + +- All inputs and outputs are known, so the checks against $\Sigma_{\le d}(Y)$ apply. +- **Coalition formation proposal known:** evaluate at its $f$, which continues the decision tree's chain. Also evaluate at the final feerate, which is a second scenario. +- **Recovery from seed:** evaluate at the final feerate only. + +## Monotonicity + +- The decision tree's estimate is the same definition restricted to the lower bound $X$, with $Y$ empty. +- Learning inputs or outputs only adds sums to $\Sigma_{\le d}(X)$ and $\Sigma_{\le d}(Y)$, so covered sums stay covered and $\ell(c)$ can only fall. +- This requires the same $f$, the same realized $O$, and the same parameters. + +## Open questions + +- Is $\varepsilon$ absolute, or relative to the target? Does it include adjustments? +- After the fact, is a sum covered if either $\Sigma_{\le d}(X)$ or $\Sigma_{\le d}(Y)$ covers it, or are the two fractions separate? diff --git a/docs/cost_function_sybil_resistance.md b/docs/cost_function_sybil_resistance.md new file mode 100644 index 0000000..b62b978 --- /dev/null +++ b/docs/cost_function_sybil_resistance.md @@ -0,0 +1,71 @@ +--- +type: concept +title: Sybil resistance +status: draft +stale_after: 2026-11-06T00:00:00Z +--- + +# 🤖 Sybil resistance + + + +The Sybil resistance liability depends on the cost of an adversary supplying the coins in the history of the coin under consideration, and the candidates from which they were selected. The assessment assumes that all candidate UTXOs in the relevant order books, and the transactions that created them, were controlled by one adversary. Observed resource requirements and estimates of unobserved costs are evaluated against the user's threat model. + +## Provenance term + +For a coin under consideration, a fidelity bond like analysis of the transaction that created it, its funding transaction: + +1. **Order book size.** Estimate the size of the order book at the time of the funding transaction, from its input set. This is the lower bound $L$ on the number of candidate UTXOs $N$ from the [Order book size estimation](sybil_resistance_index.md) chapter. +2. **Cost.** Account for the liquidity, holding times and fees visible in the observed graph. Use $L$ and the sampled paths to estimate additional costs, subject to assumptions about the unobserved candidates. A discount rate expresses the time value of capital held over those intervals. This opportunity cost can be combined with fees. +3. **Ancestors.** Repeat for earlier transactions, subject to data availability and computational limits. + +Selection bias is a property of past selection events. Those events confer Sybil resistance relevant to the assessment of later coins; the bias itself is not inherited. + +- **Why it's a cost.** For a single adversary to construct a transaction exhibiting such a bias, it must control the entire set of candidate UTXOs, not just the coins that end up being selected. Then takers would have to select the outputs of this transaction. +- **Bounds and estimates.** $L$ is a lower confidence bound on candidate count. Converting it into an estimate of unobserved costs requires assumptions about candidate values and holding times. This estimate is distinct from resource bounds established directly by the observed graph. +- **Only with the preferences.** The term can only be optimized in the presence of a market preference like the per input and pairwise terms, or no bias would be detectable. +- **Costless for honest users.** Assuming takers and makers weakly prefer the bias, it's costless, at least on average. With market demand for it, makers can be profitable. This promotes a wider CoinJoin graph, with less temporal assortativity. +- **Waiting.** The longer a UTXO is unspent, the more chances it has of being lucky. +- **Intersection attacks.** Randomization promotes a high number of paths between coins, even for bounded degree graphs, as in superconcentrator graphs.[^bhatt] It doesn't guarantee them: it draws from the non-random set of available candidate UTXOs at a point in time. The estimate can also be used for degree sequence estimation in the Karrer–Newman model of the [Counterfactual paths](cost_function_counterfactual_paths.md) chapter. + +See also Belcher's analysis of fidelity bonds.[^belcher] + +## 🤖 Observed resource requirements {#cost} + +The observed transaction graph provides lower bounds on the resources required under the hypothesis that they were controlled by one adversary: + +- **Liquidity.** Coins known to have been unspent concurrently require at least their combined value in liquidity. This bound depends on their total value, regardless of how that value is divided among coins. +- **Capital held over time.** While coins remain unspent, their value cannot also be spent in concurrent CoinJoins. Spending them ends their holding intervals. Maintaining this capital also incurs an opportunity cost due to the time value of money, which is the principal connection to the fidelity bond analysis. Coin values multiplied by their holding durations give capital-time quantities, expressed in coindays; a discount rate is used to evaluate the associated opportunity cost. +- **Fees.** The observed transactions record the fees paid to create and spend those coins. Treating these as costs to the adversary assumes that it controls only a limited share of mining hash rate. + +A fetched subgraph can already establish these bounds. It is not necessary to reconstruct the entire ancestry. + +## 🤖 Estimation from sampled paths {#whole-graph} + +The randomized subgraph is the portion of the transaction graph corresponding to biased input selections. In the bipartite representation with transaction and coin vertices, prune the coin vertices that do not appear to have been randomly selected and take the induced subgraph on the remaining vertices. The randomization is verifiable because the selection uses a cryptographic public randomness beacon. + +A path is found by traversing backwards from a UTXO in the order book until reaching CoinJoins already known to the wallet, such as descendants of CoinJoins it participated in. This establishes a flow route. The traversal is repeated several times, bounded to a particular block range. + +The observed paths are tallied as in [observed resource requirements](#cost): at a given discount rate, the total cost of their coindays and their transaction fees. This is the base Sybil resistance. + +Even if only a small number of paths are found, the [order book size estimate](sybil_resistance_index.md) extends the tally to a cost for the randomized subgraph concurrent with the observed paths: a total cost to the adversary, assuming the observed paths are representative. The representativeness is supported by observable selection bias in the inputs of the traversed transactions. + +The estimate is restricted to this randomized subgraph. Only quantities estimated from the subset of inputs exhibiting the selection bias are scaled; other inputs encountered in the fetched history are excluded from that extrapolation. The order book size estimate supplies $L$, a lower confidence bound on candidate count, to estimate the width of the randomized subgraph. + +From the observed paths, estimate the candidate-value and holding-time distributions and their means as functions of time, retaining the number of observations supporting each estimate. Scale the estimated means by $L$ to estimate the corresponding aggregate quantities for the randomized subgraph concurrent with the observed paths. Resource estimates derived this way depend on the representativeness assumption, unlike bounds established directly from the observed graph. + +Concurrent transactions with similar selection bias provide additional observations of the same candidate population. Combining comparable path samples refines the estimated distributions and their means; it does not add separate population sizes. With two comparable paths, the quantity scaled by $L$ is their mean, rather than their sum. The same applies to more paths: the number of observations supports the estimate and is not an additional width multiplier. + +## 🤖 Subjective liability + +The observed lower bound and estimated cost are assessed against the user's threat model. There is no universal threshold for sufficient adversarial cost. The cost judged prohibitive depends on the severity of the user's real-world threat model; more severe threats require a higher threshold. + +The liability is zero when the attack cost is judged prohibitive under that model. Otherwise, it represents a subjective loss scaled by the user's privacy budget. This valuation guides the combined decision framework; it does not establish that the chosen privacy measures cover every threat to the user. + +## 🤖 In the decision tree {#in-the-decision-tree} + +The term of a coin under consideration is fixed once its funding transaction confirms, so it's computed once per coin and cached. The transaction's own outputs get theirs after confirmation, as the [randomized selection](cost_function_randomized_selection.md#after-confirmation) chapter describes. + +[^belcher]: C. Belcher, [*Financial mathematics of JoinMarket fidelity bonds*](https://gist.github.com/chris-belcher/87ebbcbb639686057a389acb9ab3e25b#cost-of-sybil-attacks). + +[^bhatt]: S. N. Bhatt, [*On Concentration and Connection Networks*](https://hdl.handle.net/1721.1/149007), MIT, 1981. diff --git a/docs/index.md b/docs/index.md index 18aee53..53c61b8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,13 +2,46 @@ okf_version: "0.2" --- -# BIP Drafts +# Problem Statement -* [PSBT Scrubber](bip-drafts/scrubber.md) - Which PSBT fields can be shared with trusted and untrusted parties such that privacy is preserved. +* [Collaborative transaction privacy](collaborative_txn_privacy.md) - Challenges for privacy in multiparty transaction settings, from PayJoin to CoinJoin. + +# Protocol Suite + +* [Overview](overview.md) - Collaborative transaction construction, privacy, fault tolerance and coalition formation. +* [Abstract transport interfaces](transport-interfaces.md) - Send, receive and bidirectional channels, the kinds of messaging the protocol needs, and broadcast built from peer to peer channels. +* [🤖 Peer and broadcast channels](channels.md) - Broadcast to a group or to the world, built by gossip over peer to peer channels. +* [Contacts and payment messaging](contacts.md) - What interactive payments need from peer to peer messaging between payer and payee. +* [Market-based coalition formation](coalition_formation.md) - Bilateral negotiation and aggregation of co-spend proposals into a unanimously accepted coalition formation proposal. +* [Transaction construction](transaction-construction.md) - Content and state synchronization, the phases, the optimistic and recovery tracks, and what the validity proofs enforce. + * [Block DAG](block-dag.md) - The validator blocks both tracks share, with their objects, nonce commitments and equivocation evidence, genesis, causal order and frontiers. + * [🤖 Optimistic track: blocks and phase states](optimistic-track.md) - Unanimity and phase closure on the optimistic track, phase by phase. + * [Recovery track](recovery-track.md) - How a stalled phase of the optimistic track turns into a recovery coalition formation proposal. Draft. +* [🤖 Peer set reconciliation](set-reconciliation.md) - Requesting hash preimages, naive reconciliation, unordered sets, and range and rateless reconciliation as optimizations. +* [🤖 Protocol messages](protocol-messages.md) - The messages peers exchange, who sends them, when, and what each requires of its channel. +* [🤖 Validity proofs](validity-proofs.md) - Selected design: proving outputs are covered by inputs through anonymous allocation registration. -# In Review +# Privacy Optimization Strategy -* [Collaborative transaction privacy](collaborative_txn_privacy.md) - Under review in #7. -* [Cost function framework for Bitcoin wallets](cost_function_abstract.md) - Under review in #15. -* [Concurrent PSBT Construction](psbt-concurrent.md) - Under review in #16. -* [Market-based coalition formation for collaborative transaction construction](coalition_formation.md) - Under review in #18. +* [Optimization framework for Bitcoin wallets](optimization_framework.md) - Objective costs, privacy liabilities and payment utility as the basis for automated wallet decisions. +* [🤖 Pure Strategy Evaluation](pure_strategy_evaluation.md) - How the cost of a pure strategy is evaluated: the structure of the cost function, its privacy liability terms, and the privacy metrics they take as input. + * [🤖 Cost function structure](cost_function_structure.md) - The structure shared by the family of cost functions that evaluate pure strategies: time dependence, linear combination of terms and bracketing. + * [🤖 Privacy liability terms](cost_function_concrete.md) - The privacy objectives assessed by each liability term and how the terms interact. + * [Randomized selection](cost_function_randomized_selection.md) - Selection preferences that randomize which coins are co-spent, and a lower bound on the size of the order book they were selected from. + * [🤖 Sybil resistance](cost_function_sybil_resistance.md) - Observed resource requirements and sampled cost estimates assessed against the user's threat model. + * [🤖 Subset sum ambiguity](cost_function_subset_sum_ambiguity.md) - Outline of a concrete cost function term for the subset sum ambiguity of input and output values. + * [🤖 Consolidation penalty](cost_function_consolidation.md) - Outline of a concrete cost function term penalizing consolidation unless the subset sums are very dense and the coins are impervious to intersections. + * [🤖 Sibling output penalty](cost_function_siblings.md) - Outline of a concrete cost function term penalizing spending sibling outputs together. + * [🤖 Privacy metrics](privacy_metrics.md) - Measures computed from public data that the privacy liability terms take as input. + * [🤖 Order book size estimation](sybil_resistance_index.md) - A relatively conservative estimate of a lower bound on the number of candidate coins a transaction's inputs were selected from, and how to find the block hash they were selected with. + * [🤖 Subset sum density](subset_sum_density.md) - How many subsets of a multiset of effective values sum into a target interval, a quantity the subset sum ambiguity and consolidation terms reuse, how it's estimated, and how co-spend proposals and the aggregator optimize it. + * [🤖 Counterfactual paths](cost_function_counterfactual_paths.md) - Outline of how to count disjoint counterfactual paths with one max flow, and how to estimate the count. +* [🤖 Mixed strategy](mixed_strategy.md) - How to compose a mixed strategy from the cost of pure strategies: randomization, time dependence, internalization and the decision loop. +* [Tactics](tactics.md) - Generating the decision tree bottom up, with coin selection and change decomposition, and when to re-evaluate it. + * [Bottom-up construction](bottom_up_construction.md) - Building the decision tree from the leaves: partitions of the intent queue, coin selection, change construction, order book coins, action sequences, and bracketing. + * [Radix CoinJoin Denominations](Denominations_and_gap_size_distributions.ipynb) - Why small Hamming weight denominations suit CoinJoin outputs, and how closely sums of a few of them approximate arbitrary amounts. + +# BIP Drafts + +* [PSBT Scrubber](bip-drafts/scrubber.md) - Which PSBT fields can be shared with trusted and untrusted parties such that privacy is preserved. +* [Concurrent PSBT Construction](psbt-concurrent.md) - PSBT fields and rules for combining partial transactions and terminating concurrent construction. diff --git a/docs/mixed_strategy.md b/docs/mixed_strategy.md new file mode 100644 index 0000000..7ebdeba --- /dev/null +++ b/docs/mixed_strategy.md @@ -0,0 +1,32 @@ +--- +type: concept +title: Mixed strategy +status: draft +stale_after: 2026-11-06T00:00:00Z +--- + +# 🤖 Mixed strategy + +This chapter recommends how to compose a mixed strategy out of the cost of pure strategies, as set out in the [Optimization framework](optimization_framework.md) chapter, using the concrete monotone terms of the evaluation in the [Privacy liability terms](cost_function_concrete.md) chapter. + +## Randomization + +An adversary that knows the wallet's state and pure strategy can predict its next action. A mixed strategy randomizes over pure strategies, but its effect depends on how the observable outcomes differ. + +Uniform selection among $k$ distinct leaves has $\log_2(k)$ bits of entropy over leaf identity. However, similarities between their outcomes can reduce the uncertainty over the distinctions relevant to an adversary. Sampling should give less weight to similar alternatives so that the resulting distribution is approximately uniform over materially different choices. How to measure similarity and construct this sampling distribution remains open. + +## Time dependence + +Every term of the cost of a pure strategy is a piecewise linear function of time, so the cost is too. The cost is a transparent sum of such terms partly so that crossing times can be solved for, and the brackets derived efficiently at predicted future times. Since the predicted times are themselves uncertain, the cost brackets can also be augmented with time brackets, i.e. bounds on those predicted times. + +## Internalization + +The solver searches for sequences that lead to states with greater valuation. It values the leaves first, then propagates their brackets and the tree level expectation toward the root. The tree level expectation internalizes the optionality of the leaves into their parent: it is the mean of the worst cases of the $k$ least worst leaves below that parent, since the mixed strategy chooses uniformly among them. This ignores that leaves aren't independent, as they may share actions. This reduces a plan involving many contingent future actions to comparisons among the actions available now. + +Internalizing the expectations about a node's children into the node gives the node its own piecewise linear curve. Solving it for the time at which the next child is expected to have positive utility determines when to take that branch, unless new information invalidates the decision in the meantime. + +## Decision loop + +The wallet acts in a decision loop. Internalization is what allows this loop to be run as a greedy search, going one level down the tree per iteration: since each node already accounts for what may follow it, a look ahead of depth 1 is sufficient. Internalizing takes one pass over the tree, and doesn't need to be repeated on every iteration of the loop. + +From the current state, the wallet finds the next action, i.e. the child of the root, that will become attractive soonest, waits for it to do so, and takes it. It then prunes that action's siblings, committing to the sub-tree below it. There can be multiple paths to the same outcome, for example through repeated actions or states that converge, so an implementation may share sub-trees and represent the tree as a DAG. diff --git a/docs/optimistic-track.md b/docs/optimistic-track.md new file mode 100644 index 0000000..b1bb3b4 --- /dev/null +++ b/docs/optimistic-track.md @@ -0,0 +1,220 @@ +--- +type: Specification +title: "Optimistic track: blocks and phase states" +description: Unanimity and phase closure on the optimistic track, phase by phase. +status: draft +stale_after: 2027-04-15T00:00:00Z +--- + + + +# 🤖 Optimistic track: blocks and phase states + +## Scope and status + +This specification describes how Fungi transaction construction obtains consistency on the optimistic track, with threshold $t=n$. The [recovery track](recovery-track.md), with $t + +## Phase closure + +🤖 The optimistic track is defined for the asynchronous communication model. Every phase closes by two rounds of unanimous acknowledgement of the same contribution set. Cooperative participants advance as soon as they hold the evidence; a silent participant can stall progress. The [recovery track](recovery-track.md) handles missing per-input messages and stalled validator participation. + +Finalizing each phase's contribution set keeps it stable for the next. This matters most for the input set, which must be stable before outputs: + +- **Validity proofs and their privacy.** Proving an output before a late input arrives would need a more complicated proof statement and would harm privacy, so it is not supported. +- **The balance condition.** With only some of the inputs and some of the outputs, the two could sum to the same amount, and the balance would reach zero too early. +- **Choosing output values.** Most importantly, output values are chosen on the basis of the input set, including the auxiliary inputs. This is a privacy requirement. + +### State acknowledgement and unanimity + +Set finalization uses two rounds of acknowledgements carried implicitly by ordinary DAG blocks. In the first round, each validator acknowledges its phase state with nothing further to add. In the second, each validator acknowledges that all validators' first-round acknowledgements refer to the same set. These are roles of blocks in the construction phase, not separate block types or payload messages. + +Let $N$ be the fixed validator set and $V_\phi(b)$ the contribution set represented by block $b$ for construction phase $\phi$. For first-round acknowledgement blocks $b_i$, synchronization requires a common set $S$: + +$$ +V_\phi(b_i)=S \qquad \text{for every } i\in N. +$$ + +A second-round acknowledgement has causal evidence of first-round acknowledgements from every validator for that same $S$, and still represents $S$ itself. A participant finalizes the set once it has the second-round acknowledgements from every validator. The blocks need not have equal heights or identical parents; the contribution sets they acknowledge must agree. + +Receiving one block from every validator is therefore insufficient if those blocks represent different sets. Taking their union does not establish that the first-round acknowledgements were synchronized. Reconciliation must continue until the common-set condition is met. 🤖 When a validator may give its first-round acknowledgement depends on whether the phase's [keys](#keyed-and-anonymous-phases) are listed or anonymous. + +### Phase transitions + +🤖 A validator enters phase $\phi$ once it has the second-round acknowledgements from all of $N$ finalizing the same set for $\phi-1$. Kickoff is entered on holding the genesis. Validation of an individual contribution does not itself establish a phase's completion. + +A participant advances when the relevant evidence becomes available; others catch up through causal delivery. Local phase changes need not be simultaneous. + +The exact successor phase is a deterministic function of the completed state and the transaction protocol's rules. A late message cannot silently amend an already closed phase: its treatment must follow those rules or belong to a new attempt. A claimed transition without the required evidence is not accepted as a valid transition. + +No phase transition can infer readiness solely from local quiescence. Conversely, obtaining a closing certificate does not require proving that no further network traffic exists. The finite agreement is on $S$ and its readiness conditions. Reconciliation completion, quiescence and phase completion are distinct events. + +### 🤖 Keyed messages {#keyed-and-anonymous-phases} + +🤖 Every transaction-level message is keyed: it relates to one input, one output or one fee contribution. In the optimistic phases, fee contributions are explicit and keyed for idempotence. In the proven phases, explicit fee contributions are no longer required, because nobody can claim more than they can prove. Whatever no output claims is fee. A key can have more than one message. The block DAG witnesses every message it includes, so all validators see duplicates under the same key. Two valid input proofs from one input with different allocation commitments are evidence against that input, as described under [per-input messages](#per-input-messages). + +🤖 Ideally every kind of equivocation would expose the online key, as conflicting validator blocks expose the validator key through [nonce commitments](block-dag.md#nonce-commitments-and-compact-equivocation-evidence). For anonymously published messages, this could use double-authentication-preventing (DAPS) ring signatures, which could also rate-limit messages per key. This remains to be specified. + +🤖 An initial input publishes its messages through its validator. Auxiliary inputs and outputs are published by connection-oriented anonymous broadcast. It can relay several messages for the same key, as long as each connection carries only one auxiliary input or one output. + +🤖 Phases differ only in when a validator gives its first-round acknowledgement: + +- **Listed keys**: kickoff, initial-input proofs and signatures. The keys are fixed when the phase opens. A validator acknowledges once its view holds a valid message for every key. +- **Anonymous keys**: auxiliary inputs, outputs and fee contributions, proven auxiliary inputs, allocation registrations and proven outputs. A validator acknowledges under the [anonymous-phase publication rule](#anonymous-phase-publication). + +### Hashes and identifiers + +- $H(\mathit{tag}, m) = \mathrm{SHA256}(\mathrm{SHA256}(\mathit{tag}) \Vert \mathrm{SHA256}(\mathit{tag}) \Vert m)$, the tagged hash of BIP 340.[^schnorr] Tags begin with `fungi/`. +- Instance id: $\mathit{sid} = H(\texttt{fungi/session}, \mathit{genesis})$. +- Outpoint: $\mathit{op}$ = txid (32 bytes, internal byte order) followed by vout (u32, little-endian). +- Validator: its index in $N$, in genesis order. + +### Input lists + +🤖 The initial inputs $I$ are listed in the genesis. Every initial-input owner participates as a validator, validating and acknowledging the construction state. The aggregator owns an initial input and is therefore a validator too. Each input acts through the online key enrolled by its ownership proof; its spending authority is used for transaction signing. Auxiliary inputs are submitted anonymously, first without proofs and, only after overflow, with the required proofs. + +🤖 Optimistic auxiliary inputs, optimistic outputs and fee contributions, auxiliary-input proofs, allocation registrations and output proofs are submitted anonymously. Input proofs and final signatures identify the input by outpoint; anonymous submission does not make the transaction's outpoints private. The [optimistic phases](transaction-construction.md#phases), which add content without validity proofs, concern transaction data; they are distinct from the optimistic track this chapter describes, which concerns agreement. + +### Per-input messages + +A per-input message is signed by, or bound to, one input. These are the only messages that can blame an input. 🤖 Each list $L_\phi$ of listed keys is sorted by outpoint bytes, ascending. + +| Phase | List $L_\phi$ | Message | Valid if | +| --- | --- | --- | --- | +| kickoff | the initial inputs $I$ | $\mathrm{ACCEPT}(i)$ | signature by the online key of $i$ over $H(\texttt{fungi/accept}, \mathit{sid})$ | +| initial-input proofs, only after overflow | the initial inputs $I$ | input proof of $i$ | verifies under the validity proofs and is authenticated by the online key of $i$, bound to $\mathit{sid}$ and $\mathit{op}_i$ | +| signatures | the inputs of the final unsigned transaction | signature of $i$ | a valid witness for $i$ over the final unsigned transaction | + +An invalid message counts as absent. + +🤖 Validators take the union of the per-input messages they receive, each identified by its input's outpoint. An input commits to one input proof. If it posts two valid input proofs for the same $\mathit{sid}$ with different allocation commitments, the DAG reveals both. Their online-key authentication binds them to that input, so, as in Cordial Miners,[^cordial] the pair is evidence of malfeasance by that specific input. As the [block DAG](block-dag.md#nonce-commitments-and-compact-equivocation-evidence) requires, both are removed from the phase state. [Recovery](recovery-track.md#evidence-that-excludes-at-once) additionally excludes the input. Two different valid signatures over the same transaction, or two valid ACCEPT messages, are not equivocation; either one serves. + +### Blocks and acknowledgements + +🤖 Validators publish blocks in the shared block-DAG format. A block's payload holds received messages not yet in its causal history. Anonymous submissions become eligible for inclusion once received through synchronization, without distinguishing the validator's own submissions from those of other participants. A block with no new messages can acknowledge the state established by its causal history. + +The acknowledgement rounds use optimistic-track blocks. Recovery-track blocks use the separate recovery nonce commitment, as described in the [block format](block-dag.md#nonce-commitments-and-compact-equivocation-evidence). The permitted branching between tracks is not equivocation. + +Successive blocks by one validator are not equivocation merely because they belong to the same construction phase. Equivocation evidence follows the predecessor and nonce-commitment rules of the block DAG. + + + +🤖 A validator can leave message collection to other validators, or follow a trusted or TEE-attested validator, while still producing its own acknowledgement blocks. The block DAG describes this under [optional attested validation and acknowledgement relay](block-dag.md#optional-attested-validation-and-acknowledgement-relay). + +## Phases + +Each phase below admits its content, then closes by the rules above. The phases run in the order given in [transaction construction](transaction-construction.md#phases). + +### Kickoff + +🤖 Kickoff is the validators' acknowledgement of the coalition formation proposal, the genesis. It is keyed by the initial inputs, each acknowledging with an $\mathrm{ACCEPT}$ message. Its two acknowledgement rounds are the first two layers of the [block DAG](block-dag.md#optimistic-and-recovery-tracks). Once a peer holds second-round acknowledgements from all $n$ validators, kickoff is complete for it, and it can begin anonymously disseminating auxiliary inputs. + +A missing acknowledgement can stall kickoff. The [recovery overlay](recovery-track.md#recovery-overlay) begins after the genesis acknowledgement layers; this rule does not itself provide a recovery mechanism for incomplete kickoff. + +### Anonymous-phase publication + +🤖 In each anonymous phase, a validator waits for reconciliation quiescence and at least the phase's minimum waiting period before its first-round acknowledgement. Inclusion of its own anonymous contributions is not a condition for either acknowledgement round. The same rule applies to auxiliary inputs, outputs and fee contributions, allocation registrations, and proven outputs. The waiting periods and reconciliation scope remain to be specified. Quiescence permits publication under this rule; phase closure still requires both rounds of unanimous acknowledgements described above. + +🤖 Conditioning an identified validator's block on receipt or inclusion of its own anonymous registration or output would let adversarial peers test the association by selectively withholding that contribution. A participant therefore continues validating and acknowledging the construction even if every other validator omits its contributions. If the resulting transaction does not satisfy its output or payment requirements, it refuses transaction signing instead. A missing signature identifies an input, but does not by itself identify the omitted anonymous contribution or establish why the participant refused to sign. + +### Auxiliary inputs + +🤖 Auxiliary inputs are admitted anonymously. Omitted auxiliary inputs are not part of this transaction. + +### Outputs + +🤖 Outputs and fee contributions are admitted anonymously without validity proofs. This is the same content protocol as in the semi-honest setting. The initial inputs are already known, and the optimistic auxiliary-input set has been agreed. No mandatory destination-commitment phase precedes these contributions. + +🤖 Every optimistic output or fee contribution accounts for at least 1 sat. The balance in a validator's view is the total of $I \cup A$ minus the outputs and fee contributions in that view. A participant may post the overflow signal, equivalent to a fee contribution of `MAX_MONEY`, to make that balance negative. This starts the need for proving; it does not bypass the anonymous-phase waiting rule or the phase-closing acknowledgements. + +The balance of the finalized set determines the next phase: + +- **Balanced.** At a balance of zero, the phase continues to signatures. 🤖 This is the only outcome that terminates on the optimistic track. Agreement on this balance does not establish that every participant's outputs are present or that its payment requirements are satisfied; participants check those conditions before signing. +- **Overspent.** If the balance is negative, at least one output or fee contribution is not covered. The phase continues with the proven phases, as the [validity proofs](validity-proofs.md) require. In the Byzantine setting anyone can force this. For example, a faulty party posts an output for exactly the remaining amount before an honest output arrives; the honest output then makes the balance negative. +- 🤖 **Underspent.** A positive balance does not terminate the optimistic track. Unclaimed balances are possible only on the [recovery track](recovery-track.md), which is a different termination path. + + + + +### Initial-input proofs + +🤖 The proven phases run only after overflow in the optimistic outputs phase. Optimistic outputs are discarded. Participants choose fresh, unguessable output ids for the proven phases. This phase is keyed by the initial inputs: each posts its proof, identified by outpoint and authenticated by its online key. The proof commits to its allocations of funds and vbytes. The finalized initial-input-proof set supplies the allocations used for auxiliary admission. + +### Proven auxiliary inputs + +🤖 Auxiliary inputs are submitted anonymously with their proofs. Each proof message is authenticated by that input's own online key, enrolled by its BIP-322 ownership proof, and bound to the session. Each admission consumes a vbyte allocation committed by an initial input. Only once the proven auxiliary-input set is finalized is the session root derived from the accepted initial and auxiliary input allocations. The [validity proofs](validity-proofs.md#phases-and-data-dependencies) describe the dependency; the current PoC does not implement the vbyte-allocation admission relation. + +### Allocation registration and proven outputs + +🤖 Output proving has two anonymous phases. First, allocation registrations are submitted against the final session root. Their finalized set determines the registered-leaf root. Then outputs are submitted with proofs against that root. The proofs enforce coverage. As in the outputs phase, only a balance of zero terminates the optimistic track. Script authorization follows the validity proofs. + +### Signatures + +🤖 Signatures are keyed by the inputs of the final unsigned transaction. Once every validator holds every signature, the transaction is complete. + +## Payment confirmation commitments + +🤖 A payment confirmation states that a particular construction state satisfies the payment agreement: the payee confirms delivery of the funds to their ultimate destination, including any onward payments. Counterparties exchange confirmations after output finalization and before input signing. The payer checks that the output set committed to by its input signature is consistent with that confirmation. This check does not require the payer to learn which output belongs to the payee. The [concurrent PSBT specification](psbt-concurrent.md#confirmation-of-successful-payment-prior-to-signing) defines the dependencies between counterparties' confirmations. + +🤖 The confirmed construction state is bound by the protocol transcript's Merkle-set commitment. That transcript includes the transaction contributions and required proofs, and its commitment is used as the deterministic sort seed for constructing the unsigned transaction. The payer checks that the payee's confirmation names the same transcript commitment that it uses to construct the output set it signs. Acknowledgement-only blocks can change a DAG frontier without changing this construction state. + +🤖 In the Byzantine setting, the wire objects are specified protocol messages. Their accepted state projects into the PSBT data used to construct and sign the transaction. Honest and semi-honest construction can use PSBT extensions; the Byzantine construction requires specified protocol extensions rather than accepting arbitrary PSBT extensions as protocol messages. + +## Block publication and quiescence + +🤖 Quiescence minimizes the number of block DAG waves per phase. Convergence on a phase's contributions happens by gossip; the block DAG exists to verify that convergence did occur. Waiting for convergence among its neighbors before authoring a block therefore avoids needless waves. This applies even when the cordial parent threshold is already met, as with $t=n$. Fewer blocks are also more compressible on the wire. [Peer set reconciliation](set-reconciliation.md) is an input to this rule, whichever reconciliation algorithm is used. + +Reconciliation between neighbors precedes the release of a new cordial block. The objective is to publish a consolidated view rather than a sequence of intermediate views that exposes the order in which contributions reached the validator. This reduces observable correlations between the block contents and the network's propagation topology. + +For a fixed reconciliation scope, local quiescence means that its advertised sets have been reconciled and there is no outstanding reconciliation work for that scope. It is a local condition: it neither proves that no further message exists nor closes admission to a phase. A newly advertised root can create more work. + +A publication rule must specify which neighbors and advertised roots belong to the scope, how concurrent advertisements affect it, and how stalled neighbors are handled. Those choices are not yet fixed. Waiting for all future advertisements is not a finite condition; waiting for every neighbor can indefinitely delay publication. Any cutoff or recovery policy must be evaluated together with the intended privacy and liveness properties. + +Cordial parent-inclusion rules additionally limit block production according to progress by other validators.[^cordial] Quiescence batches the available contributions before a permitted block is released; it does not replace the parent threshold. On a hub-and-spoke topology, a well-connected validator can assemble most payloads while others acknowledge them. This is workload concentration, without requiring a privileged leader. + +The privacy objective is to avoid additional attribution beyond the transaction, authorized counterparty knowledge and the transport's guarantees. Channel-randomized transfer schedules reduce redundant traffic; quiescent publication reduces intermediate public views. Neither alone establishes a topology-hiding theorem. The remaining leakage includes publication timing, neighbor failures and the selected quiescence policy. + +## Dissemination interface + +🤖 Blocks and their messages are disseminated by [peer set reconciliation](set-reconciliation.md). Its [naive reconciliation](set-reconciliation.md#naive-reconciliation), which requests the preimages of unknown hashes until it reaches known blocks, is sufficient for causal delivery; the other algorithms there are optimizations. Reconciliation supplies contents and completion status. It does not decide block validity, unanimity or phase transitions. Beluga's block synchronizer is a reference for this boundary and for evaluating recovery traffic.[^beluga] + +## Resource bounds and validation + +🤖 Bounds on neighbor exchanges, speculative decoder work and unresolved roots are given in [peer set reconciliation](set-reconciliation.md#resource-bounds-and-validation). The transaction protocol bounds admitted contributions; the DAG rules must additionally bound block production and recovery proposals. Invalid contributions do not enter validated application state, and reconciliation cannot force a withholding participant to sign. + +## Open specification choices + +The remaining choices are: + +* Canonical block encodings and the interface to peer-layer committed sets. +* Quiescence scope and publication scheduling, including handling of continuing traffic and stalled neighbors. +* Exact interpretation of the two acknowledgement rounds in the block DAG, admission boundaries, and their interaction with late contributions and recovery. +* Bounds on block production and branch proliferation. +* 🤖 Equivocation evidence that exposes the online key for every kind of keyed message, for example using DAPS ring signatures, and its use for rate limiting. + +The DAG interpretation and phase rules are independent of the peer layer's choice of reconciliation algorithm. + +## References + +[^bec]: Martin Kleppmann and Heidi Howard. [Byzantine Eventual Consistency and the Fundamental Limits of Peer-to-Peer Databases](https://arxiv.org/abs/2012.00472). + +[^schnorr]: Pieter Wuille, Jonas Nick and Tim Ruffing. [BIP 340: Schnorr Signatures for secp256k1](https://bips.dev/340/). Reference for the Schnorr verification equation and key-prefixed challenges; the predecessor nonce commitments and equivocation-evidence policy are part of this protocol. + +[^cordial]: Idit Keidar, Oded Naor, Ouri Poupko and Ehud Shapiro. [Cordial Miners: Fast and Efficient Consensus for Every Eventuality](https://arxiv.org/abs/2205.09174). + +[^beluga]: Tasos Kichidis et al. [Beluga: Block Synchronization for BFT Consensus Protocols](https://arxiv.org/abs/2511.15517). diff --git a/docs/optimization_framework.md b/docs/optimization_framework.md new file mode 100644 index 0000000..193172e --- /dev/null +++ b/docs/optimization_framework.md @@ -0,0 +1,215 @@ +--- +type: concept +title: Optimization framework for Bitcoin wallets +status: draft +stale_after: 2026-10-31T00:00:00Z +--- + +# Optimization framework for Bitcoin wallets + +This document describes how to score the outcomes of transacting on Bitcoin, in particular privacy outcomes. This is the basis for automating various decisions delegated by the user to the wallet. + +🤖 It sets out the general approach to implementing the wallet's strategy, which is to generate decisions and evaluate them, and the requirements this places on the cost function. Unlike the protocols, which are normative, the strategy is a recommendation, and can't be enforced. + +## 🤖 Preliminaries {#preliminaries} + +Automating the decisions delegated to a wallet is an optimization problem, and every optimization problem has a cost function. + +A *pure strategy* is a complete plan: a sequence of actions leading from the current wallet state to one specific outcome, i.e. one path down the [decision tree](#decision-tree-structure). *The* cost function, the one this document defines, evaluates pure strategies. It is a sum of terms of three kinds: + +- objective costs, such as fees +- privacy liabilities +- payoffs from completing goals, such as making a payment + +Every term is a piecewise linear function of time, and is known to be either privacy related or not. A pure strategy is evaluated at a point in time by evaluating each of its terms at that time and taking their sum. + +The strategy is implemented by generating decisions and evaluating them. Tactics generate the decision tree from the wallet state. The evaluation is mostly defined in terms of pure strategies, because these are easier to make transparent: a sum of terms, each labelled as privacy related or not, and each a piecewise linear function of time. Pruning and the decision loop then turn these evaluations into the wallet's mixed strategy. + +The wallet doesn't simply follow the best pure strategy. If it did, an adversary able to predict the wallet's state could also predict its choices. Instead it plays a *mixed strategy*, a random choice among pure strategies. The [Mixed strategy](mixed_strategy.md) chapter recommends how to compose one. + +A cost function for the mixed strategy exists, but it is a more complicated mathematical object, which this document doesn't define or study. It only describes how the mixed strategy is played. + +## 🤖 Wallet states and actions {#wallet-states-and-actions} + +The input domain of the cost function is *wallet states*. A wallet state includes the wallet's confirmed and unconfirmed transactions, current observations and beliefs, policy parameters, and a queue of *intents*. + +Technically partial wallet states are permitted, since incomplete information about future transactions must still be evaluated. This is done under the assumption that the available information is a lower bound on the outcome. For example a co-spend proposal has a lower bound on the set of inputs in any transaction where it may be in effect. + +Intents can be on chain payments, i.e. a `TxOut` to be created, or more generally any unordered PSBT fragment. + +### Decision tree structure + +A wallet constructs a decision tree whose root is the current wallet state. Each edge is an available action, and each node is the predicted wallet state produced by the sequence of actions leading up to it from the root. + +Leaves are mutually exclusive outcomes under consideration. An action may create or modify a collaborative transaction, advance a coalition formation negotiation, or fall back to a unilateral transaction. When a transaction is confirmed the corresponding intents are removed from the queue. + +Actions include announcements and negotiation, not just the steps of transaction construction. For example: + +- broadcasting an [ownership proof](coalition_formation.md) for a coin +- updating a coin's listen advertisement to solicit co-spend proposals +- making a co-spend proposal naming specific coins, and choosing the payoff for each +- making a co-spend proposal naming a single coin, with a surplus and a subset sum density requirement, leaving the search over the order book to an aggregator +- accepting a co-spend proposal, or a coalition formation proposal +- adding auxiliary inputs and outputs to a committed transaction, and signing it + +How the tree is built is part of the strategy, and is described in the [Tactics](tactics.md) chapter. + +How the wallet chooses among the pure strategies in the tree, and when it acts, is described in the [Mixed strategy](mixed_strategy.md) chapter. + +## Coin selection with objective costs + +The coin selection problem in Bitcoin is that of deciding which of the unspent transaction outputs available to a wallet should be used when constructing a new transaction. Coin selection is constrained by the desired outcomes of constructing a transaction. The simplest example of such an outcome is when the user is intending to make an on-chain payment: a transaction which includes an output whose value is the payment amount, and whose `scriptPubKey` is determined by the receiver. The most basic constraint then is that the payment output is included, giving control over those funds to the receiver. + +Because confirmation is needed for payment finality, the feerate of a transaction is also constrained. For a transaction to be valid, the value of the new outputs must be covered by the value of the spent outputs, and the fees paid by a transaction consist of the difference between these sums. The feerate is a transaction's fees divided by its size. For timely confirmation the feerate must provide a strong enough incentive for miners to include the given transaction in their block templates, as compared to alternative transactions they might wish to include instead. + +With respect to some given feerate, the *effective value* of an unspent transaction output is its nominal value, minus the cost of the blockspace consumed by the input which spends it. Similarly, the *effective cost* of an output accounts not just for its nominal value, but also the cost of the block space required to create it. + +Sometimes it's possible to closely approximate the effective cost of a payment output as the sum of the effective values of a subset of the spendable coins. However, typically the smallest sum of effective values that is larger than the sum of the effective costs will be significantly larger. A *change* output with an effective cost equal to the excess balance is then created instead of overpaying in fees. + +Framed as an optimization problem, coin selection aims to minimize transaction costs while still achieving the desired outcomes (e.g. making payments). Since the decision space scales exponentially in the number of available UTXOs, a brute force search will in general be intractable, requiring an approach such as [branch and bound](https://bitcoin.stackexchange.com/questions/119919/how-does-the-branch-and-bound-coin-selection-algorithm-work). + +## Expectation and bracketing + +### Internalizing future costs + +The immediate costs of some action may not represent its long term consequences. Internalizing expectations of the future into the cost of an action makes optimization simpler, since decisions can be evaluated one step at a time. + +🤖 Abstractly, one might recursively consider all actions that may follow any particular state. An expected cost can be derived by first assigning a cost to each terminal state, then weighting it according to a probability distribution. Adding these costs to the cost of the actions which immediately precede the terminal states internalizes future expected costs, and this can be propagated all the way back to the immediately available actions. + +Unfortunately, enumerating every contingency like this, even if the depth is restricted, is not only intractable, but often hard to define. Assigning probabilities can also be tricky. Due to these challenges, in practice simplified models are instead used to internalize such future costs into the cost of the immediately available actions. Although this might not account for everything that may eventually happen, that isn't really a goal worth pursuing so long as relative comparisons between alternatives are made possible. + +### 🤖 Bracketed evaluation under incomplete information {#bracketed-evaluation-under-incomplete-information} + +During decision-making, states are evaluated with incomplete information, as a bracket between a best case and a worst case, described in the [Cost function structure](cost_function_structure.md#bracketing) chapter. An automated action is taken only when the cost-function evaluation predicts an improvement, accounting for the wallet's subjective balance, objective costs and the utility of completing payments. As information about other users' coins becomes available, the lower bound can improve. Once the transaction is fully constructed, the same cost function evaluates the complete state, including the other users' output values. The completed evaluation determines the liabilities and the accounting for privacy-budget expenditure. + +### Future cost of spending (Bitcoin Core's waste metric) + +At the time an output is created, the size of the input that will eventually spend it is already known (or an expected size in the case of P2TR outputs). This size is independent of whatever else happens in that transaction. Reliably predicting a feerate, on the other hand, is not possible, as that is a market prediction problem. + +While specific future feerates are inherently unpredictable, if at some point in time it's clear that a low feerate is sufficient for timely confirmation, then it is possible to reliably predict that at any point in the future the feerate is likely to be higher. When this is the case it makes sense to spend a larger set of potentially smaller outputs, consolidating their values, because although the total blockspace required to spend a set of outputs is fixed regardless of when each output is spent, the cost can be minimized if more of this blockspace is consumed at lower feerates. + +Optimizing these costs is the underlying motivation for the [*waste metric*](https://bitcoin.stackexchange.com/questions/113622/what-does-waste-metric-mean-in-the-context-of-coin-selection) used in Bitcoin Core's coin selection. This term in the cost function which governs coin selection internalizes an expected cost of spending a coin to the evaluation of the cost of its output. When the target feerate is lower than this predicted future feerate, this makes the evaluation of spending an input right now lower than this predicted future cost. + +A simplified version of the waste metric (omitting some terms) is to consider some expected future feerate as effectively the zero point, by subtracting it from the target feerate at the time of coin selection. When the target feerate is lower, this will be negative, which makes *larger* transactions seem cheaper than smaller ones. The rationale for rewarding larger transactions is that the total blockspace that will eventually be consumed spending all of the coins available in a wallet is essentially fixed, but what matters is simply *when* that blockspace is consumed, and at what feerate. During times of low demand for blockspace (and therefore low target feerates), coin selection will therefore tend to consolidate a fragmented wallet. When demand rises again, if coin selection must be done at the higher target feerate, since there would be fewer, higher value coins available on average, the expected transaction size at these higher target feerates will be lower, which in turn will result in lower overall spending on fees. The waste metric is only one of the terms of the cost function, and is included in the evaluation of every automated transaction. Spending coins together may also affect other terms, such as privacy liabilities, so whether such consolidation happens depends on how the waste metric weighs against these and against the urgency of any payments. + +### Cost of CPFP transactions + +Child-pays-for-parent (CPFP) transactions spend one or more outputs of transactions that have not yet been confirmed, and at a higher feerate than the unconfirmed transactions' average feerate. This gives miners an incentive to include the parent(s), as the more lucrative child transaction can only be confirmed after the parent(s). + +From the point of view of a wallet, spending unconfirmed outputs is therefore more costly in expectation, because to do so at a higher feerate requires paying for the parent transaction(s)' blockspace as well. + +Arguably this is already accounted for by the waste metric future feerate parameter, but a qualitative distinction is being made here because there is more uncertainty in predicting the payments a wallet is expected to make at any point in the indefinite future, as opposed to only what is due before some inflight transaction is expected to confirm. + +### Utility of payments + +For the purposes of this document a *payment* will mean a net transfer of funds between two parties. Transactions are a way of realizing payments, but a single transaction can perform multiple payments or even net settlement for multiparty transactions. + +An *intent* is a concrete representation of the goal of creating some output (or input, in which case the goal is the destruction of some unspent output) before some deadline. The deadline can refer to the transmission of a signed transaction to the recipient out of band, broadcasting the transaction, or its confirmation in a block. For simplicity, and without loss of generality, output creation intents will be assumed to correspond to payments but that isn't necessarily the case (for example funding a lightning channel). We will assume intents are made known to the wallet some time in advance of the deadline. + +🤖 The change in the balance of a wallet resulting from a transaction, negated, is its *objective cost*: positive when the balance decreases, and negative when it increases, for example when receiving a payment. In contrast, the utility obtained from a transaction confirming may include subjective terms as well. Subjective costs inherently depend on beliefs or preferences, and are the basis for any surplus created from transactions as any redistribution of on chain funds is necessarily zero sum. + +Reliably confirming transactions at the lowest possible feerate before the deadline of any payments it realizes is not feasible, because predicting future feerates is a market prediction problem. Attempting to confirm as close to the deadline as possible can incur additional costs due to the variability of fees, or risk missing the deadline. If payment deadlines are missed, the utility obtained from making the payments may be diminished. Some risk of missing the deadline or overpaying fees is always inherent. + +This perspective suggests that the same action performed at different times is in fact not the same action, but two different ones, which will have different costs. However, to keep things simple we will not consider actions-at-a-point-in-time separately, but rather each action's cost evaluation will output not just a single numerical value, but a function of time, and different actions can be compared across all of time. + +## Payment batching + +Confirming transactions at the earliest possible time (well in advance of the deadline) is sub-optimal as it precludes any possibilities of batching payments. However, before confirmation it is possible to replace transactions by double spending at least one of their spent outputs in a transaction which is more attractive to miners (which also diminishes the importance of introducing any CPFP liability). This is known as replace-by-fee (RBF), and multiple policies for allowing this, some defunct, have existed over the years. + +A reasonable strategy that utilizes RBF for batching is to simply broadcast a transaction which underpays fees as soon as a payment becomes known, and then replace the transaction with progressively higher feerate transactions, growing the batch of payments with each such replacement. This conserves blockspace: the blockspace increase of another payment is primarily just the cost of an additional output. If some subsequent transaction is much more urgent than inflight ones, then it of course can also be realized in a separate, higher feerate transaction, in order to avoid paying for the entire batch at the higher feerate. + +This batching strategy can reduce costs, minimizing the opportunity costs of the eager but naive strategy (successfully confirming before the deadline precludes RBF based batching) or the risk of missing deadlines in the lazier one. Unfortunately this RBF-eager strategy also leaks a lot more information about the payments made and the wallet making them than simply posting the full batch as late as possible (for example as discussed in [this paper](https://arxiv.org/pdf/2303.01012)). A lazy strategy will make the same batching possible without such leaks, at the cost of forgoing any low fee opportunities that may be available well in advance of the earliest deadline. + +## Privacy Liabilities + +Whether or not one should broadcast eagerly and then bump fees, or wait in order to limit how much information is revealed by fee bumping depends on whether the harms from the loss of privacy outweigh the expected savings from broadcasting earlier. + +Unilaterally spending more than one output reveals to the adversary, based on the *common input ownership* or *multi-input* heuristic, that they are likely to be owned by the same entity. More broadly, all transactions necessarily reveal which coins they spend, the total amount involved, the values of the inputs and outputs, script types used, and a number of *wallet fingerprints* such as the value of `nLockTime` or details of signature encoding. This information is useful for wallet clustering ([1](https://spiralbtc.substack.com/p/the-scroll-2-wallet-clustering-basics), [2](https://spiralbtc.substack.com/p/the-scroll-3-a-brief-history-of-wallet), [3](https://spiralbtc.substack.com/p/the-scroll-4-intersection-attacks)), a cornerstone of Bitcoin chain analysis and deanonymization. + +The adversary is anyone who might be attempting to deanonymize the user. This can be a third party or a counterparty. In some cases information linking several coins may already be known to the adversary. For example, suppose a customer makes one payment to a merchant in an on-chain transaction, creating a change output, and then eventually spends that change output to make another payment to the same merchant. If these payments are already linkable, for example because they are both associated with the same email address, then no further information is revealed to the merchant by spending a coin that it already knows belongs to that customer. + +On the other hand it may be the case that two payments are made by the same customer to the same merchant, but no information with which the merchant could link these payments is available. In such cases the appropriate behavior might be to deliberately avoid any coins linked to the previous payment when making the later one. + +The worst case for this kind of leakage, in terms of how much information is revealed in a single transaction, is when the entire wallet's balance is spent in a single transaction. This is problematic not just because it links all coins together but also because it reveals the wallet's total balance, potentially aiding in additional analysis (such as correlating this amount to past transactions that aren't unambiguously linked to it). + +Let's momentarily ignore both the severity of the harm of such privacy leaks (assume it's just some fixed penalty), as well as the risk, i.e. the probability that liquidating the entire wallet is necessary (for example when under duress, in response to a security incident, or when needing to make an urgent payment for an amount close to the available balance). What then determines the cost is how much information is leaked. Considering this potential contingency after every wallet state, and then internalizing the cost into the cost of the transaction which results in that state encodes the implicit goal of privacy enhancing transactions, which is to leave the wallet in a state where the harm of any such liquidation is reduced, because the information leaks are minimized. + +### Censorship risk + +On-chain privacy techniques in Bitcoin come in two flavors: overt or covert. Overt techniques add ambiguity in a way that is apparent, and therefore can be identified as privacy enhanced transactions (e.g. CoinJoin). Contrast this with covert techniques (e.g. CoinSwap), which aren't easily identifiable. + +Both overt and covert techniques carry censorship risk. For overt techniques this is inherent, as the use of the technique is self-evident, and exchanges that may regard this as a compliance risk (which incidentally is more often the case for fraudulent exchanges) are more likely to reject or even confiscate deposits that are linkable to such techniques. For covert techniques, although the technique itself doesn't flag a deposit, it may result in [counterfactual linking](collaborative_txn_privacy.md) of the deposit funds to coins that are deemed tainted. + + + +## Parameterizing the cost function according to user preferences + +The design space of a cost function for privacy has three main axes: improving privacy, minimizing delays, and economizing on cost, all of which trade off against each other. When considering each transaction independently, although there are 3 dimensions for optimization, there are only two degrees of freedom. Meaningfully improving privacy on Bitcoin requires interaction with others, which can inherently introduce delays, or it can require improving the ambiguity of the transaction structure with the goal of frustrating analysis, and this often requires utilizing more blockspace. The sooner this is needed, the higher the fees incurred. + +### Privacy sensitivity + +To quantify privacy, wallet software must include some kind of privacy metric. Metrics make it possible to measure progress, and to define stopping conditions for any privacy optimizations (which aren't costless). For example, an estimate of an anonymity set size of a coin might be one such metric. Developer provided default thresholds can allow non-expert users to choose a threshold appropriate for their threat model, on a per intent basis (distinguishing between sensitive payments and those that only require opportunistic privacy). + +The metrics discussed here will attempt to ascertain how well the payments of the user blend in with those of others. Due to the limitations of Bitcoin's consensus layer (cleartext amounts, overt spend graph), multiparty transactions are necessary in order to meaningfully resist clustering. Multiparty transactions are those which involve the actions of more than one user. Although there are other aspects to Bitcoin privacy, this framework is primarily concerned with on chain notions, which can be defined in terms of wallet clustering. + +#### Sybil resistance + +Complicating matters, since Bitcoin is permissionless it's not directly observable whether a transaction involves $n$ parties with non-trivial $n$ ($n > 2$) or not. Since only coins have identity, and there is no notion of accounts or users in the protocol, all an honest user knows definitively is which coins are under its own control vs. those that aren't. It's not possible, in general, to determine whether or not the coins that an honest user does not control are all controlled by a single entity or multiple separate ones. + +A *sybil* attack on a network or distributed system involves a single entity controlling many apparent identities, the closest analog of which are coins. As a component of a deanonymization attack, a sybil attack can be used to isolate the honest parties. If all actions other than those of the victim are visible to the adversary, a scenario known as an $n-1$ deanonymization attack, then the adversary is able to observe the victim's actions with full transparency. Unfortunately the only recourse for this kind of attack is to impose or at least account for the cost of such an attack. + +When any privacy metrics are interpreted, the implied cost to the adversary of doing an $n-1$ deanonymization attack, i.e. the cost of controlling the inputs to the metrics (note: not inputs as in spent coins, but in the sense of all information that is fed into an analysis being under adversarial control), should be factored into the weight of the interpretation of the metric. + +We might turn cluster analysis on its head, and as the defender attempt to detect such attacks heuristically. However, evading this only adds some overhead for the adversary, and this overhead may be very low in the case of covert techniques. + +Ideally whatever the cost is, it should exceed the value to the adversary obtained by deanonymization, deterring such attacks through incentives. However, in reality the economics for targeted vs. dragnet surveillance will vary, and costs, even liquidity costs, may be far from equilibrium, so it is very hard to say what level of cost will suffice. The value of surveillance for, say, advertising may be more or less limited by the victim's disposable income, whereas for targets like political dissidents, significant resources might be allocated by the attacker. Ultimately this is very subjective and depends on the threat model. + +What is possible to say is that this cost can be quantified concretely by accounting for the fees incurred by others in the construction of transactions which seem attractive and are used to support the analysis of some metric. With a discount rate, the age of a spent coin can be used to estimate a liquidity cost for the adversary, as in [fidelity bonds](https://gist.github.com/chris-belcher/87ebbcbb639686057a389acb9ab3e25b#cost-of-sybil-attacks). + +### Payment urgency + +As described in abstract terms above, a per intent deadline or confirmation target similar to the standard user experience for determining feerates can be used to control the time sensitivity of specific actions. + +🤖 More generally, every term of the cost function may depend on time. How this is modeled is described in the [Cost function structure](cost_function_structure.md#time-dependence) chapter. + +The privacy sensitivity of a transaction determines whether the preferred behavior is to execute a payment even if privacy is sacrificed as the deadline approaches, or whether it's better to miss the deadline or even forgo the transaction entirely if the payment cannot be made privately. + +🤖 This is determined by the shape of the intent's utility curve. If it plateaus or turns downwards before outweighing the privacy liabilities, the wallet may miss the deadline or forgo the payment. A curve that keeps rising can model a hard deadline by eventually outweighing those liabilities. + +### 🤖 Global privacy budget {#global-privacy-budget} + +Finally, a global (i.e. per wallet, not per intent or transaction) budget is used to normalize all metrics so that the costs of actions with different privacy outcomes are directly comparable. The budget has two parts: the *budget rate* $p$, a percentage chosen by the user, and the *remaining budget* $B$, an amount in satoshis. Only funds received at external addresses add to the remaining budget, which grows by $p$ times their value, and privacy-motivated expenses are deducted from it. + +This global budget limits overall spending for the purposes of privacy. The user consents to the wallet's behavior for discharging privacy liabilities and is willing to spend up to this budget to obtain it. This implies that the expected subjective harm of leaving those liabilities undischarged is at least as great as the subjective cost of spending the budget, accounting for downsides such as censorship risk or additional resources consumed. Accordingly, all privacy liabilities collectively reduce a new privacy-problematic coin's subjective value by the budget fraction of its nominal value. Each term evaluates a defined problem; evidence that the problem has been removed discharges the corresponding liability to 0. These are subjective valuations under the specified criteria, rather than guarantees of privacy. + +🤖 How the budget turns privacy metrics into amounts in satoshis, so that all terms can be summed, is described in the [Cost function structure](cost_function_structure.md#linear-combination) chapter. + +## Use in multiparty protocols + +In the context of a multiparty transaction construction, a fixed overhead of 10.5-12.5 vB per transaction incurs a cost that can be shared with others. Since this is substantially smaller than a typical input, the savings are arguably negligible. If a cross input signature aggregation soft fork is enabled then instead of a fixed overhead, a per input overhead can additionally be shared among participants, providing a much stronger incentive than the fast diminishing fixed overhead's savings. Such savings are limited, ultimately by consensus block size limits, and practically by policy, which limits transactions to 100KvB (though this limit can be overcome by use of multisig and pre-signed transaction trees). + +Subjective benefits, in particular those related to privacy metrics, can be more strongly positive sum. Since terms derived from privacy metrics are often concerned with data controlled by the other parties, this can be strongly positive sum as the actions of each user individually may benefit every other user, not just themselves, a quadratic number of opportunities to create a surplus. + +Unless parties wish to censor each other, they should at the very least be indifferent to the actions of the other users. This is important for liveness, since secure transactions generally require unanimous consent which presents an inherent challenge for liveness. Therefore it makes sense to have prior agreement to avoid any actions which may result in negative utility. + +For instance, suppose Alice stands to benefit from funding a lightning channel. In order to do this she needs to add the appropriate output, no different than a regular output, but on its own this is insufficient to be as valuable as a unilaterally controlled output: lightning channels require backout transactions signed by the other party to the channel, and secure presigned transactions require stable transaction IDs (no malleability). For this reason if some other party to the transaction chooses to add a non-SegWit input, this suddenly devalues Alice's proposed output, and she has a rational reason to avoid signing the resulting transaction. + +For this reason we require that any such requirements are specified upfront, and that all parties agree to them before accepting the [coalition formation proposal](coalition_formation.md). This must cover technical restrictions, such as the `nLockTime` required by inputs encumbered with `OP_CLTV`, since height-based and time-based locktimes are mutually exclusive, but also constraints on things like the feerate, the script types of inputs and outputs (and/or spend types for P2TR outputs), and the values of inputs, whether nominal values, for example to require some multiplicity of standard denominations, or effective values, which determine [subset sum densities](collaborative_txn_privacy.md). This agreement must also distribute the net allocation of virtual bytes or weight units in the transaction to the parties involved, ensuring that the total size does not overflow. + +With such a setup, it is reasonable to define honest parties as being indifferent to others' arbitrary actions. For this to be incentive compatible we must also demand that the cost function which governs the decisions made during the protocol execution is indeed monotonically decreasing in new information. Since the input domain of the cost function includes partial wallet states, lower bounds on the information contained within the transactions, such as a subset of the inputs or the outputs (unordered), can be evaluated as well. Monotonicity ensures that the subjective costs can only decrease as additional transaction data is revealed from the other parties, allowing decisions to be made with access to partial information. + +Note that this does allow the evaluation to change. For example, if one party's choice of inputs is already committed, and they then learn of the inputs of the other parties, this may change their evaluation of which set of outputs to add in the next stage of the protocol. Monotonicity ensures that this evaluation can only improve in the critical section of the protocol. + +🤖 This is a substantive restriction. Many sensible cost functions don't satisfy it, for example one that is averse to a certain kind of counterparty, and such cost functions aren't compatible with these protocols. It is required because transactions are signed with `SIGHASH_ALL`: if any party defects, all other parties need to renegotiate and retry transaction construction, which is costly, and defections can cascade. Monotonicity is therefore required for liveness guarantees to be incentive compatible. Byzantine parties may not respect it at all. + + + +🤖 Accepting a coalition formation proposal means agreeing to all compatible actions by all parties, effectively declaring that the wallet's cost function is monotone with respect to anything outside of the restrictions agreed to upfront. The protocols also exploit this to make the transaction construction state a join semilattice (see [concurrent PSBT construction](psbt-concurrent.md)). Both the state and the game theory are needed for transaction construction to succeed: safety is inherent in `SIGHASH_ALL`, but liveness is fragile to crash and byzantine faults. + +### 🤖 Commitment {#commitment} + +Co-spend proposals may be made or accepted in anticipation of a good outcome, but accepting a coalition formation proposal is binding: defecting has reputational costs, since other peers may discount the UTXOs of a party that fails to sign. Accepting a coalition formation proposal therefore commits the wallet to the sub-tree it belongs to, and requires that this sub-tree has at least $k$ acceptable leaves (see [Preliminaries](#preliminaries)), i.e. at least $k$ contingencies to select from for that transaction. These must remain acceptable for long enough that a run of the protocol can be expected to complete. If they are only briefly acceptable, then as that window closes, a payment whose deadline is about to be missed may have to be made unilaterally instead, which may in turn leave the remaining intents without any urgency, so that it's better to wait. + +Full RBF means that inputs can be double spent at will, so the inputs named in an accepted coalition formation proposal are bound to its transaction construction session, but not exclusively: the commitment is only to see the session through. + +The committed sub-tree typically has a fixed set of output intents, but some may be dropped, for example if a payment becomes urgent and the feerate of the CoinJoin is too low. Even if some outputs or auxiliary inputs are omitted, there should be at least $k$ options for decomposing the committed outputs, with different denominations under consideration. Change decomposition is the observable that an adversary able to predict the wallet's state could otherwise predict, if the cost function had no noise and simply optimized. This amounts to a recursive invariant of the committed sub-tree: at least $k$ options for every retained action, not just at its root. diff --git a/docs/overview.md b/docs/overview.md new file mode 100644 index 0000000..175f967 --- /dev/null +++ b/docs/overview.md @@ -0,0 +1,127 @@ +--- +type: Overview +title: Fungi protocol overview +description: Collaborative transaction construction, privacy, fault tolerance and coalition formation. +status: draft +stale_after: 2026-10-31T00:00:00Z +--- + +# Fungi protocol overview + +Fungi is a suite of protocols for collaborative Bitcoin transactions. Its goal is to support interactive payments and net settlement with counterparties, as well as decentralized, market-based CoinJoins with untrusted parties. + +While the protocols themselves support arbitrary transaction structures, obtaining privacy outcomes is a matter of participants acting in their own self-interest and cooperating with others to achieve the desired results. The [problem definition](./collaborative_txn_privacy.md) describes conditions for a transaction graph to preserve privacy on chain. These conditions are specified in terms of properties of the graph, both the transactions that form it and its overall structure. The repository also discusses the definition of a [cost function](./optimization_framework.md) for optimizing for this outcome. That said, the protocols for collaborative transactions summarized in this document are agnostic to the details of such a cost function. + +Depending on whether peers must be considered adversarial, and the underlying transport mechanisms, different variations of transaction construction are defined. These are the honest, semi-honest (also known as honest-but-curious) and Byzantine settings. + +In the honest setting, we assume peers can be trusted to follow the protocol and never leak any information apart from the final transaction (deliberately or otherwise). In the semi-honest setting we no longer trust peers with privacy; privacy-preserving transports are used to hide the attribution of different transaction fragments. In the Byzantine setting fault tolerance means tolerating arbitrary and potentially malicious behavior from peers, to the extent possible. + +These protocols are designed to allow interactive payments with net settlement. While net settlement on its own is beneficial for privacy in some ways, it does not adequately obscure the community structure that is inherent in real-world economic networks. Randomizing peer selection is one of the requirements for building CoinJoin graphs with the desired privacy enhancing properties. + +In order to randomize peer selection, the last component needed is the [coalition formation](./coalition_formation.md) protocol. It provides a market-based mechanism to allow mutually distrusting strangers to anonymously start an instance of the Byzantine fault tolerant (BFT) transaction construction protocol. + +## PSBT concurrency + +[BIP 174](https://bips.dev/174/) defines Partially Signed Bitcoin Transactions (PSBTs), which allow a device with UTXO data to prepare a transaction for signing on a separate signing device. Signatures can be collected in any order, so multiple signing devices can be used, with a well-defined procedure for how to assemble everything into a signed transaction that can be broadcast. + +While BIP 174 has been used in several collaborative transaction protocols, as specified it can only represent a fully formed unsigned transaction. [BIP 370](https://bips.dev/370/) extends the format to explicitly allow the input and output lists to be modifiable. The fact that these lists are ordered presents a challenge for concurrent transaction construction. + +The first component of the Fungi protocol suite is the proposed [Concurrent PSBT specification](./psbt-concurrent.md). It treats these collections as unordered sets rather than lists, allowing fragments to be combined regardless of arrival order, not just when collecting signatures but also when authoring the transaction. A consistent ordering is established before signing. + +In the "sneakernet" setting participants can pass around a single PSBT file, editing it in turn before handing it to the next party, but with concurrent PSBTs they can also concurrently modify different copies and merge them as well. And anything in between. Because divergent copies can be merged into one coherent transaction, the details of communication don't need to be specified; it could be a shared directory on a server, or one or more USB sticks, perhaps files shared over email, or some combination of the above. + +## Consistency, safety and liveness + +Consistency has to do not just with peers synchronizing their states, but also detecting when they have been successfully synchronized. Two properties of distributed systems related to this are safety and liveness: safety excludes unacceptable outcomes; liveness concerns whether the protocol eventually completes.[^safety-liveness] + +Because transactions are subject to the safety guarantees of the Bitcoin protocol, collaborative transaction construction can more or less take it for granted. In all transaction construction variants the consistency requirement is agreeing on the exact unsigned transaction. We assume `SIGHASH_ALL`, which means that a signature by an input only authorizes that exact transaction, with its full list of inputs and outputs. In order to combine the signatures and obtain a fully valid transaction, all of the signatures must be made against the same transaction data. + +Because even in the honest setting spending authority is never delegated and signing is unanimous, safety violations (sending money to an unintended destination) are precluded. The unfortunate cost of such unconditional theft resistance is that any input owner can effectively veto a transaction, disrupting the liveness property even if all the other parties agree to proceed with it. + +As a result, liveness is inherently brittle. Consistency is a liveness requirement, not a safety requirement, and all of the mechanisms described here are primarily concerned with enhancing liveness without breaking the privacy assurances made to honest participants. + +## Interactive transaction construction in the honest setting + +All of the protocols described here, starting with this one, assume interactivity. The PSBT concurrency spec describes how to merge states without specifying how peers communicate, whereas the protocols prescribe specific messages to be exchanged between peers. Some of these messages correspond to unordered PSBT fragments, and can merged according the concurrent PSBT specification. + +An *honest* participant is one that complies with the protocol. Faulty peers may deviate from the protocol, by being unresponsive or potentially with arbitrary, possibly malicious behavior. In the honest setting we assume that the only kind of fault is being unresponsive. Not only that, peers are additionally expected to keep confidential all of the information pertaining to the protocol's execution. + +🤖 Peers exchange payment details with their counterparties, and send transaction contributions to the group as a whole. The [abstract transport interfaces](transport-interfaces.md) describe this communication as messages on send and receive channels, independently of the transport: authenticated peer to peer channels, and broadcast to the group built from them by [gossip](channels.md). + +The honest setting accommodates geographically separated co-signers within a multisig wallet, coordination between separately managed funds within an organization, collaborative batching, and interactive payments. Before signing, every participant checks this transaction, ensuring their funds end up in the destinations they intended. Although the model assumes no malicious edits to the transaction, performing these checks is what enforces safety. Doing this ensures that if the assumption does not hold, the system still fails closed, and any faults that aren't explicitly accounted for in the model will only lead to denial of service, not loss of funds. Needless to say, this check also applies to the more adversarial settings described below. + +## Net settlement + +One of the motivating use cases for interactive transaction construction is more efficient and private on-chain payments. Several parties can batch arbitrarily many payments into one transaction. Each participant's inputs and outputs express only the net difference. Individual payment amounts need not appear on chain. + +Net settlement adds both safety and liveness considerations. Before signing, a participant must know that its funds reach the intended destinations. It can check outputs returning funds to itself directly; for a payment, it needs the payee to confirm that the transaction satisfies their agreement. This can add sequential dependencies between peers. Within each payment cycle at least one party will receive as much as it sends or more, and can therefore safely initiate a cascade of confirmations. See the [concurrent PSBT specification](./psbt-concurrent.md#confirmation-of-successful-payment-prior-to-signing) for additional details. + +## Fault tolerance + +Because of the unanimity condition, a peer which is offline and not able to sign its inputs essentially vetoes the transaction even if not intentionally. Transaction construction therefore naturally has two tracks: the *optimistic track*, which requires unanimity, and the *recovery track*, which facilitates restarting transaction construction with a subset of participants. Recovery is a permissioned instance of the coalition formation protocol described in more detail in the last section of this overview. + +🤖 Liveness is therefore inherently brittle and sensitive to delays. Deciding when a peer is unresponsive depends on what can be assumed about message delivery. The [recovery track](recovery-track.md#fault-tolerance-under-different-communication-models) describes the asynchronous, synchronous and partially synchronous communication models, and what each allows. + +## Transaction construction in the semi-honest setting + +In the semi-honest setting, participants are still assumed to cooperate, but are no longer trusted with privacy. Instead we assume the adversary can see their observations, regardless of whether this information is leaked accidentally or deliberately shared.[^honest-but-curious] + +🤖 Preserving privacy therefore requires anonymous broadcast to the group, while payment messages need only authenticate the receiver. The [abstract transport interfaces](transport-interfaces.md#unlinkability) and [contacts](contacts.md) chapters describe these requirements. + +The privacy objective is to avoid revealing anything more than what is inherent in the transaction data to the world, and the minimal payment details to counterparties. Anonymous communication is a necessary but insufficient requirement for this; it does not prevent inference from amounts or transaction structure, nor from the wider transaction graph. The on-chain limitations described in the [problem definition](./collaborative_txn_privacy.md) still apply. + +This setting is inherently more brittle, because when disruptive messages are shared anonymously not only is it unclear how to recover, in general it isn't possible to tell apart the disruptive messages from the honest ones without some additional mechanism. + +## Byzantine fault tolerant transaction construction + +The semi-honest setting assumes that participants claim only what they are entitled to in outputs, and cooperate until the transaction is successfully constructed and signed. While crash faults can be detected depending on the communication model, there are of course many other ways participants can be disruptive, especially if they have malicious goals like preventing the other parties from transacting.[^byzantine-generals] A Byzantine fault tolerant (BFT) protocol is one that is resilient to such disruption. + +Participation is voluntary, and no party can be compelled to sign. The protocol therefore operates in the non-cooperative game-theoretic setting: any agreement to transact or sign cannot be binding, and must be self-enforcing through incentives in order to have any bearing. We therefore additionally define an honest participant as one which intends to complete the protocol and sign, regardless of which permitted actions the other honest participants choose to take. The agreed conditions must preserve that incentive throughout construction; the coalition formation protocol, discussed at the end of this overview, provides a mechanism for negotiating those conditions and aligning incentives for cooperation. For now we will simply assume that the honest users' incentives are already aligned when transaction construction commences. + +Under the rules of the semi-honest setting a malicious participant might attempt to overspend, causing the combined transaction to be invalid even if signatures are given for all inputs. A malicious peer might also equivocate: give conflicting accounts of its actions to different peers. Or it might simply withhold a signature, causing delays. In the Byzantine setting the honest peers must be resilient to such disruption. This means ensuring flood protection and fairness. + +### Optimistic transaction construction + +The first problem is to establish that transaction fragments are valid without attributing them to specific participants. Validity means that the cost of an output is covered by input funds without double spending. Validity can be proven using zero-knowledge proofs, but this is costly, so we would like to avoid it where possible. + +Due to the unanimity condition even in the Byzantine setting, successful termination requires that all participants in a particular transaction construction session comply with the protocol, which includes being responsive. When this happens to be the case, the optimistic approach is to let everything proceed exactly as in the semi-honest setting: Participants anonymously add their fragment, and once everyone acknowledges the same balanced transaction they can simply sign. The Byzantine fault-tolerant variant of Fungi is therefore designed to recover liveness by identifying at least one input controlled by a faulty peer, and then attempting transaction construction again with the faulty inputs excluded. Once all faulty participants have been excluded the honest participants will be able to successfully carry out transaction construction. + +### Validity proofs + +The purpose of validity proofs is to restore the possibility of completion by preventing the same funds from being claimed more than once. The proofs establish that outputs and fee contributions are covered by input funds, including any funds that originate from payments between participants. They must accomplish this *without* sacrificing privacy, which is why they must be zero-knowledge proofs. They do not replace each participant's final approval, nor can they compel any participant into providing the remaining proofs or signatures. They ensure that honest, responsive participants can successfully add all of their intended inputs and outputs to the shared state without obstruction. + +A widely circulated misconception is that validity proofs in such protocols, due to the use of zero knowledge somehow themselves are a source of privacy. This is false. All they can do is enforce validity, and if done correctly, they can enforce this without requiring privacy to be destroyed. + +🤖 [Transaction construction](transaction-construction.md#validity-proofs) describes when proving is required in the optimistic phase, and why the proofs remove any reason for honest participants to withhold their signatures. + +### Consistency, liveness and termination in the presence of Byzantine faults + +🤖 Byzantine faults take different forms, and each is handled differently. An invalid transaction output, one that overspends, is excluded by validity proofs, which reduce it to an omission fault. An equivocated block, two conflicting blocks signed by one validator, exposes that validator's key, which serves as [compact evidence](block-dag.md#nonce-commitments-and-compact-equivocation-evidence) against its coin. Together, these leave delay as the effective attack on liveness: withholding messages, and above all withholding a signature at the end, which is maximally disruptive. + +🤖 Since successful termination requires unanimity, a majority agreeing is not enough. Instead, peers agree on the available evidence, such as which inputs' signatures are missing, and recover by excluding those inputs in another attempt. The [recovery track](recovery-track.md#consistency-liveness-and-termination-in-the-presence-of-byzantine-faults) describes this reasoning, and [branched execution](recovery-track.md#fault-tolerance-via-branched-execution) how recovery attempts proceed alongside the original one. + +## Synchronizing protocol state + +🤖 Peers synchronize protocol state using a [block DAG](block-dag.md#synchronizing-protocol-state). It is a special case of Byzantine eventual consistency, narrowed in steps: validator blocks with cordial parent requirements, a threshold for each track, one validator taking on the collection work, and optional TEE attestations. The same structure therefore accommodates several communication models and trust assumptions, to suit a variety of client capabilities and circumstances. + +🤖 Two things distinguish this from typical DAG consensus, including protocols that switch between modes or tracks. First, the optimistic track requires unanimity, not a quorum. Second, the optimistic and recovery tracks may race, and different sessions may attempt to spend the same inputs. This can't be prevented in a permissionless setting, and it is useful for replace-by-fee (RBF). Racing is not a safety violation, because Bitcoin itself resolves conflicts between competing transactions. In consensus protocols, by contrast, every mode or track must agree on a single log. + +## Coalition formation + +Until now we have assumed an initial set of participants, some of which will be removed in new branches of the protocol as these are spun off in response to failures. We have not discussed how this initial set of participants is formed. The honest and semi-honest settings imply some degree of trust, which means such groups can form out of band. + +The Byzantine setting, on the other hand, is designed to facilitate transacting with potentially malicious, ideally randomly selected peers, because as discussed in the [problem definition](collaborative_txn_privacy.md) document, such randomness is required for privacy guarantees to be robust, but this still depends on the initial set of participants being defined. For this purpose we define a coalition formation protocol, and that comes with its own set of challenges, first among which is that it operates in the permissionless setting. + +The [coalition formation](./coalition_formation.md) protocol is designed to allow mutually distrusting strangers to bootstrap transaction construction using a market-based mechanism. + +🤖 Agreements between strangers can't be binding without a confirmed transaction, so it operates in the non-cooperative setting, and aligns incentives by redistributing the surplus from collaboration as sats. The [background](coalition_formation.md#hedonic-games-and-games-with-transferable-utility) explains why. + +This is exactly the mechanism that the coalition formation protocol attempts to build: co-spend proposals are anonymous and confidential proposals, each of which is a bundle of bilateral agreements between the proposer and the owners of the other UTXOs listed in the proposal. The distinguishing feature of co-spend proposals is that they can be aggregated together, which generalizes a JoinMarket-like fee mechanism: it allows multiple "takers" to pay a single "maker" as a kind of group buy, as well as multiple independent "makers", all in the same transaction. This generality means that the distinction between taker and maker is removed; any participant can play both roles in a single transaction, depending on the co-spend proposals it makes or accepts. + +Coalition formation proposals bundle together a collection of co-spend proposals, each of which has been unanimously accepted. Unanimous acceptance of a coalition formation proposal by the owners of all inputs named in all proposals kicks off the permissioned transaction construction with an initial set of inputs, and the terms of the aggregated co-spend proposals in effect. The aggregator role is undertaken by peers proposing coalition formation proposals. + +[^safety-liveness]: B. Alpern and F. B. Schneider, [*Defining Liveness*](https://www.cs.cornell.edu/fbs/publications/85-650.pdf) (1985). Formal definitions of safety and liveness, and their decomposition of system properties. + +[^honest-but-curious]: A. Paverd, A. Martin and I. Brown, [*Modelling and Automatically Analysing Privacy Properties for Honest-but-Curious Adversaries*](https://ajpaverd.org/publications/casper-privacy-report.pdf). Section II-A defines an honest-but-curious participant as following the protocol while attempting to infer all possible information from legitimately received messages; the paper studies undetectability and unlinkability. + +[^byzantine-generals]: L. Lamport, R. Shostak and M. Pease, [*The Byzantine Generals Problem*](https://lamport.azurewebsites.net/pubs/byz.pdf) (1982). The foundational treatment of agreement in the presence of arbitrary faults, including conflicting messages sent to different participants. diff --git a/docs/privacy_metrics.md b/docs/privacy_metrics.md new file mode 100644 index 0000000..234123e --- /dev/null +++ b/docs/privacy_metrics.md @@ -0,0 +1,14 @@ +--- +type: concept +title: Privacy metrics +status: draft +stale_after: 2026-11-09T00:00:00Z +--- + +# 🤖 Privacy metrics + +Measures computed from public data, which the [privacy liability terms](cost_function_concrete.md) take as input. Unlike the terms, they don't depend on the wallet's threat model or preferences. + +- [Order book size estimation](sybil_resistance_index.md): how many candidate coins a transaction's inputs were selected from. +- [Subset sum density](subset_sum_density.md): how many subsets of a multiset of values sum into a target interval. +- [Counterfactual paths](cost_function_counterfactual_paths.md): how many times an amount could have travelled from a source coin to sink coins, along disjoint counterfactual paths. diff --git a/docs/protocol-messages.md b/docs/protocol-messages.md new file mode 100644 index 0000000..9ff512c --- /dev/null +++ b/docs/protocol-messages.md @@ -0,0 +1,310 @@ +--- +type: Specification +title: Protocol messages +description: The messages peers exchange, who sends them, when, and what each requires of its channel. +status: draft +stale_after: 2027-04-22T00:00:00Z +--- + + + +# 🤖 Protocol messages + +## Scope and status + +This chapter lists the messages peers exchange in the Fungi protocol suite. For each message it says who sends it, to whom, in which setting, what it carries, and what the channel carrying it must provide. + +It is a draft. Wire encodings, field sizes and signature profiles are not specified yet. Sizes below are orders of magnitude. Each section ends with its open questions. + +The messages fall into these groups: + +| Group | Purpose | Settings | +| --- | --- | --- | +| [Peer introduction](#peer-introduction) | Learn and label peers out of band | honest, semi-honest | +| [Gossip](#gossip) | Disseminate objects within a namespace | all | +| [Sets](#sets) | Commit to, list and reconcile sets of objects | all | +| [Public gossip](#public-gossip) | Order book for coalition formation | Byzantine | +| [Negotiation](#negotiation) | Bilateral co-spend and coalition proposals | Byzantine | +| [Session initialization](#session-initialization) | Start a construction session | all | +| [Transaction construction](#transaction-construction) | Build the transaction | all | +| [Interactive payments](#interactive-payments) | Grant funds and confirm payments | honest, semi-honest | +| [Blocks](#blocks) | Synchronize state and signal phase changes | semi-honest, Byzantine | + +## Channel requirements + +Channels are described by their properties, not by a transport. Choosing a transport that has these properties belongs to another layer. + +| Property | Values | Interface | +| --- | --- | --- | +| Direction | send, receive, or both | `SendChannel`, `RecvChannel`, `Bidirectional` | +| Delivery mode | one peer, or broadcast | `PeerChannel`, `BroadcastChannel` | +| Unlinkability | per channel, or per message | `UnlinkableMessageChannel` | +| Delivery guarantees | reliable or unreliable | | +| Timing | asynchronous or synchronous | | +| Metadata hiding | hides metadata, or not | | + +Delivery guarantees, timing and metadata hiding are tags: properties declared about a channel. + +Metadata hiding is always with respect to the initiator: the sender, or the side that connects on a stream. The responder is always identified, by its peer ID or its address. + +An unlinkable channel used for one message at a time yields unlinkable messages, with caveats. For example, an implementation that reuses circuits can leak timing metadata. + +Every message type states explicitly which channels are appropriate for it. Two are specified so far: + +| Messages | Direction | Delivery mode | Unlinkability | Delivery | Metadata hiding | Authentication | +| --- | --- | --- | --- | --- | --- | --- | +| [Transaction construction](#transaction-construction), semi-honest and Byzantine | send | broadcast | per message | reliable | required | — | +| [Interactive payments](#interactive-payments) | send and receive | peer | either | reliable | — | the payer authenticates the payee; the payee may or may not authenticate the payer | + +Open questions: + +- What do gossip, set and public gossip messages require of their channels? +- What do transaction construction messages require in the honest setting? + +## Peer introduction + +Honest and semi-honest settings only. + +A user adds a peer ID out of band, with one of four trust levels: + +| Trust level | Meaning | +| --- | --- | +| self | the user's own devices | +| trusted | trusted with privacy and liveness, e.g. in the same organization | +| semi-trusted | trusted with liveness | +| untrusted | the peer ID is stored and labeled, but not used | + +Open questions: + +- Should there be an introducer role, for self, trusted and semi-trusted peers, that may add peers at or below its own trust level? + +## Gossip + +Gossip always happens within a namespace, also called a topic. + +Some namespaces are ephemeral. Their name is derived from a shared secret using a tagged hash. Some are well known, such as the version 1 public order book. Co-spend proposals are namespaced by a Bitcoin block hash. If an object's ID is derived from a namespace that includes a block hash, the ID can be short. + +### Minimal gossip + +These three messages suffice in the honest setting: + +| Message | Contents | Notes | +| --- | --- | --- | +| announce | object hash | throttled, or suppressed by [set reconciliation](#set-reconciliation) | +| pull | object hash | requests an announced object | +| push | object | solicited: answers a pull | + +🤖 Small messages are pushed eagerly to neighbors. A block is pushed as just its header, expecting the receiver to already know its Merkle tree. + +🤖 After an anonymous submission enters the broadcast domain, peers disseminate it by gossip or set reconciliation. Anonymous submission does not replace dissemination. + +### Unsolicited push + +The semi-honest and Byzantine settings add one message: + +| Message | Contents | Notes | +| --- | --- | --- | +| push (unsolicited) | object | used for anonymous broadcast | + +A peer receiving a new object by unsolicited push forwards it by push to one randomly selected peer, and announces it to its other peers. + +Open questions: + +- How to scope ephemeral namespaces: by shard, by time, or by number of messages. + +## Sets + +Every message carries a state commitment. It includes the Merkle roots of the sender's mutable sets, its height and its set sizes. + +### Immutable sets + +An immutable set is referenced by its Merkle root. Sets are sparse Merkle trees, in the style of Libra's. A block commits to two immutable sets: its parents and its messages. + +### Mutable sets + +A mutable set is tracked as a sequence of Merkle roots. A peer has these: + +| Set | Monotone | +| --- | --- | +| roots: the highest blocks, and the messages in no block | its closure is; the set itself is not | +| all blocks known to the peer | yes | +| blocks known to the peer at a given height | yes | +| all messages in blocks known to the peer | yes | + +Fetching an ever-growing collection of sets is a resource exhaustion risk. Blocks are needed for progress, and are rate limited by cordiality. A dishonest majority can still flood. + +### Set listing + +| Message | Contents | Reply | +| --- | --- | --- | +| pull | Merkle root | its preimage | +| list | Merkle root | all of its leaves | + +Leaves here are hashes, not preimages. Listing all leaves lets the receiver recompute the root. + +### Set reconciliation + +Two methods are candidates: + +- **Range based.** List to a given depth, with clamping. +- **RIBLT.** A stream of rateless coded symbols for a set. + +For mutable sets, randomize the hash and restart the stream on each new item. Reply to a range based request with the children, then stream RIBLT data. + +The RIBLT cells need a multiset hash. Elliptic curve multiset hash (ECMH) candidates are: + +- GLS254; +- a GLS254 analogue with m = 61 or m = 67, where complete formulae should hold; +- the curve25519 ECMH in fastcrypto; +- secp256k1. + +Open questions: + +- Can only the latest root of each mutable set be queried? +- Should listing to a given depth return the intermediate nodes? +- Should a range based reply jump ahead, up to some listing size, instead of returning only the children? How does range based reconciliation apply to mutable sets? +- Is range based reconciliation only for immutable sets, or throttled for mutable ones? +- Should immutable sets use a hybrid, interspersing RIBLT with range based reconciliation? +- Can reconciliation data be carried in padding and in announce messages? + +## Public gossip + +Public gossip uses a well known namespace. These objects form the order book for [coalition formation](coalition_formation.md). + +| Object | Contents | Flood protection | +| --- | --- | --- | +| ownership proof | BIP 322 proof for a UTXO, committing to its online key, a validity interval and a block hash | proof hash below a threshold; replaces higher hashes for the same UTXO | +| UTXO directory entry | ownership proof, prevout or previous transaction, listen advertisements | — | +| listen advertisement | channel to reach the owner, constraints on proposals, willingness to be a validator, signed by the online key | signature hash, as for ownership proofs | +| co-spend proposal, unanimously accepted | see [negotiation](#negotiation) | one MuSig2 signature per proposal | +| co-spend proposal, partially accepted | opt-in only | time dependent key images | +| coalition proposal | see [negotiation](#negotiation) | signature hash of the aggregator's key | + +Willingness to be a validator is one of: demands it, opts in at the aggregator's discretion, or declines. + +## Negotiation + +Byzantine setting. These messages go over the channel named in the recipient's listen advertisement, or are gossiped as partial proposals where peers opt in. + +| Message | From | To | Contents | +| --- | --- | --- | --- | +| co-spend proposal | proposer | each named UTXO owner | outpoints, conditions, ownership proof commitments, one adjustment commitment per UTXO with range proofs, surplus and balance proof, expiry, optional conflict hints, the opening of the recipient's adjustment | +| acceptance | each owner | involved peers | a linkable ring signature by its online key | +| MuSig2 nonces and partial signatures | each owner | involved peers | turn a unanimously accepted proposal into a fully accepted one | +| coalition proposal | aggregator | every implicated owner | fully accepted co-spend proposals, concrete parameters, adjustment vector, protocol version, committed listen advertisements naming the validators | +| coalition acceptance | each owner | involved peers | a signature by its online key | + +In the semi-honest setting the ring signatures can be skipped. Owners then negotiate MuSig2 directly. + +## Session initialization + +| Setting | How a session starts | +| --- | --- | +| honest, semi-honest | a peer invites others to a random gossip topic | +| Byzantine | the gossip topic is the hash of the coalition formation proposal, including secret data encrypted to all participants | + +## Transaction construction + +These messages are gossiped to the session's topic. Transaction contributions project into unordered PSBT state and combine according to [concurrent PSBT construction](psbt-concurrent.md). In the Byzantine setting, the wire format consists of specified protocol messages, rather than arbitrary PSBTs. Honest and semi-honest construction can tolerate PSBT extensions; extensions in the Byzantine setting must be specified as protocol extensions. + +In the semi-honest and Byzantine settings they need a send channel with unlinkable messages, reliable delivery and broadcast addressing. Outputs in particular must always be message-unlinkable and hide metadata. + +| Message | Contents | Size | Settings | +| --- | --- | --- | --- | +| initialize | session parameters | — | all | +| add input | input with prevout data | hundreds of bytes | all | +| add output | output with its unique ID | hundreds of bytes | all | +| add fee contribution | explicit fee contribution | tens of bytes | all | +| issue from initial input | validity proof | several KiB | Byzantine | +| issue from auxiliary input | validity proof | several KiB | Byzantine | +| redeem | validity proof | several KiB | Byzantine | +| sign | signatures for one input | tens of bytes, more in the Byzantine setting | all | + +### Initialize + +Sets up the session parameters. The sort seed is the transcript hash: the Merkle set commitment of the accepted construction messages at the agreed state before signing, including the applicable proofs. Later input signatures and acknowledgement-only blocks do not change this seed. Concurrent PSBT construction allows this by setting `PSBT_GLOBAL_SORT_DETERMINISTIC` and leaving `PSBT_GLOBAL_SORT_SEED` unset, so each replica supplies the seed when it orders the transaction. + +### Add input + +An input map with its prevout data. In the Byzantine setting, initial inputs are named by the coalition formation proposal, so only auxiliary inputs carry prevout data. The message also carries: + +- an ownership proof committing to an online key; +- a signature by that online key on the message, committing to the session ID or gossip topic. + +### Add output + +An output contribution, which projects into a PSBT output map. Its unique ID becomes `PSBT_OUT_UNIQUE_ID`, so adding it twice is idempotent, while two equal outputs added separately stay distinct. + +🤖 In the optimistic phases, each admitted output has an amount of at least 1 sat, as required by the [construction rules](transaction-construction.md#validity-proofs). + +### Add fee contribution + +A 16 byte unique ID and an amount, which project into a `PSBT_GLOBAL_EXPLICIT_FEE_CONTRIBUTION` entry. Fee contributions let peers account for fees exactly. + +🤖 In the optimistic phases, each admitted fee contribution accounts for at least 1 sat. The overflow signal has the separate meaning described [below](#phase-change-signals). + +### Issue and redeem + +Byzantine setting only. These messages carry validity proofs. Issuance is from initial inputs or from auxiliary inputs. Their contents depend on the validity proof construction, which is specified separately. + +### Sign + +The signer first converts the PSBT to an ordered one, then signs with `SIGHASH_ALL`. A signature is tens of bytes. In the Byzantine setting the message can be larger, bounded by the size of the input's ownership proof. + +Signers differ in how they can be used: + +| Signer | Behavior | +| --- | --- | +| hot key | signs automatically, any number of times | +| manual | the user approves each signature | +| limited | e.g. a hardware security module, or a virtual one | + +## Interactive payments + +Messages to a designated peer, the counterparty of a payment: + +| Message | From | To | Meaning | +| --- | --- | --- | --- | +| grant | payer | payee | grants n sats of the payer's funds to the payee | +| confirm | payee | payer | confirms the committed state the payer's signature depends on | + +The [concurrent PSBT specification](psbt-concurrent.md#confirmation-of-successful-payment-prior-to-signing) defines what is confirmed and in what order, including how cycles are broken by net receivers. It is concerned with state only. These messages carry that state between the counterparties. + +These messages need send and receive channels with reliable delivery and peer addressing. They may be linkable or unlinkable. The payer must authenticate the payee. Whether the payee authenticates the payer depends on the payment; game theory suggests it shouldn't. + +Interactive payments belong to the honest or semi-honest threat model, not the Byzantine one. They can still take place within a broader Byzantine session. + +## Blocks + +Blocks provide consistency and synchronization, in the style of a blocklace. They are used in the semi-honest and Byzantine settings. + +A block contains: + +- the Merkle set commitment of its parent blocks; +- the Merkle set commitment of the gossiped transaction construction messages it includes; +- its parent block by the same node; +- the nonce point R its successor will be signed with. + +A block is signed with the nonce point committed in its own-node parent. + +| Setting | Signing key | +| --- | --- | +| Byzantine | the UTXO's online key | +| semi-honest | an ephemeral key, for simplicity, though the model doesn't need it | + +### Phase change signals + +Blocks also signal phase changes: + +| Signal | Effect | +| --- | --- | +| inputs fixed | clears the inputs modifiable flag | +| overflow | acts as a single fee contribution with ID "" and amount `MAX_MONEY`, the top of the lattice | +| outputs fixed | clears the outputs modifiable flag and sorts the transaction | +| initial input issuance | issuance from initial inputs | +| auxiliary input issuance | issuance from auxiliary inputs | +| outputs proven | all outputs are proven, and invalid outputs pruned | + +Open questions: + +- In the semi-honest setting, can additional validators just join? If not, how is initialization synchronized? diff --git a/docs/psbt-concurrent.md b/docs/psbt-concurrent.md index 180e685..fd7c76c 100644 --- a/docs/psbt-concurrent.md +++ b/docs/psbt-concurrent.md @@ -1,5 +1,5 @@ --- -type: Stub +type: BIP Draft title: Concurrent PSBT Construction status: draft stale_after: 2027-04-15T00:00:00Z @@ -7,4 +7,277 @@ stale_after: 2027-04-15T00:00:00Z # Concurrent PSBT Construction -This chapter is under review in [#16](https://github.com/fungi-protocol/docs/pull/16). Its draft is on [the pull request's branch](https://github.com/fungi-protocol/docs/blob/concurrent-psbt/psbt-concurrent.md). +## Abstract + +New fields and rules for combining PSBTs in a distributed setting. This provides an alternative to the BIP 370 constructor role that is less sensitive to order of operations and therefore more amenable to concurrency, which reduces the coordination required for collaborative transaction construction. + +## Motivation + +BIP 174 defines *Combiner* functionality. Its purpose is to integrate information add by either the *Updater* or *Signer* roles to divergent copies of a PSBT. According to the specification the combiner is intended for for PSBTs whose underlying unsigned transactions are identical, i.e. it is restricted to the *Updater* and *Signer* roles. + +BIP 370 introduced a *Constructor* role, which allows signalling that the inputs or outputs of a PSBT are modifiable. Arbitrary mutation of the inputs and outputs is then allowed, but this assumes such state updates are done sequentially. The combiner role is mostly unchanged in BIP 370, and is restricted to only allow combining fields of PSBTs which spend and create the same outputs, and in the same order. This facilitates aggregating signatures from multiple parties in any order, but has limited usefulness during the construction of the PSBT. + +In a distributed system it is easier to deliver messages without guaranteeing the order of delivery is consistent across nodes. Agreement on the set of outputs to spend and a set of outputs to create is sufficient for constructing a transaction, it isn't necessary to agree on the order in which they were added. This document defines an order insensitive merging procedure which generalizes the *Combiner* role to non-identical modifiable PSBTs which may still overlap in some of their data. To terminate concurrent transaction construction, a consistent ordering procedure is also defined for producing a a consistent PSBT which can subsequently be manipulated using the normal BIP 174 roles. + +## Specification + +TODO diagram for the combined state machine, indicate when downconversion (to v2 or v0) can happen + + creator -> constructor -> constructor (bip 370) -> updater -> signer -> combiner -> finalizer -> extractor + +TODO discuss scrubbing after signer and before combiner + +The new field types for distributed PSBT construction are as follows: + +### New global types + +| Name | `keytype` | `keydata` | `keydata` Description | `valuedata` | `valuedata` Description | +| --- | --- | --- | --- | --- | --- | +| Transaction Unordered Flag | `PSBT_GLOBAL_TX_UNORDERED = TBD` | None | No key data | `<8-bit uint>` | If present, must be set to a value `0x03` to indicate inputs and outputs are unordered. | +| Sort Seed | `PSBT_GLOBAL_SORT_SEED = TBD` | None | No key data | `` | Random seed used to derive deterministic sort keys when explicit per-map sort keys are absent. | +| Deterministic Sort Flag | `PSBT_GLOBAL_SORT_DETERMINISTIC = TBD` | None | No key data | `<8-bit uint>` | A value of `0x01` indicates sort keys must be deterministically derived and explicit `PSBT_IN_SORT_KEY` / `PSBT_OUT_SORT_KEY` fields are disallowed. A value of `0x00` indicates sort keys are required and `PSBT_GLOBAL_SORT_SEED` is disallowed. | +| Removed Input | `PSBT_GLOBAL_REMOVED_INPUT = TBD` | `` | `PSBT_IN_UNIQUE_ID` of an input removed from the logical input set. | None | No value data. | +| Removed Output | `PSBT_GLOBAL_REMOVED_OUTPUT = TBD` | `` | `PSBT_OUT_UNIQUE_ID` removed from the logical output set. | None | No value data. | + +### New per-input types + +| Name | `keytype` | `keydata` | `keydata` Description | `valuedata` | `valuedata` Description | +| --- | --- | --- | --- | --- | --- | +| Input Sort Key | `PSBT_IN_SORT_KEY = TBD` | None | No key data | `` | Arbitrary lexicographically comparable value used to order inputs. | +| Input Unique ID | `PSBT_IN_UNIQUE_ID = TBD` | None | No key data | `` | Optional unique suffix for outpoint identity, used for input removal extensions. | + +### New per-output types + +| Name | `keytype` | `keydata` | `keydata` Description | `valuedata` | `valuedata` Description | +| --- | --- | --- | --- | --- | --- | +| Output Unique ID | `PSBT_OUT_UNIQUE_ID = TBD` | None | No key data | `` | Universally unique identifier for output map identity under unordered output semantics. | +| Output Sort Key | `PSBT_OUT_SORT_KEY = TBD` | None | No key data | `` | Arbitrary lexicographically comparable value used to order outputs when transitioning from unordered to ordered mode. | + +### PSBT identity and transaction effects + +The BIP 174 *Combiner* role specifies how to merge diverging copies of the same PSBT. PSBTs are considered "the same", by identifying them based on the unsigned transaction. Two PSBTs with the same unsigned transaction but potentially different key value pairs are considered two versions of the same PSBT. + +BIP 370 introduces the notion of a [unique ID](https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki#user-content-Unique_Identification) which is computed as a hash that commits to UTXOs being spent and the new outputs being created, thereby ensuring PSBTs with the same ID have the same structure, but abstracting away some details of the transaction, thereby introducing a notion of equivalence that is a bit more general. + +The effects of a transaction on the distribution of money are determined by its effects the UTXO set: which outputs does it spend and create. However, with regards to money changing hands, we would like to treat equivalent outputs as interchangeable by disregarding the specific outpoints by which specific coins are identified. + +Both notions of identity ensure that PSBTs with the same ID have the same effects, but it is not true that PSBTs with the same effects will have the same ID, since depends on the specific order of the inputs and outputs, among other things. By abstracting over these details we obtain a more general notion of PSBT identity than in BIP 370. The details of how to compute this ID are [provided below](#unique-identification-of-unordered-psbts). + +### Combiner role and transaction effects + +The BIP 174 *Combiner* role requires that the PSBTs have the same identity. In order to relax this constraint and allow the *Combiner* role to be used in conjunction with (a more general notion of) the *Constructor* role, the *Combiner* role has to be made more conservative in other regards. + +BIP 174 specifies that fields with duplicate keys and more than one distinct value may be combined by [picking one of the values arbitrarily](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki#handling-duplicated-keys). This is safe within the scope of BIP 174 because any inconsistency will only affect the validity of a transaction. In other words, when choosing one value over another for a duplicate field, although signing may fail to produce a valid signature, no money will be lost because if the IDs are the same, the the effects are identical. + +This notion of safety can be extend beyond just combining signing related data, so that effects of a transaction formed by combining PSBTs do not depend in any way on the order in which the PSBTs were combined, nor even on combination being done sequentially. Note that this does not require that the effects of the constituent PSBT be identical, only that all of them are combined at some point. More formally, in order to be safe, combining should be monotone in the transaction effects. + +Unfortunately choosing between conflicting values arbitrarily does not preserve this notion of safety when merging PSBTs where the inputs or outputs of one PSBT don't correspond to the inputs or outputs which occupy the same positions in the second PSBT. For example, if the first inputs of two PSBTs spend different coins, and one PSBT takes precedence, the input in the other transaction will be omitted. If the `PSBT_IN_PREVIOUS_TXID` field of one PSBT overrides the other but this precedence is reversed for `PSBT_IN_OUTPUT_INDEX`, the one remaining input will be corrupted. + +#### `joinpsbts` vs. the Combiner role + +Bitcoin Core additionally implements a `joinpsbts` RPC command which does allow merging PSBTs with different identities, so long as their spent output sets are disjoint. + +`joinpsbts` is not idempotent with respect to inputs (writing it as $+$, idempotence would mean that $A + A = A$). Attempting to join a PSBT more than once fails closed: if $B$ contains an input, and $A + B$ is defined, then $(A + B) + B$ will fail, because a transaction cannot spend the same coin twice. + +`joinpsbts` is also not idempotent with respect to the outputs, but unfortunately also does not fail closed, potentially leading to overspending: if $B$ contains just an output, then $B + B$ will contain two copies of that output. + +Although not strictly associative or commutative, due to use of shuffling, in regards to transaction effects it does hold that $(A + B) + C = A + (B + C)$ and that $A + B = B + A$. + +#### Strict Combiner + +In order for combination being deterministic, idempotent and commutative and associative in regards to transaction effects, when either bits 0 or 1 of `PSBT_GLOBAL_TX_MODIFIABLE` are set, indicating the transaction is modifiable, instead of choosing arbitrarily the strict *Combiner* MUST fail whenever duplicate fields have conflicting (unequal) values. + +Exceptions to this are detailed in the next sections, preserving idempotence, commutativity and associativity. + +This establishes a more conservative foundation for ensuring that the effects of a transaction formed by combining a set of PSBTs will always be the same regardless how these PSBTs were combined to obtain a complete transaction. + +### Unordered input and output sets + +Since transaction effects are invariant under permutations of the inputs or outputs, treating the inputs and outputs as unordered sets as opposed to order lists allows safe combining to be defined for PSBTs that are not identical. + +To represent this we define a global field `PSBT_GLOBAL_TX_UNORDERED`, indicating whether the order of inputs and outputs should be ignored. The value is an unsigned 8 bit integer and if present must be set to `0x03`, indicating the transaction in unordered. + +Rationale: Since there is no known use case that requires input or output to be marked unordered or ordered separately from each other, that is omitted from the spec. The value `0x03` simplifies forward compatibility with any specification that might amend this by allowing either bit to be set independently, so long as it overlaps with this specification when both are set. + +If set, the `Has SIGHASH_SINGLE` flag of `PSBT_GLOBAL_TX_MODIFIABLE` must not be set. `SIGHASH_SINGLE` inputs [MUST not be used](#divergence-and-sighash-flags) in unordered transactions. + +Unordered PSBTs MUST be shuffled prior to reserialization. This is easily accomplished by storing them in randomized hashmaps, keyed by their unique identifiers as defined below. If all inputs and outputs have [sort keys](#ordering-inputs-and-outputs), the key based ordering may be used instead of shuffling. + +[fn:Join is implicitly defined on equivalence class of all permutations of inputs/outputs, but the PSBT contents is a random representative. + +Rationale: Not shuffling presents a privacy hazard, leaking information about the sequence of actions leading to a transaction's construction. When a transaction is unordered, shuffling by definition doesn't change its meaning, but ensures the incidental order can't accidentally be relied upon. + +#### Combining PSBTs with different identities + +When `PSBT_GLOBAL_TX_UNORDERED` is set, the input or output maps are no longer distinguished by their index, but instead by a unique identifier defined for each input or output. + +Inputs or outputs with identical unique IDs (those which are present in both PSBTs) are merged by combining their key-value pairs with the stricter, idempotent combination defined above. + +These sets of combined inputs and outputs are then unioned with any inputs or outputs from that have distinct unique identifiers (i.e. are only present in one of the PSBTs, and therefore aren't combined with a counterparts). Distinct identifiers are only allowed if the corresponding `PSBT_GLOBAL_TX_MODIFIABLE` flag is set, because such combinations represent additions of inputs or outputs. If this is not the case but a distinct input or output is present, then combining must fail. + +#### Unique identifiers for inputs + +Inputs are identified by their outpoint, i.e. the tuple of their `PSBT_IN_PREVIOUS_TXID` and `PSBT_IN_OUTPUT_INDEX`, both of which must be set. + +#### Unique identifiers for outputs + +Outputs are identified by a new `PSBT_OUT_UNIQUE_ID` field, which must be universally unique (e.g. 16 bytes of randomness). + +This ensures that repeated addition of the same output is idempotent, but that if two different distributed constructors both attempt to add an identical output (same `PSBT_OUT_VALUE` and `PSBT_OUT_SCRIPT`), that will still result in two copies of the output as intended. This is important because a transaction with only a single copy will appear correct but end up losing the value of all missing copies to mining fees. + +Outputs with an identical `PSBT_OUT_SCRIPT` can be merged, and their values summed together after `PSBT_GLOBAL_TX_UNORDERED` is cleared and an order is determined, using BIP 370 construction rules. See the next section on ordering. + +### Ordering inputs and outputs + +- TODO: unique ID can be derived by sorting even if sort key is empty, but txn finalization must not be unless all sort keys are provided explicitly (regardless of DETERMINISTIC) +- add section for unique ID derivation a la BIP 370 + +Clearing the `PSBT_GLOBAL_TX_UNORDERED` field indicates the order of the inputs and outputs. Due to the shuffling requirement, the given order will in general not be consistent across replicas if this is done without determining an order, resulting in diverging unsigned transactions. + +For consistent ordering we define `PSBT_IN_SORT_KEY` and `PSBT_OUT_SORT_KEY` fields for inputs and outputs respectively, that may include up to 32 bytes of arbitrary data, used as a sort key for lexicographical sorting. + +If the global field `PSBT_GLOBAL_SORT_DETERMINISTIC` is set (unsigned 8 bit integer) to `0x01`, then sort keys MUST NOT be set, and `PSBT_GLOBAL_SORT_SEED` MUST be set and contain at least 128 bits of randomness. + +If `PSBT_GLOBAL_SORT_DETERMINISTIC` is set to `0x00`, explicit sort keys are required to be set and used prior to clearing the `PSBT_GLOBAL_TX_UNORDERED` field and fixing the transaction order. + +If any `PSBT_IN_SORT_KEY` and `PSBT_OUT_SORT_KEY` are omitted, the global `PSBT_GLOBAL_SORT_SEED` field is set, and `PSBT_GLOBAL_SORT_DETERMINISTIC` is either omitted or set to `0x01`, the sort keys are derived deterministically. A missing `PSBT_IN_SORT_KEY` is derived as `H(PSBT_GLOBAL_SORT_SEED || PSBT_IN_PREVIOUS_TXID || PSBT_IN_OUTPUT_INDEX)` and `PSBT_OUT_SORT_KEY` as `H(PSBT_GLOBAL_SORT_SEED || PSBT_OUT_UNIQUE_ID)`, where `H_s` is a BIP 341 style tagged hash, with the tag preimage being `BIP ???? deterministic ordering` (TODO pick a real domain separator). + +If any sort key is missing, ordering can only proceed after `PSBT_GLOBAL_SORT_SEED` is set. + +A *Creator* creating an unordered transaction SHOULD set `PSBT_GLOBAL_SORT_DETERMINISTIC` to ensure consistent ordering rules are enforced. + +For sufficiently large transactions the ordering itself (and therefore the per input signatures) is a cryptographically binding commitment to the `PSBT_GLOBAL_SORT_SEED` value. This is because the entropy of the ordering of $n$ elements is $log_2(n!)$. For reference, $\log_2(35!) > 128$, $\log_2(25!) > 80$, and $\log_2(15!) > 40$. + +This can provides additional integrity to a collaborative transaction construction protocol, since [`SIGHASH_ALL`](#divergence-and-sighash-flags) signatures must agree on the ordering. + +In applications where this is desirable, the *Creator* should only set `PSBT_GLOBAL_SORT_DETERMINISTIC` to `0x01`, and leave `PSBT_GLOBAL_SORT_SEED` unset. Each replica will locally provide a value for `PSBT_GLOBAL_SORT_SEED` just in time, as a commitment to protocol transcript (e.g. the root hash of a Merkle set of protocol messages). + +If that is not the case, the *Creator* should initialize `PSBT_GLOBAL_SORT_SEED` with sufficient randomness thereby ensure some order can always be determined, or set `PSBT_GLOBAL_SORT_DETERMINISTIC` to `0x00` to indicate explicit sort keys are required.. + +TODO global sort seed || hash of fee contributions or expect application to commit to that in transcript if appropriate? + +TODO: Rationale for allowing explicit sort key: lightning interactive-tx `serial_id` field. should always use odd parity form, encoded in network order so that lexicographical sorting works the same as the interactive-tx sorting rule. + +### Unique identification of unordered PSBTs + +In order to derive unique IDs as in BIP 370 for unordered transactions, the `PSBT_GLOBAL_SORT_SEED` and `PSBT_IN_SORT_KEY` and `PSBT_OUT_SORT_KEY` fields are cleared, and then the ordering procedure of the previous section is used without the restriction of a non-empty `PSBT_GLOBAL_SORT_SEED` (sorting with an empty seed). + +TODO: domain separation from PSBT v2, it doesn't make sense to treat an ordered BIP 370 PSBT as the same PSBT even if it agrees on its content when it doesn't agree that the order is meaningless. how to do this? hashing output unique IDs of outputs is insufficient for domain separation of input only partially constructed PSBTs, but maybe that's OK. + +### Divergence and SIGHASH flags + +Signers MUST sign only using `SIGHASH_ALL`. + +If `SIGHASH_ANYONECANPAY` or `SIGHASH_NONE` is used by a signer, the signature is valid for an (ill defined) equivalence class of transactions, with non-equivalent transaction effects. + +At minimum any such signature could lead to txid malleability, and so is not composable with any protocol that requires pre-signed descendant transactions. + +Furthermore, members of this equivalence class of transactions may differ substantially in their effects, potentially leading to loss of funds, not only due to byzantine faults but even omission faults. To ensure undesired transactions are not inadvertently authorized, the full output list should always be committed to using `SIGHASH_ALL`. + +Rationale: No known use cases for such flags in true multiparty transactions (i.e. three or more parties). If necessary, a carve out can be specified in a separate document (e.g. for kickstarter-style crowdfunding with `SIGHASH_ANYONECANPAY|SIGHASH_ALL` signing). + +### Confirmation of successful payment prior to signing + +Parties which neither send nor receive payments within a transaction can safely sign so long as all of their intended outputs are covered by the input signature. This may require signing more than once if some messages are delayed, but TODO see also termination via explicit fee contributions. + +If there is any net transfer between the parties, it is insufficient for a sender (any party that makes an outgoing payment to another party within the transaction regardless of their net send/receive balance) to rely only on the signature committing to the outputs they added, because some of their funds will be used by other parties and their actions need to have been registered as well. + +Before signing, every sender must wait until it has positive confirmation of the PSBT's unique ID (which commits to the full output set) from every one of its receivers, and that in every case the confirmed ID matches the one they derive locally. + +Every receiver whose net balance is non-negative (they may be a sender too but they receive at least as much as they send) can confirm the unique PSBT ID to their respective senders output set contains all of their added outputs. + +Every receiver whose balance is net negative (they send more than they receive) must wait for confirmation from all receivers for whom it is a sender before it confirms the unique ID to the senders for whom it is a receiver. + +If there is a cyclic payment graph, for example Alice pays Bob, Bob pays Carol, and Carol pays Alice, net positive receivers can safely initiate confirmations, breaking the circular dependency, because senders will sign will only occur after all receivers have confirmed and if all net positive receivers have confirmed then all funds are accounted for. At least one such node must exist in every cyclic payment structure, since the sum of the payments along a cycle will be 0. + +If there is any mismatch in the confirmations, either the receiver or the sender has not yet received the full message set. If a receiver learns of an additional input or output after previously confirming, they must confirm the new unique ID which incorporates this additional data. If a sender learns of an additional input or output, they can derive a new unique ID, and stop waiting if this matches all of their receivers' confirmations. + +Such a confirmation mechanism does not require an agreement or consensus mechanism, only eventual consistency. If messages are guaranteed to be delivered eventually then every receiver will eventually confirm a consistent least upper bound. + +TODO sender/receiver examples, including an example with a receiver that contributes no inputs, only outputs + +TODO net-sender, net-receiver, explain in terms of breaking cyclic graph to a tree with net-receivers at the leaves, propagate confirmation up the chain. + +### Input or output removal (optional) + +As in BIP 174, the combination of several PSBTs must contain all the key-value pairs from each of the input PSBTs. + +If support for removal of inputs and outputs is needed, two global fields `PSBT_GLOBAL_REMOVED_INPUT` and `PSBT_GLOBAL_REMOVED_OUTPUT` can be used to represent a [two phase set](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type#2P-Set_(Two-Phase_Set)) by specifying the inputs or outputs to be removed in the keydata. Inputs or outputs whose unique IDs are specified must be pruned from the input or output. + +Because inputs are identified by outpoint, an input spending the same coin as an input whose outpoint is in the set of removed inputs can't normally be added. Therefore we introduce an optional `PSBT_IN_UNIQUE_ID` field, whose value (if provided) is appended to the outpoint. + +Support for removal is entirely optional. Implementations may explicitly fail when combining with a PSBT that sets either `PSBT_GLOBAL_REMOVED_INPUT` or `PSBT_GLOBAL_REMOVED_OUTPUT`, but completely ignoring these fields is fail safe. + +Assuming [`SIGHASH_ALL` is used](#divergence-and-sighash-flags), it's sufficient to simply rely on the signature hashing. If an output was removed, a peer which does not implement removal it will diverge from those that do, and therefore produce a signature that will not be valid for the transaction supporting peers will produce and subsequently sign, and vice versa, ensuring that neither transaction is valid. + +This optionality extends the `PSBT_IN_UNIQUE_ID` field, a removal and re-insertion with incompatible data will either cause combination to fail due to a mismatch or succeed by ignoring the removal and treating the insertion as idempotent, but otherwise diverge. + +While this would allow limited interoperability among clients, that is not recommended, and is described as an argument for the safety of omitting any removal related functionality. Implementations which omit removal functionality SHOULD fail or at least warn if combining a PSBT that signals removal. + +TODO: while combine is monotone of data / PSBT fields including removals, it is no longer monotone in transaction effects. This does not present a safety issue if [only `SIGHASH_ALL` is used](#divergence-and-sighash-flags). + +Rationale for optionality: not implementing is safe, couldn't find usage of `tx_remove_{input,output}`, non-monotonic state makes termination / limits trickier. + +TODO for interactive-tx, set `PSBT_IN_UNIQUE_ID` to odd parity `serial_id`. this makes it possible to support `tx_remove_{input,output}` operations. + +### PSBT CRDT (optional) + +In some circumstances a conflict free replicated data type (CRDT) can be defined as a subtype of (unordered) PSBTs. In a CRDT, in addition to being idempotent, commutative and associative, combination is additionally [guaranteed to succeed](https://en.wikipedia.org/wiki/Semilattice). + +Success here means producing a useful output, which ideally would guarantee a transaction that would be valid if fully signed, which also conforms to standardness policy. This can only be guaranteed under assumptions that must be realized by some additional protocol, beyond the scope of this document. + +#### Mutually exclusive inputs + +Two `OP_CLTV` encumbered coins, one with a height based and one with a time based `nLocktime` constraint will impose mutually exclusive validity requirements on their spending transactions, and therefore cannot be spent together in the same transaction. + +In order to ensure the least upper bound of any two inputs under consideration not only can be defined, but will correspond to a valid transaction, the *Creator* role can restrict the domain of spendable inputs before inputs are added. + +TODO `PSBT_GLOBAL_{REQUIRED,MAXIMUM}_{HEIGHT,TIME}_LOCKTIME` height and time separately or just integer range? separately is consistent with other PSBT specs. a single nlocktime interval field with two unsigned integers, required and max-required would make many invalid states unrepresentable, but is more fiddly and unfamiliar. + +#### Size Limits + +advisory fields: `MAX_WEIGHT_PER_PARTICIPANT`, `MAX_TRANSACTION_WEIGHT` (default 400000?) - determines max number of participants while also signalling size limit is enforced + +if every participant effectively restricts the domain by respecting the limit the least upper bound is guaranteed not to exceed the limit making the join valid. + +assumes the number of participants can be restricted via some external mechanism. + +#### Termination + +knowing when to proceed to signing + +- global fee contribution + - `PSBT_GLOBAL_EXPLICIT_FEE_CONTRIBUTION` + - keydata = 16 byte uuid + - value = u64 amount of funds explicitly contributed as fees + - needs `PSBT_IN_NON_WITNESS_UTXO` or `PSBT_IN_WITNESS_UTXO` for nominal value + - effective values/costs would a specific feerate and input size estimation, + instead all such fee contributions should also be added (but can be + computed deterministically in case this is known) + +inputs before outputs? +only rely on payment ACKs + +## Rationale + +## Backwards Compatibility + +## Reference Implementation + +--- + +# TODO + +- new PSBT version? + - con: new PSBT version + pro: deserializing unordered txns in psbtv2 will error instead of + potentially leaking unshuffled input/output order + +- Move inline rationales to their own section + +- BIP 174 describes how to aggregate signatures via combiner. example includes a manual coinjoin flow, joining of PSBTs not defined in the spec. technically this involves two different PSBTs. discuss what happens when not sequential, as well as conceptual issues. + +--- + +- discuss liveness. safety WRT transaction effects is nice but we also want to + minimize irrecoverable failures. discuss both generally and in CRDT section. diff --git a/docs/pure_strategy_evaluation.md b/docs/pure_strategy_evaluation.md new file mode 100644 index 0000000..1116342 --- /dev/null +++ b/docs/pure_strategy_evaluation.md @@ -0,0 +1,10 @@ +--- +type: concept +title: Pure Strategy Evaluation +status: draft +stale_after: 2026-11-06T00:00:00Z +--- + +# 🤖 Pure Strategy Evaluation + +How the cost of a pure strategy is evaluated, in three parts. The [Cost function structure](cost_function_structure.md) chapter describes the structure shared by the family of cost functions: time dependence, the linear combination of terms, and bracketing. The [Privacy liability terms](cost_function_concrete.md) chapter summarizes the terms, each of which is specified in its own chapter. The [Privacy metrics](privacy_metrics.md) chapter describes the measures the terms take as input. diff --git a/docs/recovery-track.md b/docs/recovery-track.md new file mode 100644 index 0000000..644d552 --- /dev/null +++ b/docs/recovery-track.md @@ -0,0 +1,566 @@ +--- +type: Specification +title: Recovery track +description: How a stalled phase of the optimistic track turns into a recovery coalition formation proposal. +status: draft +stale_after: 2026-11-06T00:00:00Z +--- + + + +# Recovery track + +🤖 A stalled phase can produce recovery observations in validator blocks, each signed by its validator and committing to what that validator is missing. Any participant can turn those observations into a recovery coalition formation proposal that anyone can check. The intended synchrony properties are exclusion of a faulty party without excluding an honest one, apart from the [counterparty-stall exception](#counterparty-stalls). Claims below that depend on identifying missing first- or second-round acknowledgements remain unresolved under the two-round finalization rule. + +🤖 This chapter describes the recovery track ($t \lt n$). The block structure and the per-track nonce commitments are described in the [block DAG](block-dag.md) chapter. The closing of each phase is described in the [optimistic track](optimistic-track.md#phase-closure) chapter ($t = n$). Dissemination and set reconciliation are out of scope here. + +🤖 Several names in this chapter and in [phase closure](optimistic-track.md#phase-closure) are placeholders, chosen only so the rules can be stated: *per-input message*, *quorum mode*, *own-view mode*, *deny list*, *late pass*, *coin binding*, *evidence-only proposal*, *boundary split* and *light participant*. A light participant is one that does not see the DAG. + +## Fault tolerance via branched execution + +Somewhat surprisingly, the optimistic track and the recovery track can both proceed more or less independently. + +Under asynchrony and in the presence of (Byzantine) faults, due to the unanimity requirement the best consistency guarantee that can be made for the optimistic track is eventual consistency. No liveness guarantee is possible in the presence of faults for a particular run of the transaction construction protocol. + +Recall that when multiple transactions attempt to spend some of the same coins, it is up to miners to determine which one (if any) will be confirmed in a block. Miners are assumed to follow their incentives, maximizing fee revenues. Even if transaction replacement wasn't useful or desirable, there is no mechanism that can enforce that unspent outputs are exclusively bound to one transaction construction session over another without *global* consensus. + +As we have seen, the success path always reaches termination, and can only reach it by observing unanimous agreement, and when that is possible progress requires only eventual consistency. Validity proofs reduce Byzantine faults to omission faults, so recovering liveness in the presence of failure requires partial synchrony assumptions at the very least. + +Since input exclusivity is neither desirable nor enforceable, we can embrace its absence and reframe liveness in a simpler way by treating all failure recovery as branching off another instance of the protocol with a subset of the participants precisely when that subset of the participants can agree among themselves that a failure condition has been detected. Such agreement inherently requires synchrony or partial synchrony, and so explains why this is needed for fault tolerance. In this case the blocks at some height $h$ with $t < n$ parent blocks will be produced as part of the recovery synchronization protocol on top of which a new transaction construction session will commence. If messages are delivered allowing a block at height $h$ to be produced with $t = n$ messages, the asynchronous base protocol can resume progress resulting in the diverging protocol states at height $h$. This special case has the same structure as all-to-all broadcast. + +Since recovery is just permissioned coalition formation, any participant may act as an aggregator and make a coalition formation proposal based on its local view; the proposed participants must all accept before it starts. Membership changes can alter anonymity or payment terms, so participants may renegotiate or decline. Recovery also has a privacy cost: excluding an input links it to the outputs that drop out with it, even if its owner was merely unresponsive. + +The reason this framing is simpler is that recovery attempts do not need to terminate the run of the protocol that they are trying to recover. In the case that both branches eventually succeed, Bitcoin itself will adjudicate the conflicting transactions. We can treat failure recovery as a (more) synchronous layer building on a fundamentally asynchronous optimistic base protocol with BEC semantics. + +## 🤖 Recovery overlay {#recovery-overlay} + +Each optimistic session is monotone and append-only. Its optimistic and recovery tracks are interleaved within the same block DAG, distinguished by the threshold used for progress: $t=n$ for unanimous construction and $t3f$.[^acs] These are guarantees within a fixed instance; they do not imply global agreement between separate recovery branches. + +Overlapping proposals provide a useful inclusion condition. Suppose each proposal $X_i$ is a validated fragment set, and $H_x$ is the set of honest proposers whose submitted sets contain fragment $x$. Since at most $f$ proposals are omitted, + +$$ +|H_x|>f\ \Longrightarrow\ Q\cap H_x\neq\varnothing +\ \Longrightarrow\ x\in\bigcup_{i\in Q}X_i. +$$ + +🤖 This counting argument protects a sufficiently replicated fragment even when its original observer's proposal is omitted. It concerns the submitted sets, not information learned after submission. Causal ancestry can witness this inclusion without identifying the anonymous author of the fragment. ACS alone gives no corresponding guarantee for a fragment present in only one honest proposal. This inclusion calculation is not a phase-finalization rule: the union of selected differing views is not the synchronized first-round set required by the second acknowledgement round. A participant continues validator duties independently of inclusion of its own anonymous contributions; its authority to withhold transaction signatures remains separate. + +### Membership, resilience and recovery + +Active-parties set agreement (APSA) establishes a common set of participant identities without knowing their number in advance. Its validity condition includes every participant active from the start that remains honest until termination, excludes identities not activated by termination, and permits inclusion of faulty participants. The construction uses synchronous rounds, signatures and a certificate-authority setup; it does not identify exactly the honest or currently responsive participants.[^choi] This is relevant to the recovery overlay: the parent session has known membership, but the subset available for a successor is not fixed in advance. An aggregator's view-derived active set need not be globally agreed; APSA supplies a stronger comparison in which eligible honest participants agree on one set. Once a successor coalition proposal is accepted, its construction instance has fixed membership. Agreement on an active set is not a substitute for acceptance of that proposal's terms or for future signing cooperation. + +Authenticated synchronous broadcast admits dishonest-majority constructions. Dolev–Strong is the classical example; FlintBB adds an optimistic execution path when actual faults are lower than the configured bound.[^dm] Their timing assumptions cannot be replaced by DAG height alone. Conversely, allowing separate successor instances weakens the global agreement objective without proving any particular broadcast or inclusion guarantee within those instances. + +Sample-based reliable broadcast addresses a different dimension: reducing communication and computation with probabilistic guarantees.[^sample-brb] Its uniform sampling and hidden-communication assumptions require examination before exposing its evidence in validator blocks. It is a dissemination alternative, not a replacement for unanimous acceptance. + +The specification does not yet select one of these constructions as the recovery agreement mechanism. + +## References + +[^bip340]: P. Wuille, J. Nick and T. Ruffing, [*BIP 340: Schnorr Signatures for secp256k1*](https://bips.dev/340/). The signature equation behind key exposure. + +[^bip352]: josibake, R. Somsen and S. Falbesoner, [*BIP 352: Silent Payments*](https://bips.dev/352/). Output derivation tweaked by the transaction's inputs. + +[^choi]: W. Choi, R. Cohen, J. Garay, N. Skoumios and V. Zikas, [*Byzantine Broadcast with Unknown Participants*](https://eprint.iacr.org/2025/2133) (2025). Defines active-parties set agreement. + +[^dolev-strong]: D. Dolev and H. R. Strong, [*Authenticated Algorithms for Byzantine Agreement*](https://doi.org/10.1137/0212045), SIAM Journal on Computing (1983). + +[^vigil]: J. Cheng, H. Sun, R. Zhou, J. Zhou and Z. Chen, [*Vigil: Accountable Liveness against Selective Silence*](https://arxiv.org/abs/2609.18778) (2026). + +[^deligios]: G. Deligios, I. Klasovita and C.-D. Liu-Zhang, [*Asymptotically Optimal Early Termination for Dishonest Majority Broadcast*](https://eprint.iacr.org/2024/1656), Eurocrypt 2025. The lower bound is cited there on p. 2. + +[^loss-nielsen]: J. Loss and J. B. Nielsen, [*Early Stopping for Any Number of Corruptions*](https://eprint.iacr.org/2023/1813), Eurocrypt 2024. + +[^cordial]: Idit Keidar, Oded Naor, Ouri Poupko and Ehud Shapiro. [Cordial Miners: Fast and Efficient Consensus for Every Eventuality](https://arxiv.org/abs/2205.09174). + +[^dual-track]: Minghang Li et al. [TockOwl: Asynchronous Consensus with Fault and Network Adaptability](https://eprint.iacr.org/2025/134) (USENIX Security 2025). TockOwl+ combines fast and slow tracks using hedging delays. + +[^crbb]: Ittai Abraham, Yuval Efron and Ling Ren. [The Latency Cost of Censorship Resistance](https://eprint.iacr.org/2025/2136). + +[^ic]: Panos Diamantopoulos, Stathis Maneas, Christos Patsonakis, Nikos Chondros and Mema Roussopoulos. [Interactive Consistency in practical, mostly-asynchronous systems](https://arxiv.org/abs/1410.7256). + +[^acs]: Andrew Miller, Yu Xia, Kyle Croman, Elaine Shi and Dawn Song. [The Honey Badger of BFT Protocols](https://eprint.iacr.org/2016/199). See also Sisi Duan, Michael K. Reiter and Haibin Zhang, [BEAT: Asynchronous BFT Made Practical, Section 5](https://reitermk.github.io/papers/2018/CCS.pdf), for the ACS properties. + +[^dm]: Danny Dolev and H. Raymond Strong. [Authenticated Algorithms for Byzantine Agreement](https://doi.org/10.1137/0212045). Ruomu Hou and Haifeng Yu. [Optimistic Execution in Byzantine Broadcast Protocols That Tolerate Malicious Majority](https://doi.org/10.1016/j.jpdc.2025.105203). + +[^sample-brb]: Rachid Guerraoui et al. [Scalable Byzantine Reliable Broadcast](https://arxiv.org/abs/1908.01738). + +[^dls]: C. Dwork, N. Lynch and L. Stockmeyer, [*Consensus in the Presence of Partial Synchrony*](https://groups.csail.mit.edu/tds/papers/Lynch/jacm88.pdf) (1988). The introduction contrasts synchronous and asynchronous models and defines the two forms of partial synchrony used here: an unknown timing bound, or a bound that holds only eventually. diff --git a/docs/set-reconciliation.md b/docs/set-reconciliation.md new file mode 100644 index 0000000..38b1c44 --- /dev/null +++ b/docs/set-reconciliation.md @@ -0,0 +1,158 @@ +--- +type: Specification +title: Peer set reconciliation +description: Requesting hash preimages, naive reconciliation, sets outside the block DAG, and range and rateless reconciliation as optimizations of the same mechanism. +status: draft +stale_after: 2027-04-15T00:00:00Z +--- + + + +# 🤖 Peer set reconciliation + +## Push gossip + +[Epidemic gossip](channels.md#dissemination-methods) disseminates data by pushing it: a peer that learns of a new message passes it on to its neighbors, and they pass it on in turn. Every peer eventually receives every message, assuming the required connectivity and delivery. A peer can also request missing messages by hash or reconcile its set with another peer's set, as described below. + +🤖 Small messages are pushed eagerly to neighbors. A block is pushed as just its header, expecting the receiver to already know its Merkle tree. + +## Requesting hash preimages + +A block refers to its parents and to the messages it includes by hash, and a set of messages is committed to by a Merkle root. A peer can therefore hold a root without knowing the leaves it commits to. Such a peer wants to pull the missing leaves, not wait for someone to push them. + +## Naive reconciliation + +Pulling works because honest peers follow two rules: + +* An honest peer never sends a message containing hashes for which it has not validated the preimages. +* An honest peer responds to a pull for a hash with its preimage. + +This is analogous to `getdata` in Bitcoin's peer to peer protocol. A peer that receives a hash can pull its preimage from the sender. It repeats this for the hashes in the obtained message, until it reaches messages it already has. This is enough for the naive reconciliation of Byzantine Eventual Consistency (BEC).[^bec] In the block DAG, the hashes are a block's parents and included messages. The number of round trips can be up to the length of the longest path of missing messages. Kleppmann and Howard reduce it using Bloom filters; that optimization is not needed. + +Reconciliation uses [peer to peer channels](transport-interfaces.md), independently of whether delivery uses a live connection or store-and-forward messages. Exchanges identify their root and scope so delayed replies remain interpretable after a newer advertisement or transport rebuild. A reconciliation stream is a sequence of messages, not a requirement for a connection-based byte stream. Neighbor identity and acknowledged knowledge belong to peer management; they need not expire with the transport connection. + +## Sparse Merkle sets + +Sets are represented by sparse Merkle trees keyed by the cryptographic hash of each referenced object. The key is its set identity; repeated insertion is idempotent. The tree commits to an unordered set, independently of arrival order or the peer that supplied an element. + +The DAG does not order messages, so its message sets are unordered. Where an order is wanted, for example if a block's parents are committed to in an arbitrary order, the commitment is to a list instead: a Merkle tree over positions, like the Merkle tree of a Bitcoin block, which commits to an ordered list of transactions. Ordered versus unordered is the distinction between a list and a set. Whether a set is included in the block DAG determines its consistency guarantees, not its order. + +Empty subtrees have a canonical representation. A singleton subtree is represented by its leaf rather than a chain of otherwise empty internal nodes, following the compression described for Libra's sparse Merkle trees.[^libra] Leaf, internal-node and empty-node encodings must be unambiguous and domain separated. The exact encoding and hash function are pending choices. + +Every message sent to a neighbor carries the relevant set root. An advertised root adds that set to the reconciliation allow-list for that neighbor. Reconciliation requests are scoped to such an advertised set, or to a subtree established during its reconciliation. Advertising a root authorizes reconciliation; it does not establish that the contents are valid or available. + +Immutable sets coexist with changing inventory sets. For example, a block DAG can advertise its current frontier, unincorporated contributions or all known blocks; the frontier can change while its causal closure grows monotonically. An inventory advertisement identifies the kind of set as well as its current root; the retention policy for superseded inventory roots remains to be specified. + +An exchange identifies an immutable root. Later advertisements can introduce newer roots without changing the meaning of an exchange already in flight. Obtained messages are shared across exchanges and neighbors through the local content-addressed inventory. + +## Sets outside the block DAG + +The same mechanism can exchange the Merkle set roots of messages that are not in any block. These sets are ephemeral and have no protocol consistency guarantees; they are just used to trigger set reconciliation. + +* In the peer to group context, this is analogous to a mempool: contributions to a transaction construction session that no block includes yet. +* In the peer to world context, this is the order book of coalition formation: listen advertisements, co-spend proposals, and their ownership proofs. + +Peer to world does not rely on BEC or on blocks. Peers just exchange Merkle trees with adjacent peers. The coalition formation protocol decides which objects are valid, which are kept, and which are eligible for negotiation. + +The [DAG's equivocation mechanism](block-dag.md#nonce-commitments-and-compact-equivocation-evidence) exposes a validator's BIP-322-endorsed online private key. Gossiping this scalar and its endorsement evidence lets other peers verify the fraud proof and ban the associated coin from coalition formation without obtaining the equivocated blocks. Reconciliation disseminates the evidence; the consuming protocol validates it and applies the admission policy. + +## Quiescence before block authoring + +🤖 Set reconciliation is an input to block publication: a validator waits for its neighbors' sets to converge before authoring its next block, whichever reconciliation algorithm is used. The rule and its purpose, avoiding needless block DAG waves, are described under [block publication and quiescence](optimistic-track.md#block-publication-and-quiescence) in the optimistic track. + +## Optimizations + +Range-based set reconciliation (RBSR), and RBSR combined with rateless invertible Bloom lookup tables (RIBLT), come naturally from the same mechanism. Instead of exchanging a root and pulling every leaf, two peers compare subtrees, and pull only where their sets differ. We call the combination **hybrid recursive/rateless set reconciliation**: RBSR recursively controls the scope of the exchange; optional `rateless` and `rateless` streams can use available bandwidth while range replies are in flight. These algorithms target different device and network tradeoffs; an optimal switching policy has not yet been established. + +### Mutual and asymmetric knowledge + +Each peer has a local inventory and neighbor-specific evidence about the neighbor's inventory. A root identifies a set without establishing that the receiver possesses its elements. The receiver may know only the commitment, some leaves, or the complete set. Missing identifiers and missing message preimages are distinct: learning a leaf hash can identify a subsequent content request. + +Mutual knowledge here means an operationally established shared subset, not epistemic common knowledge. A jointly identified baseline can be omitted from both sides of a reconciliation exchange. Asymmetric knowledge also helps: a peer can request particular missing objects or avoid resending acknowledged objects without first establishing identical inventories. Mere absence from an advertisement need not establish that the neighbor lacks an object. + +### Range reconciliation and streaming + +The first optimization direction is range-based set reconciliation in the style of Meyer and Scherer.[^rbsr] It is not needed for the base functionality. A sparse-tree prefix identifies a key range. Equal subtree commitments require no further exchange; unequal ranges are subdivided or resolved by transmitting leaves. + +A subtree advertisement includes its key prefix as well as its root. The receiver can compare it directly with the corresponding position in its local tree, without first requesting every intervening level. The sender may skip levels and stream intermediate subtrees of comparable population, reducing sequential round trips. Population estimates used for scheduling are not substitutes for checking the committed set. + +Each channel independently randomizes the order of streamed subtrees, for example using an ephemeral channel secret. If several neighbors possess the same set, their different schedules tend to expose different missing ranges first. Recovered objects immediately update the common inventory and can satisfy work pending on other channels. This reduces duplicate transfers in expectation; it does not guarantee disjoint work. + +Restricting comparisons to sparse-tree prefixes is a specialization of the range approach. It does not automatically inherit bounds for arbitrary equal-population range partitions; the cost of representing such partitions by multiple prefixes requires evaluation. + +The range protocol remains usable without a homomorphic fingerprint. Rateless reconciliation, described below, has additional requirements. + +### Shared-knowledge baselines + +Acknowledged set commitments provide evidence of data already shared with a neighbor. Application-level references can compactly supply further evidence; a block DAG is one such application. Let $S$ and $T$ be the two sets being reconciled and let $K$ be a mutually identified subset of their intersection. Then + +$$ +(S\setminus K)\mathbin{\triangle}(T\setminus K)=S\mathbin{\triangle}T. +$$ + +Removing $K$ reduces the number of elements to encode without changing the difference to recover. This is useful even when the residual elements are widely scattered across the key space. + +In either setting, acknowledged inventory roots and object receipts can establish shared knowledge. In the DAG setting, additional neighbor-specific information is available: + +* A neighbor's validated blocks identify payloads and causal ancestors that the local node has also obtained. +* Blocks from that neighbor which build upon local blocks acknowledge the corresponding causal closure. +* The local transmission log identifies objects already sent to that neighbor. Until receipt is established, this is speculative knowledge rather than an acknowledged common baseline. + +Baseline references must determine the same $K$ at both endpoints. A local belief about a neighbor's inventory is insufficient. A baseline can be named by agreed DAG frontiers; its use is restricted to elements common to the sets in the current exchange. Knowing an object does not imply that it belongs to every advertised block payload. For cumulative causal inventories, a shared ancestral frontier supplies this subset directly. + +The original root remains the target commitment. Residual reconciliation need not create a separate authenticated tree for each neighbor. PinSketch subtraction, for example, can remove a common baseline algebraically, whereas range traversal can skip established shared subtrees or account for known leaves. + +A Byzantine neighbor may acknowledge data it does not possess. Such an acknowledgement does not permit either endpoint to accept unchecked contents. Missing data can still be requested, and the exchange can fall back to a smaller baseline or none. Baseline agreement and fallback messages remain to be encoded. + +### Hybrid recursive/rateless set reconciliation + +The second optimization direction combines range reconciliation with rateless streams. + +An advertised root may be followed immediately by a rateless reconciliation stream for that set. This uses the time before a range-based reply arrives. The `rateless` candidate uses an elliptic-curve multiset hash (ECMH) for its homomorphic cell checks, together with a channel-specific sampling schedule.[^riblt] The ECMH and adversarial-set adaptations are distinct from the published RIBLT construction and require their own analysis.[^ephemeral-ecmh] + +A range reply narrowing the work to subsets is an **unconditional stop signal** for the parent stream. Stopping does not depend on whether its decoder has completed. Further optional streams are scoped to the unresolved subsets. The exchange identifies the root, prefix and stream parameters so that delayed parent cells cannot be mistaken for child cells. + +Streams with different sampling parameters have separate decoder state. Recovered objects can be shared across decoders; differently parameterized cells cannot be pooled as one sketch. Previously received cells may be retained locally, but stopping a stream ends further transmission for that scope. + +The relevant robustness target includes honest peers reconciling sets whose elements were chosen adversarially by third parties. Channel-specific schedule randomness and ECMH checks address different concerns: deliberate concentration in the sampling schedule and false cell recovery, respectively. Neither compels a malicious neighbor to send data. Parameter selection and bounds on decoding work remain open. + +### Sparse differences and `rateless` + +A small difference spread throughout a large set can require many tree comparisons. PinSketch is a candidate for resolving such ranges directly. A capacity-$c$ sketch of $b$-bit nonzero field elements occupies $bc$ bits and can recover a symmetric difference of at most $c$ elements. Sketches combine by XOR.[^minisketch] + +Capacity depends on the difference size, while construction work also depends on the population being encoded. Straightforward construction over $N$ elements costs $O(Nc)$ field operations. Conventional decoding has quadratic scaling in the supported difference size. A shared-knowledge baseline reduces $N$ without reducing the required capacity for the same difference. + +Two extensions are under evaluation: + +| Variant | Operation | Tradeoff | +| --- | --- | --- | +| Additional syndromes | Extend the PinSketch for the same range without retransmitting earlier syndromes. | Increasing capacity increases computation; reuse of failed decoding work requires implementation support. | +| Small PinSketch cells | Use small-capacity sketches with a rateless sampling sequence, allowing a cell to recover several residual elements. | Bounds local decoding work, but changes the peeling algorithm and requires new performance and robustness analysis. | + +In either case, a narrowing range reply stops transmission for the parent scope. Computational budgets can trigger subdivision rather than further sketch expansion. Small fixed-capacity sketches cached at selected tree nodes can reduce repeated encoding work, at a storage and update cost. Channel-dependent sampling limits reuse of cached sampled sketches. + +Decoding beyond capacity can return a false candidate rather than an explicit failure. Sketch results are provisional until checked against the committed data. A sampled-cell construction must account for false recovery before propagating it through peeling; checking only the final root detects failure but does not bound wasted decoding work. Mapping message hashes into smaller field elements also requires collision handling. These details remain part of the sketch profile, not changes to the DAG semantics. + +## Resource bounds and validation + +Outstanding neighbor exchanges, speculative decoder work and retained unresolved roots require explicit bounds. An advertised root scopes requests but does not establish that its set is small or admissible. Duplicate data does not earn repeated processing rights. Retrieved contents are checked against commitments; application validity is checked by the consuming protocol. + +## Open specification choices + +Remaining choices include canonical tree encodings; advertisement scopes and retention; baseline references and fallback; range scheduling; rateless parameters and ECMH checks; field-element mapping and sketch validation; and computational and bandwidth budgets. Measurements should vary set population, symmetric difference, latency, device capability and number of neighbors independently. + +The reconciliation mechanism reports completion for a specified scope. Whether that completion permits publishing a block or advancing a phase belongs to the consuming protocol. + +## References + +[^libra]: Zachary Amsden et al. [The Libra Blockchain](https://sonnino.com/papers/libra.pdf), sparse Merkle tree discussion. + +[^bec]: Martin Kleppmann and Heidi Howard. [Byzantine Eventual Consistency and the Fundamental Limits of Peer-to-Peer Databases](https://arxiv.org/abs/2012.00472), §5. + +[^rbsr]: Aljoscha Meyer and Konstantin Scherer. [Range-Based Set Reconciliation Without Homomorphic Hashing](https://aljoscha-meyer.de/assets/landing/rbsr_nonhomomorphic.pdf). + +[^riblt]: Lei Yang, Yossi Gilad and Mohammad Alizadeh. [Practical Rateless Set Reconciliation](https://arxiv.org/abs/2402.02668). + +[^ephemeral-ecmh]: [Ephemeral ECMH](https://nothingmuch.github.io/ephemeral-ecmh/), on whether small elliptic curves can serve as the checksum in rateless set reconciliation, against adversarially chosen items, with a public beacon instead of a shared secret. + +[^minisketch]: [Minisketch: an optimized library for BCH-based set reconciliation](https://github.com/bitcoin-core/minisketch), including its mathematical explanation and incremental-decoding discussion. diff --git a/docs/subset_sum_density.md b/docs/subset_sum_density.md new file mode 100644 index 0000000..dbfbf85 --- /dev/null +++ b/docs/subset_sum_density.md @@ -0,0 +1,67 @@ +--- +type: concept +title: Subset sum density +status: draft +stale_after: 2026-11-06T00:00:00Z +--- + +# 🤖 Subset sum density + + + +How many subsets of a multiset of effective values sum into a target interval. It's a quantity that cost function terms reuse, not a term on its own: + +- The [subset sum ambiguity](cost_function_subset_sum_ambiguity.md) term checks how well the sumsets of the other users' inputs, and after the fact their outputs, cover the sumsets of the user's inputs and outputs. +- The [consolidation penalty](cost_function_consolidation.md) uses the same coverage for the user's inputs. + +Dense subset sums give many readings of which inputs funded which outputs. Where the subset sums of different users' coins on the same side overlap, they also give readings of which coins belong to which user. This chapter covers how the index is estimated, and how co-spend proposals and the aggregator optimize it. + +## Effective values + +Effective values are computed at the [coalition formation proposal](coalition_formation.md)'s feerate $f$, with no adjustments. They form the multiset whose subset sums are counted. + +- This isn't a perfect model, but it's one of the plausible scenarios the adversary must consider. +- For all the adversary knows, the feerate was the coalition formation's and every adjustment was 0. So any reading found under it is one the adversary can't rule out. + +## Estimates and enumerators + +- **Saddle point estimate.** [Sasamoto, Toyoizumi and Nishimori](https://arxiv.org/abs/cond-mat/0106125) estimate the number of subsets summing to a target. + - Their grand partition function, $\prod_j (1 + e^{\mu - \beta a_j})$, counts subsets by size as well as by sum. + - It's a product over inputs, so adding or removing coins changes only their factors. Re-solving $\beta$ and $\mu$ costs $O(n)$ per Newton step. + - It's only valid where the number of solutions is large. +- **Distinct sums.** [Salas](https://arxiv.org/abs/2507.15511) enumerates the $U$ distinct subset sums in $O(U n^2)$ time, or $O(U n)$ expected, independent of the range. It keeps one witness subset per sum, but gives no counts. +- **Sparse convolution.** Bringmann, Fischer and Nakos convolve nonnegative vectors in time near-linear in the number of nonzero entries of the output, [with a Monte Carlo algorithm](https://arxiv.org/abs/2105.05984), and [deterministically or Las Vegas](https://arxiv.org/abs/2107.07625). + - Convolving the count vectors of groups of coins gives the explicit sumset with its counts, not only which sums are reachable. + - Where the distinct sums are far fewer than the range, this is cheaper than a table over the whole range. +- **Bitmaps and counts.** Bellman's algorithm over a bounded range, as implemented by the [subset sum ambiguity](cost_function_subset_sum_ambiguity.md) term. + +## Co-spend proposals + +- **Challenges.** A co-spend proposal can require density with challenges, and attach a reward for them in the surplus. Aggregators aren't guaranteed a payout. + - $\rho$, the interval width and a subset size cap $q_{\max}$ are difficulty parameters. Co-spend proposals challenge whatever they like. + - A simple client can send a single-UTXO proposal with a high density requirement and a large surplus, delegating the search over the order book to the aggregator. +- **Perturbation** ([fungi-protocol/docs#75](https://github.com/fungi-protocol/docs/issues/75)). Given the convolution implied by a co-spend proposal, add desired values, e.g. standard denominations, and check whether the set becomes dense enough. + - Simulated annealing makes the same moves, adding or removing a coin. It can generate co-spend proposals for the decision tree, and optimize coin selection. + - Unlike branch and bound, it needs no bounds on the cost function. + +## Aggregator + +The aggregator searches over combinations of co-spend proposals, for ones whose inputs solve each other's challenges easily. + +- **Terms.** A combination's terms must intersect. The aggregator determines the feerate and the other concrete parameters from the intersection, and the feerate fixes the effective values. +- **Score.** The interval is only known once the coalition formation proposal is hashed. So a challenge is easy if density is high across its whole range of interval positions, by the saddle point estimate. + - It respects $q_{\max}$, since it counts by size. + - It doesn't check disjointness. The prover does. +- **Moves.** Add or remove a co-spend proposal, as in simulated annealing. + - Seed with proposals that offer large surpluses. + - Prefer additions that raise the score in the most challenge ranges per unit of weight. Proposals whose challenge ranges overlap reinforce each other. + - Each addition brings its own challenges, which must be easy too. + - Accept a combination once every challenge is easy. Among those, prefer larger rewards within the weight limit. +- **Grinding.** Rehashing for an easier interval is acceptable. Finding better coins to aggregate with is easier. +- **Prover.** Once the combination is fixed and hashed, solve each challenge interval $I = [c, c + w]$ for $\rho$ disjoint subsets of the inputs. If it fails, perturb the combination and rehash. + 1. **Bounds.** Give up if $\rho > \lfloor \sum a / c \rfloor$, or if $\rho > \lfloor n / q_{\min} \rfloor$, where $q_{\min}$ is the number of largest values needed to reach $c$. + 2. **Singletons** by binary search. **Pairs** by two pointers, then a maximum matching. + 3. **Larger subsets.** Run Bellman's algorithm over the unused coins, storing per cell the smallest subset size up to $q_{\max}$ and the last item. Extract a smallest subset, remove it, and repeat. + - Round values down to multiples of $\Delta$, and target $[c, c + w - q_{\max} \Delta]$, so exact sums stay in $I$. + 4. **Repair.** If stuck below $\rho$, move or swap coins between subsets and the unused pool. Stop at $\rho$. +- **Encoding.** One label per input in $\{0, \dots, \rho\}$, with 0 for unused. The subsets are disjoint by construction, and verification is $O(n)$. diff --git a/docs/sybil_resistance_index.md b/docs/sybil_resistance_index.md new file mode 100644 index 0000000..c3e32f3 --- /dev/null +++ b/docs/sybil_resistance_index.md @@ -0,0 +1,166 @@ +--- +type: concept +title: Order book size estimation +status: draft +stale_after: 2026-11-06T00:00:00Z +--- + +# 🤖 Order book size estimation + +A relatively conservative estimate of a lower bound $L$ on the number of candidate coins a transaction's inputs were selected from, and a [median estimate](#median-estimate) $\hat{N}$ of that number. Both measure the effect of the selection preferences in the [randomized selection](cost_function_randomized_selection.md) chapter. The [Sybil resistance](cost_function_sybil_resistance.md) term uses $L$, and the [Counterfactual paths](cost_function_counterfactual_paths.md) chapter uses $\hat{N}$ for its degree sequence. + +## Candidates + +**Candidates** are the coins whose owners are active and offering them in the order book. $N$ is how many there are. It isn't directly observable. + +- Under the actual block hash $t$, the candidates' hashes are uniform. The selected inputs are a subset. If the selection depends on the hashes, the subset deviates from uniform, which bounds $N$ from below, much like estimating the hash rate from proofs of work. +- Candidates must be fixed before $t$ is known. +- Each candidate is one draw. Spending the same coin twice isn't a second draw. +- To exhibit the deviation, an adversary must control all the candidates, not just the selected coins. + +## Hashes + +- $x_i = H(t, i)$ for each input outpoint $i$. $H$ is a tagged hash, truncated to 64 bits and read as an integer modulo $Q = 2^{64}$, so the $x_i$ are points on a circle. +- Truncation keeps the guarantees below: the truncated hashes are uniform on the grid of $Q$ points, and the extra grid unit per span covers the rounding. + +## Pool size bound + +For the $n$ input hashes of a transaction and a confidence parameter $\delta$: + +1. **Spans.** Sort the hashes around the circle. An $m$-span runs from a hash to its $m$-th successor. Its width is the distance between them, plus one grid unit. +2. **Sums.** For each $1 \le m \lt n$ and $1 \le r \le n/m$, $T_{m,r}$ is the smallest total width of $r$ spans with disjoint interiors. Spans may share endpoints. Let $\tau_{m,r} = T_{m,r} / Q$. + - For $m = 1$, this is the sum of the $r$ smallest gaps. + - Larger $m$ detects groups of nearby hashes. +3. **Tail bound.** For a hypothetical pool of $M$ candidates: + $$ + q_{m,r}(M) = \min\left(1, \frac{M^{r(m+1)} \, \tau_{m,r}^{rm}}{r! \, (rm)!}\right) + $$ +4. **Score.** With weights that sum to 1 over all $m, r \ge 1$: + $$ + S(M) = \sum_{m,r} \frac{q_{m,r}(M)^{-1/2} - 1}{m(m+1)r(r+1)} + $$ +5. **Bound.** $L$ is the smallest integer $M \ge n$ with $S(M) \lt 1/\delta$. + +### Why it's conservative + +$P(L \gt N) \le \delta$ for every selection strategy. This includes choosing the inputs, and how many, after seeing the hashes, in order to maximize $L$. + +- **One placement.** In a uniform pool of $M$, the total of $r$ fixed disjoint blocks of $m$ gaps is $\text{Beta}(rm, M - rm)$. Its lower tail is at most $(M \tau)^{rm} / (rm)!$. +- **Every placement.** There are at most $M^r / r!$ ways to place the blocks. A union bound covers taking the minimum after seeing the pool. +- **Subsets.** Each selected $m$-span contains at least $m$ gaps of the full pool. So no subset has smaller totals than the pool itself. The extra grid unit per span covers rounding hashes to integers. +- **Combining.** Each $q$ is a conservative p-value, so $E[q^{-1/2} - 1] \le 1$. By Markov's inequality, $P(S(N) \ge 1/\delta) \le \delta$. The terms may be dependent. + +### Properties + +- **Monotone.** At a fixed beacon and $\delta$, adding inputs never lowers $L$. So withholding coins from a fixed pool can't raise it. +- **Symmetric.** No position on the circle is special. Rotating or reflecting the hashes doesn't change $L$, so it doesn't matter which hashes count as lucky. +- **All inputs.** Every input's hash enters through the spans. +- **Integer arithmetic.** Each weighted term is rounded down to a multiple of $2^{-64}$, using integer square roots. Rounding only lowers the score, so it keeps both guarantees. +- **Caps.** Leaving out the terms above a fixed $m$ or $r$ keeps both guarantees: their weight goes unused. It costs power. +- **Cost.** $O(n^3)$ arithmetic operations over all $m$, on integers of $O(n (\log Q + \log M))$ bits. + - A Python reference implementation takes a median of 25 ms for 64 inputs and 92 ms for 100. + - A Rust implementation takes 0.01–2.5 ms for up to 100 inputs, and 17 ms for 200, on an Apple M4. It decides in floating point, and falls back to the exact integer score near the threshold, so it returns the same $L$ as the reference. + +## 🤖 Median estimate {#median-estimate} + +$\hat{N}$ inverts the joint sums at their median instead of at $\delta$. For a chosen $m$ and $r$, it is the smallest $M \ge n$ at which the observed $\tau_{m,r}$ is at least the median of the same quantity for a uniform pool of $M$ candidates. + +- **Same construction as $L$.** The spans and sums are those of the [pool size bound](#pool-size-bound), with $1/2$ in place of $\delta$. For $m = 1$, the quantity is the sum of the $r$ smallest gaps, whose exact law is known.[^holst] +- **Median-unbiased only for the pool's own spans.** $\hat{N}$ reads $N$ correctly in the median only when the observed spans are spans of the full pool, as when the whole pool is observed. +- **Reads low under weaker selection.** As in [Why it's conservative](#why-its-conservative), no selected set has smaller joint sums than the pool itself, so $\hat{N}$ is lower. +- **Reads high on small pools.** It spends no $\delta$, so nothing bounds how often it exceeds $N$. +- **Not the largest over $m$ and $r$.** Taking the largest $\hat{N}$ over all $m$ and $r$ reads high. +- **No lowest error estimate.** Without a probability law for the selection, no estimator has lowest error. The tails are heavy, so estimators are compared by quantiles rather than by mean squared error. + +Measured in the prototype for a related statistic, the median inversion of the $k$-th smallest gap: + +- With clustering and $n \ll N$, it reads about $\sqrt{n N}$. At $N = 10^4$ and $n = 200$, the median reading is $0.15 N$. +- At $N \le 2n$, it overshoots $N$ in 28% of runs, and in 22 of 40 runs at $n = N = 200$. + +## Finding the block hash + +Someone examining a transaction doesn't know which block hash the selection used. They can guess it from the confirmation time, or from the nLockTime, but not exactly. So they evaluate every candidate $t$, at $\delta / W$ each for $W$ candidates, and take the largest $L$. + +- **Candidate block hashes.** 1000 or more for every transaction that looks like a CoinJoin, all mined after its inputs confirmed. +- **No false beacon.** Under a block hash the selection didn't use, the input hashes are independent and uniform: a fully observed pool of $n$. So $L \gt n$ with probability at most $\delta / W$ for each such block hash, and at most $\delta$ for all of them. +- **Screen.** Only the $m = 1$ terms, sums of the smallest gaps, are evaluated for every block hash, once, at $M = n$. That is a sort and one score. The full bound is evaluated only when the screen gives $L \gt n$. The screen's threshold is fixed, so both guarantees hold. +- **Cost.** With $W = 1000$ and up to 100 inputs, 2–9 ms per transaction in Rust, mostly hashing (about 75 ns per hash) and the screen (1–4 µs per block hash). Hashes may be cached per outpoint and block hash. + +### Simulation + +1000 random block hashes per transaction, $\delta = 0.05$, 32 transactions per configuration, using the Python reference. + +- **No block hash used.** Inputs drawn uniformly. In all 96 transactions ($n$ = 16, 32, 80), no block hash gave $L \gt n$. At $\delta$ instead of $\delta / 1000$, 25 of them had one, up to $16 n$. +- **One block hash used**, by lowest hashes, XOR pairs or the tightest cluster, with $N$ = 1000 or 100,000. In all 576 transactions, it gave the largest $L$, no other gave $L \gt n$, and $n \lt L \le N$. +- **Cost of the split.** Median $L$ at $\delta / 1000$ is lower than at $\delta$ by about 2.6 times at $n = 16$, 1.7 at $n = 32$ and 1.3 at $n = 80$. + +### Caps + +Median $L / N$ of the used block hash with $N = 100{,}000$ and $n = 80$, at $\delta / 1000$: + +| Cap | Lowest hashes | XOR pairs | Cluster | +|---|---:|---:|---:| +| $m \le 1$ | 0.010 | 0.329 | 0.013 | +| $m \le 8$ | 0.108 | 0.329 | 0.167 | +| $m \le 16$ | 0.156 | 0.329 | 0.238 | +| $m \le 4$, $r \le 8$ | 0.051 | 0.106 | 0.075 | +| none | 0.225 | 0.329 | 0.350 | + +- **Don't cap $r$.** Pairs need many $m = 1$ terms. +- **Capping $m$** loses clusters and lowest hashes. The full bound runs on about one block hash per transaction, so it can stay uncapped up to about 100 inputs. +- The screen missed the used block hash in 1 of 32 transactions (lowest hashes, $N = 1000$, $n = 16$). + +## Measurements + +From the prototype, with $\delta = 0.05$. Nine selection strategies are applied to the same candidate hashes in each trial. + +Median $L$ with $N = 1000$, over 32 trials: + +| $n$ | XOR pairs | Lowest hashes | Closest pairs | Uniform | +|---:|---:|---:|---:|---:| +| 4 | 57.5 | 11 | 66.5 | 4 | +| 16 | 227.5 | 116.5 | 265 | 16 | +| 32 | 346.5 | 225 | 378.5 | 32 | +| 100 | 400 | 327 | 457.5 | 100 | + +- With $N = 100{,}000$ and $n = 80$, median $L / N$ ranges from 0.28 (lowest hashes) to 0.47 (two clusters). +- **Uniform selection** gives $L = n$. A large pool shows nothing unless the selection is biased. +- **Overshoot.** $L \gt N$ in none of the 1,152 selected sets at $N = 100{,}000$, and none of the 2,304 at $N = 1000$. + - This doesn't prove coverage. The proof does. + - The guarantee bounds how often $L$ exceeds $N$, not by how much. + +### Tighter alternatives + +Overestimating $N$ awards credit for Sybil resistance that isn't there. That is worse than underestimating it, so the bound above is preferred over tighter ones. + +- **Density profile.** Anchored ranks, Beta spans and Rényi gap ranks, at $\delta/3$ each. + - Median $L / N$ between 0.66 and 0.78 in the same comparison. + - $L \gt N$ in 5 of the 1,152 sets, by up to 1.30 times, and in 11 of the 2,304. + - Its returned bound has only been tested to be monotone, not proved. It also treats fixed positions on the circle specially. +- **Gap curve.** Accumulates the evidence of every ordered gap, with fixed weights $1/r$ and power $9/10$. + +## Limitations + +- **Candidates, not owners.** $L$ bounds the number of candidate coins, not the number of users. One owner with many coins is many candidates. +- **Values.** The adversary's cost is proportional to $L$ only if the selected coins' values are typical of the candidates. +- **Lower bound only.** $L$ isn't an estimate of $N$. There is no likelihood for the selected set given $N$. +- **Power.** The fixed weights, the union bound and the square root lose power. + - The minimum totals discard some of where the hashes are. + - In a fixed example with one dense cluster, adding a second cluster at half the density raised $L$ by about 3%. + - Splitting $\delta$ over 1000 block hashes costs most at small $n$: about 2.6 times at $n = 16$. +- **Concealment.** A selection strategy can keep $L$ near $n$. Monotonicity only prevents raising $L$ by withholding coins. +- **Review.** The calibration argument hasn't been reviewed outside the prototype. + +## Open questions + +- Which $m$ and $r$ should $\hat{N}$ use, or how should they be combined? +- How should the median be computed for $m \gt 1$, and for large $M$? +- Can $L$ be updated as inputs are added? A wallet compares many candidate transactions. +- **More power.** Options next to the bound above: + - Combine the terms by a weighted minimum, rejecting $M$ if any $q_{m,r} \le w_{m,r} \delta$, instead of the square root. This loses less to the split over block hashes. + - Tighter tails for $m = 1$. In a uniform pool, the gaps are exponential variables divided by their sum.[^renyi] Sums of the smallest gaps then have an exact law,[^holst] but it is impractical for large $n$ and small sums. A Chernoff bound on this form is practical, and gains about 1.3–1.6 times in $L$, only for large $r$. Nothing comparable is known for $m \gt 1$. + - Anchored ranks for the per-input preference, which are tighter for lowest hashes, at part of $\delta$. They treat the anchor specially, so symmetry is lost. + +[^renyi]: A. Rényi, "On the theory of order statistics", *Acta Mathematica Academiae Scientiarum Hungaricae* 4 (1953), 191–231, [doi:10.1007/BF02127580](https://doi.org/10.1007/BF02127580). + +[^holst]: L. Holst, "On the lengths of the pieces of a stick broken at random", *Journal of Applied Probability* 17(3) (1980), 623–634, [doi:10.2307/3212956](https://doi.org/10.2307/3212956). diff --git a/docs/tactics.md b/docs/tactics.md new file mode 100644 index 0000000..6723546 --- /dev/null +++ b/docs/tactics.md @@ -0,0 +1,30 @@ +--- +type: concept +title: Tactics +status: draft +stale_after: 2026-11-06T00:00:00Z +--- + +# Tactics + +🤖 A procedure for constructing the decision tree that the [cost function](optimization_framework.md) evaluates, using the terms in the [Privacy liability terms](cost_function_concrete.md) chapter. The input is the current wallet state. The output is a tree whose edges are actions and whose nodes are successor wallet states. + +## 🤖 Inputs and output {#inputs-and-output} + +The wallet state contains the spendable UTXO set, inflight transactions, current protocol observations and beliefs, policy parameters, and an ordered queue $Q=(q_1,\ldots,q_n)$ of pending actions. An entry may be a PSBT fragment, a lone `TxOut` for an intended payment, or an arbitrary transaction fragment. This procedure calls every such entry an *intent* without assuming that it already defines a complete transaction. + +The edges of the tree are the actions listed in the [Optimization framework](optimization_framework.md) chapter, together with constructing, signing, broadcasting, or replacing a unilateral transaction, and deferring or skipping an intent. + +Each path must be executable from the current wallet state. Each leaf denotes the resulting wallet state after a mutually exclusive plan, including its remaining queue and unilateral fallbacks. + +🤖 The [Bottom-up construction](bottom_up_construction.md) chapter builds the tree from the leaves toward the root: it partitions the queue of intents, selects coins, constructs change, extends outcomes with order book coins, expands leaves into action sequences, and brackets and backs up their values. + +## Re-evaluation + +Each path down the tree is a plan, i.e. a pure strategy. Since announcements and co-spend proposals are actions like any other, they are planned as well. New alternatives can be added to the tree, or a whole new tree can be computed from any state and combined with the current one as further alternatives. + +Because the tree is potentially large and costly to generate and evaluate, most of it is generated up front. It is then updated as co-spend proposals, coalition formation proposals, and the auxiliary inputs of committed transactions are learned. + +🤖 The decision loop is specified in the [Mixed strategy](mixed_strategy.md) chapter. The tree is extended or rebuilt within the available compute budget, and re-evaluated with current brackets and action-duration estimates, whenever the pending-action queue changes or other new information arrives. + +🤖 Relevant events include new co-spend proposals, changes to randomization terms during coalition formation, fee or time updates, and observing additional inputs before committing to particular output choices. Event-driven re-evaluation allows the wallet to exploit new information without requiring exhaustive precomputation of the partition lattice. diff --git a/docs/transaction-construction.md b/docs/transaction-construction.md new file mode 100644 index 0000000..c3a1d94 --- /dev/null +++ b/docs/transaction-construction.md @@ -0,0 +1,62 @@ +--- +type: Specification +title: Transaction construction +description: Content and state synchronization, the phases, the optimistic and recovery tracks, and what the validity proofs enforce. +status: draft +stale_after: 2027-04-23T00:00:00Z +--- + +# Transaction construction + +🤖 Transaction construction starts from an accepted coalition formation proposal and ends with a signed transaction. This chapter describes it in the abstract. Its sub-chapters define the [block DAG](block-dag.md) that the tracks share, and describe each track. + +## 🤖 Content and state {#content-and-state} + +Construction synchronizes two different things: + +- **Content**: the transaction-level messages, such as inputs, outputs, fee contributions and their proofs. The [validity proofs](validity-proofs.md) constrain which content is valid. +- **State**: which admitted content is in the agreed state of each phase. State synchronization uses agreement-level messages, the validator blocks. Validity proofs do not cover blocks. Blocks have their own mechanisms, such as the [nonce commitments](block-dag.md#nonce-commitments-and-compact-equivocation-evidence) that expose the key of a validator that equivocates. + +Transmitting either between peers is described in [peer set reconciliation](set-reconciliation.md). + +## 🤖 Phases {#phases} + +🤖 The initial inputs are already fixed by the accepted coalition formation proposal. The *optimistic phases* add content without validity proofs. They concern transaction data, and are not to be confused with the [optimistic track](optimistic-track.md), which concerns agreement. The optimistic phases are the semi-honest construction, including when it is used in the Byzantine setting. + +🤖 Every message is [keyed](optimistic-track.md#keyed-and-anonymous-phases): it relates to one input, one output or one fee contribution. Phases differ in whether their keys are listed when the phase opens or arrive anonymously. + +| Phase | Keys | Content | Next | +| --- | --- | --- | --- | +| 1. Kickoff | listed: initial inputs | acknowledgement of the proposal | 2 | +| 2. Optimistic auxiliary inputs | anonymous | auxiliary inputs, without proofs | 3 | +| 3. Optimistic outputs and fee contributions | anonymous | outputs and fee contributions, without destination commitments or proofs | balance zero: 8; overflow: 4 | +| 4. Initial-input proofs | listed: initial inputs | commitments to allocations of funds and vbytes | 5 | +| 5. Auxiliary-input proofs | anonymous | proofs authenticated by each auxiliary input's own online key, consuming initial inputs' vbyte allocations | 6 | +| 6. Allocation registration | anonymous | proofs of allocations against the session root | 7 | +| 7. Output proofs | anonymous | proofs of coverage against the registered-leaf root | 8 | +| 8. Signatures | listed: final inputs | input signatures | done | + +🤖 Phases 4 to 7 are the proven phases. They run only if the optimistic outputs and fee contributions overflow the available balance. The optimistic outputs are then discarded, and the proven phases use fresh, unguessable output ids. Once phase 5 closes, both input-proof sets determine the session root; the closed registration set determines the registered-leaf root. Output scripts are authorized as specified by the [validity proofs](validity-proofs.md). On the optimistic track, only a balance of zero continues to signatures. Unclaimed balances are possible only on the [recovery track](recovery-track.md), which is a different termination path. How output values are chosen is a matter of strategy, not of this protocol. + +Each phase closes on a stable state before the next one starts. The [optimistic track](optimistic-track.md#phase-closure) says why, and gives the acknowledgement rule for each kind of phase. The [overview](overview.md) describes the honest, semi-honest and Byzantine settings these phases run in. + +## 🤖 Tracks {#tracks} + +Both tracks use the [block DAG](block-dag.md). + +- [**Optimistic track**](optimistic-track.md), with threshold $t = n$. It is asynchronous, and phases advance by unanimous acknowledgement. On its own, it is sufficient in the honest and semi-honest settings. +- [**Recovery track**](recovery-track.md), with $t \lt n$. It is optional, and assumes synchrony or partial synchrony. It turns a stalled phase into a recovery coalition formation proposal. + +## Validity proofs + +🤖 [Validity proofs](validity-proofs.md) are needed only once overspending is detected. They reduce the validity of transaction-level messages to omission faults: a participant can still withhold a message, but cannot get an invalid one accepted. They enforce: + +- **No inflation.** Amounts are non-negative, and the outputs sum to at most the value of the inputs. What no output claims is fee. +- 🤖 **Flood protection.** In the proven phases, auxiliary inputs consume initial inputs' vbyte allocations, registrations consume input slots, and each output claims a registered leaf. In the optimistic outputs phase, every output or fee contribution accounts for at least 1 sat, so the available input balance bounds contributions before overflow. An overflow signal can trigger proving, but the phase still closes under its normal agreement rule. These are contribution bounds, not bounds on all network traffic. +- **Session binding.** No statement can be replayed in another session. + +🤖 They enforce this without revealing how a participant splits its inputs' value among its outputs and payments. Payment satisfaction is checked by counterparty confirmation before signing, as the [concurrent PSBT specification](psbt-concurrent.md#confirmation-of-successful-payment-prior-to-signing) defines. In the proven phases, a receipt additionally proves that the payment allocation was claimed; it does not replace confirmation. + +In the optimistic phase, no proofs are needed if every participant can verify that all of its funds are accounted for in its outputs and fees contributions, and no overspending has occurred, and everyone acknowledges that exact state. Overspending triggers proving so that contentious outputs and fee contributions can be validated. An anonymous, oversized fee contribution permits any participant to abort the optimistic phase and force validity proofs to be required. + +Only valid transactions have consequences for the owners of the inputs, because an invalid transaction cannot actually spend any coins, even if fully signed. The sense in which the fragments themselves must be valid according to the proofs is that when combined they would result in a valid transaction if it were fully signed. Taken together with the incentive compatibility assumption, the lack of obstruction removes any reason for honest participants to withhold their signatures: by following the protocol their funds will be sent to the destination they intended, and since this applies to all participants, this removes any valid reason for honest participants to withhold their input signatures. diff --git a/docs/transport-interfaces.md b/docs/transport-interfaces.md new file mode 100644 index 0000000..a5ee5cf --- /dev/null +++ b/docs/transport-interfaces.md @@ -0,0 +1,80 @@ +--- +type: Specification +title: Abstract transport interfaces +description: Send, receive and bidirectional channels, the kinds of messaging the protocol needs, and broadcast built from peer to peer channels. +status: draft +stale_after: 2027-04-22T00:00:00Z +--- + + + +# Abstract transport interfaces + +🤖 These interfaces give the protocol an abstract syntax for messages. Every part of the protocol is described in terms of messages: who sends them, who receives them, and what a message reveals about its sender. How a message travels is up to the transport. + +🤖 Delivering messages is the transport's job. Its non-malicious delivery faults and delays constrain the timing model the layers above can assume. Agreeing on what was delivered belongs to those layers. Protocol timeouts need not match transport timeouts; see the [communication models](recovery-track.md#fault-tolerance-under-different-communication-models). Wire encodings are out of scope. + +## 🤖 Channels {#channels} + +* A **send channel** accepts messages, one per send. +* A **receive channel** yields messages, one at a time. +* A **bidirectional channel** is both. Its two directions may carry different message types. + +A channel may offer only one direction, and a participant needs only the direction it uses. A receive channel need not belong to one sender: some transports deliver every message for an address to one receive channel. + +The protocol should make progress even if a channel delivers only one message at a time. In the asynchronous and partially synchronous models, the network adversary can already impose this. + +## Kinds of messaging + +With some well-defined way to transmit messages from one peer to another, we can start to reason about how synchronization between peers can happen by using interactivity. Communication serves two purposes: peers exchange payment details directly with their counterparties, and send transaction contributions to the group as a whole. + +In order to realize peer-to-peer channels, any transport that provides authentication, integrity and confidentiality may be used. This allows peers to send messages to each other directly, for initiating as well as carrying out transaction construction. + +🤖 The protocol needs three kinds of messaging: + +| Kind | Sender | +| --- | --- | +| Peer to peer | Authenticated | +| Peer to group | Anonymous | +| Peer to world | Anonymous | + +🤖 Peer to group and peer to world are both broadcast. In line with the literature on reliable broadcast, this specification uses "broadcast" for both. They differ in the broadcast domain: + +* a **group** is the participants of one session, such as a transaction construction session. Peer to group is also called multicast. +* the **world** is open to anyone, such as the readers of a public order book. + +🤖 Some uses: + +| Use | Direction | Sender | +| --- | --- | --- | +| Session initiation with known peers (honest and semi-honest settings) | Bidirectional | Authenticated | +| Interactive payments: notification and confirmation for net settlement | Bidirectional, reliable, to one peer | The receiver is authenticated and can reply. The sender need not be authenticated, and game theory suggests it shouldn't be. | +| Offering co-spend proposals in coalition formation | Bidirectional | Sender anonymous | +| Anonymous broadcast within a session, such as transaction outputs in the semi-honest and Byzantine settings | To the group | Message unlinkable and metadata hiding | + +## Unlinkability + +An authenticated channel may identify the sender of a message, which would be problematic for this notion of privacy. Even if the sender isn't authenticated, transport-related metadata such as IP addresses can leak information about the sender. If transaction fragments are exchanged this way, this can indicate links between inputs and outputs that belong to the same user, even when the final transaction would leave those relationships ambiguous to an outside observer. This is an undesirable trust assumption. + +Preserving privacy requires anonymous broadcast to the group. Overlay networks such as Tor can be used to anonymously send messages to peers for relaying. The privacy guarantees of the underlying transport form the basis of message unlinkability, and once a message is not linked to its owner it can be relayed even on a non-anonymous channel. While this can also be achieved without external dependencies, for example using DC-nets, this approach does not scale to large numbers of participants, and is hard to make fault tolerant in addition to still revealing transport-related metadata. + +🤖 Two properties describe what a send channel reveals to the peer that receives its messages: + +| Property | Messages linkable to each other | Messages linkable to the sender | +| --- | --- | --- | +| Message unlinkability | No | No | +| Connection unlinkability | Yes | No | + +* Leaving out a sender field does not make a channel anonymous. Identity can still leak through the transport, or be part of it, as when a connecting peer authenticates. +* Metadata hiding is always with respect to the initiator: the sender, or the side that connects. The responder is identified by its address. +* A connection unlinkable channel that carries only one message is message unlinkable. The same holds for one set of inherently related messages, such as a transaction input and its signature. Timing metadata can still link messages. + +## Broadcast from peer channels + +Group communication can be built out of peer-to-peer channels; this is known as gossip or rumor-spreading. Alternatively, a specialized broadcast channel implementation can be used. So long as each peer eventually receives all messages sent by every other peer, they will converge on the same transaction fragments, and combine them in the same way to obtain a consistent view of the unsigned transaction. + +🤖 Peer to group and peer to world are built by gossip over peer to peer channels that are sender anonymous and message unlinkable. + +🤖 A sender submits its message to a member of the broadcast domain over such a channel. From then on, peers relay it like any other message, over channels that need not be anonymous. The anonymity of a broadcast therefore rests on the channel it was submitted on, not on the channels between gossip neighbors. + +🤖 [Peer and broadcast channels](channels.md) describes the gossip. diff --git a/docs/validity-proofs.md b/docs/validity-proofs.md new file mode 100644 index 0000000..484de23 --- /dev/null +++ b/docs/validity-proofs.md @@ -0,0 +1,870 @@ +--- +type: Specification +title: Validity proofs by allocation registration +description: "Selected design: proving outputs are covered by inputs through anonymous allocation registration." +status: draft +stale_after: 2027-04-17T00:00:00Z +--- + + + +# 🤖 Validity proofs by allocation registration + +> 🤖 **Status: selected (2026-10-25).** Allocation registration was chosen +> because the payee doesn't learn the paying input, at the cost of a separate +> registration phase between the input and output proofs; see +> [Compared with other approaches](#compared-with-other-approaches). The +> code is being rewritten from scratch for Fungi. Figures marked *measured* +> come from a proof of concept on a shared machine; parts marked *proposed* +> are not implemented yet. The [open questions](#open-questions) list what is +> not specified yet. + +The [overview](overview.md#validity-proofs) explains when validity proofs are +needed: once overspending has been detected, outputs and fee contributions +must prove they are covered by input funds, without revealing how each +participant allocates its funds. This document specifies one way to do that. + +🤖 Proofs are needed only in the proven phases, phases 4 to 7 of +[transaction construction](transaction-construction.md#phases). They run only +after overflow in the optimistic outputs phase. The optimistic phases before +them carry no proofs. + +🤖 In outline: each input commits to how its value is split, with an input +proof. Each part is then registered anonymously, and each output proves +anonymously that registered parts cover its amount. The +[intuition](#intuition) below explains how, and [Statements](#statements) +specifies each proof. + +## Intuition + +### Slots, registration and outputs + +Three steps carry value from an input to an output: + +1. 🤖 **Slots.** Each input splits its value into $D = 9$ slots. Each slot + specifies an amount and a destination. The input commits to its slots with + an input proof. Initial inputs prove first, identified by outpoint; + auxiliary inputs are submitted anonymously with their proofs afterward. +2. **Registration.** Each non-zero slot is turned into a *registered leaf* by + a registration proof, posted anonymously. The proof shows the slot belongs + to some admitted input without saying which. +3. **Outputs.** An output proves that up to $K = 2$ registered leaves name it + as their destination, and that their amounts sum to its amount. It is + posted anonymously. + +A payment is just a slot whose destination is someone else's output. The +payer registers it; the payee claims it. + +Payments need no proof about the payment from the payer to the payee, no +recursion and no multi-party computation. The payer only hands the payee its +registration proof early, which is a public object anyway. + +Interactive payments and [net settlement](overview.md#net-settlement) are +in scope. The circuits check only the endpoint allocation: slots from +inputs, registered, and claimed by outputs. They have no payment variables. +Payment obligations, including net settlement (a participant without inputs +that receives from A and pays C, or a cycle of payments), are mapped onto +slots, and confirmed with counterparties, by private messages around the +proofs. This document specifies those messages for a direct payment from an +input to an output; the rest is open. $D = 9$ and $K = 2$ bound the endpoint +allocation, not the number of payments. + +### Two trees, so payer and payee never share a path + +Each proof proves membership in a tree that everyone builds from public, +agreed data: + +- the **session tree** over the inputs' slot commitments, used by + registrations; +- the **registration tree** over registered leaves, used by outputs. + +The payer's path, from slot to input, lives only inside its zero-knowledge +registration proof. The payee's path, from leaf to the registration tree's +root, is computed from public data. No input membership path crosses from +payer to payee, so the payee can't learn the paying input, and the payer +can't learn the funded output. What does pass between them is the binding +$B_k$, the registration proof and the receipt. + +### A tag per slot limits each input to D registrations + +Registration is anonymous, so something has to stop an input registering the +same slot twice. Each registration publishes a tag + +$$\mathit{tag}_i = H_\mathsf{RTAG}(\mathit{session}, s, i),\quad 0 \le i \lt D,$$ + +where $s$ is a secret the input committed to. The tag is deterministic in +$(s, i)$, so a second registration of the same slot repeats the tag and is +dropped. It is pseudorandom without $s$, so it doesn't reveal the input. This +is the idea behind periodic $n$-times anonymous authentication.[^clone-wars] +Here the bound is the number of slots, and the slot's position in the tree +supplies $i$. + +### Flood protection + +🤖 These bounds apply to the proven phases: + +- Auxiliary inputs consume vbyte allocations committed by initial inputs. +- A registration spends one of an admitted input's $D$ slots, so there are at + most $9 \times 729$ registrations under the input capacity in + [Parameters](#parameters). +- A proven output must claim at least one registered leaf, and each leaf can + be claimed by only one output. + +🤖 Before overflow, each optimistic output or fee contribution accounts for at +least 1 sat, so the input balance bounds them. These contribution bounds do not +bound all network traffic. + +### Destination fixed at commitment + +A slot commits to its destination's binding when the input proves +(*destination mode*). So the registered leaf is fully determined by the slot, +and any valid registration of a slot is identical. This is why the payee +must give the payer its binding $B_k$ before the payer's input proof. + +The payer hands its registration proof to the payee once $R_S$ is agreed, +and either one can submit it. After the payee has it, the payer can't renege +by withholding its registration. It can only refuse to sign, and then its +input is identified by outpoint. Before that, the payer can still withhold the proof itself +(see [Signing and failures](#signing-and-failures)). + +## The flow graph + +A transaction moves value from inputs to outputs. Each participant decides +how its own inputs' value is split. Some of that value goes to its own +outputs, and some to payments to other participants. + +### As a matrix + +Write the flows as a matrix $M$. Rows are sources and columns are sinks. +There are four kinds of vertex: + +- **inputs**, whose values are public; +- **outputs**, whose amounts are public; +- **the fee**, a public sink: each input's hidden excess, or fee + pseudo-outputs; +- **payment vertices**, one per payment. Each is shared by exactly one payer + and one payee, and is not labelled publicly. + +$M$ is the sum of one sparse matrix per participant, $M = \sum_j M_j$. A +participant's $M_j$ has non-zero entries only on edges at its own vertices, +or at payment vertices it shares: + +- from its inputs to its own outputs; +- from its inputs to a payment vertex, if it is a payer; +- from a payment vertex to its outputs, if it is a payee. + +A payment of $a$ from payer $j$ to payee $k$ through payment vertex $p$ +appears in two blocks: the edge into $p$ in $M_j$, and the edge out of $p$ +in $M_k$. Both edges stay in the sum. What cancels is the net flow at $p$: +$+a$ in from $M_j$, $-a$ out from $M_k$, so $p$ neither creates nor destroys +value. Contracting $p$ gives an entry of $a$ from the payer's input to the +payee's output. + +Contracting every payment vertex leaves a bipartite allocation from inputs +to outputs and the fee. Payments are structure inside its edges, and don't +change its row and column sums. Those sums are public; its entries are not. + +```mermaid +flowchart LR + subgraph payer["payer's matrix M_j"] + I1["input i (value public)"] + end + subgraph payee["payee's matrix M_k"] + O2["output o (amount public)"] + end + I1 -->|"a_change"| O1["payer's change output"] + I1 -->|"a"| P(("payment vertex p")) + P -->|"a"| O2 + I2["payee's input"] -->|"b"| O2 +``` + +### What is observable + +- **The boundary is public.** Row sums over input rows are the input values. + Column sums over output columns are the output amounts. These are exactly + the public inputs of the proofs below. +- **Each block is private to its participant.** The proofs reveal nothing + about how a participant splits its inputs beyond the boundary. +- **Each payment entry is known to its payer and payee.** The payer knows its + input and the amount. The payee knows the amount and its output. The + proofs reveal neither side to the other. +- **No one is shown the full matrix.** In particular, the proofs don't reveal + the entry from a payer's input to a payee's output. + +These hold under the stated leakage: the public boundary, what counterparties +know of their own payments, and anonymous submission. Amounts, small +anonymity sets and colluding counterparties can still reveal more. + +### How the proofs enforce it + +The proofs check that no vertex creates value, without anyone assembling +$M$: + +| Vertex | Conservation | Checked by | +|---|---|---| +| input | its slot amounts plus a hidden excess equal its public value | input proof | +| payment vertex | the payee can claim at most what the payer registered | registration proof plus output proof, linked by the binding | +| output | its claimed leaves sum to its public amount | output proof | + +🤖 Anything registered but not claimed, or committed but not registered, becomes +fee. The proofs establish non-inflation. Counterparty confirmation establishes +that the committed construction satisfies the payment agreement. In the proven +phases, the payer also checks a receipt showing that its allocation was claimed +before signing. + +The cost of each proof depends on one participant's block, a fixed small +number of slots, and on the tree depths fixed by the session's capacity. + +## Requirements + +| Requirement | Status | +|---|---| +| **Privacy.** No association among inputs and outputs beyond the public boundary and what counterparties know of their own payments. | Argued in [Privacy](#privacy), not formalized. Relies on anonymous submission. | +| **Counterparty privacy, both ways.** The payee doesn't learn the paying input; the payer doesn't learn the funded output. | Met by the [two trees](#two-trees-so-payer-and-payee-never-share-a-path) and one blinding $\beta_k$ per source. | +| **No inflation.** Amounts are non-negative, each registered leaf funds at most one output, and outputs sum to at most the inputs. | Met; see [No value is created](#no-value-is-created). | +| 🤖 **Flood protection in the proven phases.** Auxiliary inputs consume initial inputs' vbyte allocations; registrations and outputs consume allocations from admitted inputs. | Registrations are bounded by $D$ per admitted input, and each output must claim a registered leaf. Duplicates count once and equivocation is removed ([Acceptance rules](#acceptance-rules)). vbyte admission is [not in the proof of concept](#not-in-the-proof-of-concept). | +| 🤖 **Session binding.** No statement replays across sessions. | Enforced by the [acceptance rules](#acceptance-rules): validators build each root from statements accepted for that session and verify dependent proofs against the expected root. This is [not in the proof of concept](#not-in-the-proof-of-concept). | +| 🤖 **Honest allocations can't be blocked.** Other participants can't consume or block an honest allocation, apart from the dependency between a payer and its payee. | Tags are per slot, and a leaf is claimable only under its own binding. Proven outputs use [fresh output ids](#fresh-output-ids). | +| **Attributable failure.** A run either completes, or names an input that recovery can exclude. | Met by per-input signatures and the [signing rules](#signing-and-failures). [Completion proofs](#completion-proof-optional) are optional. | +| **Interactive payments and net settlement**, including recipients without inputs, intermediaries and cycles. | In scope. The circuits check any endpoint allocation within $D$ and $K$. The private messages for net settlement are open. | + + + + + +## Phases and data dependencies + +Each public phase ends with agreement on its contribution set (see +[phase closure](optimistic-track.md#phase-closure)). Everyone then +computes the phase's root from the agreed set. Proofs in the next phase use +that root, alongside their own public inputs. No proof depends on another +party's private proof. A phase's boundary is a +[phase transition](optimistic-track.md#phase-transitions) in the +[block DAG](block-dag.md). + +🤖 Every public phase is a set to agree on, not a sequence. Proofs within a +phase can be made and posted in any order, and are verified against the +phase's fixed public inputs and roots. + +🤖 Initial-input proofs are identified by outpoint and authenticated by their +enrolled online keys. They commit to allocations of funds and vbytes. Their +agreed set supplies the vbyte allocations that auxiliary-input proofs consume. +Once both input-proof sets are fixed, everyone derives the final $R_S$ from the +accepted initial and auxiliary input roots. Output proving then has two stages: +anonymous allocation registration against $R_S$, followed by anonymous output +proofs against the resulting $R_L$. + +```mermaid +flowchart TD + S["session and initial inputs"] --> A["optimistic auxiliary inputs"] + A --> U["optimistic outputs and fee contributions"] + U -->|"balance zero"| SIG["signatures by outpoint"] + U -->|"overflow"| IP["initial-input proofs by outpoint"] + IP -->|"agreed initial allocations, including vbytes"| AP["auxiliary-input proofs, submitted anonymously"] + AP -->|"accepted initial and auxiliary input roots"| RS["R_S"] + RS --> RP["allocation registration, anonymous"] + RP -->|"agreed leaves, dedup by tag"| RL["R_L"] + RL --> OP["output proofs, anonymous"] + RP -.->|"agreed tags"| RT["R_T"] + RT -.-> CP["completion proofs, optional, by outpoint"] + OP -->|"agreed outputs, dedup by output id"| RC["R_C"] + OP --> SA["script authorizations"] + RC --> RCP["receipts, private, payee to payer"] + RCP --> SIG + SA --> SIG +``` + +🤖 The proven phases have the following dependencies, numbered as in +[transaction construction](transaction-construction.md#phases). Payment +confirmation is required before signing on both paths; receipts are additional +checks in the proven phases. + +| Phase | Submission | Depends on | Produces | +|---|---|---|---| +| 4. Initial-input proofs | by outpoint | `session`, fixed initial inputs | agreed initial-input allocations, including vbytes | +| 5. Auxiliary-input proofs | anonymous | agreed initial vbyte allocations | accepted auxiliary-input allocations; final $R_S$ | +| 6. Allocation registration | anonymous | `session`, $R_S$ | registered-leaf root $R_L$; tag root $R_T$ if needed | +| completion proofs, optional | by outpoint | input root, $R_T$ | evidence that an input's non-zero slots were registered | +| 7. Output proofs | anonymous | `session`, $R_L$ | proven output set, claim root $R_C$ | +| script authorization | anonymous | output id, output key, script | authorized final outputs | +| 8. Signatures | by outpoint | final transaction, payment confirmations and applicable receipts | transaction | + +### Private messages between payer and payee + +🤖 In the proven phases, each direct payment adds the following three private +proof messages. They are exchanged only when proving is needed, within the +windows shown below. The ordinary payment-confirmation exchange remains +required as well. + +```mermaid +sequenceDiagram + participant Payee + participant Payer + participant DAG as Validators (block DAG) + Payee->>Payee: discard optimistic outputs, choose fresh pk and id, prepare amount and binding + Payee->>Payer: binding B_k + Payer->>DAG: input proof by outpoint, in the applicable input-proof phase + DAG-->>Payer: final R_S after initial and auxiliary input proofs + Payer->>Payee: registration proof + Payer-->>DAG: registration (or Payee submits it) + DAG-->>Payee: agreed R_L + Payee->>DAG: output proof + DAG-->>Payee: agreed output set and R_C + Payee->>DAG: script, signed under pk + Payee->>Payer: receipt + Payer->>DAG: signature after receipt, script and payment-confirmation checks +``` + +| Message | After | Before | +|---|---|---| +| payee → payer: binding $B_k$ | `session` known; output amount and id chosen | the payer's input proof | +| payer → payee: registration proof | $R_S$ agreed | registrations close | +| payee → payer: receipt | $R_C$ agreed | the payer signs | + +What this means for being online: + +- 🤖 Payer and payee must be available for payment confirmation after output + finalization and before input signing, and, if proving becomes necessary, + for these proof messages. +- 🤖 The payee chooses [fresh output ids](#fresh-output-ids), and supplies the + binding before the applicable input proof. Script authorization follows the + proven output set. +- Third parties never see a pair's private messages. But a party waiting on + one may delay its part in a public agreement, so third parties can wait on + them indirectly. A stalled agreement is resolved by + [recovery](recovery-track.md#fault-tolerance-via-branched-execution), not by the proofs. + +## Parameters + +| Symbol | Value | Meaning | +|---|---|---| +| curve | BN254 | proof system field and pairing | +| proof system | TurboPlonk, KZG, jellyfish | universal setup | +| $H$ | Poseidon, width 4, rate 3, $\alpha = 5$, 8 full and 56 partial rounds | all in-circuit hashing | +| arity | 3 | every Merkle tree | +| $D$ | 9 | slots per input (2 tree levels) | +| inputs | at most 729 | session tree, 6 levels | +| registrations | at most 6,561 | registration tree, 8 levels | +| $K$ | 2 | registered leaves per output | +| amount bits | 51 | $2^{51} > $ 21 million BTC in satoshis | +| excess bits | 32 | an input's hidden fee share | + +*Placeholder constants:* the proof of concept generates Poseidon constants +with arkworks' Grain generator. They are not the reference constants. +Production must load the reference constants. + +## Hashes and objects + +$H_\mathsf{dom}(x_1, \dots, x_m)$ is the Poseidon sponge with the capacity +element set to the domain constant $\mathsf{dom}$, absorbing three elements +per permutation. Each domain has a fixed input length. Tree nodes are one +permutation of $(\mathsf{NODE}, c_1, c_2, c_3)$. + +In the proof of concept: + +- The state is $(\mathsf{dom}, 0, 0, 0)$. Each block of up to three inputs + is added to elements 1–3, then the state is permuted. The hash is element 1 + of the final state, and so is a tree node. +- Domain constants and input lengths: + + | Domain | Constant | Inputs | + |---|---|---| + | ALLOC | 7 | 3 | + | OUT | 8 | 3 | + | SLOT | 11 | 3 | + | RTAG | 12 | 3 | + | CLAIM | 13 | 3 | + | SID | 14 | 1 | + | NODE | $2^{32}$ | 3 children | + +- Amounts and slot indices enter as field elements of their integer value. +- The output id is the first 31 bytes of the SHA-256 digest read as a + little-endian integer. SHA-256 is taken over the 32-byte x-only + serialization of $\mathit{pk}$. +- In the script authorization message, `session` and the id are 32-byte + little-endian field encodings, followed by the raw script. +- Padding for trees smaller than their capacity is not defined yet. The + jellyfish tests use random siblings. The Groth16 reference pads with a + hash of a separate EMPTY domain, but under a different Poseidon instance. +- 🤖 `session` is the instance id $\mathit{sid}$ of the + [optimistic track](optimistic-track.md#hashes-and-identifiers), a hash of the + [coalition formation](overview.md#coalition-formation) proposal, as a + field element. The mapping is not fixed yet; the first 31 bytes as a + little-endian integer, as for the output id, would do (*proposed*). The + proof of concept takes `session` as a field element directly. + +| Object | Definition | Known to | Public | +|---|---|---|---| +| $s$ | random, fresh per input and per attempt | the input's owner | no | +| $a_i$, $B_i$ | slot $i$'s amount and destination binding | the input's owner; the payee for its own slot | no | +| slot | $\mathit{slot}_i = H_\mathsf{SLOT}(a_i, B_i, s)$ | the input's owner | no | +| input root | 2-level tree over $\mathit{slot}_0 \dots \mathit{slot}_8$ | everyone | yes | +| $R_S$ | session root: 6-level tree over the agreed input roots, in the agreed input order | everyone | yes | +| tag | $\mathit{tag}_i = H_\mathsf{RTAG}(\mathit{session}, s, i)$ | everyone, after registration | yes | +| leaf | $\mathit{leaf}_i = H_\mathsf{ALLOC}(a_i, B_i, \mathit{tag}_i)$ | everyone, after registration | yes | +| $R_L$ | registration root: 8-level tree over the agreed leaves, sorted by leaf hash (*proposed*) | everyone | yes | +| $R_T$ | tag root: 8-level tree over the agreed registrations' tags; only for completion proofs | everyone | yes | +| $\mathit{pk}$ | [fresh](#fresh-output-ids) key per proven output; not a spending key | the payee | after proven outputs | +| output id | $\mathrm{SHA256}(\mathit{pk})$, first 31 bytes | the payee until the output-proof phase; then everyone | yes, when posted | +| binding | $B_k = H_\mathsf{OUT}(\mathit{amount}, \mathit{id}, \beta_k)$, one random blinding $\beta_k$ per source $k$ | the payee; payer $k$ sees only $B_k$ | no | +| claim commitment | $\mathit{cc} = H_\mathsf{CLAIM}(u_1 \mathit{leaf}_1, u_2 \mathit{leaf}_2, r)$ | everyone | yes | +| $R_C$ | claim root: 8-level tree over the agreed outputs' claim commitments | everyone | yes | + +The output id follows the +[concurrent PSBT](psbt-concurrent.md#unique-identifiers-for-outputs) +requirement that each output has a unique identifier. A scriptPubKey can't +serve, because it may not be stable until after the output set is. Taking the +id as the hash of a fresh key lets the payee later authorize the output's +script. + + + +🤖 **Fresh output ids.** Optimistic outputs are discarded when the proven +phases start, and their ids are not reused. For each proven output, the payee +chooses a fresh key $\mathit{pk}$, distinct from its optimistic outputs and +earlier attempts, so the output id is unguessable. The payee keeps the id +private until the output-proof phase, after the input allocations and +registrations are fixed. Until then, payers see only their bindings $B_k$. + +🤖 A slot's binding $B_i$ is the binding $B_k$ that the payee gave for that +source: $i$ indexes the payer's slots, and $k$ the output's sources. + +🤖 The payee keeps each blinding $\beta_k$ private. Revealing it to payer $k$ +would let that payer test its binding $B_k$ against the public output +amounts and ids. + +🤖 Each source uses an independently sampled blinding. With a shared binding, +a payer could combine its known allocation amount with a candidate public +output amount to guess the other source's amount, then test that guess +against the public registration leaves and tags. Independent bindings +prevent this test because the payer does not know the other source's +binding. + +🤖 The binding doesn't repeat `session`. An output proof is verified against the +registration root of its own session, and that root is built only from +registrations verified in that session, so a leaf is claimable only where it +was registered. See [Acceptance rules](#acceptance-rules). + +## Statements + +All circuits are TurboPlonk over BN254 with the parameters above. + +### Input proof + +*Purpose:* conservation at an input, and commitment to its slots. + +🤖 The statement below covers the allocation of value. Initial-input proofs +also commit to vbyte allocations, which auxiliary-input proofs consume; that +part is [not in the proof of concept](#not-in-the-proof-of-concept). +Input-proof messages identify their input by outpoint and bind the statement to +the session. Both initial and auxiliary input-proof messages are authenticated +by the input's own online key, enrolled by its BIP-322 ownership proof. +Auxiliary-input messages are still submitted anonymously. + +- **Public:** `session`, value (the input's amount), input root. +- **Witness:** $s$; for each slot, $a_i$ and $B_i$; the excess $e$. +- **Constraints:** + - $a_i \lt 2^{51}$ for every slot, and $e \lt 2^{32}$; + - $\sum_i a_i + e = \mathit{value}$; + - the input root is the tree over $\mathit{slot}_i = H_\mathsf{SLOT}(a_i, B_i, s)$. +- **Cost (*measured*):** 1,855 gates, domain $2^{11}$, 0.31 s to prove. + +The range checks stop a hidden slot of $p - x$ cancelling an oversized +slot. Nine 51-bit slots and a 32-bit excess can't wrap the field. The excess +is this input's share of the fee. Fee pseudo-outputs, which spend a slot like +an output, are an alternative. A zero slot needs no destination; any $B_i$ +will do. A self-transfer is a slot whose binding is the participant's own +output. + +### Registration proof + +*Purpose:* turn a committed slot into an anonymous registered leaf, at most +once. + +- **Public:** `session`, $R_S$, tag, leaf. +- **Witness:** $s$, $a_i$, $B_i$, the 8-level path from $\mathit{slot}_i$ to + $R_S$. +- **Constraints:** + - the path proves $\mathit{slot}_i$ is in $R_S$. The two inner levels expose + the position as base-3 digits, which give $i$. The outer six hide which + input it is; + - $\mathit{tag} = H_\mathsf{RTAG}(\mathit{session}, s, i)$; + - $\mathit{leaf} = H_\mathsf{ALLOC}(a_i, B_i, \mathit{tag})$, with the same + $a_i$ and $B_i$ variables as the slot. +- **Cost (*measured*):** 1,017 gates, domain $2^{10}$, 0.16 s to prove. + +No range check is needed, because $a_i$ is the slot's range-checked amount. + +### Output proof + +*Purpose:* conservation at an output. + +- **Public:** `session`, $R_L$, amount, output id, cc. +- **Witness:** for $k \in \{1, 2\}$, $\beta_k$, $a_k$, $\mathit{tag}_k$ + and a path; $u_2$ (second source used); a filler value; $r$. $u_1$ is the + constant 1. An unused source's path starts from the filler instead of its + leaf, and is not checked against $R_L$, but the prover must still supply + one. +- **Constraints:** + - $B_k = H_\mathsf{OUT}(\mathit{amount}, \mathit{id}, \beta_k)$ for each source; + - for each used source, $H_\mathsf{ALLOC}(a_k, B_k, \mathit{tag}_k)$ is in $R_L$; + - $u_1 = 1$, so every output claims at least one leaf. Without this, an + output with no sources and amount 0 would verify, and outputs would be + ungated; + - 🤖 $u_2 \in \{0, 1\}$, so the second source is used whole or not at all. + Without this, $u_2 a_2$ could be any field element; + - if both sources are used, their leaves differ; + - $\sum_k u_k a_k = \mathit{amount}$; + - $\mathit{cc} = H_\mathsf{CLAIM}(u_1 \mathit{leaf}_1, u_2 \mathit{leaf}_2, r)$. + An unused source enters as 0, so a receipt can open only on a leaf the + output actually spent. +- **Cost (*measured*):** 1,931 gates, domain $2^{11}$, 0.32 s to prove. + +$K = 2$ covers one payment plus the payee's own slot. A payee paid by +several payers uses one output per payment, or a larger $K$. Larger $K$ is not +measured. $K = 4$ probably moves to domain $2^{12}$, about 0.6 s +(*estimate*). + +### Receipt (private) + +*Purpose:* show the payer its payment was claimed, without saying which +output claimed it. + +🤖 A receipt is distinct from payment confirmation. It proves that the payment +allocation was claimed in the proven state. Confirmation tells the payer that +the committed construction satisfies the payment agreement, as the +[concurrent PSBT specification](psbt-concurrent.md#confirmation-of-successful-payment-prior-to-signing) +defines. The proven phases require both checks before signing. + +- **Public:** $R_C$, the payer's leaf. +- **Witness:** the output's claim commitment, its path to $R_C$, the other + claimed leaf, $r$, and which side the payer's leaf is on. +- **Constraints:** the commitment is in $R_C$ and opens to the payer's leaf on + one side. +- **Cost (*measured*):** 827 gates for an 8-level $R_C$, domain $2^{10}$, + 0.17 s to prove. A 6-level $R_C$ (729 outputs) is 645 gates (*counted*). + It is verified only by the payer. + +### Completion proof (optional) + +*Purpose:* show that every non-zero slot of an input was registered. Where +the session requires it, an input that doesn't give one is identified by +outpoint as incomplete or unresponsive. That doesn't show who failed: the payer +may not have handed over its registration proof, or the payee may have received it +and not posted it. + +No other rule needs it: an omitted registration +only removes value from what can be claimed, and that value goes to the fee. +It can't inflate funds or consume another participant's allocation. A +counterparty that doesn't complete can make its partner withhold a +signature, which recovery already handles. The completion proof only adds +attribution within the pair: without it, a payer that reneges can make its +payee appear faulty. + +🤖 The measured completion proof takes about 2.3 s on one +thread, compared with 0.16–0.33 s for the other proof types. + +- **Public:** `session`, input root, $R_T$. +- **Constraints:** for each slot, $a_i = 0$, or + $\mathit{tag}_i = H_\mathsf{RTAG}(\mathit{session}, s, i)$ is in $R_T$. +- **Cost:** 8,578 gates, domain $2^{14}$ (*counted*). 2.3 s to prove, + measured at 8,569 gates without destination bindings, in the same domain. + +A variant publishes an input identifier $H_\mathsf{SID}(s)$ in the input +proof and binds the completion proof to it, with the same $R_T$. That fits $2^{13}$ +(1.1 s). But it loses the zero-slot exemption: every input then registers +all nine slots, with dummies. + +The root-bound proof could instead prove its leaves are in $R_L$, with no +$R_T$. That costs about 810 more gates, still in $2^{14}$ (*estimate*). The +$H_\mathsf{SID}$ variant can't, because it has no amounts or bindings. + +## Acceptance rules + +Every validator applies the same deterministic rules to the agreed sets: + +- **Verification.** Each proof verifies against its circuit's fixed + verifying key and the agreed root it names. A phase's proofs can be checked + in one `batch_verify`, which accepts a mix of circuits. +- **Duplicates and equivocation.** These are validator rules, not part of + the proofs; the proofs make them possible by exposing the tag and the + output id as public keys. Proofs of the same statement are duplicates, even + if their bytes differ, and are counted once. Different valid statements + under one key are equivocation, and only identify which output every + validator removes. An agreed set has no order, so no rule may depend on + which arrived first. The + proof of concept keeps the first in list order instead. +- 🤖 **Inputs:** keyed by outpoint. An input proof is posted by its outpoint + and authenticated by the input's online key, bound to `session`; two + different input proofs for one outpoint are per-input equivocation, as + defined in the [optimistic track](optimistic-track.md#per-input-messages), and + remove the input. +- **Registrations:** keyed by tag. The slot fixes the leaf, so every + registration of a slot has the same statement, and equivocation can't + happen. +- 🤖 **Outputs:** keyed by output id. Two statements for one id can differ in + the claim commitment or in which leaves they spend. Conflicting statements + remove that output, and its leaves' value goes to the fee. Because proven + output ids are [fresh](#fresh-output-ids), other participants cannot prepare + their own allocation to an honest output id; see + [No value is created](#no-value-is-created). +- **Trees:** each in an order that doesn't depend on arrival: + - $R_S$ over input roots in the agreed input order; + - $R_L$ over agreed leaves sorted by leaf hash (*proposed*; the proof of + concept uses arrival order); + - $R_C$ over exactly the kept outputs' claim commitments, sorted by output + id (*proposed*); + - $R_T$, if completion proofs are used, over the kept registrations' tags. + + 🤖 Each tree is built only from statements that verified with this session's + `session` as a public input, and each proof is verified against its own + session's root. The bindings don't carry `session`; this rule is what stops a + leaf being claimed in another session. Validators must enforce this + association when constructing roots and accepting dependent proofs. +- **Script authorization.** After the output set is agreed, each output's + owner posts $(\mathit{pk}, \mathit{script}, \sigma)$, with $\mathit{pk}$ an + x-only secp256k1 key. It is accepted if the first 31 bytes of + $\mathrm{SHA256}(\mathit{pk})$ equal the output id, and $\sigma$ is a valid + BIP 340 signature under $\mathit{pk}$ over + $\mathrm{SHA256}(\mathit{session} \| \mathit{id} \| \mathit{script})$. + Conflicting authorizations for one id are equivocation, and remove the + output. This matters only for consistency, not for incentives. Removal is + simpler than any other way to break the tie. The proof + of concept checks the output proof, key hash and signature together, as one + posted output. The spec separates them because the script may only be + stable after the output set is. +- **Balance.** The fee is $\sum \mathit{value} - \sum \mathit{amount}$. It is + public and must meet the session's terms. + +## Signing and failures + +🤖 These signing rules apply after the proven phases. Every sender also +obtains the payment confirmations required by the +[concurrent PSBT specification](psbt-concurrent.md#confirmation-of-successful-payment-prior-to-signing). + +- **A payer signs only after verifying a receipt** for each of its payments, + and only the complete transaction with every output's script authorized. + Otherwise it risks its funds going to the fee. A receipt shows the payment + was claimed in $R_C$; it doesn't show the script or the settlement. +- **A payee signs its own inputs only if its output is in the transaction** + with the agreed amount and script. + +If either fails, the other $n - 2$ participants must be able to make +progress without them: + +- 🤖 **A refusal is attributable.** Signatures are identified by outpoint, so + an input that doesn't sign is identified by that outpoint. Blame may fall on + the pair, payer or payee or both, because they trust each other for liveness. They don't trust third parties + for it. +- 🤖 **Retry without the excluded outpoint.** The retry is a new recovery + proposal, so it has a new `session` and keeps the exclusions of earlier + attempts. It follows the same phase order, including the optimistic phases; + any subsequent proving uses fresh secrets, amounts, keys and output ids. + The measured value-allocation proof work is about 1.1 s per participant on + one thread: an input, two registrations, an output and a receipt (*derived*). + This excludes vbyte admission. +- **Not in place.** Continuing the same attempt without the excluded input + would show which outputs drop out. Those are exactly that input's payees, + so the link would leak for whichever member of the pair was honest. + +What each failure costs: + +| Failure | Who is identified by outpoint | Who loses | +|---|---|---| +| payer refuses to sign after a valid receipt | the payer's input | the payee's payment, until the retry | +| payee never claims | the payer's input (no receipt, so it won't sign) | the pair | +| payer never hands over its registration proof | the payer's input, if it follows the signing rule (no receipt); the payee's inputs, if it has any and refuses to sign; with completion proofs required, an input that can't give one, which is the same if the payee received the proof and didn't post it | the pair | +| anyone posts an invalid proof | nobody needs to be: it is rejected | nobody | + +🤖 A payee that never claims can get each payer who agreed to pay it identified +by outpoint once. +That stays within the trust the pair placed in each other. A missing +completion proof shows that an input didn't meet its obligations, under the +session's rules. It doesn't show whether that was malice or failure. + +## Security sketch + +### No value is created + +1. **Input:** the hidden slots plus the excess equal the public value, and + none can be negative. +2. **Registration:** each slot registers at most once, because its tag is + unique. A leaf carries the slot's own amount and binding. +3. **One output:** its used leaves are distinct, and they sum to its amount. +4. **Across outputs:** a leaf names one binding, which contains one output + id. Outputs are deduplicated by output id, so no leaf is claimed twice. + +So $\sum \mathit{amount} \le \sum \mathit{registered} \le \sum \mathit{value}$. +🤖 The rest is fee. This proves non-inflation. Payment satisfaction is checked +by counterparty confirmation, with an additional receipt check in the proven +phases, before signing. Failures are attributed as in +[Signing and failures](#signing-and-failures). + +🤖 Non-inflation uses deduplication by output id and the destination binding. +Liveness additionally relies on [fresh output ids](#fresh-output-ids). An +attacker that learns an id when it is posted cannot change its committed +allocations to fund a conflicting statement under that id. This argument does +not cover ids disclosed before those commitments are fixed. + +🤖 The PoC also checks the output-id key and a signature over the session, id +and script together with the output proof. That signature authorizes the script; +it does not bind the amount, allocation sources or claim commitment. The +liveness argument above relies on the ordering and secrecy of the fresh id, +rather than treating that signature as authentication of the whole funding +statement. Script authorization may remain separate from output proving. + +### Privacy + +- **The payee doesn't learn the paying input.** The payer's path is a + zero-knowledge witness. Tags are pseudorandom without $s$. +- **The payer doesn't learn the funded output.** It knows only $B_k$. The + output id becomes public when the output is posted, but the blinding never + leaves the payee, so the payer can't match $B_k$ to it. Each source has its + own blinding, so the payer can't test the other sources' leaves either. The + receipt hides which commitment it opens. +- **Registrations are unlinkable to inputs.** This assumes anonymous + submission, and tree orders that don't depend on arrival. + Peers submit over a sender-anonymous transport. If the transport doesn't + provide message unlinkability, each connection carries only one message. + The sender checks through gossip that its message reached the peers. +- **Payments per output are hidden.** Every output proof has $K$ source + positions, whether the second is used is a witness, and the claim + commitment hides which leaves it spent. +- **The payment count depends on the session's terms.** The number of + registrations is public. If the terms fix the number of registrations per + input, with zero slots registered as dummies to fill it, the count reveals + nothing about payments. The numbers of inputs and outputs are inherently + public. + + The fixed number should make enough payments plausible that actual + payments could change the analysis significantly. A handful of plausible + payments in a large transaction is a strong constraint, suggesting the + sub-transaction model may apply. No proof enforces the number; an input + that registers fewer only weakens it. +- **Proof blinding.** jellyfish randomizes the wire, permutation and + quotient polynomials. The privacy argument assumes zero knowledge for the + proof system and transcript used here. + +### Assumptions + +- KZG and TurboPlonk on BN254 in the algebraic group model, with a ceremony + that had at least one honest contributor. +- BN254's security is about 100 bits, not 128. +- Poseidon is collision resistant, and pseudorandom when keyed by $s$ (tags). +- $B_k$ and the claim commitment hide their contents, given their random + blindings $\beta_k$ and $r$. +- Anonymous submission of registrations and outputs. + +🤖 The non-inflation argument relies on proof soundness and the binding +properties of the hashes. If either fails, the allocation proofs no longer +establish funding coverage. A forged conflicting statement under an honest +output id can also cause that output to be removed, disrupting completion +without identifying the forger. Failure of anonymous submission instead +exposes links between messages and their senders. + +🤖 The setup must produce an SRS whose trapdoor is unknown to every participant, +including the aggregator. An existing compatible ceremony can supply this +SRS; initiating a session does not require generating a new setup. + +Attempting a transaction leaks information that no proof can hide. Fresh +amounts, keys and output ids on each attempt limit what recurs across +attempts. + + + +## Implementation and performance {#performance} + +1. **Rust implementation.** The proofs use the + [jellyfish](https://github.com/EspressoSystems/jellyfish) implementation + of TurboPlonk with KZG commitments. +2. **Universal setup.** No per-circuit ceremony. Any BN254 powers-of-tau + ceremony of degree at least 2,050 works for the input, registration, + output and receipt proofs. The optional completion proof needs 16,386 + (8,194 for its variant). For example + [Perpetual Powers of Tau](https://github.com/privacy-scaling-explorations/perpetualpowersoftau) + or [Aztec Ignition](https://github.com/AztecProtocol/ignition-verification). + +*Measured* with jellyfish on BN254, under load 3–6, medians of 3: + +| Proof | Gates | Domain | Prove, 1 / 10 threads | Verify, single | Batched, per proof | +|---|---|---|---|---|---| +| input | 1,855 | $2^{11}$ | 309 / 66 ms | 1.22 ms | 50 µs | +| registration | 1,017 | $2^{10}$ | 164 / 37 ms | 1.26 ms | 51 µs | +| output, with claim commitment | 1,931 | $2^{11}$ | 324 / 63 ms | 1.32 ms | 56 µs | +| receipt | 827 | $2^{10}$ | 165 / 36 ms | 1.24 ms | 43 µs | +| completion (optional) | 8,578 | $2^{14}$ | 2,261 / 440 ms[^value-mode] | 1.22 ms | 42 µs | + +Every proof is 769 bytes, and each verifying key is 1,146 bytes. + +A session with 500 inputs, 1,000 registrations and 500 outputs has 2,000 +proofs, 1.79 MB including public inputs. It verifies in one batch in 90 ms on +one thread, or 21 ms on ten. Each participant proves in about 1 s on one +thread: one input, two registrations and one output. 🤖 500 inputs is an +example below the 729-input capacity. + +### 🤖 Not in the proof of concept {#not-in-the-proof-of-concept} + +- **vbyte admission.** The proof of concept treats initial and auxiliary + inputs as one input type. Initial-input vbyte allocations, and their + consumption by auxiliary inputs, are protocol requirements it doesn't + implement. Its measurements don't include their cost. +- **Per-session roots.** It checks single proofs and doesn't build the trees, + so it doesn't implement the [acceptance rule](#acceptance-rules) that builds + each root from statements accepted for that session. + +### Compared with other approaches + +🤖 jellyfish was chosen over these alternatives: + +- **Groth16.**[^groth16] It needs a trusted setup for each circuit, which is problematic for privacy. The setup's second phase is specific to the circuit, and its participants contribute one after another,[^bgm] which doesn't work well here. A universal setup reuses an existing ceremony instead. +- **Sigma protocols and STARKs.** They need no trusted setup, but their verifier complexity is too high. +- **Curve Forests.**[^curve-forests] Its verifier cost is logarithmic in the set size, but for our range of set sizes its overhead dominates over a Triptych sigma protocol,[^triptych] whose verifier cost is linear. +- **Anonymous credentials.** With roughly 500 validators, credential issuance and its proof work may cost each validator too much, depending on the scheme, the threshold and the number of contributions. This needs measuring. + +🤖 Payment negotiation state stays with the two counterparties. Their payment confirmations bind to the proof messages in the DAG; the negotiation transcript does not become shared validator state. + +🤖 The table below also compares two ways of proving payments directly, +without a registration phase: + +- **Split proving.** The payer proves its own allocation with a + commit-carrying Groth16 proof, which the payee re-randomizes for its output + proof. +- **Recursion.** The payee's output proof verifies the payer's proof, one + level deep: inner proofs on BLS12-377, the outer proof on BW6-761. + +For an output funded by two payers: + +| Approach | Setup | Bytes | Payee proving | +|---|---|---|---| +| this one | universal | 2,723 (two registrations and one output, with public inputs) | 0.32 s | +| split proving, Groth16 | per circuit | 1,176, with public inputs | not measured | +| recursion, Groth16 two-chain | per circuit | 484 | 6.0 s | + +## Open questions + +- Sorting the registration tree. +- The private messages for net settlement: payments through participants + without inputs, and cycles, mapped to slots bound to final outputs. +- Tree padding. +- Measured cost of $K > 2$. +- 🤖 Whether registrations can be posted anonymously, or in the same phase as + the input proofs, under an auxiliary rate-limiting mechanism. That would + merge the registration phase into the input phase. +- Whether to keep completion proofs at all, as an optional extension. +- Whether the concurrent PSBT specification already authenticates a late + script for an output id, so script authorization can reuse it. +- Reference Poseidon constants, and the choice of ceremony. +- The number of registrations per input to fix in the session's terms, and + its cost: 0.16 s and 769 B per dummy registration. + +[^value-mode]: Measured at 8,569 gates, without destination bindings. + +[^groth16]: J. Groth, [*On the Size of Pairing-based Non-interactive Arguments*](https://eprint.iacr.org/2016/260) (2016). + +[^curve-forests]: M. Campanelli, M. Hall-Andersen and S. H. Kamp, [*Curve Forests: Transparent Zero-Knowledge Set Membership with Batching and Strong Security*](https://eprint.iacr.org/2024/1647) (2024). + +[^triptych]: S. Noether and B. Goodell, [*Triptych: Logarithmic-sized Linkable Ring Signatures with Applications*](https://eprint.iacr.org/2020/018) (2020). + +[^bgm]: S. Bowe, A. Gabizon and I. Miers, [*Scalable Multi-party Computation for zk-SNARK Parameters in the Random Beacon Model*](https://eprint.iacr.org/2017/1050) (2017). + +[^clone-wars]: J. Camenisch, S. Hohenberger, M. Kohlweiss, A. Lysyanskaya and M. Meyerovich, [*How to Win the Clone Wars: Efficient Periodic n-Times Anonymous Authentication*](https://eprint.iacr.org/2006/454) (2006). diff --git a/flake.nix b/flake.nix index c0e75f6..5443704 100644 --- a/flake.nix +++ b/flake.nix @@ -18,6 +18,7 @@ ./nix/preprocessors.nix ./nix/site.nix ./nix/devshell.nix + ./nix/notebook.nix ./nix/spellcheck.nix ./nix/apps/validate-commits ]; diff --git a/nix/notebook.nix b/nix/notebook.nix new file mode 100644 index 0000000..0b9f140 --- /dev/null +++ b/nix/notebook.nix @@ -0,0 +1,36 @@ +{ ... }: +{ + perSystem = + { pkgs, ... }: + let + # Every dependency of the notebook is packaged in nixpkgs. + notebookDeps = + p: with p; [ + ipykernel + matplotlib + nbconvert + numpy + pandas + seaborn + ]; + in + { + # The notebook, re-executed. Execution is deterministic and records no + # timing metadata, so an up to date notebook is byte-identical to the + # build output. + packages.notebook = + pkgs.runCommand "Denominations_and_gap_size_distributions.ipynb" + { nativeBuildInputs = [ (pkgs.python3.withPackages notebookDeps) ]; } + '' + export HOME=$(mktemp -d) + install -m 644 ${../docs/Denominations_and_gap_size_distributions.ipynb} notebook.ipynb + jupyter nbconvert --execute --inplace --to notebook \ + --ExecutePreprocessor.record_timing=False notebook.ipynb + cp notebook.ipynb $out + ''; + + devShells.notebook = pkgs.mkShell { + packages = [ (pkgs.python3.withPackages (p: notebookDeps p ++ [ p.jupyterlab ])) ]; + }; + }; +} diff --git a/nix/site.nix b/nix/site.nix index a8d0f35..3ac628d 100644 --- a/nix/site.nix +++ b/nix/site.nix @@ -61,12 +61,12 @@ ''; # lychee loads CA certificates to build its HTTP client even with --offline. links = pkgs.runCommand "links" { nativeBuildInputs = [ pkgs.lychee pkgs.cacert ]; } '' - # The site is served from /docs/, so a link from the root leaves it. - mkdir root && ln -s ${site} root/docs - # The 404 page needs for browsers to find its assets. + # The site is served from /docs-draft/, so a link from the root leaves it. + mkdir root && ln -s ${site} root/docs-draft + # The 404 page needs for browsers to find its assets. # Lychee does not check this, so verify it separately. - grep -qF '' root/docs/404.html - lychee --offline --include-fragments --no-progress --root-dir $PWD/root root/docs + grep -qF '' root/docs-draft/404.html + lychee --offline --include-fragments --no-progress --root-dir $PWD/root root/docs-draft touch $out ''; }; diff --git a/theme/nb-table.js b/theme/nb-table.js new file mode 100644 index 0000000..22e1235 --- /dev/null +++ b/theme/nb-table.js @@ -0,0 +1,67 @@ +// Paginate long notebook tables. The Colab `data_table` widget is interactive +// JS that cannot run in a static book, so its rendered fallback is one long +// table; this restores page-through navigation client-side, no dependencies. +(function () { + var PAGE = 20; + + var style = document.createElement("style"); + style.textContent = + ".nb-pagination{display:flex;gap:.25rem;flex-wrap:wrap;margin:.5rem 0 1rem}" + + ".nb-pagination button{font:inherit;padding:.15rem .5rem;cursor:pointer;" + + "border:1px solid var(--sidebar-active,#4183c4);border-radius:4px;" + + "background:transparent;color:inherit;opacity:.7}" + + ".nb-pagination button.active{opacity:1;background:var(--sidebar-active,#4183c4);" + + "color:var(--sidebar-bg,#fff);border-color:transparent}" + + // print shows every row, so shrink the table to keep its widest rows on the page + "@media print{.nb-output tbody tr{display:table-row!important}" + + ".nb-output table{font-size:.85em}.nb-output th,.nb-output td{padding:3px 8px}" + + ".nb-pagination{display:none}}"; + document.head.appendChild(style); + + function paginate(table) { + var body = table.tBodies[0]; + if (!body) return; + var rows = Array.prototype.slice.call(body.rows); + if (rows.length <= PAGE) return; + + var pages = Math.ceil(rows.length / PAGE); + var nav = document.createElement("div"); + nav.className = "nb-pagination"; + var buttons = []; + + function show(p) { + rows.forEach(function (r, i) { + r.style.display = i >= p * PAGE && i < (p + 1) * PAGE ? "" : "none"; + }); + buttons.forEach(function (b, i) { + b.classList.toggle("active", i === p); + }); + } + + for (var p = 0; p < pages; p++) { + (function (p) { + var b = document.createElement("button"); + b.type = "button"; + b.textContent = String(p + 1); + b.addEventListener("click", function () { + show(p); + }); + nav.appendChild(b); + buttons.push(b); + })(p); + } + + table.parentNode.insertBefore(nav, table.nextSibling); + show(0); + } + + function run() { + document.querySelectorAll(".nb-output table").forEach(paginate); + } + + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", run); + } else { + run(); + } +})();