Name | Verification status | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
OpWorldID_Zero | Unsuccessful L2BEAT has tried the verification procedure and wasn't able to regenerate the onchain verifier. | ||||||||||||||||||||||||||||||
Verifier 0x5eB2…A9FBLast used 1 year agoDescription Semaphore verifier for the ‘phone’ anonymity set. It contains many subverifiers from size 16 to 32, but only the one with size 30 is being actively used. The verification appears as unsuccessful due to circom@2.0.3 not being deterministic when producing the r1cs file.
| Description Semaphore verifier for the ‘phone’ anonymity set. It contains many subverifiers from size 16 to 32, but only the one with size 30 is being actively used. The verification appears as unsuccessful due to circom@2.0.3 not being deterministic when producing the r1cs file.
| ||||||||||||||||||||||||||||||
OpWorldID_One | Unsuccessful L2BEAT has tried the verification procedure and wasn't able to regenerate the onchain verifier. | ||||||||||||||||||||||||||||||
Verifier 0x3D40…47eFLast used 1 year agoDescription Semaphore verifier of size 30 for the ‘orb’ anonymity set. The verification appears as unsuccessful due to circom@2.0.3 not being deterministic when producing the r1cs file.
| Description Semaphore verifier of size 30 for the ‘orb’ anonymity set. The verification appears as unsuccessful due to circom@2.0.3 not being deterministic when producing the r1cs file.
| ||||||||||||||||||||||||||||||
Size 100 Register | Not verified Verification was not performed for this verifier. | ||||||||||||||||||||||||||||||
Verifier 0xb5f2…3258Last used 1 year agoDescription SMTB Register verifier of size 100.
| Description SMTB Register verifier of size 100.
| ||||||||||||||||||||||||||||||
Size 600 Register | Not verified Verification was not performed for this verifier. | ||||||||||||||||||||||||||||||
Verifier 0xFC1c…A1c1Last used 1 year agoDescription SMTB Register verifier of size 600.
| Description SMTB Register verifier of size 600.
| ||||||||||||||||||||||||||||||
Size 1200 Register | Not verified Verification was not performed for this verifier. | ||||||||||||||||||||||||||||||
Verifier 0xE44c…CeF9Last used 1 year agoDescription SMTB Register verifier of size 1200.
| Description SMTB Register verifier of size 1200.
| ||||||||||||||||||||||||||||||
Size 10 Delete | Not verified Verification was not performed for this verifier. | ||||||||||||||||||||||||||||||
Verifier 0xCA7d…bFb1Last used 1 year agoDescription SMTB Delete verifier of size 10.
| Description SMTB Delete verifier of size 10.
| ||||||||||||||||||||||||||||||
Size 100 Delete | Not verified Verification was not performed for this verifier. | ||||||||||||||||||||||||||||||
Verifier 0x43B6…40edLast used 1 year agoDescription SMTB Delete verifier of size 100.
| Description SMTB Delete verifier of size 100.
|
Worldcoin uses two types of circuits: Semaphore to prove the inclusion of a WorldId in the anonymity set, and the Semaphore Merkle Tree Batcher (SMTB) to efficiently insert or delete users from the Semaphore Merkle trees.
Worldcoin uses two semaphore anonymity sets, one called 'orb' (OpWorldID_One), used for verified humans, and the other called 'phone' (OpWorldID_Zero) for verified unique devices. More information can be found here. The two contracts have the same source code and contain multiple verification keys for multiple semaphore verifiers of different sizes, going from size 16 to 32. Currently, only the ones with size 30 are used. An example of a semaphore verification transaction can be found here.
The circuit is written in circom and the keys are generated using the snarkjs library. The semaphore artifacts can be found here.
The procedure is explained for the semaphore circuit of size 30. While, as mentioned, the verifier contains the verification keys for all semaphore sizes from 16 to 32, the verification is always called with size 30 as the param is hardcoded, which can be verified here for OPWorldID_One and here for OPWorldID_Zero. To verify that the value 30 is actually the one used it is sufficient to look at one transaction for each of them. A script that semi-automatically performs the verification process from this point on can be found here. If you perform the verification manually, make sure to install the needed tools with the correct versions, as the verification fails with the latest ones.
From the .circom to the .r1cs file: the circom version used in the original verification key generation process is non deterministic, meaning that a different r1cs file is generated every time the circom file is compiled. A workaround is currently being investigated.
From the .r1cs to the onchain verification keys: download the corresponding r1cs file from the semaphore artifacts. This can be done manually or with the following command:
curl https://storage.googleapis.com/trustedsetup-a86f4.appspot.com/semaphore/semaphore30/semaphore30.r1cs -o semaphore30.r1cs
Then, download the corresponding PPOT:
curl https://storage.googleapis.com/trustedsetup-a86f4.appspot.com/ptau/pot14_final.ptau -o pot14_final.ptau
Finally, we need to download the claimed verification keys:
curl https://storage.googleapis.com/trustedsetup-a86f4.appspot.com/semaphore/semaphore30/semaphore30_final.zkey -o semaphore30_final.zkey
Now we can run snarkjs to verify that the claimed verification keys have been indeed generated from the r1cs and the PPOT:
snarkjs zkv semaphore30.r1cs pot14_final.ptau semaphore30_final.zkey
If the verification is successful, the output will be ZKey Ok!
.
We can now extract the verification keys from the zkey file:
snarkjs zkev semaphore30_final.zkey verification_key30.json
Now it's time to compare the onchain verification keys to the generated ones. Download the corresponding onchain verifier either manually or using the following command using Foundry:
cast etherscan-source 0x3D40F9b177aFb9BF7e41999FFaF5aBA6cb3847eF --etherscan-api-key "${ETHERSCAN_API_KEY}" --chain optimism > SemaphoreVerifier.sol
The _getVerificationKey
function shows how the verification keys are fetched. In particular, the alpha1
, beta2
and gamma2
values are hardcoded in the function (because size-independent) while the delta2
and IC
values are fetched from the VK_POINTS
array depending on the size.
The official verification guide can be found here.
Tool name | Version | Tool docs |
---|---|---|
snarkjs | v0.6.11 | More informationMore info |
circom | v2.0.3 | More informationMore info |