In order to comprehend the functioning of the blockchain system, it is crucial to have a grasp of various cryptographic concepts. One such example is secp256k1, which is an asymmetric signature algorithm and curve utilized to sign and verify accounts within Bitcoin and Ethereum systems. Additionally, hash algorithms like sha256 are employed to compress variable-length information into fixed-length codes, while base58 can be utilized to encode information into a string represented by printable characters. Another significant algorithm is ECDH, which is a Diffie-Hellman key exchange algorithm that allows for secure communication key exchange between P2P nodes.
Zero-knowledge Proof, or ZKP/ZK for short, is a cryptographic algorithm that enables the proof of a proposition’s correctness without revealing any additional information. This attribute of ZKP, which has sparked significant interest, is commonly referred to as “zero-knowledge,” although some argue that “Zero Leakage Proof” is a more accurate name that better represents its fundamental capabilities.
Despite being introduced in 1985, Zero-knowledge Proof (ZKP) did not see widespread practical applications for a long time, resulting in slow technological development. However, with the emergence of Bitcoin in 2009, people began to recognize its potential in addressing privacy and scalability issues in blockchain technology. Since then, significant investments have been made in both the development and engineering applications of ZKP, resulting in numerous implementations such as Groth16, PlonK, STARK, and others. Currently, there is no definitive industry standard for ZKP. This article aims to provide an inventory of the technical features of various ZKP implementations to aid in your study, research, and engineering development.
Field of Application of ZKP
- Privacy Certificate
Zcash was perhaps the first widely adopted use case of ZKP. It leverages the Bitcoin source code and applies ZKP to token transfers to ensure complete transaction confidentiality while enabling blockchain nodes to verify the transactions.
Tornado Cash, on the other hand, is a coin mixer that operates on the Ethereum network. It utilizes ZKP to authenticate nodes on the Merkle-Tree. Users can deposit a predetermined quantity of tokens into the fund pool and then use the Proof generated by ZKP to verify the deposited funds without having to disclose transaction information.
2. Computing Outsourcing
In blockchain systems, each node has limited computing power. However, ZKP technology allows nodes to outsource a considerable number of calculations to off-chain nodes. In this scenario, the correctness of the calculations can be determined by verifying the calculation proofs and results submitted by the outsourcing party.
zksync1.0 is a compelling example of this. It enables off-chain transfers and trading of Ethereum tokens, with the results subsequently submitted to the nodes. By verifying the ZKP proof, the nodes can determine whether the calculations were performed according to the declared method.
3. Data Compression
Filecoin leverages ZKP to establish a space-time proof system that verifies the local storage of specific files by users. The system has been proven to be capable of storing up to 18 EiB of data.
Mina presents another example, particularly in high-speed blockchain systems where the transaction data volume is significant, and the consensus protocol verification requires maintaining all blocks. Consequently, the hardware requirements for such systems are high, with permanent storage necessitating continuous disk space and data indexing capability expansion for blockchain nodes. In such cases, ZKP can be applied to compress verification data. Through recursive zero-knowledge proof, Mina reduces the ledger to 11 KB, while still ensuring block correctness verification.
The proof system serves as the fundamental algorithm implementation of ZKP and can be classified into two categories: interactive and non-interactive.
- Interactive Proof System
The interactive proof system involves two parties, namely, the Prover (P) and the Verifier. P holds a specific secret, such as the secret key of a public key cryptosystem or a quadratic residue square root, and aims to convince the Verifier that they possess the secret. The interactive proof system consists of multiple rounds where P and V exchange messages based on received messages and their own computed results. In a typical scenario, V queries P during each round, and P responds accordingly. After all rounds are completed, V decides whether to accept P’s proof based on their ability to accurately answer each query sent by V during the rounds.
2. Non-interactive Proof System
The previously described interactive proof system involves direct communication between P and V, with P generating the proof and V directly verifying it. Such a proof system is referred to as a non-interactive proof system (NIZK).
In the blockchain context, NIZK is the generally used proof system, where the verifier V is the blockchain node, and the prover P is either the end user or the two-layer network (Layer2).
The reference link offers a description of the publicly published NIZK schemes and their characteristics over the past ten years.
For practical engineering applications, performance and versatility are the primary focus, leading to a more comprehensive classification and comparison of commonly used proof systems, as detailed in the reference link .
Characteristics: Compact proof size, absence of trusted settings, but with a lengthy proof generation and verification process.
Representative projects: Bulletproofs, Halo, Halo2.
- SNARKs (Succinct Non-interactive ARguments of Knowledge)
Characteristics: Compact proof size and relatively short proof verification time, but circuit trust is required.
Representative project: Groth16.
- SNORKs (Succinct Non-interactive Oecumenical/Universal Arguments of Knowledge)
Characteristics: Compact proof size and the need for only one trusted setup to be established for all circuits.
Representative projects: Sonic, PlonK, Marlin, Plonky2.
- STARKs (Succinct (Scalable) Transparent Arguments of Knowledge)
Characteristics: Large proof size, absence of trusted setup requirement, and excellent scalability.
Representative project: STARK.
3. Performance Comparison
The circuit represents the business logic implementation of the ZKP system, and the development of ZKP applications requires circuit programming. The ZKP logic code is referred to as a “circuit” due to the following reasons:
- The ZKP proof code is transformed into a set of simple constraint expressions called R1CS, which is then converted into a large polynomial QAP using the Lagrange interpolation method. Finally, it is constrained in the form of gate circuits.
- Similar to hardware circuits, all code branches execute simultaneously.
- Similar to hardware circuits, ZKP enforces the absence of recursion and complex loops within the circuit, with the number of loops limited to a constant.
It isn’t necessary to start building ZKP applications from scratch using cryptography. Many development libraries have already implemented underlying proof systems, enabling developers to focus solely on business logic implementation. These libraries operate at varying levels of abstraction, with some requiring knowledge of circuit expression descriptions and others being simple to implement by defining the code based on the process.
- Commonly Used Development Libraries
This is a C++ language implementation of the general proof system, basic circuit library, and application examples.
Proof systems: BBFR15, BCCT12, BCCT13, BCGTV13, BCIOP13, BCTV14a, BCTV14b, CTV15, DFGK14, Groth16, GM17, GGPR13, PGHR13.
This is a proof system designed in Go, which offers a high-level API for circuit design.
Proof systems: Groth16, PlonK.
This is a Rust-based proof system that offers a circuit interface, infrastructure, and basic circuit implementations, including boolean and numerical abstractions.
Proof system: Groth16.
Proof systems: Groth16, PlonK.
This is a Python-based implementation that enables the generation of proofs in the user’s browser, utilizing Ethereum smart contracts as validators. Currently, project development is inactive, with Circom proving a better alternative in the same scenario.
Proof system: Groth16.
This is a Rust-based proof system that is currently under development, offering single and aggregate range proofs, multi-party computations with strong typing, and a constraint system API that supports the proving of arbitrary statements.
Proof system: bulletproofs.
This proof system is based on a Rust implementation, and is maintained by the ZCash team. Halo2 is designed specifically for PLONKish and affords direct control over how circuits are represented in arithmetic operations, making it a great choice for building highly optimized circuits.
Proof system: Halo2.
2. Development Process
Using gnark as an example, a typical workflow involves:
1)Use code to describe the problem that needs to be solved.
2)Compile the code into an R1CS constraint system.
3)Establish credible settings on the R1CS to acquire the Proving key and Verify key.
4)The Prover utilizes the R1CS and Proving key to calculate private data and generate a Proof.
5)The Verifier uses the Verify key to verify the Proof.
Special Language for Circuit Programming
- Based on the Ethereum Platform
Cairo is a programming language designed for building programs that can be proven to function correctly, with one party able to verify that a computation was performed accurately. Utilizing Cairo and other proof systems offers a means of scaling blockchains. StarkNet employs the Cairo programming language as its infrastructure, as well as for developing StarkNet contracts.
Proof system: STARK.
Zokrates leverages a domain-specific language (DSL) to describe circuits, offering commonly used circuit libraries that enable the utilization of verifiable calculations in DApps. From standardizing programs in high-level languages to generating calculation proofs, and then verifying these proofs in Solidity, Zokrates can assist in the use of verifiable calculations.
Proof systems: GM17, Groth16, Marlin.
Circom is a language that leverages DSL to describe circuits, which can work together with snarkjs to generate proofs in users’ browsers, using Ethereum smart contracts as verifiers.
Proof systems: Groth16, PlonK.
Noir is a privacy programming language built by Aztec in Rust, leveraging a DSL to describe circuits, enabling the safe and straightforward construction of privacy-preserving zero-knowledge circuits.
Proof system: PlonK.
- ZkE VM
Similar to the EVM, the zkEVM is a virtual machine that progresses between states through program operations. However, the zkEVM verifies the accuracy of each computation stage through proof generation. In essence, zkEVM utilizes a mechanism for proving that execution steps adhere to the rules.
Currently, teams such as zkSync, Polygon, Scroll, Starkware, and others are working on realizing zkEVM and have made notable strides.
2. Based on the Public Chain Platform
- zkApp (Mina)
zkApps are smart contracts powered by zero-knowledge proofs in the Mina Protocol. These contracts can carry out arbitrarily complex computations off-chain and only charge a fixed fee for sending the zero-knowledge proofs to the chain to verify the computation. This is in contrast to other blockchains that perform on-chain computations and employ a variable gas fee model. zkApps are written in Typescript.
Proof system: PlonK.
- LEO (Aleo)
Aleo’s LEO is a statically-typed programming language created specifically for developing private applications. Leo can be built seamlessly on top of the Aleo blockchain to provide a secure foundation for a decentralized, private ecosystem. The language is designed with developers in mind and offers features that ensure privacy, security, and ease of use.
Proof system: Marlin.
ZKP Common Security Issues
The SlowMist security team has been conducting security audits on various well-known ZKP products, including ZKSwap, Zkdex, and Zksafe, among others. These audits have revealed several medium and high-risk vulnerabilities, which have given the team a greater understanding of the security issues in ZKP applications. The most common security problems identified by the SlowMist team during ZKP application audits include:
- Trust Parameter Risk
One of the major security concerns in ZKP applications is the risk associated with trust parameters. To use zk-SNARKs, a set of parameters known as the Common Reference String (CRS) is required. However, during the creation of these parameters, private parameters are also generated. If these private parameters fall into the wrong hands, they can be used to forge proofs.
The generation of the CRS must also be audited to ensure that no backdoors are introduced, and that the private parameters are not intentionally preserved. Similarly, zk-SNORKs requires that the Structured Reference String (SRS) is trusted.
To mitigate these security risks during the trusted configuration stage, secure multi-party computing (MPC) can be used. The MPC ensures that the final calculation result is credible as long as at least one participant is honest.
- Static Code Security
This part mainly deals with security issues resulting from non-standard coding practices, such as unchecked parameters, unhandled return values, numerical overflow, unchecked boundaries, etc. If the circuit programming language is C/C++, there is also a risk of memory overflow.
- Supply Chain Attack Risk
The risk of supply chain attacks in ZKP applications mainly arises from the use of vulnerable code bases, including outdated versions. Typically, ZKP applications are used in conjunction with clients or web front-ends, which can also be vulnerable to hacking through various means.
- Logical Error
Logical errors are the most common errors in circuit implementation. It is important to ensure that the circuit design meets the requirements outlined in the requirements document.
- Double Spend Attack
Incorrect circuit design can result in double spend attacks, for example, some ZKP libraries may have scalability vulnerabilities, and attackers can use known proofs to generate different proofs. If the circuit design is improper, this can lead to double spending attacks.
- Proof Forgery
One of the primary objectives of ZKP is to ensure the completeness and reliability of proofs, making sure that “false cannot be true and true cannot be false”. Therefore, the issue of proof forgery, i.e., the ability to create a false proof, is a major concern. This is usually caused by vulnerabilities in the underlying library, and it is recommended that project teams use publicly-audited ZKP libraries and stable release versions to avoid such issues.
- Side Channel Attack
Improper circuit design can result in different computing characteristics for different private information, making it possible for attackers to guess private input data through public input or proof, which is known as a side-channel attack.
- Circuit Constraint Failure
Improperly defined circuit expressions may lead to variables that are not properly constrained.
- Special Value Attack
Special input values such as 0 or null may bypass the validation logic of the system, leading to a potential attack.
- Privacy Input Guessing
Strict auditing of input data is required to prevent privacy leakage in applications such as Tornado Cash where guessing of input information can result in serious privacy issues.
- Rugpull Risk
Projects that have special administrator privileges may have a risk of RugPull, where once these privileges are used illegally, the project’s funds and user assets can be stolen.
- Smart Contract Risk
The verification process of some ZKP proofs is done through smart contracts, for instance, with Circom or ZoKrates. However, smart contracts may have security risks such as re-entry, replay, and logical errors. For more information on this, you can refer to the smart contract security audit service offered by the SlowMist Security Team.
To address the security concerns regarding ZKP mentioned above, the SlowMist security team has developed a set of security measures based on their practical experience in offensive and defensive operations. These measures are combined with various testing methods including black box, grey box, and white box testing, and are aimed at providing ZKP circuit audits to the blockchain industry.
Zero-knowledge proofs offer an effective solution to privacy, scalability, and data compression issues in blockchain. There are various implementation schemes with different performance and security benchmarks. When developing a zero-knowledge proof circuit, developers must choose an appropriate framework according to their requirements and ensure that a comprehensive security audit has been conducted before going live.
Lastly, special thanks to Safeheron, a professional one-stop self-custody digital asset service provider, for their technical expertise.