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