# 4/20 ZK Study --- ZoKrates
[TOC]
## Introduction
- **Original paper:** [ZoKrates - Scalable Privacy-Preserving
Off-Chain Computations](http://www.ise.tu-berlin.de/fileadmin/fg308/publications/2018/2018_eberhardt_ZoKrates.pdf)
> *Jacob Eberhardt, Stefan Tai
> Information Systems Engineering (ISE)
> TU Berlin, 2018*
- **Github:** [Zokrates/ZoKrates](https://github.com/Zokrates/ZoKrates)
- **Document:** [Introduction](https://zokrates.github.io/introduction.html)
## Sokrates 蘇格拉底

$$
I\ know\ that\ I\ am\ intelligent,\ because\ I\ know\ that\ I\ know\ nothing.
$$
## ZoKrates
- Supports generation of zkSNARKs from high level language code including Smart Contracts for proof verification on the Ethereum Blockchain.
$$
I\ know\ that\ I\ show\ nothing!
$$
## Workflow

## Getting started
- [Document](https://zokrates.github.io/gettingstarted.html)
### Remix
- [Remix](https://remix.ethereum.org/)
- Plugin manager -> ZoKrates -> Activate

### One-line installation
```a
$ curl -LSfs get.zokrat.es | sh
```
```a
$ curl -LSfs get.zokrat.es | sh
ZoKrates: Tag: latest (0.7.0)
ZoKrates: Detected architecture: x86_64-apple-darwin
ZoKrates: Installing to: /Users/<USER_NAME>/.zokrates
ZoKrates: Fetching: https://github.com/ZoKrates/ZoKrates/releases/download/0.7.0/zokrates-0.7.0-x86_64-apple-darwin.tar.gz
ZoKrates was installed successfully!
If this is the first time you're installing ZoKrates run the following:
export PATH=$PATH:/Users/<USER_NAME>/.zokrates/bin
$ export PATH=$PATH:/Users/<USER_NAME>/.zokrates/bin
```
### Hello ZoKrates
- 新增一個檔名為`root.zok`的檔案
```python=
def main(private field a, field b) -> bool:
return a * a == b
```
> 檢查 `a` 平方是否等於 `b`
>
> 其中 `a` 是 private input,
> `b` 是 public input,
> 輸出一個 `bool` 為 public output
- 執行
```python=
# compile
zokrates compile -i root.zok
# check
zokrates check -i root.zok
# perform the setup phase
zokrates setup
# execute the program
zokrates compute-witness -a 337 113569
# generate a proof of computation
zokrates generate-proof
# print proof
zokrates print-proof --format remix
# export a solidity verifier
zokrates export-verifier
# off-chain verification
zokrates verify
```
## Types
| Type | example | note |
| -------- | -------- | -------- |
| `field` | `field x = p-1` | |
| `bool` | `bool a = true` | |
| `u8/u16/u32/u64` | `u16 y = 2**16-1` | |
| `array` | `field[3] a = [1,2,3]` | |
| `struct` | `Struct Point {` <br/> `field x,` <br/> `field y` <br/> `}` <br/><br/> `Point p = Point {x: 1, y: 0}` | |
## Operators
| Operator | Description | note |
| -------- | -------- | -------- |
| `**` | Power | |
| `+x` | Positive | v 0.7.0 |
| `-x` | Negative | v 0.7.0 |
| `!x` | Negation | |
| `*` | Multiplication | |
| `/` | Devision | |
| `%` | Remainder | v 0.7.0 |
| `+` | Addition | |
| `-` | Subtraction| |
| `<<` | Left shift | |
| `>>` | Right shift| |
| `&` | Bitwise AN| |
| `|` | Bitwise OR | |
| `^` | Bitwise XOR | |
| `>=` | Greater or equal | |
| `>` | Greater | |
| `<=` | Lower or equal | |
| `<` | Lower | |
| `!=` | Not equal | |
| `==` | Equal | |
| `&&` | Boolean AND | |
| `||` | Boolean OR | |
## Properties
- Call by value
```rust=
def incr(field a) -> field:
a = a + 1
return a
def main():
field x = 1
field res = incr(x)
assert(x == 1) // x has not changed
return
```
- Constraint inside a calculating block
- circom example
```rust
template Main() {
signal private input a;
signal private input b;
signal input c;
signal input flag;
if (flag == 1) {
c <== a*b
}
}
component main = Main();
```
:::danger
Constraint inside a calculating block
:::
- ZoKrates example
```rust
def main(private field a, private field b, field c, field flag) -> bool:
bool result = if flag == 1 then a*b == c else true fi
return result
```
:::success
Successfully compiled!
:::
## Standard library
- **Hashes**
- blake2
- keccak
- SHA3
- SHA256
- Pedersen
- Poseidon
- MiMC
- **Ellipic Curve**
- EdDSA
- **utils**
- packing/ unpaking
- cast
- multiplexer
## Proving scheme
- Curves
| Curve | CLI flag | Supported by Ethereum |
| ----- | -------- | --------------------- |
| ALT_BN128 | `--curve bn128` | Yes ([EIP-196](https://eips.ethereum.org/EIPS/eip-196), [EIP-197](https://eips.ethereum.org/EIPS/eip-197)) |
| BLS12_381 | `--curve bls12_381` | No ([EIP-2537](https://eips.ethereum.org/EIPS/eip-2537))|
| BLS12_377 | `--curve bls12_377` | No ([EIP-2539](https://eips.ethereum.org/EIPS/eip-2539))|
| BW6_761 | `--curve bw6_761` | No ([EIP-3026](https://eips.ethereum.org/EIPS/eip-3026)) |
- Proving schemes
| Scheme | CLI flag | Curves |
| ---- | -------- | ------ |
| [G16](https://eprint.iacr.org/2016/260) | `--proving-scheme g16` | ALTBN_128, BLS12_381 |
| [GM17](https://eprint.iacr.org/2017/540) | `--proving-scheme gm17` | ALTBN_128, BLS12_377, BW6_761 |
| [PGHR13](https://eprint.iacr.org/2013/279) | `--proving-scheme pghr13` | ALTBN_128 |
- Backends
| Backend | CLI flag | Proving schemes | Curves |
| ---- | -------- | --------------- | ------ |
| Bellman | `--backend bellman` | G16 | ALTBN_128, BLS12_381 |
| Libsnark | `--backend libsnark` | GM17, PGHR13 | ALTBN_128 |
| Ark | `--backend ark` | GM17 | ALTBN_128, BLS12_377, BW6_761 |
- 執行不同的 curve 的 example
```python=
# compile
zokrates compile -i root.zok --curve bls12_381
# check
zokrates check -i root.zok --curve bls12_381
# perform the setup phase
zokrates setup
# execute the program
zokrates compute-witness -a 337 113569
# generate a proof of computation
zokrates generate-proof
# print proof
zokrates print-proof --format remix
# export a solidity verifier
zokrates export-verifier --curve bls12_381 # not supported
# off-chain verification
zokrates verify --curve bls12_381
```
- 執行不同 proving scheme 的 example
```python=
# compile
zokrates compile -i root.zok
# check
zokrates check -i root.zok
# perform the setup phase
zokrates setup -b ark -s gm17
# execute the program
zokrates compute-witness -a 337 113569
# generate a proof of computation
zokrates generate-proof -b ark -s gm17
# print proof
zokrates print-proof --format remix
# export a solidity verifier
zokrates export-verifier -s gm17
# off-chain verification
zokrates verify -b ark -s gm17
```
- 可執行的 curve, proving scheme, backend
| Backend | Curve | Scheme | Note |
| ---- | -------- | ------ |-- |
| Bellman | Bn128 | G16 | |
| Bellman | Bls12_381 | G16 ||
| Ark | Bls12_377 | GM17 ||
| Ark | Bw6_761 | GM17 ||
| Ark | Bn128 | GM17 ||
| Libsnark | Bn128 | GM17 |not supported|
| Libsnark | Bn128 | PGHR13 |not supported|
## `zokrates-js`
- 安裝
```bash=
npm install zokrates-js
```
- index.js
```javascript=
const { initialize } = require('zokrates-js/node');
initialize().then((zokratesProvider) => {
const source = "def main(private field a) -> field: return a * a";
// compilation
const artifacts = zokratesProvider.compile(source);
// computation
const { witness, output } = zokratesProvider.computeWitness(artifacts, ["2"]);
// run setup
const keypair = zokratesProvider.setup(artifacts.program);
// generate proof
const proof = zokratesProvider.generateProof(artifacts.program, witness, keypair.pk);
// console.log(proof)
// export solidity verifier
const verifier = zokratesProvider.exportSolidityVerifier(keypair.vk, "v1");
const result = zokratesProvider.verify(keypair.vk, proof);
console.log(result)
});
```
- 執行
```bash=
node index.js
```
## Examples
- [example codes](https://hackmd.io/Li5cwGn2ToClFvQuaHdOHw)
- [more examples](https://github.com/Zokrates/ZoKrates/tree/develop/zokrates_cli/examples)
- [standard library](https://github.com/Zokrates/ZoKrates/tree/develop/zokrates_stdlib)
## help
```python=
ZoKrates 0.7.0
Jacob Eberhardt, Thibaut Schaeffer, Stefan Deml, Darko Macesic
Supports generation of zkSNARKs from high level language code including Smart Contracts for proof verification on the
Ethereum Blockchain.
'I know that I show nothing!'
USAGE:
zokrates [FLAGS] <SUBCOMMAND>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
--verbose Verbose mode
SUBCOMMANDS:
check Checks a program for errors
compile Compiles into flattened conditions. Produces two files: human-readable '.ztf' file for
debugging and binary file
compute-witness Calculates a witness for a given constraint system
export-verifier Exports a verifier as Solidity smart contract
generate-proof Calculates a proof for a given constraint system and witness
help Prints this message or the help of the given subcommand(s)
print-proof Prints proof in the chosen format
setup Performs a trusted setup for a given constraint system
verify Verifies a given proof with the given verification key
```
### Compile
```python=
zokrates-compile
Compiles into flattened conditions. Produces two files: human-readable '.ztf' file for debugging and binary file
USAGE:
zokrates compile [FLAGS] [OPTIONS] --input <FILE>
FLAGS:
--allow-unconstrained-variables Allow unconstrained variables by inserting dummy constraints
-h, --help Prints help information
-V, --version Prints version information
--verbose Verbose mode
--ztf Write human readable output (ztf)
OPTIONS:
-s, --abi-spec <FILE> Path of the ABI specification [default: abi.json]
-c, --curve <curve> Curve to be used in the compilation [default: bn128] [possible values: bn128,
bls12_381, bls12_377, bw6_761]
-i, --input <FILE> Path of the source code
-o, --output <FILE> Path of the output binary [default: out]
--stdlib-path <PATH> Path to the standard library [env: ZOKRATES_STDLIB=] [default:
/Users/<USER_NAME>/.zokrates/stdlib]
```
### Check
```python=
zokrates-check
Checks a program for errors
USAGE:
zokrates check [FLAGS] [OPTIONS] --input <FILE>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
--verbose Verbose mode
OPTIONS:
-c, --curve <curve> Curve to be used in the compilation [default: bn128] [possible values: bn128,
bls12_381, bls12_377, bw6_761]
-i, --input <FILE> Path of the source code
--stdlib-path <PATH> Path to the standard library [env: ZOKRATES_STDLIB=] [default:
/Users/<USER_NAME>/.zokrates/stdlib]
```
### Setup
```python=
zokrates-setup
Performs a trusted setup for a given constraint system
USAGE:
zokrates setup [FLAGS] [OPTIONS]
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
--verbose Verbose mode
OPTIONS:
-b, --backend <backend> Backend to use [default: bellman] [possible values: bellman, ark]
-i, --input <FILE> Path of the binary [default: out]
-p, --proving-key-path <FILE> Path of the generated proving key file [default: proving.key]
-s, --proving-scheme <proving-scheme> Proving scheme to use in the setup [default: g16] [possible values: g16,
pghr13, gm17]
-v, --verification-key-path <FILE> Path of the generated verification key file [default: verification.key]
```
### Compute witness
```python=
zokrates-compute-witness
Calculates a witness for a given constraint system
USAGE:
zokrates compute-witness [FLAGS] [OPTIONS]
FLAGS:
--abi Use ABI encoding. Arguments are expected as a JSON object as specified at
zokrates.github.io/toolbox/abi.html#abi-input-format
-h, --help Prints help information
--stdin Read arguments from stdin
-V, --version Prints version information
--verbose Verbose mode
OPTIONS:
-s, --abi-spec <FILE> Path of the ABI specification [default: abi.json]
-a, --arguments <arguments>... Arguments for the program's main function, when not using ABI encoding. Expects a
space-separated list of field elements like `-a 1 2 3`
-i, --input <FILE> Path of the binary [default: out]
-o, --output <FILE> Path of the output file [default: witness]
```
### Generate proof
```python=
zokrates-generate-proof
Calculates a proof for a given constraint system and witness
USAGE:
zokrates generate-proof [FLAGS] [OPTIONS]
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
--verbose Verbose mode
OPTIONS:
-b, --backend <backend> Backend to use [default: bellman] [possible values: bellman, ark]
-i, --input <FILE> Path of the binary [default: out]
-j, --proof-path <FILE> Path of the JSON proof file [default: proof.json]
-p, --proving-key-path <FILE> Path of the proving key file [default: proving.key]
-s, --proving-scheme <FILE> Proving scheme to use to generate the proof [default: g16] [possible values: g16,
pghr13, gm17]
-w, --witness <FILE> Path of the witness file [default: witness]
```
### Print proof
```python=
zokrates-print-proof
Prints proof in the chosen format
USAGE:
zokrates print-proof [FLAGS] [OPTIONS] --format <FORMAT>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
--verbose Verbose mode
OPTIONS:
-f, --format <FORMAT> Format in which the proof should be printed [possible values: remix, json]
-j, --proof-path <FILE> Path of the JSON proof file [default: proof.json]
```
### Export verifier
```python=
zokrates-export-verifier
Exports a verifier as Solidity smart contract
USAGE:
zokrates export-verifier [FLAGS] [OPTIONS]
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
--verbose Verbose mode
OPTIONS:
-c, --curve <curve> Curve to be used to export the verifier [default: bn128] [possible values:
bn128, bls12_381, bls12_377, bw6_761]
-i, --input <FILE> Path of the verifier [default: verification.key]
-o, --output <FILE> Path of the output file [default: verifier.sol]
-s, --proving-scheme <FILE> Proving scheme to use to export the verifier [default: g16] [possible values:
g16, pghr13, gm17]
-a, --solidity-abi <solidity-abi> Flag for setting the version of the ABI Encoder used in the contract [default:
v1] [possible values: v1, v2]
```
### Verify
```python=
zokrates-verify
Verifies a given proof with the given verification key
USAGE:
zokrates verify [FLAGS] [OPTIONS]
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
--verbose Verbose mode
OPTIONS:
-b, --backend <backend> Backend to use [default: bellman] [possible values: bellman, ark]
-c, --curve <curve> Curve to be used in the verification [default: bn128] [possible values:
bn128, bls12_381, bls12_377, bw6_761]
-j, --proof-path <FILE> Path of the JSON proof file [default: proof.json]
-s, --proving-scheme <FILE> Proving scheme to use in the setup. Available options are G16 (default),
PGHR13 and GM17 [default: g16]
-v, --verification-key-path <FILE> Path of the generated verification key file [default: verification.key]
```