Skip to content

Commit

Permalink
added main dizkus circuit, scripts to generate zkey/vkey, and some ci…
Browse files Browse the repository at this point in the history
…rcom_tester tests
  • Loading branch information
EC2 Default User committed Jun 23, 2022
1 parent 3fdbc3b commit 47f9fa1
Show file tree
Hide file tree
Showing 21 changed files with 1,922 additions and 103 deletions.
105 changes: 2 additions & 103 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,104 +1,3 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
build/
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

# parcel-bundler cache (https://parceljs.org/)
.cache

# Next.js build output
.next

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port
pot*.ptau
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[submodule "circom-ecdsa"]
path = circom-ecdsa
url = https://github.com/0xPARC/circom-ecdsa
[submodule "rapidsnark"]
path = rapidsnark
url = https://github.com/iden3/rapidsnark
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,27 @@
# dizkus-circuits

diZKus standard circuit

## Setup

(from https://github.com/0xPARC/cabal/blob/main/circuits/README.md)

After you clone the repo, from the root of the repo run:
```
git submodule update --init
```

Follow the intructions here to get circom2 (the ZKSnark compiler) installed in your system
https://docs.circom.io/getting-started/installation/

You should probably also install VSCode extension to work with circom.

To install dependencies.
```
yarn
cd circom-ecdsa
yarn
```

Download a Powers of Tau file with `2^21` constraints and copy it into the
`circuits` subdirectory of the project, with the name `pot21_final.ptau`. We do not provide such a file in this repo due to its large size. You can download and copy Powers of Tau files from the Hermez trusted setup from [this repository](https://github.com/iden3/snarkjs#7-prepare-phase-2).
1 change: 1 addition & 0 deletions circom-ecdsa
Submodule circom-ecdsa added at 08c2c9
80 changes: 80 additions & 0 deletions circuits/dizkus.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
pragma circom 2.0.2;

include "../circom-ecdsa/circuits/ecdsa.circom";
include "../circom-ecdsa/circuits/zk-identity/eth.circom";
include "./merkle.circom";

/*
This circuit allows a user to prove membership in a group and
anonymously post a message. They input their public key, a signature
of the message they post, and a merkle tree membership proof in the
group they're looking to post to.
Steps
0) before circuit, verify pubkey is valid
1) verify signature of message with public key
2) get address associated with public key
3) verify address is in group with merkle tree proof
Inputs
- merkle proof (depth d)
- root
- branch
- branch side
- signature verification (encoded with k registers of n bits each)
- signature (r, s)
- msghash
- pubkey
*/
template Dizkus(n, k, d) {
assert(k >= 2);
assert(k <= 100);

signal input root;
signal input pathElements[d];
signal input pathIndices[d];

signal input r[k];
signal input s[k];
signal input msghash[k];
signal input pubkey[2][k];

// Step 1: signature verification
component verifySignature = ECDSAVerifyNoPubkeyCheck(n, k);
for (var i = 0; i < k; i++) {
verifySignature.r[i] <== r[i];
verifySignature.s[i] <== s[i];
verifySignature.msghash[i] <== msghash[i];
for (var j = 0; j < 2; j++) {
verifySignature.pubkey[j][i] <== pubkey[j][i];
}
}
verifySignature.result === 1;

// Step 2: get address associated with public key
// adapted from https://github.com/jefflau/zk-identity
signal pubkeyBits[512];
signal address;
component flattenPubkey = FlattenPubkey(n, k);
for (var i = 0; i < k; i++) {
flattenPubkey.chunkedPubkey[0][i] <== pubkey[0][i];
flattenPubkey.chunkedPubkey[1][i] <== pubkey[1][i];
}
for (var i = 0; i < 512; i++) {
pubkeyBits[i] <== flattenPubkey.pubkeyBits[i];
}
component pubkeyToAddress = PubkeyToAddress();
for (var i = 0; i < 512; i++) {
pubkeyToAddress.pubkeyBits[i] <== pubkeyBits[i];
}
address <== pubkeyToAddress.address;

// Step 3: verify address is in group with merkle tree proof
component verifyMerkleProof = MerkleTreeChecker(d);
verifyMerkleProof.leaf <== address;
verifyMerkleProof.root <== root;
for (var i = 0; i < d; i++) {
verifyMerkleProof.pathElements[i] <== pathElements[i];
verifyMerkleProof.pathIndices[i] <== pathIndices[i];
}
}
46 changes: 46 additions & 0 deletions circuits/merkle.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// from https://github.com/0xPARC/cabal

pragma circom 2.0.1;

include "../circom-ecdsa/node_modules/circomlib/circuits/poseidon.circom";

// if s == 0 returns [in[0], in[1]]
// if s == 1 returns [in[1], in[0]]
template DualMux() {
signal input in[2];
signal input s;
signal output out[2];

s * (1 - s) === 0;
out[0] <== (in[1] - in[0])*s + in[0];
out[1] <== (in[0] - in[1])*s + in[1];
}

// Verifies that merkle proof is correct for given merkle root and a leaf
// pathIndices input is an array of 0/1 selectors telling whether given pathElement is on the left or right side of merkle path
template MerkleTreeChecker(levels) {
signal input leaf;
signal input root;
signal input pathElements[levels];
signal input pathIndices[levels];

component selectors[levels];
component hashers[levels];

signal zeroCheckers[levels+1];
zeroCheckers[0] <== leaf - root;

for (var i = 0; i < levels; i++) {
selectors[i] = DualMux();
selectors[i].in[0] <== i == 0 ? leaf : hashers[i - 1].out;
selectors[i].in[1] <== pathElements[i];
selectors[i].s <== pathIndices[i];

hashers[i] = Poseidon(2);
hashers[i].inputs[0] <== selectors[i].out[0];
hashers[i].inputs[1] <== selectors[i].out[1];
zeroCheckers[i+1] <== zeroCheckers[i] * (hashers[i].out - root);
}

zeroCheckers[levels] === 0;
}
12 changes: 12 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"dependencies": {
"chai": "^4.3.6",
"circom_tester": "^0.0.14",
"mocha": "^10.0.0",
"path": "^0.12.7",
"snarkjs": "git+https://github.com/vb7401/snarkjs.git#fae4fe381bdad2da13eee71010dfe477fc694ac1"
},
"scripts": {
"test": "mocha"
}
}
1 change: 1 addition & 0 deletions rapidsnark
Submodule rapidsnark added at cbe090
18 changes: 18 additions & 0 deletions scripts/1_compile.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash

CIRCUIT_NAME=dizkus_64_4_30
BUILD_DIR="../build/$CIRCUIT_NAME"

if [ ! -d "$BUILD_DIR" ]; then
echo "No build directory found. Creating build directory..."
mkdir -p "$BUILD_DIR"
fi

echo '****COMPILING CIRCUIT****'
start=`date +%s`
set -x
circom "$CIRCUIT_NAME".circom --r1cs --wasm --sym --c --wat --output "$BUILD_DIR"
{ set +x; } 2>/dev/null
end=`date +%s`
echo "DONE ($((end-start))s)"
echo
13 changes: 13 additions & 0 deletions scripts/2_gen_wtns.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash

CIRCUIT_NAME=dizkus_64_4_30
BUILD_DIR="../build/$CIRCUIT_NAME"

echo "****GENERATING WITNESS FOR SAMPLE INPUT****"
start=`date +%s`
set -x
node "$BUILD_DIR"/"$CIRCUIT_NAME"_js/generate_witness.js "$BUILD_DIR"/"$CIRCUIT_NAME"_js/"$CIRCUIT_NAME".wasm sample_input.json "$BUILD_DIR"/witness.wtns
{ set +x; } 2>/dev/null
end=`date +%s`
echo "DONE ($((end-start))s)"
echo
49 changes: 49 additions & 0 deletions scripts/3_gen_chunk_zkey.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/bin/bash

CIRCUIT_NAME=dizkus_64_4_30
BUILD_DIR="../build/$CIRCUIT_NAME"
R1CS_FILE="$BUILD_DIR/$CIRCUIT_NAME.r1cs"
PARTIAL_ZKEYS="$BUILD_DIR"/partial_zkeys
PHASE1=../circuits/pot21_final.ptau

if [ ! -d "$BUILD_DIR"/partial_zkeys ]; then
echo "No partial_zkeys directory found. Creating partial_zkeys directory..."
mkdir -p "$BUILD_DIR"/partial_zkeys
fi

echo "****GENERATING ZKEY 0****"
start=`date +%s`
set -x
../node_modules/.bin/snarkjs groth16 setup "$R1CS_FILE" "$PHASE1" "$PARTIAL_ZKEYS"/"$CIRCUIT_NAME"_0.zkey
{ set +x; } 2>/dev/null
end=`date +%s`
echo "DONE ($((end-start))s)"
echo

echo "****GENERATING ZKEY 1****"
start=`date +%s`
set -x
../node_modules/.bin/snarkjs zkey contribute "$PARTIAL_ZKEYS"/"$CIRCUIT_NAME"_0.zkey "$PARTIAL_ZKEYS"/"$CIRCUIT_NAME"_1.zkey --name="1st Contributor Name" -v
{ set +x; } 2>/dev/null
end=`date +%s`
echo "DONE ($((end-start))s)"
echo

echo "****GENERATING ZKEY 2****"
start=`date +%s`
set -x
../node_modules/.bin/snarkjs zkey contribute "$PARTIAL_ZKEYS"/"$CIRCUIT_NAME"_1.zkey "$PARTIAL_ZKEYS"/"$CIRCUIT_NAME"_2.zkey --name="2nd Contributor Name" -v
{ set +x; } 2>/dev/null
end=`date +%s`
echo "DONE ($((end-start))s)"
echo

# Use merkle root of Vivek + Lakshman MIMC merkle tree
echo "****GENERATING FINAL ZKEY****"
start=`date +%s`
set -x
../node_modules/.bin/snarkjs zkey beacon "$PARTIAL_ZKEYS"/"$CIRCUIT_NAME"_2.zkey "$BUILD_DIR"/"$CIRCUIT_NAME".zkey 12FE2EC467BD428DD0E966A6287DE2AF8DE09C2C5C0AD902B2C666B0895ABB75 10 -n="Final Beacon phase2"
{ set +x; } 2>/dev/null
end=`date +%s`
echo "DONE ($((end-start))s)"
echo
15 changes: 15 additions & 0 deletions scripts/4_gen_vkey.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

CIRCUIT_NAME=dizkus_64_4_30
BUILD_DIR="../build/$CIRCUIT_NAME"
R1CS_FILE="$BUILD_DIR/$CIRCUIT_NAME.r1cs"
PHASE1=../circuits/pot21_final.ptau

echo "****EXPORTING VKEY****"
start=`date +%s`
set -x
../node_modules/.bin/snarkjs zkey export verificationkey "$BUILD_DIR"/"$CIRCUIT_NAME".zkey "$BUILD_DIR"/vkey.json
end=`date +%s`
{ set +x; } 2>/dev/null
echo "DONE ($((end-start))s)"
echo
Loading

0 comments on commit 47f9fa1

Please sign in to comment.