Introduction

ZisK is a high-performance zkVM (Zero-Knowledge Virtual Machine) designed to generate zero-knowledge proofs of arbitrary program execution. It enables developers to prove the correctness of a computation without revealing its internal state, making ZisK a powerful tool for privacy-preserving and verifiable computation.

Proving systems traditionally involve complex cryptographic operations that require deep expertise and significant computational resources. ZisK abstracts these complexities by providing an optimized toolstack that minimizes computational overhead, making ZK technology accessible to a broader range of developers. With Rust-based execution and planned multi-language support, ZisK is designed to be developer-friendly while maintaining high performance and robust security.

Why ZisK?

  • High-performance architecture optimized for low-latency proof generation.
  • Rust-based zkVM, with future support for additional languages.
  • No recompilation required across different programs.
  • Standardized prover interface (JSON-RPC, GRPC, CLI).
  • Flexible integration: usable as a standalone service or as a library.
  • Decentralized architecture for trustless proof generation.
  • Optimized proof generation costs for real-world applications.
  • Fully open-source and backed by Polygon zkEVM and Plonky3 technology.

Installation Guide

ZisK can be installed from prebuilt binaries (recommended) or by building ZisK tools, toolchain and setup files from source.

System Requirements

ZisK currently supports Linux x86_64 systems.

Note: macOS is not yet supported, but we are actively working on adding support.

Required Tools

Ensure the following tools are installed:

Installing Dependencies

Ubuntu

Ubuntu 22.04 or higher is required.

Install all required dependencies with:

sudo apt-get install -y xz-utils jq curl build-essential qemu-system libomp-dev libgmp-dev nlohmann-json3-dev protobuf-compiler uuid-dev libgrpc++-dev libsecp256k1-dev libsodium-dev libpqxx-dev nasm libopenmpi-dev openmpi-bin openmpi-common libclang-dev clang

Installing ZisK

  1. To install ZisK using ziskup, run the following command in your terminal:

    curl https://raw.githubusercontent.com/0xPolygonHermez/zisk/main/ziskup/install.sh  | bash
    
  2. During the installation, you will be prompted to select a setup option. You can choose from the following:

    1. Install proving key (default) – Required for generating and verifying proofs.
    2. Install verify key – Needed only if you want to verify proofs.
    3. None – Choose this if you only want to compile programs and execute them using the ZisK emulator.
  3. Verify the Rust toolchain: (which includes support for the riscv64ima-polygon-ziskos compilation target):

    rustup toolchain list
    

    The output should include an entry for zisk, similar to this:

    stable-x86_64-unknown-linux-gnu (default)
    nightly-x86_64-unknown-linux-gnu
    zisk
    
  4. Verify the cargo-zisk CLI tool:

    cargo-zisk --version
    

Updating ZisK

To update ZisK to the latest version, simply run: bash ziskup

You can use the flags --provingkey, --verifykey or --nokey to specify the installation setup and skip the selection prompt.

Option 2: Building from Source

Build ZisK

  1. Clone the ZisK repository:

    git clone https://github.com/0xPolygonHermez/zisk.git
    cd zisk
    
  2. Build ZisK tools:

    cargo build --release
    

    Note: If you encounter the following error during compilation:

    --- stderr
    /usr/lib/x86_64-linux-gnu/openmpi/include/mpi.h:237:10: fatal error: 'stddef.h' file not found
    

    Follow these steps to resolve it:

    1. Locate the stddef.h file:
      find /usr -name "stddef.h"
      
    2. Set the environment variables to include the directory where stddef.h is located (e.g.):
      export C_INCLUDE_PATH=/usr/lib/gcc/x86_64-linux-gnu/13/include
      export CPLUS_INCLUDE_PATH=$C_INCLUDE_PATH
      
    3. Try building again
  3. Copy the tools to ~/.zisk/bin directory:

    mkdir -p $HOME/.zisk/bin
    cp target/release/cargo-zisk target/release/ziskemu target/release/riscv2zisk target/release/libzisk_witness.so precompiles/keccakf/src/keccakf_script.json $HOME/.zisk/bin
    
  4. Copy required files to support cargo-zisk rom-setup command:

    mkdir -p $HOME/.zisk/zisk/emulator-asm
    cp -r ./emulator-asm/src $HOME/.zisk/zisk/emulator-asm
    cp ./emulator-asm/Makefile $HOME/.zisk/zisk/emulator-asm
    cp -r ./lib-c $HOME/.zisk/zisk
    
  5. Add ~/.zisk/bin to your system PATH: For example, if you are using bash:

    echo >>$HOME/.bashrc && echo "export PATH=\"\$PATH:$HOME/.zisk/bin\"" >> $HOME/.bashrc
    source $HOME/.bashrc
    
  6. Install the ZisK Rust toolchain:

    cargo-zisk sdk install-toolchain
    

    Note: This command installs the ZisK Rust toolchain from prebuilt binaries. If you prefer to build the toolchain from source, follow these steps:

    1. Ensure all dependencies required to build the Rust toolchain from source are installed.

    2. Build and install the Rust ZisK toolchain:

    cargo-zisk sdk build-toolchain
    
  7. Verify the installation:

    rustup toolchain list
    

    Confirm taht zisk appears in the list of installed toolchains.

