/*************************************************************************************************** Each level on a SMTInsert has a state. The state of the level depends on the state of te botom level and on `xor` and `is0` signals. `isOldLev` 1 when is the level where oldLeaf is. `xor` signal is 0 if the index bit at the current level is the same in the old and the new index, and 1 if it is different. `is0` signal, is 1 if we are inserting in an empty leaf and 0 if we are inserting in a leaf that contains an element. The states are: top: While the index bits of the old and new insex in the top level is the same, whe are in the top state. old0 and old1: When the we reach insert level, we go to old0 and old1 states according to `is0` signal. btn: Once in old1 we go to btn until xor=1 new1: This level is reached when xor=1. Here is where we insert the hash of the old and the new trees with just one element. na: Not appliable. After inserting it, we go to the na level. Fnction fnc[0] fnc[1] 0 0 NOP 0 1 UPDATE 1 0 INSERT 1 1 DELETE ########### # # ┌────────────────────────────▶# upd #─────────────────────┐ │ ## ## │ │ ######### │ levIns=1 │ │ fnc[0]=0 │ │ any │ │ │ │ │ │ │ ########### │ │ levIns=1 # # │ levIns=0 │ is0=1 ┌────────────▶# old0 #────────┐ │ any ┌─────┐ │ fnc[0]=1│ ## ## │ │ ┌──────┐ │ │ │ │ ######### │ any │ │ │ │ ▼ │ │ │ ▼ ▼ │ │ ########### │ │ ########### │ │ # # ────────────┘ └────────▶# #│ └──# top # # na # ## ## ────┐ ┌──▶## ## ######### │ │ ######### │ │ │ ########### ########### │ any levIns=1 │ # # xor=1 # # │ is0=0 └───▶# old1 #─────────────▶# new1 #──┘ fnc[0]=1 ## ## ## ## #########│ ######### │ ▲ └───┐ ┌─────┘ xor=0 │ ###########│ xor=1 │ # # ▼# btn # ## ## #########◀───────┐ │ │ │ │ └────────────┘ xor=0 ***************************************************************************************************/ template SMTInsertSM() { signal input xor; signal input is0; signal input levIns; signal input fnc[2]; signal input prev_top; signal input prev_old0; signal input prev_old1; signal input prev_bot; signal input prev_new1; signal input prev_na; signal input prev_upd; signal output st_top; signal output st_old0; signal output st_old1; signal output st_bot; signal output st_new1; signal output st_na; signal output st_upd; signal aux1; signal aux2; aux1 <== prev_top * levIns; aux2 <== aux1*is0; st_top <== prev_top - aux1 // prev_top * (1-levIns) = // = prev_top - aux1; st_old0 <== aux2 * fnc[0]; // (prev_top * levIns * is0)*fnc[0] = aux2 st_old1 <== (aux1 - aux2)*fnc[0]; // (prev_top * levIns * (1-is0))*fnc[0] = // = (aux1 * (1-is0))*fnc[0] = // = (aux1 - aux2) * fnc[0] st_new1 <== (prev_old1 + prev_bot)*xor // prev_old1*xor + prev_bot*xor = // = (prev_old1 + prev_bot)*xor; st_bot <== -st_new1 + prev_old1 + prev_bot // prev_old1*(1-xor) + prev_bot*(1-xor) = // = - prev_old1*xor -prev_bot*xor + prev_old1 + prev_bot = // = -st_new1 + prev_old1 + prev_bot st_na <== prev_new1 + prev_old0 + prev_na + prev_upd; st_upd <== aux1*(1-fnc[0]); // prev_top*levIns*(1-fnc[0]) = // = aux1 * (1-fnc[0]) }