diff --git a/circuits/json/nivc/extractor.circom b/circuits/json/nivc/extractor.circom index e0a86e7..95220ab 100644 --- a/circuits/json/nivc/extractor.circom +++ b/circuits/json/nivc/extractor.circom @@ -5,11 +5,8 @@ include "@zk-email/circuits/utils/array.circom"; template MaskExtractFinal(DATA_BYTES, MAX_STACK_HEIGHT, MAX_VALUE_LENGTH) { // ------------------------------------------------------------------------------------------------------------------ // - // ~~ Set sizes at compile time ~~ - // Total number of variables in the parser for each byte of data assert(MAX_STACK_HEIGHT >= 2); - var PER_ITERATION_DATA_LENGTH = MAX_STACK_HEIGHT * 2 + 2; - var TOTAL_BYTES_ACROSS_NIVC = DATA_BYTES * (PER_ITERATION_DATA_LENGTH + 1) + 1; + var TOTAL_BYTES_ACROSS_NIVC = DATA_BYTES * 2 + 4; // aes pt/ct + ctr // ------------------------------------------------------------------------------------------------------------------ // signal input step_in[TOTAL_BYTES_ACROSS_NIVC]; signal output step_out[TOTAL_BYTES_ACROSS_NIVC]; diff --git a/circuits/json/nivc/masker.circom b/circuits/json/nivc/masker.circom index 66dbf81..97f1114 100644 --- a/circuits/json/nivc/masker.circom +++ b/circuits/json/nivc/masker.circom @@ -1,217 +1,148 @@ pragma circom 2.1.9; include "../interpreter.circom"; -include "../../utils/array.circom"; template JsonMaskObjectNIVC(DATA_BYTES, MAX_STACK_HEIGHT, MAX_KEY_LENGTH) { // ------------------------------------------------------------------------------------------------------------------ // - // ~~ Set sizes at compile time ~~ - // Total number of variables in the parser for each byte of data - assert(MAX_STACK_HEIGHT >= 2); - var PER_ITERATION_DATA_LENGTH = MAX_STACK_HEIGHT * 2 + 2; - var TOTAL_BYTES_ACROSS_NIVC = DATA_BYTES * (PER_ITERATION_DATA_LENGTH + 1) + 1; + assert(MAX_STACK_HEIGHT >= 2); // TODO (autoparallel): idk if we need this now + var TOTAL_BYTES_ACROSS_NIVC = DATA_BYTES * 2 + 4; // aes ct/pt + ctr // ------------------------------------------------------------------------------------------------------------------ // - - // ------------------------------------------------------------------------------------------------------------------ // - // ~ Unravel from previous NIVC step ~ - // Read in from previous NIVC step (JsonParseNIVC) signal input step_in[TOTAL_BYTES_ACROSS_NIVC]; signal output step_out[TOTAL_BYTES_ACROSS_NIVC]; - // Grab the raw data bytes from the `step_in` variable - var paddedDataLen = DATA_BYTES + MAX_KEY_LENGTH + 1; - signal data[paddedDataLen]; - for (var i = 0 ; i < DATA_BYTES ; i++) { - data[i] <== step_in[i]; - } - for (var i = 0 ; i < MAX_KEY_LENGTH + 1 ; i++) { - data[DATA_BYTES + i] <== 0; - } - - // Decode the encoded data in `step_in` back into parser variables - signal stack[DATA_BYTES][MAX_STACK_HEIGHT + 1][2]; - signal parsingData[DATA_BYTES][2]; - for (var i = 0 ; i < DATA_BYTES ; i++) { - for (var j = 0 ; j < MAX_STACK_HEIGHT + 1 ; j++) { - if (j < MAX_STACK_HEIGHT) { - stack[i][j][0] <== step_in[DATA_BYTES + i * PER_ITERATION_DATA_LENGTH + j * 2]; - stack[i][j][1] <== step_in[DATA_BYTES + i * PER_ITERATION_DATA_LENGTH + j * 2 + 1]; - } else { - // Add one extra stack element without doing this while parsing. - // Stack under/overflow caught in parsing. - stack[i][j][0] <== 0; - stack[i][j][1] <== 0; - } - - } - parsingData[i][0] <== step_in[DATA_BYTES + i * PER_ITERATION_DATA_LENGTH + MAX_STACK_HEIGHT * 2]; - parsingData[i][1] <== step_in[DATA_BYTES + i * PER_ITERATION_DATA_LENGTH + MAX_STACK_HEIGHT * 2 + 1]; - } - // ------------------------------------------------------------------------------------------------------------------ // - - // ------------------------------------------------------------------------------------------------------------------ // - // ~ Object masking ~ - // Key data to use to point to which object to extract + // Declaration of signals. + signal data[DATA_BYTES]; signal input key[MAX_KEY_LENGTH]; signal input keyLen; - // Signals to detect if we are parsing a key or value with initial setup - signal parsing_key[DATA_BYTES]; - signal parsing_value[DATA_BYTES]; + for(var i = 0 ; i < DATA_BYTES ; i++) { + data[i] <== step_in[i]; + } - // Flags at each byte to indicate if we are matching correct key and in subsequent value - signal is_key_match[DATA_BYTES]; - signal is_value_match[DATA_BYTES]; + // Constraints. + signal value_starting_index[DATA_BYTES - MAX_KEY_LENGTH]; + // flag determining whether this byte is matched value + signal is_value_match[DATA_BYTES - MAX_KEY_LENGTH]; - signal is_next_pair_at_depth[DATA_BYTES]; - signal is_key_match_for_value[DATA_BYTES + 1]; + component State[DATA_BYTES - MAX_KEY_LENGTH]; + State[0] = StateUpdate(MAX_STACK_HEIGHT); + State[0].byte <== data[0]; + for(var i = 0; i < MAX_STACK_HEIGHT; i++) { + State[0].stack[i] <== [0,0]; + } + State[0].parsing_string <== 0; + State[0].parsing_number <== 0; + + signal parsing_key[DATA_BYTES - MAX_KEY_LENGTH]; + signal parsing_value[DATA_BYTES - MAX_KEY_LENGTH]; + signal parsing_object_value[DATA_BYTES - MAX_KEY_LENGTH]; + signal is_key_match[DATA_BYTES - MAX_KEY_LENGTH]; + signal is_key_match_for_value[DATA_BYTES+1 - MAX_KEY_LENGTH]; is_key_match_for_value[0] <== 0; + signal is_next_pair_at_depth[DATA_BYTES - MAX_KEY_LENGTH]; + signal or[DATA_BYTES - MAX_KEY_LENGTH]; - // Initialize values knowing 0th bit of data will never be a key/value - parsing_key[0] <== 0; - parsing_value[0] <== 0; - is_key_match[0] <== 0; - - component stackSelector[DATA_BYTES]; - stackSelector[0] = ArraySelector(MAX_STACK_HEIGHT + 1, 2); - stackSelector[0].in <== stack[0]; - stackSelector[0].index <== step_in[TOTAL_BYTES_ACROSS_NIVC - 1]; + // initialise first iteration - component nextStackSelector[DATA_BYTES]; - nextStackSelector[0] = ArraySelector(MAX_STACK_HEIGHT + 1, 2); - nextStackSelector[0].in <== stack[0]; - nextStackSelector[0].index <== step_in[TOTAL_BYTES_ACROSS_NIVC - 1] + 1; + // check inside key or value + parsing_key[0] <== InsideKey()(State[0].next_stack[0], State[0].next_parsing_string, State[0].next_parsing_number); + parsing_value[0] <== InsideValueObject()(State[0].next_stack[0], State[0].next_stack[1], State[0].next_parsing_string, State[0].next_parsing_number); - is_next_pair_at_depth[0] <== NextKVPairAtDepth(MAX_STACK_HEIGHT + 1)(stack[0], data[0],step_in[TOTAL_BYTES_ACROSS_NIVC - 1]); + is_key_match[0] <== 0; + is_next_pair_at_depth[0] <== NextKVPairAtDepth(MAX_STACK_HEIGHT)(State[0].next_stack, data[0], 0); is_key_match_for_value[1] <== Mux1()([is_key_match_for_value[0] * (1-is_next_pair_at_depth[0]), is_key_match[0] * (1-is_next_pair_at_depth[0])], is_key_match[0]); - is_value_match[0] <== parsing_value[0] * is_key_match_for_value[1]; - - signal or[DATA_BYTES]; - or[0] <== is_value_match[0]; - step_out[0] <== data[0] * or[0]; - - for(var data_idx = 1; data_idx < DATA_BYTES; data_idx++) { - // Grab the stack at the indicated height (from `step_in`) - stackSelector[data_idx] = ArraySelector(MAX_STACK_HEIGHT + 1, 2); - stackSelector[data_idx].in <== stack[data_idx]; - stackSelector[data_idx].index <== step_in[TOTAL_BYTES_ACROSS_NIVC - 1]; - - nextStackSelector[data_idx] = ArraySelector(MAX_STACK_HEIGHT + 1, 2); - nextStackSelector[data_idx].in <== stack[data_idx]; - nextStackSelector[data_idx].index <== step_in[TOTAL_BYTES_ACROSS_NIVC - 1] + 1; - - // Detect if we are parsing - parsing_key[data_idx] <== InsideKey()(stackSelector[data_idx].out, parsingData[data_idx][0], parsingData[data_idx][1]); - parsing_value[data_idx] <== InsideValueObject()(stackSelector[data_idx].out, nextStackSelector[data_idx].out, parsingData[data_idx][0], parsingData[data_idx][1]); + is_value_match[0] <== parsing_value[0] * is_key_match_for_value[1]; + + step_out[0] <== data[0] * is_value_match[0]; + + // TODO (autoparallel): it might be dumb to do this with the max key length but fuck it + for(var data_idx = 1; data_idx < DATA_BYTES - MAX_KEY_LENGTH; data_idx++) { + State[data_idx] = StateUpdate(MAX_STACK_HEIGHT); + State[data_idx].byte <== data[data_idx]; + State[data_idx].stack <== State[data_idx - 1].next_stack; + State[data_idx].parsing_string <== State[data_idx - 1].next_parsing_string; + State[data_idx].parsing_number <== State[data_idx - 1].next_parsing_number; + + // - parsing key + // - parsing value (different for string/numbers and array) + // - key match (key 1, key 2) + // - is next pair + // - is key match for value + // - value_mask + // - mask + + // check if inside key or not + parsing_key[data_idx] <== InsideKey()(State[data_idx].next_stack[0], State[data_idx].next_parsing_string, State[data_idx].next_parsing_number); + // check if inside value + parsing_value[data_idx] <== InsideValueObject()(State[data_idx].next_stack[0], State[data_idx].next_stack[1], State[data_idx].next_parsing_string, State[data_idx].next_parsing_number); // to get correct value, check: // - key matches at current index and depth of key is as specified // - whether next KV pair starts // - whether key matched for a value (propogate key match until new KV pair of lower depth starts) - is_key_match[data_idx] <== KeyMatchAtIndex(paddedDataLen, MAX_KEY_LENGTH, data_idx)(data, key, keyLen, parsing_key[data_idx]); - is_next_pair_at_depth[data_idx] <== NextKVPairAtDepth(MAX_STACK_HEIGHT + 1)(stack[data_idx], data[data_idx], step_in[TOTAL_BYTES_ACROSS_NIVC - 1]); - + is_key_match[data_idx] <== KeyMatchAtIndex(DATA_BYTES, MAX_KEY_LENGTH, data_idx)(data, key, keyLen, parsing_key[data_idx]); + is_next_pair_at_depth[data_idx] <== NextKVPairAtDepth(MAX_STACK_HEIGHT)(State[data_idx].next_stack, data[data_idx], 0); is_key_match_for_value[data_idx+1] <== Mux1()([is_key_match_for_value[data_idx] * (1-is_next_pair_at_depth[data_idx]), is_key_match[data_idx] * (1-is_next_pair_at_depth[data_idx])], is_key_match[data_idx]); - is_value_match[data_idx] <== is_key_match_for_value[data_idx+1] * parsing_value[data_idx]; + is_value_match[data_idx] <== is_key_match_for_value[data_idx+1] * parsing_value[data_idx]; + + or[data_idx] <== OR()(is_value_match[data_idx], is_value_match[data_idx - 1]); - // Set the next NIVC step to only have the masked data - or[data_idx] <== OR()(is_value_match[data_idx], is_value_match[data_idx -1]); + // mask = currently parsing value and all subsequent keys matched step_out[data_idx] <== data[data_idx] * or[data_idx]; } - // Append the parser state back on `step_out` - for (var i = DATA_BYTES ; i < TOTAL_BYTES_ACROSS_NIVC - 1 ; i++) { - step_out[i] <== step_in[i]; + for(var i = DATA_BYTES - MAX_KEY_LENGTH; i < 2 * DATA_BYTES ; i ++) { + step_out[i] <== 0; } - // No need to pad as this is currently when TOTAL_BYTES == TOTAL_BYTES_ACROSS_NIVC - - // Finally, update the current depth we are extracting from - step_out[TOTAL_BYTES_ACROSS_NIVC - 1] <== step_in[TOTAL_BYTES_ACROSS_NIVC - 1] + 1; } template JsonMaskArrayIndexNIVC(DATA_BYTES, MAX_STACK_HEIGHT) { // ------------------------------------------------------------------------------------------------------------------ // - // ~~ Set sizes at compile time ~~ - // Total number of variables in the parser for each byte of data - assert(MAX_STACK_HEIGHT >= 2); - var PER_ITERATION_DATA_LENGTH = MAX_STACK_HEIGHT * 2 + 2; - var TOTAL_BYTES_ACROSS_NIVC = DATA_BYTES * (PER_ITERATION_DATA_LENGTH + 1) + 1; - // ------------------------------------------------------------------------------------------------------------------ // - + assert(MAX_STACK_HEIGHT >= 2); // TODO (autoparallel): idk if we need this now + var TOTAL_BYTES_ACROSS_NIVC = DATA_BYTES * 2 + 4; // aes ct/pt + ctr // ------------------------------------------------------------------------------------------------------------------ // - // ~ Unravel from previous NIVC step ~ - // Read in from previous NIVC step (JsonParseNIVC) - signal input step_in[TOTAL_BYTES_ACROSS_NIVC]; + signal input step_in[TOTAL_BYTES_ACROSS_NIVC]; signal output step_out[TOTAL_BYTES_ACROSS_NIVC]; - // Grab the raw data bytes from the `step_in` variable + // Declaration of signals. signal data[DATA_BYTES]; - for (var i = 0 ; i < DATA_BYTES ; i++) { - data[i] <== step_in[i]; - } + signal input index; - // Decode the encoded data in `step_in` back into parser variables - signal stack[DATA_BYTES][MAX_STACK_HEIGHT + 1][2]; - signal parsingData[DATA_BYTES][2]; - for (var i = 0 ; i < DATA_BYTES ; i++) { - for (var j = 0 ; j < MAX_STACK_HEIGHT + 1 ; j++) { - if (j < MAX_STACK_HEIGHT) { - stack[i][j][0] <== step_in[DATA_BYTES + i * PER_ITERATION_DATA_LENGTH + j * 2]; - stack[i][j][1] <== step_in[DATA_BYTES + i * PER_ITERATION_DATA_LENGTH + j * 2 + 1]; - } else { - // Add one extra stack element without doing this while parsing. - // Stack under/overflow caught in parsing. - stack[i][j][0] <== 0; - stack[i][j][1] <== 0; - } - - } - parsingData[i][0] <== step_in[DATA_BYTES + i * PER_ITERATION_DATA_LENGTH + MAX_STACK_HEIGHT * 2]; - parsingData[i][1] <== step_in[DATA_BYTES + i * PER_ITERATION_DATA_LENGTH + MAX_STACK_HEIGHT * 2 + 1]; + for(var i = 0 ; i < DATA_BYTES ; i++) { + data[i] <== step_in[i]; } - // ------------------------------------------------------------------------------------------------------------------ // - // ------------------------------------------------------------------------------------------------------------------ // - // ~ Array index masking ~ - signal input index; + // value starting index in `data` + signal value_starting_index[DATA_BYTES]; - signal parsing_array[DATA_BYTES]; + component State[DATA_BYTES]; + State[0] = StateUpdate(MAX_STACK_HEIGHT); + State[0].byte <== data[0]; + for(var i = 0; i < MAX_STACK_HEIGHT; i++) { + State[0].stack[i] <== [0,0]; + } + State[0].parsing_string <== 0; + State[0].parsing_number <== 0; - component stackSelector[DATA_BYTES]; - stackSelector[0] = ArraySelector(MAX_STACK_HEIGHT + 1, 2); - stackSelector[0].in <== stack[0]; - stackSelector[0].index <== step_in[TOTAL_BYTES_ACROSS_NIVC - 1]; + signal parsing_array[DATA_BYTES]; + signal or[DATA_BYTES]; - component nextStackSelector[DATA_BYTES]; - nextStackSelector[0] = ArraySelector(MAX_STACK_HEIGHT + 1, 2); - nextStackSelector[0].in <== stack[0]; - nextStackSelector[0].index <== step_in[TOTAL_BYTES_ACROSS_NIVC - 1] + 1; + parsing_array[0] <== InsideArrayIndexObject()(State[0].next_stack[0], State[0].next_stack[1], State[0].next_parsing_string, State[0].next_parsing_number, index); + step_out[0] <== data[0] * parsing_array[0]; // TODO (autoparallel): is this totally correcot or do we need an or, i think it's right - parsing_array[0] <== InsideArrayIndexObject()(stackSelector[0].out, nextStackSelector[0].out, parsingData[0][0], parsingData[0][1], index); - signal or[DATA_BYTES]; - or[0] <== parsing_array[0]; - step_out[0] <== data[0] * or[0]; for(var data_idx = 1; data_idx < DATA_BYTES; data_idx++) { - stackSelector[data_idx] = ArraySelector(MAX_STACK_HEIGHT + 1, 2); - stackSelector[data_idx].in <== stack[data_idx]; - stackSelector[data_idx].index <== step_in[TOTAL_BYTES_ACROSS_NIVC - 1]; + State[data_idx] = StateUpdate(MAX_STACK_HEIGHT); + State[data_idx].byte <== data[data_idx]; + State[data_idx].stack <== State[data_idx - 1].next_stack; + State[data_idx].parsing_string <== State[data_idx - 1].next_parsing_string; + State[data_idx].parsing_number <== State[data_idx - 1].next_parsing_number; - nextStackSelector[data_idx] = ArraySelector(MAX_STACK_HEIGHT + 1, 2); - nextStackSelector[data_idx].in <== stack[data_idx]; - nextStackSelector[data_idx].index <== step_in[TOTAL_BYTES_ACROSS_NIVC - 1] + 1; + parsing_array[data_idx] <== InsideArrayIndexObject()(State[data_idx].next_stack[0], State[data_idx].next_stack[1], State[data_idx].next_parsing_string, State[data_idx].next_parsing_number, index); - parsing_array[data_idx] <== InsideArrayIndexObject()(stackSelector[data_idx].out, nextStackSelector[data_idx].out, parsingData[data_idx][0], parsingData[data_idx][1], index); - - or[data_idx] <== OR()(parsing_array[data_idx], parsing_array[data_idx - 1]); + or[data_idx] <== OR()(parsing_array[data_idx], parsing_array[data_idx - 1]); step_out[data_idx] <== data[data_idx] * or[data_idx]; } - - // Write the `step_out` with masked data - - // Append the parser state back on `step_out` - for (var i = DATA_BYTES ; i < TOTAL_BYTES_ACROSS_NIVC - 1 ; i++) { - step_out[i] <== step_in[i]; + for(var i = DATA_BYTES ; i < 2 * DATA_BYTES ; i++) { + step_out[i] <== 0; } - // No need to pad as this is currently when TOTAL_BYTES == TOTAL_BYTES_USED - step_out[TOTAL_BYTES_ACROSS_NIVC - 1] <== step_in[TOTAL_BYTES_ACROSS_NIVC - 1] + 1; } diff --git a/circuits/json/nivc/parse.circom b/circuits/json/nivc/parse.circom deleted file mode 100644 index 4650dfa..0000000 --- a/circuits/json/nivc/parse.circom +++ /dev/null @@ -1,61 +0,0 @@ -pragma circom 2.1.9; - -include "../parser/parser.circom"; - -template JsonParseNIVC(DATA_BYTES, MAX_STACK_HEIGHT) { - // ------------------------------------------------------------------------------------------------------------------ // - // ~~ Set sizes at compile time ~~ - // Total number of variables in the parser for each byte of data - var PER_ITERATION_DATA_LENGTH = MAX_STACK_HEIGHT * 2 + 2; - var TOTAL_BYTES_ACROSS_NIVC = DATA_BYTES * (PER_ITERATION_DATA_LENGTH + 1) + 1; - // ------------------------------------------------------------------------------------------------------------------ // - - // Read in from previous NIVC step (AESNIVC) - signal input step_in[TOTAL_BYTES_ACROSS_NIVC]; - - // ------------------------------------------------------------------------------------------------------------------ // - // ~ Parse JSON ~ - // Initialize the parser - component State[DATA_BYTES]; - State[0] = StateUpdate(MAX_STACK_HEIGHT); - for(var i = 0; i < MAX_STACK_HEIGHT; i++) { - State[0].stack[i] <== [0,0]; - } - State[0].parsing_string <== 0; - State[0].parsing_number <== 0; - State[0].byte <== step_in[0]; - - // Parse all the data to generate the complete parser state - for(var i = 1; i < DATA_BYTES; i++) { - State[i] = StateUpdate(MAX_STACK_HEIGHT); - State[i].byte <== step_in[i]; - State[i].stack <== State[i - 1].next_stack; - State[i].parsing_string <== State[i - 1].next_parsing_string; - State[i].parsing_number <== State[i - 1].next_parsing_number; - } - // ------------------------------------------------------------------------------------------------------------------ // - - // ------------------------------------------------------------------------------------------------------------------ // - // ~ Write to `step_out` for next NIVC step - // Pass the data bytes back out in the first `step_out` signals - signal output step_out[TOTAL_BYTES_ACROSS_NIVC]; - for (var i = 0 ; i < DATA_BYTES ; i++) { - step_out[i] <== step_in[i]; - } - - // Decode the parser state into the `step_out` remaining signals - for (var i = 0 ; i < DATA_BYTES ; i++) { - for (var j = 0 ; j < MAX_STACK_HEIGHT ; j++) { - step_out[DATA_BYTES + i * PER_ITERATION_DATA_LENGTH + j * 2] <== State[i].next_stack[j][0]; - step_out[DATA_BYTES + i * PER_ITERATION_DATA_LENGTH + j * 2 + 1] <== State[i].next_stack[j][1]; - } - step_out[DATA_BYTES + i * PER_ITERATION_DATA_LENGTH + MAX_STACK_HEIGHT * 2] <== State[i].next_parsing_string; - step_out[DATA_BYTES + i * PER_ITERATION_DATA_LENGTH + MAX_STACK_HEIGHT * 2 + 1] <== State[i].next_parsing_number; - } - // No need to pad as this is currently when TOTAL_BYTES == TOTAL_BYTES_USED - step_out[TOTAL_BYTES_ACROSS_NIVC - 1] <== 0; // Initial depth set to 0 for extraction - // ------------------------------------------------------------------------------------------------------------------ // -} - -// component main { public [step_in] } = JsonParseNIVC(320, 5); - diff --git a/circuits/test/json/nivc/masker_nivc.test.ts b/circuits/test/json/nivc/masker_nivc.test.ts index be849b9..acc41ae 100644 --- a/circuits/test/json/nivc/masker_nivc.test.ts +++ b/circuits/test/json/nivc/masker_nivc.test.ts @@ -31,7 +31,6 @@ let json_input = [123, 13, 10, 32, 32, 32, 34, 100, 97, 116, 97, 34, 58, 32, 123 13, 10, 32, 32, 32, 32, 32, 32, 32, 93, 13, 10, 32, 32, 32, 125, 13, 10, 125]; describe("NIVC Extract", async () => { - let parse_circuit: WitnessTester<["step_in"], ["step_out"]>; let json_mask_object_circuit: WitnessTester<["step_in", "key", "keyLen"], ["step_out"]>; let json_mask_arr_circuit: WitnessTester<["step_in", "index"], ["step_out"]>; let extract_value_circuit: WitnessTester<["step_in"], ["step_out"]>; @@ -40,17 +39,9 @@ describe("NIVC Extract", async () => { const MAX_STACK_HEIGHT = 5; const MAX_KEY_LENGTH = 8; const MAX_VALUE_LENGTH = 35; - const PER_ITERATION_DATA_LENGTH = MAX_STACK_HEIGHT * 2 + 2; - const TOTAL_BYTES_ACROSS_NIVC = DATA_BYTES * (PER_ITERATION_DATA_LENGTH + 1) + 1; + const TOTAL_BYTES_ACROSS_NIVC = DATA_BYTES * 2 + 4; before(async () => { - parse_circuit = await circomkit.WitnessTester(`JsonParseNIVC`, { - file: "json/nivc/parse", - template: "JsonParseNIVC", - params: [DATA_BYTES, MAX_STACK_HEIGHT], - }); - console.log("#constraints:", await parse_circuit.getConstraintCount()); - json_mask_arr_circuit = await circomkit.WitnessTester(`JsonMaskArrayIndexNIVC`, { file: "json/nivc/masker", template: "JsonMaskArrayIndexNIVC", @@ -87,9 +78,8 @@ describe("NIVC Extract", async () => { let value = toByte("\"Taylor Swift\""); it("parse and mask", async () => { - let json_parse = await parse_circuit.compute({ step_in: extended_json_input }, ["step_out"]); - let json_extract_key0 = await json_mask_object_circuit.compute({ step_in: json_parse.step_out, key: key0, keyLen: key0Len }, ["step_out"]); + let json_extract_key0 = await json_mask_object_circuit.compute({ step_in: extended_json_input, key: key0, keyLen: key0Len }, ["step_out"]); let json_extract_key1 = await json_mask_object_circuit.compute({ step_in: json_extract_key0.step_out, key: key1, keyLen: key1Len }, ["step_out"]);