arnaucube
arnaucube/miksi-corePublic Self-hosted repository
miksi-core/circuits/deposit.circom
circuits/deposit.circomRaw
  1/*
  2
  3# deposit.circom
  4
  5                     +----------+
  6                     |          |
  7PRI_secret+--------->+ Poseidon +<----+PUB_key
  8          |          |          |        +
  9          |          +----------+        |
 10          |            nullifier         |
 11          |               +              |
 12          |               |              |     +----------+
 13          |               v              |     |          |
 14          |          +----+-----+        +---->+ SMT      |
 15          +--------->+          |              | Poseidon +<------+PUB_rootOld
 16                     |          +-----+------->+ Verifier |
 17PUB_coinCode+------->+ Poseidon |     |        | Non      |
 18                     |          |     |        | Existance+<------+PRI_siblings
 19PUB_amount+--------->+          |     |        |          |          +
 20                     +----------+     |        +----------+          |
 21                                      |                              |
 22                                      |                              |
 23                                      |        +----------+          |
 24                                      |        |          |          |
 25                                      |        |          |          |
 26                   +----+             |        | SMT      +<---------+
 27PUB_commitment+----> == +<------------+------->+ Poseidon |
 28                   +----+                      | Verifier |
 29                                               |          +<------+PUB_rootNew
 30                                               |          |
 31                                               +----------+
 32
 33
 34*/
 35
 36include "../node_modules/circomlib/circuits/comparators.circom";
 37include "../node_modules/circomlib/circuits/poseidon.circom";
 38include "../node_modules/circomlib/circuits/smt/smtverifier.circom";
 39
 40template Deposit(nLevels) {
 41	signal input coinCode;
 42	signal input amount;
 43	signal private input secret;
 44	signal private input oldKey;
 45	signal private input oldValue;
 46	signal private input siblingsOld[nLevels];
 47	signal private input siblingsNew[nLevels];
 48	signal input rootOld;
 49	signal input rootNew;
 50	signal input commitment;
 51	signal input key;
 52
 53	component nullifierCmp = Poseidon(2, 6, 8, 57);
 54	nullifierCmp.inputs[0] <== key;
 55	nullifierCmp.inputs[1] <== secret;
 56
 57	component hash = Poseidon(4, 6, 8, 57);
 58	hash.inputs[0] <== coinCode;
 59	hash.inputs[1] <== amount;
 60	hash.inputs[2] <== secret;
 61	hash.inputs[3] <== nullifierCmp.out; // nullifier
 62
 63	component comCheck = IsEqual();
 64	comCheck.in[0] <== hash.out;
 65	comCheck.in[1] <== commitment;
 66	comCheck.out === 1;
 67
 68	// TODO instead of 2 siblings input, get siblingsOld from
 69	// siblingsNew[len-1] both siblingsOld & siblingsNew have same values
 70	// except for one, can be merged into one, to ensure that the circuit
 71	// checks that the leaf non existing under rootOld is in the same
 72	// position than the check that the leaf exists under the rootNew
 73
 74	// check that nLevels-1 siblings match from siblingsOld & siblingsNew
 75	component siblEq[nLevels];
 76	signal count[nLevels];
 77	for (var i=0; i<nLevels; i++) {
 78		siblEq[i] = IsEqual();
 79		siblEq[i].in[0] <== siblingsOld[i];
 80		siblEq[i].in[1] <== siblingsNew[i];
 81		if (i==0) {
 82			count[0] <== siblEq[i].out;
 83		} else {
 84			count[i] <== siblEq[i].out + count[i-1];
 85		}
 86	}
 87	component countCheck = IsEqual();
 88	countCheck.in[0] <== count[nLevels-1];
 89	countCheck.in[1] <== nLevels-1;
 90	countCheck.out === 1;
 91	
 92	component smtOld = SMTVerifier(nLevels);
 93	smtOld.enabled <== 1;
 94	smtOld.fnc <== 1;
 95	smtOld.root <== rootOld;
 96	for (var i=0; i<nLevels; i++) {
 97		smtOld.siblings[i] <== siblingsOld[i];
 98	}
 99	/* smtOld.oldKey <== 1;  */
100	smtOld.oldKey <== oldKey;
101	smtOld.oldValue <== oldValue;
102	smtOld.isOld0 <== 0;
103	smtOld.key <== key;
104	smtOld.value <== hash.out;
105	
106	component smtNew = SMTVerifier(nLevels);
107	smtNew.enabled <== 1;
108	smtNew.fnc <== 0;
109	smtNew.root <== rootNew;
110	for (var i=0; i<nLevels; i++) {
111		smtNew.siblings[i] <== siblingsNew[i];
112	}
113	smtNew.oldKey <== 0;
114	smtNew.oldValue <== 0;
115	smtNew.isOld0 <== 0;
116	smtNew.key <== key;
117	smtNew.value <== hash.out;
118}