Usage flow
Diagram
The following diagram shows the flow for converting a .cpp
or a .rs
file into a proof binary and Solidity code for deployment.
Key stages
Here is a breakdown of the key stages a circuit must pass before being proven.
Write code in C++ or Rust
There is no need to use any special syntax when working with zkLLVM. A circuit is defined by simply adding a [[circuit]]
(C++) or a #[circuit]
(Rust) directive before a function. With some modifications, almost any existing C++ or Rust code can be reused for zkLLVM.
The zkLLVM repository contains several ready-made examples of circuits. They can be reused wholly or repurposed depending on the use case.
Read the materials in the Best practices and limitations section to learn more about the changes that would need to be made to existing C++ or Rust code for reuse in zkLLVM.
Compile the code into a circuit
Compiling takes only a few seconds and the entire process is done via a CLI tool which is a replacement for clang
and rustc
. This tool can be easily integrated to a CI/CD pipeline or any development environment.
It is also possible to use dedicated build management systems (Cargo and CMake) if a circuit requires the use of external dependencies.
Pass the circuit to the assigner
tool
The assigner
tool is used to prepare all inputs and witnesses for the circuit. It generates the circuit constraints and the assignment table.
After this stage is complete, the circuit should be ready for use with dynamic inputs.
Generate proof for the circuit
At this point, the circuit and its inputs can be passed to the transpiler
tool to generate a proof and Solidity contract files.
Alternatively, the circuit proof can be generated by using the proof-generator
tool.