DEV Community

Cover image for Niftyzk tutorials 1
Peter Horvath
Peter Horvath

Posted on

Niftyzk tutorials 1

This is the start of the tutorial series on Niftyzk and will go over installation and the basic commands as of NiftyZK 0.1.4

https://github.com/NiftyZk/niftyzk

Niftyzk is a scaffolding tool and circom development framework with first class support for CosmWasm.

Installation
You can find the documentation on the github repository. The project depends on Circom to be installed which depends on Rust. You also need NPM to install niftyzk the CLI.For the circom installation instructions, visit :

https://docs.circom.io/getting-started/installation

To install niftyzk, install it straight from github

npm install -g git+https://github.com/NiftyZk/niftyzk.git

This will install it and the niftyzk command will be available from the command line.

Run niftyzk --version to verify the installation, it should output:

$ niftyzk --version

0.1.4
Enter fullscreen mode Exit fullscreen mode

The help page should show the following:

Usage: niftyzk [options] [command]

Scaffold a new Circom project and circuits, compile it and run Powers of Tau
Phase-2 ceremonies. Generate a cosmwasm verifier contract. Supports Groth-16
with a BN128 curve

Options:
  -V, --version          output the version number
  -h, --help             display help for command

Commands:
  init                   Initialize and scaffold a new project
  ptaufiles [options]    Display information and download ptau files
  gencircuit             Generate circom circuits and javascript tests for the current directory
  dev [options]          Hot reload for circuit development. input.js must
                         contain a valid circuit input
  compile [options]      Compile the circuits
  ceremony               Runs a phase 2 ceremony server that accepts anonymized contributions via a website. Default port is 3000.
                         Prefix the command with PORT=number to change the
                         default port
  finalize [options]     Finalize the circuit after the phase2 ceremony is
                         finished
  vkey [options]         Generate the verification key for this circuit
  gencontract [options]  Generate a cosmwasm verifier smart contract
  help [command]         display help for command
Enter fullscreen mode Exit fullscreen mode

niftyzk init [folder]

To start a new project, you need to initialize a directory and select the scaffolded project. The init command will either work in the current directory or create a new directory depending if the folder name was specified. The command will enter the scaffolding menu that allows to to configure the generated code

Creating a new directory with name myproject
? What project do you want to scaffold? (Use arrow keys)
❯ Commit-Reveal Scheme
  Commit-Reveal Scheme with Fixed Merkle Tree
  EdDSA signature verification
  EdDSA signature verification with Fixed Merkle Tree
Enter fullscreen mode Exit fullscreen mode

As of 0.1.4 , the following schemes are available to generate. You should use these are templates and roll your own implementation using them.

A commit-reveal scheme allows proving the knowledge of a secret without revealing it. The commitments are implemented using hashing, the scheme allows a proof to be constructed that verifies the knowledge of a hash pre-image without revealing it. This scheme can serve as a basis for account abstraction or games.

A commit-reveal scheme with a fixed merkle tree adds merkle proofs to the commit-reveal scheme and allows the verification that a commitment is contained in the merkle root. The scaffolded project resembles a well known project tornado cash, which uses a similar scheme however caution is advised if in replicating that exact functionality. The scheme is a great starting point for account abstraction, identity verification, privacy and scaling solutions.

The EdDSA signature verification scheme allows for verification of an Edwards digital signature inside the circom circuit, these digital signatures are not supported by blockchains by default but can be efficiently used inside zero-knowledge circuits.The signature verification scheme is a great stating point for account abstraction, voting systems identity verification and rollups.

The EdDSA signature verification comes with an optional merkle tree implementation that allows verification that the public key of a signer is found in the merkle tree. The merkle tree effectively contains the signers that are allowed to pass verification.

? Choose the hashing algorithm to use:  (Use arrow keys)
❯ mimc7
  mimcsponge
  pedersen
  poseidon
Enter fullscreen mode Exit fullscreen mode

