diff --git a/packages/circuits/.eslintignore b/packages/circuits/.eslintignore new file mode 100644 index 0000000..a51367f --- /dev/null +++ b/packages/circuits/.eslintignore @@ -0,0 +1,4 @@ +node_modules +artifacts +cache +coverage \ No newline at end of file diff --git a/packages/circuits/.eslintrc.js b/packages/circuits/.eslintrc.js new file mode 100644 index 0000000..c637783 --- /dev/null +++ b/packages/circuits/.eslintrc.js @@ -0,0 +1,24 @@ +module.exports = { + env: { + browser: false, + es2021: true, + mocha: true, + node: true, + }, + plugins: ["@typescript-eslint"], + extends: [ + "standard", + "plugin:prettier/recommended", + "plugin:node/recommended", + ], + parser: "@typescript-eslint/parser", + parserOptions: { + ecmaVersion: 12, + }, + rules: { + "node/no-unsupported-features/es-syntax": [ + "error", + { ignores: ["modules"] }, + ], + }, +}; \ No newline at end of file diff --git a/packages/circuits/.gitignore b/packages/circuits/.gitignore new file mode 100644 index 0000000..5dc6bb7 --- /dev/null +++ b/packages/circuits/.gitignore @@ -0,0 +1,108 @@ +# ZK artifacts +zk +browser + +# 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 +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 \ No newline at end of file diff --git a/packages/circuits/README.md b/packages/circuits/README.md new file mode 100644 index 0000000..30404ce --- /dev/null +++ b/packages/circuits/README.md @@ -0,0 +1 @@ +TODO \ No newline at end of file diff --git a/packages/rust/circuits/vote_integrity.circom b/packages/circuits/circuits/vote_integrity.circom similarity index 64% rename from packages/rust/circuits/vote_integrity.circom rename to packages/circuits/circuits/vote_integrity.circom index ab9cd0f..f3bdfc9 100644 --- a/packages/rust/circuits/vote_integrity.circom +++ b/packages/circuits/circuits/vote_integrity.circom @@ -1,4 +1,3 @@ -pragma circom 2.0.0; template Vote() { // private @@ -6,4 +5,4 @@ template Vote() { vote === 0 || 1; } -component main = Vote(); \ No newline at end of file +component main = Vote(); diff --git a/packages/circuits/package.json b/packages/circuits/package.json new file mode 100644 index 0000000..813dba7 --- /dev/null +++ b/packages/circuits/package.json @@ -0,0 +1,52 @@ +{ + "name": "enclave-circuits", + "version": "0.1.0", + "description": "Zk circuits for the Enlcave protocol", + "main": "dist/src/index.js", + "types": "src/index.ts", + "author": "Nathan Ginnever ", + "files": [ + "src", + "dist", + "zk", + "circuits", + "browser" + ], + "scripts": { + "test": "ts-mocha -p tsconfig.json test/**/*.ts --timeout 30000 --exit", + "pretest": "tsc -p tsconfig.json", + "precompile": "scripts/prerequisites.sh && mkdir -p zk/circuits zk/zkeys zk/verifiers", + "postbuild": "cp zk/zkeys/main.zkey ../app/public && cp zk/circuits/main_js/main.wasm ../app/public", + "compile": "for circuit in circuits/*.circom; do circom $circuit --r1cs --sym --wasm -o zk/circuits;done && tsc", + "export:sample-zkey": "for circuit in zk/circuits/*.r1cs; do snarkjs groth16 setup $circuit powersOfTau28_hez_final_15.ptau zk/zkeys/$(basename -- $circuit .r1cs).zkey;done", + "export:verifier": "for zkey in zk/zkeys/*.zkey; do snarkjs zkey export solidityverifier $zkey zk/verifiers/$(basename -- $zkey .zkey | perl -nE 'say ucfirst').sol;done", + "build": "yarn compile && yarn export:sample-zkey && yarn export:verifier" + }, + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.6.0", + "circomlib": "^2.0.3", + "circomlibjs": "^0.1.2", + "eslint": "^7.32.0", + "eslint-config-prettier": "^8.3.0", + "eslint-config-standard": "^16.0.3", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-prettier": "^3.4.1", + "eslint-plugin-promise": "^5.2.0", + "ethers": "^5.6.4", + "snarkjs": "^0.4.16" + }, + "devDependencies": { + "@types/chai": "^4.3.1", + "@types/mocha": "^9.1.0", + "@typescript-eslint/eslint-plugin": "^4.33.0", + "@typescript-eslint/parser": "^4.33.0", + "chai": "^4.3.6", + "ts-mocha": "^9.0.2" + }, + "engines": { + "npm": ">=7.0.0", + "node": ">=14.0.0" + } +} \ No newline at end of file diff --git a/packages/circuits/scripts/prerequisites.sh b/packages/circuits/scripts/prerequisites.sh new file mode 100644 index 0000000..3f8cef9 --- /dev/null +++ b/packages/circuits/scripts/prerequisites.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +if ! command -v circom &> /dev/null +then + echo "Circom could not be found. Visit https://docs.circom.io/getting-started/installation/ and install circom2" + exit 1 +fi \ No newline at end of file diff --git a/packages/rust/circuits/src/client.ts b/packages/circuits/src/client.js similarity index 99% rename from packages/rust/circuits/src/client.ts rename to packages/circuits/src/client.js index 75ef734..bc448d5 100644 --- a/packages/rust/circuits/src/client.ts +++ b/packages/circuits/src/client.js @@ -54,4 +54,4 @@ export class ZKPClient { c: [proof.pi_c[0], proof.pi_c[1]] as [bigint, bigint], }; } -} \ No newline at end of file +} diff --git a/packages/circuits/src/index.ts b/packages/circuits/src/index.ts new file mode 100644 index 0000000..083d5a4 --- /dev/null +++ b/packages/circuits/src/index.ts @@ -0,0 +1,4 @@ +import { ZKPClient, Proof } from "./client"; + +export { ZKPClient }; +export type { Proof }; \ No newline at end of file diff --git a/packages/circuits/src/typings.d.ts b/packages/circuits/src/typings.d.ts new file mode 100644 index 0000000..8fee1d7 --- /dev/null +++ b/packages/circuits/src/typings.d.ts @@ -0,0 +1,2 @@ +declare module "snarkjs"; +declare module "circomlibjs"; \ No newline at end of file diff --git a/packages/circuits/tsconfig.json b/packages/circuits/tsconfig.json new file mode 100644 index 0000000..282dcfb --- /dev/null +++ b/packages/circuits/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "es2018", + "module": "commonjs", + "strict": true, + "esModuleInterop": true, + "outDir": "dist", + "skipLibCheck": true, + "allowJs": true + }, + "exclude": ["./dist", "node_modules"], + "include": ["./src"] +} \ No newline at end of file diff --git a/packages/rust/circuits/vote_integrity.r1cs b/packages/rust/circuits/vote_integrity.r1cs deleted file mode 100644 index f2adc3e..0000000 Binary files a/packages/rust/circuits/vote_integrity.r1cs and /dev/null differ diff --git a/packages/rust/circuits/vote_integrity.sym b/packages/rust/circuits/vote_integrity.sym deleted file mode 100644 index 8fd1e98..0000000 --- a/packages/rust/circuits/vote_integrity.sym +++ /dev/null @@ -1 +0,0 @@ -1,1,0,main.vote diff --git a/packages/rust/circuits/vote_integrity_js/generate_witness.js b/packages/rust/circuits/vote_integrity_js/generate_witness.js deleted file mode 100644 index eabb86e..0000000 --- a/packages/rust/circuits/vote_integrity_js/generate_witness.js +++ /dev/null @@ -1,20 +0,0 @@ -const wc = require("./witness_calculator.js"); -const { readFileSync, writeFile } = require("fs"); - -if (process.argv.length != 5) { - console.log("Usage: node generate_witness.js "); -} else { - const input = JSON.parse(readFileSync(process.argv[3], "utf8")); - - const buffer = readFileSync(process.argv[2]); - wc(buffer).then(async witnessCalculator => { - // const w= await witnessCalculator.calculateWitness(input,0); - // for (let i=0; i< w.length; i++){ - // console.log(w[i]); - // } - const buff= await witnessCalculator.calculateWTNSBin(input,0); - writeFile(process.argv[4], buff, function(err) { - if (err) throw err; - }); - }); -} diff --git a/packages/rust/circuits/vote_integrity_js/vote_integrity.wasm b/packages/rust/circuits/vote_integrity_js/vote_integrity.wasm deleted file mode 100644 index 39f29ff..0000000 Binary files a/packages/rust/circuits/vote_integrity_js/vote_integrity.wasm and /dev/null differ diff --git a/packages/rust/circuits/vote_integrity_js/witness_calculator.js b/packages/rust/circuits/vote_integrity_js/witness_calculator.js deleted file mode 100644 index 20e6e20..0000000 --- a/packages/rust/circuits/vote_integrity_js/witness_calculator.js +++ /dev/null @@ -1,337 +0,0 @@ -module.exports = async function builder(code, options) { - - options = options || {}; - - let wasmModule; - try { - wasmModule = await WebAssembly.compile(code); - } catch (err) { - console.log(err); - console.log("\nTry to run circom --c in order to generate c++ code instead\n"); - throw new Error(err); - } - - let wc; - - let errStr = ""; - let msgStr = ""; - - const instance = await WebAssembly.instantiate(wasmModule, { - runtime: { - exceptionHandler : function(code) { - let err; - if (code == 1) { - err = "Signal not found.\n"; - } else if (code == 2) { - err = "Too many signals set.\n"; - } else if (code == 3) { - err = "Signal already set.\n"; - } else if (code == 4) { - err = "Assert Failed.\n"; - } else if (code == 5) { - err = "Not enough memory.\n"; - } else if (code == 6) { - err = "Input signal array access exceeds the size.\n"; - } else { - err = "Unknown error.\n"; - } - throw new Error(err + errStr); - }, - printErrorMessage : function() { - errStr += getMessage() + "\n"; - // console.error(getMessage()); - }, - writeBufferMessage : function() { - const msg = getMessage(); - // Any calls to `log()` will always end with a `\n`, so that's when we print and reset - if (msg === "\n") { - console.log(msgStr); - msgStr = ""; - } else { - // If we've buffered other content, put a space in between the items - if (msgStr !== "") { - msgStr += " " - } - // Then append the message to the message we are creating - msgStr += msg; - } - }, - showSharedRWMemory : function() { - printSharedRWMemory (); - } - - } - }); - - const sanityCheck = - options -// options && -// ( -// options.sanityCheck || -// options.logGetSignal || -// options.logSetSignal || -// options.logStartComponent || -// options.logFinishComponent -// ); - - - wc = new WitnessCalculator(instance, sanityCheck); - return wc; - - function getMessage() { - var message = ""; - var c = instance.exports.getMessageChar(); - while ( c != 0 ) { - message += String.fromCharCode(c); - c = instance.exports.getMessageChar(); - } - return message; - } - - function printSharedRWMemory () { - const shared_rw_memory_size = instance.exports.getFieldNumLen32(); - const arr = new Uint32Array(shared_rw_memory_size); - for (let j=0; j { - const h = fnvHash(k); - const hMSB = parseInt(h.slice(0,8), 16); - const hLSB = parseInt(h.slice(8,16), 16); - const fArr = flatArray(input[k]); - let signalSize = this.instance.exports.getInputSignalSize(hMSB, hLSB); - if (signalSize < 0){ - throw new Error(`Signal ${k} not found\n`); - } - if (fArr.length < signalSize) { - throw new Error(`Not enough values for input signal ${k}\n`); - } - if (fArr.length > signalSize) { - throw new Error(`Too many values for input signal ${k}\n`); - } - for (let i=0; i0) { - res.unshift(0); - i--; - } - } - return res; -} - -function fromArray32(arr) { //returns a BigInt - var res = BigInt(0); - const radix = BigInt(0x100000000); - for (let i = 0; i