Originally published on Jul 6, 2022:
Semaphore is a zero-knowledge protocol that lets Ethereum users prove their membership of a group and send signals such as votes or endorsements without revealing their original identity. The ability to do these two simple things anonymously opens up a world of possibilities — some of which are already being worked on, some we can’t wait to see explored and hopefully some we haven’t even thought of yet :D.
Semaphore is not a user-facing application, but is designed to provide powerful and simple tools for Ethereum devs to build dapps with private credentials. It was first proposed by Kobi Gurkan, Koh Wei Jie and Barry Whitehat, and V1 was released in 2019.
We’re excited to share that Semaphore V2 has just been released with lots of improvements to the protocol and developer tooling, thanks to extensive contributions by Cedoor and Andrija Novakovic. Contracts have been deployed to Kovan, Goerli and Arbitrum.
Semaphore provides three main functions — creating private identities, adding identities to groups and sending anonymous signals.
There are several public and private values associated with a user’s identity:
Generating a Semaphore identity
The identity trapdoor, identity nullifier and identity secret are generated by the user when they create their Semaphore identity. These values are never revealed on-chain; instead, they are used to create zero knowledge proofs so the user can prove things about themselves publicly without revealing their identity.
Groups are an important concept when we speak about privacy and zero knowledge technologies. They can be thought of as anonymity sets, and are a way to establish necessary trust between a set of participants while letting users keep control over how their identities are stored and used.
In Semaphore, a “group” can mean many things. It might be people who have an account on some platform, employees of a specific company, voters in an election — essentially, any set of individuals who are eligible to participate in something.
For example, you might require an email address from a particular university in order to join a group. Rather than storing that email in a database and using it to log in, tying all of their activity to their identity, a user proves only that they have the credential. There is no stored record of which email address was used. Members of the group can be confident that they are interacting with fellow students or colleagues, even though individual identities are unknown.
Adding members to a Semaphore group
When a user joins a group, their public identity commitment is added to that group’s Merkle tree. This lets the protocol check that the user is in the group and is therefore eligible to send signals, without seeing their identity.
There’s no single approach to groups. Semaphore uses incremental binary Merkle trees, Poseidon hashes and Semaphore identity commitments as tree leaves (more on that later), but different types of Merkle trees, hash functions, or leaf values could theoretically be used. The goal is that Semaphore groups can act as a standard to improve composability and interoperability between protocols and applications in the Ethereum ecosystem.
Signals are signed messages which are broadcast on-chain. They contain an endorsement of some data, such as a vote, along with proofs that:
Each signal also contains a nullifier, which is a hash of the identity nullifier and a public external nullifier. If the nullifier has been used before, the protocol knows that the user has signaled more than once.
The recently-released V2 introduced a number of changes and improvements, including:
There are several apps already using Semaphore.
On a more technical level, Semaphore combines zero knowledge proofs and Ethereum smart contracts.
Zero knowledge proofs are the key to Semaphore’s ability to provide sybil- and spam-resistant private credentials. Every signal sent by a user contains proofs of the user’s group membership and the validity of the signal. Proofs are generated off-chain, and can be verified either on-chain or off-chain.
The secure parameters for these proofs were generated in a trusted setup ceremony which was recently completed with over 300 participants.
The circuit structures how the ZKP inputs and outputs are generated, hashed and verified. It has three main components:
Semaphore includes three types of contracts:
Semaphore will continue to be developed and improved over time. Some potential future directions include:
Improving the developer experience:
Maturing the protocol:
How to get involved
If you want to experiment with Semaphore, the Quick Setup guide and Semaphore Boilerplate are great places to start. Feel free to get in touch with any questions or suggestions, or just to tell us about your experience!
We would also love to hear from developers who are interested in integrating Semaphore into new or existing dapps. Let us know what you’re working on by opening an issue, or get in touch through the Semaphore Telegram group or the PSE Discord.