From 7075dc16cfc1e28c7dc3f654e25a286833c3115c Mon Sep 17 00:00:00 2001 From: Colin Roberts Date: Fri, 15 Nov 2024 16:44:47 -0700 Subject: [PATCH] perf: first optimization --- circuits/json/parser/hash_machine.circom | 21 ++++---- .../test/json/parser/hash_machine.test.ts | 54 ++++++++++--------- 2 files changed, 40 insertions(+), 35 deletions(-) diff --git a/circuits/json/parser/hash_machine.circom b/circuits/json/parser/hash_machine.circom index 6ebd9e4..922a4ab 100644 --- a/circuits/json/parser/hash_machine.circom +++ b/circuits/json/parser/hash_machine.circom @@ -348,15 +348,21 @@ template RewriteStack(n) { stateHash[1].in[i] <== tree_hash[i][1]; } + // TODO: need two signals that say whether to hash into 0 or 1 index of tree hash + signal is_object_key <== IsEqualArray(2)([current_value,[1,0]]); + signal is_object_value <== IsEqualArray(2)([current_value,[1,1]]); + signal is_array <== IsEqual()([current_value[0], 2]); signal not_to_hash <== IsZero()(parsing_string * next_parsing_string + next_parsing_number); - signal option_hash[2]; - option_hash[0] <== PoseidonChainer()([stateHash[0].out, byte]); // TODO: Trying this now so we just hash the byte stream of KVs - option_hash[1] <== PoseidonChainer()([stateHash[1].out, byte]); // TODO: Now we are double hashing, we certainly don't need to do this, so should optimize this out + signal hash_0 <== is_object_key * stateHash[0].out; + signal hash_1 <== (is_object_value + is_array) * stateHash[1].out; + signal option_hash; + option_hash <== PoseidonChainer()([hash_0 + hash_1, byte]); // TODO: Trying this now so we just hash the byte stream of KVs + // option_hash <== PoseidonChainer()([stateHash[1].out, byte]); // TODO: Now we are double hashing, we certainly don't need to do this, so should optimize this out log("to_hash: ", (1-not_to_hash)); signal next_state_hash[2]; - next_state_hash[0] <== not_to_hash * (stateHash[0].out - option_hash[0]) + option_hash[0]; // same as: (1 - not_to_hash[i]) * option_hash[i] + not_to_hash[i] * hash[i]; - next_state_hash[1] <== not_to_hash * (stateHash[1].out - option_hash[1]) + option_hash[1]; + next_state_hash[0] <== not_to_hash * (stateHash[0].out - option_hash) + option_hash; // same as: (1 - not_to_hash[i]) * option_hash[i] + not_to_hash[i] * hash[i]; + next_state_hash[1] <== not_to_hash * (stateHash[1].out - option_hash) + option_hash; // ^^^^ next_state_hash is the previous value (state_hash) or it is the newly computed value (option_hash) //--------------------------------------------------------------------------------------------// @@ -366,10 +372,7 @@ template RewriteStack(n) { signal second_index_clear[n]; signal not_changed[n][2]; - // TODO: need two signals that say whether to hash into 0 or 1 index of tree hash - signal is_object_key <== IsEqualArray(2)([current_value,[1,0]]); - signal is_object_value <== IsEqualArray(2)([current_value,[1,1]]); - signal is_array <== IsEqual()([current_value[0], 2]); + signal still_parsing_string <== parsing_string * next_parsing_string; signal to_change_zeroth <== still_parsing_string * is_object_key; diff --git a/circuits/test/json/parser/hash_machine.test.ts b/circuits/test/json/parser/hash_machine.test.ts index 54a9b97..c72d8f4 100644 --- a/circuits/test/json/parser/hash_machine.test.ts +++ b/circuits/test/json/parser/hash_machine.test.ts @@ -4,26 +4,28 @@ import { PoseidonModular } from "../../common/poseidon"; describe("hash_machine", () => { let circuit: WitnessTester<["data"]>; - // it(`array_only_input`, async () => { - // let filename = "array_only"; - // let [input, keyUnicode, output] = readJSONInputFile(`${filename}.json`, [0]); + it(`array_only_input`, async () => { + let filename = "array_only"; + let [input, keyUnicode, output] = readJSONInputFile(`${filename}.json`, [0]); - // circuit = await circomkit.WitnessTester(`Parser`, { - // file: "json/parser/hash_parser", - // template: "ParserHasher", - // params: [input.length, 3], - // }); - // console.log("#constraints:", await circuit.getConstraintCount()); + circuit = await circomkit.WitnessTester(`Parser`, { + file: "json/parser/hash_parser", + template: "ParserHasher", + params: [input.length, 3], + }); + console.log("#constraints:", await circuit.getConstraintCount()); - // await circuit.expectPass({ - // data: input - // }); - // }); + await circuit.expectPass({ + data: input + }); + }); // Numbers for the 42 read in 0th index console.log("[0,\"4\"] hash: ", PoseidonModular([0, 52])); console.log("[prev,\"2\"] hash: ", PoseidonModular([BigInt("10851631763548351427431043290272583122934382613350600043660274710013149244741"), 50])); + // Number for the "a" + console.log("[0,\"a\"] hash: ", PoseidonModular([0, 97])); // Numbers for the "b" read inside object in 1st index console.log("[0,\"b\"] hash: ", PoseidonModular([0, 98])); @@ -54,19 +56,19 @@ describe("hash_machine", () => { // }); - it(`spotify_input`, async () => { - let filename = "spotify"; - let [input, keyUnicode, output] = readJSONInputFile(`${filename}.json`, ["data"]); + // it(`spotify_input`, async () => { + // let filename = "spotify"; + // let [input, keyUnicode, output] = readJSONInputFile(`${filename}.json`, ["data"]); - circuit = await circomkit.WitnessTester(`Parser`, { - file: "json/parser/hash_parser", - template: "ParserHasher", - params: [input.length, 7], - }); - console.log("#constraints:", await circuit.getConstraintCount()); + // circuit = await circomkit.WitnessTester(`Parser`, { + // file: "json/parser/hash_parser", + // template: "ParserHasher", + // params: [input.length, 7], + // }); + // console.log("#constraints:", await circuit.getConstraintCount()); - await circuit.expectPass({ - data: input - }); - }); + // await circuit.expectPass({ + // data: input + // }); + // }); }) \ No newline at end of file