diff --git a/package.json b/package.json index ab1a7ecd6..fc4dcce5a 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,8 @@ "circom" ], "workspaces": [ - "packages/*" + "packages/*", + "packages/circuits/src" ], "packageManager": "yarn@3.2.1", "devDependencies": { diff --git a/packages/circuits/LICENSE b/packages/circuits/LICENSE new file mode 120000 index 000000000..8e505bcde --- /dev/null +++ b/packages/circuits/LICENSE @@ -0,0 +1 @@ +templates/LICENSE \ No newline at end of file diff --git a/packages/circuits/README.md b/packages/circuits/README.md new file mode 120000 index 000000000..6cb99675b --- /dev/null +++ b/packages/circuits/README.md @@ -0,0 +1 @@ +templates/README.md \ No newline at end of file diff --git a/packages/circuits/binary-merkle-root.r1cs b/packages/circuits/binary-merkle-root.r1cs new file mode 100644 index 000000000..e241bbaf2 Binary files /dev/null and b/packages/circuits/binary-merkle-root.r1cs differ diff --git a/packages/circuits/components/binary-merkle-root.circom b/packages/circuits/components/binary-merkle-root.circom new file mode 100644 index 000000000..7f59cddd4 --- /dev/null +++ b/packages/circuits/components/binary-merkle-root.circom @@ -0,0 +1,5 @@ +pragma circom 2.1.5; + +include "../templates/binary-merkle-root.circom"; + +component main {public [depth]} = BinaryMerkleRoot(16); diff --git a/packages/circuits/components/poseidon-proof.circom b/packages/circuits/components/poseidon-proof.circom new file mode 100644 index 000000000..4b45a3c87 --- /dev/null +++ b/packages/circuits/components/poseidon-proof.circom @@ -0,0 +1,5 @@ +pragma circom 2.1.5; + +include "../templates/poseidon-proof.circom"; + +component main {public [scope]} = PoseidonProof(); diff --git a/packages/circuits/merkle-root.r1cs b/packages/circuits/merkle-root.r1cs new file mode 100644 index 000000000..e241bbaf2 Binary files /dev/null and b/packages/circuits/merkle-root.r1cs differ diff --git a/packages/circuits/package.json b/packages/circuits/package.json new file mode 100644 index 000000000..1b913981c --- /dev/null +++ b/packages/circuits/package.json @@ -0,0 +1,9 @@ +{ + "name": "circuits", + "private": true, + "description": "A comprehensive library of general-purpose Circom circuits.", + "license": "MIT", + "scripts": { + "compile": "circom --r1cs -l ../../node_modules/circomlib/circuits" + } +} diff --git a/packages/circuits/poseidon-proof.r1cs b/packages/circuits/poseidon-proof.r1cs new file mode 100644 index 000000000..b8dd55104 Binary files /dev/null and b/packages/circuits/poseidon-proof.r1cs differ diff --git a/packages/circuits/templates/LICENSE b/packages/circuits/templates/LICENSE new file mode 100644 index 000000000..4377091ec --- /dev/null +++ b/packages/circuits/templates/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Ethereum Foundation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/circuits/templates/README.md b/packages/circuits/templates/README.md new file mode 100644 index 000000000..f8980fab3 --- /dev/null +++ b/packages/circuits/templates/README.md @@ -0,0 +1,50 @@ +

+

+ ZK-kit circuits +

+

A comprehensive library of general-purpose Circom circuits.

+

+ +

+ + + + + Github license + + + NPM version + + + Downloads + + + npm bundle size (scoped) + +

+ +
+

+ + 🗣️ Chat & Support + +

+
+ +--- + +## 🛠 Install + +### npm or yarn + +Install the `@zk-kit/circuits` package with npm: + +```bash +npm i @zk-kit/circuits --save +``` + +or yarn: + +```bash +yarn add @zk-kit/circuits +``` diff --git a/packages/circuits/templates/binary-merkle-root.circom b/packages/circuits/templates/binary-merkle-root.circom new file mode 100644 index 000000000..238de32f6 --- /dev/null +++ b/packages/circuits/templates/binary-merkle-root.circom @@ -0,0 +1,32 @@ +pragma circom 2.1.5; + +include "poseidon.circom"; +include "mux1.circom"; +include "comparators.circom"; + +template BinaryMerkleRoot(MAX_DEPTH) { + signal input leaf, depth, indices[MAX_DEPTH], siblings[MAX_DEPTH]; + + signal output out; + + signal nodes[MAX_DEPTH + 1]; + nodes[0] <== leaf; + + signal roots[MAX_DEPTH]; + var root = 0; + + for (var i = 0; i < MAX_DEPTH; i++) { + var a = IsEqual()([depth, i]); + + roots[i] <== a * nodes[i]; + + root += roots[i]; + + var c[2][2] = [ [nodes[i], siblings[i]], [siblings[i], nodes[i]] ]; + var childNodes[2] = MultiMux1(2)(c, indices[i]); + + nodes[i + 1] <== Poseidon(2)(childNodes); + } + + out <== root; +} diff --git a/packages/circuits/templates/package.json b/packages/circuits/templates/package.json new file mode 100644 index 000000000..3fb074be9 --- /dev/null +++ b/packages/circuits/templates/package.json @@ -0,0 +1,24 @@ +{ + "name": "@zk-kit/circuits", + "version": "0.1.0", + "description": "A comprehensive library of general-purpose Circom circuits.", + "license": "MIT", + "files": [ + "**/*.circom", + "LICENSE", + "README.md" + ], + "keywords": [ + "zk-kit", + "circom", + "circuits" + ], + "repository": "git@github.com:privacy-scaling-explorations/zk-kit.git", + "homepage": "https://github.com/privacy-scaling-explorations/zk-kit/tree/main/packages/circuits.sol", + "publishConfig": { + "access": "public" + }, + "dependencies": { + "circomlib": "^2.0.5" + } +} diff --git a/packages/circuits/templates/poseidon-proof.circom b/packages/circuits/templates/poseidon-proof.circom new file mode 100644 index 000000000..286d364cc --- /dev/null +++ b/packages/circuits/templates/poseidon-proof.circom @@ -0,0 +1,24 @@ +pragma circom 2.1.5; + +include "poseidon.circom"; + +// This circuit can be used to prove the possession of a pre-image of a +// hash without revealing the pre-image itself. It utilizes the Poseidon +// hash function, a highly efficient and secure hash function suited +// for zero-knowledge proof contexts. +// A scope value can be used to define a nullifier to prevent the same +// proof from being re-used twice. +template PoseidonProof() { + // The circuit takes two inputs: the pre-image (in) and an additional scope parameter (scope). + signal input in; + signal input scope; + + // It applies the Poseidon hash function to the pre-image to produce a hash output (out). + signal output out; + out <== Poseidon(1)([in]); + + // A nullifier is also computed using both the pre-image and the scope, providing a value + // to prevent the same proof from being reused twice. + signal output nullifier; + nullifier <== Poseidon(2)([scope, in]); +} diff --git a/yarn.lock b/yarn.lock index 0d4ead41b..9c30a359c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4382,6 +4382,14 @@ __metadata: languageName: node linkType: hard +"@zk-kit/circuits@workspace:packages/circuits/src": + version: 0.0.0-use.local + resolution: "@zk-kit/circuits@workspace:packages/circuits/src" + dependencies: + circomlib: ^2.0.5 + languageName: unknown + linkType: soft + "@zk-kit/groth16@workspace:packages/groth16": version: 0.0.0-use.local resolution: "@zk-kit/groth16@workspace:packages/groth16" @@ -6457,6 +6465,21 @@ __metadata: languageName: node linkType: hard +"circom_tester@npm:0.0.20": + version: 0.0.20 + resolution: "circom_tester@npm:0.0.20" + dependencies: + chai: ^4.3.6 + ffjavascript: ^0.2.60 + fnv-plus: ^1.3.1 + r1csfile: ^0.0.47 + snarkjs: ^0.7.0 + tmp-promise: ^3.0.3 + util: ^0.12.5 + checksum: ee9f9a4ac69ee2acb2ce46c903a817ac687b621a90a7f5b8a8bd1d8f3e42076ed694f5e3e46e0d9775febf350c73837007284a33117ac66a7b233b76cbd21ea6 + languageName: node + linkType: hard + "circom_tester@npm:^0.0.19": version: 0.0.19 resolution: "circom_tester@npm:0.0.19" @@ -6519,6 +6542,14 @@ __metadata: languageName: node linkType: hard +"circuits@workspace:packages/circuits": + version: 0.0.0-use.local + resolution: "circuits@workspace:packages/circuits" + dependencies: + circom_tester: 0.0.20 + languageName: unknown + linkType: soft + "cjs-module-lexer@npm:^0.6.0": version: 0.6.0 resolution: "cjs-module-lexer@npm:0.6.0" @@ -9314,6 +9345,17 @@ __metadata: languageName: node linkType: hard +"ffjavascript@npm:0.2.62, ffjavascript@npm:^0.2.60": + version: 0.2.62 + resolution: "ffjavascript@npm:0.2.62" + dependencies: + wasmbuilder: 0.0.16 + wasmcurves: 0.2.2 + web-worker: ^1.2.0 + checksum: c292e88fd160e16aadfac27870fc5532d3ed1f2306f51d77ef37d5077fca0146b475ffa44a52b80a489ce8834f9c1f4853265499dcb5d0b8f0ec551341c318da + languageName: node + linkType: hard + "ffjavascript@npm:^0.2.30, ffjavascript@npm:^0.2.35, ffjavascript@npm:^0.2.38": version: 0.2.55 resolution: "ffjavascript@npm:0.2.55" @@ -16032,6 +16074,18 @@ __metadata: languageName: node linkType: hard +"r1csfile@npm:0.0.47, r1csfile@npm:^0.0.47": + version: 0.0.47 + resolution: "r1csfile@npm:0.0.47" + dependencies: + "@iden3/bigarray": 0.0.2 + "@iden3/binfileutils": 0.0.11 + fastfile: 0.0.20 + ffjavascript: 0.2.60 + checksum: edeb325b83851a71cbca2e5de56eb622ee5347ecae921b526a5fc484c4825b6b30c73b6fde40e9bc5112b9d21e046af885bf212ed9cee2efbc6de93b8454ec06 + languageName: node + linkType: hard + "randombytes@npm:^2.0.0, randombytes@npm:^2.0.1, randombytes@npm:^2.0.5, randombytes@npm:^2.1.0": version: 2.1.0 resolution: "randombytes@npm:2.1.0" @@ -17422,6 +17476,26 @@ __metadata: languageName: node linkType: hard +"snarkjs@npm:^0.7.0": + version: 0.7.2 + resolution: "snarkjs@npm:0.7.2" + dependencies: + "@iden3/binfileutils": 0.0.11 + bfj: ^7.0.2 + blake2b-wasm: ^2.4.0 + circom_runtime: 0.1.24 + ejs: ^3.1.6 + fastfile: 0.0.20 + ffjavascript: 0.2.62 + js-sha3: ^0.8.0 + logplease: ^1.2.15 + r1csfile: 0.0.47 + bin: + snarkjs: build/cli.cjs + checksum: c784e2171278403b2356ddc42fac47093e7cf4c48c0ef46ac3c269c308795d2da63a00dd6b92521b166f3d0349d0b8301454f5a9633b5db447755b4568c4b5e7 + languageName: node + linkType: hard + "socks-proxy-agent@npm:^7.0.0": version: 7.0.0 resolution: "socks-proxy-agent@npm:7.0.0" @@ -19071,7 +19145,7 @@ __metadata: languageName: node linkType: hard -"util@npm:^0.12.4": +"util@npm:^0.12.4, util@npm:^0.12.5": version: 0.12.5 resolution: "util@npm:0.12.5" dependencies: