arnaucube
arnaucube/miksi-corePublic Self-hosted repository
Withdraw circuit check secret in MerkleTree Root
arnaucube root@arnaucube.com
Mon, 11 May 2020 09:08:23 +0200
commit

95d4f210be5888e55c22146caa9ce1207707b3d5

parent

e466578ddc78a613b4db01e4e51dce7c8133e85d

2 files changed, 60 insertions(+), 28 deletions(-)

jump to
M circuits/withdraw.circom → circuits/withdraw.circom

@@ -3,49 +3,61 @@ # withdraw.circom

WARNING: WIP, very initial version of the miksi circuit - +--------+ -PUB_coinCode+------->+ | - | | +----+ -PUB_amount+--------->+Poseidon+------->+ == +<-----+PUB_commitment - | | +----+ -PRI_secret+--------->+ | - +--------+ - +----+ -PUB_address+--->+ != +<---+0 - +----+ + + +----------+ + | | +PUB_nullifier+------>+----------+ | | +PUB_coinCode+------->+ | | SMT +<------+PRI_siblings + | | | Poseidon | +PUB_amount+--------->+ Poseidon +------------->+ Verifier | + | | | +<------+PUB_root +PRI_secret+--------->+ | | | + + +----------+ +----------+ | + | + +----+ +----+ | + PUB_address+--->+ != +<-------+0+------>+ != +<-------+ + +----+ +----+ */ -include "../node_modules/circomlib/circuits/babyjub.circom"; include "../node_modules/circomlib/circuits/comparators.circom"; include "../node_modules/circomlib/circuits/poseidon.circom"; -include "../node_modules/circomlib/circuits/bitify.circom"; include "../node_modules/circomlib/circuits/smt/smtverifier.circom"; -include "../node_modules/circomlib/circuits/smt/smtprocessor.circom"; -template Withdraw() { +template Withdraw(nLevels) { signal input coinCode; signal input amount; - signal input commitment; signal private input secret; + signal input nullifier; + signal private input siblings[nLevels]; + signal input root; signal input address; - component hash = Poseidon(3, 6, 8, 57); + component hash = Poseidon(4, 6, 8, 57); hash.inputs[0] <== coinCode; hash.inputs[1] <== amount; hash.inputs[2] <== secret; - - component eq = IsEqual(); - eq.in[0] <== hash.out; - eq.in[1] <== commitment; - eq.out === 1; + hash.inputs[3] <== nullifier; component z = IsZero(); z.in <== address; z.out === 0; + + component smtV = SMTVerifier(nLevels); + smtV.enabled <== 1; + smtV.fnc <== 0; + smtV.root <== root; + for (var i=0; i<nLevels; i++) { + smtV.siblings[i] <== siblings[i]; + } + smtV.oldKey <== 0; + smtV.oldValue <== 0; + smtV.isOld0 <== 0; + smtV.key <== hash.out; + smtV.value <== 0; } -component main = Withdraw(); +component main = Withdraw(5);
M test/circuits/withdraw.test.ts → test/circuits/withdraw.test.ts

@@ -3,6 +3,7 @@ const tester = require("circom").tester;

const chai = require("chai"); const assert = chai.assert; const circomlib = require("circomlib"); +const smt = require("circomlib").smt; export {};

@@ -16,20 +17,39 @@ path.join(__dirname, "../../circuits", "withdraw.circom"),

{reduceConstraints: false} ); - // const secret = Math.floor(Math.random()*1000).toString(); - const secret = "123456789"; + const nLevels = 5; + const secret = "1234567890"; - const coinCode = "1"; - const amount = "100"; + const coinCode = "0"; + const amount = '1000000000000000000'; + const nullifier = "567891234"; const poseidon = circomlib.poseidon.createHash(6, 8, 57); - const commitment = poseidon([coinCode, amount, secret]).toString(); + const commitment = poseidon([coinCode, amount, secret, nullifier]).toString(); + // add commitment into SMT + let tree = await smt.newMemEmptyTrie(); + await tree.insert(commitment, 0); + await tree.insert(1, 0); + await tree.insert(2, 0); + console.log("root", tree.root); + const res = await tree.find(commitment); + assert(res.found); + let siblings = res.siblings; + while (siblings.length < nLevels) { + siblings.push("0"); + }; + console.log("siblings", siblings); + + let root = tree.root; + const witness = await circuit.calculateWitness({ "coinCode": coinCode, "amount": amount, - "commitment": commitment, "secret": secret, + "nullifier": nullifier, + "siblings": siblings, + "root": root, "address": "987654321" }); await circuit.checkConstraints(witness);