Back to selected work

ShadeRoute. Private coordination, direct destinations and selective proof of origin

Dmitry Sergeev·10 min read

Category:Protocols

Project status:Discontinued by client

Tags:
  • Bitcoin
  • CoinJoin
  • Anonymous credentials
  • Taproot
  • Lightning
  • Provenance

Our work

We developed the coordinator and wallet flows for ShadeRoute, including anonymous amount credentials, direct destination outputs and selective origin receipts. The work connected round participation to client-side transaction checks, recovery and later proof of coin lineage.

A Bitcoin payment exposes inputs, outputs and amounts. Address reuse, change detection and later spending can connect that transaction to a wider history. A privacy tool has to address those links without making its operator the custodian of the coins or the keeper of a deposit-to-withdrawal map. ShadeRoute combines non-custodial CoinJoin coordination with destination-aware wallet behaviour and a user-controlled provenance receipt.

The architecture follows the coin beyond the mixing round. A successful mix can lose its value when the wallet consolidates outputs or combines them with unmixed funds in the next payment. A receiving venue can also request evidence of origin that an ordinary wallet history cannot provide selectively. Those requirements lead to three connected decisions: anonymous credentials separate input registration from output registration, final destinations can be outputs of the round itself, and the client retains the material needed to disclose a specific credential path later.

Coordination without an operator-held balance

ShadeRoute assembles a collaborative transaction while participants retain their spending keys. There is no deposit into a mixer-controlled wallet. Each client signs only its own inputs after checking the complete unsigned transaction, including every output it registered and the declared fees. A coordinator that substitutes a destination cannot obtain a valid signature from a correctly verifying client. It can interrupt a round, but coordination authority does not grant spending authority.

Custody separation alone would still leave a privacy problem if the operator could connect each input with its requested outputs. The design uses WabiSabi-style keyed-verification anonymous credentials, or KVAC. Input registration proves ownership and obtains credentials carrying committed value. Output registration presents randomized credentials through separate identities. The coordinator checks validity and available value without receiving a direct issuance-to-presentation link.

Two credential types account for different resources. Amount credentials carry satoshis, while virtual-size credentials budget transaction space. Reissuance lets the wallet split or combine credential value while preserving totals. Range and balance proofs constrain requests, and a per-round serial-number set rejects repeated presentations. Requests use fixed credential slots, including zero-value credentials where needed, so request shape does not directly advertise the wallet's funding structure.

The client checks more than its payout. It verifies registered inputs, exact output scripts and quantities, minimum participation, transaction size, fee limits and the signed transaction announcement. Independent chain data supports checks of input values. Client-side verification checks the transaction against the registered outputs and fees before the wallet signs its inputs.

The coordinator itself is part of the threat model

An operator could try to show a target a separate round, change parameters between clients or use different credential keys to tag presentations. ShadeRoute includes issuer parameters, fees and other round settings in the round identifier. Clients recompute that identifier and verify issuance proofs against the published key parameters. A parameter change creates a different round, while per-user issuer keys fail the expected verification.

Round announcements enter an append-only Merkle transparency log. At least two independent witnesses cosign checkpoints after checking consistency with prior history. Before registering, the client verifies inclusion and compares round announcements fetched through separately isolated Tor circuits. Finalized transactions and transcript hashes later enter the same log. This creates a public record against which clients and monitors can check what the coordinator announced.

The log does not establish who controls the participating inputs. A small round can be publicly logged, and a well-funded operator can contribute many of its own coins. Monitoring can flag abnormal participation, but witness signatures do not turn those inputs into independent users. The privacy model therefore retains explicit assumptions about adversarial participation, endpoint security and network correlation. Amounts and the fact that a transaction is a CoinJoin remain public.

We kept input and output registration separated at the network layer as well as in the credential protocol. Input identities, output identities and status requests use isolated Tor circuits without shared cookies or persistent client identifiers. Requests are spread across their phase windows rather than sent as one recognisable burst. Wallet synchronization uses BIP-157/158 compact block filters or the user's own node so the client does not upload its address set to a coordinator service. These controls reduce additional linkage channels without claiming protection against a global traffic observer.

Arbitrary amounts still need a deliberate output policy

A single-denomination pool can leave a recognisable remainder tied to the original input. Anonymous amount credentials remove the need to issue that kind of input-linked change, but arbitrary unique outputs would still expose useful amounts to an observer. ShadeRoute's wallet decomposes available value into a shared set of standard denominations. It balances expected equal-value outputs against output fees, transaction-space limits and residual value.

The decomposition runs locally after the wallet knows its amount and virtual-size budgets. Recent signed round statistics help estimate which denominations are likely to have peers. A small residual below the configured threshold becomes mining fee rather than a linked change output. This is an explicit cost of the denomination policy, not value the operator silently retains. Larger residuals need additional outputs within the available budget.

The wallet's local anonymity score helps decide whether to remix, but it is not a measured probability of identification. Equal outputs improve ambiguity only to the extent that they belong to other participants and remain unlinked by later behaviour. Unique amounts do not receive the same benefit. Standard denominations and exact payment amounts retain different privacy properties, even when they use the same credential protocol.

Mix-to-Destination removes an unnecessary spending step

If a user plans to move coins to cold storage, paying into a temporary mixing wallet first creates another transaction to manage. If that later transaction combines outputs, it may reveal common ownership. ShadeRoute makes the intended destination part of output registration. A cold-storage address, supplier payment or supported Lightning funding script can receive value directly from the collaborative transaction.

All round outputs use P2TR scripts. Cold-storage destinations derive fresh addresses from imported watch-only Taproot descriptors and use standard denominations. Exact payments can register a recipient's Taproot address and required amount, with remaining wallet value decomposed separately. That removes the extra payment hop and its fee. It does not hide a distinctive supplier payment amount from the public transaction or from the recipient.

