Skip to content

Latest commit

 

History

History
75 lines (43 loc) · 4 KB

README.md

File metadata and controls

75 lines (43 loc) · 4 KB

This is a simple example showing case how to use the chainark library.

Understanding the data and the chain structure

Suppose we have a chain structure:

data0 <- data1 <- data2 <- data3

Following the rule:

$id_{n+1}$ = SHA256($id_n$ || "chainark example")

Each data is simply composed by below two elements concatenated together hash || string_literal, where:

  1. hash is hash value of 32 bytes, which is the SHA256 hash of its predecessor data;
  2. string literal is chainark example.

Now the LinkageID is the hash value. In the supplied data file, the first hash is generated by running this command:

echo 0000000000000000000000000000000000000000000000000000000000000000 | xxd -r -p | openssl sha256 -hex

It outputs hash value 66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925.

Then data0, or the first line of the data file is simply

66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925636861696e61726b206578616d706c65

with 636861696e61726b206578616d706c65 as the hex encode of chainark example.

Going forward we may have the ID corresponding to data0 from running the command:

echo 66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925636861696e61726b206578616d706c65 | xxd -r -p | openssl sha256 -hex

and its value is 843d12c93f9079e0d63a6101c31ac8a7eda3b78d6c4ea5b63fef0bf3eb91aa85. This is then the genesis ID or id0. Usually a genesis ID is publically known and recognized.

Now data1 becomes 843d12c93f9079e0d63a6101c31ac8a7eda3b78d6c4ea5b63fef0bf3eb91aa85636861696e61726b206578616d706c65, and we can compute id1, and so on.

The proving task

Now we want to prove that following the above hashing computation rule, a hash value of ad057c8b077361d9f5673d5faa0bf4f6c5013bb5fb745339042329976637a705 could be computed starting from the data identified by the genesis ID of 843d12c93f9079e0d63a6101c31ac8a7eda3b78d6c4ea5b63fef0bf3eb91aa85.

To do this, we first need to generate the unit proofs, that is, we need a ZK-proof from a data item (hash || "chainark example") to an ID (hash) for all the IDs from genesis to the one under question. UnitCircuit is implemented in the [unit/core/circuit.go]. For demonstration, 4 types unit circuits are defined, each handle 8/4/2/1 hash iteration. Besides unit circuit definition, a main function in unit/unit.go is defined to generate the unit proofs.

Then we also need to create main functions to output the genesis and recursive proofs. The genesis circuit verifies the first unit proof, building the initial chain structure starting from the chosen genesis ID. The recursive circuit verifies first a genesis proof or a recursive proof, then a unit proof. The proof generated from the recursive circuit could be used to verify the existence of a chain from the genesis ID to the one under question.

Under the hook

Please refer to the general doc.

Running the example

generate verification keys

Note that the fingerprints of all verification keys have been hardcoded in the example codes. Usually you don't need to worry about it. But if you have modified some of the circuits, or if you are planning to build your own application based on this example, here are general procedures to follow:

  1. Go to the unit folder, build the application, run ./unit --setup to generate proving key and verification key for the unit circuit;
  2. Go to the recursive folder, build the application, run ./recursive --setup to generate proving key and verification key for the recursive circuit;

Or just

sh setup.sh

compute the proofs

Now setup is complete. Run below commands to compute the proof:

  1. Go to the unit folder, run ./unit_prove.sh;
  2. Go to the recursive folder, run ./recursive_prove.sh.

Now you have exactly one proof for each and every id: the genesis id is recognized, its successor is proved with a unit proof, and the rest with a corresponding recursive proof.

compute proofs all at once

sh run.sh