The next step is to select the hash algorithm to use with your scheme. This choice is important because each hashing function targets a little different use-caseMiMC7 and MiMCSponge are very effective hashing algorithms developed for verification schemes, however they require an extra key parameter to work. The key is an added secret that should not be revealed and so these work best when used with centralized proving system that doesn’t allow individual users to access the secret variables and computes proofs on their behalf, for example to delegate rights.

Poseidon hash is the most flexible which and simple to implement that doesn’t require a secret key, unlike MiMC implementations. This is a great hashing algorithm if you want decentralized proof compute that runs in the browser.

Pedersen hashing is used to implement Pedersen commitments which are homomorphic. It’s implementation is a bit more advanced and requires working with bits instead of passing bigint values directly like the other hashing algorithms.It is recommended to use Poseidon over Pedersen however it depends on your use-case.

? Do you wish to add tamperproof public inputs? (E.g: walletaddress):  (y/N)

Enter fullscreen mode Exit fullscreen mode

If you select a commit-reveal scheme you will be asked to add tamper proof inputs, you need to type them in a comma separated list. The tamper proof inputs use hidden signals inside the circuit for tamper resistance.When a zero-knowledge proof is computed it contains public inputs which need to be revealed on a blockchain for verification. If some of the inputs are arbitrary and doesn’t partake in the commit-reveal scheme, then an adversary is able to manipulate them.Making public signals tamper proof is essential for security.

? Do you wish to add public inputs to sign? (E.g: address,amount) (y/N)

Enter fullscreen mode Exit fullscreen mode

If you selected EdDSA, you will be asked to add inputs to sign. The purpose is similar to making them tamper proof, however they will be part of the signed message itself. EdDSA signatures always sign hashes, so you can add as many inputs as you like.

When you have completed the scaffolding process you need to npm install the dependencies and ready to start iterating on your circuit.

The contents of the scaffolded projects will be explained in another tutorial, for now we move on to the other commands.

niftyzk dev

Usage: niftyzk dev [options]

Hot reload for circuit development. input.js must contain a valid circuit input

Options:
  --circuit [path]  The circuit to test. Defaults to circuits/circuit.circom
  --assertout       Asserts the output of the circuit. The output must be exported from a getOutput() function
                    from input.js
  --verbose         Show extra information for debugging
  -h, --help        display help for command
Enter fullscreen mode Exit fullscreen mode

This command is used to start the hot reload development environment.The circuits will be compiled and executed with an input. The inputs are defined in /test/input.js file, which must export a getInput() function that will be called by the hot reload. The output of the circuit can be asserted by passing the --assertout flag. The output must be implemented in the getOutput() function in the input.js file. This allows you to iterate compile and test the circuit as you develop it.You can use log(); inside your circuits for debugging. If you run it with the optional --verbose flag, more debugging information will be available.

niftyzk ptaufiles

Usage: niftyzk ptaufiles [options]

Display information and download ptau files

Options:
  -f, --filename [filename]  The file to download
  -h, --help                 display help for command

Enter fullscreen mode Exit fullscreen mode

To compile circuits you will need files created with a powers of tau ceremony. You can opt to create your own files but that’s an insecure solution. The Phase 1 of powers of tau creates reusable files, so we can use them from the Polygon Hermez ceremony. The built in download will get the files for you and place them where the compiler expects them to be. The files get quite large and not all work with the ceremony server. If your circuits are large you need to use big ptaufiles to compile them.

For automated systems, if you know the filename you can pass it as an argument, if not a dropdown menu will appear for you to manually select it.

Example file to select

powersOfTau28_hez_final_15.ptau
blake2b hash: 982372c867d229c236091f767e703253249a9b432c1710b4f326306bfa2428a17b06240359606cfe4d580b10a5a1f63fbed499527069c18ae17060472969ae6e
Power: 15, Max Constraints: 32K
Size: 36.08 MiB
Supports built in ceremony server: YES
Enter fullscreen mode Exit fullscreen mode

niftyzk compile

