diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 663e03b0..7edf9de9 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -11,7 +11,6 @@ env: jobs: build: - runs-on: ubuntu-latest steps: diff --git a/Cargo.lock b/Cargo.lock index 2085a230..338e9661 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "aes" version = "0.7.5" @@ -38,13 +44,39 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.20" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" dependencies = [ "memchr", ] +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" + +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "colored", + "num-traits", + "rand", +] + [[package]] name = "arrayref" version = "0.3.7" @@ -65,14 +97,25 @@ checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.13", + "syn 2.0.15", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", ] [[package]] name = "auto_impl" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a8c1df849285fbacd587de7818cc7d13be6cd2cbcd47a04fb1801b0e2706e33" +checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" dependencies = [ "proc-macro-error", "proc-macro2", @@ -141,6 +184,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitvec" version = "0.17.4" @@ -292,9 +341,9 @@ checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" [[package]] name = "bumpalo" -version = "3.12.0" +version = "3.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +checksum = "3c6ed94e98ecff0c12dd1b04c15ec0d7d9458ca8fe806cea6f12954efe74c63b" [[package]] name = "byte-slice-cast" @@ -336,6 +385,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "bytemuck" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" + [[package]] name = "byteorder" version = "1.4.3" @@ -351,6 +406,12 @@ dependencies = [ "serde", ] +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + [[package]] name = "cfg-if" version = "1.0.0" @@ -363,8 +424,13 @@ version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" dependencies = [ + "iana-time-zone", + "js-sys", "num-integer", "num-traits", + "time", + "wasm-bindgen", + "winapi", ] [[package]] @@ -377,14 +443,22 @@ dependencies = [ ] [[package]] -name = "circuits-halo2" -version = "0.1.0" +name = "cmake" +version = "0.1.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" dependencies = [ - "eth-types", - "gadgets", - "halo2_gadgets", - "halo2_proofs", - "merkle-sum-tree-rust", + "cc", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", ] [[package]] @@ -440,10 +514,33 @@ dependencies = [ "serde", "serde_derive", "sha2 0.10.6", - "sha3 0.10.6", + "sha3 0.10.8", "thiserror", ] +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "colored" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" +dependencies = [ + "atty", + "lazy_static", + "winapi", +] + +[[package]] +name = "const-cstr" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3d0b5ff30645a68f35ece8cea4556ca14ef8a1651455f789a099a0513532a6" + [[package]] name = "const-oid" version = "0.9.2" @@ -462,20 +559,82 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb4a24b1aaf0fd0ce8b45161144d6f42cd91677fd5940fd431183eb023b3a2b8" +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "core-graphics" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" +dependencies = [ + "bitflags", + "core-foundation", + "foreign-types", + "libc", +] + +[[package]] +name = "core-text" +version = "19.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d74ada66e07c1cefa18f8abfba765b486f250de2e4a999e5727fc0dd4b4a25" +dependencies = [ + "core-foundation", + "core-graphics", + "foreign-types", + "libc", +] + [[package]] name = "cpufeatures" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-channel" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" dependencies = [ "cfg-if", "crossbeam-utils", @@ -582,14 +741,82 @@ dependencies = [ "cipher", ] +[[package]] +name = "cxx" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn 2.0.15", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "darling" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +dependencies = [ + "darling_core 0.10.2", + "darling_macro 0.10.2", +] + [[package]] name = "darling" version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.13.4", + "darling_macro 0.13.4", +] + +[[package]] +name = "darling_core" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.9.3", + "syn 1.0.109", ] [[package]] @@ -602,7 +829,18 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +dependencies = [ + "darling_core 0.10.2", + "quote", "syn 1.0.109", ] @@ -612,7 +850,7 @@ version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ - "darling_core", + "darling_core 0.13.4", "quote", "syn 1.0.109", ] @@ -627,6 +865,31 @@ dependencies = [ "zeroize", ] +[[package]] +name = "derive_builder" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2658621297f2cf68762a6f7dc0bb7e1ff2cfd6583daef8ee0fed6f7ec468ec0" +dependencies = [ + "darling 0.10.2", + "derive_builder_core", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder_core" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2791ea3e372c8495c0bc2033991d76b512cd799d07491fbd6890124db9458bef" +dependencies = [ + "darling 0.10.2", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "digest" version = "0.7.6" @@ -665,6 +928,48 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dlib" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794" +dependencies = [ + "libloading", +] + +[[package]] +name = "dwrote" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439a1c2ba5611ad3ed731280541d36d2e9c4ac5e7fb818a27b604bdc5a6aa65b" +dependencies = [ + "lazy_static", + "libc", + "winapi", + "wio", +] + [[package]] name = "ecdsa" version = "0.14.8" @@ -693,9 +998,9 @@ dependencies = [ "crypto-bigint", "der", "digest 0.10.6", - "ff", + "ff 0.12.1", "generic-array 0.14.7", - "group", + "group 0.12.1", "pkcs8", "rand_core", "sec1", @@ -720,7 +1025,7 @@ dependencies = [ "serde", "serde_json", "sha2 0.10.6", - "sha3 0.10.6", + "sha3 0.10.8", "thiserror", "uuid", ] @@ -728,7 +1033,7 @@ dependencies = [ [[package]] name = "eth-types" version = "0.1.0" -source = "git+https://github.com/privacy-scaling-explorations/zkevm-circuits#d4b4b81c8b57afcde8f24adee2abcef1cd10cbad" +source = "git+https://github.com/privacy-scaling-explorations/zkevm-circuits#b8ae7af639af035a6ad5081716012ee2ea48e7cb" dependencies = [ "ethers-core", "ethers-signers", @@ -743,7 +1048,7 @@ dependencies = [ "serde", "serde_json", "serde_with", - "sha3 0.10.6", + "sha3 0.10.8", "strum", "strum_macros", "subtle", @@ -762,7 +1067,7 @@ dependencies = [ "regex", "serde", "serde_json", - "sha3 0.10.6", + "sha3 0.10.8", "thiserror", "uint", ] @@ -873,11 +1178,30 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "fdeflate" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" +dependencies = [ + "simd-adler32", +] + [[package]] name = "ff" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "bitvec 1.0.1", "rand_core", @@ -896,12 +1220,89 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "flate2" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "float-ord" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bad48618fdb549078c333a7a8528acb57af271d0433bdecd523eb620628364e" + [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "font-kit" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21fe28504d371085fae9ac7a3450f0b289ab71e07c8e57baa3fb68b9e57d6ce5" +dependencies = [ + "bitflags", + "byteorder", + "core-foundation", + "core-graphics", + "core-text", + "dirs-next", + "dwrote", + "float-ord", + "freetype", + "lazy_static", + "libc", + "log", + "pathfinder_geometry", + "pathfinder_simd", + "walkdir", + "winapi", + "yeslogic-fontconfig-sys", +] + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "freetype" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee38378a9e3db1cc693b4f88d166ae375338a0ff75cb8263e1c601d51f35dc6" +dependencies = [ + "freetype-sys", + "libc", +] + +[[package]] +name = "freetype-sys" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a" +dependencies = [ + "cmake", + "libc", + "pkg-config", +] + [[package]] name = "funty" version = "2.0.0" @@ -911,7 +1312,7 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "gadgets" version = "0.1.0" -source = "git+https://github.com/privacy-scaling-explorations/zkevm-circuits#d4b4b81c8b57afcde8f24adee2abcef1cd10cbad" +source = "git+https://github.com/privacy-scaling-explorations/zkevm-circuits#b8ae7af639af035a6ad5081716012ee2ea48e7cb" dependencies = [ "digest 0.7.6", "eth-types", @@ -950,51 +1351,60 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", ] +[[package]] +name = "gif" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06" +dependencies = [ + "color_quant", + "weezl", +] + [[package]] name = "group" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ - "ff", + "ff 0.12.1", "rand_core", "subtle", ] [[package]] -name = "halo2-experiments" -version = "0.1.0" -source = "git+https://github.com/summa-dev/halo2-experiments?branch=merkle-sum-tree#6986429861b2d9abc1357ebe10189b782a9f53f0" +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "eth-types", - "gadgets", - "halo2_gadgets", - "halo2_proofs", - "rand", + "ff 0.13.0", + "rand_core", + "subtle", ] [[package]] name = "halo2_gadgets" version = "0.2.0" -source = "git+https://github.com/privacy-scaling-explorations/halo2?tag=v2023_02_02#0a8646b78286a13d320759b1c585262d6536dce4" +source = "git+https://github.com/privacy-scaling-explorations/halo2?tag=v2023_04_20#be955686f86eb618f55d2320c0e042485b313d22" dependencies = [ "arrayvec", "bitvec 1.0.1", - "ff", - "group", + "ff 0.13.0", + "group 0.13.0", "halo2_proofs", - "halo2curves 0.2.1", + "halo2curves", "lazy_static", "rand", "subtle", @@ -1004,46 +1414,33 @@ dependencies = [ [[package]] name = "halo2_proofs" version = "0.2.0" -source = "git+https://github.com/privacy-scaling-explorations/halo2?tag=v2023_02_02#0a8646b78286a13d320759b1c585262d6536dce4" +source = "git+https://github.com/privacy-scaling-explorations/halo2?tag=v2023_04_20#be955686f86eb618f55d2320c0e042485b313d22" dependencies = [ "blake2b_simd", - "ff", - "group", - "halo2curves 0.3.1", + "ff 0.13.0", + "group 0.13.0", + "halo2curves", + "plotters", + "rand_chacha", "rand_core", "rayon", "sha3 0.9.1", + "tabbycat", "tracing", ] [[package]] name = "halo2curves" -version = "0.2.1" -source = "git+https://github.com/privacy-scaling-explorations/halo2curves?tag=0.3.0#83c72d49762343ffc9576ca11a2aa615efe1029b" -dependencies = [ - "ff", - "group", - "lazy_static", - "num-bigint", - "num-traits", - "pasta_curves", - "rand", - "rand_core", - "static_assertions", - "subtle", -] - -[[package]] -name = "halo2curves" -version = "0.3.1" -source = "git+https://github.com/privacy-scaling-explorations/halo2curves.git?tag=0.3.1#9b67e19bca30a35208b0c1b41c1723771e2c9f49" +version = "0.3.2" +source = "git+https://github.com/privacy-scaling-explorations/halo2curves?tag=0.3.2#9f5c50810bbefe779ee5cf1d852b2fe85dc35d5e" dependencies = [ - "ff", - "group", + "ff 0.13.0", + "group 0.13.0", "lazy_static", "num-bigint", "num-traits", "pasta_curves", + "paste", "rand", "rand_core", "static_assertions", @@ -1074,6 +1471,15 @@ 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 = "hermit-abi" version = "0.2.6" @@ -1119,12 +1525,51 @@ dependencies = [ "hmac 0.8.1", ] +[[package]] +name = "iana-time-zone" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + [[package]] name = "ident_case" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "image" +version = "0.24.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527909aa81e20ac3a44803521443a765550f09b5130c2c2fa1ea59c2f8f50a3a" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "jpeg-decoder", + "num-rational", + "num-traits", + "png", +] + [[package]] name = "impl-codec" version = "0.6.0" @@ -1188,11 +1633,17 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +[[package]] +name = "jpeg-decoder" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" + [[package]] name = "js-sys" -version = "0.3.61" +version = "0.3.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +checksum = "68c16e1bfd491478ab155fd8b4896b86f9ede344949b641e61501e07c2b8b4d5" dependencies = [ "wasm-bindgen", ] @@ -1207,14 +1658,14 @@ dependencies = [ "ecdsa", "elliptic-curve", "sha2 0.10.6", - "sha3 0.10.6", + "sha3 0.10.8", ] [[package]] name = "keccak" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" dependencies = [ "cpufeatures", ] @@ -1224,12 +1675,25 @@ name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin", +] [[package]] name = "libc" -version = "0.2.141" +version = "0.2.144" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" + +[[package]] +name = "libloading" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] [[package]] name = "libsecp256k1" @@ -1279,6 +1743,15 @@ dependencies = [ "libsecp256k1-core", ] +[[package]] +name = "link-cplusplus" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" +dependencies = [ + "cc", +] + [[package]] name = "log" version = "0.4.17" @@ -1304,16 +1777,13 @@ dependencies = [ ] [[package]] -name = "merkle-sum-tree-rust" -version = "0.1.0" -source = "git+https://github.com/summa-dev/merkle-sum-tree-rust#8aeb7d7f30d1c6aac4d3809c4b482baeef0c05d3" +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ - "csv", - "halo2-experiments", - "halo2_gadgets", - "halo2_proofs", - "hex", - "serde", + "adler", + "simd-adler32", ] [[package]] @@ -1398,7 +1868,7 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] @@ -1422,9 +1892,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "parity-scale-codec" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637935964ff85a605d114591d4d2c13c5d1ba2806dae97cea6bf180238a749ac" +checksum = "5ddb756ca205bd108aee3c62c6d3c994e1df84a59b9d6d4a5ea42ee1fd5a9a28" dependencies = [ "arrayvec", "bitvec 1.0.1", @@ -1470,19 +1940,44 @@ dependencies = [ [[package]] name = "pasta_curves" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc65faf8e7313b4b1fbaa9f7ca917a0eed499a9663be71477f87993604341d8" +checksum = "d3e57598f73cc7e1b2ac63c79c517b31a0877cd7c402cdcaa311b5208de7a095" dependencies = [ "blake2b_simd", - "ff", - "group", + "ff 0.13.0", + "group 0.13.0", "lazy_static", "rand", "static_assertions", "subtle", ] +[[package]] +name = "paste" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" + +[[package]] +name = "pathfinder_geometry" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b7e7b4ea703700ce73ebf128e1450eb69c3a8329199ffbfb9b2a0418e5ad3" +dependencies = [ + "log", + "pathfinder_simd", +] + +[[package]] +name = "pathfinder_simd" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39fe46acc5503595e5949c17b818714d26fdf9b4920eacf3b2947f0199f4a6ff" +dependencies = [ + "rustc_version", +] + [[package]] name = "pbkdf2" version = "0.10.1" @@ -1504,6 +1999,16 @@ dependencies = [ "sha2 0.10.6", ] +[[package]] +name = "pest" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e68e84bfb01f0507134eac1e9b410a12ba379d064eab48c50ba4ce329a527b70" +dependencies = [ + "thiserror", + "ucd-trie", +] + [[package]] name = "pin-project-lite" version = "0.2.9" @@ -1520,6 +2025,71 @@ dependencies = [ "spki", ] +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "plotters" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" +dependencies = [ + "chrono", + "font-kit", + "image", + "lazy_static", + "num-traits", + "pathfinder_geometry", + "plotters-backend", + "plotters-bitmap", + "plotters-svg", + "ttf-parser", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" + +[[package]] +name = "plotters-bitmap" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4a1f21490a6cf4a84c272ad20bd7844ed99a3178187a4c5ab7f2051295beef" +dependencies = [ + "gif", + "image", + "plotters-backend", +] + +[[package]] +name = "plotters-svg" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "png" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaeebc51f9e7d2c150d3f3bfeb667f2aa985db5ef1e3d212847bdedb488beeaa" +dependencies = [ + "bitflags", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1613,9 +2183,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" dependencies = [ "proc-macro2", ] @@ -1684,11 +2254,31 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall", + "thiserror", +] + [[package]] name = "regex" -version = "1.7.3" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ "aho-corasick", "memchr", @@ -1697,9 +2287,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.29" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" [[package]] name = "rend" @@ -1800,6 +2390,15 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver", +] + [[package]] name = "rustversion" version = "1.0.12" @@ -1821,12 +2420,27 @@ dependencies = [ "cipher", ] +[[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 = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "scratch" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" + [[package]] name = "scrypt" version = "0.8.1" @@ -1860,31 +2474,49 @@ dependencies = [ "zeroize", ] +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + [[package]] name = "serde" -version = "1.0.159" +version = "1.0.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" +checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.159" +version = "1.0.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" +checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.13", + "syn 2.0.15", ] [[package]] name = "serde_json" -version = "1.0.95" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ "itoa", "ryu", @@ -1907,7 +2539,7 @@ version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" dependencies = [ - "darling", + "darling 0.13.4", "proc-macro2", "quote", "syn 1.0.109", @@ -1975,9 +2607,9 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ "digest 0.10.6", "keccak", @@ -1993,12 +2625,24 @@ dependencies = [ "rand_core", ] +[[package]] +name = "simd-adler32" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f" + [[package]] name = "simdutf8" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "spki" version = "0.6.0" @@ -2015,6 +2659,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strsim" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" + [[package]] name = "strsim" version = "0.10.0" @@ -2049,6 +2699,23 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +[[package]] +name = "summa-solvency" +version = "0.1.0" +dependencies = [ + "ark-std", + "csv", + "gadgets", + "halo2_gadgets", + "halo2_proofs", + "hex", + "num-bigint", + "plotters", + "rand", + "serde", + "tabbycat", +] + [[package]] name = "syn" version = "1.0.109" @@ -2062,21 +2729,41 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.13" +version = "2.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "tabbycat" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c45590f0f859197b4545be1b17b2bc3cc7bb075f7d1cc0ea1dc6521c0bf256a3" +dependencies = [ + "anyhow", + "derive_builder", + "regex", +] + [[package]] name = "tap" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + [[package]] name = "thiserror" version = "1.0.40" @@ -2094,7 +2781,18 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.13", + "syn 2.0.15", +] + +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", ] [[package]] @@ -2146,13 +2844,13 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.15", ] [[package]] @@ -2164,12 +2862,24 @@ dependencies = [ "once_cell", ] +[[package]] +name = "ttf-parser" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b3e06c9b9d80ed6b745c7159c40b311ad2916abb34a49e9be2653b90db0d8dd" + [[package]] name = "typenum" version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +[[package]] +name = "ucd-trie" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" + [[package]] name = "uint" version = "0.9.5" @@ -2188,6 +2898,12 @@ version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + [[package]] name = "unicode-xid" version = "0.2.4" @@ -2210,6 +2926,22 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -2218,9 +2950,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +checksum = "5b6cb788c4e39112fbe1822277ef6fb3c55cd86b95cb3d3c4c1c9597e4ac74b4" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2228,24 +2960,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +checksum = "35e522ed4105a9d626d885b35d62501b30d9666283a5c8be12c14a8bdafe7822" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.15", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +checksum = "358a79a0cb89d21db8120cbfb91392335913e4890665b1a7981d9e956903b434" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2253,32 +2985,154 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +checksum = "4783ce29f09b9d93134d41297aded3a712b7b979e9c6f28c32cb88c973a94869" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.15", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.84" +version = "0.2.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a901d592cafaa4d711bc324edfaff879ac700b19c3dfd60058d2b445be2691eb" + +[[package]] +name = "web-sys" +version = "0.3.62" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b5f940c7edfdc6d12126d98c9ef4d1b3d470011c47c76a6581df47ad9ba721" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "weezl" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +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" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.4.1" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" +checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" dependencies = [ "memchr", ] +[[package]] +name = "wio" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" +dependencies = [ + "winapi", +] + [[package]] name = "wyz" version = "0.5.1" @@ -2288,6 +3142,18 @@ dependencies = [ "tap", ] +[[package]] +name = "yeslogic-fontconfig-sys" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2bbd69036d397ebbff671b1b8e4d918610c181c5a16073b96f984a38d08c386" +dependencies = [ + "const-cstr", + "dlib", + "once_cell", + "pkg-config", +] + [[package]] name = "zeroize" version = "1.6.0" diff --git a/Cargo.toml b/Cargo.toml index 2b601e5c..f64edb20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,22 @@ [package] -name = "circuits-halo2" +name = "summa-solvency" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[features] +dev-graph = ["halo2_proofs/dev-graph", "plotters"] + [dependencies] -halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2", tag = "v2023_02_02"} -halo2_gadgets = { git = "https://github.com/privacy-scaling-explorations/halo2", tag = "v2023_02_02"} -eth-types = { git = "https://github.com/privacy-scaling-explorations/zkevm-circuits"} +halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2", tag = "v2023_04_20"} +halo2_gadgets = { git = "https://github.com/privacy-scaling-explorations/halo2", tag = "v2023_04_20"} gadgets = { git = "https://github.com/privacy-scaling-explorations/zkevm-circuits"} -merkle-sum-tree-rust = { git = "https://github.com/summa-dev/merkle-sum-tree-rust"} \ No newline at end of file +plotters = { version = "0.3.4", optional = true } +rand = "0.8" +ark-std = { version = "0.3.0", features = ["print-trace"] } +tabbycat = { version = "0.1", features = ["attributes"], optional = true } +csv = "1.1" +serde = { version = "1.0", features = ["derive"] } +hex = "0.4.3" +num-bigint = "0.4" diff --git a/README.md b/README.md index 0eb6ae4b..ae301de1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Circuits - Halo2 +# Summa Solvency This repository contains the Halo2 circuit implementation for the Proof of Solvency protocol. @@ -7,7 +7,7 @@ This library makes use of the [PSE Fork of Halo2](https://github.com/privacy-sca ## Usage `cargo build` -`cargo test -- --nocapture` +`cargo test --features dev-graph -- --nocapture` ## Chips @@ -29,7 +29,7 @@ The LessThan Chip Configuration contains: - 1 advice column `lt` that denotes the result of the comparison: 1 if `lhs < rhs` and 0 otherwise - An array of `diff` advice columns of length N_BYTES. It is basically the difference between `lhs` and `rhs` expressed in 8-bit chunks. -- An field element `range` that denotes the range in which both `lhs` and `rhs` are expected to be. This is calculated as `2^N_BYTES * 8` where `N_BYTES` is the number of bytes that we want to use to represent the values `lhs` and `rhs`. +- An field element `range` that denotes the range, expressed in bits, in which both `lhs` and `rhs` are expected to be. This is calculated as `2^N_BYTES * 8` where `N_BYTES` is the number of bytes that we want to use to represent the values `lhs` and `rhs`. The configure function takes as input the lhs and rhs virtual cells from a higher level chip and enforces the following gate: diff --git a/prints/merkle-sum-tree-layout.png b/prints/merkle-sum-tree-layout.png new file mode 100644 index 00000000..f6b49097 Binary files /dev/null and b/prints/merkle-sum-tree-layout.png differ diff --git a/src/chips.rs b/src/chips.rs deleted file mode 100644 index 37fe16ff..00000000 --- a/src/chips.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod poseidon; -pub mod merkle_sum_tree; \ No newline at end of file diff --git a/src/chips/merkle_sum_tree.rs b/src/chips/merkle_sum_tree.rs index 2f904d60..9d8030a4 100644 --- a/src/chips/merkle_sum_tree.rs +++ b/src/chips/merkle_sum_tree.rs @@ -1,39 +1,39 @@ -use super::poseidon::hash::{PoseidonChip, PoseidonConfig}; -use super::poseidon::spec::MySpec; -use halo2_proofs::{circuit::*,plonk::*, poly::Rotation}; +use crate::chips::poseidon::hash::{PoseidonChip, PoseidonConfig}; +use crate::chips::poseidon::spec::MySpec; use gadgets::less_than::{LtChip, LtConfig, LtInstruction}; -use eth_types::Field; +use halo2_proofs::halo2curves::bn256::Fr as Fp; +use halo2_proofs::{circuit::*, plonk::*, poly::Rotation}; const WIDTH: usize = 5; const RATE: usize = 4; const L: usize = 4; #[derive(Debug, Clone)] -pub struct MerkleSumTreeConfig { +pub struct MerkleSumTreeConfig { pub advice: [Column; 5], pub bool_selector: Selector, pub swap_selector: Selector, pub sum_selector: Selector, pub lt_selector: Selector, pub instance: Column, - pub poseidon_config: PoseidonConfig, - pub lt_config: LtConfig, + pub poseidon_config: PoseidonConfig, + pub lt_config: LtConfig, } #[derive(Debug, Clone)] -pub struct MerkleSumTreeChip { - config: MerkleSumTreeConfig, +pub struct MerkleSumTreeChip { + config: MerkleSumTreeConfig, } -impl MerkleSumTreeChip { - pub fn construct(config: MerkleSumTreeConfig) -> Self { +impl MerkleSumTreeChip { + pub fn construct(config: MerkleSumTreeConfig) -> Self { Self { config } } pub fn configure( - meta: &mut ConstraintSystem, + meta: &mut ConstraintSystem, advice: [Column; 5], instance: Column, - ) -> MerkleSumTreeConfig { + ) -> MerkleSumTreeConfig { let col_a = advice[0]; let col_b = advice[1]; let col_c = advice[2]; @@ -52,7 +52,7 @@ impl MerkleSumTreeChip { // enable equality for computed_sum copy constraint with instance column (col_e) meta.enable_equality(col_a); meta.enable_equality(col_b); - meta.enable_equality(col_c); + meta.enable_equality(col_c); meta.enable_equality(col_d); meta.enable_equality(col_e); meta.enable_equality(instance); @@ -62,7 +62,7 @@ impl MerkleSumTreeChip { meta.create_gate("bool constraint", |meta| { let s = meta.query_selector(bool_selector); let e = meta.query_advice(col_e, Rotation::cur()); - vec![s * e.clone() * (Expression::Constant(F::from(1)) - e)] + vec![s * e.clone() * (Expression::Constant(Fp::from(1)) - e)] }); // Enforces that if the swap bit (e) is on, l1=c, l2=d, r1=a, and r2=b. Otherwise, l1=a, l2=b, r1=c, and r2=d. @@ -80,12 +80,8 @@ impl MerkleSumTreeChip { let r2 = meta.query_advice(col_d, Rotation::next()); vec![ - s.clone() * (e.clone() * Expression::Constant(F::from(2)) * (c.clone() - a.clone()) - - (l1 - a) - - (c - r1)), - s * (e * Expression::Constant(F::from(2)) * (d.clone() - b.clone()) - - (l2 - b) - - (d - r2)), + s.clone() * e.clone() * ((l1 - a) - (c - r1)), + s * e * ((l2 - b) - (d - r2)), ] }); @@ -100,12 +96,9 @@ impl MerkleSumTreeChip { let hash_inputs = (0..WIDTH).map(|_| meta.advice_column()).collect::>(); - let poseidon_config = PoseidonChip::, WIDTH, RATE, L>::configure( - meta, - hash_inputs - ); + let poseidon_config = PoseidonChip::::configure(meta, hash_inputs); - // configure lt chip + // configure lt chip let lt_config = LtChip::configure( meta, |meta| meta.query_selector(lt_selector), @@ -121,38 +114,47 @@ impl MerkleSumTreeChip { lt_selector, instance, poseidon_config, - lt_config + lt_config, }; - meta.create_gate("verifies that `check` from current config equal to is_lt from LtChip ", |meta| { - let q_enable = meta.query_selector(lt_selector); + meta.create_gate( + "verifies that `check` from current config equal to is_lt from LtChip", + |meta| { + let q_enable = meta.query_selector(lt_selector); - let check = meta.query_advice(col_c, Rotation::cur()); + let check = meta.query_advice(col_c, Rotation::cur()); - vec![q_enable * (config.lt_config.is_lt(meta, None) - check)] - }); + vec![q_enable * (config.lt_config.is_lt(meta, None) - check)] + }, + ); config - } pub fn assing_leaf_hash_and_balance( &self, - mut layouter: impl Layouter, - leaf_hash: F, - leaf_balance: F, - ) -> Result<(AssignedCell, AssignedCell), Error> { - let leaf_hash_cell = layouter.assign_region( + mut layouter: impl Layouter, + leaf_hash: Fp, + leaf_balance: Fp, + ) -> Result<(AssignedCell, AssignedCell), Error> { + let (leaf_hash_cell, leaf_balance_cell) = layouter.assign_region( || "assign leaf hash", |mut region| { - region.assign_advice(|| "leaf hash", self.config.advice[0], 0, || Value::known(leaf_hash)) - }, - )?; + let l = region.assign_advice( + || "leaf hash", + self.config.advice[0], + 0, + || Value::known(leaf_hash), + )?; - let leaf_balance_cell = layouter.assign_region( - || "assign leaf balance", - |mut region| { - region.assign_advice(|| "leaf balance", self.config.advice[1], 0, || Value::known(leaf_balance)) + let r = region.assign_advice( + || "leaf balance", + self.config.advice[1], + 0, + || Value::known(leaf_balance), + )?; + + Ok((l, r)) }, )?; @@ -161,18 +163,18 @@ impl MerkleSumTreeChip { pub fn merkle_prove_layer( &self, - mut layouter: impl Layouter, - prev_hash: &AssignedCell, - prev_balance: &AssignedCell, - element_hash: F, - element_balance: F, - index: F, - ) -> Result<(AssignedCell, AssignedCell), Error> { + mut layouter: impl Layouter, + prev_hash: &AssignedCell, + prev_balance: &AssignedCell, + element_hash: Fp, + element_balance: Fp, + index: Fp, + ) -> Result<(AssignedCell, AssignedCell), Error> { let (left_hash, left_balance, right_hash, right_balance, computed_sum_cell) = layouter .assign_region( || "merkle prove layer", |mut region| { - // Row 0 + // Row 0 self.config.bool_selector.enable(&mut region, 0)?; self.config.swap_selector.enable(&mut region, 0)?; let l1 = prev_hash.copy_advice( @@ -199,24 +201,24 @@ impl MerkleSumTreeChip { 0, || Value::known(element_balance), )?; - let index = region.assign_advice(|| - "assign index", - self.config.advice[4], - 0, - || Value::known(index) + let index = region.assign_advice( + || "assign index", + self.config.advice[4], + 0, + || Value::known(index), )?; let mut l1_val = l1.value().map(|x| x.to_owned()); let mut l2_val = l2.value().map(|x| x.to_owned()); let mut r1_val = r1.value().map(|x| x.to_owned()); let mut r2_val = r2.value().map(|x| x.to_owned()); - + // Row 1 self.config.sum_selector.enable(&mut region, 1)?; // if index is 0 return (l1, l2, r1, r2) else return (r1, r2, l1, l2) index.value().map(|x| x.to_owned()).map(|x| { - (l1_val, l2_val, r1_val, r2_val) = if x == F::zero() { + (l1_val, l2_val, r1_val, r2_val) = if x == Fp::zero() { (l1_val, l2_val, r1_val, r2_val) } else { (r1_val, r2_val, l1_val, l2_val) @@ -252,7 +254,10 @@ impl MerkleSumTreeChip { || r2_val, )?; - let computed_sum = left_balance.value().zip(right_balance.value()).map(|(a, b)| *a + b); + let computed_sum = left_balance + .value() + .zip(right_balance.value()) + .map(|(a, b)| *a + b); // Now we can assign the sum result to the computed_sum cell. let computed_sum_cell = region.assign_advice( @@ -273,9 +278,8 @@ impl MerkleSumTreeChip { )?; // instantiate the poseidon_chip - let poseidon_chip = PoseidonChip::, WIDTH, RATE, L>::construct( - self.config.poseidon_config.clone(), - ); + let poseidon_chip = + PoseidonChip::::construct(self.config.poseidon_config.clone()); // The hash function inside the poseidon_chip performs the following action // 1. Copy the left and right cells from the previous row @@ -292,21 +296,19 @@ impl MerkleSumTreeChip { // Enforce computed sum to be less than total assets passed inside the instance column pub fn enforce_less_than( &self, - mut layouter: impl Layouter, - prev_computed_sum_cell: &AssignedCell, - computed_sum: F, - total_assets: F, + mut layouter: impl Layouter, + prev_computed_sum_cell: &AssignedCell, ) -> Result<(), Error> { - // Initiate chip config let chip = LtChip::construct(self.config.lt_config); + chip.load(&mut layouter)?; + layouter.assign_region( || "enforce sum to be less than total assets", |mut region| { - // copy the computed sum to the cell in the first column - prev_computed_sum_cell.copy_advice( + let computed_sum_cell = prev_computed_sum_cell.copy_advice( || "copy computed sum", &mut region, self.config.advice[0], @@ -314,12 +316,12 @@ impl MerkleSumTreeChip { )?; // copy the total assets from instance column to the cell in the second column - region.assign_advice_from_instance( + let total_assets_cell = region.assign_advice_from_instance( || "copy total assets", self.config.instance, 3, - self.config.advice[1], - 0 + self.config.advice[1], + 0, )?; // set check to be equal to 1 @@ -327,13 +329,25 @@ impl MerkleSumTreeChip { || "check", self.config.advice[2], 0, - || Value::known(F::from(1)), + || Value::known(Fp::from(1)), )?; - // enable lt seletor + // enable lt seletor self.config.lt_selector.enable(&mut region, 0)?; - chip.assign(&mut region, 0, computed_sum, total_assets)?; + total_assets_cell + .value() + .zip(computed_sum_cell.value()) + .map(|(total_assets, computed_sum)| { + if let Err(e) = chip.assign( + &mut region, + 0, + computed_sum.to_owned(), + total_assets.to_owned(), + ) { + println!("Error: {:?}", e); + }; + }); Ok(()) }, @@ -342,11 +356,11 @@ impl MerkleSumTreeChip { Ok(()) } - // Enforce permutation check between input cell and instance column at row passed as input + // Enforce copy constraint check between input cell and instance column at row passed as input pub fn expose_public( &self, - mut layouter: impl Layouter, - cell: &AssignedCell, + mut layouter: impl Layouter, + cell: &AssignedCell, row: usize, ) -> Result<(), Error> { layouter.constrain_instance(cell.cell(), self.config.instance, row) diff --git a/src/chips/mod.rs b/src/chips/mod.rs new file mode 100644 index 00000000..22b3a66b --- /dev/null +++ b/src/chips/mod.rs @@ -0,0 +1,2 @@ +pub mod merkle_sum_tree; +pub mod poseidon; diff --git a/src/chips/poseidon/hash.rs b/src/chips/poseidon/hash.rs index f9c6c619..b854e0ec 100644 --- a/src/chips/poseidon/hash.rs +++ b/src/chips/poseidon/hash.rs @@ -7,7 +7,8 @@ is already implemented in halo2_gadgets, there is no wrapper chip that makes it // compared to `hash_with_instance` this version doesn't use any instance column. use halo2_gadgets::poseidon::{primitives::*, Hash, Pow5Chip, Pow5Config}; -use halo2_proofs::{arithmetic::FieldExt, circuit::*, plonk::*}; +use halo2_proofs::halo2curves::bn256::Fr as Fp; +use halo2_proofs::{circuit::*, plonk::*}; use std::marker::PhantomData; #[derive(Debug, Clone)] @@ -15,27 +16,26 @@ use std::marker::PhantomData; // WIDTH, RATE and L are const generics for the struct, which represent the width, rate, and number of inputs for the Poseidon hash function, respectively. // This means they are values that are known at compile time and can be used to specialize the implementation of the struct. // The actual chip provided by halo2_gadgets is added to the parent Chip. -pub struct PoseidonConfig { - pow5_config: Pow5Config, +pub struct PoseidonConfig { + pow5_config: Pow5Config, } #[derive(Debug, Clone)] pub struct PoseidonChip< - F: FieldExt, - S: Spec, + S: Spec, const WIDTH: usize, const RATE: usize, const L: usize, > { - config: PoseidonConfig, + config: PoseidonConfig, _marker: PhantomData, } -impl, const WIDTH: usize, const RATE: usize, const L: usize> - PoseidonChip +impl, const WIDTH: usize, const RATE: usize, const L: usize> + PoseidonChip { - pub fn construct(config: PoseidonConfig) -> Self { + pub fn construct(config: PoseidonConfig) -> Self { Self { config, _marker: PhantomData, @@ -44,9 +44,9 @@ impl, const WIDTH: usize, const RATE: usize // Configuration of the PoseidonChip pub fn configure( - meta: &mut ConstraintSystem, + meta: &mut ConstraintSystem, hash_inputs: Vec>, - ) -> PoseidonConfig { + ) -> PoseidonConfig { let partial_sbox = meta.advice_column(); let rc_a = (0..WIDTH).map(|_| meta.fixed_column()).collect::>(); let rc_b = (0..WIDTH).map(|_| meta.fixed_column()).collect::>(); @@ -64,9 +64,7 @@ impl, const WIDTH: usize, const RATE: usize rc_b.try_into().unwrap(), ); - PoseidonConfig { - pow5_config, - } + PoseidonConfig { pow5_config } } // L is the number of inputs to the hash function @@ -74,10 +72,9 @@ impl, const WIDTH: usize, const RATE: usize // It uses the pow5_chip to compute the hash pub fn hash( &self, - mut layouter: impl Layouter, - input_cells: [AssignedCell; L], - ) -> Result, Error> { - + mut layouter: impl Layouter, + input_cells: [AssignedCell; L], + ) -> Result, Error> { let pow5_chip = Pow5Chip::construct(self.config.pow5_config.clone()); // initialize the hasher @@ -87,5 +84,4 @@ impl, const WIDTH: usize, const RATE: usize )?; hasher.hash(layouter.namespace(|| "hash"), input_cells) } - } diff --git a/src/chips/poseidon/mod.rs b/src/chips/poseidon/mod.rs index 9b6cf956..e88713d6 100644 --- a/src/chips/poseidon/mod.rs +++ b/src/chips/poseidon/mod.rs @@ -1,2 +1,3 @@ pub mod hash; +pub mod rate4_params; pub mod spec; diff --git a/src/chips/poseidon/rate4_params.rs b/src/chips/poseidon/rate4_params.rs new file mode 100644 index 00000000..29f8c42f --- /dev/null +++ b/src/chips/poseidon/rate4_params.rs @@ -0,0 +1,2532 @@ +//! Parameters for using rate 4 Poseidon with the BN256 field. +//! Patterned after [halo2_gadgets::poseidon::primitives::fp] +//! The parameters can be reproduced by running the following Sage script from +//! [this repository](https://github.com/daira/pasta-hadeshash): +//! +//! ```text +//! $ sage generate_parameters_grain.sage 1 0 254 5 8 60 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 --rust +//! ``` +//! +//! where 1 means "prime field", 0 means "non-negative sbox", 254 is the bitsize +//! of the field, 5 is the Poseidon width (rate + 1), 8 is the number of full +//! rounds, 60 is the number of partial rounds. +//! More info here => https://hackmd.io/@letargicus/SJOvx48Nn +use halo2_proofs::halo2curves::bn256::Fr as Fp; + +// Number of round constants: 340 +// Round constants for GF(p): +pub(crate) const ROUND_CONSTANTS: [[Fp; 5]; 68] = [ + [ + Fp::from_raw([ + 0x4f3c_2bd8_1a6d_a891, + 0xd889_bb4e_bd47_c386, + 0x7f53_e29c_cac9_8ed7, + 0x0eb5_44fe_e281_5dda, + ]), + Fp::from_raw([ + 0xba73_3f28_4751_28cb, + 0xa197_aeb1_2ea6_4713, + 0xf02f_dba7_dd73_7fbc, + 0x0554_d736_315b_8662, + ]), + Fp::from_raw([ + 0xf508_7c58_d5e8_c2d4, + 0x5490_7df0_c0fb_0035, + 0xbcd7_4805_6307_c377, + 0x2f83_b9df_259b_2b68, + ]), + Fp::from_raw([ + 0x1915_208f_5aba_9683, + 0x61f1_5f8b_41a7_5ef3, + 0x2447_ac83_0524_51b4, + 0x2ca7_0e2e_8d7f_39a1, + ]), + Fp::from_raw([ + 0x4ec7_19cb_83ec_fea9, + 0x9941_96f1_2ed2_2c5d, + 0x91b0_4d72_2227_1c94, + 0x1cb5_f931_9be6_a45e, + ]), + ], + [ + Fp::from_raw([ + 0xb9ea_08d1_8446_c122, + 0x21c7_bb47_b937_50c2, + 0xf8a4_2192_de7f_f616, + 0x2eb4_f99c_69f9_66eb, + ]), + Fp::from_raw([ + 0xd5f7_d099_e299_520e, + 0x0fc7_da8b_93ee_13b6, + 0xc519_8169_e405_d9ea, + 0x224a_28e5_a353_85a7, + ]), + Fp::from_raw([ + 0x2379_6b99_3bbd_82f7, + 0x36f3_3ecb_d9a0_f978, + 0xd8af_dd6a_fca4_9c30, + 0x0f74_11b4_65e6_00ee, + ]), + Fp::from_raw([ + 0x0626_f9ff_5d90_e4e3, + 0x19b2_08ae_3370_f99a, + 0xa2be_7150_392d_8d98, + 0x0f9d_0d5a_ad2c_9555, + ]), + Fp::from_raw([ + 0x6a12_d307_02d6_fba0, + 0x9732_b252_59cf_744b, + 0x6f52_a595_38d3_2922, + 0x1e9a_96dc_8292_bb59, + ]), + ], + [ + Fp::from_raw([ + 0xc2cd_4d52_8fb3_fe3c, + 0x3cfe_52ea_b4b9_45c6, + 0x887d_578c_4555_5e59, + 0x0878_0514_ccd9_0380, + ]), + Fp::from_raw([ + 0x59f1_19d6_29cc_b5fc, + 0xced6_4717_e355_6d5a, + 0xc814_9fa3_f73e_f8c2, + 0x2724_98fc_ed68_6c7a, + ]), + Fp::from_raw([ + 0xe3d0_ef8a_782e_f7df, + 0x45bd_350a_ff58_5f10, + 0x4b7c_b809_30bd_06eb, + 0x01ef_8f9d_d7c9_3aac, + ]), + Fp::from_raw([ + 0x97ea_0ae7_5493_4d30, + 0x8e88_6e64_bf3c_40aa, + 0x4dc0_8f22_2b46_9b13, + 0x045b_9f59_b659_5e61, + ]), + Fp::from_raw([ + 0xadf2_5842_95d6_1c66, + 0xa3e4_1e24_e247_a387, + 0x9fd6_f59d_2a40_ff8e, + 0x0ac1_e91c_57d9_da91, + ]), + ], + [ + Fp::from_raw([ + 0xd12e_68f0_4e62_d134, + 0x0fd6_7061_aee9_9979, + 0xc7f9_a421_353c_d89d, + 0x028a_1621_a940_54b0, + ]), + Fp::from_raw([ + 0xd02a_ae2a_0dcd_9dbc, + 0x50c1_9c3f_b3c9_6d09, + 0x9632_647e_d059_236e, + 0x26b4_1802_c071_ea4c, + ]), + Fp::from_raw([ + 0x4af3_4384_aedb_462b, + 0x05c9_de06_758d_b6a9, + 0xbaac_2f63_e468_215e, + 0x2fb5_dda8_072b_b72c, + ]), + Fp::from_raw([ + 0xdd05_c56e_e894_d850, + 0xad8a_b8ba_2a18_d383, + 0x44ff_3547_fd82_3249, + 0x2212_d3a0_f5fc_caf2, + ]), + Fp::from_raw([ + 0x5cd0_c7ee_d465_e2e3, + 0xa327_6fdb_19f4_4c01, + 0x58e4_dfae_ea09_be56, + 0x1b04_1ad5_b2f0_6842, + ]), + ], + [ + Fp::from_raw([ + 0xa91e_64af_b150_0eff, + 0x144f_b7e3_ac14_e846, + 0x8ecc_ff33_e76f_ded3, + 0x0a01_776b_b22f_4b6b, + ]), + Fp::from_raw([ + 0xf793_6440_810a_ce43, + 0xa4f3_3ae8_c15c_f827, + 0xf34d_3f27_5066_d549, + 0x2b7b_5674_aaec_c3cb, + ]), + Fp::from_raw([ + 0x4c1b_8033_81a3_bdfd, + 0x60b0_4225_7b78_fc00, + 0x4cf7_5779_ed54_b48c, + 0x29d2_99b8_0cd4_489e, + ]), + Fp::from_raw([ + 0x19dd_e304_24be_401e, + 0xa427_1100_32b5_e1dd, + 0x5764_1c21_9d72_1a74, + 0x1c46_831d_9a74_5293, + ]), + Fp::from_raw([ + 0x739a_e1d8_83e9_1269, + 0x3629_6c06_5767_4f80, + 0xf371_41dc_34d5_78e0, + 0x06d7_626c_953c_cb72, + ]), + ], + [ + Fp::from_raw([ + 0x0f10_8c71_cda2_930c, + 0xdc5c_440a_3022_cd96, + 0xc540_0274_8e0c_410e, + 0x28ff_ddc8_6f18_c136, + ]), + Fp::from_raw([ + 0xb8ec_0619_f6fb_c5e9, + 0xbe67_f1b7_ed2a_b6ad, + 0xf85d_eed0_9e40_0b17, + 0x2e67_f7ee_5e4a_a295, + ]), + Fp::from_raw([ + 0xe7ab_f22c_24e8_0f27, + 0xca56_859e_f759_e53c, + 0x0e97_f251_14a7_9a2d, + 0x26ce_38fa_636c_9063, + ]), + Fp::from_raw([ + 0xafac_b4c4_cfd3_5db1, + 0x42cb_3d16_a1f7_2721, + 0x4dd7_a01d_00a7_ffec, + 0x2e6e_07c3_c95b_f7c3, + ]), + Fp::from_raw([ + 0x384b_1470_da24_d8cc, + 0x8890_d276_612e_1246, + 0x5f91_d796_1c3a_54fb, + 0x2aa7_4f75_97f0_c9f4, + ]), + ], + [ + Fp::from_raw([ + 0x2ec0_ca63_9b7f_73fe, + 0x8a71_313c_1509_183e, + 0x2c7c_090f_668a_b45b, + 0x287d_681a_46a2_faae, + ]), + Fp::from_raw([ + 0x11e2_9f33_05e7_3c04, + 0xa5d3_106f_f565_aa3b, + 0xf4a4_0600_528f_3d7d, + 0x212b_d19d_f812_eaae, + ]), + Fp::from_raw([ + 0x3809_c284_0471_3504, + 0xf97f_d974_0926_dab9, + 0x1aaf_b14b_350e_b860, + 0x1154_f7cf_5191_86bf, + ]), + Fp::from_raw([ + 0xda74_7e79_661f_c207, + 0xbf51_5290_5be3_6583, + 0x4637_810a_4bd1_b16f, + 0x1dff_6385_cb31_f1c2, + ]), + Fp::from_raw([ + 0x63ea_3c60_6b55_1e5c, + 0x4011_a34d_5476_2528, + 0xc081_d34c_44c1_8e42, + 0x0e44_4582_d22b_4e76, + ]), + ], + [ + Fp::from_raw([ + 0xff72_d3aa_b7e4_eff8, + 0x8157_73e9_c284_6323, + 0xabab_6638_328f_02f1, + 0x0323_c9e4_33ba_66c4, + ]), + Fp::from_raw([ + 0xb70f_2c68_76a9_c29d, + 0x25b8_cf00_2740_112d, + 0x193b_ba79_cdec_448f, + 0x1274_6bbd_7179_1059, + ]), + Fp::from_raw([ + 0xfd04_9eb4_438a_2240, + 0xd466_c837_cf50_d73e, + 0xfd9b_9d37_5184_2c75, + 0x1173_b7d1_12c2_a798, + ]), + Fp::from_raw([ + 0x5fdb_4808_7032_43da, + 0xa8e5_713b_2502_6ebe, + 0x76d1_e555_d7fe_d13d, + 0x13d5_1c10_90a1_ad48, + ]), + Fp::from_raw([ + 0xf4a5_8ebe_b956_baa1, + 0xcb72_743f_0394_efe7, + 0xff8d_cb7c_bd2d_9743, + 0x0087_4c13_44a4_ad51, + ]), + ], + [ + Fp::from_raw([ + 0xa32a_5620_74fe_f08f, + 0x0eea_48d3_546e_97d6, + 0x65ce_236b_07f2_44fa, + 0x22df_2213_1aaa_b858, + ]), + Fp::from_raw([ + 0x8bf5_eb05_a919_f155, + 0x9845_24a5_9101_e6c1, + 0x8708_b437_a445_fc3e, + 0x0bf9_64d2_dbd2_5b90, + ]), + Fp::from_raw([ + 0x69b4_35b5_fc50_2f32, + 0x640b_9d73_a9ab_298c, + 0xa302_be1f_7f18_1e0e, + 0x09b1_8d9b_917a_55bc, + ]), + Fp::from_raw([ + 0xd674_5a50_6728_9e43, + 0xfbbb_c70a_6365_366d, + 0xa4bf_c1d5_bf3d_c05b, + 0x094f_5534_444f_ae36, + ]), + Fp::from_raw([ + 0x784f_ddc0_dc23_f01f, + 0xa3e2_40c0_da57_01cb, + 0x519f_a662_2af5_3a15, + 0x2999_bab1_a5f2_5210, + ]), + ], + [ + Fp::from_raw([ + 0x6957_5a11_b03a_3d23, + 0x8430_1bce_8a93_d136, + 0x1ca9_4db7_3710_e880, + 0x2f68_98c0_7581_f637, + ]), + Fp::from_raw([ + 0x6217_4b1a_6866_fccb, + 0x565d_eb1e_8e57_42f8, + 0xec16_d7e1_318a_4740, + 0x0726_8eaa_ba08_bc19, + ]), + Fp::from_raw([ + 0xa6c9_582c_41a0_529f, + 0x6260_3e07_8e1c_6689, + 0x1339_ff77_113b_c9eb, + 0x1862_79b0_0345_4db0, + ]), + Fp::from_raw([ + 0x0768_e552_4737_172c, + 0xb67e_2cc5_de9a_2275, + 0xe491_5bdd_04d3_e5dd, + 0x18a3_f736_5091_97d6, + ]), + Fp::from_raw([ + 0x7b59_87b8_7085_671d, + 0x725e_2d4b_cb2d_3a00, + 0x77cc_1e2e_d24c_808c, + 0x0a21_fa19_88cf_38d8, + ]), + ], + [ + Fp::from_raw([ + 0x0b36_a135_e785_fba2, + 0x8328_c184_a2c4_3bc0, + 0x1faf_5ef6_a646_2522, + 0x15b2_85cb_e26c_467f, + ]), + Fp::from_raw([ + 0x8cd2_8de3_e779_f161, + 0x0b77_75b7_c902_f578, + 0x8c08_b8c3_f980_6d56, + 0x164b_7062_c467_1cf0, + ]), + Fp::from_raw([ + 0x7a24_f651_249b_aa70, + 0x61c6_1d3d_43b6_e65d, + 0x86d9_865f_e7e5_0ef3, + 0x0890_ba08_19ac_0a6f, + ]), + Fp::from_raw([ + 0xcc2e_e0ae_d543_e922, + 0xa627_ac5c_b0eb_878c, + 0xa427_12e5_a721_e4ea, + 0x2fbe_a4d6_5d7e_d425, + ]), + Fp::from_raw([ + 0x103d_7f5f_379a_baaa, + 0x7b70_a58e_854a_b9b9, + 0x5403_03a3_b536_f85e, + 0x0492_bf38_3c36_fa55, + ]), + ], + [ + Fp::from_raw([ + 0x6a96_9d56_292d_c24e, + 0x1d61_85a9_ce85_675f, + 0x4e20_251c_5651_42d6, + 0x05e9_1fe9_44e9_4410, + ]), + Fp::from_raw([ + 0x7e38_0a76_e36e_6c1c, + 0x995b_9621_e6e4_9c3b, + 0x93d4_63cb_041a_cad0, + 0x12fe_5c20_29e4_b338, + ]), + Fp::from_raw([ + 0x06cd_01dc_6fa0_784e, + 0x1f26_29fa_dc89_4969, + 0x958f_7723_9214_7413, + 0x0241_54ad_f025_5d47, + ]), + Fp::from_raw([ + 0x8813_c134_57a4_5550, + 0xd798_8156_44f2_bbde, + 0x36ed_2462_a86b_d0ba, + 0x1882_4a09_e6af_af4a, + ]), + Fp::from_raw([ + 0xbb06_983e_3d5d_58a5, + 0xdf84_a630_af68_d50b, + 0xe9f2_55de_0c3d_bddd, + 0x0c8b_482d_ba0a_d51b, + ]), + ], + [ + Fp::from_raw([ + 0x4413_9287_8fdb_05e6, + 0x5a4f_a67f_cd6a_af86, + 0x363e_0a16_67d3_b67c, + 0x1732_5fd0_ab63_5871, + ]), + Fp::from_raw([ + 0x1cc6_d0e9_11fa_402e, + 0xe550_773f_a8d1_8bf7, + 0x122f_5af6_7b69_0f31, + 0x050a_e95f_6d2f_1519, + ]), + Fp::from_raw([ + 0x5771_ec84_edc5_0c40, + 0x4bbb_6295_f075_6988, + 0x038c_b288_d626_3676, + 0x0f0d_139a_0e81_e943, + ]), + Fp::from_raw([ + 0x9dbb_ca7b_8e74_7cd6, + 0x79b3_9ebc_7a1b_1c54, + 0xf70f_d2f2_c0f9_3d1a, + 0x1c0f_8697_7956_89cd, + ]), + Fp::from_raw([ + 0xfe53_6a16_dc1d_81e6, + 0x49be_23a4_b135_98f9, + 0x6d2b_c2e0_48bc_979e, + 0x2bd0_f940_ad93_6b79, + ]), + ], + [ + Fp::from_raw([ + 0x7ce5_4d1e_96ee_62cb, + 0xa06e_bb27_5e09_6d16, + 0x4778_c09a_0053_337f, + 0x27eb_1be2_7c9c_4e93, + ]), + Fp::from_raw([ + 0xf151_be62_548e_2aea, + 0x284f_bd30_7d1f_71b0, + 0x8f96_bdd3_155a_7ca3, + 0x2e48_89d8_30a6_7e5a, + ]), + Fp::from_raw([ + 0x6064_bbe6_fcc1_e305, + 0xc989_1f2c_adc1_65db, + 0x5d2e_c5e9_c5bd_9983, + 0x193f_e3db_0ab4_7d3c, + ]), + Fp::from_raw([ + 0x37cb_1302_7c83_e525, + 0x6e96_61c0_0967_9e4e, + 0xce41_5907_ad0c_40ed, + 0x2bf3_086e_96c3_6c7b, + ]), + Fp::from_raw([ + 0x9ff2_ea48_6e59_bb28, + 0xd5e7_e413_f741_ccf2, + 0xa98c_db69_7c6c_ad5d, + 0x12f1_6e2d_e6d4_ad46, + ]), + ], + [ + Fp::from_raw([ + 0xad91_9b03_43b9_2d2f, + 0x33f3_d5d6_ec6c_4bf0, + 0xa026_2e36_53dd_d19f, + 0x2a72_147d_2301_19f3, + ]), + Fp::from_raw([ + 0x77df_79ac_c10b_a974, + 0x0a2d_9bcc_2641_2e29, + 0x6dc4_7f95_7806_dc5f, + 0x21be_0e2c_4bfd_64e5, + ]), + Fp::from_raw([ + 0x137f_d4b6_c21b_444a, + 0x71b8_4fb9_11aa_57ae, + 0x2749_a3b5_4367_b25a, + 0x0e2d_7e1d_c946_d70b, + ]), + Fp::from_raw([ + 0x9f3f_07d4_b92b_3e2e, + 0xc31a_db0e_ae33_25dc, + 0x6170_a745_d8a4_188c, + 0x2667_f7fb_5a4f_a124, + ]), + Fp::from_raw([ + 0x830e_107d_a78e_3405, + 0x1550_c12b_08df_eb72, + 0x30a7_83b6_6064_697a, + 0x2ccc_6f43_1fb7_4007, + ]), + ], + [ + Fp::from_raw([ + 0x2ec5_0621_e38e_6e5d, + 0xae6d_bee9_e8ca_0c24, + 0x4f02_0146_2420_001f, + 0x0888_8a94_fc5a_2ca3, + ]), + Fp::from_raw([ + 0x6acf_cd3c_cbc5_3f2a, + 0xa0d2_fbe7_53af_88b3, + 0xad40_dd42_c9b6_fdd7, + 0x0297_7b34_eeaa_3cb6, + ]), + Fp::from_raw([ + 0x10b5_e9f9_71e1_6b9a, + 0xbfcf_e0d7_e6ff_8e96, + 0xfd6f_b6c9_ea13_a648, + 0x120c_cce1_3d28_b75c, + ]), + Fp::from_raw([ + 0xa0bf_2af3_2f86_ff3c, + 0x9278_7a45_75b2_bd73, + 0xc81e_1b97_70ea_098c, + 0x09fa_d226_9c4a_8e93, + ]), + Fp::from_raw([ + 0xf630_cffb_6009_2d6f, + 0x0deb_db70_775e_eb8a, + 0x0a4b_310e_4ac6_f0fa, + 0x0260_91fd_3d4c_44d5, + ]), + ], + [ + Fp::from_raw([ + 0xb904_fd2b_ca89_3994, + 0x2543_cc56_afad_6afc, + 0xbb7f_ba9d_fb6f_c321, + 0x2940_4aa2_ba56_5b77, + ]), + Fp::from_raw([ + 0xe720_1351_b7c8_83f9, + 0xf1ff_d865_90e0_827d, + 0xd4e8_7c25_4869_5b4e, + 0x2749_475c_399a_af39, + ]), + Fp::from_raw([ + 0xc755_7dab_65ff_a222, + 0xa2eb_e2dc_2e4d_a70a, + 0x3991_2b50_4246_85cb, + 0x098c_8423_2247_9f72, + ]), + Fp::from_raw([ + 0x0191_d0c0_53b5_1936, + 0x758a_ce14_c93c_4da4, + 0x3123_8e57_fead_7d5c, + 0x18ce_f581_222b_647e, + ]), + Fp::from_raw([ + 0x63b2_aa68_1698_de60, + 0x3cbc_0ca4_a108_f98d, + 0xd4e7_4674_5e43_711d, + 0x1317_7839_c68a_5080, + ]), + ], + [ + Fp::from_raw([ + 0xa907_d88e_5f0d_effd, + 0x26cc_4df7_12c0_e5f0, + 0xc088_f56f_4b74_3256, + 0x020c_a696_f531_e43e, + ]), + Fp::from_raw([ + 0x16e0_2838_7c7a_c022, + 0x93d1_3708_c646_841d, + 0xfa80_5a30_fc54_8db6, + 0x2723_0eed_e9cc_cfc9, + ]), + Fp::from_raw([ + 0x9057_d2fe_75bb_281c, + 0x6497_c059_69a0_1543, + 0xd64f_de34_a342_a178, + 0x0164_5911_c119_8b01, + ]), + Fp::from_raw([ + 0xfdca_4a45_1a5d_8643, + 0x1989_71e1_4487_056c, + 0x6e43_9c88_341c_e25f, + 0x2c32_3fe1_6481_bf49, + ]), + Fp::from_raw([ + 0x5af8_8ae6_db50_85c8, + 0xb022_c124_d3bf_fe8b, + 0x450b_d207_4c3e_22e1, + 0x0fc0_82df_e707_28e8, + ]), + ], + [ + Fp::from_raw([ + 0xfe8a_488b_4235_21ee, + 0xbe96_4211_6ac4_c77e, + 0xd8cd_ca56_8dcc_25b3, + 0x2052_c174_800d_b209, + ]), + Fp::from_raw([ + 0x8dd9_fd05_b3ec_e9c0, + 0x0be3_51ce_8129_065a, + 0xaf96_d621_d554_2319, + 0x28e4_20e1_0df2_fbb5, + ]), + Fp::from_raw([ + 0x49d6_e0bc_3ae5_069a, + 0x55d6_ae1b_dacd_1cb5, + 0x9f78_3c44_62a2_4db6, + 0x2569_8ca5_e24a_1b79, + ]), + Fp::from_raw([ + 0x34d9_b857_d698_4d35, + 0xa297_b610_7442_2ac1, + 0xcf8f_fbfa_57d5_1049, + 0x160a_9981_a5c8_9a57, + ]), + Fp::from_raw([ + 0x6464_2b06_9997_f3d4, + 0x8b7c_ebf5_9ddb_b0a0, + 0x34d9_b694_b843_f3bf, + 0x21c9_1a39_e145_c3bc, + ]), + ], + [ + Fp::from_raw([ + 0xd109_7546_1e41_734c, + 0xd6ea_a029_d93f_03b6, + 0xd2b0_9345_ef11_2345, + 0x1ac8_d80d_cd5e_e876, + ]), + Fp::from_raw([ + 0xb8db_cea5_657c_e02c, + 0x5d82_2895_e275_5544, + 0x7c16_62a4_174c_5222, + 0x0ab3_e6ad_0ecf_8b8e, + ]), + Fp::from_raw([ + 0xc5b2_237c_bdab_3377, + 0xa52e_f3ef_5909_b4e1, + 0x27e3_b0b9_17b3_a21c, + 0x1c67_5182_5126_20ae, + ]), + Fp::from_raw([ + 0x0c8a_9092_ac2b_ed45, + 0xe37a_4a3e_07a7_d75d, + 0x3d94_8d0c_85ba_d2e2, + 0x2cdb_c998_dfd7_affd, + ]), + Fp::from_raw([ + 0x3e49_1a13_3bb6_3b2e, + 0x2433_7350_309d_ff83, + 0x774b_f67c_c0de_e333, + 0x23b5_84a5_6e21_17b0, + ]), + ], + [ + Fp::from_raw([ + 0x2f3d_20de_1465_e9a5, + 0x0d13_3bc6_ba4e_c115, + 0x8cb7_3030_a3c9_d2a1, + 0x1e9e_2b31_0f60_ba9f, + ]), + Fp::from_raw([ + 0x60bc_d4f1_fa5b_22db, + 0xc9ab_5dab_9875_20c4, + 0xabc3_e720_140a_e746, + 0x0e01_e365_ba5b_3031, + ]), + Fp::from_raw([ + 0x1387_d85b_c126_4e68, + 0x4338_2011_b61c_9a4b, + 0x7b71_2734_0498_d5c4, + 0x0408_84cd_cfc6_4bfc, + ]), + Fp::from_raw([ + 0xa0a1_7de3_11ef_9668, + 0x353f_1724_d606_7ed0, + 0x0c74_a399_8f2b_ea36, + 0x190b_1ee1_205e_b950, + ]), + Fp::from_raw([ + 0xfc28_d1f8_32bd_3b2c, + 0xc1df_cf65_ce61_e165, + 0xd04f_52fc_23cd_9c08, + 0x1647_c72a_ec6c_4388, + ]), + ], + [ + Fp::from_raw([ + 0x842e_595b_71e4_541d, + 0x9f54_94d8_9fb4_8b02, + 0x7998_80cc_4c87_3626, + 0x2430_0063_46a0_145f, + ]), + Fp::from_raw([ + 0x3221_8502_52b7_57af, + 0x9d85_3902_bb16_bacb, + 0x3651_07a3_da3a_e7f6, + 0x177b_9a08_3439_17e1, + ]), + Fp::from_raw([ + 0x39b1_1d04_666d_f4f8, + 0x09cd_53d0_ae29_4234, + 0x4e58_862a_68f5_e326, + 0x04a4_20e6_42b1_1ae9, + ]), + Fp::from_raw([ + 0xcdfa_bedd_b6a2_5c8f, + 0xde24_6185_8e95_6ccc, + 0x105a_88fa_b0af_d810, + 0x25d0_e0f7_39fb_39fc, + ]), + Fp::from_raw([ + 0x2c4d_4ffa_0c74_0a27, + 0x320c_b156_10ea_ed45, + 0x8590_5cbf_5865_1edc, + 0x0447_6d91_b7ef_f2fd, + ]), + ], + [ + Fp::from_raw([ + 0xe978_0fd9_ca28_6fae, + 0x1c28_f6d5_e125_0cb5, + 0x8bc9_ca24_19eb_8dea, + 0x1090_c0b6_8b3d_7d7b, + ]), + Fp::from_raw([ + 0xbf28_99cb_5c66_17be, + 0x376f_2d43_5855_c10e, + 0x448a_725c_5c7c_d5ad, + 0x2539_3ce3_b925_6d50, + ]), + Fp::from_raw([ + 0x97d1_44f0_fab4_6630, + 0xed82_4388_d6b9_3426, + 0xfc86_2f30_6e6e_5830, + 0x2593_1c0c_7371_f4f1, + ]), + Fp::from_raw([ + 0x03f7_3f22_afbf_62f6, + 0x8a4d_3531_85d5_8082, + 0xc82a_ad51_b0fb_79cf, + 0x2396_cb50_1700_bbe6, + ]), + Fp::from_raw([ + 0xb3f0_ce03_b872_4884, + 0xa3dc_9068_c3cc_a7b5, + 0x54ea_748a_7129_a7b0, + 0x26a3_6348_3348_b589, + ]), + ], + [ + Fp::from_raw([ + 0xa7a0_e5b4_5fcd_6897, + 0xc99b_8933_3421_5f6b, + 0x8d6f_1535_b92c_5478, + 0x27ca_107c_a204_f2a1, + ]), + Fp::from_raw([ + 0x8d2d_02b3_b2d9_1056, + 0xac15_f730_1178_581d, + 0xe466_2bde_326b_2cce, + 0x26da_28fc_097e_d77c, + ]), + Fp::from_raw([ + 0x7297_1ba5_6ee0_cb89, + 0x6557_74c1_bb35_d575, + 0x703e_3055_070a_c9cc, + 0x056a_b351_691d_8bb3, + ]), + Fp::from_raw([ + 0x2d72_9af6_3237_6a90, + 0xc225_47a1_1ffc_5015, + 0xc76d_109a_2f48_1aa3, + 0x2638_b57f_23b7_54ae, + ]), + Fp::from_raw([ + 0xea7b_c551_9ede_7cef, + 0xc33e_46a5_32bd_ec80, + 0x32f4_92c2_6051_84fd, + 0x3047_54bb_8c57_d607, + ]), + ], + [ + Fp::from_raw([ + 0x752a_c93a_9b76_19ac, + 0x48ec_6857_fc55_4010, + 0x514f_155b_5806_cbf7, + 0x00d1_727f_8457_ee03, + ]), + Fp::from_raw([ + 0xc588_e509_4776_1fa3, + 0xb5bc_a868_05ec_9419, + 0x43ba_295a_303c_72fa, + 0x00ee_1f3c_66fb_c05c, + ]), + Fp::from_raw([ + 0x61f9_297e_b675_d972, + 0x10a1_9fbc_fc59_078c, + 0x4a76_b5a1_d824_15fd, + 0x0afa_fadc_f5b4_dd4a, + ]), + Fp::from_raw([ + 0xa899_6d12_4dd0_4d0a, + 0x65a2_3483_5a0a_6a5e, + 0x86ce_45e8_eed1_08ee, + 0x0b24_49f3_9746_085e, + ]), + Fp::from_raw([ + 0x6a7d_df48_23dd_5dd6, + 0xf6c6_f071_ec3b_dda7, + 0xc9f3_7b00_4522_7095, + 0x206b_0ce2_f1b2_c5b7, + ]), + ], + [ + Fp::from_raw([ + 0x52c7_e102_9459_409c, + 0xcaff_c3a4_ef20_fea8, + 0xb696_e674_3362_8cd6, + 0x0feb_a4fb_8783_4c7c, + ]), + Fp::from_raw([ + 0x8173_e972_336e_55d3, + 0x3b06_f131_5e6d_70e1, + 0x8926_752e_084e_0251, + 0x254d_bfac_74c4_9b0b, + ]), + Fp::from_raw([ + 0x3771_9edf_a0ca_8762, + 0x9606_c5bd_1791_0aeb, + 0x4655_168c_3675_59e1, + 0x0add_b137_2cee_4e16, + ]), + Fp::from_raw([ + 0x21a5_89d6_8831_d759, + 0x6ca4_d8d8_1b1a_e162, + 0xc799_024f_b019_f65c, + 0x26b2_5b7e_257f_3e97, + ]), + Fp::from_raw([ + 0x1960_b105_9e11_3ba3, + 0xa465_7b9a_b00b_db5b, + 0x413b_8d4c_6587_87e5, + 0x0909_95b7_9ace_c240, + ]), + ], + [ + Fp::from_raw([ + 0x2974_178d_44f7_3b7b, + 0xeb0d_8e40_e991_31f4, + 0xc572_9968_7843_cea3, + 0x08db_dc2e_21ef_11f2, + ]), + Fp::from_raw([ + 0x58f1_7093_9785_179f, + 0x42fe_9c49_1596_ab67, + 0x679f_af75_2a0f_78e3, + 0x09e8_aba6_7148_1197, + ]), + Fp::from_raw([ + 0x7bc7_c683_f136_3d5c, + 0x7efd_12a7_f9ee_c94b, + 0x6590_52a7_ebaf_816c, + 0x1deb_0518_0e83_3e45, + ]), + Fp::from_raw([ + 0x35fd_6523_e525_0879, + 0x2489_97e8_b2c2_4af3, + 0xa926_efbc_c04a_a9ee, + 0x19a7_0ec6_bdfc_9098, + ]), + Fp::from_raw([ + 0xeb93_abe1_0bbf_1f64, + 0x6635_3a37_77d8_a3f1, + 0x8799_86f9_aab4_8905, + 0x21d7_7366_0ada_fb8a, + ]), + ], + [ + Fp::from_raw([ + 0xf6f4_6617_841c_3901, + 0x97a6_b01f_cd66_7347, + 0x3e20_ba63_7b89_d5d3, + 0x09f1_890f_72e9_dc71, + ]), + Fp::from_raw([ + 0x08c2_145c_33b1_11c3, + 0x48fa_1f89_7bf2_19d6, + 0x2a30_0c61_e446_998d, + 0x05af_4593_61eb_454d, + ]), + Fp::from_raw([ + 0xfa12_fc85_0cc8_b513, + 0x5f33_6f15_f340_756c, + 0x664a_66dc_75a6_5733, + 0x0fa1_a1d6_829f_0345, + ]), + Fp::from_raw([ + 0x5365_5cf9_7a62_8bb0, + 0xf428_0fcf_87f6_36f8, + 0xbda0_b1c0_307a_d543, + 0x02e4_7a35_bcc0_c3a0, + ]), + Fp::from_raw([ + 0x3662_1895_204d_0f12, + 0x2034_1146_0112_4910, + 0xb8f9_0e78_bf4c_24b7, + 0x14f7_73e9_834c_6bde, + ]), + ], + [ + Fp::from_raw([ + 0xffb0_9196_2fc8_f7cc, + 0x642a_be7c_fd63_9992, + 0x255c_f19d_29bc_7d8e, + 0x102d_98cf_502e_d843, + ]), + Fp::from_raw([ + 0xcba6_86a7_e913_73c2, + 0x20d4_c73a_d329_4738, + 0x4c47_f6c6_5da7_ca23, + 0x043d_d5f4_aa5a_76dd, + ]), + Fp::from_raw([ + 0x4cfd_b2b2_6bd1_1efa, + 0x6f0e_7c79_743a_306f, + 0xa6c0_d29a_48d4_f267, + 0x2183_3819_c333_7194, + ]), + Fp::from_raw([ + 0xdc53_262a_3cff_2b53, + 0xeb4e_ca24_6c31_1eca, + 0xb474_a681_9d11_6ca3, + 0x0f28_1925_cf5e_e649, + ]), + Fp::from_raw([ + 0x93ce_662f_15c2_38d6, + 0xdf62_5dd6_0504_d5dc, + 0x4470_9c77_46d6_824e, + 0x0d3e_2477_a7b1_0beb, + ]), + ], + [ + Fp::from_raw([ + 0xacbf_c3ef_f5ae_fc44, + 0xd80f_80ab_51e7_3b49, + 0x56ff_8a01_be9c_de35, + 0x2cd7_f641_bedb_f669, + ]), + Fp::from_raw([ + 0x86dd_8613_1046_3cf8, + 0x9149_d240_4581_1d7a, + 0x4d09_380f_98b7_4e38, + 0x29e9_5b49_2bf2_f95f, + ]), + Fp::from_raw([ + 0xf8b3_c50d_f83c_c13e, + 0x9ae4_c51a_f6ff_eb57, + 0x266e_fca8_6a6c_810f, + 0x22da_66bc_62e8_f011, + ]), + Fp::from_raw([ + 0x4307_2d84_1925_554a, + 0x220d_b79e_8129_df36, + 0x3023_4917_94f4_aca3, + 0x0fe6_d30d_e7a8_2d16, + ]), + Fp::from_raw([ + 0xc7e0_7ecb_298f_d67f, + 0xd312_d03f_ef1a_dfec, + 0x123c_46ef_f185_c23a, + 0x0050_e842_a129_9909, + ]), + ], + [ + Fp::from_raw([ + 0x885c_bbdb_6310_8c21, + 0x666f_9ddf_714e_d7c5, + 0xbe34_cc53_a42d_7733, + 0x2130_a3a7_b322_1222, + ]), + Fp::from_raw([ + 0xe1d3_28e6_7b33_c9fa, + 0xaa66_731f_34a9_3280, + 0xd8d5_883f_e056_6c24, + 0x2df9_ee29_4edf_99e3, + ]), + Fp::from_raw([ + 0xa4b6_fc5f_c337_2762, + 0x5813_2396_dc25_0aeb, + 0xf26e_b68c_c21f_f541, + 0x1bf7_d6e4_89ad_8c0c, + ]), + Fp::from_raw([ + 0x5d47_78d3_1178_0e54, + 0xcf7b_8077_28bf_7fe3, + 0x61ea_f739_617a_b136, + 0x0c60_2fa1_55be_9587, + ]), + Fp::from_raw([ + 0xb63f_af01_21ed_7f21, + 0x5154_080a_2497_2fae, + 0x3240_7d86_b8d2_2d7d, + 0x2e50_e2c5_b36a_a205, + ]), + ], + [ + Fp::from_raw([ + 0xb459_123b_1803_32e1, + 0xf674_995e_e840_9b42, + 0x5710_d629_0ec4_f782, + 0x17c2_5109_82a7_b582, + ]), + Fp::from_raw([ + 0xb2ab_255f_376b_42a8, + 0x2133_7b53_8eab_d2f6, + 0x6803_ecf2_465b_885b, + 0x0b0d_52f0_3c8a_f727, + ]), + Fp::from_raw([ + 0x6197_2dd8_fab8_bd14, + 0xa9ac_77c6_c0f8_5d45, + 0x5953_d88a_63f8_0647, + 0x0f56_33df_1972_b945, + ]), + Fp::from_raw([ + 0x0354_9813_0a7f_1572, + 0x2478_0ff4_3e76_e929, + 0xe142_2e93_9681_1551, + 0x0ebf_7ad2_9ca1_3804, + ]), + Fp::from_raw([ + 0x661b_1103_a720_ffe2, + 0xe18f_94be_e27c_8a57, + 0x0b02_9621_73bb_a343, + 0x1aff_13c8_1bda_47e8, + ]), + ], + [ + Fp::from_raw([ + 0x5713_be57_efac_6c07, + 0xd3f3_1de1_a3b5_8ff3, + 0xda24_65be_8550_5862, + 0x2104_49db_f5cf_3061, + ]), + Fp::from_raw([ + 0xb93a_d1c3_ee62_9817, + 0x19d1_e2f1_d300_1044, + 0x7d75_cd6d_3c7b_9dbe, + 0x0882_30c2_794e_50c5, + ]), + Fp::from_raw([ + 0x17a4_d6db_b20e_7e3a, + 0x8cce_9a9e_16c7_7056, + 0xda08_dc46_4138_dfc7, + 0x1c40_8c25_6490_b0a1, + ]), + Fp::from_raw([ + 0x90dd_6f55_7e9e_3903, + 0x8f7c_7765_4d58_4404, + 0x22d1_7712_00fb_0765, + 0x0745_17e0_81eb_4c1f, + ]), + Fp::from_raw([ + 0xa05a_df61_e12f_dcbf, + 0xcee5_5305_59d6_cf0f, + 0x8852_4bdb_2036_91b4, + 0x02d0_4e9c_21df_1dbd, + ]), + ], + [ + Fp::from_raw([ + 0xa81d_b32c_f1b6_7b13, + 0xeb9b_4650_dae9_f11a, + 0x82e1_3ebd_75de_3b58, + 0x2eb7_a011_b8bc_e910, + ]), + Fp::from_raw([ + 0xe603_0c18_f0cf_17b5, + 0x4d2a_c6bf_9536_8304, + 0x299f_75d6_e8a8_49b5, + 0x2efd_a77e_d35f_4af0, + ]), + Fp::from_raw([ + 0xc51b_2440_192a_e064, + 0x61a7_3d10_852b_8114, + 0x2edd_beda_6520_6d4f, + 0x0919_9dca_fd50_ce64, + ]), + Fp::from_raw([ + 0x7618_1cb4_216e_1562, + 0xcb65_5d8c_1797_e9fa, + 0x4dd3_19db_666a_75b5, + 0x268c_5cfc_446d_399c, + ]), + Fp::from_raw([ + 0x0128_54ed_a11a_18dc, + 0x97b4_4e91_2cce_6687, + 0x26b0_e9a3_6c80_5786, + 0x2303_a652_c949_0718, + ]), + ], + [ + Fp::from_raw([ + 0x3707_3f4e_fb35_fbdf, + 0xbc53_53eb_1108_68d2, + 0xc3f0_41f3_1dc4_5922, + 0x27c5_3563_b12a_6ee2, + ]), + Fp::from_raw([ + 0x2c27_8f22_615d_2b0e, + 0x9969_b524_8cfe_90f4, + 0xf02b_d82d_0a51_0904, + 0x1201_a87e_af4a_e618, + ]), + Fp::from_raw([ + 0x6cb4_b43d_ab2a_443d, + 0xcafc_b1ba_2c51_e570, + 0xad82_1499_7bb0_69be, + 0x2c43_1694_39fc_d69e, + ]), + Fp::from_raw([ + 0x4fb9_847e_6304_d944, + 0x4f46_cbb3_6d70_2e3c, + 0xea03_c45d_6984_c689, + 0x0683_5973_1535_9040, + ]), + Fp::from_raw([ + 0x7779_5ad3_a798_d183, + 0xb042_5e15_8314_197b, + 0xafb9_3b12_8feb_d16f, + 0x0354_5706_706e_ab36, + ]), + ], + [ + Fp::from_raw([ + 0xedb3_93b7_1a0c_0e6b, + 0x740b_ed23_a6a3_7870, + 0xd35f_1fc0_51b3_1728, + 0x1a33_c254_ec11_7619, + ]), + Fp::from_raw([ + 0xf338_e517_f169_0c78, + 0x6e88_f71e_759b_87e6, + 0x67b0_c002_281c_af99, + 0x1ffe_6968_a447_0cd5, + ]), + Fp::from_raw([ + 0x107f_4e02_e355_b393, + 0x140d_dd5d_2a5c_4483, + 0xecb0_59c8_99fd_80f4, + 0x0fd6_6e03_ba88_08ff, + ]), + Fp::from_raw([ + 0x7be3_396b_7fe0_13ab, + 0x6c86_17a7_bdd5_d74a, + 0x1973_9455_2906_b17e, + 0x263a_b69f_13b9_66f8, + ]), + Fp::from_raw([ + 0x6eb7_e03e_39ba_4046, + 0x3bd8_7d5a_a395_8fdd, + 0x5054_d5a1_65de_413e, + 0x16a4_25e4_7d11_1062, + ]), + ], + [ + Fp::from_raw([ + 0xfcc5_f73a_f913_8d9a, + 0x53cc_31d1_3e39_e909, + 0xad75_2f03_c673_f0e2, + 0x2dc5_10a4_719e_c10c, + ]), + Fp::from_raw([ + 0xcb4a_a709_a945_76e5, + 0x423c_5179_329b_7a82, + 0x1bd1_cad2_3d07_dda3, + 0x24df_8e8d_856c_5b5e, + ]), + Fp::from_raw([ + 0xbdf2_4a6c_dce5_620f, + 0x7628_249a_01b0_9561, + 0x3cd5_c689_15a0_42e8, + 0x2bcc_94ff_4fc3_c76f, + ]), + Fp::from_raw([ + 0xb48b_e868_52da_97df, + 0xd329_5f52_c38c_ffe6, + 0x8de5_4e34_3df7_c429, + 0x076c_1e88_dc54_0c8d, + ]), + Fp::from_raw([ + 0xa990_fb8e_12cb_46e1, + 0xe40e_e160_1120_947d, + 0x1c05_1fb1_2d9a_5e4f, + 0x09b5_f209_a451_ac43, + ]), + ], + [ + Fp::from_raw([ + 0x0683_af75_eb67_7c07, + 0x64e9_424f_55b0_f1ea, + 0xaa88_d6a4_4135_a6ab, + 0x205f_17b0_d872_9e2e, + ]), + Fp::from_raw([ + 0x0cdd_1edf_9f23_7029, + 0x0916_81f0_a417_6172, + 0x9126_38c3_8be0_46cd, + 0x281c_5c68_8836_f6cf, + ]), + Fp::from_raw([ + 0x4afa_44f2_5926_21f5, + 0x009a_44e7_a02e_a50e, + 0x5f4d_6744_8c47_1cf3, + 0x1a05_3e68_78e9_00f4, + ]), + Fp::from_raw([ + 0x8174_2839_d59e_064c, + 0x68ef_cb89_7e7b_bee9, + 0x07fb_7cea_c84e_4f54, + 0x100d_c7d4_26de_be30, + ]), + Fp::from_raw([ + 0x0b1c_b31b_411e_49c8, + 0xb289_05bd_b62c_82c8, + 0xbb87_e2cf_adc8_b75f, + 0x1702_2672_a016_a957, + ]), + ], + [ + Fp::from_raw([ + 0xe0c2_7203_f954_f4d2, + 0x9fb8_b547_182b_170d, + 0x7105_3a87_ebe1_5123, + 0x1086_db7e_2760_fc8b, + ]), + Fp::from_raw([ + 0xb85d_d24f_d758_4064, + 0x2b41_fb65_a185_536f, + 0x0246_0ae4_c294_2fac, + 0x1538_4fe3_9d73_b633, + ]), + Fp::from_raw([ + 0x519e_5513_5770_9008, + 0x47b1_a853_205f_cfb5, + 0x4bf4_abc5_342c_6c74, + 0x2ebb_599f_e913_6d42, + ]), + Fp::from_raw([ + 0xd996_fac6_f4d3_7288, + 0x4cf2_7829_2b4c_e3ee, + 0xfec3_c0f0_542e_4c5a, + 0x1b4b_5e87_cfb9_262c, + ]), + Fp::from_raw([ + 0xb637_febe_659e_5057, + 0xbb4a_7581_bb4f_ba60, + 0x801f_3f82_e302_cafb, + 0x2465_053a_e50b_6885, + ]), + ], + [ + Fp::from_raw([ + 0x6e0a_b9d3_d548_59ef, + 0xda9f_05e1_8b37_08bf, + 0x095c_5bb5_d38f_1b97, + 0x114f_32ed_cdea_09cd, + ]), + Fp::from_raw([ + 0xee28_d8c2_543c_7148, + 0x2e5e_5519_f3d1_8123, + 0x6b38_7cd7_7be7_79ac, + 0x2bc7_0dfe_b2ba_ab2f, + ]), + Fp::from_raw([ + 0x12e4_9bfe_32c0_5415, + 0xa783_48b9_f6ec_68a4, + 0x775e_3a61_ad7e_77b6, + 0x01c9_bf7a_203c_e22b, + ]), + Fp::from_raw([ + 0x9f4a_d00c_cb57_ee9b, + 0x55cf_b575_ff6a_97cd, + 0x7bed_b029_5fbb_cec3, + 0x0514_b0fe_5909_ea88, + ]), + Fp::from_raw([ + 0x03e3_202d_7b6c_1b7e, + 0x2092_520b_12a2_01af, + 0x1a13_2a8b_0589_10a1, + 0x267c_76ec_8193_4cc8, + ]), + ], + [ + Fp::from_raw([ + 0xfb15_1cf7_57bd_e5d6, + 0xf162_2493_ce83_e95c, + 0xc78c_84ba_bbb4_70ad, + 0x2917_0e33_22b3_d8d5, + ]), + Fp::from_raw([ + 0x36dd_596c_a41d_9519, + 0x5c6f_09a4_5486_cab5, + 0xaf33_e5d3_873f_9c33, + 0x019f_6a81_24b1_9e33, + ]), + Fp::from_raw([ + 0x5405_d036_242b_60e9, + 0x009e_d8ea_1715_18ae, + 0x8b34_8e9d_b198_1c27, + 0x1904_aa4d_6908_544a, + ]), + Fp::from_raw([ + 0x3b93_2a47_6455_ff1a, + 0xb3ce_e1de_9dd6_f647, + 0xf7f0_4395_6694_e422, + 0x26f1_7873_949b_c679, + ]), + Fp::from_raw([ + 0xbdca_c9b1_8bc4_8f75, + 0x40c4_7603_1197_131e, + 0x193b_3372_0b8a_a540, + 0x1ac6_68f6_12b8_243c, + ]), + ], + [ + Fp::from_raw([ + 0xa52f_8156_8ef0_663d, + 0xccfb_f855_5be9_796d, + 0x196d_ae45_bf62_4766, + 0x0996_d961_a75c_0d07, + ]), + Fp::from_raw([ + 0x5425_b395_c24f_c819, + 0x74d1_71f9_9c63_febb, + 0xfd50_d1b4_383f_be66, + 0x030c_97e1_b8ca_d1d4, + ]), + Fp::from_raw([ + 0xee22_6f2d_8bd0_848f, + 0xb3e5_23f1_fe50_2642, + 0x3953_3702_55b6_8f89, + 0x06e3_ad6a_4690_0e2d, + ]), + Fp::from_raw([ + 0xa329_8905_88cc_916e, + 0x65cb_94b0_e045_5153, + 0x6b68_80e4_2f98_80f5, + 0x1d6b_3755_331c_d021, + ]), + Fp::from_raw([ + 0x3dd3_8c08_bae5_31f2, + 0xc351_89dc_0b85_ac03, + 0x59b0_4153_5e73_0ac8, + 0x28e4_dcba_4b96_f12a, + ]), + ], + [ + Fp::from_raw([ + 0x7a3b_3e4b_c4a4_7a14, + 0xb071_2a47_6260_376c, + 0x8ccf_484f_2974_b6a6, + 0x08b6_0860_46a8_3550, + ]), + Fp::from_raw([ + 0x8964_3e15_b9bb_3b52, + 0xb6fd_85fb_a6a0_536a, + 0x444b_cec9_7812_019b, + 0x162c_d2ca_7fe3_b5f1, + ]), + Fp::from_raw([ + 0x998c_01c6_4d48_3a76, + 0xb5c9_a9c1_1920_63d1, + 0x05af_5b11_937e_4f5c, + 0x28f1_e03b_aaea_9bbc, + ]), + Fp::from_raw([ + 0x6031_a0bb_6791_ce10, + 0x0127_d2aa_b4aa_7136, + 0xa395_af27_34c2_5faa, + 0x1bdb_0627_78d7_c15d, + ]), + Fp::from_raw([ + 0x5032_9ebd_d247_49cb, + 0x0fc9_8870_b232_4a8b, + 0xcb29_14e8_2962_7e0e, + 0x2375_8395_02e0_9890, + ]), + ], + [ + Fp::from_raw([ + 0xe92d_3361_1ed7_bb50, + 0x332d_c87c_fb2d_f456, + 0xad7c_5566_8dc9_423a, + 0x1fa8_662f_bcb6_1fb3, + ]), + Fp::from_raw([ + 0x3f7f_9736_079d_7694, + 0x46e2_fb2c_47a5_138f, + 0xf870_7f72_1716_c8a4, + 0x1e4f_ad2d_d6b0_a6f1, + ]), + Fp::from_raw([ + 0x61b0_f5f1_3731_ffe7, + 0xba3b_d050_059f_53d2, + 0x6df6_f5fc_dd1f_a788, + 0x2112_56d1_6c72_69fd, + ]), + Fp::from_raw([ + 0xf4a1_079b_12bc_c5a5, + 0xf420_60e5_74dd_a341, + 0x4f8e_2a2e_6af0_8318, + 0x2e49_084b_336e_ceaa, + ]), + Fp::from_raw([ + 0x758d_2589_1fb0_0bb9, + 0x1aec_ea08_dfe1_4cab, + 0x3bf3_5192_ac68_0821, + 0x0ce1_9f54_cdc3_9f7f, + ]), + ], + [ + Fp::from_raw([ + 0x84a8_468b_ab2c_14cb, + 0x8dc6_0451_e4ae_4e1c, + 0x3cc3_9422_1261_d874, + 0x0011_c5d5_6c39_0e89, + ]), + Fp::from_raw([ + 0x14a8_cd80_5157_9b4c, + 0xca60_e17b_fa39_b475, + 0x8a9e_05ee_6af3_dbb7, + 0x17d7_9ff0_6b63_ac2a, + ]), + Fp::from_raw([ + 0xcab0_0173_6390_15fa, + 0xb1a8_b35c_d641_6a2e, + 0xdc74_5600_9359_2b06, + 0x19a7_d3a4_46cb_5393, + ]), + Fp::from_raw([ + 0xaa6c_3c97_2370_37a6, + 0x31f0_4596_d892_8da7, + 0x2a80_8b2e_1b92_82f3, + 0x030c_00a0_933d_cdba, + ]), + Fp::from_raw([ + 0x9370_be8a_ab64_139c, + 0x935d_2d00_184c_4acc, + 0xae25_ad08_0695_382e, + 0x16bc_b447_ce2d_50f3, + ]), + ], + [ + Fp::from_raw([ + 0x3925_5b7c_d66f_eb1d, + 0xe621_24f3_7cab_7b6d, + 0x5ea4_ec87_1531_2997, + 0x1234_1b46_b015_0aa2, + ]), + Fp::from_raw([ + 0xdc89_212d_b6a4_9ff4, + 0x002f_c28e_296d_1044, + 0xb72a_97b2_bf61_0c84, + 0x0e86_d139_17f4_4050, + ]), + Fp::from_raw([ + 0xd059_025b_110c_7262, + 0x1052_a181_f8f2_eb14, + 0xd357_e00b_53d7_f30d, + 0x08e6_eb40_89d3_7d66, + ]), + Fp::from_raw([ + 0xe10c_48ce_97ca_7b18, + 0x0415_ccb3_51a1_e0ce, + 0x4738_d15d_d148_1a0c, + 0x2ea1_2385_6245_f6c8, + ]), + Fp::from_raw([ + 0x664d_b0f9_c84d_fa6f, + 0x4195_7890_2541_3abf, + 0x3446_e003_30b1_6310, + 0x2dca_72b2_ebca_b8c2, + ]), + ], + [ + Fp::from_raw([ + 0xc64a_26cb_d42b_6a6b, + 0xf2f6_b423_5f03_6fa4, + 0x6332_9f58_5ec9_24b3, + 0x06ff_9ed5_0d32_7e84, + ]), + Fp::from_raw([ + 0xc630_a453_5afb_f730, + 0xe2a6_0e0c_ca84_ea2a, + 0x47f7_c9bd_a3d5_4df8, + 0x246a_10b7_e3e0_0899, + ]), + Fp::from_raw([ + 0x5c96_b39d_688b_6691, + 0x2f84_6a71_5ae6_7ad7, + 0x1871_9ed9_9d70_0ee5, + 0x22a6_3501_c5f0_4b90, + ]), + Fp::from_raw([ + 0x40ec_07e5_14fa_e937, + 0xb916_4f58_351d_8aa1, + 0x7179_9ac5_d2e2_24cd, + 0x2f4c_5047_7f7f_d9c6, + ]), + Fp::from_raw([ + 0x0cda_32ca_d851_567e, + 0x38f0_ba8a_4a23_d4b5, + 0x13b1_7f4d_876d_9a1e, + 0x10ff_b7aa_d1f5_1c7d, + ]), + ], + [ + Fp::from_raw([ + 0x1a05_6935_c358_03ae, + 0x7840_2735_2187_e7af, + 0xa4d3_9722_532d_5420, + 0x0e9c_efdd_c3c2_d3be, + ]), + Fp::from_raw([ + 0xa3e8_3bdd_4ba6_2b41, + 0xa165_6f96_a33c_8978, + 0xc233_52e6_dc6e_a4af, + 0x07af_84a4_d314_1e7a, + ]), + Fp::from_raw([ + 0xe940_f3ec_8a22_c3c5, + 0x1a39_323d_6e89_b638, + 0xf8de_00d1_4b1e_566d, + 0x2d9e_31a1_0aeb_c761, + ]), + Fp::from_raw([ + 0x7656_747b_e27e_64c7, + 0xd360_34b3_14da_d844, + 0x33db_1afd_592f_66f1, + 0x27f1_9a65_32e6_6b53, + ]), + Fp::from_raw([ + 0x7e4d_617d_47d0_7ffd, + 0x180e_d99f_8f31_55cd, + 0x54b2_024c_3b4a_577a, + 0x0058_fa3c_8454_d633, + ]), + ], + [ + Fp::from_raw([ + 0x7089_6495_6816_a5d5, + 0xb041_4a20_5d3a_175d, + 0x6795_7c08_0699_343e, + 0x0416_27b6_715b_7809, + ]), + Fp::from_raw([ + 0x8988_8f12_b727_c52d, + 0xd982_0147_1cf1_f665, + 0x7f63_2e57_b958_ccec, + 0x006a_c49d_d925_3edc, + ]), + Fp::from_raw([ + 0xec46_a6bf_1830_1398, + 0xec0c_9c0d_6d25_a9a4, + 0xb1d8_c361_6bbe_3386, + 0x0131_adff_d8bd_7254, + ]), + Fp::from_raw([ + 0xcf03_0e1c_d8f9_f5b6, + 0x7797_7ad7_e25e_49a3, + 0x4138_e413_ef62_a283, + 0x1c4a_6f52_c9fc_cf7a, + ]), + Fp::from_raw([ + 0xd1f7_958d_2c26_45f6, + 0xfee0_48ae_2078_aeb7, + 0x9465_51b3_860e_a479, + 0x03f2_a6be_51ec_677f, + ]), + ], + [ + Fp::from_raw([ + 0x4d73_7639_6b8d_dc62, + 0x8a13_72d8_5431_1956, + 0x391a_0cb7_8ef3_a964, + 0x2da7_70aa_d2c2_eb09, + ]), + Fp::from_raw([ + 0x3806_2afb_75d6_4a03, + 0xc9d4_5fe8_66c3_59c7, + 0xdc18_02fe_bfab_02ce, + 0x1527_8463_665f_74cd, + ]), + Fp::from_raw([ + 0x8d58_0638_ac54_c773, + 0x34e3_8ea9_66a0_8a6f, + 0xc973_1027_0905_18d4, + 0x12fe_278a_a365_44ea, + ]), + Fp::from_raw([ + 0x21b0_6ff3_0b6a_23b6, + 0xd858_7604_ca4f_0d6e, + 0x4c45_d119_d3f4_cc7f, + 0x149b_9c80_2182_558a, + ]), + Fp::from_raw([ + 0x0adc_4959_b691_dfe4, + 0x55e0_44fd_60db_ac9a, + 0x17d1_9319_772f_3c98, + 0x0812_e7b4_d847_bc85, + ]), + ], + [ + Fp::from_raw([ + 0x2a66_9737_03a0_c61b, + 0x5558_13c7_e750_3aea, + 0xd8df_7f28_a0bf_aa7f, + 0x02ed_8d8d_deaf_e3d9, + ]), + Fp::from_raw([ + 0xa130_4038_662d_4db8, + 0x55e5_e4d9_a03d_6b6b, + 0x4deb_6029_f921_029e, + 0x0ebd_073b_a053_7b51, + ]), + Fp::from_raw([ + 0x44ee_75b6_2eff_9f59, + 0x55b3_e792_c6af_a08b, + 0x05c6_ba8d_2ccd_0282, + 0x15c7_54d5_b14b_2c42, + ]), + Fp::from_raw([ + 0xc29e_7cbc_30e8_732a, + 0x1cc1_2352_70f4_cbc5, + 0xb0ed_8fa6_fa31_1b39, + 0x1695_15c8_9ac5_479d, + ]), + Fp::from_raw([ + 0x6d91_61f5_cd9a_4fef, + 0x08bd_c29f_6ff0_3769, + 0x2388_f262_1001_1016, + 0x2547_9fbf_b3a6_8f98, + ]), + ], + [ + Fp::from_raw([ + 0xce09_486e_94be_6071, + 0xa7f8_e6e9_7218_2196, + 0x3c85_2cb0_311a_578c, + 0x1447_5c4b_d520_451f, + ]), + Fp::from_raw([ + 0x5c4e_7336_3d09_7799, + 0xd3a8_4750_2aec_8d5f, + 0xc9ba_f279_8833_a1df, + 0x045a_6910_66cc_66be, + ]), + Fp::from_raw([ + 0x013b_8bcb_37eb_a683, + 0x147a_8ca0_3722_1b90, + 0xb833_ac8a_11e3_a3f0, + 0x2602_9c0c_267c_799f, + ]), + Fp::from_raw([ + 0xb810_1d5b_948d_1641, + 0x73ce_12a6_a94a_3e45, + 0xf7c9_4696_9c1c_2608, + 0x163f_acb3_4ff5_72fb, + ]), + Fp::from_raw([ + 0xaf8e_e00c_4240_ee28, + 0x13e0_6a62_75e5_8688, + 0x1d96_9320_cc69_d5ec, + 0x2c71_4e96_e191_3b35, + ]), + ], + [ + Fp::from_raw([ + 0xd52b_804e_ff1d_5fa6, + 0xddd6_268f_06de_bfe2, + 0x5aba_8466_5ecd_2bf9, + 0x1c16_61e2_a7ce_74b7, + ]), + Fp::from_raw([ + 0xa8c3_c068_b7dc_2c71, + 0x6635_b34c_2a08_89fe, + 0x5e5a_f3e6_619a_47d2, + 0x06a6_9ae7_95ee_9bfe, + ]), + Fp::from_raw([ + 0x3141_6c85_d731_d46a, + 0x74db_dbad_f541_95c7, + 0xc5d2_8b4c_19a3_6093, + 0x113d_5853_5d89_2115, + ]), + Fp::from_raw([ + 0x2ca1_a740_63b4_6101, + 0xe534_f1ff_47f7_917a, + 0x38ff_97d7_61da_6042, + 0x2ab8_9102_e2b8_d5e6, + ]), + Fp::from_raw([ + 0x3980_4fd6_a15a_d1b3, + 0x3490_3189_3da2_b4fd, + 0x9627_30c4_5e69_9546, + 0x03c1_1ca7_9e41_fdfe, + ]), + ], + [ + Fp::from_raw([ + 0x6adf_040f_aaf2_669c, + 0xf7f6_7b4d_4cfe_846c, + 0x8801_4ddb_bbfc_9da1, + 0x2709_6c67_2621_4038, + ]), + Fp::from_raw([ + 0xaa9d_c2b5_7ef5_be0d, + 0x66db_790c_e486_130c, + 0xd504_d4de_eb53_b13c, + 0x2de3_2ad1_5497_aef4, + ]), + Fp::from_raw([ + 0x2557_5444_8eef_d001, + 0x28c7_38dd_daec_9f3d, + 0xfd5d_3413_1072_2a2d, + 0x0dc1_08f2_b0a2_80d2, + ]), + Fp::from_raw([ + 0x7d34_ca50_365d_832f, + 0xbcdc_3eeb_c409_be7c, + 0xc968_58a1_bb9e_fad5, + 0x1869_f3b7_63fe_8164, + ]), + Fp::from_raw([ + 0x8c6d_3376_7129_682d, + 0xb616_945e_16a5_68d4, + 0xf825_59fe_6a91_1843, + 0x022e_d3a2_d9ff_31cb, + ]), + ], + [ + Fp::from_raw([ + 0x10c6_aec0_77d0_26bc, + 0x92fc_a1f2_7c19_c266, + 0x3944_ed13_65bd_0e72, + 0x2155_d600_5210_169e, + ]), + Fp::from_raw([ + 0x3ea5_928c_8cae_ae85, + 0xec0c_0556_c91a_f3db, + 0xcae9_3263_f5f1_b4bb, + 0x0de1_ba7a_562a_8f7a, + ]), + Fp::from_raw([ + 0x6351_dfa7_da90_2563, + 0x126f_740b_ce8d_637b, + 0xcfce_5bf4_6ec7_da38, + 0x05db_b440_6024_beab, + ]), + Fp::from_raw([ + 0xc97e_5427_a368_fd5e, + 0x00e7_89e3_fcd7_2dcc, + 0xd4d8_dc8a_d778_d32c, + 0x05d4_149b_aac4_13be, + ]), + Fp::from_raw([ + 0x9212_e221_72c2_7b2e, + 0xf0b6_802f_a941_c787, + 0x9be5_046e_7397_e76f, + 0x01cd_f8b4_52d9_7c2b, + ]), + ], + [ + Fp::from_raw([ + 0x1b0a_2227_9d46_c07c, + 0xc4d7_c501_5ece_d8c7, + 0xaf80_85ff_81ad_ce33, + 0x1fc6_a718_6702_7f56, + ]), + Fp::from_raw([ + 0x568e_0fda_96aa_afc2, + 0xa9e1_85b7_5306_d9c3, + 0x5d4d_59a5_a7a3_a42b, + 0x1040_bef4_c642_d034, + ]), + Fp::from_raw([ + 0xa808_1475_ab8f_ad0d, + 0x2b21_e956_7643_1918, + 0xff2c_91b2_8933_4a4d, + 0x16b7_9c3a_6bf3_16e0, + ]), + Fp::from_raw([ + 0x3cbe_1cdc_d59f_474e, + 0xa340_70e5_2b60_1fc1, + 0x434b_3a13_87e3_c8c6, + 0x20df_f1bc_30f6_db6b, + ]), + Fp::from_raw([ + 0xdfb7_fd85_12ae_060d, + 0x062d_d417_1a72_6a8b, + 0xc254_9550_30a9_70f8, + 0x0212_ac2a_b7a6_eaae, + ]), + ], + [ + Fp::from_raw([ + 0x13c8_119f_6996_ae09, + 0xb02d_c031_34f0_0442, + 0x869a_109c_9215_637c, + 0x2f29_3774_9147_4442, + ]), + Fp::from_raw([ + 0x5837_d9f3_2d81_4bfa, + 0x73be_9f38_66aa_284c, + 0x25ec_93c3_3fea_6032, + 0x0984_ca6a_5f91_85d5, + ]), + Fp::from_raw([ + 0xeb0e_e929_4b24_f028, + 0xe491_361c_8a6b_d19c, + 0x0d29_9bd6_fa81_220d, + 0x0d08_0a6b_6b3b_6070, + ]), + Fp::from_raw([ + 0xce92_9ed7_c85a_4544, + 0x21ac_c85b_6400_264d, + 0x6789_5306_38cb_0ad8, + 0x0e65_cd99_e84b_052f, + ]), + Fp::from_raw([ + 0x5597_5da1_2736_920b, + 0xe30e_3d20_380f_f6a6, + 0x4808_f72c_716c_d05e, + 0x2e20_8875_bc7a_c122, + ]), + ], + [ + Fp::from_raw([ + 0x4a60_d1aa_8592_bad5, + 0xae2e_3b89_4afd_29f6, + 0x76a0_b0ff_3d7d_fac1, + 0x2989_f3ae_477c_2fd3, + ]), + Fp::from_raw([ + 0x3a74_c3ce_a718_9459, + 0x9181_06a4_6329_0a3e, + 0x9222_d101_e6fa_c0ce, + 0x1136_1ce5_44e9_4137, + ]), + Fp::from_raw([ + 0x34c8_bd05_a206_1438, + 0xd122_a822_b8fb_366c, + 0xa539_e10c_173f_6a75, + 0x1e8d_014b_86cb_5a7d, + ]), + Fp::from_raw([ + 0x212e_e2c2_8ee9_8733, + 0xa0c2_3241_67ef_6c91, + 0x7ba8_12ad_2955_8e23, + 0x173f_65ad_ec8d_eee2, + ]), + Fp::from_raw([ + 0x991b_d695_310e_ddd9, + 0x5da5_df7a_d454_99d0, + 0xafee_8bd0_c779_ac3e, + 0x01c3_6daa_f9f0_1f1b, + ]), + ], + [ + Fp::from_raw([ + 0x4a6f_5741_f381_e562, + 0xf277_d1a3_f2fc_8994, + 0xaa9a_b1c4_85bb_85ff, + 0x1353_acb0_8c05_adb4, + ]), + Fp::from_raw([ + 0x20f1_c87a_3b06_4d34, + 0x009d_33de_b4f9_3aeb, + 0x1860_e71e_a118_8ee4, + 0x2e5a_bd25_3720_7cad, + ]), + Fp::from_raw([ + 0x4217_26ba_8f69_455c, + 0x13de_b4eb_3491_3a13, + 0xd02e_edbb_7ab8_5625, + 0x191d_5c5e_daef_42d3, + ]), + Fp::from_raw([ + 0xee79_39dd_2dcd_089e, + 0x82a0_4c74_c127_de9d, + 0x82a2_63fe_a6d7_599d, + 0x11d7_f8d1_f269_2642, + ]), + Fp::from_raw([ + 0x1bad_0852_86ca_c971, + 0x3445_cb4c_d6bc_6f95, + 0x90f7_9ad5_e679_9797, + 0x0421_8fde_3668_29ed, + ]), + ], + [ + Fp::from_raw([ + 0x27b7_1c73_0d76_d6dd, + 0x027b_73b4_8930_1c32, + 0x0483_97ca_5f47_a202, + 0x0070_772f_7cf5_2453, + ]), + Fp::from_raw([ + 0xc1dc_04db_e3d2_b861, + 0x6768_1a98_cd05_1634, + 0xc865_b065_687a_1d9b, + 0x038a_389b_aef5_d9a7, + ]), + Fp::from_raw([ + 0xf198_6078_9015_a6e5, + 0x0f39_d009_66a5_0bea, + 0xcda4_46b2_b4b5_9ccd, + 0x09a5_eefa_b8b3_6a80, + ]), + Fp::from_raw([ + 0x9d16_212c_7584_cd8c, + 0x3d9e_c99e_dfac_b748, + 0xb969_c145_109b_4b58, + 0x01b5_8884_8b8b_47c8, + ]), + Fp::from_raw([ + 0xfed9_1e30_d429_54a6, + 0x545e_5abf_a323_d817, + 0x6e1a_f6df_c334_1419, + 0x0b84_6e4a_390e_560f, + ]), + ], + [ + Fp::from_raw([ + 0x85ca_bfe8_5ce7_2fe3, + 0xeb15_13bc_394f_c4f9, + 0x0d43_a02d_db90_0040, + 0x23a6_679c_7d9a_db66, + ]), + Fp::from_raw([ + 0xf72f_31d6_fe08_9254, + 0x4c34_02fb_7c85_eccc, + 0x3e5c_aa35_f135_1e9f, + 0x2e03_74a6_9919_7e34, + ]), + Fp::from_raw([ + 0x37d4_1913_a7a2_7b48, + 0x4b8c_c0b1_176b_b9ec, + 0x7f7a_08af_4cde_3ff6, + 0x0752_cd89_9e52_dc4d, + ]), + Fp::from_raw([ + 0x99e2_873d_d7ae_55a7, + 0x0275_142b_664b_802c, + 0xc349_a2b6_d573_97a5, + 0x068f_8813_1272_99da, + ]), + Fp::from_raw([ + 0xb374_330f_2da2_02b5, + 0x8687_2d04_a295_b5b8, + 0x6775_7416_7434_b3f9, + 0x2ba7_0a10_2355_d549, + ]), + ], + [ + Fp::from_raw([ + 0xb860_9e70_a0b5_0828, + 0x09f9_099b_825d_d289, + 0xa334_d1df_03b5_5213, + 0x2c46_7af8_8748_abf6, + ]), + Fp::from_raw([ + 0x96d2_9e57_63e8_f497, + 0xe3a5_2c2d_1a31_9572, + 0x0100_9a2b_448a_e881, + 0x05c5_f20b_ef1b_d827, + ]), + Fp::from_raw([ + 0x3ac8_c9fe_61b7_3871, + 0x0cd0_83a2_c649_d9f2, + 0x842a_381f_6006_e2c6, + 0x0dc6_385f_dc56_7be5, + ]), + Fp::from_raw([ + 0xd255_baa8_114b_369c, + 0x0378_d5b8_4150_d25e, + 0x19d4_9911_b867_0fa7, + 0x142d_3983_f3dc_7f7e, + ]), + Fp::from_raw([ + 0x00fa_18c1_b2df_67bf, + 0xf36f_86a7_a99a_a35c, + 0xfd7e_6d98_c96a_0fa0, + 0x29a0_1efb_2f6a_a894, + ]), + ], + [ + Fp::from_raw([ + 0xd2a1_af04_eb61_3a76, + 0x0ab9_e8af_c645_55b7, + 0x38c4_a506_6644_ec63, + 0x0525_ffee_737d_6051, + ]), + Fp::from_raw([ + 0xf177_cf42_3830_1dc8, + 0x7e16_4f61_4910_264e, + 0xf076_677c_a0e8_2276, + 0x1e80_7dca_81d7_9581, + ]), + Fp::from_raw([ + 0xdba5_6082_dbd8_757c, + 0x4c02_23e0_f733_a52f, + 0x9351_0816_4724_74d3, + 0x0385_fb3f_89c7_4dc9, + ]), + Fp::from_raw([ + 0xf558_f337_bab0_ea01, + 0xcfab_d701_6fd6_ef1a, + 0xe1a6_298e_53ca_e59f, + 0x0376_40dc_1afc_0143, + ]), + Fp::from_raw([ + 0xb7e4_c0de_8960_74b4, + 0x5fd5_6cf0_31da_8050, + 0xf12a_6c52_6082_9eee, + 0x1341_999a_1ed8_6919, + ]), + ], + [ + Fp::from_raw([ + 0x7b24_4f65_bed8_ece7, + 0x73af_d642_efdc_c565, + 0x5690_6d4b_afb1_0ad7, + 0x069e_b075_866b_0af3, + ]), + Fp::from_raw([ + 0xea19_09a6_1903_3696, + 0xd272_6101_d3af_aa02, + 0x95b3_8e8e_08b3_e646, + 0x171c_0b81_e621_36e3, + ]), + Fp::from_raw([ + 0x5575_1075_02ac_ced8, + 0xcbbd_cb39_bfe6_96f9, + 0xb6eb_55c3_1175_3e84, + 0x2c81_814c_9453_f51c, + ]), + Fp::from_raw([ + 0xe39b_8a86_a7c3_a604, + 0xb04b_3903_2adc_a92c, + 0xe3b3_3fad_cf27_4b2a, + 0x29d8_43c0_415d_35d9, + ]), + Fp::from_raw([ + 0xa766_9cf3_fae7_728b, + 0xd8e1_5ea5_947f_2cda, + 0x8436_bccd_abb7_8750, + 0x085d_6a10_70f3_513d, + ]), + ], + [ + Fp::from_raw([ + 0x9e2a_5cda_412f_c394, + 0xdbf1_dd4e_6706_b02c, + 0x10a4_4ba6_65bf_302c, + 0x1182_0363_ed54_1daa, + ]), + Fp::from_raw([ + 0x1058_40b7_51a1_6317, + 0xdfd3_150e_05f1_df5d, + 0x02b6_0d61_a837_85bd, + 0x2019_35a5_8f5c_57fc, + ]), + Fp::from_raw([ + 0xcfed_610e_87c0_2e9a, + 0x4679_4eed_d686_cd8e, + 0xe27a_952a_bd33_a03d, + 0x0a8c_2820_c569_71aa, + ]), + Fp::from_raw([ + 0xd50d_bc16_3a28_1877, + 0x650b_65ff_33e6_be1f, + 0x04ab_d6d0_bd75_00b6, + 0x1806_38ff_301a_64ca, + ]), + Fp::from_raw([ + 0x3e9b_321a_812d_d36b, + 0xf85c_a8a9_37cf_bec6, + 0x044f_9711_4a41_58a3, + 0x095c_7162_66f1_de59, + ]), + ], + [ + Fp::from_raw([ + 0x8d40_87a4_97d7_3490, + 0x83b6_18c5_c1a6_8781, + 0x20d8_6ffe_d6c7_ca15, + 0x17c3_1ea0_2fbc_3783, + ]), + Fp::from_raw([ + 0xe4d5_0a77_f192_a91b, + 0x3c17_a976_4ccd_660d, + 0x6a72_27e4_192d_149d, + 0x05b8_6c4b_b8ef_318b, + ]), + Fp::from_raw([ + 0xd6ce_74ba_986c_7a7b, + 0xab15_f4a6_ae0d_237c, + 0x6ff7_0d7e_a2fd_e2c7, + 0x265b_c95d_f4a4_c487, + ]), + Fp::from_raw([ + 0xd6c8_86d4_715c_7929, + 0x0870_1739_c5f5_b4b3, + 0xd9bb_e48f_5fef_2f69, + 0x2475_2b47_bc6c_6bc8, + ]), + Fp::from_raw([ + 0xe583_b932_4d97_4efe, + 0x78d6_24b9_8da9_6ee5, + 0xa0d8_6e52_7a96_4821, + 0x1481_4a1e_0f49_2a4e, + ]), + ], + [ + Fp::from_raw([ + 0xc752_3bca_906f_00bd, + 0x997c_8e04_1d3c_fb3d, + 0xbd60_5773_78f2_9381, + 0x10de_f931_073b_6479, + ]), + Fp::from_raw([ + 0x1b45_92c9_8610_175f, + 0xfa0b_880d_28c6_9d03, + 0x7f70_6c0d_8ab4_ed03, + 0x14f7_ae77_0bf7_e95f, + ]), + Fp::from_raw([ + 0x75c5_cc9d_ce1c_e589, + 0x9dec_c9d4_28eb_e4e7, + 0x9f92_6af4_0e80_35d1, + 0x1aef_50a0_cee7_51b5, + ]), + Fp::from_raw([ + 0x9512_14b5_7e73_cf5a, + 0x086c_2a2d_57d0_9602, + 0xba65_ca60_068d_fe3b, + 0x0419_3560_7172_f68e, + ]), + Fp::from_raw([ + 0x37a1_51d3_bf45_2cb8, + 0x0493_fbef_e83c_8198, + 0x573b_d083_959b_856c, + 0x2686_3e9d_d242_55d1, + ]), + ], + [ + Fp::from_raw([ + 0x6527_38e6_3ff8_b3af, + 0xf5ad_f251_ba62_052c, + 0xeb3d_7a06_8bd0_87c9, + 0x2036_efb6_f983_0965, + ]), + Fp::from_raw([ + 0xb00f_a4f1_b4f4_ee9b, + 0x30be_4f75_a753_f854, + 0x766b_639a_0299_69ca, + 0x0c71_2a97_5b74_dc9d, + ]), + Fp::from_raw([ + 0x3757_31d3_8753_9699, + 0x7afd_ff64_5649_2ca3, + 0x27af_c99b_fac1_e680, + 0x0801_4dab_3cd1_667e, + ]), + Fp::from_raw([ + 0xb530_09f7_9b34_e6a4, + 0x97c4_dd4d_37b4_e8f3, + 0xa82a_4a79_839d_6a2b, + 0x198d_0719_2db4_fac2, + ]), + Fp::from_raw([ + 0xfd15_784d_1f63_e572, + 0x2709_b29d_53bb_946d, + 0xb23b_4131_4268_97a3, + 0x29eb_1de4_2a3a_d381, + ]), + ], +]; +// n: 254 +// t: 5 +// N: 1270 +// Result Algorithm 1: +// [True, 0] +// Result Algorithm 2: +// [True, None] +// Result Algorithm 3: +// [True, None] +// Prime number: 0x0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 +// MDS matrix: +pub(crate) const MDS: [[Fp; 5]; 5] = [ + [ + Fp::from_raw([ + 0x4fc6_fdbc_f38d_7da1, + 0x9f22_e57a_ce3c_d7f6, + 0x080b_0af1_33b9_e436, + 0x251e_7fdf_9959_1080, + ]), + Fp::from_raw([ + 0x4855_0486_e91c_7765, + 0xfe26_ea9c_a238_d6e3, + 0x47cb_d3b1_c17d_97c7, + 0x25fb_50b6_5acf_4fb0, + ]), + Fp::from_raw([ + 0x6ea1_e31e_d576_7833, + 0x6deb_5325_f367_a455, + 0x355f_39eb_f62f_91b0, + 0x293d_617d_7da7_2102, + ]), + Fp::from_raw([ + 0x6145_f14b_a6d3_c1c4, + 0x6659_9e57_5a9b_7edf, + 0x9601_11ac_25da_4743, + 0x104d_0295_ab00_c85e, + ]), + Fp::from_raw([ + 0x3ed5_b90f_2f69_c977, + 0x792b_3813_954f_e9bf, + 0x7dea_3e33_6cd9_6a39, + 0x0aaa_35e2_c84b_af11, + ]), + ], + [ + Fp::from_raw([ + 0x69f6_61b2_eb74_c839, + 0x0529_03dc_6609_ea69, + 0xc03e_17c1_d1dc_db02, + 0x2a70_b9f1_d4bb_ccdb, + ]), + Fp::from_raw([ + 0x115b_8e2e_991c_cd7a, + 0xba9f_92ad_8ef4_b979, + 0x6315_a993_4f1b_8a1b, + 0x2811_5465_1c92_1e74, + ]), + Fp::from_raw([ + 0xb86a_894f_7db3_6c37, + 0x8ccd_8fdb_9ee2_b45f, + 0x0b53_c732_134e_fa33, + 0x28c2_be2f_8264_f95f, + ]), + Fp::from_raw([ + 0xc4ec_8fa7_5e53_0a13, + 0x9b62_6d8c_b4dc_18dc, + 0x6d42_7c89_0b18_83bb, + 0x2188_8041_e6fe_bd54, + ]), + Fp::from_raw([ + 0x350d_65e2_cbff_4941, + 0xe810_930e_3ea4_574a, + 0x8019_5b95_92d8_cf2b, + 0x14dd_b5fa_da01_71db, + ]), + ], + [ + Fp::from_raw([ + 0xa4fa_8478_970d_401d, + 0x55b9_1bff_652a_d69a, + 0xdea4_3265_306a_37ed, + 0x2f69_a719_8e1f_bcc7, + ]), + Fp::from_raw([ + 0x6d6a_3747_594d_3052, + 0x67ba_312b_3414_0e71, + 0xad93_1ab8_0e37_bbb2, + 0x001c_1edd_6264_5b73, + ]), + Fp::from_raw([ + 0xa7f9_a4b2_28bf_c32b, + 0x39c4_0c60_3049_466f, + 0xce2f_2c96_c696_63c4, + 0x15b9_8ce9_3e47_bc64, + ]), + Fp::from_raw([ + 0x6505_1de3_3163_cf9c, + 0xcba8_458b_28e4_4d92, + 0x58f6_5be2_fbac_809f, + 0x12c7_e2ad_fa52_4e59, + ]), + Fp::from_raw([ + 0x531e_c2de_53bb_d167, + 0xaf67_ce79_816e_f468, + 0x4901_8222_e7b8_922e, + 0x2efc_2b90_d688_1348, + ]), + ], + [ + Fp::from_raw([ + 0xf1af_d6c5_f721_f830, + 0x3c3f_fa45_50bd_2514, + 0x1981_e55e_3e1a_29a1, + 0x0c3f_050a_6bf5_af15, + ]), + Fp::from_raw([ + 0xeda7_7843_20a1_a36e, + 0x8b2e_fe2e_cd42_4a73, + 0xfa75_ba79_92bd_34f0, + 0x0dec_54e6_dbf7_5205, + ]), + Fp::from_raw([ + 0x7cc7_5cf3_2d81_36fa, + 0x9836_4a11_f4d9_88fb, + 0x2022_5815_034b_1960, + 0x1c48_2a25_a729_f5df, + ]), + Fp::from_raw([ + 0xb8b6_07ae_9fd8_514a, + 0x0812_ac2f_c9a1_4a5f, + 0x5273_2624_e4ab_9436, + 0x2625_ce48_a7b3_9a42, + ]), + Fp::from_raw([ + 0x9fb9_f28a_f710_251f, + 0xed7e_f8e3_00b9_a8bb, + 0x86f7_cd4f_d710_c509, + 0x07f0_17a7_ebd5_6dd0, + ]), + ], + [ + Fp::from_raw([ + 0xe2f7_8c2c_cc2e_3595, + 0x7c5e_55c2_0146_259b, + 0xf97c_9d61_86c6_c3ea, + 0x2a20_e3a4_a0e5_7d92, + ]), + Fp::from_raw([ + 0x403b_01fe_b727_a549, + 0x7016_73ae_d820_d9c4, + 0xaafb_1e9a_5d63_c0ee, + 0x1049_f821_0566_b51f, + ]), + Fp::from_raw([ + 0x61b9_299b_82d6_9c8e, + 0xef35_7a69_e3e8_6b55, + 0x6800_2bd9_d1b9_6b4b, + 0x02ec_ac68_7ef5_b4b5, + ]), + Fp::from_raw([ + 0xd4eb_cf11_bbe1_e37b, + 0xbdcb_6b58_ba40_441e, + 0x6808_f88c_9ba9_03d3, + 0x2d3a_1aea_2e6d_4446, + ]), + Fp::from_raw([ + 0xc98d_803b_fed6_5e64, + 0xb39c_4a7a_72db_b6d9, + 0xc9ad_171e_4f35_fe49, + 0x1407_4bb1_4c98_2c81, + ]), + ], +]; + +// Inverse MDS matrix: +pub(crate) const MDS_INV: [[Fp; 5]; 5] = [ + [ + Fp::from_raw([ + 0x0a07_b795_463d_35d5, + 0xfa40_1f28_8668_6830, + 0x5530_d7a8_f9f8_9493, + 0x164c_e768_9cd3_4e71, + ]), + Fp::from_raw([ + 0xd023_820e_b560_9d5c, + 0x12b2_b6d1_8e5b_b2fc, + 0xf20e_a20e_014a_394a, + 0x1db3_93d0_c226_3141, + ]), + Fp::from_raw([ + 0x0036_4d7e_376c_668a, + 0x6384_229a_60b5_b10e, + 0xc5c1_feea_7573_b0bd, + 0x2ea4_b39c_798c_b58f, + ]), + Fp::from_raw([ + 0x9d41_b342_029b_a735, + 0x81bd_3a5a_0ed0_4aed, + 0x32f7_e059_1681_966b, + 0x2d2b_4966_cbb1_a878, + ]), + Fp::from_raw([ + 0x6442_41f9_86b0_fed0, + 0xe608_a349_b9dd_3773, + 0x05c8_7598_5566_7af4, + 0x245f_6aa5_4869_51fc, + ]), + ], + [ + Fp::from_raw([ + 0x44ed_2060_93d6_aabd, + 0x1b4b_d6e6_9583_8469, + 0xd986_605b_83ae_1016, + 0x2ee7_5426_48a7_61d8, + ]), + Fp::from_raw([ + 0x1519_0ef0_969c_8858, + 0x833b_15f6_f4e4_c37d, + 0x7ed0_b2b9_3fc0_a2a6, + 0x03f8_d436_2488_e27a, + ]), + Fp::from_raw([ + 0x7510_417e_0bb5_e415, + 0x9ddd_05b3_aebe_0373, + 0x5313_8d6d_7efd_5b13, + 0x0d71_55cc_3c81_7a44, + ]), + Fp::from_raw([ + 0x8e6b_f161_2749_b599, + 0xa98d_ded9_0fa5_0d82, + 0x2dd5_fa16_bd6a_ff83, + 0x2a3f_9c29_2dfd_d278, + ]), + Fp::from_raw([ + 0xb9a9_386f_96f8_8ce4, + 0x4584_a3ce_4044_b0db, + 0x6e4a_5dbc_7bbc_2f86, + 0x2ef0_87b9_5a30_db20, + ]), + ], + [ + Fp::from_raw([ + 0x9b0a_dc8b_e22c_2097, + 0x8b3b_3579_9934_113f, + 0x1e46_b9c6_5795_09bf, + 0x268b_8879_63db_67de, + ]), + Fp::from_raw([ + 0x2b8e_5163_2fdd_069d, + 0x2a8a_52a7_6b3b_1707, + 0xd25c_3c95_da1d_1f6e, + 0x07c4_cf63_17d3_1876, + ]), + Fp::from_raw([ + 0xfd70_2b37_cca4_7eae, + 0xcd50_3388_d240_f0a3, + 0x9621_c484_9c42_8d51, + 0x1bb9_9031_ff61_99b8, + ]), + Fp::from_raw([ + 0xe85d_b447_c038_bd9b, + 0x2ea1_4994_16b4_849e, + 0x30bc_6db6_5916_28d5, + 0x2bb7_f772_403e_18b5, + ]), + Fp::from_raw([ + 0xa70f_45bf_661b_a481, + 0x0242_4059_a4aa_f101, + 0x5d41_bdd3_ccf8_e33f, + 0x07d1_50a7_2e22_cdd1, + ]), + ], + [ + Fp::from_raw([ + 0x9305_cd67_3be8_ad9e, + 0xbcd5_922e_8e81_b550, + 0xa06a_0858_2093_30f5, + 0x1aea_063d_15e7_adc4, + ]), + Fp::from_raw([ + 0xe378_276b_fdd3_2f08, + 0x5c33_6747_63c7_7b6b, + 0x438c_2b06_0ec9_9174, + 0x1ab1_8e5f_72e6_7dcc, + ]), + Fp::from_raw([ + 0x3cd9_40ae_057a_9f08, + 0x14e1_9fd3_481b_ad42, + 0xe321_6274_cde2_e859, + 0x1473_c50d_66be_6cbe, + ]), + Fp::from_raw([ + 0xbb73_27dc_2956_b7a0, + 0xc8c6_e6e7_7849_266c, + 0xef9e_e1d4_c8aa_a35a, + 0x262e_f341_6da6_8dcb, + ]), + Fp::from_raw([ + 0x58b0_d3bf_0f3e_2fdc, + 0xe85b_23a5_7fd1_48e7, + 0xd9e0_31c1_0ea9_700d, + 0x229c_fdf3_f130_b726, + ]), + ], + [ + Fp::from_raw([ + 0x9062_3a1f_a068_26c5, + 0xdeff_a4d4_9dfd_b739, + 0xf986_809c_e528_a884, + 0x125e_07c3_24bf_c084, + ]), + Fp::from_raw([ + 0x60db_1afc_a351_100f, + 0x11f1_b42a_4390_9d72, + 0xc1d2_4a0d_c7fb_7b61, + 0x10ef_80f7_94f0_c1ce, + ]), + Fp::from_raw([ + 0x89de_85d9_ecd3_c179, + 0x15b0_d5de_8c2d_49b7, + 0xe31b_fe9d_3806_054c, + 0x1e2f_2d99_8606_58a8, + ]), + Fp::from_raw([ + 0x9a25_4567_4b42_7d94, + 0x107e_cbf4_a7f5_4066, + 0x9afd_5ae4_7f61_3afa, + 0x199f_0a09_d4d0_c2bf, + ]), + Fp::from_raw([ + 0x7497_9f2e_71b0_1a16, + 0x1429_9813_8018_4c81, + 0x0164_dd73_b1a7_c35e, + 0x1cef_d8df_4cfb_e341, + ]), + ], +]; diff --git a/src/chips/poseidon/spec.rs b/src/chips/poseidon/spec.rs index 489abd33..d1153abe 100644 --- a/src/chips/poseidon/spec.rs +++ b/src/chips/poseidon/spec.rs @@ -1,32 +1,38 @@ +//! Specification for rate 4 Poseidon using the BN256 curve. +//! Patterned after [halo2_gadgets::poseidon::primitives::P128Pow5T3] + +use crate::chips::poseidon::rate4_params; use halo2_gadgets::poseidon::primitives::*; -use halo2_proofs::{arithmetic::FieldExt}; -use std::marker::PhantomData; - -// P128Pow5T3 is the default Spec provided by the Halo2 Gadget => https://github.com/privacy-scaling-explorations/halo2/blob/main/halo2_gadgets/src/poseidon/primitives/p128pow5t3.rs#L13 -// This spec hardcodes the WIDTH and RATE parameters of the hash function to 3 and 2 respectively -// This is problematic because to perform an hash of a input array of length 4, we need the WIDTH parameter to be higher than 3 -// Since the WIDTH parameter is used to define the number of hash_inputs column in the PoseidonChip. -// Because of that we need to define a new Spec -// MySpec struct allows us to define the parameters of the Poseidon hash function WIDTH and RATE +use halo2_proofs::arithmetic::Field; +use halo2_proofs::halo2curves::bn256::Fr as Fp; + #[derive(Debug, Clone, Copy)] -pub struct MySpec{ - _marker: PhantomData -} +pub struct MySpec; -impl Spec for MySpec { +pub(crate) type Mds = [[Fp; T]; T]; + +impl Spec for MySpec { fn full_rounds() -> usize { 8 } fn partial_rounds() -> usize { - 56 + 60 } - fn sbox(val: F) -> F { + fn sbox(val: Fp) -> Fp { val.pow_vartime(&[5]) } fn secure_mds() -> usize { - 0 + unimplemented!() + } + + fn constants() -> (Vec<[Fp; 5]>, Mds, Mds) { + ( + rate4_params::ROUND_CONSTANTS[..].to_vec(), + rate4_params::MDS, + rate4_params::MDS_INV, + ) } } diff --git a/src/circuits.rs b/src/circuits.rs deleted file mode 100644 index eb993211..00000000 --- a/src/circuits.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod merkle_sum_tree; \ No newline at end of file diff --git a/src/circuits/merkle_sum_tree.rs b/src/circuits/merkle_sum_tree.rs index a0a5a1ee..87f44a26 100644 --- a/src/circuits/merkle_sum_tree.rs +++ b/src/circuits/merkle_sum_tree.rs @@ -1,31 +1,27 @@ -use super::super::chips::merkle_sum_tree::{MerkleSumTreeChip, MerkleSumTreeConfig}; +use crate::chips::merkle_sum_tree::{MerkleSumTreeChip, MerkleSumTreeConfig}; +use halo2_proofs::halo2curves::bn256::Fr as Fp; use halo2_proofs::{circuit::*, plonk::*}; -use std::marker::PhantomData; -use eth_types::Field; #[derive(Default)] -pub struct MerkleSumTreeCircuit { - pub leaf_hash: F, - pub leaf_balance: F, - pub path_element_hashes: Vec, - pub path_element_balances: Vec, - pub path_indices: Vec, - pub assets_sum: F, - pub root_hash: F, - pub _marker: PhantomData +pub struct MerkleSumTreeCircuit { + pub leaf_hash: Fp, + pub leaf_balance: Fp, + pub path_element_hashes: Vec, + pub path_element_balances: Vec, + pub path_indices: Vec, + pub assets_sum: Fp, + pub root_hash: Fp, } -impl Circuit for MerkleSumTreeCircuit { - - type Config = MerkleSumTreeConfig; +impl Circuit for MerkleSumTreeCircuit { + type Config = MerkleSumTreeConfig; type FloorPlanner = SimpleFloorPlanner; fn without_witnesses(&self) -> Self { Self::default() } - fn configure(meta: &mut ConstraintSystem) -> Self::Config { - + fn configure(meta: &mut ConstraintSystem) -> Self::Config { // config columns for the merkle tree chip let col_a = meta.advice_column(); let col_b = meta.advice_column(); @@ -35,24 +31,27 @@ impl Circuit for MerkleSumTreeCircuit { let instance = meta.instance_column(); - MerkleSumTreeChip::configure( - meta, - [col_a, col_b, col_c, col_d, col_e], - instance, - ) + MerkleSumTreeChip::configure(meta, [col_a, col_b, col_c, col_d, col_e], instance) } fn synthesize( &self, config: Self::Config, - mut layouter: impl Layouter, + mut layouter: impl Layouter, ) -> Result<(), Error> { - let chip = MerkleSumTreeChip::construct(config); - let (leaf_hash, leaf_balance) = chip.assing_leaf_hash_and_balance(layouter.namespace(|| "assign leaf"), F::from(self.leaf_hash), F::from(self.leaf_balance))?; + let (leaf_hash, leaf_balance) = chip.assing_leaf_hash_and_balance( + layouter.namespace(|| "assign leaf"), + self.leaf_hash, + self.leaf_balance, + )?; chip.expose_public(layouter.namespace(|| "public leaf hash"), &leaf_hash, 0)?; - chip.expose_public(layouter.namespace(|| "public leaf balance"), &leaf_balance, 1)?; + chip.expose_public( + layouter.namespace(|| "public leaf balance"), + &leaf_balance, + 1, + )?; // apply it for level 0 of the merkle tree // node cells passed as inputs are the leaf_hash cell and the leaf_balance cell @@ -78,243 +77,10 @@ impl Circuit for MerkleSumTreeCircuit { )?; } - // compute the sum of the merkle sum tree as sum of the leaf balance and the sum of the path elements balances - let computed_sum = self.leaf_balance + self.path_element_balances.iter().fold(F::zero(), |acc, x| acc + x); - - // enforce computed sum to be less than the assets sum - chip.enforce_less_than(layouter.namespace(|| "enforce less than"), &next_sum, computed_sum, self.assets_sum)?; + // enforce computed sum to be less than the assets sum + chip.enforce_less_than(layouter.namespace(|| "enforce less than"), &next_sum)?; chip.expose_public(layouter.namespace(|| "public root"), &next_hash, 2)?; Ok(()) } } - -#[cfg(test)] -mod tests { - - use super::MerkleSumTreeCircuit; - use halo2_proofs::{ - dev::MockProver, - halo2curves::bn256::{Fr as Fp}, - }; - use std::marker::PhantomData; - use merkle_sum_tree_rust::{MerkleSumTree, MerkleProof}; - - // const WIDTH: usize = 5; - // const RATE: usize = 4; - // const L: usize = 4; - - // #[derive(Debug, Clone)] - // struct Node { - // pub hash: Fp, - // pub balance: Fp, - // } - - // fn compute_merkle_sum_root(node: &Node, elements: &Vec, indices: &Vec) -> Node { - // let k = elements.len(); - // let mut digest = node.clone(); - // let mut message: [Fp; 4]; - // for i in 0..k { - // if indices[i] == 0.into() { - // message = [digest.hash, digest.balance, elements[i].hash, elements[i].balance]; - // } else { - // message = [elements[i].hash, elements[i].balance, digest.hash, digest.balance]; - // } - - // digest.hash = poseidon::Hash::<_, MySpec, ConstantLength, WIDTH, RATE>::init() - // .hash(message); - - // digest.balance = digest.balance + elements[i].balance; - // } - // digest - // } - - fn instantiate_circuit(assets_sum: Fp) -> MerkleSumTreeCircuit{ - - let merkle_sum_tree= MerkleSumTree::new("csv_entries/entry_16.csv").unwrap(); - - let proof: MerkleProof = merkle_sum_tree.generate_proof(0).unwrap(); - - MerkleSumTreeCircuit { - leaf_hash: proof.entry.compute_leaf().hash, - leaf_balance: Fp::from(proof.entry.balance()), - path_element_hashes: proof.sibling_hashes, - path_element_balances: proof.sibling_sums, - path_indices: proof.path_indices, - assets_sum, - root_hash: proof.root_hash, - _marker: PhantomData, - } - - } - - #[test] - fn test_valid_merkle_sum_tree() { - - let assets_sum = Fp::from(556863u64); // greater than liabilities sum (556862) - - let user_balance = Fp::from(11888u64); - - let circuit = instantiate_circuit(assets_sum); - - let public_input = vec![circuit.leaf_hash, user_balance, circuit.root_hash, assets_sum]; - - let valid_prover = MockProver::run(10, &circuit, vec![public_input]).unwrap(); - - valid_prover.assert_satisfied(); - - } - - #[test] - fn test_invalid_root_hash() { - - let assets_sum = Fp::from(556863u64); // greater than liabilities sum (556862) - - let user_balance = Fp::from(11888u64); - - let circuit = instantiate_circuit(assets_sum); - - let public_input = vec![circuit.leaf_hash, user_balance, Fp::from(1000u64), assets_sum]; - - let invalid_prover = MockProver::run(10, &circuit, vec![public_input]).unwrap(); - - // invalid_prover.assert_satisfied(); - - // error => Err([Equality constraint not satisfied by cell (Column('Instance', 0 - ), outside any region, on row 2), Equality constraint not satisfied by cell (Column('Advice', 5 - ), in Region 17 ('permute state') at offset 36)]) - // computed_hash (advice column[5]) != root.hash (instance column row 2) - assert!(invalid_prover.verify().is_err()); - } - - #[test] - fn test_invalid_leaf_hash() { - - let assets_sum = Fp::from(556863u64); // greater than liabilities sum (556862) - - let user_balance = Fp::from(11888u64); - - let circuit = instantiate_circuit(assets_sum); - - let public_input = vec![Fp::from(1000u64), user_balance, circuit.root_hash, assets_sum]; - - let invalid_prover = MockProver::run(10, &circuit, vec![public_input]).unwrap(); - - // error => Equality constraint not satisfied by cell (Column('Advice', 0 - ), in Region 2 ('merkle prove layer') at offset 0). Equality constraint not satisfied by cell (Column('Instance', 0 - ), outside any region, on row 0) - // leaf_hash (advice column[0]) != leaf.hash (instance column row 0) - assert!(invalid_prover.verify().is_err()); - - } - - #[test] - fn test_invalid_leaf_balance() { - - let assets_sum = Fp::from(556863u64); // greater than liabilities sum (556862) - - let invalid_user_balance = Fp::from(11887u64); - - let circuit = instantiate_circuit(assets_sum); - - let public_input = vec![circuit.leaf_hash, invalid_user_balance, circuit.root_hash, assets_sum]; - - let invalid_prover = MockProver::run(10, &circuit, vec![public_input]).unwrap(); - - // error => Equality constraint not satisfied by cell (Column('Advice', 1 - ), in Region 2 ('merkle prove layer') at offset 0) Equality constraint not satisfied by cell (Column('Instance', 0 - ), outside any region, on row 1) - // leaf_balance (advice column[1]) != leaf.balance (instance column row 1) - - assert!(invalid_prover.verify().is_err()); - } - - #[test] - fn test_non_binary_index() { - - let assets_sum = Fp::from(556863u64); // greater than liabilities sum (556862) - - let user_balance = Fp::from(11888u64); - - let mut circuit = instantiate_circuit(assets_sum); - - circuit.path_indices[0] = Fp::from(2); - - let public_input = vec![circuit.leaf_hash, user_balance, circuit.root_hash, assets_sum]; - - let invalid_prover = MockProver::run(10, &circuit, vec![public_input]).unwrap(); - - // error: constraint not satisfied 'bool constraint' - // error: constraint not satisfied 'swap constraint' - assert!(invalid_prover.verify().is_err()); - } - - #[test] - fn test_swapping_index() { - - let assets_sum = Fp::from(556863u64); // greater than liabilities sum (556862) - - let user_balance = Fp::from(11888u64); - - let mut circuit = instantiate_circuit(assets_sum); - - // swap indices - circuit.path_indices[0] = Fp::from(1); - - let public_input = vec![circuit.leaf_hash, user_balance, circuit.root_hash, assets_sum]; - - let invalid_prover = MockProver::run(10, &circuit, vec![public_input]).unwrap(); - // error => Err([Equality constraint not satisfied by cell (Column('Instance', 0 - ), outside any region, on row 2), Equality constraint not satisfied by cell (Column('Advice', 5 - ), in Region 26 ('permute state') at offset 36)]) - // computed_hash (advice column[5]) != root.hash (instance column row 2) - assert!(invalid_prover.verify().is_err()); - } - - #[test] - fn test_is_not_less_than() { - - let less_than_assets_sum = Fp::from(556861u64); // less than liabilities sum (556862) - - let user_balance = Fp::from(11888u64); - - let circuit = instantiate_circuit(less_than_assets_sum); - - let public_input = vec![circuit.leaf_hash, user_balance, circuit.root_hash, less_than_assets_sum]; - - let invalid_prover = MockProver::run(10, &circuit, vec![public_input]).unwrap(); - - // error: constraint not satisfied - // Cell layout in region 'enforce sum to be less than total assets': - // | Offset | A2 | A11| - // +--------+----+----+ - // | 0 | x0 | x1 | <--{ Gate 'verifies that `check` from current config equal to is_lt from LtChip ' applied here - - // Constraint '': - // ((S10 * (1 - S10)) * (0x2 - S10)) * (x1 - x0) = 0 - - // Assigned cell values: - // x0 = 1 - // x1 = 0 - assert!(invalid_prover.verify().is_err()); - } - - #[cfg(feature = "dev-graph")] - #[test] - fn print_merkle_sum_tree() { - use plotters::prelude::*; - - let (leaf, elements, indices, root) = build_merkle_tree(); - - let assets_sum = Fp::from(200u64); // less than liabilities sum (400) - - let public_input = vec![leaf.hash, leaf.balance, root.hash, assets_sum]; - - let circuit = instantiate_circuit(leaf, elements, indices, assets_sum); - - let root = - BitMapBackend::new("prints/merkle-sum-tree-layout.png", (1024, 3096)).into_drawing_area(); - root.fill(&WHITE).unwrap(); - let root = root - .titled("Merkle Sum Tree Layout", ("sans-serif", 60)) - .unwrap(); - - halo2_proofs::dev::CircuitLayout::default() - .render(8, &circuit, &root) - .unwrap(); - } -} - - diff --git a/src/circuits/mod.rs b/src/circuits/mod.rs new file mode 100644 index 00000000..03755fe0 --- /dev/null +++ b/src/circuits/mod.rs @@ -0,0 +1,3 @@ +pub mod merkle_sum_tree; +pub mod tests; +pub mod utils; diff --git a/src/circuits/tests.rs b/src/circuits/tests.rs new file mode 100644 index 00000000..ab475319 --- /dev/null +++ b/src/circuits/tests.rs @@ -0,0 +1,482 @@ +#[cfg(test)] +mod test { + + use crate::circuits::merkle_sum_tree::MerkleSumTreeCircuit; + use crate::circuits::utils::{full_prover, full_verifier}; + use crate::merkle_sum_tree::{big_int_to_fp, MerkleProof, MerkleSumTree}; + use halo2_proofs::{ + dev::{FailureLocation, MockProver, VerifyFailure}, + halo2curves::bn256::{Bn256, Fr as Fp}, + plonk::{keygen_pk, keygen_vk, Any}, + poly::kzg::commitment::ParamsKZG, + }; + use num_bigint::ToBigInt; + use rand::rngs::OsRng; + + fn instantiate_circuit(assets_sum: Fp, path: &str) -> MerkleSumTreeCircuit { + let merkle_sum_tree = MerkleSumTree::new(path).unwrap(); + + let proof: MerkleProof = merkle_sum_tree.generate_proof(0).unwrap(); + + MerkleSumTreeCircuit { + leaf_hash: proof.entry.compute_leaf().hash, + leaf_balance: big_int_to_fp(proof.entry.balance()), + path_element_hashes: proof.sibling_hashes, + path_element_balances: proof.sibling_sums, + path_indices: proof.path_indices, + assets_sum, + root_hash: proof.root_hash, + } + } + + fn instantiate_empty_circuit() -> MerkleSumTreeCircuit { + MerkleSumTreeCircuit { + leaf_hash: Fp::zero(), + leaf_balance: Fp::zero(), + path_element_hashes: vec![Fp::zero(); 4], + path_element_balances: vec![Fp::zero(); 4], + path_indices: vec![Fp::zero(); 4], + assets_sum: Fp::zero(), + root_hash: Fp::zero(), + } + } + + #[test] + fn test_valid_merkle_sum_tree() { + let assets_sum = Fp::from(556863u64); // greater than liabilities sum (556862) + + let circuit = instantiate_circuit(assets_sum, "src/merkle_sum_tree/csv/entry_16.csv"); + + let public_input = vec![ + circuit.leaf_hash, + circuit.leaf_balance, + circuit.root_hash, + circuit.assets_sum, + ]; + + let valid_prover = MockProver::run(9, &circuit, vec![public_input]).unwrap(); + + valid_prover.assert_satisfied(); + } + + #[test] + fn test_valid_merkle_sum_tree_2() { + // Same as above but now the entries contain a balance that is greater than 64 bits + // liabilities sum is 18446744073710096590 + + let assets_sum_big_int = 18446744073710096591_u128.to_bigint().unwrap(); // greater than liabilities sum + + let assets_sum = big_int_to_fp(&assets_sum_big_int); + + let circuit = instantiate_circuit(assets_sum, "src/merkle_sum_tree/csv/entry_16.csv"); + + let public_input = vec![ + circuit.leaf_hash, + circuit.leaf_balance, + circuit.root_hash, + circuit.assets_sum, + ]; + + let valid_prover = MockProver::run(9, &circuit, vec![public_input]).unwrap(); + + valid_prover.assert_satisfied(); + } + + #[test] + fn test_valid_merkle_sum_tree_with_full_prover() { + let assets_sum = Fp::from(556863u64); // greater than liabilities sum (556862) + + let circuit = instantiate_empty_circuit(); + + // we generate a universal trusted setup of our own for testing + let params = ParamsKZG::::setup(9, OsRng); + + // we generate the verification key and the proving key + // we use an empty circuit just to enphasize that the circuit input are not relevant when generating the keys + // Note: the dimension of the circuit used to generate the keys must be the same as the dimension of the circuit used to generate the proof + // In this case, the dimension are represented by the heigth of the merkle tree + let vk = keygen_vk(¶ms, &circuit).expect("vk generation should not fail"); + let pk = keygen_pk(¶ms, vk.clone(), &circuit).expect("pk generation should not fail"); + + // Only now we can instantiate the circuit with the actual inputs + let circuit = instantiate_circuit(assets_sum, "src/merkle_sum_tree/csv/entry_16.csv"); + + let public_input = vec![ + circuit.leaf_hash, + circuit.leaf_balance, + circuit.root_hash, + circuit.assets_sum, + ]; + + // Generate the proof + let proof = full_prover(¶ms, &pk, circuit, &public_input); + + // verify the proof to be true + assert!(full_verifier(¶ms, &vk, proof, &public_input)); + } + + // Passing an invalid root hash in the instance column should fail the permutation check between the computed root hash and the instance column root hash + #[test] + fn test_invalid_root_hash() { + let assets_sum = Fp::from(556863u64); // greater than liabilities sum (556862) + + let circuit = instantiate_circuit(assets_sum, "src/merkle_sum_tree/csv/entry_16.csv"); + + let invalid_root_hash = Fp::from(1000u64); + + let public_input = vec![ + circuit.leaf_hash, + circuit.leaf_balance, + invalid_root_hash, + circuit.assets_sum, + ]; + + let invalid_prover = MockProver::run(9, &circuit, vec![public_input]).unwrap(); + + assert_eq!( + invalid_prover.verify(), + Err(vec![ + VerifyFailure::Permutation { + column: (Any::Instance, 0).into(), + location: FailureLocation::OutsideRegion { row: 2 } + }, + VerifyFailure::Permutation { + column: (Any::advice(), 5).into(), + location: FailureLocation::InRegion { + region: (16, "permute state").into(), + offset: 38 + } + } + ]) + ); + } + + #[test] + fn test_invalid_root_hash_with_full_prover() { + let assets_sum = Fp::from(556863u64); // greater than liabilities sum (556862) + + let circuit = instantiate_empty_circuit(); + + // we generate a universal trusted setup of our own for testing + let params = ParamsKZG::::setup(9, OsRng); + + // we generate the verification key and the proving key + // we use an empty circuit just to enphasize that the circuit input are not relevant when generating the keys + let vk = keygen_vk(¶ms, &circuit).expect("vk should not fail"); + let pk = keygen_pk(¶ms, vk.clone(), &circuit).expect("pk should not fail"); + + // Only now we can instantiate the circuit with the actual inputs + let circuit = instantiate_circuit(assets_sum, "src/merkle_sum_tree/csv/entry_16.csv"); + + let invalid_root_hash = Fp::from(1000u64); + + let public_input = vec![ + circuit.leaf_hash, + circuit.leaf_balance, + invalid_root_hash, + circuit.assets_sum, + ]; + + // Generate the proof + let proof = full_prover(¶ms, &pk, circuit, &public_input); + + // verify the proof to be false + assert!(!full_verifier(¶ms, &vk, proof, &public_input)); + } + + // Passing an invalid leaf hash as input for the witness generation should fail the permutation check between the computed root hash and the instance column root hash + #[test] + fn test_invalid_leaf_hash_as_witness() { + let assets_sum = Fp::from(556863u64); // greater than liabilities sum (556862) + + let mut circuit = instantiate_circuit(assets_sum, "src/merkle_sum_tree/csv/entry_16.csv"); + + // invalidate leaf hash + circuit.leaf_hash = Fp::from(1000u64); + + let public_input = vec![ + circuit.leaf_hash, + circuit.leaf_balance, + circuit.root_hash, + circuit.assets_sum, + ]; + + let invalid_prover = MockProver::run(9, &circuit, vec![public_input]).unwrap(); + assert_eq!( + invalid_prover.verify(), + Err(vec![ + VerifyFailure::Permutation { + column: (Any::Instance, 0).into(), + location: FailureLocation::OutsideRegion { row: 2 } + }, + VerifyFailure::Permutation { + column: (Any::advice(), 5).into(), + location: FailureLocation::InRegion { + region: (16, "permute state").into(), + offset: 38 + } + } + ]) + ); + } + + // Passing an invalid leaf hash in the instance column should fail the permutation check between the (valid) leaf hash added as part of the witness and the instance column leaf hash + #[test] + fn test_invalid_leaf_hash_as_instance() { + let assets_sum = Fp::from(556863u64); // greater than liabilities sum (556862) + + let circuit = instantiate_circuit(assets_sum, "src/merkle_sum_tree/csv/entry_16.csv"); + + // add invalid leaf hash in the instance column + let invalid_leaf_hash = Fp::from(1000u64); + + let public_input = vec![ + invalid_leaf_hash, + circuit.leaf_balance, + circuit.root_hash, + circuit.assets_sum, + ]; + + let invalid_prover = MockProver::run(9, &circuit, vec![public_input]).unwrap(); + + assert_eq!( + invalid_prover.verify(), + Err(vec![ + VerifyFailure::Permutation { + column: (Any::advice(), 0).into(), + location: FailureLocation::InRegion { + region: (1, "merkle prove layer").into(), + offset: 0 + } + }, + VerifyFailure::Permutation { + column: (Any::Instance, 0).into(), + location: FailureLocation::OutsideRegion { row: 0 } + }, + ]) + ); + } + + // Passing an invalid leaf balance as input for the witness generation should fail the permutation check between the computed root hash and the instance column root hash + #[test] + fn test_invalid_leaf_balance_as_witness() { + let assets_sum = Fp::from(556863u64); // greater than liabilities sum (556862) + + let user_balance = Fp::from(11888u64); + + let mut circuit = instantiate_circuit(assets_sum, "src/merkle_sum_tree/csv/entry_16.csv"); + + // invalid leaf balance + circuit.leaf_hash = Fp::from(1000u64); + + let public_input = vec![ + circuit.leaf_hash, + user_balance, + circuit.root_hash, + assets_sum, + ]; + + let invalid_prover = MockProver::run(9, &circuit, vec![public_input]).unwrap(); + assert_eq!( + invalid_prover.verify(), + Err(vec![ + VerifyFailure::Permutation { + column: (Any::Instance, 0).into(), + location: FailureLocation::OutsideRegion { row: 2 } + }, + VerifyFailure::Permutation { + column: (Any::advice(), 5).into(), + location: FailureLocation::InRegion { + region: (16, "permute state").into(), + offset: 38 + } + } + ]) + ); + } + + // Passing an invalid leaf balance in the instance column should fail the permutation check between the (valid) leaf balance added as part of the witness and the instance column leaf balance + #[test] + fn test_invalid_leaf_balance_as_instance() { + let assets_sum = Fp::from(556863u64); // greater than liabilities sum (556862) + + let circuit = instantiate_circuit(assets_sum, "src/merkle_sum_tree/csv/entry_16.csv"); + + // add invalid leaf balance in the instance column + let invalid_leaf_balance = Fp::from(1000u64); + + let public_input = vec![ + circuit.leaf_hash, + invalid_leaf_balance, + circuit.root_hash, + circuit.assets_sum, + ]; + + let invalid_prover = MockProver::run(9, &circuit, vec![public_input]).unwrap(); + + assert_eq!( + invalid_prover.verify(), + Err(vec![ + VerifyFailure::Permutation { + column: (Any::advice(), 1).into(), + location: FailureLocation::InRegion { + region: (1, "merkle prove layer").into(), + offset: 0 + } + }, + VerifyFailure::Permutation { + column: (Any::Instance, 0).into(), + location: FailureLocation::OutsideRegion { row: 1 } + }, + ]) + ); + } + + // Passing a non binary index should fail the bool constraint check and the permutation check between the computed root hash and the instance column root hash + #[test] + fn test_non_binary_index() { + let assets_sum = Fp::from(556863u64); // greater than liabilities sum (556862) + + let mut circuit = instantiate_circuit(assets_sum, "src/merkle_sum_tree/csv/entry_16.csv"); + + // invalidate path index inside the circuit + circuit.path_indices[0] = Fp::from(2); + + let public_input = vec![ + circuit.leaf_hash, + circuit.leaf_balance, + circuit.root_hash, + circuit.assets_sum, + ]; + + let invalid_prover = MockProver::run(9, &circuit, vec![public_input]).unwrap(); + + assert_eq!( + invalid_prover.verify(), + Err(vec![ + VerifyFailure::ConstraintNotSatisfied { + constraint: ((0, "bool constraint").into(), 0, "").into(), + location: FailureLocation::InRegion { + region: (1, "merkle prove layer").into(), + offset: 0 + }, + cell_values: vec![(((Any::advice(), 4).into(), 0).into(), "0x2".to_string()),] + }, + VerifyFailure::Permutation { + column: (Any::Instance, 0).into(), + location: FailureLocation::OutsideRegion { row: 2 } + }, + VerifyFailure::Permutation { + column: (Any::advice(), 5).into(), + location: FailureLocation::InRegion { + region: (16, "permute state").into(), + offset: 38 + } + } + ]) + ); + } + + // Swapping the indices should fail the permutation check between the computed root hash and the instance column root hash + #[test] + fn test_swapping_index() { + let assets_sum = Fp::from(556863u64); // greater than liabilities sum (556862) + + let mut circuit = instantiate_circuit(assets_sum, "src/merkle_sum_tree/csv/entry_16.csv"); + + // swap indices + circuit.path_indices[0] = Fp::from(1); + + let public_input = vec![ + circuit.leaf_hash, + circuit.leaf_balance, + circuit.root_hash, + circuit.assets_sum, + ]; + + let invalid_prover = MockProver::run(9, &circuit, vec![public_input]).unwrap(); + + assert_eq!( + invalid_prover.verify(), + Err(vec![ + VerifyFailure::Permutation { + column: (Any::Instance, 0).into(), + location: FailureLocation::OutsideRegion { row: 2 } + }, + VerifyFailure::Permutation { + column: (Any::advice(), 5).into(), + location: FailureLocation::InRegion { + region: (16, "permute state").into(), + offset: 38 + } + } + ]) + ); + } + + // Passing an assets sum that is less than the liabilities sum should fail the lessThan constraint check + #[test] + fn test_is_not_less_than() { + let less_than_assets_sum = Fp::from(556861u64); // less than liabilities sum (556862) + + let circuit = + instantiate_circuit(less_than_assets_sum, "src/merkle_sum_tree/csv/entry_16.csv"); + + let public_input = vec![ + circuit.leaf_hash, + circuit.leaf_balance, + circuit.root_hash, + circuit.assets_sum, + ]; + + let invalid_prover = MockProver::run(9, &circuit, vec![public_input]).unwrap(); + + assert_eq!( + invalid_prover.verify(), + Err(vec![VerifyFailure::ConstraintNotSatisfied { + constraint: ( + ( + 7, + "verifies that `check` from current config equal to is_lt from LtChip" + ) + .into(), + 0, + "" + ) + .into(), + location: FailureLocation::InRegion { + region: (18, "enforce sum to be less than total assets").into(), + offset: 0 + }, + cell_values: vec![ + (((Any::advice(), 2).into(), 0).into(), "1".to_string()), + // The zero means that is not less than + (((Any::advice(), 11).into(), 0).into(), "0".to_string()) + ] + }]) + ); + + assert!(invalid_prover.verify().is_err()); + } + + #[cfg(feature = "dev-graph")] + #[test] + fn print_merkle_sum_tree() { + use plotters::prelude::*; + + let assets_sum = Fp::from(556863u64); // greater than liabilities sum (556862) + + let circuit = instantiate_circuit(assets_sum, "src/merkle_sum_tree/csv/entry_16.csv"); + + let root = BitMapBackend::new("prints/merkle-sum-tree-layout.png", (2048, 16384)) + .into_drawing_area(); + root.fill(&WHITE).unwrap(); + let root = root + .titled("Merkle Sum Tree Layout", ("sans-serif", 60)) + .unwrap(); + + halo2_proofs::dev::CircuitLayout::default() + .render(8, &circuit, &root) + .unwrap(); + } +} diff --git a/src/circuits/utils.rs b/src/circuits/utils.rs new file mode 100644 index 00000000..0b58f490 --- /dev/null +++ b/src/circuits/utils.rs @@ -0,0 +1,73 @@ +use ark_std::{end_timer, start_timer}; +use halo2_proofs::{ + halo2curves::bn256::{Bn256, Fr as Fp, G1Affine}, + plonk::{create_proof, verify_proof, Circuit, ProvingKey, VerifyingKey}, + poly::{ + commitment::ParamsProver, + kzg::{ + commitment::{KZGCommitmentScheme, ParamsKZG}, + multiopen::{ProverSHPLONK, VerifierSHPLONK}, + strategy::SingleStrategy, + }, + }, + transcript::{ + Blake2bRead, Blake2bWrite, Challenge255, TranscriptReadBuffer, TranscriptWriterBuffer, + }, +}; +use rand::rngs::OsRng; + +pub fn full_prover>( + params: &ParamsKZG, + pk: &ProvingKey, + circuit: C, + public_input: &[Fp], +) -> Vec { + let pf_time = start_timer!(|| "Creating proof"); + + let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); + create_proof::< + KZGCommitmentScheme, + ProverSHPLONK<'_, Bn256>, + Challenge255, + _, + Blake2bWrite, G1Affine, Challenge255>, + _, + >( + params, + pk, + &[circuit], + &[&[public_input]], + OsRng, + &mut transcript, + ) + .expect("prover should not fail"); + let proof = transcript.finalize(); + end_timer!(pf_time); + proof +} + +pub fn full_verifier( + params: &ParamsKZG, + vk: &VerifyingKey, + proof: Vec, + public_input: &[Fp], +) -> bool { + let verifier_params = params.verifier_params(); + let strategy = SingleStrategy::new(params); + let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]); + + verify_proof::< + KZGCommitmentScheme, + VerifierSHPLONK<'_, Bn256>, + Challenge255, + Blake2bRead<&[u8], G1Affine, Challenge255>, + SingleStrategy<'_, Bn256>, + >( + verifier_params, + vk, + strategy, + &[&[public_input]], + &mut transcript, + ) + .is_ok() +} diff --git a/src/lib.rs b/src/lib.rs index cae2cab0..3607ba43 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,3 @@ pub mod chips; pub mod circuits; - +pub mod merkle_sum_tree; diff --git a/csv_entries/entry_16.csv b/src/merkle_sum_tree/csv/entry_16.csv similarity index 100% rename from csv_entries/entry_16.csv rename to src/merkle_sum_tree/csv/entry_16.csv diff --git a/src/merkle_sum_tree/csv/entry_16_bigints.csv b/src/merkle_sum_tree/csv/entry_16_bigints.csv new file mode 100644 index 00000000..0240e192 --- /dev/null +++ b/src/merkle_sum_tree/csv/entry_16_bigints.csv @@ -0,0 +1,17 @@ +username,balance +dxGaEAii,18446744073709551616 +MBlfbBGI,67823 +lAhWlEWZ,18651 +nuZweYtO,22073 +gbdSwiuY,34897 +RZNneNuP,83296 +YsscHXkp,31699 +RkLzkDun,2087 +HlQlnEYI,30605 +RqkZOFYe,16881 +NjCSRAfD,41163 +pHniJMQY,14874 +dOGIMzKR,10032 +HfMDmNLp,55683 +xPLKzCBl,79731 +AtwIxZHo,35479 \ No newline at end of file diff --git a/src/merkle_sum_tree/csv/entry_16_overflow.csv b/src/merkle_sum_tree/csv/entry_16_overflow.csv new file mode 100644 index 00000000..ca6f644c --- /dev/null +++ b/src/merkle_sum_tree/csv/entry_16_overflow.csv @@ -0,0 +1,17 @@ +username,balance +dxGaEAii,21888242871839275222246405745257275088548364400416034343698204186575808495616 +MBlfbBGI,67823 +lAhWlEWZ,18651 +nuZweYtO,22073 +gbdSwiuY,34897 +RZNneNuP,83296 +YsscHXkp,31699 +RkLzkDun,2087 +HlQlnEYI,30605 +RqkZOFYe,16881 +NjCSRAfD,41163 +pHniJMQY,14874 +dOGIMzKR,10032 +HfMDmNLp,55683 +xPLKzCBl,79731 +AtwIxZHo,35479 \ No newline at end of file diff --git a/src/merkle_sum_tree/csv/entry_16_switched_order.csv b/src/merkle_sum_tree/csv/entry_16_switched_order.csv new file mode 100644 index 00000000..25f9c6b4 --- /dev/null +++ b/src/merkle_sum_tree/csv/entry_16_switched_order.csv @@ -0,0 +1,17 @@ +username,balance +dxGaEAii,11888 +MBlfbBGI,67823 +lAhWlEWZ,18651 +nuZweYtO,22073 +gbdSwiuY,34897 +RZNneNuP,83296 +YsscHXkp,31699 +RkLzkDun,2087 +HlQlnEYI,30605 +RqkZOFYe,16881 +NjCSRAfD,41163 +pHniJMQY,14874 +dOGIMzKR,10032 +HfMDmNLp,55683 +AtwIxZHo,35479 +xPLKzCBl,79731 diff --git a/src/merkle_sum_tree/entry.rs b/src/merkle_sum_tree/entry.rs new file mode 100644 index 00000000..d0832a1d --- /dev/null +++ b/src/merkle_sum_tree/entry.rs @@ -0,0 +1,46 @@ +use crate::merkle_sum_tree::utils::{big_int_to_fp, big_intify_username, poseidon}; +use crate::merkle_sum_tree::Node; +use halo2_proofs::halo2curves::bn256::Fr as Fp; +use num_bigint::BigInt; + +#[derive(Default, Clone, Debug)] +pub struct Entry { + username_to_big_int: BigInt, + balance: BigInt, + username: String, +} + +impl Entry { + pub fn new(username: String, balance: BigInt) -> Result { + Ok(Entry { + username_to_big_int: big_intify_username(&username), + balance, + username, + }) + } + + pub fn compute_leaf(&self) -> Node { + Node { + hash: poseidon( + big_int_to_fp(&self.username_to_big_int), + big_int_to_fp(&self.balance), + Fp::from(0), + Fp::from(0), + ), + balance: big_int_to_fp(&self.balance), + } + } + + // Getters + pub fn balance(&self) -> &BigInt { + &self.balance + } + + pub fn username_to_big_int(&self) -> &BigInt { + &self.username_to_big_int + } + + pub fn username(&self) -> &str { + &self.username + } +} diff --git a/src/merkle_sum_tree/mod.rs b/src/merkle_sum_tree/mod.rs new file mode 100644 index 00000000..726b193d --- /dev/null +++ b/src/merkle_sum_tree/mod.rs @@ -0,0 +1,24 @@ +mod entry; +mod mst; +mod tests; +mod utils; +use halo2_proofs::halo2curves::bn256::Fr as Fp; + +#[derive(Default, Clone, Debug)] +pub struct MerkleProof { + pub root_hash: Fp, + pub entry: Entry, + pub sibling_hashes: Vec, + pub sibling_sums: Vec, + pub path_indices: Vec, +} + +#[derive(Default, Clone, Debug)] +pub struct Node { + pub hash: Fp, + pub balance: Fp, +} + +pub use entry::Entry; +pub use mst::MerkleSumTree; +pub use utils::{big_int_to_fp, big_intify_username}; diff --git a/src/merkle_sum_tree/mst.rs b/src/merkle_sum_tree/mst.rs new file mode 100644 index 00000000..a4589daf --- /dev/null +++ b/src/merkle_sum_tree/mst.rs @@ -0,0 +1,63 @@ +use crate::merkle_sum_tree::utils::{ + build_merkle_tree_from_entries, create_proof, index_of, parse_csv_to_entries, verify_proof, +}; +use crate::merkle_sum_tree::{Entry, MerkleProof, Node}; +use num_bigint::BigInt; + +pub struct MerkleSumTree { + root: Node, + nodes: Vec>, + depth: usize, + entries: Vec, +} + +impl MerkleSumTree { + pub const MAX_DEPTH: usize = 32; + + pub fn new(path: &str) -> Result> { + let entries = parse_csv_to_entries(path)?; + let depth = (entries.len() as f64).log2().ceil() as usize; + + if !(1..=Self::MAX_DEPTH).contains(&depth) { + return Err("The tree depth must be between 1 and 32".into()); + } + + let mut nodes = vec![]; + let root = build_merkle_tree_from_entries(&entries, depth, &mut nodes)?; + + Ok(MerkleSumTree { + root, + nodes, + depth, + entries, + }) + } + + pub fn root(&self) -> &Node { + &self.root + } + + pub fn depth(&self) -> &usize { + &self.depth + } + + pub fn leaves(&self) -> &[Node] { + &self.nodes[0] + } + + pub fn entries(&self) -> &[Entry] { + &self.entries + } + + pub fn index_of(&self, username: &str, balance: BigInt) -> Option { + index_of(username, balance, &self.nodes) + } + + pub fn generate_proof(&self, index: usize) -> Result { + create_proof(index, &self.entries, self.depth, &self.nodes, &self.root) + } + + pub fn verify_proof(&self, proof: &MerkleProof) -> bool { + verify_proof(proof) + } +} diff --git a/src/merkle_sum_tree/tests.rs b/src/merkle_sum_tree/tests.rs new file mode 100644 index 00000000..5630af8f --- /dev/null +++ b/src/merkle_sum_tree/tests.rs @@ -0,0 +1,141 @@ +#[cfg(test)] +mod test { + + use crate::merkle_sum_tree::utils::big_int_to_fp; + use crate::merkle_sum_tree::{Entry, MerkleSumTree}; + use num_bigint::{BigInt, ToBigInt}; + + #[test] + fn test_mst() { + // create new merkle tree + let merkle_tree = MerkleSumTree::new("src/merkle_sum_tree/csv/entry_16.csv").unwrap(); + + // get root + let root = merkle_tree.root(); + + // expect root hash to be different than 0 + assert!(root.hash != 0.into()); + // expect balance to match the sum of all entries + assert!(root.balance == 556862.into()); + // expect depth to be 4 + assert!(*merkle_tree.depth() == 4_usize); + + // get proof for entry 0 + let proof = merkle_tree.generate_proof(0).unwrap(); + + // verify proof + assert!(merkle_tree.verify_proof(&proof)); + + // Should generate different root hashes when changing the entry order + let merkle_tree_2 = + MerkleSumTree::new("src/merkle_sum_tree/csv/entry_16_switched_order.csv").unwrap(); + assert_ne!(root.hash, merkle_tree_2.root().hash); + + // the balance total should be the same + assert_eq!(root.balance, merkle_tree_2.root().balance); + + // should retrun the index of an entry that exist in the tree + assert_eq!( + merkle_tree.index_of("AtwIxZHo", 35479.to_bigint().unwrap()), + Some(15) + ); + + // shouldn't retrun the index of an entry that doesn't exist in the tree + assert_eq!( + merkle_tree.index_of("AtwHHHHo", 35478.to_bigint().unwrap()), + None + ); + + // should create valid proof for each entry in the tree and verify it + for i in 0..15 { + let proof = merkle_tree.generate_proof(i).unwrap(); + assert!(merkle_tree.verify_proof(&proof)); + } + + // shouldn't create a proof for an entry that doesn't exist in the tree + assert!(merkle_tree.generate_proof(16).is_err()); + + // shouldn't verify a proof with a wrong entry + let mut proof_invalid_1 = proof.clone(); + proof_invalid_1.entry = + Entry::new("AtwIxZHo".to_string(), 35479.to_bigint().unwrap()).unwrap(); + assert!(!merkle_tree.verify_proof(&proof_invalid_1)); + + // shouldn't verify a proof with a wrong root hash + let mut proof_invalid_2 = proof.clone(); + proof_invalid_2.root_hash = 0.into(); + assert!(!merkle_tree.verify_proof(&proof_invalid_2)); + + // shouldn't verify a proof with a wrong computed balance + let mut proof_invalid_3 = proof; + proof_invalid_3.sibling_sums[0] = 0.into(); + } + + #[test] + fn test_mst_overflow() { + let result = MerkleSumTree::new("src/merkle_sum_tree/csv/entry_16_overflow.csv"); + // assert!(result.is_err(), "Expected an error due to balance overflow"); + + if let Err(e) = result { + assert_eq!(e.to_string(), "Balance is larger than the modulus"); + + // Passing entries whose balance sum overflows the field should throw an error at the constructor + // MerkleSumTree::new("src/merkle_sum_tree/csv/entry_16_overflow.csv").unwrap() should throw Balance is larger than the modulus + } + } + + #[test] + fn test_mst_with_bigint() { + // create new merkle tree with entries that have balances greater than 2^64 + let merkle_tree = + MerkleSumTree::new("src/merkle_sum_tree/csv/entry_16_bigints.csv").unwrap(); + + // get root + let root = merkle_tree.root(); + + // expect root hash to be different than 0 + assert!(root.hash != 0.into()); + + // expect balance to match the sum of all entries + let exp_balance = { + let balance = 18446744073710096590_u128.to_bigint().unwrap(); + let (_, mut bytes) = BigInt::to_bytes_le(&balance); + bytes.resize(32, 0); + bytes + }; + + let root_balance = root.balance.to_bytes(); + + assert_eq!(root_balance.to_vec(), exp_balance); + + // expect depth to be 4 + assert!(*merkle_tree.depth() == 4_usize); + + // get proof for entry 0 + let proof = merkle_tree.generate_proof(0).unwrap(); + + // verify proof + assert!(merkle_tree.verify_proof(&proof)); + } + #[test] + fn test_big_int_conversion() { + let big_int = 3.to_bigint().unwrap(); + let fp = big_int_to_fp(&big_int); + + assert_eq!(fp, 3.into()); + + let big_int_over_64 = (18446744073709551616_i128).to_bigint().unwrap(); + let fp_2 = big_int_to_fp(&big_int_over_64); + + let big_int_to_bytes = { + let (_, mut bytes) = BigInt::to_bytes_le(&big_int_over_64); + bytes.resize(32, 0); + bytes + }; + + assert_eq!(fp_2.to_bytes().to_vec(), big_int_to_bytes); + + let fp_3 = fp_2 - fp; + assert_eq!(fp_3, 18446744073709551613.into()); + } +} diff --git a/src/merkle_sum_tree/utils/build_tree.rs b/src/merkle_sum_tree/utils/build_tree.rs new file mode 100644 index 00000000..a9ab3c04 --- /dev/null +++ b/src/merkle_sum_tree/utils/build_tree.rs @@ -0,0 +1,43 @@ +use crate::merkle_sum_tree::utils::create_middle_node::create_middle_node; +use crate::merkle_sum_tree::{Entry, Node}; +use halo2_proofs::halo2curves::bn256::Fr as Fp; + +pub fn build_merkle_tree_from_entries( + entries: &[Entry], + depth: usize, + nodes: &mut Vec>, +) -> Result> { + let n = entries.len(); + let mut tree = vec![ + vec![ + Node { + hash: Fp::from(0), + balance: Fp::from(0) + }; + n + ]; + depth + 1 + ]; + + // Compute the leaves + for (i, entry) in entries.iter().enumerate() { + tree[0][i] = entry.compute_leaf(); + } + + // Compute the inner nodes + for level in 1..=depth { + let nodes_in_level = (n + (1 << level) - 1) / (1 << level); + for i in 0..nodes_in_level { + tree[level][i] = + create_middle_node(&tree[level - 1][2 * i], &tree[level - 1][2 * i + 1]); + + // let left_child = tree[level - 1][2 * i].hash; + // let right_child = tree[level - 1][2 * i + 1].hash; + // tree[level][i].hash = poseidon(left_child, right_child); + } + } + + let root = tree[depth][0].clone(); + *nodes = tree; + Ok(root) +} diff --git a/src/merkle_sum_tree/utils/create_middle_node.rs b/src/merkle_sum_tree/utils/create_middle_node.rs new file mode 100644 index 00000000..30a1c3f5 --- /dev/null +++ b/src/merkle_sum_tree/utils/create_middle_node.rs @@ -0,0 +1,9 @@ +use crate::merkle_sum_tree::utils::hash::poseidon; +use crate::merkle_sum_tree::Node; + +pub fn create_middle_node(child_l: &Node, child_r: &Node) -> Node { + Node { + hash: poseidon(child_l.hash, child_l.balance, child_r.hash, child_r.balance), + balance: child_l.balance + child_r.balance, + } +} diff --git a/src/merkle_sum_tree/utils/create_proof.rs b/src/merkle_sum_tree/utils/create_proof.rs new file mode 100644 index 00000000..01e0ff6e --- /dev/null +++ b/src/merkle_sum_tree/utils/create_proof.rs @@ -0,0 +1,43 @@ +use crate::merkle_sum_tree::{Entry, MerkleProof, Node}; +use halo2_proofs::halo2curves::bn256::Fr as Fp; + +pub fn create_proof( + index: usize, + entries: &[Entry], + depth: usize, + nodes: &[Vec], + root: &Node, +) -> Result { + if index >= nodes[0].len() { + return Err("The leaf does not exist in this tree"); + } + + let mut sibling_hashes = vec![Fp::from(0); depth]; + let mut sibling_sums = vec![Fp::from(0); depth]; + let mut path_indices = vec![Fp::from(0); depth]; + let mut current_index = index; + + for level in 0..depth { + let position = current_index % 2; + let level_start_index = current_index - position; + let level_end_index = level_start_index + 2; + + path_indices[level] = Fp::from(position as u64); + + for i in level_start_index..level_end_index { + if i != current_index { + sibling_hashes[level] = nodes[level][i].hash; + sibling_sums[level] = nodes[level][i].balance; + } + } + current_index /= 2; + } + + Ok(MerkleProof { + root_hash: root.hash, + entry: entries[index].clone(), + sibling_hashes, + sibling_sums, + path_indices, + }) +} diff --git a/src/merkle_sum_tree/utils/csv_parser.rs b/src/merkle_sum_tree/utils/csv_parser.rs new file mode 100644 index 00000000..9cd99ac1 --- /dev/null +++ b/src/merkle_sum_tree/utils/csv_parser.rs @@ -0,0 +1,38 @@ +use crate::merkle_sum_tree::Entry; +use num_bigint::BigInt; +use serde::Deserialize; +use std::error::Error; +use std::fs::File; +use std::path::Path; + +#[derive(Debug, Deserialize)] +struct CsvEntry { + username: String, + balance: String, +} + +pub fn parse_csv_to_entries>(path: P) -> Result, Box> { + let mut entries = Vec::new(); + let file = File::open(path)?; + let mut rdr = csv::Reader::from_reader(file); + + let mut balance_acc = BigInt::from(0); + + for result in rdr.deserialize() { + let record: CsvEntry = result?; + let balance_big_int = BigInt::parse_bytes(record.balance.as_bytes(), 10).unwrap(); + balance_acc += &balance_big_int; + let entry = Entry::new(record.username, balance_big_int)?; + entries.push(entry); + } + + // modulus from bn256 curve impl => https://github.com/privacy-scaling-explorations/halo2curves/blob/main/src/bn256/fr.rs#L38 + const MODULUS_STR: &str = "30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"; + + // throw error if balance is larger than the modulus + if balance_acc >= BigInt::parse_bytes(MODULUS_STR.as_bytes(), 16).unwrap() { + return Err("Balance is larger than the modulus".into()); + } + + Ok(entries) +} diff --git a/src/merkle_sum_tree/utils/hash.rs b/src/merkle_sum_tree/utils/hash.rs new file mode 100644 index 00000000..01ee7e0e --- /dev/null +++ b/src/merkle_sum_tree/utils/hash.rs @@ -0,0 +1,11 @@ +use crate::chips::poseidon::spec::MySpec; +use halo2_gadgets::poseidon::primitives::{self as poseidon, ConstantLength}; +use halo2_proofs::halo2curves::bn256::Fr as Fp; + +pub fn poseidon(l1: Fp, l2: Fp, r1: Fp, r2: Fp) -> Fp { + const WIDTH: usize = 5; + const RATE: usize = 4; + const L: usize = 4; + + poseidon::Hash::, WIDTH, RATE>::init().hash([l1, l2, r1, r2]) +} diff --git a/src/merkle_sum_tree/utils/index_of.rs b/src/merkle_sum_tree/utils/index_of.rs new file mode 100644 index 00000000..971ff9b9 --- /dev/null +++ b/src/merkle_sum_tree/utils/index_of.rs @@ -0,0 +1,10 @@ +use crate::merkle_sum_tree::{Entry, Node}; +use num_bigint::BigInt; + +pub fn index_of(username: &str, balance: BigInt, nodes: &[Vec]) -> Option { + let entry = Entry::new(username.to_string(), balance).unwrap(); + let leaf = entry.compute_leaf(); + let leaf_hash = leaf.hash; + + nodes[0].iter().position(|node| node.hash == leaf_hash) +} diff --git a/src/merkle_sum_tree/utils/mod.rs b/src/merkle_sum_tree/utils/mod.rs new file mode 100644 index 00000000..f76c7610 --- /dev/null +++ b/src/merkle_sum_tree/utils/mod.rs @@ -0,0 +1,16 @@ +mod build_tree; +mod create_middle_node; +mod create_proof; +mod csv_parser; +mod hash; +mod index_of; +mod operation_helpers; +mod proof_verification; + +pub use build_tree::build_merkle_tree_from_entries; +pub use create_proof::create_proof; +pub use csv_parser::parse_csv_to_entries; +pub use hash::poseidon; +pub use index_of::index_of; +pub use operation_helpers::*; +pub use proof_verification::verify_proof; diff --git a/src/merkle_sum_tree/utils/operation_helpers.rs b/src/merkle_sum_tree/utils/operation_helpers.rs new file mode 100644 index 00000000..d3c1e712 --- /dev/null +++ b/src/merkle_sum_tree/utils/operation_helpers.rs @@ -0,0 +1,12 @@ +use halo2_proofs::halo2curves::{bn256::Fr as Fp, group::ff::PrimeField}; +use num_bigint::{BigInt, Sign}; + +// Return a BigUint representation of the username +pub fn big_intify_username(username: &str) -> BigInt { + let utf8_bytes = username.as_bytes(); + BigInt::from_bytes_be(Sign::Plus, utf8_bytes) +} + +pub fn big_int_to_fp(big_int: &BigInt) -> Fp { + Fp::from_str_vartime(&big_int.to_str_radix(10)[..]).unwrap() +} diff --git a/src/merkle_sum_tree/utils/proof_verification.rs b/src/merkle_sum_tree/utils/proof_verification.rs new file mode 100644 index 00000000..3979851c --- /dev/null +++ b/src/merkle_sum_tree/utils/proof_verification.rs @@ -0,0 +1,24 @@ +use crate::merkle_sum_tree::utils::{big_int_to_fp, create_middle_node::create_middle_node}; +use crate::merkle_sum_tree::{MerkleProof, Node}; + +pub fn verify_proof(proof: &MerkleProof) -> bool { + let mut node = proof.entry.compute_leaf(); + let mut balance = big_int_to_fp(proof.entry.balance()); + + for i in 0..proof.sibling_hashes.len() { + let sibling_node = Node { + hash: proof.sibling_hashes[i], + balance: proof.sibling_sums[i], + }; + + if proof.path_indices[i] == 0.into() { + node = create_middle_node(&node, &sibling_node); + } else { + node = create_middle_node(&sibling_node, &node); + } + + balance += sibling_node.balance; + } + + proof.root_hash == node.hash && balance == node.balance +}