Skip to main content

What is zkLLVM?

Definition

Access the project on GitHub

zkLLVM is a compiler that transforms C++ or Rust code into circuits to be used in zk-SNARK or zk-STARK systems.

The goal of zkLLVM is to make zero-knowledge proofs and provable computations accessible for everyone with knowledge of C++ or Rust programming.

zkLLVM takes code, breaks it down into circuit components, and transforms it into an arithmetic constraint system that can be used to generate and verify proofs when given public and private inputs.

Circuits generated by zkLLVM are compatible with the Placeholder proof system. To learn more about how zkLLVM can be extended to other proof systems, click here.

Placeholder proof system

The Placeholder system is PLONKish. The circuit components for this system are supplied from =nil; Foundation's blueprint library.

Recommended specs

The following specs are recommended for working with zkLLVM.

  • A Linux-based system (Ubuntu 20+ is preferable)
  • At least 16 GBs of RAM

If you are using a Windows machine, an Ubuntu distribution can be accessed via the WSL 2 service.

Pipeline

Overview

The following diagram outlines the key components and stages of the zkLLVM circuit generation pipeline. Note that some of these components are currently unsupported.

Step-by-step

Working with zkLLVM involves the following steps.

Write the 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.

Examples

The zkLLVM repository contains several ready-made examples of circuits. They can be reused wholly or repurposed depending on the use case.

Limitations

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.

Pass the circuit to the assigner tool

The assigner tool is used to prepare all inputs and witnesses for the circuit.

After this stage is complete, the circuit should be ready for use with dynamic inputs.