Continuum is a background checker using Zero Knowledge proof. This project is a proof of concept to showcase how revealing your data works with zero knowledge proof.
testnet page: https://continuum-swart.vercel.app/
mainnet page: https://continuum.tomoima525.com/
- Retrieves data from github. This will be stored only locally.
- Users can selectively reveal data from Github.
- A commitment hash which is the combination of user's signature and data to reveal is inserted to MerkleTree.
- It does not represent any personal data. Currently MerkleTree is stored on AWS using DynamoDB.
- Users can mint NFT to prove the data they revealed.
- Continuum generates MerkleProof from MerkleTree
- On the client side, users generate a zkSNARK proof using the MerkleProof
- Users submit the proof to the contract. Once verified, NFT will be issued.
You can find more details on https://speakerdeck.com/tomoima525/continuum-background-checker-with-zero-knowledge-proof or https://www.youtube.com/watch?v=bco4cvXuQUE
Call yarn install --ignore-engines
at the root of the project. (ipfs contains node v16. It is used in Lambda but not required for the whole project)
- Create a new github app at https://github.com/settings/apps
- Note app id and secret
This project uses AWS. You need to setup your AWS account which has an access to at least CDK, Lambda, DynamoDB, SecretManager.
-
aws profile setup
- Open
packages/cdk/package.json
and"cdk": "cdk --profile={your aws profile name}"
- Open
-
Secret key
- Go to https://us-west-2.console.aws.amazon.com/secretsmanager/home and create
continuum_github_key_local
for local andcontinuum_github_key_dev
for dev. Key should bePK
and value should be the github app secret key that you created
- Go to https://us-west-2.console.aws.amazon.com/secretsmanager/home and create
-
redirect url and github client id
- Open https://github.com/tomoima525/continuum/blob/main/packages/cdk/lib/auth-lambda-stack.ts#L36 and update GITHUB_CLIEND_ID and REDIRECT_URL(your dev app. If it's localhost you don't need this)
-
Run
yarn cdk deploy
from/packages/cdk
and see if everything is deployed.
- Rename local.env.sample to local.env and set your backend setup
- Run
yarn run dev
You can create your own Verifier Contract with different MerkleTree depth.
Step1. Seeding
- Seed Zero hashes and group
yarn ts-node ./seedZeroHashes.ts
yarn ts-node ./seedGroups.ts
Step2. Generate input.json
We'll generate input.json
from the actual input. We need values below.
Signal | Detail | Visibility |
---|---|---|
identityTrapdoor | Generated by signature + groupId | Private |
identityNullifier | Generated by signature + groupId | Private |
treePathIndices[nLevels] | path indices of the leaf | Private |
treeSiblings[nLevels] | siblings for MerkleProof | Private |
signalHash | arbitrary byte32 value("continuum") | Public |
externalNullifier | groupId as bigInt | Public |
Expected Output is root
and nullifierHash
which are generated by inputs above
Sample input can be found under /packages/hardhat/scripts
. It is generated with the command below. Make sure to update MERKLE_TREE_DEPTH
to your expected depth.
$ npx hardhat run ./scripts/generateSnarkInput.ts
Step3. Generate Verifier.sol
Go to /packages/hardhat/circuit
and run the command below to generate Verifier.sol using Groth16
$ circom semaphore.circom --r1cs --wasm --sym
template instances: 144
non-linear constraints: 4582
linear constraints: 0
public inputs: 2
public outputs: 2
private inputs: 34
private outputs: 0
wires: 4603
labels: 14523
// convert r1cs to json
$ snarkjs r1cs export json semaphore.r1cs semaphore.r1cs.json
// Generate witness
$ node generate_witness.js semaphore.wasm ../input.json ../witness.wtns
// Generate final key and export Verifier.sol and verification key
$ yarn ts-node scripts/generateFinalKey.ts
// Generate the proof
$ snarkjs groth16 prove semaphore_final.zkey witness.wtns proof.json public.json
// Verify the proof
$ snarkjs groth16 verify verification_key.json public.json proof.json
[INFO] snarkJS: OK!
// Generate Verifier
snarkjs zkey export solidityverifier semaphore_final.zkey ../contracts/Verifier.sol
// Generate call for Solidity for testing
$ snarkjs zkey export soliditycalldata public.json proof.json
["0x2078cd35aeaee98079cd034a2d5ec44e818f40c02d9218d0b279e4eb0893c7c4", "0x2d046623a90d7bcdcb174a4f7e73dae142d9fc817397334530b9d08f3bf372cd"],[["0x223a070a25bceb0ebafb063fc438338104090866e5b9e0ebc928bda6b471220e", "0x16555996336686fb6e9a528ecf16366312277e675fd162cc6a1c979e52896d43"],["0x02d3a006cd912e75789211e9f11601d2fd0d2ca287465c6fe89b35441af087ed", "0x10249bd8e3ccc341bf0cf317a2be56ee5a71c89fbcf3e49eb6714b7a2d210932"]],["0x2f4c3bd3eed7c8b7a703f46a4c719a2126536a0423095b99e28a5716c5a54d65", "0x211ca97c4f7e4e732b2e0b6ab9c88c08800906a290a7d961c2e3040d07b34987"],["0x2363beff769130fb20e6ebc044963247402b15e539a985cdd1128ff5566b9f2e","0x239bb965e269f6d79442fbaff13689546108b8e1fde2f632ed9e4b23388bd7bb","0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x000000000000000000000000000000006af4841553646671a088d658246d9877"]
After Deploying both Verifier.sol
and Continuum.sol
run the command below.
$ npx hardhat run ./scripts/generateSolidityInput.ts
[0x18ef594835fb0627172ea4e2473c438ca225a74764707f0578c72d5c24016de3,0x0d310cdf6cc22de74da057b527cb12cb3ef22f49e267ab963e31c5b98507c250,0x2cf34d8cfd55d5facc0aa298783a74851837f0050edc5daed87971021196b43b,0x0bc880e103839fa30848a892de9f76c26cde042a8017c51aa779384e43034b7c,0x18a5b9deb0c448d064b7344460a0abdd324463cce5e4385509fa96be0c1b77a5,0x0e515d846e29a11bfbaf1c2eb46a34488b6bb0dcc13b9918407a0db2b1543f85,0x2ff6a28ad37c2e0cca12d11e5539e3150b9c0cacd63942d72c9f35ae10727294,0x1393a5a6e3914b2e6a4bdbe402d1643cd05af0d2e2307bf0d183b6b45c506aa0]
merkleRoot: 0x2363beff769130fb20e6ebc044963247402b15e539a985cdd1128ff5566b9f2e
nullifierHash: 0x239bb965e269f6d79442fbaff13689546108b8e1fde2f632ed9e4b23388bd7bb
externalNullier: 0x6af4841553646671a088d658246d9877
Input values above to test the contract. You need to add ""
to proof inputs ["0x...", "0x...", ..]
or you'll get argument error
Testnet: 0x008150FD2e971857058Ee14254439691edb25490
Mainet: 0x1BBC601bF0b2C87E18561019488318C3C06daC29
TBD