Skip to main content
Version: V3


What is Semaphore?​

Semaphore is a zero-knowledge protocol that allows users to prove their membership in a group and send signals such as votes, feedback, or text messages without revealing the user’s identity.

This means that signals have no connection to the identities.

It also provides a simple mechanism to prevent double-signaling, which means you cannot verify the same proof twice.

Where can I ask questions about Semaphore?​

You can ask questions about Semaphore on Discord or by opening a Semaphore Discussion.

Why do identities require both the identity trapdoor and the identity nullifier?​

Having two private values provides an additional security layer. If someone breaks the nullifier hash (imagine there is some malleability that Poseidon preimage is easy to find when hashed with specific value X, which is the external nullifier chosen by devs), the attacker can find all messages the same person sent, but they cannot find which person, because there is also the trapdoor, which could be more difficult to break.

What is the difference between the identity nullifier, external nullifier and nullifier hash?​

The identity nullifier is one of the user's secret values, whereas the external nullifier can be used like a topic on which users can generate a valid proof (e.g. send anonymous votes) a limited number of times.

Both the identity nullifier and the external nullifier are used to prevent the same proof from being verified twice, which means that if a user generates the same proof (with same identity and same external nullifier) twice, the second one will not be valid.

Finally, the nullifier hash is just the hash of the identity nullifier and the external nullifier which is used to check if the same proof has already been generated.

In the case of a voting application, if you have a group and you want all members of this group to vote only once, you can use the id of the group as an external nullifier. When a user votes the first time, you can save the hash of their identity nullifier and the group id (i.e. the nullifier hash) and prevent double-voting by checking if that hash already exists.

See the Semaphore circuits for more technical information, or the Semaphore boilerplate for a real use-case.

Why should I prevent proofs from being verified twice?​

Since zero-knowledge proofs are completely anonymous, it is important to prevent those generated by eligible identities from being reused by a malicious party.

In an anonymous voting application for example, without any checks, a valid proof could be reused to vote again.

Where can I find examples of applications using Semaphore?​

You can find some applications that are using Semaphore in this blog post.

How can I start a project using Semaphore?​

There are three ways you can start using Semaphore in your project: using the Semaphore CLI, using the Semaphore boilerplate as a template or forking it, or installing the Semaphore packages manually.

Semaphore CLI​

To create a new project you could use npx or install the Semaphore CLI globally using npm and then create the new project using the semaphore create command. See the Quick Setup for more information.

There are three supported templates right now: contracts-hardhat, monorepo-ethers and monorepo-subgraph.

  • contracts-hardhat: It contains a basic Semaphore use case. It comes with a sample contract, a test for that contract and a sample task that deploys that contract.
  • monorepo-ethers: It is a complete application that demonstrates a basic Semaphore use case. It comes with a sample contract, a test for that contract and a sample task that deploys that contract. It also contains a frontend to play around with the contract. This template uses Ethers under the hood to get on-chain data.
  • monorepo-subgraph: It is the same as the monorepo-ethers template, but uses The Graph protocol under the hood to get on-chain data.

The Semaphore CLI can also be used to get group data from a supported network. There are commands like: get-groups, get-group, get-members, get-proofs:

  • get-groups: It shows the list of groups from a supported network.
  • get-group: It shows the data of a group from a supported network.
  • get-members: It shows the members of a group from a supported network.
  • get-proofs: It shows the proofs of a group from a supported network.

Semaphore boilerplate​

To create a project, you could also use the Semaphore boilerplate. You could fork it or use it as a template.

The Semaphore CLI templates and the Semaphore boilerplate contain the same code, which is a feedback application where you can create an identity, join a group, and send your feedback anonymously. They are almost the same, the only difference is that the templates use plain CSS so you can decide the CSS framework or library you want to use and the boilerplate uses ChakraUI by default.

You can also try the live Semaphore boilerplate app here:

Manual install​

Alternatively, you can also install all packages manually using npm or yarn following the Semaphore documentation.

How can I contribute to the protocol?​

There are several ways you could contribute to the protocol, you can find more information about it here: