David Richard Holtz

@david.richard.holtz

Zero Knowledge Proof Application Demo

February 17th 2019

ZKP’s are a promising rapidly developing technology and are soon going to be a critical part of many of our security protocols.

In this article we are going to get hands on with libsnarks, truffle and docker.

Before we do anything — let’s make sure we have all the required programs we’ll need to run our app. If you have issues running the below block — please install the missing dep before following along.

docker -v # Docker version 18.09.1, build 4c52b90
git --version # git version 2.17.2 (Apple Git-113)
node -v # v10.15.0
truffle version # Truffle v5.0.4 (core: 5.0.4)
python3 --version # Python 3.7.2

Also for debugging purposes we will deploy the code to a locally running blockchain: Please download Ganache as well

Now we just need to finish up by installing the python packages needed to run our app. The application is just some wrapped up calls to ZoKrates and the Blockchain.

pip3 install docker flask web3

Setup ZKP CLI app

First we need to get the some repos.

git clone https://github.com/Zokrates/ZoKrates.git
cd ZoKrates
mkdir code
docker build -t zokrates_tutorial .

We now have the ZoKrates docker container build — this is a high level library that allows us to interact with libsnark via simple command line commands.

If you’d like, you can access the ZoKrates binary by starting an interactive session with the docker container

*optional*

docker run -v $PWD/code:/home/zokrates/ZoKrates/target/debug/code -ti zokrates_tutorial /bin/bash

Awesome — if you want to learn about ZoKrates before we move on check out their docs here — https://zokrates.github.io/

We’ll get back to this container shortly, next we need to setup our Blockchain environment and get some ZKP application code.

Starting the chain

In order for us to create an environment suited for a public ledger of truth, where we can use a smart contract to execute the verifications, and commit our verification results to the network we need to connect to a blockchain.

Since we don’t want to spend any money for this POC, we’ll just use Ganache to start a tiny ETH network locally. This way we can restart the chain as needed and use the Ganache GUI to explore our tx’s.

Ganache after some Tx’s

Take a moment to appreciate

We’ve made it this far, and we now have locally running network and docker container ready to compile ZKP proofs into smart contracts.

Here would be a good starting point for anyone who wants to deploy custom ZKP verification smart contracts for their use case. However please follow along for a simple example on how to create a simple ZKP auth system.

Meeting out application

git clone https://github.com/drbh/zksnark-app-demo.git
cd zksnark-app-demo/

In this repo we have a few files that we’ll use for out application

inside of code/ we have two folders preimage and get_hashes which represent two different libsnark circuits. These are basically programs written in a special form, that snarks can create proofs for.

Along with the demo code, i’ve left an example verification.key and proving.key and other artifacts from running the setup. These are for convenience and you should not use these keys aside from following this demo.

REPEAT — DO NOT USE THESE KEYS FOR ANY PRODUCTION SYSTEM. GENERATE YOUR OWN KEYS!

However for the ease of running this demo — i’ve provided these keys so the matching Smart Contract contains the keys needed to run the demo out of the box.

import "hashes/sha256/512bitPacked.code" as sha256packed
def main(private field a, private field b, private field c, private field d, field h0Pub, field h1Pub) -> (field[2]):
h = sha256packed([a, b, c, d])
h[0] == h0Pub
h[1] == h1Pub
return h

inside of contracts we have Verifier.sol which is a precompiled version of our code above — just compiled into a smart contract written in solidity. This file has the verification.key embedded into the contract.

Starting the App

Getting the app running is simple,

Make sure we have a fresh start of Ganache running and no Tx’s have been committed. Just click restart in settings in the top right if you need a fresh chain.

Fresh start of Ganache

Next we’ll start the server

python3 app.py
Server started

Deploy Smart Contract

Great! let’s test out server. We can open up any REST client like Postman or Insomnia.

Request to compile and migrate

This request will take a few seconds ~5 or so, and you should see the console print the truffle deployment logs. below

Truffle logs

Also looking at the Ganache console, we can see 4 transactions — which were generated by the truffle migrate command, called with out deploy request.

Yay, we’ve deployed the verifier to chain

Compute Witness — Generate Hashes

Now we can test our abilities to create a hash from a preimage — the exact data we will be proving in our proof.

curl --request POST \
--url http://127.0.0.1:5000/witness \
--header 'content-type: application/json' \
--data '{
"input": "123"
}'

…or in a more visually pleasing format below

Compute a witness — get hash

Cool, we get a witness data back — the info we are interested in are our original input, and the returned digest.

Generate Proof from Witness

Now using the data from our witness, we can build a proof! We’ll pass the server all the information needed to rebuild the witness and generate a proof for that witness. We get back a proof in JSON form.

Build a proof from the hash and preimage

The proof we’ve created is a secret and as “valuable” as the preimage itself. Essentially knowing this proof, and knowing the original secret are equivalent ways to convince a 3rd party that you know the secret.

Verify Proof with Smart Contract off-chain

Now that we have a proof, let’s use it. We can make a call to the smart contract code, and run this off of chain on the local machine. This way we don’t have to make any commit to chain but we can trust that we are running the proof against trusted source code.

off-chain contract call

Verify Proof with Smart Contract on-chain!

In order to make this assertion of proof public and immutable, we need to make a transaction to the chain by running the smart contract on chain with the proof as the input.

on-chain contract transaction!

We can see in raw logs and transaction logs have received a new transaction.

The log indicates a new Tx hash hash been added to the chain at 0x9e08f4656e529da61fc45de7cb77668709604fe82f66de12989aee79fe1112db and we can now prove to all nodes in the chain that we know the pre image to the hash 0x5a00b6425adf76d719eeafd1c522be1a4b0267620e08c32fa79aec4a8a684481 which we know (since it was the example in the demo) is 123.

Added new Tx to chain as output of Smart Contract

Reflection

So we’ve gone full circle with ZKPs. We’ve created a witness, a proof, and then verified that on chain. A third party observer can trust that I know the pre image to a hash as long as they trust the initial setup and the legitimacy of the chain.

There are many use cases where knowing the truth without revealing the truth is important. These tools are making applications and processes like this possible.

Check out Ganache, and ZoKrates for more information. Also checkout Bellman ( a newer library for ZKSNARKS ). Maybe Snarks isn’t the best solution for your usecase and antother protocol like Bulletproofs, or Starks better fits your needs. There are alot of development out there for ZKPs and are rapidly changing so if your interested in ZKP’s, your journey has just begun.

For a list of resources check out another article I wrote: https://medium.com/@david.richard.holtz/zkps-for-dummies-7242e7fcaad4

Thanks for getting through this adventure with me. Please show support and 👏 (clap) for this article.
Remember you can clap up to 50 times, and clapping for this article would be really helpful in the Medium algorithm.
Any support is greatly appreciated ❤️
Also, please answer the questions and add to the discussion below

More by David Richard Holtz

More Related Stories