ROOTVIELROOTVIEL
← Academy

Module 13 · Zero-Knowledge identity & private protocols

Non-membership proofs, compliance and proof-of-innocence

Proving something IS in a set is easy: show a Merkle path. Proving something is NOT in a set is harder — you must prove a negative. Two structures make it efficient: a sparse Merkle tree, where every possible element has a fixed position and non-membership is showing that position is empty; and an indexed Merkle tree, where sorted elements with pointers let you prove non-membership by exhibiting the adjacent elements that would bracket the missing one. These power compliance patterns that try to reconcile privacy with regulation: proof-of-innocence (prove deposited funds do not trace to a blacklisted source), association sets (prove funds come from a curated allowed set), and privacy-preserving sanctions screening (prove "not on the list" without revealing who). The honesty is unusually important here: a non-membership proof is true only relative to a specific published set at a specific time, and "proof of innocence" is a protocol name, not a statement about guilt.

Learning objective

Learn how to prove a negative in zero knowledge — that an element is NOT in a set — using sparse and indexed Merkle trees, and how this primitive powers privacy-preserving compliance: proof-of-innocence (funds not from a blacklisted source), association sets (funds from an allowed set), and sanctions screening without revealing identity. Then draw the sharp honest boundary: these proofs attest membership or non-membership against a specific published set at a specific time — not legitimacy, not innocence in any moral sense, and not safety.

Track
Research
Module
13 · Zero-Knowledge identity & private protocols
Prerequisites
Merkle trees · Nullifiers, Merkle membership and the privacy-pool pattern · Anonymous credentials and selective disclosure

Conceptual introduction

Membership proofs answer "is x in the set?" with a short Merkle path. But many real questions are negatives: is this address NOT sanctioned? Does this deposit NOT trace to a known hack? Proving a negative is genuinely harder — you cannot just point at where the element sits, because it is not there. You must prove, convincingly, that it is absent from the whole set.

This primitive sits at the uncomfortable intersection of privacy and compliance. Regulators want assurance that funds are not tainted; users want to not broadcast their identity and full history. Non-membership and membership proofs let a user prove a compliance predicate — "my funds are not from this blacklist" or "my funds are from this allowed set" — in zero knowledge, revealing the predicate's truth and nothing else. Whether that reconciliation is adequate is a policy question this lesson deliberately does not resolve; its job is to be precise about what the cryptography actually proves.

Note

A non-membership proof is always relative to a specific set. "x is not in S" is a true statement about S as published at a point in time — not a universal claim. Who curates S, how it is updated, and when the snapshot was taken are part of what the proof means, and are exactly where its real-world meaning is contested.

How to prove a negative

Three constructions make non-membership efficient. Each reduces "prove absence" to "prove something present that would be impossible if the element were in the set".

Sparse Merkle tree
A tree with a fixed, predetermined position for every possible element (e.g. 2^256 virtual leaves). Membership is a non-empty leaf at the element's position; non-membership is proving the leaf at that position is the empty value. The tree is huge but mostly empty, so default-subtree roots can be precomputed and paths stay short.
Indexed Merkle tree
Elements are stored sorted, each leaf pointing to the next larger element. Non-membership of x is proven by exhibiting the leaf whose value is less than x and whose pointer skips past x — i.e. the two existing elements that bracket where x would go, showing nothing sits between them. More storage-efficient than a sparse tree; used by systems like Aztec.
RSA / cryptographic accumulators
An accumulator compresses a set into a single value with (non-)membership witnesses. Non-membership witnesses exist but are more complex and rest on number-theoretic assumptions; a trade-off versus Merkle-based approaches.
synthetic — non-membership via an indexed (sorted) tree (illustrative)
# Set contains sorted values with "next" pointers: # ... (val=40, next=55) (val=55, next=90) ... # Prove x = 50 is NOT in the set: # exhibit the leaf (val=40, next=55): # - 40 < 50 (x is greater than this element) # - next value 55 > 50 (the following element skips over x) # => nothing equal to 50 exists between them => 50 is absent. # A ZK circuit checks these inequalities and the Merkle paths, # revealing only "50 is not in S", not x's relationship to other data.

In zero knowledge, the bracketing elements and paths are the private witness; the public statement is just "x is not in S for this root". The verifier learns the predicate and nothing about x's neighbours or the rest of the set.

Proof-of-innocence and association sets

The headline compliance application is proof-of-innocence: a user of a shielded pool proves their deposited funds do not derive from a blacklisted source — without revealing which deposit is theirs. There are two dual framings, and the choice between them is consequential.

Exclusion / non-inclusion (blacklist)
Prove the funds' source is NOT in a published set of flagged addresses (hacks, sanctioned entities). The default is "allowed"; only listed sources are excluded. A non-membership proof against the blacklist root.
Inclusion / association set (whitelist)
Prove the funds DO come from a curated allowed set. The default is "not allowed"; only members of the association set pass. A membership proof against the association-set root.
Temporal proof-of-innocence
Prove a deposit occurred before a given event (e.g. a hack), so funds deposited earlier cannot be its proceeds. Proven via a timestamp/block bound bound into the statement.
Association set provider
The entity that defines and publishes a set; a community, a protocol, or a compliance service. Different providers publish different sets with different restriction levels, and users choose which to prove against.

The privacy-pools design generalises this: a pool can support multiple association sets with different restriction levels, and a withdrawal carries an extra membership (or non-membership) proof against a chosen set's root in addition to the usual spend proof. An honest user can voluntarily prove dissociation from illicit funds while remaining anonymous within the allowed set, and the anonymity set shrinks to the size of that chosen set.

