diff --git a/circuits/smt/smthash.circom b/circuits/smt/smthash_mimc.circom similarity index 100% rename from circuits/smt/smthash.circom rename to circuits/smt/smthash_mimc.circom diff --git a/circuits/smt/smthash_poseidon.circom b/circuits/smt/smthash_poseidon.circom new file mode 100644 index 0000000..5a9feb7 --- /dev/null +++ b/circuits/smt/smthash_poseidon.circom @@ -0,0 +1,56 @@ +/* + 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 . +*/ + +include "../poseidon.circom"; + + +/* + Hash1 = H(1 | key | value) + */ + +template SMTHash1() { + signal input key; + signal input value; + signal output out; + + component h = Poseidon(3, 6, 8, 57); // Constant + h.inputs[0] <== key; + h.inputs[1] <== value; + h.inputs[2] <== 1; + + out <== h.out; +} + +/* + This component is used to create the 2 nodes. + + Hash2 = H(Hl | Hr) + */ + +template SMTHash2() { + signal input L; + signal input R; + signal output out; + + component h = Poseidon(2, 6, 8, 57); // Constant + h.inputs[0] <== L; + h.inputs[1] <== R; + + out <== h.out; +} diff --git a/circuits/smt/smtprocessor.circom b/circuits/smt/smtprocessor.circom index 3ab3b66..d4e6fb4 100644 --- a/circuits/smt/smtprocessor.circom +++ b/circuits/smt/smtprocessor.circom @@ -135,7 +135,7 @@ include "../switcher.circom"; include "smtlevins.circom"; include "smtprocessorlevel.circom"; include "smtprocessorsm.circom"; -include "smthash.circom"; +include "smthash_poseidon.circom"; template SMTProcessor(nLevels) { signal input oldRoot; diff --git a/circuits/smt/smtverifier.circom b/circuits/smt/smtverifier.circom index 22e984e..fbfba25 100644 --- a/circuits/smt/smtverifier.circom +++ b/circuits/smt/smtverifier.circom @@ -35,7 +35,7 @@ include "../switcher.circom"; include "smtlevins.circom"; include "smtverifierlevel.circom"; include "smtverifiersm.circom"; -include "smthash.circom"; +include "smthash_poseidon.circom"; template SMTVerifier(nLevels) { signal input enabled; diff --git a/src/smt.js b/src/smt.js index 5b4521e..96f8522 100644 --- a/src/smt.js +++ b/src/smt.js @@ -1,7 +1,7 @@ const bigInt = require("snarkjs").bigInt; const SMTMemDB = require("./smt_memdb"); -const mimc7 = require("./mimc7"); +const {hash0, hash1} = require("./smt_hashes_poseidon"); class SMT { @@ -46,8 +46,8 @@ class SMT { const ins = []; const dels = []; - let rtOld = mimc7.multiHash([key, resFind.foundValue], bigInt.one); - let rtNew = mimc7.multiHash([key, newValue], bigInt.one); + let rtOld = hash1(key, resFind.foundValue); + let rtNew = hash1(key, newValue); ins.push([rtNew, [1, key, newValue ]]); dels.push(rtOld); @@ -62,8 +62,8 @@ class SMT { oldNode = [rtOld, sibling]; newNode = [rtNew, sibling]; } - rtOld = mimc7.multiHash(oldNode, bigInt.zero); - rtNew = mimc7.multiHash(newNode, bigInt.zero); + rtOld = hash0(oldNode[0], oldNode[1]); + rtNew = hash0(newNode[0], newNode[1]); dels.push(rtOld); ins.push([rtNew, newNode]); } @@ -92,7 +92,7 @@ class SMT { const dels = []; const ins = []; - let rtOld = mimc7.multiHash([key, resFind.foundValue], bigInt.one); + let rtOld = hash1(key, resFind.foundValue); let rtNew; dels.push(rtOld); @@ -130,9 +130,9 @@ class SMT { } const oldSibling = resFind.siblings[level]; if (keyBits[level]) { - rtOld = mimc7.multiHash([oldSibling, rtOld], bigInt.zero); + rtOld = hash0(oldSibling, rtOld); } else { - rtOld = mimc7.multiHash([rtOld, oldSibling], bigInt.zero); + rtOld = hash0(rtOld, oldSibling); } dels.push(rtOld); if (!newSibling.isZero()) { @@ -147,7 +147,7 @@ class SMT { } else { newNode = [rtNew, newSibling]; } - rtNew = mimc7.multiHash(newNode, bigInt.zero); + rtNew = hash0(newNode[0], newNode[1]); ins.push([rtNew, newNode]); } } @@ -185,7 +185,7 @@ class SMT { for (let i= res.siblings.length; oldKeyits[i] == newKeyBits[i]; i++) { res.siblings.push(bigInt.zero); } - rtOld = mimc7.multiHash([resFind.notFoundKey, resFind.notFoundValue], bigInt.one); + rtOld = hash1(resFind.notFoundKey, resFind.notFoundValue); res.siblings.push(rtOld); addedOne = true; mixed = false; @@ -197,7 +197,7 @@ class SMT { const inserts = []; const dels = []; - let rt = mimc7.multiHash([key, value], bigInt.one); + let rt = hash1(key, value); inserts.push([rt,[1, key, value]] ); for (let i=res.siblings.length-1; i>=0; i--) { @@ -207,9 +207,9 @@ class SMT { if (mixed) { const oldSibling = resFind.siblings[i]; if (newKeyBits[i]) { - rtOld = mimc7.multiHash([oldSibling, rtOld], bigInt.zero); + rtOld = hash0(oldSibling, rtOld); } else { - rtOld = mimc7.multiHash([rtOld, oldSibling], bigInt.zero); + rtOld = hash0(rtOld, oldSibling); } dels.push(rtOld); } @@ -217,10 +217,10 @@ class SMT { let newRt; if (newKeyBits[i]) { - newRt = mimc7.multiHash([res.siblings[i], rt], bigInt.zero); + newRt = hash0(res.siblings[i], rt); inserts.push([newRt,[res.siblings[i], rt]] ); } else { - newRt = mimc7.multiHash([rt, res.siblings[i]], bigInt.zero); + newRt = hash0(rt, res.siblings[i]); inserts.push([newRt,[rt, res.siblings[i]]] ); } rt = newRt; diff --git a/src/smt_hashes_mimc.js b/src/smt_hashes_mimc.js new file mode 100644 index 0000000..99887db --- /dev/null +++ b/src/smt_hashes_mimc.js @@ -0,0 +1,10 @@ +const mimc7 = require("./mimc7"); +const bigInt = require("snarkjs").bigInt; + +exports.hash0 = function (left, right) { + return mimc7.multiHash(left, right); +}; + +exports.hash1 = function(key, value) { + return mimc7.multiHash([key, value], bigInt.one); +}; diff --git a/src/smt_hashes_poseidon.js b/src/smt_hashes_poseidon.js new file mode 100644 index 0000000..8ad8770 --- /dev/null +++ b/src/smt_hashes_poseidon.js @@ -0,0 +1,12 @@ +const Poseidon = require("./poseidon"); +const bigInt = require("snarkjs").bigInt; + +const hash = Poseidon.createHash(6, 8, 57); + +exports.hash0 = function (left, right) { + return hash([left, right]); +}; + +exports.hash1 = function(key, value) { + return hash([key, value, bigInt.one]); +}; diff --git a/test/poseidoncontract.js b/test/poseidoncontract.js index b5fe208..091ec4f 100644 --- a/test/poseidoncontract.js +++ b/test/poseidoncontract.js @@ -46,12 +46,12 @@ describe("Poseidon Smart contract test", () => { const res = await mimc.methods.poseidon([1,2]).call(); - console.log("Cir: " + bigInt(res.toString(16)).toString(16)); + // console.log("Cir: " + bigInt(res.toString(16)).toString(16)); const hash = Poseidon.createHash(6, 8, 57); const res2 = hash([1,2]); - console.log("Ref: " + bigInt(res2).toString(16)); + // console.log("Ref: " + bigInt(res2).toString(16)); assert.equal(res.toString(), res2.toString()); }); diff --git a/test/smtprocessor.js b/test/smtprocessor.js index 4cff5a7..d283277 100644 --- a/test/smtprocessor.js +++ b/test/smtprocessor.js @@ -84,7 +84,7 @@ describe("SMT test", function () { let circuit; let tree; - this.timeout(100000); + this.timeout(10000000); before( async () => { const cirDef = await compiler(path.join(__dirname, "circuits", "smtprocessor10_test.circom"));