commit 556d570e807d08557d7a2a233e4637b00ab4eafa Author: Jack Gilcrest Date: Thu Apr 25 01:22:18 2024 -0600 out of bounds on constraint gen maybe 2d array? diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..029abd2 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,3171 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli 0.28.1", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "arithmetic" +version = "0.1.0" +source = "git+https://github.com/EspressoSystems/hyperplonk#8698369edfe82bd6617a9609602380f21cabd1da" +dependencies = [ + "ark-bls12-381", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "displaydoc", + "rand_chacha", + "rayon", +] + +[[package]] +name = "ark-bls12-381" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] + +[[package]] +name = "ark-bn254" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-circom" +version = "0.1.0" +source = "git+https://github.com/arnaucube/circom-compat.git#8b2d7915a029f4a6a9285eed3eb7322172cc64d4" +dependencies = [ + "ark-bn254", + "ark-crypto-primitives", + "ark-ec", + "ark-ff", + "ark-groth16", + "ark-poly", + "ark-relations", + "ark-serialize", + "ark-std", + "byteorder", + "cfg-if", + "color-eyre", + "criterion", + "ethers-core", + "fnv", + "hex", + "num", + "num-bigint", + "num-traits", + "thiserror", + "wasmer", +] + +[[package]] +name = "ark-crypto-primitives" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3a13b34da09176a8baba701233fdffbaa7c1b1192ce031a3da4e55ce1f1a56" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-r1cs-std", + "ark-relations", + "ark-serialize", + "ark-snark", + "ark-std", + "blake2", + "derivative", + "digest", + "rayon", + "sha2", + "tracing", +] + +[[package]] +name = "ark-ec" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c60370a92f8e1a5f053cad73a862e1b99bc642333cd676fa11c0c39f80f4ac2" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools 0.10.5", + "num-traits", + "rayon", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c2d42532524bee1da5a4f6f733eb4907301baa480829557adcff5dfaeee1d9a" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest", + "itertools 0.10.5", + "num-bigint", + "num-traits", + "paste", + "rayon", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-groth16" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20ceafa83848c3e390f1cbf124bc3193b3e639b3f02009e0e290809a501b95fc" +dependencies = [ + "ark-crypto-primitives", + "ark-ec", + "ark-ff", + "ark-poly", + "ark-relations", + "ark-serialize", + "ark-std", + "rayon", +] + +[[package]] +name = "ark-pallas" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760ecac12a00211188c9101b63bd284b80da5abcc5d97d9d2b3803bca1f63a52" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-r1cs-std", + "ark-std", +] + +[[package]] +name = "ark-poly" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6ec811462cabe265cfe1b102fcfe3df79d7d2929c2425673648ee9abfd0272" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "rayon", +] + +[[package]] +name = "ark-poly-commit" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a741492629ffcd228337676dc223a28551aa6792eedb8a2a22c767f00df6c89" +dependencies = [ + "ark-crypto-primitives", + "ark-ec", + "ark-ff", + "ark-poly", + "ark-relations", + "ark-serialize", + "ark-std", + "derivative", + "digest", + "rayon", +] + +[[package]] +name = "ark-r1cs-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de1d1472e5cb020cb3405ce2567c91c8d43f21b674aef37b0202f5c3304761db" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-relations", + "ark-std", + "derivative", + "num-bigint", + "num-integer", + "num-traits", + "tracing", +] + +[[package]] +name = "ark-relations" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00796b6efc05a3f48225e59cb6a2cda78881e7c390872d5786aaf112f31fb4f0" +dependencies = [ + "ark-ff", + "ark-std", + "tracing", + "tracing-subscriber 0.2.25", +] + +[[package]] +name = "ark-serialize" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e735959bc173ea4baf13327b19c22d452b8e9e8e8f7b7fc34e6bf0e316c33e" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-snark" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84d3cc6833a335bb8a600241889ead68ee89a3cf8448081fb7694c0fe503da63" +dependencies = [ + "ark-ff", + "ark-relations", + "ark-serialize", + "ark-std", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", + "rayon", +] + +[[package]] +name = "ark-vesta" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534dddabcd5017dca22582d25bf6946fadab04aa6cf15af243a126f27f6632f9" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-pallas", + "ark-r1cs-std", + "ark-std", +] + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "auto_impl" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "autocfg" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" + +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object 0.32.2", + "rustc-demangle", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[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 = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "bytecheck" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +dependencies = [ + "serde", +] + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cc" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17f6e324229dc011159fcc089755d1e2e216a90d43a7dea6853ca740b84f35e7" + +[[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 = [ + "num-traits", +] + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "bitflags 1.3.2", + "textwrap", + "unicode-width", +] + +[[package]] +name = "color-eyre" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "corosensei" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80128832c58ea9cbd041d2a759ec449224487b2c1e400453d99d244eead87a8e" +dependencies = [ + "autocfg", + "cfg-if", + "libc", + "scopeguard", + "windows-sys 0.33.0", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "cranelift-bforest" +version = "0.82.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38faa2a16616c8e78a18d37b4726b98bfd2de192f2fdc8a39ddf568a408a0f75" +dependencies = [ + "cranelift-entity", +] + +[[package]] +name = "cranelift-codegen" +version = "0.82.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26f192472a3ba23860afd07d2b0217dc628f21fcc72617aa1336d98e1671f33b" +dependencies = [ + "cranelift-bforest", + "cranelift-codegen-meta", + "cranelift-codegen-shared", + "cranelift-entity", + "gimli 0.26.2", + "log", + "regalloc", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-codegen-meta" +version = "0.82.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f32ddb89e9b89d3d9b36a5b7d7ea3261c98235a76ac95ba46826b8ec40b1a24" +dependencies = [ + "cranelift-codegen-shared", +] + +[[package]] +name = "cranelift-codegen-shared" +version = "0.82.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01fd0d9f288cc1b42d9333b7a776b17e278fc888c28e6a0f09b5573d45a150bc" + +[[package]] +name = "cranelift-entity" +version = "0.82.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3bfe172b83167604601faf9dc60453e0d0a93415b57a9c4d1a7ae6849185cf" + +[[package]] +name = "cranelift-frontend" +version = "0.82.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a006e3e32d80ce0e4ba7f1f9ddf66066d052a8c884a110b91d05404d6ce26dce" +dependencies = [ + "cranelift-codegen", + "log", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "crc32fast" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "criterion" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" +dependencies = [ + "atty", + "cast", + "clap", + "criterion-plot", + "csv", + "itertools 0.10.5", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_cbor", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" +dependencies = [ + "cast", + "itertools 0.10.5", +] + +[[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.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[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 = "csv" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + +[[package]] +name = "darling" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "darling_macro" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "either" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "enum-iterator" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eeac5c5edb79e4e39fe8439ef35207780a11f69c52cbe424ce3dfad4cb78de6" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "enumset" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" +dependencies = [ + "enumset_derive", +] + +[[package]] +name = "enumset_derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[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.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "ethabi" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" +dependencies = [ + "ethereum-types", + "hex", + "once_cell", + "regex", + "serde", + "serde_json", + "sha3", + "thiserror", + "uint", +] + +[[package]] +name = "ethbloom" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "tiny-keccak", +] + +[[package]] +name = "ethereum-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" +dependencies = [ + "ethbloom", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "primitive-types", + "scale-info", + "uint", +] + +[[package]] +name = "ethers-core" +version = "2.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6da5fa198af0d3be20c19192df2bd9590b92ce09a8421e793bec8851270f1b05" +dependencies = [ + "arrayvec", + "bytes", + "chrono", + "elliptic-curve", + "ethabi", + "generic-array", + "hex", + "k256", + "num_enum", + "open-fastrlp", + "rand", + "rlp", + "serde", + "serde_json", + "strum", + "tempfile", + "thiserror", + "tiny-keccak", + "unicode-xid", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fastrand" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "folding-schemes" +version = "0.1.0" +source = "git+https://github.com/privacy-scaling-explorations/sonobe?branch=main#8b233031a6fd84cd97154eaf279befd901d2bc8d" +dependencies = [ + "ark-circom", + "ark-crypto-primitives", + "ark-ec", + "ark-ff", + "ark-poly", + "ark-poly-commit", + "ark-r1cs-std", + "ark-relations", + "ark-serialize", + "ark-snark", + "ark-std", + "color-eyre", + "num-bigint", + "num-integer", + "rayon", + "subroutines", + "thiserror", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" +dependencies = [ + "fallible-iterator", + "indexmap 1.9.3", + "stable_deref_trait", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "grapevine_sonobe" +version = "0.1.0" +dependencies = [ + "ark-circom", + "ark-crypto-primitives", + "ark-ec", + "ark-ff", + "ark-pallas", + "ark-r1cs-std", + "ark-relations", + "ark-std", + "ark-vesta", + "color-eyre", + "folding-schemes", + "lazy_static", + "num-bigint", + "serde", + "serde_json", +] + +[[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 = "half" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash 0.7.8", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.8", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.11", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[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 = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +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.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "loupe" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" +dependencies = [ + "indexmap 1.9.3", + "loupe-derive", + "rustversion", +] + +[[package]] +name = "loupe-derive" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + +[[package]] +name = "mach2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core", + "zeroize", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "more-asserts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" + +[[package]] +name = "num" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", + "rand", +] + +[[package]] +name = "num-complex" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +dependencies = [ + "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-iter" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "object" +version = "0.28.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" +dependencies = [ + "crc32fast", + "hashbrown 0.11.2", + "indexmap 1.9.3", + "memchr", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + +[[package]] +name = "open-fastrlp" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", + "ethereum-types", + "open-fastrlp-derive", +] + +[[package]] +name = "open-fastrlp-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" +dependencies = [ + "bytes", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "parity-scale-codec" +version = "3.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +dependencies = [ + "arrayvec", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +dependencies = [ + "proc-macro-crate 2.0.2", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "plotters" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" + +[[package]] +name = "plotters-svg" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +dependencies = [ + "toml_datetime", + "toml_edit 0.20.2", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +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 = "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 = "regalloc" +version = "0.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02" +dependencies = [ + "log", + "rustc-hash", + "smallvec", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "region" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6b6ebd13bc009aef9cd476c1310d49ac354d36e240cf1bd753290f3dc7199a7" +dependencies = [ + "bitflags 1.3.2", + "libc", + "mach2", + "windows-sys 0.52.0", +] + +[[package]] +name = "rend" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "rkyv" +version = "0.7.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" +dependencies = [ + "bitvec", + "bytecheck", + "bytes", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rlp-derive", + "rustc-hex", +] + +[[package]] +name = "rlp-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustversion" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scale-info" +version = "2.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c453e59a955f81fb62ee5d596b450383d699f152d350e9d23a0db2adb78e4c0" +dependencies = [ + "cfg-if", + "derive_more", + "parity-scale-codec", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18cf6c6447f813ef19eb450e985bcce6705f9ce7660db221b59093d15c79c4b7" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" + +[[package]] +name = "serde" +version = "1.0.198" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.198" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "serde_json" +version = "1.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[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 = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + +[[package]] +name = "subroutines" +version = "0.1.0" +source = "git+https://github.com/EspressoSystems/hyperplonk#8698369edfe82bd6617a9609602380f21cabd1da" +dependencies = [ + "arithmetic", + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "displaydoc", + "itertools 0.11.0", + "rand_chacha", + "rayon", + "transcript", + "util", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[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.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" +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 = "target-lexicon" +version = "0.12.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +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 = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow", +] + +[[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-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber 0.3.18", +] + +[[package]] +name = "tracing-subscriber" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" +dependencies = [ + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "sharded-slab", + "thread_local", + "tracing-core", +] + +[[package]] +name = "transcript" +version = "0.1.0" +source = "git+https://github.com/EspressoSystems/hyperplonk#8698369edfe82bd6617a9609602380f21cabd1da" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "displaydoc", + "merlin", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "util" +version = "0.1.0" +source = "git+https://github.com/EspressoSystems/hyperplonk#8698369edfe82bd6617a9609602380f21cabd1da" +dependencies = [ + "rayon", +] + +[[package]] +name = "uuid" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[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.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.60", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "wasm-encoder" +version = "0.204.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "500cbde9b4d8dfc0335ec729d226dbf083e51e47501ac71e6addaed10ccb0a51" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasmer" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea8d8361c9d006ea3d7797de7bd6b1492ffd0f91a22430cfda6c1658ad57bedf" +dependencies = [ + "cfg-if", + "indexmap 1.9.3", + "js-sys", + "loupe", + "more-asserts", + "target-lexicon", + "thiserror", + "wasm-bindgen", + "wasmer-artifact", + "wasmer-compiler", + "wasmer-compiler-cranelift", + "wasmer-derive", + "wasmer-engine", + "wasmer-engine-dylib", + "wasmer-engine-universal", + "wasmer-types", + "wasmer-vm", + "wat", + "winapi", +] + +[[package]] +name = "wasmer-artifact" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aaf9428c29c1d8ad2ac0e45889ba8a568a835e33fd058964e5e500f2f7ce325" +dependencies = [ + "enumset", + "loupe", + "thiserror", + "wasmer-compiler", + "wasmer-types", +] + +[[package]] +name = "wasmer-compiler" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67a6cd866aed456656db2cfea96c18baabbd33f676578482b85c51e1ee19d2c" +dependencies = [ + "enumset", + "loupe", + "rkyv", + "serde", + "serde_bytes", + "smallvec", + "target-lexicon", + "thiserror", + "wasmer-types", + "wasmparser", +] + +[[package]] +name = "wasmer-compiler-cranelift" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48be2f9f6495f08649e4f8b946a2cbbe119faf5a654aa1457f9504a99d23dae0" +dependencies = [ + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "gimli 0.26.2", + "loupe", + "more-asserts", + "rayon", + "smallvec", + "target-lexicon", + "tracing", + "wasmer-compiler", + "wasmer-types", +] + +[[package]] +name = "wasmer-derive" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00e50405cc2a2f74ff574584710a5f2c1d5c93744acce2ca0866084739284b51" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "wasmer-engine" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f98f010978c244db431b392aeab0661df7ea0822343334f8f2a920763548e45" +dependencies = [ + "backtrace", + "enumset", + "lazy_static", + "loupe", + "memmap2", + "more-asserts", + "rustc-demangle", + "serde", + "serde_bytes", + "target-lexicon", + "thiserror", + "wasmer-artifact", + "wasmer-compiler", + "wasmer-types", + "wasmer-vm", +] + +[[package]] +name = "wasmer-engine-dylib" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0358af9c154724587731175553805648d9acb8f6657880d165e378672b7e53" +dependencies = [ + "cfg-if", + "enum-iterator", + "enumset", + "leb128", + "libloading", + "loupe", + "object 0.28.4", + "rkyv", + "serde", + "tempfile", + "tracing", + "wasmer-artifact", + "wasmer-compiler", + "wasmer-engine", + "wasmer-object", + "wasmer-types", + "wasmer-vm", + "which", +] + +[[package]] +name = "wasmer-engine-universal" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "440dc3d93c9ca47865a4f4edd037ea81bf983b5796b59b3d712d844b32dbef15" +dependencies = [ + "cfg-if", + "enumset", + "leb128", + "loupe", + "region", + "rkyv", + "wasmer-compiler", + "wasmer-engine", + "wasmer-engine-universal-artifact", + "wasmer-types", + "wasmer-vm", + "winapi", +] + +[[package]] +name = "wasmer-engine-universal-artifact" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f1db3f54152657eb6e86c44b66525ff7801dad8328fe677da48dd06af9ad41" +dependencies = [ + "enum-iterator", + "enumset", + "loupe", + "rkyv", + "thiserror", + "wasmer-artifact", + "wasmer-compiler", + "wasmer-types", +] + +[[package]] +name = "wasmer-object" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d831335ff3a44ecf451303f6f891175c642488036b92ceceb24ac8623a8fa8b" +dependencies = [ + "object 0.28.4", + "thiserror", + "wasmer-compiler", + "wasmer-types", +] + +[[package]] +name = "wasmer-types" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39df01ea05dc0a9bab67e054c7cb01521e53b35a7bb90bd02eca564ed0b2667f" +dependencies = [ + "backtrace", + "enum-iterator", + "indexmap 1.9.3", + "loupe", + "more-asserts", + "rkyv", + "serde", + "thiserror", +] + +[[package]] +name = "wasmer-vm" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d965fa61f4dc4cdb35a54daaf7ecec3563fbb94154a6c35433f879466247dd" +dependencies = [ + "backtrace", + "cc", + "cfg-if", + "corosensei", + "enum-iterator", + "indexmap 1.9.3", + "lazy_static", + "libc", + "loupe", + "mach", + "memoffset", + "more-asserts", + "region", + "rkyv", + "scopeguard", + "serde", + "thiserror", + "wasmer-artifact", + "wasmer-types", + "winapi", +] + +[[package]] +name = "wasmparser" +version = "0.83.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" + +[[package]] +name = "wast" +version = "204.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0e3de19692b3d4c2fa13775271a751935decf530ae59c408c9f0b510b4ead62" +dependencies = [ + "bumpalo", + "leb128", + "memchr", + "unicode-width", + "wasm-encoder", +] + +[[package]] +name = "wat" +version = "1.204.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4280322d523214024d03bc05e25bdda6088d5229d9515aecd78c5914b1f3e734" +dependencies = [ + "wast", +] + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +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 = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43dbb096663629518eb1dfa72d80243ca5a6aca764cae62a2df70af760a9be75" +dependencies = [ + "windows_aarch64_msvc 0.33.0", + "windows_i686_gnu 0.33.0", + "windows_i686_msvc 0.33.0", + "windows_x86_64_gnu 0.33.0", + "windows_x86_64_msvc 0.33.0", +] + +[[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-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.52.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[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.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..8ff0730 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "grapevine_sonobe" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib", "rlib"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +ark-pallas = { version = "0.4.0", features = ["r1cs"] } +ark-vesta = {version="0.4.0", features=["r1cs"]} +ark-circom = { git = "https://github.com/arnaucube/circom-compat.git" } +ark-ec = "0.4.1" +ark-ff = "0.4.1" +ark-r1cs-std = { version = "0.4.0", default-features = false } +ark-relations = { version = "0.4.0", default-features = false } +ark-crypto-primitives = { version = "^0.4.0", default-features = false, features = [ + "r1cs", + "sponge", + "crh", +] } +ark-std = "0.4.0" +color-eyre = "0.6.2" +num-bigint = "0.4.3" +sonobe = { git = "https://github.com/privacy-scaling-explorations/sonobe", package = "folding-schemes", branch = "main" } +serde = "1.0.198" +serde_json = "1.0.116" + +[dev-dependencies] +lazy_static = "1.4.0" diff --git a/circom/artifacts/grapevine.r1cs b/circom/artifacts/grapevine.r1cs new file mode 100644 index 0000000..2f4d218 Binary files /dev/null and b/circom/artifacts/grapevine.r1cs differ diff --git a/circom/artifacts/grapevine.wasm b/circom/artifacts/grapevine.wasm new file mode 100644 index 0000000..a16ba12 Binary files /dev/null and b/circom/artifacts/grapevine.wasm differ diff --git a/circom/compile.sh b/circom/compile.sh new file mode 100755 index 0000000..aa5a160 --- /dev/null +++ b/circom/compile.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# if artifacts does not exist, make it +if [ ! -d "./artifacts" ]; then + mkdir -p ./artifacts +fi + +# install dependencies +yarn + +# compile circuit + +circom grapevine.circom \ + --r1cs \ + --wasm \ + --prime bn128 \ + --output ./artifacts + +# cleanup +mv ./artifacts/grapevine_js/grapevine.wasm ./artifacts +rm -rf ./artifacts/grapevine_js diff --git a/circom/grapevine.circom b/circom/grapevine.circom new file mode 100644 index 0000000..cb363cb --- /dev/null +++ b/circom/grapevine.circom @@ -0,0 +1,97 @@ +pragma circom 2.1.6; + +include "node_modules/circomlib/circuits/poseidon.circom"; +include "node_modules/circomlib/circuits/mux1.circom"; +include "node_modules/circomlib/circuits/comparators.circom"; +include "node_modules/circomlib/circuits/gates.circom"; +include "./templates/chaff.circom"; + +template grapevine(num_felts) { + + // in_out schema + // 0: degrees of separation + // 1: secret hash from previous step + // 2: hash of username + secret hash from previous step + // 3: chaff + + signal input ivc_input[4]; + signal output ivc_output[4]; + + // private inputs + signal input phrase[num_felts]; // secret phrase, if first iteration + signal input usernames[2]; // prev username, current username + signal input auth_secrets[2]; // prev degree's user secret, current degree's user secret + + // name inputs from step_in + signal degrees_of_separation <== ivc_input[0]; + signal given_phrase_hash <== ivc_input[1]; + signal given_degree_secret_hash <== ivc_input[2]; + signal is_chaff_step <== ivc_input[3]; + + // determine whether degrees of separation from secret is zero + component is_degree_zero = IsZero(); + is_degree_zero.in <== degrees_of_separation; + + // compute poseidon hash of secret + // same as the word essentially + component phrase_hasher = Poseidon(num_felts); + phrase_hasher.inputs <== phrase; + + // mux between computed hash and previous iteration's hash to get phrase hash to use + // if degrees of separation = 0 use computed hash, else use hash from previous step + component phrase_mux = Mux1(); + phrase_mux.c[0] <== given_phrase_hash; + phrase_mux.c[1] <== phrase_hasher.out; + phrase_mux.s <== is_degree_zero.out; + + // compute hash of given degree secret + // H(H(preimage), username, auth_secret[0]) + // where preimage is muxed depending on whether degree N is 1 or > 1 + component degree_secret_hasher = Poseidon(3); + degree_secret_hasher.inputs[0] <== phrase_mux.out; + degree_secret_hasher.inputs[1] <== usernames[0]; + degree_secret_hasher.inputs[2] <== auth_secrets[0]; + + // compare computed degree secret hash to prev degree secret hash + component degree_secret_hash_match = IsEqual(); + degree_secret_hash_match.in[0] <== degree_secret_hasher.out; + degree_secret_hash_match.in[1] <== given_degree_secret_hash; + + // create boolean that is true if either is true: + // - given degree secret hash matches computed hash + // - is a chaff step + component degree_secret_match_or_chaff = OR(); + degree_secret_match_or_chaff.a <== degree_secret_hash_match.out; + degree_secret_match_or_chaff.b <== is_chaff_step; + + // create boolean that is muxes according to: + // - if degrees of separation = 0, always true (no check needed) + // - if degree of separation > 0, return output of degree_secret_match_or_chaff + component degree_secret_satisfied_mux = Mux1(); + degree_secret_satisfied_mux.c[0] <== degree_secret_match_or_chaff.out; + degree_secret_satisfied_mux.c[1] <== 1; + degree_secret_satisfied_mux.s <== is_degree_zero.out; + + // constrain degree_secret_satisfied_mux to be true + degree_secret_satisfied_mux.out === 1; + + // compute the next username hash + component next_degree_secret_hash = Poseidon(3); + next_degree_secret_hash.inputs[0] <== phrase_mux.out; + next_degree_secret_hash.inputs[1] <== usernames[1]; + next_degree_secret_hash.inputs[2] <== auth_secrets[1]; + + // mux step_out signal according to whether or not this is a chaff step + component chaff_mux = ChaffMux(); + chaff_mux.degrees_of_separation <== degrees_of_separation; + chaff_mux.given_phrase_hash <== given_phrase_hash; + chaff_mux.given_degree_secret_hash <== given_degree_secret_hash; + chaff_mux.is_chaff_step <== is_chaff_step; + chaff_mux.computed_phrase_hash <== phrase_mux.out; + chaff_mux.computed_degree_secret_hash <== next_degree_secret_hash.out; + + // wire output signals + ivc_output <== chaff_mux.out; +} + +component main { public [ivc_input] } = grapevine(6); \ No newline at end of file diff --git a/circom/node_modules/.yarn-integrity b/circom/node_modules/.yarn-integrity new file mode 100644 index 0000000..f78ac9c --- /dev/null +++ b/circom/node_modules/.yarn-integrity @@ -0,0 +1,16 @@ +{ + "systemParams": "linux-x64-108", + "modulesFolders": [ + "node_modules" + ], + "flags": [], + "linkedModules": [], + "topLevelPatterns": [ + "circomlib@^2.0.5" + ], + "lockfileEntries": { + "circomlib@^2.0.5": "https://registry.yarnpkg.com/circomlib/-/circomlib-2.0.5.tgz#183c703e53ed7d011811842dbeeeb9819f4cc1d6" + }, + "files": [], + "artifacts": {} +} \ No newline at end of file diff --git a/circom/node_modules/circomlib/.vscode/launch.json b/circom/node_modules/circomlib/.vscode/launch.json new file mode 100644 index 0000000..956c48b --- /dev/null +++ b/circom/node_modules/circomlib/.vscode/launch.json @@ -0,0 +1,63 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "pwa-node", + "request": "launch", + "name": "Launch Program", + "skipFiles": [ + "/**" + ], + "program": "${workspaceFolder}/calcoptimizedposeidonconsts/test_poseidon.js", + "cwd": "${workspaceFolder}/calcoptimizedposeidonconsts" + }, + { + "type": "pwa-node", + "request": "launch", + "name": "Tests", + "skipFiles": [ + "/**" + ], + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "cwd": "${workspaceFolder}", + "args": ["test/smtverifier.js"] + }, + { + "type": "pwa-node", + "request": "launch", + "name": "Test Poseidon", + "skipFiles": [ + "/**" + ], + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "cwd": "${workspaceFolder}", + "args": ["test/poseidoncircuit.js"] + }, + { + "type": "pwa-node", + "request": "launch", + "name": "Test binsum", + "skipFiles": [ + "/**" + ], + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "cwd": "${workspaceFolder}", + "args": ["test/binsum.js"] + }, + { + "type": "pwa-node", + "request": "launch", + "name": "Test babyjub", + "skipFiles": [ + "/**" + ], + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "cwd": "${workspaceFolder}", + "args": ["test/babyjub.js"] + } + + ] +} \ No newline at end of file diff --git a/circom/node_modules/circomlib/README.md b/circom/node_modules/circomlib/README.md new file mode 100644 index 0000000..a56c676 --- /dev/null +++ b/circom/node_modules/circomlib/README.md @@ -0,0 +1,18 @@ +# CircomLib + +## Description + +- This repository contains a library of circuit templates. +- All files are copyrighted under 2018 0KIMS association and part of the free software [circom](https://github.com/iden3/circom) (Zero Knowledge Circuit Compiler). +- You can read more about the circom language in [the circom documentation webpage](https://docs.circom.io/). + +## Organisation + +This respository contains 5 folders: +- `circuits`: it contains the implementation of different cryptographic primitives in circom language. +- `calcpedersenbases`: set of functions in JavaScript used to find a set of points in [Baby Jubjub](https://github.com/barryWhiteHat/baby_jubjub) elliptic curve that serve as basis for the [Pedersen Hash](https://github.com/zcash/zcash/issues/2234). +- `doc`: it contains some circuit schemes in ASCII (must be opened with Monodraw, an ASCII art editor for Mac). +- `src`: it contains similar implementation of circuits in JavaScript. +- `test`: tests. + +A description of the specific circuit templates for the `circuit` folder will be soon updated. diff --git a/circom/node_modules/circomlib/circuits/README.md b/circom/node_modules/circomlib/circuits/README.md new file mode 100644 index 0000000..40a833e --- /dev/null +++ b/circom/node_modules/circomlib/circuits/README.md @@ -0,0 +1,830 @@ +# CircomLib/Circuits + +## Description + +- This folder contains circuit templates for standard operations and many cryptographic primitives. +- Below you can find specifications of each function. In the representation of elements, there are three tyes: + - Binary + - String + - Field element (the field is specified in each case. We consider 2 possible fields: Fp and Fr, where p... and r... .) + +## Table of Contents + +[TOC] + +## Jordi + +* compconstant - Returns 1 if `in` (expanded to binary array) > `ct` +* aliascheck - check if `in` (expanded to binary array) oveflowed its 254 bits (<= -1) +* babyjub - twisted Edwards curve 168700.x^2 + y^2 = 1 + 168696.x^2.y^2 + * BabyAdd - (`xout`,`yout`) = (`x1`,`y1`) + (`x2`,`y2`) + * BabyDbl - (`xout`,`yout`) = 2*(`x`,`y`) + * BabyCheck - check that (`x`,`y`) is on the curve +* binsub - binary subtraction +* gates - logical gates +* mimc - SNARK-friendly hash Minimal Multiplicative Complexity. + * https://eprint.iacr.org/2016/492.pdf + * zcash/zcash#2233 +* smt - Sparse Merkle Tree + * https://ethresear.ch/t/optimizing-sparse-merkle-trees/3751 +* montgomery https://en.wikipedia.org/wiki/Montgomery_curve + +## Circuits + +### sha256 + +Folder containing the implementation of sha256 hash circuit. + +### smt + +Folder containing the circuit implementation of Sparse Merkle Trees. + +### aliascheck + +- `AliasCheck()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### babyjub + +Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby_jubjub) in twisted Edwards form. (TODO: Expose here the characteristics of the curve?) + + +- `BabyAdd()` + + - DESCRIPTION + + It adds two points on the Baby Jubjub curve. More specifically, given two points P1 = (`x1`, `y1`) and P2 = (`x2`, `y2`) it returns a point P3 = (`xout`, `yout`) such that + + (`xout`, `yout`) = (`x1`,`y1`) + (`x2`,`y2`) + = ((`x1y2`+`y1x2`)/(1+`dx1x2y1y2`)),(`y1y2`-`ax1x2`)/(1-`dx1x2y1y2`)) + + - SCHEMA + ``` + var a var d + | | + | | + ______v_________v_______ + input x1 ----> | | + input y1 ----> | BabyAdd() | ----> output xout + input x2 ----> | | ----> output yout + input y2 ----> |________________________| + ``` + + - INPUTS + + | Input | Representation | Description | | + | ------------- | ------------- | ------------- | ------------- | + | `x1` | Bigint | Field element of Fp | First coordinate of a point (x1, y1) on E. | + | `y1` | Bigint | Field element of Fp | Second coordinate of a point (x1, y1) on E. | + | `x2` | Bigint | Field element of Fp | First coordinate of a point (x2, y2) on E. | + | `y2` | Bigint | Field element of Fp | Second coordinate of a point (x2, y2) on E. | + + Requirement: at least `x1`!=`x2` or `y1`!=`y2`. + + - OUTPUT + + | Input | Representation | Description | | + | ------------- | ------------- | ------------- | ------------- | + | `xout` | Bigint | Field element of Fp | First coordinate of the addition point (xout, yout) = (x1, y1) + (x2, y2). | + | `yout` | Bigint | Field element of Fp | Second coordinate of the addition point (xout, yout) = (x1, y1) + (x2, y2). | + + - BENCHMARKS (constraints) + + - EXAMPLE + +- `BabyDbl()` + - DESCRIPTION : doubles a point (`xout`,`yout`) = 2*(`x`,`y`). + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `BabyCheck()` + + - DESCRIPTION : checks if a given point is in the curve. + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `BabyPbk()` + + - DESCRIPTION: : given a private key, it returns the associated public key. + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + + +### binsub + +- `BinSub(n)` + + - DESCRIPTION: binary substraction. + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### binsum + +- `nbits(a)` + + - DESCRIPTION : binary sum. + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `BinSum(n, ops)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### bitify + +- `Num2Bits()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `Num2Bits_strict()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `Bits2Num()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `Bits2Num_strict()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `Num2BitsNeg()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### comparators + +- `IsZero() ` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `IsEqual()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `ForceEqualIfEnabled()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `LessThan()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `GreaterThan()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `GreaterEqThan()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### compconstant + +- `CompConstant(ct)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### eddsa + +Edwards Digital Signature Algorithm in Baby Jubjbub (link a eddsa) + +- `EdDSAVerifier(n)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### eddsamimc + +- `EdDSAMiMCVerifier()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### eddsamimcsponge + +- `EdDSAMiMCSpongeVerifier()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### eddsaposeidon + +- `EdDSAPoseidonVerifier()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### escalarmul + +- `EscalarMulWindow(base, k)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `EscalarMul(n, base)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### escalarmulany + +- `Multiplexor2()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `BitElementMulAny()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `SegmentMulAny(n)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `EscalarMulAny(n)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### escalarmulfix + +- `WindowMulFix()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `SegmentMulFix(nWindows)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `EscalarMulFix(n, BASE)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### escalarmulw4table + +- `pointAdd` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `EscalarMulW4Table` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### gates + +- `XOR` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `AND` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `OR` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `NOT` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `NAND` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `NOR` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `MultiAND` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### mimc + +Implementation of MiMC-7 hash in Fp being... (link to description of the hash) + +- `MiMC7(nrounds)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `MultiMiMC7(nInputs, nRounds)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### mimcsponge + +- `MiMCSponge(nInputs, nRounds, nOutputs)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `MiMCFeistel(nrounds)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### montgomery + +- `Edwards2Montgomery()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `Montgomery2Edwards()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `MontgomeryAdd()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `MontgomeryDouble()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### multiplexer + +- `log2(a)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `EscalarProduct(w)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `Decoder(w)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `Multiplexer(wIn, nIn)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### mux1 + +- `MultiMux1(n)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `Mux1()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### mux2 + +- `MultiMux2(n)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `Mux2()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### mux3 + +- `MultiMux3(n)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `Mux3()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### mux4 + +- `MultiMux4(n)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `Mux4()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### pedersen_old + +Old version of the Pedersen hash (do not use any +more?). + +### pedersen + +- `Window4()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `Segment(nWindows)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `Pedersen(n)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### pointbits + +- `sqrt(n)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `Bits2Point()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `Bits2Point_Strict()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `Point2Bits` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `Point2Bits_Strict` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### poseidon + +Implementation of Poseidon hash function (LINK) + +- `Sigma()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `Ark(t, C, r)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `Mix(t, M)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +- `Poseidon(nInputs)` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### sign + +- `Sign()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE + +### switcher + +- `Switcher()` + + - DESCRIPTION + - SCHEMA + - INPUT + - OUTPUT + - BENCHMARKS + - EXAMPLE diff --git a/circom/node_modules/circomlib/circuits/aliascheck.circom b/circom/node_modules/circomlib/circuits/aliascheck.circom new file mode 100644 index 0000000..1c5a5f8 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/aliascheck.circom @@ -0,0 +1,33 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "compconstant.circom"; + + +template AliasCheck() { + + signal input in[254]; + + component compConstant = CompConstant(-1); + + for (var i=0; i<254; i++) in[i] ==> compConstant.in[i]; + + compConstant.out === 0; +} diff --git a/circom/node_modules/circomlib/circuits/babyjub.circom b/circom/node_modules/circomlib/circuits/babyjub.circom new file mode 100644 index 0000000..36810fe --- /dev/null +++ b/circom/node_modules/circomlib/circuits/babyjub.circom @@ -0,0 +1,107 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "bitify.circom"; +include "escalarmulfix.circom"; + +template BabyAdd() { + signal input x1; + signal input y1; + signal input x2; + signal input y2; + signal output xout; + signal output yout; + + signal beta; + signal gamma; + signal delta; + signal tau; + + var a = 168700; + var d = 168696; + + beta <== x1*y2; + gamma <== y1*x2; + delta <== (-a*x1+y1)*(x2 + y2); + tau <== beta * gamma; + + xout <-- (beta + gamma) / (1+ d*tau); + (1+ d*tau) * xout === (beta + gamma); + + yout <-- (delta + a*beta - gamma) / (1-d*tau); + (1-d*tau)*yout === (delta + a*beta - gamma); +} + +template BabyDbl() { + signal input x; + signal input y; + signal output xout; + signal output yout; + + component adder = BabyAdd(); + adder.x1 <== x; + adder.y1 <== y; + adder.x2 <== x; + adder.y2 <== y; + + adder.xout ==> xout; + adder.yout ==> yout; +} + + +template BabyCheck() { + signal input x; + signal input y; + + signal x2; + signal y2; + + var a = 168700; + var d = 168696; + + x2 <== x*x; + y2 <== y*y; + + a*x2 + y2 === 1 + d*x2*y2; +} + +// Extracts the public key from private key +template BabyPbk() { + signal input in; + signal output Ax; + signal output Ay; + + var BASE8[2] = [ + 5299619240641551281634865583518297030282874472190772894086521144482721001553, + 16950150798460657717958625567821834550301663161624707787222815936182638968203 + ]; + + component pvkBits = Num2Bits(253); + pvkBits.in <== in; + + component mulFix = EscalarMulFix(253, BASE8); + + var i; + for (i=0; i<253; i++) { + mulFix.e[i] <== pvkBits.out[i]; + } + Ax <== mulFix.out[0]; + Ay <== mulFix.out[1]; +} diff --git a/circom/node_modules/circomlib/circuits/binsub.circom b/circom/node_modules/circomlib/circuits/binsub.circom new file mode 100644 index 0000000..a20fbf8 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/binsub.circom @@ -0,0 +1,74 @@ + /* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ + +/* +This component creates a binary substraction. + + +Main Constraint: + (in[0][0] * 2^0 + in[0][1] * 2^1 + ..... + in[0][n-1] * 2^(n-1)) + + + 2^n + - (in[1][0] * 2^0 + in[1][1] * 2^1 + ..... + in[1][n-1] * 2^(n-1)) + === + out[0] * 2^0 + out[1] * 2^1 + + out[n-1] *2^(n-1) + aux + + + out[0] * (out[0] - 1) === 0 + out[1] * (out[0] - 1) === 0 + . + . + . + out[n-1] * (out[n-1] - 1) === 0 + aux * (aux-1) == 0 + +*/ +pragma circom 2.0.0; + +template BinSub(n) { + signal input in[2][n]; + signal output out[n]; + + signal aux; + + var lin = 2**n; + var lout = 0; + + var i; + + for (i=0; i> i) & 1; + + // Ensure out is binary + out[i] * (out[i] - 1) === 0; + + lout = lout + out[i]*(2**i); + } + + aux <-- (lin >> n) & 1; + aux*(aux-1) === 0; + lout = lout + aux*(2**n); + + // Ensure the sum; + lin === lout; +} diff --git a/circom/node_modules/circomlib/circuits/binsum.circom b/circom/node_modules/circomlib/circuits/binsum.circom new file mode 100644 index 0000000..28c7fcc --- /dev/null +++ b/circom/node_modules/circomlib/circuits/binsum.circom @@ -0,0 +1,101 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ + +/* + +Binary Sum +========== + +This component creates a binary sum componet of ops operands and n bits each operand. + +e is Number of carries: Depends on the number of operands in the input. + +Main Constraint: + in[0][0] * 2^0 + in[0][1] * 2^1 + ..... + in[0][n-1] * 2^(n-1) + + + in[1][0] * 2^0 + in[1][1] * 2^1 + ..... + in[1][n-1] * 2^(n-1) + + + .. + + in[ops-1][0] * 2^0 + in[ops-1][1] * 2^1 + ..... + in[ops-1][n-1] * 2^(n-1) + + === + out[0] * 2^0 + out[1] * 2^1 + + out[n+e-1] *2(n+e-1) + +To waranty binary outputs: + + out[0] * (out[0] - 1) === 0 + out[1] * (out[0] - 1) === 0 + . + . + . + out[n+e-1] * (out[n+e-1] - 1) == 0 + + */ + + +/* + This function calculates the number of extra bits in the output to do the full sum. + */ + pragma circom 2.0.0; + +function nbits(a) { + var n = 1; + var r = 0; + while (n-1> k) & 1; + + // Ensure out is binary + out[k] * (out[k] - 1) === 0; + + lout += out[k] * e2; + + e2 = e2+e2; + } + + // Ensure the sum; + + lin === lout; +} diff --git a/circom/node_modules/circomlib/circuits/bitify.circom b/circom/node_modules/circomlib/circuits/bitify.circom new file mode 100644 index 0000000..bfdd4e8 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/bitify.circom @@ -0,0 +1,106 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "comparators.circom"; +include "aliascheck.circom"; + + +template Num2Bits(n) { + signal input in; + signal output out[n]; + var lc1=0; + + var e2=1; + for (var i = 0; i> i) & 1; + out[i] * (out[i] -1 ) === 0; + lc1 += out[i] * e2; + e2 = e2+e2; + } + + lc1 === in; +} + +template Num2Bits_strict() { + signal input in; + signal output out[254]; + + component aliasCheck = AliasCheck(); + component n2b = Num2Bits(254); + in ==> n2b.in; + + for (var i=0; i<254; i++) { + n2b.out[i] ==> out[i]; + n2b.out[i] ==> aliasCheck.in[i]; + } +} + +template Bits2Num(n) { + signal input in[n]; + signal output out; + var lc1=0; + + var e2 = 1; + for (var i = 0; i out; +} + +template Bits2Num_strict() { + signal input in[254]; + signal output out; + + component aliasCheck = AliasCheck(); + component b2n = Bits2Num(254); + + for (var i=0; i<254; i++) { + in[i] ==> b2n.in[i]; + in[i] ==> aliasCheck.in[i]; + } + + b2n.out ==> out; +} + +template Num2BitsNeg(n) { + signal input in; + signal output out[n]; + var lc1=0; + + component isZero; + + isZero = IsZero(); + + var neg = n == 0 ? 0 : 2**n - in; + + for (var i = 0; i> i) & 1; + out[i] * (out[i] -1 ) === 0; + lc1 += out[i] * 2**i; + } + + in ==> isZero.in; + + + + lc1 + isZero.out * 2**n === 2**n - in; +} diff --git a/circom/node_modules/circomlib/circuits/comparators.circom b/circom/node_modules/circomlib/circuits/comparators.circom new file mode 100644 index 0000000..bfed032 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/comparators.circom @@ -0,0 +1,141 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "bitify.circom"; +include "binsum.circom"; + +template IsZero() { + signal input in; + signal output out; + + signal inv; + + inv <-- in!=0 ? 1/in : 0; + + out <== -in*inv +1; + in*out === 0; +} + + +template IsEqual() { + signal input in[2]; + signal output out; + + component isz = IsZero(); + + in[1] - in[0] ==> isz.in; + + isz.out ==> out; +} + +template ForceEqualIfEnabled() { + signal input enabled; + signal input in[2]; + + component isz = IsZero(); + + in[1] - in[0] ==> isz.in; + + (1 - isz.out)*enabled === 0; +} + +/* +// N is the number of bits the input have. +// The MSF is the sign bit. +template LessThan(n) { + signal input in[2]; + signal output out; + + component num2Bits0; + component num2Bits1; + + component adder; + + adder = BinSum(n, 2); + + num2Bits0 = Num2Bits(n); + num2Bits1 = Num2BitsNeg(n); + + in[0] ==> num2Bits0.in; + in[1] ==> num2Bits1.in; + + var i; + for (i=0;i adder.in[0][i]; + num2Bits1.out[i] ==> adder.in[1][i]; + } + + adder.out[n-1] ==> out; +} +*/ + +template LessThan(n) { + assert(n <= 252); + signal input in[2]; + signal output out; + + component n2b = Num2Bits(n+1); + + n2b.in <== in[0]+ (1< out; +} + +// N is the number of bits the input have. +// The MSF is the sign bit. +template GreaterThan(n) { + signal input in[2]; + signal output out; + + component lt = LessThan(n); + + lt.in[0] <== in[1]; + lt.in[1] <== in[0]; + lt.out ==> out; +} + +// N is the number of bits the input have. +// The MSF is the sign bit. +template GreaterEqThan(n) { + signal input in[2]; + signal output out; + + component lt = LessThan(n); + + lt.in[0] <== in[1]; + lt.in[1] <== in[0]+1; + lt.out ==> out; +} + diff --git a/circom/node_modules/circomlib/circuits/compconstant.circom b/circom/node_modules/circomlib/circuits/compconstant.circom new file mode 100644 index 0000000..1bca83a --- /dev/null +++ b/circom/node_modules/circomlib/circuits/compconstant.circom @@ -0,0 +1,74 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "bitify.circom"; + +// Returns 1 if in (in binary) > ct + +template CompConstant(ct) { + signal input in[254]; + signal output out; + + signal parts[127]; + signal sout; + + var clsb; + var cmsb; + var slsb; + var smsb; + + var sum=0; + + var b = (1 << 128) -1; + var a = 1; + var e = 1; + var i; + + for (i=0;i<127; i++) { + clsb = (ct >> (i*2)) & 1; + cmsb = (ct >> (i*2+1)) & 1; + slsb = in[i*2]; + smsb = in[i*2+1]; + + if ((cmsb==0)&&(clsb==0)) { + parts[i] <== -b*smsb*slsb + b*smsb + b*slsb; + } else if ((cmsb==0)&&(clsb==1)) { + parts[i] <== a*smsb*slsb - a*slsb + b*smsb - a*smsb + a; + } else if ((cmsb==1)&&(clsb==0)) { + parts[i] <== b*smsb*slsb - a*smsb + a; + } else { + parts[i] <== -a*smsb*slsb + a; + } + + sum = sum + parts[i]; + + b = b -e; + a = a +e; + e = e*2; + } + + sout <== sum; + + component num2bits = Num2Bits(135); + + num2bits.in <== sout; + + out <== num2bits.out[127]; +} diff --git a/circom/node_modules/circomlib/circuits/eddsa.circom b/circom/node_modules/circomlib/circuits/eddsa.circom new file mode 100644 index 0000000..04b5f87 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/eddsa.circom @@ -0,0 +1,139 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "compconstant.circom"; +include "pointbits.circom"; +include "pedersen.circom"; +include "escalarmulany.circom"; +include "escalarmulfix.circom"; + +template EdDSAVerifier(n) { + signal input msg[n]; + + signal input A[256]; + signal input R8[256]; + signal input S[256]; + + signal Ax; + signal Ay; + + signal R8x; + signal R8y; + + var i; + +// Ensure S compConstant.in[i]; + } + compConstant.out === 0; + S[254] === 0; + S[255] === 0; + +// Convert A to Field elements (And verify A) + + component bits2pointA = Bits2Point_Strict(); + + for (i=0; i<256; i++) { + bits2pointA.in[i] <== A[i]; + } + Ax <== bits2pointA.out[0]; + Ay <== bits2pointA.out[1]; + +// Convert R8 to Field elements (And verify R8) + + component bits2pointR8 = Bits2Point_Strict(); + + for (i=0; i<256; i++) { + bits2pointR8.in[i] <== R8[i]; + } + R8x <== bits2pointR8.out[0]; + R8y <== bits2pointR8.out[1]; + +// Calculate the h = H(R,A, msg) + + component hash = Pedersen(512+n); + + for (i=0; i<256; i++) { + hash.in[i] <== R8[i]; + hash.in[256+i] <== A[i]; + } + for (i=0; i. +*/ +pragma circom 2.0.0; + +include "compconstant.circom"; +include "pointbits.circom"; +include "mimc.circom"; +include "bitify.circom"; +include "escalarmulany.circom"; +include "escalarmulfix.circom"; + +template EdDSAMiMCVerifier() { + signal input enabled; + signal input Ax; + signal input Ay; + + signal input S; + signal input R8x; + signal input R8y; + + signal input M; + + var i; + +// Ensure S compConstant.in[i]; + } + compConstant.in[253] <== 0; + compConstant.out === 0; + +// Calculate the h = H(R,A, msg) + + component hash = MultiMiMC7(5, 91); + hash.in[0] <== R8x; + hash.in[1] <== R8y; + hash.in[2] <== Ax; + hash.in[3] <== Ay; + hash.in[4] <== M; + hash.k <== 0; + + component h2bits = Num2Bits_strict(); + h2bits.in <== hash.out; + +// Calculate second part of the right side: right2 = h*8*A + + // Multiply by 8 by adding it 3 times. This also ensure that the result is in + // the subgroup. + component dbl1 = BabyDbl(); + dbl1.x <== Ax; + dbl1.y <== Ay; + component dbl2 = BabyDbl(); + dbl2.x <== dbl1.xout; + dbl2.y <== dbl1.yout; + component dbl3 = BabyDbl(); + dbl3.x <== dbl2.xout; + dbl3.y <== dbl2.yout; + + // We check that A is not zero. + component isZero = IsZero(); + isZero.in <== dbl3.x; + isZero.out === 0; + + component mulAny = EscalarMulAny(254); + for (i=0; i<254; i++) { + mulAny.e[i] <== h2bits.out[i]; + } + mulAny.p[0] <== dbl3.xout; + mulAny.p[1] <== dbl3.yout; + + +// Compute the right side: right = R8 + right2 + + component addRight = BabyAdd(); + addRight.x1 <== R8x; + addRight.y1 <== R8y; + addRight.x2 <== mulAny.out[0]; + addRight.y2 <== mulAny.out[1]; + +// Calculate left side of equation left = S*B8 + + var BASE8[2] = [ + 5299619240641551281634865583518297030282874472190772894086521144482721001553, + 16950150798460657717958625567821834550301663161624707787222815936182638968203 + ]; + component mulFix = EscalarMulFix(253, BASE8); + for (i=0; i<253; i++) { + mulFix.e[i] <== snum2bits.out[i]; + } + +// Do the comparation left == right if enabled; + + component eqCheckX = ForceEqualIfEnabled(); + eqCheckX.enabled <== enabled; + eqCheckX.in[0] <== mulFix.out[0]; + eqCheckX.in[1] <== addRight.xout; + + component eqCheckY = ForceEqualIfEnabled(); + eqCheckY.enabled <== enabled; + eqCheckY.in[0] <== mulFix.out[1]; + eqCheckY.in[1] <== addRight.yout; +} diff --git a/circom/node_modules/circomlib/circuits/eddsamimcsponge.circom b/circom/node_modules/circomlib/circuits/eddsamimcsponge.circom new file mode 100644 index 0000000..3267c45 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/eddsamimcsponge.circom @@ -0,0 +1,124 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "compconstant.circom"; +include "pointbits.circom"; +include "mimcsponge.circom"; +include "bitify.circom"; +include "escalarmulany.circom"; +include "escalarmulfix.circom"; + +template EdDSAMiMCSpongeVerifier() { + signal input enabled; + signal input Ax; + signal input Ay; + + signal input S; + signal input R8x; + signal input R8y; + + signal input M; + + var i; + +// Ensure S compConstant.in[i]; + } + compConstant.in[253] <== 0; + compConstant.out === 0; + +// Calculate the h = H(R,A, msg) + + component hash = MiMCSponge(5, 220, 1); + hash.ins[0] <== R8x; + hash.ins[1] <== R8y; + hash.ins[2] <== Ax; + hash.ins[3] <== Ay; + hash.ins[4] <== M; + hash.k <== 0; + + component h2bits = Num2Bits_strict(); + h2bits.in <== hash.outs[0]; + +// Calculate second part of the right side: right2 = h*8*A + + // Multiply by 8 by adding it 3 times. This also ensure that the result is in + // the subgroup. + component dbl1 = BabyDbl(); + dbl1.x <== Ax; + dbl1.y <== Ay; + component dbl2 = BabyDbl(); + dbl2.x <== dbl1.xout; + dbl2.y <== dbl1.yout; + component dbl3 = BabyDbl(); + dbl3.x <== dbl2.xout; + dbl3.y <== dbl2.yout; + + // We check that A is not zero. + component isZero = IsZero(); + isZero.in <== dbl3.x; + isZero.out === 0; + + component mulAny = EscalarMulAny(254); + for (i=0; i<254; i++) { + mulAny.e[i] <== h2bits.out[i]; + } + mulAny.p[0] <== dbl3.xout; + mulAny.p[1] <== dbl3.yout; + + +// Compute the right side: right = R8 + right2 + + component addRight = BabyAdd(); + addRight.x1 <== R8x; + addRight.y1 <== R8y; + addRight.x2 <== mulAny.out[0]; + addRight.y2 <== mulAny.out[1]; + +// Calculate left side of equation left = S*B8 + + var BASE8[2] = [ + 5299619240641551281634865583518297030282874472190772894086521144482721001553, + 16950150798460657717958625567821834550301663161624707787222815936182638968203 + ]; + component mulFix = EscalarMulFix(253, BASE8); + for (i=0; i<253; i++) { + mulFix.e[i] <== snum2bits.out[i]; + } + +// Do the comparation left == right if enabled; + + component eqCheckX = ForceEqualIfEnabled(); + eqCheckX.enabled <== enabled; + eqCheckX.in[0] <== mulFix.out[0]; + eqCheckX.in[1] <== addRight.xout; + + component eqCheckY = ForceEqualIfEnabled(); + eqCheckY.enabled <== enabled; + eqCheckY.in[0] <== mulFix.out[1]; + eqCheckY.in[1] <== addRight.yout; +} diff --git a/circom/node_modules/circomlib/circuits/eddsaposeidon.circom b/circom/node_modules/circomlib/circuits/eddsaposeidon.circom new file mode 100644 index 0000000..1fce1f3 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/eddsaposeidon.circom @@ -0,0 +1,123 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "compconstant.circom"; +include "poseidon.circom"; +include "bitify.circom"; +include "escalarmulany.circom"; +include "escalarmulfix.circom"; + +template EdDSAPoseidonVerifier() { + signal input enabled; + signal input Ax; + signal input Ay; + + signal input S; + signal input R8x; + signal input R8y; + + signal input M; + + var i; + +// Ensure S compConstant.in[i]; + } + compConstant.in[253] <== 0; + compConstant.out*enabled === 0; + +// Calculate the h = H(R,A, msg) + + component hash = Poseidon(5); + + hash.inputs[0] <== R8x; + hash.inputs[1] <== R8y; + hash.inputs[2] <== Ax; + hash.inputs[3] <== Ay; + hash.inputs[4] <== M; + + component h2bits = Num2Bits_strict(); + h2bits.in <== hash.out; + +// Calculate second part of the right side: right2 = h*8*A + + // Multiply by 8 by adding it 3 times. This also ensure that the result is in + // the subgroup. + component dbl1 = BabyDbl(); + dbl1.x <== Ax; + dbl1.y <== Ay; + component dbl2 = BabyDbl(); + dbl2.x <== dbl1.xout; + dbl2.y <== dbl1.yout; + component dbl3 = BabyDbl(); + dbl3.x <== dbl2.xout; + dbl3.y <== dbl2.yout; + + // We check that A is not zero. + component isZero = IsZero(); + isZero.in <== dbl3.x; + isZero.out*enabled === 0; + + component mulAny = EscalarMulAny(254); + for (i=0; i<254; i++) { + mulAny.e[i] <== h2bits.out[i]; + } + mulAny.p[0] <== dbl3.xout; + mulAny.p[1] <== dbl3.yout; + + +// Compute the right side: right = R8 + right2 + + component addRight = BabyAdd(); + addRight.x1 <== R8x; + addRight.y1 <== R8y; + addRight.x2 <== mulAny.out[0]; + addRight.y2 <== mulAny.out[1]; + +// Calculate left side of equation left = S*B8 + + var BASE8[2] = [ + 5299619240641551281634865583518297030282874472190772894086521144482721001553, + 16950150798460657717958625567821834550301663161624707787222815936182638968203 + ]; + component mulFix = EscalarMulFix(253, BASE8); + for (i=0; i<253; i++) { + mulFix.e[i] <== snum2bits.out[i]; + } + +// Do the comparation left == right if enabled; + + component eqCheckX = ForceEqualIfEnabled(); + eqCheckX.enabled <== enabled; + eqCheckX.in[0] <== mulFix.out[0]; + eqCheckX.in[1] <== addRight.xout; + + component eqCheckY = ForceEqualIfEnabled(); + eqCheckY.enabled <== enabled; + eqCheckY.in[0] <== mulFix.out[1]; + eqCheckY.in[1] <== addRight.yout; +} diff --git a/circom/node_modules/circomlib/circuits/escalarmul.circom b/circom/node_modules/circomlib/circuits/escalarmul.circom new file mode 100644 index 0000000..809d995 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/escalarmul.circom @@ -0,0 +1,166 @@ + /* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ + +/* + + ┏━━━━━━━━━━━┓ + ┃ ┃ + ┃ ┃ + (inx, iny) ══════════════════════════════════════════▶┃ EC Point ┃ + ┃ ╠═▶ (outx, outy) + ╔══▶┃ Adder ┃ + ║ ┃ ┃ + ║ ┃ ┃ + ║ ┃ ┃ + ┏━━━━━━━━━━━┓ ┏━━━━━━━━━━━━┓ ║ ┗━━━━━━━━━━━┛ + ┃ ┃ ┃ ┃ ║ + ┃ ┃ ┃ ┃ ║ + ┃ ╠═══(p0x,p0y)═══▶┃ ┃ ║ + ┃ ╠═══(p1x,p1y)═══▶┃ ┃ ║ + ┃ ╠═══(p2x,p2y)═══▶┃ ┃ ║ + ┃ ╠═══(p3x,p3y)═══▶┃ ┃ ║ + ┃ ╠═══(p4x,p4y)═══▶┃ ┃ ║ + ┃ ╠═══(p5x,p5y)═══▶┃ ┃ ║ + ┃ ╠═══(p6x,p6y)═══▶┃ ┃ ║ + ┃ Constant ╠═══(p7x,p7y)═══▶┃ ┃ ║ + ┃ Points ┃ ┃ Mux4 ╠══╝ + ┃ ╠═══(p8x,p8y)═══▶┃ ┃ + ┃ ╠═══(p9x,p9y)═══▶┃ ┃ + ┃ ╠══(p10x,p10y)══▶┃ ┃ + ┃ ╠══(p11x,p11y)══▶┃ ┃ + ┃ ╠══(p12x,p12y)══▶┃ ┃ + ┃ ╠══(p13x,p13y)══▶┃ ┃ + ┃ ╠══(p14x,p14y)══▶┃ ┃ + ┃ ╠══(p15x,p15y)══▶┃ ┃ + ┃ ┃ ┃ ┃ + ┃ ┃ ┃ ┃ + ┗━━━━━━━━━━━┛ ┗━━━━━━━━━━━━┛ + ▲ ▲ ▲ ▲ + │ │ │ │ + s0 ─────────────────────────────────┘ │ │ │ + s1 ────────────────────────────────────┘ │ │ + s2 ───────────────────────────────────────┘ │ + s3 ──────────────────────────────────────────┘ + + + */ +pragma circom 2.0.0; + +include "mux4.circom"; +include "escalarmulw4table.circom"; +include "babyjub.circom"; + +template EscalarMulWindow(base, k) { + + signal input in[2]; + signal input sel[4]; + signal output out[2]; + + var table[16][2]; + component mux; + component adder; + + var i; + + table = EscalarMulW4Table(base, k); + mux = MultiMux4(2); + adder = BabyAdd(); + + for (i=0; i<4; i++) { + sel[i] ==> mux.s[i]; + } + + for (i=0; i<16; i++) { + mux.c[0][i] <== table[i][0]; + mux.c[1][i] <== table[i][1]; + } + + in[0] ==> adder.x1; + in[1] ==> adder.y1; + + mux.out[0] ==> adder.x2; + mux.out[1] ==> adder.y2; + + adder.xout ==> out[0]; + adder.yout ==> out[1]; +} + +/* + + + ┏━━━━━━━━━┓ ┏━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━━━━┓ + ┃ ┃ ┃ ┃ ┃ ┃ + inp ════▶┃Window(0)┃═════▶┃Window(1)┃════════ . . . . ═════════▶┃ Window(nBlocks-1) ┃═════▶ out + ┃ ┃ ┃ ┃ ┃ ┃ + ┗━━━━━━━━━┛ ┗━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━━━┛ + ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ + in[0]─────────┘ │ │ │ │ │ │ │ │ │ │ │ + in[1]───────────┘ │ │ │ │ │ │ │ │ │ │ + in[2]─────────────┘ │ │ │ │ │ │ │ 0 0 + in[3]───────────────┘ │ │ │ │ │ │ + in[4]──────────────────────────┘ │ │ │ │ │ + in[5]────────────────────────────┘ │ │ │ │ + in[6]──────────────────────────────┘ │ │ │ + in[7]────────────────────────────────┘ │ │ + . │ │ + . │ │ + in[n-2]─────────────────────────────────────────────────────────────────────┘ │ + in[n-1]───────────────────────────────────────────────────────────────────────┘ + + */ + +template EscalarMul(n, base) { + signal input in[n]; + signal input inp[2]; // Point input to be added + signal output out[2]; + + var nBlocks = ((n-1)>>2)+1; + var i; + var j; + + component windows[nBlocks]; + + // Construct the windows + for (i=0; i= n) { + windows[i].sel[j] <== 0; + } else { + windows[i].sel[j] <== in[i*4+j]; + } + } + } + + // Start with generator + windows[0].in[0] <== inp[0]; + windows[0].in[1] <== inp[1]; + + for(i=0; i windows[i+1].in[0]; + windows[i].out[1] ==> windows[i+1].in[1]; + } + + windows[nBlocks-1].out[0] ==> out[0]; + windows[nBlocks-1].out[1] ==> out[1]; +} diff --git a/circom/node_modules/circomlib/circuits/escalarmulany.circom b/circom/node_modules/circomlib/circuits/escalarmulany.circom new file mode 100644 index 0000000..f07fe7d --- /dev/null +++ b/circom/node_modules/circomlib/circuits/escalarmulany.circom @@ -0,0 +1,197 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "montgomery.circom"; +include "babyjub.circom"; +include "comparators.circom"; + +template Multiplexor2() { + signal input sel; + signal input in[2][2]; + signal output out[2]; + + out[0] <== (in[1][0] - in[0][0])*sel + in[0][0]; + out[1] <== (in[1][1] - in[0][1])*sel + in[0][1]; +} + +template BitElementMulAny() { + signal input sel; + signal input dblIn[2]; + signal input addIn[2]; + signal output dblOut[2]; + signal output addOut[2]; + + component doubler = MontgomeryDouble(); + component adder = MontgomeryAdd(); + component selector = Multiplexor2(); + + + sel ==> selector.sel; + + dblIn[0] ==> doubler.in[0]; + dblIn[1] ==> doubler.in[1]; + doubler.out[0] ==> adder.in1[0]; + doubler.out[1] ==> adder.in1[1]; + addIn[0] ==> adder.in2[0]; + addIn[1] ==> adder.in2[1]; + addIn[0] ==> selector.in[0][0]; + addIn[1] ==> selector.in[0][1]; + adder.out[0] ==> selector.in[1][0]; + adder.out[1] ==> selector.in[1][1]; + + doubler.out[0] ==> dblOut[0]; + doubler.out[1] ==> dblOut[1]; + selector.out[0] ==> addOut[0]; + selector.out[1] ==> addOut[1]; +} + +// p is montgomery point +// n must be <= 248 +// returns out in twisted edwards +// Double is in montgomery to be linked; + +template SegmentMulAny(n) { + signal input e[n]; + signal input p[2]; + signal output out[2]; + signal output dbl[2]; + + component bits[n-1]; + + component e2m = Edwards2Montgomery(); + + p[0] ==> e2m.in[0]; + p[1] ==> e2m.in[1]; + + var i; + + bits[0] = BitElementMulAny(); + e2m.out[0] ==> bits[0].dblIn[0]; + e2m.out[1] ==> bits[0].dblIn[1]; + e2m.out[0] ==> bits[0].addIn[0]; + e2m.out[1] ==> bits[0].addIn[1]; + e[1] ==> bits[0].sel; + + for (i=1; i bits[i].dblIn[0]; + bits[i-1].dblOut[1] ==> bits[i].dblIn[1]; + bits[i-1].addOut[0] ==> bits[i].addIn[0]; + bits[i-1].addOut[1] ==> bits[i].addIn[1]; + e[i+1] ==> bits[i].sel; + } + + bits[n-2].dblOut[0] ==> dbl[0]; + bits[n-2].dblOut[1] ==> dbl[1]; + + component m2e = Montgomery2Edwards(); + + bits[n-2].addOut[0] ==> m2e.in[0]; + bits[n-2].addOut[1] ==> m2e.in[1]; + + component eadder = BabyAdd(); + + m2e.out[0] ==> eadder.x1; + m2e.out[1] ==> eadder.y1; + -p[0] ==> eadder.x2; + p[1] ==> eadder.y2; + + component lastSel = Multiplexor2(); + + e[0] ==> lastSel.sel; + eadder.xout ==> lastSel.in[0][0]; + eadder.yout ==> lastSel.in[0][1]; + m2e.out[0] ==> lastSel.in[1][0]; + m2e.out[1] ==> lastSel.in[1][1]; + + lastSel.out[0] ==> out[0]; + lastSel.out[1] ==> out[1]; +} + +// This function assumes that p is in the subgroup and it is different to 0 + +template EscalarMulAny(n) { + signal input e[n]; // Input in binary format + signal input p[2]; // Point (Twisted format) + signal output out[2]; // Point (Twisted format) + + var nsegments = (n-1)\148 +1; + var nlastsegment = n - (nsegments-1)*148; + + component segments[nsegments]; + component doublers[nsegments-1]; + component m2e[nsegments-1]; + component adders[nsegments-1]; + component zeropoint = IsZero(); + zeropoint.in <== p[0]; + + var s; + var i; + var nseg; + + for (s=0; s segments[s].e[i]; + } + + if (s==0) { + // force G8 point if input point is zero + segments[s].p[0] <== p[0] + (5299619240641551281634865583518297030282874472190772894086521144482721001553 - p[0])*zeropoint.out; + segments[s].p[1] <== p[1] + (16950150798460657717958625567821834550301663161624707787222815936182638968203 - p[1])*zeropoint.out; + } else { + doublers[s-1] = MontgomeryDouble(); + m2e[s-1] = Montgomery2Edwards(); + adders[s-1] = BabyAdd(); + + segments[s-1].dbl[0] ==> doublers[s-1].in[0]; + segments[s-1].dbl[1] ==> doublers[s-1].in[1]; + + doublers[s-1].out[0] ==> m2e[s-1].in[0]; + doublers[s-1].out[1] ==> m2e[s-1].in[1]; + + m2e[s-1].out[0] ==> segments[s].p[0]; + m2e[s-1].out[1] ==> segments[s].p[1]; + + if (s==1) { + segments[s-1].out[0] ==> adders[s-1].x1; + segments[s-1].out[1] ==> adders[s-1].y1; + } else { + adders[s-2].xout ==> adders[s-1].x1; + adders[s-2].yout ==> adders[s-1].y1; + } + segments[s].out[0] ==> adders[s-1].x2; + segments[s].out[1] ==> adders[s-1].y2; + } + } + + if (nsegments == 1) { + segments[0].out[0]*(1-zeropoint.out) ==> out[0]; + segments[0].out[1]+(1-segments[0].out[1])*zeropoint.out ==> out[1]; + } else { + adders[nsegments-2].xout*(1-zeropoint.out) ==> out[0]; + adders[nsegments-2].yout+(1-adders[nsegments-2].yout)*zeropoint.out ==> out[1]; + } +} diff --git a/circom/node_modules/circomlib/circuits/escalarmulfix.circom b/circom/node_modules/circomlib/circuits/escalarmulfix.circom new file mode 100644 index 0000000..4669d36 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/escalarmulfix.circom @@ -0,0 +1,299 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "mux3.circom"; +include "montgomery.circom"; +include "babyjub.circom"; + +/* + Window of 3 elements, it calculates + out = base + base*in[0] + 2*base*in[1] + 4*base*in[2] + out4 = 4*base + + The result should be compensated. + */ + +/* + + The scalar is s = a0 + a1*2^3 + a2*2^6 + ...... + a81*2^243 + First We calculate Q = B + 2^3*B + 2^6*B + ......... + 2^246*B + + Then we calculate S1 = 2*2^246*B + (1 + a0)*B + (2^3 + a1)*B + .....+ (2^243 + a81)*B + + And Finaly we compute the result: RES = SQ - Q + + As you can see the input of the adders cannot be equal nor zero, except for the last + substraction that it's done in montgomery. + + A good way to see it is that the accumulator input of the adder >= 2^247*B and the other input + is the output of the windows that it's going to be <= 2^246*B + */ +template WindowMulFix() { + signal input in[3]; + signal input base[2]; + signal output out[2]; + signal output out8[2]; // Returns 8*Base (To be linked) + + component mux = MultiMux3(2); + + mux.s[0] <== in[0]; + mux.s[1] <== in[1]; + mux.s[2] <== in[2]; + + component dbl2 = MontgomeryDouble(); + component adr3 = MontgomeryAdd(); + component adr4 = MontgomeryAdd(); + component adr5 = MontgomeryAdd(); + component adr6 = MontgomeryAdd(); + component adr7 = MontgomeryAdd(); + component adr8 = MontgomeryAdd(); + +// in[0] -> 1*BASE + + mux.c[0][0] <== base[0]; + mux.c[1][0] <== base[1]; + +// in[1] -> 2*BASE + dbl2.in[0] <== base[0]; + dbl2.in[1] <== base[1]; + mux.c[0][1] <== dbl2.out[0]; + mux.c[1][1] <== dbl2.out[1]; + +// in[2] -> 3*BASE + adr3.in1[0] <== base[0]; + adr3.in1[1] <== base[1]; + adr3.in2[0] <== dbl2.out[0]; + adr3.in2[1] <== dbl2.out[1]; + mux.c[0][2] <== adr3.out[0]; + mux.c[1][2] <== adr3.out[1]; + +// in[3] -> 4*BASE + adr4.in1[0] <== base[0]; + adr4.in1[1] <== base[1]; + adr4.in2[0] <== adr3.out[0]; + adr4.in2[1] <== adr3.out[1]; + mux.c[0][3] <== adr4.out[0]; + mux.c[1][3] <== adr4.out[1]; + +// in[4] -> 5*BASE + adr5.in1[0] <== base[0]; + adr5.in1[1] <== base[1]; + adr5.in2[0] <== adr4.out[0]; + adr5.in2[1] <== adr4.out[1]; + mux.c[0][4] <== adr5.out[0]; + mux.c[1][4] <== adr5.out[1]; + +// in[5] -> 6*BASE + adr6.in1[0] <== base[0]; + adr6.in1[1] <== base[1]; + adr6.in2[0] <== adr5.out[0]; + adr6.in2[1] <== adr5.out[1]; + mux.c[0][5] <== adr6.out[0]; + mux.c[1][5] <== adr6.out[1]; + +// in[6] -> 7*BASE + adr7.in1[0] <== base[0]; + adr7.in1[1] <== base[1]; + adr7.in2[0] <== adr6.out[0]; + adr7.in2[1] <== adr6.out[1]; + mux.c[0][6] <== adr7.out[0]; + mux.c[1][6] <== adr7.out[1]; + +// in[7] -> 8*BASE + adr8.in1[0] <== base[0]; + adr8.in1[1] <== base[1]; + adr8.in2[0] <== adr7.out[0]; + adr8.in2[1] <== adr7.out[1]; + mux.c[0][7] <== adr8.out[0]; + mux.c[1][7] <== adr8.out[1]; + + out8[0] <== adr8.out[0]; + out8[1] <== adr8.out[1]; + + out[0] <== mux.out[0]; + out[1] <== mux.out[1]; +} + + +/* + This component does a multiplication of a escalar times a fix base + Signals: + e: The scalar in bits + base: the base point in edwards format + out: The result + dbl: Point in Edwards to be linked to the next segment. + */ + +template SegmentMulFix(nWindows) { + signal input e[nWindows*3]; + signal input base[2]; + signal output out[2]; + signal output dbl[2]; + + var i; + var j; + + // Convert the base to montgomery + + component e2m = Edwards2Montgomery(); + e2m.in[0] <== base[0]; + e2m.in[1] <== base[1]; + + component windows[nWindows]; + component adders[nWindows]; + component cadders[nWindows]; + + // In the last step we add an extra doubler so that numbers do not match. + component dblLast = MontgomeryDouble(); + + for (i=0; i out[0]; + cAdd.yout ==> out[1]; + + windows[nWindows-1].out8[0] ==> dbl[0]; + windows[nWindows-1].out8[1] ==> dbl[1]; +} + + +/* +This component multiplies a escalar times a fixed point BASE (twisted edwards format) + Signals + e: The escalar in binary format + out: The output point in twisted edwards + */ +template EscalarMulFix(n, BASE) { + signal input e[n]; // Input in binary format + signal output out[2]; // Point (Twisted format) + + var nsegments = (n-1)\246 +1; // 249 probably would work. But I'm not sure and for security I keep 246 + var nlastsegment = n - (nsegments-1)*249; + + component segments[nsegments]; + + component m2e[nsegments-1]; + component adders[nsegments-1]; + + var s; + var i; + var nseg; + var nWindows; + + for (s=0; s m2e[s-1].in[0]; + segments[s-1].dbl[1] ==> m2e[s-1].in[1]; + + m2e[s-1].out[0] ==> segments[s].base[0]; + m2e[s-1].out[1] ==> segments[s].base[1]; + + if (s==1) { + segments[s-1].out[0] ==> adders[s-1].x1; + segments[s-1].out[1] ==> adders[s-1].y1; + } else { + adders[s-2].xout ==> adders[s-1].x1; + adders[s-2].yout ==> adders[s-1].y1; + } + segments[s].out[0] ==> adders[s-1].x2; + segments[s].out[1] ==> adders[s-1].y2; + } + } + + if (nsegments == 1) { + segments[0].out[0] ==> out[0]; + segments[0].out[1] ==> out[1]; + } else { + adders[nsegments-2].xout ==> out[0]; + adders[nsegments-2].yout ==> out[1]; + } +} diff --git a/circom/node_modules/circomlib/circuits/escalarmulw4table.circom b/circom/node_modules/circomlib/circuits/escalarmulw4table.circom new file mode 100644 index 0000000..25c095a --- /dev/null +++ b/circom/node_modules/circomlib/circuits/escalarmulw4table.circom @@ -0,0 +1,52 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +function pointAdd(x1,y1,x2,y2) { + var a = 168700; + var d = 168696; + + var res[2]; + res[0] = (x1*y2 + y1*x2) / (1 + d*x1*x2*y1*y2); + res[1] = (y1*y2 - a*x1*x2) / (1 - d*x1*x2*y1*y2); + return res; +} + +function EscalarMulW4Table(base, k) { + var out[16][2]; + + var i; + var p[2]; + + var dbl[2] = base; + + for (i=0; i. +*/ +pragma circom 2.0.0; + +template XOR() { + signal input a; + signal input b; + signal output out; + + out <== a + b - 2*a*b; +} + +template AND() { + signal input a; + signal input b; + signal output out; + + out <== a*b; +} + +template OR() { + signal input a; + signal input b; + signal output out; + + out <== a + b - a*b; +} + +template NOT() { + signal input in; + signal output out; + + out <== 1 + in - 2*in; +} + +template NAND() { + signal input a; + signal input b; + signal output out; + + out <== 1 - a*b; +} + +template NOR() { + signal input a; + signal input b; + signal output out; + + out <== a*b + 1 - a - b; +} + +template MultiAND(n) { + signal input in[n]; + signal output out; + component and1; + component and2; + component ands[2]; + if (n==1) { + out <== in[0]; + } else if (n==2) { + and1 = AND(); + and1.a <== in[0]; + and1.b <== in[1]; + out <== and1.out; + } else { + and2 = AND(); + var n1 = n\2; + var n2 = n-n\2; + ands[0] = MultiAND(n1); + ands[1] = MultiAND(n2); + var i; + for (i=0; i. +*/ +pragma circom 2.0.0; + +template MiMC7(nrounds) { + signal input x_in; + signal input k; + signal output out; + + var c[91] = [ + 0, + 20888961410941983456478427210666206549300505294776164667214940546594746570981, + 15265126113435022738560151911929040668591755459209400716467504685752745317193, + 8334177627492981984476504167502758309043212251641796197711684499645635709656, + 1374324219480165500871639364801692115397519265181803854177629327624133579404, + 11442588683664344394633565859260176446561886575962616332903193988751292992472, + 2558901189096558760448896669327086721003508630712968559048179091037845349145, + 11189978595292752354820141775598510151189959177917284797737745690127318076389, + 3262966573163560839685415914157855077211340576201936620532175028036746741754, + 17029914891543225301403832095880481731551830725367286980611178737703889171730, + 4614037031668406927330683909387957156531244689520944789503628527855167665518, + 19647356996769918391113967168615123299113119185942498194367262335168397100658, + 5040699236106090655289931820723926657076483236860546282406111821875672148900, + 2632385916954580941368956176626336146806721642583847728103570779270161510514, + 17691411851977575435597871505860208507285462834710151833948561098560743654671, + 11482807709115676646560379017491661435505951727793345550942389701970904563183, + 8360838254132998143349158726141014535383109403565779450210746881879715734773, + 12663821244032248511491386323242575231591777785787269938928497649288048289525, + 3067001377342968891237590775929219083706800062321980129409398033259904188058, + 8536471869378957766675292398190944925664113548202769136103887479787957959589, + 19825444354178182240559170937204690272111734703605805530888940813160705385792, + 16703465144013840124940690347975638755097486902749048533167980887413919317592, + 13061236261277650370863439564453267964462486225679643020432589226741411380501, + 10864774797625152707517901967943775867717907803542223029967000416969007792571, + 10035653564014594269791753415727486340557376923045841607746250017541686319774, + 3446968588058668564420958894889124905706353937375068998436129414772610003289, + 4653317306466493184743870159523234588955994456998076243468148492375236846006, + 8486711143589723036499933521576871883500223198263343024003617825616410932026, + 250710584458582618659378487568129931785810765264752039738223488321597070280, + 2104159799604932521291371026105311735948154964200596636974609406977292675173, + 16313562605837709339799839901240652934758303521543693857533755376563489378839, + 6032365105133504724925793806318578936233045029919447519826248813478479197288, + 14025118133847866722315446277964222215118620050302054655768867040006542798474, + 7400123822125662712777833064081316757896757785777291653271747396958201309118, + 1744432620323851751204287974553233986555641872755053103823939564833813704825, + 8316378125659383262515151597439205374263247719876250938893842106722210729522, + 6739722627047123650704294650168547689199576889424317598327664349670094847386, + 21211457866117465531949733809706514799713333930924902519246949506964470524162, + 13718112532745211817410303291774369209520657938741992779396229864894885156527, + 5264534817993325015357427094323255342713527811596856940387954546330728068658, + 18884137497114307927425084003812022333609937761793387700010402412840002189451, + 5148596049900083984813839872929010525572543381981952060869301611018636120248, + 19799686398774806587970184652860783461860993790013219899147141137827718662674, + 19240878651604412704364448729659032944342952609050243268894572835672205984837, + 10546185249390392695582524554167530669949955276893453512788278945742408153192, + 5507959600969845538113649209272736011390582494851145043668969080335346810411, + 18177751737739153338153217698774510185696788019377850245260475034576050820091, + 19603444733183990109492724100282114612026332366576932662794133334264283907557, + 10548274686824425401349248282213580046351514091431715597441736281987273193140, + 1823201861560942974198127384034483127920205835821334101215923769688644479957, + 11867589662193422187545516240823411225342068709600734253659804646934346124945, + 18718569356736340558616379408444812528964066420519677106145092918482774343613, + 10530777752259630125564678480897857853807637120039176813174150229243735996839, + 20486583726592018813337145844457018474256372770211860618687961310422228379031, + 12690713110714036569415168795200156516217175005650145422920562694422306200486, + 17386427286863519095301372413760745749282643730629659997153085139065756667205, + 2216432659854733047132347621569505613620980842043977268828076165669557467682, + 6309765381643925252238633914530877025934201680691496500372265330505506717193, + 20806323192073945401862788605803131761175139076694468214027227878952047793390, + 4037040458505567977365391535756875199663510397600316887746139396052445718861, + 19948974083684238245321361840704327952464170097132407924861169241740046562673, + 845322671528508199439318170916419179535949348988022948153107378280175750024, + 16222384601744433420585982239113457177459602187868460608565289920306145389382, + 10232118865851112229330353999139005145127746617219324244541194256766741433339, + 6699067738555349409504843460654299019000594109597429103342076743347235369120, + 6220784880752427143725783746407285094967584864656399181815603544365010379208, + 6129250029437675212264306655559561251995722990149771051304736001195288083309, + 10773245783118750721454994239248013870822765715268323522295722350908043393604, + 4490242021765793917495398271905043433053432245571325177153467194570741607167, + 19596995117319480189066041930051006586888908165330319666010398892494684778526, + 837850695495734270707668553360118467905109360511302468085569220634750561083, + 11803922811376367215191737026157445294481406304781326649717082177394185903907, + 10201298324909697255105265958780781450978049256931478989759448189112393506592, + 13564695482314888817576351063608519127702411536552857463682060761575100923924, + 9262808208636973454201420823766139682381973240743541030659775288508921362724, + 173271062536305557219323722062711383294158572562695717740068656098441040230, + 18120430890549410286417591505529104700901943324772175772035648111937818237369, + 20484495168135072493552514219686101965206843697794133766912991150184337935627, + 19155651295705203459475805213866664350848604323501251939850063308319753686505, + 11971299749478202793661982361798418342615500543489781306376058267926437157297, + 18285310723116790056148596536349375622245669010373674803854111592441823052978, + 7069216248902547653615508023941692395371990416048967468982099270925308100727, + 6465151453746412132599596984628739550147379072443683076388208843341824127379, + 16143532858389170960690347742477978826830511669766530042104134302796355145785, + 19362583304414853660976404410208489566967618125972377176980367224623492419647, + 1702213613534733786921602839210290505213503664731919006932367875629005980493, + 10781825404476535814285389902565833897646945212027592373510689209734812292327, + 4212716923652881254737947578600828255798948993302968210248673545442808456151, + 7594017890037021425366623750593200398174488805473151513558919864633711506220, + 18979889247746272055963929241596362599320706910852082477600815822482192194401, + 13602139229813231349386885113156901793661719180900395818909719758150455500533 + ]; + + var t; + signal t2[nrounds]; + signal t4[nrounds]; + signal t6[nrounds]; + signal t7[nrounds-1]; + + for (var i=0; i nRounds should be 220 +template MiMCSponge(nInputs, nRounds, nOutputs) { + signal input ins[nInputs]; + signal input k; + signal output outs[nOutputs]; + + var i; + + // S = R||C + component S[nInputs + nOutputs - 1]; + + for (i = 0; i < nInputs; i++) { + S[i] = MiMCFeistel(nRounds); + S[i].k <== k; + if (i == 0) { + S[i].xL_in <== ins[0]; + S[i].xR_in <== 0; + } else { + S[i].xL_in <== S[i-1].xL_out + ins[i]; + S[i].xR_in <== S[i-1].xR_out; + } + } + + outs[0] <== S[nInputs - 1].xL_out; + + for (i = 0; i < nOutputs - 1; i++) { + S[nInputs + i] = MiMCFeistel(nRounds); + S[nInputs + i].k <== k; + S[nInputs + i].xL_in <== S[nInputs + i - 1].xL_out; + S[nInputs + i].xR_in <== S[nInputs + i - 1].xR_out; + outs[i + 1] <== S[nInputs + i].xL_out; + } +} + +template MiMCFeistel(nrounds) { + signal input xL_in; + signal input xR_in; + signal input k; + signal output xL_out; + signal output xR_out; + + // doesn't contain the first and last round constants, which are always zero + var c_partial[218] = [ + 7120861356467848435263064379192047478074060781135320967663101236819528304084, + 5024705281721889198577876690145313457398658950011302225525409148828000436681, + 17980351014018068290387269214713820287804403312720763401943303895585469787384, + 19886576439381707240399940949310933992335779767309383709787331470398675714258, + 1213715278223786725806155661738676903520350859678319590331207960381534602599, + 18162138253399958831050545255414688239130588254891200470934232514682584734511, + 7667462281466170157858259197976388676420847047604921256361474169980037581876, + 7207551498477838452286210989212982851118089401128156132319807392460388436957, + 9864183311657946807255900203841777810810224615118629957816193727554621093838, + 4798196928559910300796064665904583125427459076060519468052008159779219347957, + 17387238494588145257484818061490088963673275521250153686214197573695921400950, + 10005334761930299057035055370088813230849810566234116771751925093634136574742, + 11897542014760736209670863723231849628230383119798486487899539017466261308762, + 16771780563523793011283273687253985566177232886900511371656074413362142152543, + 749264854018824809464168489785113337925400687349357088413132714480582918506, + 3683645737503705042628598550438395339383572464204988015434959428676652575331, + 7556750851783822914673316211129907782679509728346361368978891584375551186255, + 20391289379084797414557439284689954098721219201171527383291525676334308303023, + 18146517657445423462330854383025300323335289319277199154920964274562014376193, + 8080173465267536232534446836148661251987053305394647905212781979099916615292, + 10796443006899450245502071131975731672911747129805343722228413358507805531141, + 5404287610364961067658660283245291234008692303120470305032076412056764726509, + 4623894483395123520243967718315330178025957095502546813929290333264120223168, + 16845753148201777192406958674202574751725237939980634861948953189320362207797, + 4622170486584704769521001011395820886029808520586507873417553166762370293671, + 16688277490485052681847773549197928630624828392248424077804829676011512392564, + 11878652861183667748838188993669912629573713271883125458838494308957689090959, + 2436445725746972287496138382764643208791713986676129260589667864467010129482, + 1888098689545151571063267806606510032698677328923740058080630641742325067877, + 148924106504065664829055598316821983869409581623245780505601526786791681102, + 18875020877782404439294079398043479420415331640996249745272087358069018086569, + 15189693413320228845990326214136820307649565437237093707846682797649429515840, + 19669450123472657781282985229369348220906547335081730205028099210442632534079, + 5521922218264623411380547905210139511350706092570900075727555783240701821773, + 4144769320246558352780591737261172907511489963810975650573703217887429086546, + 10097732913112662248360143041019433907849917041759137293018029019134392559350, + 1720059427972723034107765345743336447947522473310069975142483982753181038321, + 6302388219880227251325608388535181451187131054211388356563634768253301290116, + 6745410632962119604799318394592010194450845483518862700079921360015766217097, + 10858157235265583624235850660462324469799552996870780238992046963007491306222, + 20241898894740093733047052816576694435372877719072347814065227797906130857593, + 10165780782761211520836029617746977303303335603838343292431760011576528327409, + 2832093654883670345969792724123161241696170611611744759675180839473215203706, + 153011722355526826233082383360057587249818749719433916258246100068258954737, + 20196970640587451358539129330170636295243141659030208529338914906436009086943, + 3180973917010545328313139835982464870638521890385603025657430208141494469656, + 17198004293191777441573635123110935015228014028618868252989374962722329283022, + 7642160509228669138628515458941659189680509753651629476399516332224325757132, + 19346204940546791021518535594447257347218878114049998691060016493806845179755, + 11501810868606870391127866188394535330696206817602260610801897042898616817272, + 3113973447392053821824427670386252797811804954746053461397972968381571297505, + 6545064306297957002139416752334741502722251869537551068239642131448768236585, + 5203908808704813498389265425172875593837960384349653691918590736979872578408, + 2246692432011290582160062129070762007374502637007107318105405626910313810224, + 11760570435432189127645691249600821064883781677693087773459065574359292849137, + 5543749482491340532547407723464609328207990784853381797689466144924198391839, + 8837549193990558762776520822018694066937602576881497343584903902880277769302, + 12855514863299373699594410385788943772765811961581749194183533625311486462501, + 5363660674689121676875069134269386492382220935599781121306637800261912519729, + 13162342403579303950549728848130828093497701266240457479693991108217307949435, + 916941639326869583414469202910306428966657806899788970948781207501251816730, + 15618589556584434434009868216186115416835494805174158488636000580759692174228, + 8959562060028569701043973060670353733575345393653685776974948916988033453971, + 16390754464333401712265575949874369157699293840516802426621216808905079127650, + 168282396747788514908709091757591226095443902501365500003618183905496160435, + 8327443473179334761744301768309008451162322941906921742120510244986704677004, + 17213012626801210615058753489149961717422101711567228037597150941152495100640, + 10394369641533736715250242399198097296122982486516256408681925424076248952280, + 17784386835392322654196171115293700800825771210400152504776806618892170162248, + 16533189939837087893364000390641148516479148564190420358849587959161226782982, + 18725396114211370207078434315900726338547621160475533496863298091023511945076, + 7132325028834551397904855671244375895110341505383911719294705267624034122405, + 148317947440800089795933930720822493695520852448386394775371401743494965187, + 19001050671757720352890779127693793630251266879994702723636759889378387053056, + 18824274411769830274877839365728651108434404855803844568234862945613766611460, + 12771414330193951156383998390424063470766226667986423961689712557338777174205, + 11332046574800279729678603488745295198038913503395629790213378101166488244657, + 9607550223176946388146938069307456967842408600269548190739947540821716354749, + 8756385288462344550200229174435953103162307705310807828651304665320046782583, + 176061952957067086877570020242717222844908281373122372938833890096257042779, + 12200212977482648306758992405065921724409841940671166017620928947866825250857, + 10868453624107875516866146499877130701929063632959660262366632833504750028858, + 2016095394399807253596787752134573207202567875457560571095586743878953450738, + 21815578223768330433802113452339488275704145896544481092014911825656390567514, + 4923772847693564777744725640710197015181591950368494148029046443433103381621, + 1813584943682214789802230765734821149202472893379265320098816901270224589984, + 10810123816265612772922113403831964815724109728287572256602010709288980656498, + 1153669123397255702524721206511185557982017410156956216465120456256288427021, + 5007518659266430200134478928344522649876467369278722765097865662497773767152, + 2511432546938591792036639990606464315121646668029252285288323664350666551637, + 32883284540320451295484135704808083452381176816565850047310272290579727564, + 10484856914279112612610993418405543310546746652738541161791501150994088679557, + 2026733759645519472558796412979210009170379159866522399881566309631434814953, + 14731806221235869882801331463708736361296174006732553130708107037190460654379, + 14740327483193277147065845135561988641238516852487657117813536909482068950652, + 18787428285295558781869865751953016580493190547148386433580291216673009884554, + 3804047064713122820157099453648459188816376755739202017447862327783289895072, + 16709604795697901641948603019242067672006293290826991671766611326262532802914, + 11061717085931490100602849654034280576915102867237101935487893025907907250695, + 2821730726367472966906149684046356272806484545281639696873240305052362149654, + 17467794879902895769410571945152708684493991588672014763135370927880883292655, + 1571520786233540988201616650622796363168031165456869481368085474420849243232, + 10041051776251223165849354194892664881051125330236567356945669006147134614302, + 3981753758468103976812813304477670033098707002886030847251581853700311567551, + 4365864398105436789177703571412645548020537580493599380018290523813331678900, + 2391801327305361293476178683853802679507598622000359948432171562543560193350, + 214219368547551689972421167733597094823289857206402800635962137077096090722, + 18192064100315141084242006659317257023098826945893371479835220462302399655674, + 15487549757142039139328911515400805508248576685795694919457041092150651939253, + 10142447197759703415402259672441315777933858467700579946665223821199077641122, + 11246573086260753259993971254725613211193686683988426513880826148090811891866, + 6574066859860991369704567902211886840188702386542112593710271426704432301235, + 11311085442652291634822798307831431035776248927202286895207125867542470350078, + 20977948360215259915441258687649465618185769343138135384346964466965010873779, + 792781492853909872425531014397300057232399608769451037135936617996830018501, + 5027602491523497423798779154966735896562099398367163998686335127580757861872, + 14595204575654316237672764823862241845410365278802914304953002937313300553572, + 13973538843621261113924259058427434053808430378163734641175100160836376897004, + 16395063164993626722686882727042150241125309409717445381854913964674649318585, + 8465768840047024550750516678171433288207841931251654898809033371655109266663, + 21345603324471810861925019445720576814602636473739003852898308205213912255830, + 21171984405852590343970239018692870799717057961108910523876770029017785940991, + 10761027113757988230637066281488532903174559953630210849190212601991063767647, + 6678298831065390834922566306988418588227382406175769592902974103663687992230, + 4993662582188632374202316265508850988596880036291765531885657575099537176757, + 18364168158495573675698600238443218434246806358811328083953887470513967121206, + 3506345610354615013737144848471391553141006285964325596214723571988011984829, + 248732676202643792226973868626360612151424823368345645514532870586234380100, + 10090204501612803176317709245679152331057882187411777688746797044706063410969, + 21297149835078365363970699581821844234354988617890041296044775371855432973500, + 16729368143229828574342820060716366330476985824952922184463387490091156065099, + 4467191506765339364971058668792642195242197133011672559453028147641428433293, + 8677548159358013363291014307402600830078662555833653517843708051504582990832, + 1022951765127126818581466247360193856197472064872288389992480993218645055345, + 1888195070251580606973417065636430294417895423429240431595054184472931224452, + 4221265384902749246920810956363310125115516771964522748896154428740238579824, + 2825393571154632139467378429077438870179957021959813965940638905853993971879, + 19171031072692942278056619599721228021635671304612437350119663236604712493093, + 10780807212297131186617505517708903709488273075252405602261683478333331220733, + 18230936781133176044598070768084230333433368654744509969087239465125979720995, + 16901065971871379877929280081392692752968612240624985552337779093292740763381, + 146494141603558321291767829522948454429758543710648402457451799015963102253, + 2492729278659146790410698334997955258248120870028541691998279257260289595548, + 2204224910006646535594933495262085193210692406133533679934843341237521233504, + 16062117410185840274616925297332331018523844434907012275592638570193234893570, + 5894928453677122829055071981254202951712129328678534592916926069506935491729, + 4947482739415078212217504789923078546034438919537985740403824517728200332286, + 16143265650645676880461646123844627780378251900510645261875867423498913438066, + 397690828254561723549349897112473766901585444153303054845160673059519614409, + 11272653598912269895509621181205395118899451234151664604248382803490621227687, + 15566927854306879444693061574322104423426072650522411176731130806720753591030, + 14222898219492484180162096141564251903058269177856173968147960855133048449557, + 16690275395485630428127725067513114066329712673106153451801968992299636791385, + 3667030990325966886479548860429670833692690972701471494757671819017808678584, + 21280039024501430842616328642522421302481259067470872421086939673482530783142, + 15895485136902450169492923978042129726601461603404514670348703312850236146328, + 7733050956302327984762132317027414325566202380840692458138724610131603812560, + 438123800976401478772659663183448617575635636575786782566035096946820525816, + 814913922521637742587885320797606426167962526342166512693085292151314976633, + 12368712287081330853637674140264759478736012797026621876924395982504369598764, + 2494806857395134874309386694756263421445039103814920780777601708371037591569, + 16101132301514338989512946061786320637179843435886825102406248183507106312877, + 6252650284989960032925831409804233477770646333900692286731621844532438095656, + 9277135875276787021836189566799935097400042171346561246305113339462708861695, + 10493603554686607050979497281838644324893776154179810893893660722522945589063, + 8673089750662709235894359384294076697329948991010184356091130382437645649279, + 9558393272910366944245875920138649617479779893610128634419086981339060613250, + 19012287860122586147374214541764572282814469237161122489573881644994964647218, + 9783723818270121678386992630754842961728702994964214799008457449989291229500, + 15550788416669474113213749561488122552422887538676036667630838378023479382689, + 15016165746156232864069722572047169071786333815661109750860165034341572904221, + 6506225705710197163670556961299945987488979904603689017479840649664564978574, + 10796631184889302076168355684722130903785890709107732067446714470783437829037, + 19871836214837460419845806980869387567383718044439891735114283113359312279540, + 20871081766843466343749609089986071784031203517506781251203251608363835140622, + 5100105771517691442278432864090229416166996183792075307747582375962855820797, + 8777887112076272395250620301071581171386440850451972412060638225741125310886, + 5300440870136391278944213332144327695659161151625757537632832724102670898756, + 1205448543652932944633962232545707633928124666868453915721030884663332604536, + 5542499997310181530432302492142574333860449305424174466698068685590909336771, + 11028094245762332275225364962905938096659249161369092798505554939952525894293, + 19187314764836593118404597958543112407224947638377479622725713735224279297009, + 17047263688548829001253658727764731047114098556534482052135734487985276987385, + 19914849528178967155534624144358541535306360577227460456855821557421213606310, + 2929658084700714257515872921366736697080475676508114973627124569375444665664, + 15092262360719700162343163278648422751610766427236295023221516498310468956361, + 21578580340755653236050830649990190843552802306886938815497471545814130084980, + 1258781501221760320019859066036073675029057285507345332959539295621677296991, + 3819598418157732134449049289585680301176983019643974929528867686268702720163, + 8653175945487997845203439345797943132543211416447757110963967501177317426221, + 6614652990340435611114076169697104582524566019034036680161902142028967568142, + 19212515502973904821995111796203064175854996071497099383090983975618035391558, + 18664315914479294273286016871365663486061896605232511201418576829062292269769, + 11498264615058604317482574216318586415670903094838791165247179252175768794889, + 10814026414212439999107945133852431304483604215416531759535467355316227331774, + 17566185590731088197064706533119299946752127014428399631467913813769853431107, + 14016139747289624978792446847000951708158212463304817001882956166752906714332, + 8242601581342441750402731523736202888792436665415852106196418942315563860366, + 9244680976345080074252591214216060854998619670381671198295645618515047080988, + 12216779172735125538689875667307129262237123728082657485828359100719208190116, + 10702811721859145441471328511968332847175733707711670171718794132331147396634, + 6479667912792222539919362076122453947926362746906450079329453150607427372979, + 15117544653571553820496948522381772148324367479772362833334593000535648316185, + 6842203153996907264167856337497139692895299874139131328642472698663046726780, + 12732823292801537626009139514048596316076834307941224506504666470961250728055, + 6936272626871035740815028148058841877090860312517423346335878088297448888663, + 17297554111853491139852678417579991271009602631577069694853813331124433680030, + 16641596134749940573104316021365063031319260205559553673368334842484345864859, + 7400481189785154329569470986896455371037813715804007747228648863919991399081, + 2273205422216987330510475127669563545720586464429614439716564154166712854048, + 15162538063742142685306302282127534305212832649282186184583465569986719234456, + 5628039096440332922248578319648483863204530861778160259559031331287721255522, + 16085392195894691829567913404182676871326863890140775376809129785155092531260, + 14227467863135365427954093998621993651369686288941275436795622973781503444257, + 18224457394066545825553407391290108485121649197258948320896164404518684305122, + 274945154732293792784580363548970818611304339008964723447672490026510689427, + 11050822248291117548220126630860474473945266276626263036056336623671308219529, + 2119542016932434047340813757208803962484943912710204325088879681995922344971 + ]; + + var t; + signal t2[nrounds]; + signal t4[nrounds]; + signal xL[nrounds-1]; + signal xR[nrounds-1]; + + var c; + for (var i=0; i. +*/ + +/* + Source: https://en.wikipedia.org/wiki/Montgomery_curve + + 1 + y 1 + y + [u, v] = [ ------- , ---------- ] + 1 - y (1 - y)x + + */ + pragma circom 2.0.0; + +template Edwards2Montgomery() { + signal input in[2]; + signal output out[2]; + + out[0] <-- (1 + in[1]) / (1 - in[1]); + out[1] <-- out[0] / in[0]; + + + out[0] * (1-in[1]) === (1 + in[1]); + out[1] * in[0] === out[0]; +} + +/* + + u u - 1 + [x, y] = [ ---, ------- ] + v u + 1 + + */ +template Montgomery2Edwards() { + signal input in[2]; + signal output out[2]; + + out[0] <-- in[0] / in[1]; + out[1] <-- (in[0] - 1) / (in[0] + 1); + + out[0] * in[1] === in[0]; + out[1] * (in[0] + 1) === in[0] - 1; +} + + +/* + x2 - x1 + lamda = --------- + y2 - y1 + + x3 + A + x1 + x2 + x3 = B * lamda^2 - A - x1 -x2 => lamda^2 = ------------------ + B + + y3 = (2*x1 + x2 + A)*lamda - B*lamda^3 - y1 => + + + => y3 = lamda * ( 2*x1 + x2 + A - x3 - A - x1 - x2) - y1 => + + => y3 = lamda * ( x1 - x3 ) - y1 + +---------- + + y2 - y1 + lamda = --------- + x2 - x1 + + x3 = B * lamda^2 - A - x1 -x2 + + y3 = lamda * ( x1 - x3 ) - y1 + + */ + +template MontgomeryAdd() { + signal input in1[2]; + signal input in2[2]; + signal output out[2]; + + var a = 168700; + var d = 168696; + + var A = (2 * (a + d)) / (a - d); + var B = 4 / (a - d); + + signal lamda; + + lamda <-- (in2[1] - in1[1]) / (in2[0] - in1[0]); + lamda * (in2[0] - in1[0]) === (in2[1] - in1[1]); + + out[0] <== B*lamda*lamda - A - in1[0] -in2[0]; + out[1] <== lamda * (in1[0] - out[0]) - in1[1]; +} + +/* + + x1_2 = x1*x1 + + 3*x1_2 + 2*A*x1 + 1 + lamda = --------------------- + 2*B*y1 + + x3 = B * lamda^2 - A - x1 -x1 + + y3 = lamda * ( x1 - x3 ) - y1 + + */ +template MontgomeryDouble() { + signal input in[2]; + signal output out[2]; + + var a = 168700; + var d = 168696; + + var A = (2 * (a + d)) / (a - d); + var B = 4 / (a - d); + + signal lamda; + signal x1_2; + + x1_2 <== in[0] * in[0]; + + lamda <-- (3*x1_2 + 2*A*in[0] + 1 ) / (2*B*in[1]); + lamda * (2*B*in[1]) === (3*x1_2 + 2*A*in[0] + 1 ); + + out[0] <== B*lamda*lamda - A - 2*in[0]; + out[1] <== lamda * (in[0] - out[0]) - in[1]; +} diff --git a/circom/node_modules/circomlib/circuits/multiplexer.circom b/circom/node_modules/circomlib/circuits/multiplexer.circom new file mode 100644 index 0000000..848e31e --- /dev/null +++ b/circom/node_modules/circomlib/circuits/multiplexer.circom @@ -0,0 +1,115 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ + +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ + +// --> Assignation without constraint +// <-- Assignation without constraint +// === Constraint +// <== Assignation with constraint +// ==> Assignation with constraint +// All variables are members of the field F[p] +// https://github.com/zcash-hackworks/sapling-crypto +// https://github.com/ebfull/bellman + +/* +function log2(a) { + if (a==0) { + return 0; + } + let n = 1; + let r = 1; + while (n success; + success * (success -1) === 0; +} + + +template Multiplexer(wIn, nIn) { + signal input inp[nIn][wIn]; + signal input sel; + signal output out[wIn]; + component dec = Decoder(nIn); + component ep[wIn]; + + for (var k=0; k dec.inp; + for (var j=0; j ep[j].in1[k]; + dec.out[k] ==> ep[j].in2[k]; + } + ep[j].out ==> out[j]; + } + dec.success === 1; +} diff --git a/circom/node_modules/circomlib/circuits/mux1.circom b/circom/node_modules/circomlib/circuits/mux1.circom new file mode 100644 index 0000000..444cb84 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/mux1.circom @@ -0,0 +1,48 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +template MultiMux1(n) { + signal input c[n][2]; // Constants + signal input s; // Selector + signal output out[n]; + + for (var i=0; i mux.s; + + mux.out[0] ==> out; +} diff --git a/circom/node_modules/circomlib/circuits/mux2.circom b/circom/node_modules/circomlib/circuits/mux2.circom new file mode 100644 index 0000000..557539b --- /dev/null +++ b/circom/node_modules/circomlib/circuits/mux2.circom @@ -0,0 +1,63 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +template MultiMux2(n) { + signal input c[n][4]; // Constants + signal input s[2]; // Selector + signal output out[n]; + + signal a10[n]; + signal a1[n]; + signal a0[n]; + signal a[n]; + + signal s10; + s10 <== s[1] * s[0]; + + for (var i=0; i mux.s[i]; + } + + mux.out[0] ==> out; +} diff --git a/circom/node_modules/circomlib/circuits/mux3.circom b/circom/node_modules/circomlib/circuits/mux3.circom new file mode 100644 index 0000000..4be5f7c --- /dev/null +++ b/circom/node_modules/circomlib/circuits/mux3.circom @@ -0,0 +1,75 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +template MultiMux3(n) { + signal input c[n][8]; // Constants + signal input s[3]; // Selector + signal output out[n]; + + signal a210[n]; + signal a21[n]; + signal a20[n]; + signal a2[n]; + + signal a10[n]; + signal a1[n]; + signal a0[n]; + signal a[n]; + + // 4 constrains for the intermediary variables + signal s10; + s10 <== s[1] * s[0]; + + for (var i=0; i mux.s[i]; + } + + mux.out[0] ==> out; +} diff --git a/circom/node_modules/circomlib/circuits/mux4.circom b/circom/node_modules/circomlib/circuits/mux4.circom new file mode 100644 index 0000000..01e98bc --- /dev/null +++ b/circom/node_modules/circomlib/circuits/mux4.circom @@ -0,0 +1,119 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +template MultiMux4(n) { + signal input c[n][16]; // Constants + signal input s[4]; // Selector + signal output out[n]; + + signal a3210[n]; + signal a321[n]; + signal a320[n]; + signal a310[n]; + signal a32[n]; + signal a31[n]; + signal a30[n]; + signal a3[n]; + + signal a210[n]; + signal a21[n]; + signal a20[n]; + signal a10[n]; + signal a2[n]; + signal a1[n]; + signal a0[n]; + signal a[n]; + + // 4 constrains for the intermediary variables + signal s10; + s10 <== s[1] * s[0]; + signal s20; + s20 <== s[2] * s[0]; + signal s21; + s21 <== s[2] * s[1]; + signal s210; + s210 <== s21 * s[0]; + + + for (var i=0; i mux.s[i]; + } + + mux.out[0] ==> out; +} diff --git a/circom/node_modules/circomlib/circuits/pedersen.circom b/circom/node_modules/circomlib/circuits/pedersen.circom new file mode 100644 index 0000000..a29f486 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/pedersen.circom @@ -0,0 +1,257 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "montgomery.circom"; +include "mux3.circom"; +include "babyjub.circom"; + +template Window4() { + signal input in[4]; + signal input base[2]; + signal output out[2]; + signal output out8[2]; // Returns 8*Base (To be linked) + + component mux = MultiMux3(2); + + mux.s[0] <== in[0]; + mux.s[1] <== in[1]; + mux.s[2] <== in[2]; + + component dbl2 = MontgomeryDouble(); + component adr3 = MontgomeryAdd(); + component adr4 = MontgomeryAdd(); + component adr5 = MontgomeryAdd(); + component adr6 = MontgomeryAdd(); + component adr7 = MontgomeryAdd(); + component adr8 = MontgomeryAdd(); + +// in[0] -> 1*BASE + + mux.c[0][0] <== base[0]; + mux.c[1][0] <== base[1]; + +// in[1] -> 2*BASE + dbl2.in[0] <== base[0]; + dbl2.in[1] <== base[1]; + mux.c[0][1] <== dbl2.out[0]; + mux.c[1][1] <== dbl2.out[1]; + +// in[2] -> 3*BASE + adr3.in1[0] <== base[0]; + adr3.in1[1] <== base[1]; + adr3.in2[0] <== dbl2.out[0]; + adr3.in2[1] <== dbl2.out[1]; + mux.c[0][2] <== adr3.out[0]; + mux.c[1][2] <== adr3.out[1]; + +// in[3] -> 4*BASE + adr4.in1[0] <== base[0]; + adr4.in1[1] <== base[1]; + adr4.in2[0] <== adr3.out[0]; + adr4.in2[1] <== adr3.out[1]; + mux.c[0][3] <== adr4.out[0]; + mux.c[1][3] <== adr4.out[1]; + +// in[4] -> 5*BASE + adr5.in1[0] <== base[0]; + adr5.in1[1] <== base[1]; + adr5.in2[0] <== adr4.out[0]; + adr5.in2[1] <== adr4.out[1]; + mux.c[0][4] <== adr5.out[0]; + mux.c[1][4] <== adr5.out[1]; + +// in[5] -> 6*BASE + adr6.in1[0] <== base[0]; + adr6.in1[1] <== base[1]; + adr6.in2[0] <== adr5.out[0]; + adr6.in2[1] <== adr5.out[1]; + mux.c[0][5] <== adr6.out[0]; + mux.c[1][5] <== adr6.out[1]; + +// in[6] -> 7*BASE + adr7.in1[0] <== base[0]; + adr7.in1[1] <== base[1]; + adr7.in2[0] <== adr6.out[0]; + adr7.in2[1] <== adr6.out[1]; + mux.c[0][6] <== adr7.out[0]; + mux.c[1][6] <== adr7.out[1]; + +// in[7] -> 8*BASE + adr8.in1[0] <== base[0]; + adr8.in1[1] <== base[1]; + adr8.in2[0] <== adr7.out[0]; + adr8.in2[1] <== adr7.out[1]; + mux.c[0][7] <== adr8.out[0]; + mux.c[1][7] <== adr8.out[1]; + + out8[0] <== adr8.out[0]; + out8[1] <== adr8.out[1]; + + out[0] <== mux.out[0]; + out[1] <== - mux.out[1]*2*in[3] + mux.out[1]; // Negate y if in[3] is one +} + + +template Segment(nWindows) { + signal input in[nWindows*4]; + signal input base[2]; + signal output out[2]; + + var i; + var j; + + // Convert the base to montgomery + + component e2m = Edwards2Montgomery(); + e2m.in[0] <== base[0]; + e2m.in[1] <== base[1]; + + component windows[nWindows]; + component doublers1[nWindows-1]; + component doublers2[nWindows-1]; + component adders[nWindows-1]; + for (i=0; i 1) { + m2e.in[0] <== adders[nWindows-2].out[0]; + m2e.in[1] <== adders[nWindows-2].out[1]; + } else { + m2e.in[0] <== windows[0].out[0]; + m2e.in[1] <== windows[0].out[1]; + } + + out[0] <== m2e.out[0]; + out[1] <== m2e.out[1]; +} + +template Pedersen(n) { + signal input in[n]; + signal output out[2]; + + var BASE[10][2] = [ + [10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317], + [2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094], + [5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896], + [7107336197374528537877327281242680114152313102022415488494307685842428166594,2857869773864086953506483169737724679646433914307247183624878062391496185654], + [20265828622013100949498132415626198973119240347465898028410217039057588424236,1160461593266035632937973507065134938065359936056410650153315956301179689506], + [1487999857809287756929114517587739322941449154962237464737694709326309567994,14017256862867289575056460215526364897734808720610101650676790868051368668003], + [14618644331049802168996997831720384953259095788558646464435263343433563860015,13115243279999696210147231297848654998887864576952244320558158620692603342236], + [6814338563135591367010655964669793483652536871717891893032616415581401894627,13660303521961041205824633772157003587453809761793065294055279768121314853695], + [3571615583211663069428808372184817973703476260057504149923239576077102575715,11981351099832644138306422070127357074117642951423551606012551622164230222506], + [18597552580465440374022635246985743886550544261632147935254624835147509493269,6753322320275422086923032033899357299485124665258735666995435957890214041481] + + ]; + + var nSegments = ((n-1)\200)+1; + + component segments[nSegments]; + + var i; + var j; + var nBits; + var nWindows; + for (i=0; i1) { + packPoint.in[0] <== adders[nSegments-2].xout; + packPoint.in[1] <== adders[nSegments-2].yout; + } else { + packPoint.in[0] <== segments[0].out[0]; + packPoint.in[1] <== segments[0].out[1]; + } + + out[0] <== packPoint.out[0]; + out[1] <== packPoint.out[1]; +*/ + + if (nSegments>1) { + out[0] <== adders[nSegments-2].xout; + out[1] <== adders[nSegments-2].yout; + } else { + out[0] <== segments[0].out[0]; + out[1] <== segments[0].out[1]; + } +} + diff --git a/circom/node_modules/circomlib/circuits/pedersen_old.circom b/circom/node_modules/circomlib/circuits/pedersen_old.circom new file mode 100644 index 0000000..c338e44 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/pedersen_old.circom @@ -0,0 +1,68 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "escalarmul.circom"; + +template Pedersen(n) { + signal input in[n]; + signal output out[2]; + + var nexps = ((n-1) \ 250) + 1; + var nlastbits = n - (nexps-1)*250; + + component escalarMuls[nexps]; + + var PBASE[10][2] = [ + [10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317], + [2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094], + [5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896], + [7107336197374528537877327281242680114152313102022415488494307685842428166594,2857869773864086953506483169737724679646433914307247183624878062391496185654], + [20265828622013100949498132415626198973119240347465898028410217039057588424236,1160461593266035632937973507065134938065359936056410650153315956301179689506], + [1487999857809287756929114517587739322941449154962237464737694709326309567994,14017256862867289575056460215526364897734808720610101650676790868051368668003], + [14618644331049802168996997831720384953259095788558646464435263343433563860015,13115243279999696210147231297848654998887864576952244320558158620692603342236], + [6814338563135591367010655964669793483652536871717891893032616415581401894627,13660303521961041205824633772157003587453809761793065294055279768121314853695], + [3571615583211663069428808372184817973703476260057504149923239576077102575715,11981351099832644138306422070127357074117642951423551606012551622164230222506], + [18597552580465440374022635246985743886550544261632147935254624835147509493269,6753322320275422086923032033899357299485124665258735666995435957890214041481] + + ]; + + var i; + var j; + var nexpbits; + for (i=0; i out[0]; + escalarMuls[nexps-1].out[1] ==> out[1]; +} diff --git a/circom/node_modules/circomlib/circuits/pointbits.circom b/circom/node_modules/circomlib/circuits/pointbits.circom new file mode 100644 index 0000000..fa6007d --- /dev/null +++ b/circom/node_modules/circomlib/circuits/pointbits.circom @@ -0,0 +1,164 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "bitify.circom"; +include "aliascheck.circom"; +include "compconstant.circom"; +include "babyjub.circom"; + + +function sqrt(n) { + + if (n == 0) { + return 0; + } + + // Test that have solution + var res = n ** ((-1) >> 1); +// if (res!=1) assert(false, "SQRT does not exists"); + if (res!=1) return 0; + + var m = 28; + var c = 19103219067921713944291392827692070036145651957329286315305642004821462161904; + var t = n ** 81540058820840996586704275553141814055101440848469862132140264610111; + var r = n ** ((81540058820840996586704275553141814055101440848469862132140264610111+1)>>1); + var sq; + var i; + var b; + var j; + + while ((r != 0)&&(t != 1)) { + sq = t*t; + i = 1; + while (sq!=1) { + i++; + sq = sq*sq; + } + + // b = c ^ m-i-1 + b = c; + for (j=0; j< m-i-1; j ++) b = b*b; + + m = i; + c = b*b; + t = t*c; + r = r*b; + } + + if (r < 0 ) { + r = -r; + } + + return r; +} + + +template Bits2Point() { + signal input in[256]; + signal output out[2]; +} + +template Bits2Point_Strict() { + signal input in[256]; + signal output out[2]; + + var i; + + // Check aliasing + component aliasCheckY = AliasCheck(); + for (i=0; i<254; i++) { + aliasCheckY.in[i] <== in[i]; + } + in[254] === 0; + + component b2nY = Bits2Num(254); + for (i=0; i<254; i++) { + b2nY.in[i] <== in[i]; + } + + out[1] <== b2nY.out; + + var a = 168700; + var d = 168696; + + var y2 = out[1] * out[1]; + + var x = sqrt( (1-y2)/(a - d*y2) ); + + if (in[255] == 1) x = -x; + + out[0] <-- x; + + component babyCheck = BabyCheck(); + babyCheck.x <== out[0]; + babyCheck.y <== out[1]; + + component n2bX = Num2Bits(254); + n2bX.in <== out[0]; + component aliasCheckX = AliasCheck(); + for (i=0; i<254; i++) { + aliasCheckX.in[i] <== n2bX.out[i]; + } + + component signCalc = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808); + for (i=0; i<254; i++) { + signCalc.in[i] <== n2bX.out[i]; + } + + signCalc.out === in[255]; +} + + +template Point2Bits() { + signal input in[2]; + signal output out[256]; + + +} + +template Point2Bits_Strict() { + signal input in[2]; + signal output out[256]; + + var i; + + component n2bX = Num2Bits(254); + n2bX.in <== in[0]; + component n2bY = Num2Bits(254); + n2bY.in <== in[1]; + + component aliasCheckX = AliasCheck(); + component aliasCheckY = AliasCheck(); + for (i=0; i<254; i++) { + aliasCheckX.in[i] <== n2bX.out[i]; + aliasCheckY.in[i] <== n2bY.out[i]; + } + + component signCalc = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808); + for (i=0; i<254; i++) { + signCalc.in[i] <== n2bX.out[i]; + } + + for (i=0; i<254; i++) { + out[i] <== n2bY.out[i]; + } + out[254] <== 0; + out[255] <== signCalc.out; +} diff --git a/circom/node_modules/circomlib/circuits/poseidon.circom b/circom/node_modules/circomlib/circuits/poseidon.circom new file mode 100644 index 0000000..1c45ab9 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/poseidon.circom @@ -0,0 +1,208 @@ +pragma circom 2.0.0; + +include "./poseidon_constants.circom"; + +template Sigma() { + signal input in; + signal output out; + + signal in2; + signal in4; + + in2 <== in*in; + in4 <== in2*in2; + + out <== in4*in; +} + +template Ark(t, C, r) { + signal input in[t]; + signal output out[t]; + + for (var i=0; i0) { + ark[0].in[j] <== inputs[j-1]; + } else { + ark[0].in[j] <== initialState; + } + } + + for (var r = 0; r < nRoundsF\2-1; r++) { + for (var j=0; j0) { + ark[i].in[j] <== inputs[j-1]; + } else { + ark[i].in[j] <== 0; + } + } else { + ark[i].in[j] <== mix[i-1].out[j]; + } + } + + if (i < nRoundsF/2 || i >= nRoundsP + nRoundsF/2) { + k = i < nRoundsF/2 ? i : i - nRoundsP; + mix[i] = Mix(t, M); + for (var j=0; j. +*/ + +/* Ch + +000 0 +001 1 +010 0 +011 1 +100 0 +101 0 +110 1 +111 1 + +out = a&b ^ (!a)&c => + +out = a*(b-c) + c + +*/ +pragma circom 2.0.0; + +template Ch_t(n) { + signal input a[n]; + signal input b[n]; + signal input c[n]; + signal output out[n]; + + for (var k=0; k. +*/ +pragma circom 2.0.0; + +template H(x) { + signal output out[32]; + var c[8] = [0x6a09e667, + 0xbb67ae85, + 0x3c6ef372, + 0xa54ff53a, + 0x510e527f, + 0x9b05688c, + 0x1f83d9ab, + 0x5be0cd19]; + + for (var i=0; i<32; i++) { + out[i] <== (c[x] >> i) & 1; + } +} + +template K(x) { + signal output out[32]; + var c[64] = [ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 + ]; + + for (var i=0; i<32; i++) { + out[i] <== (c[x] >> i) & 1; + } +} diff --git a/circom/node_modules/circomlib/circuits/sha256/main.circom b/circom/node_modules/circomlib/circuits/sha256/main.circom new file mode 100644 index 0000000..88d69d6 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/sha256/main.circom @@ -0,0 +1,35 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "sha256_2.circom"; + +template Main() { + signal input a; + signal input b; + signal output out; + + component sha256_2 = Sha256_2(); + + sha256_2.a <== a; + sha256_2.b <== a; + out <== sha256_2.out; +} + +component main = Main(); diff --git a/circom/node_modules/circomlib/circuits/sha256/maj.circom b/circom/node_modules/circomlib/circuits/sha256/maj.circom new file mode 100644 index 0000000..1c0940c --- /dev/null +++ b/circom/node_modules/circomlib/circuits/sha256/maj.circom @@ -0,0 +1,45 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ + +/* Maj function for sha256 + +out = a&b ^ a&c ^ b&c => + +out = a*b + a*c + b*c - 2*a*b*c => + +out = a*( b + c - 2*b*c ) + b*c => + +mid = b*c +out = a*( b + c - 2*mid ) + mid + +*/ +pragma circom 2.0.0; + +template Maj_t(n) { + signal input a[n]; + signal input b[n]; + signal input c[n]; + signal output out[n]; + signal mid[n]; + + for (var k=0; k. +*/ +pragma circom 2.0.0; + +template RotR(n, r) { + signal input in[n]; + signal output out[n]; + + for (var i=0; i> k)&1; + } + + component ha0 = H(0); + component hb0 = H(1); + component hc0 = H(2); + component hd0 = H(3); + component he0 = H(4); + component hf0 = H(5); + component hg0 = H(6); + component hh0 = H(7); + + component sha256compression[nBlocks]; + + for (i=0; i. +*/ +pragma circom 2.0.0; + +include "constants.circom"; +include "sha256compression.circom"; +include "../bitify.circom"; + +template Sha256_2() { + signal input a; + signal input b; + signal output out; + + var i; + var k; + + component bits2num = Bits2Num(216); + component num2bits[2]; + + num2bits[0] = Num2Bits(216); + num2bits[1] = Num2Bits(216); + + num2bits[0].in <== a; + num2bits[1].in <== b; + + + component sha256compression = Sha256compression() ; + + component ha0 = H(0); + component hb0 = H(1); + component hc0 = H(2); + component hd0 = H(3); + component he0 = H(4); + component hf0 = H(5); + component hg0 = H(6); + component hh0 = H(7); + + for (k=0; k<32; k++ ) { + sha256compression.hin[0*32+k] <== ha0.out[k]; + sha256compression.hin[1*32+k] <== hb0.out[k]; + sha256compression.hin[2*32+k] <== hc0.out[k]; + sha256compression.hin[3*32+k] <== hd0.out[k]; + sha256compression.hin[4*32+k] <== he0.out[k]; + sha256compression.hin[5*32+k] <== hf0.out[k]; + sha256compression.hin[6*32+k] <== hg0.out[k]; + sha256compression.hin[7*32+k] <== hh0.out[k]; + } + + for (i=0; i<216; i++) { + sha256compression.inp[i] <== num2bits[0].out[215-i]; + sha256compression.inp[i+216] <== num2bits[1].out[215-i]; + } + + sha256compression.inp[432] <== 1; + + for (i=433; i<503; i++) { + sha256compression.inp[i] <== 0; + } + + sha256compression.inp[503] <== 1; + sha256compression.inp[504] <== 1; + sha256compression.inp[505] <== 0; + sha256compression.inp[506] <== 1; + sha256compression.inp[507] <== 1; + sha256compression.inp[508] <== 0; + sha256compression.inp[509] <== 0; + sha256compression.inp[510] <== 0; + sha256compression.inp[511] <== 0; + + for (i=0; i<216; i++) { + bits2num.in[i] <== sha256compression.out[255-i]; + } + + out <== bits2num.out; +} diff --git a/circom/node_modules/circomlib/circuits/sha256/sha256compression.circom b/circom/node_modules/circomlib/circuits/sha256/sha256compression.circom new file mode 100644 index 0000000..98f7c98 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/sha256/sha256compression.circom @@ -0,0 +1,166 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "constants.circom"; +include "t1.circom"; +include "t2.circom"; +include "../binsum.circom"; +include "sigmaplus.circom"; +include "sha256compression_function.circom"; + + +template Sha256compression() { + signal input hin[256]; + signal input inp[512]; + signal output out[256]; + signal a[65][32]; + signal b[65][32]; + signal c[65][32]; + signal d[65][32]; + signal e[65][32]; + signal f[65][32]; + signal g[65][32]; + signal h[65][32]; + signal w[64][32]; + + + var outCalc[256] = sha256compression(hin, inp); + + var i; + for (i=0; i<256; i++) out[i] <-- outCalc[i]; + + component sigmaPlus[48]; + for (i=0; i<48; i++) sigmaPlus[i] = SigmaPlus(); + + component ct_k[64]; + for (i=0; i<64; i++) ct_k[i] = K(i); + + component t1[64]; + for (i=0; i<64; i++) t1[i] = T1(); + + component t2[64]; + for (i=0; i<64; i++) t2[i] = T2(); + + component suma[64]; + for (i=0; i<64; i++) suma[i] = BinSum(32, 2); + + component sume[64]; + for (i=0; i<64; i++) sume[i] = BinSum(32, 2); + + component fsum[8]; + for (i=0; i<8; i++) fsum[i] = BinSum(32, 2); + + var k; + var t; + + for (t=0; t<64; t++) { + if (t<16) { + for (k=0; k<32; k++) { + w[t][k] <== inp[t*32+31-k]; + } + } else { + for (k=0; k<32; k++) { + sigmaPlus[t-16].in2[k] <== w[t-2][k]; + sigmaPlus[t-16].in7[k] <== w[t-7][k]; + sigmaPlus[t-16].in15[k] <== w[t-15][k]; + sigmaPlus[t-16].in16[k] <== w[t-16][k]; + } + + for (k=0; k<32; k++) { + w[t][k] <== sigmaPlus[t-16].out[k]; + } + } + } + + for (k=0; k<32; k++ ) { + a[0][k] <== hin[k]; + b[0][k] <== hin[32*1 + k]; + c[0][k] <== hin[32*2 + k]; + d[0][k] <== hin[32*3 + k]; + e[0][k] <== hin[32*4 + k]; + f[0][k] <== hin[32*5 + k]; + g[0][k] <== hin[32*6 + k]; + h[0][k] <== hin[32*7 + k]; + } + + for (t = 0; t<64; t++) { + for (k=0; k<32; k++) { + t1[t].h[k] <== h[t][k]; + t1[t].e[k] <== e[t][k]; + t1[t].f[k] <== f[t][k]; + t1[t].g[k] <== g[t][k]; + t1[t].k[k] <== ct_k[t].out[k]; + t1[t].w[k] <== w[t][k]; + + t2[t].a[k] <== a[t][k]; + t2[t].b[k] <== b[t][k]; + t2[t].c[k] <== c[t][k]; + } + + for (k=0; k<32; k++) { + sume[t].in[0][k] <== d[t][k]; + sume[t].in[1][k] <== t1[t].out[k]; + + suma[t].in[0][k] <== t1[t].out[k]; + suma[t].in[1][k] <== t2[t].out[k]; + } + + for (k=0; k<32; k++) { + h[t+1][k] <== g[t][k]; + g[t+1][k] <== f[t][k]; + f[t+1][k] <== e[t][k]; + e[t+1][k] <== sume[t].out[k]; + d[t+1][k] <== c[t][k]; + c[t+1][k] <== b[t][k]; + b[t+1][k] <== a[t][k]; + a[t+1][k] <== suma[t].out[k]; + } + } + + for (k=0; k<32; k++) { + fsum[0].in[0][k] <== hin[32*0+k]; + fsum[0].in[1][k] <== a[64][k]; + fsum[1].in[0][k] <== hin[32*1+k]; + fsum[1].in[1][k] <== b[64][k]; + fsum[2].in[0][k] <== hin[32*2+k]; + fsum[2].in[1][k] <== c[64][k]; + fsum[3].in[0][k] <== hin[32*3+k]; + fsum[3].in[1][k] <== d[64][k]; + fsum[4].in[0][k] <== hin[32*4+k]; + fsum[4].in[1][k] <== e[64][k]; + fsum[5].in[0][k] <== hin[32*5+k]; + fsum[5].in[1][k] <== f[64][k]; + fsum[6].in[0][k] <== hin[32*6+k]; + fsum[6].in[1][k] <== g[64][k]; + fsum[7].in[0][k] <== hin[32*7+k]; + fsum[7].in[1][k] <== h[64][k]; + } + + for (k=0; k<32; k++) { + out[31-k] === fsum[0].out[k]; + out[32+31-k] === fsum[1].out[k]; + out[64+31-k] === fsum[2].out[k]; + out[96+31-k] === fsum[3].out[k]; + out[128+31-k] === fsum[4].out[k]; + out[160+31-k] === fsum[5].out[k]; + out[192+31-k] === fsum[6].out[k]; + out[224+31-k] === fsum[7].out[k]; + } +} diff --git a/circom/node_modules/circomlib/circuits/sha256/sha256compression_function.circom b/circom/node_modules/circomlib/circuits/sha256/sha256compression_function.circom new file mode 100644 index 0000000..9f8d5b8 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/sha256/sha256compression_function.circom @@ -0,0 +1,112 @@ +// signal input hin[256]; +// signal input inp[512]; +// signal output out[256]; +pragma circom 2.0.0; + +function rrot(x, n) { + return ((x >> n) | (x << (32-n))) & 0xFFFFFFFF; +} + +function bsigma0(x) { + return rrot(x,2) ^ rrot(x,13) ^ rrot(x,22); +} + +function bsigma1(x) { + return rrot(x,6) ^ rrot(x,11) ^ rrot(x,25); +} + +function ssigma0(x) { + return rrot(x,7) ^ rrot(x,18) ^ (x >> 3); +} + +function ssigma1(x) { + return rrot(x,17) ^ rrot(x,19) ^ (x >> 10); +} + +function Maj(x, y, z) { + return (x&y) ^ (x&z) ^ (y&z); +} + +function Ch(x, y, z) { + return (x & y) ^ ((0xFFFFFFFF ^x) & z); +} + +function sha256K(i) { + var k[64] = [ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 + ]; + return k[i]; +} + +function sha256compression(hin, inp) { + var H[8]; + var a; + var b; + var c; + var d; + var e; + var f; + var g; + var h; + var out[256]; + for (var i=0; i<8; i++) { + H[i] = 0; + for (var j=0; j<32; j++) { + H[i] += hin[i*32+j] << j; + } + } + a=H[0]; + b=H[1]; + c=H[2]; + d=H[3]; + e=H[4]; + f=H[5]; + g=H[6]; + h=H[7]; + var w[64]; + var T1; + var T2; + for (var i=0; i<64; i++) { + if (i<16) { + w[i]=0; + for (var j=0; j<32; j++) { + w[i] += inp[i*32+31-j]<> j) & 1; + } + } + return out; +} diff --git a/circom/node_modules/circomlib/circuits/sha256/shift.circom b/circom/node_modules/circomlib/circuits/sha256/shift.circom new file mode 100644 index 0000000..317cd32 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/sha256/shift.circom @@ -0,0 +1,33 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +template ShR(n, r) { + signal input in[n]; + signal output out[n]; + + for (var i=0; i= n) { + out[i] <== 0; + } else { + out[i] <== in[ i+r ]; + } + } +} + diff --git a/circom/node_modules/circomlib/circuits/sha256/sigma.circom b/circom/node_modules/circomlib/circuits/sha256/sigma.circom new file mode 100644 index 0000000..bcb0b80 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/sha256/sigma.circom @@ -0,0 +1,77 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "xor3.circom"; +include "rotate.circom"; +include "shift.circom"; + +template SmallSigma(ra, rb, rc) { + signal input in[32]; + signal output out[32]; + var k; + + component rota = RotR(32, ra); + component rotb = RotR(32, rb); + component shrc = ShR(32, rc); + + for (k=0; k<32; k++) { + rota.in[k] <== in[k]; + rotb.in[k] <== in[k]; + shrc.in[k] <== in[k]; + } + + component xor3 = Xor3(32); + for (k=0; k<32; k++) { + xor3.a[k] <== rota.out[k]; + xor3.b[k] <== rotb.out[k]; + xor3.c[k] <== shrc.out[k]; + } + + for (k=0; k<32; k++) { + out[k] <== xor3.out[k]; + } +} + +template BigSigma(ra, rb, rc) { + signal input in[32]; + signal output out[32]; + var k; + + component rota = RotR(32, ra); + component rotb = RotR(32, rb); + component rotc = RotR(32, rc); + for (k=0; k<32; k++) { + rota.in[k] <== in[k]; + rotb.in[k] <== in[k]; + rotc.in[k] <== in[k]; + } + + component xor3 = Xor3(32); + + for (k=0; k<32; k++) { + xor3.a[k] <== rota.out[k]; + xor3.b[k] <== rotb.out[k]; + xor3.c[k] <== rotc.out[k]; + } + + for (k=0; k<32; k++) { + out[k] <== xor3.out[k]; + } +} diff --git a/circom/node_modules/circomlib/circuits/sha256/sigmaplus.circom b/circom/node_modules/circomlib/circuits/sha256/sigmaplus.circom new file mode 100644 index 0000000..35e3300 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/sha256/sigmaplus.circom @@ -0,0 +1,50 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "../binsum.circom"; +include "sigma.circom"; + +template SigmaPlus() { + signal input in2[32]; + signal input in7[32]; + signal input in15[32]; + signal input in16[32]; + signal output out[32]; + var k; + + component sigma1 = SmallSigma(17,19,10); + component sigma0 = SmallSigma(7, 18, 3); + for (k=0; k<32; k++) { + sigma1.in[k] <== in2[k]; + sigma0.in[k] <== in15[k]; + } + + component sum = BinSum(32, 4); + for (k=0; k<32; k++) { + sum.in[0][k] <== sigma1.out[k]; + sum.in[1][k] <== in7[k]; + sum.in[2][k] <== sigma0.out[k]; + sum.in[3][k] <== in16[k]; + } + + for (k=0; k<32; k++) { + out[k] <== sum.out[k]; + } +} diff --git a/circom/node_modules/circomlib/circuits/sha256/t1.circom b/circom/node_modules/circomlib/circuits/sha256/t1.circom new file mode 100644 index 0000000..e606772 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/sha256/t1.circom @@ -0,0 +1,58 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "../binsum.circom"; +include "sigma.circom"; +include "ch.circom"; + +template T1() { + signal input h[32]; + signal input e[32]; + signal input f[32]; + signal input g[32]; + signal input k[32]; + signal input w[32]; + signal output out[32]; + + var ki; + + component ch = Ch_t(32); + component bigsigma1 = BigSigma(6, 11, 25); + + for (ki=0; ki<32; ki++) { + bigsigma1.in[ki] <== e[ki]; + ch.a[ki] <== e[ki]; + ch.b[ki] <== f[ki]; + ch.c[ki] <== g[ki]; + } + + component sum = BinSum(32, 5); + for (ki=0; ki<32; ki++) { + sum.in[0][ki] <== h[ki]; + sum.in[1][ki] <== bigsigma1.out[ki]; + sum.in[2][ki] <== ch.out[ki]; + sum.in[3][ki] <== k[ki]; + sum.in[4][ki] <== w[ki]; + } + + for (ki=0; ki<32; ki++) { + out[ki] <== sum.out[ki]; + } +} diff --git a/circom/node_modules/circomlib/circuits/sha256/t2.circom b/circom/node_modules/circomlib/circuits/sha256/t2.circom new file mode 100644 index 0000000..5a83d59 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/sha256/t2.circom @@ -0,0 +1,51 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "../binsum.circom"; +include "sigma.circom"; +include "maj.circom"; + +template T2() { + signal input a[32]; + signal input b[32]; + signal input c[32]; + signal output out[32]; + var k; + + component bigsigma0 = BigSigma(2, 13, 22); + component maj = Maj_t(32); + for (k=0; k<32; k++) { + bigsigma0.in[k] <== a[k]; + maj.a[k] <== a[k]; + maj.b[k] <== b[k]; + maj.c[k] <== c[k]; + } + + component sum = BinSum(32, 2); + + for (k=0; k<32; k++) { + sum.in[0][k] <== bigsigma0.out[k]; + sum.in[1][k] <== maj.out[k]; + } + + for (k=0; k<32; k++) { + out[k] <== sum.out[k]; + } +} diff --git a/circom/node_modules/circomlib/circuits/sha256/xor3.circom b/circom/node_modules/circomlib/circuits/sha256/xor3.circom new file mode 100644 index 0000000..9c21e4e --- /dev/null +++ b/circom/node_modules/circomlib/circuits/sha256/xor3.circom @@ -0,0 +1,45 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ + +/* Xor3 function for sha256 + +out = a ^ b ^ c => + +out = a+b+c - 2*a*b - 2*a*c - 2*b*c + 4*a*b*c => + +out = a*( 1 - 2*b - 2*c + 4*b*c ) + b + c - 2*b*c => + +mid = b*c +out = a*( 1 - 2*b -2*c + 4*mid ) + b + c - 2 * mid + +*/ +pragma circom 2.0.0; + +template Xor3(n) { + signal input a[n]; + signal input b[n]; + signal input c[n]; + signal output out[n]; + signal mid[n]; + + for (var k=0; k. +*/ +pragma circom 2.0.0; + +include "compconstant.circom"; + +template Sign() { + signal input in[254]; + signal output sign; + + component comp = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808); + + var i; + + for (i=0; i<254; i++) { + comp.in[i] <== in[i]; + } + + sign <== comp.out; +} diff --git a/circom/node_modules/circomlib/circuits/smt/smthash_mimc.circom b/circom/node_modules/circomlib/circuits/smt/smthash_mimc.circom new file mode 100644 index 0000000..272e527 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/smt/smthash_mimc.circom @@ -0,0 +1,58 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "../mimc.circom"; + + +/* + Hash1 = H(1 | key | value) + */ + +template SMTHash1() { + signal input key; + signal input value; + signal output out; + + component h = MultiMiMC7(2, 91); // Constant + h.in[0] <== key; + h.in[1] <== value; + h.k <== 1; + + out <== h.out; +} + +/* + This component is used to create the 2 nodes. + + Hash2 = H(Hl | Hr) + */ + +template SMTHash2() { + signal input L; + signal input R; + signal output out; + + component h = MultiMiMC7(2, 91); // Constant + h.in[0] <== L; + h.in[1] <== R; + h.k <== 0; + + out <== h.out; +} diff --git a/circom/node_modules/circomlib/circuits/smt/smthash_poseidon.circom b/circom/node_modules/circomlib/circuits/smt/smthash_poseidon.circom new file mode 100644 index 0000000..aa6b8b3 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/smt/smthash_poseidon.circom @@ -0,0 +1,57 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ +pragma circom 2.0.0; + +include "../poseidon.circom"; + + +/* + Hash1 = H(1 | key | value) + */ + +template SMTHash1() { + signal input key; + signal input value; + signal output out; + + component h = Poseidon(3); // Constant + h.inputs[0] <== key; + h.inputs[1] <== value; + h.inputs[2] <== 1; + + out <== h.out; +} + +/* + This component is used to create the 2 nodes. + + Hash2 = H(Hl | Hr) + */ + +template SMTHash2() { + signal input L; + signal input R; + signal output out; + + component h = Poseidon(2); // Constant + h.inputs[0] <== L; + h.inputs[1] <== R; + + out <== h.out; +} diff --git a/circom/node_modules/circomlib/circuits/smt/smtlevins.circom b/circom/node_modules/circomlib/circuits/smt/smtlevins.circom new file mode 100644 index 0000000..a03ae50 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/smt/smtlevins.circom @@ -0,0 +1,103 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ + +/* + +This component finds the level where the oldInsert is done. +The rules are: + +levIns[i] == 1 if its level and all the child levels have a sibling of 0 and +the parent level has a sibling != 0. Considere that the root level always has +a parent with a sibling != 0. + + + ┌──────────────┐ + │ │ + │ │───▶ levIns[0] <== (1-done[i]) + │ │ + └──────────────┘ + ▲ + │ + │ + done[0] + + + + done[i-1] <== levIns[i] + done[i] + ▲ + │ + │ + ┌───────────┐ ┌──────────────┐ + │ │ │ │ + sibling[i-1]───▶│IsZero[i-1]│─▶│ │───▶ levIns[i] <== (1-done[i])*(1-isZero[i-1].out) + │ │ │ │ + └───────────┘ └──────────────┘ + ▲ + │ + │ + done[i] + + + + done[n-2] <== levIns[n-1] + ▲ + │ + │ + ┌───────────┐ ┌──────────────┐ + │ │ │ │ + sibling[n-2]───▶│IsZero[n-2]│─▶│ │────▶ levIns[n-1] <== (1-isZero[n-2].out) + │ │ │ │ + └───────────┘ └──────────────┘ + + ┌───────────┐ + │ │ + sibling[n-1]───▶│IsZero[n-1]│────▶ === 0 + │ │ + └───────────┘ + + */ + pragma circom 2.0.0; + +template SMTLevIns(nLevels) { + signal input enabled; + signal input siblings[nLevels]; + signal output levIns[nLevels]; + signal done[nLevels-1]; // Indicates if the insLevel has aready been detected. + + var i; + + component isZero[nLevels]; + + for (i=0; i0; i--) { + levIns[i] <== (1-done[i])*(1-isZero[i-1].out); + done[i-1] <== levIns[i] + done[i]; + } + + levIns[0] <== (1-done[0]); +} diff --git a/circom/node_modules/circomlib/circuits/smt/smtprocessor.circom b/circom/node_modules/circomlib/circuits/smt/smtprocessor.circom new file mode 100644 index 0000000..b75f17c --- /dev/null +++ b/circom/node_modules/circomlib/circuits/smt/smtprocessor.circom @@ -0,0 +1,261 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ + +/*************************************************************************************************** + +SMTProcessor: Sparse Merkle Tree processor is a component to verify an insert/update/delete elements +into the Sparse Merkle tree. + + +Insert to an empty leaf +======================= + + STATE OLD STATE NEW STATE + ===== ========= ========= + + oldRoot newRoot + ▲ ▲ + │ │ + ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ + top │Sibling├────▶┃ Hash ┃◀─┐ │Sibling├────▶┃ Hash ┃◀─┐ + └───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │ + │ │ + │ │ + ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ + top ┌─────▶┃ Hash ┃◀──┤Sibling│ ┌─────▶┃ Hash ┃◀──┤Sibling│ + │ ┗━━━━━━━┛ └───────┘ │ ┗━━━━━━━┛ └───────┘ + │ │ + │ │ + ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ + top │Sibling├──▶┃ Hash ┃◀─────┐ │Sibling├──▶┃ Hash ┃◀─────┐ + └───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │ + │ │ + │ │ + ┌────┴────┐ ┌────┴────┐ + old0 │ 0 │ │New1Leaf │ + └─────────┘ └─────────┘ + + + ┏━━━━━━━┓ ┏━━━━━━━┓ + na ┃ Hash ┃ ┃ Hash ┃ + ┗━━━━━━━┛ ┗━━━━━━━┛ + + + ┏━━━━━━━┓ ┏━━━━━━━┓ + na ┃ Hash ┃ ┃ Hash ┃ + ┗━━━━━━━┛ ┗━━━━━━━┛ + + + +Insert to a used leaf. +===================== + + STATE OLD STATE NEW STATE + ===== ========= ========= + + + oldRoot newRoot + ▲ ▲ + │ │ + ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ + top │Sibling├────▶┃ Hash ┃◀─┐ │Sibling├────▶┃ Hash ┃◀─┐ + └───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │ + │ │ + │ │ + ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ + top ┌─────▶┃ Hash ┃◀──┤Sibling│ ┌─────▶┃ Hash ┃◀──┤Sibling│ + │ ┗━━━━━━━┛ └───────┘ │ ┗━━━━━━━┛ └───────┘ + │ │ + │ │ + ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ + top │Sibling├──▶┃ Hash ┃◀─────┐ │Sibling├──▶┃ Hash ┃◀─────┐ + └───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │ + │ │ + │ │ + ┌────┴────┐ ┏━━━┻━━━┓ ┌───────┐ + bot │Old1Leaf │ ┌─────▶┃ Hash ┃◀──┼─ 0 │ + └─────────┘ │ ┗━━━━━━━┛ └───────┘ + │ + │ + ┏━━━━━━━┓ ┌───────┐ ┏━━━┻━━━┓ + bot ┃ Hash ┃ │ 0 ─┼──▶┃ Hash ┃◀─────┐ + ┗━━━━━━━┛ └───────┘ ┗━━━━━━━┛ │ + │ + │ + ┏━━━━━━━┓ ┏━━━┻━━━┓ ┌───────┐ + bot ┃ Hash ┃ ┌─────▶┃ Hash ┃◀──│ 0 │ + ┗━━━━━━━┛ │ ┗━━━━━━━┛ └───────┘ + │ + │ + ┏━━━━━━━┓ ┌─────────┐ ┏━━━┻━━━┓ ┌─────────┐ + new1 ┃ Hash ┃ │Old1Leaf ├──▶┃ Hash ┃◀──│New1Leaf │ + ┗━━━━━━━┛ └─────────┘ ┗━━━━━━━┛ └─────────┘ + + + ┏━━━━━━━┓ ┏━━━━━━━┓ + na ┃ Hash ┃ ┃ Hash ┃ + ┗━━━━━━━┛ ┗━━━━━━━┛ + + + ┏━━━━━━━┓ ┏━━━━━━━┓ + na ┃ Hash ┃ ┃ Hash ┃ + ┗━━━━━━━┛ ┗━━━━━━━┛ + + +Fnction +fnc[0] fnc[1] +0 0 NOP +0 1 UPDATE +1 0 INSERT +1 1 DELETE + + +***************************************************************************************************/ +pragma circom 2.0.0; + +include "../gates.circom"; +include "../bitify.circom"; +include "../comparators.circom"; +include "../switcher.circom"; +include "smtlevins.circom"; +include "smtprocessorlevel.circom"; +include "smtprocessorsm.circom"; +include "smthash_poseidon.circom"; + +template SMTProcessor(nLevels) { + signal input oldRoot; + signal output newRoot; + signal input siblings[nLevels]; + signal input oldKey; + signal input oldValue; + signal input isOld0; + signal input newKey; + signal input newValue; + signal input fnc[2]; + + signal enabled; + + var i; + + enabled <== fnc[0] + fnc[1] - fnc[0]*fnc[1]; + + component hash1Old = SMTHash1(); + hash1Old.key <== oldKey; + hash1Old.value <== oldValue; + + component hash1New = SMTHash1(); + hash1New.key <== newKey; + hash1New.value <== newValue; + + component n2bOld = Num2Bits_strict(); + component n2bNew = Num2Bits_strict(); + + n2bOld.in <== oldKey; + n2bNew.in <== newKey; + + component smtLevIns = SMTLevIns(nLevels); + for (i=0; i. +*/ + +/****** + +SMTProcessorLevel + +This circuit has 2 hash + +Outputs according to the state. + +State oldRoot newRoot +===== ======= ======= +top H'(oldChild, sibling) H'(newChild, sibling) +old0 0 new1leaf +bot old1leaf H'(newChild, 0) +new1 old1leaf H'(new1leaf, old1leaf) +na 0 0 + +upd old1leaf new1leaf + +H' is the Hash function with the inputs shifted acordingly. + +*****/ +pragma circom 2.0.0; + + +template SMTProcessorLevel() { + signal input st_top; + signal input st_old0; + signal input st_bot; + signal input st_new1; + signal input st_na; + signal input st_upd; + + signal output oldRoot; + signal output newRoot; + signal input sibling; + signal input old1leaf; + signal input new1leaf; + signal input newlrbit; + signal input oldChild; + signal input newChild; + + signal aux[4]; + + component oldProofHash = SMTHash2(); + component newProofHash = SMTHash2(); + + component oldSwitcher = Switcher(); + component newSwitcher = Switcher(); + + // Old side + + oldSwitcher.L <== oldChild; + oldSwitcher.R <== sibling; + + oldSwitcher.sel <== newlrbit; + oldProofHash.L <== oldSwitcher.outL; + oldProofHash.R <== oldSwitcher.outR; + + aux[0] <== old1leaf * (st_bot + st_new1 + st_upd); + oldRoot <== aux[0] + oldProofHash.out * st_top; + + // New side + + aux[1] <== newChild * ( st_top + st_bot); + newSwitcher.L <== aux[1] + new1leaf*st_new1; + + aux[2] <== sibling*st_top; + newSwitcher.R <== aux[2] + old1leaf*st_new1; + + newSwitcher.sel <== newlrbit; + newProofHash.L <== newSwitcher.outL; + newProofHash.R <== newSwitcher.outR; + + aux[3] <== newProofHash.out * (st_top + st_bot + st_new1); + newRoot <== aux[3] + new1leaf * (st_old0 + st_upd); +} diff --git a/circom/node_modules/circomlib/circuits/smt/smtprocessorsm.circom b/circom/node_modules/circomlib/circuits/smt/smtprocessorsm.circom new file mode 100644 index 0000000..e40356f --- /dev/null +++ b/circom/node_modules/circomlib/circuits/smt/smtprocessorsm.circom @@ -0,0 +1,165 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ + +/*************************************************************************************************** +Each level on a SMTProcessor has a state. + +The state of the level depends on the state of te botom level and on `xor` and +`is0` signals. + +`isOldLev` 1 when is the level where oldLeaf is. + +`xor` signal is 0 if the index bit at the current level is the same in the old +and the new index, and 1 if it is different. + +`is0` signal, is 1 if we are inserting/deleting in an empty leaf and 0 if we +are inserting/deleting in a leaf that contains an element. + +The states are: + +top: While the index bits of the old and new insex in the top level is the same, whe are in the top state. +old0: When the we reach insert level, we go to old0 state +if `is0`=1. +btn: Once in insert level and `is0` =0 we go to btn or new1 level if xor=1 +new1: This level is reached when xor=1. Here is where we insert/delete the hash of the +old and the new trees with just one element. +na: Not appliable. After processing it, we go to the na level. + + +Fnction +fnc[0] fnc[1] +0 0 NOP +0 1 UPDATE +1 0 INSERT +1 1 DELETE + + + ########### + # # + ┌────────────────────────────▶# upd #─────────────────────┐ + │ ## ## │ + │ ######### │ + levIns=1 │ │ + fnc[0]=0 │ │ any + │ │ + │ │ + │ │ + │ ########### │ + │ levIns=1 # # │ + levIns=0 │ is0=1 ┌────────────▶# old0 #────────┐ │ any + ┌─────┐ │ fnc[0]=1│ ## ## │ │ ┌──────┐ + │ │ │ │ ######### │ any │ │ │ + │ ▼ │ │ │ ▼ ▼ │ + │ ########### │ │ ########### │ + │ # # ────────────┘ └────────▶# #│ + └──# top # # na # + ## ## ───────────────────┐ levIns=1 ┌──▶## ## + ######### │ is0=0 │ ######### + │ │ fnc[0]=1 │ + │ │ xor=1 ########### │ any + │ └──────────────────▶# # │ + │ # new1 #──┘ + │ ## ## + └────────────────────────────────┐ ######### + levIns=1 │ ▲ + is0=0 │ ┌─────┘ + fnc[0]=1 │ ###########│ xor=1 + xor=0 │ # # + ▼# btn # + ## ## + #########◀───────┐ + │ │ + │ │ + └────────────┘ + xor=0 + +***************************************************************************************************/ +pragma circom 2.0.0; + +template SMTProcessorSM() { + signal input xor; + signal input is0; + signal input levIns; + signal input fnc[2]; + + signal input prev_top; + signal input prev_old0; + signal input prev_bot; + signal input prev_new1; + signal input prev_na; + signal input prev_upd; + + signal output st_top; + signal output st_old0; + signal output st_bot; + signal output st_new1; + signal output st_na; + signal output st_upd; + + signal aux1; + signal aux2; + + aux1 <== prev_top * levIns; + aux2 <== aux1*fnc[0]; // prev_top * levIns * fnc[0] + + // st_top = prev_top*(1-levIns) + // = + prev_top + // - prev_top * levIns = aux1 + + st_top <== prev_top - aux1; + + // st_old0 = prev_top * levIns * is0 * fnc[0] + // = + prev_top * levIns * is0 * fnc[0] = aux2 * is0 + + st_old0 <== aux2 * is0; // prev_top * levIns * is0 * fnc[0] + + // st_new1 = prev_top * levIns * (1-is0)*fnc[0] * xor + prev_bot*xor = + // = + prev_top * levIns * fnc[0] * xor = aux2 * xor + // - prev_top * levIns * is0 * fnc[0] * xor = st_old0 * xor + // + prev_bot * xor = prev_bot * xor + + st_new1 <== (aux2 - st_old0 + prev_bot)*xor; + + + // st_bot = prev_top * levIns * (1-is0)*fnc[0] * (1-xor) + prev_bot*(1-xor); + // = + prev_top * levIns * fnc[0] + // - prev_top * levIns * is0 * fnc[0] + // - prev_top * levIns * fnc[0] * xor + // + prev_top * levIns * is0 * fnc[0] * xor + // + prev_bot + // - prev_bot * xor + + st_bot <== (1-xor) * (aux2 - st_old0 + prev_bot); + + + // st_upd = prev_top * (1-fnc[0]) *levIns; + // = + prev_top * levIns + // - prev_top * levIns * fnc[0] + + st_upd <== aux1 - aux2; + + // st_na = prev_new1 + prev_old0 + prev_na + prev_upd; + // = + prev_new1 + // + prev_old0 + // + prev_na + // + prev_upd + + st_na <== prev_new1 + prev_old0 + prev_na + prev_upd; + +} diff --git a/circom/node_modules/circomlib/circuits/smt/smtverifier.circom b/circom/node_modules/circomlib/circuits/smt/smtverifier.circom new file mode 100644 index 0000000..152eba3 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/smt/smtverifier.circom @@ -0,0 +1,138 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ + +/* + +SMTVerifier is a component to verify inclusion/exclusion of an element in the tree + + +fnc: 0 -> VERIFY INCLUSION + 1 -> VERIFY NOT INCLUSION + + */ + pragma circom 2.0.0; + + +include "../gates.circom"; +include "../bitify.circom"; +include "../comparators.circom"; +include "../switcher.circom"; +include "smtlevins.circom"; +include "smtverifierlevel.circom"; +include "smtverifiersm.circom"; +include "smthash_poseidon.circom"; + +template SMTVerifier(nLevels) { + signal input enabled; + signal input root; + signal input siblings[nLevels]; + signal input oldKey; + signal input oldValue; + signal input isOld0; + signal input key; + signal input value; + signal input fnc; + + var i; + + component hash1Old = SMTHash1(); + hash1Old.key <== oldKey; + hash1Old.value <== oldValue; + + component hash1New = SMTHash1(); + hash1New.key <== key; + hash1New.value <== value; + + component n2bOld = Num2Bits_strict(); + component n2bNew = Num2Bits_strict(); + + n2bOld.in <== oldKey; + n2bNew.in <== key; + + component smtLevIns = SMTLevIns(nLevels); + for (i=0; i. +*/ + +/****** + +SMTVerifierLevel + +This circuit has 1 hash + +Outputs according to the state. + +State root +===== ======= +top H'(child, sibling) +i0 0 +iold old1leaf +inew new1leaf +na 0 + +H' is the Hash function with the inputs shifted acordingly. + +*****/ +pragma circom 2.0.0; + +template SMTVerifierLevel() { + signal input st_top; + signal input st_i0; + signal input st_iold; + signal input st_inew; + signal input st_na; + + signal output root; + signal input sibling; + signal input old1leaf; + signal input new1leaf; + signal input lrbit; + signal input child; + + signal aux[2]; + + component proofHash = SMTHash2(); + component switcher = Switcher(); + + switcher.L <== child; + switcher.R <== sibling; + + switcher.sel <== lrbit; + proofHash.L <== switcher.outL; + proofHash.R <== switcher.outR; + + aux[0] <== proofHash.out * st_top; + aux[1] <== old1leaf*st_iold; + + root <== aux[0] + aux[1] + new1leaf*st_inew; +} diff --git a/circom/node_modules/circomlib/circuits/smt/smtverifiersm.circom b/circom/node_modules/circomlib/circuits/smt/smtverifiersm.circom new file mode 100644 index 0000000..63d2c41 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/smt/smtverifiersm.circom @@ -0,0 +1,106 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ + +/* +Each level in the SMTVerifier has a state. + +This is the state machine. + +The signals are + +levIns: 1 if we are in the level where the insertion should happen +xor: 1 if the bitKey of the old and new keys are different in this level +is0: Input that indicates that the oldKey is 0 +fnc: 0 -> VERIFY INCLUSION + 1 -> VERIFY NOT INCLUSION + +err state is not a state itself. It's a lack of state. + +The end of the last level will have to be `na` + + levIns=0 any + ┌────┐ ┌────┐ + │ │ │ │ + │ ▼ levIns=1 ▼ │ + │ ########### is0=1 ########### ########### │ + │ # # fnc=1 # # any # # │ + └──# top # ─────────────────────▶# i0 #───────────────▶# na #──┘ + ## ## ──────────┐ ## ## ┌───────▶## ## + ########─────────────┐│ ######### │┌────────▶######### + ││ levIns=1 ││ + ││ is0=0 ########### ││ + ││ fnc=1 # # any│ + │└──────────▶ # iold #────────┘│ + │ ## ## │ + │ ######### │ + │ │ + │ levIns=1 ########### │ + │ fnc=0 # # any + └────────────▶# inew #─────────┘ + ## ## + ######### + + */ + pragma circom 2.0.0; + + +template SMTVerifierSM() { + signal input is0; + signal input levIns; + signal input fnc; + + signal input prev_top; + signal input prev_i0; + signal input prev_iold; + signal input prev_inew; + signal input prev_na; + + signal output st_top; + signal output st_i0; + signal output st_iold; + signal output st_inew; + signal output st_na; + + signal prev_top_lev_ins; + signal prev_top_lev_ins_fnc; + + prev_top_lev_ins <== prev_top * levIns; + prev_top_lev_ins_fnc <== prev_top_lev_ins*fnc; // prev_top * levIns * fnc + + // st_top = prev_top * (1-levIns) + // = + prev_top + // - prev_top * levIns + st_top <== prev_top - prev_top_lev_ins; + + // st_inew = prev_top * levIns * (1-fnc) + // = + prev_top * levIns + // - prev_top * levIns * fnc + st_inew <== prev_top_lev_ins - prev_top_lev_ins_fnc; + + // st_iold = prev_top * levIns * (1-is0)*fnc + // = + prev_top * levIns * fnc + // - prev_top * levIns * fnc * is0 + st_iold <== prev_top_lev_ins_fnc * (1 - is0); + + // st_i0 = prev_top * levIns * is0 + // = + prev_top * levIns * is0 + st_i0 <== prev_top_lev_ins * is0; + + st_na <== prev_na + prev_inew + prev_iold + prev_i0; +} diff --git a/circom/node_modules/circomlib/circuits/switcher.circom b/circom/node_modules/circomlib/circuits/switcher.circom new file mode 100644 index 0000000..e2e19a6 --- /dev/null +++ b/circom/node_modules/circomlib/circuits/switcher.circom @@ -0,0 +1,42 @@ +/* + Copyright 2018 0KIMS association. + + This file is part of circom (Zero Knowledge Circuit Compiler). + + circom is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + circom is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with circom. If not, see . +*/ + +/* + Assume sel is binary. + + If sel == 0 then outL = L and outR=R + If sel == 1 then outL = R and outR=L + + */ + +pragma circom 2.0.0; + +template Switcher() { + signal input sel; + signal input L; + signal input R; + signal output outL; + signal output outR; + + signal aux; + + aux <== (R-L)*sel; // We create aux in order to have only one multiplication + outL <== aux + L; + outR <== -aux + R; +} diff --git a/circom/node_modules/circomlib/doc/root_transfer.monopic b/circom/node_modules/circomlib/doc/root_transfer.monopic new file mode 100644 index 0000000..032c0ba Binary files /dev/null and b/circom/node_modules/circomlib/doc/root_transfer.monopic differ diff --git a/circom/node_modules/circomlib/doc/smt_diagram_0.monopic b/circom/node_modules/circomlib/doc/smt_diagram_0.monopic new file mode 100644 index 0000000..c8e5b9b Binary files /dev/null and b/circom/node_modules/circomlib/doc/smt_diagram_0.monopic differ diff --git a/circom/node_modules/circomlib/doc/smt_diagram_1.monopic b/circom/node_modules/circomlib/doc/smt_diagram_1.monopic new file mode 100644 index 0000000..2f645f2 Binary files /dev/null and b/circom/node_modules/circomlib/doc/smt_diagram_1.monopic differ diff --git a/circom/node_modules/circomlib/doc/smt_hash.monopic b/circom/node_modules/circomlib/doc/smt_hash.monopic new file mode 100644 index 0000000..afb506a Binary files /dev/null and b/circom/node_modules/circomlib/doc/smt_hash.monopic differ diff --git a/circom/node_modules/circomlib/doc/smt_levins.monopic b/circom/node_modules/circomlib/doc/smt_levins.monopic new file mode 100644 index 0000000..2c306a8 Binary files /dev/null and b/circom/node_modules/circomlib/doc/smt_levins.monopic differ diff --git a/circom/node_modules/circomlib/doc/smt_sm.monopic b/circom/node_modules/circomlib/doc/smt_sm.monopic new file mode 100644 index 0000000..f3ee288 Binary files /dev/null and b/circom/node_modules/circomlib/doc/smt_sm.monopic differ diff --git a/circom/node_modules/circomlib/doc/smt_verifier_sm.monopic b/circom/node_modules/circomlib/doc/smt_verifier_sm.monopic new file mode 100644 index 0000000..60551cb Binary files /dev/null and b/circom/node_modules/circomlib/doc/smt_verifier_sm.monopic differ diff --git a/circom/node_modules/circomlib/doc/voting.monopic b/circom/node_modules/circomlib/doc/voting.monopic new file mode 100644 index 0000000..0e1710d Binary files /dev/null and b/circom/node_modules/circomlib/doc/voting.monopic differ diff --git a/circom/node_modules/circomlib/doc/window.monopic b/circom/node_modules/circomlib/doc/window.monopic new file mode 100644 index 0000000..309dfb1 Binary files /dev/null and b/circom/node_modules/circomlib/doc/window.monopic differ diff --git a/circom/node_modules/circomlib/doc/window_chain.monopic b/circom/node_modules/circomlib/doc/window_chain.monopic new file mode 100644 index 0000000..47c18bd Binary files /dev/null and b/circom/node_modules/circomlib/doc/window_chain.monopic differ diff --git a/circom/node_modules/circomlib/index.js b/circom/node_modules/circomlib/index.js new file mode 100644 index 0000000..139597f --- /dev/null +++ b/circom/node_modules/circomlib/index.js @@ -0,0 +1,2 @@ + + diff --git a/circom/node_modules/circomlib/package.json b/circom/node_modules/circomlib/package.json new file mode 100644 index 0000000..4bda978 --- /dev/null +++ b/circom/node_modules/circomlib/package.json @@ -0,0 +1,33 @@ +{ + "name": "circomlib", + "version": "2.0.5", + "description": "Basic circuits library for Circom", + "main": "index.js", + "directories": { + "test": "test" + }, + "scripts": { + "test": "mocha --max-old-space-size=4000" + }, + "keywords": [ + "pedersen", + "hash", + "ethereum", + "circuit", + "circom", + "zksnark" + ], + "repository": { + "type": "git", + "url": "https://github.com/iden3/circomlib.git" + }, + "author": "0Kims", + "license": "GPL-3.0", + "devDependencies": { + "blake-hash": "^2.0.0", + "chai": "^4.3.4", + "circom_tester": "0.0.13", + "circomlibjs": "^0.1.4", + "mocha": "^9.1.3" + } +} diff --git a/circom/node_modules/circomlib/test/aliascheck.js b/circom/node_modules/circomlib/test/aliascheck.js new file mode 100644 index 0000000..1568026 --- /dev/null +++ b/circom/node_modules/circomlib/test/aliascheck.js @@ -0,0 +1,77 @@ +const chai = require("chai"); +const path = require("path"); + +const assert = chai.assert; + +const Scalar = require("ffjavascript").Scalar; +const F1Field = require("ffjavascript").F1Field; +const utils = require("ffjavascript").utils; +const q = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"); +const F = new F1Field(q); + +const wasm_tester = require("circom_tester").wasm; + +function print(circuit, w, s) { + console.log(s + ": " + w[circuit.getSignalIdx(s)]); +} + +function getBits(v, n) { + const res = []; + for (let i=0; i { + + cir = await wasm_tester(path.join(__dirname, "circuits", "aliascheck_test.circom")); + }); + + it("Satisfy the aliastest 0", async () => { + const inp = getBits(0, 254); + await cir.calculateWitness({in: inp}, true); + }); + + it("Satisfy the aliastest 3", async () => { + const inp = getBits(3, 254); + await cir.calculateWitness({in: inp}, true); + }); + + it("Satisfy the aliastest q-1", async () => { + const inp = getBits(F.e(-1), 254); + // console.log(JSON.stringify(utils.stringifyBigInts(inp))); + await cir.calculateWitness({in: inp}, true); + }); + + it("Should not satisfy an input of q", async () => { + const inp = getBits(q, 254); + try { + await cir.calculateWitness({in: inp}, true); + assert(false); + } catch(err) { + assert(err.message.includes("Assert Failed")); + } + }); + + it("Should not satisfy all ones", async () => { + + const inp = getBits(Scalar.sub(Scalar.shl(1, 254) , 1) , 254); + try { + await cir.calculateWitness({in: inp}, true); + assert(false); + } catch(err) { + assert(err.message.includes("Assert Failed")); + } + }); + +}); diff --git a/circom/node_modules/circomlib/test/babyjub.js b/circom/node_modules/circomlib/test/babyjub.js new file mode 100644 index 0000000..3f3e3bb --- /dev/null +++ b/circom/node_modules/circomlib/test/babyjub.js @@ -0,0 +1,118 @@ +const chai = require("chai"); +const path = require("path"); + +const createBlakeHash = require("blake-hash"); +const buildEddsa = require("circomlibjs").buildEddsa; + +const assert = chai.assert; + +const wasm_tester = require("circom_tester").wasm; +const utils = require("ffjavascript").utils; +const Scalar = require("ffjavascript").Scalar; + +describe("Baby Jub test", function () { + let eddsa; + let F; + let circuitAdd; + let circuitTest; + let circuitPbk; + + this.timeout(100000); + + before( async() => { + + eddsa = await buildEddsa(); + F = eddsa.F; + + circuitAdd = await wasm_tester(path.join(__dirname, "circuits", "babyadd_tester.circom")); + + circuitTest = await wasm_tester(path.join(__dirname, "circuits", "babycheck_test.circom")); + + circuitPbk = await wasm_tester(path.join(__dirname, "circuits", "babypbk_test.circom")); + }); + + it("Should add point (0,1) and (0,1)", async () => { + + const input={ + x1: 0, + y1: 1, + x2: 0, + y2: 1 + }; + + const w = await circuitAdd.calculateWitness(input, true); + + await circuitAdd.assertOut(w, {xout: 0, yout: 1}); + }); + + it("Should add 2 same numbers", async () => { + + const input={ + x1: 17777552123799933955779906779655732241715742912184938656739573121738514868268n, + y1: 2626589144620713026669568689430873010625803728049924121243784502389097019475n, + x2: 17777552123799933955779906779655732241715742912184938656739573121738514868268n, + y2: 2626589144620713026669568689430873010625803728049924121243784502389097019475n + }; + + const w = await circuitAdd.calculateWitness(input, true); + + await circuitAdd.assertOut(w, { + xout: 6890855772600357754907169075114257697580319025794532037257385534741338397365n, + yout: 4338620300185947561074059802482547481416142213883829469920100239455078257889n + }); + + }); + + it("Should add 2 different numbers", async () => { + + const input={ + x1: 17777552123799933955779906779655732241715742912184938656739573121738514868268n, + y1: 2626589144620713026669568689430873010625803728049924121243784502389097019475n, + x2: 16540640123574156134436876038791482806971768689494387082833631921987005038935n, + y2: 20819045374670962167435360035096875258406992893633759881276124905556507972311n + }; + + const w = await circuitAdd.calculateWitness(input, true); + + await circuitAdd.assertOut(w, { + xout: 7916061937171219682591368294088513039687205273691143098332585753343424131937n, + yout: 14035240266687799601661095864649209771790948434046947201833777492504781204499n + }); + + }); + + it("Should check (0,1) is a valid point", async() => { + const w = await circuitTest.calculateWitness({x: 0, y:1}, true); + + await circuitTest.checkConstraints(w); + }); + + it("Should check (1,0) is an invalid point", async() => { + try { + await circuitTest.calculateWitness({x: 1, y: 0}, true); + assert(false, "Should be a valid point"); + } catch(err) { + assert(err.message.includes("Assert Failed")); + } + }); + + it("Should extract the public key from the private one", async () => { + + const rawpvk = Buffer.from("0001020304050607080900010203040506070809000102030405060708090021", "hex"); + const pvk = eddsa.pruneBuffer(createBlakeHash("blake512").update(rawpvk).digest().slice(0,32)); + const S = Scalar.shr(utils.leBuff2int(pvk), 3); + + const A = eddsa.prv2pub(rawpvk); + + const input = { + in : S + }; + + const w = await circuitPbk.calculateWitness(input, true); + + await circuitPbk.assertOut(w, {Ax : F.toObject(A[0]), Ay: F.toObject(A[1])}); + + await circuitPbk.checkConstraints(w); + }); + +}); diff --git a/circom/node_modules/circomlib/test/binsub.js b/circom/node_modules/circomlib/test/binsub.js new file mode 100644 index 0000000..12809c9 --- /dev/null +++ b/circom/node_modules/circomlib/test/binsub.js @@ -0,0 +1,52 @@ +const path = require("path"); + +const Scalar = require("ffjavascript").Scalar; +const wasm_tester = require("circom_tester").wasm; + +function print(circuit, w, s) { + console.log(s + ": " + w[circuit.getSignalIdx(s)]); +} + +async function checkSub(_a,_b, circuit) { + let a=Scalar.e(_a); + let b=Scalar.e(_b); + if (Scalar.lt(a, 0)) a = Scalar.add(a, Scalar.shl(1, 16)); + if (Scalar.lt(b, 0)) b = Scalar.add(b, Scalar.shl(1, 16)); + const w = await circuit.calculateWitness({a: a, b: b}, true); + + let res = Scalar.sub(a, b); + if (Scalar.lt(res, 0)) res = Scalar.add(res, Scalar.shl(1, 16)); + + await circuit.assertOut(w, {out: res}); +} + +describe("BinSub test", function () { + + this.timeout(100000); + + let circuit; + before( async() => { + circuit = await wasm_tester(path.join(__dirname, "circuits", "binsub_test.circom")); + }); + + it("Should check variuos ege cases", async () => { + await checkSub(0,0, circuit); + await checkSub(1,0, circuit); + await checkSub(-1,0, circuit); + await checkSub(2,1, circuit); + await checkSub(2,2, circuit); + await checkSub(2,3, circuit); + await checkSub(2,-1, circuit); + await checkSub(2,-2, circuit); + await checkSub(2,-3, circuit); + await checkSub(-2,-3, circuit); + await checkSub(-2,-2, circuit); + await checkSub(-2,-1, circuit); + await checkSub(-2,0, circuit); + await checkSub(-2,1, circuit); + await checkSub(-2,2, circuit); + await checkSub(-2,3, circuit); + }); + + +}); diff --git a/circom/node_modules/circomlib/test/binsum.js b/circom/node_modules/circomlib/test/binsum.js new file mode 100644 index 0000000..bd42bf1 --- /dev/null +++ b/circom/node_modules/circomlib/test/binsum.js @@ -0,0 +1,38 @@ +const chai = require("chai"); +const path = require("path"); + +const wasm_tester = require("circom_tester").wasm; + +const F1Field = require("ffjavascript").F1Field; +const Scalar = require("ffjavascript").Scalar; +exports.p = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"); +const Fr = new F1Field(exports.p); + +const assert = chai.assert; + +describe("Binary sum test", function () { + this.timeout(100000000); + + it("Should create a constant circuit", async () => { + const circuit = await wasm_tester(path.join(__dirname, "circuits", "constants_test.circom")); + await circuit.loadConstraints(); + assert.equal(circuit.nVars, 2); + assert.equal(circuit.constraints.length, 1); + + const witness = await circuit.calculateWitness({ "in": Fr.toString(Fr.e("0xd807aa98"))}, true); + + assert(Fr.eq(Fr.e(witness[0]),Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]),Fr.e("0xd807aa98"))); + }); + it("Should create a sum circuit", async () => { + const circuit = await wasm_tester(path.join(__dirname, "circuits", "sum_test.circom")); + await circuit.loadConstraints(); + + assert.equal(circuit.constraints.length, 97); // 32 (in1) + 32(in2) + 32(out) + 1 (carry) + + const witness = await circuit.calculateWitness({ "a": "111", "b": "222" }, true); + + assert(Fr.eq(Fr.e(witness[0]),Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]),Fr.e("333"))); + }); +}); diff --git a/circom/node_modules/circomlib/test/circuits/aliascheck_test.circom b/circom/node_modules/circomlib/test/circuits/aliascheck_test.circom new file mode 100644 index 0000000..942b77c --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/aliascheck_test.circom @@ -0,0 +1,4 @@ +pragma circom 2.0.0; +include "../../circuits/aliascheck.circom"; + +component main = AliasCheck(); diff --git a/circom/node_modules/circomlib/test/circuits/babyadd_tester.circom b/circom/node_modules/circomlib/test/circuits/babyadd_tester.circom new file mode 100644 index 0000000..18c9d8c --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/babyadd_tester.circom @@ -0,0 +1,4 @@ +pragma circom 2.0.0; +include "../../circuits/babyjub.circom"; + +component main = BabyAdd(); diff --git a/circom/node_modules/circomlib/test/circuits/babycheck_test.circom b/circom/node_modules/circomlib/test/circuits/babycheck_test.circom new file mode 100644 index 0000000..bdcdc69 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/babycheck_test.circom @@ -0,0 +1,4 @@ +pragma circom 2.0.0; +include "../../circuits/babyjub.circom"; + +component main = BabyCheck(); diff --git a/circom/node_modules/circomlib/test/circuits/babypbk_test.circom b/circom/node_modules/circomlib/test/circuits/babypbk_test.circom new file mode 100644 index 0000000..5e1f8a5 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/babypbk_test.circom @@ -0,0 +1,4 @@ +pragma circom 2.0.0; +include "../../circuits/babyjub.circom"; + +component main = BabyPbk(); diff --git a/circom/node_modules/circomlib/test/circuits/binsub_test.circom b/circom/node_modules/circomlib/test/circuits/binsub_test.circom new file mode 100644 index 0000000..33cd1a4 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/binsub_test.circom @@ -0,0 +1,33 @@ +pragma circom 2.0.0; + +include "../../circuits/bitify.circom"; +include "../../circuits/binsub.circom"; + +template A() { + signal input a; //private + signal input b; + signal output out; + + var i; + + component n2ba = Num2Bits(16); + component n2bb = Num2Bits(16); + component sub = BinSub(16); + component b2n = Bits2Num(16); + + n2ba.in <== a; + n2bb.in <== b; + + for (i=0; i<16; i++) { + sub.in[0][i] <== n2ba.out[i]; + sub.in[1][i] <== n2bb.out[i]; + } + + for (i=0; i<16; i++) { + b2n.in[i] <== sub.out[i]; + } + + out <== b2n.out; +} + +component main = A(); diff --git a/circom/node_modules/circomlib/test/circuits/constants_test.circom b/circom/node_modules/circomlib/test/circuits/constants_test.circom new file mode 100644 index 0000000..1acb271 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/constants_test.circom @@ -0,0 +1,20 @@ +pragma circom 2.0.0; + +include "../../circuits/sha256/constants.circom"; + +template A() { + signal input in; + component h0; + h0 = K(8); + + var lc = 0; + var e = 1; + for (var i=0; i<32; i++) { + lc = lc + e*h0.out[i]; + e *= 2; + } + + lc === in; +} + +component main {public [in]} = A(); diff --git a/circom/node_modules/circomlib/test/circuits/eddsa_test.circom b/circom/node_modules/circomlib/test/circuits/eddsa_test.circom new file mode 100644 index 0000000..b04ef9b --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/eddsa_test.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/eddsa.circom"; + +component main = EdDSAVerifier(80); diff --git a/circom/node_modules/circomlib/test/circuits/eddsamimc_test.circom b/circom/node_modules/circomlib/test/circuits/eddsamimc_test.circom new file mode 100644 index 0000000..ca1a979 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/eddsamimc_test.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/eddsamimc.circom"; + +component main = EdDSAMiMCVerifier(); diff --git a/circom/node_modules/circomlib/test/circuits/eddsaposeidon_test.circom b/circom/node_modules/circomlib/test/circuits/eddsaposeidon_test.circom new file mode 100644 index 0000000..22ee599 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/eddsaposeidon_test.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/eddsaposeidon.circom"; + +component main = EdDSAPoseidonVerifier(); diff --git a/circom/node_modules/circomlib/test/circuits/edwards2montgomery.circom b/circom/node_modules/circomlib/test/circuits/edwards2montgomery.circom new file mode 100644 index 0000000..7fce4d7 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/edwards2montgomery.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/montgomery.circom"; + +component main = Edwards2Montgomery(); diff --git a/circom/node_modules/circomlib/test/circuits/escalarmul_min_test.circom b/circom/node_modules/circomlib/test/circuits/escalarmul_min_test.circom new file mode 100644 index 0000000..50ce99e --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/escalarmul_min_test.circom @@ -0,0 +1,27 @@ +pragma circom 2.0.0; + +include "../../circuits/escalarmul.circom"; + + +template Main() { + signal input in[256]; + signal output out[2]; + + var i; + + var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553, 16950150798460657717958625567821834550301663161624707787222815936182638968203]; + + component escalarMul = EscalarMul(256, base); + + escalarMul.inp[0] <== 0; + escalarMul.inp[1] <== 1; + + for (i=0; i<256; i++) { + in[i] ==> escalarMul.in[i]; + } + + escalarMul.out[0] ==> out[0]; + escalarMul.out[1] ==> out[1]; +} + +component main = Main(); diff --git a/circom/node_modules/circomlib/test/circuits/escalarmul_test.circom b/circom/node_modules/circomlib/test/circuits/escalarmul_test.circom new file mode 100644 index 0000000..1988633 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/escalarmul_test.circom @@ -0,0 +1,33 @@ +pragma circom 2.0.0; + +include "../../circuits/escalarmul.circom"; +include "../../circuits/bitify.circom"; + + +template Main() { + signal input in; + signal output out[2]; + + var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553, + 16950150798460657717958625567821834550301663161624707787222815936182638968203]; + + + component n2b = Num2Bits(253); + component escalarMul = EscalarMul(253, base); + + escalarMul.inp[0] <== 0; + escalarMul.inp[1] <== 1; + + var i; + + in ==> n2b.in; + + for (i=0; i<253; i++) { + n2b.out[i] ==> escalarMul.in[i]; + } + + escalarMul.out[0] ==> out[0]; + escalarMul.out[1] ==> out[1]; +} + +component main = Main(); diff --git a/circom/node_modules/circomlib/test/circuits/escalarmul_test_min.circom b/circom/node_modules/circomlib/test/circuits/escalarmul_test_min.circom new file mode 100644 index 0000000..422e0a8 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/escalarmul_test_min.circom @@ -0,0 +1,28 @@ +pragma circom 2.0.0; + +include "../../circuits/escalarmul.circom"; + + +template Main() { + signal input in[256]; + signal output out[2]; + + var i; + + var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553, + 16950150798460657717958625567821834550301663161624707787222815936182638968203]; + + component escalarMul = EscalarMul(256, base); + + escalarMul.inp[0] <== 0; + escalarMul.inp[1] <== 1; + + for (i=0; i<256; i++) { + in[i] ==> escalarMul.in[i]; + } + + escalarMul.out[0] ==> out[0]; + escalarMul.out[1] ==> out[1]; +} + +component main = Main(); diff --git a/circom/node_modules/circomlib/test/circuits/escalarmulany_test.circom b/circom/node_modules/circomlib/test/circuits/escalarmulany_test.circom new file mode 100644 index 0000000..5e79bbe --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/escalarmulany_test.circom @@ -0,0 +1,30 @@ +pragma circom 2.0.0; + +include "../../circuits/escalarmulany.circom"; +include "../../circuits/bitify.circom"; + +template Main() { + signal input e; + signal input p[2]; + signal output out[2]; + + component n2b = Num2Bits(253); + component escalarMulAny = EscalarMulAny(253); + + escalarMulAny.p[0] <== p[0]; + escalarMulAny.p[1] <== p[1]; + + var i; + + e ==> n2b.in; + + for (i=0; i<253; i++) { + n2b.out[i] ==> escalarMulAny.e[i]; + } + + escalarMulAny.out[0] ==> out[0]; + escalarMulAny.out[1] ==> out[1]; +} + +component main = Main(); + diff --git a/circom/node_modules/circomlib/test/circuits/escalarmulfix_test.circom b/circom/node_modules/circomlib/test/circuits/escalarmulfix_test.circom new file mode 100644 index 0000000..54cd7ba --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/escalarmulfix_test.circom @@ -0,0 +1,31 @@ +pragma circom 2.0.0; + +include "../../circuits/escalarmulfix.circom"; +include "../../circuits/bitify.circom"; + + +template Main() { + signal input e; + signal output out[2]; + + var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553, + 16950150798460657717958625567821834550301663161624707787222815936182638968203]; + + + component n2b = Num2Bits(253); + component escalarMul = EscalarMulFix(253, base); + + var i; + + e ==> n2b.in; + + for (i=0; i<253; i++) { + n2b.out[i] ==> escalarMul.e[i]; + } + + escalarMul.out[0] ==> out[0]; + escalarMul.out[1] ==> out[1]; +} + +component main = Main(); + diff --git a/circom/node_modules/circomlib/test/circuits/escalarmulw4table.circom b/circom/node_modules/circomlib/test/circuits/escalarmulw4table.circom new file mode 100644 index 0000000..74b4334 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/escalarmulw4table.circom @@ -0,0 +1,20 @@ +pragma circom 2.0.0; + +include "../../circuits/escalarmulw4table.circom"; + + + + +template Main() { + signal output out[16][2]; + var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553, + 16950150798460657717958625567821834550301663161624707787222815936182638968203]; + + var escalarMul[16][2] = EscalarMulW4Table(base, 0); + for (var i=0; i<16; i++) { + out[i][0] <== escalarMul[i][0]; + out[i][1] <== escalarMul[i][1]; + } +} + +component main = Main(); diff --git a/circom/node_modules/circomlib/test/circuits/escalarmulw4table_test.circom b/circom/node_modules/circomlib/test/circuits/escalarmulw4table_test.circom new file mode 100644 index 0000000..ed2ac41 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/escalarmulw4table_test.circom @@ -0,0 +1,19 @@ +pragma circom 2.0.0; + +include "../../circuits/escalarmulw4table.circom"; + + +template Main() { + signal input in; + signal output out[16][2]; + var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553, + 16950150798460657717958625567821834550301663161624707787222815936182638968203]; + + var escalarMul[16][2] = EscalarMulW4Table(base, 0); + for (var i=0; i<16; i++) { + out[i][0] <== escalarMul[i][0]*in; + out[i][1] <== escalarMul[i][1]*in; + } +} + +component main = Main(); diff --git a/circom/node_modules/circomlib/test/circuits/escalarmulw4table_test3.circom b/circom/node_modules/circomlib/test/circuits/escalarmulw4table_test3.circom new file mode 100644 index 0000000..14c0ee8 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/escalarmulw4table_test3.circom @@ -0,0 +1,19 @@ +pragma circom 2.0.0; + +include "../../circuits/escalarmulw4table.circom"; + + +template Main() { + signal input in; + signal output out[16][2]; + var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553, + 16950150798460657717958625567821834550301663161624707787222815936182638968203]; + + var escalarMul[16][2] = EscalarMulW4Table(base, 3); + for (var i=0; i<16; i++) { + out[i][0] <== escalarMul[i][0]*in; + out[i][1] <== escalarMul[i][1]*in; + } +} + +component main = Main(); diff --git a/circom/node_modules/circomlib/test/circuits/greatereqthan.circom b/circom/node_modules/circomlib/test/circuits/greatereqthan.circom new file mode 100644 index 0000000..8e53f94 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/greatereqthan.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/comparators.circom"; + +component main = GreaterEqThan(32); diff --git a/circom/node_modules/circomlib/test/circuits/greaterthan.circom b/circom/node_modules/circomlib/test/circuits/greaterthan.circom new file mode 100644 index 0000000..d214237 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/greaterthan.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/comparators.circom"; + +component main = GreaterThan(32); diff --git a/circom/node_modules/circomlib/test/circuits/isequal.circom b/circom/node_modules/circomlib/test/circuits/isequal.circom new file mode 100644 index 0000000..eb4fcc4 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/isequal.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/comparators.circom"; + +component main = IsEqual(); diff --git a/circom/node_modules/circomlib/test/circuits/iszero.circom b/circom/node_modules/circomlib/test/circuits/iszero.circom new file mode 100644 index 0000000..0ce848a --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/iszero.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/comparators.circom"; + +component main = IsZero(); diff --git a/circom/node_modules/circomlib/test/circuits/lesseqthan.circom b/circom/node_modules/circomlib/test/circuits/lesseqthan.circom new file mode 100644 index 0000000..9b9a89b --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/lesseqthan.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/comparators.circom"; + +component main = LessEqThan(32); diff --git a/circom/node_modules/circomlib/test/circuits/lessthan.circom b/circom/node_modules/circomlib/test/circuits/lessthan.circom new file mode 100644 index 0000000..78660b7 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/lessthan.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/comparators.circom"; + +component main = LessThan(32); diff --git a/circom/node_modules/circomlib/test/circuits/mimc_sponge_hash_test.circom b/circom/node_modules/circomlib/test/circuits/mimc_sponge_hash_test.circom new file mode 100644 index 0000000..68a8ab5 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/mimc_sponge_hash_test.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/mimcsponge.circom"; + +component main = MiMCSponge(2, 220, 3); diff --git a/circom/node_modules/circomlib/test/circuits/mimc_sponge_test.circom b/circom/node_modules/circomlib/test/circuits/mimc_sponge_test.circom new file mode 100644 index 0000000..367c615 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/mimc_sponge_test.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/mimcsponge.circom"; + +component main = MiMCFeistel(220); diff --git a/circom/node_modules/circomlib/test/circuits/mimc_test.circom b/circom/node_modules/circomlib/test/circuits/mimc_test.circom new file mode 100644 index 0000000..2325e65 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/mimc_test.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/mimc.circom"; + +component main = MiMC7(91); diff --git a/circom/node_modules/circomlib/test/circuits/montgomery2edwards.circom b/circom/node_modules/circomlib/test/circuits/montgomery2edwards.circom new file mode 100644 index 0000000..af344a4 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/montgomery2edwards.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/montgomery.circom"; + +component main = Montgomery2Edwards(); diff --git a/circom/node_modules/circomlib/test/circuits/montgomeryadd.circom b/circom/node_modules/circomlib/test/circuits/montgomeryadd.circom new file mode 100644 index 0000000..8d0e73b --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/montgomeryadd.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/montgomery.circom"; + +component main = MontgomeryAdd(); diff --git a/circom/node_modules/circomlib/test/circuits/montgomerydouble.circom b/circom/node_modules/circomlib/test/circuits/montgomerydouble.circom new file mode 100644 index 0000000..51909db --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/montgomerydouble.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/montgomery.circom"; + +component main = MontgomeryDouble(); diff --git a/circom/node_modules/circomlib/test/circuits/mux1_1.circom b/circom/node_modules/circomlib/test/circuits/mux1_1.circom new file mode 100644 index 0000000..ff13ae2 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/mux1_1.circom @@ -0,0 +1,33 @@ +pragma circom 2.0.0; + +include "../../circuits/mux1.circom"; +include "../../circuits/bitify.circom"; + + +template Constants() { + var i; + signal output out[2]; + + out[0] <== 37; + out[1] <== 47; +} + +template Main() { + var i; + signal input selector;//private + signal output out; + + component mux = Mux1(); + component n2b = Num2Bits(1); + component cst = Constants(); + + selector ==> n2b.in; + n2b.out[0] ==> mux.s; + for (i=0; i<2; i++) { + cst.out[i] ==> mux.c[i]; + } + + mux.out ==> out; +} + +component main = Main(); diff --git a/circom/node_modules/circomlib/test/circuits/mux2_1.circom b/circom/node_modules/circomlib/test/circuits/mux2_1.circom new file mode 100644 index 0000000..419fe62 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/mux2_1.circom @@ -0,0 +1,37 @@ +pragma circom 2.0.0; + +include "../../circuits/mux2.circom"; +include "../../circuits/bitify.circom"; + + +template Constants() { + var i; + signal output out[4]; + + out[0] <== 37; + out[1] <== 47; + out[2] <== 53; + out[3] <== 71; +} + +template Main() { + var i; + signal input selector;//private + signal output out; + + component mux = Mux2(); + component n2b = Num2Bits(2); + component cst = Constants(); + + selector ==> n2b.in; + for (i=0; i<2; i++) { + n2b.out[i] ==> mux.s[i]; + } + for (i=0; i<4; i++) { + cst.out[i] ==> mux.c[i]; + } + + mux.out ==> out; +} + +component main = Main(); diff --git a/circom/node_modules/circomlib/test/circuits/mux3_1.circom b/circom/node_modules/circomlib/test/circuits/mux3_1.circom new file mode 100644 index 0000000..8723c8b --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/mux3_1.circom @@ -0,0 +1,41 @@ +pragma circom 2.0.0; + +include "../../circuits/mux3.circom"; +include "../../circuits/bitify.circom"; + + +template Constants() { + var i; + signal output out[8]; + + out[0] <== 37; + out[1] <== 47; + out[2] <== 53; + out[3] <== 71; + out[4] <== 89; + out[5] <== 107; + out[6] <== 163; + out[7] <== 191; +} + +template Main() { + var i; + signal input selector;//private + signal output out; + + component mux = Mux3(); + component n2b = Num2Bits(3); + component cst = Constants(); + + selector ==> n2b.in; + for (i=0; i<3; i++) { + n2b.out[i] ==> mux.s[i]; + } + for (i=0; i<8; i++) { + cst.out[i] ==> mux.c[i]; + } + + mux.out ==> out; +} + +component main = Main(); diff --git a/circom/node_modules/circomlib/test/circuits/mux4_1.circom b/circom/node_modules/circomlib/test/circuits/mux4_1.circom new file mode 100644 index 0000000..c9b10dd --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/mux4_1.circom @@ -0,0 +1,56 @@ +pragma circom 2.0.0; + +include "../../circuits/mux4.circom"; +include "../../circuits/bitify.circom"; + + +template Constants() { + var i; + signal output out[16]; + + out[0] <== 123; + out[1] <== 456; + out[2] <== 789; + out[3] <== 012; + out[4] <== 111; + out[5] <== 222; + out[6] <== 333; + out[7] <== 4546; + out[8] <== 134523; + out[9] <== 44356; + out[10] <== 15623; + out[11] <== 4566; + out[12] <== 1223; + out[13] <== 4546; + out[14] <== 4256; + out[15] <== 4456; + +/* + for (i=0;i<16; i++) { + out[i] <== i*2+100; + } +*/ + +} + +template Main() { + var i; + signal input selector;//private + signal output out; + + component mux = Mux4(); + component n2b = Num2Bits(4); + component cst = Constants(); + + selector ==> n2b.in; + for (i=0; i<4; i++) { + n2b.out[i] ==> mux.s[i]; + } + for (i=0; i<16; i++) { + cst.out[i] ==> mux.c[i]; + } + + mux.out ==> out; +} + +component main = Main(); diff --git a/circom/node_modules/circomlib/test/circuits/pedersen2_test.circom b/circom/node_modules/circomlib/test/circuits/pedersen2_test.circom new file mode 100644 index 0000000..c407d53 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/pedersen2_test.circom @@ -0,0 +1,34 @@ +pragma circom 2.0.0; + +include "../../circuits/pedersen.circom"; +include "../../circuits/bitify.circom"; + + +template Main() { + signal input in; + signal output out[2]; + + component pedersen = Pedersen(256); + + component n2b; + n2b = Num2Bits(253); + + var i; + + in ==> n2b.in; + + for (i=0; i<253; i++) { + pedersen.in[i] <== n2b.out[i]; + } + + for (i=253; i<256; i++) { + pedersen.in[i] <== 0; + } + + pedersen.out[0] ==> out[0]; + pedersen.out[1] ==> out[1]; +} + +component main = Main(); + + diff --git a/circom/node_modules/circomlib/test/circuits/pedersen_test.circom b/circom/node_modules/circomlib/test/circuits/pedersen_test.circom new file mode 100644 index 0000000..eba561c --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/pedersen_test.circom @@ -0,0 +1,31 @@ +pragma circom 2.0.0; + +include "../../circuits/pedersen_old.circom"; +include "../../circuits/bitify.circom"; + + +template Main() { + signal input in[2]; + signal output out[2]; + + component pedersen = Pedersen(250*2); + + component n2b[2]; + n2b[0] = Num2Bits(250); + n2b[1] = Num2Bits(250); + + var i; + + in[0] ==> n2b[0].in; + in[1] ==> n2b[1].in; + + for (i=0; i<250; i++) { + n2b[0].out[i] ==> pedersen.in[i]; + n2b[1].out[i] ==> pedersen.in[250+i]; + } + + pedersen.out[0] ==> out[0]; + pedersen.out[1] ==> out[1]; +} + +component main = Main(); diff --git a/circom/node_modules/circomlib/test/circuits/pointbits_loopback.circom b/circom/node_modules/circomlib/test/circuits/pointbits_loopback.circom new file mode 100644 index 0000000..cbba8fc --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/pointbits_loopback.circom @@ -0,0 +1,25 @@ +pragma circom 2.0.0; + +include "../../circuits/pointbits.circom"; + + +template Main() { + signal input in[2]; + + var i; + + component p2b = Point2Bits_Strict(); + component b2p = Bits2Point_Strict(); + + p2b.in[0] <== in[0]; + p2b.in[1] <== in[1]; + + for (i=0; i<256; i++) { + b2p.in[i] <== p2b.out[i]; + } + + b2p.out[0] === in[0]; + b2p.out[1] === in[1]; +} + +component main = Main(); diff --git a/circom/node_modules/circomlib/test/circuits/poseidon3_test.circom b/circom/node_modules/circomlib/test/circuits/poseidon3_test.circom new file mode 100644 index 0000000..1b06c18 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/poseidon3_test.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/poseidon.circom"; + +component main = Poseidon(2); diff --git a/circom/node_modules/circomlib/test/circuits/poseidon6_test.circom b/circom/node_modules/circomlib/test/circuits/poseidon6_test.circom new file mode 100644 index 0000000..83cd1cf --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/poseidon6_test.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/poseidon.circom"; + +component main = Poseidon(5); diff --git a/circom/node_modules/circomlib/test/circuits/poseidonex_test.circom b/circom/node_modules/circomlib/test/circuits/poseidonex_test.circom new file mode 100644 index 0000000..171fbd2 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/poseidonex_test.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/poseidon.circom"; + +component main = PoseidonEx(16, 17); \ No newline at end of file diff --git a/circom/node_modules/circomlib/test/circuits/sha256_2_test.circom b/circom/node_modules/circomlib/test/circuits/sha256_2_test.circom new file mode 100644 index 0000000..13a445d --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/sha256_2_test.circom @@ -0,0 +1,17 @@ +pragma circom 2.0.0; + +include "../../circuits/sha256/sha256_2.circom"; + +template Main() { + signal input a; //private + signal input b; //private + signal output out; + + component sha256_2 = Sha256_2(); + + sha256_2.a <== a; + sha256_2.b <== b; + out <== sha256_2.out; +} + +component main = Main(); diff --git a/circom/node_modules/circomlib/test/circuits/sha256_test448.circom b/circom/node_modules/circomlib/test/circuits/sha256_test448.circom new file mode 100644 index 0000000..7a9843c --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/sha256_test448.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/sha256/sha256.circom"; + +component main = Sha256(448); diff --git a/circom/node_modules/circomlib/test/circuits/sha256_test512.circom b/circom/node_modules/circomlib/test/circuits/sha256_test512.circom new file mode 100644 index 0000000..06db0d3 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/sha256_test512.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/sha256/sha256.circom"; + +component main = Sha256(512); diff --git a/circom/node_modules/circomlib/test/circuits/sign_test.circom b/circom/node_modules/circomlib/test/circuits/sign_test.circom new file mode 100644 index 0000000..2dae52c --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/sign_test.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/sign.circom"; + +component main = Sign(); diff --git a/circom/node_modules/circomlib/test/circuits/smtprocessor10_test.circom b/circom/node_modules/circomlib/test/circuits/smtprocessor10_test.circom new file mode 100644 index 0000000..3030054 --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/smtprocessor10_test.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/smt/smtprocessor.circom"; + +component main = SMTProcessor(10); diff --git a/circom/node_modules/circomlib/test/circuits/smtverifier10_test.circom b/circom/node_modules/circomlib/test/circuits/smtverifier10_test.circom new file mode 100644 index 0000000..5b6d47a --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/smtverifier10_test.circom @@ -0,0 +1,5 @@ +pragma circom 2.0.0; + +include "../../circuits/smt/smtverifier.circom"; + +component main = SMTVerifier(10); diff --git a/circom/node_modules/circomlib/test/circuits/sum_test.circom b/circom/node_modules/circomlib/test/circuits/sum_test.circom new file mode 100644 index 0000000..b0be22f --- /dev/null +++ b/circom/node_modules/circomlib/test/circuits/sum_test.circom @@ -0,0 +1,33 @@ +pragma circom 2.0.0; + +include "../../circuits/bitify.circom"; +include "../../circuits/binsum.circom"; + +template A() { + signal input a; //private + signal input b; + signal output out; + + var i; + + component n2ba = Num2Bits(32); + component n2bb = Num2Bits(32); + component sum = BinSum(32,2); + component b2n = Bits2Num(32); + + n2ba.in <== a; + n2bb.in <== b; + + for (i=0; i<32; i++) { + sum.in[0][i] <== n2ba.out[i]; + sum.in[1][i] <== n2bb.out[i]; + } + + for (i=0; i<32; i++) { + b2n.in[i] <== sum.out[i]; + } + + out <== b2n.out; +} + +component main = A(); diff --git a/circom/node_modules/circomlib/test/comparators.js b/circom/node_modules/circomlib/test/comparators.js new file mode 100644 index 0000000..157c5f8 --- /dev/null +++ b/circom/node_modules/circomlib/test/comparators.js @@ -0,0 +1,187 @@ +const chai = require("chai"); +const path = require("path"); +const F1Field = require("ffjavascript").F1Field; +const Scalar = require("ffjavascript").Scalar; +exports.p = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"); +const Fr = new F1Field(exports.p); + +const wasm_tester = require("circom_tester").wasm; + +const assert = chai.assert; + +describe("Comparators test", function () { + + this.timeout(100000); + + it("Should create a iszero circuit", async() => { + const circuit = await wasm_tester(path.join(__dirname, "circuits", "iszero.circom")); + + let witness; + witness = await circuit.calculateWitness({ "in": 111}, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(0))); + + witness = await circuit.calculateWitness({ "in": 0 }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(1))); + }); + it("Should create a isequal circuit", async() => { + const circuit = await wasm_tester(path.join(__dirname, "circuits", "isequal.circom")); + + let witness; + witness = await circuit.calculateWitness({ "in": [111,222] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(0))); + + + witness = await circuit.calculateWitness({ "in": [444,444] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(1))); + }); + it("Should create a comparison lessthan", async() => { + const circuit = await wasm_tester(path.join(__dirname, "circuits", "lessthan.circom")); + + let witness; + witness = await circuit.calculateWitness({ "in": [333,444] }), true; + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(1))); + + witness = await circuit.calculateWitness({ "in":[1,1] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(0))); + + witness = await circuit.calculateWitness({ "in": [661, 660] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(0))); + + witness = await circuit.calculateWitness({ "in": [0, 1] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(1))); + + witness = await circuit.calculateWitness({ "in": [0, 444] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(1))); + + witness = await circuit.calculateWitness({ "in": [1, 0] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(0))); + + witness = await circuit.calculateWitness({ "in": [555, 0] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(0))); + + witness = await circuit.calculateWitness({ "in": [0, 0] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(0))); + }); + it("Should create a comparison lesseqthan", async() => { + + const circuit = await wasm_tester(path.join(__dirname, "circuits", "lesseqthan.circom")); + + let witness; + witness = await circuit.calculateWitness({ "in": [333,444] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(1))); + + witness = await circuit.calculateWitness({ "in":[1,1] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(1))); + + witness = await circuit.calculateWitness({ "in": [661, 660] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(0))); + + witness = await circuit.calculateWitness({ "in": [0, 1] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(1))); + + witness = await circuit.calculateWitness({ "in": [0, 444] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(1))); + + witness = await circuit.calculateWitness({ "in": [1, 0] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(0))); + + witness = await circuit.calculateWitness({ "in": [555, 0] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(0))); + + witness = await circuit.calculateWitness({ "in": [0, 0] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(1))); + }); + it("Should create a comparison greaterthan", async() => { + + const circuit = await wasm_tester(path.join(__dirname, "circuits", "greaterthan.circom")); + + let witness; + witness = await circuit.calculateWitness({ "in": [333,444] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(0))); + + witness = await circuit.calculateWitness({ "in":[1,1] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(0))); + + witness = await circuit.calculateWitness({ "in": [661, 660] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(1))); + + witness = await circuit.calculateWitness({ "in": [0, 1] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(0))); + + witness = await circuit.calculateWitness({ "in": [0, 444] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(0))); + + witness = await circuit.calculateWitness({ "in": [1, 0] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(1))); + + witness = await circuit.calculateWitness({ "in": [555, 0] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(1))); + + witness = await circuit.calculateWitness({ "in": [0, 0] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(0))); + }); + it("Should create a comparison greatereqthan", async() => { + const circuit = await wasm_tester(path.join(__dirname, "circuits", "greatereqthan.circom")); + + let witness; + witness = await circuit.calculateWitness({ "in": [333,444] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(0))); + + witness = await circuit.calculateWitness({ "in":[1,1] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(1))); + + witness = await circuit.calculateWitness({ "in": [661, 660] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(1))); + + witness = await circuit.calculateWitness({ "in": [0, 1] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(0))); + + witness = await circuit.calculateWitness({ "in": [0, 444] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(0))); + + witness = await circuit.calculateWitness({ "in": [1, 0] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(1))); + + witness = await circuit.calculateWitness({ "in": [555, 0] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(1))); + + witness = await circuit.calculateWitness({ "in": [0, 0] }, true); + assert(Fr.eq(Fr.e(witness[0]), Fr.e(1))); + assert(Fr.eq(Fr.e(witness[1]), Fr.e(1))); + }); +}); diff --git a/circom/node_modules/circomlib/test/eddsa.js b/circom/node_modules/circomlib/test/eddsa.js new file mode 100644 index 0000000..7d7e5d9 --- /dev/null +++ b/circom/node_modules/circomlib/test/eddsa.js @@ -0,0 +1,75 @@ +const chai = require("chai"); +const path = require("path"); + +const wasm_tester = require("circom_tester").wasm; + +const buildEddsa = require("circomlibjs").buildEddsa; +const buildBabyjub = require("circomlibjs").buildBabyjub; + +const Scalar = require("ffjavascript").Scalar; + +const assert = chai.assert; + +function print(circuit, w, s) { + console.log(s + ": " + w[circuit.getSignalIdx(s)]); +} + +function buffer2bits(buff) { + const res = []; + for (let i=0; i>j)&1) { + res.push(1n); + } else { + res.push(0n); + } + } + } + return res; +} + + +describe("EdDSA test", function () { + let circuit; + let eddsa; + let babyJub; + let F; + + this.timeout(100000); + + before( async () => { + eddsa = await buildEddsa(); + babyJub = await buildBabyjub(); + F = babyJub.F; + circuit = await wasm_tester(path.join(__dirname, "circuits", "eddsa_test.circom")); + }); + + + it("Sign a single 10 bytes from 0 to 9", async () => { + const msg = Buffer.from("00010203040506070809", "hex"); + +// const prvKey = crypto.randomBytes(32); + + const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); + + const pubKey = eddsa.prv2pub(prvKey); + + const pPubKey = babyJub.packPoint(pubKey); + + const signature = eddsa.signPedersen(prvKey, msg); + + const pSignature = eddsa.packSignature(signature); + const uSignature = eddsa.unpackSignature(pSignature); + + assert(eddsa.verifyPedersen(msg, uSignature, pubKey)); + + const msgBits = buffer2bits( msg); + const r8Bits = buffer2bits( pSignature.slice(0, 32)); + const sBits = buffer2bits( pSignature.slice(32, 64)); + const aBits = buffer2bits( pPubKey); + + const w = await circuit.calculateWitness({A: aBits, R8: r8Bits, S: sBits, msg: msgBits}, true); + + await circuit.checkConstraints(w); + }); +}); diff --git a/circom/node_modules/circomlib/test/eddsamimc.js b/circom/node_modules/circomlib/test/eddsamimc.js new file mode 100644 index 0000000..0cf5121 --- /dev/null +++ b/circom/node_modules/circomlib/test/eddsamimc.js @@ -0,0 +1,102 @@ +const chai = require("chai"); +const path = require("path"); +const wasm_tester = require("circom_tester").wasm; + +const buildEddsa = require("circomlibjs").buildEddsa; +const buildBabyjub = require("circomlibjs").buildBabyjub; + +const assert = chai.assert; + +describe("EdDSA MiMC test", function () { + let circuit; + let eddsa; + let babyJub; + let F; + + this.timeout(100000); + + before( async () => { + eddsa = await buildEddsa(); + babyJub = await buildBabyjub(); + F = babyJub.F; + + circuit = await wasm_tester(path.join(__dirname, "circuits", "eddsamimc_test.circom")); + }); + + it("Sign a single number", async () => { + const msg = F.e(1234); + + const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); + + const pubKey = eddsa.prv2pub(prvKey); + + const signature = eddsa.signMiMC(prvKey, msg); + + assert(eddsa.verifyMiMC(msg, signature, pubKey)); + + const w = await circuit.calculateWitness({ + enabled: 1, + Ax: F.toObject(pubKey[0]), + Ay: F.toObject(pubKey[1]), + R8x: F.toObject(signature.R8[0]), + R8y: F.toObject(signature.R8[1]), + S: signature.S, + M: F.toObject(msg)}, true); + + + await circuit.checkConstraints(w); + + }); + + it("Detect Invalid signature", async () => { + const msg = F.e(1234); + + const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); + + const pubKey = eddsa.prv2pub(prvKey); + + + const signature = eddsa.signMiMC(prvKey, msg); + + assert(eddsa.verifyMiMC(msg, signature, pubKey)); + try { + const w = await circuit.calculateWitness({ + enabled: 1, + Ax: F.toObject(pubKey[0]), + Ay: F.toObject(pubKey[1]), + R8x: F.toObject(F.add(signature.R8[0], F.e(1))), + R8y: F.toObject(signature.R8[1]), + S: signature.S, + M: F.toObject(msg)}, true); + assert(false); + } catch(err) { + assert(err.message.includes("Assert Failed")); + } + }); + + + it("Test a dissabled circuit with a bad signature", async () => { + const msg = F.e(1234); + + const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); + + const pubKey = eddsa.prv2pub(prvKey); + + + const signature = eddsa.signMiMC(prvKey, msg); + + assert(eddsa.verifyMiMC(msg, signature, pubKey)); + + const w = await circuit.calculateWitness({ + enabled: 0, + Ax: F.toObject(pubKey[0]), + Ay: F.toObject(pubKey[1]), + R8x: F.toObject(F.add(signature.R8[0], F.e(1))), + R8y: F.toObject(signature.R8[1]), + S: signature.S, + M: F.toObject(msg)}, true); + + await circuit.checkConstraints(w); + + }); +}); diff --git a/circom/node_modules/circomlib/test/eddsaposeidon.js b/circom/node_modules/circomlib/test/eddsaposeidon.js new file mode 100644 index 0000000..3dec2cd --- /dev/null +++ b/circom/node_modules/circomlib/test/eddsaposeidon.js @@ -0,0 +1,103 @@ +const chai = require("chai"); +const path = require("path"); +const wasm_tester = require("circom_tester").wasm; + +const buildEddsa = require("circomlibjs").buildEddsa; +const buildBabyjub = require("circomlibjs").buildBabyjub; + +const assert = chai.assert; + +describe("EdDSA Poseidon test", function () { + let circuit; + let eddsa; + let babyJub; + let F; + + this.timeout(100000); + + before( async () => { + eddsa = await buildEddsa(); + babyJub = await buildBabyjub(); + F = babyJub.F; + circuit = await wasm_tester(path.join(__dirname, "circuits", "eddsaposeidon_test.circom")); + }); + + it("Sign a single number", async () => { + const msg = F.e(1234); + + const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); + + const pubKey = eddsa.prv2pub(prvKey); + + const signature = eddsa.signPoseidon(prvKey, msg); + + assert(eddsa.verifyPoseidon(msg, signature, pubKey)); + + const input = { + enabled: 1, + Ax: F.toObject(pubKey[0]), + Ay: F.toObject(pubKey[1]), + R8x: F.toObject(signature.R8[0]), + R8y: F.toObject(signature.R8[1]), + S: signature.S, + M: F.toObject(msg) + }; + + // console.log(JSON.stringify(utils.stringifyBigInts(input))); + + const w = await circuit.calculateWitness(input, true); + + await circuit.checkConstraints(w); + }); + + it("Detect Invalid signature", async () => { + const msg = F.e(1234); + + const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); + + const pubKey = eddsa.prv2pub(prvKey); + + + const signature = eddsa.signPoseidon(prvKey, msg); + + assert(eddsa.verifyPoseidon(msg, signature, pubKey)); + try { + await circuit.calculateWitness({ + enabled: 1, + Ax: F.toObject(pubKey[0]), + Ay: F.toObject(pubKey[1]), + R8x: F.toObject(F.add(signature.R8[0], F.e(1))), + R8y: F.toObject(signature.R8[1]), + S: signature.S, + M: F.toObject(msg)}, true); + assert(false); + } catch(err) { + assert(err.message.includes("Assert Failed")); + } + }); + + + it("Test a dissabled circuit with a bad signature", async () => { + const msg = F.e(1234); + + const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); + + const pubKey = eddsa.prv2pub(prvKey); + + + const signature = eddsa.signPoseidon(prvKey, msg); + + assert(eddsa.verifyPoseidon(msg, signature, pubKey)); + + const w = await circuit.calculateWitness({ + enabled: 0, + Ax: F.toObject(pubKey[0]), + Ay: F.toObject(pubKey[1]), + R8x: F.toObject(F.add(signature.R8[0], F.e(1))), + R8y: F.toObject(signature.R8[1]), + S: signature.S, + M: F.toObject(msg)}, true); + + await circuit.checkConstraints(w); + }); +}); diff --git a/circom/node_modules/circomlib/test/escalarmul.js b/circom/node_modules/circomlib/test/escalarmul.js new file mode 100644 index 0000000..8a65294 --- /dev/null +++ b/circom/node_modules/circomlib/test/escalarmul.js @@ -0,0 +1,121 @@ +const chai = require("chai"); +const path = require("path"); +const wasm_tester = require("circom_tester").wasm; +const buildBabyjub = require("circomlibjs").buildBabyjub; + +const Scalar = require("ffjavascript").Scalar; + +const assert = chai.assert; + +function print(circuit, w, s) { + console.log(s + ": " + w[circuit.getSignalIdx(s)]); +} + +describe("Exponentioation test", function () { + let babyJub; + let Fr; + this.timeout(100000); + + before( async () => { + babyJub = await buildBabyjub(); + Fr = babyJub.F; + }); + + it("Should generate the Exponentiation table in k=0", async () => { + + const circuit = await wasm_tester(path.join(__dirname, "circuits", "escalarmulw4table_test.circom")); + + const w = await circuit.calculateWitness({in: 1}); + + await circuit.checkConstraints(w); + + let g = [ + Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"), + Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203") + ]; + + let dbl= [Fr.e("0"), Fr.e("1")]; + + const expectedOut = []; + + for (let i=0; i<16; i++) { + + expectedOut.push([Fr.toObject(dbl[0]), Fr.toObject(dbl[1])]); + dbl = babyJub.addPoint(dbl,g); + } + + await circuit.assertOut(w, {out: expectedOut}); + + }); + + it("Should generate the Exponentiation table in k=3", async () => { + + const circuit = await wasm_tester(path.join(__dirname, "circuits", "escalarmulw4table_test3.circom")); + + const w = await circuit.calculateWitness({in: 1}); + + await circuit.checkConstraints(w); + + let g = [ + Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"), + Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203") + ]; + + for (let i=0; i<12;i++) { + g = babyJub.addPoint(g,g); + } + + let dbl= [Fr.e("0"), Fr.e("1")]; + + const expectedOut = []; + + for (let i=0; i<16; i++) { + expectedOut.push([Fr.toObject(dbl[0]), Fr.toObject(dbl[1])]); + + dbl = babyJub.addPoint(dbl,g); + } + + await circuit.assertOut(w, {out: expectedOut}); + + }); + + it("Should exponentiate g^31", async () => { + + const circuit = await wasm_tester(path.join(__dirname, "circuits", "escalarmul_test.circom")); + + const w = await circuit.calculateWitness({"in": 31}); + + await circuit.checkConstraints(w); + + let g = [ + Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"), + Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203") + ]; + + let c = [Fr.e(0), Fr.e(1)]; + + for (let i=0; i<31;i++) { + c = babyJub.addPoint(c,g); + } + + await circuit.assertOut(w, {out: [Fr.toObject(c[0]), Fr.toObject(c[1])] }); + + const w2 = await circuit.calculateWitness({"in": Scalar.add(Scalar.shl(Scalar.e(1), 252),Scalar.e(1))}); + + c = [g[0], g[1]]; + for (let i=0; i<252;i++) { + c = babyJub.addPoint(c,c); + } + c = babyJub.addPoint(c,g); + + await circuit.assertOut(w2, {out: [Fr.toObject(c[0]), Fr.toObject(c[1])] }); + + }).timeout(10000000); + + it("Number of constrains for 256 bits", async () => { + + const circuit = await wasm_tester(path.join(__dirname, "circuits", "escalarmul_test_min.circom")); + + }).timeout(10000000); + +}); diff --git a/circom/node_modules/circomlib/test/escalarmulany.js b/circom/node_modules/circomlib/test/escalarmulany.js new file mode 100644 index 0000000..7295970 --- /dev/null +++ b/circom/node_modules/circomlib/test/escalarmulany.js @@ -0,0 +1,51 @@ +const chai = require("chai"); +const path = require("path"); +const wasm_tester = require("circom_tester").wasm; + +const F1Field = require("ffjavascript").F1Field; +const Scalar = require("ffjavascript").Scalar; +exports.p = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"); +const Fr = new F1Field(exports.p); + +function print(circuit, w, s) { + console.log(s + ": " + w[circuit.getSignalIdx(s)]); +} + +describe("Escalarmul test", function () { + let circuitEMulAny; + + this.timeout(100000); + + let g; + + before( async() => { + circuitEMulAny = await wasm_tester(path.join(__dirname, "circuits", "escalarmulany_test.circom")); + g = [ + Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"), + Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203") + ] + }); + + it("Should generate Same escalar mul", async () => { + + const w = await circuitEMulAny.calculateWitness({"e": 1, "p": g}); + + await circuitEMulAny.checkConstraints(w); + + await circuitEMulAny.assertOut(w, {out: g}, true); + + }); + + it("If multiply by order should return 0", async () => { + + const r = Fr.e("2736030358979909402780800718157159386076813972158567259200215660948447373041"); + const w = await circuitEMulAny.calculateWitness({"e": r, "p": g}); + + await circuitEMulAny.checkConstraints(w); + + await circuitEMulAny.assertOut(w, {out: [0,1]}, true); + + }); + +}); + diff --git a/circom/node_modules/circomlib/test/escalarmulfix.js b/circom/node_modules/circomlib/test/escalarmulfix.js new file mode 100644 index 0000000..ec4d8b6 --- /dev/null +++ b/circom/node_modules/circomlib/test/escalarmulfix.js @@ -0,0 +1,95 @@ +const chai = require("chai"); +const path = require("path"); +const wasm_tester = require("circom_tester").wasm; +const buildBabyjub = require("circomlibjs").buildBabyjub; +const Scalar = require("ffjavascript").Scalar; + +const assert = chai.assert; + +function print(circuit, w, s) { + console.log(s + ": " + w[circuit.getSignalIdx(s)]); +} + +describe("Escalarmul test", function () { + let babyJub; + let Fr; + let circuit; + + this.timeout(100000); + + + before( async() => { + babyJub = await buildBabyjub(); + Fr = babyJub.F; + circuit = await wasm_tester(path.join(__dirname, "circuits", "escalarmulfix_test.circom")); + }); + + it("Should generate Same escalar mul", async () => { + + const w = await circuit.calculateWitness({"e": 0}); + + await circuit.checkConstraints(w); + + await circuit.assertOut(w, {out: [0,1]}, true); + + }); + + it("Should generate Same escalar mul", async () => { + + const w = await circuit.calculateWitness({"e": 1}, true); + + await circuit.checkConstraints(w); + + await circuit.assertOut(w, {out: [Fr.toObject(babyJub.Base8[0]), Fr.toObject(babyJub.Base8[1])]}); + + }); + + it("Should generate scalar mul of a specific constant", async () => { + + const s = Scalar.e("2351960337287830298912035165133676222414898052661454064215017316447594616519"); + const base8 = [ + Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"), + Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203") + ]; + + const w = await circuit.calculateWitness({"e": s}, true); + + await circuit.checkConstraints(w); + + const expectedRes = babyJub.mulPointEscalar(base8, s); + + await circuit.assertOut(w, {out: [Fr.toObject(expectedRes[0]), Fr.toObject(expectedRes[1])]}); + + }); + + it("Should generate scalar mul of the firsts 50 elements", async () => { + + const base8 = [ + Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"), + Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203") + ]; + + for (let i=0; i<50; i++) { + const s = Scalar.e(i); + + const w = await circuit.calculateWitness({"e": s}, true); + + await circuit.checkConstraints(w); + + const expectedRes = babyJub.mulPointEscalar(base8, s); + + await circuit.assertOut(w, {out: [Fr.toObject(expectedRes[0]), Fr.toObject(expectedRes[1])]}); + } + }); + + it("If multiply by order should return 0", async () => { + + const w = await circuit.calculateWitness({"e": babyJub.subOrder }, true); + + await circuit.checkConstraints(w); + + await circuit.assertOut(w, {out: [0,1]}); + }); + +}); + diff --git a/circom/node_modules/circomlib/test/helpers/printsignal.js b/circom/node_modules/circomlib/test/helpers/printsignal.js new file mode 100644 index 0000000..796274d --- /dev/null +++ b/circom/node_modules/circomlib/test/helpers/printsignal.js @@ -0,0 +1,22 @@ + +const snarkjs = require("snarkjs"); + +const bigInt = snarkjs.bigInt; + +module.exports = function hexBits(cir, witness, sig, nBits) { + let v = bigInt(0); + for (let i=nBits-1; i>=0; i--) { + v = v.shiftLeft(1); + const name = sig+"["+i+"]"; + const idx = cir.getSignalIdx(name); + const vbit = bigInt(witness[idx].toString()); + if (vbit.equals(bigInt(1))) { + v = v.add(bigInt(1)); + } else if (vbit.equals(bigInt(0))) { + v; + } else { + console.log("Not Binary: "+name); + } + } + return v.toString(16); +}; diff --git a/circom/node_modules/circomlib/test/helpers/sha256.js b/circom/node_modules/circomlib/test/helpers/sha256.js new file mode 100644 index 0000000..ec58ee1 --- /dev/null +++ b/circom/node_modules/circomlib/test/helpers/sha256.js @@ -0,0 +1,178 @@ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +/* SHA-256 (FIPS 180-4) implementation in JavaScript (c) Chris Veness 2002-2017 */ +/* MIT Licence */ +/* www.movable-type.co.uk/scripts/sha256.html */ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +'use strict'; + + +/** + * SHA-256 hash function reference implementation. + * + * This is an annotated direct implementation of FIPS 180-4, without any optimisations. It is + * intended to aid understanding of the algorithm rather than for production use. + * + * While it could be used where performance is not critical, I would recommend using the ‘Web + * Cryptography API’ (developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest) for the browser, + * or the ‘crypto’ library (nodejs.org/api/crypto.html#crypto_class_hash) in Node.js. + * + * See csrc.nist.gov/groups/ST/toolkit/secure_hashing.html + * csrc.nist.gov/groups/ST/toolkit/examples.html + */ +class Sha256 { + + /** + * Generates SHA-256 hash of string. + * + * @param {string} msg - (Unicode) string to be hashed. + * @param {Object} [options] + * @param {string} [options.msgFormat=string] - Message format: 'string' for JavaScript string + * (gets converted to UTF-8 for hashing); 'hex-bytes' for string of hex bytes ('616263' ≡ 'abc') . + * @param {string} [options.outFormat=hex] - Output format: 'hex' for string of contiguous + * hex bytes; 'hex-w' for grouping hex bytes into groups of (4 byte / 8 character) words. + * @returns {string} Hash of msg as hex character string. + */ + static hash(msg, options) { + const defaults = { msgFormat: 'string', outFormat: 'hex' }; + const opt = Object.assign(defaults, options); + + // note use throughout this routine of 'n >>> 0' to coerce Number 'n' to unsigned 32-bit integer + + switch (opt.msgFormat) { + default: // default is to convert string to UTF-8, as SHA only deals with byte-streams + case 'string': msg = utf8Encode(msg); break; + case 'hex-bytes':msg = hexBytesToString(msg); break; // mostly for running tests + } + + // constants [§4.2.2] + const K = [ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 ]; + + // initial hash value [§5.3.3] + const H = [ + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ]; + + // PREPROCESSING [§6.2.1] + + msg += String.fromCharCode(0x80); // add trailing '1' bit (+ 0's padding) to string [§5.1.1] + + // convert string msg into 512-bit blocks (array of 16 32-bit integers) [§5.2.1] + const l = msg.length/4 + 2; // length (in 32-bit integers) of msg + ‘1’ + appended length + const N = Math.ceil(l/16); // number of 16-integer (512-bit) blocks required to hold 'l' ints + const M = new Array(N); // message M is N×16 array of 32-bit integers + + for (let i=0; i>> 32, but since JS converts + // bitwise-op args to 32 bits, we need to simulate this by arithmetic operators + const lenHi = ((msg.length-1)*8) / Math.pow(2, 32); + const lenLo = ((msg.length-1)*8) >>> 0; + M[N-1][14] = Math.floor(lenHi); + M[N-1][15] = lenLo; + + // HASH COMPUTATION [§6.2.2] + + for (let i=0; i>> 0; + } + + // 2 - initialise working variables a, b, c, d, e, f, g, h with previous hash value + let a = H[0], b = H[1], c = H[2], d = H[3], e = H[4], f = H[5], g = H[6], h = H[7]; + + // 3 - main loop (note '>>> 0' for 'addition modulo 2^32') + for (let t=0; t<64; t++) { + const T1 = h + Sha256.Σ1(e) + Sha256.Ch(e, f, g) + K[t] + W[t]; + const T2 = Sha256.Σ0(a) + Sha256.Maj(a, b, c); + h = g; + g = f; + f = e; + e = (d + T1) >>> 0; + d = c; + c = b; + b = a; + a = (T1 + T2) >>> 0; + } + + // 4 - compute the new intermediate hash value (note '>>> 0' for 'addition modulo 2^32') + H[0] = (H[0]+a) >>> 0; + H[1] = (H[1]+b) >>> 0; + H[2] = (H[2]+c) >>> 0; + H[3] = (H[3]+d) >>> 0; + H[4] = (H[4]+e) >>> 0; + H[5] = (H[5]+f) >>> 0; + H[6] = (H[6]+g) >>> 0; + H[7] = (H[7]+h) >>> 0; + } + + // convert H0..H7 to hex strings (with leading zeros) + for (let h=0; h prev + String.fromCharCode(curr), ''); + } catch (e) { // no TextEncoder available? + return unescape(encodeURIComponent(str)); // monsur.hossa.in/2012/07/20/utf-8-in-javascript.html + } + } + + function hexBytesToString(hexStr) { // convert string of hex numbers to a string of chars (eg '616263' -> 'abc'). + const str = hexStr.replace(' ', ''); // allow space-separated groups + return str=='' ? '' : str.match(/.{2}/g).map(byte => String.fromCharCode(parseInt(byte, 16))).join(''); + } + } + + + + /** + * Rotates right (circular right shift) value x by n positions [§3.2.4]. + * @private + */ + static ROTR(n, x) { + return (x >>> n) | (x << (32-n)); + } + + + /** + * Logical functions [§4.1.2]. + * @private + */ + static Σ0(x) { return Sha256.ROTR(2, x) ^ Sha256.ROTR(13, x) ^ Sha256.ROTR(22, x); } + static Σ1(x) { return Sha256.ROTR(6, x) ^ Sha256.ROTR(11, x) ^ Sha256.ROTR(25, x); } + static σ0(x) { return Sha256.ROTR(7, x) ^ Sha256.ROTR(18, x) ^ (x>>>3); } + static σ1(x) { return Sha256.ROTR(17, x) ^ Sha256.ROTR(19, x) ^ (x>>>10); } + static Ch(x, y, z) { return (x & y) ^ (~x & z); } // 'choice' + static Maj(x, y, z) { return (x & y) ^ (x & z) ^ (y & z); } // 'majority' + +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +if (typeof module != 'undefined' && module.exports) module.exports = Sha256; // ≡ export default Sha256 + diff --git a/circom/node_modules/circomlib/test/mimccircuit.js b/circom/node_modules/circomlib/test/mimccircuit.js new file mode 100644 index 0000000..ed40376 --- /dev/null +++ b/circom/node_modules/circomlib/test/mimccircuit.js @@ -0,0 +1,27 @@ +const chai = require("chai"); +const path = require("path"); +const wasm_tester = require("circom_tester").wasm; + +const buildMimc7 = require("circomlibjs").buildMimc7; + +describe("MiMC Circuit test", function () { + let circuit; + let mimc7; + + this.timeout(100000); + + before( async () => { + mimc7 = await buildMimc7(); + circuit = await wasm_tester(path.join(__dirname, "circuits", "mimc_test.circom")); + }); + + it("Should check constrain", async () => { + const w = await circuit.calculateWitness({x_in: 1, k: 2}, true); + + const res2 = mimc7.hash(1,2,91); + + await circuit.assertOut(w, {out: mimc7.F.toObject(res2)}); + + await circuit.checkConstraints(w); + }); +}); diff --git a/circom/node_modules/circomlib/test/mimcspongecircuit.js b/circom/node_modules/circomlib/test/mimcspongecircuit.js new file mode 100644 index 0000000..e3dbf63 --- /dev/null +++ b/circom/node_modules/circomlib/test/mimcspongecircuit.js @@ -0,0 +1,47 @@ +const path = require("path"); +const wasm_tester = require("circom_tester").wasm; + +const buildMimcSponge = require("circomlibjs").buildMimcSponge; + + +describe("MiMC Sponge Circuit test", function () { + let circuit; + let mimcSponge; + let F; + + this.timeout(100000); + + before( async () => { + mimcSponge = await buildMimcSponge(); + F = mimcSponge.F; + }); + + + it("Should check permutation", async () => { + + circuit = await wasm_tester(path.join(__dirname, "circuits", "mimc_sponge_test.circom")); + + const w = await circuit.calculateWitness({xL_in: 1, xR_in: 2, k: 3}); + + const out2 = mimcSponge.hash(1,2,3); + + await circuit.assertOut(w, {xL_out: F.toObject(out2.xL), xR_out: F.toObject(out2.xR)}); + + await circuit.checkConstraints(w); + + }); + + it("Should check hash", async () => { + circuit = await wasm_tester(path.join(__dirname, "circuits", "mimc_sponge_hash_test.circom")); + + const w = await circuit.calculateWitness({ins: [1, 2], k: 0}); + + const out2 = mimcSponge.multiHash([1,2], 0, 3); + + for (let i=0; i { + babyJub = await buildBabyjub(); + Fr = babyJub.F; + g = [ + Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"), + Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203") + ]; + + circuitE2M = await wasm_tester(path.join(__dirname, "circuits", "edwards2montgomery.circom")); + await circuitE2M.loadSymbols(); + circuitM2E = await wasm_tester(path.join(__dirname, "circuits", "montgomery2edwards.circom")); + await circuitM2E.loadSymbols(); + circuitMAdd = await wasm_tester(path.join(__dirname, "circuits", "montgomeryadd.circom")); + await circuitMAdd.loadSymbols(); + circuitMDouble = await wasm_tester(path.join(__dirname, "circuits", "montgomerydouble.circom")); + await circuitMDouble.loadSymbols(); + }); + + it("Convert Edwards to Montgomery and back again", async () => { + let w, xout, yout; + + w = await circuitE2M.calculateWitness({ in: [Fr.toObject(g[0]), Fr.toObject(g[1])]}, true); + + xout = w[circuitE2M.symbols["main.out[0]"].varIdx]; + yout = w[circuitE2M.symbols["main.out[1]"].varIdx]; + + mg = [xout, yout]; + + w = await circuitM2E.calculateWitness({ in: [xout, yout]}, true); + + xout = w[circuitM2E.symbols["main.out[0]"].varIdx]; + yout = w[circuitM2E.symbols["main.out[1]"].varIdx]; + + assert(Fr.eq(Fr.e(xout), g[0])); + assert(Fr.eq(Fr.e(yout), g[1])); + }); + it("Should double a point", async () => { + let w, xout, yout; + + g2 = babyJub.addPoint(g,g); + + w = await circuitMDouble.calculateWitness({ in: mg}, true); + + xout = w[circuitE2M.symbols["main.out[0]"].varIdx]; + yout = w[circuitE2M.symbols["main.out[1]"].varIdx]; + + mg2 = [xout, yout]; + + w = await circuitM2E.calculateWitness({ in: mg2}, true); + + xout = w[circuitM2E.symbols["main.out[0]"].varIdx]; + yout = w[circuitM2E.symbols["main.out[1]"].varIdx]; + + + assert(Fr.eq(Fr.e(xout), g2[0])); + assert(Fr.eq(Fr.e(yout), g2[1])); + }); + it("Should add a point", async () => { + let w, xout, yout; + + g3 = babyJub.addPoint(g,g2); + + w = await circuitMAdd.calculateWitness({ in1: mg, in2: mg2}, true); + + xout = w[circuitMAdd.symbols["main.out[0]"].varIdx]; + yout = w[circuitMAdd.symbols["main.out[1]"].varIdx]; + + mg3 = [xout, yout]; + + w = await circuitM2E.calculateWitness({ in: mg3}, true); + + xout = w[circuitM2E.symbols["main.out[0]"].varIdx]; + yout = w[circuitM2E.symbols["main.out[1]"].varIdx]; + + assert(Fr.eq(Fr.e(xout), g3[0])); + assert(Fr.eq(Fr.e(yout), g3[1])); + }); +}); diff --git a/circom/node_modules/circomlib/test/multiplexer.js b/circom/node_modules/circomlib/test/multiplexer.js new file mode 100644 index 0000000..945a872 --- /dev/null +++ b/circom/node_modules/circomlib/test/multiplexer.js @@ -0,0 +1,101 @@ +const path = require("path"); +const wasm_tester = require("circom_tester").wasm; +const F1Field = require("ffjavascript").F1Field; +const Scalar = require("ffjavascript").Scalar; +exports.p = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"); +const Fr = new F1Field(exports.p); + +describe("Mux4 test", function() { + this.timeout(100000); + it("Should create a constant multiplexer 4", async () => { + + const circuit = await wasm_tester(path.join(__dirname, "circuits", "mux4_1.circom")); + + const ct16 = [ + Fr.e("123"), + Fr.e("456"), + Fr.e("789"), + Fr.e("012"), + Fr.e("111"), + Fr.e("222"), + Fr.e("333"), + Fr.e("4546"), + Fr.e("134523"), + Fr.e("44356"), + Fr.e("15623"), + Fr.e("4566"), + Fr.e("1223"), + Fr.e("4546"), + Fr.e("4256"), + Fr.e("4456") + ]; + + for (let i=0; i<16; i++) { + const w = await circuit.calculateWitness({ "selector": i }, true); + + await circuit.checkConstraints(w); + + await circuit.assertOut(w, {out: ct16[i]}); + } + }); + + it("Should create a constant multiplexer 3", async () => { + + const circuit = await wasm_tester(path.join(__dirname, "circuits", "mux3_1.circom")); + + const ct8 = [ + Fr.e("37"), + Fr.e("47"), + Fr.e("53"), + Fr.e("71"), + Fr.e("89"), + Fr.e("107"), + Fr.e("163"), + Fr.e("191") + ]; + + for (let i=0; i<8; i++) { + const w = await circuit.calculateWitness({ "selector": i }, true); + + await circuit.checkConstraints(w); + + await circuit.assertOut(w, {out: ct8[i]}); + } + }); + it("Should create a constant multiplexer 2", async () => { + + const circuit = await wasm_tester(path.join(__dirname, "circuits", "mux2_1.circom")); + + const ct4 = [ + Fr.e("37"), + Fr.e("47"), + Fr.e("53"), + Fr.e("71"), + ]; + + for (let i=0; i<4; i++) { + const w = await circuit.calculateWitness({ "selector": i }, true); + + await circuit.checkConstraints(w); + + await circuit.assertOut(w, {out: ct4[i]}); + } + }); + it("Should create a constant multiplexer 1", async () => { + + const circuit = await wasm_tester(path.join(__dirname, "circuits", "mux1_1.circom")); + + const ct2 = [ + Fr.e("37"), + Fr.e("47"), + ]; + + for (let i=0; i<2; i++) { + const w = await circuit.calculateWitness({ "selector": i }, true); + + await circuit.checkConstraints(w); + + await circuit.assertOut(w, {out: ct2[i]}); + } + }); +}); diff --git a/circom/node_modules/circomlib/test/pedersen.js b/circom/node_modules/circomlib/test/pedersen.js new file mode 100644 index 0000000..62106f8 --- /dev/null +++ b/circom/node_modules/circomlib/test/pedersen.js @@ -0,0 +1,83 @@ +const chai = require("chai"); +const path = require("path"); + +const Scalar = require("ffjavascript").Scalar; + +const wasm_tester = require("circom_tester").wasm; + +const buildBabyjub = require("circomlibjs").buildBabyjub; + + +describe("Double Pedersen test", function() { + let babyJub; + let Fr; + let PBASE; + let circuit; + this.timeout(100000); + before( async() => { + babyJub = await buildBabyjub(); + Fr = babyJub.F; + PBASE = + [ + [Fr.e("10457101036533406547632367118273992217979173478358440826365724437999023779287"),Fr.e("19824078218392094440610104313265183977899662750282163392862422243483260492317")], + [Fr.e("2671756056509184035029146175565761955751135805354291559563293617232983272177"),Fr.e("2663205510731142763556352975002641716101654201788071096152948830924149045094")], + [Fr.e("5802099305472655231388284418920769829666717045250560929368476121199858275951"),Fr.e("5980429700218124965372158798884772646841287887664001482443826541541529227896")], + [Fr.e("7107336197374528537877327281242680114152313102022415488494307685842428166594"),Fr.e("2857869773864086953506483169737724679646433914307247183624878062391496185654")], + [Fr.e("20265828622013100949498132415626198973119240347465898028410217039057588424236"),Fr.e("1160461593266035632937973507065134938065359936056410650153315956301179689506")] + ]; + circuit = await wasm_tester(path.join(__dirname, "circuits", "pedersen_test.circom")); + + }); + + it("Should pedersen at zero", async () => { + + let w; + + w = await circuit.calculateWitness({ in: ["0", "0"]}, true); + + await circuit.assertOut(w, {out: [0,1]}); + + }); + it("Should pedersen at one first generator", async () => { + let w; + + w = await circuit.calculateWitness({ in: ["1", "0"]}, true); + + await circuit.assertOut(w, {out: [Fr.toObject(PBASE[0][0]), Fr.toObject(PBASE[0][1])]}); + + }); + it("Should pedersen at one second generator", async () => { + let w; + + w = await circuit.calculateWitness({ in: ["0", "1"]}, true); + + await circuit.assertOut(w, {out: [Fr.toObject(PBASE[1][0]), Fr.toObject(PBASE[1][1])]}); + + }); + it("Should pedersen at mixed generators", async () => { + let w; + w = await circuit.calculateWitness({ in: ["3", "7"]}, true); + + const r = babyJub.addPoint( + babyJub.mulPointEscalar(PBASE[0], 3), + babyJub.mulPointEscalar(PBASE[1], 7) + ); + + await circuit.assertOut(w, {out: [Fr.toObject(r[0]), Fr.toObject(r[1])]}); + + }); + it("Should pedersen all ones", async () => { + let w; + + const allOnes = Scalar.sub(Scalar.shl(Scalar.e(1), 250), Scalar.e(1)); + w = await circuit.calculateWitness({ in: [allOnes, allOnes]}, true); + + + const r2 = babyJub.addPoint( + babyJub.mulPointEscalar(PBASE[0], allOnes), + babyJub.mulPointEscalar(PBASE[1], allOnes) + ); + + await circuit.assertOut(w, {out: [Fr.toObject(r2[0]), Fr.toObject(r2[1])]}); + }); +}); diff --git a/circom/node_modules/circomlib/test/pedersen2.js b/circom/node_modules/circomlib/test/pedersen2.js new file mode 100644 index 0000000..bde1531 --- /dev/null +++ b/circom/node_modules/circomlib/test/pedersen2.js @@ -0,0 +1,56 @@ +const path = require("path"); + +const Scalar = require("ffjavascript").Scalar; + +const buildPedersenHash = require("circomlibjs").buildPedersenHash; +const buildBabyJub = require("circomlibjs").buildBabyjub; + +const wasm_tester = require("circom_tester").wasm; + + +describe("Pedersen test", function() { + let babyJub + let pedersen; + let F; + let circuit; + this.timeout(100000); + before( async() => { + + babyJub = await buildBabyJub(); + F = babyJub.F; + pedersen = await buildPedersenHash(); + circuit = await wasm_tester(path.join(__dirname, "circuits", "pedersen2_test.circom")); + }); + it("Should pedersen at zero", async () => { + + let w; + + w = await circuit.calculateWitness({ in: 0}, true); + + const b = Buffer.alloc(32); + + const h = pedersen.hash(b); + const hP = babyJub.unpackPoint(h); + + await circuit.assertOut(w, {out: [F.toObject(hP[0]), F.toObject(hP[1])] }); + + }); + it("Should pedersen with 253 ones", async () => { + + let w; + + const n = F.e(Scalar.sub(Scalar.shl(Scalar.e(1), 253), Scalar.e(1))); + + w = await circuit.calculateWitness({ in: F.toObject(n)}, true); + + const b = Buffer.alloc(32); + for (let i=0; i<31; i++) b[i] = 0xFF; + b[31] = 0x1F; + + const h = pedersen.hash(b); + const hP = babyJub.unpackPoint(h); + + await circuit.assertOut(w, {out: [F.toObject(hP[0]), F.toObject(hP[1])] }); + + }); +}); diff --git a/circom/node_modules/circomlib/test/point2bits.js b/circom/node_modules/circomlib/test/point2bits.js new file mode 100644 index 0000000..98af516 --- /dev/null +++ b/circom/node_modules/circomlib/test/point2bits.js @@ -0,0 +1,30 @@ +const path = require("path"); +const wasm_tester = require("circom_tester").wasm; +const buildBabyJub = require("circomlibjs").buildBabyjub; + +const babyJub = require("circomlibjs").babyjub; + + +describe("Point 2 bits test", function() { + let babyJub; + let F; + let circuit; + this.timeout(100000); + before( async() => { + babyJub = await buildBabyJub(); + F = babyJub.F; + + circuit = await wasm_tester(path.join(__dirname, "circuits", "pointbits_loopback.circom")); + }); + + it("Should do the both convertions for 8Base", async () => { + const w = await circuit.calculateWitness({ in: [F.toObject(babyJub.Base8[0]), F.toObject(babyJub.Base8[1])]}, true); + + await circuit.checkConstraints(w); + }); + it("Should do the both convertions for Zero point", async () => { + const w = await circuit.calculateWitness({ in: [0, 1]}, true); + + await circuit.checkConstraints(w); + }); +}); diff --git a/circom/node_modules/circomlib/test/poseidoncircuit.js b/circom/node_modules/circomlib/test/poseidoncircuit.js new file mode 100644 index 0000000..86e14d7 --- /dev/null +++ b/circom/node_modules/circomlib/test/poseidoncircuit.js @@ -0,0 +1,80 @@ +const chai = require("chai"); +const path = require("path"); +const wasm_tester = require("circom_tester").wasm; + +const buildPoseidon = require("circomlibjs").buildPoseidon; + +const assert = chai.assert; + +describe("Poseidon Circuit test", function () { + let poseidon; + let F; + let circuit6; + let circuit3; + let circuitEx; + + this.timeout(1000000); + + before( async () => { + poseidon = await buildPoseidon(); + F = poseidon.F; + circuit6 = await wasm_tester(path.join(__dirname, "circuits", "poseidon6_test.circom")); + circuit3 = await wasm_tester(path.join(__dirname, "circuits", "poseidon3_test.circom")); + circuitEx = await wasm_tester(path.join(__dirname, "circuits", "poseidonex_test.circom")); + }); + + it("Should check constrain of hash([1, 2]) t=6", async () => { + const w = await circuit6.calculateWitness({inputs: [1, 2, 0,0,0]}, true); + + const res2 = poseidon([1,2,0,0,0]); + + assert(F.eq(F.e("1018317224307729531995786483840663576608797660851238720571059489595066344487"), F.e(res2))); + await circuit6.assertOut(w, {out : F.toObject(res2)}); + await circuit6.checkConstraints(w); + }); + + it("Should check constrain of hash([3, 4]) t=6", async () => { + const w = await circuit6.calculateWitness({inputs: [3, 4,5,10,23]}); + + const res2 = poseidon([3, 4,5,10,23]); + + assert(F.eq(F.e("13034429309846638789535561449942021891039729847501137143363028890275222221409"), F.e(res2))); + await circuit6.assertOut(w, {out : F.toObject(res2)}); + await circuit6.checkConstraints(w); + }); + + + it("Should check constrain of hash([1, 2]) t=3", async () => { + const w = await circuit3.calculateWitness({inputs: [1, 2]}); + + const res2 = poseidon([1,2]); + + assert(F.eq(F.e("7853200120776062878684798364095072458815029376092732009249414926327459813530"), F.e(res2))); + await circuit3.assertOut(w, {out : F.toObject(res2)}); + await circuit3.checkConstraints(w); + }); + + it("Should check constrain of hash([3, 4]) t=3", async () => { + const w = await circuit3.calculateWitness({inputs: [3, 4]}); + + const res2 = poseidon([3, 4]); + + assert(F.eq(F.e("14763215145315200506921711489642608356394854266165572616578112107564877678998"), F.e(res2))); + await circuit3.assertOut(w, {out : F.toObject(res2)}); + await circuit3.checkConstraints(w); + }); + + it("Should check constrain of hash with state and 16 ins and outs", async () => { + const ins = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] + const w = await circuitEx.calculateWitness({inputs: ins, initialState: 17}); + + const res2 = poseidon(ins, 17, 17); + const res2f = []; + for (let i=0; i> (7-j) &1)); + } + } + return res; +} + +function bitArray2buffer(a) { + const len = Math.floor((a.length -1 )/8)+1; + const b = new Buffer.alloc(len); + + for (let i=0; i { + const b = new Buffer.alloc(64); + for (let i=0; i<64; i++) { + b[i] = i+1; + } + const a = buffer2bitArray(b); + const b2 = bitArray2buffer(a); + + assert.equal(b.toString("hex"), b2.toString("hex"), true); + }); + + it("Should calculate a hash of 1 compressor", async () => { + const cir = await wasm_tester(path.join(__dirname, "circuits", "sha256_2_test.circom")); + + const witness = await cir.calculateWitness({ "a": "1", "b": "2" }, true); + + const b = new Buffer.alloc(54); + b[26] = 1; + b[53] = 2; + + const hash = crypto.createHash("sha256") + .update(b) + .digest("hex"); + const r = "0x" + hash.slice(10); + + const hash2 = sha256.hash(b.toString("hex"), {msgFormat: "hex-bytes"}); + + assert.equal(hash, hash2); + + assert(Fr.eq(witness[1], Fr.e(r))); + }).timeout(1000000); + + it("Should calculate a hash of 2 compressor", async () => { + const cir = await wasm_tester(path.join(__dirname, "circuits", "sha256_test512.circom")); + + const b = new Buffer.alloc(64); + for (let i=0; i<64; i++) { + b[i] = i+1; + } + + const hash = crypto.createHash("sha256") + .update(b) + .digest("hex"); + + const arrIn = buffer2bitArray(b); + const witness = await cir.calculateWitness({ "in": arrIn }, true); + + const arrOut = witness.slice(1, 257); + const hash2 = bitArray2buffer(arrOut).toString("hex"); + + assert.equal(hash, hash2); + + }).timeout(1000000); + it ("Should calculate a hash of 2 compressor", async () => { + const cir = await wasm_tester(path.join(__dirname, "circuits", "sha256_test448.circom")); + + const testStr = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; + + const b = Buffer.from(testStr, "utf8"); + + const hash = crypto.createHash("sha256") + .update(b) + .digest("hex"); + + const arrIn = buffer2bitArray(b); + + const witness = await cir.calculateWitness({ "in": arrIn }, true); + + const arrOut = witness.slice(1, 257); + const hash2 = bitArray2buffer(arrOut).toString("hex"); + + assert.equal(hash, hash2); + }); + +}); diff --git a/circom/node_modules/circomlib/test/sign.js b/circom/node_modules/circomlib/test/sign.js new file mode 100644 index 0000000..05c9c6a --- /dev/null +++ b/circom/node_modules/circomlib/test/sign.js @@ -0,0 +1,82 @@ +const path = require("path"); +const F1Field = require("ffjavascript").F1Field; +const Scalar = require("ffjavascript").Scalar; +exports.p = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"); +const Fr = new F1Field(exports.p); +const wasm_tester = require("circom_tester").wasm; + +function print(circuit, w, s) { + console.log(s + ": " + w[circuit.getSignalIdx(s)]); +} + +function getBits(v, n) { + const res = []; + for (let i=0; i { + circuit = await wasm_tester(path.join(__dirname, "circuits", "sign_test.circom")); + }); + + it("Sign of 0", async () => { + const inp = getBits(Scalar.e(0), 254); + const w = await circuit.calculateWitness({in: inp}, true); + + await circuit.assertOut(w, {sign: 0}); + }); + + it("Sign of 3", async () => { + const inp = getBits(Scalar.e(3), 254); + const w = await circuit.calculateWitness({in: inp}, true); + + await circuit.assertOut(w, {sign: 0}); + }); + + it("Sign of q/2", async () => { + const inp = getBits(Scalar.shr(q, 1), 254); + const w = await circuit.calculateWitness({in: inp}, true); + + await circuit.assertOut(w, {sign: 0}); + }); + + it("Sign of q/2+1", async () => { + const inp = getBits(Scalar.add(Scalar.shr(q, 1), 1) , 254); + const w = await circuit.calculateWitness({in: inp}, true); + + await circuit.assertOut(w, {sign: 1}); + }); + + it("Sign of q-1", async () => { + const inp = getBits(Scalar.sub(q, 1), 254); + const w = await circuit.calculateWitness({in: inp}, true); + + await circuit.assertOut(w, {sign: 1}); + }); + + it("Sign of q", async () => { + const inp = getBits(q, 254); + const w = await circuit.calculateWitness({in: inp}, true); + + await circuit.assertOut(w, {sign: 1}); + }); + + it("Sign of all ones", async () => { + const inp = getBits(Scalar.sub(Scalar.shl(1,254),1), 254); + const w = await circuit.calculateWitness({in: inp}, true); + + await circuit.assertOut(w, {sign: 1}); + }); +}); diff --git a/circom/node_modules/circomlib/test/smtprocessor.js b/circom/node_modules/circomlib/test/smtprocessor.js new file mode 100644 index 0000000..1935b9e --- /dev/null +++ b/circom/node_modules/circomlib/test/smtprocessor.js @@ -0,0 +1,219 @@ +const chai = require("chai"); +const path = require("path"); +const wasm_tester = require("circom_tester").wasm; +const F1Field = require("ffjavascript").F1Field; +const Scalar = require("ffjavascript").Scalar; + +const newMemEmptyTrie = require("circomlibjs").newMemEmptyTrie; + +const assert = chai.assert; + +function print(circuit, w, s) { + console.log(s + ": " + w[circuit.getSignalIdx(s)]); +} + +async function testInsert(tree, _key, _value, circuit ) { + const key = tree.F.e(_key); + const value = tree.F.e(_value) + + const res = await tree.insert(key,value); + let siblings = res.siblings; + for (let i=0; i { + circuit = await wasm_tester(path.join(__dirname, "circuits", "smtprocessor10_test.circom")); + await circuit.loadSymbols(); + + tree = await newMemEmptyTrie(); + Fr = tree.F; + }); + + it("Should verify an insert to an empty tree", async () => { + const key = Fr.e(111); + const value = Fr.e(222); + + await testInsert(tree, key, value, circuit); + }); + + it("It should add another element", async () => { + const key = Fr.e(333); + const value = Fr.e(444); + + await testInsert(tree, key, value, circuit); + }); + + it("Should remove an element", async () => { + await testDelete(tree, 111, circuit); + await testDelete(tree, 333, circuit); + }); + + it("Should test convination of adding and removing 3 elements", async () => { + const keys = [Fr.e(8), Fr.e(9), Fr.e(32)]; + const values = [Fr.e(88), Fr.e(99), Fr.e(3232)]; + const tree1 = await newMemEmptyTrie(); + const tree2 = await newMemEmptyTrie(); + const tree3 = await newMemEmptyTrie(); + const tree4 = await newMemEmptyTrie(); + const tree5 = await newMemEmptyTrie(); + const tree6 = await newMemEmptyTrie(); + + await testInsert(tree1,keys[0],values[0], circuit); + await testInsert(tree1,keys[1],values[1], circuit); + await testInsert(tree1,keys[2],values[2], circuit); + + await testInsert(tree2,keys[0],values[0], circuit); + await testInsert(tree2,keys[2],values[2], circuit); + await testInsert(tree2,keys[1],values[1], circuit); + + await testInsert(tree3,keys[1],values[1], circuit); + await testInsert(tree3,keys[0],values[0], circuit); + await testInsert(tree3,keys[2],values[2], circuit); + + await testInsert(tree4,keys[1],values[1], circuit); + await testInsert(tree4,keys[2],values[2], circuit); + await testInsert(tree4,keys[0],values[0], circuit); + + await testInsert(tree5,keys[2],values[2], circuit); + await testInsert(tree5,keys[0],values[0], circuit); + await testInsert(tree5,keys[1],values[1], circuit); + + await testInsert(tree6,keys[2],values[2], circuit); + await testInsert(tree6,keys[1],values[1], circuit); + await testInsert(tree6,keys[0],values[0], circuit); + + + await testDelete(tree1, keys[0], circuit); + await testDelete(tree1, keys[1], circuit); + await testDelete(tree2, keys[1], circuit); + await testDelete(tree2, keys[0], circuit); + + await testDelete(tree3, keys[0], circuit); + await testDelete(tree3, keys[2], circuit); + await testDelete(tree4, keys[2], circuit); + await testDelete(tree4, keys[0], circuit); + + + await testDelete(tree5, keys[1], circuit); + await testDelete(tree5, keys[2], circuit); + await testDelete(tree6, keys[2], circuit); + await testDelete(tree6, keys[1], circuit); + + await testDelete(tree1, keys[2], circuit); + await testDelete(tree2, keys[2], circuit); + await testDelete(tree3, keys[1], circuit); + await testDelete(tree4, keys[1], circuit); + await testDelete(tree5, keys[0], circuit); + await testDelete(tree6, keys[0], circuit); + }); + + it("Should match a NOp with random vals", async () => { + let siblings = []; + while (siblings.length<10) siblings.push(88); + const w = await circuit.calculateWitness({ + fnc: [0,0], + oldRoot: 11, + siblings: siblings, + oldKey: 33, + oldValue: 44, + isOld0: 55, + newKey: 66, + newValue: 77 + }); + + const root1 = Fr.e(w[circuit.symbols["main.oldRoot"].varIdx]); + const root2 = Fr.e(w[circuit.symbols["main.newRoot"].varIdx]); + + await circuit.checkConstraints(w); + + assert(Fr.eq(root1, root2)); + }); + it("Should update an element", async () => { + const tree1 = await newMemEmptyTrie(); + const tree2 = await newMemEmptyTrie(); + + await testInsert(tree1,8,88, circuit); + await testInsert(tree1,9,99, circuit); + await testInsert(tree1,32,3232, circuit); + + await testInsert(tree2,8,888, circuit); + await testInsert(tree2,9,999, circuit); + await testInsert(tree2,32,323232, circuit); + + await testUpdate(tree1, 8, 888, circuit); + await testUpdate(tree1, 9, 999, circuit); + await testUpdate(tree1, 32, 323232, circuit); + }); +}); diff --git a/circom/node_modules/circomlib/test/smtverifier.js b/circom/node_modules/circomlib/test/smtverifier.js new file mode 100644 index 0000000..78528f0 --- /dev/null +++ b/circom/node_modules/circomlib/test/smtverifier.js @@ -0,0 +1,141 @@ +const chai = require("chai"); +const path = require("path"); +const Scalar = require("ffjavascript").Scalar; +const wasm_tester = require("circom_tester").wasm; + +const newMemEmptyTrie = require("circomlibjs").newMemEmptyTrie; + +const assert = chai.assert; + +function print(circuit, w, s) { + console.log(s + ": " + w[circuit.getSignalIdx(s)]); +} + +async function testInclusion(tree, _key, circuit) { + const key = tree.F.e(_key); + const res = await tree.find(key); + + assert(res.found); + let siblings = res.siblings; + for (let i=0; i { + circuit = await wasm_tester(path.join(__dirname, "circuits", "smtverifier10_test.circom")); + + tree = await newMemEmptyTrie(); + Fr = tree.F; + await tree.insert(7,77); + await tree.insert(8,88); + await tree.insert(32,3232); + }); + + it("Check inclussion in a tree of 3", async () => { + await testInclusion(tree, 7, circuit); + await testInclusion(tree, 8, circuit); + await testInclusion(tree, 32, circuit); + }); + + it("Check exclussion in a tree of 3", async () => { + await testExclusion(tree, 0, circuit); + await testExclusion(tree, 6, circuit); + await testExclusion(tree, 9, circuit); + await testExclusion(tree, 33, circuit); + await testExclusion(tree, 31, circuit); + await testExclusion(tree, 16, circuit); + await testExclusion(tree, 64, circuit); + }); + + it("Check not enabled accepts any thing", async () => { + let siblings = []; + for (let i=0; i<10; i++) siblings.push(i); + + const w = await circuit.calculateWitness({ + enabled: 0, + fnc: 0, + root: 1, + siblings: siblings, + oldKey: 22, + oldValue: 33, + isOld0: 0, + key: 44, + value: 0 + }); + + + await circuit.checkConstraints(w); + }); + + it("Check inclussion Adria case", async () => { + const e1_hi= Fr.e("17124152697573569611556136390143205198134245887034837071647643529178599000839"); + const e1_hv= Fr.e("19650379996168153643111744440707177573540245771926102415571667548153444658179"); + + const e2ok_hi= Fr.e("16498254692537945203721083102154618658340563351558973077349594629411025251262"); + const e2ok_hv= Fr.e("19650379996168153643111744440707177573540245771926102415571667548153444658179"); + + const e2fail_hi= Fr.e("17195092312975762537892237130737365903429674363577646686847513978084990105579"); + const e2fail_hv= Fr.e("19650379996168153643111744440707177573540245771926102415571667548153444658179"); + + const tree1 = await newMemEmptyTrie(); + await tree1.insert(e1_hi,e1_hv); + await tree1.insert(e2ok_hi,e2ok_hv); + + await testInclusion(tree1, e2ok_hi, circuit); + + const tree2 = await newMemEmptyTrie(); + await tree2.insert(e1_hi,e1_hv); + await tree2.insert(e2fail_hi,e2fail_hv); + + await testInclusion(tree2, e2fail_hi, circuit); + }); + + +}); diff --git a/circom/package.json b/circom/package.json new file mode 100644 index 0000000..3f1d084 --- /dev/null +++ b/circom/package.json @@ -0,0 +1,9 @@ +{ + "name": "circuits", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "dependencies": { + "circomlib": "^2.0.5" + } +} diff --git a/circom/templates/chaff.circom b/circom/templates/chaff.circom new file mode 100644 index 0000000..216e3d1 --- /dev/null +++ b/circom/templates/chaff.circom @@ -0,0 +1,50 @@ +pragma circom 2.1.6; + +include "../node_modules/circomlib/circuits/mux1.circom"; +include "../node_modules/circomlib/circuits/comparators.circom"; + +// multiplexes signals according to whether this is a chaff step or not +template ChaffMux() { + // inputs from step_in + signal input degrees_of_separation; + signal input given_phrase_hash; + signal input given_degree_secret_hash; + signal input is_chaff_step; + // computed inputs from circuit + signal input computed_phrase_hash; + signal input computed_degree_secret_hash; + // output formatted for step_out + signal output out[4]; + + // constrain is_chaff_step to be 0 or 1 + is_chaff_step * (is_chaff_step - 1) === 0; + + // mux 3 different inputs selected by is_chaff_step + component mux = MultiMux1(3); + mux.s <== is_chaff_step; + + // mux the degree of separation + // if ! chaff step, increment degree of separation + mux.c[0][0] <== degrees_of_separation + 1; + mux.c[0][1] <== degrees_of_separation; + + // mux the secret hash + // if ! chaff step, grab muxed hash output + mux.c[1][0] <== computed_phrase_hash; + mux.c[1][1] <== given_phrase_hash; + + // mux the username hash + // if ! chaff step, grab the computed current username hash + mux.c[2][0] <== computed_degree_secret_hash; + mux.c[2][1] <== given_degree_secret_hash; + + // flip chaff step + component flipped_chaff_step = IsZero(); + flipped_chaff_step.in <== is_chaff_step; + + // set step output + out[0] <== mux.out[0]; + out[1] <== mux.out[1]; + out[2] <== mux.out[2]; + out[3] <== flipped_chaff_step.out; +} \ No newline at end of file diff --git a/circom/yarn.lock b/circom/yarn.lock new file mode 100644 index 0000000..fef776b --- /dev/null +++ b/circom/yarn.lock @@ -0,0 +1,8 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +circomlib@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/circomlib/-/circomlib-2.0.5.tgz#183c703e53ed7d011811842dbeeeb9819f4cc1d6" + integrity sha512-O7NQ8OS+J4eshBuoy36z/TwQU0YHw8W3zxZcs4hVwpEll3e4hDm3mgkIPqItN8FDeLEKZFK3YeT/+k8TiLF3/A== diff --git a/src/circom.rs b/src/circom.rs new file mode 100644 index 0000000..e5b7b87 --- /dev/null +++ b/src/circom.rs @@ -0,0 +1,409 @@ +use ark_circom::circom::CircomCircuit; +use ark_ff::PrimeField; +use ark_r1cs_std::{alloc::AllocVar, fields::fp::FpVar, R1CSVar}; +use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError}; +use ark_std::fmt::Debug; +use num_bigint::BigInt; +use sonobe::{frontend::FCircuit, Error as SonobeError}; +use std::path::PathBuf; + +use crate::errors::GrapevineError; +use crate::utils::wrapper::{CircomPrivateInput, CircomWrapper}; + +// Define Circom FCircuit +#[derive(Clone, Debug)] +pub struct GrapevineFCircuit { + circom_wrapper: CircomWrapper, + private_input: CircomPrivateInput, +} + +impl GrapevineFCircuit { + pub fn set_private_input(&mut self, input: CircomPrivateInput) { + self.private_input = input; + } +} + +impl FCircuit for GrapevineFCircuit { + type Params = (PathBuf, PathBuf); + + fn new(params: Self::Params) -> Self { + let (r1cs_path, wasm_path) = params; + let circom_wrapper = CircomWrapper::new(r1cs_path, wasm_path); + Self { + circom_wrapper, + private_input: CircomPrivateInput::empty(false), + } + } + + fn state_len(&self) -> usize { + 4 + } + + fn step_native(&self, _i: usize, z_i: Vec) -> Result, SonobeError> { + // convert ivc_input from ark ff to BigInt + let ivc_input = z_i + .iter() + .map(|val| CircomWrapper::ark_primefield_to_num_bigint(*val)) + .collect::>(); + let mut inputs = vec![("ivc_input".to_string(), ivc_input)]; + + // set the private inputs + if self.private_input.uninitialized() { + return Err(SonobeError::Other("Private input not set".to_string())); + } + let private_input = CircomWrapper::::marshal_private_inputs(&self.private_input); + inputs.extend(private_input); + + // calculate witness + let witness = self.circom_wrapper.extract_witness(&inputs).map_err(|e| { + SonobeError::WitnessCalculationError(format!("Failed to calculate witness: {}", e)) + })?; + + // extract the z_i1 (next state) from witvec + let z_i1 = witness[1..1 + self.state_len()].to_vec(); + Ok(z_i1) + } + + fn generate_step_constraints( + &self, + cs: ConstraintSystemRef, + _i: usize, + z_i: Vec>, + ) -> Result>, SynthesisError> { + // convert ivc input from FpVar to ark ff to BigInt + let ivc_input: Vec = z_i + .iter() + .map(|val| CircomWrapper::ark_primefield_to_num_bigint(val.value().unwrap())) + .collect(); + let mut inputs = vec![("ivc_input".to_string(), ivc_input)]; + + // set the private inputs + if self.private_input.uninitialized() { + return Err(SynthesisError::AssignmentMissing); + } + let private_input = CircomWrapper::::marshal_private_inputs(&self.private_input); + inputs.extend(private_input); + + println!("Inputs: {:?}", inputs); + + // extract r1cs and witness + let (r1cs, witness) = self + .circom_wrapper + .extract_r1cs_and_witness(&inputs) + .map_err(|_| SynthesisError::AssignmentMissing)?; + + println!("Wire map len: {:?}", r1cs.clone().wire_mapping.unwrap().len()); + println!("Constraints len: {:?}", r1cs.clone().constraints.len()); + println!("Witness len: {:?}", witness.clone().unwrap().len()); + + // Initialize CircomCircuit + let circom_circuit = CircomCircuit { + r1cs, + witness: witness.clone(), + inputs_already_computed: false, + }; + + circom_circuit + .generate_constraints(cs.clone()) + .map_err(|_| SynthesisError::Unsatisfiable)?; + + if !cs.is_satisfied().unwrap() { + return Err(SynthesisError::Unsatisfiable); + }; + + let w = witness.ok_or(SynthesisError::Unsatisfiable)?; + + let z_i1: Vec> = + Vec::>::new_witness(cs.clone(), || Ok(w[1..1 + self.state_len()].to_vec()))?; + + Ok(z_i1) + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::params::test_nova_setup; + use crate::utils::{ + inputs::{get_z0, random_f_bigint}, + wrapper::CircomPrivateInput, + }; + use ark_pallas::{constraints::GVar, Fr, Projective}; + use ark_r1cs_std::alloc::AllocVar; + use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystem}; + use ark_vesta::{constraints::GVar as GVar2, Projective as Projective2}; + use lazy_static::lazy_static; + use num_bigint::BigInt; + use sonobe::{ + commitment::pedersen::Pedersen, folding::nova::Nova, + transcript::poseidon::poseidon_test_config, Error, FoldingScheme, + }; + use std::env::current_dir; + use std::time::Instant; + + lazy_static! { + pub static ref R1CS_PATH: PathBuf = PathBuf::from("./circom/artifacts/grapevine.r1cs"); + pub static ref WASM_PATH: PathBuf = PathBuf::from("./circom/artifacts/grapevine.wasm"); + pub static ref PHRASE: String = String::from("This is a secret"); + pub static ref USERNAMES: [String; 5] = [ + String::from("alice"), + String::from("bob"), + String::from("charlie"), + String::from("david"), + String::from("eve") + ]; + pub static ref AUTH_SECRETS: [BigInt; 5] = (0..5) + .map(|_| random_f_bigint::()) + .collect::>() + .try_into() + .unwrap(); + } + + #[test] + fn test_step_native() { + // define inputs + let step_0_inputs = CircomPrivateInput { + phrase: Some(String::from(&*PHRASE)), + usernames: [None, Some(String::from(&*USERNAMES[0]))], + auth_secrets: [None, Some(AUTH_SECRETS[0].clone())], + chaff: false, + }; + let z_0 = get_z0(); + + // initialize new Grapevine function circuit + let mut f_circuit = GrapevineFCircuit::::new((R1CS_PATH.clone(), WASM_PATH.clone())); + f_circuit.set_private_input(step_0_inputs); + + let z_1 = f_circuit.step_native(0, z_0.to_vec()).unwrap(); + println!("z_1: {:?}", z_1); + } + + #[test] + fn test_step_constraints() { + // initialize new Grapevine function circuit + let mut f_circuit = GrapevineFCircuit::::new((R1CS_PATH.clone(), WASM_PATH.clone())); + + // define inputs + let step_0_inputs = CircomPrivateInput { + phrase: Some(String::from(&*PHRASE)), + usernames: [None, Some(String::from(&*USERNAMES[0]))], + auth_secrets: [None, Some(AUTH_SECRETS[0].clone())], + chaff: false, + }; + f_circuit.set_private_input(step_0_inputs); + + // assign z0 + let cs = ConstraintSystem::::new_ref(); + let z_0_var = Vec::>::new_witness(cs.clone(), || Ok(get_z0())).unwrap(); + + // compute constraints for step 0 + let cs = ConstraintSystem::::new_ref(); + let z_1_var = f_circuit + .generate_step_constraints(cs.clone(), 1, z_0_var) + .unwrap(); + println!("z_1: {:?}", z_1_var); + + // assert_eq!(z_i1_var.value().unwrap(), vec![Fr::from(38), Fr::from(1)]); + } + + #[test] + fn test_multiple_steps_native() { + // initialize new Grapevine function circuit + let mut f_circuit = GrapevineFCircuit::::new((R1CS_PATH.clone(), WASM_PATH.clone())); + + /* DEGREE 1 */ + // define degree 1 logic inputs + let inputs = CircomPrivateInput { + phrase: Some(String::from(&*PHRASE)), + usernames: [None, Some(String::from(&*USERNAMES[0]))], + auth_secrets: [None, Some(AUTH_SECRETS[0].clone())], + chaff: false, + }; + f_circuit.set_private_input(inputs); + + // compute step 0 (degree 1 logic step) + let z_i = f_circuit.step_native(0, get_z0().to_vec()).unwrap(); + + // define degree 1 chaff inputs + let inputs = CircomPrivateInput::empty(true); + f_circuit.set_private_input(inputs); + + // compute step 1 (degree 1 chaff step) + let z_i = f_circuit.step_native(1, z_i.to_vec()).unwrap(); + println!("z_i: {:?}", z_i); + + /* DEGREE 2 */ + // define degree 2 logic inputs + let inputs = CircomPrivateInput { + phrase: None, + usernames: [ + Some(String::from(&*USERNAMES[0])), + Some(String::from(&*USERNAMES[1])), + ], + auth_secrets: [Some(AUTH_SECRETS[0].clone()), Some(AUTH_SECRETS[1].clone())], + chaff: false, + }; + f_circuit.set_private_input(inputs); + + // compute step 2 (degree 2 logic step) + let z_i = f_circuit.step_native(2, z_i.to_vec()).unwrap(); + + // define degree 2 chaff inputs + let inputs = CircomPrivateInput::empty(true); + f_circuit.set_private_input(inputs); + + // compute step 3 (degree 2 chaff step) + let z_i = f_circuit.step_native(3, z_i.to_vec()).unwrap(); + + /* DEGREE 3 */ + // define degree 3 logic inputs + let inputs = CircomPrivateInput { + phrase: None, + usernames: [ + Some(String::from(&*USERNAMES[1])), + Some(String::from(&*USERNAMES[2])), + ], + auth_secrets: [Some(AUTH_SECRETS[1].clone()), Some(AUTH_SECRETS[2].clone())], + chaff: false, + }; + f_circuit.set_private_input(inputs); + + // compute step 4 (degree 3 logic step) + let z_i = f_circuit.step_native(4, z_i.to_vec()).unwrap(); + + // define degree 3 chaff inputs + let inputs = CircomPrivateInput::empty(true); + f_circuit.set_private_input(inputs); + + // compute step 5 (degree 3 chaff step) + let z_i = f_circuit.step_native(5, z_i.to_vec()).unwrap(); + + /* RESULT */ + // @todo: compute hashes natively + assert_eq!(z_i[0], Fr::from(3)); + assert_eq!(z_i[3], Fr::from(0)); + } + + // #[test] + // fn test_multiple_steps_constraints() { + // // initialize new Grapevine function circuit + // let mut f_circuit = GrapevineFCircuit::::new((R1CS_PATH.clone(), WASM_PATH.clone())); + // + // /* DEGREE 1 */ + // // define degree 1 logic inputs + // let inputs = CircomPrivateInput { + // phrase: Some(String::from(&*PHRASE)), + // usernames: [None, Some(String::from(&*USERNAMES[0]))], + // auth_secrets: [None, Some(AUTH_SECRETS[0].clone())], + // chaff: false + // }; + // f_circuit.set_private_input(inputs); + // + // // assign z0 + // let cs = ConstraintSystem::::new_ref(); + // let z_0_var = Vec::>::new_witness(cs.clone(), || Ok(get_z0())).unwrap(); + // + // // compute constraints for step 0 (degree 1 logic step) + // let cs = ConstraintSystem::::new_ref(); + // let z_1_var = f_circuit + // .generate_step_constraints(cs.clone(), 0, z_0_var) + // .unwrap(); + // println!("z_1: {:?}", z_1_var); + // + // // define degree 1 chaff inputs + // let inputs = CircomPrivateInput::empty(true); + // f_circuit.set_private_input(inputs); + // + // // compute step 1 (degree 1 chaff step) + // let z_i = f_circuit.step_native(1, z_i.to_vec()).unwrap(); + // println!("z_i: {:?}", z_i); + // + // // define inputs + // let step_0_inputs = CircomPrivateInput { + // phrase: Some(String::from(&*PHRASE)), + // usernames: [None, Some(String::from(&*USERNAMES[0]))], + // auth_secrets: [None, Some(AUTH_SECRETS[0].clone())], + // chaff: false + // }; + // + // // initialize new Grapevine function circuit + // let mut f_circuit = GrapevineFCircuit::::new((R1CS_PATH.clone(), WASM_PATH.clone())); + // f_circuit.set_private_input(step_0_inputs); + // + // } + + #[test] + fn test_full_one_step() { + // initialize new Grapevine function circuit + let mut f_circuit = GrapevineFCircuit::::new((R1CS_PATH.clone(), WASM_PATH.clone())); + + // Get test params + let (prover_params, verifier_params) = + test_nova_setup::>(f_circuit.clone()); + + + // define inputs + // define inputs + let step_0_inputs = CircomPrivateInput { + phrase: Some(String::from(&*PHRASE)), + usernames: [None, Some(String::from(&*USERNAMES[0]))], + auth_secrets: [None, Some(AUTH_SECRETS[0].clone())], + chaff: false, + }; + // let z_0 = get_z0(); + } + + #[test] + fn test_full() { + let num_steps = 10; + let initial_state = vec![Fr::from(19), Fr::from(0)]; + + let r1cs_path = PathBuf::from("./circom/artifacts/grapevine.r1cs"); + let wasm_path = PathBuf::from("./circom/artifacts/grapevine.wasm"); + + let f_circuit = GrapevineFCircuit::::new((r1cs_path, wasm_path)); + + let start = Instant::now(); + println!("Generating params..."); + let (prover_params, verifier_params) = + test_nova_setup::>(f_circuit.clone()); + println!("Generated params: {:?}", start.elapsed()); + type NOVA = Nova< + Projective, + GVar, + Projective2, + GVar2, + GrapevineFCircuit, + Pedersen, + Pedersen, + >; + + let start = Instant::now(); + println!("Initializing folding scheme..."); + let mut folding_scheme = + NOVA::init(&prover_params, f_circuit, initial_state.clone()).unwrap(); + println!("Initialized folding scheme: {:?}", start.elapsed()); + + for i in 0..num_steps { + let start = Instant::now(); + folding_scheme.prove_step().unwrap(); + println!("Proved step {}: {:?}", i, start.elapsed()); + } + + let (running_instance, incoming_instance, cyclefold_instance) = folding_scheme.instances(); + + println!("Running IVC Verifier..."); + let start = Instant::now(); + NOVA::verify( + verifier_params, + initial_state.clone(), + folding_scheme.state(), + Fr::from(num_steps as u32), + running_instance, + incoming_instance, + cyclefold_instance, + ) + .unwrap(); + println!("Verified: {:?}", start.elapsed()); + } +} diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 0000000..a2f6ec1 --- /dev/null +++ b/src/errors.rs @@ -0,0 +1,16 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum GrapevineError { + InputsEmpty, +} + +impl std::fmt::Display for GrapevineError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + GrapevineError::InputsEmpty => write!(f, "No private input provided to F circuit!") + } + } +} + +impl std::error::Error for GrapevineError {} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..11654f4 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,5 @@ +pub mod circom; +pub mod nova; +pub mod params; +pub mod utils; +pub mod errors; diff --git a/src/nova.rs b/src/nova.rs new file mode 100644 index 0000000..906a961 --- /dev/null +++ b/src/nova.rs @@ -0,0 +1,46 @@ +use ark_crypto_primitives::{ + crh::{ + poseidon::constraints::{CRHGadget, CRHParametersVar}, + poseidon::CRH, + CRHScheme, CRHSchemeGadget, + }, + sponge::{poseidon::PoseidonConfig, Absorb}, +}; +use ark_ff::PrimeField; +use ark_pallas::{constraints::GVar, Fr, Projective}; +use ark_r1cs_std::{alloc::AllocVar, fields::FieldVar, fields::fp::FpVar}; +use ark_relations::r1cs::{ConstraintSystemRef, SynthesisError}; +use ark_std::Zero; +use ark_vesta::{constraints::GVar as Gvar2, Projective as Projective2}; +use core::marker::PhantomData; +use std::time::Instant; +use sonobe::{ + commitment::{pedersen::Pedersen, CommitmentScheme}, + folding::nova::{get_r1cs, ProverParams, VerifierParams}, + frontend::FCircuit, + transcript::poseidon::poseidon_test_config +}; + +use crate::{ + params::test_nova_setup, + circom::GrapevineFCircuit, +}; + +#[cfg(test)] +mod test { + use super::*; + use std::path::PathBuf; + use std::time::Instant; + #[test] + fn test_generate_params() { + let r1cs_path = PathBuf::from("./circom/artifacts/circuit.r1cs"); + let wasm_path = PathBuf::from("./circom/artifacts/circuit.wasm"); + let f_circuit = GrapevineFCircuit::::new((r1cs_path, wasm_path)); + let pre = Instant::now(); + let (prover_params, verifier_params) = test_nova_setup::>(f_circuit); + // let prover_params_str = serde_json::to_string(&prover_params).unwrap(); + // let verifier_params_str = serde_json::to_string(&verifier_params).unwrap(); + + println!("Time to generate params: {:?}", pre.elapsed()); + } +} diff --git a/src/params.rs b/src/params.rs new file mode 100644 index 0000000..f98cc65 --- /dev/null +++ b/src/params.rs @@ -0,0 +1,45 @@ +use ark_pallas::{constraints::GVar, Fr, Projective}; +use ark_vesta::{constraints::GVar as GVar2, Projective as Projective2}; + +use sonobe::{ + commitment::{pedersen::Pedersen, CommitmentScheme}, + folding::nova::{get_r1cs, ProverParams, VerifierParams}, + frontend::FCircuit, + transcript::poseidon::poseidon_test_config +}; + +pub fn test_nova_setup>( + f_circuit: FC +) -> ( + ProverParams, Pedersen>, + VerifierParams +) { + let mut rng = ark_std::test_rng(); + let poseidon_config = poseidon_test_config::(); + + // get CM & CF_CM len + let (r1cs, cf_r1cs) = get_r1cs::( + &poseidon_config, + f_circuit, + ).unwrap(); + let cf_len = r1cs.A.n_rows; + let cf_cf_len = cf_r1cs.A.n_rows; + + let (pedersen_params, _) = Pedersen::::setup(&mut rng, cf_len).unwrap(); + let (cf_pedersen_params, _) = Pedersen::::setup(&mut rng, cf_cf_len).unwrap(); + + let prover_params = + ProverParams::, Pedersen>{ + poseidon_config: poseidon_config.clone(), + cs_params: pedersen_params, + cf_cs_params: cf_pedersen_params + }; + + let verifier_params = VerifierParams::{ + poseidon_config: poseidon_config.clone(), + r1cs, + cf_r1cs + }; + + (prover_params, verifier_params) +} \ No newline at end of file diff --git a/src/utils/inputs.rs b/src/utils/inputs.rs new file mode 100644 index 0000000..18ebea2 --- /dev/null +++ b/src/utils/inputs.rs @@ -0,0 +1,71 @@ +use ark_ff::{PrimeField, BigInteger}; +use ark_pallas::Fr; +use ark_std::rand::rngs::OsRng; +use std::error::Error; +use num_bigint::{BigInt, Sign::Plus, RandBigInt}; + +use super::{MAX_SECRET_LENGTH, MAX_USERNAME_LENGTH, SECRET_FIELD_LENGTH}; + +/** Get the starting ivc inputs (z0) for the grapevine circuit */ +pub fn get_z0() -> [F; 4] { + (0..4).map(|_| F::zero()).collect::>().try_into().unwrap() +} + +/** Generates a random field element for given field as bigint */ +pub fn random_f_bigint() -> BigInt { + let lower_bound = BigInt::from(0); + let upper_bound = BigInt::from_bytes_be(Plus, &F::MODULUS.to_bytes_be()); + OsRng.gen_bigint_range(&lower_bound, &upper_bound) +} + +/** + * Converts a given word to array of 6 field elements + * @dev split into 31-byte strings to fit in finite field and pad with 0's where necessary + * + * @param phrase - the string entered by user to compute hash for (will be length checked) + * @return - array of 6 Fr elements + */ +pub fn serialize_phrase( + phrase: &String, +) -> Result<[BigInt; SECRET_FIELD_LENGTH], Box> { + // check length + if phrase.len() > MAX_SECRET_LENGTH { + return Err("Phrase must be <= 180 characters".into()); + } + // convert each 31-byte chunk to field element + let mut chunks: [BigInt; SECRET_FIELD_LENGTH] = Default::default(); + for i in 0..SECRET_FIELD_LENGTH { + // get the range + let start = i * 31; + let end = (i + 1) * 31; + let mut chunk: [u8; 32] = [0; 32]; + // select slice from range and pad if needed + if start >= phrase.len() { + } else if end > phrase.len() { + chunk[1..(phrase.len() - start + 1)].copy_from_slice(&phrase.as_bytes()[start..]); + } else { + chunk[1..32].copy_from_slice(&phrase.as_bytes()[start..end]); + } + // wrap in field element + chunks[i] = BigInt::from_bytes_be(Plus, &chunk); + } + Ok(chunks) +} + +/** +* Converts a given username to a field element +* +* @param username - the username to convert to utf8 and into field element +* @return - the username serialied into the field element +*/ +pub fn serialize_username(username: &String) -> Result> { + // check length + if username.len() > MAX_USERNAME_LENGTH { + return Err("Username must be <= 30 characters".into()); + } + // convert to big endian bytes + let mut bytes: [u8; 32] = [0; 32]; + bytes[1..(username.len() + 1)].copy_from_slice(&username.as_bytes()[..]); + // convert to bigint + Ok(BigInt::from_bytes_be(Plus, &bytes)) +} diff --git a/src/utils/mod.rs b/src/utils/mod.rs new file mode 100644 index 0000000..3d235b1 --- /dev/null +++ b/src/utils/mod.rs @@ -0,0 +1,15 @@ +use ark_pallas::Fr; +use ark_ff::UniformRand; +use ark_std::rand::rngs::OsRng; + +pub mod wrapper; +pub mod inputs; + +pub const SECRET_FIELD_LENGTH: usize = 6; +pub const MAX_SECRET_LENGTH: usize = 180; +pub const MAX_USERNAME_LENGTH: usize = 30; + +/** Get a random field element */ +pub fn random_fr() -> ark_pallas::Fr { + Fr::rand(&mut OsRng) +} \ No newline at end of file diff --git a/src/utils/wrapper.rs b/src/utils/wrapper.rs new file mode 100644 index 0000000..e1f3149 --- /dev/null +++ b/src/utils/wrapper.rs @@ -0,0 +1,177 @@ +use crate::utils::inputs::{random_f_bigint, serialize_phrase, serialize_username}; +use ark_circom::{ + circom::{r1cs_reader, R1CS}, + WitnessCalculator, +}; +use ark_ff::{BigInteger, PrimeField}; +use color_eyre::Result; +use num_bigint::{BigInt, Sign}; +use sonobe::Error as SonobeError; +use std::{fs::File, io::BufReader, marker::PhantomData, path::PathBuf}; + +#[derive(Clone, Debug)] +pub struct CircomPrivateInput { + pub phrase: Option, + pub usernames: [Option; 2], + pub auth_secrets: [Option; 2], + pub chaff: bool, +} + +impl CircomPrivateInput { + + /** + * Creates empty inputs + * + * @param chaff - if true, should compute random vars for chaff in circuit + */ + pub fn empty(chaff: bool) -> Self { + Self { + phrase: None, + usernames: [None, None], + auth_secrets: [None, None], + chaff, + } + } + + pub fn uninitialized(&self) -> bool { + let not_chaff =self.phrase.is_none() + && self.usernames.iter().all(|u| u.is_none()) + && self.auth_secrets.iter().all(|a| a.is_none()); + not_chaff && !self.chaff + } +} + +// Wrapper for circom functionalities (extract R1CS and witness) +#[derive(Clone, Debug)] +pub struct CircomWrapper { + r1cs_path: PathBuf, + wc_path: PathBuf, + _marker: PhantomData, +} + +impl CircomWrapper { + // creates a new instance of the wrapper with filepaths + pub fn new(r1cs_path: PathBuf, wc_path: PathBuf) -> Self { + Self { + r1cs_path, + wc_path, + _marker: PhantomData, + } + } + + /** + * Marshals the private inputs into the format expected by circom + * + * @param inputs - the private inputs + * @return - the marshalled inputs + */ + pub fn marshal_private_inputs(inputs: &CircomPrivateInput) -> [(String, Vec); 3] { + // handle phrase presence (if not present infer chaff) + let phrase = match &inputs.phrase { + Some(phrase) => serialize_phrase(&phrase).unwrap().to_vec(), + None => (0..6) + .map(|_| random_f_bigint::()) + .collect::>(), + }; + + // determine inputs: first step ([0] = None), Nth step ([1] = Some), and chaff ([2] = None) + // marshal usernames + let usernames = match inputs.usernames[0] { + Some(_) => inputs + .usernames + .iter() + .map(|u| serialize_username(&u.clone().unwrap()).unwrap()) + .collect::>(), + None => match &inputs.usernames[1] { + Some(username) => vec![BigInt::from(0), serialize_username(&username).unwrap()], + None => vec![random_f_bigint::(), random_f_bigint::()], + }, + }; + + // marshal auth secrets + let auth_sec = match inputs.auth_secrets[0] { + Some(_) => inputs + .auth_secrets + .iter() + .map(|a| a.clone().unwrap()) + .collect::>(), + None => match &inputs.auth_secrets[1] { + Some(auth_secret) => vec![BigInt::from(0), auth_secret.clone()], + None => vec![random_f_bigint::(), random_f_bigint::()], + }, + }; + + // label the inputs for circom + [ + ("phrase".to_string(), phrase), + ("usernames".to_string(), usernames), + ("auth_secrets".to_string(), auth_sec), + ] + } + + // aggregated function to obtain r1cs and witness from circom + pub fn extract_r1cs_and_witness( + &self, + inputs: &[(String, Vec)], + ) -> Result<(R1CS, Option>), SonobeError> { + // extract R1CS + let file = File::open(&self.r1cs_path)?; + let reader = BufReader::new(file); + let r1cs_file = r1cs_reader::R1CSFile::::new(reader)?; + let r1cs = r1cs_reader::R1CS::::from(r1cs_file); + + // extract witness vector + let witness_vec = self.extract_witness(inputs)?; + + Ok((r1cs, Some(witness_vec))) + } + + pub fn extract_witness(&self, inputs: &[(String, Vec)]) -> Result, SonobeError> { + let witness_bigint = self.calculate_witness(inputs)?; + witness_bigint + .iter() + .map(|bigint| { + Self::num_bigint_to_ark_bigint(bigint) + .and_then(|ark_bigint| { + F::from_bigint(ark_bigint).ok_or_else(|| { + SonobeError::Other("Could not get F from bigint".to_string()) + }) + }) + }) + .collect() + } + + pub fn calculate_witness( + &self, + inputs: &[(String, Vec)], + ) -> Result, SonobeError> { + let mut calculator = WitnessCalculator::new(&self.wc_path).map_err(|e| { + SonobeError::WitnessCalculationError(format!( + "Failed to create WitnessCalculator: {}", + e + )) + })?; + calculator + .calculate_witness(inputs.iter().cloned(), true) + .map_err(|e| { + SonobeError::WitnessCalculationError(format!("Failed to calculate witness: {}", e)) + }) + } + + pub fn num_bigint_to_ark_bigint(value: &BigInt) -> Result { + let big_uint = value + .to_biguint() + .ok_or_else(|| SonobeError::BigIntConversionError("BigInt is negative".to_string()))?; + F::BigInt::try_from(big_uint).map_err(|_| { + SonobeError::BigIntConversionError( + "Failed to convert to Primefield::BigInt".to_string(), + ) + }) + } + + pub fn ark_primefield_to_num_bigint(value: F) -> BigInt { + let primefield_bigint: F::BigInt = value.into_bigint(); + let bytes = primefield_bigint.to_bytes_be(); + BigInt::from_bytes_be(Sign::Plus, &bytes) + } +}