Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: value extractor #37

Merged
merged 134 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from 123 commits
Commits
Show all changes
134 commits
Select commit Hold shift + click to select a range
d2be624
add: `reddit_response.json`
Autoparallel Aug 7, 2024
6d4b7c3
refactor tests + add failing case
Autoparallel Aug 8, 2024
afcacda
easier fix
Autoparallel Aug 8, 2024
99e0e5c
test: parse to key
Autoparallel Aug 8, 2024
3a20a47
tests: key parsing
Autoparallel Aug 8, 2024
98a3b51
bug: `next_end_of_kv` on read `:`
Autoparallel Aug 8, 2024
44bcc18
fix: `end_of_kv` bug
Autoparallel Aug 8, 2024
fb0fb34
test: find value
Autoparallel Aug 8, 2024
0f82ab0
tests: `inside_value` and `inside_value_to_exit`
Autoparallel Aug 8, 2024
0b166ea
test: parse to NEXT key
Autoparallel Aug 8, 2024
fc81c78
parses JSON with two string keys
Autoparallel Aug 8, 2024
f1ebb51
WIP: value inside value
Autoparallel Aug 8, 2024
07fd671
comment
Autoparallel Aug 8, 2024
a62dd35
refactor (#10)
Autoparallel Aug 8, 2024
63a00d5
feat: 2 key depth 1 json
Autoparallel Aug 8, 2024
9528248
2 kv json and all tests passing
Autoparallel Aug 9, 2024
86bb82d
nested json works!!!
Autoparallel Aug 9, 2024
4142ab0
reduce constraints
Autoparallel Aug 9, 2024
1d425e5
cleanup
Autoparallel Aug 9, 2024
ec6ec0e
rename variables
Autoparallel Aug 9, 2024
ba8888f
more cleaning
Autoparallel Aug 9, 2024
887786a
more cleanup
Autoparallel Aug 9, 2024
621e130
make comments clean
Autoparallel Aug 9, 2024
18c68d8
WAYLON NITPICKING ME LOL
Autoparallel Aug 9, 2024
52fa826
feat: improved CLI for witness
Autoparallel Aug 9, 2024
331f218
gitignore input.json
Autoparallel Aug 9, 2024
7eef73e
Update main.rs
Autoparallel Aug 9, 2024
ca148b5
feat: update rust
Autoparallel Aug 9, 2024
c95b72f
feat: parse with array as value
Autoparallel Aug 9, 2024
5998757
feat; `InRange` template
Autoparallel Aug 9, 2024
e9d8b17
WIP: number parsing
Autoparallel Aug 9, 2024
b8923e7
good stopping point
Autoparallel Aug 10, 2024
c673c1b
compiling again
Autoparallel Aug 10, 2024
5432b17
stack hard
Autoparallel Aug 10, 2024
0e04f42
save progress
Autoparallel Aug 10, 2024
ded3c36
save wip
Autoparallel Aug 10, 2024
a11efb8
getting through tests
Autoparallel Aug 10, 2024
536b661
add optimised
lonerapier Aug 7, 2024
7329f38
resolve random input bug using poseidon hash
lonerapier Aug 8, 2024
4d4f02a
import circomlib and remove circuits
lonerapier Aug 11, 2024
ea1ebf7
add array and hash circuits
lonerapier Aug 11, 2024
c7425eb
add search
lonerapier Aug 11, 2024
8c7f55c
add js poseidon
lonerapier Aug 11, 2024
5b028c5
update tests
lonerapier Aug 11, 2024
fbf32c6
add search tests
lonerapier Aug 11, 2024
ce1bde9
wip: stack
Autoparallel Aug 11, 2024
1e4979d
big ints killing me
Autoparallel Aug 11, 2024
226d691
use strings for tests
Autoparallel Aug 11, 2024
8126615
reduce and fix some tests!
Autoparallel Aug 11, 2024
577152f
refactor tests
lonerapier Aug 12, 2024
a2e0c9a
reduce and fix some tests!
Autoparallel Aug 11, 2024
0652140
moar tests
Autoparallel Aug 12, 2024
982bb6c
Merge branch 'feat/stack-machine' of https://github.com/pluto/extract…
Autoparallel Aug 12, 2024
e2fb192
cosmetics
Autoparallel Aug 12, 2024
40f88c5
continuing with tests
Autoparallel Aug 12, 2024
d08ff4c
save state
Autoparallel Aug 12, 2024
ad2e643
renumbered stack entries
Autoparallel Aug 12, 2024
0884909
wip: handle end of arr/obj
Autoparallel Aug 12, 2024
780e8c2
maybe progress
Autoparallel Aug 12, 2024
f1c674c
save
Autoparallel Aug 12, 2024
cb7fa98
almost!
Autoparallel Aug 12, 2024
59fdcf1
tests passing
Autoparallel Aug 12, 2024
c1ac3ea
cleaning
Autoparallel Aug 12, 2024
b862535
wip: big example
Autoparallel Aug 12, 2024
2b283a8
bug: fails to parse example.json
Autoparallel Aug 12, 2024
762992c
add basic switch template again
Autoparallel Aug 12, 2024
d544d5c
feat: `GetTopOfStack`
Autoparallel Aug 12, 2024
3f38c79
IT"S LIVING
Autoparallel Aug 13, 2024
449ac72
refactor: use `circomlib` directly
Autoparallel Aug 13, 2024
f4fc944
refactor: JSONs
Autoparallel Aug 13, 2024
e4e256b
redo all in `circuits.json`
Autoparallel Aug 13, 2024
ccb86bf
changeable stack height
Autoparallel Aug 13, 2024
43d0a14
save state
Autoparallel Aug 13, 2024
304987f
reorganize tests
Autoparallel Aug 13, 2024
9e4426c
small cleanup
Autoparallel Aug 13, 2024
70688ba
continuing test cleanup
Autoparallel Aug 13, 2024
dbf5c8f
remove antiquated tests
Autoparallel Aug 13, 2024
38683a3
cleanup
Autoparallel Aug 13, 2024
049d45b
refactor: `language.circom`
Autoparallel Aug 13, 2024
e553e04
todo note
Autoparallel Aug 13, 2024
83ad3a1
Merge branch 'feat/substring-matching' into temp-fetcher
lonerapier Aug 14, 2024
a79fd4e
good save state
Autoparallel Aug 14, 2024
6f5a203
good state!
Autoparallel Aug 14, 2024
37c28bf
Update notes.md
Autoparallel Aug 14, 2024
558ba96
2d stack
Autoparallel Aug 14, 2024
e0f8893
basic array tracking
Autoparallel Aug 14, 2024
33fbe23
tests passing
Autoparallel Aug 14, 2024
7a30f8a
small cleanup
Autoparallel Aug 14, 2024
caa4941
almost there!
Autoparallel Aug 14, 2024
17f1105
arrays!
Autoparallel Aug 14, 2024
7294dd5
satisfying!
Autoparallel Aug 14, 2024
2270ac9
another example
Autoparallel Aug 14, 2024
267e913
Update notes.md
Autoparallel Aug 14, 2024
d83e3ab
Merge branch 'feat/stack-machine' into temp-fetcher
lonerapier Aug 15, 2024
ea18b67
save notes
Autoparallel Aug 15, 2024
e84b196
Squashed commit of the following:
Autoparallel Aug 15, 2024
d5c06e1
WIP: remove `pointer` state
Autoparallel Aug 15, 2024
9b94cd9
WIP: cleaning further
Autoparallel Aug 16, 2024
a34f328
WIP: reduced many variables
Autoparallel Aug 16, 2024
afff6a8
all tests pass
Autoparallel Aug 16, 2024
b7bbc74
updated circuits
Autoparallel Aug 16, 2024
6d10e1b
formatting
Autoparallel Aug 16, 2024
c3e8ef3
Merge branch 'feat/stack-machine' into temp-fetcher
lonerapier Aug 16, 2024
c42e2bb
add zkemail
lonerapier Aug 17, 2024
be08e0d
extracting string yayyy!!!!!
lonerapier Aug 17, 2024
cbb657c
add tests for string extractor
lonerapier Aug 17, 2024
631ea57
parse numbers
lonerapier Aug 18, 2024
ea91ba7
convert unicode number array to number
lonerapier Aug 18, 2024
ebba402
extracting array index
lonerapier Aug 20, 2024
8875441
yay!! multi-depth key extraction done. onto more nested structures noww
lonerapier Aug 21, 2024
62a4dfd
extract nested array working
lonerapier Aug 21, 2024
e67e8dc
add nested structure example circuit
lonerapier Aug 21, 2024
e5f68a8
Merge branch 'main' into temp-fetcher
lonerapier Aug 23, 2024
bfcd828
delete utils
lonerapier Aug 23, 2024
ab1b567
move input generation to separate binary
lonerapier Aug 27, 2024
bdc226e
initial codegen
lonerapier Aug 27, 2024
01c2a79
fix: correct hardcoded signals
lonerapier Aug 27, 2024
fa63840
add codegen example
lonerapier Aug 28, 2024
0a4dd57
remove old code and rename to interpreter
lonerapier Aug 28, 2024
5598c2c
codegen changes
lonerapier Aug 28, 2024
7743775
add test files
lonerapier Aug 28, 2024
2e430dc
feat(codegen): add output filename
lonerapier Aug 28, 2024
c84e46a
complete tests
lonerapier Aug 28, 2024
6ea32ce
Merge branch 'main' into temp-fetcher
lonerapier Aug 28, 2024
34a2b6c
chore(tests): remove duplicate
lonerapier Aug 28, 2024
614d184
chore(docs): interpreter
lonerapier Aug 28, 2024
4aff062
tests: add interpreter
lonerapier Aug 28, 2024
f7a49ce
fix(test): add tests failing in parallel
lonerapier Aug 28, 2024
f2b5a4d
fix(codegen): add poseidon hasher
lonerapier Aug 28, 2024
1dbf8d4
Merge branch 'main' into temp-fetcher
lonerapier Aug 28, 2024
26031e3
refactor: code reorganisation
lonerapier Aug 28, 2024
20ef2b4
experiment with mocha parallel tests
lonerapier Aug 28, 2024
8c3e624
review nits
lonerapier Aug 28, 2024
b8f1e30
handle conflicting files
lonerapier Aug 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
196 changes: 196 additions & 0 deletions circuits/interpreter.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
pragma circom 2.1.9;

include "extract.circom";
include "parser.circom";
include "language.circom";
include "search.circom";
include "./utils/array.circom";
include "circomlib/circuits/mux1.circom";
include "circomlib/circuits/gates.circom";
include "@zk-email/circuits/utils/functions.circom";
include "@zk-email/circuits/utils/array.circom";

// TODOs:
// - remove use of random_signal in key match from 100
//

template InsideKey(n) {
signal input stack[n][2];
signal input parsing_string;
signal input parsing_number;

signal output out;

component topOfStack = GetTopOfStack(n);
topOfStack.stack <== stack;
signal currentVal[2] <== topOfStack.value;

signal parsingStringOrNumber <== parsing_string + parsing_number;
signal ifParsingKey <== currentVal[0] * (1-currentVal[1]);

out <== ifParsingKey * parsingStringOrNumber;
}

template InsideValue(n) {
signal input stack[n][2];
signal input parsing_string;
signal input parsing_number;

signal output out;

component topOfStack = GetTopOfStack(n);
topOfStack.stack <== stack;
signal current_val[2] <== topOfStack.value;

signal parsing_string_or_number <== parsing_string + parsing_number;
signal if_parsing_value <== current_val[0] * current_val[1];

out <== if_parsing_value * parsing_string_or_number;
}

template InsideObjectAtDepth(n, depth) {
signal input stack[n][2];
signal input parsing_string;
signal input parsing_number;

signal output out;

signal if_parsing_value <== stack[depth][0] * stack[depth][1];

out <== if_parsing_value * (parsing_string + parsing_number);
}

template InsideArrayIndex(n, index) {
signal input stack[n][2];
signal input parsing_string;
signal input parsing_number;

signal output out;

component topOfStack = GetTopOfStack(n);
topOfStack.stack <== stack;
signal current_val[2] <== topOfStack.value;

signal inside_array <== IsEqual()([current_val[0], 2]);
signal inside_index <== IsEqual()([current_val[1], index]);
signal inside_array_index <== inside_array * inside_index;
out <== inside_array_index * (parsing_string + parsing_number);
}

template InsideArrayIndexAtDepth(n, index, depth) {
signal input stack[n][2];
signal input parsing_string;
signal input parsing_number;

signal output out;

signal inside_array <== IsEqual()([stack[depth][0], 2]);
signal inside_index <== IsEqual()([stack[depth][1], index]);
signal inside_array_index <== inside_array * inside_index;
out <== inside_array_index * (parsing_string + parsing_number);
}

template NextKVPair(n) {
signal input stack[n][2];
signal input currByte;
signal output out;

component topOfStack = GetTopOfStack(n);
topOfStack.stack <== stack;
signal currentVal[2] <== topOfStack.value;

signal isNextPair <== IsEqualArray(2)([currentVal, [1, 0]]);
signal isComma <== IsEqual()([currByte, 44]); // `, -> 44`
Autoparallel marked this conversation as resolved.
Show resolved Hide resolved

out <== isNextPair*isComma ;
}

/// Checks current byte is at depth greater than specified `depth`
/// and returns whether next key-value pair starts.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bit confused about this comment

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, let me add more details

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added more details in comment

///
/// # Arguments
/// - `n`: maximum stack depth
/// - `depth`: depth of matched key-value pair
///
/// # Inputs
/// - `stack`: current stack state
/// - `curr_byte`: current parsed byte
///
/// # Output
/// - `out`: Returns `1` for next key-value pair at specified depth.
template NextKVPairAtDepth(n, depth) {
signal input stack[n][2];
signal input currByte;
signal output out;

var logMaxDepth = log2Ceil(n);

component topOfStack = GetTopOfStack(n);
topOfStack.stack <== stack;
signal current_val[2] <== topOfStack.value;
signal pointer <== topOfStack.pointer;

signal isNextPair <== IsEqualArray(2)([current_val, [1, 0]]);
// log("isNextPair", current_val[0], current_val[1], isNextPair);
signal isComma <== IsEqual()([currByte, 44]); // `, -> 44`
// log("isComma", isComma, currByte);
// pointer <= depth
signal atLessDepth <== LessEqThan(logMaxDepth)([pointer, depth]);
// log("atLessDepth:", pointer, depth, atLessDepth);
// current depth is less than key depth
signal isCommaAtDepthLessThanCurrent <== isComma * atLessDepth;

out <== isNextPair * isCommaAtDepthLessThanCurrent;
}

template KeyMatch(dataLen, keyLen) {
signal input data[dataLen];
signal input key[keyLen];
signal input r;
signal input index;
signal input parsing_key;

signal end_of_key <== IndexSelector(dataLen)(data, index + keyLen);
signal is_end_of_key_equal_to_quote <== IsEqual()([end_of_key, 34]);

signal start_of_key <== IndexSelector(dataLen)(data, index - 1);
signal is_start_of_key_equal_to_quote <== IsEqual()([start_of_key, 34]);

signal substring_match <== SubstringMatchWithIndex(dataLen, keyLen)(data, key, 100, index);

signal is_key_between_quotes <== is_start_of_key_equal_to_quote * is_end_of_key_equal_to_quote;
signal is_parsing_correct_key <== is_key_between_quotes * parsing_key;
// log("key match", index, end_of_key, is_end_of_key_equal_to_quote, substring_match);

signal output out <== substring_match * is_parsing_correct_key;
}

template KeyMatchAtDepth(dataLen, n, keyLen, depth) {
signal input data[dataLen];
signal input key[keyLen];
signal input r;
signal input index;
signal input parsing_key;
signal input stack[n][2];

component topOfStack = GetTopOfStack(n);
topOfStack.stack <== stack;
signal pointer <== topOfStack.pointer;

signal end_of_key <== IndexSelector(dataLen)(data, index + keyLen);
signal is_end_of_key_equal_to_quote <== IsEqual()([end_of_key, 34]);

signal start_of_key <== IndexSelector(dataLen)(data, index - 1);
signal is_start_of_key_equal_to_quote <== IsEqual()([start_of_key, 34]);

signal substring_match <== SubstringMatchWithIndex(dataLen, keyLen)(data, key, 100, index);

signal is_key_between_quotes <== is_start_of_key_equal_to_quote * is_end_of_key_equal_to_quote;
// log("key pointer", pointer, depth);
signal is_parsing_correct_key <== is_key_between_quotes * parsing_key;
signal is_key_at_depth <== IsEqual()([pointer-1, depth]);
signal is_parsing_correct_key_at_depth <== is_parsing_correct_key * is_key_at_depth;
// log("key match", index, end_of_key, is_end_of_key_equal_to_quote, substring_match);

signal output out <== substring_match * is_parsing_correct_key_at_depth;
}
2 changes: 1 addition & 1 deletion circuits/language.circom
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ template Command() {
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 ]; // 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 END_BRACKET[3] <== [-2, 0, -1 ]; // Command returned by switch if we hit a start bracket `]`
Autoparallel marked this conversation as resolved.
Show resolved Hide resolved
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 `,`
Expand Down
7 changes: 5 additions & 2 deletions circuits/search.circom
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ template SubstringMatchWithIndex(dataLen, keyLen) {
signal input r;
signal input start;

signal output out;

// key end index in `data`
signal end;
end <== start + keyLen;
Expand Down Expand Up @@ -198,7 +200,7 @@ template SubstringMatchWithIndex(dataLen, keyLen) {
}

// final sum for data and key should be equal
hashMaskedData[dataLen - 1] === hashMaskedKey[keyLen - 1];
out <== IsZero()(hashMaskedData[dataLen-1]-hashMaskedKey[keyLen-1]);
}

/*
Expand Down Expand Up @@ -236,7 +238,8 @@ template SubstringMatch(dataLen, keyLen) {

// matches a `key` in `data` at `pos`
// NOTE: constrained verification assures correctness
SubstringMatchWithIndex(dataLen, keyLen)(data, key, r, start);
signal isMatch <== SubstringMatchWithIndex(dataLen, keyLen)(data, key, r, start);
isMatch === 1;

position <== start;
}
30 changes: 30 additions & 0 deletions circuits/test/array.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { circomkit, WitnessTester } from "./common";

describe("array", () => {
describe("Slice", () => {
let circuit: WitnessTester<["in"], ["out"]>;
before(async () => {
circuit = await circomkit.WitnessTester(`Slice`, {
file: "circuits/utils/array",
template: "Slice",
params: [10, 2, 4],
});
console.log("#constraints:", await circuit.getConstraintCount());
});

it("witness: [random*10], start: 2, end: 4", async () => {
const input = Array.from({ length: 10 }, () => Math.floor(Math.random() * 256));
await circuit.expectPass(
{ in: input },
{ out: input.slice(2, 4) }
);
});

it("witness: [random*9], start: 2, end: 4", async () => {
const input = Array.from({ length: 9 }, () => Math.floor(Math.random() * 256));
await circuit.expectFail(
{ in: input },
);
});
});
});
Loading
Loading