From 835ddb8810eb8253b3a8aecd20764c06bcf8da33 Mon Sep 17 00:00:00 2001 From: arnaucube Date: Mon, 11 May 2020 12:02:02 +0200 Subject: [PATCH] Add initial version of deposit circuit --- circuits/deposit.circom | 84 +++++++++++++++++++++++++++++++++++ circuits/withdraw.circom | 11 ++--- test/circuits/deposit.test.ts | 72 ++++++++++++++++++++++++++++++ 3 files changed, 162 insertions(+), 5 deletions(-) create mode 100644 circuits/deposit.circom create mode 100644 test/circuits/deposit.test.ts diff --git a/circuits/deposit.circom b/circuits/deposit.circom new file mode 100644 index 0000000..bb0fea2 --- /dev/null +++ b/circuits/deposit.circom @@ -0,0 +1,84 @@ +/* + +# deposit.circom + + +----------+ +----------+ +PUB_nullifier+------>+ | | | + | | | SMT | +PUB_coinCode+------->+ | | Poseidon +<------+PUB_rootOld + | Poseidon +-+----------->+ Verifier | +PUB_amount+--------->+ | | | Non | + | | | | Existance+<------+PRI_siblings +PRI_secret+--------->+ | | | | + + +----------+ | +----------+ | + | | + | | + | +----------+ | + | | | | + | | | | + +----+ | | SMT +<---------+ +PUB_commitment+----> == +<--------+----------->+ Poseidon | + +----+ | Verifier | + | +<------+PUB_rootNew + | | + +----------+ + + +*/ + +include "../node_modules/circomlib/circuits/comparators.circom"; +include "../node_modules/circomlib/circuits/poseidon.circom"; +include "../node_modules/circomlib/circuits/smt/smtverifier.circom"; + +template Deposit(nLevels) { + signal input coinCode; + signal input amount; + signal private input secret; + signal input nullifier; + signal private input siblingsOld[nLevels]; + signal private input siblingsNew[nLevels]; + signal input rootOld; + signal input rootNew; + signal input commitment; + + component hash = Poseidon(4, 6, 8, 57); + hash.inputs[0] <== coinCode; + hash.inputs[1] <== amount; + hash.inputs[2] <== secret; + hash.inputs[3] <== nullifier; + + component comCheck = IsEqual(); + comCheck.in[0] <== hash.out; + comCheck.in[1] <== commitment; + comCheck.out === 1; + + // TODO instead of 2 siblings input, get siblingsOld from siblingsNew[len-1] + + component smtOld = SMTVerifier(nLevels); + smtOld.enabled <== 1; + smtOld.fnc <== 1; + smtOld.root <== rootOld; + for (var i=0; i+----------+ | | + -----------+ +----------+ +PUB_nullifier+------>+ | | | + | | | | PUB_coinCode+------->+ | | SMT +<------+PRI_siblings - | | | Poseidon | -PUB_amount+--------->+ Poseidon +------------->+ Verifier | + | Poseidon +------------->+ Poseidon | +PUB_amount+--------->+ | | Verifier | | | | +<------+PUB_root PRI_secret+--------->+ | | | + +----------+ +----------+ | | + | +----+ +----+ | PUB_address+--->+ != +<-------+0+------>+ != +<-------+ +----+ +----+ diff --git a/test/circuits/deposit.test.ts b/test/circuits/deposit.test.ts new file mode 100644 index 0000000..fdc54e3 --- /dev/null +++ b/test/circuits/deposit.test.ts @@ -0,0 +1,72 @@ +const path = require("path"); +const tester = require("circom").tester; +const chai = require("chai"); +const assert = chai.assert; +const circomlib = require("circomlib"); +const smt = require("circomlib").smt; + +export {}; + +describe("deposit test", function () { + this.timeout(200000); + + + it("Test Deposit", async () => { + const circuit = await tester( + path.join(__dirname, "../../circuits", "deposit.circom"), + {reduceConstraints: false} + ); + + const nLevels = 5; + const secret = "1234567890"; + + const coinCode = "0"; + const amount = '1000000000000000000'; + const nullifier = "567891234"; + + const poseidon = circomlib.poseidon.createHash(6, 8, 57); + const commitment = poseidon([coinCode, amount, secret, nullifier]).toString(); + + // add commitment into SMT + let tree = await smt.newMemEmptyTrie(); + await tree.insert(1, 0); + await tree.insert(2, 0); + + let rootOld = tree.root; + let res = await tree.find(commitment); + // console.log(res); + assert(!res.found); + let siblingsOld = res.siblings; + while (siblingsOld.length < nLevels) { + siblingsOld.push("0"); + }; + console.log("siblingsOld", siblingsOld); + + await tree.insert(commitment, 0); + let rootNew = tree.root; + + res = await tree.find(commitment); + // console.log(res); + assert(res.found); + let siblingsNew = res.siblings; + while (siblingsNew.length < nLevels) { + siblingsNew.push("0"); + }; + console.log("siblingsNew", siblingsNew); + console.log("rootOld", rootOld); + console.log("rootNew", rootNew); + + const witness = await circuit.calculateWitness({ + "coinCode": coinCode, + "amount": amount, + "secret": secret, + "nullifier": nullifier, + "siblingsOld": siblingsOld, + "siblingsNew": siblingsNew, + "rootOld": rootOld, + "rootNew": rootNew, + "commitment": commitment + }); + await circuit.checkConstraints(witness); + }); +});