From be5ae078a3ccff220d1e4a5c6eebec3bce1707ba Mon Sep 17 00:00:00 2001 From: Kobi Gurkan Date: Sun, 25 Aug 2019 20:40:02 +0300 Subject: [PATCH] feat: adds id trapdoor and upgrades deps versions (#27) * feat: adds id trapdoor * fix: makes tests work with latest deps * fix: adds identity trapdoor to tests * fix: fixes trapdoor typo * fix: adds trapdoor to contract tests * feat: updates semaphore-merkle-tree version * fix: updates README * fix: updates README * fix: updates README * feat: updates snarkjs and circomlib versions * fix: removes sbmtjs from README * fix: invalidates cache * feat: updates semaphore-merkle-tree version --- .circleci/config.yml | 8 +- README.md | 12 +- semaphorejs/package-lock.json | 144 +++++++----------- semaphorejs/package.json | 10 +- semaphorejs/scripts/run_all_test.sh | 1 + semaphorejs/snark/semaphore-base.circom | 8 +- semaphorejs/src/client/semaphore.js | 11 +- semaphorejs/src/server/server.js | 6 +- semaphorejs/src/util/index.js | 4 +- semaphorejs/src/web/client_web.js | 2 +- .../test/circuits/semaphore/circuit.js | 4 +- semaphorejs/test/contracts/semaphore.js | 8 +- 12 files changed, 99 insertions(+), 119 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 32ec2854..b42a4443 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,14 +19,14 @@ jobs: - restore_cache: name: restore-npm-cache keys: - - v1.9-dependencies-{{ checksum "package-lock.json" }} + - v1.10-dependencies-{{ checksum "package-lock.json" }} - run: npm install - save_cache: paths: - node_modules - key: v1.9-dependencies-{{ checksum "package-lock.json" }} + key: v1.10-dependencies-{{ checksum "package-lock.json" }} # checksum the snarks definitions - run: @@ -37,7 +37,7 @@ jobs: - restore_cache: name: restore-snark-cache keys: - - v1.9-dependencies-{{ checksum "build/.snark_checksum" }} + - v1.10-dependencies-{{ checksum "build/.snark_checksum" }} # build snarks - run: @@ -47,7 +47,7 @@ jobs: # cache generated snark circuit and keys - save_cache: - key: v1.9-dependencies-{{ checksum "build/.snark_checksum" }} + key: v1.10-dependencies-{{ checksum "build/.snark_checksum" }} paths: - build/circuit.json - build/proving_key.bin diff --git a/README.md b/README.md index a6b114b2..998cb6d1 100644 --- a/README.md +++ b/README.md @@ -28,12 +28,12 @@ The contract allows administrative operations that only the owner is allowed to * Managing identities using the **insertIdentity** and **updateIdentity** methods. * Setting the **external_nullifier**. - * Setting the **gas_price_max**. + * Setting the broadcast permissioning - whether only the owner can broadcast. The contract allows anyone to read the current state: * Reading the roots of the two trees. -* Reading the current parameters of **external_nullifier** and **gas_price_max**. +* Reading the current parameters of **external_nullifier**. The contract allows anyone to attempt broadcasting a signal, given a signal, a proof and the relevant public inputs. The contract allows anyone to fund the contract for gas refund and rewards. @@ -63,6 +63,7 @@ The statement assures that given public inputs: and private inputs: * **identity_pk** * **identity_nullifier** + * **identity_trapdoor** * **identity_path_elements** * **identity_path_index** * **auth_sig_r** @@ -70,8 +71,8 @@ and private inputs: the following conditions hold: - * The commitment of the identity structure (**identity_pk**, **identity_nullifier**) exists in the identity tree with the root **root**, using the path (**identity_path_elements**, **identity_path_index**). This ensures that the user was added to the system at some point in the past. - * **nullifiers_hash** is uniquely derived from **external_nullifier** and **identity_nullifier**. This ensures a user cannot broadcast a signal with the same **external_nullifier** more than once. + * The commitment of the identity structure (**identity_pk**, **identity_nullifier**, **identity_trapdoor**) exists in the identity tree with the root **root**, using the path (**identity_path_elements**, **identity_path_index**). This ensures that the user was added to the system at some point in the past. + * **nullifiers_hash** is uniquely derived from **external_nullifier**, **identity_nullifier** and **identity_path_index**. This ensures a user cannot broadcast a signal with the same **external_nullifier** more than once. * The message (**external_nullifier**, **signal_hash**, **broadcaster_address**) is signed by the secret key corresponding to **identity_pk**, having the signature (**auth_sig_r**, **auth_sig_s**). This ensures that the user approves the signal broadcast by a specific **broadcaster_address**, preventing front-running attacks, and a specific state of the contract having a specific **external_nullifier**, ensuring no double-signaling. #### Cryptographic primitives @@ -91,11 +92,10 @@ Implemented in [**semaphorejs/src/server/server.js**](semaphorejs/src/server/ser * A client to ask for a path from an identity commitment to the current root of the tree, relieving the client from the need to manage this tree by themselves. * A client to ask a list of signals, together with their paths to the signals tree root. * An owner to set the external nullifier. - * An owner to set the max gas price. The server relies on an Ethereum node and the events in the smart contract to synchronize to the current state and handle rollbacks if they occur. -It uses [**sbmtjs**](sbmtjs) - *storage-backed merkle tree*. Semaphore requires managing a growing merkle tree containing the identities allowed to signal and the signals broadcast by users. sbmtjs manages the trees using a database, making the tree scale by the disk size. +It uses [**semaphore-merkle-tree**](https://github.com/weijiekoh/semaphore-merkle-tree) - Semaphore requires managing a growing merkle tree containing the identities allowed to signal and the signals broadcast by users. semaphore-merkle-tree manages the trees either in-memory, for browser usage or a database, making the tree scale by the disk size. ### Client diff --git a/semaphorejs/package-lock.json b/semaphorejs/package-lock.json index 61bcd705..f009e2cd 100644 --- a/semaphorejs/package-lock.json +++ b/semaphorejs/package-lock.json @@ -51,9 +51,9 @@ } }, "@types/jest": { - "version": "24.0.15", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.15.tgz", - "integrity": "sha512-MU1HIvWUme74stAoc3mgAi+aMlgKOudgEvQDIm1v4RkrDudBh1T+NFp5sftpBAdXdx1J0PbdpJ+M2EsSOi1djA==", + "version": "24.0.18", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.18.tgz", + "integrity": "sha512-jcDDXdjTcrQzdN06+TSVsPPqxvsZA/5QkYfIZlq1JMw7FdP5AZylbOc+6B/cuDurctRe+MziUMtQ3xQdrbjqyQ==", "requires": { "@types/jest-diff": "*" } @@ -264,9 +264,9 @@ "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==" }, "acorn-jsx": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", - "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==" + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", + "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==" }, "aes-js": { "version": "3.0.0", @@ -1866,9 +1866,9 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "caniuse-lite": { - "version": "1.0.30000985", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000985.tgz", - "integrity": "sha512-1ngiwkgqAYPG0JSSUp3PUDGPKKY59EK7NrGGX+VOxaKCNzRbNc7uXMny+c3VJfZxtoK3wSImTvG9T9sXiTw2+w==" + "version": "1.0.30000989", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz", + "integrity": "sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw==" }, "caseless": { "version": "0.12.0", @@ -1975,9 +1975,9 @@ } }, "circom": { - "version": "0.0.27", - "resolved": "https://registry.npmjs.org/circom/-/circom-0.0.27.tgz", - "integrity": "sha512-WkhR5tjd0EjZWj37qw56THMaRvmoXXiOaMYzwn/knsm3DtPD05NtfF/tRj5wW+9WbN58UW7JHoVIxww/WWHuMA==", + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/circom/-/circom-0.0.30.tgz", + "integrity": "sha512-jZqk8ZzEUy2+HqkK/7DJ7t98NhV28fgaRitOK+iQ7f97+sznACAbItBmPbnmSwQfT9lFtidAtVnXPlD0tIy+DQ==", "requires": { "big-integer": "^1.6.32", "optimist": "^0.6.1", @@ -1985,9 +1985,9 @@ } }, "circomlib": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/circomlib/-/circomlib-0.0.10.tgz", - "integrity": "sha512-+/gEnk3I1zuU7Nbm/gig+Yc87p2R+t9agDWnOVrg+warKLOFLgtbH6OuefbAtqGwHf8qq0pEmeaJfvaf53lKxQ==", + "version": "0.0.13", + "resolved": "https://registry.npmjs.org/circomlib/-/circomlib-0.0.13.tgz", + "integrity": "sha512-QHCSOzVT42shVK6goSyZkbEyZa9WTsdfYHkxSDypBj+fKM1gJCms3NQ+PT/v/f/8lwZye2KDMM0B8IsvC9pMrA==", "requires": { "blake-hash": "^1.1.0", "blake2b": "^2.1.3", @@ -2947,9 +2947,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.201", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.201.tgz", - "integrity": "sha512-aCTPIfY1Jvuam5b6vuWRjt1F8i4kY7zX0Qtpu5SNd6l1zjuxU9fDNpbM4o6+oJsra+TMD2o7D20GnkSIgpTr9w==" + "version": "1.3.238", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.238.tgz", + "integrity": "sha512-k+s6EIiSTgfOm7WiMlGBMMMtBQXSui8OfLN1sXU3RohJOuLGVq0lVm7hXyDIDBcbPM0MeZabAdIPQOSEZT3ZLg==" }, "elliptic": { "version": "6.3.3", @@ -3208,17 +3208,17 @@ } }, "eslint-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.0.tgz", - "integrity": "sha512-7ehnzPaP5IIEh1r1tkjuIrxqhNkzUJa9z3R92tLJdZIVdWaczEhr3EbhGtsMrVxi1KeR8qA7Off6SWc5WNQqyQ==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", + "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", "requires": { "eslint-visitor-keys": "^1.0.0" } }, "eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==" }, "espree": { "version": "5.0.1", @@ -3505,7 +3505,7 @@ "integrity": "sha1-L9w1dvIykDNYl26znaeDIT/5Uj8=" }, "ethereumjs-abi": { - "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#572d4bafe08a8a231137e1f9daeb0f8a23f197d2", + "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#1cfbb13862f90f0b391d8a699544d5fe4dfb8c7b", "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", "requires": { "bn.js": "^4.11.8", @@ -3594,9 +3594,9 @@ } }, "ethereumjs-common": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-1.3.0.tgz", - "integrity": "sha512-/jdFHyHOIS3FiAnunwRZ+oNulFtNNSHyWii3PaNHReOUmBAxij7KMyZLKh0tE16JEsJtXOVz1ceYuq++ILzv+g==" + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-1.3.1.tgz", + "integrity": "sha512-kexqNgM2q29RKoZPPjehPREeqbr/vhYfT9Ho8FVeH3f7USjBuYp1iZ1qjqklk8FSMvEKPpMJFYSOunikw30Prw==" }, "ethereumjs-tx": { "version": "1.3.7", @@ -8814,13 +8814,13 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#8431eab7b3384e65e8126a4602520b78031666fb", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#8431eab7b3384e65e8126a4602520b78031666fb", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#8431eab7b3384e65e8126a4602520b78031666fb", "requires": { "bn.js": "^4.11.8", "ethereumjs-util": "^6.0.0" @@ -15941,13 +15941,13 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#8431eab7b3384e65e8126a4602520b78031666fb", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#8431eab7b3384e65e8126a4602520b78031666fb", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#8431eab7b3384e65e8126a4602520b78031666fb", "requires": { "bn.js": "^4.11.8", "ethereumjs-util": "^6.0.0" @@ -16034,7 +16034,7 @@ "requires": { "underscore": "1.8.3", "web3-core-helpers": "1.0.0-beta.35", - "websocket": "git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible" + "websocket": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2" }, "dependencies": { "debug": { @@ -16048,7 +16048,7 @@ }, "websocket": { "version": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2", - "from": "git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible", + "from": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2", "optional": true, "requires": { "debug": "^2.2.0", @@ -17330,9 +17330,9 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, "inquirer": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.0.tgz", - "integrity": "sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", "requires": { "ansi-escapes": "^3.2.0", "chalk": "^2.4.2", @@ -20459,55 +20459,14 @@ "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==" }, "semaphore-merkle-tree": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/semaphore-merkle-tree/-/semaphore-merkle-tree-1.0.4.tgz", - "integrity": "sha512-MDDW5OSNyFkctV7H1HsSNHON7iOyLkkZRFCboQnWil+gi/gn6zdv1p+RtXtnyoIGLD2NM5ubLmYc+XVnsJJ+rA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/semaphore-merkle-tree/-/semaphore-merkle-tree-1.0.6.tgz", + "integrity": "sha512-02x9Jaz3GKl9V10uVAuqKMUivIcRUMBPdAEuO6gKBDIY7hQtFOk5qkbe5BJHir/cM2gCJTijf7sTjriyCSAIdA==", "requires": { "@types/jest": "^24.0.15", "await-lock": "^1.1.3", - "circomlib": "0.0.10", - "snarkjs": "^0.1.14" - }, - "dependencies": { - "circomlib": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/circomlib/-/circomlib-0.0.10.tgz", - "integrity": "sha512-+/gEnk3I1zuU7Nbm/gig+Yc87p2R+t9agDWnOVrg+warKLOFLgtbH6OuefbAtqGwHf8qq0pEmeaJfvaf53lKxQ==", - "requires": { - "blake-hash": "^1.1.0", - "blake2b": "^2.1.3", - "snarkjs": "0.1.11", - "typedarray-to-buffer": "^3.1.5", - "web3": "^1.0.0-beta.55" - }, - "dependencies": { - "snarkjs": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/snarkjs/-/snarkjs-0.1.11.tgz", - "integrity": "sha512-NoMNn03Uwbt18V340ZlHSZscyfIu8F6fMOL7LT9Xr1zQY/nmzScM8442ATyJfzSI5bDTAz1QQGbCerP2BCKljA==", - "requires": { - "big-integer": "^1.6.35", - "chai": "^4.1.2", - "escape-string-regexp": "^1.0.5", - "eslint": "^5.3.0", - "yargs": "^12.0.2" - } - } - } - }, - "snarkjs": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/snarkjs/-/snarkjs-0.1.14.tgz", - "integrity": "sha512-mNsWx5K0ojz73689ZARwqyY62ENvW43movC+WMEHVYsFdcX9lpG+ZjiJGvnQh7LkYg2WY2lFzsXTUZI35TxqeA==", - "requires": { - "big-integer": "^1.6.43", - "chai": "^4.2.0", - "escape-string-regexp": "^1.0.5", - "eslint": "^5.16.0", - "keccak": "^2.0.0", - "yargs": "^12.0.5" - } - } + "circomlib": "0.0.13", + "snarkjs": "0.1.17" } }, "semver": { @@ -20837,8 +20796,9 @@ } }, "snarkjs": { - "version": "git+https://github.com/iden3/snarkjs.git#c428706ef69930e378c31199ff8d66ee13fada85", - "from": "git+https://github.com/iden3/snarkjs.git#c428706ef69930e378c31199ff8d66ee13fada85", + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/snarkjs/-/snarkjs-0.1.17.tgz", + "integrity": "sha512-V/rZL/w16oYUzARIq6DXnlRnpSze79KOSTocnGyPiLMCIsfZ/qNiTExCcA4iTXljHLdlHnUHyw7MOXSILwclPQ==", "requires": { "big-integer": "^1.6.43", "chai": "^4.2.0", @@ -21249,9 +21209,9 @@ } }, "table": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.4.tgz", - "integrity": "sha512-IIfEAUx5QlODLblLrGTTLJA7Tk0iLSGBvgY8essPRVNGHAzThujww1YqHLs6h3HfTg55h++RzLHH5Xw/rfv+mg==", + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", "requires": { "ajv": "^6.10.2", "lodash": "^4.17.14", @@ -22970,10 +22930,12 @@ } }, "websnark": { - "version": "git+https://github.com/iden3/websnark.git#3b6cf0c77e48ab0867a2d710c0b35794b16bde7d", - "from": "git+https://github.com/iden3/websnark.git", + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/websnark/-/websnark-0.0.5.tgz", + "integrity": "sha512-JRJDLYa6GyHgRp7RQmauZBLgClx7OGclEnJLfW2uUyRFYDCBGdgirIH7E2g1s1BR6GUqEBb0uHneqBKvO6Bt9A==", "requires": { - "big-integer": "^1.6.42" + "big-integer": "^1.6.42", + "blakejs": "^1.1.0" } }, "websocket": { diff --git a/semaphorejs/package.json b/semaphorejs/package.json index bd844588..42245b63 100644 --- a/semaphorejs/package.json +++ b/semaphorejs/package.json @@ -20,8 +20,8 @@ }, "dependencies": { "blakejs": "^1.1.0", - "circom": "0.0.27", - "circomlib": "0.0.10", + "circom": "0.0.30", + "circomlib": "0.0.13", "cors": "^2.8.5", "del": "^4.1.0", "ethers": "^4.0.33", @@ -33,8 +33,8 @@ "mocha": "^6.0.2", "node-fetch": "^2.3.0", "require-nocache": "^1.0.0", - "semaphore-merkle-tree": "^1.0.4", - "snarkjs": "git+https://github.com/iden3/snarkjs.git#c428706ef69930e378c31199ff8d66ee13fada85", + "semaphore-merkle-tree": "1.0.6", + "snarkjs": "0.1.17", "truffle": "^5.0.10", "truffle-artifactor": "^4.0.10", "truffle-contract": "^4.0.11", @@ -42,7 +42,7 @@ "truffle-privatekey-provider": "^1.1.0", "web3": "^1.0.0-beta.51", "webpack": "^4.30.0", - "websnark": "git+https://github.com/iden3/websnark.git#3b6cf0c77e48ab0867a2d710c0b35794b16bde7d", + "websnark": "0.0.5", "winston": "^3.2.1" }, "devDependencies": { diff --git a/semaphorejs/scripts/run_all_test.sh b/semaphorejs/scripts/run_all_test.sh index da53a321..b3ef2ae2 100755 --- a/semaphorejs/scripts/run_all_test.sh +++ b/semaphorejs/scripts/run_all_test.sh @@ -62,6 +62,7 @@ CREATION_HASH=`cat ../build/contracts/Semaphore.json | jq ".networks.\"${CHAIN_I CHAIN_ID=${CHAIN_ID} CONTRACT_ADDRESS=$ADDRESS FROM_ADDRESS=0x1929c15f4e818abf2549510622a50c440c474223 FROM_PRIVATE_KEY=0x6738837df169e8d6ffc6e33a2947e58096d644fa4aa6d74358c8d9d57c12cd21 NODE_URL=${NODE_URL} EXTERNAL_NULLIFIER=12312 SEMAPHORE_SERVER_URL=http://localhost:3000 CONFIG_ENV=true BASE_DIR=../.. npx semaphorejs-client generate_identity +echo done IDENTITY_COMMITMENT=`cat ./semaphore_identity.json | jq '.identity_commitment' | sed 's/"//g'` echo ${IDENTITY_COMMITMENT} diff --git a/semaphorejs/snark/semaphore-base.circom b/semaphorejs/snark/semaphore-base.circom index b0ee6a21..0b438679 100644 --- a/semaphorejs/snark/semaphore-base.circom +++ b/semaphorejs/snark/semaphore-base.circom @@ -51,6 +51,7 @@ template Semaphore(jubjub_field_size, n_levels, n_rounds) { // mimc vector commitment signal private input identity_pk[2]; signal private input identity_nullifier; + signal private input identity_trapdoor; signal private input identity_path_elements[n_levels]; signal private input identity_path_index[n_levels]; @@ -79,10 +80,13 @@ template Semaphore(jubjub_field_size, n_levels, n_rounds) { component identity_nullifier_bits = Num2Bits(248); identity_nullifier_bits.in <== identity_nullifier; + component identity_trapdoor_bits = Num2Bits(248); + identity_trapdoor_bits.in <== identity_trapdoor; + component identity_pk_0_bits = Num2Bits_strict(); identity_pk_0_bits.in <== dbl3.xout; - component identity_commitment = Pedersen(2*256); + component identity_commitment = Pedersen(3*256); // BEGIN identity commitment for (var i = 0; i < 256; i++) { if (i < 254) { @@ -93,8 +97,10 @@ template Semaphore(jubjub_field_size, n_levels, n_rounds) { if (i < 248) { identity_commitment.in[i + 256] <== identity_nullifier_bits.out[i]; + identity_commitment.in[i + 2*256] <== identity_trapdoor_bits.out[i]; } else { identity_commitment.in[i + 256] <== 0; + identity_commitment.in[i + 2*256] <== 0; } } // END identity commitment diff --git a/semaphorejs/src/client/semaphore.js b/semaphorejs/src/client/semaphore.js index 3303c1d4..e2cc2ed2 100644 --- a/semaphorejs/src/client/semaphore.js +++ b/semaphorejs/src/client/semaphore.js @@ -96,8 +96,9 @@ class SemaphoreClient { const pubKey = eddsa.prv2pub(prvKey); this.identity_nullifier = loaded_identity.identity_nullifier; + this.identity_trapdoor = loaded_identity.identity_trapdoor; - this.identity_commitment = pedersenHash([bigInt(circomlib.babyJub.mulPointEscalar(pubKey, 8)[0]), bigInt(this.identity_nullifier)]); + this.identity_commitment = pedersenHash([bigInt(circomlib.babyJub.mulPointEscalar(pubKey, 8)[0]), bigInt(this.identity_nullifier), bigInt(this.identity_trapdoor)]); this.web3 = new Web3(node_url); this.web3.eth.transactionConfirmationBlocks = transaction_confirmation_blocks; @@ -147,6 +148,7 @@ class SemaphoreClient { assert(eddsa.verifyMiMCSponge(msg, signature, pubKey)); const identity_nullifier = this.identity_nullifier; + const identity_trapdoor = this.identity_trapdoor; let identity_path; if (this.identity_index === null) { @@ -177,6 +179,7 @@ class SemaphoreClient { signal_hash, external_nullifier, identity_nullifier, + identity_trapdoor, identity_path_elements, identity_path_index, }; @@ -283,14 +286,16 @@ function generate_identity(logger) { const pubKey = eddsa.prv2pub(prvKey); const identity_nullifier = '0x' + crypto.randomBytes(31).toString('hex'); - logger.info(`generate identity from (private_key, public_key[0], public_key[1], identity_nullifier): (${private_key}, ${pubKey[0]}, ${pubKey[1]}, ${identity_nullifier})`); + const identity_trapdoor = '0x' + crypto.randomBytes(31).toString('hex'); + logger.info(`generate identity from (private_key, public_key[0], public_key[1], identity_nullifier): (${private_key}, ${pubKey[0]}, ${pubKey[1]}, ${identity_nullifier}, ${identity_trapdoor})`); - const identity_commitment = pedersenHash([bigInt(circomlib.babyJub.mulPointEscalar(pubKey, 8)[0]), bigInt(identity_nullifier)]); + const identity_commitment = pedersenHash([bigInt(circomlib.babyJub.mulPointEscalar(pubKey, 8)[0]), bigInt(identity_nullifier), bigInt(identity_trapdoor)]); logger.info(`identity_commitment : ${identity_commitment}`); const generated_identity = { private_key, identity_nullifier: identity_nullifier.toString(), + identity_trapdoor: identity_trapdoor.toString(), identity_commitment: identity_commitment.toString(), }; diff --git a/semaphorejs/src/server/server.js b/semaphorejs/src/server/server.js index 84bc7233..45b7519d 100755 --- a/semaphorejs/src/server/server.js +++ b/semaphorejs/src/server/server.js @@ -128,7 +128,7 @@ class SemaphoreServer { this.identity_tree_index = await this.contract.methods.getIdTreeIndex().call({from: from_address}, last_processed_block); - const state_root = await this.contract.methods.roots(this.identity_tree_index).call({from: from_address}, last_processed_block); + const state_root = await this.contract.methods.root(this.identity_tree_index).call({from: from_address}, last_processed_block); logger.debug(`state_root: ${state_root}`); const saved_state_block = await this.get_state_for_block(last_processed_block); @@ -153,7 +153,7 @@ class SemaphoreServer { ); if (logs.length > 0) { - const state_root = await this.contract.methods.roots(this.identity_tree_index).call({from: from_address}, target_block_number); + const state_root = await this.contract.methods.root(this.identity_tree_index).call({from: from_address}, target_block_number); logger.verbose(`state_root: ${state_root}`); const saved_state_block = await this.get_state_for_block(target_block_number); @@ -351,7 +351,7 @@ async function fund() { } async function disablePermissioning() { - const encoded = await semaphore.contract.methods.disablePermissioning().encodeABI(); + const encoded = await semaphore.contract.methods.setPermissioning(false).encodeABI(); await send_transaction(encoded); } diff --git a/semaphorejs/src/util/index.js b/semaphorejs/src/util/index.js index cbed3523..7f1dee24 100644 --- a/semaphorejs/src/util/index.js +++ b/semaphorejs/src/util/index.js @@ -71,11 +71,11 @@ function convertWitness(witnessJson) { return Buffer.from(buff); } -const buildGroth16 = require('websnark/src/groth16.js'); +const buildGroth16 = require('websnark/src/bn128.js'); async function prove(witness, provingKey) { const groth16 = await buildGroth16(); - const p = await groth16.proof(witness, provingKey); + const p = await groth16.groth16GenProof(witness, provingKey); //groth16.terminate(); return snarkjs.unstringifyBigInts(p); } diff --git a/semaphorejs/src/web/client_web.js b/semaphorejs/src/web/client_web.js index 435b69a4..42c82ac1 100644 --- a/semaphorejs/src/web/client_web.js +++ b/semaphorejs/src/web/client_web.js @@ -139,7 +139,7 @@ const SemaphoreABI = require('../../build/contracts/Semaphore.json'); async function update_state() { $('#s_block_number').text(await web3js.eth.getBlockNumber()); const id_tree_index = await semaphore_contract.methods.id_tree_index().call(); - const root = await semaphore_contract.methods.roots(id_tree_index.toString()).call(); + const root = await semaphore_contract.methods.root(id_tree_index.toString()).call(); $('#s_root').text('0x' + bigInt(root.toString()).toString(16)); const external_nullifier = await semaphore_contract.methods.external_nullifier().call(); $('#s_external_nullifier').text('0x' + bigInt(external_nullifier.toString()).toString(16)); diff --git a/semaphorejs/test/circuits/semaphore/circuit.js b/semaphorejs/test/circuits/semaphore/circuit.js index df9baa04..654b2f2a 100644 --- a/semaphorejs/test/circuits/semaphore/circuit.js +++ b/semaphorejs/test/circuits/semaphore/circuit.js @@ -87,7 +87,8 @@ describe('circuit test', function () { assert(eddsa.verifyMiMCSponge(msg, signature, pubKey)); const identity_nullifier = bigInt('230'); - const identity_commitment = pedersenHash([bigInt(circomlib.babyJub.mulPointEscalar(pubKey, 8)[0]), bigInt(identity_nullifier)]); + const identity_trapdoor = bigInt('231'); + const identity_commitment = pedersenHash([bigInt(circomlib.babyJub.mulPointEscalar(pubKey, 8)[0]), bigInt(identity_nullifier), bigInt(identity_trapdoor)]); const tree = build_merkle_tree_example(20, identity_commitment); @@ -104,6 +105,7 @@ describe('circuit test', function () { signal_hash, external_nullifier, identity_nullifier, + identity_trapdoor, identity_path_elements, identity_path_index, }); diff --git a/semaphorejs/test/contracts/semaphore.js b/semaphorejs/test/contracts/semaphore.js index 04ed04a9..7b10287b 100644 --- a/semaphorejs/test/contracts/semaphore.js +++ b/semaphorejs/test/contracts/semaphore.js @@ -117,6 +117,7 @@ contract('Semaphore', function (accounts) { assert(eddsa.verifyMiMCSponge(msg, signature, pubKey)); const identity_nullifier = bigInt('231'); + const identity_trapdoor = bigInt('232'); const storage_path = '/tmp/rocksdb_semaphore_test'; if (fs.existsSync(storage_path)) { @@ -143,7 +144,7 @@ contract('Semaphore', function (accounts) { default_value, ); - const identity_commitment = pedersenHash([bigInt(circomlib.babyJub.mulPointEscalar(pubKey, 8)[0]), bigInt(identity_nullifier)]); + const identity_commitment = pedersenHash([bigInt(circomlib.babyJub.mulPointEscalar(pubKey, 8)[0]), bigInt(identity_nullifier), bigInt(identity_trapdoor)]); identity_commitment1 = identity_commitment; const semaphore = await Semaphore.deployed(); @@ -173,6 +174,7 @@ contract('Semaphore', function (accounts) { signal_hash, external_nullifier, identity_nullifier, + identity_trapdoor, identity_path_elements, identity_path_index, }); @@ -286,6 +288,7 @@ contract('Semaphore', function (accounts) { assert(eddsa.verifyMiMCSponge(msg, signature, pubKey)); const identity_nullifier = bigInt('230'); + const identity_trapdoor = bigInt('233'); const storage_path = '/tmp/rocksdb_semaphore_test'; if (fs.existsSync(storage_path)) { @@ -313,7 +316,7 @@ contract('Semaphore', function (accounts) { ); - const identity_commitment = pedersenHash([bigInt(circomlib.babyJub.mulPointEscalar(pubKey, 8)[0]), bigInt(identity_nullifier)]); + const identity_commitment = pedersenHash([bigInt(circomlib.babyJub.mulPointEscalar(pubKey, 8)[0]), bigInt(identity_nullifier), bigInt(identity_trapdoor)]); const semaphore = await Semaphore.deployed(); const receipt = await semaphore.insertIdentity(identity_commitment.toString()); @@ -344,6 +347,7 @@ contract('Semaphore', function (accounts) { signal_hash, external_nullifier, identity_nullifier, + identity_trapdoor, identity_path_elements, identity_path_index, });