/* Copyright 2018 0KIMS association. This file is part of circom (Zero Knowledge Circuit Compiler). circom is a free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. circom is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with circom. If not, see . */ /*************************************************************************************************** SMTProcessor: Sparse Merkle Tree processor is a component to verify an insert/update/delete elements into the Sparse Merkle tree. Insert to an empty leaf ======================= STATE OLD STATE NEW STATE ===== ========= ========= oldRoot newRoot ▲ ▲ │ │ ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ top │Sibling├────▶┃ Hash ┃◀─┐ │Sibling├────▶┃ Hash ┃◀─┐ └───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │ │ │ │ │ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ top ┌─────▶┃ Hash ┃◀──┤Sibling│ ┌─────▶┃ Hash ┃◀──┤Sibling│ │ ┗━━━━━━━┛ └───────┘ │ ┗━━━━━━━┛ └───────┘ │ │ │ │ ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ top │Sibling├──▶┃ Hash ┃◀─────┐ │Sibling├──▶┃ Hash ┃◀─────┐ └───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │ │ │ │ │ ┌────┴────┐ ┌────┴────┐ old0 │ 0 │ │New1Leaf │ └─────────┘ └─────────┘ ┏━━━━━━━┓ ┏━━━━━━━┓ na ┃ Hash ┃ ┃ Hash ┃ ┗━━━━━━━┛ ┗━━━━━━━┛ ┏━━━━━━━┓ ┏━━━━━━━┓ na ┃ Hash ┃ ┃ Hash ┃ ┗━━━━━━━┛ ┗━━━━━━━┛ Insert to a used leaf. ===================== STATE OLD STATE NEW STATE ===== ========= ========= oldRoot newRoot ▲ ▲ │ │ ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ top │Sibling├────▶┃ Hash ┃◀─┐ │Sibling├────▶┃ Hash ┃◀─┐ └───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │ │ │ │ │ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ top ┌─────▶┃ Hash ┃◀──┤Sibling│ ┌─────▶┃ Hash ┃◀──┤Sibling│ │ ┗━━━━━━━┛ └───────┘ │ ┗━━━━━━━┛ └───────┘ │ │ │ │ ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ top │Sibling├──▶┃ Hash ┃◀─────┐ │Sibling├──▶┃ Hash ┃◀─────┐ └───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │ │ │ │ │ ┌────┴────┐ ┏━━━┻━━━┓ ┌───────┐ bot │Old1Leaf │ ┌─────▶┃ Hash ┃◀──┼─ 0 │ └─────────┘ │ ┗━━━━━━━┛ └───────┘ │ │ ┏━━━━━━━┓ ┌───────┐ ┏━━━┻━━━┓ bot ┃ Hash ┃ │ 0 ─┼──▶┃ Hash ┃◀─────┐ ┗━━━━━━━┛ └───────┘ ┗━━━━━━━┛ │ │ │ ┏━━━━━━━┓ ┏━━━┻━━━┓ ┌───────┐ bot ┃ Hash ┃ ┌─────▶┃ Hash ┃◀──│ 0 │ ┗━━━━━━━┛ │ ┗━━━━━━━┛ └───────┘ │ │ ┏━━━━━━━┓ ┌─────────┐ ┏━━━┻━━━┓ ┌─────────┐ new1 ┃ Hash ┃ │Old1Leaf ├──▶┃ Hash ┃◀──│New1Leaf │ ┗━━━━━━━┛ └─────────┘ ┗━━━━━━━┛ └─────────┘ ┏━━━━━━━┓ ┏━━━━━━━┓ na ┃ Hash ┃ ┃ Hash ┃ ┗━━━━━━━┛ ┗━━━━━━━┛ ┏━━━━━━━┓ ┏━━━━━━━┓ na ┃ Hash ┃ ┃ Hash ┃ ┗━━━━━━━┛ ┗━━━━━━━┛ Fnction fnc[0] fnc[1] 0 0 NOP 0 1 UPDATE 1 0 INSERT 1 1 DELETE ***************************************************************************************************/ pragma circom 2.0.0; include "../gates.circom"; include "../bitify.circom"; include "../comparators.circom"; include "../switcher.circom"; include "smtlevins.circom"; include "smtprocessorlevel.circom"; include "smtprocessorsm.circom"; include "smthash_poseidon.circom"; template SMTProcessor(nLevels) { signal input oldRoot; signal output newRoot; signal input siblings[nLevels]; signal input oldKey; signal input oldValue; signal input isOld0; signal input newKey; signal input newValue; signal input fnc[2]; signal enabled; var i; enabled <== fnc[0] + fnc[1] - fnc[0]*fnc[1]; component hash1Old = SMTHash1(); hash1Old.key <== oldKey; hash1Old.value <== oldValue; component hash1New = SMTHash1(); hash1New.key <== newKey; hash1New.value <== newValue; component n2bOld = Num2Bits_strict(); component n2bNew = Num2Bits_strict(); n2bOld.in <== oldKey; n2bNew.in <== newKey; component smtLevIns = SMTLevIns(nLevels); for (i=0; i