Build Setup

The setup building process is highly intensive in terms of CPU and memory usage. You will need a machine with at least the following hardware requirements:

  • 32 CPUs
  • 512 GB of RAM
  • 100 GB of free disk space

Please note that the process can be long, taking approximately 2–3 hours depending on the machine used.

NodeJS version 20.x or higher is required to build the setup files.

  1. Clone the following repositories in the parent folder of the zisk folder created in the previous section:

    git clone https://github.com/0xPolygonHermez/pil2-compiler.git
    git clone https://github.com/0xPolygonHermez/pil2-proofman.git
    git clone https://github.com/0xPolygonHermez/pil2-proofman-js
    
  2. Install packages:

    (cd pil2-compiler && npm i)
    (cd pil2-proofman-js && npm i)
    
    
  3. All subsequent commands must be executed from the zisk folder created in the previous section:

    cd ~/zisk
    
  4. Adjust memory mapped areas and JavaScript heap size:

    echo "vm.max_map_count=655300" | sudo tee -a /etc/sysctl.conf
    sudo sysctl -w vm.max_map_count=655300
    export NODE_OPTIONS="--max-old-space-size=230000"
    
  5. Compile ZisK PIL: (Note that this command may take 20-30 minutes to complete)

    node --max-old-space-size=131072 ../pil2-compiler/src/pil.js pil/zisk.pil -I pil,../pil2-proofman/pil2-components/lib/std/pil,state-machines,precompiles -o pil/zisk.pilout
    

    This command will create the pil/zisk.pilout file

  6. Generate fixed data:

    cargo run --release --bin keccakf_fixed_gen
    mkdir -p build
    mv precompiles/keccakf/src/keccakf_fixed.bin build
    

    These commands generates the keccakf_fixed.bin file in the build directory.

  7. Generate setup data: (Note that this command may take 2–3 hours to complete):

    node --max-old-space-size=65536 ../pil2-proofman-js/src/main_setup.js -a ./pil/zisk.pilout -b build -i ./build/keccakf_fixed.bin -r
    

    This command generates the provingKey directory.

  8. Copy (or move) the provingKey directory to $HOME/.zisk directory:

    cp -R build/provingKey $HOME/.zisk
    
  9. Generate constant tree files:

    cargo-zisk check-setup -a
    

Uninstall Zisk

  1. Uninstall ZisK toolchain:

    rustup uninstall zisk
    
  2. Delete ZisK folder

    rm -rf $HOME/.zisk
    

Quickstart

In this guide, you will learn how to install ZisK, create a simple program and run it using ZisK.

Installation

ZisK currently supports Linux x86_64 systems.

Ubuntu 22.04 or higher is required.

Note: macOS is not yet supported, but we are actively working on adding support.

  1. Make sure you have Rust installed.

  2. Install all required dependencies with:

    sudo apt-get install -y xz-utils jq curl build-essential qemu-system libomp-dev libgmp-dev nlohmann-json3-dev protobuf-compiler uuid-dev libgrpc++-dev libsecp256k1-dev libsodium-dev libpqxx-dev nasm libopenmpi-dev openmpi-bin openmpi-common
    
  3. To install ZisK using ziskup, run the following command in your terminal:

    curl https://raw.githubusercontent.com/0xPolygonHermez/zisk/main/ziskup/install.sh | bash
    

Create a Project

