
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 : h...

NiftyZK - Sparse Merkle Trees
The new version of NiftyZK is available, v0.2.0, which contains a long awaited feature, sparse merkle trees (SMT)$ niftyzk --version 0.2.0 The previous implementation of Merkle Trees in NiftyZk were fixed merkle trees which can be used with commit-reveals and EdDSA schemes. The fixed trees allow for inclusion proofs and are always fully populated and never contain zeroes in the leaves. The fixed tree must be computed and updated off-chain and the updated root is created with arbitrary verific...

Niftyzk tutorial 2, The Commit-reveal scheme
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. So 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 y...
zkp development

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 : h...

NiftyZK - Sparse Merkle Trees
The new version of NiftyZK is available, v0.2.0, which contains a long awaited feature, sparse merkle trees (SMT)$ niftyzk --version 0.2.0 The previous implementation of Merkle Trees in NiftyZk were fixed merkle trees which can be used with commit-reveals and EdDSA schemes. The fixed trees allow for inclusion proofs and are always fully populated and never contain zeroes in the leaves. The fixed tree must be computed and updated off-chain and the updated root is created with arbitrary verific...

Niftyzk tutorial 2, The Commit-reveal scheme
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. So 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 y...
zkp development

Subscribe to strawberry

Subscribe to strawberry
Share Dialog
Share Dialog
<100 subscribers
<100 subscribers


In this tutorial, we will create a circuit, compile it and then deploy our ceremony server on a VPS to accept anonymous contributions. After this we will finalize the circuit and export the final Verification key
Let’s run niftyzk init projectname to create a new project
Creating a new directory with name projectname
? 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): no
Generating circuits
Generating javascript
Done
Run npm install in your project folder
So run npm install and let’s download the ptau files
niftyzk ptaufiles , we are going to grab a smaller file for our commit-reveal scheme
? Select a ptau file to download powersOfTau28_hez_final_14.ptau
Connecting to download powersOfTau28_hez_final_14.ptau
Starting to download 18.08 MiB
downloading [====================] 100% 0.0s
Now just run niftyzk compile and select the ptau file, so far so good.
Now run git init and do a git add .
If you check git status You should see;
$ git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: .gitignore
new file: circuits/circuit.circom
new file: circuits/commitment_hasher.circom
new file: circuits/compiled/circuit.r1cs
new file: circuits/compiled/circuit.sym
new file: circuits/compiled/circuit_js/circuit.wasm
new file: circuits/compiled/circuit_js/generate_witness.js
new file: circuits/compiled/circuit_js/witness_calculator.js
new file: circuits/compiled/zkeys/circuit_0000.zkey
new file: lib/index.js
new file: package-lock.json
new file: package.json
new file: readme.md
new file: test/index.test.js
new file: test/input.js
These are the files that were created during the scaffold and compilation. You can see the circuits/compiled directory contains all the artifacts outputted by the compiler and there is the zkey which will be used for contributions during the ceremony. The ptau files are not commited due to their size but you can always just download them again.
Let’s commit the files
$ git commit -m "initial commit"
[master (root-commit) 946c8e7] initial commit
15 files changed, 7212 insertions(+)
create mode 100644 .gitignore
create mode 100644 circuits/circuit.circom
create mode 100644 circuits/commitment_hasher.circom
create mode 100644 circuits/compiled/circuit.r1cs
create mode 100644 circuits/compiled/circuit.sym
create mode 100644 circuits/compiled/circuit_js/circuit.wasm
create mode 100644 circuits/compiled/circuit_js/generate_witness.js
create mode 100644 circuits/compiled/circuit_js/witness_calculator.js
create mode 100644 circuits/compiled/zkeys/circuit_0000.zkey
create mode 100644 lib/index.js
create mode 100644 package-lock.json
create mode 100644 package.json
create mode 100644 readme.md
create mode 100644 test/index.test.js
create mode 100644 test/input.js
Go over to your favorite git hosting solution, I’m using github but you can use whatever you want and push the repository. We will clone it to a VPS later, but you can also copy the whole directory there manually, that’s up to you.
The repository is here for reference:
https://github.com/NiftyZk/projectname
Manual Deployment
For the VPS, I’m creating a Hetzner server. You can use any hosting solution, or even self-host on a raspberry pi. You will need SSH to log in. We will configure Nginx and even configure a domain using namecheap.
On console.hetzner.cloud I created a 2VCPU, 4 GB Ram X86 VPS for €4.11/month running Ubuntu, and configured it with my SSH keys. If you are new to SSH you should invest some time to learn about it.
ssh root@serverip
So I’m connecting to the remote VPS I created with the SSH client, I’m connecting as root as there are no other users configured. You can configure that for yourself, it’s out of scope for now for showcasing the ceremony.
sudo apt update
sudo apt upgrade
sudo apt install nginxWe install snap for certbot
sudo apt install snapd
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo certbot --nginx
You should configure your domain to have an A record with host @ pointing to the IP of your VPS for certbot to issue the certificate. Your DNS changes will take time to propagate but if you did everything well, the IP address should already show NGINX is running.
Next we are going to install nodejs using the official docs
https://nodejs.org/en/download
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
This installs nvm and you might need to restart the ssh session after installation. Install a new node version using nvm
nvm install 22
We are going to install pm2, this will help keep the ceremony server open when the ssh session is closed.
npm install -g pm2
pm2 startup systemd
Clone the repository we created earlier using Git to your home directory and don’t forget to install niftyzk
npm install -g git+https://github.com/NiftyZk/niftyzk.git
Next step is to configure nginx to proxy the port 3000 to 443 SSL and upgrade all non-SSL connections to use it.You need to copy this file to /etc/nginx/sites-available/default and make sure to edit YOURDOMAIN parts to use your configured domain name!
server {
#SSL only
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
client_max_body_size 200M;
ssl_certificate /etc/letsencrypt/live/YOURDOMAIN/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/YOURDOMAIN/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
server_name YOURDOMAIN;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Connection ‘upgrade’;
proxy_pass http://127.0.0.1:3000; #port where you are serving your express app.
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_ssl_server_name on;
proxy_pass_header Server;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
}
server {
listen 80;
listen [::]:80;
server_name _;
return 301 https://$host$request_uri;
}
Then after editing the file, reload nginx
sudo systemctl reload nginx
Now, we are going to create a shell script to execute niftyzk ceremony, that can be ran by pm2
cd into your cloned project’s directory and npm install then touch run.sh and open it with an editor.
#!/usr/bin/bash
niftyzk ceremony
Download the used ptau file with niftyzk ptaufiles , we used the 14th for compiling, you must select the same.To finally run the ceremony, pm2 start run.sh
Congrats, you got the ceremony server running on your domain.When you visit it you should see this:

