<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Peter Horvath</title>
    <description>The latest articles on DEV Community by Peter Horvath (@strawberry666).</description>
    <link>https://dev.to/strawberry666</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2688310%2Ff3400495-e4e8-40e4-a35b-6ac087e2a048.png</url>
      <title>DEV Community: Peter Horvath</title>
      <link>https://dev.to/strawberry666</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/strawberry666"/>
    <language>en</language>
    <item>
      <title>Niftyzk Tutorials 5 - CosmWasm</title>
      <dc:creator>Peter Horvath</dc:creator>
      <pubDate>Sat, 11 Jan 2025 04:41:37 +0000</pubDate>
      <link>https://dev.to/strawberry666/niftyzk-tutorials-5-cosmwasm-1g6n</link>
      <guid>https://dev.to/strawberry666/niftyzk-tutorials-5-cosmwasm-1g6n</guid>
      <description>&lt;p&gt;This tutorial is the continuation of the series to explain Niftyzk for ZKP development and you should check out the previous tutorials to understand everything that’s going on here.&lt;/p&gt;

&lt;p&gt;in Tutorials 4, we completed a Phase-2 ceremony for Groth-16 proving system, now we will continue that and export a CosmWasm contract&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/strawberry666/niftyzk-tutorial-4-ceremony-2enj"&gt;Previous tutorial&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, to export a cosmwasm contract, you will need a verification_key using &lt;code&gt;niftyzk vkey&lt;/code&gt; and the unit tests need to pass.. You don’t need to finalize the circuits to create a verifier contract from it, however you will need to reexport your contract after finalization to match the new verification key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;niftyzk gencontract&lt;/code&gt; command accepts the above arguments. You can specify the name of the circuit if your using one with a different name. The &lt;code&gt;--ark&lt;/code&gt; and &lt;code&gt;--bellman&lt;/code&gt; allows you to select a Rust library and the &lt;code&gt;--folder [name]&lt;/code&gt; lets you name the folder where you export the contract to. If the folder exists already, you need to explicitly overwrite it with the &lt;code&gt;--overwrite&lt;/code&gt; flag.&lt;/p&gt;

&lt;p&gt;Let’s export a contract now from a compiled circuit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ niftyzk gencontract --ark --folder contract
Writing .cargo/config.toml
Writing Cargo.toml
Writing .gitignore
Writing src/lib.rs
Writing src/msg.rs
Writing src/contract.rs
Writing src/verify.rs
Done

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You need to have rust installed. To compile the contract, the rust compiler backed must be installed: &lt;code&gt;rustup target add wasm32-unknown-unknown&lt;/code&gt; and then run &lt;code&gt;cargo test&lt;/code&gt; inside the directory, that will install the dependencies and runs the generated tests.&lt;/p&gt;

&lt;p&gt;Build the contracts using &lt;code&gt;cargo wasm&lt;/code&gt; and if you have installed cosmwasm-check with &lt;code&gt;cargo insall cosmwasm-check&lt;/code&gt; you can verify that these are valid cosmwasm contracts &lt;code&gt;cosmwasm-check ./target/wasm32-unknown-unknown/release/contract.wasm&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;now we verified that the contracts are correct. Let’s see what we got in the source code.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;src/lib.rs&lt;/code&gt; is the entry point of our contract and &lt;code&gt;/src/contract.rs&lt;/code&gt; contains the implementations. The zkp verification is found inside &lt;code&gt;src/verify.rs&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You are free to modify all code however if you change the inlined parameters your verification will fail.&lt;/p&gt;

&lt;p&gt;To trigger the smart contract, you call the Query function with a &lt;code&gt;VerifyProof&lt;/code&gt; message.&lt;br&gt;
For the accepted proof format see the &lt;code&gt;lib/contract.rs&lt;/code&gt; unit test &lt;code&gt;test_verify&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;proof_str&lt;/code&gt; variable is a json string that is serialized directly from the snarkjs &lt;code&gt;groth16.fullProve&lt;/code&gt; proof , while the &lt;code&gt;pub_input_str&lt;/code&gt; is the stringified publicSignals variable. Using it is pretty straight forward, which is the benefit of choosing Arkworks implementation. However while easy to use, the &lt;strong&gt;Arkworks library is not fully audited.&lt;br&gt;
See the documentation to learn more:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://arkworks.rs/" rel="noopener noreferrer"&gt;arkworks.rs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/arkworks-rs/groth16" rel="noopener noreferrer"&gt;arkworks github source code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bellman&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Bellman library was originally developed for ZCash by Matter Labs and we are importing the DoraFactory fork, the old version has been archived.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ niftyzk gencontract --bellman --folder secondcontract         
Writing .cargo/config.toml
Writing .gitignore
Writing Cargo.toml
Writing src/lib.rs
Writing src/msg.rs
Writing src/parser.rs
Writing src/types.rs
Writing src/verify.rs
Writing src/contract.rs
Writing lib/adapter.js
Done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We generate a new contract inside the secondcontract directory and as you can see there are more things going on. It not only created a new contract directory with the rust code, but added a &lt;code&gt;lib/adapter.js&lt;/code&gt; file to our lib!&lt;/p&gt;

&lt;p&gt;The Bellman library uses uncompressed vkey and proofs which are in a different format.&lt;br&gt;
Let’s see the adapter.&lt;br&gt;
&lt;code&gt;lib/adapter.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * The verification key adapter transforms the verification key into a format usable by the Bellman_ce based verifier
 * @param {string} verification_key_string - The verification_key.json as a string
 * @returns {string} uncompressed_vkey - Returns an uncompressed version of the verificaiton_key.json which can be parsed inside the rust verifier contract
 */
export async function verificationKeyAdapter(verification_key_string);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You need to adapt the verification key for use, this was done for you by the code generating process and the adapted vkey is inlined into the rust code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * The proofAdapter adapts proofs generated with snarkjs into a format parsable by a bellman verifier.
 * Use this function on the front-end, to adapt proofs generated by the client for on-chain use
 * @param {string} verification_key_string - The contents of the verification_key.json as a string
 * @param {string} proof_string - The snarkjs generated proof as a string
 * @returns {string} - Returns the adapted proof to use inside rust bellman verifier
 */
