# Semaphore proofs

Once a user joins their Semaphore identity to a Semaphore group, the user can signal anonymously with a zero-knowledge proof that proves the following:

- the user is a member of the group,
- the same user created the signal and the proof.

Developers can use Semaphore for the following:

## Generate a proof off-chainâ€‹

Use the `@semaphore-protocol/proof`

library to generate an off-chain proof.
To generate a proof, pass the following parameters to the `generateProof`

function:

`identity`

: the Semaphore identity of the user broadcasting the signal and generating the proof;`group`

: the group to which the user belongs;`externalNullifier`

: the value that prevents double-signaling;`signal`

: the signal the user wants to send anonymously;`snarkArtifacts`

: the`zkey`

and`wasm`

trusted setup files.

In the voting system use case, once all the voters have joined their identities to the ballot group,
a voter can generate a proof to vote for a proposal.
In the call to `generateProof`

, the voting system passes the unique ballot ID (the Merkle tree root of the group) as the
`externalNullifier`

to prevent the voter signaling more than once for the ballot.
The following code sample shows how to use `generateProof`

to generate the voting proof:

`import { generateProof } from "@semaphore-protocol/proof"`

const externalNullifier = group.root

const signal = 1

const fullProof = await generateProof(identity, group, externalNullifier, signal, {

zkeyFilePath: "./semaphore.zkey",

wasmFilePath: "./semaphore.wasm"

})

## Verify a proof off-chainâ€‹

Use the `@semaphore-protocol/proof`

library to verify a Semaphore proof off-chain.
To verify a proof, pass the following to the `verifyProof`

function:

`fullProof`

: the Semaphore proof;`treeDepth`

: the Merkle tree depth.

The following code sample shows how to verify the previously generated proof:

`import { verifyProof } from "@semaphore-protocol/proof"`

await verifyProof(fullProof, 20) // true or false.

`verifyProof`

returns a Promise that resolves to `true`

or `false`

.

## Verify a proof on-chainâ€‹

Use the `Semaphore.sol`

contract to verify proofs on-chain.

See our deployed contracts to find the addresses for your network.

To verify Semaphore proofs in your contract, import `ISemaphore.sol`

, pass it the `Semaphore.sol`

address and call the `verifyProof`

method with following parameters:

`groupId`

: the identifier of the group;`merkleTreeRoot`

: the root of the Merkle tree;`signal`

: the signal the user wants to send anonymously;`nullifierHash`

: a nullifier hash;`externalNullifier`

: the value that prevents double-signaling;`proof`

: a Solidity-compatible Semaphore proof.

You can import `ISemaphore.sol`

and other Semaphore contracts from the `@semaphore-protocol/contracts`

NPM module.