# Sin7y Tech Review (33): Principles of private transactions and regulatory compliance issues
![](https://hackmd.io/_uploads/HJfd6sM-2.png)
In August 2022, the Office of Foreign Assets Control (OFAC) [announced sanctions against Tornado Cash](https://jackofalltechs.com/2022/08/23/rep-emmer-demands-an-explanation-of-ofacs-tornado-cash-sanction-from-sec-yellen/), which directly cast a shadow on protocols aiming to achieve privacy on public blockchains. This led to discouragement in the market towards privacy and raised regulatory concerns. However, Ola, an Ethereum Layer 2 network that supports programmable privacy utilizing its ZK-ZKVM architecture, still recognizes the urgent need for robust privacy across the blockchain space.
Ola is not the first project dedicated to bringing privacy to blockchains, nor will it be the last. As a member of the blockchain community, Ola is committed to interpreting the privacy technologies used in most projects and the regulatory compliance issues involved in privacy transactions, in order to help the market understand privacy on top of public blockchains more comprehensively.
## 1. Why was Tornado Cash banned?
The reason for Tornado Cash's blacklisting by OFAC is obvious: its transactions can not be tracked. This has made Tornado Cash widely used for illegal activities.
The principle of privacy in Tornado Cash differs from that of Zcash, which is entirely based on ZK technology. Tornado Cash combines coin mixing and ZK technology, with coin mixing making transactions untraceable. As the coin-mixing pool grows larger, the chances of tracking it approach zero. ZK is only used to realize its own asset proof once the coin mixing is complete.
Therefore, Tornado Cash is called a haven for hackers and black money, as it is impossible to track the addresses to which non-performing assets are withdrawn after entering the mixing pool. This is also the underlying reason for Tornado Cash's blacklisting. Many articles interpret the [principle of coin-mixing](https://www.sanctions.io/blog/ofacs-tornado-cash-sanctions) in Tornado Cash, which readers can find for themselves.
In the following sections, we will explain how private transactions based solely on ZK technology can not only protect privacy but also allow transaction information to be reviewed and tracked when required (through the design of the view key).
## 2. Why do blockchains need privacy
Although blockchain technology provides anonymity to user identity, it does not offer privacy protection for data such as transaction volume. This leaves users vulnerable to revealing their real identity and intentions through behavior-based clustering analysis and other methods, which has led to various emerging fraud and attacks, such as front-running and replay attacks, causing significant losses to many users.
Furthermore, the lack of privacy on the blockchain limits its potential applications in real-world business scenarios. Without adequate privacy, the mainstream adoption of blockchain technology is unlikely. For instance, in financial infrastructure, if sensitive financial information such as users' salaries or payments for services like healthcare is publicly viewable, potential users of blockchain-based payment systems may be hesitant to use them. The same goes for social networking services, decentralized lending protocols, philanthropic platforms, and any other cases where users value the privacy of their information.
Currently, privacy and data protection have become some of the most discussed and concerning issues in various industries, and data protection is now being legislated in many countries. Consequently, adding privacy protection features will become the future development trend of blockchain technology. Numerous cross-disciplinary and cross-industry giants are focusing on privacy and data protection.
## 3. Definition of regulated private transactions
A blockchain transaction is primarily composed of sender information, transaction data (amount), and recipient information. Currently, blockchain transactions are open and transparent, allowing anyone to view and analyze transaction details at any time. Private transactions, on the other hand, use zero-knowledge technology and cryptography to conceal transaction information (sender information, transaction data, and recipient information) and protect user privacy.
The crackdown on Tornado Cash reveals the fact that the industry does require privacy, but it must be regulated, and private transaction information should be available if needed to enable tracking of private asset transfers. [Zcash](https://z.cash/) provides a good starting point for the privacy track, enabling both privacy and regulatory compliance. Zcash has published a separate article outlining the [compliance of the project](https://z.cash/wp-content/uploads/2020/07/Zcash-Regulatory-Brief-062020.pdf). Other ZK-based privacy projects like Ola, Aleo, Aztec, and the Manta network, which use similar privacy architectures to Zcash but with differences in programmability implementations, are on par with regulatory issues (See [Design Principles of Private Transactions in Aleo and Zcash](https://twitter.com/Sin7y_Labs/status/1565652363049897986)).
## 4. Implementation principle of private transactions
There are four technical solutions for private transactions: CoinJoin (DASH), hidden address + ring signature (Monero), Mimblewimble (Litecoin), and zero-knowledge proof (Zcash). In this article, we will only focus on the principle of private transactions based on zero-knowledge technology.
### 4.1 Encryption process of private transactions
A transaction typically consists of the sender address, the receiver address, and the transaction data (such as which method of the contract is called). In a private transaction, each of these three pieces of information is encrypted using various keys.
#### 4.1.1 Introduction to the Key System
The key system is the basis for private transactions. The current key system of the latest version of Zcash is shown in Figure 1:
![](https://hackmd.io/_uploads/r1eBWtzZh.png)
*Figure 1: Zcash Key System (Orchard)*
The key system contains a variety of keys for different purposes, the most important of which are the following:
- sk: Spending key, used to derive other keys, similar to the private key in Bitcoin, must not be shared with others
- ask: Spend authorizing key, used to generate the signature spendAuthSig of Spend transfer, must not be shared with others
- (ak, nk, rivk): Full viewing key, used to view all transactions of the user, needs to be shared with the delegator to generate zkSNARK proof
- ak: Spend validating key, used to verify the transfer signature spendAuthSig
- nk: The recipient's nullifier deriving key, used to generate the nullifier
- rivk: Used to generate shielded payment addresses
- (dk, ivk): Incoming viewing key, used to view all transactions sent to the user, privacy will be leaked after disclosure
- dk: Diversifier key, used to generate diversified parameters in shielded payment addresses *d*
- ivk: Private key in the key agreement scheme, used to generate the symmetric encryption key, and transmission key $pk_d$
- ovk: Outgoing viewing key, used to view transactions issued by all users, privacy will be leaked after disclosure
- (d, $pk_d$): Shielded payment address, used as the recipient's address of the transaction, needs to be given to the sender
#### 4.1.2 The UTXO Model
Zcash uses the Unspent Transaction Output (UTXO) model, similar to Bitcoin, and expands on Bitcoin's transparent transfer mechanism. In Zcash, a user's funds are stored in a data structure called a note, with each note representing a certain amount of ZEC tokens. To transfer funds, the sender selects some notes received in previous transactions, destroys them (by calculating and revealing their nullifiers), creates new notes (by revealing their note commitments), encrypts these new notes, and sends the ciphertexts to the blockchain. The recipient can then use their viewing key to decrypt the note ciphertexts and view the amount, while others are unable to access the plaintext of the notes.
The newly created note can be expressed as$$(d, pk_d, v, \rho, \psi, rcm)$$, where:
- (d, $pk_d$): The owner address of the note, that is, the shielded payment address of the recipient
- v: Value, i.e. the amount of ZEC tokens
- $(\rho, \psi)$: Two random numbers, used to generate a nullifier when the recipient consumes this note in the future
- rcm: Used to check whether the note commitment is correct
#### 4.1.3 Structure of transactions
![](https://hackmd.io/_uploads/HyS7ZKGb3.png)
Zcash transactions comprise zero or more Action transfers, each of which is encoded into an Action description, representing a transfer that involves destroying an old note and creating a new one. Each Action description requires generating a proof, and the zero-knowledge proof algorithm is utilized to verify that the data is accurate. Eventually, all proofs are condensed into a final proof using the Halo2 algorithm and stored in the transaction.
The data contained in the Action description are the following:
- $cv^{net}$: Commitment to the change of the value in the pool after the transfer
- The committed value is the result of the input note's value minus the output note's value
- $rt: \{0..q_P-1\}$, the output treestate of a previous block
- Treestate contains a note commitment tree and a nullifier set
- $nf:\{0..q_P-1\}$input note nullifier
- rk: randomized validating key, used to validate spendAuthSig
- spendAuthSig: a signature generated by the sender using ask
- $cm_x: \{0..q_P-1\}$, x coordinate of output note commitment on the elliptic curve
- epk: Ephemeral public key used in the key agreement scheme
- $C^{enc}$: ciphertext of the output note
- The recipient can decrypt it using his own full viewing key or incoming viewing key
- $C^{out}$: The recipient can use his own ock (outgoing cipher key) to decrypt it to get the $pk_d$ and ephemeral private key $esk$, and can further generate a symmetric encryption key to decrypt the entire note plaintext
- enableSpends: 0 or 1. This flag is used to enable the non-zero-value function in Action Inputs
- 1 means there is an input note, and 0 means there is no input note
- enableOutputs: 0 or 1. This flag is used to enable the non-zero-value function in Action Outputs
- 1 means there is an output note, and 0 means there is no output note
- $\pi$: The zkSNARK proof of the statement:$$(cv, rt^{Orchard}, nf, rk, cm_x, enableSpends, enableOutputs)$$
$rt, enableSpends, OutputSpends$ are three attributes that are the same for all Action transfers within a transaction, so they are actually stored in the body of the transaction, not in the Action description. $\pi$ is the aggregate proof of all Action proofs stored in the transaction's proofsOrchard field.
#### 4.1.4 Process of sending a transaction
![](https://hackmd.io/_uploads/B1gBZtM-2.png)
To initiate a transfer in Zcash, the sender needs to create a transaction that includes one or more Action descriptions. In order to encrypt the note plaintext, the sender generates an ephemeral key pair using the recipient's shielded payment address $(d, pk_d)$ and derives a symmetric encryption key by combining the ephemeral private key and the recipient's public key $pk_d$. The encryption process can be outlined as follows:
* Let leadByte be 0x02
* For each Action description, choose a value $v$ and the recipient's shielded payment address $(d, pk_d)$
* Check $pk_d$
* Calculate $g_d = DiversifyHash(d)$
* Choose a uniformly random commitment trapdoor $rcv \leftarrow ValueCommit.GenTrapdoor()$
* Choose uniformly random $rseed \leftarrow B^{Y^{32}}$
* Let $\rho = nf^{old}$, $\underline{\rho} = I2LEOSP_{256}(\rho)$
* Calculate $esk = ToScalar(PRF^{expand}_{rseed}([4]||\underline{\rho}))$
* Calculate $rcm = ToScalar(PRF^{expand}_{rseed}([5]||\underline{\rho}))$
* Calculate $\psi = ToBase(PRF^{expand}_{rseed}([9]||\underline{\rho}))$
* Let cv net be the value commitment to the value of the input note minus the value v of the output note for this Action transfer, choose a uniformly random commitment trapdoor $rcv$
* Calculate $cm_x = Extract'_P(NoteCommit_{rcm}(repr(g_d), repr(pk_d), v, \rho, \psi))$
* $np = (leadByte, d, v, rseed, memo)$
Use the recipient's shielded payment address $(g_d, pk_d)$ and $ovk$ to encrypt the note, get the transmitted note ciphertext $(epk, C^{enc}, C^{out})$. The process is as follows:
* Let $P^{enc}$ be the raw encoding of the note plaintext
* $epk = KA.DerivePublic(esk, g_d)$
* $ephemeralKey = LEBS2OSP_{l_G}(repr_G(epk))$
* $sharedSecret = KA.Agree(esk, pk_d)$
* $K^{enc} = KDF(sharedSecret, ephemeralKey)$
* $C^{enc} = Sym.Encrypt_{k^{enc}}(P^{enc})$
* $cv = LEBS2OSP(repr(cv))$
* cv is value commitment
* $cmx = LEBS2OSP_{256}(Extract_{G^{(r)}}(cm))$
* cm is note commitment, cmx is x-coordinate of cm
* $ock = PRF^{ock}_{ovk}(cv, cmx, ephemeralKey)$
* Outgoing cipher key, used to generate $C^{out}$
* $op = LEBS2OSP(repr_{G}(pk_d)||I2LEBSP_{256}(esk))$
* $C^{out} = Sym.Encrypt_{ock}(op)$
* Return$(ephemeralKey, C^{enc}, C^{out})$
* Return zkSNARK proof $\pi$
* Return $(cv, cm_x, epk, C^{enc}, C^{out}, \pi)$
* If there is no real note spent in this Action description, you need to create a dummy note to spend, using the nullifier of the dummy note as $\rho$.
* Randomize the order of Action descriptions
* Send the transaction to the network
#### 4.1.5 Hiding sender information
The sender generates an ephemeral key pair each time and generates a symmetric encryption key $K^{nec}$ in the key agreement scheme, uses $K^{nec}$ to encrypt the note plaintext, and does not use his own sk (spending key) or ask (spend authorizing key), so the sender's information can be hidden.
#### 4.1.6 Hiding recipient information
The recipient generates different new shielded payment addresses for different transactions, so the destination addresses in the transactions are different, and other users on the network can not decrypt the note ciphertext, nor can they see the recipient's address, so the recipient's information can be hidden.
#### 4.1.7 Hiding the transfer amount
The transfer amount is stored in the note and encrypted by the sender using a symmetric encryption key, denoted as $K^{nec}$, to generate a ciphertext of the note. This means that besides the sender and receiver, other users on the network, including the validator, can only verify that the input amount and output amount in the transaction are balanced, but can not view the specific transfer amount. Therefore, the transfer amount can be hidden.
### 4.2 Decryption process of private transactions
![](https://hackmd.io/_uploads/S1gr-tG-n.png)
The recipient can use their incoming viewing key or full viewing key to decrypt the note ciphertext in the transaction. Additionally, the recipient can use the ephemeral public key stored by the sender in the transaction to generate the same symmetric encryption key $K^{nec}$ as the sender. By using the decryption algorithm in the symmetric encryption scheme, the recipient can generate the note plaintext.
#### 4.2.1 Decrypting using an incoming viewing key
The decryption process using an incoming viewing key is as follows:
* $ivk$ is the recipient's KA private key
* $epk = abst_G(ephemeralKey)$
* $sharedSecret = KA.Agree(ivk, epk)$
* $K^{enc} = KDF(sharedSecret, ephemeralKey)$
* $P^{enc} = Sym.Decrypt_{k^{enc}}(C^{enc})$
* $np = (leadByte, d, v, rseed, memo)$
* $rcm = LEOS2IP_{256}(rseed)$
* $g_d = DiversifyHash(d)$
* $pk_d = KA.DerivePublic(ivk, g_d)$
* $n = (d, pk_d, v, \rho, \psi, rcm)$
check $Extract(NoteCommit(n))\ and \ cmx$ are equal
$\psi = ToBase(PRF^{expand}_{rseed}([9]||\underline{\rho}^{opt}))$
$\rho$ is used to calculate the nullifier in the future
* return $(n, memo)$
#### 4.2.2 Decrypting using a full viewing key
The decryption process using a full viewing key is as follows:
* $ovk$ is outgoing viewing key
* $ock = PRF^{ock}_{ovk}(cv, cmx, ephemeralKey)$
* $op = Sum.Decrypt_{ock}(C^{out})$
* $(pk*_d, \underline{esk}) = op$
* $esk = LEOS2IP_{256}(\underline{esk})$
* $pk_d = abst_G(pk*_d)$
* $sharedSecret = KA.Agree(esk, pk_d)$
* $K^{enc} = KDF(sharedSecret, ephemeralKey)$
* $P^{enc} = Sym.Decrypt_{K^{enc}}(C^{enc})$
* $np = (leadByte, d, v, rseed, memo)$
* $\underline{rcm} = rseed$
* $\rho = nf^{old}$
* $rcm = LEOS2IP_{256}(\underline{rcm})$
* $g_d = DiversifyHash(d)$
* $n = (d, pk_d, v, \rho, \psi, rcm)$
$$\psi = ToBase(PRF^{expand}_{rseed}([9]||\underline{\rho}^{out}))$$
* $cm' = NoteCommiemnt(n)$
check ($Extract(cm')\ and\ cmx$ are equal
* return $(n, memo)$
## 5. Compliance-Friendly Design in Ola
The purpose of private transactions in a blockchain setting is to address the issues of fraud, social engineering, asset theft by malicious actors as well as other attacks and manipulations of applications, all resulting from the complete transparency of current blockchains, as well as the potential risks associated with the exposure of sensitive financial data to third parties. It is essential to maintain regulatory and compliance standards to ensure the healthy development of the entire industry.
Ola has adopted a "view key" design that is friendly not only for developers and common users but also for regulatory compliance, as depicted in the figure below:
![](https://hackmd.io/_uploads/Hkex3Fz-3.jpg)
If you have any questions about regulatory compliance with private transactions, please feel free to contact us at <contact@sin7y.org >. Welcome to follow Ola's official [Twitter](https://twitter.com/Sin7Y_Labs), join our [Discord](https://discord.gg/vDFy7YEG6j) server, and get the latest updates from Ola!
---
**About**
This report aims to provide an update on the latest developments and news related to Ola and zero-knowledge cryptography, which has the potential to revolutionize the way we approach privacy and security in the digital age. We will continue to monitor and report on the latest developments in this field. Please write to <contact@sin7y.org> if you’d like to join or partner with us.
**Stay Tuned**
[Website](https://sin7y.org/) | [Whitepaper](https://olavm.org/) |[GitHub](https://github.com/Sin7Y) | [Twitter](https://twitter.com/Sin7Y_Labs) | [Discord](https://discord.gg/vDFy7YEG6j) | [HackMD](https://hackmd.io/team/sin7y?nav=overview) | [Medium](https://medium.com/@sin7y) | [HackerNoon](https://hackernoon.com/u/sin7y)