Introduction

Semaphore is a zero-knowledge protocol that allows you to cast a message (for example, a vote or endorsement) as a provable group member without revealing your identity. Additionally, it provides a simple mechanism to prevent double-signaling. Use cases include private voting, whistleblowing, anonymous DAOs and mixers. The original Semaphore circuit was written in Circom. For NRG #3, we implemented Semaphore in Noir with the support of Privacy + Scaling Explorations (PSE) and Aztec Labs. We'd like to thank both teams for sponsoring and their valuable feedback and support during the process.

Summary of achieved work

For this project we rewrote the Semphore circuits in Noir and updated the SDK with respect to the Noir circuit. To make the SDK more suitable for the design of Noir, we also updated the snark-artifacts to load the different Noir circuits and verification keys for different use cases. A big part of Semaphore is the Solidity contracts for on-chain verification. For this, we also updated the design of the contracts to provide seamless transition form the original Semaphore verifier contract to the Semaphore Noir one. Details on the design for the circuit, SDK, and contracts are including in the later part of this report.

One new feature we added to Semaphore that is unlocked by Noir is the batching functionality of proofs. In the original Semaphore, every proof must be verified individually. However, with the recursive proofs feature provided by Noir, we can now batch multiple proofs together and only verify the final result once. This feature also works for the on-chain verifier. That means if we have a large amount of proofs to verify on-chain, we don't have to send one transaction for every proof and pay the transaction fee each time. Instead, we can first batch the proofs together off-chain and only call the on-chain verifier once for the final result. The batching functionality could potentially improve the efficiency for some use cases of Semaphore in the future. More details on this can be found in this part of the report.

We updated the benchmark library for Semaphore so users can run it with the updated circuit. The benchmark result can be found here and here for batching. The current result while being slightly slower than Semaphore in Circom, is very comparable in most settings. Thanks to some of our optimization strategies like pre-computing the verification keys and pre-initializing and reusing the proving backends. Some details of the optimization can be found here.

This report

In this report we first walk through the design of Semaphore in Noir and the benchmarks. Then we focus on the batching function and its benchmarks. Finally we give some future research ideas as well as some potential applications for Semaphore Noir. Along with this report, we also provide two tutorials for Semaphore Noir and the batching functions.