The Anonymity Gap: Understanding Real Privacy in Shielded UTXO-based Protocols for DeFi
Analyze & explore related research in Conceptio
Connect this record directly into your research workflow or AI agent. Explore citations across open repositories, query full text, and export structured proof bundles.
arXiv:2608.22987v1 [cs.CR] 24 Aug 2026
The Anonymity Gap: Understanding Real Privacy in Shielded UTXO-based Protocols for DeFi Hanze Guo UCL Centre for Blockchain Technologies, UK
Stefanos Chaliasos UCL Centre for Blockchain Technologies, UK zkSecurity, USA
Yebo Feng Nanyang Technological University, Singapore
Jiahua Xu UCL Centre for Blockchain Technologies, UK Exponential Science, Switzerland
Abstract
Mixer
Action Role in Fund Flow ...
Shielded UTXO-based protocols are becoming a core form of privacy infrastructure for DeFi. Unlike mixers that organize privacy mainly around deposits and withdrawals, these protocols allow assets, once inside the shielded pool, to continue moving and being re-spent within the hidden state, and to become public only when users withdraw or interact with public DeFi protocols. Their anonymity is therefore no longer a flat pool-size problem, but a provenance problem that propagates across the note/UTXO, proof, and transaction layers. Yet, a unified analysis framework for this setting is still missing. We propose a layered system model and an analysis pipeline that uses prior history as the temporal baseline, applies cumulative pruning and cross-proof propagation to each proof’s Commitment Set, and recursively traces the survivors through historical hidden-state transitions to derive the final transaction-level Anonymity Set Size. We evaluate our methodology on the complete on-chain histories of all four Railgun production deployments and five independent Hinkal pools across six EVM chains, analyzing 186,356 unshielding spend transactions. Using only public protocol traces and constraints, our non-heuristic analysis yields mean Anonymity Set Size reductions of 40.1%–59.0% relative to each deployment’s temporal baseline; 3,679 transactions retain at most 10 addresses, including 1,228 singletons. Public token constraints are the strongest and most stable source of pruning in both protocols, while the effects of tree number, proof roots, and value constraints vary with protocol design and historical state. Together with representative cases, these results reveal interpretable anonymity-loss patterns and implications for user behavior and future protocol design.
1
Shielded UTXO-based
Shield Unshield
... ...
Shielded Transfer Unshield and Shielded Transfer
Fig. 1: One-hop mixer matching versus recursive provenance in shielded UTXO-based protocols.
mixers supporting separate deposit and withdrawal pools to shielded unspent transaction output (UTXO)-based protocols that support richer hidden-state operations. Railgun, a leading representative of the latter category, illustrates this trend: a recent Cambridge analysis reports that daily transactions on Tornado Cash Classic and Tornado Cash Nova fell by 97% and 91%, respectively, after the Tornado Cash sanctions, while Railgun’s share of transactions among major Ethereum privacy protocols rose from 13% in 2022 to 71% in 2025 [3]. As of our observation cutoff, its total value locked (TVL) was approximately $80.23 million.1 Unlike mixers, these shielded UTXO-based protocols let users move assets into the shielded pool (shield), continue transferring, splitting, merging, and re-spending them inside the hidden state (shielded transfer), and execute public release (unshield) only when they need to return to the public state, for example, to withdraw or interact with public decentralized finance (DeFi) protocols. As Fig. 1 shows, this protocol form changes the object of anonymity analysis. In mixer-style systems, fund flow is organized around the correspondence between deposit and withdrawal [4–6], whereas in shielded UTXO-based protocols, hidden state can be created, transferred, and re-spent, while a single spend transaction may aggregate multiple proofs. Accordingly, the feasible provenance sets underlying one unshield, and hence its Anonymity Set Size, are no longer a one-hop pool-matching problem. Instead, provenance propagates across the note/UTXO, proof, and transaction layers: the note layer provides candidate hidden-state objects, the
Introduction
Since the Office of Foreign Assets Control (OFAC) sanctions on Tornado Cash in August 2022 [1], on-chain demand for privacy has not disappeared; instead, protocol forms have continued to evolve [2]. Privacy usage is shifting from coin
1 TVL on July 30, 2026, from DefiLlama.
1
proof layer captures private-state relations, and the transaction layer exposes entry and exit addresses. Previous work has used address clustering, timing, value patterns, and other behavioral or attribution heuristics to reassess deployed privacy, including for Zcash, smart-contract mixers, Umbra, and, most recently, Railgun on Ethereum [4, 7–9]. A distinct line derives eliminations from public ring-membership structure in Monero and related systems, sometimes combined with temporal or decoy-selection heuristics [10–12]. To the best of our knowledge, this work provides the first systematic, non-heuristic analysis of how recursive provenance shapes transaction-level anonymity in deployed shielded UTXObased protocols for DeFi. Using only publicly observable protocol traces and constraints, we set the analysis boundary at the transaction level: the unit is a transaction that executes unshield, and its candidate sources are protocol-visible shielding addresses. This design isolates anonymity loss caused by the protocol’s own public constraints. We neither cluster addresses into users or entities nor weight candidates probabilistically. The former typically requires heuristic or offchain attribution and the latter an explicit probabilistic model. Separating these choices from protocol-visible constraints yields a non-heuristic baseline for either extension. Within this scope, we ask: from which shielding addresses could the funds released by a transaction that executes unshield have originated, and by how much can that address set be reduced? To answer this question, we design an empirical analysis that operates on executed traces and propagates constraints across layers. We organize the problem into three connected parts: first, the system model and privacy metrics; second, the proof-level shrinking of feasible hidden sources; third, the connection from these proof-level results to the final Anonymity Set Size at the transaction level. This organization reflects the actual distribution of public constraints in the target systems: hidden-state objects live at the note layer, private-state relations at the proof layer, and the visible anonymity outcome at the transaction layer. Layered system model and privacy metrics. We first formalize a layered system model for shielded UTXO-based protocols and define transaction-level Anonymity Set Size together with the proof-level Commitment Set Size used to compute it. Commitment Set Size captures how many historical commitments remain feasible as hidden inputs for a given proof. Anonymity Set Size captures how many shielding addresses could have originated the funds released by one transaction that executes unshield. The model connects local hidden-source feasibility to final public release across the note, proof, and transaction layers. The formal model and metrics are developed in Sec. 3. Commitment-source pruning. We then construct the Commitment Set of each proof and perform cumulative pruning over that set. Temporal order, tree number, historical roots, token compatibility, and value feasibility jointly determine whether one historical commitment can still serve as a feasible
hidden input to the current proof. Starting from the temporal baseline, we apply these constraints and propagate their consequences to shrink each proof’s feasible hidden sources. No address clustering, behavioral patterns, or external attribution signals are used. The full pipeline is presented in Sec. 4. Closure-based lifting to transaction anonymity. Finally, we start from the Commitment Set obtained for each proof after cumulative pruning and propagation and trace its feasible provenance backward along the hidden-state history. These commitments may be introduced directly by shield or created by later shielded transfer and unshield and shielded transfer steps, while the final Anonymity Set Size identifies the shielding addresses through which the released funds could originally have entered the pool. We therefore connect the still-reachable commitments to historical shield transactions and their shielding addresses, and aggregate these address sets within each transaction. We instantiate this process on the complete histories of all four Railgun production deployments and the five most active independent pools in Hinkal’s largest coordinated Ethereum Virtual Machine (EVM)-compatible deployment generation by aggregate commitments. Across these analyses, we cover 313,492 proofs and 259,049 spend transactions, of which 186,356 are unshielding spend transactions. Relative to their respective temporal baselines, the mean Anonymity Set Size shrinks by 40.1%–59.0% across the Railgun chains and by 48.9%–57.4% across the Hinkal chains. The final set contains at most ten addresses in 2,968 Railgun and 711 Hinkal transactions, including 920 and 308 singleton cases, respectively. From these measurements, we distill interpretable anonymity-loss patterns, explain when very small sets emerge, and derive practical implications for user behavior, protocol interfaces, and privacy-protocol design, as developed in Sec. 5 and Sec. 6. Contributions. This work makes the following contributions: • We formalize a layered system model for shielded UTXO-based protocols and define transaction-level Anonymity Set Size together with the proof-level Commitment Set Size used to compute it. • We introduce a non-heuristic recursive provenance analysis combining four-stage pruning with cross-layer lifting to trace feasible hidden-state histories to shielding addresses and derive transaction-level Anonymity Set Size. • We analyze the complete on-chain histories of all four Railgun production deployments and five independent Hinkal pools, finding mean Anonymity Set Size reductions of 40.1%–59.0% and 48.9%–57.4%, respectively, relative to their temporal baselines. • We identify an eight-pattern anonymity-loss taxonomy across proof-level specialization, proof-structure effects, and transaction-level aggregation, support it with case studies, and distill it into practical implications for user behavior, privacy-protocol interfaces and design. 2
2
Table 1: Mechanism-level feature comparison of representative blockchain privacy protocols (• = yes, ◦ = no).
Background
Permissionless blockchains such as Ethereum execute transactions in a globally agreed order on a shared append-only ledger, yielding a publicly inspectable trace [13, 14]. Smart contracts store protocol state and enforce state transitions, but their calls, execution order, state updates, and events remain visible even when cryptography hides the underlying asset state [2]. DeFi-facing privacy protocols must preserve hidden state in this public setting. We study shielded UTXO-based protocols for DeFi, a target class defined by five features that distinguish it from other blockchain privacy protocols, such as mixers and stealth address protocols.
Feature
Commitment-Nullifier State Shielded Transfer Token-Encoded Notes Recipient Discovery DeFi-Facing Design
Railgun Hinkal Nocturne Tornado Cash zkBob Zcash Umbra [26] [25] [23] [24] [20] [21] Classic Nova [27] [22]
• • • • •
• • • • •
• • • • •
• ◦ ◦ ◦ ◦
• • ◦ • ◦
• • ◦ • •
• • ◦ • ◦
◦ ◦ ◦ • ◦
the protocol itself lets shielded state feed broader on-chain financial activity, rather than only allowing withdrawal followed by external use. Railgun unshields assets into the Relay Adapt contract, executes external calls, and shields the result back in one transaction [21]. Hinkal’s pool similarly executes external calls using shielded state, supporting private swaps, lending, and staking; transactions may be submitted through relayers [25]. Tornado Cash Nova instead centers on deposit, in-pool transfer, and withdrawal [22]. Table 1 compares representative protocols along these dimensions and motivates three scopes:
Commitment-Nullifier State. At the state-model level, the target class represents value as discrete notes rather than mutable account balances [2]. Creating a note posts a hiding commitment to an append-only accumulator, typically a Merkle tree [15]. To spend privately, a user publishes a note-derived nullifier and uses a zero-knowledge proof (ZKP) to prove knowledge of and authorization for a note whose commitment is covered by a recorded public Merkle root, as well as the nullifier’s correctness, without revealing the consumed commitment [16, 17]. The published nullifier prevents double spending. Deployed systems typically instantiate this proof as a succinct non-interactive argument of knowledge (SNARK) [16, 18, 19]. This commitment-nullifier discipline defines the hidden-state machine later abstracted in our model. Umbra instead derives receiver-specific stealth addresses without such a commitment-nullifier pool [20].
• Shielded UTXO-based Protocols for DeFi combine all five features and form our direct modeling target; this class includes Railgun, Hinkal, and Nocturne.2 • Adjacent Commitment-Nullifier Designs, including Tornado Cash Nova, zkBob, and Zcash, share much of the hidden-state machinery but differ in token encoding or DeFi-facing scope. Tornado Cash Classic is a simpler mixer within the broader commitment-nullifier family.
Shielded Transfer. A private transition can consume existing notes and create new ones, while a ZKP proves input, output, and protocol consistency without revealing the witnesses [16, 17]. Unlike withdrawal-oriented mixers (see Fig. 1), value can remain hidden, recur as new notes, and continue through later private transitions [21–24].
• Other Blockchain Privacy Protocols, such as the stealth address protocol Umbra, lie outside this family and require a distinct anonymity model because their state transitions expose different public constraints.
Token-Encoded Notes. Supporting multiple assets requires locating asset identity. A single-asset pool fixes it by deployment; the target class instead encodes it in each note, allowing one hidden-state machine to represent multiple assets and enforcing token consistency in private transitions [21, 25, 26]. Note encoding does not determine public visibility: an implementation may expose the token directly or reveal only transaction-specific constraints from which it can sometimes be inferred. Such token information can induce publicly observable pruning constraints, whereas single-asset pools factor this distinction out at deployment time [23, 27].
3
System Model and Privacy Metrics
For the target class of Sec. 2, this section formalizes the protocol lifecycle across note, proof, and transaction layers and defines Commitment Set Size and Anonymity Set Size with their temporal baselines. The transaction layer is our public observation boundary, whose visible units are on-chain entry and exit addresses; the metrics therefore characterize address-level ambiguity over shielding addresses. Extending the address metric to users or entities requires address attribution, often using off-chain information or heuristics, and lies outside our protocol-visible analysis. Because one user may control multiple shielding addresses, address-level set sizes generally upper-bound user-level sizes, except when multiple users share one shielding address.
Recipient Discovery. To recover and spend a note created by another user, the recipient must identify its public commitment. The sender typically publishes recipient-bound data derived from the recipient’s public key with the commitment, allowing the recipient to scan with a private key [21, 25]; otherwise, recovery data must be conveyed off-protocol [27].
2 Nocturne ceased operations in 2024.
DeFi-Facing Design. We call a design DeFi-facing when 3
3.1
System Model
by the consumed notes. Let mi and ki denote the numbers of notes consumed and commitments newly created by πi , respectively. We distinguish three proof types corresponding to Actions 2 – 4 : Proof 2 , Proof 3 , and Proof 4 .
Shielded Pool. A shielded pool P is the protocol-maintained private state over supported assets and exposes four actions. 1 Shield. One asset type, such as an ERC-20 token or nonfungible token (NFT), is moved from the public state into P . The protocol creates notes that encode the corresponding spending rights in the pool.
• Unshield proof (Proof 2 ). The proof consumes existing notes and releases all spent value through a plaintext output Oi = (τi ,Ui ). No new commitments are created. • Shielded-transfer proof (Proof 3 ). The proof consumes existing notes, releases no value from P , and keeps all spent value within the shielded state, with Oi = ∅ throughout.
2 – 4 Spending. The user spends notes of a single asset type inside P . Recording their nullifiers consumes them, and the spent value is processed as follows.
• 2 Unshield: All spent value is unshielded from P to an external address, moving assets back to the public state.
• Unshield-and-shielded-transfer proof (Proof 4 ). The proof consumes existing notes, releases part of the spent value through a plaintext output Oi = (τi ,Ui ), and keeps the rest within the shielded state.
• 3 Shielded Transfer: All spent value remains within P and is reassigned within the shielded state.
Commitments in P are shield commitments introduced by Action 1 or proof-created commitments introduced by Proof 3 or Proof 4 . Each proof-created commitment has a unique creating proof, denoted π(c). This classification identifies how a commitment is created rather than requiring mutually exclusive funding provenance: when a transaction combines shielding and spending, a proof-created commitment may depend on a public entry and earlier shielded notes.
• 4 Unshield and Shielded Transfer: The spent value is split such that one part is unshielded to an arbitrary external address, while the remaining part stays within the shielded state of P . 3.1.1
Note (UTXO) Layer
The note (UTXO) layer contains the basic state objects of the shielded pool and their permanent on-chain execution trace. Note. A note N represents the abstract state object created and consumed by the four actions. Each note is created exactly once and can be consumed at most once. Notes are not stored on-chain and are represented by commitments.
3.1.3
The transaction layer defines the execution boundary and temporal order of P state transitions. Commitments created within a transaction cannot serve as inputs to its proofs; only those present before execution are eligible. Shield and spend roles in the public trace need not be mutually exclusive. Shield transaction. A shield transaction corresponds to Action 1 : it inserts shield commitments into P . Shielding address. The shielding address of a shield transaction is the public address from which assets enter P —the entry point to hidden state. Spend transaction. A spend transaction aggregates one or more proofs and is either:
Commitment. Each note N maps one-to-one to an on-chain commitment c. A commitment encodes the note’s fixed asset attributes. A commitment remains on-chain regardless of whether the underlying note has already been consumed. Nullifier. When a note represented by commitment c is consumed, the protocol records a unique public nullifier deterministically derived from that note’s secrets. The nullifier prevents double spending without revealing c or note attributes. 3.1.2
Transaction Layer
Proof Layer
The proof layer captures the same-token input–output relations through which P processes spent notes.
• Internal spend transaction: every constituent proof is Proof 3 , so no assets are released to the public state.
Proof. A proof, denoted by πi , models one such relation; a cryptographic proof may jointly authenticate multiple such relations. It consumes existing notes, records their nullifiers, and may create new commitments. All notes consumed by πi share one token type, and their values must satisfy the protocol’s balance relation. Each proof may include a plaintext output Oi = (τi ,Ui ), whose token type and value describe assets released from P to the public state; Oi = ∅ denotes a purely internal proof. When present, its revealed semantics must match the token type and released value induced
• Unshielding spend transaction: at least one constituent proof is Proof 2 or Proof 4 . Only this class carries the Anonymity Set Size defined below. Unshielding address. The public address to which a Proof 2 or Proof 4 releases assets from P is its unshielding address, marking the exit point from hidden state. Fig. 2 instantiates the three-layer model. Shield transactions T1 and T2 from A1 create N1 , N2 and N3 , N4 , N5 , respectively. Transaction T3 , initiated by A2 , aggregates P1 , P2 , P3 , 4
where Addr(Ω(i)) denotes the potential shielding addresses obtained by tracing the commitments in Ω(i), together with any protocol-visible predecessor relation attached directly to πi , back to the shield transactions from which they could originate. Its size |A (T )| is the Anonymity Set Size. Temporal baseline A0 (T ). For an unshielding spend transaction T , the temporal baseline A0 (T ) contains the shielding addresses of all preceding shield transactions. In Fig. 2, T1 and T2 both use A1 , so A0 (T3 ) = {A1 }. We report the relative reduction redA (T ) = 1 − |A (T )|/|A0 (T )|.
Fig. 2: Illustrative transaction-intent view of the system model for shielded pool P . Transactions T1 and T2 are initiated by address A1 , and T3 by address A2 . The symbol → denotes fund transfers, while 99K denotes ownership transfers within P . The red arrow → indicates note insertion into P , and the red dashed arrow 99K indicates note nullification. Action 1 : Shield; 2 : Unshield; 3 : Shielded Transfer; 4 : Unshield and Shielded Transfer. Red-background notes are consumed by the corresponding proof; unshaded notes are newly created.
4
Non-Heuristic Provenance Analysis
This section instantiates the metrics defined in Sec. 3.2. Cumulative pruning constructs Ω(i) from public traces, and lifting maps the survivors to shielding addresses and unions them within each unshielding spend transaction to obtain A (T ).
4.1 which are Proof 2 , Proof 3 , and Proof 4 , respectively. P1 consumes N1 , N3 and creates none; P2 consumes N2 and creates N6 ; P3 consumes N4 , N5 , creates N7 , and releases value to the public state. The example connects note creation and consumption to proof aggregation and shows why outputs created within T3 cannot feed another proof in T3 .
3.2
Commitment Set Construction
Starting from the temporal baseline Ω0 (i) defined in Sec. 3.2, the pipeline evaluates four cumulative stages: tree number, proof-root coverage, token consistency, and value feasibility, denoted by StreeNumber , SproofRoot , Stoken , and Svalue . They yield Ω1 (i) through Ω4 (i) before cross-proof propagation; a structurally inapplicable stage acts as the identity. Fig. 3 illustrates each constraint on πi separately. These snapshots report one feasible-set construction, not extra pruning assumptions: Ω4 (i) contains baseline candidates not ruled out by applicable public constraints. The tree/root constraints are intersective; tree-first evaluation is efficient because root coverage is treelocal. The token/value tail is representation-dependent: Stoken constructs Θi before Svalue tests each branch for joint token– value feasibility. Thus, order affects snapshots and attribution, not the final local feasible set used by propagation.
Privacy Metrics
The metrics below count the commitments or shielding addresses that remain feasible under protocol-visible constraints, without ranking them by likelihood. A probability-weighted view requires an explicit posterior based, for example, on behavioral priors, attribution models, or off-chain information; these sets can then serve as candidate spaces for entropybased anonymity metrics [28, 29]. Commitment Set Size |Ω(i)|. For a proof πi , Ω(i) is the set of commitments feasible as its hidden inputs; |Ω(i)| is the Commitment Set Size. The metric has proof granularity because all nullifiers recorded by the same proof share the same constraints and hence the same Commitment Set.
4.1.1
Strategy 1: Tree Number
Panel 1 of Fig. 3 shows the simplest structural cut. A private spend proves membership in one public Merkle tree, so timeeligible commitments in other trees are impossible; in the example, the reference to tree 2 excludes the earlier leaves in tree 1. Fig. 4 formalizes this public comparison, retaining commitments in the same tree as πi to form Ω1 (i) without token or value reasoning.
Temporal baseline Ω0 (i). For a proof πi , the temporal baseline Ω0 (i) contains all commitments present when its containing spend transaction begins execution. In Fig. 2, the proof in T3 that consumes N4 and N5 has the five historical commitments as its baseline; N6 and N7 , created within T3 , are excluded, so both nullifiers share that baseline.
4.1.2
Anonymity Set Size |A (T )|. For an unshielding spend transaction T , A (T ) is the set of shielding addresses from which T ’s released funds could have originated: [ A (T ) = Addr Ω(i) , (1)
Strategy 2: Proof Root
Panel 2 of Fig. 3 refines this boundary within the selected tree. A spend is verified against one public root snapshot, so any commitment inserted after its largest covered index is too new. In the example, the leaf added between r0 and r1 becomes eligible only when the spend references r1 . Fig. 5 formalizes the prefix test ℓ(c) ≤ ℓmax (πi ), whose survivors form Ω2 (i).
πi ∈T Oi ̸=∅
5
1. Tree Number 1
2. Proof Root
3. Token
2
Baseline
4.1. Residual-Value Case 1 WETH 2-3 WBTC
4.2. Exact-Value Case
1 WETH 2-3 WBTC
1 WETH 2-3 WBTC
5 WBTC
1WBTC 2-3 WBTC 4 WBTC
1 WETH 2 WBTC 3 WBTC
1 WETH 2 WBTC 3 WBTC
4.3. Bounded-Value Case
4 WBTC
1WBTC 2 WBTC 3 WBTC
5 WBTC 0-1 WBTC
Fig. 3: Leaf insertions t0 –t7 and dashed Merkle-tree snapshots at t1 ,t3 illustrate commitment-set pruning. Candidate leaves carry applicable token/value labels; the blue user marks the spend; green ticks/red crosses denote retained/pruned candidates. 4.1.4
Strategy StreeNumber Notation. tree(πi ) denotes the tree referenced by πi . For each c ∈ Ω0 (i), tree(c) denotes the tree containing c. function StreeNumber (πi , Ω0 (i)) Ω1 (i) ← ∅ for c ∈ Ω0 (i) do if tree(c) = tree(πi ) then Ω1 (i) ← Ω1 (i) ∪ {c} return Ω1 (i) end function
Fig. 4: Strategy 1 StreeNumber . Strategy SproofRoot Notation. ℓmax (πi ) denotes the largest covered leaf index of the proof root referenced by πi . For each c ∈ Ω1 (i), ℓ(c) is the insertion index of c. function SproofRoot (πi , Ω1 (i)) Ω2 (i) ← ∅ for c ∈ Ω1 (i) do if ℓ(c) ≤ ℓmax (πi ) then Ω2 (i) ← Ω2 (i) ∪ {c} return Ω2 (i)
Strategy Stoken
Panels 4.1–4.3 of Fig. 3 show where arithmetic starts pruning. With neither a public token nor a public output value, each token branch must independently support the required inputs; one leaf cannot explain a two-input spend. With an exact public amount, only candidates whose values can participate in attaining it survive. With 5 WBTC revealed and one hidden output, the total input may instead lie within a bounded interval, excluding leaves entirely outside it. Fig. 7 evaluates value feasibility within each branch t ∈ Θi retained by Stoken . The filter Φi,t applies the public balance relation of πi to produce the feasible branch slice Ωt4 (i). For Panels 4.1–4.3, the targets are [0, kiVmax ], [Ui ,Ui ], and [Ui ,Ui + kiVmax ], where ki is the number of commitments created by πi , Ui is its revealed output value when present, and Vmax bounds the value of one created commitment. The extractor Γi,t then returns the branch-local mandatory set Mt (i), whose leaves occur in every remaining feasible explanation. The surviving branches form Θ⋆i ; the union of their slices gives Ω4 (i), while the intersection of their mandatory sets gives M(i). This branch-local operator is conservative: it removes a candidate only when the public token and value constraints rule out its participation; an unresolved value is insufficient. It does not enumerate every concrete mi -input tuple during each fixpoint update, so a candidate may remain even if exhaustive joint solving could eliminate it. The reported sets therefore upper-bound the exact jointly feasible candidate sets.
Notation. mi denotes the required input count of πi . For each c ∈ Ω2 (i), Λ(c) is the set of tokens not ruled out by the public creation trace of c and may be non-singleton. Independently, Ti is the token set permitted by the public trace of πi . Θi denotes the surviving token branches of πi . Branch cardinalities count distinct commitments within one token branch. Since Ω3 (i) is a set, a commitment compatible with multiple surviving branches appears in it only once. The procedure retains every branch supported by at least mi commitments and never selects among publicly indistinguishable branches. function Stoken (πi , Ω2 (i)) Θi ← ∅ for c ∈ Ω2 (i) do Θi ← Θi ∪ Λ(c) Θi ← Θi ∩ Ti for t ∈ Θi do if |{ c ∈ Ω2 (i) | t ∈ Λ(c) }| < mi then Θi ← Θi \ {t} Ω3 (i) ← ∅ for c ∈ Ω2 (i) do if Λ(c) ∩ Θi ̸= ∅ then Ω3 (i) ← Ω3 (i) ∪ {c} return Θi , Ω3 (i) end function
end function
Fig. 6: Strategy 3 Stoken . Fig. 5: Strategy 2 SproofRoot .
4.1.3
Strategy 4: Value
Strategy 3: Token
Panel 3 of Fig. 3 shows the first semantic cut: which token interpretations can explain the proof’s hidden inputs. In the left example, the token is not revealed, so BTC and ETH inherited from the remaining candidates stay feasible, while USDT does not. In the right example, under the BTC branch, an ETH-only leaf drops out, whereas a commitment still compatible with BTC and ETH survives. Fig. 6 formalizes this test. For each candidate c, Λ(c) is the token set permitted by its public creation trace and, if c is proof-created, the current feasible output state of its creating proof π(c); propagation can only narrow it. Intersecting these labels with the token set Ti permitted by πi , the algorithm removes branches with fewer than the required mi inputs and returns the survivors Θi and their commitments Ω3 (i).
4.1.5
Cross-Proof Global Propagation
The four local strategies treat each proof in isolation, but proofs can constrain one another in two ways: a mandatory input is consumed and unavailable to other compatible proof domains, while a created commitment may carry a narrower token or value interpretation into later private transitions. Cross-proof propagation follows the public state-transition semantics and revisits only affected proofs until no state can shrink further. Operationally, propagation keeps the structural 6
non-empty together. A proof-created commitment follows π(c) under the same guard unless the public trace determines another token relation. Each guarded state is expanded once; the final loop then computes A (T ) via Equation 1.
Closure-Based Lifting Πclosure
Strategy Svalue Notation. mi denotes the required input count of πi . Φi,t and Γi,t denote the branch-local valuefeasibility filter and mandatory extractor for πi . Ωt4 (i) and Mt (i) denote the branch candidate set and branch-local mandatory set. Θ⋆i denotes the surviving branch set, and M(i) denotes the mandatory input set. function Svalue (πi , Ω3 (i), Θi ) Θ⋆ i ←∅ for t ∈ Θi do Ωt4 (i) ← Φi,t (Ω3 (i)) if |Ωt4 (i)| ≥ mi then Mt (i) ← Γi,t (Ωt4 (i)) if |Mt (i)| = mi then Ωt4 (i) ← Mt (i) if Ωt4 (i) ̸= ∅ then ⋆ Θ⋆ i ← Θi ∪ {t} else t Ω4 (i) ← ∅ if Θ⋆ i = ∅ then M(i) ← ∅ Ω4 (i) ← ∅ else T M(i) ← t∈Θ⋆ Mt (i) S i Ω4 (i) ← t∈Θ⋆ Ωt4 (i) i ⋆ return Θi , Ω4 (i), M(i), {Ωt4 (i)}t∈Θ⋆ i
Notation. Addr(e) is the shielding address of terminal shield transaction e; Σ(i) is the surviving token-guarded slice family of πi . Seed(i) = {(i,t) | t guards a slice in Σ(i)}; Slice( j,t) is the t-guarded slice in Σ( j). Entryπ (i) and Predπ (i) are, respectively, the terminal shield transactions and earlier guarded proof states exposed directly by πi ; Entry(c,t) and Pred(c,t) are the corresponding sets permitted by c’s public creation trace under t. Every entry/predecessor set retains all publicly indistinguishable alternatives. function Πclosure (πi , Ω(i), Σ(i))n i=1 for all proof πi do Qi ← Seed(i) ∪ Predπ (i) Seeni ← ∅ E (i) ← Entryπ (i) while Qi ̸= ∅ do ( j,t) ← pop(Qi ) if ( j,t) ∈ Seeni then continue Seeni ← Seeni ∪ {( j,t)} E (i) ← E (i) ∪ Entryπ ( j) Qi ← Qi ∪ Predπ ( j) for c ∈ Slice( j,t) do E (i) ← E (i) ∪ Entry(c,t) Qi ← Qi ∪ Pred(c,t) for all unshielding spend transaction T do A (T ) ← ∅ for all proof πi in T with Oi ̸= ∅ do A (T ) ← A (T ) ∪ {Addr(e) | e ∈ E (i)} return {E (i)}ni=1 and {A (T )}
end function
end function
Fig. 7: Strategy 4 Svalue .
Fig. 8: Closure Πclosure .
5
This section evaluates the pipeline of Sec. 4 using the inclusive cutoff July 30, 2026 at 23:59:59 UTC. For Railgun, we reconstruct and analyze the complete on-chain histories of all four production deployments—Ethereum, Arbitrum, Polygon, and BNB Chain—from the initial deployment on each chain through the cutoff, covering every commitment, nullifier, proof, shield transaction, spend transaction, and Merkletree rollover recorded within the window. Hinkal, by contrast, has a highly fragmented deployment landscape: among 39 independently deployed pool states across ten chains, 37 are nonempty and 23 of those contain fewer than 1,000 commitments. Because each deployment maintains an independent commitment tree and pool state, these pools cannot be concatenated into one continuous anonymity domain. Appendix B inventories this landscape. We therefore select the coordinated EVM-compatible generation deployed on June 27, 2025, which has the largest aggregate commitment population among Hinkal’s coordinated cross-chain generations in the window, and evaluate its five most active pools on Ethereum, Arbitrum, Polygon, Base, and Optimism. To keep the cross-protocol comparison consistent with Sec. 3.1.2, we count proofs at the granularity of same-token input–output relations. A Railgun JoinSplit proof contains one such relation, whereas a single Hinkal cryptographic proof may jointly authenticate several; accordingly, each inputbearing same-token relation within a Hinkal cryptographic proof is counted separately. Appendix C gives the implementation mapping and evidence boundary, and Appendix D documents the full-trace reconstruction and fail-closed analysis checks. Table 2a and Table 2b summarize the resulting datasets. The Hinkal Anonymity Set Size evaluation covers contract-identified recipient withdrawals: outputs that are provably fee-only under the contract’s execution semantics are excluded, while transactions containing both a recipient withdrawal and a fee remain included.
prefix from Strategies 1 and 2 fixed and recomputes only the token–value state after a newly mandatory input or a narrowed label on a created commitment. Such contractions reach a fixpoint whose final Ω(i) and token-guarded family Σ(i) feed closure lifting; Appendix A gives the formal procedure.
4.2
Closure-Based Lifting to Anonymity Sets
Local pruning identifies commitments that can explain each analyzed spend, but not their entry origins. Closure-based lifting recursively follows publicly determined shielded-state dependencies from each survivor and any predecessor exposed directly by the analyzed proof relation, yielding the historical shield transactions from which the released funds could have originated. The backward operator Πclosure traces the final Commitment Set Ω(i), under its surviving token-guarded family Σ(i), to its feasible terminal shield transactions E (i):
E (i) = Πclosure (πi , Ω(i), Σ(i)).
Results
(2)
Mapping the transactions in E (i) to their shielding addresses yields Addr(Ω(i)) in Equation 1. To evaluate Equation 2, Fig. 8 keeps one backward queue per analyzed proof; a state ( j,t) traces π j under token guard t. The sets Entryπ ( j) and Predπ ( j) contain terminal shield transactions and guarded predecessor states exposed directly by π j ; both are empty if its trace exposes no such edge. A direct predecessor remains traversable without a commitment input. For each candidate c, Entry(c,t) and Pred(c,t) respectively return the terminal shield transactions and earlier guarded proof states permitted by its public creation trace. Both retain all publicly indistinguishable alternatives and may be
5.1
Commitment Set Sizes
We evaluate the cumulative effects of Sec. 4 on the Commitment Set Size |Ω(i)| defined in Sec. 3.2. After cumulative pruning and cross-proof propagation, the mean size relative to the temporal baseline decreases by 82.2%, 66.7%, 58.5%, and 38.2% on Railgun’s Ethereum, Arbitrum, Polygon, and BNB Chain deployments, respectively, and by 72.8%, 76.7%, 75.8%, 77.5%, and 80.4% on Hinkal’s Ethereum, Arbitrum, Polygon, Base, and Optimism pools. Public token constraints are a major, persistent filter in both protocols, and Value and 7
Table 2: Cross-Protocol Dataset Overview.
from 1,017 to 491. Across the five selected Hinkal pools, this stage reduces each pool’s mean Commitment Set Size by less than 0.03%, indicating that proofs generally use roots close to the latest available state. Token. Token further excludes, from the Proof Root output, commitments incompatible with the target proof’s public token information. In Railgun, proof-created commitments may inherit multiple feasible token labels: Fig. 10 shows which tokens commonly appear in shield and unshield activity, while Fig. 11 shows their distribution in the historical commitment pool; together, these distributions determine how broad a target token branch remains. When WETH dominates both activity and candidate history, the common branches on Ethereum and Arbitrum remain broad; Polygon’s more dispersed token composition, and BNB Chain’s split between the two major WBNB and USDT branches, allow more commitments in other branches to be excluded once a token is fixed. Measured over all proof relations on each chain, the cumulative decrease in mean Commitment Set Size from Ω0 (i) through Ω3 (i) is approximately 79.1%, 62.1%, 55.7%, and 34.3% on Ethereum, Arbitrum, Polygon, and BNB Chain, respectively. By contrast, Hinkal has no uncertainty from inherited token labels: every same-token input–output relation publicly exposes an exact token address, so its candidates are tested against a singleton token branch and asset composition affects only the size of that branch. As shown in Fig. 17, the cumulative decreases on Ethereum, Arbitrum, Polygon, Base, and Optimism are 69.6%, 72.0%, 72.5%, 71.8%, and 76.5%, respectively, reflecting the strong partitioning effect of public token information. Value. Value uses public amounts and balance relations to test feasibility within the branches that survive Token. After Value and propagation, the mean final Commitment Set Size ranges from 13,736 to 22,286 across the four Railgun chains and from 861 to 2,716 across the five selected Hinkal pools. Token remains the main persistent filter, while the final checkpoint removes candidates ruled out by numerical feasibility and its propagated consequences. Hinkal’s smaller final sets also reflect its smaller independent pools and exact token addresses, which remove cross-token candidates before Value. The figures report Ω1 (i), Ω2 (i), and Ω3 (i) after the first three cumulative stages and the propagated final set Ω(i) after Value; Ω4 (i) before propagation is not reported separately. Sec. 4.1 explains the order and representation dependencies.
(a) Railgun. Chain
Commit.† Nullif. 61,804 60,984 51,428 43,257
Proofs Shield Txs Shield Addrs.‡ Spend Txs Unshield Txs
Ethereum
65,536 65,535 65,536 52,695
33,124 33,478 31,780 24,880
57,970
28,486
105,608
85,157
Arbitrum
65,535 60,810 34,605 50,782 38,436 26,196
30,049
10,911
50,933
42,256
Polygon
65,536 58,122 34,244 20,676 16,549 11,209
18,318
5,516
35,262
27,719
BNB Chain
45,203 39,808 21,604
12,028
5,493
18,667
14,708
Total
497,034 431,198 251,120
118,365
47,576
210,470
169,840
† For each chain, successive rows represent trees 0, 1, . . . in order.
(b) Hinkal. Chain
Commit. Nullif. Proofs Shield Txs Shield Addrs.‡ Spend Txs Unshield Txs
Ethereum Arbitrum Polygon Base Optimism
5,997 5,683 5,167 8,579 8,187 7,009 13,692 12,863 10,302 24,453 23,586 19,712 25,132 24,180 20,182
2,629 4,446 6,154 12,267 12,456
780 630 655 2,327 437
4,169 5,576 8,276 15,431 15,127
1,884 1,613 3,156 5,851 4,012
Total
77,853 74,499 62,372
37,952
4,123
48,579
16,516
‡ Chain rows count distinct shielding addresses within each chain; Total
deduplicates identical EVM addresses across chains.
propagation further refine the survivors. Railgun also benefits from Tree Number after a rollover, unlike Hinkal’s long-lived single-tree pools. Hinkal’s cumulative reductions are consequently more consistent across chains, whereas Railgun varies with tree count, asset composition, and history. Tree Number. Railgun distributes commitments across multiple trees, each with capacity 216 = 65,536. Because a proof’s tree number is public and its Merkle root authenticates only that tree’s state, Ω1 (i) contains at most the commitments already inserted there. Tree Number can therefore sharply reduce the candidate set immediately after a new tree opens. In Fig. 9, the local median Commitment Set Size falls to 550, 791, and 722 after Ethereum’s three rollovers, and to 222 and 120 after the rollovers on Arbitrum and Polygon, respectively. BNB Chain remains in one tree throughout the observation window and shows no such reduction. By contrast, Table 5 shows that each selected Hinkal pool maintains one long-lived tree of height 200, with capacity 2199 leaves. These pools require no Railgun-style rollovers within the observation window and thus have no Tree Number stage.
5.2
Proof Root. Within the tree selected by Tree Number, or within an independent Hinkal pool, Proof Root further excludes commitments not covered by the authenticated state used by the proof. Its aggregate effect is limited because most proofs use a root close to the latest state available at execution time; nevertheless, a proof using an older root can exclude a substantial suffix of later commitments. In the Polygon case examined in Table 4, Proof Root reduces the candidate set
Anonymity Set Sizes
This subsection first answers the source-range part of the research question in Sec. 1: from which shielding addresses could the funds released by a transaction that executes unshield have originated? Table 3 reports the final feasibleaddress distributions. Among 169,840 Railgun unshielding spend transactions, 2,968 retain at most ten addresses, including 920 singletons; however, 118,480 (69.8%) still retain more than 1,000. Ethereum has the largest mean final set, at 8
Commitment Set Size
105 44,736 44,687 23,136 44,736 44,687 23,134 35,665 34,782 32,297 32,993 15,194 104 15,826 14,368 14,368 10,590 9,346 3 10 1,592 722 722 1,592 550 791 549 791 548 533 1,270 476 598 1,177 452 541 102 (i) (i) (i) (i) (i) (i) (i) (i) 0 1 0 2 0 3 0 100 2022-05 2023-10 2025-03 2026-07 2022-05 2023-10 2025-03 2026-07 2022-05 2023-10 2025-03 2026-07 2022-05 2023-10 2025-03 2026-07
Commitment Set Size
105
(a) Ethereum 104 103 3,433 102 100 2023-02
16,840 0(i)
48,694
43,380 3,433
1(i)
2024-04
222
16,840 0(i)
2025-06
2026-07 2023-02
48,694
2(i)
2024-04
43,380 2,627
222
13,384
2026-07 2023-02
27,838
12,638
31,942
23,066
2,177 0(i)
2025-06
37,528
3(i)
2024-04
132
0(i)
2025-06
2026-07 2023-02
(i) 2024-04
112 2025-06
2026-07
Commitment Set Size
(b) Arbitrum 104
17,579
42,717
103 1,809 102 100 2022-05
17,579
17,254
42,717
17,254
12,595
1,809 0(i)
120
1(i)
2023-10
2025-04
120
2(i)
2023-10
2025-04
26,819
8,104
1,430 3(i) 2023-10
88
0(i)
2026-07 2022-05
11,038
8,842
1,477 0(i)
2026-07 2022-05
29,030
2025-04
(i) 2023-10
88
0(i)
2026-07 2022-05
2025-04
2026-07
Commitment Set Size
(c) Polygon 104
19,054
31,190
36,938 42,714
103
1,002 102 100 2022-05
19,054
31,190
36,938 42,714
13,412
1,002 0(i) 1(i) 2025-05
2026-02
0(i) 2(i) 2026-07 2022-05 2025-05
21,111
36,851 22,494
738 2026-07 2022-05
18,915
36,851 20,335
581 0(i)
2026-02
12,454
3(i)
2025-05
0(i)
2026-02
2026-07 2022-05
(i) 2025-05
2026-02
2026-07
(d) BNB Chain
Fig. 9: Temporal evolution of Railgun Commitment Set Size through July 30, 2026 (UTC), in 500 equal-count block-order bins per chain. Successive panels compare Ω0 (i) with Ω1 (i), Ω2 (i), Ω3 (i), and the propagated final Ω(i) after Value. Curves show P50; shading spans P0–P100; labels mark selected times, with colored outlines identifying tree rollovers. 8,796, whereas Polygon has the smallest, at 1,058. Among Hinkal’s 16,516 unshielding spend transactions, 711 retain at most ten addresses, including 308 singletons, and the chainlevel mean final sets range from 119 to 499.3 Hinkal’s smaller absolute sets partly reflect the shorter histories and smaller temporal baselines of its independent pools; a cross-protocol comparison must therefore also consider reduction relative to each protocol’s own baseline. The second part of the research question asks how far public protocol constraints can reduce this address set. Table 7 shows mean Anonymity Set Size reductions of 40.1%, 46.3%, 59.0%, and 47.6% for Railgun on Ethereum, Arbitrum, Polygon, and BNB Chain, respectively, and 57.0%, 57.4%, 53.0%, 52.0%, and 48.9% for Hinkal on Ethereum, Arbitrum, Polygon, Base, and Optimism. The Railgun chronology in Fig. 12, together with the corresponding Hinkal chronology in Appendix F, shows that these reductions persist throughout the observation window rather than arising from a few extreme transac-
tions. For Railgun, much of the cross-chain variation reflects token-branch width. As Fig. 10 and Fig. 11 jointly show, public unshield activity determines which token branches are queried frequently, while the asset distribution of historical commitments determines how wide those branches are. WETH dominates both activity and historical candidates on Ethereum and Arbitrum, so common transactions still fall into broad branches. Polygon’s more dispersed asset distribution generally allows a fixed target token to exclude a larger share of historical commitments, explaining its stronger addresslevel reduction. Hinkal exposes the exact asset address for every same-token relation and therefore creates a sharper partition at the commitment layer. After recursive closure, however, each surviving commitment may still connect to many historical shielding addresses, so this local advantage does not yield a proportional final address-set reduction. Proof composition further affects the final result. Table 7 shows that Railgun Proof 2 -only transactions have mean reductions of 53.4%–74.1%, higher than the 38.4%–56.7% for Proof 4 -only transactions; the latter release funds publicly while continuing to create shielded commitments and therefore generally retain broader feasible histories. Hinkal shows
3 Unlike Railgun, Hinkal permits relayed Shields. When Hinkal releases funds publicly, recipient transfers and relayer fees both appear as pool outflows. We therefore identify shielding addresses and exclude pure relayer-fee branches using contract semantics and asset transfers; see Appendix C.
9
41K (64.3%)
WETH
9.6K (14.9%) USDT 24K (14.4%) 8.4K (13.0%) USDC 23K (13.4%) (3.4%) DAI 2.2K6.8K (4.0%) (1.0%) WBTC 651 972 (0.6%) (3.4%) Others 2.2K 2.5K (1.5%)
111K (66.1%)
Shield Value ($2.11B)
Unshield Value ($2.01B)
0.5% 58.3% 1.6% 9.3% 13.3% 16.7%
0.6% 1.6% 9.2% 13.7% 16.5%
Unknown
58.5%
Unknown
(a) Ethereum
(b) Arbitrum
(a) Ethereum 18K (54.0%)
WETH USDC
8.9K (26.5%)
46K (59.4%)
17K (21.4%)
3.5K (10.6%) 7.8K (10.1%) 1.2K (3.5%) USDC.e 3.6K (4.7%) (2.0%) DAI 659 1.8K (2.3%) (3.5%) Others 1.2K 1.6K (2.1%) USDT
Shield Value ($128.8M)
(c) Polygon
2.6% 4.1% 11.7% 34.8%
(d) BNB Chain
Fig. 11: Token shares of all Railgun commitments over time.
35.0%
USDC.e DAI Others
12K (22.6%)
3.1K (14.4%) Unshield Value ($52.9M) 6.5K (12.0%) Shield Value ($54.3M) 2.8% 1.7K (8.1%) 44.2% 43.3% 2.3% 5.3K (9.8%) 4.3% 4.0% 2.1% 1.9% 1.0K (4.7%) 2.9K (5.4%) 10.2% 10.1% 2.1K (10.0%) 37.5% 37.3% 4.5K (8.4%)
WBNB USDT
6.4K (42.5%)
595 (3.9%) 1.6K (5.1%) 734 (4.9%) USDC 1.4K (4.4%) (0.7%) DAI 101 213 (0.7%) 720 (4.8%) Others 936 (3.0%) BUSD
15K (46.7%) 13K (40.2%)
Shield Value ($71.2M) 0.9% 0.7% 2.5% 8.1% 38.5%
Unshield Value ($67.9M)
49.2% 1.0% 0.6% 2.6% 6.2% 39.5%
1,568
102 130 100 2022-05
2023-10
103
0(T)
776
102 20 100 2022-05
(T)
2025-03
2023-10
431 0(T)
104 103
1,588
2,498
1,420 2,456
0(T)
(T)
373 2
10 100 2026-07 2023-02
2024-04
2025-06
2026-07
(b) Arbitrum
1,235 1,602
2025-04
(c) Polygon
50.2%
(T)
103
102 58 100 2026-07 2022-05
2,166
2025-05
927
1,143 1,650
0(T)
(T)
2026-02
2026-07
(d) BNB Chain
Fig. 12: Railgun Anonymity Set Size over time: temporal baseline (dashed) and final transaction-level union after closure lifting (solid). P50 curves use equal-count block-order bins of about 100 transactions; P0–P100 shading and labels at the 5%, 25%, 50%, 75%, and 95% timeline positions.
(d) BNB Chain Shield Commitment Count
5,577
103
12,948 22,589
(a) Ethereum
(c) Polygon 6.5K (43.2%)
104
Anonymity Set Size
USDC
5.1K (23.9%)
Anonymity Set Size
USDT
23K (41.9%)
Anonymity Set Size
8.3K (38.8%)
Anonymity Set Size
(b) Arbitrum WPOL
Unknown
39.8%
40.2% 6.8%
6.7% 2.6% 4.0% 11.7%
Unknown
Unshield Value ($125.0M)
Unshield Nullifier Count
Fig. 10: Top token activity across Railgun’s four deployment chains. The inset pies show USD-value shares for priced tokens, computed as described in Appendix E.
them by maximum hops within each chain, and compare the bottom and top quartiles. Railgun’s mean reduction falls from 54.5%–66.0% in the shallowest quartile to 12.3%–43.6% in the deepest; Hinkal’s corresponding ranges are 61.6%–73.5% and 45.6%–55.3%. Deeper feasible ancestry therefore generally accumulates more historical shielding addresses during closure lifting and weakens final reduction.
no consistent ordering between the two proof types, whose chain-level means differ by only 0.9–4.1 percentage points. Both protocols instead show a consistent within-transaction union effect: because the final set is the deduplicated union of proof-level address sets, one broad proof can offset substantial pruning in the others, so final privacy depends on their widths and overlaps rather than the most strongly pruned proof. Recursive depth also relates to final Anonymity Set Size (Table 8). We count one hop whenever backward tracing crosses one historical private state transition and record the maximum over all feasible source paths per transaction. The chain-level medians range from 4,628.5 to 24,872 for Railgun, substantially above Hinkal’s 645–2,608, showing that Railgun’s feasible sources usually extend through deeper histories. To isolate within-transaction union, we retain transactions for which exactly one proof contributes to A (T ), rank
5.3
Patterns and Case Studies
To expose the mechanisms behind Sec. 5.2, Table 4 traces representative Railgun unshielding spend transactions from Ω0 (i) through cumulative pruning and cross-proof propagation to Ω(i), then through closure lifting to E (i) and (|A0 (T )|, |A (T )|). The cases cover proof-level specialization, proof-structure effects, and transaction-level aggregation. Proof-Level Specialization. This category arises directly from the local pruning constraints of Sec. 4.1. Pattern 1.1, tree10
Table 3: Final Anonymity Set Size by protocol and chain; buckets give transaction counts and row percentages.
Proof 2 -only and Proof 4 -only rows in Table 7. Pattern 2.1, low-input rigidity is illustrated by two Ethereum WETH cases. Transaction 0xb0d961...d7df contains a Proof 2 with mi = 1 and ki = 0, so its single input must explain the complete public output value; after Value and propagation, the final Commitment Set falls from 52,158 to 38,929 candidates. By contrast, 0x8ebf10...8342 contains a Proof 4 with mi = 2 and ki = 1, for which the unreleased remainder may enter the newly created commitment; its candidate set stops shrinking after Token at 25,309. This local distinction does not by itself determine the transaction-level result, because the projected sets of multiple contributing proofs are subsequently unioned. Pattern 2.2, low-output rigidity is the corresponding effect of ki in Proof 4 . When ki = 1, only one newly created shielded note can carry the unreleased remainder, narrowing the admissible total-input range in Sec. 4.1.4. In the Arbitrum case 0xc0ea77...f050, both Proof 4 branches that produce public outputs have ki = 1. Their final Commitment Sets contain 2,397 and 3,970 candidates, and closure lifting maps them to 80 and 28 shielding addresses. The partially overlapping address sets yield a transaction-level union of 98 addresses, far below the temporal baseline of 1,712. Transaction-Level Aggregation. At the transaction layer, A (T ) is the deduplicated union of the shielding-address sets projected from all constituent proofs with public outputs, so the result depends on their widths and overlap. Pattern 3.1, broad-proof shielding is the regime in which one broad proof dominates the union. In Ethereum transaction 0x520db5...7820, the Proof 4 branch still maps to 9,620 feasible shielding addresses after closure, whereas the accompanying Proof 2 branch collapses to one. That singleton is already contained in the broader set, so the transactionlevel union remains 9,620 and the overall reduction is only 10.04%. A strongly pruned proof therefore cannot offset another broad proof in the same transaction. Pattern 3.2, overlap collapse is the opposite regime. In BNB Chain transaction 0x78d080...2ca7, the three Proof 2 branches have different final Commitment Sets, but closure lifting maps all three to the same 52 historical shield transactions and the same 30 shielding addresses. Because the projected sets coincide, deduplication adds no new addresses and the multi-proof transaction retains a final Anonymity Set Size of 30. Pattern Analysis of Small-Set Cases. Small-set cases show that the final Anonymity Set Size depends not only on how many candidate commitments remain, but also on how many shielding addresses those commitments can reach under backward tracing. Tree Number and Proof Root restrict only which commitments the current proof may consume directly; they do not sever those commitments’ links to earlier private states, because, for example, a commitment in a new tree may descend from funds represented by notes in an older tree. Accordingly, Pattern 1.1 leaves only seven commitments, yet closure lifting reaches 3,186 shield transactions and 1,014 shielding addresses; by contrast, the Ethereum ENS case retains 2,015
(a) Railgun. Count (%)
Chain
Mean Median
1
2–10
11–100
101–1000
Ethereum Arbitrum Polygon BNB Chain
373 (0.4%) 153 (0.4%) 243 (0.9%) 151 (1.0%)
669 (0.8%) 411 (1.0%) 440 (1.6%) 528 (3.6%)
1,477 (1.7%) 1,503 (3.6%) 2,194 (7.9%) 1,003 (6.8%)
10,667 (12.5%) 71,971 (84.5%) 8,796 11,083 (26.2%) 29,106 (68.9%) 3,066 14,714 (53.1%) 10,128 (36.5%) 1,058 5,751 (39.1%) 7,275 (49.5%) 1,297
Total
920 (0.5%) 2,048 (1.2%) 6,177 (3.6%) 42,215 (24.9%) 118,480 (69.8%) 5,458
Max
Min
5,881 1,993 646 987
26,509 10,305 4,998 5,273
1 1 1 1
2,445
26,509
1
1001+
(b) Hinkal. Count (%)
Chain 1
2–10
11–100
45 (2.4%) 338 (17.9%) 79 (4.9%) 470 (29.1%) 75 (2.4%) 885 (28.0%) 95 (1.6%) 743 (12.7%) 109 (2.7%) 1,508 (37.6%)
Mean Median Max Min 101–1000
1001+
Ethereum Arbitrum Polygon Base Optimism
44 (2.3%) 27 (1.7%) 56 (1.8%) 138 (2.4%) 43 (1.1%)
1,457 (77.3%) 0 (0.0%) 1,037 (64.3%) 0 (0.0%) 2,140 (67.8%) 0 (0.0%) 4,309 (73.6%) 566 (9.7%) 2,352 (58.6%) 0 (0.0%)
202 140 156 499 119
198 137 155 433 117
702 608 625 2,181 410
1 1 1 1 1
Total
308 (1.9%) 403 (2.4%) 3,944 (23.9%) 11,295 (68.4%) 566 (3.4%)
272
171
2,181
1
number fragmentation appears in the Arbitrum rollover case 0x16f6d4...08f4. The proof is in tree 1, whereas its temporal baseline still includes the complete history of tree 0, so Tree Number cuts the candidate set from 65,548 to 13. After the remaining stages and closure lifting, the final Anonymity Set contains 1,014 shielding addresses against a temporal baseline of 6,602. Pattern 1.2, proof-root staleness captures the corresponding restriction within one tree. In the Polygon case 0x30c459...2259, Tree Number is inactive, but Proof Root cuts the candidate set from 1,017 to 491. The remaining pipeline reduces the final Commitment Set to 177, and closure lifting leaves only six feasible shielding addresses from a baseline of 60. Pattern 1.3, asset specialization is illustrated by the Ethereum AAVE case 0x54ae52...b41b and the Ethereum ENS NFT case 0x8a77c4...8a3a. In the AAVE case, the structural stages do nothing, but Token cuts the candidate set from 63,213 to 46 and closure lifting leaves a singleton Anonymity Set. In the ENS case, the token branch still contains 2,015 commitments, yet closure lifting maps them to a single feasible shielding address. Thus, a narrow asset branch need not become a singleton at the commitment layer to converge to a very small address set. Pattern 1.4, value specialization is illustrated by the BNB Chain WBNB case 0xf70917...9471. Because WBNB retains a relatively broad historical token branch, Token narrows it only from 407 to 304; after Value and propagation, the final Commitment Set contains 97 candidates. Closure lifting reaches 61 historical shield transactions and 32 of the 42 baseline shielding addresses, a 23.81% reduction. This case shows that value feasibility and propagation can add useful constraints even when the target asset’s historical branch remains broad. Proof-Structure Effects. The public input and output structure of a proof changes the strength of the Value constraint, helping to explain the aggregate difference between the 11
Table 4: Representative Railgun unshielding spends illustrating the anonymity-loss patterns. Pattern ID Chain
Spend Tx
Time (UTC)
Proof Token
1.1
Arbitrum
0x16f6d4...08f4
2025-05-08 11:44
4
USDC
1.2
Polygon
0x30c459...2259
2022-07-01 18:14
1.3 1.3
Ethereum Ethereum
0x54ae52...b41b 0x8a77c4...8a3a
1.4
Value
13
13
8
7
3,186
6,602
1,014
84.64%
4
WETH
3,480 65,548
1,017
491
182
177
6
60
6
90.00%
2024-11-18 04:41 2024-01-24 06:27
4 2
AAVE 100.250627 63,213 63,213 63,213 ENS (NFT) 1 26,477 26,477 26,477
46 2,015
46 2,015
1 1
8,766 3,552
1 1
99.99% 99.97%
BNB Chain 0xf70917...9471
2022-08-19 14:50
4
WBNB
183.064222
304
97
61
42
32
23.81%
2.1
Ethereum Ethereum
0xb0d961...d7df 0x8ebf10...8342
2025-01-29 23:09 2024-04-16 15:57
2 4
WETH WETH
332.787559 73,045 65,536 65,536 52,158 38,929 13,165 0.512282 31,815 31,815 31,815 25,309 25,309 6,411
10,142 4,406
8,155 3,995
19.59% 9.33%
2.2
Arbitrum
0xc0ea77...f050
2024-01-05 12:43
4 4
USDC WBTC
161 34
1,712
98
94.28%
3.1
Ethereum
0x520db5...7820
2025-02-24 10:30
4 2
WETH FXI
0.048337 77,981 12,445 12,445 10,173 50,000 77,981 12,445 12,445 8
9,912 15,553 7 1
10,694
9,620
10.04%
3.2
BNB Chain 0x78d080...2ca7
2023-07-25 08:32
2 2 2
USDC USDC USDC
34.445306 51.1101 11.657887
2,027 2,029 1,975
800
30
96.25%
0.997436
1,017
407
407
407
9,950 16,372 16,372 16,372 0.17 16,372 16,372 16,372
commitments, all of which trace to one shielding address. Token and Value instead restrict candidate branches using public asset and amount relations, and the token condition remains in force during backward tracing, so asset branches with smaller histories and more concentrated sources are more likely to yield small sets. At the transaction layer, any contributing proof that still maps to many shielding addresses can dominate the final union; a multi-proof transaction therefore forms a small set only when the projected address set of every contributing proof is narrow or when those sets overlap.
6
|Ω0 (i)| |Ω1 (i)| |Ω2 (i)| |Ω3 (i)| |Ω(i)| |E (i)| |A0 (T )| |A (T )| redA (T )
7,062 7,062 7,062
7,062 7,062 7,062
7,062 7,062 7,062
2,589 3,990
2,065 2,065 2,065
2,397 3,970
52 52 52
tion remains below 0.03%, at the cost of submitting a proof before its root expires or regenerating it afterward. Implications for Protocol Designers. Upgrade policy likewise determines whether accumulated anonymity history survives across versions. On the three chains with a V1–V2 transition, Railgun continued the same production pool’s commitment-tree state, so old commitments remain feasible sources in V2. Each Hinkal contract generation instead starts an independent pool, disconnecting its predecessors and excluding their commitments from new proofs. Table 5 shows that 23 of Hinkal’s 37 nonempty pools contain fewer than 1,000 commitments; each new pool therefore restarts anonymity accumulation. Protocol upgrades should preserve pool state and anonymity-domain continuity where possible. Public asset information additionally partitions each pool by token. Hinkal exposes the exact token address of each same-token relation, so Token reduces mean Commitment Set Size from the temporal baseline by 69.6%–76.5% across the five chains; Railgun shielded transfers do not directly reveal the exact token and can retain multiple feasible branches. This partition survives closure: in Appendix F, 1,813 of 1,884 Ethereum unshielding spend transactions (96.2%) publicly release one token, and every feasible historical source in their complete closures has that token. Their mean shieldingaddress baseline falls from 485 to 198 when restricted to the public token, and the complete closure leaves 197. Hinkal’s address-level reduction is milder than its commitment-level contraction because a transaction’s Anonymity Set unions its constituent proofs’ source sets, widening the transaction-level set but not any proof’s token domain. Public token information thus causes persistent privacy loss across commitment, proof, and transaction layers.
Discussion
Performance–Anonymity Tradeoffs. Railgun and Hinkal make different state-management tradeoffs (Appendix C). Railgun’s fixed-depth-16 Merkle trees have predictable update paths, but a new tree opens when the current tree cannot accommodate the next commitment batch, and public tree numbers partition one deployment’s history into candidate domains. Hinkal’s much larger logical tree maintains only the depth reached by its state, so the evaluated pools neither roll over nor support Tree Number pruning. Railgun thus trades bounded per-tree state for structural partitioning, whereas Hinkal preserves continuity within each pool but lets the maintained path grow with the state. Tree height, capacity, and rollover policy jointly shape maintenance cost and how much history remains in one anonymity domain. Root retention similarly balances state cost, proofsubmission flexibility, and effective anonymity history. Railgun accepts historical roots indefinitely, keeping old proofs usable but growing retained on-chain state and allowing a stale root to fix the candidate set at an earlier prefix. Hinkal’s circular history retains the latest 200 roots, bounding state growth and stale-root exposure; its mean Proof Root reduc-
Implications for Users. Users should use the freshest available root: an old Proof Root removes up to 10,384 candidates 12
Non-heuristic structure-based privacy analysis. Ringbased systems provide the closest precedent for non-heuristic structural propagation: because each ring publishes its candidate members, eliminating one candidate can constrain subsequent transactions along the public graph. Monero studies combine such chain reactions with heuristic inference [10, 35], while later work formalizes structure-only attacks and studies graph-analysis resistance and sustainable ring construction [11, 12, 36]. Protocol-design research also spans commitment-nullifier payments [16, 17], account- and ledger-based confidentiality [37, 38], programmable private computation [39–42], and commitment-backed UTXO stealth addresses [43]; a recent systematization compares these designs [2]. These bodies of work establish structural inference techniques, protocol constructions, security notions, and programming models, but not a method for measuring recursive provenance in deployed shielded systems. The shielded UTXO-based systems studied here present a more involved reconstruction problem: consumed commitments are not published, value can traverse multiple hidden-state transitions through newly created notes, and the relevant public constraints span the commitment, proof, and transaction layers. Analysis therefore cannot propagate over an already published candidate graph; it must first reconstruct each proof’s feasible commitments, recursively lift them through historical hiddenstate transitions to shielding addresses, and aggregate them at the transaction layer.
from a single Railgun proof in our data. After long delays or failed submissions followed by pool activity, users should update the witness and regenerate the proof rather than retry against old state. When compatible pools are available, they should prefer a mature active pool over a newer one with little history; publicly withdrawing from the old pool and Shielding into the new one creates a new public boundary without carrying over the old anonymity history. They should also judge the target asset’s history, not total pool size. In Table 4, Token reduces the AAVE case from 63,213 candidates to 46, after which closure reaches one shielding address; when flexible, users should let new or rarely used token branches accumulate history. In the WBNB case, Value and propagation reduce the 304 candidates surviving Token to 97; when possible, users should prefer common ranges to rare exact values. Toward Better Privacy Protocols. Better privacy protocols should not make baseline anonymity depend on a particular time, asset, or pool. If an in-place upgrade cannot preserve the commitment-tree state, a new pool could verify a private migration proof against the old state, consume an old note, and create a new one without a public withdrawal and subsequent Shield, thereby preserving provenance. This mechanism must prevent cross-pool double-spending and address root finality and state synchronization. Likewise, token identity could remain inside commitments and zero-knowledge circuits, with the exact asset revealed only for necessary public settlement and token consistency and value conservation proved in-circuit. Private conversion proofs could keep a public output token from deterministically fixing its historical input token, at the cost of larger circuits and proofs and new liquidity, pricing, and manipulation-resistance constraints.
7
8
Conclusion
This paper presents a non-heuristic privacy-measurement framework for shielded UTXO-based protocols for DeFi, grounded in a three-layer note/proof/transaction abstraction. Using only public ledger traces and protocol rules, it recursively traces each proof’s feasible commitments through historical hidden-state transitions to shielding addresses and aggregates them into transaction-level Anonymity Set Size. Across the complete histories of all Railgun production deployments and five independent Hinkal pools, the framework yields mean Anonymity Set Size reductions of 40.1%–59.0% relative to the temporal baseline. The analysis deliberately excludes heuristic methods such as user/entity attribution, thereby isolating anonymity loss caused by public protocol constraints. The three-layer framework can also be instantiated, according to public protocol semantics, for broader commitment-nullifier privacy protocols beyond our target class: in Zcash, for example, structural tree/root constraints can still bound candidate history, while its single-asset design renders the Token stage inapplicable. Broader commitmentnullifier privacy protocols can thus first compare anonymity loss caused by public protocol constraints under a common non-heuristic baseline, then layer on heuristic analyses for specific applications, such as money-laundering prevention.
Related Work
Heuristic attribution-based privacy analysis. Huseynov et al. apply five heuristics based on timing, address reuse, publicgraph proximity, and amount patterns to Railgun on Ethereum, uniquely linking 17.65% of withdrawals to one deposit and reporting a 3.42-bit median anonymity loss [9]. Much of the broader privacy-measurement literature similarly approaches user-level privacy through clustering, timing, value patterns, or other heuristic attribution signals [30–33], including studies of Zcash, mixers, Tornado Cash, and Umbra [4,7,8,34]. What is missing, especially for widely deployed shielded UTXObased protocols, is a non-heuristic baseline that first isolates anonymity loss from protocol-visible constraints alone and systematically traces recursive provenance through hiddenstate transitions. We provide such a framework by decomposing the system across commitment, proof, and transaction layers and measuring address-level feasible sets without user attribution. This makes our results complementary to user-level analysis: entity linking, heuristic attribution, and probability-weighted metrics can be layered on top. 13
Ethical Considerations
ac.uk/2026/crypto-privacy-after-sanctions -the-return-of-coin-mixers/.
We considered the effects of this research on protocol users, developers and operators, and researchers or analysts. The study passively analyzes public, append-only blockchain data and public protocol semantics; it submits no transactions, changes no protocol state, uses no non-public data, and involves no human participants. Our analysis uses only protocolvisible constraints and makes no identity or ownership attributions, behavioral inferences, or probabilistic rankings. The results are dual use: small or singleton feasible sets may help narrow transaction provenance, while the same measurements help users assess effective anonymity and designers mitigate privacy loss. We limit incremental harm by reporting feasible address sets rather than identities and by not combining results with off-chain attribution signals, although others could do so. Because the study measures public protocol behavior rather than exposing a secret implementation flaw, we do not treat it as requiring a separate vulnerability-disclosure process. We judged both the study and its publication justified because the traces and constraints are already public, while systematic analysis enables concrete defensive guidance and more privacy-preserving designs.
[4] Zhipeng Wang, Stefanos Chaliasos, Kaihua Qin, Liyi Zhou, Lifeng Gao, Pascal Berrang, Benjamin Livshits, and Arthur Gervais. On how zero-knowledge proof blockchain mixers improve, and worsen user privacy. In Proceedings of the ACM Web Conference 2023, pages 2022–2032. ACM, 2023. URL: https://dl.acm.org /doi/10.1145/3543507.3583217, doi:10.1145/35 43507.3583217. [5] Sarah Meiklejohn and Rebekah Mercer. Möbius: Trustless tumbling for transaction privacy. Proceedings on Privacy Enhancing Technologies, 2018(2):105–121, 2018. doi:10.1515/popets-2018-0015. [6] Ethan Heilman, Leen AlShenibr, Foteini Baldimtsi, Alessandra Scafuro, and Sharon Goldberg. TumbleBit: An untrusted Bitcoin-compatible anonymous payment hub. In Proceedings 2017 Network and Distributed System Security Symposium. Internet Society, 2017. doi:10.14722/ndss.2017.23086. [7] George Kappos, Haaroon Yousaf, Mary Maller, and Sarah Meiklejohn. An empirical analysis of anonymity in zcash. In 27th USENIX Security Symposium (USENIX Security 18), pages 463–477. USENIX Association, 2018. URL: https://www.usenix.org/confere nce/usenixsecurity18/presentation/kappos.
Open Science An anonymized artifact is available at https://anonym ous.4open.science/r/the_anonymity_gap-BCDD/RE ADME.md. It provides the complete acquisition-to-analysis workflow and code for reconstructing the public-chain inputs and reproducing commitment pruning, backward closure, transaction-level anonymity metrics, and closure-depth measurements for every evaluated deployment. Its linked data archive contains the exact prepared inputs and frozen outputs for the observation window ending July 30, 2026.
[8] Alex Márk Kovács and István András Seres. Anonymity analysis of the umbra stealth address scheme on ethereum. In Companion Proceedings of the ACM Web Conference 2024, WWW ’24, pages 1768–1775, New York, NY, USA, 2024. Association for Computing Machinery. doi:10.1145/3589335.3651963. [9] Kanan Huseynov, Ali Shahzaib, István András Seres, and János Tapolcai. A tattered cloak of invisibility: Measuring anonymity loss in railgun on ethereum, 2026. URL: https://arxiv.org/abs/2606.25926, arXi v:2606.25926.
References [1] U.S. Department of the Treasury. U.S. treasury sanctions notorious virtual currency mixer tornado cash, 8 2022. Published 2022-08-08; accessed 2026-08-16. URL: https://home.treasury.gov/news/press-r eleases/jy0916.
[10] Malte Möser, Kyle Soska, Ethan Heilman, Kevin Lee, Henry Heffan, Shashvat Srivastava, Kyle Hogan, Jason Hennessey, Andrew Miller, Arvind Narayanan, and Nicolas Christin. An empirical analysis of traceability in the monero blockchain. Proceedings on Privacy Enhancing Technologies, 2018(3):143–163, 2018. URL: https://petsymposium.org/popets/2018/popet s-2018-0025.php, doi:10.1515/popets-2018-0 025.
[2] Foteini Baldimtsi, Kostas Chalkias, Varun Madathil, and Arnab Roy. SoK: Privacy-preserving transactions in blockchains. Cryptology ePrint Archive, Paper 2024/1959, 2024. URL: https://eprint.iacr.org/ 2024/1959. [3] Wenbin Wu and Keith Bear. Crypto privacy after sanctions: The return of coin mixers, 2 2026. Cambridge Judge Business School. Published 2026-02-24. Accessed 2026-04-14. URL: https://www.jbs.cam.
[11] Saravanan Vijayakumaran. Analysis of cryptonote transaction graphs using the dulmage-mendelsohn decomposition. In 5th Conference on Advances in Financial Tech14
nologies (AFT 2023), volume 282 of Leibniz International Proceedings in Informatics (LIPIcs), pages 28:1– 28:22. Schloss Dagstuhl – Leibniz-Zentrum für Informatik, 2023. URL: https://drops.dagstuhl.de/en tities/document/10.4230/LIPIcs.AFT.2023.28, doi:10.4230/LIPIcs.AFT.2023.28.
[21] RAILGUN. RAILGUN documentation, 2026. Accessed 2026-08-16. URL: https://docs.railgun.org/. [22] Tornado Cash. Tornado cash documentation: Shielded transfers on nova, 2026. Accessed 2026-08-16. URL: https://docs.tornado.cash/tornado-cash-nov a/shielded-transfers-on-nova.
[12] Sherman S. M. Chow, Christoph Egger, Russell W. F. Lai, Viktoria Ronge, and Ivy K. Y. Woo. On sustainable ring-based anonymous systems. In 2023 IEEE 36th Computer Security Foundations Symposium (CSF), pages 568–583. IEEE, 2023. doi:10.1109/CSF57540 .2023.00035.
[23] zkBob. zkbob documentation, 2026. Accessed 2026-0816. URL: https://docs.zkbob.com/. [24] Daira-Emma Hopwood, Sean Bowe, Taylor Hornby, and Nathan Wilcox. Zcash protocol specification, 2026. Accessed 2026-08-16. URL: https://zips.z.cash/pr otocol/protocol.pdf.
[13] Gavin Wood. Ethereum: A secure decentralised generalised transaction ledger. Ethereum Yellow Paper, 2014. URL: https://ethereum.github.io/yellowpaper /paper.pdf.
[25] Hinkal. Hinkal whitepaper, 2023. Accessed 2026-08-16. URL: https://hinkal-team.gitbook.io/hinkal. [26] Nocturne. Nocturne documentation, 2026. Accessed 2026-08-16. URL: https://nocturne-xyz.gitbook .io/nocturne.
[14] Ferenc Béres, István A. Seres, András A. Benczúr, and László Kocsis. Blockchain is watching you: Profiling and deanonymizing ethereum users, 2021. URL: https: //arxiv.org/abs/2005.14051, arXiv:2005.140 51.
[27] Tornado Cash. Tornado cash documentation: How does tornado cash work?, 2026. Accessed 2026-08-16. URL: https://docs.tornado.cash/general/how-doe s-tornado-cash-work.
[15] Ralph C. Merkle. A digital signature based on a conventional encryption function. In Advances in Cryptology — CRYPTO ’87, volume 293 of Lecture Notes in Computer Science, pages 369–378. Springer, 1988. doi:10.1007/3-540-48184-2_32.
[28] Claudia Díaz, Stefaan Seys, Joris Claessens, and Bart Preneel. Towards measuring anonymity. In Privacy Enhancing Technologies, volume 2482 of Lecture Notes in Computer Science, pages 54–68. Springer, 2003. doi: 10.1007/3-540-36467-6_5.
[16] Eli Ben-Sasson, Alessandro Chiesa, Christina Garman, Matthew Green, Ian Miers, Eran Tromer, and Madars Virza. Zerocash: Decentralized anonymous payments from Bitcoin. In 2014 IEEE Symposium on Security and Privacy, pages 459–474. IEEE, 2014. doi:10.1109/ SP.2014.36.
[29] Andrei Serjantov and George Danezis. Towards an information theoretic metric for anonymity. In Privacy Enhancing Technologies, volume 2482 of Lecture Notes in Computer Science, pages 41–53. Springer, 2003. doi: 10.1007/3-540-36467-6_4.
[17] Antoine Rondelet and Michal Zajac. Zeth: On integrating zerocash on ethereum, 2019. URL: https://arxi v.org/abs/1904.00905, arXiv:1904.00905.
[30] Sarah Meiklejohn, Marjori Pomarole, Grant Jordan, Kirill Levchenko, Damon McCoy, Geoffrey M. Voelker, and Stefan Savage. A fistful of Bitcoins: Characterizing payments among men with no names. In Proceedings of the 2013 Internet Measurement Conference, IMC ’13, pages 127–140. ACM, 2013. doi: 10.1145/2504730.2504747.
[18] Jens Groth. On the size of pairing-based non-interactive arguments. In Advances in Cryptology — EUROCRYPT 2016, volume 9665 of Lecture Notes in Computer Science, pages 305–326. Springer, 2016. doi: 10.1007/978-3-662-49896-5_11. [19] Hanze Guo, Yebo Feng, Cong Wu, Zengpeng Li, and Jiahua Xu. Benchmarking ZK-friendly hash functions and SNARK proving systems for EVM-compatible blockchains, 2024. URL: https://arxiv.org/ab s/2409.01976, arXiv:2409.01976.
[31] Elli Androulaki, Ghassan O. Karame, Marc Roeschlin, Tobias Scherer, and Srdjan Capkun. Evaluating user privacy in Bitcoin. In Financial Cryptography and Data Security, volume 7859 of Lecture Notes in Computer Science, pages 34–51. Springer, 2013. doi:10.1007/ 978-3-642-39884-1_4.
[20] ScopeLift. Umbra protocol documentation, 2026. Accessed 2026-08-16. URL: https://github.com/Sco peLift/umbra-protocol.
[32] Haaroon Yousaf, George Kappos, and Sarah Meiklejohn. Tracing transactions across cryptocurrency ledgers. In 28th USENIX Security Symposium, pages 15
837–850. USENIX Association, 2019. URL: https: //www.usenix.org/conference/usenixsecurity 19/presentation/yousaf.
[40] Sean Bowe, Alessandro Chiesa, Matthew Green, Ian Miers, Pratyush Mishra, and Howard Wu. ZEXE: Enabling decentralized private computation. In 2020 IEEE Symposium on Security and Privacy, pages 947–964. IEEE, 2020. doi:10.1109/SP40000.2020.00050.
[33] Harry Kalodner, Malte Möser, Kevin Lee, Steven Goldfeder, Martin Plattner, Alishah Chator, and Arvind Narayanan. BlockSci: Design and applications of a blockchain analysis platform. In 29th USENIX Security Symposium, pages 2721–2738. USENIX Association, 2020. URL: https://www.usenix.org/conferenc e/usenixsecurity20/presentation/kalodner.
[41] Samuel Steffen, Benjamin Bichsel, Mario Gersbach, Noa Melchior, Petar Tsankov, and Martin Vechev. zkay: Specifying and enforcing data privacy in smart contracts. In Proceedings of the 2019 ACM SIGSAC Conference on Computer and Communications Security, CCS ’19, pages 1759–1776. ACM, 2019. doi: 10.1145/3319535.3363222.
[34] Mike Wu, Will McTighe, Kaili Wang, Istvan A. Seres, Nick Bax, Manuel Puebla, Mariano Mendez, Federico Carrone, Tomás De Mattey, Herman O. Demaestri, Mariano Nicolini, and Pedro Fontana. Tutela: An opensource tool for assessing user-privacy on ethereum and tornado cash, 2022. URL: https://arxiv.org/abs/ 2201.06811, arXiv:2201.06811.
[42] Thomas Kerber, Aggelos Kiayias, and Markulf Kohlweiss. KACHINA: Foundations of private smart contracts. In 2021 IEEE 34th Computer Security Foundations Symposium, pages 1–16. IEEE, 2021. doi:10.1109/CSF51468.2021.00002. [43] Hanze Guo, Yebo Feng, Cong Wu, Zengpeng Li, and Jiahua Xu. StealthHub: UTXO-Based Stealth Address Protocol. In 2025 IEEE International Conference on Web Services (ICWS), pages 996–1003, 2025. URL: https://ieeexplore.ieee.org/document/11169 586, doi:10.1109/ICWS67624.2025.00131.
[35] Amrit Kumar, Clément Fischer, Shruti Tople, and Prateek Saxena. A traceability analysis of monero’s blockchain. In Computer Security – ESORICS 2017, volume 10493 of Lecture Notes in Computer Science, pages 153–173. Springer, 2017. doi:10.1007/978-3 -319-66399-9_9. [36] Christoph Egger, Russell W. F. Lai, Viktoria Ronge, Ivy K. Y. Woo, and Hoover H. F. Yin. On defeating graph analysis of anonymous transactions. Proceedings on Privacy Enhancing Technologies, 2022(3):538– 557, 2022. URL: https://www.petsymposium .org/popets/2022/popets- 2022- 0085.php, doi:10.56553/POPETS-2022-0085.
A
Formal Propagation Procedure
This appendix formalizes the propagation stage of Sec. 4.1.5 by specifying its analysis order, state, update actions, and fixpoint. It uses the conservative local operator of Sec. 4.1.4: an update removes a candidate only when a public constraint or a mandatory spend makes it unavailable. Proof Relations and Public Order. We use the proof abstraction πi defined in Sec. 3.1.2. It need not coincide oneto-one with a cryptographic proof: one cryptographic proof may jointly authenticate several such relations. Propagation requires an analysis order, not a claim that those relations were verified separately or sequentially. Let ≺ denote the canonical order induced by the public state-transition trace. Across transactions, it follows ledger execution order; among relations within one transaction or jointly authenticated by one cryptographic proof, it uses only an order exposed by that trace. The order directs conservative information flow. In particular, commitments created within a spend transaction remain unavailable to every proof in that transaction, as required by Sec. 3.1.3, and their projected labels can affect only later state transitions. If no internal order is public, the relations share one execution boundary and no order-dependent creating-proof edge is introduced.
[37] Benedikt Bünz, Shashank Agrawal, Mahdi Zamani, and Dan Boneh. Zether: Towards privacy in a smart contract world. In Financial Cryptography and Data Security, volume 12059 of Lecture Notes in Computer Science, pages 423–443. Springer, 2020. doi:10.1007/978-3 -030-51280-4_23. [38] Ethan Cecchetti, Fan Zhang, Yan Ji, Ahmed Kosba, Ari Juels, and Elaine Shi. Solidus: Confidential distributed ledger transactions via PVORM. In Proceedings of the 2017 ACM SIGSAC Conference on Computer and Communications Security, CCS ’17, pages 701–717. ACM, 2017. doi:10.1145/3133956.3134010. [39] Ahmed Kosba, Andrew Miller, Elaine Shi, Zikai Wen, and Charalampos Papamanthou. Hawk: The blockchain model of cryptography and privacy-preserving smart contracts. In 2016 IEEE Symposium on Security and Privacy, pages 839–858. IEEE, 2016. doi:10.1109/ SP.2016.55.
Propagated Proof State. For each proof πi , Ξ(i) contains its fixed structural domain Ω2 (i), current Commitment Set Ω(i), mandatory set M(i), token-guarded family Σ(i), and 16
projected output labels. The structural domain is produced by Strategies 1 and 2 and includes the identity case when either strategy is inapplicable. Every later state satisfies M(i) ⊆ Ω(i) ⊆ Ω2 (i). Propagation never changes Ω2 (i); subsequent contraction comes from reservations or from reevaluating the token–value tail under narrower public interpretations. The propagated state also retains the immutable public inputs introduced in Sec. 3.1.2, Sec. 4.1.3, and Sec. 4.1.4: mi , ki , Ti , the public balance relation of πi , and Ui when Oi ̸= ∅. They are fixed properties of πi and its public trace. Token-Guarded Representation. The family Σ(i) = {Ωt (i)}t∈Θ(i) records the surviving token interpretations of πi , where Θ(i) ⊆ Θ⋆i is the current token-guard set. Each Ωt (i) descends from the local slice Ωt4 (i) returned by Sec. 4.1.4, and their union is the current Commitment Set, Ω(i) = S t t∈Θ(i) Ω (i). Whether Σ(i) is a singleton is determined by the public trace, not by the Proof 2 – 4 name. If the trace fixes one token, then Θ(i) = {t} and the unique guarded slice equals Ω(i). If several token interpretations remain possible, Σ(i) retains one slice for each surviving interpretation. Removing a token branch removes its guard from Θ(i) and its slice from Σ(i). For each branch, Mt (i) contains the commitments present in every explanation under guard t. The cross-branch set is T M(i) = t∈Θ(i) Mt (i), so a commitment is globally mandatory only when every surviving token interpretation forces it. Projected Labels on Created Commitments. We use the feasible token set Λ(c) from Sec. 4.1.3 and the creating proof π(c) from Sec. 3.1.2. The current output state of π(c) may further narrow Λ(c) and the feasible value interval carried by c under each surviving guard. Later proofs read these projected labels when reapplying Stoken and Svalue . The projection always respects the public creation relation. A token label is not copied blindly from an input branch: the same guard is inherited only when the public trace relates the created commitment to that token, and a different guard is propagated only when the trace determines the corresponding token relation. Likewise, a public token at creation yields a singleton label even if other relations jointly authenticated by the same cryptographic proof use different tokens. The value component is the current feasible output-value interval under each token guard, intersected with any value information exposed at creation. The guarded proof state and the commitment labels are two views of the same semantic information. Σ(i) stores the surviving interpretations of πi ; projected labels expose the corresponding output interpretation to later proofs that contain commitments created by πi in their structural domains. All output labels affected by an upstream branch removal or an output-interval contraction are synchronized before downstream recomputation. This forward semantic channel is separate from closure provenance. A proof-created commitment may depend on both a direct Shield source and earlier proofcreated state. Propagation records its feasible token/value
Cross-Proof Propagation Πprop Notation. ≺ is the canonical order of proof relations πi induced by the public state-transition trace. Ξ(i) stores the fixed structural domain Ω2 (i), the current Ω(i) and M(i), the guarded family Σ(i), and the projected token/value labels attached to commitments created by πi . R is the shared reserved-commitment set and Q is a fair work queue. Init, Refresh, Lock, and Notify are defined in Appendix A. function Πprop (πi , Ω0 (i))ni=1 Q←∅ R←∅ for all πi in order ≺ do Ξ(i) ← Init(i, Ω0 (i)) Lock(i) Q ← Q ∪ Notify(i) while Q ̸= ∅ do i ← pop(Q) Refresh(i) Lock(i) Q ← Q ∪ Notify(i) return {Ω(i)}ni=1 , {Σ(i)}ni=1 extracted from {Ξ(i)}ni=1 end function
Fig. 13: Cross-proof propagation to a common fixpoint.
state; Entry and Pred in Sec. 4.2 retain the publicly permitted provenance alternatives during backward lifting. Shared Propagation State. Let R be the shared reservedcommitment set. A commitment enters R once it is mandatory for one proof. Because the corresponding note is consumed there, it is unavailable to any other compatible proof domain. This reservation uses only the commitment–nullifier singlespend rule of Sec. 3.1.1; it does not select among merely optional candidates. The notification relation is instantiated conservatively from the public trace. Railgun removes a uniquely reserved commitment leaf from every other compatible domain whose authenticated root covers it. Hinkal processes reservations chronologically, reserving all commitments for a proof relation only when its surviving domain equals its nonzero input count, and suppresses this rule when duplicate commitment values prevent a unique mapping to leaf occurrences. Both instantiations remove only commitments whose reuse is impossible; their scheduling affects pruning completeness, not soundness. Let Q be a fair work queue of proofs whose semantic states may shrink. A proof is enqueued when either a mandatory set enlarges R or a projected label on one of its proof-created candidates narrows. These are the two propagation channels: the reservation channel removes notes forced into another spend, while the label channel propagates narrowed token/value labels through created commitments. Initialization. As shown in Fig. 13, Init(i, Ω0 (i)) constructs the state Ξ(i) defined above. It fixes Ω2 (i) using Strategies 1 and 2, then evaluates the token–value tail under the reservations and projected labels available when πi is first reached in order ≺. As required by Sec. 4.1.4, unresolved hidden as17
Table 5: Hinkal pool inventory; shading marks selected pools.
signments do not by themselves remove candidates from the initialized guarded slices. Refresh. Refresh(i) is used only after a notified update. It keeps Ω2 (i) and all immutable public parameters fixed, and recomputes the semantic tail under the current R and current projected labels. A candidate may disappear because it is now reserved by another proof, because its token label no longer intersects a surviving branch, or because its value interval no longer supports the public balance relation. No other removal rule is available. If refresh changes Θ(i), a guarded slice, M(i), or an output label owned by πi , the change is recorded before affected proofs are enqueued. If refresh makes every branch infeasible, the analysis terminates rather than selecting an interpretation unsupported by the public constraints. Lock. Lock(i) adds every newly mandatory commitment in M(i) to R. The definition of M(i) already requires the commitment to appear in every surviving explanation, so locking it introduces no choice among feasible hidden assignments. If |M(i)| = mi , all inputs of πi are uniquely determined and remain fixed thereafter. The simpler condition |Ω(i)| = mi is sufficient for this case, but it is not the definition of mandatory status: commitments may be mandatory even when additional optional candidates remain. Reservations are monotone. Once a commitment has been proved mandatory for one relation, later shrinkage cannot make it available to another without contradicting the first relation’s surviving explanation set.
Chain
Order Contract / Program Deployment Date (UTC) Tree Height Commitments
Ethereum
D1† D2 D3 D4 D5† D6
0x59a5...0c75 0x2ea8...2e28 0x13b6...8cd6 0x25e5...a826 0xed03...ea1c 0x7cb6...cfa4
2023-09-29 2023-11-10 2025-05-23 2025-06-27 2026-07-15 2026-07-16
25 25 200 200 200 200
23 1,911 30 5,997 7 159
Arbitrum
D1† D2 D3 D4 D5
0x8498...456c 0x4165...64de 0x13b6...8cd6 0x25e5...a826 0x7cb6...cfa4
2023-09-26 2023-11-08 2025-05-23 2025-06-27 2026-07-16
25 25 200 200 200
140 20,835 565 8,579 190
Polygon
D1† D2† D3 D4 D5 D6† D7
0xd7b7...34d6 0x2609...64fb 0xeeee...cdd5 0x13b6...8cd6 0x25e5...a826 0xed03...ea1c 0x7cb6...cfa4
2023-09-18 2023-09-22 2023-11-07 2025-05-23 2025-06-27 2026-07-15 2026-07-16
25 25 25 200 200 200 200
3 168 15,956 506 13,692 124 624
BNB Chain
D1 D2 D3 D4†
0x0036...a069 0x13b6...8cd6 0x25e5...a826 0x7cb6...cfa4
2023-11-08 2025-05-23 2025-06-27 2026-07-29
25 200 200 200
5,512 0 0 37
Base
D1 D2 D3 D4
0x4165...64de 0x13b6...8cd6 0x25e5...a826 0x7cb6...cfa4
2024-03-22 2025-05-23 2025-06-27 2026-07-16
25 200 200 200
17,385 611 24,453 767
Optimism
D1† D2 D3 D4 D5
0x4369...d853 0x4165...64de 0x13b6...8cd6 0x25e5...a826 0x969e...8188
2023-10-05 2023-11-08 2025-05-23 2025-06-27 2026-07-23
25 25 200 200 200
24 11,555 2,477 25,132 4
Avalanche
D1† D2 D3 D4
0x390f...322f 0x4165...64de 0x13b6...8cd6 0x25e5...a826
2023-09-26 2023-11-09 2025-05-23 2025-06-27
25 25 200 200
116 2,284 197 280
Tempo
D1
0x631c...5a5e
2026-06-02
200
455
Tron
D1
TKFU...9axaw
2026-03-16
200
61
Solana
D1 D2
BD7y...95ER J4Ss...cG5H
2025-12-30‡ 2026-03-12‡
200 200
48 6,352
Total: 39 deployed pools (37 nonempty)
167,259
†
Pool identified and verified directly on-chain, supplementing the recovered public deployment records for that period. ‡ Solana deployment date inferred from the earliest visible program signature as the closest observable on-chain timestamp.
Notification. Notify(i) identifies proofs π j allowed by the instantiation’s notification relation. It enqueues π j if its fixed structural domain contains a newly reserved commitment or if it contains a proof-created commitment whose projected label was narrowed by the current state of πi . The latter case is necessarily forward because a created commitment can enter only a later authenticated state. Proofs that satisfy neither condition are not revisited.
B
Hinkal Deployments and Selection
Each independently deployed Hinkal pool maintains its own commitment tree and therefore forms a separate anonymity domain. Table 5 inventories these states and the selection used in Sec. 5. Labels D1, D2, . . . give deployment order within a chain; they are not cross-chain version identifiers. At the inclusive cutoff (July 30, 2026, 23:59:59 UTC), 39 pool states are deployed across ten chains. The 37 nonempty pools contain 167,259 commitments, but activity is fragmented: 23 contain fewer than 1,000 commitments. A second Tempo deployment on July 31, 2026, at 08:26:34 UTC falls outside the window. We combine public deployment records with direct chain histories and verify every listed pool against its commitmenttree state. For EVM-compatible pools, the commitment count is the cutoff state index minus the initial leaf-index offset, cross-checked against commitment-insertion events. “Tree Height” is the deployed tree’s level parameter, not its ob-
Monotonicity, Fixpoint, and Termination. Propagation operates on a finite product state. The reserved set R only grows; Ω(i) and its guarded slices only shrink; M(i) only gains newly forced commitments; and Θ(i) and projected labels only narrow. No action can restore a candidate or interpretation already ruled out. The updates are therefore monotone and contracting. Fair processing reaches the greatest common fixpoint below the initial states under the declared notification relation: queue order may change the number of revisits, but an effective contraction always re-enqueues every affected proof. Termination follows because each effective update strictly changes a finite component. When Q is empty, the algorithm returns the final Ω(i) and Σ(i) consumed by closure lifting in Sec. 4.2. 18
Railgun V1 and V2. We identify the production proxies from Railgun’s deployment registry and inspect the deployed V1 contract and the public V2 contract and circuit repositories. On the three deployments spanning both versions, V2 continues through the same production proxy and preserves the existing commitment-tree state, so we reconstruct one continuous history rather than separate version-specific pools. Fig. 14 summarizes the model-relevant V2 circuit constraints. At the contract-visible boundary, V1 Shield validates public note preimages, transfers their assets into the pool, and records the derived commitments. A V1 spend requires a previously seen root and unused nullifiers before proof verification. If a public withdrawal preimage is present, its hash must equal the final output commitment; the contract releases that value, excludes the final output from Merkle insertion, and inserts the remaining private outputs. Both Shield paths expose the created note preimages while inserting only their commitment hashes. Each Railgun JoinSplit proof instantiates one proof relation πi : it uses one tree and authenticated root, consumes notes of one token, and may create private commitments plus one plaintext output Oi . V1 represents Oi by a public withdrawal preimage, whereas V2 exposes it through the Unshield path. Its commitment is the final circuit output but is excluded from Merkle insertion, so ki in Sec. 3.1.2 counts only private outputs. All proofs in a spend transaction are checked before any of their private outputs are inserted, matching Sec. 3.1.3. The reconstruction uses the public events that record Shield commitments, nullifiers, proof-created commitments, and Unshield outputs. V2’s JoinSplit circuit additionally enforces the common-token relation used by Sec. 4.1.3. Administrative events are excluded because they do not alter note creation, consumption, or public release. The model is unchanged across versions, but reconstruction accounts for V2’s more specific events and additional token classes, and for the different exposure of the public recipient. Because the V1 circuit is unavailable, its evidence boundary remains contract-visible; Appendix D reports the corresponding full-trace checks.
Railgun V2 JoinSplit proof Public input: a Merkle root R, a bound-parameter hash hbp , input nulliout q fiers (ni )m i=1 , and circuit output commitments (c j ) j=1 . Witness: a common token identifier τ, a spending public key PK, a signature σ, a nullifying key nk, input-note tuples (ρi , vi , ℓi , pathi )m i=1 , out q and output-note tuples (npkout j , v j ) j=1 , where ℓi is the input leaf index. Poseidon denotes the appropriate-arity hash. Compute the signed public message h as the Poseidon hash of R, hbp , all input nullifiers, and all output commitments. Check authorization and binding: • verify the signature σ on h under PK; • because h includes hbp , the proof is bound to the transaction parameters as well as its nullifiers and output commitments; • compute the master public key mpk = Poseidon(PKx , PKy , nk); • use the same τ in every input and output commitment, so all consumed and created notes share one asset type, as in Sec. 3.1.2. For each input note i ∈ {1, . . . , m}: • derive the nullifier ni = Poseidon(nk, ℓi ); • derive the input note public key npkin i = Poseidon(mpk, ρi ); • reconstruct ci = Poseidon(npkin i , τ, vi ); • verify with pathi that ci belongs to the tree rooted at R. For each output note j ∈ {1, . . . , q}: • require vout j to fit into the prescribed bit range; out out • compute cbout j = Poseidon(npk j , τ, v j ); out out • require cbj = c j . q
out Require value conservation, ∑m i=1 vi = ∑ j=1 v j . If a plaintext output is present, the contract treats the final circuit output as Oi and omits it from Merkle insertion; hence ki = q − 1, and otherwise ki = q, as defined in Sec. 3.1.2. Accept if all checks above hold.
Fig. 14: Railgun V2 JoinSplit proof. served leaf count. Tron events and Solana signatures use the same UTC cutoff. All explorer links were accessed August 15, 2026. The five shaded rows are the most active pools in the coordinated EVM-compatible generation deployed on June 27, 2025. That generation contains 78,133 commitments across its EVM-compatible pools at the cutoff—the largest aggregate among Hinkal’s coordinated cross-chain generations—while its BNB Chain and Avalanche pools contain zero and 280, respectively. Fixing one generation keeps the implementation comparable across chains; no pool from another generation is merged into an evaluated anonymity domain.
C
Hinkal. Each Hinkal contract selected in Appendix B maintains an independent pool and commitment tree. We inspect the verified pool contract and execution contracts active at deployment and the cutoff. We found neither verified source for the contract that assembles the verifier’s public inputs nor public circuit source for these pools. The mapping therefore uses only the observable proof-call boundary and infers no hidden circuit constraint. We treat this as an evidence boundary rather than inferred circuit semantics: no unavailable witness constraint is used to eliminate a candidate. Additional witness constraints could make the exact feasible set smaller than the reported set, but every reported elimination is justified by an observable proof-call input, a contract-enforced state transition, or a corresponding asset transfer. The Hinkal results are therefore conservative with respect to unavailable circuit se-
Protocol Instantiations
This appendix maps the model of Sec. 3 and the analysis of Sec. 4 to the deployed protocols evaluated in Sec. 5. Table 6 summarizes the correspondence. Railgun V2 publishes contract and circuit source; for Railgun V1 and the evaluated Hinkal pools, the analysis uses contract-visible semantics and public proof inputs without inferring witness constraints absent from the available source. All implementation links below were accessed August 15, 2026. 19
Table 6: Instantiation of the system model and analysis in Railgun and Hinkal. Model element
Railgun V1/V2
Hinkal pools deployed June 27, 2025
Authenticated pool state
Each deployment maintains a sequence of fixed-capacity Merkle trees; πi identifies one tree and one authenticated historical root. Shield transfers assets into P , and its public trace directly identifies the shielding address.
Each evaluated pool maintains one independent commitment tree; πi identifies a historical state through the call’s authenticated root, without a tree-number partition. Shield may use the proofless entry point or be part of the unified call. The protocol-executed transfer into P identifies the shielding address, which may differ from the submitter. One cryptographic proof may jointly authenticate several same-token relations, each represented by a separate πi . The exact public token address and balance change of each same-token relation determine Token and Value feasibility.
Shield and shielding address Proof granularity (πi ) Token and Value constraints Plaintext output Oi Commitment provenance for closure
Transaction boundary
One JoinSplit proof instantiates one same-token input– output relation. A JoinSplit uses one common token; public Shield/Unshield data, commitment-creation histories, and the balance relation determine Token and Value feasibility. A V1 withdrawal preimage or V2 Unshield output instantiates Oi and records the token and value released from P . A commitment is introduced by Shield or a JoinSplit; closure follows a proof-created commitment through its creating proof under the same token guard. A spend transaction may aggregate JoinSplit proofs, all checked before any private commitments are inserted.
mantics and do not constitute an audit of circuit completeness or verifier soundness. The pool exposes a proofless Shield entry point (prooflessDeposit) and a unified proof-verified entry point (transact) that may combine private inputs and outputs with Shield, Unshield, or external execution. A unified call submits one cryptographic proof and publicly groups its nullifiers, created commitments, and balance changes by token. The model represents its input-bearing same-token relations as distinct proof relations πi . This is an analytical projection of the public call, not a decomposition of its cryptographic proof: it preserves the granularity of Sec. 3.1.2 without assuming separate or sequential verification, and all relations contributing to a public release are reunited at the transaction layer. A public outflow may instead consume value that an earlier private transition placed in persistent authorization state. We model this as a same-token relation whose direct predecessor is that earlier transition, even when the current relation records no nullifier: closure follows Predπ (i) and never treats the outflow as a new Shield source. The relation is Proof 2 without a private commitment and Proof 4 otherwise. For these proof relations, Tree Number is inapplicable because the pool exposes no Railgun-style tree number; Proof Root uses the prefix covered by the authenticated historical root; Token uses the relation’s exact public token address; and Value uses its public balance change and the contract-enforced balance equation. These are precisely the protocol-visible constraints of Sec. 4.1. The unified path also explains the provenance extension in Sec. 4.2: a created commitment may depend on both a Shield source and private predecessors, so Entry(c,t) and Pred(c,t) may both be nonempty. When public external exe-
The public outflow to the unshielding address instantiates Oi ; a protocol-distinguished relayer fee does not. A commitment may have a Shield source, private predecessors, or both. Closure changes token guards only when the public execution trace links the corresponding input and output tokens. A unified call may jointly authenticate several relations; verification and public execution complete before its new commitments are inserted.
cution relates different token branches, closure follows every permitted cross-token predecessor; otherwise it preserves the token guard. On Unshield, recipient value and the relayer fee are separate contract-governed outflows, so a fee-only branch is excluded from Oi without treating the transaction submitter as a shielding or unshielding address. Pool state persists across auxiliary-contract changes, which we replay and validate in ledger order (Appendix D).
D
Reconstruction and Analysis Validation
This appendix records the fail-closed checks at the boundaries that determine the reported Commitment and Anonymity Sets: any missing or inconsistent input terminates the analysis. Fig. 15 and Fig. 16 show representative excerpts from the analysis and its independent validation. The excerpts preserve the executed checks while aligning identifiers with model terminology and omitting setup and diagnostics; every check runs over the complete analyzed datasets. Trace Reconstruction and Graph Integrity. The analysis admits a proof relation only when every public nullifier has an exact decoded relation and authenticated root, and admits a proof-created commitment only when its creating proof is unique. Fig. 15a shows both Railgun checks. Root lookup uses the reconstructed history of the referenced tree; a missing root or tree mismatch terminates the analysis before pruning. Hinkal additionally requires contiguous commitment insertion, one decoded call for each cryptographic proof, unique proof-relation identifiers, exact reconstruction of every rootcovered prefix, and one creating proof for each proof-created commitment. These checks cover the datasets in Table 2: 20
1 2 3 4 5 6 7 8
let proof_relation_id = proof_relation_by_nullifier .get(&nullifier_key).copied().ok_or_else(|| { format!("missing proof relation for nullifier {}", nullifier) })?; let proof_root = root_by_nullifier .get(&nullifier_key).cloned().ok_or_else(|| { format!("missing exact proof root for nullifier {}", nullifier) })?;
1
// Later, while constructing the commitment-creator map: match creator_by_commitment.get(&commitment_key) { None => { creator_by_commitment.insert( commitment_key.clone(), creating_proof.clone()); } Some(existing) if existing == &creating_proof => {} Some(existing) => { return Err(format!( "conflicting creators for {}: {:?} vs {:?}", commitment, existing, creating_proof)); } }
8
2 3 4 5 6 7
9 10 11 12 13 14 15 16 17 18 19 20 21 22
9 10 11 12 13 14 15 16 17 18 19 20
(a) Exact nullifier/root coverage and creating-proof uniqueness. 1 2 3 4 5 6 7 8 9
21
let feasible_tokens = feasible_tokens_by_tree .get(tree_id) .and_then(|per_tree| per_tree.get(leaf_index)) .cloned() .ok_or_else(|| format!( "missing token labels for created output {}", leaf_index) )?; if feasible_tokens.is_empty() { return Err("empty token labels on created output".into()); }
12 13 14 15 16 17 18 19 20 21
const priorSet = commitmentSetByProof.get(proofRelationId); if (priorSet) requireCondition( priorSet.digest === setDigest && compareArrays(priorSet.indices, candidates), "same-proof Commitment Sets differ");
(a) Independent reconstruction of a Hinkal Commitment Set. 1 2 3 4 5 6
10 11
const candidates = []; for (let leafIndex = 0; leafIndex < authenticatedLeafCount; leafIndex += 1) { const commitment = commitments[leafIndex]; if (commitment.tokenAddress !== proofRelation.tokenAddress) continue; if (hasValueConstraint) { const label = valueLabelByLeaf.get(leafIndex); if (label && String(label.amountFieldValue) !== requiredInputValue) continue; } candidates.push(leafIndex); } const setDigest = digestCommitmentIndices(candidates); requireCondition(candidates.length === storedPruningResult.size, "set size mismatch"); requireCondition(setDigest === storedPruningResult.digest, "set digest mismatch"); requireCondition(candidates.length > 0, "empty Commitment Set");
7
let mut tokens_without_bounds = Vec::new(); for token in &feasible_tokens { if !projected_value_bounds.contains_key(token) { tokens_without_bounds.push(token.clone()); } } if !tokens_without_bounds.is_empty() { return Err(format!( "created-output value bounds missing tokens: {:?}", tokens_without_bounds)); }
8 9 10 11 12 13 14
function ledgerPosition(event) { return [event.blockNumber, event.transactionIndex, event.callIndex ?? -1, event.logIndex ?? -1].map(Number ); } function precedes(left, right) { const a = ledgerPosition(left), b = ledgerPosition(right); for (let i = 0; i < a.length; i += 1) if (a[i] < b[i]) return true; else if (a[i] > b[i]) return false; return false; } function deriveMetrics(proof, sources) { for (const source of sources) requireCondition(precedes(source, proof), "non-prior source"); const sourceTxs = new Set(sources.map((s) => s.transactionHash) ); const anonymitySet = new Set(sources.flatMap((s) => s. shieldingAddresses)); return { sourceTxs, anonymitySet };
15 16 17
(b) Completeness of labels projected through created outputs.
18
Fig. 15: Representative fail-closed checks for Railgun.
}
(b) Ledger-order validation and transaction-level address projection.
Fig. 16: Representative fail-closed checks for Hinkal. 497,034 commitments and 431,198 nullifiers for Railgun, and 77,853 commitments and 74,499 nullifiers for Hinkal. indices must match the stored local-pruning result. Validation then replays chronological mandatory-input reservations to reconstruct the final Ω(i). Nullifiers in the same proof relation must reconstruct identical sets, and an empty set terminates the analysis; neither stage trusts the closure output.
Propagation-State Consistency. Projected token/value labels are shared state: when an earlier proof narrows, every later candidate created by it must observe the same update. The analysis therefore associates each projected output label with its creating proof, synchronizes it after a reservation or label contraction, and rejects an empty token set or a value map missing any surviving token guard. Fig. 15b shows the latter checks. This prevents an outdated or incomplete output label from surviving merely because the commitment was inserted before its creating proof reached the fixpoint. For Hinkal, closure independently reconstructs every local Value-stage Commitment Set from the root-covered prefix, exact public token address, and value-stage labels. As shown in Fig. 16a, its size and a deterministic digest of its ordered commitment
Closure and Transaction-Level Lifting. Every terminal Shield source reached by closure must precede the analyzed proof in canonical ledger order, including intra-transaction call and log order, as illustrated in Fig. 16b. Railgun analogously checks each source against the reconstructed spend boundary and rejects unmapped or non-prior shield commitments. Address lifting deduplicates the reached shield transactions and shielding addresses; transactions with multiple contributing proofs use one common temporal baseline before 21
Table 7: Anonymity Set Size reduction by proof composition.
Table 8: Anonymity Set Size reduction by depth quartile.
(a) Railgun.
(a) Railgun.
Ethereum
Class
Count
Arbitrum
Mean
Count
Mean
Polygon Count
Mean
Count
85,157 40.1% 42,256 46.3% 27,719 59.0% 14,708 47.6%
Proof 2 -only 1 proof > 1 proofs
10,025 53.4% 6,611 65.6% 3,828 74.1% 1,992 58.1% 8,942 55.8% 6,392 66.4% 3,689 74.9% 1,853 60.0% 1,083 33.6% 219 44.4% 139 53.8% 139 32.8%
Proof 4 -only 1 proof > 1 proofs
74,352 38.4% 35,331 42.8% 23,574 56.7% 12,434 46.2% 73,967 38.4% 35,114 42.9% 23,244 56.9% 12,345 46.3% 385 24.0% 217 24.6% 330 40.1% 89 32.0%
Mixed ( 2 + 4 )
780
314
31.9%
317
46.2%
282
Ethereum
Arbitrum
Chain
Base
1,884 57.0% 1,613 57.4% 3,156 53.0% 5,851 52.0% 4,012 48.9%
Proof 2 -only 1 proof > 1 proofs
1,019 56.2% 992 56.9% 27 29.2%
767 739 28
59.1% 1,568 53.5% 3,622 50.5% 2,291 48.1% 59.9% 1,464 54.9% 3,429 51.0% 2,149 49.4% 40.2% 104 34.8% 193 41.7% 142 27.7%
Proof 4 -only 1 proof > 1 proofs
848 821 27
58.3% 59.5% 22.7%
835 813 22
56.2% 1,566 52.6% 2,178 54.6% 1,695 50.4% 56.9% 1,505 53.7% 2,100 55.2% 1,609 51.9% 27.5% 61 26.2% 78 38.1% 86 23.1%
Mixed ( 2 + 4 )
17
34.9%
11
29.2%
51
45.0%
Q3
Q4
54.5% 59.8% 66.0% 59.8%
51.1% 57.2% 64.0% 49.5%
43.3% 52.0% 64.0% 43.6%
12.3% 17.1% 43.6% 39.7%
1,884 1,613 3,156 5,851 4,012
1,813 (96.2%) 1,552 (96.2%) 2,969 (94.1%) 5,529 (94.5%) 3,758 (93.7%)
645 821 1,531.5 2,608 1,697.5
Q1
Q2
Q3
Q4
69.9% 64.9% 64.7% 73.5% 61.6%
57.8% 56.5% 57.6% 45.8% 44.9%
57.1% 56.6% 49.1% 40.3% 44.6%
47.5% 55.3% 45.6% 50.8% 50.7%
Supporting Commitment-Set Analyses
Optimism
All
44.0%
24,872 12,005 7,727 4,628.5
Q2
35.3%
This appendix supplies the Hinkal time-evolution view and the pricing coverage for the descriptive Railgun token-activity insets in Sec. 5.1.
Count Mean Count Mean Count Mean Count Mean Count Mean
22
82,909 (97.4%) 41,506 (98.2%) 26,933 (97.2%) 14,198 (96.5%)
Transactions One contributing proof (%) Median max. hops
Ethereum Arbitrum Polygon Base Optimism
E
Polygon
85,157 42,256 27,719 14,708
Q1
(b) Hinkal.
(b) Hinkal. Class
Transactions One contributing proof (%) Median max. hops
Ethereum Arbitrum Polygon BNB Chain
Mean
All
32.6%
Chain
BNB Chain
26
Hinkal Commitment Set Size. Fig. 17 complements the Railgun chronology in Fig. 9. Each selected Hinkal pool has one long-lived tree and no Railgun-style tree number, so its panels compare the temporal baseline with Proof Root, Token, and the propagated final set after Value. They use the same cumulative sets and block-order aggregation as Sec. 5.1.
29.0%
USD Aggregation for Token-Activity Insets. The inset pies of Fig. 10 describe value concentration for the token categories in the count-based bars; they do not affect pruning or closure lifting. We count shield-side value once per commitment with a public plaintext amount and unshield-side value once per public Unshield record. One record may correspond to several nullifiers but exposes only one released amount, so that amount is never multiplied by its nullifier count. Tokens are matched by chain and contract address; CoinMarketCap and CoinGecko provide metadata and spot prices. A fungible token contributes only when this exact-address lookup resolves a USD price. The pies use the same top-five categories as the bars and merge the remainder into Others. Exact-address prices cover 99.17%, 99.26%, 97.66%, and 97.55% of ERC-20 public-value records on Ethereum, Arbitrum, Polygon, and BNB Chain, respectively. This denominator differs from the unshield bars, which count consumed nullifiers. The bars therefore cover all decoded activity, whereas the USD-value pies omit unpriced long-tail tokens and NFTs.
union. Independently computed depth records must match all 169,840 Railgun and 16,516 Hinkal unshielding transactions. Protocol-Specific Evidence Boundaries. Railgun V2 is checked against both its public contracts and JoinSplit circuit. Because the V1 circuit is unavailable, V1 validation is limited to contract-visible semantics but covers every decoded V1 call: 3,452 spend transactions containing 4,482 proof relations. Every rebuilt root predates its spend, every encoded proof and ciphertext array satisfies the V1 contract’s format checks, all 5,483 nullifiers and 9,080 inserted commitments match their events, and all 2,343 withdrawal preimages hash to the final output commitment excluded from insertion. Hinkal external execution can transfer value from private notes into persistent authorization state before a later transaction consumes it. Validation replays every such state change in ledger order, matches it to the decoded call and emitted event, and requires each debit to be supported by prior state. It also validates Shield provenance and fee-only branches against contract semantics and asset transfers. Where the public trace permits multiple predecessor transitions, closure retains all of them rather than selecting one. Any missing mapping, inconsistent state, incomplete metric match, or unsupported branch invalidates the analysis. All checks passed on the reported datasets.
F
Supporting Anonymity-Set Analyses
This appendix provides the Hinkal Anonymity Set Size chronology and the chain-level proof-composition and closure-depth results supporting Sec. 5.2. 22
Commitment Set Size
5,926 2,823 4,119
103
490
102
108 100 2025-07
0(i)
2(i)
2025-11
2026-03
66 2026-07 2025-07
165
1,062 1,602
635 0(i)
3(i)
2025-11
2026-03
66 2026-07 2025-07
165
634
1,062 955
(i) 0(i) 2025-11 2026-03
2026-07
Commitment Set Size
(a) Ethereum
103
580
102 100 2025-06
1,608
4,524
6,809 8,570
0(i)
2(i)
2025-11
2026-03
284 2026-07 2025-06
1,282
1,984 2,440
0(i)
3(i)
2025-11
2026-03
588
284 2026-07 2025-06
588
1,242
1,984 2,326
(i) 0(i) 2025-11 2026-03
2026-07
Commitment Set Size
(b) Arbitrum
104 103
1,052
102 100 2025-06
3,734
7,756 10,60113,675
0(i) 2(i) 2025-11 2026-03
142 2026-07 2025-06
3,448 4,802
2,313
667
0(i) 3(i) 2025-11 2026-03
142 2026-07 2025-06
667
1,789
3,336 4,802
(i) 0(i) 2025-11 2026-03
2026-07
Commitment Set Size
(c) Polygon
104 103
867
102 100 2025-06
4,297
12,908 19,72123,968 0(i)
2(i)
2025-11
2026-03
301 2026-07 2025-06
8,446 3,361 6,159
1,186
0(i)
3(i)
2025-11
2026-03
300 2026-07 2025-06
677
3,353 2,750 6,066
(i) 0(i) 2025-11 2026-03
2026-07
Commitment Set Size
(d) Base
104 103
1,004
102 100 2025-06
3,316
11,617 18,827 0(i)
2(i)
2025-11
2026-03
24,646 290 550 2026-07 2025-06
6,971 2,655 4,726 0(i)
3(i)
2025-11
2026-03
290 550
2026-07 2025-06
6,962 2,359 4,201
(i) 0(i) 2025-11 2026-03
2026-07
(e) Optimism
Fig. 17: Temporal evolution of Hinkal Commitment Set Size through July 30, 2026 (UTC), in 500 equal-count block-order bins per selected pool. Successive panels compare Ω0 (i) with Ω2 (i), Ω3 (i), and the propagated final Ω(i) after Value; Tree Number is inapplicable. Curves show P50; shading spans P0–P100; labels mark selected times. Hinkal Anonymity Set Size. Fig. 18 complements the Railgun chronology in Fig. 12, using the same temporal baseline and final transaction-level Anonymity Set after closure lifting and within-transaction union.
has a mean size of 197.47. Thus, the public token partition persists from commitment candidates to address-level provenance. Unlike the one-contributor stratification in Table 8, token ancestry classifies terminal-source tokens rather than proof sets unioned at the transaction layer.
Token Partition Through Closure. To test whether Hinkal’s public token information remains constraining after closure lifting, we classify an Ethereum unshielding spend transaction as token-pure when it publicly releases one token and every feasible terminal shielding source reached by the complete closure has that same token. Of the 1,884 evaluated transactions, 1,813 (96.2%) are token-pure, none of the single-token transactions has cross-token ancestry, and the remaining 71 publicly release multiple tokens. Within the token-pure cohort, the mean temporal shielding-address baseline is 484.98; restricting that baseline to the public token leaves 197.73 addresses, and the final Anonymity Set after complete closure
Proof-Composition Breakdown. Table 7 partitions each chain’s unshielding transactions into Proof 2 -only, Proof 4 only, and mixed classes. Count gives the number of transactions in each class, and Mean is its average Anonymity Set Size reduction relative to A0 (T ). Indented rows distinguish whether one or multiple proofs contribute to A (T ), exposing how proof form interacts with within-transaction union; the strata are descriptive rather than causal. Closure-Depth Analysis. One closure hop crosses one historical private state transition. For each transaction, maximum depth is the longest feasible path from a contributing proof 23
115
100 2025-07 2025-11 2026-03 2026-07
61 10 100 2025-06 2025-11 2026-03 2026-07
(a) Ethereum
(b) Arbitrum
13
63
102
36
96
98
139
103 102
298 35 76
522 523
Anonymity Set Size
102
243
Anonymity Set Size
167
189 233
Anonymity Set Size
124
Anonymity Set Size
Anonymity Set Size
102
223
102 16
37
98
147
223
100 2025-06 2025-11 2026-03 2026-07
100 2025-06 2025-11 2026-03 2026-07
100 2025-06 2025-11 2026-03 2026-07
(c) Polygon
(d) Base
(e) Optimism
Fig. 18: Hinkal Anonymity Set Size over time: temporal baseline (dashed) and final transaction-level union after closure lifting (solid). P50 curves use equal-count block-order bins of about 100 transactions; P0–P100 shading and labels at the 5%, 25%, 50%, 75%, and 95% timeline positions. to a Shield source. To separate depth from within-transaction union, we rank only transactions for which exactly one proof contributes to A (T ), independently within each chain, and divide the complete ordering into four near-equal rank quartiles from shallowest (Q1) to deepest (Q4). Table 8 covers all 169,840 Railgun and 16,516 Hinkal unshielding transactions, each with a matching depth record. The one-contributor comparison retains 96.5%–98.2% and 93.7%–96.2% of the respective chain cohorts. Median hops use all transactions; Q1–Q4 report mean Anonymity Set Size reduction within the ranked one-contributor cohort. Reduction declines from Q1 to Q4 on every Railgun chain, and Hinkal likewise has lower Q4 than Q1 on every chain. Base and Optimism nevertheless rebound in Q4 relative to Q3, showing that depth is informative but not sufficient by itself: token composition and pool history also shape the final set. These descriptive associations do not isolate depth from growth in protocol history and its temporal baseline.
24
Related documents
- Protection Goals for Privacy Engineering#335818
- Untraceable electronic mail, return addresses, and digital pseudonyms#6581
- A Principled Approach to Defining Anonymization As Applied to EU Data Protection Law#461707
- Logit-Boundary Geometric Belief Interfaces and Sparse Sheaf-Enclave Protocols: A Self-Contained Substrate for Secure Network Electronic Health Record (EHR) Interoperability#444579
- Assessing Local Differential Privacy for Compliance with the Personal Data Protection Law in Integrated Data Systems#318388
Retrieved via Conceptio: every document is proof-bundled with source, license, and retrieval metadata.
Read the Docs → · View CLI source on GitHub · Conceptio Open Knowledge Archive