Skip to content

Commit

Permalink
fix: empty array and object (#108)
Browse files Browse the repository at this point in the history
* test: circom empties

* fix: rust parser empty object
  • Loading branch information
Autoparallel authored Feb 12, 2025
1 parent fd29efa commit 10c8fd4
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 1 deletion.
60 changes: 60 additions & 0 deletions circuits/test/json/extraction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,66 @@ describe("JSON Extraction", () => {
console.log("> Fourth subtest passed.");
});

it(`input: empty`, async () => {
let filename = "empty";
let [input, _keyUnicode, _output] = readJSONInputFile(`${filename}.json`, []);
let input_padded = input.concat(Array(DATA_BYTES - input.length).fill(-1));

// Test `{}` in "empty" key
let keySequence: JsonMaskType[] = [
{ type: "Object", value: strToBytes("empty") },
];
let [stack, treeHashes] = jsonTreeHasher(mock_ct_digest, keySequence, MAX_STACK_HEIGHT);
console.log(treeHashes);
let sequence_digest = compressTreeHash(mock_ct_digest, [stack, treeHashes]);
let sequence_digest_hashed = poseidon1([sequence_digest]);

let value_digest = BigInt(0);

let data_digest = PolynomialDigest(input, mock_ct_digest, BigInt(0));

let state = Array(MAX_STACK_HEIGHT * 4 + 4).fill(0);
let state_digest = PolynomialDigest(state, mock_ct_digest, BigInt(0));

let step_in = [data_digest, 0, 0, 0, 0, 0, 0, 1, state_digest, sequence_digest_hashed, 0];

let json_extraction_step_out = await hash_parser.compute({
data: input_padded,
ciphertext_digest: mock_ct_digest,
sequence_digest,
value_digest,
step_in,
state,
}, ["step_out"]);
assert.deepEqual((json_extraction_step_out.step_out as BigInt[])[0], value_digest);
assert.deepEqual((json_extraction_step_out.step_out as BigInt[])[7], modPow(mock_ct_digest, BigInt(input.length)));
assert.deepEqual((json_extraction_step_out.step_out as BigInt[])[9], sequence_digest_hashed);
console.log("> First subtest passed.");

// Test `[]` in "arr" key
keySequence = [
{ type: "Object", value: strToBytes("arr") },
];
[stack, treeHashes] = jsonTreeHasher(mock_ct_digest, keySequence, MAX_STACK_HEIGHT);
sequence_digest = compressTreeHash(mock_ct_digest, [stack, treeHashes]);
sequence_digest_hashed = poseidon1([sequence_digest]);
value_digest = BigInt(0);
step_in = [data_digest, 0, 0, 0, 0, 0, 0, 1, state_digest, sequence_digest_hashed, 0];;

json_extraction_step_out = await hash_parser.compute({
data: input_padded,
ciphertext_digest: mock_ct_digest,
sequence_digest,
value_digest,
step_in,
state,
}, ["step_out"]);
assert.deepEqual((json_extraction_step_out.step_out as BigInt[])[0], value_digest);
assert.deepEqual((json_extraction_step_out.step_out as BigInt[])[7], modPow(mock_ct_digest, BigInt(input.length)));
assert.deepEqual((json_extraction_step_out.step_out as BigInt[])[9], sequence_digest_hashed);
console.log("> Second subtest passed.");
});

it(`input: spotify`, async () => {
let filename = "spotify";
let [input, _keyUnicode, _output] = readJSONInputFile(`${filename}.json`, []);
Expand Down
1 change: 1 addition & 0 deletions examples/json/empty.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"object":{},"arr":[]}
6 changes: 5 additions & 1 deletion witness-generator/src/json/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,10 @@ pub fn parse<const MAX_STACK_HEIGHT: usize>(
)),
},
END_BRACE => match (machine.clone().status, machine.current_location()) {
(Status::None | Status::ParsingPrimitive(_), Location::ObjectValue) => {
(
Status::None | Status::ParsingPrimitive(_),
Location::ObjectKey | Location::ObjectValue,
) => {
machine.location[machine.pointer() - 1] = Location::None;
machine.status = Status::None;
machine.clear_label_stack();
Expand Down Expand Up @@ -387,6 +390,7 @@ mod tests {
r#"{"null": null, "false": false, "true": true, "num1": 2.0E-1, "num2": 2.0e+1}"#
)]
#[case::primitives_array(r#"[null,false,true,2.0E-1,2.0e+1]"#)]
#[case::empty(r#"{"object":{},"arr":[]}"#)]
fn test_json_parser_valid(#[case] input: &str) {
let polynomial_input = create_polynomial_input();

Expand Down

0 comments on commit 10c8fd4

Please sign in to comment.