You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

106 lines
3.5 KiB

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