From 1f43c1f884b399571a7ca633378c361cf3c8e2d1 Mon Sep 17 00:00:00 2001 From: Ray Gao Date: Tue, 17 Dec 2024 18:11:40 -0500 Subject: [PATCH 01/13] Graft ceno prover --- circ_blocks/Cargo.lock | 1129 ++++++++++++++++- spartan_parallel/Cargo.toml | 6 + spartan_parallel/src/dense_mlpoly.rs | 4 +- spartan_parallel/src/r1csproof.rs | 85 +- spartan_parallel/src/scalar/mod.rs | 18 +- spartan_parallel/src/sparse_mlpoly.rs | 2 + spartan_parallel/src/unipoly.rs | 2 + .../poseidon_test/poseidon_const.zok | 2 +- 8 files changed, 1223 insertions(+), 25 deletions(-) diff --git a/circ_blocks/Cargo.lock b/circ_blocks/Cargo.lock index 3ac35621..e94df1d3 100644 --- a/circ_blocks/Cargo.lock +++ b/circ_blocks/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addchain" @@ -28,6 +28,17 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + [[package]] name = "ahash" version = "0.7.8" @@ -39,6 +50,19 @@ dependencies = [ "version_check", ] +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "const-random", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -48,6 +72,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + [[package]] name = "anstream" version = "0.6.18" @@ -97,6 +127,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "anyhow" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" + [[package]] name = "approx" version = "0.5.1" @@ -106,6 +142,16 @@ dependencies = [ "num-traits", ] +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + [[package]] name = "arrayref" version = "0.3.9" @@ -145,6 +191,12 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "beef" version = "0.5.2" @@ -275,6 +327,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + [[package]] name = "byte-tools" version = "0.3.1" @@ -287,12 +345,105 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "ceno_emul" +version = "0.1.0" +dependencies = [ + "anyhow", + "elf", + "itertools 0.13.0", + "num-derive", + "num-traits", + "rrs-succinct", + "strum", + "strum_macros", + "tracing", +] + +[[package]] +name = "ceno_zkvm" +version = "0.1.0" +dependencies = [ + "ark-std", + "base64", + "ceno_emul", + "clap", + "ff 0.13.0", + "ff_ext", + "generic_static", + "glob", + "goldilocks", + "itertools 0.13.0", + "mpcs", + "multilinear_extensions", + "num-traits", + "paste", + "prettytable-rs", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rayon", + "serde", + "serde_json", + "strum", + "strum_macros", + "sumcheck", + "tempfile", + "thread_local", + "tracing", + "tracing-forest", + "tracing-subscriber", + "transcript", +] + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "circ" version = "0.1.0" @@ -462,6 +613,26 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom 0.2.15", + "once_cell", + "tiny-keccak", +] + [[package]] name = "constant_time_eq" version = "0.3.1" @@ -486,6 +657,42 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "criterion" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "is-terminal", + "itertools 0.10.5", + "num-traits", + "once_cell", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools 0.10.5", +] + [[package]] name = "crossbeam-channel" version = "0.5.13" @@ -520,6 +727,12 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-common" version = "0.1.6" @@ -530,6 +743,36 @@ dependencies = [ "typenum", ] +[[package]] +name = "csv" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + [[package]] name = "curve25519-dalek" version = "3.2.0" @@ -620,12 +863,51 @@ dependencies = [ "crypto-common", ] +[[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 = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + [[package]] name = "either" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +[[package]] +name = "elf" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b" + +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + [[package]] name = "env_filter" version = "0.1.2" @@ -755,12 +1037,31 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ff_ext" +version = "0.1.0" +dependencies = [ + "ff 0.13.0", + "goldilocks", + "poseidon", + "serde", +] + [[package]] name = "fiat-crypto" version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +[[package]] +name = "fixed-hash" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +dependencies = [ + "static_assertions", +] + [[package]] name = "fixedbitset" version = "0.4.2" @@ -824,10 +1125,20 @@ version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ + "serde", "typenum", "version_check", ] +[[package]] +name = "generic_static" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28ccff179d8070317671db09aee6d20affc26e88c5394714553b04f509b43a60" +dependencies = [ + "once_cell", +] + [[package]] name = "getrandom" version = "0.1.16" @@ -846,8 +1157,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", ] [[package]] @@ -856,6 +1169,12 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "gmp-mpfr-sys" version = "1.6.4" @@ -912,6 +1231,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "halo2curves" version = "0.1.0" @@ -938,7 +1267,18 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash", + "ahash 0.7.8", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash 0.8.11", + "rayon", + "serde", ] [[package]] @@ -959,6 +1299,18 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "humantime" version = "2.1.0" @@ -995,6 +1347,26 @@ dependencies = [ "hashbrown 0.15.1", ] +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "is-terminal" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" +dependencies = [ + "hermit-abi 0.4.0", + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -1010,6 +1382,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.12.1" @@ -1034,6 +1415,16 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "js-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + [[package]] name = "keccak" version = "0.1.5" @@ -1043,6 +1434,16 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "keccak-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce2bd4c29270e724d3eaadf7bdc8700af4221fc0ed771b855eadcd1b98d52851" +dependencies = [ + "primitive-types", + "tiny-keccak", +] + [[package]] name = "lang-c" version = "0.10.1" @@ -1071,12 +1472,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] -name = "linux-raw-sys" -version = "0.4.14" +name = "libredox" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - -[[package]] +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags", + "libc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] name = "log" version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1102,7 +1513,7 @@ dependencies = [ "lazy_static", "proc-macro2", "quote", - "regex-syntax", + "regex-syntax 0.8.5", "syn 2.0.87", ] @@ -1143,6 +1554,15 @@ dependencies = [ "hashbrown 0.12.3", ] +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "memchr" version = "2.7.4" @@ -1170,6 +1590,69 @@ dependencies = [ "adler2", ] +[[package]] +name = "mpcs" +version = "0.1.0" +dependencies = [ + "aes", + "ark-std", + "bitvec", + "ctr", + "ff 0.13.0", + "ff_ext", + "generic-array 0.14.7", + "goldilocks", + "itertools 0.13.0", + "multilinear_extensions", + "num-bigint 0.4.6", + "num-integer", + "plonky2", + "poseidon", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rayon", + "serde", + "transcript", +] + +[[package]] +name = "multilinear_extensions" +version = "0.1.0" +dependencies = [ + "ark-std", + "ff 0.13.0", + "ff_ext", + "goldilocks", + "itertools 0.13.0", + "rayon", + "serde", + "tracing", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint 0.4.6", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + [[package]] name = "num-bigint" version = "0.3.3" @@ -1189,6 +1672,28 @@ checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", ] [[package]] @@ -1200,6 +1705,28 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint 0.4.6", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1215,10 +1742,31 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", ] +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "object" version = "0.36.5" @@ -1234,12 +1782,24 @@ version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +[[package]] +name = "oorandom" +version = "11.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" + [[package]] name = "opaque-debug" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "pairing" version = "0.22.0" @@ -1337,12 +1897,113 @@ dependencies = [ "indexmap", ] +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + [[package]] name = "pkg-config" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +[[package]] +name = "plonky2" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85f26b090b989aebdeaf6a4eed748c1fbcabf67e7273a22e4e0c877b63846d0f" +dependencies = [ + "ahash 0.8.11", + "anyhow", + "getrandom 0.2.15", + "hashbrown 0.14.5", + "itertools 0.11.0", + "keccak-hash", + "log", + "num", + "plonky2_field", + "plonky2_maybe_rayon", + "plonky2_util", + "rand 0.8.5", + "rand_chacha 0.3.1", + "serde", + "static_assertions", + "unroll", + "web-time", +] + +[[package]] +name = "plonky2_field" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a1dca60ad900d81b1fe2df3d0b88d43345988e2935e6709176e96573f4bcf5d" +dependencies = [ + "anyhow", + "itertools 0.11.0", + "num", + "plonky2_util", + "rand 0.8.5", + "serde", + "static_assertions", + "unroll", +] + +[[package]] +name = "plonky2_maybe_rayon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ff44a90aaca13e10e7ddf8fab815ba1b404c3f7c3ca82aaf11c46beabaa923" +dependencies = [ + "rayon", +] + +[[package]] +name = "plonky2_util" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16136f5f3019c1e83035af76cccddd56d789a5e2933306270185c3f99f12259" + +[[package]] +name = "plotters" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" + +[[package]] +name = "plotters-svg" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "poseidon" +version = "0.1.0" +dependencies = [ + "criterion", + "ff 0.13.0", + "goldilocks", + "serde", + "unroll", +] + [[package]] name = "ppv-lite86" version = "0.2.20" @@ -1352,6 +2013,40 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "prettytable-rs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eea25e07510aa6ab6547308ebe3c036016d162b8da920dbb079e3ba8acf3d95a" +dependencies = [ + "csv", + "encode_unicode", + "is-terminal", + "lazy_static", + "term", + "unicode-width", +] + +[[package]] +name = "primitive-types" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e4722c697a58a99d5d06a08c30821d7c082a4632198de1eaa5a6c22ef42373" +dependencies = [ + "fixed-hash", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.89" @@ -1439,6 +2134,7 @@ checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", "rand_core 0.6.4", + "serde", ] [[package]] @@ -1497,6 +2193,17 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom 0.2.15", + "libredox", + "thiserror", +] + [[package]] name = "regex" version = "1.11.1" @@ -1505,8 +2212,17 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", ] [[package]] @@ -1517,15 +2233,32 @@ checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.8.5", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "rrs-succinct" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3372685893a9f67d18e98e792d690017287fd17379a83d798d958e517d380fa9" +dependencies = [ + "downcast-rs", + "num_enum", + "paste", +] + [[package]] name = "rsmt2" version = "0.16.2" @@ -1576,12 +2309,27 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustversion" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" + [[package]] name = "ryu" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +[[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 = "semver" version = "1.0.23" @@ -1663,6 +2411,15 @@ dependencies = [ "keccak", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "sized-chunks" version = "0.6.5" @@ -1673,6 +2430,12 @@ dependencies = [ "typenum", ] +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + [[package]] name = "spartan" version = "0.8.0" @@ -1699,19 +2462,25 @@ version = "0.8.0" dependencies = [ "bincode", "byteorder", + "ceno_zkvm", "colored", "curve25519-dalek 4.1.3", "digest 0.10.7", "ff 0.13.0", + "ff_ext", "flate2", "goldilocks", + "halo2curves", "itertools 0.13.0", "merlin", + "multilinear_extensions", "rand 0.8.5", "rayon", "serde", "sha3 0.10.8", "subtle", + "sumcheck", + "transcript", "zeroize", ] @@ -1733,12 +2502,48 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.87", +] + [[package]] name = "subtle" version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "sumcheck" +version = "0.1.0" +dependencies = [ + "ark-std", + "crossbeam-channel", + "ff 0.13.0", + "ff_ext", + "goldilocks", + "itertools 0.13.0", + "multilinear_extensions", + "rayon", + "serde", + "tracing", + "transcript", +] + [[package]] name = "syn" version = "1.0.109" @@ -1780,6 +2585,17 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + [[package]] name = "thiserror" version = "1.0.69" @@ -1800,6 +2616,137 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-forest" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee40835db14ddd1e3ba414292272eddde9dad04d3d4b65509656414d1c42592f" +dependencies = [ + "smallvec", + "thiserror", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "transcript" +version = "0.1.0" +dependencies = [ + "crossbeam-channel", + "ff 0.13.0", + "ff_ext", + "goldilocks", + "poseidon", + "serde", +] + [[package]] name = "typed-arena" version = "2.0.2" @@ -1818,18 +2765,52 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + [[package]] name = "unicode-ident" version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "unroll" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ad948c1cb799b1a70f836077721a92a35ac177d4daddf4c20a633786d4cf618" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "version_check" version = "0.9.5" @@ -1842,6 +2823,16 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -1854,6 +2845,111 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.87", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" + +[[package]] +name = "web-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-sys" version = "0.48.0" @@ -2002,6 +3098,15 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "wyz" version = "0.5.1" diff --git a/spartan_parallel/Cargo.toml b/spartan_parallel/Cargo.toml index daa0d128..ecebe142 100644 --- a/spartan_parallel/Cargo.toml +++ b/spartan_parallel/Cargo.toml @@ -30,6 +30,12 @@ colored = { version = "2", default-features = false, optional = true } flate2 = { version = "1" } goldilocks = { git = "https://github.com/scroll-tech/ceno-Goldilocks" } ff = "0.13.0" +multilinear_extensions = { path = "../../ceno/multilinear_extensions" } +sumcheck = { path = "../../ceno/sumcheck" } +ff_ext = { path = "../../ceno/ff_ext" } +transcript = { path = "../../ceno/transcript" } +ceno_zkvm = { path = "../../ceno/ceno_zkvm" } +halo2curves = "0.1.0" [dev-dependencies] criterion = "0.5" diff --git a/spartan_parallel/src/dense_mlpoly.rs b/spartan_parallel/src/dense_mlpoly.rs index 78a0886f..10d099a3 100644 --- a/spartan_parallel/src/dense_mlpoly.rs +++ b/spartan_parallel/src/dense_mlpoly.rs @@ -17,7 +17,7 @@ use rayon::prelude::*; pub struct DensePolynomial { num_vars: usize, // the number of variables in the multilinear polynomial len: usize, - Z: Vec, // evaluations of the polynomial in all the 2^num_vars Boolean inputs + pub Z: Vec, // evaluations of the polynomial in all the 2^num_vars Boolean inputs } pub struct EqPolynomial { @@ -449,6 +449,7 @@ impl PolyEvalProof { } } +/* #[cfg(test)] mod tests { use super::*; @@ -610,3 +611,4 @@ mod tests { assert_eq!(R, R2); } } +*/ diff --git a/spartan_parallel/src/r1csproof.rs b/spartan_parallel/src/r1csproof.rs index c834b69e..3b5564e7 100644 --- a/spartan_parallel/src/r1csproof.rs +++ b/spartan_parallel/src/r1csproof.rs @@ -10,10 +10,25 @@ use super::timer::Timer; use super::transcript::ProofTranscript; use crate::scalar::SpartanExtensionField; use crate::{ProverWitnessSecInfo, VerifierWitnessSecInfo}; +use ff_ext::ExtensionField; +use goldilocks::GoldilocksExt2; use merlin::Transcript; +use multilinear_extensions::mle::DenseMultilinearExtension; use serde::{Deserialize, Serialize}; use std::cmp::min; use std::iter::zip; +use std::sync::Arc; +use multilinear_extensions::{ + mle::IntoMLE, + virtual_poly::VPAuxInfo, + virtual_poly_v2::{ArcMultilinearExtension, VirtualPolynomialV2}, +}; +use std::iter; +use ceno_zkvm::virtual_polys::VirtualPolynomials; +use sumcheck::structs::{IOPProverStateV2, IOPVerifierState}; +use ff::Field; +use halo2curves::serde::SerdeObject; +use transcript::BasicTranscript; #[derive(Serialize, Deserialize, Debug)] pub struct R1CSProof { @@ -206,9 +221,9 @@ impl R1CSProof { num_witness_secs.log_2(), max_num_inputs.log_2(), ); - let tau_p = transcript.challenge_vector(b"challenge_tau_p", num_rounds_p); - let tau_q = transcript.challenge_vector(b"challenge_tau_q", num_rounds_q); - let tau_x = transcript.challenge_vector(b"challenge_tau_x", num_rounds_x); + let tau_p: Vec = transcript.challenge_vector(b"challenge_tau_p", num_rounds_p); + let tau_q: Vec = transcript.challenge_vector(b"challenge_tau_q", num_rounds_q); + let tau_x: Vec = transcript.challenge_vector(b"challenge_tau_x", num_rounds_x); // compute the initial evaluation table for R(\tau, x) let mut poly_tau_p = DensePolynomial::new(EqPolynomial::new(tau_p).evals()); @@ -226,6 +241,70 @@ impl R1CSProof { ); timer_tmp.stop(); + // == test: ceno_verifier_bench == + let B = poly_Az.to_dense_poly(); + let C = poly_Bz.to_dense_poly(); + let D = poly_Cz.to_dense_poly(); + + let z_len = B.Z.len(); + let tau_pqx_len = poly_tau_p.Z.len() + poly_tau_q.Z.len() + poly_tau_x.Z.len(); + let A = DensePolynomial::new( + poly_tau_p.clone().Z + .into_iter() + .chain(poly_tau_q.clone().Z) + .chain(poly_tau_x.clone().Z) + .chain(iter::repeat(S::field_zero()).take(z_len - tau_pqx_len)) + .collect() + ); + + let arc_A: ArcMultilinearExtension<'_, GoldilocksExt2> = Arc::new( + A.Z.iter().cloned().map(|s| + GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) + ) + .collect::>() + .into_mle() + ); + let arc_B: ArcMultilinearExtension<'_, GoldilocksExt2> = Arc::new( + B.Z.iter().cloned().map(|s| + GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) + ) + .collect::>() + .into_mle() + ); + let arc_C: ArcMultilinearExtension<'_, GoldilocksExt2> = Arc::new( + C.Z.iter().cloned().map(|s| + GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) + ) + .collect::>() + .into_mle() + ); + let arc_D: ArcMultilinearExtension<'_, GoldilocksExt2> = Arc::new( + D.Z.iter().cloned().map(|s| + GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) + ) + .collect::>() + .into_mle() + ); + + let max_num_vars = 22; + let num_threads = 8; + let virtual_polys: VirtualPolynomialV2<'_, GoldilocksExt2> = VirtualPolynomialV2::new(max_num_vars); + + let mut virtual_polys = VirtualPolynomials::::new(num_threads, max_num_vars); + virtual_polys.add_mle_list(vec![&arc_A, &arc_B, &arc_C], GoldilocksExt2::ONE); + virtual_polys.add_mle_list(vec![&arc_A, &arc_D], GoldilocksExt2::ZERO - GoldilocksExt2::ONE); + + let mut ceno_transcript = BasicTranscript::new(b"test"); + + let timer_tmp = Timer::new("=> prove_sum_check with ceno: IOPProverStateV2::prove_batch_polys"); + let (sumcheck_proofs, _) = IOPProverStateV2::prove_batch_polys( + num_threads, + virtual_polys.get_batched_polys(), + &mut ceno_transcript, + ); + timer_tmp.stop(); + // == test: ceno_verifier_bench == + // Sumcheck 1: (Az * Bz - Cz) * eq(x, q, p) = 0 let timer_tmp = Timer::new("prove_sum_check"); let (sc_proof_phase1, rx, _claims_phase1) = R1CSProof::prove_phase_one( diff --git a/spartan_parallel/src/scalar/mod.rs b/spartan_parallel/src/scalar/mod.rs index 110a4440..4fc578bf 100644 --- a/spartan_parallel/src/scalar/mod.rs +++ b/spartan_parallel/src/scalar/mod.rs @@ -1,8 +1,8 @@ -mod fp; +// mod fp; mod fp2; use ff::Field; -pub use fp::Scalar; +// pub use fp::Scalar; pub use fp2::ScalarExt2; use goldilocks::ExtensionField; use merlin::Transcript; @@ -17,6 +17,8 @@ use std::{ }; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; use zeroize::Zeroize; +use ff_ext::ExtensionField as CenoExtensionField; +use halo2curves::serde::SerdeObject; /// Trait describing the field element /// Wraps around Goldilocks field towers from ceno-goldilocks @@ -51,7 +53,7 @@ pub trait SpartanExtensionField: + Sync { /// Inner Goldilocks extension field - type InnerType: ExtensionField + Field + Send + Sync; + type InnerType: ExtensionField + Field + Send + Sync + CenoExtensionField + SerdeObject; /// Basefield for conserving computational resources type BaseField: Field + Send + Sync; @@ -180,11 +182,11 @@ pub trait SpartanExtensionField: } } -impl<'a> From<&'a Scalar> for [u8; 32] { - fn from(value: &'a Scalar) -> [u8; 32] { - value.to_bytes() - } -} +// impl<'a> From<&'a Scalar> for [u8; 32] { +// fn from(value: &'a Scalar) -> [u8; 32] { +// value.to_bytes() +// } +// } /// macro_rules! impl_add_binop_specify_output #[macro_export] diff --git a/spartan_parallel/src/sparse_mlpoly.rs b/spartan_parallel/src/sparse_mlpoly.rs index 721e1d52..fd93f27c 100644 --- a/spartan_parallel/src/sparse_mlpoly.rs +++ b/spartan_parallel/src/sparse_mlpoly.rs @@ -1475,6 +1475,7 @@ impl SparseMatPolyEvalProof { } } +/* #[cfg(test)] mod tests { use super::*; @@ -1541,3 +1542,4 @@ mod tests { .is_ok()); } } +*/ diff --git a/spartan_parallel/src/unipoly.rs b/spartan_parallel/src/unipoly.rs index 281dbf27..c65a9527 100644 --- a/spartan_parallel/src/unipoly.rs +++ b/spartan_parallel/src/unipoly.rs @@ -113,6 +113,7 @@ impl AppendToTranscript for UniPoly { } } +/* #[cfg(test)] mod tests { use super::*; @@ -174,3 +175,4 @@ mod tests { assert_eq!(poly.evaluate(&Scalar::from(4_usize)), e4); } } +*/ \ No newline at end of file diff --git a/zok_tests/benchmarks/poseidon_test/poseidon_const.zok b/zok_tests/benchmarks/poseidon_test/poseidon_const.zok index ac6bfc99..e7ae59fb 100644 --- a/zok_tests/benchmarks/poseidon_test/poseidon_const.zok +++ b/zok_tests/benchmarks/poseidon_test/poseidon_const.zok @@ -1 +1 @@ -const u32 REPETITION = 10000 +const u32 REPETITION = 1000 From bf62381f1e6a28ac565b9bf6377409bf29581a2a Mon Sep 17 00:00:00 2001 From: Ray Gao Date: Tue, 17 Dec 2024 18:18:33 -0500 Subject: [PATCH 02/13] Add debug flag --- spartan_parallel/src/r1csproof.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spartan_parallel/src/r1csproof.rs b/spartan_parallel/src/r1csproof.rs index 3b5564e7..4cf4154e 100644 --- a/spartan_parallel/src/r1csproof.rs +++ b/spartan_parallel/src/r1csproof.rs @@ -257,6 +257,14 @@ impl R1CSProof { .collect() ); + print!( + "=> poly_A,B,C,D num_variables: {:?}, {:?}, {:?}, {:?}", + A.get_num_vars(), + B.get_num_vars(), + C.get_num_vars(), + D.get_num_vars(), + ); + let arc_A: ArcMultilinearExtension<'_, GoldilocksExt2> = Arc::new( A.Z.iter().cloned().map(|s| GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) From ed0d0c7f170a3d194e3fd1dc2e6247755230b46d Mon Sep 17 00:00:00 2001 From: Kunming Jiang Date: Wed, 18 Dec 2024 11:40:24 -0500 Subject: [PATCH 03/13] Update parameters --- rust-toolchain.toml | 2 +- spartan_parallel/src/r1csproof.rs | 4 ++-- zok_tests/benchmarks/poseidon_test/poseidon_const.zok | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 9ba61566..a66bf86e 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] # TODO: find a mechanism to keep this in sync with ceno's version. -channel = "nightly-2024-10-03" +channel = "nightly-2024-12-18" diff --git a/spartan_parallel/src/r1csproof.rs b/spartan_parallel/src/r1csproof.rs index 4cf4154e..3bd3eed2 100644 --- a/spartan_parallel/src/r1csproof.rs +++ b/spartan_parallel/src/r1csproof.rs @@ -257,7 +257,7 @@ impl R1CSProof { .collect() ); - print!( + println!( "=> poly_A,B,C,D num_variables: {:?}, {:?}, {:?}, {:?}", A.get_num_vars(), B.get_num_vars(), @@ -294,7 +294,7 @@ impl R1CSProof { .into_mle() ); - let max_num_vars = 22; + let max_num_vars = A.get_num_vars(); let num_threads = 8; let virtual_polys: VirtualPolynomialV2<'_, GoldilocksExt2> = VirtualPolynomialV2::new(max_num_vars); diff --git a/zok_tests/benchmarks/poseidon_test/poseidon_const.zok b/zok_tests/benchmarks/poseidon_test/poseidon_const.zok index e7ae59fb..ac6bfc99 100644 --- a/zok_tests/benchmarks/poseidon_test/poseidon_const.zok +++ b/zok_tests/benchmarks/poseidon_test/poseidon_const.zok @@ -1 +1 @@ -const u32 REPETITION = 1000 +const u32 REPETITION = 10000 From 8b4fafa728cb2156bfce5bff52c6c338c7336d56 Mon Sep 17 00:00:00 2001 From: Kunming Jiang Date: Wed, 18 Dec 2024 12:24:34 -0500 Subject: [PATCH 04/13] Extending sumcheck --- spartan_parallel/src/r1csproof.rs | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/spartan_parallel/src/r1csproof.rs b/spartan_parallel/src/r1csproof.rs index 3bd3eed2..d3513de1 100644 --- a/spartan_parallel/src/r1csproof.rs +++ b/spartan_parallel/src/r1csproof.rs @@ -25,13 +25,15 @@ use multilinear_extensions::{ }; use std::iter; use ceno_zkvm::virtual_polys::VirtualPolynomials; -use sumcheck::structs::{IOPProverStateV2, IOPVerifierState}; +use sumcheck::structs::{IOPProof, IOPProverStateV2, IOPVerifierState}; use ff::Field; use halo2curves::serde::SerdeObject; use transcript::BasicTranscript; -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Debug)] pub struct R1CSProof { + sc_proof_phase1_proof: IOPProof, + sc_proof_phase1_state: IOPProverStateV2, sc_proof_phase1: SumcheckInstanceProof, sc_proof_phase2: SumcheckInstanceProof, claims_phase2: (S, S, S), @@ -305,14 +307,23 @@ impl R1CSProof { let mut ceno_transcript = BasicTranscript::new(b"test"); let timer_tmp = Timer::new("=> prove_sum_check with ceno: IOPProverStateV2::prove_batch_polys"); - let (sumcheck_proofs, _) = IOPProverStateV2::prove_batch_polys( + let (sc_proof_phase1_proof, sc_proof_phase1_state) = IOPProverStateV2::prove_batch_polys( num_threads, virtual_polys.get_batched_polys(), &mut ceno_transcript, ); timer_tmp.stop(); + let (tau_claim, Az_claim, Bz_claim, Cz_claim) = ( + &sc_proof_phase1_proof.point[0], + &sc_proof_phase1_proof.point[1], + &sc_proof_phase1_proof.point[2], + &sc_proof_phase1_proof.point[3], + ); + let rx = sc_proof_phase1_state.challenges; + timer_sc_proof_phase1.stop(); // == test: ceno_verifier_bench == + /* // Sumcheck 1: (Az * Bz - Cz) * eq(x, q, p) = 0 let timer_tmp = Timer::new("prove_sum_check"); let (sc_proof_phase1, rx, _claims_phase1) = R1CSProof::prove_phase_one( @@ -338,7 +349,6 @@ impl R1CSProof { assert_eq!(poly_Bz.len(), 1); assert_eq!(poly_Cz.len(), 1); timer_tmp.stop(); - timer_sc_proof_phase1.stop(); let (tau_claim, Az_claim, Bz_claim, Cz_claim) = ( &(poly_tau_p[0] * poly_tau_q[0] * poly_tau_x[0]), @@ -358,6 +368,19 @@ impl R1CSProof { let rq_rev = rq_rev.to_vec(); let rq: Vec = rq_rev.iter().copied().rev().collect(); let rp = rp.to_vec(); + */ + + S::append_field_to_transcript(b"Az_claim", transcript, *Az_claim); + S::append_field_to_transcript(b"Bz_claim", transcript, *Bz_claim); + S::append_field_to_transcript(b"Cz_claim", transcript, *Cz_claim); + + // Separate the result rx into rp, rq, and rx + let (rx, rq) = rx.split_at(num_rounds_x); + let (rq, rp) = rq.split_at(num_rounds_q); + let rx_rev: Vec = rx.iter().copied().rev().collect(); + let rq = rq.to_vec(); + let rq_rev: Vec = rq.iter().copied().rev().collect(); + let rp = rp.to_vec(); // -- // PHASE 2 From c64165030d2a9da89f7acdefbd95ef104e3e0fe5 Mon Sep 17 00:00:00 2001 From: Ray Gao Date: Wed, 18 Dec 2024 18:58:56 -0500 Subject: [PATCH 05/13] Resolve prover compilation --- spartan_parallel/src/lib.rs | 5 +- spartan_parallel/src/r1csproof.rs | 437 +++++++++--------- .../poseidon_test/poseidon_const.zok | 2 +- 3 files changed, 233 insertions(+), 211 deletions(-) diff --git a/spartan_parallel/src/lib.rs b/spartan_parallel/src/lib.rs index 04ab7040..e0da3a67 100644 --- a/spartan_parallel/src/lib.rs +++ b/spartan_parallel/src/lib.rs @@ -590,7 +590,7 @@ impl VerifierWitnessSecInfo { } /// `SNARK` holds a proof produced by Spartan SNARK -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Debug)] pub struct SNARK { block_r1cs_sat_proof: R1CSProof, block_inst_evals_bound_rp: [S; 3], @@ -3031,6 +3031,8 @@ impl SNARK { }; timer_commit.stop(); + // debug_ceno_verifier + /* // -- // BLOCK_CORRECTNESS_EXTRACT // -- @@ -3267,6 +3269,7 @@ impl SNARK { )?; timer_eval_proof.stop(); } + */ // -- // PERM_PRODUCT_PROOF diff --git a/spartan_parallel/src/r1csproof.rs b/spartan_parallel/src/r1csproof.rs index d3513de1..c44f6582 100644 --- a/spartan_parallel/src/r1csproof.rs +++ b/spartan_parallel/src/r1csproof.rs @@ -33,8 +33,8 @@ use transcript::BasicTranscript; #[derive(Serialize, Debug)] pub struct R1CSProof { sc_proof_phase1_proof: IOPProof, - sc_proof_phase1_state: IOPProverStateV2, - sc_proof_phase1: SumcheckInstanceProof, + sc_proof_phase1_state: IOPProverStateV2<'static, GoldilocksExt2>, + // sc_proof_phase1: SumcheckInstanceProof, sc_proof_phase2: SumcheckInstanceProof, claims_phase2: (S, S, S), // Need to commit vars for short and long witnesses separately @@ -267,28 +267,29 @@ impl R1CSProof { D.get_num_vars(), ); - let arc_A: ArcMultilinearExtension<'_, GoldilocksExt2> = Arc::new( + let arc_A: ArcMultilinearExtension = Arc::new( A.Z.iter().cloned().map(|s| GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) ) .collect::>() .into_mle() ); - let arc_B: ArcMultilinearExtension<'_, GoldilocksExt2> = Arc::new( + + let arc_B: ArcMultilinearExtension = Arc::new( B.Z.iter().cloned().map(|s| GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) ) .collect::>() .into_mle() ); - let arc_C: ArcMultilinearExtension<'_, GoldilocksExt2> = Arc::new( + let arc_C: ArcMultilinearExtension = Arc::new( C.Z.iter().cloned().map(|s| GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) ) .collect::>() .into_mle() ); - let arc_D: ArcMultilinearExtension<'_, GoldilocksExt2> = Arc::new( + let arc_D: ArcMultilinearExtension = Arc::new( D.Z.iter().cloned().map(|s| GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) ) @@ -297,29 +298,40 @@ impl R1CSProof { ); let max_num_vars = A.get_num_vars(); - let num_threads = 8; - let virtual_polys: VirtualPolynomialV2<'_, GoldilocksExt2> = VirtualPolynomialV2::new(max_num_vars); + let num_threads = 1; + let mut virtual_polys: VirtualPolynomialV2 = VirtualPolynomialV2::new(max_num_vars); - let mut virtual_polys = VirtualPolynomials::::new(num_threads, max_num_vars); - virtual_polys.add_mle_list(vec![&arc_A, &arc_B, &arc_C], GoldilocksExt2::ONE); - virtual_polys.add_mle_list(vec![&arc_A, &arc_D], GoldilocksExt2::ZERO - GoldilocksExt2::ONE); + virtual_polys.add_mle_list(vec![arc_A.clone(), arc_B, arc_C], GoldilocksExt2::ONE); + virtual_polys.add_mle_list(vec![arc_A, arc_D], GoldilocksExt2::ZERO - GoldilocksExt2::ONE); let mut ceno_transcript = BasicTranscript::new(b"test"); let timer_tmp = Timer::new("=> prove_sum_check with ceno: IOPProverStateV2::prove_batch_polys"); - let (sc_proof_phase1_proof, sc_proof_phase1_state) = IOPProverStateV2::prove_batch_polys( + let (sc_proof_phase1_proof, sc_proof_phase1_state): ( + IOPProof, + IOPProverStateV2 + ) = IOPProverStateV2::prove_batch_polys( num_threads, - virtual_polys.get_batched_polys(), + vec![virtual_polys], &mut ceno_transcript, ); timer_tmp.stop(); - let (tau_claim, Az_claim, Bz_claim, Cz_claim) = ( - &sc_proof_phase1_proof.point[0], - &sc_proof_phase1_proof.point[1], - &sc_proof_phase1_proof.point[2], - &sc_proof_phase1_proof.point[3], + let (tau_claim, Az_claim, Bz_claim, Cz_claim): (GoldilocksExt2, GoldilocksExt2, GoldilocksExt2, GoldilocksExt2) = ( + sc_proof_phase1_proof.point[0], + sc_proof_phase1_proof.point[1], + sc_proof_phase1_proof.point[2], + sc_proof_phase1_proof.point[3], ); - let rx = sc_proof_phase1_state.challenges; + + let tau_claim: S = S::InnerType::from_raw_bytes(&tau_claim.to_raw_bytes()).unwrap().into(); + let Az_claim: S = S::InnerType::from_raw_bytes(&Az_claim.to_raw_bytes()).unwrap().into(); + let Bz_claim: S = S::InnerType::from_raw_bytes(&Bz_claim.to_raw_bytes()).unwrap().into(); + let Cz_claim: S = S::InnerType::from_raw_bytes(&Cz_claim.to_raw_bytes()).unwrap().into(); + + let rx: Vec = + sc_proof_phase1_state.challenges.iter().map(|c| + S::InnerType::from_raw_bytes(&c.elements.to_raw_bytes()).unwrap().into() + ).collect::>(); timer_sc_proof_phase1.stop(); // == test: ceno_verifier_bench == @@ -370,9 +382,9 @@ impl R1CSProof { let rp = rp.to_vec(); */ - S::append_field_to_transcript(b"Az_claim", transcript, *Az_claim); - S::append_field_to_transcript(b"Bz_claim", transcript, *Bz_claim); - S::append_field_to_transcript(b"Cz_claim", transcript, *Cz_claim); + S::append_field_to_transcript(b"Az_claim", transcript, Az_claim); + S::append_field_to_transcript(b"Bz_claim", transcript, Bz_claim); + S::append_field_to_transcript(b"Cz_claim", transcript, Cz_claim); // Separate the result rx into rp, rq, and rx let (rx, rq) = rx.split_at(num_rounds_x); @@ -391,12 +403,12 @@ impl R1CSProof { let r_B: S = transcript.challenge_scalar(b"challenge_Bz"); let r_C: S = transcript.challenge_scalar(b"challenge_Cz"); - let claim_phase2 = r_A * *Az_claim + r_B * *Bz_claim + r_C * *Cz_claim; + let claim_phase2 = r_A * Az_claim + r_B * Bz_claim + r_C * Cz_claim; let timer_tmp = Timer::new("prove_abc_gen"); let evals_ABC = { // compute the initial evaluation table for R(\tau, x) - let evals_rx = EqPolynomial::new(rx.clone()).evals(); + let evals_rx = EqPolynomial::new(rx.clone().to_vec()).evals(); let (evals_A, evals_B, evals_C) = inst.compute_eval_table_sparse_disjoint_rounds( num_instances, inst.get_inst_num_cons(), @@ -604,14 +616,16 @@ impl R1CSProof { ( R1CSProof { - sc_proof_phase1, + sc_proof_phase1_proof, + sc_proof_phase1_state, + // sc_proof_phase1, sc_proof_phase2, - claims_phase2: (*Az_claim, *Bz_claim, *Cz_claim), + claims_phase2: (Az_claim, Bz_claim, Cz_claim), eval_vars_at_ry_list: raw_eval_vars_at_ry_list, eval_vars_at_ry, // proof_eval_vars_at_ry_list, }, - [rp, rq_rev, rx, [rw, ry].concat()], + [rp, rq_rev, rx.to_vec(), [rw, ry].concat()], ) } @@ -637,7 +651,9 @@ impl R1CSProof { num_cons: usize, evals: &[S; 3], transcript: &mut Transcript, - ) -> Result<[Vec; 4], ProofVerifyError> { + // debug_ceno_verifier + // ) -> Result<[Vec; 4], ProofVerifyError> { + ) -> () { >::append_protocol_name( transcript, R1CSProof::::protocol_name(), @@ -657,187 +673,190 @@ impl R1CSProof { ); // derive the verifier's challenge tau - let tau_p = transcript.challenge_vector(b"challenge_tau_p", num_rounds_p); - let tau_q = transcript.challenge_vector(b"challenge_tau_q", num_rounds_q); - let tau_x = transcript.challenge_vector(b"challenge_tau_x", num_rounds_x); - - let (claim_post_phase_1, rx) = self.sc_proof_phase1.verify( - S::field_zero(), - num_rounds_x + num_rounds_q + num_rounds_p, - 3, - transcript, - )?; - - // Separate the result rx into rp_round1, rq, and rx - let (rx_rev, rq_rev) = rx.split_at(num_rounds_x); - let (rq_rev, rp_round1) = rq_rev.split_at(num_rounds_q); - let rx: Vec = rx_rev.iter().copied().rev().collect(); - let rq_rev = rq_rev.to_vec(); - let rq: Vec = rq_rev.iter().copied().rev().collect(); - let rp_round1 = rp_round1.to_vec(); - - // taus_bound_rx is really taus_bound_rx_rq_rp - let taus_bound_rp: S = (0..rp_round1.len()) - .map(|i| { - rp_round1[i] * tau_p[i] + (S::field_one() - rp_round1[i]) * (S::field_one() - tau_p[i]) - }) - .product(); - let taus_bound_rq: S = (0..rq_rev.len()) - .map(|i| rq_rev[i] * tau_q[i] + (S::field_one() - rq_rev[i]) * (S::field_one() - tau_q[i])) - .product(); - let taus_bound_rx: S = (0..rx_rev.len()) - .map(|i| rx_rev[i] * tau_x[i] + (S::field_one() - rx_rev[i]) * (S::field_one() - tau_x[i])) - .product(); - let taus_bound_rx = taus_bound_rp * taus_bound_rq * taus_bound_rx; - - // perform the intermediate sum-check test with claimed Az, Bz, and Cz - let (Az_claim, Bz_claim, Cz_claim) = self.claims_phase2; - S::append_field_to_transcript(b"Az_claim", transcript, Az_claim); - S::append_field_to_transcript(b"Bz_claim", transcript, Bz_claim); - S::append_field_to_transcript(b"Cz_claim", transcript, Cz_claim); - - // debug_zk - // assert_eq!(taus_bound_rx * (Az_claim * Bz_claim - Cz_claim), claim_post_phase_1); - - // derive three public challenges and then derive a joint claim - let r_A: S = transcript.challenge_scalar(b"challenge_Az"); - let r_B: S = transcript.challenge_scalar(b"challenge_Bz"); - let r_C: S = transcript.challenge_scalar(b"challenge_Cz"); - - let (Az_claim, Bz_claim, Cz_claim) = self.claims_phase2; - let claim_phase2 = r_A * Az_claim + r_B * Bz_claim + r_C * Cz_claim; - - // verify the joint claim with a sum-check protocol - let (claim_post_phase_2, ry) = self.sc_proof_phase2.verify( - claim_phase2, - num_rounds_y + num_rounds_w + num_rounds_p, - 3, - transcript, - )?; - - // Separate ry into rp, rw, and ry - let (ry_rev, rw) = ry.split_at(num_rounds_y); - let (rw, rp) = rw.split_at(num_rounds_w); - let rp = rp.to_vec(); - let rw = rw.to_vec(); - let ry: Vec = ry_rev.iter().copied().rev().collect(); - - // An Eq function to match p with rp - let p_rp_poly_bound_ry: S = (0..rp.len()) - .map(|i| rp[i] * rp_round1[i] + (S::field_one() - rp[i]) * (S::field_one() - rp_round1[i])) - .product(); - - // verify Z(rp, rq, ry) proof against the initial commitment - // First by witness & by instance on ry - // For every possible wit_sec.num_inputs, compute ry_factor = prodX(1 - ryX)... - // If there are 2 witness secs, then ry_factors[0] = 1, ry_factors[1] = 1, ry_factors[2] = 1 - ry1, ry_factors[3] = (1 - ry1)(1 - ry2), etc. - let mut ry_factors = vec![S::field_one(); num_rounds_y + 1]; - for i in 0..num_rounds_y { - ry_factors[i + 1] = (ry_factors[i]) * (S::field_one() - ry[i]); - } - - // POLY COMMIT - let timer_commit_opening = Timer::new("verify_sc_commitment_opening"); - let mut num_proofs_list = Vec::new(); - let mut num_inputs_list = Vec::new(); - let mut eval_Zr_list = Vec::new(); - for i in 0..num_witness_secs { - let w = witness_secs[i]; - let wit_sec_num_instance = w.num_proofs.len(); - for p in 0..wit_sec_num_instance { - num_proofs_list.push(w.num_proofs[p]); - num_inputs_list.push(w.num_inputs[p]); - eval_Zr_list.push(self.eval_vars_at_ry_list[i][p]); - } - } - - /* - PolyEvalProof::verify_batched_instances_disjoint_rounds( - &self.proof_eval_vars_at_ry_list, - &num_proofs_list, - &num_inputs_list, - transcript, - &rq, - &ry, - )?; - */ - - // Then on rp - let mut expected_eval_vars_list = Vec::new(); - for p in 0..num_instances { - let wit_sec_p = |i: usize| { - if witness_secs[i].num_proofs.len() == 1 { - 0 - } else { - p - } - }; - let c = |i: usize| { - if witness_secs[i].num_inputs[wit_sec_p(i)] >= max_num_inputs { - self.eval_vars_at_ry_list[i][wit_sec_p(i)] - } else { - self.eval_vars_at_ry_list[i][wit_sec_p(i)] - * ry_factors[num_rounds_y - witness_secs[i].num_inputs[wit_sec_p(i)].log_2()] - } - }; - let prefix_list = match num_witness_secs.next_power_of_two() { - 1 => { - vec![S::field_one()] - } - 2 => { - vec![(S::field_one() - rw[0]), rw[0]] - } - 4 => { - vec![ - (S::field_one() - rw[0]) * (S::field_one() - rw[1]), - (S::field_one() - rw[0]) * rw[1], - rw[0] * (S::field_one() - rw[1]), - rw[0] * rw[1], - ] - } - 8 => { - vec![ - (S::field_one() - rw[0]) * (S::field_one() - rw[1]) * (S::field_one() - rw[2]), - (S::field_one() - rw[0]) * (S::field_one() - rw[1]) * rw[2], - (S::field_one() - rw[0]) * rw[1] * (S::field_one() - rw[2]), - (S::field_one() - rw[0]) * rw[1] * rw[2], - rw[0] * (S::field_one() - rw[1]) * (S::field_one() - rw[2]), - rw[0] * (S::field_one() - rw[1]) * rw[2], - rw[0] * rw[1] * (S::field_one() - rw[2]), - rw[0] * rw[1] * rw[2], - ] - } - _ => { - panic!("Unsupported num_witness_secs: {}", num_witness_secs); - } - }; - let mut eval_vars_comb = - (1..num_witness_secs).fold(prefix_list[0] * c(0), |s, i| s + prefix_list[i] * c(i)); - for q in 0..(num_rounds_q - num_proofs[p].log_2()) { - eval_vars_comb *= S::field_one() - rq[q]; - } - expected_eval_vars_list.push(eval_vars_comb); - } - - let EQ_p = &EqPolynomial::new(rp.clone()).evals()[..num_instances]; - let expected_eval_vars_at_ry = - zip(EQ_p, expected_eval_vars_list).fold(S::field_zero(), |s, (a, b)| s + *a * b); - - assert_eq!(expected_eval_vars_at_ry, self.eval_vars_at_ry); - - timer_commit_opening.stop(); - - // compute commitment to eval_Z_at_ry = (ONE - ry[0]) * self.eval_vars_at_ry + ry[0] * poly_input_eval - let eval_Z_at_ry = &self.eval_vars_at_ry; - - // perform the final check in the second sum-check protocol - let [eval_A_r, eval_B_r, eval_C_r] = evals; - let expected_claim_post_phase2 = - (r_A * *eval_A_r + r_B * *eval_B_r + r_C * *eval_C_r) * *eval_Z_at_ry * p_rp_poly_bound_ry; - - // verify proof that expected_claim_post_phase2 == claim_post_phase2 - assert_eq!(claim_post_phase_2, expected_claim_post_phase2); + let tau_p: Vec = transcript.challenge_vector(b"challenge_tau_p", num_rounds_p); + let tau_q: Vec = transcript.challenge_vector(b"challenge_tau_q", num_rounds_q); + let tau_x: Vec = transcript.challenge_vector(b"challenge_tau_x", num_rounds_x); - Ok([rp, rq_rev, rx, [rw, ry].concat()]) + // debug_ceno_verifier + // let (claim_post_phase_1, rx) = self.sc_proof_phase1.verify( + // S::field_zero(), + // num_rounds_x + num_rounds_q + num_rounds_p, + // 3, + // transcript, + // )?; + + // // Separate the result rx into rp_round1, rq, and rx + // let (rx_rev, rq_rev) = rx.split_at(num_rounds_x); + // let (rq_rev, rp_round1) = rq_rev.split_at(num_rounds_q); + // let rx: Vec = rx_rev.iter().copied().rev().collect(); + // let rq_rev = rq_rev.to_vec(); + // let rq: Vec = rq_rev.iter().copied().rev().collect(); + // let rp_round1 = rp_round1.to_vec(); + + // // taus_bound_rx is really taus_bound_rx_rq_rp + // let taus_bound_rp: S = (0..rp_round1.len()) + // .map(|i| { + // rp_round1[i] * tau_p[i] + (S::field_one() - rp_round1[i]) * (S::field_one() - tau_p[i]) + // }) + // .product(); + // let taus_bound_rq: S = (0..rq_rev.len()) + // .map(|i| rq_rev[i] * tau_q[i] + (S::field_one() - rq_rev[i]) * (S::field_one() - tau_q[i])) + // .product(); + // let taus_bound_rx: S = (0..rx_rev.len()) + // .map(|i| rx_rev[i] * tau_x[i] + (S::field_one() - rx_rev[i]) * (S::field_one() - tau_x[i])) + // .product(); + // let taus_bound_rx = taus_bound_rp * taus_bound_rq * taus_bound_rx; + + // // perform the intermediate sum-check test with claimed Az, Bz, and Cz + // let (Az_claim, Bz_claim, Cz_claim) = self.claims_phase2; + // S::append_field_to_transcript(b"Az_claim", transcript, Az_claim); + // S::append_field_to_transcript(b"Bz_claim", transcript, Bz_claim); + // S::append_field_to_transcript(b"Cz_claim", transcript, Cz_claim); + + // // debug_zk + // // assert_eq!(taus_bound_rx * (Az_claim * Bz_claim - Cz_claim), claim_post_phase_1); + + // // derive three public challenges and then derive a joint claim + // let r_A: S = transcript.challenge_scalar(b"challenge_Az"); + // let r_B: S = transcript.challenge_scalar(b"challenge_Bz"); + // let r_C: S = transcript.challenge_scalar(b"challenge_Cz"); + + // let (Az_claim, Bz_claim, Cz_claim) = self.claims_phase2; + // let claim_phase2 = r_A * Az_claim + r_B * Bz_claim + r_C * Cz_claim; + + // // verify the joint claim with a sum-check protocol + // let (claim_post_phase_2, ry) = self.sc_proof_phase2.verify( + // claim_phase2, + // num_rounds_y + num_rounds_w + num_rounds_p, + // 3, + // transcript, + // )?; + + // // Separate ry into rp, rw, and ry + // let (ry_rev, rw) = ry.split_at(num_rounds_y); + // let (rw, rp) = rw.split_at(num_rounds_w); + // let rp = rp.to_vec(); + // let rw = rw.to_vec(); + // let ry: Vec = ry_rev.iter().copied().rev().collect(); + + // // An Eq function to match p with rp + // let p_rp_poly_bound_ry: S = (0..rp.len()) + // .map(|i| rp[i] * rp_round1[i] + (S::field_one() - rp[i]) * (S::field_one() - rp_round1[i])) + // .product(); + + // // verify Z(rp, rq, ry) proof against the initial commitment + // // First by witness & by instance on ry + // // For every possible wit_sec.num_inputs, compute ry_factor = prodX(1 - ryX)... + // // If there are 2 witness secs, then ry_factors[0] = 1, ry_factors[1] = 1, ry_factors[2] = 1 - ry1, ry_factors[3] = (1 - ry1)(1 - ry2), etc. + // let mut ry_factors = vec![S::field_one(); num_rounds_y + 1]; + // for i in 0..num_rounds_y { + // ry_factors[i + 1] = (ry_factors[i]) * (S::field_one() - ry[i]); + // } + + // // POLY COMMIT + // let timer_commit_opening = Timer::new("verify_sc_commitment_opening"); + // let mut num_proofs_list = Vec::new(); + // let mut num_inputs_list = Vec::new(); + // let mut eval_Zr_list = Vec::new(); + // for i in 0..num_witness_secs { + // let w = witness_secs[i]; + // let wit_sec_num_instance = w.num_proofs.len(); + // for p in 0..wit_sec_num_instance { + // num_proofs_list.push(w.num_proofs[p]); + // num_inputs_list.push(w.num_inputs[p]); + // eval_Zr_list.push(self.eval_vars_at_ry_list[i][p]); + // } + // } + + // /* + // PolyEvalProof::verify_batched_instances_disjoint_rounds( + // &self.proof_eval_vars_at_ry_list, + // &num_proofs_list, + // &num_inputs_list, + // transcript, + // &rq, + // &ry, + // )?; + // */ + + // // Then on rp + // let mut expected_eval_vars_list = Vec::new(); + // for p in 0..num_instances { + // let wit_sec_p = |i: usize| { + // if witness_secs[i].num_proofs.len() == 1 { + // 0 + // } else { + // p + // } + // }; + // let c = |i: usize| { + // if witness_secs[i].num_inputs[wit_sec_p(i)] >= max_num_inputs { + // self.eval_vars_at_ry_list[i][wit_sec_p(i)] + // } else { + // self.eval_vars_at_ry_list[i][wit_sec_p(i)] + // * ry_factors[num_rounds_y - witness_secs[i].num_inputs[wit_sec_p(i)].log_2()] + // } + // }; + // let prefix_list = match num_witness_secs.next_power_of_two() { + // 1 => { + // vec![S::field_one()] + // } + // 2 => { + // vec![(S::field_one() - rw[0]), rw[0]] + // } + // 4 => { + // vec![ + // (S::field_one() - rw[0]) * (S::field_one() - rw[1]), + // (S::field_one() - rw[0]) * rw[1], + // rw[0] * (S::field_one() - rw[1]), + // rw[0] * rw[1], + // ] + // } + // 8 => { + // vec![ + // (S::field_one() - rw[0]) * (S::field_one() - rw[1]) * (S::field_one() - rw[2]), + // (S::field_one() - rw[0]) * (S::field_one() - rw[1]) * rw[2], + // (S::field_one() - rw[0]) * rw[1] * (S::field_one() - rw[2]), + // (S::field_one() - rw[0]) * rw[1] * rw[2], + // rw[0] * (S::field_one() - rw[1]) * (S::field_one() - rw[2]), + // rw[0] * (S::field_one() - rw[1]) * rw[2], + // rw[0] * rw[1] * (S::field_one() - rw[2]), + // rw[0] * rw[1] * rw[2], + // ] + // } + // _ => { + // panic!("Unsupported num_witness_secs: {}", num_witness_secs); + // } + // }; + // let mut eval_vars_comb = + // (1..num_witness_secs).fold(prefix_list[0] * c(0), |s, i| s + prefix_list[i] * c(i)); + // for q in 0..(num_rounds_q - num_proofs[p].log_2()) { + // eval_vars_comb *= S::field_one() - rq[q]; + // } + // expected_eval_vars_list.push(eval_vars_comb); + // } + + // let EQ_p = &EqPolynomial::new(rp.clone()).evals()[..num_instances]; + // let expected_eval_vars_at_ry = + // zip(EQ_p, expected_eval_vars_list).fold(S::field_zero(), |s, (a, b)| s + *a * b); + + // assert_eq!(expected_eval_vars_at_ry, self.eval_vars_at_ry); + + // timer_commit_opening.stop(); + + // // compute commitment to eval_Z_at_ry = (ONE - ry[0]) * self.eval_vars_at_ry + ry[0] * poly_input_eval + // let eval_Z_at_ry = &self.eval_vars_at_ry; + + // // perform the final check in the second sum-check protocol + // let [eval_A_r, eval_B_r, eval_C_r] = evals; + // let expected_claim_post_phase2 = + // (r_A * *eval_A_r + r_B * *eval_B_r + r_C * *eval_C_r) * *eval_Z_at_ry * p_rp_poly_bound_ry; + + // // verify proof that expected_claim_post_phase2 == claim_post_phase2 + // assert_eq!(claim_post_phase_2, expected_claim_post_phase2); + + // Ok([rp, rq_rev, rx, [rw, ry].concat()]) + + () } } diff --git a/zok_tests/benchmarks/poseidon_test/poseidon_const.zok b/zok_tests/benchmarks/poseidon_test/poseidon_const.zok index ac6bfc99..e7ae59fb 100644 --- a/zok_tests/benchmarks/poseidon_test/poseidon_const.zok +++ b/zok_tests/benchmarks/poseidon_test/poseidon_const.zok @@ -1 +1 @@ -const u32 REPETITION = 10000 +const u32 REPETITION = 1000 From 79efbbcc01acc14cd30ffea1349d664a4191850a Mon Sep 17 00:00:00 2001 From: Ray Gao Date: Wed, 18 Dec 2024 19:39:00 -0500 Subject: [PATCH 06/13] Correct lifetime --- spartan_parallel/src/lib.rs | 2 +- spartan_parallel/src/r1csproof.rs | 41 ++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/spartan_parallel/src/lib.rs b/spartan_parallel/src/lib.rs index e0da3a67..aa3302fa 100644 --- a/spartan_parallel/src/lib.rs +++ b/spartan_parallel/src/lib.rs @@ -642,7 +642,7 @@ impl PartialEq for InstanceSortHelper { } impl Eq for InstanceSortHelper {} -impl SNARK { +impl<'a, S: SpartanExtensionField + Send + Sync> SNARK { fn protocol_name() -> &'static [u8] { b"Spartan SNARK proof" } diff --git a/spartan_parallel/src/r1csproof.rs b/spartan_parallel/src/r1csproof.rs index c44f6582..d231ebe6 100644 --- a/spartan_parallel/src/r1csproof.rs +++ b/spartan_parallel/src/r1csproof.rs @@ -29,11 +29,12 @@ use sumcheck::structs::{IOPProof, IOPProverStateV2, IOPVerifierState}; use ff::Field; use halo2curves::serde::SerdeObject; use transcript::BasicTranscript; +use std::array; #[derive(Serialize, Debug)] pub struct R1CSProof { sc_proof_phase1_proof: IOPProof, - sc_proof_phase1_state: IOPProverStateV2<'static, GoldilocksExt2>, + sc_proof_phase1_state_evals: Vec, // sc_proof_phase1: SumcheckInstanceProof, sc_proof_phase2: SumcheckInstanceProof, claims_phase2: (S, S, S), @@ -44,7 +45,7 @@ pub struct R1CSProof { // proof_eval_vars_at_ry_list: Vec>, } -impl R1CSProof { +impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { fn prove_phase_one( num_rounds: usize, num_rounds_x_max: usize, @@ -267,7 +268,7 @@ impl R1CSProof { D.get_num_vars(), ); - let arc_A: ArcMultilinearExtension = Arc::new( + let arc_A: ArcMultilinearExtension<'a, GoldilocksExt2> = Arc::new( A.Z.iter().cloned().map(|s| GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) ) @@ -275,21 +276,32 @@ impl R1CSProof { .into_mle() ); - let arc_B: ArcMultilinearExtension = Arc::new( + // let arc_A: [ArcMultilinearExtension<'a, GoldilocksExt2>; 2] = array::from_fn(|_| { + // A.Z.iter().cloned().map(|s| + // GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) + // ) + // .collect::>() + // .into_mle() + // .into() + // }); + + let arc_B: ArcMultilinearExtension<'a, GoldilocksExt2> = Arc::new( B.Z.iter().cloned().map(|s| GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) ) .collect::>() .into_mle() ); - let arc_C: ArcMultilinearExtension = Arc::new( + + let arc_C: ArcMultilinearExtension<'a, GoldilocksExt2> = Arc::new( C.Z.iter().cloned().map(|s| GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) ) .collect::>() .into_mle() ); - let arc_D: ArcMultilinearExtension = Arc::new( + + let arc_D: ArcMultilinearExtension<'a, GoldilocksExt2> = Arc::new( D.Z.iter().cloned().map(|s| GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) ) @@ -298,11 +310,13 @@ impl R1CSProof { ); let max_num_vars = A.get_num_vars(); - let num_threads = 1; - let mut virtual_polys: VirtualPolynomialV2 = VirtualPolynomialV2::new(max_num_vars); + let num_threads = 8; - virtual_polys.add_mle_list(vec![arc_A.clone(), arc_B, arc_C], GoldilocksExt2::ONE); - virtual_polys.add_mle_list(vec![arc_A, arc_D], GoldilocksExt2::ZERO - GoldilocksExt2::ONE); + let mut virtual_polys = + VirtualPolynomials::new(num_threads, max_num_vars); + + virtual_polys.add_mle_list(vec![&arc_A, &arc_B, &arc_C], GoldilocksExt2::ONE); + virtual_polys.add_mle_list(vec![&arc_A, &arc_D], GoldilocksExt2::ZERO - GoldilocksExt2::ONE); let mut ceno_transcript = BasicTranscript::new(b"test"); @@ -312,7 +326,8 @@ impl R1CSProof { IOPProverStateV2 ) = IOPProverStateV2::prove_batch_polys( num_threads, - vec![virtual_polys], + // vec![virtual_polys], + virtual_polys.get_batched_polys(), &mut ceno_transcript, ); timer_tmp.stop(); @@ -614,10 +629,12 @@ impl R1CSProof { timer_prove.stop(); + let sc_proof_phase1_state_evals = sc_proof_phase1_state.get_mle_final_evaluations(); + ( R1CSProof { sc_proof_phase1_proof, - sc_proof_phase1_state, + sc_proof_phase1_state_evals, // sc_proof_phase1, sc_proof_phase2, claims_phase2: (Az_claim, Bz_claim, Cz_claim), From 064d0aaac6fa75949f9c00e84358385a22ae506f Mon Sep 17 00:00:00 2001 From: Ray Gao Date: Thu, 19 Dec 2024 00:49:29 -0500 Subject: [PATCH 07/13] Graft ceno verifier --- spartan_parallel/src/r1csproof.rs | 403 +++++++++--------- .../poseidon_test/poseidon_const.zok | 2 +- 2 files changed, 214 insertions(+), 191 deletions(-) diff --git a/spartan_parallel/src/r1csproof.rs b/spartan_parallel/src/r1csproof.rs index d231ebe6..fa04fabd 100644 --- a/spartan_parallel/src/r1csproof.rs +++ b/spartan_parallel/src/r1csproof.rs @@ -11,7 +11,7 @@ use super::transcript::ProofTranscript; use crate::scalar::SpartanExtensionField; use crate::{ProverWitnessSecInfo, VerifierWitnessSecInfo}; use ff_ext::ExtensionField; -use goldilocks::GoldilocksExt2; +use goldilocks::{Goldilocks, GoldilocksExt2}; use merlin::Transcript; use multilinear_extensions::mle::DenseMultilinearExtension; use serde::{Deserialize, Serialize}; @@ -43,6 +43,8 @@ pub struct R1CSProof { eval_vars_at_ry_list: Vec>, eval_vars_at_ry: S, // proof_eval_vars_at_ry_list: Vec>, + max_num_vars: usize, + claim_phase_1: GoldilocksExt2, } impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { @@ -276,15 +278,6 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { .into_mle() ); - // let arc_A: [ArcMultilinearExtension<'a, GoldilocksExt2>; 2] = array::from_fn(|_| { - // A.Z.iter().cloned().map(|s| - // GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) - // ) - // .collect::>() - // .into_mle() - // .into() - // }); - let arc_B: ArcMultilinearExtension<'a, GoldilocksExt2> = Arc::new( B.Z.iter().cloned().map(|s| GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) @@ -326,11 +319,11 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { IOPProverStateV2 ) = IOPProverStateV2::prove_batch_polys( num_threads, - // vec![virtual_polys], virtual_polys.get_batched_polys(), &mut ceno_transcript, ); timer_tmp.stop(); + let sc_proof_phase1_state_evals = sc_proof_phase1_state.get_mle_final_evaluations(); let (tau_claim, Az_claim, Bz_claim, Cz_claim): (GoldilocksExt2, GoldilocksExt2, GoldilocksExt2, GoldilocksExt2) = ( sc_proof_phase1_proof.point[0], sc_proof_phase1_proof.point[1], @@ -342,7 +335,7 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { let Az_claim: S = S::InnerType::from_raw_bytes(&Az_claim.to_raw_bytes()).unwrap().into(); let Bz_claim: S = S::InnerType::from_raw_bytes(&Bz_claim.to_raw_bytes()).unwrap().into(); let Cz_claim: S = S::InnerType::from_raw_bytes(&Cz_claim.to_raw_bytes()).unwrap().into(); - + let rx: Vec = sc_proof_phase1_state.challenges.iter().map(|c| S::InnerType::from_raw_bytes(&c.elements.to_raw_bytes()).unwrap().into() @@ -350,6 +343,21 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { timer_sc_proof_phase1.stop(); // == test: ceno_verifier_bench == + let fn_eval = |fs: &[ArcMultilinearExtension; 4]| -> GoldilocksExt2 { + let mut evals = vec![GoldilocksExt2::ZERO; 1 << fs[0].num_vars()]; + let A = fs[0].get_ext_field_vec(); + let B = fs[1].get_ext_field_vec(); + let C = fs[2].get_ext_field_vec(); + let D = fs[3].get_ext_field_vec(); + + for ((((e, a), b), c), d) in evals.iter_mut().zip(A).zip(B).zip(C).zip(D) { + *e += *a * b * c - *a * d; + } + + evals.iter().sum::() + }; + let claim_phase_1 = fn_eval(&[arc_A.clone(), arc_B.clone(), arc_C.clone(), arc_D.clone()]); + /* // Sumcheck 1: (Az * Bz - Cz) * eq(x, q, p) = 0 let timer_tmp = Timer::new("prove_sum_check"); @@ -629,8 +637,6 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { timer_prove.stop(); - let sc_proof_phase1_state_evals = sc_proof_phase1_state.get_mle_final_evaluations(); - ( R1CSProof { sc_proof_phase1_proof, @@ -641,6 +647,8 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { eval_vars_at_ry_list: raw_eval_vars_at_ry_list, eval_vars_at_ry, // proof_eval_vars_at_ry_list, + max_num_vars, + claim_phase_1, }, [rp, rq_rev, rx.to_vec(), [rw, ry].concat()], ) @@ -668,9 +676,7 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { num_cons: usize, evals: &[S; 3], transcript: &mut Transcript, - // debug_ceno_verifier - // ) -> Result<[Vec; 4], ProofVerifyError> { - ) -> () { + ) -> Result<[Vec; 4], ProofVerifyError> { >::append_protocol_name( transcript, R1CSProof::::protocol_name(), @@ -694,186 +700,203 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { let tau_q: Vec = transcript.challenge_vector(b"challenge_tau_q", num_rounds_q); let tau_x: Vec = transcript.challenge_vector(b"challenge_tau_x", num_rounds_x); - // debug_ceno_verifier + // == test: ceno_verifier_bench == + let mut ceno_transcript = BasicTranscript::new(b"test"); + let subclaim = IOPVerifierState::::verify( + self.claim_phase_1, + &self.sc_proof_phase1_proof, + &VPAuxInfo { + max_degree: 3, + num_variables: self.max_num_vars, + phantom: std::marker::PhantomData, + }, + &mut ceno_transcript, + ); + let rx: Vec = + subclaim.point.iter().map(|c| + S::InnerType::from_raw_bytes(&c.elements.to_raw_bytes()).unwrap().into() + ).collect::>(); + // == test: ceno_verifier_bench == + + /* // let (claim_post_phase_1, rx) = self.sc_proof_phase1.verify( // S::field_zero(), // num_rounds_x + num_rounds_q + num_rounds_p, // 3, // transcript, // )?; + */ - // // Separate the result rx into rp_round1, rq, and rx - // let (rx_rev, rq_rev) = rx.split_at(num_rounds_x); - // let (rq_rev, rp_round1) = rq_rev.split_at(num_rounds_q); - // let rx: Vec = rx_rev.iter().copied().rev().collect(); - // let rq_rev = rq_rev.to_vec(); - // let rq: Vec = rq_rev.iter().copied().rev().collect(); - // let rp_round1 = rp_round1.to_vec(); - - // // taus_bound_rx is really taus_bound_rx_rq_rp - // let taus_bound_rp: S = (0..rp_round1.len()) - // .map(|i| { - // rp_round1[i] * tau_p[i] + (S::field_one() - rp_round1[i]) * (S::field_one() - tau_p[i]) - // }) - // .product(); - // let taus_bound_rq: S = (0..rq_rev.len()) - // .map(|i| rq_rev[i] * tau_q[i] + (S::field_one() - rq_rev[i]) * (S::field_one() - tau_q[i])) - // .product(); - // let taus_bound_rx: S = (0..rx_rev.len()) - // .map(|i| rx_rev[i] * tau_x[i] + (S::field_one() - rx_rev[i]) * (S::field_one() - tau_x[i])) - // .product(); - // let taus_bound_rx = taus_bound_rp * taus_bound_rq * taus_bound_rx; - - // // perform the intermediate sum-check test with claimed Az, Bz, and Cz - // let (Az_claim, Bz_claim, Cz_claim) = self.claims_phase2; - // S::append_field_to_transcript(b"Az_claim", transcript, Az_claim); - // S::append_field_to_transcript(b"Bz_claim", transcript, Bz_claim); - // S::append_field_to_transcript(b"Cz_claim", transcript, Cz_claim); - - // // debug_zk - // // assert_eq!(taus_bound_rx * (Az_claim * Bz_claim - Cz_claim), claim_post_phase_1); - - // // derive three public challenges and then derive a joint claim - // let r_A: S = transcript.challenge_scalar(b"challenge_Az"); - // let r_B: S = transcript.challenge_scalar(b"challenge_Bz"); - // let r_C: S = transcript.challenge_scalar(b"challenge_Cz"); - - // let (Az_claim, Bz_claim, Cz_claim) = self.claims_phase2; - // let claim_phase2 = r_A * Az_claim + r_B * Bz_claim + r_C * Cz_claim; - - // // verify the joint claim with a sum-check protocol - // let (claim_post_phase_2, ry) = self.sc_proof_phase2.verify( - // claim_phase2, - // num_rounds_y + num_rounds_w + num_rounds_p, - // 3, - // transcript, - // )?; + // Separate the result rx into rp_round1, rq, and rx + let (rx_rev, rq_rev) = rx.split_at(num_rounds_x); + let (rq_rev, rp_round1) = rq_rev.split_at(num_rounds_q); + let rx: Vec = rx_rev.iter().copied().rev().collect(); + let rq_rev = rq_rev.to_vec(); + let rq: Vec = rq_rev.iter().copied().rev().collect(); + let rp_round1 = rp_round1.to_vec(); + + // taus_bound_rx is really taus_bound_rx_rq_rp + let taus_bound_rp: S = (0..rp_round1.len()) + .map(|i| { + rp_round1[i] * tau_p[i] + (S::field_one() - rp_round1[i]) * (S::field_one() - tau_p[i]) + }) + .product(); + let taus_bound_rq: S = (0..rq_rev.len()) + .map(|i| rq_rev[i] * tau_q[i] + (S::field_one() - rq_rev[i]) * (S::field_one() - tau_q[i])) + .product(); + let taus_bound_rx: S = (0..rx_rev.len()) + .map(|i| rx_rev[i] * tau_x[i] + (S::field_one() - rx_rev[i]) * (S::field_one() - tau_x[i])) + .product(); + let taus_bound_rx = taus_bound_rp * taus_bound_rq * taus_bound_rx; + + // perform the intermediate sum-check test with claimed Az, Bz, and Cz + let (Az_claim, Bz_claim, Cz_claim) = self.claims_phase2; + S::append_field_to_transcript(b"Az_claim", transcript, Az_claim); + S::append_field_to_transcript(b"Bz_claim", transcript, Bz_claim); + S::append_field_to_transcript(b"Cz_claim", transcript, Cz_claim); - // // Separate ry into rp, rw, and ry - // let (ry_rev, rw) = ry.split_at(num_rounds_y); - // let (rw, rp) = rw.split_at(num_rounds_w); - // let rp = rp.to_vec(); - // let rw = rw.to_vec(); - // let ry: Vec = ry_rev.iter().copied().rev().collect(); - - // // An Eq function to match p with rp - // let p_rp_poly_bound_ry: S = (0..rp.len()) - // .map(|i| rp[i] * rp_round1[i] + (S::field_one() - rp[i]) * (S::field_one() - rp_round1[i])) - // .product(); - - // // verify Z(rp, rq, ry) proof against the initial commitment - // // First by witness & by instance on ry - // // For every possible wit_sec.num_inputs, compute ry_factor = prodX(1 - ryX)... - // // If there are 2 witness secs, then ry_factors[0] = 1, ry_factors[1] = 1, ry_factors[2] = 1 - ry1, ry_factors[3] = (1 - ry1)(1 - ry2), etc. - // let mut ry_factors = vec![S::field_one(); num_rounds_y + 1]; - // for i in 0..num_rounds_y { - // ry_factors[i + 1] = (ry_factors[i]) * (S::field_one() - ry[i]); - // } - - // // POLY COMMIT - // let timer_commit_opening = Timer::new("verify_sc_commitment_opening"); - // let mut num_proofs_list = Vec::new(); - // let mut num_inputs_list = Vec::new(); - // let mut eval_Zr_list = Vec::new(); - // for i in 0..num_witness_secs { - // let w = witness_secs[i]; - // let wit_sec_num_instance = w.num_proofs.len(); - // for p in 0..wit_sec_num_instance { - // num_proofs_list.push(w.num_proofs[p]); - // num_inputs_list.push(w.num_inputs[p]); - // eval_Zr_list.push(self.eval_vars_at_ry_list[i][p]); - // } - // } - - // /* - // PolyEvalProof::verify_batched_instances_disjoint_rounds( - // &self.proof_eval_vars_at_ry_list, - // &num_proofs_list, - // &num_inputs_list, - // transcript, - // &rq, - // &ry, - // )?; - // */ - - // // Then on rp - // let mut expected_eval_vars_list = Vec::new(); - // for p in 0..num_instances { - // let wit_sec_p = |i: usize| { - // if witness_secs[i].num_proofs.len() == 1 { - // 0 - // } else { - // p - // } - // }; - // let c = |i: usize| { - // if witness_secs[i].num_inputs[wit_sec_p(i)] >= max_num_inputs { - // self.eval_vars_at_ry_list[i][wit_sec_p(i)] - // } else { - // self.eval_vars_at_ry_list[i][wit_sec_p(i)] - // * ry_factors[num_rounds_y - witness_secs[i].num_inputs[wit_sec_p(i)].log_2()] - // } - // }; - // let prefix_list = match num_witness_secs.next_power_of_two() { - // 1 => { - // vec![S::field_one()] - // } - // 2 => { - // vec![(S::field_one() - rw[0]), rw[0]] - // } - // 4 => { - // vec![ - // (S::field_one() - rw[0]) * (S::field_one() - rw[1]), - // (S::field_one() - rw[0]) * rw[1], - // rw[0] * (S::field_one() - rw[1]), - // rw[0] * rw[1], - // ] - // } - // 8 => { - // vec![ - // (S::field_one() - rw[0]) * (S::field_one() - rw[1]) * (S::field_one() - rw[2]), - // (S::field_one() - rw[0]) * (S::field_one() - rw[1]) * rw[2], - // (S::field_one() - rw[0]) * rw[1] * (S::field_one() - rw[2]), - // (S::field_one() - rw[0]) * rw[1] * rw[2], - // rw[0] * (S::field_one() - rw[1]) * (S::field_one() - rw[2]), - // rw[0] * (S::field_one() - rw[1]) * rw[2], - // rw[0] * rw[1] * (S::field_one() - rw[2]), - // rw[0] * rw[1] * rw[2], - // ] - // } - // _ => { - // panic!("Unsupported num_witness_secs: {}", num_witness_secs); - // } - // }; - // let mut eval_vars_comb = - // (1..num_witness_secs).fold(prefix_list[0] * c(0), |s, i| s + prefix_list[i] * c(i)); - // for q in 0..(num_rounds_q - num_proofs[p].log_2()) { - // eval_vars_comb *= S::field_one() - rq[q]; - // } - // expected_eval_vars_list.push(eval_vars_comb); - // } - - // let EQ_p = &EqPolynomial::new(rp.clone()).evals()[..num_instances]; - // let expected_eval_vars_at_ry = - // zip(EQ_p, expected_eval_vars_list).fold(S::field_zero(), |s, (a, b)| s + *a * b); - - // assert_eq!(expected_eval_vars_at_ry, self.eval_vars_at_ry); - - // timer_commit_opening.stop(); - - // // compute commitment to eval_Z_at_ry = (ONE - ry[0]) * self.eval_vars_at_ry + ry[0] * poly_input_eval - // let eval_Z_at_ry = &self.eval_vars_at_ry; - - // // perform the final check in the second sum-check protocol - // let [eval_A_r, eval_B_r, eval_C_r] = evals; - // let expected_claim_post_phase2 = - // (r_A * *eval_A_r + r_B * *eval_B_r + r_C * *eval_C_r) * *eval_Z_at_ry * p_rp_poly_bound_ry; - - // // verify proof that expected_claim_post_phase2 == claim_post_phase2 - // assert_eq!(claim_post_phase_2, expected_claim_post_phase2); - - // Ok([rp, rq_rev, rx, [rw, ry].concat()]) - - () + // debug_zk + // assert_eq!(taus_bound_rx * (Az_claim * Bz_claim - Cz_claim), claim_post_phase_1); + + // derive three public challenges and then derive a joint claim + let r_A: S = transcript.challenge_scalar(b"challenge_Az"); + let r_B: S = transcript.challenge_scalar(b"challenge_Bz"); + let r_C: S = transcript.challenge_scalar(b"challenge_Cz"); + + let (Az_claim, Bz_claim, Cz_claim) = self.claims_phase2; + let claim_phase2 = r_A * Az_claim + r_B * Bz_claim + r_C * Cz_claim; + + // verify the joint claim with a sum-check protocol + let (claim_post_phase_2, ry) = self.sc_proof_phase2.verify( + claim_phase2, + num_rounds_y + num_rounds_w + num_rounds_p, + 3, + transcript, + )?; + + // Separate ry into rp, rw, and ry + let (ry_rev, rw) = ry.split_at(num_rounds_y); + let (rw, rp) = rw.split_at(num_rounds_w); + let rp = rp.to_vec(); + let rw = rw.to_vec(); + let ry: Vec = ry_rev.iter().copied().rev().collect(); + + // An Eq function to match p with rp + let p_rp_poly_bound_ry: S = (0..rp.len()) + .map(|i| rp[i] * rp_round1[i] + (S::field_one() - rp[i]) * (S::field_one() - rp_round1[i])) + .product(); + + // verify Z(rp, rq, ry) proof against the initial commitment + // First by witness & by instance on ry + // For every possible wit_sec.num_inputs, compute ry_factor = prodX(1 - ryX)... + // If there are 2 witness secs, then ry_factors[0] = 1, ry_factors[1] = 1, ry_factors[2] = 1 - ry1, ry_factors[3] = (1 - ry1)(1 - ry2), etc. + let mut ry_factors = vec![S::field_one(); num_rounds_y + 1]; + for i in 0..num_rounds_y { + ry_factors[i + 1] = (ry_factors[i]) * (S::field_one() - ry[i]); + } + + // POLY COMMIT + let timer_commit_opening = Timer::new("verify_sc_commitment_opening"); + let mut num_proofs_list = Vec::new(); + let mut num_inputs_list = Vec::new(); + let mut eval_Zr_list = Vec::new(); + for i in 0..num_witness_secs { + let w = witness_secs[i]; + let wit_sec_num_instance = w.num_proofs.len(); + for p in 0..wit_sec_num_instance { + num_proofs_list.push(w.num_proofs[p]); + num_inputs_list.push(w.num_inputs[p]); + eval_Zr_list.push(self.eval_vars_at_ry_list[i][p]); + } + } + + /* + PolyEvalProof::verify_batched_instances_disjoint_rounds( + &self.proof_eval_vars_at_ry_list, + &num_proofs_list, + &num_inputs_list, + transcript, + &rq, + &ry, + )?; + */ + + // Then on rp + let mut expected_eval_vars_list = Vec::new(); + for p in 0..num_instances { + let wit_sec_p = |i: usize| { + if witness_secs[i].num_proofs.len() == 1 { + 0 + } else { + p + } + }; + let c = |i: usize| { + if witness_secs[i].num_inputs[wit_sec_p(i)] >= max_num_inputs { + self.eval_vars_at_ry_list[i][wit_sec_p(i)] + } else { + self.eval_vars_at_ry_list[i][wit_sec_p(i)] + * ry_factors[num_rounds_y - witness_secs[i].num_inputs[wit_sec_p(i)].log_2()] + } + }; + let prefix_list = match num_witness_secs.next_power_of_two() { + 1 => { + vec![S::field_one()] + } + 2 => { + vec![(S::field_one() - rw[0]), rw[0]] + } + 4 => { + vec![ + (S::field_one() - rw[0]) * (S::field_one() - rw[1]), + (S::field_one() - rw[0]) * rw[1], + rw[0] * (S::field_one() - rw[1]), + rw[0] * rw[1], + ] + } + 8 => { + vec![ + (S::field_one() - rw[0]) * (S::field_one() - rw[1]) * (S::field_one() - rw[2]), + (S::field_one() - rw[0]) * (S::field_one() - rw[1]) * rw[2], + (S::field_one() - rw[0]) * rw[1] * (S::field_one() - rw[2]), + (S::field_one() - rw[0]) * rw[1] * rw[2], + rw[0] * (S::field_one() - rw[1]) * (S::field_one() - rw[2]), + rw[0] * (S::field_one() - rw[1]) * rw[2], + rw[0] * rw[1] * (S::field_one() - rw[2]), + rw[0] * rw[1] * rw[2], + ] + } + _ => { + panic!("Unsupported num_witness_secs: {}", num_witness_secs); + } + }; + let mut eval_vars_comb = + (1..num_witness_secs).fold(prefix_list[0] * c(0), |s, i| s + prefix_list[i] * c(i)); + for q in 0..(num_rounds_q - num_proofs[p].log_2()) { + eval_vars_comb *= S::field_one() - rq[q]; + } + expected_eval_vars_list.push(eval_vars_comb); + } + + let EQ_p = &EqPolynomial::new(rp.clone()).evals()[..num_instances]; + let expected_eval_vars_at_ry = + zip(EQ_p, expected_eval_vars_list).fold(S::field_zero(), |s, (a, b)| s + *a * b); + + assert_eq!(expected_eval_vars_at_ry, self.eval_vars_at_ry); + + timer_commit_opening.stop(); + + // compute commitment to eval_Z_at_ry = (ONE - ry[0]) * self.eval_vars_at_ry + ry[0] * poly_input_eval + let eval_Z_at_ry = &self.eval_vars_at_ry; + + // perform the final check in the second sum-check protocol + let [eval_A_r, eval_B_r, eval_C_r] = evals; + let expected_claim_post_phase2 = + (r_A * *eval_A_r + r_B * *eval_B_r + r_C * *eval_C_r) * *eval_Z_at_ry * p_rp_poly_bound_ry; + + // verify proof that expected_claim_post_phase2 == claim_post_phase2 + assert_eq!(claim_post_phase_2, expected_claim_post_phase2); + + Ok([rp, rq_rev, rx, [rw, ry].concat()]) } } diff --git a/zok_tests/benchmarks/poseidon_test/poseidon_const.zok b/zok_tests/benchmarks/poseidon_test/poseidon_const.zok index e7ae59fb..ecd81ed4 100644 --- a/zok_tests/benchmarks/poseidon_test/poseidon_const.zok +++ b/zok_tests/benchmarks/poseidon_test/poseidon_const.zok @@ -1 +1 @@ -const u32 REPETITION = 1000 +const u32 REPETITION = 100 From 9ca0199cbd6a73cf73de4c393504fff594339b7f Mon Sep 17 00:00:00 2001 From: Kunming Jiang Date: Thu, 19 Dec 2024 13:45:12 -0500 Subject: [PATCH 08/13] Ceno verifier incorporation for sumcheck 1 --- spartan_parallel/src/lib.rs | 3 - spartan_parallel/src/r1csproof.rs | 80 +++++++++---------- spartan_parallel/src/sumcheck.rs | 2 +- .../poseidon_test/poseidon_const.zok | 2 +- 4 files changed, 40 insertions(+), 47 deletions(-) diff --git a/spartan_parallel/src/lib.rs b/spartan_parallel/src/lib.rs index aa3302fa..53dc6f68 100644 --- a/spartan_parallel/src/lib.rs +++ b/spartan_parallel/src/lib.rs @@ -3031,8 +3031,6 @@ impl<'a, S: SpartanExtensionField + Send + Sync> SNARK { }; timer_commit.stop(); - // debug_ceno_verifier - /* // -- // BLOCK_CORRECTNESS_EXTRACT // -- @@ -3269,7 +3267,6 @@ impl<'a, S: SpartanExtensionField + Send + Sync> SNARK { )?; timer_eval_proof.stop(); } - */ // -- // PERM_PRODUCT_PROOF diff --git a/spartan_parallel/src/r1csproof.rs b/spartan_parallel/src/r1csproof.rs index fa04fabd..8a9493f0 100644 --- a/spartan_parallel/src/r1csproof.rs +++ b/spartan_parallel/src/r1csproof.rs @@ -34,7 +34,6 @@ use std::array; #[derive(Serialize, Debug)] pub struct R1CSProof { sc_proof_phase1_proof: IOPProof, - sc_proof_phase1_state_evals: Vec, // sc_proof_phase1: SumcheckInstanceProof, sc_proof_phase2: SumcheckInstanceProof, claims_phase2: (S, S, S), @@ -226,6 +225,8 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { num_witness_secs.log_2(), max_num_inputs.log_2(), ); + + /* let tau_p: Vec = transcript.challenge_vector(b"challenge_tau_p", num_rounds_p); let tau_q: Vec = transcript.challenge_vector(b"challenge_tau_q", num_rounds_q); let tau_x: Vec = transcript.challenge_vector(b"challenge_tau_x", num_rounds_x); @@ -234,6 +235,9 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { let mut poly_tau_p = DensePolynomial::new(EqPolynomial::new(tau_p).evals()); let mut poly_tau_q = DensePolynomial::new(EqPolynomial::new(tau_q).evals()); let mut poly_tau_x = DensePolynomial::new(EqPolynomial::new(tau_x).evals()); + */ + let tau: Vec = transcript.challenge_vector(b"challenge_tau", num_rounds_p + num_rounds_q + num_rounds_x); + let mut poly_tau = DensePolynomial::new(EqPolynomial::new(tau).evals()); let (mut poly_Az, mut poly_Bz, mut poly_Cz) = inst.multiply_vec_block( num_instances, num_proofs.clone(), @@ -247,21 +251,11 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { timer_tmp.stop(); // == test: ceno_verifier_bench == + let A = poly_tau; let B = poly_Az.to_dense_poly(); let C = poly_Bz.to_dense_poly(); let D = poly_Cz.to_dense_poly(); - let z_len = B.Z.len(); - let tau_pqx_len = poly_tau_p.Z.len() + poly_tau_q.Z.len() + poly_tau_x.Z.len(); - let A = DensePolynomial::new( - poly_tau_p.clone().Z - .into_iter() - .chain(poly_tau_q.clone().Z) - .chain(poly_tau_x.clone().Z) - .chain(iter::repeat(S::field_zero()).take(z_len - tau_pqx_len)) - .collect() - ); - println!( "=> poly_A,B,C,D num_variables: {:?}, {:?}, {:?}, {:?}", A.get_num_vars(), @@ -306,7 +300,7 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { let num_threads = 8; let mut virtual_polys = - VirtualPolynomials::new(num_threads, max_num_vars); + VirtualPolynomials::new(num_threads, max_num_vars); virtual_polys.add_mle_list(vec![&arc_A, &arc_B, &arc_C], GoldilocksExt2::ONE); virtual_polys.add_mle_list(vec![&arc_A, &arc_D], GoldilocksExt2::ZERO - GoldilocksExt2::ONE); @@ -325,21 +319,21 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { timer_tmp.stop(); let sc_proof_phase1_state_evals = sc_proof_phase1_state.get_mle_final_evaluations(); let (tau_claim, Az_claim, Bz_claim, Cz_claim): (GoldilocksExt2, GoldilocksExt2, GoldilocksExt2, GoldilocksExt2) = ( - sc_proof_phase1_proof.point[0], - sc_proof_phase1_proof.point[1], - sc_proof_phase1_proof.point[2], - sc_proof_phase1_proof.point[3], + sc_proof_phase1_state_evals[0], + sc_proof_phase1_state_evals[1], + sc_proof_phase1_state_evals[2], + sc_proof_phase1_state_evals[3], ); - let tau_claim: S = S::InnerType::from_raw_bytes(&tau_claim.to_raw_bytes()).unwrap().into(); + let _tau_claim: S = S::InnerType::from_raw_bytes(&tau_claim.to_raw_bytes()).unwrap().into(); let Az_claim: S = S::InnerType::from_raw_bytes(&Az_claim.to_raw_bytes()).unwrap().into(); let Bz_claim: S = S::InnerType::from_raw_bytes(&Bz_claim.to_raw_bytes()).unwrap().into(); let Cz_claim: S = S::InnerType::from_raw_bytes(&Cz_claim.to_raw_bytes()).unwrap().into(); let rx: Vec = - sc_proof_phase1_state.challenges.iter().map(|c| - S::InnerType::from_raw_bytes(&c.elements.to_raw_bytes()).unwrap().into() - ).collect::>(); + sc_proof_phase1_proof.point.iter().map(|c| + S::InnerType::from_raw_bytes(&c.to_raw_bytes()).unwrap().into() + ).rev().collect::>(); timer_sc_proof_phase1.stop(); // == test: ceno_verifier_bench == @@ -410,9 +404,8 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { S::append_field_to_transcript(b"Cz_claim", transcript, Cz_claim); // Separate the result rx into rp, rq, and rx - let (rx, rq) = rx.split_at(num_rounds_x); - let (rq, rp) = rq.split_at(num_rounds_q); - let rx_rev: Vec = rx.iter().copied().rev().collect(); + let (rp, rq) = rx.split_at(num_rounds_p); + let (rq, rx) = rq.split_at(num_rounds_q); let rq = rq.to_vec(); let rq_rev: Vec = rq.iter().copied().rev().collect(); let rp = rp.to_vec(); @@ -425,13 +418,12 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { let r_A: S = transcript.challenge_scalar(b"challenge_Az"); let r_B: S = transcript.challenge_scalar(b"challenge_Bz"); let r_C: S = transcript.challenge_scalar(b"challenge_Cz"); - let claim_phase2 = r_A * Az_claim + r_B * Bz_claim + r_C * Cz_claim; let timer_tmp = Timer::new("prove_abc_gen"); let evals_ABC = { // compute the initial evaluation table for R(\tau, x) - let evals_rx = EqPolynomial::new(rx.clone().to_vec()).evals(); + let evals_rx = EqPolynomial::new(rx.to_vec()).evals(); let (evals_A, evals_B, evals_C) = inst.compute_eval_table_sparse_disjoint_rounds( num_instances, inst.get_inst_num_cons(), @@ -640,7 +632,6 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { ( R1CSProof { sc_proof_phase1_proof, - sc_proof_phase1_state_evals, // sc_proof_phase1, sc_proof_phase2, claims_phase2: (Az_claim, Bz_claim, Cz_claim), @@ -696,9 +687,12 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { ); // derive the verifier's challenge tau + /* let tau_p: Vec = transcript.challenge_vector(b"challenge_tau_p", num_rounds_p); let tau_q: Vec = transcript.challenge_vector(b"challenge_tau_q", num_rounds_q); let tau_x: Vec = transcript.challenge_vector(b"challenge_tau_x", num_rounds_x); + */ + let tau: Vec = transcript.challenge_vector(b"challenge_tau", num_rounds_p + num_rounds_q + num_rounds_x); // == test: ceno_verifier_bench == let mut ceno_transcript = BasicTranscript::new(b"test"); @@ -715,7 +709,8 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { let rx: Vec = subclaim.point.iter().map(|c| S::InnerType::from_raw_bytes(&c.elements.to_raw_bytes()).unwrap().into() - ).collect::>(); + ).rev().collect::>(); + let claim_post_phase_1 = S::InnerType::from_raw_bytes(&subclaim.expected_evaluation.to_raw_bytes()).unwrap().into(); // == test: ceno_verifier_bench == /* @@ -725,15 +720,6 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { // 3, // transcript, // )?; - */ - - // Separate the result rx into rp_round1, rq, and rx - let (rx_rev, rq_rev) = rx.split_at(num_rounds_x); - let (rq_rev, rp_round1) = rq_rev.split_at(num_rounds_q); - let rx: Vec = rx_rev.iter().copied().rev().collect(); - let rq_rev = rq_rev.to_vec(); - let rq: Vec = rq_rev.iter().copied().rev().collect(); - let rp_round1 = rp_round1.to_vec(); // taus_bound_rx is really taus_bound_rx_rq_rp let taus_bound_rp: S = (0..rp_round1.len()) @@ -748,22 +734,32 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { .map(|i| rx_rev[i] * tau_x[i] + (S::field_one() - rx_rev[i]) * (S::field_one() - tau_x[i])) .product(); let taus_bound_rx = taus_bound_rp * taus_bound_rq * taus_bound_rx; + */ + let taus_bound_rx: S = (0..num_rounds_p + num_rounds_q + num_rounds_x) + .map(|i| { + rx[i] * tau[i] + (S::field_one() - rx[i]) * (S::field_one() - tau[i]) + }) + .product(); + + // Separate the result rx into rp_round1, rq, and rx + let (rp_round1, rq) = rx.split_at(num_rounds_p); + let (rq, rx) = rq.split_at(num_rounds_q); + let rx = rx.to_vec(); + let rq = rq.to_vec(); + let rq_rev: Vec = rq.iter().copied().rev().collect(); + let rp_round1 = rp_round1.to_vec(); // perform the intermediate sum-check test with claimed Az, Bz, and Cz let (Az_claim, Bz_claim, Cz_claim) = self.claims_phase2; S::append_field_to_transcript(b"Az_claim", transcript, Az_claim); S::append_field_to_transcript(b"Bz_claim", transcript, Bz_claim); S::append_field_to_transcript(b"Cz_claim", transcript, Cz_claim); - - // debug_zk - // assert_eq!(taus_bound_rx * (Az_claim * Bz_claim - Cz_claim), claim_post_phase_1); + assert_eq!(taus_bound_rx * (Az_claim * Bz_claim - Cz_claim), claim_post_phase_1); // derive three public challenges and then derive a joint claim let r_A: S = transcript.challenge_scalar(b"challenge_Az"); let r_B: S = transcript.challenge_scalar(b"challenge_Bz"); let r_C: S = transcript.challenge_scalar(b"challenge_Cz"); - - let (Az_claim, Bz_claim, Cz_claim) = self.claims_phase2; let claim_phase2 = r_A * Az_claim + r_B * Bz_claim + r_C * Cz_claim; // verify the joint claim with a sum-check protocol diff --git a/spartan_parallel/src/sumcheck.rs b/spartan_parallel/src/sumcheck.rs index 57b11cf4..c1218b86 100644 --- a/spartan_parallel/src/sumcheck.rs +++ b/spartan_parallel/src/sumcheck.rs @@ -357,7 +357,7 @@ impl SumcheckInstanceProof { /* if j == 0 { println!("\nNEW INSTANCE"); - let mut expected = ZERO; + let mut expected = S::field_zero; for p in 0..min(instance_len, num_inputs.len()) { let p_inst = if single_inst { 0 } else { p }; for w in 0..min(witness_secs_len, num_witness_secs) { diff --git a/zok_tests/benchmarks/poseidon_test/poseidon_const.zok b/zok_tests/benchmarks/poseidon_test/poseidon_const.zok index ecd81ed4..ac6bfc99 100644 --- a/zok_tests/benchmarks/poseidon_test/poseidon_const.zok +++ b/zok_tests/benchmarks/poseidon_test/poseidon_const.zok @@ -1 +1 @@ -const u32 REPETITION = 100 +const u32 REPETITION = 10000 From 06c97fc88942d8decc1cba353e779771d98a4285 Mon Sep 17 00:00:00 2001 From: Ray Gao Date: Thu, 19 Dec 2024 19:07:28 -0500 Subject: [PATCH 09/13] Convert phase 2 prove/verify --- spartan_parallel/src/r1csproof.rs | 127 +++++++++++++++--- .../poseidon_test/poseidon_const.zok | 2 +- 2 files changed, 106 insertions(+), 23 deletions(-) diff --git a/spartan_parallel/src/r1csproof.rs b/spartan_parallel/src/r1csproof.rs index 8a9493f0..0addaa75 100644 --- a/spartan_parallel/src/r1csproof.rs +++ b/spartan_parallel/src/r1csproof.rs @@ -4,38 +4,32 @@ use super::dense_mlpoly::{DensePolynomial, EqPolynomial}; use super::errors::ProofVerifyError; use super::math::Math; use super::r1csinstance::R1CSInstance; -use super::random::RandomTape; use super::sumcheck::SumcheckInstanceProof; use super::timer::Timer; use super::transcript::ProofTranscript; use crate::scalar::SpartanExtensionField; use crate::{ProverWitnessSecInfo, VerifierWitnessSecInfo}; -use ff_ext::ExtensionField; -use goldilocks::{Goldilocks, GoldilocksExt2}; +use goldilocks::GoldilocksExt2; use merlin::Transcript; -use multilinear_extensions::mle::DenseMultilinearExtension; -use serde::{Deserialize, Serialize}; +use serde::Serialize; use std::cmp::min; use std::iter::zip; use std::sync::Arc; use multilinear_extensions::{ mle::IntoMLE, virtual_poly::VPAuxInfo, - virtual_poly_v2::{ArcMultilinearExtension, VirtualPolynomialV2}, + virtual_poly_v2::ArcMultilinearExtension, }; -use std::iter; use ceno_zkvm::virtual_polys::VirtualPolynomials; use sumcheck::structs::{IOPProof, IOPProverStateV2, IOPVerifierState}; use ff::Field; use halo2curves::serde::SerdeObject; use transcript::BasicTranscript; -use std::array; #[derive(Serialize, Debug)] pub struct R1CSProof { sc_proof_phase1_proof: IOPProof, - // sc_proof_phase1: SumcheckInstanceProof, - sc_proof_phase2: SumcheckInstanceProof, + sc_proof_phase2_proof: IOPProof, claims_phase2: (S, S, S), // Need to commit vars for short and long witnesses separately // The long version must exist, the short version might not @@ -43,7 +37,9 @@ pub struct R1CSProof { eval_vars_at_ry: S, // proof_eval_vars_at_ry_list: Vec>, max_num_vars: usize, - claim_phase_1: GoldilocksExt2, + claim_phase1: GoldilocksExt2, + max_num_vars_phase2: usize, + claim_phase2: GoldilocksExt2, } impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { @@ -237,8 +233,8 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { let mut poly_tau_x = DensePolynomial::new(EqPolynomial::new(tau_x).evals()); */ let tau: Vec = transcript.challenge_vector(b"challenge_tau", num_rounds_p + num_rounds_q + num_rounds_x); - let mut poly_tau = DensePolynomial::new(EqPolynomial::new(tau).evals()); - let (mut poly_Az, mut poly_Bz, mut poly_Cz) = inst.multiply_vec_block( + let poly_tau = DensePolynomial::new(EqPolynomial::new(tau).evals()); + let (poly_Az, poly_Bz, poly_Cz) = inst.multiply_vec_block( num_instances, num_proofs.clone(), max_num_proofs, @@ -307,7 +303,7 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { let mut ceno_transcript = BasicTranscript::new(b"test"); - let timer_tmp = Timer::new("=> prove_sum_check with ceno: IOPProverStateV2::prove_batch_polys"); + let timer_tmp = Timer::new("=> prove_sum_check with ceno (phase 1): IOPProverStateV2::prove_batch_polys"); let (sc_proof_phase1_proof, sc_proof_phase1_state): ( IOPProof, IOPProverStateV2 @@ -350,7 +346,7 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { evals.iter().sum::() }; - let claim_phase_1 = fn_eval(&[arc_A.clone(), arc_B.clone(), arc_C.clone(), arc_D.clone()]); + let claim_phase1 = fn_eval(&[arc_A.clone(), arc_B.clone(), arc_C.clone(), arc_D.clone()]); /* // Sumcheck 1: (Az * Bz - Cz) * eq(x, q, p) = 0 @@ -418,7 +414,7 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { let r_A: S = transcript.challenge_scalar(b"challenge_Az"); let r_B: S = transcript.challenge_scalar(b"challenge_Bz"); let r_C: S = transcript.challenge_scalar(b"challenge_Cz"); - let claim_phase2 = r_A * Az_claim + r_B * Bz_claim + r_C * Cz_claim; + let claim_phase2 = GoldilocksExt2::from_raw_bytes(&(r_A * Az_claim + r_B * Bz_claim + r_C * Cz_claim).inner().to_raw_bytes()).unwrap(); let timer_tmp = Timer::new("prove_abc_gen"); let evals_ABC = { @@ -447,7 +443,7 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { } evals_ABC }; - let mut ABC_poly = DensePolynomialPqx::new_rev( + let ABC_poly = DensePolynomialPqx::new_rev( &evals_ABC, vec![1; num_instances], 1, @@ -471,8 +467,71 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { timer_tmp.stop(); // An Eq function to match p with rp - let mut eq_p_rp_poly = DensePolynomial::new(EqPolynomial::new(rp).evals()); + let eq_p_rp_poly = DensePolynomial::new(EqPolynomial::new(rp).evals()); + // == test ceno_verifier_bench + let ABC_poly = ABC_poly.to_dense_poly(); + let Z_poly = Z_poly.to_dense_poly(); + + println!( + "=> ABC_poly, Z_poly, eq_p_rop_poly num_variables: {:?}, {:?}, {:?}", + ABC_poly.get_num_vars(), + Z_poly.get_num_vars(), + eq_p_rp_poly.get_num_vars(), + ); + + let arc_A: ArcMultilinearExtension<'a, GoldilocksExt2> = Arc::new( + ABC_poly.Z.iter().cloned().map(|s| + GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) + ) + .collect::>() + .into_mle() + ); + + let arc_B: ArcMultilinearExtension<'a, GoldilocksExt2> = Arc::new( + Z_poly.Z.iter().cloned().map(|s| + GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) + ) + .collect::>() + .into_mle() + ); + + let arc_C: ArcMultilinearExtension<'a, GoldilocksExt2> = Arc::new( + eq_p_rp_poly.Z.iter().cloned().map(|s| + GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) + ) + .collect::>() + .into_mle() + ); + + let max_num_vars_phase2 = eq_p_rp_poly.get_num_vars(); + let num_threads_phase2 = 8; + + let mut virtual_polys = + VirtualPolynomials::new(num_threads_phase2, max_num_vars_phase2); + + virtual_polys.add_mle_list(vec![&arc_A, &arc_B, &arc_C], GoldilocksExt2::ONE); + + let mut ceno_transcript = BasicTranscript::new(b"test"); + + let timer_tmp = Timer::new("=> prove_sum_check with ceno (phase 2): IOPProverStateV2::prove_batch_polys"); + let (sc_proof_phase2_proof, _sc_proof_phase2_state): ( + IOPProof, + IOPProverStateV2 + ) = IOPProverStateV2::prove_batch_polys( + num_threads, + virtual_polys.get_batched_polys(), + &mut ceno_transcript, + ); + timer_tmp.stop(); + + let ry: Vec = + sc_proof_phase2_proof.point.iter().map(|c| + S::InnerType::from_raw_bytes(&c.to_raw_bytes()).unwrap().into() + ).rev().collect::>(); + // == test ceno_verifier_bench + + /* // Sumcheck 2: (rA + rB + rC) * Z * eq(p) = e let (sc_proof_phase2, ry, _claims_phase2) = R1CSProof::prove_phase_two( num_rounds_y + num_rounds_w + num_rounds_p, @@ -488,6 +547,7 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { &mut Z_poly, transcript, ); + */ timer_sc_proof_phase2.stop(); // Separate ry into rp, rw, and ry @@ -633,13 +693,15 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { R1CSProof { sc_proof_phase1_proof, // sc_proof_phase1, - sc_proof_phase2, + sc_proof_phase2_proof, claims_phase2: (Az_claim, Bz_claim, Cz_claim), eval_vars_at_ry_list: raw_eval_vars_at_ry_list, eval_vars_at_ry, // proof_eval_vars_at_ry_list, max_num_vars, - claim_phase_1, + claim_phase1, + max_num_vars_phase2, + claim_phase2, }, [rp, rq_rev, rx.to_vec(), [rw, ry].concat()], ) @@ -697,7 +759,7 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { // == test: ceno_verifier_bench == let mut ceno_transcript = BasicTranscript::new(b"test"); let subclaim = IOPVerifierState::::verify( - self.claim_phase_1, + self.claim_phase1, &self.sc_proof_phase1_proof, &VPAuxInfo { max_degree: 3, @@ -760,8 +822,28 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { let r_A: S = transcript.challenge_scalar(b"challenge_Az"); let r_B: S = transcript.challenge_scalar(b"challenge_Bz"); let r_C: S = transcript.challenge_scalar(b"challenge_Cz"); - let claim_phase2 = r_A * Az_claim + r_B * Bz_claim + r_C * Cz_claim; + let claim_phase2 = GoldilocksExt2::from_raw_bytes(&(r_A * Az_claim + r_B * Bz_claim + r_C * Cz_claim).inner().to_raw_bytes()).unwrap(); + // == test: ceno_verifier_bench == + let mut ceno_transcript = BasicTranscript::new(b"test"); + let subclaim = IOPVerifierState::::verify( + claim_phase2, + &self.sc_proof_phase2_proof, + &VPAuxInfo { + max_degree: 3, + num_variables: self.max_num_vars_phase2, + phantom: std::marker::PhantomData, + }, + &mut ceno_transcript, + ); + let ry: Vec = + subclaim.point.iter().map(|c| + S::InnerType::from_raw_bytes(&c.elements.to_raw_bytes()).unwrap().into() + ).rev().collect::>(); + let claim_post_phase_2: S = S::InnerType::from_raw_bytes(&subclaim.expected_evaluation.to_raw_bytes()).unwrap().into(); + // == test: ceno_verifier_bench == + + /* // verify the joint claim with a sum-check protocol let (claim_post_phase_2, ry) = self.sc_proof_phase2.verify( claim_phase2, @@ -769,6 +851,7 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { 3, transcript, )?; + */ // Separate ry into rp, rw, and ry let (ry_rev, rw) = ry.split_at(num_rounds_y); diff --git a/zok_tests/benchmarks/poseidon_test/poseidon_const.zok b/zok_tests/benchmarks/poseidon_test/poseidon_const.zok index ac6bfc99..ecd81ed4 100644 --- a/zok_tests/benchmarks/poseidon_test/poseidon_const.zok +++ b/zok_tests/benchmarks/poseidon_test/poseidon_const.zok @@ -1 +1 @@ -const u32 REPETITION = 10000 +const u32 REPETITION = 100 From c4024af0d3e081657d1973629c0cdd8509c72c80 Mon Sep 17 00:00:00 2001 From: Ray Gao Date: Thu, 19 Dec 2024 19:39:10 -0500 Subject: [PATCH 10/13] Pad eq_val --- spartan_parallel/src/r1csproof.rs | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/spartan_parallel/src/r1csproof.rs b/spartan_parallel/src/r1csproof.rs index 0addaa75..62c2b025 100644 --- a/spartan_parallel/src/r1csproof.rs +++ b/spartan_parallel/src/r1csproof.rs @@ -496,15 +496,23 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { .into_mle() ); + let max_num_vars_phase2 = ABC_poly.get_num_vars(); + + let ABC_eval_len = ABC_poly.Z.len(); + let eq_eval_len = eq_p_rp_poly.Z.len(); + let eq_padding = std::iter::repeat(GoldilocksExt2::ZERO).take(ABC_eval_len - eq_eval_len); + let arc_C: ArcMultilinearExtension<'a, GoldilocksExt2> = Arc::new( - eq_p_rp_poly.Z.iter().cloned().map(|s| - GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) - ) - .collect::>() - .into_mle() + eq_p_rp_poly.Z + .into_iter() + .map(|s| + GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) + ) + .chain(eq_padding) + .collect::>() + .into_mle() ); - - let max_num_vars_phase2 = eq_p_rp_poly.get_num_vars(); + let num_threads_phase2 = 8; let mut virtual_polys = @@ -557,9 +565,6 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { let rw = rw.to_vec(); let ry: Vec = ry_rev.iter().copied().rev().collect(); - assert_eq!(Z_poly.len(), 1); - assert_eq!(ABC_poly.len(), 1); - // -- // POLY COMMIT // -- From c3469b36640b565234dd189d825642ec8e1ccebb Mon Sep 17 00:00:00 2001 From: Ray Gao Date: Thu, 19 Dec 2024 20:38:01 -0500 Subject: [PATCH 11/13] Pad rp for eq_poly --- spartan_parallel/src/r1csproof.rs | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/spartan_parallel/src/r1csproof.rs b/spartan_parallel/src/r1csproof.rs index 62c2b025..be5034fd 100644 --- a/spartan_parallel/src/r1csproof.rs +++ b/spartan_parallel/src/r1csproof.rs @@ -404,7 +404,7 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { let (rq, rx) = rq.split_at(num_rounds_q); let rq = rq.to_vec(); let rq_rev: Vec = rq.iter().copied().rev().collect(); - let rp = rp.to_vec(); + let mut rp = rp.to_vec(); // -- // PHASE 2 @@ -466,13 +466,15 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { Z_poly.bound_poly_vars_rq(&rq_rev.to_vec()); timer_tmp.stop(); - // An Eq function to match p with rp - let eq_p_rp_poly = DensePolynomial::new(EqPolynomial::new(rp).evals()); - // == test ceno_verifier_bench let ABC_poly = ABC_poly.to_dense_poly(); let Z_poly = Z_poly.to_dense_poly(); + // An Eq function to match p with rp + let max_num_vars_phase2 = ABC_poly.get_num_vars(); + rp.extend(std::iter::repeat(S::field_one()).take(max_num_vars_phase2 - rp.len())); + let eq_p_rp_poly = DensePolynomial::new(EqPolynomial::new(rp).evals()); + println!( "=> ABC_poly, Z_poly, eq_p_rop_poly num_variables: {:?}, {:?}, {:?}", ABC_poly.get_num_vars(), @@ -496,21 +498,12 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { .into_mle() ); - let max_num_vars_phase2 = ABC_poly.get_num_vars(); - - let ABC_eval_len = ABC_poly.Z.len(); - let eq_eval_len = eq_p_rp_poly.Z.len(); - let eq_padding = std::iter::repeat(GoldilocksExt2::ZERO).take(ABC_eval_len - eq_eval_len); - let arc_C: ArcMultilinearExtension<'a, GoldilocksExt2> = Arc::new( - eq_p_rp_poly.Z - .into_iter() - .map(|s| - GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) - ) - .chain(eq_padding) - .collect::>() - .into_mle() + eq_p_rp_poly.Z.iter().clone().map(|s| + GoldilocksExt2::from_raw_bytes_unchecked(&s.inner().to_raw_bytes()) + ) + .collect::>() + .into_mle() ); let num_threads_phase2 = 8; From 302d2ea948f672f7cae8eeaf87b4b60d48dee33b Mon Sep 17 00:00:00 2001 From: Kunming Jiang Date: Fri, 20 Dec 2024 11:55:34 -0500 Subject: [PATCH 12/13] Finished sumcheck 2 --- spartan_parallel/src/r1csproof.rs | 43 ++++++++++++++++--- .../poseidon_test/poseidon_const.zok | 2 +- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/spartan_parallel/src/r1csproof.rs b/spartan_parallel/src/r1csproof.rs index be5034fd..37142b98 100644 --- a/spartan_parallel/src/r1csproof.rs +++ b/spartan_parallel/src/r1csproof.rs @@ -404,7 +404,7 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { let (rq, rx) = rq.split_at(num_rounds_q); let rq = rq.to_vec(); let rq_rev: Vec = rq.iter().copied().rev().collect(); - let mut rp = rp.to_vec(); + let rp = rp.to_vec(); // -- // PHASE 2 @@ -472,11 +472,30 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { // An Eq function to match p with rp let max_num_vars_phase2 = ABC_poly.get_num_vars(); - rp.extend(std::iter::repeat(S::field_one()).take(max_num_vars_phase2 - rp.len())); - let eq_p_rp_poly = DensePolynomial::new(EqPolynomial::new(rp).evals()); + // rp.extend(std::iter::repeat(S::field_one()).take(max_num_vars_phase2 - rp.len())); + // let rp = rp.into_iter().rev().collect(); + let tmp_rp_poly = EqPolynomial::new(rp).evals(); + // Every entry of tmp_rp_poly needs to be repeated "scale" times + let scale = ABC_poly.len() / tmp_rp_poly.len(); + let eq_p_rp_poly = DensePolynomial::new( + tmp_rp_poly.into_iter().map(|i| vec![i; scale]).collect::>>().concat() + ); + + let mut claimed_sum = S::field_zero(); + let mut claimed_partial_sum = S::field_zero(); + let mut a_sum = S::field_zero(); + let mut b_sum = S::field_zero(); + let mut c_sum = S::field_zero(); + for (a, (b, c)) in zip(&eq_p_rp_poly.Z, zip(&ABC_poly.Z, &Z_poly.Z)) { + claimed_sum += a.clone() * b.clone() * c.clone(); + claimed_partial_sum += b.clone() * c.clone(); + a_sum += a.clone(); + b_sum += b.clone(); + c_sum += c.clone(); + } println!( - "=> ABC_poly, Z_poly, eq_p_rop_poly num_variables: {:?}, {:?}, {:?}", + "=> ABC_poly, Z_poly, eq_p_rp_poly num_variables: {:?}, {:?}, {:?}", ABC_poly.get_num_vars(), Z_poly.get_num_vars(), eq_p_rp_poly.get_num_vars(), @@ -552,11 +571,18 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { timer_sc_proof_phase2.stop(); // Separate ry into rp, rw, and ry + /* let (ry_rev, rw) = ry.split_at(num_rounds_y); let (rw, rp) = rw.split_at(num_rounds_w); let rp = rp.to_vec(); let rw = rw.to_vec(); let ry: Vec = ry_rev.iter().copied().rev().collect(); + */ + let (rp, ry) = ry.split_at(num_rounds_p); + let (rw, ry) = ry.split_at(num_rounds_w); + let rp = rp.to_vec(); + let rw = rw.to_vec(); + let ry = ry.to_vec(); // -- // POLY COMMIT @@ -849,7 +875,6 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { 3, transcript, )?; - */ // Separate ry into rp, rw, and ry let (ry_rev, rw) = ry.split_at(num_rounds_y); @@ -857,6 +882,14 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { let rp = rp.to_vec(); let rw = rw.to_vec(); let ry: Vec = ry_rev.iter().copied().rev().collect(); + */ + + // Separate ry into rp, rw, and ry + let (rp, ry) = ry.split_at(num_rounds_p); + let (rw, ry) = ry.split_at(num_rounds_w); + let rp = rp.to_vec(); + let rw = rw.to_vec(); + let ry = ry.to_vec(); // An Eq function to match p with rp let p_rp_poly_bound_ry: S = (0..rp.len()) diff --git a/zok_tests/benchmarks/poseidon_test/poseidon_const.zok b/zok_tests/benchmarks/poseidon_test/poseidon_const.zok index ecd81ed4..ac6bfc99 100644 --- a/zok_tests/benchmarks/poseidon_test/poseidon_const.zok +++ b/zok_tests/benchmarks/poseidon_test/poseidon_const.zok @@ -1 +1 @@ -const u32 REPETITION = 100 +const u32 REPETITION = 10000 From 4e6e23195d08e093e092f8f2a9dbb0dab34c17bc Mon Sep 17 00:00:00 2001 From: Ray Gao Date: Mon, 23 Dec 2024 02:53:37 -0500 Subject: [PATCH 13/13] Increase thread count --- spartan_parallel/src/r1csproof.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spartan_parallel/src/r1csproof.rs b/spartan_parallel/src/r1csproof.rs index 37142b98..9ec730d4 100644 --- a/spartan_parallel/src/r1csproof.rs +++ b/spartan_parallel/src/r1csproof.rs @@ -293,7 +293,7 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { ); let max_num_vars = A.get_num_vars(); - let num_threads = 8; + let num_threads = 32; let mut virtual_polys = VirtualPolynomials::new(num_threads, max_num_vars); @@ -525,7 +525,7 @@ impl<'a, S: SpartanExtensionField + Send + Sync> R1CSProof { .into_mle() ); - let num_threads_phase2 = 8; + let num_threads_phase2 = 32; let mut virtual_polys = VirtualPolynomials::new(num_threads_phase2, max_num_vars_phase2);