The first step is to generate a new example project using the cargo-zisk sdk new <name> command. This command creates a new directory named <name> in your current directory. For example:

cargo-zisk sdk new sha_hasher
cd sha_hasher

This will create a project with the following structure:

.
├── build.rs
├── Cargo.toml
├── .gitignore
└── src
    └── main.rs

The example program takes a number n as input and computes the SHA-256 hash n times.

The build.rs file generates an input.bin file containing the value of n (e.g., 20). This file is used in main.rs as input to calculate the hash.

You can run the program on your native architecture with the following command:

cargo run

The output will be:

public 0: 0x98211882
public 1: 0xbd13089b
public 2: 0x6ccf1fca
public 3: 0x81f7f0e4
public 4: 0xabf6352a
public 5: 0x0c39c9b1
public 6: 0x1f142cac
public 7: 0x233f1280

Build

The next step is to build the program using the cargo-zisk command to generate an ELF file (RISC-V), which will be used later to generate the proof. Execute:

cargo-zisk build --release

This command builds the program using the riscv64ima_polygon_ziskos target. The resulting sha_hasher ELF file (without extension) is generated in the ./target/riscv64ima-polygon-ziskos-elf/release directory.

Execute

Before generating a proof, you can test the program using the ZisK emulator to ensure its correctness. Specify the ELF file (using the -e or --elf flag) and the input file input.bin (using the -i or --inputs flag):

ziskemu -e target/riscv64ima-polygon-ziskos-elf/release/sha_hasher -i build/input.bin

The output will be:

98211882
bd13089b
6ccf1fca
81f7f0e4
abf6352a
0c39c9b1
1f142cac
233f1280

Alternatively, you can build and run the program with:

cargo-zisk run --release -i build/input.bin

Prove

Before generating a proof, you need to generate the program setup files. Execute:

cargo-zisk rom-setup -e target/riscv64ima-polygon-ziskos-elf/release/sha_hasher

Once the program setup is complete, you can generate and verify a proof using the cargo-zisk prove command by providing the ELF file (with the -e or --elf flag) and the input file (with the -i or --input flag).

To generate and verify a proof for the previously built ELF and input files, execute:

cargo-zisk prove -e target/riscv64ima-polygon-ziskos-elf/release/sha_hasher -i build/input.bin -o proof -a -y

This command generates the proof in the ./proof directory. If everything goes well, you will see a message similar to:

...
[INFO ] ProofMan:     ✓ Vadcop Final proof was verified
[INFO ]      stop <<< GENERATING_VADCOP_PROOF 91706ms
[INFO ] ProofMan: Proofs generated successfully

Note: You can use concurrent proof generation and GPU support to reduce proving time. For more details, refer to the Writing Programs guide.

Verify Proof

To verify a generated proof, use the following command:

cargo-zisk verify -p ./proof/proofs/vadcop_final_proof.json -u ./proof/publics.json

Writing Programs

This document explains how to write or modify a Rust program for execution in ZisK.

Setup

Code changes

Writing a Rust program for ZisK is similar to writing a standard Rust program, with a few minor modifications. Follow these steps:

  1. Modify main.rs file:

    Add the following code to mark the main function as the entry point for ZisK:

    
    #![allow(unused)]
    #![no_main]
    fn main() {
    ziskos::entrypoint!(main);
    }
    
  2. Modify Cargo.toml file:

    Add the ziskos crate as a dependency:

    [dependencies]
    ziskos = { git = "https://github.com/0xPolygonHermez/zisk.git" }
    

Let's show these changes using the example program from the Quickstart section.

Example program

main.rs:

// This example program takes a number `n` as input and computes the SHA-256 hash `n` times sequentially.

// Mark the main function as the entry point for ZisK
#![no_main]
ziskos::entrypoint!(main);

use sha2::{Digest, Sha256};
use std::convert::TryInto;
use ziskos::{read_input, set_output};
use byteorder::ByteOrder;

fn main() {
    // Read the input data as a byte array from ziskos
    let input: Vec<u8> = read_input();

    // Get the 'n' value converting the input byte array into a u64 value
    let n: u64 = u64::from_le_bytes(input.try_into().unwrap());

    let mut hash = [0u8; 32];

    // Compute SHA-256 hashing 'n' times
    for _ in 0..n {
        let mut hasher = Sha256::new();
        hasher.update(hash);
        let digest = &hasher.finalize();
        hash = Into::<[u8; 32]>::into(*digest);
    }

    // Split 'hash' value into chunks of 32 bits and write them to ziskos output
    for i in 0..8 {
        let val = byteorder::BigEndian::read_u32(&mut hash[i * 4..i * 4 + 4]);
        set_output(i, val);
    }
}