export async function proofAdapter(verification_key_string, proof_string);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The proof adapter is a function you will need to use on the client or server after you have created the proofs and want to call a smart contract with them.&lt;/p&gt;

&lt;p&gt;If you check out the tests in &lt;code&gt;src/contract.rs&lt;/code&gt; you will see an example of a adapted proof string and a adapted public input string.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The bellman library is more mature and recommended to use over the arkworks implementation, you should evaluate which fits your use-case better.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can again run &lt;code&gt;cargo wasm&lt;/code&gt; and use &lt;code&gt;cosmwasm-check ./target/wasm32-unknown-unknown/release/contract.wasm&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once you have verified the contracts are valid they are ready for deployment.&lt;/p&gt;

&lt;p&gt;I hope you like niftyzk and the tutorial series and keep on building!&lt;/p&gt;

</description>
      <category>cosmwasm</category>
      <category>circom</category>
      <category>blockchain</category>
      <category>web3</category>
    </item>
    <item>
      <title>Niftyzk tutorial 4 - Ceremony</title>
      <dc:creator>Peter Horvath</dc:creator>
      <pubDate>Sat, 11 Jan 2025 04:28:13 +0000</pubDate>
      <link>https://dev.to/strawberry666/niftyzk-tutorial-4-ceremony-2enj</link>
      <guid>https://dev.to/strawberry666/niftyzk-tutorial-4-ceremony-2enj</guid>
      <description>&lt;p&gt;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&lt;/p&gt;

&lt;p&gt;Let’s run &lt;code&gt;niftyzk init projectname&lt;/code&gt; to create a new project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So run &lt;code&gt;npm install&lt;/code&gt; and let’s download the ptau files&lt;/p&gt;

&lt;p&gt;&lt;code&gt;niftyzk ptaufiles&lt;/code&gt; , we are going to grab a smaller file for our commit-reveal scheme&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;? 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

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now just run &lt;code&gt;niftyzk compile&lt;/code&gt; and select the ptau file, so far so good.&lt;/p&gt;

&lt;p&gt;Now run &lt;code&gt;git init&lt;/code&gt; and do a &lt;code&gt;git add .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you check &lt;code&gt;git status&lt;/code&gt; You should see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached &amp;lt;file&amp;gt;..." 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

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are the files that were created during the scaffold and compilation. You can see the &lt;code&gt;circuits/compiled&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;Let’s commit the files&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ 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

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;The repository is here for reference:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/NiftyZk/projectname" rel="noopener noreferrer"&gt;https://github.com/NiftyZk/projectname&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Manual Deployment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ssh root@serverip&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo apt update&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo apt upgrade&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo apt install nginx&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We install snap for certbot&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo apt install snapd&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo snap install --classic certbot&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo ln -s /snap/bin/certbot /usr/bin/certbot&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo certbot --nginx&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You should configure your domain to have an A record with host &lt;code&gt;@&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;Next we are going to install nodejs using the official docs&lt;br&gt;
&lt;a href="https://nodejs.org/en/download" rel="noopener noreferrer"&gt;https://nodejs.org/en/download&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This installs nvm and you might need to restart the ssh session after installation. Install a new node version using nvm&lt;/p&gt;

&lt;p&gt;&lt;code&gt;nvm install 22&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We are going to install pm2, this will help keep the ceremony server open when the ssh session is closed.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install -g pm2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pm2 startup systemd&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Clone the repository we created earlier using Git to your home directory and don’t forget to install niftyzk&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install -g git+https://github.com/NiftyZk/niftyzk.git&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;/etc/nginx/sites-available/default&lt;/code&gt; and make sure to &lt;strong&gt;edit YOURDOMAIN parts to use your configured domain name!&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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;

}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then after editing the file, reload nginx&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo systemctl reload nginx&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, we are going to create a shell script to execute niftyzk ceremony, that can be ran by pm2&lt;/p&gt;

&lt;p&gt;cd into your cloned project’s directory and &lt;code&gt;npm install&lt;/code&gt; then &lt;code&gt;touch run.sh&lt;/code&gt; and open it with an editor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/usr/bin/bash
niftyzk ceremony
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Download the used ptau file with &lt;code&gt;niftyzk ptaufiles&lt;/code&gt; , we used the 14th for compiling, you must select the same.To finally run the ceremony, &lt;code&gt;pm2 start run.sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Congrats, you got the ceremony server running on your domain.When you visit it you should see this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq9a099yxohoc19yvgdn6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq9a099yxohoc19yvgdn6.png" alt="Cropped screenshot" width="733" height="755"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does it work?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;A directory have been added to your repository called contributions, that contains the log.csv file.&lt;/p&gt;

&lt;p&gt;So let’s enter the name: &lt;code&gt;helloworld&lt;/code&gt; and add some random entropy.What happened? A contribution was added to the &lt;code&gt;/circuits/compiled/zkeys/&lt;/code&gt; directory called &lt;code&gt;circuit_0001.zkey&lt;/code&gt; and the log file has a csv entry added&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Contribution,936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af,087ec9f31cc05fa8db3c46ed360a5294fd6c99aaa97e244044ca936c3e302e35cd34080e86eaa4a67d1e2c717d25b90759f46cb4af692ac5b3e2d17f04bacbfa,circuit_0001.zkey

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; echo -n helloworld | sha256sum 
936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af  -

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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 &lt;code&gt;niftyzk ptaufiles&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;powersOfTau28_hez_final_15.ptau blake2b hash: 982372c867d229c236091f767e703253249a9b432c1710b4f326306bfa2428a17b06240359606cfe4d580b10a5a1f63fbed499527069c18ae17060472969ae6e Power: 15, Max Constraints: 32K Size: 36.08 MiB Supports built in ceremony server: YES

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reason for this is the networking bottleneck. &lt;code&gt;Any circuits that require more than max 32k constraints will need to do a ceremony manually using snarkjs.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So after a few contributions, you can take down the server. For testing now we can add contributions manually.&lt;/p&gt;