How does it work?
Anyone can visit your ceremony, the participation is public. They enter a name and then they are placed in a queue. When it’s their turn to contribute, they will be prompted to enter some entropy and on the client side they run SnarkJS to make a contribution to the last zkey.
The participation in the ceremony can be verified by downloading the log file and comparing the entries in the log file with the sha256 hash of your name.
A directory have been added to your repository called contributions, that contains the log.csv file.
So let’s enter the name: helloworld and add some random entropy.What happened? A contribution was added to the /circuits/compiled/zkeys/ directory called circuit_0001.zkey and the log file has a csv entry added
Contribution,936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af,087ec9f31cc05fa8db3c46ed360a5294fd6c99aaa97e244044ca936c3e302e35cd34080e86eaa4a67d1e2c717d25b90759f46cb4af692ac5b3e2d17f04bacbfa,circuit_0001.zkey
The first hash is a sha256 hash of the name entered, the second is the blake2b hash of the circuit which will be later logged on circuit finalization.
echo -n helloworld | sha256sum
936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af -
The ceremony can be online indefinitely and as long as one of the contributors don’t cheat, it’s secure. The largest PTAU file the ceremony server supports can be logged with niftyzk ptaufiles
powersOfTau28_hez_final_15.ptau blake2b hash: 982372c867d229c236091f767e703253249a9b432c1710b4f326306bfa2428a17b06240359606cfe4d580b10a5a1f63fbed499527069c18ae17060472969ae6e Power: 15, Max Constraints: 32K Size: 36.08 MiB Supports built in ceremony server: YES
The reason for this is the networking bottleneck. Any circuits that require more than max 32k constraints will need to do a ceremony manually using snarkjs.
So after a few contributions, you can take down the server. For testing now we can add contributions manually.
Then do a git add .
root@niftyzk-ceremony:/home/nifty/projectname# git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: circuits/compiled/contributions/log.csv
new file: circuits/compiled/zkeys/circuit_0001.zkey
new file: circuits/compiled/zkeys/circuit_0002.zkey
new file: circuits/compiled/zkeys/circuit_0003.zkey
new file: run.sh
And commit these zkeys and push to your repository.You can turn off your webserver now.
Finalize the circuit
You can finalize the ceremony locally, just pull the changes and select a random beacon to use.
niftyzk finalize --beacon 0000000000000000000102b8a74a6e9b9344f0abb3ba25dea7f847c7296fb21d
Niftyzk finalize will complete the ceremony, I used a bitcoin block hash for a beacon. It should be a verifiable hexadecimal number.
When the finalization finished, you should see the contributions are logged.It will be always verifiable that your contribution is in the final zkey as long as you know the name you entered.
[INFO] niftyzk: contribution #1 936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af:
087ec9f3 1cc05fa8 db3c46ed 360a5294
fd6c99aa a97e2440 44ca936c 3e302e35
cd34080e 86eaa4a6 7d1e2c71 7d25b907
59f46cb4 af692ac5 b3e2d17f 04bacbfa
[INFO] niftyzk: ZKey Ok!
This creates the circuit.final.zkey
Now you can run niftyzk vkey --final and create the final verification_key.jsonnow your circuit is secure and ready for production.
In this tutorial, we will create a circuit, compile it and then deploy our ceremony server on a VPS to accept anonymous contributions. After this we will finalize the circuit and export the final Verification key
Let’s run niftyzk init projectname to create a new project
Creating a new directory with name projectname
? 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): no
Generating circuits
Generating javascript
Done
Run npm install in your project folder
So run npm install and let’s download the ptau files
niftyzk ptaufiles , we are going to grab a smaller file for our commit-reveal scheme
? Select a ptau file to download powersOfTau28_hez_final_14.ptau
Connecting to download powersOfTau28_hez_final_14.ptau
Starting to download 18.08 MiB
downloading [====================] 100% 0.0s
Now just run niftyzk compile and select the ptau file, so far so good.
Now run git init and do a git add .
If you check git status You should see;
$ git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: .gitignore
new file: circuits/circuit.circom
new file: circuits/commitment_hasher.circom
new file: circuits/compiled/circuit.r1cs
new file: circuits/compiled/circuit.sym
new file: circuits/compiled/circuit_js/circuit.wasm
new file: circuits/compiled/circuit_js/generate_witness.js
new file: circuits/compiled/circuit_js/witness_calculator.js
new file: circuits/compiled/zkeys/circuit_0000.zkey
new file: lib/index.js
new file: package-lock.json
new file: package.json
new file: readme.md
new file: test/index.test.js
new file: test/input.js
These are the files that were created during the scaffold and compilation. You can see the circuits/compiled directory contains all the artifacts outputted by the compiler and there is the zkey which will be used for contributions during the ceremony. The ptau files are not commited due to their size but you can always just download them again.
Let’s commit the files
$ git commit -m "initial commit"
[master (root-commit) 946c8e7] initial commit
15 files changed, 7212 insertions(+)
create mode 100644 .gitignore
create mode 100644 circuits/circuit.circom
create mode 100644 circuits/commitment_hasher.circom
create mode 100644 circuits/compiled/circuit.r1cs
create mode 100644 circuits/compiled/circuit.sym
create mode 100644 circuits/compiled/circuit_js/circuit.wasm
create mode 100644 circuits/compiled/circuit_js/generate_witness.js
create mode 100644 circuits/compiled/circuit_js/witness_calculator.js
create mode 100644 circuits/compiled/zkeys/circuit_0000.zkey
create mode 100644 lib/index.js
create mode 100644 package-lock.json
create mode 100644 package.json
create mode 100644 readme.md
create mode 100644 test/index.test.js
create mode 100644 test/input.js
Go over to your favorite git hosting solution, I’m using github but you can use whatever you want and push the repository. We will clone it to a VPS later, but you can also copy the whole directory there manually, that’s up to you.
The repository is here for reference:
https://github.com/NiftyZk/projectname
Manual Deployment
For the VPS, I’m creating a Hetzner server. You can use any hosting solution, or even self-host on a raspberry pi. You will need SSH to log in. We will configure Nginx and even configure a domain using namecheap.
On console.hetzner.cloud I created a 2VCPU, 4 GB Ram X86 VPS for €4.11/month running Ubuntu, and configured it with my SSH keys. If you are new to SSH you should invest some time to learn about it.
ssh root@serverip
So I’m connecting to the remote VPS I created with the SSH client, I’m connecting as root as there are no other users configured. You can configure that for yourself, it’s out of scope for now for showcasing the ceremony.
sudo apt update
sudo apt upgrade
sudo apt install nginxWe install snap for certbot
sudo apt install snapd
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo certbot --nginx
You should configure your domain to have an A record with host @ pointing to the IP of your VPS for certbot to issue the certificate. Your DNS changes will take time to propagate but if you did everything well, the IP address should already show NGINX is running.
Next we are going to install nodejs using the official docs
https://nodejs.org/en/download
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
This installs nvm and you might need to restart the ssh session after installation. Install a new node version using nvm
nvm install 22
We are going to install pm2, this will help keep the ceremony server open when the ssh session is closed.
npm install -g pm2
pm2 startup systemd
Clone the repository we created earlier using Git to your home directory and don’t forget to install niftyzk
npm install -g git+https://github.com/NiftyZk/niftyzk.git
Next step is to configure nginx to proxy the port 3000 to 443 SSL and upgrade all non-SSL connections to use it.You need to copy this file to /etc/nginx/sites-available/default and make sure to edit YOURDOMAIN parts to use your configured domain name!
server {
#SSL only
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
client_max_body_size 200M;
ssl_certificate /etc/letsencrypt/live/YOURDOMAIN/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/YOURDOMAIN/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
server_name YOURDOMAIN;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Connection ‘upgrade’;
proxy_pass http://127.0.0.1:3000; #port where you are serving your express app.
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_ssl_server_name on;
proxy_pass_header Server;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
}
server {
listen 80;
listen [::]:80;
server_name _;
return 301 https://$host$request_uri;
}
Then after editing the file, reload nginx
sudo systemctl reload nginx
Now, we are going to create a shell script to execute niftyzk ceremony, that can be ran by pm2
cd into your cloned project’s directory and npm install then touch run.sh and open it with an editor.
#!/usr/bin/bash
niftyzk ceremony
Download the used ptau file with niftyzk ptaufiles , we used the 14th for compiling, you must select the same.To finally run the ceremony, pm2 start run.sh
Congrats, you got the ceremony server running on your domain.When you visit it you should see this:

