DEV Community

Cover image for Niftyzk tutorial 4 - Ceremony
Peter Horvath
Peter Horvath

Posted on

Niftyzk tutorial 4 - Ceremony

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
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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 nginx

We 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;

}

Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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:

Cropped screenshot

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

Enter fullscreen mode Exit fullscreen mode

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  -

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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!

Enter fullscreen mode Exit fullscreen mode

This creates the circuit.final.zkey

Now you can run niftyzk vkey --final and create the final verification_key.json
now your circuit is secure and ready for production.

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read full post →

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more