Groth16 proofs are very popular and are used by many protocols in production.

Overview

Geometry presents: the Groth16 Malleability Challenge

Preamble

Groth16 proofs are very popular and are used by many protocols in production. Libraries such as snarkjs and ark-groth do a good job abstracting proof systems and providing a nice interface for writing circuits. Nevertheless in order to write sound and safe protocols, it's very important to understand deeper cryptographic concepts.

The challenge

When learning about cryptographic protocols, it's extremely valuable to learn about potential attacks and problems, and the best way to learn is by attempting. To that end, Geometry Research is conducting The Groth16 Malleability Challenge. Any intrepid hackers who complete this challenge will earn a special NFT sponsored by Geometry. We provide a modified version of snarkjs which makes malleable proofs possible; your task is to modify a proof such that it remains valid but one of its public inputs differs.

Criteria

There is a challenge contract deployed at 0x4af905A972eab5020F965889EAd5bB4a20c1C2c3 on the Ethereum mainnet. It exposes a solve() function which accepts a Groth16 proof. The proof corresponds to the circuit described below. solve() will call a verifier function which will use the caller's Ethereum address as the first public input a.

If the verification passes, the contract will mint a non-transferable prize NFT to the caller.

The circuit

The circuit code can be found here: circuits/circuit.circom.

All zkey files are already in build/snark/circuit folder, so please do not build it again, as it will make it incompatible with the verifying key in the contract.

snarkjs modifications

This puzzle cannot be solved without tiny modifications to snarkjs. If you take a closer look in dependency section of package.json you'll see that this snarkjs fork is used and it only differs in one line:

diff --git a/build/main.cjs b/build/main.cjs
index 00e6965..ef1bd6f 100644
--- a/build/main.cjs
+++ b/build/main.cjs
@@ -4328,7 +4328,8 @@ async function newZKey(r1csName, ptauName, zkeyName, logger) {
             }
         }
 