Usage: niftyzk compile [options]

Compile the circuits

Options:
  --circuit [path]  Specify the location for the circuit. Defaults to circuits/circuit.circom
  -h, --help        display help for command

Enter fullscreen mode Exit fullscreen mode

This command invokes the circom compiler which depends on Rust. It must be installed beforehand to proceed with the compilation.The current circuits will be compiled and the output will be in the circuits/compiled directory. You should commit this file to git because it contains the compilation results, recompiling will always yield a different circuit and verification parameters so you should keep this to continue. If you alter the circuit you need o recompile each time.

niftyzk ceremony

Usage: niftyzk ceremony [options]

Runs a phase 2 ceremony server that accepts anonymized contributions via a website. Default port is 3000. Prefix
the command with PORT=number to change the default port

Options:
  -h, --help  display help for command
Enter fullscreen mode Exit fullscreen mode

There will be a dedicated tutorial to explain how to deploy a ceremony server, for now all you need to know is that to secure groth-16 proving circuits the Powers of tau ceremony needs to be repeated, it has a circuit specific phase. The compilation outputs a zkey files into the compiled directory which can be contributed to. The contribution creates a new zkey from the previous one, they are stored indexed. The contribution takes place in the browser and niftyzk contains a webserver. The contributions are anonymous and as long as a single participant remains honest the ceremony is secure.

niftyzk vkey

Usage: niftyzk vkey [options]

Generate the verification key for this circuit

Options:
  --final     Export the final verification key after the phase2 ceremony
  -h, --help  display help for command

Enter fullscreen mode Exit fullscreen mode

You need to export a verification key to run tests, compute proofs or generate a cosmwasm contract. The vkey can be created before or after the ceremony, the final key must be exported after the finalize

niftyzk finalize

Usage: niftyzk finalize [options]

Finalize the circuit after the phase2 ceremony is finished

Options:
  -b, --beacon [string]  A random beacon to use for finalizing the ceremony. For example a block hash or a hex number outputted by a Verifiable Delay Function (VDF)
  -i, --iter [num]       Number of iterations
  -n, --name [string]    The name of the final contribution
  -h, --help             display help for command
Enter fullscreen mode Exit fullscreen mode

The finalize command requires a random beacon to finalize the circuit. This should be ran after the ceremony is finished and all the contributions are done. The beacon is a hex number that should be outputted by a Verifiable Delay Function, often a block hash is used. You need to export a new vkey after the finalization to continue.

niftyzk gencontract

After you acquired the verification key you can generate the contract. The circuits don’t need to be finalized for this, however your verification will be vulnerable without a ceremony and finalization.

Usage: niftyzk gencontract [options]

Generate a cosmwasm verifier smart contract

Options:
  --circuit        The full name of the circuit file to use. Defaults to circuit.circom
  --ark            Use the Arkworks Groth-16 verifier implementation
  --bellman        Use the Bellman Groth-16 verifier implementation
  --overwrite      If a contract directory already exists, you are required use this option to overwrite it.
  --folder [name]  Specify the name of the generated contract's folder
  -h, --help       display help for command

Enter fullscreen mode Exit fullscreen mode

The available libraries to use for the Rust verifier are Arkworks or Bellman. You can find both on crates.io.
You need to specify the folder name and if the folder exists already explicitly overwrite it.

Checking the generated contracts:
Install the wasm rust compiler backend: rustup target add wasm32-unknown-unknown

Run cargo test to run the generated tests

Build the contracts using cargo wasm

Verify the contract.wasm using the cosmwasm-check utility cargo install cosmwasm-check

cosmwasm-check ./target/wasm32-unknown-unknown/release/contract.wasm

And you are done, you created a verifier for a cosmwasm contract from your circuit

*The development pipeline could be drawn with the graph as :
*

Niftyk development flow visualized

I hope you like niftyzk, in the next tutorials I will explain more about the generated code, showcase the merkle tree utils and deploy a ceremony server on a VPS.

Top comments (0)