Comment on page
Private Proofs of Innocence
Learn about the state of the art Zero-Knowledge assurance tool
Private Proofs of Innocence (Private POI) is a decentralized assurance system built by zero-knowledge (ZK) cryptography researchers and contributors to the RAILGUN Project. Private POI 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. Private POI sits alongside (but is separate from) the RAILGUN smart contracts and is open-source infrastructure that can be used by other protocols.
Private POI 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, Private POI 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. Private POI achieves similar aims to a similar level of effectiveness whilst only using public on-chain data and requires no personal information.
Private POI 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.
Architecture of the Private POI process
Private POI 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 Private POI is auto-generated stating that the funds in the shield are not a part of the List Provider dataset
- 4.Private POI is 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 Private POI 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.
With Private POI, 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 Private POI, 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 Private POI as List Provider update times improve.
Private POI works at the balance and transaction level. Meaning, Private POI 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.
- 1.Alice shields 100 USDC into a 0zk address and generates a Private POI 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 Private POI.
- 2.She then sends that 100 USDC to Bob, who can use Alice’s existing Private POI 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 Private POI 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 Private POI proof that applies to that shield of 50 USDC.
Private POI 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 Private POI 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. Private POI 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 Private POI or proofs to List Providers, and they cannot log IP addresses.
Private POI Nodes sync proof data and make it available for anyone interested in verifying Private POI 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 Private POI 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 Private POI. Again, there is no special insight for Private POI nodes
Like IPFS, anyone can run a Private POI node. This ensures decentralized verification of Private POI 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 Relayers who will. Public Relayers broadcast 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 Relayers can do this with any given set of funds, those funds must have a completed Private POI check. Relayers have Private POI nodes which sync and verifies proof data.
In cases where there is an incomplete Private POI check for a series of funds (such as during the Unshield-Only Standby Period), users can Self-Relay a transaction to return funds back to the original shielder.
The following is an example on how RAILGUN private transaction flow following completed Private POI after an initial shield.
- 1.Bob's tokens begin with a Private POI, 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 Private POI 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 Relayer. As part of the proof, Bob generates a special Proof of Spendability, which verifies the Private POI for the Relayer, and guarantees that the received fee will be verified and spendable.
- 3.Bob sends the transaction through the Relayer and waits for it to be forwarded and confirmed by the blockchain.
- 4.Once confirmed, Bob's wallet automatically generates a Private POI 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 Private POI.
This ensures the Private POI 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 Private POI is needed would be if the funds are unshielded and re-shielded again.
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 Private POI 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, Private POI 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. Private POI 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.