In this guide we show how to get started with zero-knowledge proofs on Ethereum, using the ZoKrates language and toolset.

Installing is easy provided you’re comfortable with their automated install script (though you may be out of luck for the time being if you’re on Windows):

```
$ curl -LSfs get.zokrat.es | sh
```

If the installation is successful, you should get a suggestion to add ZoKrates to your path:

```
$ export PATH=$PATH:$HOME/.zokrates/bin
$ export ZOKRATES_HOME=$HOME/.zokrates/stdlib
```

If all is fine, you should be good to go. This guide is tested with the following version

```
$ zokrates --version
ZoKrates 0.4.9
```

Let’s write a simple program in ZoKrates that proves knowledge of the result of a (field) division $x/y$. In other words, knowledge of a field element $z$ such that $zy=x$.

```
def main(field x, field y, private field z) -> (field):
field result = if z * y == x then 1 else 0 fi
return result
```

Save this to a file `div.code`

. Compile this with

```
$ zokrates compile -i div.code
```

This generates a file `out.code`

containing the *R1CS* (Rank-1 Constraint System) constraints - or at least, a close variant of this - corresponding to our program. Let’s take a look:

```
def main(_0, _1, _2) -> (1):
(1 * _2) * (1 * _1) == 1 * _5
# _3, _4 = Rust::ConditionEq((-1) * _0 + 1 * _5)
((-1) * _0 + 1 * _5) * (1 * _4) == 1 * _3
(1 * ~one + (-1) * _3) * ((-1) * _0 + 1 * _5) == 0
(1 * ~one + (-1) * _3) * (1 * ~one + (-1) * _3) == 1 * ~one + (-1) * _3
(1 * _3) * (0) == 1 * _13
(1 * ~one) * (1 * ~one + (-1) * _3 + 1 * _13) == 1 * ~out_0
return ~out_0
```

To demystify this a bit, let’s look at the first constraint as an example:

```
(1 * _2) * (1 * _1) == 1 * _5
```

First note that the variables `_0`

, `_1`

and `_2`

correspond to $x$, $y$ and $z$ respectively. Then the constraint corresponds to an equality between $zy$ and another (intermediate) variable `_5`

. When compiling the program, ZoKrates generates all the necessary intermediate variables and constraints.

Next run the setup

```
$ zokrates setup
```

which generates the keys `proving.key`

and `verification.key`

. The prover $P$ will need the former later to generate a proof. For now, we need just the latter to generate a verifier contract

```
$ zokrates export-verifier
```

This creates a Solidity contract `verifier.sol`

that (conveniently) contains the verification key. Now the contract is deployed, and `proving.key`

is given to $P$.

Notice that so far $P$ hasn’t yet played any part, so the contract does not contain any proof data as such at this stage.

Let’s assume the prover $P$ and verifier $V$ agree on the public inputs $x=8$ and $y=2$. Given this, $P$ (equipped with `proving.key`

as mentioned above) computes a witness $z=4$:

```
$ zokrates compute-witness -a 8 2 4
```

This produces `witness`

as follows

```
~out_0 1
~one 1
_0 8
_1 2
_2 4
_3 0
_4 1
_5 8
_13 0
```

Notice that the witness includes not only the values for $x$, $y$ and $z$ but also all the intermediate variables `_3`

, `_4`

, etc. Finally, $P$ can generate a proof with this witness:

```
$ zokrates generate-proof
```

giving us the proof object rendered in `proof.json`

```
{
"proof": {
"a": [
"0x156a5830f50b1682ec4f669e3e74b6ff5c02266f9279bc7c2231c03f4ba110ab",
"0x0154cd9d51436ea60d70b81a5ecd6548b4cb2e849aada2f0accb4ae830043d7a"
],
"b": [
["0x0f5d0a0a45e969e38ee3c0beb744c83f45c33321af837c199278ad480f76acb5",
"0x1486424972757d1ee3b2187780c9999b27fbbc0acaeaee7992bc603a853617cb"],
["0x0cecaa7f1f2448f8595d8a8783ecf27fe81050e7fa72a3f442b96bb57f1d2b2e",
"0x17d5d238c965d5c0266a94e3d9de4efce1f28d1add21b416adce853b1b7d3b97"]
],
"c": [
"0x20d68643704e84a4d2e2cb51b8e6f7c63f293978a66c8c5cca88612cb212a34e",
"0x1e075b9e726ca91cdc8835bfda4ea09c6c5f3d585798e16a90e1fc1cc60ab128"
]
},
"inputs": [
"0x0000000000000000000000000000000000000000000000000000000000000008",
"0x0000000000000000000000000000000000000000000000000000000000000002",
"0x0000000000000000000000000000000000000000000000000000000000000001"
]
}
```

The proof consists of the parameters $(a,b,c)$ making up the zk-SNARK proof (in this case, *G16* scheme - though this can be configured on the ZoKrates CLI). It also contains the public inputs $x,y$ and the return value `~out_0`

(in this case $1$) of our program. Notice that the *private* input $z$ is not included!

In order for $V$ to check this proof, $P$ should now submit the above to the deployed verification contract. In particular, the contract contains a function `verifyTx`

```
function verifyTx(uint[2] memory a,
uint[2][2] memory b,
uint[2] memory c,
uint[3] memory input) public returns (bool r) {
// ...
}
```

that takes as parameters the data contained in `proof.json`

. How does $V$ get notified of this? By monitoring the event `Verified`

also contained in the contract. This event emits when the transaction sent by $P$ has been verified, by which point $V$ will see that this was sent from $P$'s (public) address. When this happens, $V$ can be sure that $P$ knows $z$ such that $zy=x$ without learning anything about $z$.

This completes the rough overview. We’ve covered how to get set up with ZoKrates, as well as the basic workflow. We’ve had to skip a lot of details. The next in this series will cover some of the parts (e.g. the verification contract and the proof object) a bit more closely, and we’ll also show some practical steps for testing out the contract!