diff --git a/Cargo.lock b/Cargo.lock index f7d2691..06d63c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -121,6 +121,15 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "pabuild" +version = "0.0.0" +dependencies = [ + "clap", + "serde", + "serde_json", +] + [[package]] name = "proc-macro2" version = "1.0.86" @@ -278,12 +287,3 @@ name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "wpbuild" -version = "0.0.0" -dependencies = [ - "clap", - "serde", - "serde_json", -] diff --git a/Cargo.toml b/Cargo.toml index dbfe087..d252b64 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "wpbuild" +name = "pabuild" edition = "2021" [dependencies] diff --git a/README.md b/README.md index 6b88400..20ccb22 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- SPARK + Parser Attestor

@@ -16,67 +16,118 @@ ## Overview -SPARK (Succinct Parser Attestation for Reconciliation of Knowledge) is a project focused on implementing parsers and extractors for various data formats using zero-knowledge proofs. +`parser-attestor` is a project focused on implementing parsers and extractors/selective-disclosure for various data formats inside of zero-knowledge circuits. ## Repository Structure -- `src/bin`: Binaries - - `witness`: Used for witness generation - - `codegen`: Used for generating extractor circuits based on input - `circuits/`: Current implementation of circuits - `http`: HTTP parser and extractor - `json`: JSON parser and extractor + - `json` has its own documentation [here](docs/json.md) - `utils`: Utility circuits - `test`: Circuit tests +- `src/`: Rust `pabuild` binary + - `pabuild` has its own documentation [here](docs/pabuild.md) - `examples/`: Reference examples for JSON and HTTP parsers +Documentation, in general, can be found in the `docs` directory. +We will add to this over time to make working with `parser-attestor` easier. + ## Getting Started ### Prerequisites -To use this repo, you need to install the following: +To use this repo, you will need to install the following dependencies. +These instructions should work on Linux/GNU and MacOS, but aren't guaranteed to work on Windows. -1. `circom` and `snarkjs`: - ```sh - git clone https://github.com/iden3/circom.git - cd circom - cargo build --release - cargo install --path circom - npm install -g snarkjs +#### Install Rust +To install Rust, you need to run: +```sh +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +exec $SHELL +``` +Check this is installed by running: +```sh +rustc --version && cargo --version +``` +to see the path to your Rust compiler and Cargo package manager. -### Circomkit -You will need `yarn` on your system (brew, or apt-get or something). -Then run: `npm install` to get everything else. +#### Install Circom +Succinctly, `cd` to a directory of your choosing and run: +```sh +git clone https://github.com/iden3/circom.git +cd circom +cargo build --release +cargo install --path circom +``` +in order to install `circom` globally. -#### Commands -To see what you can do, I suggest running: +#### Install Node +First, install `nvm` by running: +```sh +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash +exec $SHELL ``` -npx circomkit help +Now with `nvm` installed, run: +```sh +nvm install --lts +nvm use --lts +node --version && npm --version ``` -from the repository root. -#### Compiling and Witnessgen -For example, to compile the extractor, you can: +#### Node packages +From the root of the repository, you can now run: +```sh +npm install ``` -npx circomkit compile extract +which will install all the necessary packages for working with Circom. +This includes executables `circomkit`, `snarkjs`, and `mocha` which are accessible with Node: `npx`. + +##### Circomkit +This repository uses `circomkit` to manage Circom circuits. +To see what you can do with `circomkit`, we suggest running: ``` -Then you can do +npx circomkit help ``` -npx circomkit witness extract witness +`circomkit` can essentially do everything you would want to do with these Circuits, though we can't guarantee all commands work properly. + +**Example:** +For example, to compile the `json-parser`, you can run the following from the repository root: ``` -And even: +npx circomkit compile json-parser ``` -npx circomkit prove extract witness +which implicitly checks the `circuits.json` for an object that points to the circuit's code itself. + +If you are having trouble with `circomkit`, consider: + +##### SNARKJS +Likewise, `snarkjs` is used to handle proofs and verification under the hood. +There is [documentation](https://docs.circom.io/getting-started/compiling-circuits/) on Circom's usage to work with this. +We suggest starting at that link and carrying through to "Proving circuits with ZK". + +##### Mocha +`mocha` will also be installed from before. +Running +```sh +npx mocha ``` +will run every circuit test. +To filter tests, you can use the `-g` flag (very helpful!). -To clean up, just run: + +### Install `pabuild` +From the root of this repository, run: +```sh +cargo install --path . ``` -npx circomkit clean extract +to install the `wpbuild` binary. +You can see a help menu with the subcommands by: +```sh +wpbuild --help ``` +This is our local Rust command line application. +Please see the [documentation](docs/pabuild.md) for how to use this alongside the other tools. -All of the above should be ran from repository root. - -## Binaries ### Rust Example Witness JSON Creation To generate example input JSON files for the Circom circuits, run: @@ -101,111 +152,6 @@ witness http --input-file examples/http/get_request.http --output-dir inputs/get Afterwards, you can run `circomkit compile get_request` then `circomkit witness get_request input`. -### Codegen - -JSON extractor circuit is generated using rust to handle arbitrary keys and array indices. - -Run: -```bash -cargo run --bin codegen -- --help -``` -to get options: -``` -Usage: codegen [OPTIONS] --json-file - -Options: - -j, --json-file Path to the JSON file - -o, --output-filename Output circuit file name [default: extractor] -``` -Takes input 2 arguments: -- `json-file`: input json file. Examples are located in [codegen](./examples/json/test/codegen/) -- `output-filename`: circuit filename to save. Located in [circuits/main](./circuits/main/). If not given, defaults to `extractor.circom`. - -To test an end-to-end JSON extraction proof: -- Run codegen to generate circuits. Replace `value_string` with input filename. - ```bash - cargo run --bin codegen -- --json-file ./examples/json/test/codegen/value_string.json --output-filename value_string - ``` - -- Compile circom circuit using - ``` - circom ./circuits/main/value_string.circom --r1cs --wasm - ``` - -- To use circomkit: add circuit config to [circuits.json](./circuits.json). and input file to [inputs](./inputs/) - -- Generate witness: - ```bash - node build/json_extract_value_string/json_extract_value_string_js/generate_witness inputs/json_extract_value_string/value_string.json build/json_extract_value_string/witness/ - ``` - or generate using circomkit: - ```bash - npx circomkit witness json_extract_value_string value_string - ``` - -- create trusted setup: - ```bash - npx circomkit setup json_extract_value_string - # OR - snarkjs groth16 setup build/json_extract_value_string/json_extract_value_string.r1cs ptau/powersOfTau28_hez_final_14.ptau build/json_extract_value_string/groth16_pkey.zkey - ``` - -- create proof: - ```bash - npx circomkit prove json_extract_value_string value_string - # OR - snarkjs groth16 prove build/json_extract_value_string/groth16_pkey.zkey build/json_extract_value_string/value_string/witness.wtns build/json_extract_value_string/value_string/groth16_proof.json inputs/json_extract_value_string/value_string.json - ``` - -- verify proof: - ```bash - npx circomkit verify json_extract_value_string value_string - # OR - snarkjs groth16 verify build/json_extract_value_string/groth16_vkey.json inputs/json_extract_value_string/value_string.json build/json_extract_value_string/value_string/groth16_proof.json - ``` - -## Testing -To test, you can just run -``` -npx mocha -``` -from the repository root. - -To run specific tests, use the `-g` flag for `mocha`, e.g., to run any proof described with "State" we can pass: -``` -npx mocha -g State -``` - -> [!NOTE] -> Currently [search](./circuits/search.circom) circuit isn't working with circomkit, so you might have to compile using circom: `circom circuits/main/search.circom --r1cs --wasm -l node_modules/ -o build/search/` - -## (MOSTLY DEPRECATED DUE TO CIRCOMKIT) Running an example -``` -circom extract.circom --r1cs --wasm - -# in rust? circom witness rs -node extract_js/generate_witness.js extract_js/extract.wasm input.json witness.wtns - -## -# IF YOU NEED A NEW pot (works for all circuits) -snarkjs powersoftau new bn128 14 pot14_0000.ptau -v -snarkjs powersoftau contribute pot14_0000.ptau pot14_0001.ptau --name="First contribution" -v -snarkjs powersoftau prepare phase2 pot14_0001.ptau pot14_final.ptau -v -## - -snarkjs groth16 setup extract.r1cs pot14_final.ptau extract_0000.zkey - -snarkjs zkey contribute extract_0000.zkey extract_0001.zkey --name="1st Contributor Name" -v - -snarkjs zkey export verificationkey extractor_0001.zkey verification_key.json - -# in rust -snarkjs groth16 prove extractor_0001.zkey witness.wtns proof.json public.json - -# in rust -snarkjs groth16 verify verification_key.json public.json proof.json -``` - ## Contributing diff --git a/circuits.json b/circuits.json index 9139100..09f0948 100644 --- a/circuits.json +++ b/circuits.json @@ -1,5 +1,5 @@ { - "extract": { + "json-parser": { "file": "json/parser/parser", "template": "Parser", "params": [ @@ -7,93 +7,11 @@ 13 ] }, - "value_string": { - "file": "json/parser/parser", - "template": "Parser", - "params": [ - 12, - 1 - ] - }, - "value_number": { - "file": "json/parser/parser", - "template": "Parser", - "params": [ - 12, - 2 - ] - }, - "value_array": { - "file": "json/parser/parser", - "template": "Parser", - "params": [ - 18, - 2 - ] - }, - "value_array_nested": { - "file": "json/parser/parser", - "template": "Parser", - "params": [ - 24, - 4 - ] - }, - "value_array_object": { - "file": "json/parser/parser", - "template": "Parser", - "params": [ - 25, - 4 - ] - }, - "value_array_object_array": { - "file": "json/parser/parser", - "template": "Parser", - "params": [ - 31, - 5 - ] - }, - "value_object": { - "file": "json/parser/parser", - "template": "Parser", - "params": [ - 21, - 3 - ] - }, - "search": { - "file": "search", - "template": "SubstringMatch", - "params": [ - 787, - 10 - ] - }, - "get_request": { + "http-parser": { "file": "http/parser/parser", "template": "Parser", "params": [ 60 ] - }, - "get_response": { - "file": "http/parser/parser", - "template": "Parser", - "params": [ - 89 - ] - }, - "json_extract_value_string": { - "file": "main/value_string", - "template": "ExtractStringValue", - "params": [ - 12, - 1, - 1, - 0, - 1 - ] } } \ No newline at end of file diff --git a/circuits/test/http/codegen.test.ts b/circuits/test/http/codegen.test.ts index 1d08884..580f72e 100644 --- a/circuits/test/http/codegen.test.ts +++ b/circuits/test/http/codegen.test.ts @@ -89,7 +89,7 @@ describe("HTTP :: Codegen :: Request", async () => { circuit = await circomkit.WitnessTester(`Extract`, { - file: `circuits/main/${lockfile}`, + file: `main/${lockfile}`, template: "LockHTTPRequest", params: params, }); @@ -130,7 +130,7 @@ describe("HTTP :: Codegen :: Request", async () => { circuit = await circomkit.WitnessTester(`Extract`, { - file: `circuits/main/${lockfile}`, + file: `main/${lockfile}`, template: "LockHTTPRequest", params: params, }); @@ -179,7 +179,7 @@ describe("HTTP :: Codegen :: Response", async () => { circuit = await circomkit.WitnessTester(`Extract`, { - file: `circuits/main/${lockfile}`, + file: `main/${lockfile}`, template: "LockHTTPResponse", params: params, }); @@ -224,7 +224,7 @@ describe("HTTP :: Codegen :: Response", async () => { circuit = await circomkit.WitnessTester(`Extract`, { - file: `circuits/main/${lockfile}`, + file: `main/${lockfile}`, template: "LockHTTPResponse", params: params, }); diff --git a/circuits/test/http/extractor.test.ts b/circuits/test/http/extractor.test.ts index 6619de4..c69c7a7 100644 --- a/circuits/test/http/extractor.test.ts +++ b/circuits/test/http/extractor.test.ts @@ -9,7 +9,7 @@ describe("HTTP :: body Extractor", async () => { it(`(valid) witness: ${description} ${desc}`, async () => { circuit = await circomkit.WitnessTester(`ExtractResponseData`, { - file: "circuits/http/extractor", + file: "http/extractor", template: "ExtractResponse", params: [input.length, expected.length], }); @@ -60,7 +60,7 @@ describe("HTTP :: header Extractor", async () => { it(`(valid) witness: ${description} ${desc}`, async () => { circuit = await circomkit.WitnessTester(`ExtractHeaderValue`, { - file: "circuits/http/extractor", + file: "http/extractor", template: "ExtractHeaderValue", params: [input.length, headerName.length, headerValue.length], }); diff --git a/circuits/test/http/interpreter.test.ts b/circuits/test/http/interpreter.test.ts index 5c46d95..ac1a330 100644 --- a/circuits/test/http/interpreter.test.ts +++ b/circuits/test/http/interpreter.test.ts @@ -9,7 +9,7 @@ describe("HTTP :: Interpreter", async () => { it(`(valid) witness: ${description} ${desc}`, async () => { circuit = await circomkit.WitnessTester(`LockRequestLineData`, { - file: "circuits/http/interpreter", + file: "http/interpreter", template: "MethodMatch", params: [input.length, method.length], }); @@ -24,7 +24,7 @@ describe("HTTP :: Interpreter", async () => { it(`(invalid) witness: ${description} ${desc}`, async () => { circuit = await circomkit.WitnessTester(`LockRequestLineData`, { - file: "circuits/http/interpreter", + file: "http/interpreter", template: "MethodMatch", params: [input.length, method.length], }); diff --git a/circuits/test/http/locker.test.ts b/circuits/test/http/locker.test.ts index 1a67fc1..4969b39 100644 --- a/circuits/test/http/locker.test.ts +++ b/circuits/test/http/locker.test.ts @@ -8,7 +8,7 @@ describe("HTTP :: Locker :: Request Line", async () => { it(`(valid) witness: ${description} ${desc}`, async () => { circuit = await circomkit.WitnessTester(`LockStartLine`, { - file: "circuits/http/locker", + file: "http/locker", template: "LockStartLine", params: [input.length, beginning.length, middle.length, final.length], }); @@ -23,7 +23,7 @@ describe("HTTP :: Locker :: Request Line", async () => { it(`(invalid) witness: ${description} ${desc}`, async () => { circuit = await circomkit.WitnessTester(`LockStartLine`, { - file: "circuits/http/locker", + file: "http/locker", template: "LockStartLine", params: [input.length, beginning.length, middle.length, final.length], }); @@ -58,7 +58,7 @@ describe("HTTP :: Locker :: Status Line", async () => { it(`(valid) witness: ${description} ${desc}`, async () => { circuit = await circomkit.WitnessTester(`LockStartLine`, { - file: "circuits/http/locker", + file: "http/locker", template: "LockStartLine", params: [input.length, beginning.length, middle.length, final.length], }); @@ -73,7 +73,7 @@ describe("HTTP :: Locker :: Status Line", async () => { it(`(invalid) witness: ${description} ${desc}`, async () => { circuit = await circomkit.WitnessTester(`LockStartLine`, { - file: "circuits/http/locker", + file: "http/locker", template: "LockStartLine", params: [input.length, beginning.length, middle.length, final.length], }); @@ -100,7 +100,7 @@ describe("HTTP :: Locker :: Header", async () => { it(`(valid) witness: ${description} ${desc}`, async () => { circuit = await circomkit.WitnessTester(`LockHeader`, { - file: "circuits/http/locker", + file: "http/locker", template: "LockHeader", params: [input.length, header.length, value.length], }); @@ -115,7 +115,7 @@ describe("HTTP :: Locker :: Header", async () => { it(`(invalid) witness: ${description} ${desc}`, async () => { circuit = await circomkit.WitnessTester(`LockHeader`, { - file: "circuits/http/locker", + file: "http/locker", template: "LockHeader", params: [input.length, header.length, value.length], }); diff --git a/circuits/test/json/extractor/extractor.test.ts b/circuits/test/json/extractor/extractor.test.ts index 11ab965..aa0426a 100644 --- a/circuits/test/json/extractor/extractor.test.ts +++ b/circuits/test/json/extractor/extractor.test.ts @@ -40,7 +40,7 @@ describe("ExtractValue", async () => { let [input, keyUnicode, output] = readJSONInputFile(`${filename}.json`, ["k"]); circuit = await circomkit.WitnessTester(`Extract`, { - file: `circuits/main/${filename}`, + file: `main/${filename}`, template: "ExtractStringValue", params: [input.length, 1, 1, 0, 1], }); @@ -60,7 +60,7 @@ describe("ExtractValue", async () => { let [input, keyUnicode, output] = readJSONInputFile(`${filename}.json`, ["key2"]); circuit = await circomkit.WitnessTester(`Extract`, { - file: `circuits/main/${filename}`, + file: `main/${filename}`, template: "ExtractStringValue", params: [input.length, 1, 4, 0, 3], }); @@ -75,7 +75,7 @@ describe("ExtractValue", async () => { let [input, keyUnicode, output] = readJSONInputFile(`${filename}.json`, ["k"]); circuit = await circomkit.WitnessTester(`Extract`, { - file: `circuits/main/${filename}`, + file: `main/${filename}`, template: "ExtractNumValue", params: [input.length, 1, 1, 0, 2], }); @@ -94,7 +94,7 @@ describe("ExtractValue", async () => { let [input, keyUnicode, output] = readJSONInputFile("value_array.json", ["b", i]); circuit = await circomkit.WitnessTester(`Extract`, { - file: `circuits/main/${filename}`, + file: `main/${filename}`, template: "ExtractStringValue", params: [input.length, 2, 1, 0, i, 1, output.length], }); @@ -112,7 +112,7 @@ describe("ExtractValue", async () => { let [input, keyUnicode, output] = readJSONInputFile("value_array.json", ["k", i]); circuit = await circomkit.WitnessTester(`Extract`, { - file: `circuits/main/${filename}`, + file: `main/${filename}`, template: "ExtractNumValue", params: [input.length, 2, 1, 0, i, 1, output.length], }); @@ -131,7 +131,7 @@ describe("ExtractValue", async () => { let [input, keyUnicode, output] = readJSONInputFile(`${filename}.json`, ["a", index_0, index_1]); circuit = await circomkit.WitnessTester(`Extract`, { - file: `circuits/main/${filename}`, + file: `main/${filename}`, template: "ExtractNumValue", params: [input.length, 3, 1, 0, index_0, 1, index_1, 2, 1], }); @@ -155,7 +155,7 @@ describe("ExtractValueMultiDepth", () => { let [input, keyUnicode, output] = readJSONInputFile(`${filename}.json`, ["e", "e"]); circuit = await circomkit.WitnessTester(`Extract`, { - file: `circuits/main/${filename}`, + file: `main/${filename}`, template: "ExtractStringValue", params: [input.length, 3, 1, 0, 1, 1, 1], }); @@ -183,7 +183,7 @@ describe("ExtractValueArrayObject", () => { let [input, keyUnicode, output] = readJSONInputFile(`${filename}.json`, ["a", index_0, "b", index_1]); circuit = await circomkit.WitnessTester(`Extract`, { - file: `circuits/main/${filename}`, + file: `main/${filename}`, template: "ExtractNumValue", params: [input.length, 4, 1, 0, index_0, 1, 1, 2, index_1, 3, 1], }); diff --git a/circuits/test/json/extractor/interpreter.test.ts b/circuits/test/json/extractor/interpreter.test.ts index cb2bfd6..26643b1 100644 --- a/circuits/test/json/extractor/interpreter.test.ts +++ b/circuits/test/json/extractor/interpreter.test.ts @@ -7,7 +7,7 @@ describe("Interpreter", async () => { before(async () => { circuit = await circomkit.WitnessTester(`InsideKey`, { - file: "circuits/json/interpreter", + file: "json/interpreter", template: "InsideKey", params: [4], }); @@ -46,7 +46,7 @@ describe("Interpreter", async () => { before(async () => { circuit = await circomkit.WitnessTester(`InsideValue`, { - file: "circuits/json/interpreter", + file: "json/interpreter", template: "InsideValue", params: [4], }); @@ -88,7 +88,7 @@ describe("Interpreter", async () => { it(`(valid) witness: ${description} ${desc}`, async () => { circuit = await circomkit.WitnessTester(`InsideValueAtDepth`, { - file: "circuits/json/interpreter", + file: "json/interpreter", template: "InsideValueAtDepth", params: [4, depth], }); @@ -125,7 +125,7 @@ describe("Interpreter", async () => { it(`(valid) witness: ${description} ${desc}`, async () => { circuit = await circomkit.WitnessTester(`InsideArrayIndex`, { - file: "circuits/json/interpreter", + file: "json/interpreter", template: "InsideArrayIndex", params: [4, index], }); @@ -165,7 +165,7 @@ describe("Interpreter", async () => { it(`(valid) witness: ${description} ${desc}`, async () => { circuit = await circomkit.WitnessTester(`InsideArrayIndexAtDepth`, { - file: "circuits/json/interpreter", + file: "json/interpreter", template: "InsideArrayIndexAtDepth", params: [4, index, depth], }); @@ -199,7 +199,7 @@ describe("Interpreter", async () => { before(async () => { circuit = await circomkit.WitnessTester(`NextKVPair`, { - file: "circuits/json/interpreter", + file: "json/interpreter", template: "NextKVPair", params: [4], }); @@ -239,7 +239,7 @@ describe("Interpreter", async () => { it(`(valid) witness: ${description} ${desc}`, async () => { circuit = await circomkit.WitnessTester(`NextKVPairAtDepth`, { - file: "circuits/json/interpreter", + file: "json/interpreter", template: "NextKVPairAtDepth", params: [4, depth], }); @@ -273,7 +273,7 @@ describe("Interpreter", async () => { it(`(valid) witness: ${description} ${desc}`, async () => { circuit = await circomkit.WitnessTester(`KeyMatch`, { - file: "circuits/json/interpreter", + file: "json/interpreter", template: "KeyMatch", params: [input.data.length, input.key.length], }); @@ -314,7 +314,7 @@ describe("Interpreter", async () => { it(`(valid) witness: ${description} ${desc}`, async () => { circuit = await circomkit.WitnessTester(`KeyMatchAtDepth`, { - file: "circuits/json/interpreter", + file: "json/interpreter", template: "KeyMatchAtDepth", params: [input.data.length, 4, input.key.length, depth], }); diff --git a/circuits/test/json/parser/parsing_types.test.ts b/circuits/test/json/parser/parsing_types.test.ts index a5783dc..88d892e 100644 --- a/circuits/test/json/parser/parsing_types.test.ts +++ b/circuits/test/json/parser/parsing_types.test.ts @@ -19,7 +19,7 @@ describe("StateUpdate", () => { before(async () => { circuit = await circomkit.WitnessTester(`StateUpdate`, { - file: "circuits/json/parser/machine", + file: "json/parser/machine", template: "StateUpdate", params: [4], }); diff --git a/circuits/test/json/parser/stack.test.ts b/circuits/test/json/parser/stack.test.ts index f719582..860737e 100644 --- a/circuits/test/json/parser/stack.test.ts +++ b/circuits/test/json/parser/stack.test.ts @@ -5,7 +5,7 @@ describe("GetTopOfStack", () => { let circuit: WitnessTester<["stack"], ["value", "pointer"]>; before(async () => { circuit = await circomkit.WitnessTester(`GetTopOfStack`, { - file: "circuits/json/parser/machine", + file: "json/parser/machine", template: "GetTopOfStack", params: [4], }); @@ -34,7 +34,7 @@ describe("StateUpdate :: RewriteStack", () => { >; before(async () => { circuit = await circomkit.WitnessTester(`GetTopOfStack`, { - file: "circuits/json/parser/machine", + file: "json/parser/machine", template: "StateUpdate", params: [4], }); diff --git a/circuits/test/json/parser/values.test.ts b/circuits/test/json/parser/values.test.ts index 2bca379..069525b 100644 --- a/circuits/test/json/parser/values.test.ts +++ b/circuits/test/json/parser/values.test.ts @@ -8,7 +8,7 @@ describe("StateUpdate :: Values", () => { >; before(async () => { circuit = await circomkit.WitnessTester(`GetTopOfStack`, { - file: "circuits/json/parser/machine", + file: "json/parser/machine", template: "StateUpdate", params: [4], }); diff --git a/circuits/test/utils/array.test.ts b/circuits/test/utils/array.test.ts index ae4a42e..c951452 100644 --- a/circuits/test/utils/array.test.ts +++ b/circuits/test/utils/array.test.ts @@ -5,7 +5,7 @@ describe("array", () => { let circuit: WitnessTester<["in"], ["out"]>; before(async () => { circuit = await circomkit.WitnessTester(`Slice`, { - file: "circuits/utils/array", + file: "utils/array", template: "Slice", params: [10, 2, 4], }); @@ -33,7 +33,7 @@ describe("IsEqualArray", () => { let circuit: WitnessTester<["in"], ["out"]>; before(async () => { circuit = await circomkit.WitnessTester(`IsEqualArray`, { - file: "circuits/utils/array", + file: "utils/array", template: "IsEqualArray", params: [3], }); @@ -87,7 +87,7 @@ describe("Contains", () => { let circuit: WitnessTester<["in", "array"], ["out"]>; before(async () => { circuit = await circomkit.WitnessTester(`Contains`, { - file: "circuits/utils/array", + file: "utils/array", template: "Contains", params: [3], }); @@ -128,7 +128,7 @@ describe("ArrayAdd", () => { let circuit: WitnessTester<["lhs", "rhs"], ["out"]>; before(async () => { circuit = await circomkit.WitnessTester(`ArrayAdd`, { - file: "circuits/utils/array", + file: "utils/array", template: "ArrayAdd", params: [3], }); @@ -148,7 +148,7 @@ describe("ArrayMul", () => { let circuit: WitnessTester<["lhs", "rhs"], ["out"]>; before(async () => { circuit = await circomkit.WitnessTester(`ArrayMul`, { - file: "circuits/utils/array", + file: "utils/array", template: "ArrayMul", params: [3], }); @@ -168,7 +168,7 @@ describe("GenericArrayAdd", () => { let circuit: WitnessTester<["arrays"], ["out"]>; before(async () => { circuit = await circomkit.WitnessTester(`ArrayAdd`, { - file: "circuits/utils/array", + file: "utils/array", template: "GenericArrayAdd", params: [3, 2], }); diff --git a/circuits/test/utils/bytes.test.ts b/circuits/test/utils/bytes.test.ts index 5ee55ef..d0690a3 100644 --- a/circuits/test/utils/bytes.test.ts +++ b/circuits/test/utils/bytes.test.ts @@ -4,7 +4,7 @@ describe("ASCII", () => { let circuit: WitnessTester<["in"], ["out"]>; before(async () => { circuit = await circomkit.WitnessTester(`ASCII`, { - file: "circuits/utils/bytes", + file: "utils/bytes", template: "ASCII", params: [13], }); diff --git a/circuits/test/utils/hash.test.ts b/circuits/test/utils/hash.test.ts index e834cc7..1661367 100644 --- a/circuits/test/utils/hash.test.ts +++ b/circuits/test/utils/hash.test.ts @@ -7,7 +7,7 @@ describe("hash", () => { before(async () => { circuit = await circomkit.WitnessTester(`PoseidonModular`, { - file: "circuits/utils/hash", + file: "utils/hash", template: "PoseidonModular", params: [16], }); @@ -30,7 +30,7 @@ describe("hash", () => { before(async () => { circuit = await circomkit.WitnessTester(`PoseidonModular`, { - file: "circuits/utils/hash", + file: "utils/hash", template: "PoseidonModular", params: [379], }); diff --git a/circuits/test/utils/operators.test.ts b/circuits/test/utils/operators.test.ts index 7c82c61..67c0069 100644 --- a/circuits/test/utils/operators.test.ts +++ b/circuits/test/utils/operators.test.ts @@ -4,7 +4,7 @@ describe("SwitchArray", () => { let circuit: WitnessTester<["case", "branches", "vals"], ["match", "out"]>; before(async () => { circuit = await circomkit.WitnessTester(`SwitchArray`, { - file: "circuits/utils/operators", + file: "utils/operators", template: "SwitchArray", params: [3, 2], }); @@ -59,7 +59,7 @@ describe("Switch", () => { let circuit: WitnessTester<["case", "branches", "vals"], ["match", "out"]>; before(async () => { circuit = await circomkit.WitnessTester(`Switch`, { - file: "circuits/utils/operators", + file: "utils/operators", template: "Switch", params: [3], }); @@ -101,7 +101,7 @@ describe("InRange", () => { let circuit: WitnessTester<["in", "range"], ["out"]>; before(async () => { circuit = await circomkit.WitnessTester(`InRange`, { - file: "circuits/utils/operators", + file: "utils/operators", template: "InRange", params: [8], }); diff --git a/circuits/test/utils/search.test.ts b/circuits/test/utils/search.test.ts index f0938db..e6cbbe1 100644 --- a/circuits/test/utils/search.test.ts +++ b/circuits/test/utils/search.test.ts @@ -14,7 +14,7 @@ describe("search", () => { const hashResult = PoseidonModular(concatenatedInput); circuit = await circomkit.WitnessTester(`SubstringSearch`, { - file: "circuits/utils/search", + file: "utils/search", template: "SubstringSearch", params: [data.length, key.length], }); @@ -32,7 +32,7 @@ describe("search", () => { const hashResult = PoseidonModular(concatenatedInput); circuit = await circomkit.WitnessTester(`SubstringSearch`, { - file: "circuits/utils/search", + file: "utils/search", template: "SubstringSearch", params: [data.length, key.length], }); @@ -51,7 +51,7 @@ describe("search", () => { const key = [1, 0]; circuit = await circomkit.WitnessTester(`SubstringSearch`, { - file: "circuits/utils/search", + file: "utils/search", template: "SubstringSearch", params: [data.length, key.length], }); @@ -67,7 +67,7 @@ describe("search", () => { const hashResult = PoseidonModular(concatenatedInput); circuit = await circomkit.WitnessTester(`SubstringSearch`, { - file: "circuits/utils/search", + file: "utils/search", template: "SubstringSearch", params: [witness["data"].length, witness["key"].length], }); @@ -85,7 +85,7 @@ describe("search", () => { before(async () => { circuit = await circomkit.WitnessTester(`SubstringSearch`, { - file: "circuits/utils/search", + file: "utils/search", template: "SubstringMatchWithIndex", params: [787, 10], }); @@ -122,7 +122,7 @@ describe("search", () => { before(async () => { circuit = await circomkit.WitnessTester(`SubstringSearch`, { - file: "circuits/utils/search", + file: "utils/search", template: "SubstringMatch", params: [787, 10], }); diff --git a/docs/pabuild.md b/docs/pabuild.md new file mode 100644 index 0000000..c218d3b --- /dev/null +++ b/docs/pabuild.md @@ -0,0 +1,107 @@ +# `wpbuild` CLI Tool +This repository contains a small Rust CLI tool called `wpbuild`. + +## Install `wpbuild` +From the root of this repository, run: +```sh +cargo install --path . +``` +to install the `wpbuild` binary. +You can see a help menu with the subcommands by: +```sh +wpbuild --help +``` + +## Witnessgen +To get the basic idea, run +```sh +pabuild witness --help +``` +It can process and generate JSON files to be used for these circuits. + +### Examples +**JSON Parsing:** +If we have a given JSON file we want to parse such as `examples/json/test/example.json` for the `json-parser` circuit (see `circuits.json`), then we can: + +```sh +pabuild witness json --input-file examples/json/test/example.json --output-dir inputs/json-parser --output-filename input.json +``` + +Afterwards, you can run `npx circomkit compile json-parser` then `circomkit witness json-parser input`. + +**HTTP Parsing:** +If we have a given HTTP request/response (as a file) we want to parse such as `examples/http/get_request.http` for the `http-parser` circuit (see `circuits.json`), then we can: + +```sh +pabuild witness http --input-file examples/json/get_request.http --output-dir inputs/http-parser --output-filename input.json +``` + +Afterwards, you can run `npx circomkit compile http-parser` then `circomkit witness http-parser input`. + +## Codegen + +### JSON Extraction +JSON extractor circuit is generated using rust to handle arbitrary keys and array indices. + +Run: +```bash +cargo run --bin codegen -- --help +``` +to get options: +``` +Usage: codegen [OPTIONS] --json-file + +Options: + -j, --json-file Path to the JSON file + -o, --output-filename Output circuit file name [default: extractor] +``` +Takes input 2 arguments: +- `json-file`: input json file. Examples are located in [codegen](./examples/json/test/codegen/) +- `output-filename`: circuit filename to save. Located in [circuits/main](./circuits/main/). If not given, defaults to `extractor.circom`. + +To test an end-to-end JSON extraction proof: +- Run codegen to generate circuits. Replace `value_string` with input filename. + ```bash + cargo run --bin codegen -- --json-file ./examples/json/test/codegen/value_string.json --output-filename value_string + ``` + +- Compile circom circuit using + ``` + circom ./circuits/main/value_string.circom --r1cs --wasm + ``` + +- To use circomkit: add circuit config to [circuits.json](./circuits.json). and input file to [inputs](./inputs/) + +- Generate witness: + ```bash + node build/json_extract_value_string/json_extract_value_string_js/generate_witness inputs/json_extract_value_string/value_string.json build/json_extract_value_string/witness/ + ``` + or generate using circomkit: + ```bash + npx circomkit witness json_extract_value_string value_string + ``` + +- create trusted setup: + ```bash + npx circomkit setup json_extract_value_string + # OR + snarkjs groth16 setup build/json_extract_value_string/json_extract_value_string.r1cs ptau/powersOfTau28_hez_final_14.ptau build/json_extract_value_string/groth16_pkey.zkey + ``` + +- create proof: + ```bash + npx circomkit prove json_extract_value_string value_string + # OR + snarkjs groth16 prove build/json_extract_value_string/groth16_pkey.zkey build/json_extract_value_string/value_string/witness.wtns build/json_extract_value_string/value_string/groth16_proof.json inputs/json_extract_value_string/value_string.json + ``` + +- verify proof: + ```bash + npx circomkit verify json_extract_value_string value_string + # OR + snarkjs groth16 verify build/json_extract_value_string/groth16_vkey.json inputs/json_extract_value_string/value_string.json build/json_extract_value_string/value_string/groth16_proof.json + ``` + +### HTTP Locking and Extraction + +TODO \ No newline at end of file diff --git a/docs/wpbuild.md b/docs/wpbuild.md deleted file mode 100644 index 212fc4a..0000000 --- a/docs/wpbuild.md +++ /dev/null @@ -1,25 +0,0 @@ -# `wpbuild` CLI Tool -This repository contains a small Rust CLI tool called `wpbuild`. - -## Install Rust -To install Rust, you need to run: -```sh -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -``` -and reload your shell. -Check this is installed by running: -```sh -which rustc && which cargo -``` -to see the path to your Rust compiler and Cargo package manager. - -## Install `wpbuild` -From the root of this repository, run: -```sh -cargo install --path . -``` -to install the `wpbuild` binary. -You can see a help menu with the subcommands by: -```sh -wpbuild --help -``` \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 8c41d03..3265ba4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,16 +10,17 @@ "license": "Apache-2.0", "dependencies": { "@zk-email/circuits": "^6.1.1", - "circomkit": "^0.2.1", "circomlib": "^2.0.5" }, "devDependencies": { "@types/mocha": "^10.0.1", - "@types/node": "^22.1.0", - "mocha": "^10.2.0", - "poseidon-lite": "^0.2.0", + "@types/node": "22.5.4", + "circomkit": "0.3.0", + "mocha": "10.7.3", + "poseidon-lite": "0.3.0", + "snarkjs": "0.7.4", "ts-node": "^10.9.1", - "typescript": "^5.1.3" + "typescript": "5.6.2" } }, "node_modules/@cspotcode/source-map-support": { @@ -45,6 +46,7 @@ "version": "0.0.11", "resolved": "https://registry.npmjs.org/@iden3/binfileutils/-/binfileutils-0.0.11.tgz", "integrity": "sha512-LylnJoZ0CTdgErnKY8OxohvW4K+p6UHD3sxt+3P9AmMyBQjYR4IpoqoYZZ+9aMj89cmCQ21UvdhndAx04er3NA==", + "dev": true, "license": "GPL-3.0", "dependencies": { "fastfile": "0.0.20", @@ -115,19 +117,20 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", - "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==", + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz", + "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.13.0" + "undici-types": "~6.19.2" } }, "node_modules/@types/snarkjs": { "version": "0.7.8", "resolved": "https://registry.npmjs.org/@types/snarkjs/-/snarkjs-0.7.8.tgz", "integrity": "sha512-x37Jsv1vx6I6RMJdfvYEmDUOLYgzYMecwlk13gniDOcN20xLVe9hy9DlQxWeCPirqpDY/jwugQSqCi2RxehU3g==", + "dev": true, "license": "MIT", "peer": true }, @@ -254,6 +257,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, "license": "MIT", "engines": { "node": "*" @@ -269,6 +273,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" @@ -371,6 +376,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", @@ -403,6 +409,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "dev": true, "license": "MIT", "dependencies": { "assertion-error": "^1.1.0", @@ -437,6 +444,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, "license": "MIT", "dependencies": { "get-func-name": "^2.0.2" @@ -455,6 +463,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz", "integrity": "sha512-Wmza/JzL0SiWz7kl6MhIKT5ceIlnFPJX+lwUGj7Clhy5MMldsSoJR0+uvRzOS5Kv45Mq7t1PoE8TsOA9bzvb6g==", + "dev": true, "license": "ISC" }, "node_modules/chokidar": { @@ -509,6 +518,7 @@ "version": "0.0.19", "resolved": "https://registry.npmjs.org/circom_tester/-/circom_tester-0.0.19.tgz", "integrity": "sha512-SNHaBsGxcBH6XsVWfsRbRPA7NF8m8AMKJI9dtJJCFGUtOTT2+zsoIqAwi50z6XCnO4TtjyXq7AeXa1PLHqT0tw==", + "dev": true, "license": "GPL-3.0", "dependencies": { "chai": "^4.3.6", @@ -525,6 +535,7 @@ "version": "0.1.21", "resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.1.21.tgz", "integrity": "sha512-qTkud630B/GK8y76hnOaaS1aNuF6prfV0dTrkeRsiJKnlP1ryQbP2FWLgDOPqn6aKyaPlam+Z+DTbBhkEzh8dA==", + "dev": true, "license": "Apache-2.0", "dependencies": { "ffjavascript": "0.2.56" @@ -537,6 +548,7 @@ "version": "0.2.56", "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.56.tgz", "integrity": "sha512-em6G5Lrj7ucIqj4TYEgyoHs/j99Urwwqa4+YxEVY2hggnpRimVj+noX5pZQTxI1pvtiekZI4rG65JBf0xraXrg==", + "dev": true, "license": "GPL-3.0", "dependencies": { "wasmbuilder": "0.0.16", @@ -548,6 +560,7 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/snarkjs/-/snarkjs-0.5.0.tgz", "integrity": "sha512-KWz8mZ2Y+6wvn6GGkQo6/ZlKwETdAGohd40Lzpwp5TUZCn6N6O4Az1SuX1rw/qREGL6Im+ycb19suCFE8/xaKA==", + "dev": true, "license": "GPL-3.0", "dependencies": { "@iden3/binfileutils": "0.0.11", @@ -569,15 +582,17 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.2.0.tgz", "integrity": "sha512-3e2rbxdujOwaod657gxgmdhZNn+i1qKdHO3Y/bK+8E7bV8ttV/fu5FO4/WLBACF375cK0QDLOP+65Na63qYuWA==", + "dev": true, "license": "GPL-3.0", "dependencies": { "wasmbuilder": "0.0.16" } }, "node_modules/circomkit": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/circomkit/-/circomkit-0.2.1.tgz", - "integrity": "sha512-7O8QsOLUq2QvwGMimvWxwdg7OgV33OT7ZBND+81dv3JrVp8ove93yV16jF3TW6XBncSY92/Aka8F4CAi/H9VQw==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/circomkit/-/circomkit-0.3.0.tgz", + "integrity": "sha512-U9GUKwy24AAdUre0MJ/6KyqZM6q5QRwiNNDLOVKARjuvOaCm6+WZ4hU5felAsdWq4QtZygrc5uKeRzAbJbZANQ==", + "dev": true, "license": "MIT", "dependencies": { "circom_tester": "^0.0.19", @@ -635,6 +650,7 @@ "version": "12.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -695,6 +711,7 @@ "version": "4.1.4", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, "license": "MIT", "dependencies": { "type-detect": "^4.0.0" @@ -713,6 +730,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", @@ -762,6 +780,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4" @@ -774,6 +793,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -883,6 +903,7 @@ "version": "0.2.63", "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.63.tgz", "integrity": "sha512-dBgdsfGks58b66JnUZeZpGxdMIDQ4QsD3VYlRJyFVrKQHb2kJy4R2gufx5oetrTxXPT+aEjg0dOvOLg1N0on4A==", + "dev": true, "license": "GPL-3.0", "dependencies": { "wasmbuilder": "0.0.16", @@ -964,12 +985,14 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/fnv-plus/-/fnv-plus-1.3.1.tgz", "integrity": "sha512-Gz1EvfOneuFfk4yG458dJ3TLJ7gV19q3OM/vVvvHf7eT02Hm1DleB4edsia6ahbKgAYxO9gvyQ1ioWZR+a00Yw==", + "dev": true, "license": "MIT" }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, "license": "MIT", "dependencies": { "is-callable": "^1.1.3" @@ -1001,6 +1024,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1020,6 +1044,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, "license": "MIT", "engines": { "node": "*" @@ -1029,6 +1054,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -1105,6 +1131,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" @@ -1126,6 +1153,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" @@ -1138,6 +1166,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -1150,6 +1179,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -1162,6 +1192,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -1177,6 +1208,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -1220,12 +1252,14 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, "license": "ISC" }, "node_modules/is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.2", @@ -1255,6 +1289,7 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -1287,6 +1322,7 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" @@ -1335,6 +1371,7 @@ "version": "1.1.13", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, "license": "MIT", "dependencies": { "which-typed-array": "^1.1.14" @@ -1457,6 +1494,7 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.1.tgz", "integrity": "sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6.0" @@ -1476,6 +1514,7 @@ "version": "2.3.7", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, "license": "MIT", "dependencies": { "get-func-name": "^2.0.1" @@ -1501,9 +1540,9 @@ } }, "node_modules/mocha": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.0.tgz", - "integrity": "sha512-v8/rBWr2VO5YkspYINnvu81inSz2y3ODJrhO175/Exzor1RcEZZkizgE2A+w/CAXXoESS8Kys5E62dOHGHzULA==", + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz", + "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==", "dev": true, "license": "MIT", "dependencies": { @@ -1671,6 +1710,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, "license": "MIT", "engines": { "node": "*" @@ -1690,9 +1730,9 @@ } }, "node_modules/poseidon-lite": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/poseidon-lite/-/poseidon-lite-0.2.0.tgz", - "integrity": "sha512-vivDZnGmz8W4G/GzVA72PXkfYStjilu83rjjUfpL4PueKcC8nfX6hCPh2XhoC5FBgC6y0TA3YuUeUo5YCcNoig==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/poseidon-lite/-/poseidon-lite-0.3.0.tgz", + "integrity": "sha512-ilJj4MIve4uBEG7SrtPqUUNkvpJ/pLVbndxa0WvebcQqeIhe+h72JR4g0EvwchUzm9sOQDlOjiDNmRAgxNZl4A==", "dev": true, "license": "MIT" }, @@ -1700,6 +1740,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -1717,6 +1758,7 @@ "version": "0.0.41", "resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.41.tgz", "integrity": "sha512-Q1WDF3u1vYeAwjHo4YuddkA8Aq0TulbKjmGm99+Atn13Lf5fTsMZBnBV9T741w8iSyPFG6Uh6sapQby77sREqA==", + "dev": true, "license": "GPL-3.0", "dependencies": { "@iden3/bigarray": "0.0.2", @@ -1729,6 +1771,7 @@ "version": "0.2.56", "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.56.tgz", "integrity": "sha512-em6G5Lrj7ucIqj4TYEgyoHs/j99Urwwqa4+YxEVY2hggnpRimVj+noX5pZQTxI1pvtiekZI4rG65JBf0xraXrg==", + "dev": true, "license": "GPL-3.0", "dependencies": { "wasmbuilder": "0.0.16", @@ -1740,6 +1783,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.2.0.tgz", "integrity": "sha512-3e2rbxdujOwaod657gxgmdhZNn+i1qKdHO3Y/bK+8E7bV8ttV/fu5FO4/WLBACF375cK0QDLOP+65Na63qYuWA==", + "dev": true, "license": "GPL-3.0", "dependencies": { "wasmbuilder": "0.0.16" @@ -1813,6 +1857,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", @@ -1956,6 +2001,7 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, "license": "MIT", "engines": { "node": ">=14.14" @@ -1965,6 +2011,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "dev": true, "license": "MIT", "dependencies": { "tmp": "^0.2.0" @@ -2059,15 +2106,16 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2085,9 +2133,9 @@ "license": "MIT" }, "node_modules/undici-types": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", - "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==", + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true, "license": "MIT" }, @@ -2095,6 +2143,7 @@ "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -2136,6 +2185,7 @@ "version": "1.1.15", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", diff --git a/package.json b/package.json index 8f55708..4a8cfdb 100644 --- a/package.json +++ b/package.json @@ -8,16 +8,17 @@ }, "dependencies": { "@zk-email/circuits": "^6.1.1", - "circomkit": "^0.2.1", "circomlib": "^2.0.5" }, "devDependencies": { + "circomkit": "0.3.0", + "snarkjs": "0.7.4", + "typescript": "5.6.2", + "@types/node": "22.5.4", + "mocha": "10.7.3", "@types/mocha": "^10.0.1", - "@types/node": "^22.1.0", - "mocha": "^10.2.0", - "poseidon-lite": "^0.2.0", - "ts-node": "^10.9.1", - "typescript": "^5.1.3" + "poseidon-lite": "0.3.0", + "ts-node": "^10.9.1" }, "repository": { "type": "git", diff --git a/src/main.rs b/src/main.rs index ba083e9..0d20918 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,7 +22,7 @@ pub enum Command { #[derive(Parser, Debug)] pub struct WitnessArgs { - #[command(subcommand)] + #[arg(global = true, value_enum)] subcommand: WitnessSubcommand, /// Path to the JSON file @@ -38,7 +38,7 @@ pub struct WitnessArgs { output_filename: String, } -#[derive(Subcommand, Debug)] +#[derive(clap::ValueEnum, Clone, Debug)] pub enum WitnessSubcommand { Json, Http, diff --git a/src/witness.rs b/src/witness.rs index 8375627..346e4db 100644 --- a/src/witness.rs +++ b/src/witness.rs @@ -2,7 +2,9 @@ use super::*; use std::io::Write; #[derive(serde::Serialize)] -pub struct Witness(Vec); +pub struct Witness { + data: Vec, +} pub fn witness(args: WitnessArgs) -> Result<(), Box> { let data = match &args.subcommand { @@ -22,7 +24,7 @@ pub fn witness(args: WitnessArgs) -> Result<(), Box> { } }; - let witness = Witness(data.clone()); + let witness = Witness { data: data.clone() }; if !args.output_dir.exists() { std::fs::create_dir_all(&args.output_dir)?;