# ZoKrates$ZoKrates$$ZoKrates$: Getting Started

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

## Setup

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 ## ZoKrates program Let’s write a simple program in ZoKrates that proves knowledge of the result of a (field) division $x/y$$x/y$. In other words, knowledge of a field element $z$$z$ such that $zy=x$$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$$x$, $y$$y$ and $z$$z$ respectively. Then the constraint corresponds to an equality between $zy$$zy$ and another (intermediate) variable _5. When compiling the program, ZoKrates generates all the necessary intermediate variables and constraints.

## Verification contract

Next run the setup

$zokrates setup which generates the keys proving.key and verification.key. The prover $P$$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$$P$.

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

## Proof submission

Let’s assume the prover $P$$P$ and verifier $V$$V$ agree on the public inputs $x=8$$x=8$ and $y=2$$y=2$. Given this, $P$$P$ (equipped with proving.key as mentioned above) computes a witness $z=4$$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$$x$, $y$$y$ and $z$$z$ but also all the intermediate variables _3, _4, etc. Finally, $P$$P$ can generate a proof with this witness:$ zokrates generate-proof

giving us the proof object rendered in proof.json

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

The proof consists of the parameters $\left(a,b,c\right)$$(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$$x,y$ and the return value ~out_0 (in this case $1$$1$) of our program. Notice that the private input $z$$z$ is not included!

In order for $V$$V$ to check this proof, $P$$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$$V$ get notified of this? By monitoring the event Verified also contained in the contract. This event emits when the transaction sent by $P$$P$ has been verified, by which point $V$$V$ will see that this was sent from $P$$P$'s (public) address. When this happens, $V$$V$ can be sure that $P$$P$ knows $z$$z$ such that $zy=x$$zy=x$ without learning anything about $z$$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!