Skip to content

Commit

Permalink
Merge branch 'main' into temp-fetcher
Browse files Browse the repository at this point in the history
  • Loading branch information
lonerapier committed Aug 23, 2024
2 parents e67e8dc + 71b4470 commit e5f68a8
Show file tree
Hide file tree
Showing 22 changed files with 1,244 additions and 190 deletions.
2 changes: 1 addition & 1 deletion circuits/extract.circom
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pragma circom 2.1.9;

include "utils.circom";
include "./utils/bytes.circom";
include "parser.circom";

template Extract(DATA_BYTES, MAX_STACK_HEIGHT) {
Expand Down
7 changes: 3 additions & 4 deletions circuits/language.circom
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,11 @@ template Syntax() {

template Command() {
// STATE = [read_write_value, parsing_string, parsing_number]
signal output NOTHING[3] <== [0, 0, -1 ]; // Command returned by switch if we want to do nothing, e.g. read a whitespace char while looking for a key
signal output START_BRACE[3] <== [1, 0, 0 ]; // Command returned by switch if we hit a start brace `{`
signal output END_BRACE[3] <== [-1, 0, -1 ]; // Command returned by switch if we hit a end brace `}`
signal output START_BRACKET[3] <== [2, 0, 0 ]; // TODO: Might want `in_value` to toggle. Command returned by switch if we hit a start bracket `[` (TODO: could likely be combined with end bracket)
signal output END_BRACKET[3] <== [-2, 0, -1 ]; // Command returned by switch if we hit a start bracket `]`
signal output QUOTE[3] <== [0, 1, 0 ]; // TODO: Mightn ot want this to toglle `parsing_array`. Command returned by switch if we hit a quote `"`
signal output START_BRACKET[3] <== [2, 0, 0 ]; // Command returned by switch if we hit a start bracket `[`
signal output END_BRACKET[3] <== [-2, 0, -1 ]; // Command returned by switch if we hit a start bracket `]`
signal output QUOTE[3] <== [0, 1, 0 ]; // Command returned by switch if we hit a quote `"`
signal output COLON[3] <== [3, 0, 0 ]; // Command returned by switch if we hit a colon `:`
signal output COMMA[3] <== [4, 0, -1 ]; // Command returned by switch if we hit a comma `,`
signal output NUMBER[3] <== [256, 0, 1 ]; // Command returned by switch if we hit some decimal number (e.g., ASCII 48-57)
Expand Down
355 changes: 228 additions & 127 deletions circuits/parser.circom

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions circuits/search.circom
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
pragma circom 2.1.9;
pragma circom 2.1.9;

include "circomlib/circuits/mux1.circom";
include "./utils/hash.circom";
include "utils.circom";
include "./utils/operators.circom";
include "./utils/array.circom";

/*
SubstringSearch
Expand Down
108 changes: 78 additions & 30 deletions circuits/test/parser/values.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,43 +22,91 @@ describe("StateUpdate :: Values", () => {
});
}

//-TEST_1----------------------------------------------------------//
// idea: Read a number value after a key in an object.
// state: stack == [[1, 1], [0, 0], [0, 0], [0, 0]]
// read: `0`
// expect: stack --> [[1, 1], [0, 0], [0, 0], [0, 0]]
// parsing_number --> 1
let read_number = { ...INITIAL_IN };
read_number.stack = [[1, 1], [0, 0], [0, 0], [0, 0]];
read_number.byte = Numbers.ZERO;
let read_number_out = { ...INITIAL_OUT };
read_number_out.next_stack = [[1, 1], [0, 0], [0, 0], [0, 0]];
read_number_out.next_parsing_number = 1;
generatePassCase(read_number, read_number_out, ">>>> `0` read");
describe("StateUpdate :: Values :: Number", () => {
//-TEST_1----------------------------------------------------------//
// idea: Read a number value after a key in an object.
// state: stack == [[1, 1], [0, 0], [0, 0], [0, 0]]
// read: `0`
// expect: stack --> [[1, 1], [0, 0], [0, 0], [0, 0]]
// parsing_number --> 1
let read_number = { ...INITIAL_IN };
read_number.stack = [[1, 1], [0, 0], [0, 0], [0, 0]];
read_number.byte = Numbers.ZERO;
let read_number_out = { ...INITIAL_OUT };
read_number_out.next_stack = [[1, 1], [0, 0], [0, 0], [0, 0]];
read_number_out.next_parsing_number = 1;
generatePassCase(read_number, read_number_out, ">>>> `0` read");

// // TODO: Note that reading a space while reading a number will not throw an error!
// // TODO: Note that reading a space while reading a number will not throw an error!

//-TEST_2----------------------------------------------------------//
// idea: Inside a number value after a key in an object.
// state: pointer == 2, stack == [1,3,0,0], parsing_number == 1
// read: `1`
// expect: pointer --> 2
// stack --> [1,3,0,0]
// parsing_number --> 0
let inside_number_continue = { ...INITIAL_IN };
inside_number_continue.stack = [[1, 1], [0, 0], [0, 0], [0, 0]];
inside_number_continue.parsing_number = 1;
inside_number_continue.byte = Numbers.ONE;
let inside_number_continue_out = { ...INITIAL_OUT };
inside_number_continue_out.next_stack = [[1, 1], [0, 0], [0, 0], [0, 0]];
inside_number_continue_out.next_parsing_number = 1;
generatePassCase(inside_number_continue, inside_number_continue_out, ">>>> `1` read");
//-TEST_2----------------------------------------------------------//
// idea: Inside a number value after a key in an object.
// state: stack == [[1, 1], [0, 0], [0, 0], [0, 0]], parsing_number == 1
// read: `1`
// expect: stack --> [[1, 1], [0, 0], [0, 0], [0, 0]]
// parsing_number --> 0
let inside_number_continue = { ...INITIAL_IN };
inside_number_continue.stack = [[1, 1], [0, 0], [0, 0], [0, 0]];
inside_number_continue.parsing_number = 1;
inside_number_continue.byte = Numbers.ONE;
let inside_number_continue_out = { ...INITIAL_OUT };
inside_number_continue_out.next_stack = [[1, 1], [0, 0], [0, 0], [0, 0]];
inside_number_continue_out.next_parsing_number = 1;
generatePassCase(inside_number_continue, inside_number_continue_out, ">>>> `1` read");

//-TEST_2----------------------------------------------------------//
// idea: Inside a number value after a key in an object.
// state: stack == [[1, 1], [0, 0], [0, 0], [0, 0]], parsing_number == 1
// read: `1`
// expect: stack --> [[1, 1], [0, 0], [0, 0], [0, 0]]
// parsing_number --> 0
let inside_number_exit = { ...INITIAL_IN };
inside_number_exit.stack = [[1, 1], [0, 0], [0, 0], [0, 0]];
inside_number_exit.parsing_number = 1;
inside_number_exit.byte = WhiteSpace.SPACE;
let inside_number_exit_out = { ...INITIAL_OUT };
inside_number_exit_out.next_stack = [[1, 1], [0, 0], [0, 0], [0, 0]];
inside_number_exit_out.next_parsing_number = 0;
generatePassCase(inside_number_exit, inside_number_exit_out, ">>>> ` ` read");

//-TEST_3----------------------------------------------------------//
// idea: Inside a number value after a key in an object.
// state: stack == [[1, 1], [0, 0], [0, 0], [0, 0]], parsing_number == 1
// read: `$`
// expect: stack --> [[1, 1], [0, 0], [0, 0], [0, 0]]
// parsing_number --> 0
let inside_number_exit2 = { ...INITIAL_IN };
inside_number_exit2.stack = [[1, 1], [0, 0], [0, 0], [0, 0]];
inside_number_exit2.parsing_number = 1;
inside_number_exit2.byte = 36; // Dollar sign `$`
let inside_number_exit2_out = { ...INITIAL_OUT };
inside_number_exit2_out.next_stack = [[1, 1], [0, 0], [0, 0], [0, 0]];
inside_number_exit2_out.next_parsing_number = 0;
generatePassCase(inside_number_exit2, inside_number_exit2_out, ">>>> `$` read");
});

describe("StateUpdate :: Values :: String", () => {
//-TEST_4----------------------------------------------------------//
// idea: Inside a string key inside an object
// state: stack == [[1, 0], [0, 0], [0, 0], [0, 0]], parsing_string == 1
// read: `,`
// expect: stack --> [[1, 0], [0, 0], [0, 0], [0, 0]]
// parsing_string --> 0
let inside_number = { ...INITIAL_IN };
inside_number.stack = [[1, 1], [0, 0], [0, 0], [0, 0]];
inside_number.parsing_string = 1;
inside_number.byte = Delimiters.COMMA;
let inside_number_out = { ...INITIAL_OUT };
inside_number_out.next_stack = [[1, 0], [0, 0], [0, 0], [0, 0]];
inside_number_out.next_parsing_string = 1;
generatePassCase(inside_number, inside_number_out, ">>>> `,` read");
});

describe("StateUpdate :: Values :: Array", () => {
// Internal array parsing -----------------------------------------//

//-TEST_10----------------------------------------------------------//
// init: stack == [[1, 0], [2, 0], [0, 0], [0, 0]]
// init: stack == [[1, 0], [2, 0], [0, 0], [0, 0]]
// read: `,`
// expext: stack --> [[1, 0], [2, 1], [0, 0], [0, 0]]
let in_arr = { ...INITIAL_IN };
Expand Down
21 changes: 15 additions & 6 deletions circuits/test/search.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ describe("search", () => {
);
});

it("wrong random_num input, correct key position: 2", async () => {
/// highlights the importance of appropriate calculation of random number for linear matching.
/// `1` as used here leads to passing constraints because [1, 0] matches with [0, 1]
/// because both have equal linear combination sum.
it("(INVALID `r=1` value) random_num input passes for different position, correct key position: 2", async () => {
const data = [0, 0, 1, 0, 0];
const key = [1, 0];

Expand All @@ -59,7 +62,7 @@ describe("search", () => {
);
});

it("data = inputs.json:data, key = inputs.json:key, r = hash(data+key)", async () => {
it("data = witness.json:data, key = witness.json:key, r = hash(data+key)", async () => {
const concatenatedInput = witness["key"].concat(witness["data"]);
const hashResult = PoseidonModular(concatenatedInput);

Expand Down Expand Up @@ -89,7 +92,7 @@ describe("search", () => {
console.log("#constraints:", await circuit.getConstraintCount());
});

it("data = inputs.json:data, key = inputs.json:key, r = hash(data+key)", async () => {
it("data = witness.json:data, key = witness.json:key, r = hash(key+data)", async () => {
await circuit.expectPass(
{
data: witness["data"],
Expand All @@ -100,7 +103,7 @@ describe("search", () => {
);
});

it("data = inputs.json:data, key = inputs.json:key, r = hash(data+key), incorrect position", async () => {
it("data = witness.json:data, key = witness.json:key, r = hash(key+data), incorrect position", async () => {
await circuit.expectFail(
{
data: witness["data"],
Expand All @@ -124,17 +127,23 @@ describe("search", () => {
console.log("#constraints:", await circuit.getConstraintCount());
});

it("data = inputs.json:data, key = inputs.json:key", async () => {
it("data = witness.json:data, key = witness.json:key", async () => {
await circuit.expectPass(
{ data: witness["data"], key: witness["key"] },
{ position: 6 },
);
});

it("data = inputs.json:data, key = wrong key", async () => {
it("data = witness.json:data, key = invalid key byte", async () => {
await circuit.expectFail(
{ data: witness["data"], key: witness["key"].concat(257) },
);
});

it("data = witness.json:data, key = wrong key", async () => {
await circuit.expectFail(
{ data: witness["data"], key: witness["key"].concat(0) },
);
});
});
});
Loading

0 comments on commit e5f68a8

Please sign in to comment.