Add initial version of deposit circuit
arnaucube root@arnaucube.com
Mon, 11 May 2020 12:02:02 +0200
3 files changed,
162 insertions(+),
5 deletions(-)
A
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<nLevels; i++) { + smtOld.siblings[i] <== siblingsOld[i]; + } + smtOld.oldKey <== 1; + smtOld.oldValue <== 0; + smtOld.isOld0 <== 0; + smtOld.key <== hash.out; + smtOld.value <== 0; + + component smtNew = SMTVerifier(nLevels); + smtNew.enabled <== 1; + smtNew.fnc <== 0; + smtNew.root <== rootNew; + for (var i=0; i<nLevels; i++) { + smtNew.siblings[i] <== siblingsNew[i]; + } + smtNew.oldKey <== 0; + smtNew.oldValue <== 0; + smtNew.isOld0 <== 0; + smtNew.key <== hash.out; + smtNew.value <== 0; +} + +component main = Deposit(5);
M
circuits/withdraw.circom
→
circuits/withdraw.circom
@@ -5,15 +5,16 @@ WARNING: WIP, very initial version of the miksi circuit
- +----------+ - | | -PUB_nullifier+------>+----------+ | | + -----------+ +----------+ +PUB_nullifier+------>+ | | | + | | | | PUB_coinCode+------->+ | | SMT +<------+PRI_siblings - | | | Poseidon | -PUB_amount+--------->+ Poseidon +------------->+ Verifier | + | Poseidon +------------->+ Poseidon | +PUB_amount+--------->+ | | Verifier | | | | +<------+PUB_root PRI_secret+--------->+ | | | + +----------+ +----------+ | + | | +----+ +----+ | PUB_address+--->+ != +<-------+0+------>+ != +<-------+
A
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); + }); +});