Note

The framing choice is a power choice. A blacklist (exclusion) treats everyone as allowed until listed; a whitelist (association set) treats everyone as disallowed until admitted. They have very different effects on who can transact, who decides, and who is excluded by default or by error — and the cryptography is identical for both. That politics is outside the proof and must not be hidden by it.

Privacy-preserving screening and its limits

The same primitives give privacy-preserving sanctions screening: a user proves "my address is not in the sanctions set" against a published sanctions-list Merkle root, revealing neither their address nor anything else. Combined with anonymous credentials, an exchange can require "not sanctioned, not a politically-exposed person, resident of an allowed country" as predicate proofs, learning the predicates' truth but not the underlying data.

The limits are real and must be stated. The proof is only as good as the list: a sanctioned entity absent from the published set passes trivially, and a wrongly-listed address is excluded with no recourse inside the protocol. The snapshot time matters — a proof against yesterday's list says nothing about today's additions. And none of this addresses funds that are illicit but untainted by any list, or an adversary with no detectable pattern. Screening narrows a design problem; it does not close it.

Honest boundary: a name is not a verdict (RootRaven)

When a verifier accepts a non-membership (or association) proof, it has established a precise statement: the private element is absent from (or present in) the set with this root, as published at this time, under the tree construction and commitment assumptions. That is a useful, checkable fact about a set.

It does not establish that the set is correct, complete or current; that the curator is honest or neutral; that funds absent from a blacklist are lawfully obtained; or — most importantly — that the user is "innocent" in any sense beyond "not in this list". "Proof-of-innocence" is a protocol name, not a legal or moral finding. For RootRaven the discipline is strict: report the proof as evidence about a specific published set at a specific time, name the curator and the framing (exclusion vs inclusion), and never let the word "innocence" in a protocol's name stand in for a judgment the cryptography did not make. A valid proof against a list is not a verdict about a person.

Exercise

Note

A shielded pool adds "proof-of-innocence": on withdrawal, users must prove their deposit's source is not in a blacklist Merkle root published daily by a single provider. A compliance officer says "a valid proof means the funds are clean, so we can treat these withdrawals as fully compliant." Identify at least four things this conflates, and restate precisely what a valid proof does and does not establish.

Expected direction: Conflations: (1) Set-relative vs absolute — the proof shows absence from THIS blacklist, not that the funds are clean; illicit funds not on the list pass trivially. (2) Time — the root is published daily, so a valid proof reflects the list at a snapshot and says nothing about additions since; a source flagged today can have passed yesterday. (3) Curator trust — a single provider defines the list, so completeness, correctness and neutrality all rest on that provider; a wrongly-listed address is excluded with no protocol recourse, and a missing entry passes. (4) Name vs verdict — "proof-of-innocence" is a protocol name, not a legal or moral finding; "not in a list" is not "innocent". (Also: exclusion framing treats everyone as allowed until listed, a policy choice the cryptography hides.) Precise restatement: a valid proof establishes that the deposit's private source is absent from the set with the given root as published at that time, under the tree/commitment assumptions — and nothing about the funds' actual provenance, legality, the list's accuracy or currency, or whether treating the withdrawal as compliant is correct. The officer should treat it as one piece of time-bound, set-relative evidence from a named curator, not as a clean-funds verdict.

Check your understanding

Why is non-membership harder than membership, and how does a sparse Merkle tree solve it?
Membership points at where an element sits; non-membership must prove absence from the whole set (proving a negative). A sparse Merkle tree gives every possible element a fixed position, so non-membership is proving the leaf at the element's position holds the empty value — a short path, since empty-subtree roots are precomputed.
How does an indexed Merkle tree prove non-membership, and what is its advantage?
Elements are stored sorted with pointers to the next larger element; to prove x is absent you exhibit the existing element just below x whose pointer skips past x, showing nothing equal to x lies between them. Its advantage is far less storage than a sparse tree while keeping efficient non-membership proofs.
Contrast exclusion (blacklist) and inclusion (association set) framings — cryptographically and politically.
Cryptographically they are duals: exclusion is a non-membership proof against a flagged set (default allowed), inclusion is a membership proof against a curated allowed set (default disallowed); the machinery is the same. Politically they differ sharply — a blacklist allows everyone until listed, a whitelist disallows everyone until admitted — affecting who transacts by default, who decides, and who is excluded by error. The proof hides that choice; it must be stated.
Why is "proof-of-innocence" a misleading name, and what does such a proof actually establish?
Because it suggests a verdict about guilt or clean funds, while the proof only establishes that a private element is absent from (or present in) a specific published set at a specific time, under stated assumptions. It says nothing about the set's correctness or currency, the curator's honesty, the funds' real provenance or legality, or whether acting on it is safe. The name is a protocol label, not a legal or moral finding.

References

  1. [1]Banco ZK — Vol. III (2025): non-membership proofs (sparse / indexed Merkle trees), proof-of-innocence, association sets, privacy-preserving screening — external educational reference
  2. [2]Buterin, Illum, Nadler, Schär & Soleimani — Blockchain Privacy and Regulatory Compliance: Towards a Practical Equilibrium (privacy pools / association sets)
  3. [3]Aztec — indexed Merkle tree construction for efficient non-membership, as documented

References point to public, well-known technical sources for further study.

Related articles