Date:

Niftyzk Tutorial 2: Commit-Reveal Scheme

Scaffolding a Commit-Reveal Scheme with Niftyzk

Introduction

This tutorial will contain information about the generated code. This is the continuation of the previous tutorial, Niftyzk Tutorial 1. You should read that one first.

Scaffolding a New Project

Let’s scaffold a new project using niftyzk init. We will select a commit-reveal scheme with Poseidon hash and add 2 inputs for tamper-proofing, address and amount.

niftyzk init

Setting up your current directory
? What project do you want to scaffold? Commit-Reveal Scheme
? Choose the hashing algorithm to use: Poseidon
? Do you wish to add tamperproof public inputs? (E.g: walletaddress): yes
? Enter the name of the public inputs in a comma separated list (no numbers or special characters): address,amount
Generating circuits
Generating javascript
Done
Run npm install in your project folder

The Circuits Directory

Navigate to the /circuits/ directory to see the generated code. It should contain 2 files, circuits.circom which is the entry point and commitment_hasher.circom which contains the hashing implementation.

circuits.circom

pragma circom 2.0.0;
include "./commitment_hasher.circom";

template CommitmentRevealScheme(){
    // Public inputs
    signal input nullifierHash;
    signal input commitmentHash;
    signal input address;
    signal input amount;

    // Private inputs
    signal input nullifier;
    signal input secret;

    // Hidden signals to validate inputs so they can't be tampared with
    signal addressSquare;
    signal amountSquare;

    component commitmentHasher = CommitmentHasher();

    commitmentHasher.nullifier <== nullifier;
    commitmentHasher.secret <== secret;

    // Check if the nullifierHash and commitment are valid
    commitmentHasher.nullifierHash === nullifierHash;
    commitmentHasher.commitment === commitmentHash;

    // An extra operation with the public signal to avoid tampering
    addressSquare <== address * address;
    amountSquare <== amount * amount;

}

component main {public [nullifierHash,commitmentHash,address,amount]} = CommitmentRevealScheme();

JavaScript Code

First, we look at the library that was scaffolded and then the tests.

The project depends on ffjavascript, snarkjs, circomlib, circomlibjs, and circom_tester.

lib/index.js contains the source code for the client-side code.

First, you will see the functions for generating circuit inputs:

// new public and private inputs and new templates.
// So first we have the merkle tree root as a new public input and pathElements and pathIndices,
// these contain the merkle proof. The levels variable specifies the size of the merkle tree,
// the default 20 will give a lot of branches to work with.

template MerkleTreeChecker(levels) {
    signal input leaf;
    signal input root;
    signal input pathElements[levels];
    signal input pathIndices[levels];

    component selectors[levels];
    component hashers[levels];

    signal levelHashes[levels];

    levelHashes[0] <== leaf;

    for (var i = 1; i < levels; i++) {
        selectors[i] = DualMux();
        hashers[i] = HashLeftRight();

        selectors[i].in[1] <== levelHashes[i - 1];
        selectors[i].in[0] <== pathElements[i];
        selectors[i].s <== pathIndices[i];

        hashers[i].left <== selectors[i].out[0];
        hashers[i].right <== selectors[i].out[1];

        levelHashes[i] <== hashers[i].hash;
    }

    root === levelHashes[levels - 1];
}

Merkle Tree Commands

The project gives you a few commands to work with from the CLI to interact with merkle trees manually. There are many use-cases, for example if you want to manage a tree for withdrawing airdrops, you might just manipulate it manually.

lib/run.js contains the commands:

  • new: creates a new merkle tree with a similar output.
  • proof: asks you for a root hash and a commitment to verify. It will split out a JSON which contains the merkle proof.
  • verify: asks you for the merkle root and the proof and verifies the proof.

Conclusion

I hope this saves you a lot of time developing your circuits.

FAQs

Q: What is a commit-reveal scheme?
A: A commit-reveal scheme is a way to prove possession of a secret without revealing the secret itself.

Q: What is Poseidon hash?
A: Poseidon hash is a cryptographic hash function used in this tutorial.

Q: What are the public inputs in the circuit?
A: The public inputs in the circuit are nullifierHash, commitmentHash, address, and amount.

Q: What are the private inputs in the circuit?
A: The private inputs in the circuit are nullifier and secret.

Latest stories

Read More

LEAVE A REPLY

Please enter your comment!
Please enter your name here