-        for (let s = 0; s <= nPublic ; s++) {
+//         for (let s = 0; s <= nPublic ; s++) {
+        for (let s = 0; s < 1 ; s++) {
             const l1t = TAU_G1;
             const l1 = sG1*(r1cs.nConstraints + s);
             const l2t = BETATAU_G1;

That's correct — with a modification to only one line, malleable proofs can be crafted.

Submitting your proof

In src/solution.js there is a template for creating a malleable proof. You can run it with npm run solve. As expected, it fails, and your task will be to make it work.

Step 1: Make sure that the wallet address you put in:

const new_a = BigInt("PUT_YOUR_ADDRESS_HERE");

matches the address you plan to submit proof with!.

Step 2: Do some magic on proof such that script runs with no errors and you will get output like this:

[9033671481509310303480432375584986467146091997413160063526744094065848123115,1134048701020180641101291596483848464593285629853388726406614166877915275766,9735231883876420451920486462692839352481483823164847775245009097080002888605,18840452748006100068490126604883025783982577474616558019215463905727488555872,10499146114916491429815578549277100422153716639543017208844093487768363764387,7254171176247254130704409555297684571142738087816156016743992872816776219110,19434752999601924861048365747389278784362237409704016406266170338427127573370,2667505953663721770463958924381297083990119574041705395843873986309548427123]

Next, navigate to the verifier contract page on Etherscan, connect your web3 wallet (using the account whose address is the first public input), and submit the above formatted proof to the solve() textbox. Click on "Write" to submit your transaction.

If your transaction succeeds, you will receive a non-transferable prize NFT. Congratulations!

Refund Policy

When you invoke the contract's solve() function via a transaction, the contract will provide a gas refund.

    // Perform the gas refund
    // 28521 was estimated using Remix
    uint256 gasSpent = gasBefore - gasleft() + 28521;
    address payable sender = payable(msg.sender);

    uint gaspice = tx.gasprice < refundingGasPrice ? tx.gasprice : refundingGasPrice;
    sender.transfer(gasSpent * gaspice);

Just make sure that gasprice you specify is no larger than refundingGasPrice in the contract. This is the upper bound that we are willing to refund. Please also note that if there is high volatility in gas prices, just be patient. We will make sure to adapt refundingGasPrice such that your transaction gets executed as quickly as possible.

You might also like...

This blog is still under development! I present a project scope for science articles, it can now be used in production! But there are some details that need to be put up front.

Science-Blog 🛑 Attention! This blog is still under development! I present a project scope for science articles, it can now be used in production! But

Sep 19, 2022

This project is used to extract media from various posting platfroms like Twitter, Reddit, Pixiv, Youtube and many other

Social-Picker-API This project is used to extract media from various posting platfroms like Twitter, Reddit, Pixiv, Youtube and many others. It's writ

Nov 29, 2022

Prototype of real-time comments and a proposal of how to make it "production-ready".

Prototype of real-time comments and a proposal of how to make it

Real-time comments prototype Simple demonstration of real-time commenting. Installation After forking it, run npm install, then you need two environme

Jan 16, 2022

A highly opinionated and complete starter for Next.js projects ready to production

A highly opinionated and complete starter for Next.js projects ready to production

The aim for this starter is to give you a starting point with everything ready to work and launch to production. Web Vitals with 100% by default. Folder structure ready. Tooling ready. SEO ready. SSR ready.

Nov 27, 2022

The most advanced responsive front-end framework in the world. Quickly create prototypes and production code for sites that work on any kind of device.

The most advanced responsive front-end framework in the world. Quickly create prototypes and production code for sites that work on any kind of device.

Install | Documentation | Releases | Contributing Foundation is the most advanced responsive front-end framework in the world. Quickly go from prototy

Jan 4, 2023

this is a single-page web application. we built a book website where the user can add , remove and display books. we used modules to implement these functionalities. also, we used the Date class to display the date and time.

Awsome Books In this Project, we have built A Books websites. Built With 🔨 HTML CSS javascript Git & Github Live Demo Here you can find the live Demo

Aug 3, 2022

The world of cryptocurrencies is diverse and becoming more and more popular

The world of cryptocurrencies is diverse and becoming more and more popular

We are providing an user with a simple learning resource for an intro into the CryptoCurrency World. Along with a community grown message board to assist with further learning.

Jun 20, 2022

The high efficent browser driver on top of puppeteer, ready for production scenarios.

The high efficent browser driver on top of puppeteer, ready for production scenarios.

browserless is an efficient driver for controlling headless browsers built on top of puppeteer developed for scenarios where performance matters. High

Jan 6, 2023

Portfolio for Intro to Photography/Digital Media Production

This is a Next.js project bootstrapped with create-next-app. Getting Started First, run the development server: npm run dev # or yarn dev Open http://

May 26, 2022
Owner
Geometry
Geometry
This Next.js app is designed to be used with the Figment Learn Pathways, to help developers learn about various blockchain protocols such as Solana, NEAR, Secret, Polygon and Polkadot!

???? What is learn-web3-dapp? We made this decentralized application (dApp) to help developers learn about Web 3 protocols. It's a Next.js app that us

t0nto 8 Oct 1, 2022
Vite plugin to client bundle i18next locales composited from one to many json/yaml files from one to many libraries. Zero config HMR support included.

vite-plugin-i18next-loader yarn add -D vite-plugin-i18next-loader Vite plugin to client bundle i18next locales composited from one to many json/yaml f

AlienFast 4 Nov 30, 2022
A workshop about JavaScript iteration protocols: iterator, iterable, async iterator, async iterable

JavaScript Iteration protocol workshop A workshop about JavaScript iteration protocols: iterator, iterable, async iterator, async iterable by @loige.

Luciano Mammino 96 Dec 20, 2022
Solidity NFT whitelist contract example using MerkleTree.js for constructing merkle root and merkle proofs.

MerkleTree.js Solidity NFT Whitelist example Allow NFT minting only to whitelisted accounts by verifying merkle proof in Solidity contract. Merkle roo

Miguel Mota 65 Dec 29, 2022
Node.js module for verifying Plumo proofs and reading states based on it

plumo-verifier Node.js module for verifying Plumo proofs and reading states based on it. Plumo is a SNARK-based light client verifier for the Celo blo

Celo 3 Dec 15, 2022
The zkPass browser extension can proxy three parties TLS and generate zero-knowledge proofs

zkPass Extension zkPass a Chromium extension which can proxy three parties TLS and generate zero-knowledge proofs. Technology Dependence Multi-party c

zkPass 9 Nov 1, 2022
Dapp example for airdropping ERC-20 tokens using World ID, preserving privacy for the claimers with zero-knowledge proofs.

World ID Example - Mesha Airdrop This repository contains an example decentralized application (dapp) for World ID. With Mesha Airdrop test airdroppin

Worldcoin 14 Dec 16, 2022
2FA with Zero-Knowledge proofs

zkAuth ??️ ?? Zero-Knowledge protected onchain two-factor Authentication This project provides 2FA for EVM blockchains, compatible with the broadly ad

Daniel Contreras Salinas 22 Dec 26, 2022
An exercise in building a very minimal (and very stupid) in-memory SQL-like database for educational purposes.

Stupid Database This is an exercise in building a very minimal (and very stupid) in-memory SQL-like database for educational purposes. None of this co

Fabio Akita 196 Dec 20, 2022
A Very Good Documentation Site created by the Very Good Ventures Team 🦄

Very Good Docs Site Developed with ?? by Very Good Ventures ?? A Very Good Docs Site created by the Very Good Ventures Team. Generated by the Very Goo

Very Good Open Source 8 Nov 2, 2022