DestinationOutputAmountBoundary
Cold storageP2TR addressStandardTiming inference
SupplierP2TR addressExactVisible amount
LightningMuSig2 keyStandardPeer knows channel
RemixFresh P2TRStandardParticipant quality

The wallet also protects coins that remain under its management. Spending policy prevents unsafe combinations of mixed and unmixed funds and restricts consolidation that would connect outputs from the same round. Fresh addresses and separated spending times address additional linkage paths. Mix-to-Destination removes one common opportunity for a mistake, while these rules govern the transactions that still follow. Neither mechanism makes later spending outside the wallet automatically private.

Lightning funding introduces a signing dependency

A supported simple Taproot channel uses a MuSig2 aggregate funding key, giving its funding output the same script form as other P2TR outputs in the round. Choosing a standard denomination as channel capacity also avoids identifying the channel through a unique value. We restricted in-round funding to that channel type. If the local node and peer cannot negotiate it, the wallet does not fall back to a distinctive script inside the transaction.

The difficult part is sequencing. The wallet releases its CoinJoin signatures only after the Lightning node holds the peer's signature on the initial commitment transaction. Otherwise, the funding output could become unusable without the required recovery path. The adapter requests PSBT funding with publication disabled, registers the agreed funding script and waits until the unsigned round transaction is fixed. It then passes that transaction to the node for verification and completes the commitment exchange before signing its round inputs.

A failed peer negotiation means the wallet withholds its signature and cancels the pending channel. A replacement or blame round requires fresh negotiation because the transaction identifier changes. This couples channel setup to round completion and can cause a round to fail when the peer is slow. The integration therefore checks peer readiness and requires tests against a pinned node version, including third-party publication of the completed transaction. Script compatibility alone is insufficient to establish a safe funding flow.

Lineage receipts bind value origins to the output

A venue reviewing a mixed deposit may need evidence connecting it to an earlier withdrawal. Signatures from an input key and an output key show control of both keys, but they do not establish that one funded the other. Two cooperating participants could sign such a statement for unrelated coins. ShadeRoute therefore distinguishes a basic control receipt from a credential-lineage receipt whose intended claim follows value through the round.

The lineage construction starts at registration. The input ownership proof commits to the credential requests associated with that input. Finalized-round transcripts record issuance, reissuance and output presentation, with their hashes committed to the witnessed log. The wallet retains the randomizers needed to open its own credential path. A receipt discloses those openings for the selected origin and destination, allowing the verifier to check continuity and value coverage against the transcript.

The custom receipt construction is a separate cryptographic review boundary from ordinary credential verification. Its release criteria require independently verified lineage steps, rejection of altered openings and detection of duplicated value claims. For an output combining several inputs, lineage disclosure covers every contributing origin. The export flow shows that scope before the user proceeds. It cannot honestly offer a single-origin receipt for a path that merged several sources.

Replay protection binds the receipt to a named verifier and a fresh challenge. BIP-322 signatures from the required origin and subject-output keys cover that statement. A receipt prepared for one exchange cannot authenticate another exchange's challenge, and its credential path cannot be substituted onto an unrelated output. These bindings address resale as evidence for someone else's coins. They do not prevent the intended recipient from retaining or sharing information it has already received.

The receipt establishes a disclosed value path, not that an origin is universally clean. The venue applies its own policy to those origins and decides whether to accept the deposit. Other participants' private openings are not included, although identifying one path necessarily reduces ambiguity for the verifier observing that round. This is selective disclosure with an explicit privacy cost, rather than a guarantee of exchange acceptance.

Published transcripts support independent verification

The receiving venue runs a self-hosted verifier using confirmed transactions, mirrored transcripts and witnessed log checkpoints. It does not ask the coordinator to confirm a customer's story. Receipt verification distinguishes VALID_LINEAGE, VALID_CONTROL and invalid submissions, preserving the difference between value provenance and key possession. The wallet derives credential randomness from its seed and round context so confirmed-round receipts can be reconstructed from the seed and published transcript material.

Live coordination takes the opposite storage approach. One single-writer actor owns each active round, including its issuer keys and spent-serial set. Ephemeral state is discarded when the round ends. If the actor crashes before completion, the round aborts rather than recovering a partially understood credential session. Completed signed transactions cross into a chain gateway that persists them before acknowledgement. Clients reconcile broadcast or conflicting-spend state before making their inputs available again.

Public transcripts exclude request timestamps and network metadata, and failed rounds publish only their parameters and failure reason. This reduces the operational record available for correlation while retaining the finalized evidence required by receipts. Published transcripts remain part of the privacy boundary: evidence that supports independent verification can also create linkage surfaces.

Client checks constrain the coordinator

We kept transaction approval on the wallet side. Before signing, the wallet checks its outputs, amounts and fees against the accepted round. Credential serials and round identifiers prevent reuse across unrelated requests, while origin receipts bind later disclosure to the finalized transaction.

Round completion still depends on participants, Tor connectivity and Bitcoin block space. Phase windows bound how long the coordinator waits, and recovery reconciles signing and broadcast state before releasing inputs. Adding coordinator capacity does not remove those network and participation limits.

ShadeRoute connects private coordination to the destination and evidence a user needs afterward. Anonymous credentials separate registrations, client verification protects the transaction being signed, and selective lineage disclosure explains one coin's origin without publishing the wallet's full history.

See our architecture in practice.

DEVLAB · ARCHITECTURE EXAMPLE

Agent
Commerce

A look inside the software architecture behind Agent Commerce.

View architecture
Agent Commerce — Software Architecture, designed by Dmitry Sergeev