Privacy Pools - Private Proofs of Innocence

Learn about the state of the art Zero-Knowledge assurance tool


Privacy Pools, otherwise known as private proofs of innocence, is a decentralized assurance system built by zero-knowledge (ZK) cryptography researchers and contributors to the RAILGUN Project. Privacy Pools is a tool to give cryptographic assurance that funds entering the RAILGUN smart contract are not from a known list of transactions or actors considered undesirable by respective wallet providers. Users create a ZK proof (a small piece of sealed data) that their funds are not a part of a pre-set list of transactions and wallets. This process is end-to-end encrypted and enables decentralized and private assurance of funds, without compromising user privacy. Privacy Pools sits alongside (but is separate from) the RAILGUN smart contracts and is open-source infrastructure that can be used by other protocols.

Privacy Pools uses only publicly available data and does not reveal anything else about RAILGUN users or their balances and activity nor does it give any third party any access into the RAILGUN privacy system. It also does not lower the privacy from using RAILGUN nor does it change how the underlying smart contracts’ spending system works; all transactions from 0zk addresses are and always will be impossible to deanonymize by anyone. Because of this, Privacy Pools is a superior assurance tool to previously existing methods and is an advancement in both ZK and privacy technology. Every legacy form of assurance required users to give up some personal data like identity documents to a centralized middleman or firm stored in a centralized data lake, exposing personal information to potential vulnerabilities. Privacy Pools achieves similar aims to a similar level of effectiveness whilst only using public on-chain data and requires no personal information.

Privacy Pools protects all RAILGUN users in the following ways:

  • Users can be sure that they are not sharing a privacy system with known bad actors which reduces the risk for every single RAILGUN user that their transactions are questioned

  • Exchanges or other external participants can receive confidence on transactions they receive from RAILGUN users, ensuring smoother processing and reducing wait times

  • Users can be sure that private payments they receive from other RAILGUN users are safe and not from known suspicious activity

  • Flexible input data which can be adjusted to the user’s risk profile and local jurisdiction, i.e., European users can pick lists relevant to the European Union or United States users can pick lists relevant to the USA etc.

How it works

Privacy Pools checks begin when funds enter the RAILGUN privacy system after a shield transaction. Broadly, the steps are as follows:

  1. List Providers input public, non-personal, and on-chain data of bad transactions

  2. User shields tokens and waits for the Unshield-Only Standby Period (1 hour to begin with but will likely be reduced in future)

  3. A blinded proof is auto-generated stating that the funds in the shield are not a part of the List Provider dataset

  4. Privacy Pools checks are then carried forward for any subsequent transactions involving the checked tokens

  5. If those tokens are sent to an external exchange, that exchange (or any independent party) can see the valid Privacy Pools proof without seeing anything else about the user like their 0zk address, balances, or history. This helps external actors gain confidence on funds they receive from a RAILGUN address without affecting user privacy in any way.

Unshield-Only Standby Period

With Privacy Pools, there is an Unshield-Only Standby Period, during which the only available action will be to unshield funds back to the original shielding wallet. This Unshield-Only Standby Period is to give List Providers enough time to update their data such that bad actors are unable to hop addresses quickly to outrun data updates. As always, during this Unshield-Only Standby Period, users retain full control and custody over their funds and can be unshielded back to the shielding address if needed urgently.

To begin with, in the wallet applications that support Privacy Pools, this Unshield-Only Standby Period will be 1 hour, meaning funds in new shields will have to wait 1 hour before they can be used in further transactions other than unshielding back to the original address. This Unshield-Only Standby Period will likely be reduced in future iterations of Privacy Pools as List Provider update times improve.

Transaction Level Checks

Privacy Pools works at the balance and transaction level. Meaning, Privacy Pools proofs are generated after the initial shield transaction and apply to the tokens that are a part of that transaction. They are then carried forward for every following transaction within RAILGUN involving those tokens.

For example:

  1. Alice shields 100 USDC into a 0zk address and generates a Privacy Pools proof which applies to that 100 USDC. In this example, she is using AliceWallet; one wallet option of many that features RAILGUN privacy options and Privacy Pools.

  2. She then sends that 100 USDC to Bob, who can use Alice’s existing Privacy Pools proof to show that the funds he received from Alice are not a part of the list of bad transactions.

  3. Bob then unshields that 100 USDC to a wallet owned by Carl. All Carl knows is that the 100 USDC he received has a valid Privacy Pools proof. As it is a RAILGUN transaction, he does not know anything else about Alice and Bob’s on-chain activity other than what they choose to tell him personally. He would not even know that the unshield was from Bob as Bob’s 0zk address is not revealed unless Bob chooses to tell him.

  4. Alice then shields an additional 50 USDC which generates another Privacy Pools proof that applies to that shield of 50 USDC.

List Providers

Privacy Pools starts with a List Provider, a dataset of transactions and addresses through an API (Application Programming Interface) of which to prove against (i.e., a list of bad actor activity for users to ZK prove that they are not a part of). Anyone can choose to publish their own lists and be a List Provider. Users and wallets are free to use whatever combination of List Providers they please, although some wallet providers will require a default List Provider. The ZK-cryptography generates an independent proof per Privacy Pools List Provider, which is verified and made available for further usage, without revealing any of the encrypted details of the transaction or the user.

