<aside> ❗ Note: This project is in beta! If you find a bug or have a feature request, please open an issue here: https://github.com/SarahMAmann/zkWeb/issues or join our team as a contributor ✨

</aside>

zkWeb Docs

Introduction

Welcome to zkWeb, your gateway to the fascinating world of Zero-Knowledge Proofs (ZKPs). In these docs we will introduce you to this innovative web app that harnesses the cryptographic power of ZKPs to secure your secrets without ever revealing them, and bring zero-knowledge proofs to the web - for everyone!

What Are Zero-Knowledge Proofs?

Zero-Knowledge Proofs are cryptographic techniques that enable one party, the prover, to demonstrate knowledge of a specific piece of information to another party, the verifier, without revealing the actual information itself. Think of it as a magic act, where the magician reveals a trick without disclosing the secret behind it 🪄 You can read more about ZKPs here: https://ethereum.org/zero-knowledge-proofs

Why Are ZKPs Important?

ZKPs hold the potential to revolutionize digital privacy and security in an increasingly interconnected world. They allow us to verify facts, authenticate identities, and ensure data integrity without exposing sensitive details. Imagine a future where you can prove ownership of your data, authenticate your identity, or confirm transactions without ever divulging your private information!

How Does zkWeb Work?

With zkWeb, you can take on the role of either the verifier or the prover. As the verifier, you define a key (which can be a simple phrase, a specific date, or even an image file). zkWeb then generates a zero-knowledge proof based on this key. Anyone can then submit a key to this proof, and zkWeb will check that key against the verifier’s proof. If the exact correct key has been provided, it will be validated as a match, proving that they possess the secret key without disclosing it to anyone, not even the verifier (creator of the original proof).

zkWeb Features:

Try It Out

Check out the example proof here and enter the key Super secret key! in the Message box to get a valid match. Then try changing one character or space in the key and submitting again and see what happens!

Generate Your First Proof (Verifier)

Follow these simple steps to create your first proof:

  1. Visit zk-web.xyz/verifier.
  2. Give your proof a name that makes it easy to identify and search for later.
  3. Pay attention to the Secret Key input requirements! Your secret key can be anything you want, as long as:
  4. Keep in mind that all proofs generated using zkWeb are public, and anyone can submit a key for validation. Your key itself is not stored anywhere - only the cryptographic proof it generates.
  5. After successfully generating the proof, you'll be presented with the Prover URL. You can either save this link or easily find it by searching for the proof name on the home page.

Prove You Know The Secret Key (Prover)

To prove you have someone’s secret key:

  1. Start by visiting zkWeb's home page and utilize the search bar to search for the name of the specific proof you want to submit a key to (zk-web.xyz/prover/[your-proof-id])
  2. Enter the secret key associated with the proof you've selected.
  3. If your entered key matches the verifier's secret key precisely, both you and the verifier will receive an email notification. This notification will confirm that a correct key, linked to the email address you provide, has been successfully submitted to the proof. Note that if there is even one character difference in the keys, there will mot be a match! If the key you provide is not correct, you will simply be presented with a modal that your key incorrect and you can try again.

Can’t Find A Proof You Generated?

Just generate a new one….because it’s so easy to do with zkWeb! 😉

API

Once you’ve generated a proof using the zkWeb UI, anyone can call the prove API endpoint with their secret key in the request body to validate it against that proof. You will need your proof ID to do this (the proof ID is displayed right after you generate the proof, and can always be found in the URL path of your proof in the app).

The base URL for the endpoint is https://www.zk-web.xyz/api/prove.

Example POST request body:

{
    "id": "",
    "dataType": "",
    "inputData": "",
    "email": ""
}

"dataType" takes one of the following values depending on your secret key:

"textData"
"dateData"
"fileData"

"inputData" is your secret key string value. This could be a paragraph of text, a date in milliseconds, or the baseURL of an image file that matches one of the supported file formats listed above.

"email" is the email address where you would like to receive a confirmation when you submit a correct key to the proof.

The endpoint returns true or false.

Size limits

zkWeb limits the size of certain parameters. "fileData" key input input cannot exceed 50000 bytes. "textData" key input has not been tested on text longer than 54,000 characters.

Technical Implementation

zokrates.js

The core functionality of zkWeb is built using zokrates.js.

ZoKrates is a toolbox for zkSNARKs on Ethereum. It helps you create off-chain programs and link them to the Ethereum blockchain. zokrates.js is the JavaScript bindings for this tool.

https://zokrates.github.io/introduction.html

Proof Generation, Computation, and Verification

Key Input

When a verifier first submits a key to generate a new proof, the key is sent to the API as a string. If it’s a text paragraph, the whole paragraph is sent as a string. If it’s an image, the baseURL is taken.

A unique cryptographic hex hash is then generated from the string. The more digits that can be used the more collision proof the hashing is, but right now 14 digits is the longest string of numbers zokrates.js can accommodate for compilation in this program. So the input string is sha256 hashed and then a 14-digit substring is taken from the hash.

Proof Generation

Zokrates.js is then initialized with the following simple Solidity code designed to return true or false for matching input:

import "hashes/sha256/512bitPacked" as sha256packed; def main(private field a, private field b, private field c, private field d) -> field[2] { field[2] mut h = sha256packed([a, b, c, d]); return h; }

The hashed input value is then passed into the Zokrates.js computeWitness method along with the compiled solidity code to compute a witness which can be used to generate a proof.

This compilation output includes an array of two 128-bit integers that represent the input. Because these numbers are too large for JavaScript 🫠, they are each broken into four separate segments. Those segments are passed into the Solidity code which is then recompiled, so that the Solidity program will only return true for that specific input.

From this, zokrates generates a verification keypair, which is stored in the zkWeb Supabase database along with the proof.

Proving The Key

When a prover submits a key, the same process is followed - the input is hashed into a 14-digit hex string and passed into Zokrates.js to generate a proof from it.

Then the verifier’s proof that the prover is looking to match is selected from the database (along with it’s verification keypair), and that verifier proof’s inputs array is replaced with the inputs array from the new proof that was just computed for the prover’s key. This verifier proof with the replaced inputs array is then passed into the zokrates.js verify method along with the verification key from the original verifier proof. Zokrates.js will return a response of true if the provided key input matches the key that was used to create the verifier proof, and false if it does not.

Roadmap

Contribute

If you would like to become a zkWeb contributor, please reach out to [email protected] and introduce yourself and tell us why you want to help out!

Codebase: https://github.com/SarahMAmann/zkWeb Open Tickets: https://github.com/users/SarahMAmann/projects/1

Contact

For all questions, comments and other feedback, say hey at

[email protected] 🚀