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.

100 lines
4.0 KiB

6 years ago
6 years ago
6 years ago
  1. /*
  2. Copyright 2018 0KIMS association.
  3. This file is part of circom (Zero Knowledge Circuit Compiler).
  4. circom is a free software: you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. circom is distributed in the hope that it will be useful, but WITHOUT
  9. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  11. License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with circom. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. /*
  16. This component finds the level where the oldInsert is done.
  17. The rules are:
  18. levIns[i] == 1 if its level and all the child levels have a sibling of 0 and
  19. the parent level has a sibling != 0. Considere that the root level always has
  20. a parent with a sibling != 0.
  21. ┌──────────────┐
  22. │ │
  23. │ │───▶ levIns[0] <== (1-done[i])
  24. │ │
  25. └──────────────┘
  26. done[0]
  27. done[i-1] <== levIns[i] + done[i]
  28. ┌───────────┐ ┌──────────────┐
  29. │ │ │ │
  30. sibling[i-1]───▶│IsZero[i-1]│─▶│ │───▶ levIns[i] <== (1-done[i])*(1-isZero[i-1].out)
  31. │ │ │ │
  32. └───────────┘ └──────────────┘
  33. done[i]
  34. done[n-2] <== levIns[n-1]
  35. ┌───────────┐ ┌──────────────┐
  36. │ │ │ │
  37. sibling[n-2]───▶│IsZero[n-2]│─▶│ │────▶ levIns[n-1] <== (1-isZero[n-2].out)
  38. │ │ │ │
  39. └───────────┘ └──────────────┘
  40. ┌───────────┐
  41. │ │
  42. sibling[n-1]───▶│IsZero[n-1]│────▶ === 0
  43. │ │
  44. └───────────┘
  45. */
  46. template SMTLevIns(nLevels) {
  47. signal input enabled;
  48. signal input siblings[nLevels];
  49. signal output levIns[nLevels];
  50. signal done[nLevels-1]; // Indicates if the insLevel has aready been detected.
  51. component isZero[nLevels];
  52. for (var i=0; i<nLevels; i++) {
  53. isZero[i] = IsZero();
  54. isZero[i].in <== siblings[i];
  55. }
  56. // The last level must always have a sibling of 0. If not, then it cannot be inserted.
  57. (isZero[nLevels-1].out - 1) * enabled === 0;
  58. levIns[nLevels-1] <== (1-isZero[nLevels-2].out);
  59. done[nLevels-2] <== levIns[nLevels-1];
  60. for (var i=nLevels-2; i>0; i--) {
  61. levIns[i] <== (1-done[i])*(1-isZero[i-1].out)
  62. done[i-1] <== levIns[i] + done[i];
  63. }
  64. levIns[0] <== (1-done[0]);
  65. }