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.

216 lines
12 KiB

  1. /***************************************************************************************************
  2. Insert to an empty leaf
  3. =======================
  4. STATE OLD STATE NEW STATE
  5. ===== ========= =========
  6. oldRoot newRoot
  7. ▲ ▲
  8. │ │
  9. ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓
  10. top │Sibling├────▶┃ Hash ┃◀─┐ │Sibling├────▶┃ Hash ┃◀─┐
  11. └───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │
  12. │ │
  13. │ │
  14. ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ ┌───────┐
  15. top ┌─────▶┃ Hash ┃◀──┤Sibling│ ┌─────▶┃ Hash ┃◀──┤Sibling│
  16. │ ┗━━━━━━━┛ └───────┘ │ ┗━━━━━━━┛ └───────┘
  17. │ │
  18. │ │
  19. ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓
  20. top │Sibling├──▶┃ Hash ┃◀─────┐ │Sibling├──▶┃ Hash ┃◀─────┐
  21. └───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │
  22. │ │
  23. │ │
  24. ┌────┴────┐ ┌────┴────┐
  25. old0 │ 0 │ │New1Leaf │
  26. └─────────┘ └─────────┘
  27. ┏━━━━━━━┓ ┏━━━━━━━┓
  28. na ┃ Hash ┃ ┃ Hash ┃
  29. ┗━━━━━━━┛ ┗━━━━━━━┛
  30. ┏━━━━━━━┓ ┏━━━━━━━┓
  31. na ┃ Hash ┃ ┃ Hash ┃
  32. ┗━━━━━━━┛ ┗━━━━━━━┛
  33. Insert to a used leaf.
  34. =====================
  35. STATE OLD STATE NEW STATE
  36. ===== ========= =========
  37. oldRoot newRoot
  38. ▲ ▲
  39. │ │
  40. ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓
  41. top │Sibling├────▶┃ Hash ┃◀─┐ │Sibling├────▶┃ Hash ┃◀─┐
  42. └───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │
  43. │ │
  44. │ │
  45. ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ ┌───────┐
  46. top ┌─────▶┃ Hash ┃◀──┤Sibling│ ┌─────▶┃ Hash ┃◀──┤Sibling│
  47. │ ┗━━━━━━━┛ └───────┘ │ ┗━━━━━━━┛ └───────┘
  48. │ │
  49. │ │
  50. ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓
  51. top │Sibling├──▶┃ Hash ┃◀─────┐ │Sibling├──▶┃ Hash ┃◀─────┐
  52. └───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │
  53. │ │
  54. │ │
  55. ┌────┴────┐ ┏━━━┻━━━┓ ┌───────┐
  56. bot │Old1Leaf │ ┌─────▶┃ Hash ┃◀──┼─ 0 │
  57. └─────────┘ │ ┗━━━━━━━┛ └───────┘
  58. ┏━━━━━━━┓ ┌───────┐ ┏━━━┻━━━┓
  59. bot ┃ Hash ┃ │ 0 ─┼──▶┃ Hash ┃◀─────┐
  60. ┗━━━━━━━┛ └───────┘ ┗━━━━━━━┛ │
  61. ┏━━━━━━━┓ ┏━━━┻━━━┓ ┌───────┐
  62. bot ┃ Hash ┃ ┌─────▶┃ Hash ┃◀──│ 0 │
  63. ┗━━━━━━━┛ │ ┗━━━━━━━┛ └───────┘
  64. ┏━━━━━━━┓ ┌─────────┐ ┏━━━┻━━━┓ ┌─────────┐
  65. new1 ┃ Hash ┃ │Old1Leaf ├──▶┃ Hash ┃◀──│New1Leaf │
  66. ┗━━━━━━━┛ └─────────┘ ┗━━━━━━━┛ └─────────┘
  67. ┏━━━━━━━┓ ┏━━━━━━━┓
  68. na ┃ Hash ┃ ┃ Hash ┃
  69. ┗━━━━━━━┛ ┗━━━━━━━┛
  70. ┏━━━━━━━┓ ┏━━━━━━━┓
  71. na ┃ Hash ┃ ┃ Hash ┃
  72. ┗━━━━━━━┛ ┗━━━━━━━┛
  73. Fnction
  74. fnc[0] fnc[1]
  75. 0 0 NOP
  76. 0 1 UPDATE
  77. 1 0 INSERT
  78. 1 1 DELETE
  79. ***************************************************************************************************/
  80. include "../gates.circom";
  81. include "../bitify.circom";
  82. include "../comparators.circom";
  83. include "../switcher.circom";
  84. include "smtlevins.circom";
  85. include "smtinsertlevel.circom";
  86. include "smtinsertsm.circom";
  87. include "smthash.circom";
  88. template SMTInsert(nLevels) {
  89. signal input oldRoot;
  90. signal input newRoot;
  91. signal input siblings[nLevels];
  92. signal input oldKey;
  93. signal input oldValue;
  94. signal input isOld0;
  95. signal input newKey;
  96. signal input newValue;
  97. signal input fnc[2];
  98. signal enabled;
  99. enabled <== fnc[0] + fnc[1] - fnc[0]*fnc[1]
  100. component hash1Old = SMTHash1();
  101. hash1Old.key <== oldKey;
  102. hash1Old.value <== oldValue;
  103. component hash1New = SMTHash1();
  104. hash1New.key <== newKey;
  105. hash1New.value <== newValue;
  106. component n2bOld = Num2Bits_strict();
  107. component n2bNew = Num2Bits_strict();
  108. n2bOld.in <== oldKey;
  109. n2bNew.in <== newKey;
  110. component smtLevIns = SMTLevIns(nLevels);
  111. for (var i=0; i<nLevels; i++) smtLevIns.siblings[i] <== siblings[i];
  112. smtLevIns.enabled <== enabled;
  113. component xors[nLevels];
  114. for (var i=0; i<nLevels; i++) {
  115. xors[i] = XOR();
  116. xors[i].a <== n2bOld.out[i];
  117. xors[i].b <== n2bNew.out[i];
  118. }
  119. component sm[nLevels];
  120. for (var i=0; i<nLevels; i++) {
  121. sm[i] = SMTInsertSM();
  122. if (i==0) {
  123. sm[i].prev_top <== enabled;
  124. sm[i].prev_old0 <== 0;
  125. sm[i].prev_bot <== 0;
  126. sm[i].prev_new1 <== 0;
  127. sm[i].prev_na <== 1-enabled;
  128. sm[i].prev_upd <== 0;
  129. } else {
  130. sm[i].prev_top <== sm[i-1].st_top;
  131. sm[i].prev_old0 <== sm[i-1].st_old0;
  132. sm[i].prev_bot <== sm[i-1].st_bot;
  133. sm[i].prev_new1 <== sm[i-1].st_new1;
  134. sm[i].prev_na <== sm[i-1].st_na;
  135. sm[i].prev_upd <== sm[i-1].st_upd;
  136. }
  137. sm[i].is0 <== isOld0;
  138. sm[i].xor <== xors[i].out;
  139. sm[i].fnc[0] <== fnc[0];
  140. sm[i].fnc[1] <== fnc[1];
  141. sm[i].levIns <== smtLevIns.levIns[i];
  142. }
  143. sm[nLevels-1].st_na === 1;
  144. component levels[nLevels];
  145. for (var i=nLevels-1; i != -1; i--) {
  146. levels[i] = SMTInsertLevel();
  147. levels[i].st_top <== sm[i].st_top;
  148. levels[i].st_old0 <== sm[i].st_old0;
  149. levels[i].st_bot <== sm[i].st_bot;
  150. levels[i].st_new1 <== sm[i].st_new1;
  151. levels[i].st_na <== sm[i].st_na;
  152. levels[i].st_upd <== sm[i].st_upd;
  153. levels[i].sibling <== siblings[i];
  154. levels[i].old1leaf <== hash1Old.out;
  155. levels[i].new1leaf <== hash1New.out;
  156. levels[i].newlrbit <== n2bNew.out[i];
  157. if (i==nLevels-1) {
  158. levels[i].oldChild <== 0;
  159. levels[i].newChild <== 0;
  160. } else {
  161. levels[i].oldChild <== levels[i+1].oldRoot;
  162. levels[i].newChild <== levels[i+1].newRoot;
  163. }
  164. }
  165. component topSwitcher = Switcher();
  166. topSwitcher.sel <== fnc[0]*fnc[1];
  167. topSwitcher.L <== levels[0].oldRoot;
  168. topSwitcher.R <== levels[0].newRoot;
  169. topSwitcher.outL === oldRoot*enabled;
  170. topSwitcher.outR === newRoot*enabled;
  171. }