&lt;p&gt;Then do a &lt;code&gt;git add .&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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 &amp;lt;file&amp;gt;..." 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

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And commit these zkeys and push to your repository.You can turn off your webserver now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Finalize the circuit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can finalize the ceremony locally, just pull the changes and select a random beacon to use.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;niftyzk finalize --beacon 0000000000000000000102b8a74a6e9b9344f0abb3ba25dea7f847c7296fb21d&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Niftyzk finalize will complete the ceremony, I used a bitcoin block hash for a beacon. It should be a verifiable hexadecimal number.&lt;/p&gt;

&lt;p&gt;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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[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!

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates the &lt;code&gt;circuit.final.zkey&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now you can run &lt;code&gt;niftyzk vkey --final&lt;/code&gt; and create the final &lt;code&gt;verification_key.json&lt;/code&gt; &lt;br&gt;
now your circuit is secure and ready for production.&lt;/p&gt;

</description>
      <category>circom</category>
      <category>cosmos</category>
      <category>zkp</category>
      <category>powersoftau</category>
    </item>
    <item>
      <title>Niftyzk tutorials 3 - Edwards-curve Digital Signatures</title>
      <dc:creator>Peter Horvath</dc:creator>
      <pubDate>Sat, 11 Jan 2025 04:16:54 +0000</pubDate>
      <link>https://dev.to/strawberry666/niftyzk-tutorials-3-edwards-curve-digital-signatures-35am</link>
      <guid>https://dev.to/strawberry666/niftyzk-tutorials-3-edwards-curve-digital-signatures-35am</guid>
      <description>&lt;p&gt;Niftyzk supports EdDSA which is a public cryptography digital signature scheme.This tutorial will contain information about the generated code and you will need to read the previous tutorials to understand everything.&lt;/p&gt;

&lt;p&gt;Let’s start with &lt;code&gt;niftyzk init&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Setting up your current directory
? What project do you want to scaffold? EdDSA signature verification
? Choose the hashing algorithm to use:  mimc7
? Do you wish to add public inputs to sign? (E.g: address,amount) 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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we selected EdDSA with mimc7 and added some inputs to sign, address, amount&lt;/p&gt;

&lt;p&gt;Using MiMC7 hash means we will have to use a key to create hashes which is kept secret. However for signing with EdDSA using MiMC, the key is not used. That decision to not use the key for signing was made by the developers of circomlib, as using a default key is not an issue, the signed data is a public hash.&lt;/p&gt;

&lt;p&gt;Let’s see the generated circuits, you see there is a &lt;code&gt;circuit.circom&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma circom 2.0.0;

include "../node_modules/circomlib/circuits/eddsamimc.circom";
include "../node_modules/circomlib/circuits/mimc.circom";

template VerifySignature(){
    signal input message;
    signal input address;
    signal input amount;

    signal input k;

    signal input Ax;
    signal input Ay;
    signal input S;
    signal input R8x;
    signal input R8y;

    component eddsa = EdDSAMiMCVerifier();

    component mimc7Hash = MultiMiMC7(3, 91);
    mimc7Hash.k &amp;lt;== k;
    mimc7Hash.in[0] &amp;lt;== message;
    mimc7Hash.in[1] &amp;lt;== address;
    mimc7Hash.in[2] &amp;lt;== amount;


    eddsa.enabled &amp;lt;== 1;
    eddsa.Ax &amp;lt;== Ax;
    eddsa.Ay &amp;lt;== Ay;
    eddsa.S &amp;lt;== S;
    eddsa.R8x &amp;lt;== R8x;
    eddsa.R8y &amp;lt;== R8y;
    eddsa.M &amp;lt;== mimc7Hash.out;

    }

component main {public [message,address,amount]}  = VerifySignature(); 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we import the required dependencies, we use the same hashing algorithm for the signatures and the message hash.&lt;/p&gt;

&lt;p&gt;So we got a &lt;code&gt;message&lt;/code&gt; input, &lt;code&gt;address&lt;/code&gt; and &lt;code&gt;amount&lt;/code&gt; which were extra and these are our public inputs that will be revealed on-chain for verification.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;k&lt;/code&gt; is the secret used for the mimc hashing&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Ax&lt;/code&gt;,&lt;code&gt;Ay&lt;/code&gt; are the points used for the public key, &lt;code&gt;S&lt;/code&gt;, &lt;code&gt;R8x&lt;/code&gt;,&lt;code&gt;R8y&lt;/code&gt; are signature parameters returned by the signing function.&lt;/p&gt;

&lt;p&gt;We compute a MiMC7 hash using &lt;code&gt;k&lt;/code&gt; and then just assign the inputs to the &lt;code&gt;eddsa&lt;/code&gt; template input signals. By specifying &lt;code&gt;eddsa.enabled &amp;lt;== 1;&lt;/code&gt; we assert that the signature must be valid for the hash.Now let’s look at some javascript&lt;br&gt;
Accounts are created using EdDSA:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * The signature parameters used for verifying pedersen hash signed EdDSA
 * @typedef {Object} Account
 * @property {Buffer} prvKey - Private key buffer
 * @property {Uint8Array[]} pubKey - Public key is a tuple of 32 bit Uint8Array
 */

/**
 * @param {any} eddsa - The EdDSA object
 * @returns {Account}
 * Generate a new account which composes of a private and public key
*/
export function generateAccount(eddsa) {
    const prvKey = rbytes();
    const pubKey = eddsa.prv2pub(prvKey);
    return {
        prvKey,
        pubKey
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use 32 bytes for the account, the &lt;code&gt;rbytes()&lt;/code&gt; returns a random buffer. It uses &lt;code&gt;crypto.randomBytes(32)&lt;/code&gt;The public keys are a tuple of Uint8Array, 32 bits in size each.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * 
 * @param {Array&amp;lt;bigint&amp;gt;} pubKey - Used for computing an address
 * @param {bigin | number} key -The key used for the mimc7 hash
 * @returns 
 */

export async function getAddressFromPubkey(pubKey, key) {
    return mimc7(pubKey, key);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We compute “addresses” from the public key by hashing it. These addresses are not valid blockchain addresses but usable for account abstraction. You can derive addresses from a public key using different schemes and derivation paths. It’s up to you what you choose.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * @typedef {Object} Message
 * @property {string | bigint} message
 * @property {string | bigint} address
 * @property {string | bigint} amount
 */

/**
 * 
 * @param {Message} data - The data content of the message. The hash of the data object will be signed
 * @param key {number | bigint} - The key used for the mimc7 hash
 * @returns {bigint} Returns a mimc7 hash
 */
export async function computeMessageHash(data, key) {
    return await mimc7(
        [
            BigInt(data.message),
            BigInt(data.address),
            BigInt(data.amount)
        ], key)
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The message hash is computed using mimc7, it’s the same hashing that happens inside the circuit for verification.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * @param {any} eddsa - the built EDDSA
 * @param {bigint} messagehash - The poseidon hash of the message
 * @param {Buffer} prvKey - The private key used to sign the message 
 * @returns {Signature} signature
 */
export function signMessage(eddsa, messageHash, prvKey) {
    const signature = eddsa.signMiMC(prvKey, eddsa.F.e(messageHash));
    const pubKey = eddsa.prv2pub(prvKey);
    assert(eddsa.verifyMiMC(eddsa.F.e(messageHash), signature, pubKey))

    return {
        signature,
        pubKey
    }
}

/**
 * @typedef {Object} Signature
 * @property {Uint8Array[]} R8
 * @property {bigint} S
 * /

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Message signing uses the above function. You pass an eddsa object, the computed message hash and the private key created for your account. You can see the type of the signature defined with JsDoc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * @typedef {Object} SignatureParameters
 * @property {bigint} Ax
 * @property {bigint} Ay
 * @property {bigint} R8x
 * @property {bigint} R8y
 * @property {bigint} S
 */

/**
 * @param {any} eddsa
 * @param {Uint8Array[]} pubKey - The public key of the account
 * @param {Signature} signature - The signature of the signed message
 * @returns {SignatureParameters} - The signature parameters are prepared parameters, ready to use for the circuit
 */
export function getSignatureParameters(eddsa, pubKey, signature) {
    return {
        Ax: eddsa.F.toObject(pubKey[0]),
        Ay: eddsa.F.toObject(pubKey[1]),
        R8x: eddsa.F.toObject(signature.R8[0]),
        R8y: eddsa.F.toObject(signature.R8[1]),
        S: signature.S
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now to use this signature in circom, we need to convert it. So we get the signature parameters for verification with the above function. &lt;code&gt;/test/input.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * This is a test input, generated for the starting circuit.
 * If you update the inputs, you need to update this function to match it.
 */
export async function getInput(){

    await buildHashImplementation()
    const eddsa = await getEDDSA();

    const account = generateAccount(eddsa);
    const key = 313; // just an example key for tests
    const message = rbigint();
    const address = rbigint()
    const amount = rbigint()
    const messageHash = await computeMessageHash({message,address,amount}, key)

    const signedMessage = signMessage(eddsa, messageHash, account.prvKey);

    const signatureParameters = getSignatureParameters(eddsa, account.pubKey, signedMessage.signature)

    return {
        Ax: signatureParameters.Ax, 
        Ay: signatureParameters.Ay,
        S: signatureParameters.S,
        R8x: signatureParameters.R8x,
        R8y: signatureParameters.R8y,

        k: key,
        address,
        amount,
        message
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And above you can see how we compute the input for the circuits. it’s used for the hot reload and the tests&lt;/p&gt;

&lt;p&gt;Now I’ll show you how the merkle trees work with EdDSA&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Setting up your current directory
? What project do you want to scaffold? EdDSA signature verification with Fixed Merkle Tree
? Choose the hashing algorithm to use:  poseidon
? Do you wish to add public inputs to sign? (E.g: address,amount) no

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So regenerated the project using &lt;code&gt;niftyzk init&lt;/code&gt; and selected different parameters.And this is the &lt;code&gt;circuit.circom&lt;/code&gt; file now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma circom 2.0.0;

include "../node_modules/circomlib/circuits/eddsaposeidon.circom";
include "../node_modules/circomlib/circuits/poseidon.circom";
include "./merkletree.circom";


template VerifySignature(levels){

    signal input message;
    signal input root;

    signal input pathIndices[levels];
    signal input pathElements[levels];


    //The parameters for the signature
    //The Ax and Ay parameters are the public key, Ax = pubKey[0], Ay = pubKey[1]
    signal input Ax;
    signal input Ay;
    signal input S;
    signal input R8x;
    signal input R8y;
    component eddsa = EdDSAPoseidonVerifier();

    component poseidon = Poseidon(1);
    poseidon.inputs[0] &amp;lt;== message;

    // Verify the signature on the message hash

    eddsa.enabled &amp;lt;== 1;
    eddsa.Ax &amp;lt;== Ax;
    eddsa.Ay &amp;lt;== Ay;
    eddsa.S &amp;lt;== S;
    eddsa.R8x &amp;lt;== R8x;
    eddsa.R8y &amp;lt;== R8y;
    eddsa.M &amp;lt;== poseidon.out;

    //We compute a public key by hashing Ax and Ay, 
   // this will be later used with the merkle tree
   component pubKeyHasher = Poseidon(2);
   pubKeyHasher.inputs[0] &amp;lt;== Ax;
   pubKeyHasher.inputs[1] &amp;lt;== Ay;

   //Verify the merkle tree
   component tree = MerkleTreeChecker(levels);


  for (var i = 0; i &amp;lt; levels; i++) {
      tree.pathElements[i] &amp;lt;== pathElements[i];
      tree.pathIndices[i] &amp;lt;== pathIndices[i];
  }
  tree.root &amp;lt;== root;
  tree.leaf &amp;lt;== pubKeyHasher.out; 
    }

component main {public [message,root]}  = VerifySignature(20); 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So you can see there are some differences. I didn’t add more extra parameters to sign this time, so there is only two public inputs, &lt;code&gt;message&lt;/code&gt; and &lt;code&gt;root&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So &lt;code&gt;root&lt;/code&gt; is the merkle tree root we going to verify that the public key that signed this message is contained inside the tree. It’s a way of access control, so we know that the signature is valid and the signer public key is allowed to pass the verification because his key is inside the tree.&lt;/p&gt;

&lt;p&gt;We compute the address using the &lt;code&gt;pubKeyHasher&lt;/code&gt; from Ax and Ay, you can see it does exactly the same as the Javascript code I showed earlier. The &lt;code&gt;MerkleTreeChecker&lt;/code&gt; asserts correctness and will fail if the leaf is not contained in the root.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pathIndices&lt;/code&gt; and &lt;code&gt;pathElements&lt;/code&gt; are the merkle proof. You can explore the merkle tree circuit in the file &lt;code&gt;merkletree.circom&lt;/code&gt; I explained it in a previous tutorial.&lt;/p&gt;

&lt;p&gt;So to manually create merkle trees using the cli, we can use &lt;code&gt;npm run new&lt;/code&gt; that will generate addresses and create a tree using them as leaves.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATING A NEW MERKLE TREE

Enter how many accounts would you like to generate:
4
Generating accounts and addresses. Please wait!
Done
Generating merkle tree from addresses!
Done.Root is 21804813178957116268623645093306988559564490743632413729059072914509024611553 
Serializing data.
Writing to file.
Done

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The private keys for the corresponding accounts are placed in the &lt;code&gt;private&lt;/code&gt; directory while the rest is placed in the &lt;code&gt;public&lt;/code&gt; directory. If you chose &lt;code&gt;MiMC7&lt;/code&gt; or &lt;code&gt;MiMCSponge&lt;/code&gt; hashes then the key parameter is saved in the private dir and needed for verification, otherwise you don’t need to use the private details to create a merkle proof and verify it.&lt;/p&gt;

&lt;p&gt;so let’s run &lt;code&gt;npm run proof&lt;/code&gt; and it will ask for a root and an address and spit out a merkle proof&lt;/p&gt;

&lt;p&gt;then &lt;code&gt;npm run verify&lt;/code&gt; will ask for a root and the proof and if eveything is running correctly the proof will be valid.&lt;/p&gt;

&lt;p&gt;You can use EdDSA for Identity, Rollups, Scaling,Voting or Account Abstraction. It’s up to you :)&lt;/p&gt;

</description>
      <category>web3</category>
      <category>circom</category>
      <category>zkp</category>
      <category>cosmwasm</category>
    </item>
    <item>
      <title>Niftyzk tutorial 2, The Commit-reveal scheme</title>
      <dc:creator>Peter Horvath</dc:creator>
      <pubDate>Sat, 11 Jan 2025 04:08:42 +0000</pubDate>
      <link>https://dev.to/strawberry666/niftyzk-tutorial-2-the-commit-reveal-scheme-25ll</link>
      <guid>https://dev.to/strawberry666/niftyzk-tutorial-2-the-commit-reveal-scheme-25ll</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;So let’s scaffold a new project using &lt;code&gt;niftyzk init&lt;/code&gt; we will select a commit-reveal scheme with poseidon hash and add 2 inputs for tamper proofing, address and amount.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ 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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The circuits directory&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;code&gt;circuits.circom&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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 &amp;lt;== nullifier;
    commitmentHasher.secret &amp;lt;== 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 &amp;lt;== address * address;
    amountSquare &amp;lt;== amount * amount;

}

component main {public [nullifierHash,commitmentHash,address,amount]} = CommitmentRevealScheme();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s see from top to bottom what’s going on.&lt;/p&gt;

&lt;p&gt;First, it’s using circom 2.0.0 and imports the commitment_hasher.circom template&lt;/p&gt;

&lt;p&gt;Next, as you can see on the bottom we have 4 public inputs, these inputs will be exposed to the blockchain when verifying a circuit there. &lt;code&gt;nullifierHash&lt;/code&gt; is used for nullification inside the contract, you can use this variable to make sure the proof is not used twice. &lt;code&gt;commitmentHash&lt;/code&gt;is the hash used for the commit-reveal scheme. We prove we know the preimage of this hash with the proof. &lt;code&gt;address&lt;/code&gt; and &lt;code&gt;amount&lt;/code&gt; are extra public inputs which are added into the circuit. the creator of the proof can add these inputs and submit the proof to the blockchain. A malicious relayer who acquires the proof is unable to modify these inputs if they are made tamper proof as you will see soon.&lt;/p&gt;

&lt;p&gt;The private inputs are &lt;code&gt;secret&lt;/code&gt; and &lt;code&gt;nullifier&lt;/code&gt; , both must be kept private. They are used for nullification and the commit reveal scheme.&lt;/p&gt;

&lt;p&gt;Hidden signals make sure our extra public inputs are unalterable after the proof is created.We create the commitment hasher and assert that the output includes the public inputs. That’s it. The commitment hasher looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma circom 2.0.0;

include "../node_modules/circomlib/circuits/poseidon.circom";

template CommitmentHasher(){
    signal input nullifier;
    signal input secret;

    signal output commitment;
    signal output nullifierHash;


    component commitmentPoseidon = Poseidon(2);

    commitmentPoseidon.inputs[0] &amp;lt;== nullifier;
    commitmentPoseidon.inputs[1] &amp;lt;== secret;

    commitment &amp;lt;== commitmentPoseidon.out;

    component nullifierPoseidon = Poseidon(1);

    nullifierPoseidon.inputs[0] &amp;lt;== nullifier;

    nullifierHash &amp;lt;== nullifierPoseidon.out;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see it combines the inputs and creates new outputs. the commitmentHash is linked to the nullifier, so it’s verifiable that they are related.You could use the commitmentHash for nullification, or keep it like this, it’s up to you. It was designed like this because if you want to have reusable commitments you can add an extra input &lt;code&gt;nonce&lt;/code&gt; to the nullifierHash but keep the commitment as is. That way the owner of the secret can create multiple proofs using the same commitment with a slightly different nullification strategy. It’s useful for account abstraction if you want the account to be reusable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Javascript code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First we look at the library that was scaffolded and then the tests.&lt;/p&gt;

&lt;p&gt;The project depends on &lt;code&gt;ffjavascript&lt;/code&gt;,&lt;code&gt;snarkjs&lt;/code&gt;,&lt;code&gt;circomlib&lt;/code&gt;,&lt;code&gt;circomlibjs&lt;/code&gt;,&lt;code&gt;circom_tester&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;lib/index.js&lt;/code&gt; contains the source code for the client side code.&lt;/p&gt;

&lt;p&gt;First you will the functions for generating circuit inputs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
/**
 * @returns {bigint} Returns a random bigint
 */
export function rbigint() { return utils.leBuff2int(crypto.randomBytes(31)) };

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the inputs, 31 byte sized bigint is used. The reason for 31 bytes is because if we use random 32 bytes it can be higher than the &lt;strong&gt;snark scalar field&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;21888242871839275222246405745257275088548364400416034343698204186575808495617&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and that would make our circuits fail. So 31 bytes for max input. Next you see the hashing implementation which depends on what was selected and the &lt;code&gt;computeProof&lt;/code&gt; and &lt;code&gt;verifyProof&lt;/code&gt;functions that call snarkjs&lt;/p&gt;

&lt;p&gt;&lt;code&gt;test/input.js&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Creating the input for a circuit is very important part of development. This file will be called when the unit tests run and also during hot reload.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import { rbigint, generateCommitmentHash, generateNullifierHash,buildHashImplementation } from "../lib/index.js";

/**
 * This is a test input, generated for the starting circuit.
 * If you update the inputs, you need to update this function to match it.
 */
export async function getInput(){
    await buildHashImplementation();

    const secret = rbigint();
    const nullifier = rbigint();

    let address = rbigint();
    let amount = rbigint();

    const commitmentHash = await generateCommitmentHash(nullifier, secret);
    const nullifierHash = await generateNullifierHash(nullifier);

    return {secret, nullifier, nullifierHash,commitmentHash,address,amount}
}

// Assert the output for hotreload by returning the expected output
// Edit this to fit your circuit
export async function getOutput() {
    return { out: 0 }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;getInput()&lt;/code&gt; function defines our circuit input and the &lt;code&gt;getOutput&lt;/code&gt; function is used for output assertion when running &lt;code&gt;niftyzk dev&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let’s see what’s going on. First we build the hash implementation. It’s because all implementations are wasm and need to be built first. The built wasm is cached for reuse.&lt;/p&gt;

&lt;p&gt;Then we assign random numbers for inputs, compute the hashes and return them. The return values are a mix of private and public inputs and they are fed to the circuit directly.&lt;/p&gt;

&lt;p&gt;The current circuit template doesn’t have output signals, so the &lt;code&gt;getOutput&lt;/code&gt; function is not implemented. You should return values you expect here after changing your circuit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Merkle tree&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now let’s take a look at a commit-reveal scheme with a merkle tree&lt;/p&gt;

&lt;p&gt;&lt;code&gt;niftyzk init&lt;/code&gt; will can rebuild the current project into a new one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Setting up your current directory
? What project do you want to scaffold? Commit-Reveal Scheme with Fixed Merkle Tree
? 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

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s set up one with poseidon hash and merkle tree&lt;/p&gt;

&lt;p&gt;You will see that the &lt;code&gt;commitment_hasher.circom&lt;/code&gt; file stayed the same but the &lt;code&gt;circuits.circom&lt;/code&gt; changed and there is a new &lt;code&gt;merkletree.circom&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;include "./commitment_hasher.circom";
include "./merkletree.circom";

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

    signal input root;
    signal input pathElements[levels]; // The merkle proof which is fixed size, pathElements contains the hashes
    signal input pathIndices[levels]; // Indices encode if we hash left or right
    // 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 &amp;lt;== nullifier;
    commitmentHasher.secret &amp;lt;== 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 &amp;lt;== address * address;
    amountSquare &amp;lt;== amount * amount;


    // Check if the merkle root contains the commitmentHash!
    component tree = MerkleTreeChecker(levels);

    tree.leaf &amp;lt;== commitmentHasher.commitment;
    tree.root &amp;lt;== root;

    for (var i = 0; i &amp;lt; levels; i++) {
        tree.pathElements[i] &amp;lt;== pathElements[i];
        tree.pathIndices[i] &amp;lt;== pathIndices[i];
    }


}

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


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So quite a few things changed. We got new public and private inputs and new templates.&lt;/p&gt;

&lt;p&gt;So first we have the merkle tree &lt;code&gt;root&lt;/code&gt; as a new public input and &lt;code&gt;pathElements&lt;/code&gt; and &lt;code&gt;pathIndices&lt;/code&gt;, these contain the merkle proof. The &lt;code&gt;levels&lt;/code&gt; variable taken specifies the size of the merkle tree, the default 20 will give a lot of branches to work with.&lt;/p&gt;

&lt;p&gt;The new template we use is the &lt;code&gt;MerkleTreeChecker&lt;/code&gt; and we just assign the signals to it’s inputs. The MerkleTreeChecker will assert correctness. It’s assumed that the commitment is one of the leaves and the merkle proof is used for proving it. The &lt;code&gt;pathElements&lt;/code&gt; contain the leaves and the &lt;code&gt;pathIndices&lt;/code&gt; specify if we hash left or right.&lt;/p&gt;

&lt;p&gt;Let’s see the other file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma circom 2.0.0;

include "../node_modules/circomlib/circuits/poseidon.circom";

template HashLeftRight(){
  signal input left;
  signal input right;
  signal output hash;

  component poseidonHash = Poseidon(2);

  poseidonHash.inputs[0] &amp;lt;== left;
  poseidonHash.inputs[1] &amp;lt;== right;

  hash &amp;lt;== poseidonHash.out;
}



// if s == 0 returns [in[0], in[1]]
// if s == 1 returns [in[1], in[0]]
template DualMux() {
    signal input in[2];
    signal input s;
    signal output out[2];

    s * (1 - s) === 0;
    out[0] &amp;lt;== (in[1] - in[0])*s + in[0];
    out[1] &amp;lt;== (in[0] - in[1])*s + in[1];
}


// Verifies that a merkle proof is correct for given root and leaf
// pathIndices input in an array of 0/1 selectors telling whether 
// given pathElement is on the left or right side of the merkle path
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] &amp;lt;== leaf;

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

        selectors[i].in[1] &amp;lt;== levelHashes[i - 1];
        selectors[i].in[0] &amp;lt;== pathElements[i];
        selectors[i].s &amp;lt;== pathIndices[i];

        hashers[i].left &amp;lt;== selectors[i].out[0];
        hashers[i].right &amp;lt;== selectors[i].out[1];

        levelHashes[i] &amp;lt;== hashers[i].hash;
    }

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

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay, so quite a few things going on. Let me explain.&lt;/p&gt;

&lt;p&gt;First we have a hasher that hashes leaves from left to right. It’s uses the implementation we selected.&lt;/p&gt;

&lt;p&gt;After this the &lt;code&gt;DualMux&lt;/code&gt; is a Multiplexer that will just swap inputs. It works based on &lt;code&gt;pathIndices&lt;/code&gt; and aligns the &lt;code&gt;pathElements&lt;/code&gt; correctly so we can hash left to right for all cases.&lt;/p&gt;

&lt;p&gt;The merkle tree checker takes inputs and computes the merkle &lt;code&gt;root&lt;/code&gt; by combining &lt;code&gt;pathElements&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I hope this saves you a lot of time developing your circuits.now lets jump to javascript:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;lib/merkletree.js&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The important changes you will find in a new file, merkletree.js which now contains functions to work with merkle trees.It’s zero extra dependency and everything is implemented from scratch. You can run it in any environment.&lt;/p&gt;

&lt;p&gt;You will see new functions to call, &lt;code&gt;generateMerkleTree&lt;/code&gt;,&lt;code&gt;generateMerkleProof&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You need to supply an array of leaves which are commitments and call &lt;code&gt;generateMerkleTree&lt;/code&gt; to obtain the tree. Once you have a commitment you want to create a proof for, you can call &lt;code&gt;generateMerkleProof&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To use the merkle proof as pathElements and pathIndices you call &lt;code&gt;encodeForCircuit&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important!&lt;/strong&gt; Trees with uneven leaves are padded! The padding works by duplicating the last branch. This means that the merkle tree contains duplicate leaves but it never contains zeros. Other padding methods could pad with zeroes, so could use the hash(0) for a leaf, that implementation would be insecure on the blockchain.Every uneven level is padded. If we have 9 leaves on the first level, then the last leaf is duplicated etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Merkle tree commands&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;lib/run.js&lt;/code&gt; contains that gives you 3 commands, new, proof, verify, you can access them using npm also.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm run new&lt;/code&gt; will create a new merkle tree with a similar output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATING A NEW MERKLE TREE

Enter how many secrets would you like to generate:
8
Generating secrets and hashing commitments. Please wait!
Done
Generating merkle tree from commitments!
Done.Root is 9399890428704023149822996752765634449585627060469866502272705510954136382993 
Serializing data.
Writing to file.
Done

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you will see it created a &lt;code&gt;private&lt;/code&gt; and a &lt;code&gt;public&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;The public directory contains the merkle tree and commitment hashes, nullifier hashes and the private contains secrets used to compute them.The files are named using the root hashes.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm run proof&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The command will ask you for a root hash and a commitment to verify. It will split out a JSON which contains the merkle proof. I do not copy it here due to it’s size.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm run verify&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command will ask you for the merkle root and the proof and verifies the proof.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You are free to modify the merkle tree tooling to adjust it to work with your circuits&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>web3</category>
      <category>circom</category>
      <category>cosmwasm</category>
      <category>zkp</category>
    </item>
    <item>
      <title>Niftyzk tutorials 1</title>
      <dc:creator>Peter Horvath</dc:creator>
      <pubDate>Sat, 11 Jan 2025 03:53:14 +0000</pubDate>
      <link>https://dev.to/strawberry666/niftyzk-tutorials-1-4i5e</link>
      <guid>https://dev.to/strawberry666/niftyzk-tutorials-1-4i5e</guid>
      <description>&lt;p&gt;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&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/NiftyZk/niftyzk" rel="noopener noreferrer"&gt;https://github.com/NiftyZk/niftyzk&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Niftyzk is a scaffolding tool and circom development framework with first class support for CosmWasm.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;br&gt;
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 :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.circom.io/getting-started/installation" rel="noopener noreferrer"&gt;https://docs.circom.io/getting-started/installation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To install niftyzk, install it straight from github&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install -g git+https://github.com/NiftyZk/niftyzk.git&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will install it and the &lt;code&gt;niftyzk&lt;/code&gt; command will be available from the command line.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;niftyzk --version&lt;/code&gt; to verify the installation, it should output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ niftyzk --version

0.1.4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The help page should show the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;niftyzk init [folder]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;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&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;? Choose the hashing algorithm to use:  (Use arrow keys)
❯ mimc7
  mimcsponge
  pedersen
  poseidon
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;? Do you wish to add tamperproof public inputs? (E.g: walletaddress):  (y/N)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;? Do you wish to add public inputs to sign? (E.g: address,amount) (y/N)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;When you have completed the scaffolding process you need to &lt;code&gt;npm install&lt;/code&gt; the dependencies and ready to start iterating on your circuit.&lt;/p&gt;

&lt;p&gt;The contents of the scaffolded projects will be explained in another tutorial, for now we move on to the other commands.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;niftyzk dev&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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 &lt;code&gt;/test/input.js&lt;/code&gt; file, which must export a &lt;code&gt;getInput()&lt;/code&gt; function that will be called by the hot reload. The output of the circuit can be asserted by passing the &lt;code&gt;--assertout&lt;/code&gt; flag. The output must be implemented in the &lt;code&gt;getOutput()&lt;/code&gt; function in the input.js file. This allows you to iterate compile and test the circuit as you develop it.You can use &lt;code&gt;log();&lt;/code&gt; inside your circuits for debugging. If you run it with the optional &lt;code&gt;--verbose&lt;/code&gt; flag, more debugging information will be available.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;niftyzk ptaufiles&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Usage: niftyzk ptaufiles [options]

Display information and download ptau files

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

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Example file to select&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;powersOfTau28_hez_final_15.ptau
blake2b hash: 982372c867d229c236091f767e703253249a9b432c1710b4f326306bfa2428a17b06240359606cfe4d580b10a5a1f63fbed499527069c18ae17060472969ae6e
Power: 15, Max Constraints: 32K
Size: 36.08 MiB
Supports built in ceremony server: YES
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;niftyzk compile&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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 &lt;code&gt;circuits/compiled&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;niftyzk ceremony&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;niftyzk vkey&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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&lt;/p&gt;

&lt;p&gt;&lt;code&gt;niftyzk finalize&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;niftyzk gencontract&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Checking the generated contracts:&lt;br&gt;
Install the wasm rust compiler backend: &lt;code&gt;rustup target add wasm32-unknown-unknown&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;cargo test&lt;/code&gt; to run the generated tests&lt;/p&gt;

&lt;p&gt;Build the contracts using &lt;code&gt;cargo wasm&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Verify the contract.wasm using the cosmwasm-check utility &lt;code&gt;cargo install cosmwasm-check&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cosmwasm-check ./target/wasm32-unknown-unknown/release/contract.wasm&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And you are done, you created a verifier for a cosmwasm contract from your circuit&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;The development pipeline could be drawn with the graph as :&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fms4g7ikhgmkpvy2whmcz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fms4g7ikhgmkpvy2whmcz.png" alt="Niftyk development flow visualized" width="673" height="697"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>circom</category>
      <category>cosmwasm</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Introducing Niftyzk</title>
      <dc:creator>Peter Horvath</dc:creator>
      <pubDate>Fri, 10 Jan 2025 23:21:11 +0000</pubDate>
      <link>https://dev.to/strawberry666/introducing-niftyzk-2ekd</link>
      <guid>https://dev.to/strawberry666/introducing-niftyzk-2ekd</guid>
      <description>&lt;p&gt;Niftyzk is a circom development tool and framework that targets CosmWasm ecosystem supporting groth-16 proofs with bn128 curve.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/NiftyZk/niftyzk" rel="noopener noreferrer"&gt;https://github.com/NiftyZk/niftyzk&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project scaffolding&lt;/strong&gt;&lt;br&gt;
Initialize a new project niftyzk init and select from the available templates, the generated code can be configured based on the verification schemes selected. There is support for Poseidon, Pedersen, MiMC and MiMCSponge hashing functions and additional circuit inputs. Niftyzk generates code instead of cloning a repository, so you get the benefit of configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Javascript library&lt;/strong&gt;&lt;br&gt;
A library will be generated for you with all functions required to interact with the circuits and merkle tree. The javascript is isomorphic and typed using JSDoc so you can run it in the browser and server without modification and use it with Typescript.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hot reload&lt;/strong&gt;&lt;br&gt;
Develop your circom circuits using hot reload. niftyzk devIterative development allows you to debug and update your circuits without recompiling them each time which is time consuming. The circuits are rebuilt and the outputs are asserted. Niftyzk expects the circuit inputs and output asserts defined in an input.js file, which allows you to keep your business logic to generate inputs neat and fully tested during development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Powers of Tau&lt;/strong&gt;&lt;br&gt;
The powers of tau ceremony is essential for zero knowledge proof circuits for security. niftyzk ptaufilesThe phase 1 ceremony is reusable hence we can use the Polygon Hermez ceremony files. The files are available to download from the CLI with a simple command&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compilation&lt;/strong&gt;&lt;br&gt;
niftyzk compile uses circom compiler for compilation and so depends on Rust and requires circom to be installed. It wraps and abstracts away complex commands and makes compiling straight forward&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verification Keys&lt;/strong&gt;&lt;br&gt;
The compiled circuits require the exporting of verification keys, these keys are used for testing in deployment. niftyzk vkey&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase-2 ceremony&lt;/strong&gt;&lt;br&gt;
The built in ceremony server allows you to host a phase-2 ceremony.Invoking the command niftyzk ceremony will start up a server that hosts a contribution page.The contribution is anonymous and the contributors are queued using websockets. The project at this stage can be deployed on a VPS using Git and the ceremony can be hosted there.The ceremony server only supports smaller PTAU files due to the netwoking, each client needs to download it to make a contribution.Only a single contributor to the phase-2 ceremony needs to be honest for the process to work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Finalization&lt;/strong&gt;&lt;br&gt;
After the ceremony we can finalize the circuit, this means we can’t update our circuits anymore and it will be ready for deployment. niftyzk finalize expects a --beacon argument which is our random beacon used for finalization. The process wraps snarkjs and simplifies the commands used there. If you want to learn more about it, you can read the snarkjs documentation. After finalization, you will need to export a new vkey&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generate CosmWasm contract&lt;/strong&gt;&lt;br&gt;
And finally we can generate a CosmWasm verifier contract for the circuit. niftyzk gencontact You can generate it before finalization for testing your smart contracts, it requires passing unit tests and the verification key to generate the contract.The gencontract command expects an argument for the Rust library used, which can be Arkworks or Bellman. The Bellman requires an adapter which will be generated in javascript for you.Check the readme for verifying cosmwasm contracts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full test coverage&lt;/strong&gt;&lt;br&gt;
All generated code contains full test coverage, including the CosmWasm contracts. Niftyzk supports test based development and runtime assertions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Support&lt;/strong&gt;&lt;br&gt;
You can support this project by using it. Open a issue if you encounter any errors. This is a public good and available for quadratic funding in the Atom Economic Zone, you can contribute Atom on dorahacks&lt;br&gt;
&lt;a href="https://dorahacks.io/buidl/14323" rel="noopener noreferrer"&gt;https://dorahacks.io/buidl/14323&lt;/a&gt;&lt;/p&gt;

</description>
      <category>circom</category>
      <category>cosmwasm</category>
      <category>blockchain</category>
      <category>web3</category>
    </item>
  </channel>
</rss>
