mirror of
https://github.com/semaphore-protocol/semaphore.git
synced 2026-04-28 03:00:41 -04:00
Circuit updates (#8)
* feat: moves code to use mimcsponge, uses blake2s for commitment * fix: makes ci timeout larger * fix: updates sbmtjs's reference to circomlib to mimcsponge * fix: replaces rinkeby sponge address * fix: moves to a wasm compatible blake2 library * fix: attempts removing blake2.wasm from webpack * fix: moves to native js blake2 * fix: fixes webpack config to remove blake2 * fix: makes generate_identity sync * fix: changes mimc7 to mimcsponge in client_web * fix: updates websnark for smaller memory * fix: updates websnark for smaller memory * fix: adds enlarged heap for compilation * fix: adds enlarged heap for compilation * fix: makes tests pass * fix: makes MerkleTree use mimc sponge * feat: adds position to the nullifiers hash * feat: makes identity_nullifier 256 bits again, and makes external_nullifier 224 bits to make room for position * fix: makes sure that we index identity_path_index correctly in hash * feat: moves back to iden3's websnark version * feat: uses (8*pk).x for identity commitment * fix: changes identity_commitment to match circuit * fix: fixes contract end-to-end test to use new primitives * fix: ci uses local version of zkp-sbmtjs * feat: updates package versions * fix: removes npm link from ci * fix: changes tests to use MimcSpongeHasher * feat: attempts storing artifacts * feat: updates rinkeby contract address * feat: updates package-lock
This commit is contained in:
@@ -38,4 +38,8 @@ jobs:
|
||||
- run:
|
||||
name: end-to-end
|
||||
command: cd scripts && ./ci.sh
|
||||
no_output_timeout: 30m
|
||||
no_output_timeout: 600m
|
||||
|
||||
- store_artifacts:
|
||||
path: ~/semaphore/semaphorejs/build
|
||||
|
||||
|
||||
3
sbmtjs/package-lock.json
generated
3
sbmtjs/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "zkp-sbmtjs",
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -340,6 +340,7 @@
|
||||
"requires": {
|
||||
"blake-hash": "^1.1.0",
|
||||
"snarkjs": "0.1.11",
|
||||
"typedarray-to-buffer": "^3.1.5",
|
||||
"web3": "^1.0.0-beta.36"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "zkp-sbmtjs",
|
||||
"version": "0.2.1",
|
||||
"version": "0.3.0",
|
||||
"description": "Storage-backed Merkle tree",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@@ -16,7 +16,7 @@
|
||||
"await-lock": "^1.1.3",
|
||||
"chai": "^4.2.0",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"circomlib": "git+https://github.com/kobigurk/circomlib.git",
|
||||
"circomlib": "git+https://github.com/kobigurk/circomlib.git#f4a7f30faa9867be77522aea42332585338c235d",
|
||||
"del": "^4.0.0",
|
||||
"level-rocksdb": "^3.0.1",
|
||||
"snarkjs": "^0.1.11",
|
||||
|
||||
33
sbmtjs/src/hasher/mimcsponge/index.js
Normal file
33
sbmtjs/src/hasher/mimcsponge/index.js
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* sbmtjs - Storage-backed Merkle tree
|
||||
* Copyright (C) 2019 Kobi Gurkan <kobigurk@gmail.com>
|
||||
*
|
||||
* This file is part of sbmtjs.
|
||||
*
|
||||
* sbmtjs is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* sbmtjs is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with sbmtjs. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const circomlib = require('circomlib');
|
||||
const mimcsponge = circomlib.mimcsponge;
|
||||
const snarkjs = require('snarkjs');
|
||||
|
||||
const bigInt = snarkjs.bigInt;
|
||||
|
||||
class MimcSpongeHasher {
|
||||
hash(level, left, right) {
|
||||
return mimcsponge.multiHash([bigInt(left), bigInt(right)]).toString();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MimcSpongeHasher;
|
||||
@@ -21,7 +21,7 @@
|
||||
pragma solidity >=0.4.21;
|
||||
|
||||
library MiMC {
|
||||
function MiMCpe7(uint256 in_x, uint256 in_k) pure public returns (uint256 out_x);
|
||||
function MiMCSponge(uint256 in_xL, uint256 in_xR, uint256 in_k) pure public returns (uint256 xL, uint256 xR);
|
||||
}
|
||||
|
||||
contract MerkleTree {
|
||||
@@ -52,12 +52,16 @@ contract MerkleTree {
|
||||
|
||||
function HashLeftRight(uint256 left, uint256 right) public pure returns (uint256 mimc_hash) {
|
||||
uint256 k = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
|
||||
uint256 r0 = 0;
|
||||
uint256 h0 = MiMC.MiMCpe7(left, r0);
|
||||
uint256 r1 = addmod(r0, addmod(left, h0, k), k);
|
||||
uint256 h1 = MiMC.MiMCpe7(right, r1);
|
||||
uint256 r2 = addmod(r1, addmod(right, h1, k), k);
|
||||
mimc_hash = r2;
|
||||
uint256 R = 0;
|
||||
uint256 C = 0;
|
||||
|
||||
R = addmod(R, left, k);
|
||||
(R, C) = MiMC.MiMCSponge(R, C, 0);
|
||||
|
||||
R = addmod(R, right, k);
|
||||
(R, C) = MiMC.MiMCSponge(R, C, 0);
|
||||
|
||||
mimc_hash = R;
|
||||
}
|
||||
|
||||
function insert(uint256 leaf) internal {
|
||||
@@ -90,34 +94,14 @@ contract MerkleTree {
|
||||
emit LeafAdded(leaf, leaf_index);
|
||||
}
|
||||
|
||||
function update(uint256 old_leaf, uint256 leaf, uint32 leaf_index, uint256[] memory old_path, uint256[] memory path) internal {
|
||||
function update(uint256 leaf, uint32 leaf_index, uint256[] memory path) internal {
|
||||
uint32 current_index = leaf_index;
|
||||
|
||||
uint256 current_level_hash = old_leaf;
|
||||
uint256 current_level_hash = leaf;
|
||||
uint256 left;
|
||||
uint256 right;
|
||||
|
||||
for (uint8 i = 0; i < levels; i++) {
|
||||
if (current_index % 2 == 0) {
|
||||
left = current_level_hash;
|
||||
right = old_path[i];
|
||||
} else {
|
||||
left = old_path[i];
|
||||
right = current_level_hash;
|
||||
}
|
||||
|
||||
current_level_hash = HashLeftRight(left, right);
|
||||
|
||||
current_index /= 2;
|
||||
}
|
||||
|
||||
require(root == current_level_hash);
|
||||
|
||||
current_index = leaf_index;
|
||||
|
||||
current_level_hash = leaf;
|
||||
|
||||
for (i = 0; i < levels; i++) {
|
||||
if (current_index % 2 == 0) {
|
||||
left = current_level_hash;
|
||||
right = path[i];
|
||||
@@ -131,8 +115,6 @@ contract MerkleTree {
|
||||
current_index /= 2;
|
||||
}
|
||||
|
||||
root = current_level_hash;
|
||||
|
||||
emit LeafUpdated(leaf, leaf_index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
pragma solidity >=0.4.21;
|
||||
|
||||
library MiMC {
|
||||
function MiMCpe7(uint256 in_x, uint256 in_k) pure public returns (uint256 out_x);
|
||||
function MiMCSponge(uint256 in_xL, uint256 in_xR, uint256 in_k) pure public returns (uint256 xL, uint256 xR);
|
||||
}
|
||||
|
||||
contract MultipleMerkleTree {
|
||||
@@ -61,12 +61,16 @@ contract MultipleMerkleTree {
|
||||
|
||||
function HashLeftRight(uint256 left, uint256 right) public pure returns (uint256 mimc_hash) {
|
||||
uint256 k = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
|
||||
uint256 r0 = 0;
|
||||
uint256 h0 = MiMC.MiMCpe7(left, r0);
|
||||
uint256 r1 = addmod(r0, addmod(left, h0, k), k);
|
||||
uint256 h1 = MiMC.MiMCpe7(right, r1);
|
||||
uint256 r2 = addmod(r1, addmod(right, h1, k), k);
|
||||
mimc_hash = r2;
|
||||
uint256 R = 0;
|
||||
uint256 C = 0;
|
||||
|
||||
R = addmod(R, left, k);
|
||||
(R, C) = MiMC.MiMCSponge(R, C, 0);
|
||||
|
||||
R = addmod(R, right, k);
|
||||
(R, C) = MiMC.MiMCSponge(R, C, 0);
|
||||
|
||||
mimc_hash = R;
|
||||
}
|
||||
|
||||
function insert(uint8 tree_index, uint256 leaf) internal {
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
|
||||
const path = require('path');
|
||||
|
||||
const mimcGenContract = require('circomlib/src/mimc_gencontract.js');
|
||||
const mimcGenContract = require('circomlib/src/mimcsponge_gencontract.js');
|
||||
const Artifactor = require('truffle-artifactor');
|
||||
|
||||
const SEED = 'mimc';
|
||||
const SEED = 'mimcsponge';
|
||||
|
||||
|
||||
module.exports = function(deployer) {
|
||||
@@ -34,7 +34,7 @@ module.exports = function(deployer) {
|
||||
await artifactor.save({
|
||||
contractName: mimcContractName,
|
||||
abi: mimcGenContract.abi,
|
||||
unlinked_binary: mimcGenContract.createCode(SEED, 91),
|
||||
unlinked_binary: mimcGenContract.createCode(SEED, 220),
|
||||
})
|
||||
.then(async () => {
|
||||
const MiMC = artifacts.require(mimcContractName);
|
||||
|
||||
54
semaphorejs/package-lock.json
generated
54
semaphorejs/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "zkp-semaphorejs",
|
||||
"version": "0.2.1",
|
||||
"version": "0.3.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -1302,6 +1302,11 @@
|
||||
"nan": "^2.2.1"
|
||||
}
|
||||
},
|
||||
"blakejs": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz",
|
||||
"integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U="
|
||||
},
|
||||
"block-stream": {
|
||||
"version": "0.0.9",
|
||||
"resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
|
||||
@@ -1757,8 +1762,8 @@
|
||||
}
|
||||
},
|
||||
"circomlib": {
|
||||
"version": "git+https://github.com/iden3/circomlib.git#d91afa804ace6481f4468eebc0bf55229771e24c",
|
||||
"from": "git+https://github.com/iden3/circomlib.git#d91afa804ace6481f4468eebc0bf55229771e24c",
|
||||
"version": "git+https://github.com/kobigurk/circomlib.git#f4a7f30faa9867be77522aea42332585338c235d",
|
||||
"from": "git+https://github.com/kobigurk/circomlib.git#f4a7f30faa9867be77522aea42332585338c235d",
|
||||
"requires": {
|
||||
"blake-hash": "^1.1.0",
|
||||
"snarkjs": "0.1.11",
|
||||
@@ -12271,9 +12276,9 @@
|
||||
}
|
||||
},
|
||||
"node-abi": {
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.8.0.tgz",
|
||||
"integrity": "sha512-1/aa2clS0pue0HjckL62CsbhWWU35HARvBDXcJtYKbYR7LnIutmpxmXbuDMV9kEviD2lP/wACOgWmmwljghHyQ==",
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.9.0.tgz",
|
||||
"integrity": "sha512-jmEOvv0eanWjhX8dX1pmjb7oJl1U1oR4FOh0b2GnvALwSYoOdU7sj+kLDSAyjo4pfC9aj/IxkloxdLJQhSSQBA==",
|
||||
"requires": {
|
||||
"semver": "^5.4.1"
|
||||
}
|
||||
@@ -16461,8 +16466,8 @@
|
||||
}
|
||||
},
|
||||
"websnark": {
|
||||
"version": "git+https://github.com/kobigurk/websnark.git#30a4b3d7fba78421aaf9e6b11e6c8b399eacced2",
|
||||
"from": "git+https://github.com/kobigurk/websnark.git#30a4b3d7fba78421aaf9e6b11e6c8b399eacced2",
|
||||
"version": "git+https://github.com/iden3/websnark.git#3b6cf0c77e48ab0867a2d710c0b35794b16bde7d",
|
||||
"from": "git+https://github.com/iden3/websnark.git",
|
||||
"requires": {
|
||||
"big-integer": "^1.6.42"
|
||||
}
|
||||
@@ -16752,43 +16757,18 @@
|
||||
}
|
||||
},
|
||||
"zkp-sbmtjs": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/zkp-sbmtjs/-/zkp-sbmtjs-0.2.1.tgz",
|
||||
"integrity": "sha512-v2xSE1Wm3qA+hyh3g+wCEQNM6xGH3q9FauZDGd9q6NI0h3z07GuVADpEVNYs2BEKj5t8ZrGuJLGhpFaMALcZCg==",
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/zkp-sbmtjs/-/zkp-sbmtjs-0.3.0.tgz",
|
||||
"integrity": "sha512-0x+o+JEJBFDTnupf9H2RyC2JufEA7OgRJfZ8unzqq2/fjgmMzZiai1T7+McucyEvpuE76hMvVwGmFy8ZFBUa+A==",
|
||||
"requires": {
|
||||
"await-lock": "^1.1.3",
|
||||
"chai": "^4.2.0",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"circomlib": "git+https://github.com/kobigurk/circomlib.git",
|
||||
"circomlib": "git+https://github.com/kobigurk/circomlib.git#f4a7f30faa9867be77522aea42332585338c235d",
|
||||
"del": "^4.0.0",
|
||||
"level-rocksdb": "^3.0.1",
|
||||
"snarkjs": "^0.1.11",
|
||||
"uuid": "^3.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"circomlib": {
|
||||
"version": "git+https://github.com/kobigurk/circomlib.git#b254beaa50db7857ff6d8163c24d579c3f338f4b",
|
||||
"from": "git+https://github.com/kobigurk/circomlib.git",
|
||||
"requires": {
|
||||
"blake-hash": "^1.1.0",
|
||||
"snarkjs": "0.1.11",
|
||||
"web3": "^1.0.0-beta.36"
|
||||
},
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "zkp-semaphorejs",
|
||||
"version": "0.2.5",
|
||||
"version": "0.3.0",
|
||||
"description": "Zero-knowledge signaling on Ethereum",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@@ -18,8 +18,9 @@
|
||||
"url": "https://github.com/kobigurk/semaphore.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"blakejs": "^1.1.0",
|
||||
"circom": "0.0.27",
|
||||
"circomlib": "git+https://github.com/iden3/circomlib.git#d91afa804ace6481f4468eebc0bf55229771e24c",
|
||||
"circomlib": "git+https://github.com/kobigurk/circomlib.git#f4a7f30faa9867be77522aea42332585338c235d",
|
||||
"cors": "^2.8.5",
|
||||
"del": "^4.1.0",
|
||||
"file-saver": "^2.0.1",
|
||||
@@ -39,7 +40,7 @@
|
||||
"webpack": "^4.30.0",
|
||||
"websnark": "git+https://github.com/iden3/websnark.git",
|
||||
"winston": "^3.2.1",
|
||||
"zkp-sbmtjs": "^0.2.1"
|
||||
"zkp-sbmtjs": "^0.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"npm-update-git-deps": "^1.2.4",
|
||||
|
||||
@@ -24,6 +24,7 @@ echo "Working directory: `pwd`"
|
||||
./do_setup.sh
|
||||
./convert_to_wasm.sh
|
||||
./build_verifier.sh
|
||||
|
||||
npx mocha --recursive ../test/circuits
|
||||
../node_modules/.bin/ganache-cli -p 7545 -l 8800000 -i 5777 --account='0x6738837df169e8d6ffc6e33a2947e58096d644fa4aa6d74358c8d9d57c12cd21,100000000000000000000000000' --account='0x6738837df169e8d6ffc6e33a2947e58096d644fa4aa6d74358c8d9d57c12cd21,10000000000000000000000000' -q &
|
||||
../node_modules/.bin/truffle migrate --reset
|
||||
|
||||
@@ -22,5 +22,6 @@
|
||||
mkdir -p ../build
|
||||
cd ../build
|
||||
|
||||
export NODE_OPTIONS=--max-old-space-size=4096
|
||||
npx circom ../snark/semaphore.circom
|
||||
|
||||
|
||||
@@ -19,5 +19,6 @@
|
||||
# along with semaphorejs. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
export NODE_OPTIONS=--max-old-space-size=4096
|
||||
node ../node_modules/websnark/tools/buildpkey.js -i ../build/proving_key.json -o ../build/proving_key.bin
|
||||
|
||||
|
||||
@@ -22,5 +22,6 @@
|
||||
mkdir -p ../build
|
||||
cd ../build
|
||||
|
||||
export NODE_OPTIONS=--max-old-space-size=4096
|
||||
npx snarkjs setup --protocol groth
|
||||
|
||||
|
||||
@@ -63,6 +63,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
|
||||
|
||||
IDENTITY_COMMITMENT=`cat ./semaphore_identity.json | jq '.identity_commitment' | sed 's/"//g'`
|
||||
echo ${IDENTITY_COMMITMENT}
|
||||
|
||||
tmux \
|
||||
new-session "source ~/.bashrc; export CONFIG_ENV=true LOG_LEVEL=${LOG_LEVEL} CHAIN_ID=${CHAIN_ID} CONTRACT_ADDRESS=$ADDRESS NODE_URL=${SERVER_NODE_URL} SEMAPHORE_PORT=3000 FROM_ADDRESS=0x1929c15f4e818abf2549510622a50c440c474223 FROM_PRIVATE_KEY=0x6738837df169e8d6ffc6e33a2947e58096d644fa4aa6d74358c8d9d57c12cd21 TRANSACTION_CONFIRMATION_BLOCKS=1 CREATION_HASH=${CREATION_HASH}; npx semaphorejs-server fund; npx semaphorejs-server; bash -i" \; \
|
||||
|
||||
@@ -122,10 +122,12 @@ template Blake2sCompression(t, f) {
|
||||
}
|
||||
|
||||
signal v_pass_1[16][32];
|
||||
component v_12_xor = Uint32Xor();
|
||||
component v_13_xor = Uint32Xor();
|
||||
component v_14_xor = Uint32Xor();
|
||||
|
||||
for (var i = 0; i < 16; i++) {
|
||||
if (i == 12) {
|
||||
component v_12_xor = Uint32Xor();
|
||||
for (var j = 0; j < 32; j++) {
|
||||
v_12_xor.a_bits[j] <== v_h[i][j];
|
||||
v_12_xor.b_bits[j] <== (t >> j) & 1;
|
||||
@@ -134,7 +136,6 @@ template Blake2sCompression(t, f) {
|
||||
v_pass_1[i][j] <== v_12_xor.out_bits[j];
|
||||
}
|
||||
} else if (i == 13) {
|
||||
component v_13_xor = Uint32Xor();
|
||||
for (var j = 0; j < 32; j++) {
|
||||
v_13_xor.a_bits[j] <== v_h[i][j];
|
||||
v_13_xor.b_bits[j] <== (t >> (32 + j)) & 1;
|
||||
@@ -142,14 +143,23 @@ template Blake2sCompression(t, f) {
|
||||
for (var j = 0; j < 32; j++) {
|
||||
v_pass_1[i][j] <== v_13_xor.out_bits[j];
|
||||
}
|
||||
} else if ((i == 14) && (f == 1)) {
|
||||
component v_14_xor = Uint32Xor();
|
||||
for (var j = 0; j < 32; j++) {
|
||||
v_14_xor.a_bits[j] <== v_h[i][j];
|
||||
v_14_xor.b_bits[j] <== 1;
|
||||
}
|
||||
for (var j = 0; j < 32; j++) {
|
||||
v_pass_1[i][j] <== v_14_xor.out_bits[j];
|
||||
} else if ((i == 14)) {
|
||||
if (f == 1) {
|
||||
for (var j = 0; j < 32; j++) {
|
||||
v_14_xor.a_bits[j] <== v_h[i][j];
|
||||
v_14_xor.b_bits[j] <== 1;
|
||||
}
|
||||
for (var j = 0; j < 32; j++) {
|
||||
v_pass_1[i][j] <== v_14_xor.out_bits[j];
|
||||
}
|
||||
} else {
|
||||
for (var j = 0; j < 32; j++) {
|
||||
v_14_xor.a_bits[j] <== v_h[i][j];
|
||||
v_14_xor.b_bits[j] <== 0;
|
||||
}
|
||||
for (var j = 0; j < 32; j++) {
|
||||
v_pass_1[i][j] <== v_h[i][j];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (var j = 0; j < 32; j++) {
|
||||
@@ -352,7 +362,7 @@ template Blake2s(n_bits, personalization) {
|
||||
}
|
||||
}
|
||||
for (var l = 0; l < 16; l++) {
|
||||
current_bit = 32*l + j;
|
||||
current_bit = 512*i + 32*l + j;
|
||||
if (current_bit < n_bits) {
|
||||
compressions[i].in_m[l][j] <== in_bits[current_bit];
|
||||
} else {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
include "../node_modules/circomlib/circuits/mimc.circom";
|
||||
include "../node_modules/circomlib/circuits/mimcsponge.circom";
|
||||
include "../node_modules/circomlib/circuits/bitify.circom";
|
||||
include "../node_modules/circomlib/circuits/eddsamimc.circom";
|
||||
include "../node_modules/circomlib/circuits/eddsamimcsponge.circom";
|
||||
include "./blake2s/blake2s.circom";
|
||||
|
||||
template HashLeftRight(n_rounds) {
|
||||
@@ -9,12 +9,12 @@ template HashLeftRight(n_rounds) {
|
||||
|
||||
signal output hash;
|
||||
|
||||
component hasher = MultiMiMC7(2, n_rounds);
|
||||
left ==> hasher.in[0];
|
||||
right ==> hasher.in[1];
|
||||
component hasher = MiMCSponge(2, n_rounds, 1);
|
||||
left ==> hasher.ins[0];
|
||||
right ==> hasher.ins[1];
|
||||
hasher.k <== 0;
|
||||
|
||||
hash <== hasher.out;
|
||||
hash <== hasher.outs[0];
|
||||
}
|
||||
|
||||
template Selector() {
|
||||
@@ -51,7 +51,6 @@ 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_r;
|
||||
signal private input identity_path_elements[n_levels];
|
||||
signal private input identity_path_index[n_levels];
|
||||
|
||||
@@ -59,20 +58,36 @@ template Semaphore(jubjub_field_size, n_levels, n_rounds) {
|
||||
signal private input auth_sig_r[2];
|
||||
signal private input auth_sig_s;
|
||||
|
||||
// get a prime subgroup element derived from identity_pk
|
||||
component dbl1 = BabyDbl();
|
||||
dbl1.x <== identity_pk[0];
|
||||
dbl1.y <== identity_pk[1];
|
||||
component dbl2 = BabyDbl();
|
||||
dbl2.x <== dbl1.xout;
|
||||
dbl2.y <== dbl1.yout;
|
||||
component dbl3 = BabyDbl();
|
||||
dbl3.x <== dbl2.xout;
|
||||
dbl3.y <== dbl2.yout;
|
||||
|
||||
// mimc hash
|
||||
signal output root;
|
||||
signal output nullifiers_hash;
|
||||
|
||||
// END signals
|
||||
|
||||
component identity_commitment = MultiMiMC7(4, n_rounds);
|
||||
|
||||
component identity_nullifier_bits = Num2Bits(256);
|
||||
identity_nullifier_bits.in <== identity_nullifier;
|
||||
|
||||
component identity_pk_0_bits = Num2Bits(256);
|
||||
identity_pk_0_bits.in <== dbl3.xout;
|
||||
|
||||
component identity_commitment = Blake2s(2*256, 0);
|
||||
// BEGIN identity commitment
|
||||
identity_commitment.in[0] <== identity_pk[0];
|
||||
identity_commitment.in[1] <== identity_pk[1];
|
||||
identity_commitment.in[2] <== identity_nullifier;
|
||||
identity_commitment.in[3] <== identity_r;
|
||||
identity_commitment.k <== 0;
|
||||
for (var i = 0; i < 256; i++) {
|
||||
identity_commitment.in_bits[i] <== identity_pk_0_bits.out[i];
|
||||
identity_commitment.in_bits[i + 256] <== identity_nullifier_bits.out[i];
|
||||
}
|
||||
// END identity commitment
|
||||
|
||||
// BEGIN tree
|
||||
@@ -90,7 +105,12 @@ template Semaphore(jubjub_field_size, n_levels, n_rounds) {
|
||||
selectors[i].right ==> hashers[i].right;
|
||||
}
|
||||
|
||||
identity_commitment.out ==> selectors[0].input_elem;
|
||||
component identity_commitment_num = Bits2Num(253);
|
||||
for (var i = 0; i < 253; i++) {
|
||||
identity_commitment_num.in[i] <== identity_commitment.out[i];
|
||||
}
|
||||
|
||||
identity_commitment_num.out ==> selectors[0].input_elem;
|
||||
|
||||
for (var i = 1; i < n_levels; i++) {
|
||||
hashers[i-1].hash ==> selectors[i].input_elem;
|
||||
@@ -100,15 +120,21 @@ template Semaphore(jubjub_field_size, n_levels, n_rounds) {
|
||||
// END tree
|
||||
|
||||
// BEGIN nullifiers
|
||||
component identity_nullifier_bits = Num2Bits(254);
|
||||
identity_nullifier_bits.in <== identity_nullifier;
|
||||
component external_nullifier_bits = Num2Bits(254);
|
||||
component external_nullifier_bits = Num2Bits(256);
|
||||
external_nullifier_bits.in <== external_nullifier;
|
||||
|
||||
component nullifiers_hasher = Blake2s(508, 248018401820981);
|
||||
for (var i = 0; i < 254; i++) {
|
||||
component nullifiers_hasher = Blake2s(512, 0);
|
||||
for (var i = 0; i < 256; i++) {
|
||||
nullifiers_hasher.in_bits[i] <== identity_nullifier_bits.out[i];
|
||||
nullifiers_hasher.in_bits[254 + i] <== external_nullifier_bits.out[i];
|
||||
if (i < 224) {
|
||||
nullifiers_hasher.in_bits[256 + i] <== external_nullifier_bits.out[i];
|
||||
} else {
|
||||
if ( (i-224) < n_levels ) {
|
||||
nullifiers_hasher.in_bits[256 + i] <== identity_path_index[i - 224];
|
||||
} else {
|
||||
nullifiers_hasher.in_bits[256 + i] <== 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component nullifiers_hash_num = Bits2Num(253);
|
||||
@@ -121,20 +147,20 @@ template Semaphore(jubjub_field_size, n_levels, n_rounds) {
|
||||
// END nullifiers
|
||||
|
||||
// BEGIN verify sig
|
||||
component msg_hasher = MultiMiMC7(3, n_rounds);
|
||||
msg_hasher.in[0] <== external_nullifier;
|
||||
msg_hasher.in[1] <== signal_hash;
|
||||
msg_hasher.in[2] <== broadcaster_address;
|
||||
component msg_hasher = MiMCSponge(3, n_rounds, 1);
|
||||
msg_hasher.ins[0] <== external_nullifier;
|
||||
msg_hasher.ins[1] <== signal_hash;
|
||||
msg_hasher.ins[2] <== broadcaster_address;
|
||||
msg_hasher.k <== 0;
|
||||
|
||||
component sig_verifier = EdDSAMiMCVerifier();
|
||||
component sig_verifier = EdDSAMiMCSpongeVerifier();
|
||||
1 ==> sig_verifier.enabled;
|
||||
identity_pk[0] ==> sig_verifier.Ax;
|
||||
identity_pk[1] ==> sig_verifier.Ay;
|
||||
auth_sig_r[0] ==> sig_verifier.R8x;
|
||||
auth_sig_r[1] ==> sig_verifier.R8y;
|
||||
auth_sig_s ==> sig_verifier.S;
|
||||
msg_hasher.out ==> sig_verifier.M;
|
||||
msg_hasher.outs[0] ==> sig_verifier.M;
|
||||
|
||||
// END verify sig
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
include "./semaphore-base.circom";
|
||||
|
||||
component main = Semaphore(251, 20, 91);
|
||||
component main = Semaphore(251, 20, 220);
|
||||
|
||||
@@ -35,7 +35,6 @@ const circomlib = require('circomlib');
|
||||
const bigInt = snarkjs.bigInt;
|
||||
|
||||
const eddsa = circomlib.eddsa;
|
||||
const mimc7 = circomlib.mimc7;
|
||||
|
||||
const groth = snarkjs.groth;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
const crypto = require('crypto');
|
||||
const path = require('path');
|
||||
const {unstringifyBigInts, stringifyBigInts} = require('websnark/tools/stringifybigint.js');
|
||||
|
||||
const blake2 = require('blakejs');
|
||||
|
||||
const chai = require('chai');
|
||||
const assert = chai.assert;
|
||||
@@ -32,7 +32,7 @@ const circomlib = require('circomlib');
|
||||
const bigInt = snarkjs.bigInt;
|
||||
|
||||
const eddsa = circomlib.eddsa;
|
||||
const mimc7 = circomlib.mimc7;
|
||||
const mimcsponge = circomlib.mimcsponge;
|
||||
|
||||
const proof_util = require('../util');
|
||||
|
||||
@@ -42,6 +42,20 @@ const Web3 = require('web3');
|
||||
|
||||
let logger;
|
||||
|
||||
/* uint8array to hex */
|
||||
|
||||
function hex(byteArray) {
|
||||
return Array.prototype.map.call(byteArray, function(byte) {
|
||||
return ('0' + (byte & 0xFF).toString(16)).slice(-2);
|
||||
}).join('');
|
||||
}
|
||||
|
||||
const cutDownBits = function(b, bits) {
|
||||
let mask = bigInt(1);
|
||||
mask = mask.shl(bits).sub(bigInt(1));
|
||||
return b.and(mask);
|
||||
}
|
||||
|
||||
beBuff2int = function(buff) {
|
||||
let res = bigInt.zero;
|
||||
for (let i=0; i<buff.length; i++) {
|
||||
@@ -74,10 +88,12 @@ class SemaphoreClient {
|
||||
const pubKey = eddsa.prv2pub(prvKey);
|
||||
|
||||
this.identity_nullifier = loaded_identity.identity_nullifier;
|
||||
this.identity_r = loaded_identity.identity_r;
|
||||
|
||||
this.identity_commitment = mimc7.multiHash([bigInt(pubKey[0]), bigInt(pubKey[1]), bigInt(this.identity_nullifier), bigInt(this.identity_r)]);
|
||||
logger.verbose(`identity_commitment: ${this.identity_commitment}`);
|
||||
const identity_commitment_ints = [bigInt(circomlib.babyJub.mulPointEscalar(pubKey, 8)[0]), bigInt(this.identity_nullifier)];
|
||||
const identity_commitment_buffer = Buffer.concat(
|
||||
identity_commitment_ints.map(x => x.leInt2Buff(32))
|
||||
);
|
||||
this.identity_commitment_buffer = identity_commitment_buffer;
|
||||
|
||||
this.web3 = new Web3(node_url);
|
||||
this.web3.eth.transactionConfirmationBlocks = transaction_confirmation_blocks;
|
||||
@@ -98,6 +114,13 @@ class SemaphoreClient {
|
||||
|
||||
async broadcast_signal(signal_str) {
|
||||
logger.info(`broadcasting signal ${signal_str}`);
|
||||
|
||||
const identity_commitment_digest = blake2.blake2sHex(this.identity_commitment_buffer);
|
||||
logger.verbose(`identity_commitment digest: ${identity_commitment_digest}`);
|
||||
const identity_commitment_uncut = beBuff2int(new Buffer(identity_commitment_digest, 'hex'));
|
||||
logger.verbose(`identity_commitment_uncut: ${identity_commitment_uncut}`);
|
||||
this.identity_commitment = cutDownBits(identity_commitment_uncut, 253);
|
||||
logger.verbose(`identity_commitment: ${this.identity_commitment}`);
|
||||
//const prvKey = Buffer.from('0001020304050607080900010203040506070809000102030405060708090001', 'hex');
|
||||
const prvKey = Buffer.from(this.private_key, 'hex');
|
||||
|
||||
@@ -115,13 +138,12 @@ class SemaphoreClient {
|
||||
const signal_hash = beBuff2int(signal_hash_raw.slice(0, 31));
|
||||
const broadcaster_address = bigInt(this.broadcaster_address);
|
||||
|
||||
const msg = mimc7.multiHash([external_nullifier, signal_hash, broadcaster_address]);
|
||||
const signature = eddsa.signMiMC(prvKey, msg);
|
||||
const msg = mimcsponge.multiHash([external_nullifier, signal_hash, broadcaster_address]);
|
||||
const signature = eddsa.signMiMCSponge(prvKey, msg);
|
||||
|
||||
assert(eddsa.verifyMiMC(msg, signature, pubKey));
|
||||
assert(eddsa.verifyMiMCSponge(msg, signature, pubKey));
|
||||
|
||||
const identity_nullifier = this.identity_nullifier;
|
||||
const identity_r = this.identity_r;
|
||||
|
||||
let identity_path;
|
||||
if (this.identity_index === null) {
|
||||
@@ -152,7 +174,6 @@ class SemaphoreClient {
|
||||
signal_hash,
|
||||
external_nullifier,
|
||||
identity_nullifier,
|
||||
identity_r,
|
||||
identity_path_elements,
|
||||
identity_path_index,
|
||||
broadcaster_address,
|
||||
@@ -165,6 +186,7 @@ class SemaphoreClient {
|
||||
const root = w[this.circuit.getSignalIdx('main.root')];
|
||||
const nullifiers_hash = w[this.circuit.getSignalIdx('main.nullifiers_hash')];
|
||||
assert(this.circuit.checkWitness(w));
|
||||
logger.info(`identity commitment from proof: ${w[this.circuit.getSignalIdx('main.identity_commitment_num.out')].toString()}`);
|
||||
assert.equal(w[this.circuit.getSignalIdx('main.root')].toString(), identity_path.root);
|
||||
|
||||
logger.info(`generating proof (started at ${Date.now()})`);
|
||||
@@ -253,21 +275,24 @@ class SemaphoreClient {
|
||||
}
|
||||
|
||||
function generate_identity(logger) {
|
||||
|
||||
const private_key = crypto.randomBytes(32).toString('hex');
|
||||
const prvKey = Buffer.from(private_key, 'hex');
|
||||
const pubKey = eddsa.prv2pub(prvKey);
|
||||
|
||||
const identity_nullifier = '0x' + crypto.randomBytes(31).toString('hex');
|
||||
const identity_r = '0x' + crypto.randomBytes(31).toString('hex');
|
||||
logger.info(`generate identity from (private_key, public_key[0], public_key[1], identity_nullifier, identity_r): (${private_key}, ${pubKey[0]}, ${pubKey[1]}, ${identity_nullifier}, ${identity_r})`);
|
||||
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_commitment = mimc7.multiHash([bigInt(pubKey[0]), bigInt(pubKey[1]), bigInt(identity_nullifier), bigInt(identity_r)]);
|
||||
const identity_commitment_ints = [bigInt(circomlib.babyJub.mulPointEscalar(pubKey, 8)[0]), bigInt(identity_nullifier)];
|
||||
const identity_commitment_buffer = Buffer.concat(
|
||||
identity_commitment_ints.map(x => x.leInt2Buff(32))
|
||||
);
|
||||
const identity_commitment = cutDownBits(beBuff2int(new Buffer(blake2.blake2sHex(identity_commitment_buffer), 'hex')), 253);
|
||||
|
||||
logger.info(`identity_commitment : ${identity_commitment}`);
|
||||
const generated_identity = {
|
||||
private_key,
|
||||
identity_nullifier: identity_nullifier.toString(),
|
||||
identity_r: identity_r.toString(),
|
||||
identity_commitment: identity_commitment.toString(),
|
||||
};
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
const RocksDb = require('zkp-sbmtjs/src/storage/rocksdb');
|
||||
const MerkleTree = require('zkp-sbmtjs/src/tree');
|
||||
const Mimc7Hasher = require('zkp-sbmtjs/src/hasher/mimc7');
|
||||
const MimcSpongeHasher = require('zkp-sbmtjs/src/hasher/mimcsponge');
|
||||
|
||||
const Web3 = require('web3');
|
||||
const SemaphoreABI = require('../../build/contracts/Semaphore.json');
|
||||
@@ -284,7 +284,7 @@ class SemaphoreServer {
|
||||
|
||||
const prefix = 'semaphore';
|
||||
const storage = new RocksDb(server_config.DB_PATH || 'semaphore_server.db');
|
||||
const hasher = new Mimc7Hasher();
|
||||
const hasher = new MimcSpongeHasher();
|
||||
const default_value = '0';
|
||||
|
||||
const tree = new MerkleTree(
|
||||
|
||||
@@ -24,7 +24,7 @@ const circomlib = require('circomlib');
|
||||
|
||||
const bigInt = snarkjs.bigInt;
|
||||
|
||||
const mimc7 = circomlib.mimc7;
|
||||
const mimcsponge = circomlib.mimcsponge;
|
||||
|
||||
let build_merkle_tree_example = (n_levels, identity_commitment) => {
|
||||
let current_index = 0;
|
||||
@@ -33,7 +33,7 @@ let build_merkle_tree_example = (n_levels, identity_commitment) => {
|
||||
let current_element = identity_commitment;
|
||||
for (let i = 0; i < n_levels; i++) {
|
||||
path_elements.push(bigInt(0));
|
||||
current_element = mimc7.multiHash([ bigInt(current_element), bigInt(0) ]);
|
||||
current_element = mimcsponge.multiHash([ bigInt(current_element), bigInt(0) ]);
|
||||
|
||||
path_index.push(current_index % 2);
|
||||
current_index = Math.floor(current_index / 2);
|
||||
@@ -60,7 +60,7 @@ let build_full_merkle_tree_example = (n_levels, index, identity_commitment) => {
|
||||
tree_level.push(bigInt(j));
|
||||
}
|
||||
} else {
|
||||
tree_level.push(mimc7.multiHash([ tree[i-1][2*j], tree[i-1][2*j+1] ]));
|
||||
tree_level.push(mimcsponge.multiHash([ tree[i-1][2*j], tree[i-1][2*j+1] ]));
|
||||
}
|
||||
}
|
||||
if (current_index % 2 == 0) {
|
||||
@@ -73,7 +73,7 @@ let build_full_merkle_tree_example = (n_levels, index, identity_commitment) => {
|
||||
current_index = Math.floor(current_index / 2);
|
||||
}
|
||||
|
||||
const root = mimc7.multiHash([ tree[n_levels - 1][0], tree[n_levels - 1][1] ]);
|
||||
const root = mimcsponge.multiHash([ tree[n_levels - 1][0], tree[n_levels - 1][1] ]);
|
||||
|
||||
return [root, tree, path_elements, path_index];
|
||||
};
|
||||
|
||||
@@ -29,7 +29,7 @@ const snarkjs = require('snarkjs');
|
||||
const bigInt = snarkjs.bigInt;
|
||||
|
||||
const eddsa = require('circomlib/src/eddsa');
|
||||
const mimc7 = require('circomlib/src/mimc7');
|
||||
const mimcsponge = require('circomlib/src/mimcsponge');
|
||||
|
||||
const groth = snarkjs.groth;
|
||||
|
||||
@@ -136,7 +136,7 @@ const SemaphoreABI = require('../../build/contracts/Semaphore.json');
|
||||
left = data.path.path_elements[i];
|
||||
right = current_hash;
|
||||
}
|
||||
current_hash = bigInt(mimc7.multiHash([bigInt(left), bigInt(right)]));
|
||||
current_hash = bigInt(mimcsponge.multiHash([bigInt(left), bigInt(right)]));
|
||||
}
|
||||
const expected_root = '0x' + current_hash.toString(16);
|
||||
const signals_root = $('#s_signals_root').text();
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
external_nullifier: 'auto',
|
||||
semaphore_server_url: 'https://semaphore-server.kobi.one',
|
||||
semaphore_server_address: '0x1929c15f4e818abf2549510622a50c440c474223',
|
||||
semaphore_contract_address: '0xde297a7213b238F4a65F0a5B65F19C25c165dB38',
|
||||
semaphore_contract_address: '0x7A1f706D1051b320E876088cB38E28001f3E6130',
|
||||
from_private_key: '0x6738837df169e8d6ffc6e33a2947e58096d644fa4aa6d74358c8d9d57c12cd21',
|
||||
from_address: '0x1929c15f4e818abf2549510622a50c440c474223',
|
||||
chain_id: '4',
|
||||
|
||||
@@ -33,15 +33,15 @@ describe("blake2s test", () => {
|
||||
}).timeout(1000000);
|
||||
|
||||
it("Should run blake2s", async () => {
|
||||
const cirDef = await compiler(path.join(__dirname, "blake2s_test.circom"));
|
||||
fs.writeFileSync('blake2sdef.json', JSON.stringify(cirDef));
|
||||
//const cirDef = JSON.parse(fs.readFileSync('blake2sdef.json'));
|
||||
const cirDef = await compiler(path.join(__dirname, "blake2s_test.circom"));
|
||||
fs.writeFileSync('blake2sdef.json', JSON.stringify(cirDef));
|
||||
//const cirDef = JSON.parse(fs.readFileSync('blake2sdef.json'));
|
||||
const circuit = new snarkjs.Circuit(cirDef);
|
||||
|
||||
console.log("Vars: "+circuit.nVars);
|
||||
console.log("Constraints: "+circuit.nConstraints);
|
||||
|
||||
const bits = '00001000001110010010000001101001110100110001101010001101011010110001011101100001111111100000010000000000101010111001101001011110010100001111101011000010010000011010001111010100110100011001000110010001000000001001100011111011110010100000010000101011011000010000010111100110110011110111000100110110000101100100011011010010011010100110100101000010111010100000011101101011100000110111100011100000100000101110100011001101100001100100111011111111110011111101011110001011011001010011011100011000010111111001111010101010';
|
||||
const bits = '1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
|
||||
const inputs = {};
|
||||
for (let i = 0; i < bits.length; i++) {
|
||||
inputs[`in_bits[${i}]`] = bigInt(bits[i]);
|
||||
@@ -56,7 +56,7 @@ describe("blake2s test", () => {
|
||||
coeff = coeff.shl(1);
|
||||
}
|
||||
console.log(`blake2s hash: 0x${result.toString(16)}`);
|
||||
assert.equal(result.toString(16), '96dbac58ccef5c10e5226b1da1b20b44ea0ca52aa21abe80279a85686e838118');
|
||||
assert.equal(result.toString(16), 'c8a7a6e87d10557e3214979b2dda05b16a0e845a7367bcacb1890bfed50aaa97');
|
||||
|
||||
for (let i = 0; i < witness.length; i++) {
|
||||
//console.log(circuit.signalNames(i));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
include "../../../snark/blake2s/blake2s.circom";
|
||||
|
||||
component main = Blake2s(512, 248018401820981);
|
||||
component main = Blake2s(1024, 0);
|
||||
/*
|
||||
49 * 2**(0*8) +
|
||||
50 * 2**(1*8) +
|
||||
|
||||
@@ -24,6 +24,7 @@ const snarkjs = require('snarkjs');
|
||||
const compiler = require('circom');
|
||||
const fs = require('fs');
|
||||
const circomlib = require('circomlib');
|
||||
const blake2 = require('blakejs');
|
||||
|
||||
const test_util = require('../../../src/test_util');
|
||||
const build_merkle_tree_example = test_util.build_merkle_tree_example;
|
||||
@@ -33,7 +34,24 @@ const assert = chai.assert;
|
||||
const bigInt = snarkjs.bigInt;
|
||||
|
||||
const eddsa = circomlib.eddsa;
|
||||
const mimc7 = circomlib.mimc7;
|
||||
const mimcsponge = circomlib.mimcsponge;
|
||||
|
||||
const cutDownBits = function(b, bits) {
|
||||
let mask = bigInt(1);
|
||||
mask = mask.shl(bits).sub(bigInt(1));
|
||||
return b.and(mask);
|
||||
}
|
||||
|
||||
beBuff2int = function(buff) {
|
||||
let res = bigInt.zero;
|
||||
for (let i=0; i<buff.length; i++) {
|
||||
const n = bigInt(buff[buff.length - i - 1]);
|
||||
res = res.add(n.shl(i*8));
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
|
||||
describe('circuit test', function () {
|
||||
let circuit;
|
||||
@@ -56,14 +74,20 @@ describe('circuit test', function () {
|
||||
const signal_hash = bigInt('5');
|
||||
const broadcaster_address = bigInt('0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413');
|
||||
|
||||
const msg = mimc7.multiHash([bigInt(external_nullifier), bigInt(signal_hash), bigInt(broadcaster_address)]);
|
||||
const signature = eddsa.signMiMC(prvKey, msg);
|
||||
const msg = mimcsponge.multiHash([bigInt(external_nullifier), bigInt(signal_hash), bigInt(broadcaster_address)]);
|
||||
const signature = eddsa.signMiMCSponge(prvKey, msg);
|
||||
|
||||
assert(eddsa.verifyMiMC(msg, signature, pubKey));
|
||||
assert(eddsa.verifyMiMCSponge(msg, signature, pubKey));
|
||||
|
||||
const identity_nullifier = bigInt('230');
|
||||
const identity_r = bigInt('12311');
|
||||
const tree = build_merkle_tree_example(20, mimc7.multiHash([bigInt(pubKey[0]), bigInt(pubKey[1]), bigInt(identity_nullifier), bigInt(identity_r)]));
|
||||
const identity_commitment_ints = [bigInt(circomlib.babyJub.mulPointEscalar(pubKey, 8)[0]), bigInt(identity_nullifier)];
|
||||
const identity_commitment_buffer = Buffer.concat(
|
||||
identity_commitment_ints.map(x => x.leInt2Buff(32))
|
||||
);
|
||||
const identity_commitment = cutDownBits(beBuff2int(new Buffer(blake2.blake2sHex(identity_commitment_buffer), 'hex')), 253);
|
||||
|
||||
|
||||
const tree = build_merkle_tree_example(20, identity_commitment);
|
||||
|
||||
const identity_path_elements = tree[1];
|
||||
const identity_path_index = tree[2];
|
||||
@@ -78,7 +102,6 @@ describe('circuit test', function () {
|
||||
signal_hash,
|
||||
external_nullifier,
|
||||
identity_nullifier,
|
||||
identity_r,
|
||||
identity_path_elements,
|
||||
identity_path_index,
|
||||
broadcaster_address,
|
||||
|
||||
@@ -32,7 +32,7 @@ const MerkleTreeTester = artifacts.require('MerkleTreeTester');
|
||||
|
||||
const RocksDb = require('zkp-sbmtjs/src/storage/rocksdb');
|
||||
const MerkleTreeLib = require('zkp-sbmtjs/src/tree');
|
||||
const Mimc7Hasher = require('zkp-sbmtjs/src/hasher/mimc7');
|
||||
const MimcSpongeHasher = require('zkp-sbmtjs/src/hasher/mimcsponge');
|
||||
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ contract('MerkleTree', () => {
|
||||
}
|
||||
const default_value = '4';
|
||||
const storage = new RocksDb(storage_path);
|
||||
const hasher = new Mimc7Hasher();
|
||||
const hasher = new MimcSpongeHasher();
|
||||
const prefix = 'semaphore';
|
||||
const tree = new MerkleTreeLib(
|
||||
prefix,
|
||||
@@ -67,7 +67,7 @@ contract('MerkleTree', () => {
|
||||
}
|
||||
const default_value = '4';
|
||||
const storage = new RocksDb(storage_path);
|
||||
const hasher = new Mimc7Hasher();
|
||||
const hasher = new MimcSpongeHasher();
|
||||
const prefix = 'semaphore';
|
||||
const tree = new MerkleTreeLib(
|
||||
prefix,
|
||||
|
||||
@@ -34,7 +34,7 @@ const test_util = require('../../src/test_util');
|
||||
const bigInt = snarkjs.bigInt;
|
||||
|
||||
const eddsa = circomlib.eddsa;
|
||||
const mimc7 = circomlib.mimc7;
|
||||
const mimcsponge = circomlib.mimcsponge;
|
||||
|
||||
const groth = snarkjs.groth;
|
||||
const {unstringifyBigInts} = require('snarkjs/src/stringifybigint.js');
|
||||
@@ -47,7 +47,9 @@ const proof_util = require('../../src/util');
|
||||
|
||||
const RocksDb = require('zkp-sbmtjs/src/storage/rocksdb');
|
||||
const MerkleTree = require('zkp-sbmtjs/src/tree');
|
||||
const Mimc7Hasher = require('zkp-sbmtjs/src/hasher/mimc7');
|
||||
const MimcSpongeHasher = require('zkp-sbmtjs/src/hasher/mimcsponge');
|
||||
|
||||
const blake2 = require('blakejs');
|
||||
|
||||
beBuff2int = function(buff) {
|
||||
let res = bigInt.zero;
|
||||
@@ -58,6 +60,12 @@ beBuff2int = function(buff) {
|
||||
return res;
|
||||
};
|
||||
|
||||
const cutDownBits = function(b, bits) {
|
||||
let mask = bigInt(1);
|
||||
mask = mask.shl(bits).sub(bigInt(1));
|
||||
return b.and(mask);
|
||||
}
|
||||
|
||||
contract('Semaphore', function () {
|
||||
it('tests proof', async () => {
|
||||
const cirDef = JSON.parse(fs.readFileSync(path.join(__dirname,'../../build/circuit.json')).toString());
|
||||
@@ -75,13 +83,12 @@ contract('Semaphore', function () {
|
||||
const accounts = await web3.eth.getAccounts();
|
||||
const broadcaster_address = bigInt(accounts[0].toString());
|
||||
|
||||
const msg = mimc7.multiHash([bigInt(external_nullifier), bigInt(signal_hash), bigInt(broadcaster_address)]);
|
||||
const signature = eddsa.signMiMC(prvKey, msg);
|
||||
const msg = mimcsponge.multiHash([bigInt(external_nullifier), bigInt(signal_hash), bigInt(broadcaster_address)]);
|
||||
const signature = eddsa.signMiMCSponge(prvKey, msg);
|
||||
|
||||
assert(eddsa.verifyMiMC(msg, signature, pubKey));
|
||||
assert(eddsa.verifyMiMCSponge(msg, signature, pubKey));
|
||||
|
||||
const identity_nullifier = bigInt('230');
|
||||
const identity_r = bigInt('12311');
|
||||
|
||||
const storage_path = '/tmp/rocksdb_semaphore_test';
|
||||
if (fs.existsSync(storage_path)) {
|
||||
@@ -89,7 +96,7 @@ contract('Semaphore', function () {
|
||||
}
|
||||
const default_value = '0';
|
||||
const storage = new RocksDb(storage_path);
|
||||
const hasher = new Mimc7Hasher();
|
||||
const hasher = new MimcSpongeHasher();
|
||||
const prefix = 'semaphore';
|
||||
const tree = new MerkleTree(
|
||||
prefix,
|
||||
@@ -99,7 +106,13 @@ contract('Semaphore', function () {
|
||||
default_value,
|
||||
);
|
||||
|
||||
const identity_commitment = mimc7.multiHash([bigInt(pubKey[0]), bigInt(pubKey[1]), bigInt(identity_nullifier), bigInt(identity_r)]);
|
||||
const identity_commitment_ints = [bigInt(circomlib.babyJub.mulPointEscalar(pubKey, 8)[0]), bigInt(identity_nullifier)];
|
||||
const identity_commitment_buffer = Buffer.concat(
|
||||
identity_commitment_ints.map(x => x.leInt2Buff(32))
|
||||
);
|
||||
const identity_commitment = cutDownBits(beBuff2int(new Buffer(blake2.blake2sHex(identity_commitment_buffer), 'hex')), 253);
|
||||
|
||||
|
||||
const semaphore = await Semaphore.deployed();
|
||||
const receipt = await semaphore.insertIdentity(identity_commitment.toString());
|
||||
assert.equal(receipt.logs[0].event, 'LeafAdded');
|
||||
@@ -124,7 +137,6 @@ contract('Semaphore', function () {
|
||||
signal_hash,
|
||||
external_nullifier,
|
||||
identity_nullifier,
|
||||
identity_r,
|
||||
identity_path_elements,
|
||||
identity_path_index,
|
||||
broadcaster_address,
|
||||
|
||||
Reference in New Issue
Block a user