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