Skip to content

Latest commit

 

History

History

example

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

Pact-zk-generator Example

Goal

Create a zk-SNARK smart contract verifying that the prover owns a Secret satisfying the following equation: Hash(Secret * Multiplier) = X, using the Pedersen hash function.

Create the circuit

Create a circuit called pedersen-multiplier.zok

import "hashes/pedersen/512bit" as pedersen_hash;
import "utils/pack/u32/nonStrictUnpack256" as unpacker;
import "utils/pack/u32/pack256" as packer;


def main(private field my_secret, public field multiplier) -> field {
  u32[8] input_unpacked = unpacker(my_secret * multiplier);
  u32[8] zeros = [0; 8];
  u32[16] pedersen_input = [...input_unpacked ,...zeros];
  u32[8] hash = pedersen_hash(pedersen_input);
  return packer(hash);
}

Compile the circuit and generates keys

For this example a basic and unstruted setup is used.

$ zokrates compile -i pedersen-multiplier.zok
$ zokrates setup

You can check that verification.key and abi.json have been generated by ZoKrates. These 2 files will be used to create the Pact verifier contract.

Generate the module/contract

$ pact_zk_gen gen-module --module-name pedersen-mult-verifier --proof-type string

If everything is fine, the file pedersen-mult-verifier.pact has been created.

This file is a valid Pact module. It can be deployed on-chain.

It contrains the following function:

(defun verify:bool (multiplier:integer out:integer proof:string)

This function will be called to verify the proof given by the prover. The 3 parameters are:

  • multiplier: public argument multiplier of the circuit.
  • out: output of the circuit (ie: The hash).
  • proof: proof to verify in a stringified format

Test it locally in REPL

To test the module, we need:

  • the Pact interpreter
  • the toolbox pact-util-lib

First run the circuit, and generate a proof. For this example, we choose Secret=123456789 and Multiplier of 26.

$ zokrates compute-witness -a 123456789 26
$ zokrates generate-proof

A proof.json file should have been generated by ZoKrates. It contains our inputs and the zk-SNARK proof.

Now let's create a REPL example:

$ pact_zk_gen gen-test

If the tool complains of not finding the pact-util-lib directory, you can help it by adding the --util-lib-dir parameter.

If everything is fine, the file pedersen-mult-verifier.repl has been created.

We can check that it contains a call to our verification module:

  (pedersen-mult-verifier.verify 26 2933680909359551385860926297411111605298109531248341983485101731930035552281 "DK0Y2C3h7tI720JHVcyzl1xTU336qrzMXroq9tH9IOECow7sahTOZx-Xgr90-OinVBD3Wx1hdxgAIksC4cWVxQHu0_n0VuDI-C7OWJ4haDWB4T7vHLiR2ViLnAdUlrhyMCjUkKRDPq0VpZFkQj_QzSn937w_A7e2A3h-Gi5uP31cFPxcCFxpP-62f35TPARfR-cupre-E3hcWIbR1E24KAkDjQU74p_WwTYquUHZewunmLqquf3MAj2oGrWdsptveQL6snKuJk5vUYhlfGvkeSo7TPdRJ_SKXmFU31T7folEQEQxJgCjowIOqpl3DsIsyl7kdpVd_n0LnZOI6prDX0V8")
  • 1st parameter: 293368.... is the hash.
  • 2nd parameter 26is the output multiplier.
  • 3rd parameter: "DK0Y2C3h7tI72... is the zk-SNARK proof

Run the test:

$ pact pedersen-mult-verifier.repl
Proof verification result: true
Load successful

Well done, we've just proven to the smart contract that we know the secret satisfying the equation.