{"_id":"@0xagnish/zkcircuits","_rev":"1-4f28a9dff62c6bff1e4a3ac8b53c5fb8","name":"@0xagnish/zkcircuits","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@0xagnish/zkcircuits","version":"1.0.0","description":"### What is Circom?","main":"index.js","scripts":{"test":"mocha","build":"bash scripts/build.sh"},"keywords":[],"author":"","license":"ISC","dependencies":{"@0xagnish/zk-data-prep":"^0.0.3","@types/jest":"^29.5.2","big-integer":"^1.6.51","chai":"^4.3.7","circom_tester":"^0.0.19","circomlib":"^2.0.5","circomlibjs":"^0.0.8","mocha":"^10.2.0","pyt-merkle-sum-tree":"^0.0.21","snarkjs":"^0.5.0","ts-jest":"^29.1.1","tslint":"^6.1.3","tslint-config-prettier":"^1.18.0","typescript":"^5.1.6"},"gitHead":"62be99d6efa71a509274c47de106657f2b382fba","_id":"@0xagnish/zkcircuits@1.0.0","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-SH32jX52nwDKj0ZuRvzdJdLBp4+OQGVq1HWndK9Oa4rnBmtF78PqyZ2RJ7q6WJULnr0L6VYmBmV/6St16ZGeHw==","shasum":"12f5c648cb2106e0cae143007f4ef74295499f35","tarball":"https://registry.npmjs.org/@0xagnish/zkcircuits/-/zkcircuits-1.0.0.tgz","fileCount":13,"unpackedSize":19959284,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDK2E8UKYmk4B807Az7Zzf4a2uiFTaQRnjsb+K3dsn5PAiEA02xPGeCzQYjyvyWk9deGG/1oXOXSncWpiFecB+pEJKM="}]},"_npmUser":{"name":"0xagnish","email":"iamagnix@gmail.com"},"directories":{},"maintainers":[{"name":"0xagnish","email":"iamagnix@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/zkcircuits_1.0.0_1688628679034_0.0004123761079297683"},"_hasShrinkwrap":false},"1.0.1":{"name":"@0xagnish/zkcircuits","version":"1.0.1","description":"### What is Circom?","main":"index.js","scripts":{"test":"mocha","build":"bash scripts/build.sh"},"keywords":[],"author":"","license":"ISC","dependencies":{"@0xagnish/zk-data-prep":"^0.0.3","@types/jest":"^29.5.2","big-integer":"^1.6.51","chai":"^4.3.7","circom_tester":"^0.0.19","circomlib":"^2.0.5","circomlibjs":"^0.0.8","mocha":"^10.2.0","pyt-merkle-sum-tree":"^0.0.21","snarkjs":"^0.5.0","ts-jest":"^29.1.1","tslint":"^6.1.3","tslint-config-prettier":"^1.18.0","typescript":"^5.1.6"},"gitHead":"7f17bdf22d1f5fd60e746d5f340021219ff6ae3d","_id":"@0xagnish/zkcircuits@1.0.1","_nodeVersion":"18.16.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-v4Ow1L4AaL7rPwoa9xyeujZmmcbl52+XAU8iRdaGBRdpSxub5QaA7XGpX4IIDanX9y6/Ji6ML8+Ahxvh6+tq9g==","shasum":"2147ab48d9947c5e92b0afa9f5b73e7d4dd8002a","tarball":"https://registry.npmjs.org/@0xagnish/zkcircuits/-/zkcircuits-1.0.1.tgz","fileCount":13,"unpackedSize":19960469,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEH1BOYm8jXiAN7ao37+cEv7GXMvy4jc96NCJUzldLMQAiEAlX6stquECnGVAzVZ0Uvq9D4lLmzqhy6O/pZh0wLSg6Q="}]},"_npmUser":{"name":"0xagnish","email":"iamagnix@gmail.com"},"directories":{},"maintainers":[{"name":"0xagnish","email":"iamagnix@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/zkcircuits_1.0.1_1688636430825_0.22018770659073894"},"_hasShrinkwrap":false}},"time":{"created":"2023-07-06T07:31:18.918Z","1.0.0":"2023-07-06T07:31:19.457Z","modified":"2023-07-06T09:40:31.405Z","1.0.1":"2023-07-06T09:40:31.259Z"},"maintainers":[{"name":"0xagnish","email":"iamagnix@gmail.com"}],"description":"### What is Circom?","keywords":[],"license":"ISC","readme":"# zkSNARK construction on Circom\n\n### What is Circom?\n\nCircom, short for Circuit Compiler, is a domain-specific language (DSL) and compiler designed for creating arithmetic circuits. It is commonly used in the field of zero-knowledge proofs (ZKPs) and secure multiparty computation (MPC).\n\n### What are these circuits?\n\nArithmetic circuits are mathematical representations of computations, where inputs and outputs are represented as wires, and gates perform operations on these wires. Circom allows you to express complex computations as circuits in a high-level language, making it easier to reason about and analyze the behavior of these circuits.\n\n### Importance of Circom\n\nCircom is often used in conjunction with other tools and libraries in the area of ZKPs, such as zk-SNARKs (zero-knowledge succinct non-interactive arguments of knowledge). These cryptographic constructions enable the verification of computations without revealing the inputs or intermediate values, providing privacy and security guarantees.\n\n### What can we do with Circom?\n\nBy using Circom, developers can define the desired computation, compile it into an arithmetic circuit, and then generate the necessary proofs or verification keys to interact with the circuit. This process allows for the creation of privacy-preserving applications and protocols where sensitive data can be processed securely without exposing its contents.\n\nYou can find the Research Paper for Circom [here](https://ieeexplore.ieee.org/document/10002421/)\n\nCircuits for Proof Of Solvency.\n\nThe circuit, written in circom, enforces the rules that the Exchange must abide by when generating a Proof Of Solvency for a specific user.\n\nThe circuit checks that:\n\n    - A user-balance entry has been included in the Merkle Sum Tree\n    - The computation of the sum going from the user's entry to the root has been performed correctly\n    - No sum overflow happened during the computation\n    - The computed sum (namely the total liabilities of an exchange) is less or equal to the total sum of the assets of the exchange\n\nThe prover system guarantees credible and self-auditable proof while preserving the secrecy of the Exchange's business information such as:\n\n- Number of users of the exchanges\n- Users balances\n- Siblings partial sum balances\n- Total liabilities of the exchange\n\nThe prover relies on [zkDataPrep](https://github.com/teamHITK/zkExchange/tree/master/zkDataPrep) for the Merkle Sum tree operations.\n\n## Circuit Design\n\n| Input                  | Description                                                                       | Public or Private |\n| ---------------------- | --------------------------------------------------------------------------------- | ----------------- |\n| rootHash               | Root Hash of the Merkle Sum Tree publicly committed by the exchange               | Public            |\n| username               | The username (in BigInt format) of user to which the proof is being generated for | Private           |\n| balance                | The balance of the user to which the proof is being generated for                 | Private           |\n| pathIndices[nLevels]   | A bit array that contains the path to the user leaf inside the Merkle Sum Tree    | Private           |\n| siblingHashes[nLevels] | Array of hashes of the siblings of the user leaf                                  | Private           |\n| siblingsSums[nLevels]  | Array of sum-balances of the siblings of the user leaf                            | Private           |\n| assetsSum              | The total assets that the Exchange claims to have                                 | Public            |\n\n| Output   | Description                         | Public or Private   |\n| -------- | ----------------------------------- | ------------------- |\n| leafHash | Poseidon Hash `H(username,balance)` | Public (by default) |\n\n![image](https://github.com/teamHITK/zkExchange/assets/80243668/20e61f60-71ce-4781-8c86-10561a8eb133)\n\nThe `ToLeafHash` component performs the poseidon hash of the `username` and the `balance` and outputs the `leafHash`. The `leafHash` is then used as the first `hash` in the `NextMerkleSumTreeLevel` component.\n\nThe `NextMerkleSumTreeLevel` component recursively computes the current `hash` (for the first level it is the `leafHash`), the current `sum` (for the first level it is the `balance`), the current `siblingHash` and the current `siblingSum`. The output of the nextLevel component are the `nextHash` and the `nextSum`. These are calculated as follows:\n\n- `nextHash = H(hash, sum, siblingHash, siblingSum)` if the pathIndex is 0, where H is the poseidon hash function\n- `nextHash = H(siblingHash, siblingSum, hash, sum)` if the pathIndex is 1, where H is the poseidon hash function\n- `nextSum = sum + siblingSum`\n\nAfter the last level is computed, the circuit checks that the `nextHash` is equal to the `rootHash` and that the `nextSum` is `LessEqThan` the `assetsSum`.\n\nFurther circuit components not shown in the circuit diagram are:\n\n- `SafeSum`, ensures that no overflow happens during the computation of the sum\n- `SafeLessEqThan`, safely compare two n-bit numbers avoiding overflows\n\n## Checks to be executed outside the circuit\n\nA proof generated using the circuit, even if verified, doesn't ensure that the prover is solvent. Further checks must be on the public signals of the circuit to ensure that the prover is solvent. These checks are:\n\n- The `rootHash` (input of the circuit) must be the root hash of the Merkle Sum Tree committed by the exchange on a Public Bulletin Board\n- The `assetsSum` (input of the circuit) must be the total assets of the exchange. The way in which the exchange generates its proof of assets is out of the scope of this project.\n- The `leafHash` (output of the circuit) must equal to `H(username, balance)` that contains the data of the user to which the proof is being generated for\n\n\n## Workflow of the Circom Compiler and it's Dependencies\n\n![image](https://github.com/teamHITK/zkExchange/assets/80243668/8c6b0b3a-8b16-49bd-893d-f621c8bdfa93)\n## Required Dependency\n\n- [circom](https://docs.circom.io/)\n\n## Build\n\nIn order to compile the circuit, execute the trusted setup, generate the proof (and verify it) using groth16 as proving system run from the root directory:\n\n```\n$ npm run build\n```\n\nThe script will:\n\n- Download the trusted [Powers Of Tau](https://github.com/iden3/snarkjs#7-prepare-phase-2) setup generated from the Hermez Community\n- Do the trusted setup required for the groth16 proving system\n- Compile the circuit\n- Generate a witness based on a pre generated sample input. In order to generate other inputs you can use this program:\n\n  ```javascript\n\n  const { IncrementalMerkleSumTree } = require(\"ts-merkle-sum-tree\")\n\n  ...\n\n  proof = tree.createProofWithTargetSum(5, BigInt(125))\n\n  inputToCircuit = JSON.strigify(proof)\n\n  ```\n\n- Generate the proof based on the witness\n- Verify the proof\n\n## Test\n\nTo run the tests, run the following command:\n\n```\n$ npm test\n```\n\n## Benchmarks\n\nAll benchmarks are run on a Ubuntu 22 LTS, 8GB memory. The benchmark was run on a Merkle Sum Tree with 16 levels (2^16 leaves).\n\n|                                    | **groth16** |\n| ---------------------------------- | ----------- |\n| Constraints                        | 13892       |\n| Circuit compilation                | 2s          |\n| Witness generation                 | 0s          |\n| Setup key generation               | 40s         |\n| Trusted setup phase 2 contribution | 6s          |\n| Proving key size                   | 12.3MB      |\n| Proving key verification           | 41s         |\n| Proving time                       | 2s          |\n| Proof verification time            | 0s          |\n\n## Trusted Setup Artifcats\n\nA trusted setup run by me is publicly available to test the prove/verify process. The available artifacts is based on a Merkle Sum Tree with 16 levels (2^16 leaves).\n\nThe artifacts generated during the Trusted Setup are publicly available :\n\n- proving key zkey `wget https://pan-y-tomate.s3.eu-west-3.amazonaws.com/pyt-pos-16_final.zkey`\n- circuit wasm `wget  https://pan-y-tomate.s3.eu-west-3.amazonaws.com/pyt-pos-16.wasm`\n- verification key vkey `wget https://pan-y-tomate.s3.eu-west-3.amazonaws.com/vkey.json`\n\nArficats for further merkle tree levels will be available soon.\n","readmeFilename":"README.md"}