miksi-core/circuits/withdraw.circom
circuits/withdraw.circomRaw
1/*
2# withdraw.circom
3
4WARNING: WIP, very initial version of the miksi circuit
5
6
7 +----------+
8 | |
9PRI_secret+--------->+ Poseidon +<------+PRI_key+---------+
10 | | | |
11 | +----------+ +----+ |
12 | nullifier+----->+ != +<-----+0 |
13 | + +----+ v
14 | | +--+-------+
15 | v | |
16 | +-----+----+ | |
17 +--------->+ | | SMT +<------+PRI_siblings
18 | +--------------------->+ Poseidon |
19PUB_coinCode+------->+ Poseidon | | Verifier |
20 | | | +<------+PUB_root
21PUB_amount+--------->+ | | | +
22 +----------+ +----------+ |
23 |
24 |
25 +----+ +----+ |
26 PUB_address+--->+ != +<-------+0+-------------->+ != +<-------+
27 +----+ +----+
28
29
30
31*/
32
33include "../node_modules/circomlib/circuits/comparators.circom";
34include "../node_modules/circomlib/circuits/poseidon.circom";
35include "../node_modules/circomlib/circuits/smt/smtverifier.circom";
36
37template Withdraw(nLevels) {
38 signal input coinCode;
39 signal input amount;
40 signal private input secret;
41 signal input nullifier;
42 signal private input siblings[nLevels];
43 signal input root;
44 signal input address;
45 signal private input key;
46
47 component nullifierCmp = Poseidon(2, 6, 8, 57);
48 nullifierCmp.inputs[0] <== key;
49 nullifierCmp.inputs[1] <== secret;
50
51 component nullifierCheck = IsEqual();
52 nullifierCheck.in[0] <== nullifierCmp.out;
53 nullifierCheck.in[1] <== nullifier;
54 nullifierCheck.out === 1;
55
56 component hash = Poseidon(4, 6, 8, 57);
57 hash.inputs[0] <== coinCode;
58 hash.inputs[1] <== amount;
59 hash.inputs[2] <== secret;
60 hash.inputs[3] <== nullifierCmp.out;
61
62 component z = IsZero();
63 z.in <== address;
64 z.out === 0;
65
66 component smtV = SMTVerifier(nLevels);
67 smtV.enabled <== 1;
68 smtV.fnc <== 0;
69 smtV.root <== root;
70 for (var i=0; i<nLevels; i++) {
71 smtV.siblings[i] <== siblings[i];
72 }
73 smtV.oldKey <== 0;
74 smtV.oldValue <== 0;
75 smtV.isOld0 <== 0;
76 smtV.key <== key;
77 smtV.value <== hash.out;
78}