Cargo.toml:

[package]
name = "sha_hasher"
version = "0.1.0"
edition = "2021"
default-run = "sha_hasher"

[dependencies]
byteorder = "1.5.0"
sha2 = "0.10.8"
ziskos = { git = "https://github.com/0xPolygonHermez/zisk.git" }

Input/Output Data

To provide input data for ZisK, you need to write that data in a binary file (e.g., input.bin).

If your program requires complex input data, consider using a serialization mechanism (like bincode crate) to store it in input.bin file.

In your program, use the ziskos::read_input() function to retrieve the input data from the input.bin file:


#![allow(unused)]
fn main() {
// Read the input data as a byte array from ziskos
let input: Vec<u8> = read_input();
}

To write public output data, use the ziskos::set_output() function. Since the function accepts u32 values, split the output data into 32-bit chunks if necessary and increase the id parameter of the function in each call:


#![allow(unused)]
fn main() {
// Split 'hash' value into chunks of 32 bits and write them to ziskos output
for i in 0..8 {
    let val = byteorder::BigEndian::read_u32(&mut hash[i * 4..i * 4 + 4]);
    set_output(i, val);
}
}

Build

Before compiling your program for ZisK, you can test it on the native architecture just like any regular Rust program using the cargo command.

Once your program is ready to run on ZisK, compile it into an ELF file (RISC-V architecture), using the cargo-zisk CLI tool:

cargo-zisk build

This command compiles the program using the riscv64ima_polygon_ziskos target. The resulting sha_hasher ELF file (without extension) is generated in the ./target/riscv64ima-polygon-ziskos-elf/debug directory.

For production, compile the ELF file with the --release flag, similar to how you compile Rust projects:

cargo-zisk build --release

In this case, the sha_hasher ELF file will be generated in the ./target/riscv64ima-polygon-ziskos-elf/release directory.

Execute

You can test your compiled program using the ZisK emulator (ziskemu) before generating a proof. Use the -e (--elf) flag to specify the location of the ELF file and the -i (--inputs) flag to specify the location of the input file:

cargo-zisk build --release
ziskemu -e target/riscv64ima-polygon-ziskos-elf/release/sha_hasher -i build/input.bin

Alternatively, you can build and execute the program in the ZisK emulator with a single command:

cargo-zisk run --release -i build/input.bin

If the program requires a large number of ZisK steps, you might encounter the following error:

Error during emulation: EmulationNoCompleted
Error: Error executing Run command

To resolve this, you can increase the number of execution steps using the -n (--max-steps) flag. For example:

ziskemu -e target/riscv64ima-polygon-ziskos-elf/release/sha_hasher -i build/input.bin -n 10000000000

Metrics and Statistics

Performance Metrics

You can get performance metrics related to the program execution in ZisK using the -m (--log-metrics) flag in the cargo-zisk run command or in ziskemu tool:

cargo-zisk run --release -i build/input.bin -m

Or

ziskemu -e target/riscv64ima-polygon-ziskos-elf/release/sha_hasher -i build/input.bin -m

The output will include details such as execution time, throughput, and clock cycles per step:

process_rom() steps=85309 duration=0.0009 tp=89.8565 Msteps/s freq=3051.0000 33.9542 clocks/step
98211882
bd13089b
6ccf1fca
...

Execution Statistics

You can get statistics related to the program execution in Zisk using the -x (--stats) flag in the cargo-zisk run command or in ziskemu tool:

cargo-zisk run --release -i build/input.bin -x

Or

ziskemu -e target/riscv64ima-polygon-ziskos-elf/release/sha_hasher -i build/input.bin -x

The output will include details such as cost definitions, total cost, register reads/writes, opcode statistics, etc:

Cost definitions:
    AREA_PER_SEC: 1000000 steps
    COST_MEMA_R1: 0.00002 sec
    COST_MEMA_R2: 0.00004 sec
    COST_MEMA_W1: 0.00004 sec
    COST_MEMA_W2: 0.00008 sec
    COST_USUAL: 0.000008 sec
    COST_STEP: 0.00005 sec

