diff --git a/bin/gnark/darwin-arm64-libprove.so b/bin/gnark/darwin-arm64-libprove.so new file mode 100644 index 0000000..9d69b1b Binary files /dev/null and b/bin/gnark/darwin-arm64-libprove.so differ diff --git a/bin/gnark/darwin-arm64-libverify.so b/bin/gnark/darwin-arm64-libverify.so new file mode 100644 index 0000000..ebbbf5e Binary files /dev/null and b/bin/gnark/darwin-arm64-libverify.so differ diff --git a/expander/.gitignore b/expander/.gitignore new file mode 100644 index 0000000..1de5659 --- /dev/null +++ b/expander/.gitignore @@ -0,0 +1 @@ +target \ No newline at end of file diff --git a/expander/Cargo.lock b/expander/Cargo.lock new file mode 100644 index 0000000..6a6e540 --- /dev/null +++ b/expander/Cargo.lock @@ -0,0 +1,2341 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +dependencies = [ + "anstyle", + "windows-sys 0.59.0", +] + +[[package]] +name = "arith" +version = "0.1.0" +dependencies = [ + "ark-std", + "cfg-if", + "ethnum", + "halo2curves", + "log", + "rand", + "raw-cpuid", + "sha2", + "thiserror", + "tynm", +] + +[[package]] +name = "arith" +version = "0.1.0" +source = "git+https://github.com/reclaimprotocol/Expander?branch=wasm#7f2ac635a2d54cf59cbe0d6911ddfa2471536bae" +dependencies = [ + "ark-std", + "cfg-if", + "ethnum", + "halo2curves", + "log", + "rand", + "raw-cpuid", + "sha2", + "thiserror", + "tynm", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.85", + "which", +] + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + +[[package]] +name = "blake2b_simd" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "build-probe-mpi" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3234fa6de2f6e0e338c7183ba09ae68c8f2bd6919d8763362597627362b7f8fe" +dependencies = [ + "pkg-config", + "shell-words", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" + +[[package]] +name = "cc" +version = "1.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" +dependencies = [ + "shlex", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets", +] + +[[package]] +name = "circuit" +version = "0.1.0" +dependencies = [ + "arith 0.1.0", + "ark-std", + "config 0.1.0", + "ethnum", + "log", + "thiserror", + "transcript 0.1.0", +] + +[[package]] +name = "circuit" +version = "0.1.0" +source = "git+https://github.com/reclaimprotocol/Expander?branch=wasm#7f2ac635a2d54cf59cbe0d6911ddfa2471536bae" +dependencies = [ + "arith 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "ark-std", + "config 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "ethnum", + "log", + "thiserror", + "transcript 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + +[[package]] +name = "config" +version = "0.1.0" +dependencies = [ + "arith 0.1.0", + "ark-std", + "getrandom", + "gf2 0.1.0", + "gf2_128 0.1.0", + "halo2curves", + "mersenne31 0.1.0", + "mpi", + "transcript 0.1.0", +] + +[[package]] +name = "config" +version = "0.1.0" +source = "git+https://github.com/reclaimprotocol/Expander?branch=wasm#7f2ac635a2d54cf59cbe0d6911ddfa2471536bae" +dependencies = [ + "arith 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "ark-std", + "getrandom", + "gf2 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "gf2_128 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "halo2curves", + "mersenne31 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "mpi", + "transcript 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "conv" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299" +dependencies = [ + "custom_derive", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "custom_derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9" + +[[package]] +name = "data-encoding" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "env_filter" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "ethnum" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" + +[[package]] +name = "expander_compiler" +version = "0.1.0" +dependencies = [ + "arith 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "ark-std", + "chrono", + "circuit 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "clap", + "config 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "ethnum", + "gf2 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "gkr 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "halo2curves", + "mersenne31 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "rand", + "tiny-keccak", +] + +[[package]] +name = "expander_symmetric_crypto" +version = "0.1.0" +dependencies = [ + "arith 0.1.0", + "circuit 0.1.0", + "config 0.1.0", + "console_error_panic_hook", + "expander_compiler", + "getrandom", + "gkr 0.1.0", + "peak_alloc", + "transcript 0.1.0", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "bitvec", + "rand_core", + "subtle", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gf2" +version = "0.1.0" +dependencies = [ + "arith 0.1.0", + "ark-std", + "cfg-if", + "ethnum", + "halo2curves", + "log", + "rand", + "raw-cpuid", + "sha2", + "thiserror", +] + +[[package]] +name = "gf2" +version = "0.1.0" +source = "git+https://github.com/reclaimprotocol/Expander?branch=wasm#7f2ac635a2d54cf59cbe0d6911ddfa2471536bae" +dependencies = [ + "arith 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "ark-std", + "cfg-if", + "ethnum", + "halo2curves", + "log", + "rand", + "raw-cpuid", + "sha2", + "thiserror", +] + +[[package]] +name = "gf2_128" +version = "0.1.0" +dependencies = [ + "arith 0.1.0", + "ark-std", + "gf2 0.1.0", + "rand", +] + +[[package]] +name = "gf2_128" +version = "0.1.0" +source = "git+https://github.com/reclaimprotocol/Expander?branch=wasm#7f2ac635a2d54cf59cbe0d6911ddfa2471536bae" +dependencies = [ + "arith 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "ark-std", + "gf2 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "rand", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "gkr" +version = "0.1.0" +dependencies = [ + "arith 0.1.0", + "ark-std", + "bytes", + "chrono", + "circuit 0.1.0", + "clap", + "config 0.1.0", + "env_logger", + "ethnum", + "gf2 0.1.0", + "gf2_128 0.1.0", + "halo2curves", + "log", + "mersenne31 0.1.0", + "mpi", + "polynomials 0.1.0", + "rand", + "sha2", + "sumcheck 0.1.0", + "thiserror", + "tiny-keccak", + "tokio", + "transcript 0.1.0", + "tynm", + "warp", +] + +[[package]] +name = "gkr" +version = "0.1.0" +source = "git+https://github.com/reclaimprotocol/Expander?branch=wasm#7f2ac635a2d54cf59cbe0d6911ddfa2471536bae" +dependencies = [ + "arith 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "ark-std", + "bytes", + "chrono", + "circuit 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "clap", + "config 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "env_logger", + "ethnum", + "gf2 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "gf2_128 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "halo2curves", + "log", + "mersenne31 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "mpi", + "polynomials 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "rand", + "sha2", + "sumcheck 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "thiserror", + "tiny-keccak", + "tokio", + "transcript 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "tynm", + "warp", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "halo2curves" +version = "0.6.1" +source = "git+https://github.com/PolyhedraZK/halo2curves#79a953d0e2cd12478d4046cabdbe72d3abad9166" +dependencies = [ + "blake2", + "digest", + "ff", + "group", + "lazy_static", + "num-bigint", + "num-traits", + "pairing", + "pasta_curves", + "paste", + "rand", + "rand_core", + "rayon", + "sha2", + "static_assertions", + "subtle", + "unroll", +] + +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + +[[package]] +name = "headers" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +dependencies = [ + "base64", + "bytes", + "headers-core", + "http 0.2.12", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http 0.2.12", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http 0.2.12", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.161" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" + +[[package]] +name = "libffi" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce826c243048e3d5cec441799724de52e2d42f820468431fc3fceee2341871e2" +dependencies = [ + "libc", + "libffi-sys", +] + +[[package]] +name = "libffi-sys" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36115160c57e8529781b4183c2bb51fdc1f6d6d1ed345591d84be7703befb3c" +dependencies = [ + "cc", +] + +[[package]] +name = "libloading" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if", + "windows-targets", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "mersenne31" +version = "0.1.0" +dependencies = [ + "arith 0.1.0", + "ark-std", + "cfg-if", + "ethnum", + "halo2curves", + "log", + "rand", + "raw-cpuid", + "sha2", + "thiserror", +] + +[[package]] +name = "mersenne31" +version = "0.1.0" +source = "git+https://github.com/reclaimprotocol/Expander?branch=wasm#7f2ac635a2d54cf59cbe0d6911ddfa2471536bae" +dependencies = [ + "arith 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "ark-std", + "cfg-if", + "ethnum", + "halo2curves", + "log", + "rand", + "raw-cpuid", + "sha2", + "thiserror", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi", + "libc", + "wasi", + "windows-sys 0.52.0", +] + +[[package]] +name = "mpi" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677762a4bde2c81158fc566a69b97d11b0c3358694e64f4f922ac5189be311cc" +dependencies = [ + "build-probe-mpi", + "conv", + "libffi", + "mpi-sys", + "once_cell", + "smallvec", + "thiserror", +] + +[[package]] +name = "mpi-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f35fdd7bdb38959515f008d12598065631de9624f6d42c11caef19e8e0d10de" +dependencies = [ + "bindgen", + "build-probe-mpi", + "cc", +] + +[[package]] +name = "multer" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http 0.2.12", + "httparse", + "log", + "memchr", + "mime", + "spin", + "version_check", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "pairing" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" +dependencies = [ + "group", +] + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "pasta_curves" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e57598f73cc7e1b2ac63c79c517b31a0877cd7c402cdcaa311b5208de7a095" +dependencies = [ + "blake2b_simd", + "ff", + "group", + "lazy_static", + "rand", + "static_assertions", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "peak_alloc" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c4e8e2dd832fd76346468f822e4e600d30ba4e5aa545a128abf12cfae7ea3e" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "polynomials" +version = "0.1.0" +dependencies = [ + "arith 0.1.0", + "ark-std", + "halo2curves", +] + +[[package]] +name = "polynomials" +version = "0.1.0" +source = "git+https://github.com/reclaimprotocol/Expander?branch=wasm#7f2ac635a2d54cf59cbe0d6911ddfa2471536bae" +dependencies = [ + "arith 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "ark-std", + "halo2curves", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "prettyplease" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +dependencies = [ + "proc-macro2", + "syn 2.0.85", +] + +[[package]] +name = "proc-macro2" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "raw-cpuid" +version = "11.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ab240315c661615f2ee9f0f2cd32d5a7343a84d5ebcccb99d46e6637565e7b0" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.213" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.213" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "serde_json" +version = "1.0.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "sumcheck" +version = "0.1.0" +dependencies = [ + "arith 0.1.0", + "circuit 0.1.0", + "config 0.1.0", + "env_logger", + "log", + "polynomials 0.1.0", + "transcript 0.1.0", +] + +[[package]] +name = "sumcheck" +version = "0.1.0" +source = "git+https://github.com/reclaimprotocol/Expander?branch=wasm#7f2ac635a2d54cf59cbe0d6911ddfa2471536bae" +dependencies = [ + "arith 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "circuit 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "config 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "env_logger", + "log", + "polynomials 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "transcript 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "thiserror" +version = "1.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite", +] + +[[package]] +name = "tokio-util" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "transcript" +version = "0.1.0" +dependencies = [ + "arith 0.1.0", + "sha2", + "tiny-keccak", +] + +[[package]] +name = "transcript" +version = "0.1.0" +source = "git+https://github.com/reclaimprotocol/Expander?branch=wasm#7f2ac635a2d54cf59cbe0d6911ddfa2471536bae" +dependencies = [ + "arith 0.1.0 (git+https://github.com/reclaimprotocol/Expander?branch=wasm)", + "sha2", + "tiny-keccak", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tungstenite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http 1.1.0", + "httparse", + "log", + "rand", + "sha1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "tynm" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd30d05e69d1478e13fe3e7a853409cfec82cebc2cf9b8d613b3c6b0081781ed" +dependencies = [ + "nom", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicase" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" + +[[package]] +name = "unicode-bidi" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unroll" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ad948c1cb799b1a70f836077721a92a35ac177d4daddf4c20a633786d4cf618" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "url" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "warp" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4378d202ff965b011c64817db11d5829506d3404edeadb61f190d111da3f231c" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "headers", + "http 0.2.12", + "hyper", + "log", + "mime", + "mime_guess", + "multer", + "percent-encoding", + "pin-project", + "scoped-tls", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-tungstenite", + "tokio-util", + "tower-service", + "tracing", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.85", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" + +[[package]] +name = "web-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] diff --git a/expander/Cargo.toml b/expander/Cargo.toml new file mode 100644 index 0000000..f532267 --- /dev/null +++ b/expander/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "expander_symmetric_crypto" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +console_error_panic_hook = "0.1.7" +web-sys = { version = "0.3", features = ["console"] } +wasm-bindgen = "0.2.95" +getrandom = { version = "0.2", features = ["js"] } + +expander_circuit = { path = "../../Expander/circuit", package = "circuit" } +expander_config = { path = "../../Expander/config", package = "config" } +expander_gkr = { path = "../../Expander/gkr", package = "gkr" } +expander_arith = { path = "../../Expander/arith", package = "arith" } +expander_transcript = { path = "../../Expander/transcript", package = "transcript" } +expander_compiler = { path = "../../ExpanderCompilerCollection/expander_compiler", package = "expander_compiler" } + +[dev-dependencies] +peak_alloc = "0.2.0" \ No newline at end of file diff --git a/expander/scripts/build-wasm.sh b/expander/scripts/build-wasm.sh new file mode 100644 index 0000000..272ca1f --- /dev/null +++ b/expander/scripts/build-wasm.sh @@ -0,0 +1,9 @@ +export MODE="${MODE:-release}" + +echo "Building $MODE wasm" + +wasm-pack build --target web --$MODE +mv pkg/expander_symmetric_crypto_bg.wasm ../resources/expander/$MODE.wasm + +mv pkg/expander_symmetric_crypto.js ../js/src/expander/wasm-binding.js +mv pkg/expander_symmetric_crypto.d.ts ../js/src/expander/wasm-binding.d.ts diff --git a/expander/serialise_witness.js b/expander/serialise_witness.js new file mode 100644 index 0000000..68a66b3 --- /dev/null +++ b/expander/serialise_witness.js @@ -0,0 +1,31 @@ + + +function serialiseWitness({ + public: publicInputs, + private: privateInputs, +}) { + return serialiseData(publicInputs) +} + +/** + * Serialises all values in the data object, in order, + * into a single Uint8Array. Will use 32 bytes for each + * value, and will pad with zeroes if the value is not + * exactly 32 bytes. + * + * @param {{ [_: string]: Uint8Array | (number | bigint)[] }} data + */ +function serialiseData(data) { + const values = Object.values(data) + .flatMap((key) => Array.isArray(key) ? key : Array.from(key)) + const serialised = new Uint8Array(values.length * 32) + const dataview = new DataView(serialised.buffer) + + for (const [i, value] of values.entries()) { + dataview.setBigUint64(i * 32, BigInt(value), true) + } + + return serialised +} + +module.exports = { serialiseWitness } \ No newline at end of file diff --git a/expander/src/lib.rs b/expander/src/lib.rs new file mode 100644 index 0000000..9377d85 --- /dev/null +++ b/expander/src/lib.rs @@ -0,0 +1,222 @@ +use std::{io::Cursor, panic}; + +use expander_arith::{Field, FieldSerde, FieldSerdeError}; +use expander_circuit::{Circuit, FromEccSerde, RecursiveCircuit}; +use expander_compiler::{frontend::{BN254Config, WitnessSolver}, utils::serde::Serde}; +use expander_config::{BN254ConfigKeccak, Config, GKRConfig, GKRScheme, MPIConfig}; +use expander_gkr::{Prover, Verifier}; +use expander_transcript::Proof; +use wasm_bindgen::prelude::*; + +extern crate web_sys; +extern crate console_error_panic_hook; + +type _ZKMode = BN254ConfigKeccak; +type _Circuit = Circuit<_ZKMode>; +type _WitnessSolver = WitnessSolver; +type ProofData = Vec; + +#[derive(Clone, Copy, Debug)] +#[wasm_bindgen] +pub enum SymmetricCryptoAlgorithm { + ChaCha20 = 0, +} + +#[derive(Debug)] +pub enum Error { + CircuitNotLoaded(SymmetricCryptoAlgorithm), + SolverNotLoaded(SymmetricCryptoAlgorithm), +} + +static mut CIRCUITS: Vec> = Vec::new(); +static mut SOLVERS: Vec> = Vec::new(); + +#[wasm_bindgen] +pub fn load_circuit(alg: SymmetricCryptoAlgorithm, bytes: Vec) { + prep(); + + let cursor = Cursor::new(bytes); + let rc = RecursiveCircuit::deserialize_from(cursor); + let circuit = rc.flatten(); + + set_circuit(alg, circuit); +} + +#[wasm_bindgen] +pub fn load_solver( + alg: SymmetricCryptoAlgorithm, + bytes: Vec, +) { + prep(); + + let cursor = Cursor::new(bytes); + let solver = <_WitnessSolver as expander_compiler::utils::serde::Serde> + ::deserialize_from(cursor).unwrap(); + let solver_static: &'static _WitnessSolver = Box::leak(Box::new(solver)); + + set_solver(alg, solver_static); +} + +#[wasm_bindgen] +pub fn is_circuit_loaded(alg: SymmetricCryptoAlgorithm) -> bool { + prep(); + return get_circuit(alg).is_ok(); +} + +#[wasm_bindgen] +pub fn is_solver_loaded(alg: SymmetricCryptoAlgorithm) -> bool { + prep(); + return get_solver(alg).is_ok(); +} + +#[wasm_bindgen] +pub fn prove( + alg: SymmetricCryptoAlgorithm, + priv_input_bits: Vec, + pub_input_bits: Vec, +) -> ProofData { + prep(); + + let solver = get_solver(alg).unwrap(); + let wtns = solver.solve_witness_from_raw_inputs( + map_to_circuit_fields(&priv_input_bits), + map_to_circuit_fields(&pub_input_bits), + ).unwrap(); + + let mut wtns_serialised = Vec::new(); + wtns.serialize_into(&mut wtns_serialised).unwrap(); + + let mut circuit = get_circuit(alg).unwrap(); + circuit.load_witness_bytes(&wtns_serialised, false); + + let mut prover = Prover::new(&get_config()); + prover.prepare_mem(&circuit); + + let (claimed_v, proof) = prover.prove(&mut circuit); + + return dump_proof_and_claimed_v(&proof, &claimed_v).unwrap(); +} + +#[wasm_bindgen] +pub fn verify( + alg: SymmetricCryptoAlgorithm, + pub_input_bits: Vec, + proof_data: ProofData +) -> bool { + prep(); + + let mut circuit: Circuit = get_circuit(alg).unwrap(); + + circuit.set_random_input_for_test(); + circuit.public_input = map_to_circuit_fields(&pub_input_bits); + circuit.evaluate(); + + let public_input = circuit.public_input.clone(); + let verifier = Verifier::new(&get_config()); + let (proof, claimed_v) = load_proof_and_claimed_v(&proof_data) + .unwrap(); + return verifier.verify(&mut circuit, &public_input, &claimed_v, &proof); +} + +fn set_circuit(alg: SymmetricCryptoAlgorithm, circuit: _Circuit) { + let alg_value = alg as usize; + unsafe { + // append to array till we reach the index + while CIRCUITS.len() <= alg_value { + CIRCUITS.push(None); + } + + CIRCUITS[alg_value] = Some(circuit); + } +} + +/** + * Retrieve clone of the circuit for the given algorithm, + * or return an error if the algorithm is not supported. + */ +fn get_circuit(alg: SymmetricCryptoAlgorithm) -> Result<_Circuit, Error> { + let alg_value = alg as usize; + unsafe { + if CIRCUITS.len() <= alg_value { + return Err(Error::CircuitNotLoaded(alg)); + } + + let circuit_opt = CIRCUITS[alg_value].clone(); + return circuit_opt.ok_or(Error::CircuitNotLoaded(alg)); + } +} + + +fn set_solver(alg: SymmetricCryptoAlgorithm, value: &'static _WitnessSolver) { + let alg_value = alg as usize; + unsafe { + // append to array till we reach the index + while SOLVERS.len() <= alg_value { + SOLVERS.push(None); + } + + SOLVERS[alg_value] = Some(value); + } +} + +/** + * Retrieve clone of the circuit for the given algorithm, + * or return an error if the algorithm is not supported. + */ +fn get_solver(alg: SymmetricCryptoAlgorithm) -> Result<&'static _WitnessSolver, Error> { + let alg_value = alg as usize; + unsafe { + if SOLVERS.len() <= alg_value { + return Err(Error::SolverNotLoaded(alg)); + } + + return SOLVERS[alg_value].ok_or(Error::SolverNotLoaded(alg)); + } +} + +fn get_config() -> Config<_ZKMode> { + let mpi_config = MPIConfig::new(); + let config = Config::<_ZKMode>::new(GKRScheme::Vanilla, mpi_config.clone()); + return config +} + +fn prep() { + panic::set_hook(Box::new(console_error_panic_hook::hook)); +} + +fn dump_proof_and_claimed_v( + proof: &Proof, + claimed_v: &F, +) -> Result, FieldSerdeError> { + let mut bytes = Vec::new(); + + proof.serialize_into(&mut bytes)?; + claimed_v.serialize_into(&mut bytes)?; + + Ok(bytes) +} + +fn load_proof_and_claimed_v( + bytes: &[u8], +) -> Result<(Proof, F), FieldSerdeError> { + let mut cursor = Cursor::new(bytes); + + let proof = Proof::deserialize_from(&mut cursor)?; + let claimed_v = F::deserialize_from(&mut cursor)?; + + Ok((proof, claimed_v)) +} + +fn map_to_circuit_fields(arr: &[u8]) -> Vec<::CircuitField> { + let mut pub_inputs = Vec::new(); + let sample = [0u8; 32]; + + for byte in arr { + let mut sample_mut = sample.clone(); + sample_mut[0] = *byte; + let value = ::CircuitField::from_uniform_bytes(&sample_mut); + pub_inputs.push(value); + } + + return pub_inputs; +} \ No newline at end of file diff --git a/expander/src/main.rs b/expander/src/main.rs new file mode 100644 index 0000000..937b305 --- /dev/null +++ b/expander/src/main.rs @@ -0,0 +1,51 @@ +mod lib; + +use lib::{load_circuit, load_solver, prove, SymmetricCryptoAlgorithm}; +// use peak_alloc::PeakAlloc; +use std::{fs, time::Instant}; + +//#[global_allocator] +//static PEAK_ALLOC: PeakAlloc = PeakAlloc; + +fn main() { + prove_circuit_file_inner( + "../resources/expander/chacha20.txt", + "../resources/expander/chacha20-solver.txt", + ); + println!("Hello, world!"); +} + +fn prove_circuit_file_inner( + circuit_filename: &str, + solver_filename: &str, +) { + let circuit_bytes = fs::read(circuit_filename).unwrap(); + let solver_bytes = fs::read(solver_filename).unwrap(); + let pub_bytes = fs::read("../resources/expander/pub.txt").unwrap(); + let priv_bytes = fs::read("../resources/expander/priv.txt").unwrap(); + + load_circuit(SymmetricCryptoAlgorithm::ChaCha20, circuit_bytes.clone()); + load_solver(SymmetricCryptoAlgorithm::ChaCha20, solver_bytes.clone()); + //solver.solve_witness_from_raw_inputs(vars, public_vars); + println!("yay done"); + // let wtns = Witness::deserialize_from(&witness_bytes[..]).unwrap(); + //let proof_bytes = fs::read("./pkg/proof.txt").unwrap(); + + let now = Instant::now(); + // let verified = verify(SymmetricCryptoAlgorithm::ChaCha20, witness_bytes, proof_bytes); + // println!("Verified: {}", verified); + for _ in 0..10 { + prove(SymmetricCryptoAlgorithm::ChaCha20, priv_bytes.clone(), pub_bytes.clone()); + } + + let elapsed = now.elapsed(); + println!("Elapsed: {:.2?}", elapsed); + //let current_mem = PEAK_ALLOC.peak_usage_as_mb(); + //println!("This program max used {} MB of RAM.", current_mem); + // let mut bytes = Vec::new(); + + // proof.(&mut bytes)?; + // claimed_v.serialize_into(&mut bytes)?; + + // Ok(bytes); +} \ No newline at end of file diff --git a/gnark/expandergen/expandergen.go b/gnark/expandergen/expandergen.go new file mode 100644 index 0000000..8a5c283 --- /dev/null +++ b/gnark/expandergen/expandergen.go @@ -0,0 +1,49 @@ +package main + +import ( + "fmt" + "gnark-symmetric-crypto/circuits/chachaV3" + "os" + + "github.com/PolyhedraZK/ExpanderCompilerCollection/ecgo" + "github.com/consensys/gnark-crypto/ecc" +) + +const GEN_FILES_DIR = "../resources/expander/" + +var CURVE = ecc.BN254.ScalarField() + +func main() { + err := generateChaChaV3() + if err != nil { + panic(err) + } +} + +func generateChaChaV3() error { + circuit, err := ecgo.Compile(ecc.BN254.ScalarField(), &chachaV3.ChaChaCircuit{}) + if err != nil { + return err + } + + c := circuit.GetLayeredCircuit() + solver := circuit.GetInputSolver() + + circuitfilename := GEN_FILES_DIR + "chacha20.txt" + err = os.WriteFile(circuitfilename, c.Serialize(), 0o644) + if err != nil { + return err + } + + fmt.Printf("generated circuit file: %s\n", circuitfilename) + + solverfilename := GEN_FILES_DIR + "chacha20-solver.txt" + err = os.WriteFile(solverfilename, solver.Serialize(), 0o644) + if err != nil { + return err + } + + fmt.Printf("generated solver file: %s\n", solverfilename) + + return nil +} diff --git a/gnark/scripts/build.sh b/gnark/scripts/build.sh index 44f495a..218bd74 100644 --- a/gnark/scripts/build.sh +++ b/gnark/scripts/build.sh @@ -4,21 +4,24 @@ if [ -z "${GOARCH}" ]; then fi export GOOS="${GOOS:-linux}" -OUT_PREFIX="../bin/gnark/$GOOS-$GOARCH-" +OUT_PREFIX="../bin/gnark/$GOOS-$GOARCH" set -e build() { - local module="$1" + local path="$1" + local module="$2" + CGO_ENABLED=1 go build \ -trimpath \ -ldflags '-s -w' \ -buildmode=c-shared \ -o "$OUT_PREFIX-$module.so" \ - libraries/prover/$module.go + $path/$module.go + rm "$OUT_PREFIX-$module.h" echo "Built $module" } -build "libprove" -build "libverify" +build "libraries/prover" "libprove" +build "libraries/verifier" "libverify" diff --git a/js/.eslintignore b/js/.eslintignore index 60ad458..8ac017f 100644 --- a/js/.eslintignore +++ b/js/.eslintignore @@ -1,4 +1,5 @@ lib node_modules bin -jest.config.js \ No newline at end of file +jest.config.js +src/expander/wasm-binding.* \ No newline at end of file diff --git a/js/package-lock.json b/js/package-lock.json index 9e4c7d1..80f7e38 100644 --- a/js/package-lock.json +++ b/js/package-lock.json @@ -10,7 +10,8 @@ "license": "See License in ", "dependencies": { "@stablelib/chacha20poly1305": "^1.0.0", - "js-base64": "^3.7.7" + "js-base64": "^3.7.7", + "p-queue": "^6.0.0" }, "devDependencies": { "@adiwajshing/eslint-config": "github:adiwajshing/eslint-config", @@ -27,6 +28,7 @@ "jest": "^29.7.0", "koffi": "^2.8.11", "snarkjs": "git+https://github.com/reclaimprotocol/snarkjs.git", + "tinybench": "^3.0.3", "typescript": "^5.2.2" }, "peerDependencies": { @@ -4804,6 +4806,12 @@ "node": ">=0.10.0" } }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -7569,6 +7577,15 @@ "@oxc-resolver/binding-win32-x64-msvc": "1.12.0" } }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -7611,6 +7628,34 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -8758,6 +8803,16 @@ "readable-stream": "3" } }, + "node_modules/tinybench": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-3.0.3.tgz", + "integrity": "sha512-uJx7Wn5Dp5qd2TBbbixMaFSxod6HvJxhA7rb55BJD27Gcsz+zoHRA/Gk8pBl91GiWbKtoGqU02XS8GOVJhe1KA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/tmp": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", diff --git a/js/package.json b/js/package.json index c508252..4c67aaa 100644 --- a/js/package.json +++ b/js/package.json @@ -4,7 +4,9 @@ "description": "JS Wrappers for Various ZK Snark Circuits", "main": "lib/index.js", "scripts": { - "test": "NODE_ENV=test jest --forceExit --detectOpenHandles", + "run:tsc": "SWC_NODE_IGNORE_DYNAMIC=true node -r @swc-node/register", + "test": "SWC_NODE_IGNORE_DYNAMIC=true NODE_ENV=test node --experimental-strip-types node_modules/.bin/jest --forceExit --detectOpenHandles", + "bench": "NODE_ENV=test npm run run:tsc -- ./src/tests/benchmark", "build": "npm exec tsc", "prepare": "npm run build", "commitlint": "commitlint --edit", @@ -47,7 +49,8 @@ }, "dependencies": { "@stablelib/chacha20poly1305": "^1.0.0", - "js-base64": "^3.7.7" + "js-base64": "^3.7.7", + "p-queue": "^6.0.0" }, "devDependencies": { "@adiwajshing/eslint-config": "github:adiwajshing/eslint-config", @@ -64,6 +67,7 @@ "jest": "^29.7.0", "koffi": "^2.8.11", "snarkjs": "git+https://github.com/reclaimprotocol/snarkjs.git", + "tinybench": "^3.0.3", "typescript": "^5.2.2" } } diff --git a/js/src/expander/node-worker.ts b/js/src/expander/node-worker.ts new file mode 100644 index 0000000..8db1b4c --- /dev/null +++ b/js/src/expander/node-worker.ts @@ -0,0 +1,122 @@ +import { isMainThread, parentPort, Worker, workerData } from 'worker_threads' +import type { Logger } from '../types' +import type { ErrorRPCMessage, RPCMessageMap, WorkerChannel, WorkerInitData } from './types' +import init, { prove } from './wasm-binding.js' + +const BYTES_PER_PAGE = 65536 +const logger: Logger = console + +type Output = [ + 'reply', + T | ErrorRPCMessage +] + +async function main() { + const { module, initialisationMemory } = workerData as WorkerInitData + const wasm = await init({ 'module_or_path': module }) + + const growthRequired = ( + initialisationMemory.byteLength - wasm.memory.buffer.byteLength + ) / BYTES_PER_PAGE + + if(growthRequired > 0) { + wasm.memory.grow(growthRequired) + logger.debug({ growthRequired }, 'memory grown') + } + + // copy initialisation memory + const memory = new Uint8Array(wasm.memory.buffer) + memory.set(initialisationMemory) + + logger.debug('worker initialised w memory') + + parentPort!.on('message', async(msg) => { + const [type, input] = msg as Parameters + if(type === 'prove') { + try { + const result = await prove(...input.args) + sendOutputRpcBack({ id: input.id!, result }) + + logger.debug({ id: input.id }, 'prove done') + } catch(err) { + logger.error({ err }, 'prove error') + sendOutputRpcBack({ + id: input.id!, + type: 'error', + message: err.message, + stack: err.stack + }) + } + + return + } + + throw new Error(`Unknown message type: ${type}`) + }) + + parentPort!.postMessage({ type: 'online' }) + + function sendOutputRpcBack( + output: RPCMessageMap[T]['output'] | ErrorRPCMessage + ) { + parentPort!.postMessage(['reply', output]) + } +} + +export async function initWorker(workerData: WorkerInitData) { + const worker = new Worker(__filename, { workerData }) + await new Promise((resolve, reject) => { + worker.once('message', resolve) + worker.once('error', reject) + }) + + const channel: WorkerChannel = { + rpc(type, input) { + input.id ||= createRpcId() + + const wait = waitForRpcReply< + RPCMessageMap[typeof type]['output'] + >(input.id) + worker.postMessage([type, input]) + return wait + }, + close() { + return worker.terminate() + } + } + + return channel + + async function waitForRpcReply(id: string) { + return new Promise((resolve, reject) => { + worker.on('message', listener) + worker.once('error', reject) + + async function listener([type, output]: Output) { + if(type !== 'reply' || output.id !== id) { + return + } + + worker.off('message', listener) + worker.off('error', reject) + + if('type' in output && output.type === 'error') { + const err = new Error(output.message) + err.stack = output.stack + reject(err) + return + } + + resolve(output as T) + } + }) + } +} + +function createRpcId() { + return Math.random().toString(36).slice(2) +} + +if(!isMainThread) { + main() +} diff --git a/js/src/expander/operator.ts b/js/src/expander/operator.ts new file mode 100644 index 0000000..b0b8377 --- /dev/null +++ b/js/src/expander/operator.ts @@ -0,0 +1,118 @@ +import { CONFIG } from '../config' +import { Logger, MakeZKOperatorOpts, ZKOperator } from '../types' +import { initWorker } from './node-worker' +import { loadCircuitIfRequired, loadExpander, loadProverCircuitIfRequired, makeWorkerPool } from './utils' +import { prove, verify } from './wasm-binding' + +let wasmInit: ReturnType | undefined + +export type ExpanderOpts = { + /** + * Number of parallel workers to use. + * Set to 0 to disable parallelism. + * @default 0 + */ + maxWorkers?: number +} + +export function makeExpanderZkOperator({ + algorithm, + fetcher, + options: { maxWorkers = 0 } = {} +}: MakeZKOperatorOpts): ZKOperator { + const { index: id, keySizeBytes } = CONFIG[algorithm] + const workerPool = maxWorkers + ? makeWorkerPool(maxWorkers, _initWorker) + : undefined + + let proverLoader: Promise | undefined + let circuitLoader: Promise | undefined + + return { + generateWitness(input) { + const witness = new Uint8Array([ + // let's just call this the version flag + 1, + ...input.counter, + ...input.nonce, + ...input.in, + ...input.out, + ...input.key + ]) + return witness + }, + async groth16Prove(witness, logger) { + const version = readFromWitness(1)[0] + if(version !== 1) { + throw new Error(`Unsupported witness version: ${version}`) + } + + const pubBits = readFromWitness(-keySizeBytes * 8) + const privBits = witness + + await loadProverAsRequired(logger) + if(!workerPool) { + const bytes = prove(id, privBits, pubBits) + return { proof: bytes } + } + + const worker = await workerPool.getNext() + const { result: proof } = await ( + worker.rpc('prove', { args: [id, privBits, pubBits] }) + ) + + return { proof } + + function readFromWitness(length: number) { + const result = witness.slice(0, length) + witness = witness.slice(length) + return result + } + }, + async groth16Verify(publicSignals, proof, logger) { + if(!(proof instanceof Uint8Array)) { + throw new Error('Expected proof to be binary') + } + + await loadCircuitAsRequired(logger) + + const pubSignals = new Uint8Array([ + ...publicSignals.counter, + ...publicSignals.nonce, + ...publicSignals.in, + ...publicSignals.out, + ]) + + return verify(id, pubSignals, proof) + }, + release() { + return workerPool?.release() + } + } + + async function loadProverAsRequired(logger?: Logger) { + wasmInit ||= loadExpander(fetcher, logger) + await wasmInit + + proverLoader ||= loadProverCircuitIfRequired(algorithm, fetcher, logger) + circuitLoader ||= loadCircuitIfRequired(algorithm, fetcher, logger) + await Promise.all([proverLoader, circuitLoader]) + } + + async function loadCircuitAsRequired(logger?: Logger) { + wasmInit ||= loadExpander(fetcher, logger) + await wasmInit + + circuitLoader ||= loadCircuitIfRequired(algorithm, fetcher, logger) + await circuitLoader + } +} + +async function _initWorker() { + const { wasm, module } = await wasmInit! + + return initWorker({ + module, + initialisationMemory: new Uint8Array(wasm.memory.buffer), + }) +} \ No newline at end of file diff --git a/js/src/expander/types.ts b/js/src/expander/types.ts new file mode 100644 index 0000000..8d7f11f --- /dev/null +++ b/js/src/expander/types.ts @@ -0,0 +1,39 @@ +import type { prove } from './wasm-binding' + +export type WorkerInitData = { + module: Uint8Array + initialisationMemory: Uint8Array +} + +export type WorkerPool = { + getNext(): Promise + release(): Promise +} + +export type ErrorRPCMessage = { + id: string + type: 'error' + message: string + stack?: string +} + +export type RPCMessageMap = { + 'prove': { + input: { + id?: string + args: Parameters + } + output: { + id: string + result: Uint8Array + } + } +} + +export type WorkerChannel = { + rpc( + type: R, + payload: RPCMessageMap[R]['input'] + ): Promise + close(): void +} \ No newline at end of file diff --git a/js/src/expander/utils.ts b/js/src/expander/utils.ts new file mode 100644 index 0000000..5ab5b3e --- /dev/null +++ b/js/src/expander/utils.ts @@ -0,0 +1,93 @@ +import { EncryptionAlgorithm, FileFetch, Logger } from '../types' +import { WorkerChannel, WorkerPool } from './types' +import init, { is_circuit_loaded, is_solver_loaded, load_circuit, load_solver } from './wasm-binding' + +const BIN_NAME = 'release' + +export async function loadExpander( + fetcher: FileFetch, + logger?: Logger +) { + const buff = await fetcher + .fetch('expander', `${BIN_NAME}.wasm`, logger) + const wasm = await init({ 'module_or_path': buff }) + return { wasm, module: buff } +} + +export async function loadCircuitIfRequired( + alg: EncryptionAlgorithm, + fetcher: FileFetch, + logger?: Logger +) { + const id = 0 + if(is_circuit_loaded(id)) { + return + } + + logger?.debug({ alg }, 'fetching circuit') + + const circuit = await fetcher.fetch( + 'expander', + `${alg}.txt` + ) + + logger?.debug({ alg }, 'circuit fetched, loading...') + + load_circuit(id, circuit) + + logger?.debug({ alg }, 'circuit loaded') +} + +export async function loadProverCircuitIfRequired( + alg: EncryptionAlgorithm, + fetcher: FileFetch, + logger?: Logger +) { + const id = 0 + if(is_solver_loaded(id)) { + return + } + + logger?.debug({ alg }, 'fetching solver') + + const circuit = await fetcher.fetch( + 'expander', + `${alg}-solver.txt` + ) + + logger?.debug({ alg }, 'solver fetched, loading...') + + load_solver(id, circuit) + + logger?.debug({ alg }, 'solver loaded') +} + +export function makeWorkerPool( + maxWorkers: number, + initWorker: () => Promise, +): WorkerPool { + let pool: Promise[] = [] + let nextIdx = 0 + + return { + getNext() { + if(pool.length < maxWorkers) { + pool.push(initWorker()) + } + + const worker = pool[nextIdx] + nextIdx = (nextIdx + 1) % pool.length + + return worker + }, + async release() { + const _pool = pool + pool = [] + + for(const worker of _pool) { + const _res = await worker.catch(() => undefined) + _res?.close() + } + }, + } +} \ No newline at end of file diff --git a/js/src/expander/wasm-binding.d.ts b/js/src/expander/wasm-binding.d.ts new file mode 100644 index 0000000..cb567a1 --- /dev/null +++ b/js/src/expander/wasm-binding.d.ts @@ -0,0 +1,79 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * @param {SymmetricCryptoAlgorithm} alg + * @param {Uint8Array} bytes + */ +export function load_circuit(alg: SymmetricCryptoAlgorithm, bytes: Uint8Array): void; +/** + * @param {SymmetricCryptoAlgorithm} alg + * @param {Uint8Array} bytes + */ +export function load_solver(alg: SymmetricCryptoAlgorithm, bytes: Uint8Array): void; +/** + * @param {SymmetricCryptoAlgorithm} alg + * @returns {boolean} + */ +export function is_circuit_loaded(alg: SymmetricCryptoAlgorithm): boolean; +/** + * @param {SymmetricCryptoAlgorithm} alg + * @returns {boolean} + */ +export function is_solver_loaded(alg: SymmetricCryptoAlgorithm): boolean; +/** + * @param {SymmetricCryptoAlgorithm} alg + * @param {Uint8Array} priv_input_bits + * @param {Uint8Array} pub_input_bits + * @returns {Uint8Array} + */ +export function prove(alg: SymmetricCryptoAlgorithm, priv_input_bits: Uint8Array, pub_input_bits: Uint8Array): Uint8Array; +/** + * @param {SymmetricCryptoAlgorithm} alg + * @param {Uint8Array} pub_input_bits + * @param {Uint8Array} proof_data + * @returns {boolean} + */ +export function verify(alg: SymmetricCryptoAlgorithm, pub_input_bits: Uint8Array, proof_data: Uint8Array): boolean; +export enum SymmetricCryptoAlgorithm { + ChaCha20 = 0, +} + +export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; + +export interface InitOutput { + readonly memory: WebAssembly.Memory; + readonly load_circuit: (a: number, b: number, c: number) => void; + readonly load_solver: (a: number, b: number, c: number) => void; + readonly is_circuit_loaded: (a: number) => number; + readonly is_solver_loaded: (a: number) => number; + readonly prove: (a: number, b: number, c: number, d: number, e: number) => Array; + readonly verify: (a: number, b: number, c: number, d: number, e: number) => number; + readonly __wbindgen_export_0: WebAssembly.Table; + readonly __wbindgen_malloc: (a: number, b: number) => number; + readonly __wbindgen_free: (a: number, b: number, c: number) => void; + readonly __wbindgen_exn_store: (a: number) => void; + readonly __externref_table_alloc: () => number; + readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; + readonly __wbindgen_start: () => void; +} + +export type SyncInitInput = BufferSource | WebAssembly.Module; +/** +* Instantiates the given `module`, which can either be bytes or +* a precompiled `WebAssembly.Module`. +* +* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated. +* +* @returns {InitOutput} +*/ +export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput; + +/** +* If `module_or_path` is {RequestInfo} or {URL}, makes a request and +* for everything else, calls `WebAssembly.instantiate` directly. +* +* @param {{ module_or_path: InitInput | Promise }} module_or_path - Passing `InitInput` directly is deprecated. +* +* @returns {Promise} +*/ +export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise } | InitInput | Promise): Promise; diff --git a/js/src/expander/wasm-binding.js b/js/src/expander/wasm-binding.js new file mode 100644 index 0000000..2bdaf3e --- /dev/null +++ b/js/src/expander/wasm-binding.js @@ -0,0 +1,431 @@ +let wasm; + +const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } ); + +if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); }; + +let cachedUint8ArrayMemory0 = null; + +function getUint8ArrayMemory0() { + if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) { + cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8ArrayMemory0; +} + +function getStringFromWasm0(ptr, len) { + ptr = ptr >>> 0; + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + +let WASM_VECTOR_LEN = 0; + +function passArray8ToWasm0(arg, malloc) { + const ptr = malloc(arg.length * 1, 1) >>> 0; + getUint8ArrayMemory0().set(arg, ptr / 1); + WASM_VECTOR_LEN = arg.length; + return ptr; +} +/** + * @param {SymmetricCryptoAlgorithm} alg + * @param {Uint8Array} bytes + */ +export function load_circuit(alg, bytes) { + const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + wasm.load_circuit(alg, ptr0, len0); +} + +/** + * @param {SymmetricCryptoAlgorithm} alg + * @param {Uint8Array} bytes + */ +export function load_solver(alg, bytes) { + const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + wasm.load_solver(alg, ptr0, len0); +} + +/** + * @param {SymmetricCryptoAlgorithm} alg + * @returns {boolean} + */ +export function is_circuit_loaded(alg) { + const ret = wasm.is_circuit_loaded(alg); + return ret !== 0; +} + +/** + * @param {SymmetricCryptoAlgorithm} alg + * @returns {boolean} + */ +export function is_solver_loaded(alg) { + const ret = wasm.is_solver_loaded(alg); + return ret !== 0; +} + +function getArrayU8FromWasm0(ptr, len) { + ptr = ptr >>> 0; + return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len); +} +/** + * @param {SymmetricCryptoAlgorithm} alg + * @param {Uint8Array} priv_input_bits + * @param {Uint8Array} pub_input_bits + * @returns {Uint8Array} + */ +export function prove(alg, priv_input_bits, pub_input_bits) { + const ptr0 = passArray8ToWasm0(priv_input_bits, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passArray8ToWasm0(pub_input_bits, wasm.__wbindgen_malloc); + const len1 = WASM_VECTOR_LEN; + const ret = wasm.prove(alg, ptr0, len0, ptr1, len1); + var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); + return v3; +} + +/** + * @param {SymmetricCryptoAlgorithm} alg + * @param {Uint8Array} pub_input_bits + * @param {Uint8Array} proof_data + * @returns {boolean} + */ +export function verify(alg, pub_input_bits, proof_data) { + const ptr0 = passArray8ToWasm0(pub_input_bits, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passArray8ToWasm0(proof_data, wasm.__wbindgen_malloc); + const len1 = WASM_VECTOR_LEN; + const ret = wasm.verify(alg, ptr0, len0, ptr1, len1); + return ret !== 0; +} + +function addToExternrefTable0(obj) { + const idx = wasm.__externref_table_alloc(); + wasm.__wbindgen_export_0.set(idx, obj); + return idx; +} + +function handleError(f, args) { + try { + return f.apply(this, args); + } catch (e) { + const idx = addToExternrefTable0(e); + wasm.__wbindgen_exn_store(idx); + } +} + +const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } ); + +const encodeString = (typeof cachedTextEncoder.encodeInto === 'function' + ? function (arg, view) { + return cachedTextEncoder.encodeInto(arg, view); +} + : function (arg, view) { + const buf = cachedTextEncoder.encode(arg); + view.set(buf); + return { + read: arg.length, + written: buf.length + }; +}); + +function passStringToWasm0(arg, malloc, realloc) { + + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg); + const ptr = malloc(buf.length, 1) >>> 0; + getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf); + WASM_VECTOR_LEN = buf.length; + return ptr; + } + + let len = arg.length; + let ptr = malloc(len, 1) >>> 0; + + const mem = getUint8ArrayMemory0(); + + let offset = 0; + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset); + } + ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0; + const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len); + const ret = encodeString(arg, view); + + offset += ret.written; + ptr = realloc(ptr, len, offset, 1) >>> 0; + } + + WASM_VECTOR_LEN = offset; + return ptr; +} + +let cachedDataViewMemory0 = null; + +function getDataViewMemory0() { + if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) { + cachedDataViewMemory0 = new DataView(wasm.memory.buffer); + } + return cachedDataViewMemory0; +} + +export const SymmetricCryptoAlgorithm = Object.freeze({ ChaCha20:0,"0":"ChaCha20", }); + +async function __wbg_load(module, imports) { + if (typeof Response === 'function' && module instanceof Response) { + if (typeof WebAssembly.instantiateStreaming === 'function') { + try { + return await WebAssembly.instantiateStreaming(module, imports); + + } catch (e) { + if (module.headers.get('Content-Type') != 'application/wasm') { + console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); + + } else { + throw e; + } + } + } + + const bytes = await module.arrayBuffer(); + return await WebAssembly.instantiate(bytes, imports); + + } else { + const instance = await WebAssembly.instantiate(module, imports); + + if (instance instanceof WebAssembly.Instance) { + return { instance, module }; + + } else { + return instance; + } + } +} + +function __wbg_get_imports() { + const imports = {}; + imports.wbg = {}; + imports.wbg.__wbg_crypto_1d1f22824a6a080c = function(arg0) { + const ret = arg0.crypto; + return ret; + }; + imports.wbg.__wbindgen_is_object = function(arg0) { + const val = arg0; + const ret = typeof(val) === 'object' && val !== null; + return ret; + }; + imports.wbg.__wbg_process_4a72847cc503995b = function(arg0) { + const ret = arg0.process; + return ret; + }; + imports.wbg.__wbg_versions_f686565e586dd935 = function(arg0) { + const ret = arg0.versions; + return ret; + }; + imports.wbg.__wbg_node_104a2ff8d6ea03a2 = function(arg0) { + const ret = arg0.node; + return ret; + }; + imports.wbg.__wbindgen_is_string = function(arg0) { + const ret = typeof(arg0) === 'string'; + return ret; + }; + imports.wbg.__wbg_require_cca90b1a94a0255b = function() { return handleError(function () { + const ret = module.require; + return ret; + }, arguments) }; + imports.wbg.__wbindgen_is_function = function(arg0) { + const ret = typeof(arg0) === 'function'; + return ret; + }; + imports.wbg.__wbindgen_string_new = function(arg0, arg1) { + const ret = getStringFromWasm0(arg0, arg1); + return ret; + }; + imports.wbg.__wbg_msCrypto_eb05e62b530a1508 = function(arg0) { + const ret = arg0.msCrypto; + return ret; + }; + imports.wbg.__wbg_randomFillSync_5c9c955aa56b6049 = function() { return handleError(function (arg0, arg1) { + arg0.randomFillSync(arg1); + }, arguments) }; + imports.wbg.__wbg_getRandomValues_3aa56aa6edec874c = function() { return handleError(function (arg0, arg1) { + arg0.getRandomValues(arg1); + }, arguments) }; + imports.wbg.__wbg_new_abda76e883ba8a5f = function() { + const ret = new Error(); + return ret; + }; + imports.wbg.__wbg_stack_658279fe44541cf6 = function(arg0, arg1) { + const ret = arg1.stack; + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }; + imports.wbg.__wbg_error_f851667af71bcfc6 = function(arg0, arg1) { + let deferred0_0; + let deferred0_1; + try { + deferred0_0 = arg0; + deferred0_1 = arg1; + console.error(getStringFromWasm0(arg0, arg1)); + } finally { + wasm.__wbindgen_free(deferred0_0, deferred0_1, 1); + } + }; + imports.wbg.__wbg_newnoargs_1ede4bf2ebbaaf43 = function(arg0, arg1) { + const ret = new Function(getStringFromWasm0(arg0, arg1)); + return ret; + }; + imports.wbg.__wbg_call_a9ef466721e824f2 = function() { return handleError(function (arg0, arg1) { + const ret = arg0.call(arg1); + return ret; + }, arguments) }; + imports.wbg.__wbg_self_bf91bf94d9e04084 = function() { return handleError(function () { + const ret = self.self; + return ret; + }, arguments) }; + imports.wbg.__wbg_window_52dd9f07d03fd5f8 = function() { return handleError(function () { + const ret = window.window; + return ret; + }, arguments) }; + imports.wbg.__wbg_globalThis_05c129bf37fcf1be = function() { return handleError(function () { + const ret = globalThis.globalThis; + return ret; + }, arguments) }; + imports.wbg.__wbg_global_3eca19bb09e9c484 = function() { return handleError(function () { + const ret = global.global; + return ret; + }, arguments) }; + imports.wbg.__wbindgen_is_undefined = function(arg0) { + const ret = arg0 === undefined; + return ret; + }; + imports.wbg.__wbg_call_3bfa248576352471 = function() { return handleError(function (arg0, arg1, arg2) { + const ret = arg0.call(arg1, arg2); + return ret; + }, arguments) }; + imports.wbg.__wbg_buffer_ccaed51a635d8a2d = function(arg0) { + const ret = arg0.buffer; + return ret; + }; + imports.wbg.__wbg_newwithbyteoffsetandlength_7e3eb787208af730 = function(arg0, arg1, arg2) { + const ret = new Uint8Array(arg0, arg1 >>> 0, arg2 >>> 0); + return ret; + }; + imports.wbg.__wbg_new_fec2611eb9180f95 = function(arg0) { + const ret = new Uint8Array(arg0); + return ret; + }; + imports.wbg.__wbg_set_ec2fcf81bc573fd9 = function(arg0, arg1, arg2) { + arg0.set(arg1, arg2 >>> 0); + }; + imports.wbg.__wbg_newwithlength_76462a666eca145f = function(arg0) { + const ret = new Uint8Array(arg0 >>> 0); + return ret; + }; + imports.wbg.__wbg_subarray_975a06f9dbd16995 = function(arg0, arg1, arg2) { + const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0); + return ret; + }; + imports.wbg.__wbindgen_throw = function(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); + }; + imports.wbg.__wbindgen_memory = function() { + const ret = wasm.memory; + return ret; + }; + imports.wbg.__wbindgen_init_externref_table = function() { + const table = wasm.__wbindgen_export_0; + const offset = table.grow(4); + table.set(0, undefined); + table.set(offset + 0, undefined); + table.set(offset + 1, null); + table.set(offset + 2, true); + table.set(offset + 3, false); + ; + }; + + return imports; +} + +function __wbg_init_memory(imports, memory) { + +} + +function __wbg_finalize_init(instance, module) { + wasm = instance.exports; + __wbg_init.__wbindgen_wasm_module = module; + cachedDataViewMemory0 = null; + cachedUint8ArrayMemory0 = null; + + + wasm.__wbindgen_start(); + return wasm; +} + +function initSync(module) { + if (wasm !== undefined) return wasm; + + + if (typeof module !== 'undefined') { + if (Object.getPrototypeOf(module) === Object.prototype) { + ({module} = module) + } else { + console.warn('using deprecated parameters for `initSync()`; pass a single object instead') + } + } + + const imports = __wbg_get_imports(); + + __wbg_init_memory(imports); + + if (!(module instanceof WebAssembly.Module)) { + module = new WebAssembly.Module(module); + } + + const instance = new WebAssembly.Instance(module, imports); + + return __wbg_finalize_init(instance, module); +} + +async function __wbg_init(module_or_path) { + if (wasm !== undefined) return wasm; + + + if (typeof module_or_path !== 'undefined') { + if (Object.getPrototypeOf(module_or_path) === Object.prototype) { + ({module_or_path} = module_or_path) + } else { + console.warn('using deprecated parameters for the initialization function; pass a single object instead') + } + } + + if (typeof module_or_path === 'undefined') { + module_or_path = new URL('expander_symmetric_crypto_bg.wasm', import.meta.url); + } + const imports = __wbg_get_imports(); + + if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) { + module_or_path = fetch(module_or_path); + } + + __wbg_init_memory(imports); + + const { instance, module } = await __wbg_load(await module_or_path, imports); + + return __wbg_finalize_init(instance, module); +} + +export { initSync }; +export default __wbg_init; diff --git a/js/src/gnark/operator.ts b/js/src/gnark/operator.ts index 5e1979b..7680548 100644 --- a/js/src/gnark/operator.ts +++ b/js/src/gnark/operator.ts @@ -41,7 +41,12 @@ export function makeGnarkZkOperator({ cipher: algorithm, proof: proofStr, publicSignals: Base64.fromUint8Array( - bitsToUint8Array(publicSignals.flat()) + bitsToUint8Array([ + ...publicSignals.out, + ...publicSignals.nonce, + ...publicSignals.counter, + ...publicSignals.in + ]) ), } diff --git a/js/src/gnark/utils.ts b/js/src/gnark/utils.ts index cb0379e..2fa6dbd 100644 --- a/js/src/gnark/utils.ts +++ b/js/src/gnark/utils.ts @@ -27,14 +27,14 @@ const ARCH_MAP = { } export async function loadGnarkLib(): Promise { - const koffi = await import('koffi') + const koffiMod = await import('koffi') .catch(() => undefined) - if(!koffi) { + if(!koffiMod) { throw new Error('Koffi not available, cannot use gnark') } const { join } = await import('path') - + const { default: koffi } = koffiMod koffi.reset() //otherwise tests will fail // define object GoSlice to map to: diff --git a/js/src/index.ts b/js/src/index.ts index c2ccd5a..3883e0f 100644 --- a/js/src/index.ts +++ b/js/src/index.ts @@ -1,6 +1,7 @@ export * from './zk' export * from './snarkjs/operator' export * from './gnark/operator' +export * from './expander/operator' export * from './types' export * from './utils' export * from './config' diff --git a/js/src/snarkjs/operator.ts b/js/src/snarkjs/operator.ts index ca378e2..6d57825 100644 --- a/js/src/snarkjs/operator.ts +++ b/js/src/snarkjs/operator.ts @@ -1,3 +1,4 @@ +import PQueue from 'p-queue' import { CircuitWasm, Logger, MakeZKOperatorOpts, VerificationKey, ZKOperator } from '../types' type WitnessData = { @@ -5,6 +6,10 @@ type WitnessData = { data?: Uint8Array } +type SnarkJSOpts = { + maxProofConcurrency?: number +} + // 5 pages is enough for the witness data // calculation const WITNESS_MEMORY_SIZE_PAGES = 5 @@ -32,15 +37,17 @@ const WITNESS_MEMORY_SIZE_PAGES = 5 */ export function makeSnarkJsZKOperator({ algorithm, - fetcher -}: MakeZKOperatorOpts<{}>): ZKOperator { - // require here to avoid loading snarkjs in - // any unsupported environments - const snarkjs = require('snarkjs') + fetcher, + options: { maxProofConcurrency = 2 } = {} +}: MakeZKOperatorOpts): ZKOperator { let zkey: Promise | VerificationKey | undefined let circuitWasm: Promise | CircuitWasm | undefined let wc: Promise | undefined + const snarkjs = loadSnarkjs() + + const concurrencyLimiter = new PQueue({ concurrency: maxProofConcurrency }) + return { // eslint-disable-next-line @typescript-eslint/no-unused-vars async generateWitness({ out, ...input }, logger) { @@ -92,13 +99,21 @@ export function makeSnarkJsZKOperator({ async groth16Prove(witness, logger) { zkey ||= getZkey() const { data } = await zkey - return snarkjs.groth16.prove( - data, - witness, - logger - ) + + const { proof } = await concurrencyLimiter.add(() => ( + snarkjs.groth16.prove( + data, + witness, + logger + ) + )) + return { proof: JSON.stringify(proof) } }, async groth16Verify(publicSignals, proof, logger) { + if(typeof proof !== 'string') { + throw new Error('Proof must be a string') + } + zkey ||= getZkey() const zkeyResult = await zkey if(!zkeyResult.json) { @@ -108,8 +123,13 @@ export function makeSnarkJsZKOperator({ return snarkjs.groth16.verify( zkeyResult.json, - publicSignals, - proof, + [ + ...publicSignals.out, + ...publicSignals.nonce, + ...publicSignals.counter, + ...publicSignals.in + ], + JSON.parse(proof), logger ) }, @@ -129,4 +149,8 @@ export function makeSnarkJsZKOperator({ .fetch('snarkjs', `${algorithm}/circuit_final.zkey`, logger) return { data } } +} + +function loadSnarkjs() { + return require('snarkjs') } \ No newline at end of file diff --git a/js/src/tests/benchmark.ts b/js/src/tests/benchmark.ts new file mode 100644 index 0000000..b8045e0 --- /dev/null +++ b/js/src/tests/benchmark.ts @@ -0,0 +1,108 @@ +import { randomBytes } from 'crypto' +import { Bench } from 'tinybench' +import { CONFIG } from '../config' +import { EncryptionAlgorithm, PrivateInput, PublicInput, ZKOperator } from '../types' +import { generateZkWitness } from '../zk' +import { encryptData, ZK_CONFIG_MAP, ZK_CONFIGS } from './utils' + +const ALL_ALGOS: EncryptionAlgorithm[] = [ + 'chacha20', + //'aes-256-ctr', + //'aes-128-ctr', +] + +const DATA_LENGTH = 1024 + +const BENCHES = ALL_ALGOS.map((algo) => { + let bench = new Bench({ + name: `Generate Proof - ${algo}`, + iterations: 1, + }) + + for(const engine of ZK_CONFIGS) { + const operator = ZK_CONFIG_MAP[engine](algo) + let witnesses: Uint8Array[] + bench = bench.add( + engine, + async() => { + try { + const now = Date.now() + await Promise.all( + witnesses.map((witness) => ( + operator.groth16Prove(witness) + )) + ) + const elapsed = Date.now() - now + console.log( + `Generated ${witnesses.length} proofs for ${algo} using ${engine}, ${elapsed}ms` + ) + } catch(err) { + console.error(err) + } + }, + { + beforeEach: async() => { + witnesses = await prepareDataForAlgo(algo, operator) + console.log( + `Prepared ${witnesses.length} witnesses for ${algo} using ${engine}` + ) + }, + } + ) + } + + return bench +}) + +async function main() { + for(const bench of BENCHES) { + await bench.run() + + console.log(bench.name) + console.table(bench.table()) + } +} + +async function prepareDataForAlgo( + algo: EncryptionAlgorithm, + operator: ZKOperator +) { + const { keySizeBytes, chunkSize, bitsPerWord } = CONFIG[algo] + const plaintext = new Uint8Array(randomBytes(DATA_LENGTH)) + const privateInput: PrivateInput = { + key: Buffer.alloc(keySizeBytes, 2), + } + + const iv = new Uint8Array(12).fill(0) + + const ciphertext = encryptData( + algo, + plaintext, + privateInput.key, + iv + ) + + const witnesses: Uint8Array[] = [] + const chunkSizeBytes = chunkSize * bitsPerWord / 8 + + for(let i = 0; i < ciphertext.length; i += chunkSizeBytes) { + const publicInput: PublicInput = { + ciphertext: ciphertext.subarray(i, i + chunkSizeBytes), + iv: iv, + offset: i + } + const { witness } = await generateZkWitness({ + algorithm: algo, + privateInput, + publicInput, + operator + }) + + witnesses.push(witness) + } + + return witnesses +} + +main() + diff --git a/js/src/tests/lib.test.ts b/js/src/tests/lib.test.ts index 1c96f0d..7eb42b0 100644 --- a/js/src/tests/lib.test.ts +++ b/js/src/tests/lib.test.ts @@ -3,22 +3,19 @@ import { CONFIG, EncryptionAlgorithm, generateProof, - makeGnarkZkOperator, - makeLocalFileFetch, - makeSnarkJsZKOperator, PrivateInput, verifyProof, - ZKEngine, ZKOperator, } from '../index' -import { encryptData } from './utils' +import { encryptData, ZK_CONFIG_MAP, ZK_CONFIGS } from './utils' jest.setTimeout(20_000) +// TODO: add back AES tests const ALL_ALGOS: EncryptionAlgorithm[] = [ 'chacha20', - 'aes-256-ctr', - 'aes-128-ctr', + //'aes-256-ctr', + //'aes-128-ctr', ] const ALG_TEST_CONFIG = { @@ -33,26 +30,9 @@ const ALG_TEST_CONFIG = { }, } -const fetcher = makeLocalFileFetch() - -const ALL_ZK_ENGINES: { - [E in ZKEngine]: (algorithm: EncryptionAlgorithm) => ZKOperator -} = { - 'snarkjs': (algorithm) => ( - makeSnarkJsZKOperator({ algorithm, fetcher }) - ), - 'gnark': (algorithm) => ( - makeGnarkZkOperator({ algorithm, fetcher }) - ), -} - -const ZK_ENGINES = Object.keys(ALL_ZK_ENGINES) as ZKEngine[] - describe.each(ALL_ALGOS)('%s Lib Tests', (algorithm) => { - describe.each(ZK_ENGINES)('%s engine', (zkEngine) => { - const { - encLength, - } = ALG_TEST_CONFIG[algorithm] + describe.each(ZK_CONFIGS)('%s engine', (zkEngine) => { + const { encLength } = ALG_TEST_CONFIG[algorithm] const { bitsPerWord, chunkSize, @@ -63,7 +43,11 @@ describe.each(ALL_ALGOS)('%s Lib Tests', (algorithm) => { let operator: ZKOperator beforeAll(async() => { - operator = await ALL_ZK_ENGINES[zkEngine](algorithm) + operator = await ZK_CONFIG_MAP[zkEngine](algorithm) + }) + + afterEach(async() => { + await operator.release?.() }) it('should verify encrypted data', async() => { diff --git a/js/src/tests/utils.ts b/js/src/tests/utils.ts index 3c55f70..aec6b81 100644 --- a/js/src/tests/utils.ts +++ b/js/src/tests/utils.ts @@ -1,7 +1,15 @@ import { wasm as WasmTester } from 'circom_tester' import { createCipheriv } from 'crypto' +import { cpus } from 'os' import { join } from 'path' -import { EncryptionAlgorithm } from '../types' +import { + EncryptionAlgorithm, + makeExpanderZkOperator, + makeGnarkZkOperator, + makeLocalFileFetch, + makeSnarkJsZKOperator, + ZKOperator +} from '../index' export function encryptData( algorithm: EncryptionAlgorithm, @@ -29,4 +37,42 @@ export function encryptData( export function loadCircuit(name: string) { return WasmTester(join(__dirname, `../../circuits/tests/${name}.circom`)) -} \ No newline at end of file +} + +const fetcher = makeLocalFileFetch() + +type ConfigItem = 'snarkjs' + | 'gnark' + | 'expander-single-thread' + | 'expander-multi-thread' + +export const ZK_CONFIG_MAP: { + [E in ConfigItem]: (algorithm: EncryptionAlgorithm) => ZKOperator +} = { + 'snarkjs': (algorithm) => ( + makeSnarkJsZKOperator({ + algorithm, + fetcher, + options: { maxProofConcurrency: 2 } + }) + ), + 'gnark': (algorithm) => ( + makeGnarkZkOperator({ algorithm, fetcher }) + ), + 'expander-single-thread': (algorithm) => ( + makeExpanderZkOperator({ + algorithm, + fetcher, + options: { maxWorkers: 0 } + }) + ), + 'expander-multi-thread': (algorithm) => ( + makeExpanderZkOperator({ + algorithm, + fetcher, + options: { maxWorkers: cpus().length } + }) + ), +} + +export const ZK_CONFIGS = Object.keys(ZK_CONFIG_MAP) as ConfigItem[] \ No newline at end of file diff --git a/js/src/types.ts b/js/src/types.ts index 42f3935..9bc3d75 100644 --- a/js/src/types.ts +++ b/js/src/types.ts @@ -2,7 +2,7 @@ export type EncryptionAlgorithm = 'aes-256-ctr' | 'aes-128-ctr' | 'chacha20' -export type ZKEngine = 'snarkjs' | 'gnark' +export type ZKEngine = 'snarkjs' | 'gnark' | 'expander' // the Array type used in the circuit // it's a Uint32Array, as all ChaCha20 operations @@ -11,8 +11,8 @@ export type UintArray = Uint32Array export type Proof = { algorithm: EncryptionAlgorithm - /** serialised SnarkJS proof */ - proofJson: string + /** serialised proof */ + proofData: ZKProof /** * the plaintext obtained as an output * of the ZK circuit @@ -105,23 +105,26 @@ export type AlgorithmConfig = { }): Promise | Uint8Array } -type ZKProof = { [_: string]: unknown } | string +type ZKProof = string | Uint8Array type ZKProofOutput = { proof: ZKProof publicSignals?: number[] } -type ZKInputItem = number[] | number[][] +type ZKInputItem = number[] -type ZKProofInput = { - key: ZKInputItem +type ZKProofPublicSignals = { nonce: ZKInputItem counter: ZKInputItem in: ZKInputItem out: ZKInputItem } +type ZKProofAllSignals = { + key: ZKInputItem +} & ZKProofPublicSignals + /** * the operator to use for proving and verifying the groth16 * proof of the ChaCha20 circuit @@ -130,10 +133,13 @@ type ZKProofInput = { * for different implementations */ export type ZKOperator = { - generateWitness(input: ZKProofInput, logger?: Logger): Promise + generateWitness( + input: ZKProofAllSignals, + logger?: Logger + ): Promise | Uint8Array groth16Prove(witness: Uint8Array, logger?: Logger): Promise groth16Verify( - publicSignals: number[], + publicSignals: ZKProofPublicSignals, proof: ZKProof, logger?: Logger ): Promise diff --git a/js/src/zk.ts b/js/src/zk.ts index 5bec382..fb4faba 100644 --- a/js/src/zk.ts +++ b/js/src/zk.ts @@ -15,9 +15,7 @@ export async function generateProof(opts: GenerateProofOpts): Promise { return { algorithm, - proofJson: typeof proof === 'string' - ? proof - : JSON.stringify(proof), + proofData: proof, plaintext: plaintextArray } } @@ -31,7 +29,7 @@ export async function generateZkWitness({ algorithm, privateInput: { key }, publicInput: { ciphertext, iv, offset }, - operator + operator, }: GenerateProofOpts, ) { const { @@ -90,9 +88,10 @@ export async function generateZkWitness({ * @param zkey */ export async function verifyProof({ - proof: { algorithm, proofJson, plaintext }, + proof: { algorithm, proofData, plaintext }, publicInput: { ciphertext, iv, offset }, operator, + logger }: VerifyProofOpts): Promise { const { uint8ArrayToBits, isLittleEndian } = CONFIG[algorithm] const startCounter = getCounterForChunk(algorithm, offset) @@ -106,16 +105,15 @@ export async function verifyProof({ } // serialise to array of numbers for the ZK circuit - const pubInputs = [ - ...uint8ArrayToBits(plaintext), - ...uint8ArrayToBits(iv), - ...serialiseCounter(), - ...uint8ArrayToBits(ciphertextArray), - ].flat() - const verified = await operator.groth16Verify( - pubInputs, - JSON.parse(proofJson), + { + nonce: uint8ArrayToBits(iv), + counter: serialiseCounter(), + in: uint8ArrayToBits(ciphertextArray), + out: uint8ArrayToBits(plaintext), + }, + proofData, + logger ) if(!verified) { diff --git a/readme.md b/readme.md index 692aa31..2479ee7 100644 --- a/readme.md +++ b/readme.md @@ -29,28 +29,34 @@ We currently support the following algorithms: Our library implements multiple ZK proof systems: - **[Circom Circuits](/circom/)** backed by `snarkjs` (groth16). - **[`gnark` Frontend Circuits](/gnark/)** backed by `gnark` (groth16). -- **[`gnark` Frontend Circuits](/expander/)** backed by `expander` (groth16). +- **[`gnark` Frontend Circuits](/expander/)** backed by `expander` (GKR): + - Note: This is a work in progress and may be insecure. It is also only available for `chacha20` at the moment. All these proof systems can be accessed easily via a single **[JS Package](/js)**. This package provides user-friendly abstract interfaces for generating and verifying proofs. πŸ‘‰ If you’re just looking to integrate this library into your project, check out the **[JS Package's README](/js/readme.md)**. ## 🀝 Contributing to Our Project + We're thrilled that you're interested in contributing! πŸŽ‰ Before you get started, please review the following guidelines: ### πŸ“œ Code of Conduct + To ensure a positive and inclusive environment for all contributors, please read and follow our [Code of Conduct](https://github.com/reclaimprotocol/.github/blob/main/Code-of-Conduct.md). ### πŸ” Security If you discover any security-related issues, please refer to our [Security Policy](https://github.com/reclaimprotocol/.github/blob/main/SECURITY.md) for information on how to responsibly disclose vulnerabilities. ### ✍️ Contributor License Agreement + Before contributing to this project, please read and sign our [Contributor License Agreement (CLA)](https://github.com/reclaimprotocol/.github/blob/main/CLA.md). ### 🌱 Indie Hackers + For Indie Hackers: [Check out our guidelines and potential grant opportunities](https://github.com/reclaimprotocol/.github/blob/main/Indie-Hackers.md). ## πŸ“„ License + This project is licensed under a [custom license](https://github.com/reclaimprotocol/.github/blob/main/LICENSE). By contributing, you agree that your contributions will be licensed under its terms. --- diff --git a/resources/expander/chacha20-solver.txt b/resources/expander/chacha20-solver.txt new file mode 100644 index 0000000..2e5e295 Binary files /dev/null and b/resources/expander/chacha20-solver.txt differ diff --git a/resources/expander/chacha20.txt b/resources/expander/chacha20.txt new file mode 100644 index 0000000..4f0344e Binary files /dev/null and b/resources/expander/chacha20.txt differ diff --git a/resources/expander/release.wasm b/resources/expander/release.wasm new file mode 100644 index 0000000..0ae3ce8 Binary files /dev/null and b/resources/expander/release.wasm differ