diff --git a/package.json b/package.json index ab1a7ecd6..7d372804f 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,8 @@ "circom" ], "workspaces": [ - "packages/*" + "packages/*", + "packages/circuits/templates" ], "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/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..2f5185fd8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4382,6 +4382,14 @@ __metadata: languageName: node linkType: hard +"@zk-kit/circuits@workspace:packages/circuits/templates": + version: 0.0.0-use.local + resolution: "@zk-kit/circuits@workspace:packages/circuits/templates" + 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" @@ -6519,6 +6527,12 @@ __metadata: languageName: node linkType: hard +"circuits@workspace:packages/circuits": + version: 0.0.0-use.local + resolution: "circuits@workspace:packages/circuits" + languageName: unknown + linkType: soft + "cjs-module-lexer@npm:^0.6.0": version: 0.6.0 resolution: "cjs-module-lexer@npm:0.6.0"