Total Cost: 12.81 sec
    Main Cost: 4.27 sec 85308 steps
    Mem Cost: 2.22 sec 222052 steps
    Mem Align: 0.05 sec 2701 steps
    Opcodes: 6.24 sec 1270 steps (81182 ops)
    Usual: 0.03 sec 4127 steps
    Memory: 135563 a reads + 1625 na1 reads + 10 na2 reads + 84328 a writes + 524 na1 writes + 2 na2 writes = 137198 reads + 84854 writes = 222052 r/w

Opcodes:
    flag: 0.00 sec (0 steps/op) (89 ops)
    copyb: 0.00 sec (0 steps/op) (10568 ops)
    add: 1.12 sec (77 steps/op) (14569 ops)
    ltu: 0.01 sec (77 steps/op) (101 ops)
    ...
    xor: 1.06 sec (77 steps/op) (13774 ops)
    signextend_b: 0.03 sec (109 steps/op) (320 ops)
    signextend_w: 0.03 sec (109 steps/op) (320 ops)

98211882
bd13089b
6ccf1fca
...

Prove

Program Setup

Before generating a proof (or verifying the constraints), you need to generate the program setup files. This must be done the first time after building the program ELF file, or any time it changes:

cargo-zisk rom-setup -e target/riscv64ima-polygon-ziskos-elf/release/sha_hasher -k $HOME/.zisk/provingKey

In this command:

  • -e (--elf) specifies the ELF file location.
  • -k (--proving-key) specifies the directory containing the proving key. This is optional and defaults to $HOME/.zisk/provingKey.

The program setup files will be generated in the cache directory located at $HOME/.zisk.

To clean the cache directory content, use the following command:

cargo-zisk clean

Verify Constraints

Before generating a proof (which can take some time), you can verify that all constraints are satisfied:

cargo-zisk verify-constraints -e target/riscv64ima-polygon-ziskos-elf/release/sha_hasher -i build/input.bin -w $HOME/.zisk/bin/libzisk_witness.so -k $HOME/.zisk/provingKey

In this command:

  • -e (--elf) specifies the ELF file location.
  • -i (--input) specifies the input file location.
  • -w (--witness) specifies the location of the witness library. This is optional and defaults to $HOME/.zisk/bin/libzisk_witness.so.
  • -k (--proving-key) specifies the directory containing the proving key. This is optional and defaults to $HOME/.zisk/provingKey.

If everything is correct, you will see an output similar to:

[INFO ] GlCstVfy: --> Checking global constraints
[INFO ] CstrVrfy: ··· ✓ All global constraints were successfully verified
[INFO ] CstrVrfy: ··· ✓ All constraints were verified

Generate Proof

To generate a proof, run the following command:

cargo-zisk prove -e target/riscv64ima-polygon-ziskos-elf/release/sha_hasher -i build/input.bin -w $HOME/.zisk/bin/libzisk_witness.so -k $HOME/.zisk/provingKey -o proof -a -y

In this command:

  • -e (--elf) specifies the ELF file location.
  • -i (--input) specifies the input file location.
  • -w (--witness) specifies the location of the witness library. This is optional and defaults to $HOME/.zisk/bin/libzisk_witness.so.
  • -k (--proving-key) specifies the directory containing the proving key. This is optional and defaults to $HOME/.zisk/provingKey.
  • -o (--output) determines the output directory (in this example proof).
  • -a (--aggregation) indicates that a final aggregated proof (containing all generated sub-proofs) should be produced.
  • -y (--verify-proofs) instructs the tool to verify the proof immediately after it is generated (verification can also be performed later using the cargo-zisk verify command).

If the process is successful, you should see a message similar to:

...
[INFO ] ProofMan:     ✓ Vadcop Final proof was verified
[INFO ]      stop <<< GENERATING_VADCOP_PROOF 91706ms
[INFO ] ProofMan: Proofs generated successfully

Concurrent Proof Generation

Zisk proofs can be generated using multiple processes concurrently to improve performance and scalability. The standard MPI (Message Passing Interface) approach is used to launch these processes, which can run either on the same server or across multiple servers.

To execute a Zisk proof using multiple processes, use the following command:

