Skip to content

Commit

Permalink
json object extract
Browse files Browse the repository at this point in the history
  • Loading branch information
Autoparallel committed Nov 7, 2024
1 parent 94257f0 commit 16ff091
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 147 deletions.
9 changes: 9 additions & 0 deletions circuits.json
Original file line number Diff line number Diff line change
Expand Up @@ -242,5 +242,14 @@
"params": [
1024
]
},
"nivc_json_object": {
"file": "json/nivc/masker",
"template": "JsonMaskObjectNIVC",
"params": [
1024,
10,
10
]
}
}
3 changes: 1 addition & 2 deletions circuits/http/nivc/body_mask.circom
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ template HTTPMaskBodyNIVC(DATA_BYTES) {
}

// Hash the new data so this can now be used in the chain later
signal body_mask_hash <== DataHasher(DATA_BYTES)(bodyMasked);
step_out[0] <== body_mask_hash;
step_out[0] <== DataHasher(DATA_BYTES)(bodyMasked);
}

98 changes: 50 additions & 48 deletions circuits/json/nivc/masker.circom
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,18 @@ pragma circom 2.1.9;
include "../interpreter.circom";

template JsonMaskObjectNIVC(DATA_BYTES, MAX_STACK_HEIGHT, MAX_KEY_LENGTH) {
// ------------------------------------------------------------------------------------------------------------------ //
assert(MAX_STACK_HEIGHT >= 2); // TODO (autoparallel): idk if we need this now
var TOTAL_BYTES_ACROSS_NIVC = DATA_BYTES + 4; // aes ct/pt + ctr
// ------------------------------------------------------------------------------------------------------------------ //
signal input step_in[TOTAL_BYTES_ACROSS_NIVC];
signal output step_out[TOTAL_BYTES_ACROSS_NIVC];

// Declaration of signals.
signal data[DATA_BYTES];

signal input step_in[1];
signal input key[MAX_KEY_LENGTH];
signal input keyLen;

for(var i = 0 ; i < DATA_BYTES ; i++) {
data[i] <== step_in[i];
}
signal output step_out[1];

// Authenticate the (potentially further masked) plaintext we are passing in
signal input data[DATA_BYTES];
signal data_hash <== DataHasher(DATA_BYTES)(data);
data_hash === step_in[0];

// flag determining whether this byte is matched value
signal is_value_match[DATA_BYTES - MAX_KEY_LENGTH];
Expand Down Expand Up @@ -50,46 +47,51 @@ template JsonMaskObjectNIVC(DATA_BYTES, MAX_STACK_HEIGHT, MAX_KEY_LENGTH) {
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];

step_out[0] <== data[0] * is_value_match[0];
signal masked[DATA_BYTES];
signal output maskedData[DATA_BYTES]; // TODO temp
masked[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(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];

or[data_idx - 1] <== 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 - 1];
}
for(var i = DATA_BYTES - MAX_KEY_LENGTH; i < DATA_BYTES + 4; i ++) {
step_out[i] <== 0;
for(var data_idx = 1; data_idx < DATA_BYTES; data_idx++) {
if(data_idx < DATA_BYTES - MAX_KEY_LENGTH) {
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(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];

or[data_idx - 1] <== OR()(is_value_match[data_idx], is_value_match[data_idx - 1]);

// mask = currently parsing value and all subsequent keys matched
masked[data_idx] <== data[data_idx] * or[data_idx - 1]; // TODO here
} else {
masked[data_idx] <== 0;
}
}
maskedData <== masked;
step_out[0] <== DataHasher(DATA_BYTES)(masked);
}

template JsonMaskArrayIndexNIVC(DATA_BYTES, MAX_STACK_HEIGHT) {
Expand Down
Loading

0 comments on commit 16ff091

Please sign in to comment.