mirror of
https://github.com/tornadocash/tornado-nova
synced 2024-02-02 14:53:56 +01:00
transaaction circuit with custom input count
This commit is contained in:
parent
a19a226277
commit
960b6adb30
@ -14,7 +14,7 @@ commitment = hash(amount, blinding, pubKey)
|
||||
nullifier = hash(commitment, privKey, merklePath)
|
||||
*/
|
||||
|
||||
// Universal JoinSplit transaction with 2 inputs and 2 outputs
|
||||
// Universal JoinSplit transaction with nIns inputs and 2 outputs
|
||||
template Transaction(levels, nIns, nOuts, zeroLeaf) {
|
||||
signal input root;
|
||||
signal input newRoot;
|
||||
@ -107,10 +107,18 @@ template Transaction(levels, nIns, nOuts, zeroLeaf) {
|
||||
component feeCheck = Num2Bits(248);
|
||||
feeCheck.in <== fee;
|
||||
|
||||
component sameNullifiers = IsEqual();
|
||||
sameNullifiers.in[0] <== inputNullifier[0];
|
||||
sameNullifiers.in[1] <== inputNullifier[1];
|
||||
sameNullifiers.out === 0;
|
||||
// check that there are no same nullifiers among all inputs
|
||||
component sameNullifiers[nIns * (nIns - 1) / 2];
|
||||
var index = 0;
|
||||
for (var i = 0; i < nIns - 1; i++) {
|
||||
for (var j = i + 1; j < nIns; j++) {
|
||||
sameNullifiers[index] = IsEqual();
|
||||
sameNullifiers[index].in[0] <== inputNullifier[i];
|
||||
sameNullifiers[index].in[1] <== inputNullifier[j];
|
||||
sameNullifiers[index].out === 0;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
// verify amount invariant
|
||||
sumIns + extAmount === sumOuts + fee;
|
||||
@ -119,8 +127,9 @@ template Transaction(levels, nIns, nOuts, zeroLeaf) {
|
||||
component treeUpdater = TreeUpdater(levels, zeroLeaf);
|
||||
treeUpdater.oldRoot <== root;
|
||||
treeUpdater.newRoot <== newRoot;
|
||||
treeUpdater.leaf[0] <== outputCommitment[0];
|
||||
treeUpdater.leaf[1] <== outputCommitment[1];
|
||||
for (var i = 0; i < nOuts; i++) {
|
||||
treeUpdater.leaf[i] <== outputCommitment[i];
|
||||
}
|
||||
treeUpdater.pathIndices <== outPathIndices;
|
||||
for (var i = 0; i < levels - 1; i++) {
|
||||
treeUpdater.pathElements[i] <== outPathElements[i];
|
||||
|
@ -17,6 +17,7 @@ import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; // todo: maybe remov
|
||||
|
||||
interface IVerifier {
|
||||
function verifyProof(bytes memory _proof, uint256[9] memory _input) external returns(bool);
|
||||
function verifyProof(bytes memory _proof, uint256[23] memory _input) external returns(bool);
|
||||
}
|
||||
|
||||
contract TornadoPool is ReentrancyGuard {
|
||||
@ -26,7 +27,8 @@ contract TornadoPool is ReentrancyGuard {
|
||||
mapping(bytes32 => bool) public nullifierHashes;
|
||||
bytes32 public currentRoot;
|
||||
uint public currentCommitmentIndex;
|
||||
IVerifier public verifier;
|
||||
IVerifier public verifier2;
|
||||
IVerifier public verifier16;
|
||||
|
||||
struct ExtData {
|
||||
address payable recipient;
|
||||
@ -42,10 +44,12 @@ contract TornadoPool is ReentrancyGuard {
|
||||
|
||||
/**
|
||||
@dev The constructor
|
||||
@param _verifier the address of SNARK verifier for this contract
|
||||
@param _verifier2 the address of SNARK verifier for this contract
|
||||
@param _verifier16 the address of SNARK verifier for this contract
|
||||
*/
|
||||
constructor(IVerifier _verifier, bytes32 _currentRoot) public {
|
||||
verifier = _verifier;
|
||||
constructor(IVerifier _verifier2, IVerifier _verifier16, bytes32 _currentRoot) public {
|
||||
verifier2 = _verifier2;
|
||||
verifier16 = _verifier16;
|
||||
currentRoot = _currentRoot;
|
||||
}
|
||||
|
||||
@ -66,7 +70,7 @@ contract TornadoPool is ReentrancyGuard {
|
||||
require(!isSpent(_inputNullifiers[0]), "Input 0 is already spent");
|
||||
require(!isSpent(_inputNullifiers[1]), "Input 1 is already spent");
|
||||
require(uint256(_extDataHash) == uint256(keccak256(abi.encode(_extData))) % FIELD_SIZE, "Incorrect external data hash");
|
||||
require(verifier.verifyProof(_proof, [
|
||||
require(verifier2.verifyProof(_proof, [
|
||||
uint256(_root),
|
||||
uint256(_newRoot),
|
||||
uint256(_inputNullifiers[0]),
|
||||
|
@ -1 +0,0 @@
|
||||
../artifacts/circuits/Verifier.sol
|
1
contracts/Verifier16.sol
Symbolic link
1
contracts/Verifier16.sol
Symbolic link
@ -0,0 +1 @@
|
||||
../artifacts/circuits/Verifier16.sol
|
1
contracts/Verifier2.sol
Symbolic link
1
contracts/Verifier2.sol
Symbolic link
@ -0,0 +1 @@
|
||||
../artifacts/circuits/Verifier2.sol
|
@ -7,11 +7,10 @@
|
||||
"test": "test"
|
||||
},
|
||||
"scripts": {
|
||||
"circuit": "./scripts/buildCircuit.sh transaction2 && ./scripts/buildCircuit.sh transaction16",
|
||||
"circuit": "./scripts/buildCircuit.sh 2 && ./scripts/buildCircuit.sh 16",
|
||||
"compile": "npx hardhat compile",
|
||||
"build": "npm run circuit && npm run compile",
|
||||
"migrate": "npx hardhat run scripts/deploy.js --network localhost",
|
||||
"start": "node ./src/index.js"
|
||||
"test": "npx hardhat test"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
@ -32,7 +31,7 @@
|
||||
"ffjavascript": "^0.2.36",
|
||||
"fixed-merkle-tree": "^0.5.0",
|
||||
"hardhat": "^2.3.0",
|
||||
"snarkjs": "^0.4.5",
|
||||
"snarkjs": "git+https://github.com/tornadocash/snarkjs.git#c103e3bf10e95e2e9bbf0f7952ed13812f8e39d3",
|
||||
"tmp-promise": "^3.0.2"
|
||||
}
|
||||
}
|
||||
|
@ -8,10 +8,11 @@ if [ ! -f artifacts/circuits/ptau$POWERS_OF_TAU ]; then
|
||||
npx snarkjs powersoftau prepare phase2 artifacts/circuits/tmp2_ptau$POWERS_OF_TAU artifacts/circuits/ptau$POWERS_OF_TAU
|
||||
rm artifacts/circuits/tmp_ptau$POWERS_OF_TAU artifacts/circuits/tmp2_ptau$POWERS_OF_TAU
|
||||
fi
|
||||
npx circom -v -r artifacts/circuits/$1.r1cs -w artifacts/circuits/$1.wasm -s artifacts/circuits/$1.sym circuits/$1.circom
|
||||
npx snarkjs groth16 setup artifacts/circuits/$1.r1cs artifacts/circuits/ptau$POWERS_OF_TAU artifacts/circuits/tmp_$1.zkey
|
||||
npx snarkjs zkey contribute artifacts/circuits/tmp_$1.zkey artifacts/circuits/$1.zkey
|
||||
npx snarkjs zkey export solidityverifier artifacts/circuits/$1.zkey artifacts/circuits/Verifier.sol
|
||||
#zkutil setup -c artifacts/circuits/$1.r1cs -p artifacts/circuits/$1.params
|
||||
#zkutil generate-verifier -p artifacts/circuits/$1.params -v artifacts/circuits/Verifier.sol
|
||||
npx snarkjs info -r artifacts/circuits/$1.r1cs
|
||||
npx circom -v -r artifacts/circuits/transaction$1.r1cs -w artifacts/circuits/transaction$1.wasm -s artifacts/circuits/transaction$1.sym circuits/transaction$1.circom
|
||||
npx snarkjs groth16 setup artifacts/circuits/transaction$1.r1cs artifacts/circuits/ptau$POWERS_OF_TAU artifacts/circuits/tmp_transaction$1.zkey
|
||||
npx snarkjs zkey contribute artifacts/circuits/tmp_transaction$1.zkey artifacts/circuits/transaction$1.zkey
|
||||
npx snarkjs zkey export solidityverifier artifacts/circuits/transaction$1.zkey artifacts/circuits/Verifier$1.sol
|
||||
sed -i.bak "s/contract Verifier/contract Verifier${1}/g" artifacts/circuits/Verifier$1.sol
|
||||
#zkutil setup -c artifacts/circuits/transaction$1.r1cs -p artifacts/circuits/transaction$1.params
|
||||
#zkutil generate-verifier -p artifacts/circuits/transaction$1.params -v artifacts/circuits/Verifier.sol
|
||||
npx snarkjs info -r artifacts/circuits/transaction$1.r1cs
|
||||
|
@ -14,16 +14,21 @@ const toFixedHex = (number, length = 32) =>
|
||||
).padStart(length * 2, '0')
|
||||
|
||||
async function main() {
|
||||
const Verifier = await ethers.getContractFactory('Verifier')
|
||||
const verifier = await Verifier.deploy()
|
||||
await verifier.deployed()
|
||||
console.log(`verifier: ${verifier.address}`)
|
||||
const Verifier2 = await ethers.getContractFactory('Verifier2')
|
||||
const verifier2 = await Verifier2.deploy()
|
||||
await verifier2.deployed()
|
||||
console.log(`verifier2: ${verifier2.address}`)
|
||||
|
||||
const Verifier16 = await ethers.getContractFactory('Verifier16')
|
||||
const verifier16 = await Verifier16.deploy()
|
||||
await verifier16.deployed()
|
||||
console.log(`verifier16: ${verifier16.address}`)
|
||||
|
||||
const tree = new MerkleTree(MERKLE_TREE_HEIGHT, [], { hashFunction: poseidonHash2 })
|
||||
const root = await tree.root()
|
||||
|
||||
const Pool = await ethers.getContractFactory('TornadoPool')
|
||||
const tornado = await Pool.deploy(verifier.address, toFixedHex(root))
|
||||
const tornado = await Pool.deploy(verifier2.address, verifier16.address, toFixedHex(root))
|
||||
console.log("TornadoPool's address ", tornado.address)
|
||||
}
|
||||
|
||||
|
@ -14,15 +14,19 @@ describe('TornadoPool', () => {
|
||||
|
||||
/* prettier-ignore */
|
||||
before(async function () {
|
||||
const Verifier = await ethers.getContractFactory('Verifier')
|
||||
const verifier = await Verifier.deploy()
|
||||
await verifier.deployed()
|
||||
const Verifier2 = await ethers.getContractFactory('Verifier2')
|
||||
const verifier2 = await Verifier2.deploy()
|
||||
await verifier2.deployed()
|
||||
|
||||
const Verifier16 = await ethers.getContractFactory('Verifier16')
|
||||
const verifier16 = await Verifier16.deploy()
|
||||
await verifier16.deployed()
|
||||
|
||||
const tree = new MerkleTree(MERKLE_TREE_HEIGHT, [], { hashFunction: poseidonHash2 })
|
||||
const root = await tree.root()
|
||||
|
||||
const Pool = await ethers.getContractFactory('TornadoPool')
|
||||
tornadoPool = await Pool.deploy(verifier.address, toFixedHex(root))
|
||||
tornadoPool = await Pool.deploy(verifier2.address, verifier16.address, toFixedHex(root))
|
||||
|
||||
snapshotId = await takeSnapshot()
|
||||
})
|
||||
|
27
yarn.lock
27
yarn.lock
@ -7423,10 +7423,20 @@ snapdragon@^0.8.1:
|
||||
source-map-resolve "^0.5.0"
|
||||
use "^3.1.0"
|
||||
|
||||
snarkjs@^0.4.5:
|
||||
"snarkjs@git+https://github.com/tornadocash/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5":
|
||||
version "0.1.20"
|
||||
resolved "git+https://github.com/tornadocash/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5"
|
||||
dependencies:
|
||||
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"
|
||||
|
||||
"snarkjs@git+https://github.com/tornadocash/snarkjs.git#c103e3bf10e95e2e9bbf0f7952ed13812f8e39d3":
|
||||
version "0.4.5"
|
||||
resolved "https://registry.yarnpkg.com/snarkjs/-/snarkjs-0.4.5.tgz#c7246b0bdcdafd25c67c0ecc395556715b059a14"
|
||||
integrity sha512-rgxbp3JMhGdPgkhCrssq+a4Bv2vm2QucWwK9QG5cdyRRpx8f5EOpyMPy7pi/U8VUyyyulAaDowKBf7x7chB7zg==
|
||||
resolved "git+https://github.com/tornadocash/snarkjs.git#c103e3bf10e95e2e9bbf0f7952ed13812f8e39d3"
|
||||
dependencies:
|
||||
"@iden3/binfileutils" "0.0.8"
|
||||
blake2b-wasm "https://github.com/jbaylina/blake2b-wasm.git"
|
||||
@ -7439,17 +7449,6 @@ snarkjs@^0.4.5:
|
||||
r1csfile "0.0.32"
|
||||
readline "^1.3.0"
|
||||
|
||||
"snarkjs@git+https://github.com/tornadocash/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5":
|
||||
version "0.1.20"
|
||||
resolved "git+https://github.com/tornadocash/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5"
|
||||
dependencies:
|
||||
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"
|
||||
|
||||
solc@0.7.3:
|
||||
version "0.7.3"
|
||||
resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a"
|
||||
|
Loading…
Reference in New Issue
Block a user