How does it work?
Anyone can visit your ceremony, the participation is public. They enter a name and then they are placed in a queue. When it’s their turn to contribute, they will be prompted to enter some entropy and on the client side they run SnarkJS to make a contribution to the last zkey.
The participation in the ceremony can be verified by downloading the log file and comparing the entries in the log file with the sha256 hash of your name.
A directory have been added to your repository called contributions, that contains the log.csv file.
So let’s enter the name: helloworld and add some random entropy.What happened? A contribution was added to the /circuits/compiled/zkeys/ directory called circuit_0001.zkey and the log file has a csv entry added
Contribution,936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af,087ec9f31cc05fa8db3c46ed360a5294fd6c99aaa97e244044ca936c3e302e35cd34080e86eaa4a67d1e2c717d25b90759f46cb4af692ac5b3e2d17f04bacbfa,circuit_0001.zkey
The first hash is a sha256 hash of the name entered, the second is the blake2b hash of the circuit which will be later logged on circuit finalization.
echo -n helloworld | sha256sum
936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af -
The ceremony can be online indefinitely and as long as one of the contributors don’t cheat, it’s secure. The largest PTAU file the ceremony server supports can be logged with niftyzk ptaufiles
powersOfTau28_hez_final_15.ptau blake2b hash: 982372c867d229c236091f767e703253249a9b432c1710b4f326306bfa2428a17b06240359606cfe4d580b10a5a1f63fbed499527069c18ae17060472969ae6e Power: 15, Max Constraints: 32K Size: 36.08 MiB Supports built in ceremony server: YES
The reason for this is the networking bottleneck. Any circuits that require more than max 32k constraints will need to do a ceremony manually using snarkjs.
So after a few contributions, you can take down the server. For testing now we can add contributions manually.
Then do a git add .
root@niftyzk-ceremony:/home/nifty/projectname# git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: circuits/compiled/contributions/log.csv
new file: circuits/compiled/zkeys/circuit_0001.zkey
new file: circuits/compiled/zkeys/circuit_0002.zkey
new file: circuits/compiled/zkeys/circuit_0003.zkey
new file: run.sh
And commit these zkeys and push to your repository.You can turn off your webserver now.
Finalize the circuit
You can finalize the ceremony locally, just pull the changes and select a random beacon to use.
niftyzk finalize --beacon 0000000000000000000102b8a74a6e9b9344f0abb3ba25dea7f847c7296fb21d
Niftyzk finalize will complete the ceremony, I used a bitcoin block hash for a beacon. It should be a verifiable hexadecimal number.
When the finalization finished, you should see the contributions are logged.It will be always verifiable that your contribution is in the final zkey as long as you know the name you entered.
[INFO] niftyzk: contribution #1 936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af:
087ec9f3 1cc05fa8 db3c46ed 360a5294
fd6c99aa a97e2440 44ca936c 3e302e35
cd34080e 86eaa4a6 7d1e2c71 7d25b907
59f46cb4 af692ac5 b3e2d17f 04bacbfa
[INFO] niftyzk: ZKey Ok!
This creates the circuit.final.zkey
Now you can run niftyzk vkey --final and create the final verification_key.jsonnow your circuit is secure and ready for production.
No activity yet