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.

118 lines
4.0 KiB

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