Note: List Providers only look at publicly available data and gain no special insight into transactions. Privacy Pools does not affect privacy levels in the RAILGUN privacy system. All data relating to 0zk addresses (including balances, history, and addresses) are and always will be encrypted to everyone.

List Providers are a read-only data source. Wallets do not send any data from Privacy Pools proofs to List Providers, and they cannot log IP addresses.

Privacy Pools Nodes

Privacy Pools Nodes sync proof data and make it available for anyone interested in verifying Privacy Pools checks. To prevent spam from being submitted, proof data is synced in a manner similar to the Interplanetary File System (IPFS), a decentralized data storage network.

Wallets create proofs with encrypted data and update a shared list through Privacy Pools Nodes. Only the sending and receiving parties can decrypt this data, so no other party gets any information about what transactions they are linked to or what transactions are proved, ensuring complete privacy. Since unshields have a public recipient, anyone can check if an unshield is proved (and thereby knowing that it has a series of private proofs to a shield that is not on the bad transaction list), but they cannot see into the transaction other than that it was validly proved to not be from a publicly known set of bad transactions.

This enables RAILGUN integrated wallets, centralized exchanges, or anyone needing to verify that a shield has a Privacy Pools. Again, there is no special insight for Privacy Pools nodes

Like IPFS, anyone can run a Privacy Pools node. This ensures decentralized verification of Privacy Pools data such that every participant in the system can check proof validity for themselves rather than relying on a centralized actor.


As 0zk addresses cannot broadcast transactions or pay gas to Ethereum nodes without unshielding, they can use public Broadcasters who will. Public Broadcasters send transactions to the network and pay the gas fee. They receive a RAILGUN private payment at the same time to recover their costs, which is done in a private transaction. Before Broadcasters can do this with any given set of funds, those funds must have a completed Privacy Pools check. Broadcasters have Privacy Pools nodes which sync and verifies proof data.

In cases where there is an incomplete Privacy Pools check for a series of funds (such as during the Unshield-Only Standby Period), users can Self-Broadcast a transaction to return funds back to the original shielder.

Full Transaction Privacy Pools Flow

The following is an example on how RAILGUN private transaction flow following completed Privacy Pools after an initial shield.

  1. Bob's tokens begin with a Privacy Pools, either from a shield or a 0zk-0zk transfer. This will be generated automatically by the sender's wallet, designating Bob's funds as "Spendable." In the case of a shield, the Privacy Pools proof will be automatically generated by each List based on public on-chain data.

  2. Bob proves a transaction to send DAI to Alice through a Broadcaster. As part of the proof, Bob generates a special Proof of Spendability, which verifies the Privacy Pools proof for the Broadcaster, and guarantees that the received fee will be verified and spendable.

  3. Bob sends the transaction through the RBroadcaster and waits for it to be forwarded and confirmed by the blockchain.

  4. Once confirmed, Bob's wallet automatically generates a Privacy Pools proof for a blinded hash of the UTXO commitment that he sent to Alice. The POI data is validated by POI nodes, which make the blinded data available publicly.

  5. Alice's wallet inherits the Private Proof of Innocence, based on the blinded commitment that only her viewing key could decrypt. This automatically designates her tokens as Spendable, for transfers, unshields or swaps & DeFi dApps, without her needing to generate her own Privacy Pools proof.

This ensures the Privacy Pools system is efficient as proofs need to only occur once within the RAILGUN system for each shield, even if those tokens are then spent by the initial shielding user. The only case where an additional Privacy Pools proof is needed would be if the funds are unshielded and re-shielded again.

ZK Cryptography

Privacy Pools works with existing RAILGUN ZK cryptographic systems. Each RAILGUN 0zk balance is comprised of a set of encrypted UTXOs organized via a private Merkle Tree.

Every RAILGUN transaction, such as a Private Send, generates a ZK proof through cryptographic circuits that the sender has sufficient UTXOs in their balance to send the transaction. If the balance is enough for the transaction, then it is valid and the Merkle Tree updates with the new change in balance and state. This is how RAILGUN internal balances are maintained.

As Privacy Pools sits alongside the RAILGUN smart contracts, does not affect this Merkle Tree based spending system in any way. Instead, it enables users to generate an additional recursive proof, which is a proof that the underlying proofs of a user’s balance are not a part of the bad transaction list. As RAILGUN allows for intermediate 0zk balance transfers between shielding and unshielding and each of these transactions is itself a proof, Privacy Pools has a recursion mechanism to assert further statements about these existing proofs.

Recursive SNARKs can prove the entire flow of funds from the initial shield satisfies the conditions of the Merkle proof of non-inclusion. Privacy Pools will compute proofs for every leaf in the regular Merkle Tree that apply to a balance of UTXOs and account for intermediate transactions between shielding and unshielding. This is done through recursive SNARKs which tie the whole proving system together.

Last updated