mpirun --bind-to none -np <num_processes> -x OMP_NUM_THREADS=<num_threads_per_process> target/release/cargo-zisk <zisk arguments>

In this command:

  • -np <num_processes> specifies the number of processes to launch.
  • -x OMP_NUM_THREADS=<num_threads_per_process> sets the number of threads used by each process via the OMP_NUM_THREADS environment variable.
  • --bind-to none prevents binding processes to specific cores, allowing the operating system to schedule them dynamically for better load balancing.

Running a Zisk proof with multiple processes enables efficient workload distribution across multiple servers. On a single server with many cores, splitting execution into smaller subsets of cores generally improves performance by increasing concurrency. As a general rule, <number_of_processes> * <number_of_threads_per_process> should match the number of available CPU cores or double that if hyperthreading is enabled.

The total memory requirement increases proportionally with the number of processes. If each process requires approximately 25GB of memory, running P processes will require roughly (25 * P)GB of memory. Ensure that the system has sufficient available memory to accommodate all running processes.

GPU Proof Generation

Zisk proofs can also be generated using GPUs to significantly improve performance and scalability. Follow these steps to enable GPU support:

  1. GPU support is only available for NVIDIA GPUs.

  2. Make sure the CUDA Toolkit is installed.

  3. Build Zisk with GPU support enabled. GPU support must be enabled at compile time. Follow the instructions in the Build ZisK section under Option 2: Building from source in the Installation guide, but replace the build command with:

    cargo build --release --features gpu
    
  4. Build Zisk on the target GPU server. It is recommended to compile Zisk directly on the server where it will be executed. The binary will be optimized for the local GPU architecture, which can lead to better runtime performance.

You can combine GPU-based execution with concurrent proof generation using multiple processes, as described in the Concurrent Proof Generation section. For better performance in this setup, it is recommended to enable NVIDIA’s Multi-Process Service (MPS). You can activate it by running:

nvidia-cuda-mps-control -d

Note: GPU memory is typically more limited than CPU memory. When combining GPU execution with concurrent proof generation, ensure that each process has sufficient memory available on the GPU to avoid out-of-memory errors.

Verify Proof

To verify a generated proof, use the following command:

cargo-zisk verify -p ./proof/proofs/vadcop_final_proof.json -u ./proof/publics.json -s $HOME/.zisk/provingKey/zisk/vadcop_final/vadcop_final.starkinfo.json -e $HOME/.zisk/provingKey/zisk/vadcop_final/vadcop_final.verifier.bin -k $HOME/.zisk/provingKey/zisk/vadcop_final/vadcop_final.verkey.json

In this command:

  • -p (--proof) specifies the final proof file generated with cargo-zisk prove.
  • -u (--public-inputs) provides the path to the public inputs associated with the proof.
  • The remaining flags specify the files required for verification; they are optional, set by default to the files found in the $HOME/.zisk directory.

Precompiles

Precompiles are built-in system functions within ZisK’s operating system that accelerate computationally expensive and frequently used operations such as the Keccak-f permutation and Secp256k1 addition and doubling.

These precompiles improve proving efficiency by offloading intensive computations from ZisK programs to dedicated, pre-integrated sub-processors. ZisK manages precompiles as system calls using the RISC-V ecall instruction.

How Precompiles Work

Precompiles are primarily used to patch third-party crates, replacing costly operations with system calls. This ensures that commonly used cryptographic primitives like Keccak hashing and elliptic curve operations can be efficiently executed within ZisK programs.

Typically, precompiles are used to patch third-party crates that implement these operations and are then used as dependencies in the Zisk programs we write.

You can see here an example of the patched tiny-keccak crate.

Available Precompiles in ZisK

Below is a summary of the precompiles currently available in ZisK:

Ziskof

Riscof tests

The following test generates the riscof test files, converts the corresponding .elf files into ZisK ROMs, and executes them providing the output in stdout for comparison against a reference RISCV implementation. This process is not trivial and has been semi-automatized.

First, compile the ZisK Emulator:

$ cargo clean
$ cargo build --release

Second, download and run a docker image from the riscof repository to generate and run the riscof tests:

$ docker run --rm -v ./target/release/ziskemu:/program -v ./riscof/:/workspace/output/ -ti  hermeznetwork/ziskof:latest

The test can take a few minutes to complete. Any error would be displayed in red.