diff --git a/.gitignore b/.gitignore index 606f7a0..067f740 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,10 @@ target/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html Cargo.lock +**/Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk +.DS_Store +.vscode/ diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index 44fe11f..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,1497 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -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.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" - -[[package]] -name = "anstyle-parse" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" -dependencies = [ - "anstyle", - "windows-sys", -] - -[[package]] -name = "arrayref" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" - -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - -[[package]] -name = "autocfg" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - -[[package]] -name = "base58ck" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c8d66485a3a2ea485c1913c4572ce0256067a5377ac8c75c4960e1cda98605f" -dependencies = [ - "bitcoin-internals", - "bitcoin_hashes", -] - -[[package]] -name = "bech32" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" - -[[package]] -name = "bitcoin" -version = "0.31.0" -source = "git+https://github.com/cyl19970726/rust-bitcoin?rev=ffad6f3#ffad6f309054e62aacc36311fc0cc08492f81848" -dependencies = [ - "base58ck", - "bech32", - "bitcoin-internals", - "bitcoin-io", - "bitcoin-units", - "bitcoin_hashes", - "hex-conservative", - "hex_lit", - "secp256k1", - "serde", -] - -[[package]] -name = "bitcoin-internals" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bdbe14aa07b06e6cfeffc529a1f099e5fbe249524f8125358604df99a4bed2" -dependencies = [ - "serde", -] - -[[package]] -name = "bitcoin-io" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "340e09e8399c7bd8912f495af6aa58bea0c9214773417ffaa8f6460f93aaee56" - -[[package]] -name = "bitcoin-script" -version = "0.2.0" -source = "git+https://github.com/cyl19970726/rust-bitcoin-script?rev=eda97c5#eda97c5c919908ae28c87b6f2a78318c0f6a5817" -dependencies = [ - "bitcoin", - "hex", - "lazy_static", - "proc-macro-error", - "proc-macro2", - "quote", -] - -[[package]] -name = "bitcoin-scriptexec" -version = "0.0.0" -source = "git+https://github.com/cyl19970726/rust-bitcoin-scriptexec?rev=09c601e#09c601e9dc48f3ffec795177855677275e3633c7" -dependencies = [ - "bitcoin", - "clap", - "console_error_panic_hook", - "getrandom", - "hex", - "lazy_static", - "serde", - "serde-wasm-bindgen", - "serde_json", - "wasm-bindgen", -] - -[[package]] -name = "bitcoin-units" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb54da0b28892f3c52203a7191534033e051b6f4b52bc15480681b57b7e036f5" -dependencies = [ - "bitcoin-internals", - "serde", -] - -[[package]] -name = "bitcoin_hashes" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16" -dependencies = [ - "bitcoin-io", - "hex-conservative", - "serde", -] - -[[package]] -name = "blake3" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52" -dependencies = [ - "arrayref", - "arrayvec", - "cc", - "cfg-if", - "constant_time_eq", -] - -[[package]] -name = "bumpalo" -version = "3.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" - -[[package]] -name = "cast" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" - -[[package]] -name = "cc" -version = "1.0.99" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" - -[[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 = "clap" -version = "4.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "clap_lex" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" - -[[package]] -name = "colorchoice" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" - -[[package]] -name = "console_error_panic_hook" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" -dependencies = [ - "cfg-if", - "wasm-bindgen", -] - -[[package]] -name = "constant_time_eq" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" - -[[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-deque" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "either" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" - -[[package]] -name = "fri" -version = "0.1.0" -dependencies = [ - "bitcoin", - "bitcoin-script", - "bitcoin-scriptexec", - "blake3", - "criterion", - "itertools 0.12.1", - "p3-baby-bear", - "p3-blake3", - "p3-challenger", - "p3-dft", - "p3-field", - "p3-goldilocks", - "p3-interpolation", - "p3-keccak", - "p3-matrix", - "p3-maybe-rayon", - "p3-mds", - "p3-merkle-tree", - "p3-mersenne-31", - "p3-symmetric", - "p3-util", - "primitives", - "rand", - "rand_chacha", - "scripts", - "serde", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "gcd" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "half" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" -dependencies = [ - "cfg-if", - "crunchy", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hex-conservative" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd" -dependencies = [ - "arrayvec", -] - -[[package]] -name = "hex_lit" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd" - -[[package]] -name = "is-terminal" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys", -] - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "js-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.155" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" - -[[package]] -name = "log" -version = "0.4.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" - -[[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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" - -[[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-bigint" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" -dependencies = [ - "num-integer", - "num-traits", - "rand", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "nums" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf3c74f925fb8cfc49a8022f2afce48a0683b70f9e439885594e84c5edbf5b01" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", - "rand", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "oorandom" -version = "11.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "p3" -version = "0.1.0" - -[[package]] -name = "p3-baby-bear" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#fde81db95b8eeb39e07890f4099a7d59daeec52f" -dependencies = [ - "num-bigint", - "p3-field", - "p3-mds", - "p3-poseidon2", - "p3-symmetric", - "rand", - "serde", -] - -[[package]] -name = "p3-blake3" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#fde81db95b8eeb39e07890f4099a7d59daeec52f" -dependencies = [ - "blake3", - "p3-symmetric", -] - -[[package]] -name = "p3-challenger" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#fde81db95b8eeb39e07890f4099a7d59daeec52f" -dependencies = [ - "p3-field", - "p3-maybe-rayon", - "p3-symmetric", - "p3-util", - "tracing", -] - -[[package]] -name = "p3-commit" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#fde81db95b8eeb39e07890f4099a7d59daeec52f" -dependencies = [ - "itertools 0.13.0", - "p3-challenger", - "p3-field", - "p3-matrix", - "p3-util", - "serde", -] - -[[package]] -name = "p3-dft" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#fde81db95b8eeb39e07890f4099a7d59daeec52f" -dependencies = [ - "p3-field", - "p3-matrix", - "p3-maybe-rayon", - "p3-util", - "tracing", -] - -[[package]] -name = "p3-field" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#fde81db95b8eeb39e07890f4099a7d59daeec52f" -dependencies = [ - "itertools 0.13.0", - "num-bigint", - "num-integer", - "num-traits", - "nums", - "p3-util", - "rand", - "serde", -] - -[[package]] -name = "p3-goldilocks" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#fde81db95b8eeb39e07890f4099a7d59daeec52f" -dependencies = [ - "num-bigint", - "p3-dft", - "p3-field", - "p3-mds", - "p3-poseidon2", - "p3-symmetric", - "p3-util", - "rand", - "serde", -] - -[[package]] -name = "p3-interpolation" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#fde81db95b8eeb39e07890f4099a7d59daeec52f" -dependencies = [ - "p3-field", - "p3-matrix", - "p3-util", -] - -[[package]] -name = "p3-keccak" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#fde81db95b8eeb39e07890f4099a7d59daeec52f" -dependencies = [ - "p3-symmetric", - "tiny-keccak", -] - -[[package]] -name = "p3-matrix" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#fde81db95b8eeb39e07890f4099a7d59daeec52f" -dependencies = [ - "itertools 0.13.0", - "p3-field", - "p3-maybe-rayon", - "p3-util", - "rand", - "serde", - "tracing", -] - -[[package]] -name = "p3-maybe-rayon" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#fde81db95b8eeb39e07890f4099a7d59daeec52f" - -[[package]] -name = "p3-mds" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#fde81db95b8eeb39e07890f4099a7d59daeec52f" -dependencies = [ - "itertools 0.12.1", - "p3-dft", - "p3-field", - "p3-matrix", - "p3-symmetric", - "p3-util", - "rand", -] - -[[package]] -name = "p3-merkle-tree" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#fde81db95b8eeb39e07890f4099a7d59daeec52f" -dependencies = [ - "itertools 0.13.0", - "p3-commit", - "p3-field", - "p3-matrix", - "p3-maybe-rayon", - "p3-symmetric", - "p3-util", - "serde", - "tracing", -] - -[[package]] -name = "p3-mersenne-31" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#fde81db95b8eeb39e07890f4099a7d59daeec52f" -dependencies = [ - "itertools 0.13.0", - "num-bigint", - "p3-dft", - "p3-field", - "p3-matrix", - "p3-maybe-rayon", - "p3-mds", - "p3-poseidon2", - "p3-symmetric", - "p3-util", - "rand", - "serde", -] - -[[package]] -name = "p3-poseidon2" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#fde81db95b8eeb39e07890f4099a7d59daeec52f" -dependencies = [ - "gcd", - "p3-field", - "p3-mds", - "p3-symmetric", - "rand", -] - -[[package]] -name = "p3-symmetric" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#fde81db95b8eeb39e07890f4099a7d59daeec52f" -dependencies = [ - "itertools 0.13.0", - "p3-field", - "serde", -] - -[[package]] -name = "p3-util" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#fde81db95b8eeb39e07890f4099a7d59daeec52f" -dependencies = [ - "serde", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" - -[[package]] -name = "plotters" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" - -[[package]] -name = "plotters-svg" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" -dependencies = [ - "plotters-backend", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "primitives" -version = "0.1.0" -dependencies = [ - "bitcoin", - "bitcoin-script", - "bitcoin-scriptexec", - "blake3", - "itertools 0.12.1", - "lazy_static", - "p3-baby-bear", - "p3-challenger", - "p3-field", - "p3-maybe-rayon", - "p3-symmetric", - "p3-util", - "rand", - "rand_chacha", - "scripts", - "serde", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.85" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rayon" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "regex" -version = "1.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", -] - -[[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]] -name = "regex-automata" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax 0.8.4", -] - -[[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.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" - -[[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 = "scripts" -version = "0.1.0" -dependencies = [ - "bitcoin", - "bitcoin-script", - "bitcoin-scriptexec", - "blake3", - "criterion", - "hex", - "itertools 0.12.1", - "lazy_static", - "once_cell", - "p3-baby-bear", - "p3-challenger", - "p3-dft", - "p3-field", - "p3-goldilocks", - "p3-mds", - "p3-merkle-tree", - "p3-mersenne-31", - "p3-poseidon2", - "p3-symmetric", - "p3-util", - "rand", - "rand_chacha", -] - -[[package]] -name = "secp256k1" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e0cc0f1cf93f4969faf3ea1c7d8a9faed25918d96affa959720823dfe86d4f3" -dependencies = [ - "bitcoin_hashes", - "secp256k1-sys", - "serde", -] - -[[package]] -name = "secp256k1-sys" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1433bd67156263443f14d603720b082dd3121779323fce20cba2aa07b874bc1b" -dependencies = [ - "cc", -] - -[[package]] -name = "serde" -version = "1.0.203" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-wasm-bindgen" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" -dependencies = [ - "js-sys", - "serde", - "wasm-bindgen", -] - -[[package]] -name = "serde_derive" -version = "1.0.203" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "serde_json" -version = "1.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[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 = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[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 = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-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.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[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.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.66", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" - -[[package]] -name = "web-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "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.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" -dependencies = [ - "windows-sys", -] - -[[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.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" diff --git a/Cargo.toml b/Cargo.toml index 09fe24e..78b0e8f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,32 @@ [workspace] members = [ "fri", - "primitives", - "p3", - "scripts" -] + "basic", + "scripts", + "common", + "uni-stark" +, "script_expr"] +[patch.crates-io.base58check] +git = "https://github.com/bitlayer-org/rust-bitcoin" +branch = "bitvm" + +[patch.crates-io.bitcoin] +git = "https://github.com/bitlayer-org/rust-bitcoin" +branch = "bitvm" + +[patch.crates-io.bitcoin_hashes] +git = "https://github.com/bitlayer-org/rust-bitcoin" +branch = "bitvm" + +[patch.crates-io.bitcoin-internals] +git = "https://github.com/bitlayer-org/rust-bitcoin" +branch = "bitvm" + +[patch.crates-io.bitcoin-io] +git = "https://github.com/bitlayer-org/rust-bitcoin" +branch = "bitvm" + +[patch.crates-io.bitcoin-units] +git = "https://github.com/bitlayer-org/rust-bitcoin" +branch = "bitvm" diff --git a/README.md b/README.md new file mode 100644 index 0000000..fe561af --- /dev/null +++ b/README.md @@ -0,0 +1,120 @@ +# TapStark + +TapStark is a Bitcoin-friendly proof system enabling on-chain verification through BitVM2 paradigm and Taptree commitment scheme. Built upon Plonky3, it operates independently of OP_CAT. + +## Core Components +- **Polynomial Commitment**: Combines Taptree commitment with bit commitment +- **Cryptographic Hash**: Uses Blake3 for permutation hashing +- **Low Degree Testing**: Implements FRI protocol +- **STARK Protocol**: Follows [Plonky3's uni-stark](https://github.com/Plonky3/Plonky3/tree/main/uni-stark) approach +- **Verification DSL**: Custom domain-specific language for Bitcoin script generation + +## Documentation +- For a conceptual overview, read our [introductory article](https://blog.bitlayer.org/introduce-bf-stark/) +- For technical details, see our [comprehensive paper](./doc/TapSTARK.pdf) + +## Domain Specific Language (DSL) +Our DSL facilitates rapid development of Bitcoin verifiers for TapStark. It serves two key purposes: +1. Streamlines verifier script development +2. Automates constraint script generation via [ScriptAirBuilder](./script_expr/script_builder.rs) + +### Supported Operations +The DSL supports the following operations over babybear field and its extension: +```rust +pub(crate) enum StandardOpcodeId { + Add, + Mul, + Sub, + Neg, + Equal, + EqualVerify, + NumToField, + Constant, + ExpConst, + IndexToRou, + Lookup, + InputVarMove, + InputVarCopy, + Table, + Square, + Double, + Blake3Perm, + ToSample, + SampleBase, + SampleExt, + ReverseBitslen, +} +``` + +### Usage Example +```rust +// Initialize field elements +let vec = vec![ + BabyBear::from_canonical_u32(1), + BabyBear::from_canonical_u32(2), + BabyBear::from_canonical_u32(3), + BabyBear::from_canonical_u32(4), + BabyBear::from_canonical_u32(5), +]; + +// Setup environment +let mut stack = StackTracker::new(); +let bmap = BTreeMap::new(); + +// Demonstrate table lookup and arithmetic +let table = Dsl::from_table(&vec); +let index = 4; +let m = table.lookup(index, vec.len()); + +let a = Dsl::constant_f(BabyBear::one()); +let b = Dsl::constant_f(BabyBear::two()); +let c = a + b + m; + +// Verify computation +let equal = h.equal_for_f(Babybear::from_canonical_u32(7)); +let res = equal.express_with_optimize(); +println!("Optimized script length: {:?}", res.0.get_script().len()); +let res = res.0.run(); +assert!(res.success); +``` +### Data +| bit security(conjectured soundness with 36 pow bits) | log blowup factor | query_num | trace | table height(degree) | table width | public inputs | total u32 num(intermediate states) | fri u32 num(intermediate states) | total script len | script len for fri query | verify trace constraint script len | compute quotient poly | challenge script size | +|-------------------------------------------------------:|--------------------:|------------:|:-------------|:-----------------------|--------------:|----------------:|-------------------------------------:|-----------------------------------:|:-------------------|:---------------------------|:-------------------------------------|:------------------------|:------------------------| +| 91 | 2 | 28 | Fibonacci | 1 << 3 | 2 | 3 | 360 | 341 | 12177kb | 28 x 428 = 11984 kb | 120kb | 73kb | nan | +| 67 | 2 | 16 | Fibonacci | 1 << 3 | 2 | 3 | 300 | 284 | 7041kb | 16 x 428 = 6848 kb | 120kb | 73 kb | nan | +| 99 | 4 | 16 | Fibonacci | 1 << 3 | 2 | 3 | 300 | 284 | 7041 kb | 16 x 428 = 6848 kb | 120kb | 73kb | nan | +| 67 | 2 | 16 | Fibonacci | 1 << 4 | 2 | 3 | 424 | 408 | 8113 kb | 16 x 495 = 7920 kb | 120kb | 73kb | nan | +| 67 | 2 | 16 | Fibonacci | 1 << 5 | 2 | 3 | 490 | 471 | 9185 kb | 16 x 562 = 8992 kb | 120kb | 73kb | nan | +| 67 | 2 | 16 | Fibonacci | 1 << 10 | 2 | 3 | 829 | 810 | 14593kb | 16 x 900 = 14400 kb | 120kb | 73kb | nan | +| 67 | 2 | 16 | Fibonacci | 1 << 11 | 2 | 3 | 956 | 937 | 15681 kb | 16 x 968 = 15488 kb | 120kb | 73kb | nan | +| 99 | 4 | 16 | Recursive R0 | 1 << 18 | 163 | nan | 2904 | 1600 | 129.44 MB | 16 x 1444 = 23104 kb | 100.878mb | 6mb (s=5) | 2.2 mb | + + +## TODO List +### Taptree Commitmtment +- [x] support taptree commmitment +- [x] intergate into fri + - [x] genereate new taptree for per-query +- [x] intergate into pcs +- [x] intergate into uni-stark + +### ScriptExpr Verifier +- [x] uni-stark script_expr + - [x] compute selector script_expr + - [x] compute quotient script_expr + - [x] compute constraints script_expr +- [x] two-adic-pcs script_expr +- [x] fri script_expr +- [x] challenge script_expr + +### ScriptExpr +- [x] support input variable +- [x] automatic management of input variables + - [x] automatic computation of the number of inputs +- [x] implement copy variable to optimize the compiler +- [ ] Implementing automatic segmentation tool + - [ ] bitcommitment assign + - [ ] extract intermidiate value +- [x] add verify hint gadget + + diff --git a/basic/Cargo.toml b/basic/Cargo.toml new file mode 100644 index 0000000..b0f0df9 --- /dev/null +++ b/basic/Cargo.toml @@ -0,0 +1,38 @@ +[package] +name = "basic" +version = "0.1.0" +edition = "2021" + +[dependencies] +bitcoin-script = { git = "https://github.com/bitlayer-org/rust-bitcoin-script" } +bitcoin = { git = "https://github.com/bitlayer-org/rust-bitcoin", branch = "bitvm", features = ["serde"] } +bitcoin-scriptexec = { git = "https://github.com/bitlayer-org/rust-bitcoin-scriptexec", branch = "bitvm"} +bitcomm = { git = "https://github.com/bitlayer-org/bitcoin-verifier", branch = "bitvm"} +primitives = { git = "https://github.com/bitlayer-org/bitcoin-verifier", branch = "bitvm" } + +lazy_static = "1.4.0" +itertools = "0.12.0" +tracing = "0.1.37" +tracing-subscriber = { version = "0.3.17", features = ["std", "env-filter"] } +serde = { version = "1.0", default-features = false, features = ["derive", "alloc"] } +blake3 = "1.5" +rand = "0.8.5" +rand_chacha = "0.3.1" + + +p3-symmetric ={ git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-field = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-baby-bear = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-challenger = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-util = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-maybe-rayon ={ git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-matrix = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-commit = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } + +common = { path = "../common"} +scripts = {path = "../scripts"} + +[dev-dependencies] +p3-interpolation = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-dft = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-maybe-rayon ={ git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } \ No newline at end of file diff --git a/basic/src/bf_pcs.rs b/basic/src/bf_pcs.rs new file mode 100644 index 0000000..fd368c8 --- /dev/null +++ b/basic/src/bf_pcs.rs @@ -0,0 +1,116 @@ +//! Traits for polynomial commitment schemes. + +use core::fmt::Debug; + +use p3_commit::PolynomialSpace; +use p3_field::ExtensionField; +use p3_matrix::dense::RowMajorMatrix; +use p3_matrix::Matrix; +use serde::de::DeserializeOwned; +use serde::Serialize; + +pub type Val = ::Val; + +/// A (not necessarily hiding) polynomial commitment scheme, for committing to (batches of) polynomials +// TODO: Should we have a super-trait for weakly-binding PCSs, like FRI outside unique decoding radius? +pub trait Pcs +where + Challenge: ExtensionField>, +{ + type Domain: PolynomialSpace; + + /// The commitment that's sent to the verifier. + type Commitment: Clone + Serialize + DeserializeOwned; + + /// Data that the prover stores for committed polynomials, to help the prover with opening. + type ProverData; + + /// The opening argument. + type Proof: Clone + Serialize + DeserializeOwned; + + type Error: Debug; + + /// This should return a coset domain (s.t. Domain::next_point returns Some) + fn natural_domain_for_degree(&self, degree: usize) -> Self::Domain; + + #[allow(clippy::type_complexity)] + fn commit( + &self, + evaluations: Vec<(Self::Domain, RowMajorMatrix>)>, + ) -> (Self::Commitment, Self::ProverData); + + fn get_evaluations_on_domain<'a>( + &self, + prover_data: &'a Self::ProverData, + idx: usize, + domain: Self::Domain, + ) -> impl Matrix> + 'a; + + fn open( + &self, + // For each round, + rounds: Vec<( + &Self::ProverData, + // for each matrix, + Vec< + // points to open + Vec, + >, + )>, + challenger: &mut Challenger, + ) -> (OpenedValues, Self::Proof); + + #[allow(clippy::type_complexity)] + fn verify( + &self, + // For each round: + rounds: Vec<( + Self::Commitment, + // for each matrix: + Vec<( + // its domain, + Self::Domain, + // for each point: + Vec<( + // the point, + Challenge, + // values at the point + Vec, + )>, + )>, + )>, + proof: &Self::Proof, + challenger: &mut Challenger, + ) -> Result<(), Self::Error>; +} + +pub trait PcsExpr: Pcs +where + Challenge: ExtensionField>, +{ + fn generate_verify_expr( + &self, + // For each round: + rounds: Vec<( + Self::Commitment, + // for each matrix: + Vec<( + // its domain, + Self::Domain, + // for each point: + Vec<( + // the point, + Challenge, + // values at the point + Vec, + )>, + )>, + )>, + proof: &Self::Proof, + challenger: &mut Challenger, + ) -> Result; +} +pub type OpenedValues = Vec>; +pub type OpenedValuesForRound = Vec>; +pub type OpenedValuesForMatrix = Vec>; +pub type OpenedValuesForPoint = Vec; diff --git a/primitives/src/challenger/chan_field.rs b/basic/src/challenger/chan_field.rs similarity index 93% rename from primitives/src/challenger/chan_field.rs rename to basic/src/challenger/chan_field.rs index 39aff6c..913dd43 100644 --- a/primitives/src/challenger/chan_field.rs +++ b/basic/src/challenger/chan_field.rs @@ -1,8 +1,9 @@ - use core::array; use p3_baby_bear::BabyBear; use p3_field::PrimeField32; +use serde::de::DeserializeOwned; +use serde::Serialize; pub trait ChallengeField: PrimeField32 + Clone + Default + Copy + Ord { fn u8_num() -> usize { U8_NUM @@ -21,7 +22,7 @@ impl ChallengeField<4> for BabyBear {} // the PremutationField only support U8_NUM<=8 // Use LittleEndian pub trait PermutationField: - Clone + Default + Copy + Ord + Sized + Send + Sync + Clone + Default + Copy + Ord + Sized + Send + Sync + Serialize + DeserializeOwned { fn u8_num() -> usize { U8_NUM @@ -37,7 +38,7 @@ pub trait PermutationField: for _ in 0..U8_NUM { by.push(0); } - 1 << U8_NUM * 3 + 1 << (U8_NUM * 3) } fn from_u64(value: u64) -> Self { diff --git a/primitives/src/challenger/mod.rs b/basic/src/challenger/mod.rs similarity index 89% rename from primitives/src/challenger/mod.rs rename to basic/src/challenger/mod.rs index 8d5be76..e327acb 100644 --- a/primitives/src/challenger/mod.rs +++ b/basic/src/challenger/mod.rs @@ -1,23 +1,15 @@ - -use core::array; -use core::marker::PhantomData; use std::any::{Any, TypeId}; -use bitcoin::hashes::serde::Serializer; +use chan_field::{ChallengeField, PermutationField, U32}; use p3_baby_bear::BabyBear; +use p3_challenger::{CanObserve, CanSample, CanSampleBits}; use p3_field::extension::BinomialExtensionField; -use p3_field::{ - AbstractExtensionField, AbstractField,ExtensionField, Field, PackedValue, - PrimeField, PrimeField32, -}; -use chan_field::{PermutationField,ChallengeField,U32}; +use p3_field::{AbstractExtensionField, AbstractField, Field, PrimeField32}; use p3_maybe_rayon::prelude::*; use p3_symmetric::{CryptographicPermutation, Hash, Permutation}; use tracing; use tracing::instrument; -use p3_challenger::{CanObserve, CanSample, CanSampleBits}; - pub mod chan_field; /// A challenger that operates natively on PF but produces challenges of F: Field + BitExtractor,. @@ -41,7 +33,7 @@ impl Permutation for Blake3Permutation { fn permute_mut(&self, input: &mut StateLength) { let mut hasher = blake3::Hasher::new(); - for chunk in input.clone() { + for chunk in *input { hasher.update(&chunk); } let hashed: [u8; 32] = hasher.finalize().into(); @@ -108,7 +100,7 @@ where .expect("failed to find witness"); assert!(self.check_witness(bits, witness)); self.grind_bits = Some(bits); - self.grind_output = self.sample_output.last().unwrap().clone(); + self.grind_output = *self.sample_output.last().unwrap(); witness } @@ -146,7 +138,7 @@ where pub fn record_sample(&mut self, input: &Vec, output: &F) { self.sample_input.push(input.clone()); - self.sample_output.push(output.clone()); + self.sample_output.push(*output); } } @@ -166,17 +158,17 @@ where // Record this permutation to build fiat shamir subtree for future self.permutation_input_records - .push(self.sponge_state.try_into().unwrap()); + .push(self.sponge_state.into()); // Apply the permutation. self.permutation.permute_mut(&mut self.sponge_state); self.permutation_output_records - .push(self.sponge_state[WIDTH / 2..WIDTH].try_into().unwrap()); + .push(self.sponge_state[WIDTH / 2..WIDTH].into()); self.output_buffer.clear(); for i in WIDTH / 2..WIDTH { - self.output_buffer.push(self.sponge_state[i].clone()); + self.output_buffer.push(self.sponge_state[i]); } tracing::debug! {"state change: {:?}", u32::from_le_bytes(self.sponge_state[8].as_u8_array())}; } @@ -216,6 +208,20 @@ where } } +impl CanObserve> + for BfChallenger +where + F: Field + BitExtractor, + PF: PermutationField<4>, + P: CryptographicPermutation<[PF; WIDTH]>, +{ + fn observe(&mut self, values: Vec<[PF; N]>) { + for value in values { + self.observe(value); + } + } +} + impl CanObserve> for BfChallenger where @@ -270,7 +276,7 @@ where // commit records let output = BabyBear::from_pf(&value); sample_input.push(value); - res = (&output as &dyn Any).downcast_ref::().unwrap().clone(); + res = *(&output as &dyn Any).downcast_ref::().unwrap(); } // else, F would be a extension field of Babybear else if TypeId::of::() == TypeId::of::>() { @@ -295,11 +301,14 @@ where // commit records let output = BinomialExtensionField::::from_base_slice(&base_slice); - res = (&output as &dyn Any).downcast_ref::().unwrap().clone(); + res = *(&output as &dyn Any).downcast_ref::().unwrap(); } else { panic!("the type of base or f is invalid") } // no other implementation yet self.record_sample(&sample_input, &res); + + //TODO:adapt our challenger expr implementation + //self.output_buffer.clear(); res } } @@ -316,10 +325,8 @@ impl BitExtractor for BabyBear { impl BitExtractor for BinomialExtensionField { fn as_usize(&self) -> usize { - let s: BabyBear = >::as_base_slice(self) - .get(0) - .unwrap() - .clone(); + let s: BabyBear = *>::as_base_slice(self).first() + .unwrap(); s.as_canonical_u32() as usize } } diff --git a/primitives/src/field/mod.rs b/basic/src/field/mod.rs similarity index 84% rename from primitives/src/field/mod.rs rename to basic/src/field/mod.rs index 594db29..fa87431 100644 --- a/primitives/src/field/mod.rs +++ b/basic/src/field/mod.rs @@ -1,8 +1,9 @@ -use p3_baby_bear::BabyBear; -use p3_field::extension::BinomialExtensionField; -use p3_field::{AbstractExtensionField, AbstractField, PrimeField32, TwoAdicField}; +use common::AsU32Vec; +pub use p3_baby_bear::BabyBear; +pub use p3_field::extension::BinomialExtensionField; +pub use p3_field::{AbstractExtensionField, AbstractField, PrimeField32, TwoAdicField}; -pub trait BfField: AbstractField + TwoAdicField + Clone + Copy { +pub trait BfField: AbstractField + TwoAdicField + Clone + Copy + AsU32Vec { const BIS_SIZE: usize; const MOD: u32; const U32_SIZE: usize; @@ -23,7 +24,7 @@ pub trait BfField: AbstractField + TwoAdicField + Clone + Copy { subgroups.push(Self::one()); for _ in 0..group_size - 1 { subgroups.push(acc); - acc = acc * generator; + acc *= generator; } subgroups } @@ -61,12 +62,9 @@ impl BfField for BinomialExtensionField { .collect() } } - +#[cfg(test)] mod tests { - use p3_baby_bear::BabyBear; - use p3_field::{AbstractField, PrimeField32}; - - use super::BfField; + use super::*; #[test] fn test_subgroup() { diff --git a/basic/src/lib.rs b/basic/src/lib.rs new file mode 100644 index 0000000..afaac7c --- /dev/null +++ b/basic/src/lib.rs @@ -0,0 +1,5 @@ +pub mod bf_pcs; +pub mod challenger; +pub mod field; +pub mod mmcs; +pub mod tcs; diff --git a/fri/src/mmcs/bf_mmcs.rs b/basic/src/mmcs/bf_mmcs.rs similarity index 52% rename from fri/src/mmcs/bf_mmcs.rs rename to basic/src/mmcs/bf_mmcs.rs index c56c76b..0a9d29c 100644 --- a/fri/src/mmcs/bf_mmcs.rs +++ b/basic/src/mmcs/bf_mmcs.rs @@ -1,10 +1,10 @@ -use alloc::vec; -use alloc::vec::Vec; +// use alloc::vec; +// use alloc::vec::Vec; use core::fmt::Debug; use p3_matrix::dense::RowMajorMatrix; -// use serde::de::DeserializeOwned; -// use serde::Serialize; +use serde::de::DeserializeOwned; +use serde::Serialize; /// A "Mixed Matrix Commitment Scheme" (MMCS) is a generalization of a vector commitment scheme; it /// supports committing to matrices and then opening rows. It is also batch-oriented; one can commit @@ -16,10 +16,8 @@ use p3_matrix::dense::RowMajorMatrix; /// useful in the FRI protocol. See the documentation for `open_batch` for more details. pub trait BFMmcs: Clone { type ProverData; - // type Commitment: Clone + Serialize + DeserializeOwned; - // type Proof: Clone + Serialize + DeserializeOwned; - type Commitment: Clone; - type Proof: Clone; + type Commitment: Clone + Serialize + DeserializeOwned; + type Proof: Clone + Serialize + DeserializeOwned; type Error: Debug; fn commit(&self, inputs: Vec>) -> (Self::Commitment, Self::ProverData); @@ -35,10 +33,36 @@ pub trait BFMmcs: Clone { self.commit_matrix(RowMajorMatrix::new_col(input)) } - fn open_taptree(&self, index: usize, prover_data: &Self::ProverData) -> Self::Proof; - fn verify_taptree( + fn open_batch( &self, + query_times_index: usize, + query_index: usize, // This is the index corresponding to the highest matrix + prover_data: &Self::ProverData, + ) -> (Vec>, Self::Proof); + + fn verify_batch( + &self, + query_times_index: usize, + opened_values: &Vec>, proof: &Self::Proof, root: &Self::Commitment, ) -> Result<(), Self::Error>; + + /// Get the matrices that were committed to. + fn get_matrices<'a>(&self, prover_data: &'a Self::ProverData) -> Vec<&'a RowMajorMatrix>; + + fn get_matrix_heights(&self, prover_data: &Self::ProverData) -> Vec { + self.get_matrices(prover_data) + .iter() + .map(|matrix| matrix.values.len() / matrix.width) + .collect() + } + + /// Get the largest height of any committed matrix. + fn get_max_height(&self, prover_data: &Self::ProverData) -> usize { + self.get_matrix_heights(prover_data) + .into_iter() + .max() + .unwrap_or_else(|| panic!("No committed matrices?")) + } } diff --git a/basic/src/mmcs/error.rs b/basic/src/mmcs/error.rs new file mode 100644 index 0000000..63bf56f --- /dev/null +++ b/basic/src/mmcs/error.rs @@ -0,0 +1,19 @@ +use bitcoin::taproot::TaprootBuilderError; +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum BfError { + TaprootBuilderError(TaprootBuilderError), + TaprootError, + TapLeafError, + TapTreeError, + EvaluationLeafError, + ExecuteScriptError, + InvalidMerkleProof, + InvalidOpenedValue, + IndexWithEmptyLeaf(u32, u32), +} + +impl From for BfError { + fn from(error: TaprootBuilderError) -> Self { + BfError::TaprootBuilderError(error) + } +} diff --git a/fri/src/mmcs/mod.rs b/basic/src/mmcs/mod.rs similarity index 66% rename from fri/src/mmcs/mod.rs rename to basic/src/mmcs/mod.rs index c0c563f..ea2ad1e 100644 --- a/fri/src/mmcs/mod.rs +++ b/basic/src/mmcs/mod.rs @@ -1,6 +1,5 @@ #![feature(slice_pattern)] pub mod bf_mmcs; -pub mod tapleaf; -pub mod taptree; +pub mod error; pub mod taptree_mmcs; diff --git a/basic/src/mmcs/taptree_mmcs.rs b/basic/src/mmcs/taptree_mmcs.rs new file mode 100644 index 0000000..3d8924b --- /dev/null +++ b/basic/src/mmcs/taptree_mmcs.rs @@ -0,0 +1,239 @@ +use core::marker::PhantomData; +use core::usize; + +use bitcoin::hashes::Hash as Bitcoin_HASH; +use bitcoin::TapNodeHash; +use itertools::Itertools; +use p3_matrix::dense::RowMajorMatrix; +use p3_matrix::Matrix; +use p3_util::log2_ceil_usize; + +use super::bf_mmcs::BFMmcs; +use super::error::BfError; +use crate::challenger::chan_field::{u256_to_u32, u32_to_u256, U32}; +use crate::field::BfField; +use crate::tcs::{ + CommitedData, CommitedProof, DefaultSyncBcManager, PolyTCS, B, BM, BO, SG, TCS, +}; + +pub type TreeRoot = [U32; ROOT_WIDTH]; +// Commit two adjacent points to a leaf node +pub const DEFAULT_MATRIX_WIDTH: usize = 2; +pub const LOG_DEFAULT_MATRIX_WIDTH: usize = 1; + +pub const ROOT_WIDTH: usize = 8; +#[derive(Clone)] +pub struct TapTreeMmcs { + tcs: TCS, + num_queries: usize, + _marker: PhantomData, +} + +impl<'a, F> TapTreeMmcs { + pub fn new(manager: DefaultSyncBcManager, num_queries: usize) -> Self { + Self { + tcs: TCS::new(manager), + num_queries, + _marker: PhantomData, + } + } +} + +impl BFMmcs for TapTreeMmcs { + type ProverData = Vec>; + type Proof = CommitedProof; + type Commitment = Vec; + type Error = BfError; + + fn open_batch( + &self, + query_times_index: usize, + query_index: usize, // This is the index corresponding to the highest matrix + prover_data: &Self::ProverData, + ) -> (Vec>, Self::Proof) { + let max_height = prover_data[0].get_max_height(); + let log_max_height = log2_ceil_usize(max_height); + let openings = prover_data[0] + .leaves + .iter() + .map(|matrix| { + let log2_height = log2_ceil_usize(matrix.height()); + let bits_reduced = log_max_height - log2_height; + let reduced_index = query_index >> bits_reduced; + matrix.row(reduced_index).collect() + }) + .collect_vec(); + + let (commited_proof, openings_evals) = self.tcs.open_with_one_query( + query_times_index, + query_index, + prover_data, + self.num_queries, + ); + let openings_flatten: Vec = openings.clone().into_iter().flatten().collect(); + assert_eq!(openings_flatten, openings_evals); + + (openings, commited_proof) + } + + fn verify_batch( + &self, + query_times_index: usize, + opened_values: &Vec>, + proofs: &Self::Proof, + roots: &Self::Commitment, + ) -> Result<(), Self::Error> { + let openings_flatten: Vec = opened_values.clone().into_iter().flatten().collect(); + + let commitments: Vec = roots + .iter() + .map(|root| TapNodeHash::from_byte_array(u32_to_u256(*root))) + .collect(); + + let success = self + .tcs + .verify(commitments[query_times_index], proofs, openings_flatten); + if success { + Ok(()) + } else { + Err(BfError::InvalidOpenedValue) + } + } + + fn commit(&self, inputs: Vec>) -> (Self::Commitment, Self::ProverData) { + let commited_data = self + .tcs + .commit_poly_with_query_times(inputs, self.num_queries); + let commitments: Vec<[U32; 8]> = commited_data + .iter() + .map(|data| { + let root = *data + .commit_taptree + .root() + .hash + .as_byte_array(); + u256_to_u32(root) + }) + .collect(); + + (commitments, commited_data) + } + + fn get_matrices<'a>(&self, prover_data: &'a Self::ProverData) -> Vec<&'a RowMajorMatrix> { + prover_data[0].leaves.iter().collect() + } +} + +#[cfg(test)] +mod test { + + use p3_baby_bear::BabyBear; + use p3_field::AbstractField; + use p3_matrix::dense::RowMajorMatrix; + + + use super::TapTreeMmcs; + use crate::mmcs::bf_mmcs::BFMmcs; + use crate::tcs::DefaultSyncBcManager; + type F = BabyBear; + + #[test] + fn test_taptree_mmcs() { + // mat_1 = [ + // 0 1 + // 2 1 + // 2 2 + // 1 0 + // ] + let mat_1 = RowMajorMatrix::new( + vec![ + F::zero(), + F::one(), + F::two(), + F::one(), + F::two(), + F::two(), + F::one(), + F::zero(), + ], + 2, + ); + + // mat_2 = [ + // 0 1 2 1 + // 2 2 1 0 + // 0 1 2 1 + // 2 2 1 0 + // ] + let mat_2 = RowMajorMatrix::new( + vec![ + F::zero(), + F::one(), + F::two(), + F::one(), + F::two(), + F::two(), + F::one(), + F::zero(), + F::zero(), + F::one(), + F::two(), + F::one(), + F::two(), + F::two(), + F::one(), + F::zero(), + ], + 4, + ); + + // mat_3 = [ + // 0 + // 1 + // 2 + // 1 + // 2 + // 2 + // 1 + // 0 + // ] + let mat_3 = RowMajorMatrix::new( + vec![ + F::zero(), + F::one(), + F::two(), + F::one(), + F::two(), + F::two(), + F::one(), + F::zero(), + ], + 1, + ); + + // we get pointleafs like: + // index:0, ys:[0, 0, 1, 0, 1, 2, 1] + // index:1, ys:[1, 0, 1, 0, 1, 2, 1] + // index:2, ys:[2, 2, 1, 2, 2, 1, 0] + // index:3, ys:[1, 2, 1, 2, 2, 1, 0] + // index:4, ys:[2, 2, 2, 0, 1, 2, 1] + // index:5, ys:[2, 2, 2, 0, 1, 2, 1] + // index:6, ys:[1, 1, 0, 2, 2, 1, 0] + // index:7, ys:[0, 1, 0, 2, 2, 1, 0] + + // let inputs = vec![mat_1, mat_2, mat_3]; + let inputs = vec![mat_3, mat_2, mat_1]; + let query_times = 10; + let mmcs = TapTreeMmcs::new(DefaultSyncBcManager::new(), query_times); + let (commits, prover_datas) = mmcs.commit(inputs); + + for query_index in 0..8 { + for query_times_index in 0..query_times { + let (openings, proof) = + mmcs.open_batch(query_times_index, query_index, &prover_datas); + mmcs.verify_batch(query_times_index, &openings, &proof, &commits) + .unwrap(); + } + } + } +} diff --git a/basic/src/tcs/builder.rs b/basic/src/tcs/builder.rs new file mode 100644 index 0000000..ade17da --- /dev/null +++ b/basic/src/tcs/builder.rs @@ -0,0 +1,106 @@ +use bitcoin::taproot::LeafVersion::TapScript; +use bitcoin::taproot::NodeInfo; +use bitcoin::ScriptBuf; +use itertools::Itertools; + +use super::complete_taptree::CompleteTaptree; + +#[derive(Clone, Debug, Default)] +pub struct TreeBuilder { + pub(crate) leaf_count: usize, + pub(crate) leaf_indices: Vec, + pub(crate) to_add_leaves: Vec, +} + +impl TreeBuilder { + pub fn new() -> Self { + Self { + leaf_count: 0, + leaf_indices: Vec::new(), + to_add_leaves: Vec::new(), + } + } + + pub fn add_leaf(&mut self, leaf_script: ScriptBuf) { + self.leaf_count += 1; + let leaf = NodeInfo::new_leaf_with_ver(leaf_script, TapScript); + self.leaf_indices.push(self.leaf_count - 1); + self.to_add_leaves.push(leaf); + } + + /* + The leaves_indices are postion info of merkle tree leaves in the taptree. + When we building the taptree, it is much easier to work with a dict where the index is + the taptree position and the element is the merkle tree postion. + We flip the dict and save it to the leaf_indices. + + */ + pub fn build_tree(&mut self) -> CompleteTaptree { + let leaf_count = self.to_add_leaves.len(); + assert!(is_power_of_two(leaf_count as u32)); + // this build tree now only working on the leaf-num equal to + let mut working_nodes = self.to_add_leaves.clone(); + let mut t_idx_to_m_idx = self.leaf_indices.clone(); + + while working_nodes.len() > 1 { + // println!("working_nodes len:{:?}", working_nodes.len()); + //the tuple() method in itertool will drop the elements in Iter if the size is not enough to + //generate a tuple, so we have to save the last node if the size of working node is odd. + let mut reminder_node: Option = None; + if working_nodes.len() % 2 == 1 { + reminder_node = working_nodes.pop(); + } + + let node_tuples = working_nodes.into_iter().tuples(); + let mut todo: Vec = Vec::new(); + let mut a_start_idx = 0usize; // will be updated after finishing combining two nodes. + + for (a, b) in node_tuples { + let a_leaf_size = a.leaf_nodes().len(); + let a_end_idx = a_start_idx + a_leaf_size; + let b_start_idx = a_end_idx; + let b_leaf_size = b.leaf_nodes().len(); + let b_end_idx = b_start_idx + b_leaf_size; + let (ret_node, left_first) = NodeInfo::combine_with_order(a, b).unwrap(); + + todo.push(ret_node); + + //swap index when !left_first + if !left_first { + let mut temp_a_leaf_indices = vec![0usize; a_leaf_size]; + temp_a_leaf_indices + .as_mut_slice() + .copy_from_slice(&t_idx_to_m_idx[a_start_idx..a_end_idx]); + + let mut temp_b_leaf_indices = vec![0usize; b_leaf_size]; + temp_b_leaf_indices + .as_mut_slice() + .copy_from_slice(&t_idx_to_m_idx[b_start_idx..b_end_idx]); + temp_b_leaf_indices.append(&mut temp_a_leaf_indices); + t_idx_to_m_idx[a_start_idx..b_end_idx] + .copy_from_slice(temp_b_leaf_indices.as_slice()); + } + a_start_idx += a_leaf_size + b_leaf_size; + } + working_nodes = todo; + todo = Vec::new(); + } + CompleteTaptree::new( + working_nodes.into_iter().next().unwrap(), + leaf_count, + reverse_idx_dict(&t_idx_to_m_idx), + ) + } +} + +pub(crate) fn reverse_idx_dict(idx_dict: &Vec) -> Vec { + let mut ret_vec = vec![0usize; idx_dict.len()]; + for (idx, pos) in idx_dict.iter().enumerate() { + ret_vec[*pos] = idx; + } + ret_vec +} + +fn is_power_of_two(n: u32) -> bool { + n > 0 && (n & (n - 1)) == 0 +} diff --git a/basic/src/tcs/complete_taptree.rs b/basic/src/tcs/complete_taptree.rs new file mode 100644 index 0000000..2222bf3 --- /dev/null +++ b/basic/src/tcs/complete_taptree.rs @@ -0,0 +1,372 @@ +use bitcoin::taproot::{LeafNode, LeafNodes, NodeInfo, TaprootMerkleBranch}; +use bitcoin::TapNodeHash; + +use super::builder::TreeBuilder; +use super::{combine_two_nodes, ScriptToEmbbed, TaptreeConcater}; + +#[derive(Clone, Debug)] +pub(crate) struct CompleteTaptree { + pub root_node: NodeInfo, + leaf_count: usize, + leaf_indices: Vec, +} + +impl CompleteTaptree { + pub fn new(root: NodeInfo, leaf_count: usize, leaf_indices: Vec) -> Self { + CompleteTaptree { + root_node: root, + leaf_count, + leaf_indices, + } + } + + pub fn root(&self) -> &NodeInfo { + + (&self.root_node) as _ + } + + pub fn leaf_count(&self) -> usize { + self.leaf_count + } + + pub fn leaves(&self) -> LeafNodes { + let nodes = self.root_node.leaf_nodes(); + nodes + } + + pub fn get_leaf_merkle_path(&self, index: usize) -> Option<&TaprootMerkleBranch> { + let index = self.index_map(index); + if let Some(leaf) = self.leaves().nth(index) { + Some(leaf.merkle_branch()) + } else { + None + } + } + + fn index_map(&self, index: usize) -> usize { + self.leaf_indices[index] + } + + pub fn get_tapleaf(&self, index: usize) -> Option<&LeafNode> { + let index = self.index_map(index); + self.leaves().nth(index) + } + + pub(crate) fn verify_inclusion_by_index(&self, index: usize) -> bool { + let index = self.index_map(index); + let leaf = self.get_tapleaf(index).unwrap(); + let path = self.get_leaf_merkle_path(index).unwrap(); + let mut first_node_hash = TapNodeHash::from_node_hashes(leaf.node_hash(), path[0]); + path[1..].iter().for_each(|sibling_node| { + first_node_hash = TapNodeHash::from_node_hashes(first_node_hash, *sibling_node); + }); + + first_node_hash == self.root().node_hash() + } +} + +pub fn verify_inclusion(root: TapNodeHash, leaf: &LeafNode) -> bool { + let path = leaf.merkle_branch(); + let mut first_node_hash = TapNodeHash::from_node_hashes(leaf.node_hash(), path[0]); + path[1..].iter().for_each(|sibling_node| { + first_node_hash = TapNodeHash::from_node_hashes(first_node_hash, *sibling_node); + }); + + first_node_hash == root +} + +impl TaptreeConcater for CompleteTaptree { + fn new_with_scripts(scripts: Vec) -> Self { + let mut builder = TreeBuilder::new(); + for script in scripts { + builder.add_leaf(script.compelte_script()); + } + builder.build_tree() + } + + // todo: add test + fn combine_other_script(&mut self, scripts: Vec) -> Self { + let mut builder = TreeBuilder::new(); + for script in scripts { + builder.add_leaf(script.compelte_script()); + } + let other_tapree = builder.build_tree(); + self.combine(other_tapree) + } + + fn combine(&self, other: impl TaptreeConcater) -> Self { + let mut a_leaf_indices: Vec = self.get_indices().clone(); + let mut b_leaf_indices = other.get_indices().clone(); + + let (combined_tree, left_first) = + combine_two_nodes(self.get_root().clone(), other.get_root().clone()).unwrap(); + + // if the left_first is ture, leaves will places as [a.leaves... ,b.leaves...] + let taptree_indices = match left_first { + // for swap no happen, for the merkletree index is [a_merkle_tree_indices,b_merkle_tree_indices] + // the acctually taptree indices is [a_taptree_indices,b_taptree_indices] + true => { + for b_idx in b_leaf_indices.iter_mut() { + *b_idx += self.leaf_count(); + } + a_leaf_indices.append(&mut b_leaf_indices); + println!("left first {:?}", a_leaf_indices); + a_leaf_indices + } + false => { + // for swap happen, for the merkletree index is still [a_merkle_tree_indices,b_merkle_tree_indices] + // the acctually taptree indices is [b_taptree_indices,a_taptree_indices] + for a_idx in a_leaf_indices.iter_mut() { + *a_idx += other.leaf_count(); + } + a_leaf_indices.append(&mut b_leaf_indices); + + println!("right first {:?}", a_leaf_indices); + a_leaf_indices + } + }; + + Self { + root_node: combined_tree, + leaf_count: taptree_indices.len(), + leaf_indices: taptree_indices, + } + } + + fn get_indices(&self) -> &Vec { + &self.leaf_indices + } + + fn leaf_count(&self) -> usize { + self.leaf_count + } + + fn get_root(&self) -> &NodeInfo { + &self.root_node + } + + fn get_leaf_proof(&self, index: usize) -> (LeafNode, TaprootMerkleBranch) { + let leaf = self.get_tapleaf(index).unwrap(); + let path = self.get_leaf_merkle_path(index).unwrap(); + (leaf.clone(), path.clone()) + } +} + +#[cfg(test)] +mod tests { + + + use bitcoin::ScriptBuf; + use bitcoin_script::{define_pushable, script}; + + use super::{CompleteTaptree, TaptreeConcater}; + define_pushable!(); + + #[test] + fn test_build_tree() { + let nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15u32]; + // let nums = vec![0,1,2,3,4,5,6,7,8,10,11,12,13,14,15u32]; + // let nums = vec![1u32]; + let scripts = nums + .iter() + .map(|index| { + script! { + {*index} + OP_ADD + + } + }) + .collect::>(); + + let a_tree = CompleteTaptree::new_with_scripts(scripts); + + assert_eq!(a_tree.leaf_count(), 16); + + let ap = a_tree.get_tapleaf(0).unwrap(); + assert_eq!( + ap.leaf().as_script().unwrap().0.as_bytes(), + script! { {0} OP_ADD}.as_bytes() + ); + + let ap = a_tree.get_tapleaf(6).unwrap(); + assert_eq!( + ap.leaf().as_script().unwrap().0.as_bytes(), + script! { {6} OP_ADD}.as_bytes() + ); + + let indices = a_tree.get_indices(); + println!("{:?}", indices); + // let ap = a_tree.get_tapleaf(8).unwrap(); + // println!("ap {:?}",ap); + + for (query_index, value) in nums.iter().enumerate() { + println!("query_index {:?}, value: {:?}", query_index, value); + let ap = a_tree.get_tapleaf(query_index).unwrap(); + assert!(a_tree.verify_inclusion_by_index(query_index)); + assert_eq!( + ap.leaf().as_script().unwrap().0.as_bytes(), + script! { {*value} OP_ADD}.as_bytes() + ); + } + } + + #[test] + fn test_combine_tree() { + let nums = [0, 1, 2, 3, 4, 5, 6, 7u32]; + let scripts = nums + .iter() + .map(|index| { + script! { + {*index} + OP_ADD + + } + }) + .collect::>(); + + let a_tree = CompleteTaptree::new_with_scripts(scripts); + + for (query_index, value) in nums.iter().enumerate() { + let ap = a_tree.get_tapleaf(query_index).unwrap(); + assert_eq!( + ap.leaf().as_script().unwrap().0.as_bytes(), + script! { {*value} OP_ADD}.as_bytes() + ); + } + + let b_nums = [8, 9, 10, 11, 12, 13, 14, 15u32]; + let b_scripts = b_nums + .iter() + .map(|index| { + script! { + {*index} + OP_ADD + + } + }) + .collect::>(); + let b_tree = CompleteTaptree::new_with_scripts(b_scripts); + for (query_index, value) in b_nums.iter().enumerate() { + let ap = b_tree.get_tapleaf(query_index).unwrap(); + assert_eq!( + ap.leaf().as_script().unwrap().0.as_bytes(), + script! { {*value} OP_ADD}.as_bytes() + ); + } + + // combine tree with right-first + let c_tree = a_tree.clone().combine(b_tree.clone()); + println!("a_tree: {:?}", a_tree.leaf_indices); + println!("b_tree: {:?}", b_tree.leaf_indices); + println!("c_tree: {:?}", c_tree.leaf_indices); + let expect_nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15u32]; + for (query_index, value) in expect_nums.iter().enumerate() { + println!("query_index {:?}, value: {:?}", query_index, value); + let ap = c_tree.get_tapleaf(query_index).unwrap(); + println!("{:?}", ap.leaf().as_script().unwrap()); + assert!(c_tree.verify_inclusion_by_index(query_index)); + assert_eq!( + ap.leaf().as_script().unwrap().0.as_bytes(), + script! { {*value} OP_ADD}.as_bytes() + ); + } + + // combine tree with left-first + let c_tree = b_tree.clone().combine(a_tree.clone()); + + println!("a_tree: {:?}", a_tree.leaf_indices); + println!("b_tree: {:?}", b_tree.leaf_indices); + println!("c_tree: {:?}", c_tree.leaf_indices); + let expect_nums = [8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7u32]; + for (query_index, value) in expect_nums.iter().enumerate() { + println!("query_index {:?}, value: {:?}", query_index, value); + let ap = c_tree.get_tapleaf(query_index).unwrap(); + println!("{:?}", ap.leaf().as_script().unwrap()); + assert!(c_tree.verify_inclusion_by_index(query_index)); + assert_eq!( + ap.leaf().as_script().unwrap().0.as_bytes(), + script! { {*value} OP_ADD}.as_bytes() + ); + } + } + + #[test] + fn test_combine_with_different_depth() { + let nums = [0, 1, 2, 3, 4, 5, 6, 7u32]; + let scripts = nums + .iter() + .map(|index| { + script! { + {*index} + OP_ADD + + } + }) + .collect::>(); + + let a_tree = CompleteTaptree::new_with_scripts(scripts); + + for (query_index, value) in nums.iter().enumerate() { + let ap = a_tree.get_tapleaf(query_index).unwrap(); + assert_eq!( + ap.leaf().as_script().unwrap().0.as_bytes(), + script! { {*value} OP_ADD}.as_bytes() + ); + } + + let b_nums = [8, 9, 10, 11u32]; + let b_scripts = b_nums + .iter() + .map(|index| { + script! { + {*index} + OP_ADD + + } + }) + .collect::>(); + let b_tree = CompleteTaptree::new_with_scripts(b_scripts); + for (query_index, value) in b_nums.iter().enumerate() { + let ap = b_tree.get_tapleaf(query_index).unwrap(); + assert_eq!( + ap.leaf().as_script().unwrap().0.as_bytes(), + script! { {*value} OP_ADD}.as_bytes() + ); + } + + // combine tree with right-first + let c_tree = a_tree.clone().combine(b_tree.clone()); + println!("a_tree: {:?}", a_tree.leaf_indices); + println!("b_tree: {:?}", b_tree.leaf_indices); + println!("c_tree: {:?}", c_tree.leaf_indices); + let expect_nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11u32]; + for (query_index, value) in expect_nums.iter().enumerate() { + println!("query_index {:?}, value: {:?}", query_index, value); + let ap = c_tree.get_tapleaf(query_index).unwrap(); + println!("{:?}", ap.leaf().as_script().unwrap()); + assert!(c_tree.verify_inclusion_by_index(query_index)); + assert_eq!( + ap.leaf().as_script().unwrap().0.as_bytes(), + script! { {*value} OP_ADD}.as_bytes() + ); + } + + // combine tree with left-first + let c_tree = b_tree.clone().combine(a_tree.clone()); + + println!("a_tree: {:?}", a_tree.leaf_indices); + println!("b_tree: {:?}", b_tree.leaf_indices); + println!("c_tree: {:?}", c_tree.leaf_indices); + let expect_nums = [8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7u32]; + for (query_index, value) in expect_nums.iter().enumerate() { + println!("query_index {:?}, value: {:?}", query_index, value); + let ap = c_tree.get_tapleaf(query_index).unwrap(); + println!("{:?}", ap.leaf().as_script().unwrap()); + assert!(c_tree.verify_inclusion_by_index(query_index)); + assert_eq!( + ap.leaf().as_script().unwrap().0.as_bytes(), + script! { {*value} OP_ADD}.as_bytes() + ); + } + } +} diff --git a/basic/src/tcs/error.rs b/basic/src/tcs/error.rs new file mode 100644 index 0000000..c6eb505 --- /dev/null +++ b/basic/src/tcs/error.rs @@ -0,0 +1,11 @@ +use bitcoin::taproot::TaprootBuilderError; +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum TCSError { + TaprootBuilderError(TaprootBuilderError), +} + +impl From for TCSError { + fn from(error: TaprootBuilderError) -> Self { + TCSError::TaprootBuilderError(error) + } +} diff --git a/basic/src/tcs/mod.rs b/basic/src/tcs/mod.rs new file mode 100644 index 0000000..f682a75 --- /dev/null +++ b/basic/src/tcs/mod.rs @@ -0,0 +1,718 @@ +// use std::str::pattern::SearchStep; + +use std::cmp::Reverse; +use std::marker::PhantomData; +use std::slice::Iter; +use std::sync::{Arc, Mutex}; + +use bitcoin::taproot::{LeafNode, NodeInfo, TaprootMerkleBranch}; +use bitcoin::{ScriptBuf, TapNodeHash}; +use bitcoin_script::{define_pushable, script}; +use bitcomm::{BcManagerIns, BcOperator, SecretGenIns, Winternitz}; +use complete_taptree::{verify_inclusion, CompleteTaptree}; +use error::TCSError; +use itertools::Itertools; +use p3_matrix::dense::RowMajorMatrix; +use p3_matrix::Matrix; +use p3_util::log2_ceil_usize; +use primitives::{ + BCManager, BCommitOperator, BCommitWithSecret, CommitType, CompressType, SecretGen, +}; +use scripts::execute_script_with_inputs; +use serde::{Deserialize, Serialize}; + +use crate::field::BfField; +define_pushable!(); + +pub mod builder; +pub mod complete_taptree; +pub mod error; + +pub type SG = SecretGenIns; +pub type B = Winternitz; +pub type BO = BcOperator; +pub type BM = BcManagerIns; +pub type DefaultSyncBcManager = SyncBcManager; + +#[derive(Clone)] +pub struct SyncBcManager< + BM: BCManager, + SG: SecretGen, + BC: BCommitOperator, + B: BCommitWithSecret, +> { + bc_manager: Arc>>, + _marker: PhantomData<(SG, BC, B)>, +} + +impl, SG: SecretGen, BC: BCommitOperator, B: BCommitWithSecret> Default for SyncBcManager { + fn default() -> Self { + Self::new() + } +} + +impl, SG: SecretGen, BC: BCommitOperator, B: BCommitWithSecret> + SyncBcManager +{ + fn assign_bc(&self, ct: CommitType) -> BC { + self.bc_manager.lock().unwrap().assign_bc(ct) + } + + pub fn new() -> Self { + Self { + bc_manager: Arc::new(Mutex::new(Box::new(BM::new(SG::new())))), + _marker: PhantomData, + } + } +} + +#[derive(Clone)] +pub struct TCS< + BM: BCManager, + SG: SecretGen, + BC: BCommitOperator, + B: BCommitWithSecret, +> { + bc_manager: SyncBcManager, + _marker: PhantomData<(SG, BC, B)>, +} + +#[derive(Clone)] +pub struct CommitedData, B: BCommitWithSecret> { + pub(crate) leaves: Vec>, + pub(crate) commit_leaves: Vec>, + pub(crate) commit_taptree: CompleteTaptree, + pub(crate) use_bcs: UseBComm, +} + +impl, B: BCommitWithSecret> CommitedData { + pub(crate) fn get_max_height(&self) -> usize { + let mut max_height = 0; + for matrix in &self.leaves { + max_height = max_height.max(matrix.height()); + } + max_height + } +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(bound = "")] +pub struct CommitedProof, B: BCommitWithSecret> { + leaf: LeafNode, + use_bcs: UseBComm, + query_index: usize, +} + +type CommitProofAlias = (LeafNode, UseBComm, usize); + +impl, B: BCommitWithSecret> From> + for CommitedProof +{ + fn from(alias: CommitProofAlias) -> Self { + CommitedProof { + leaf: alias.0, + use_bcs: alias.1, + query_index: alias.2, + } + } +} + +impl, B: BCommitWithSecret> CommitedProof { + fn to_commited_leaf(self, evaluations: Vec) -> CommitedLeaf { + CommitedLeaf { + index: self.query_index, + evaluations, + use_bcs: self.use_bcs, + _marker: PhantomData, + } + } +} + +impl, B: BCommitWithSecret> CommitedData { + fn query_proof(&self, query_index: usize) -> CommitedProof { + let tapleaf = self.commit_taptree.get_tapleaf(query_index).unwrap(); + (tapleaf.clone(), self.use_bcs.clone(), query_index).into() + } +} + +pub fn verify_proof(root: TapNodeHash, leaf: &LeafNode, witness: Vec>) -> bool { + let inclusion = verify_inclusion(root, leaf); + let success = execute_script_with_inputs(leaf.script().unwrap().into(), witness).success; + inclusion && success +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(bound = "")] +pub struct CommitedLeaf, B: BCommitWithSecret> { + use_bcs: UseBComm, + index: usize, + evaluations: Vec, + _marker: PhantomData, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(bound = "")] +pub struct UseBComm, B: BCommitWithSecret> { + index_bc: BC, + evaluations_bc: Vec, + _marker: PhantomData, +} + +impl, B: BCommitWithSecret> CommitedLeaf { + fn new_with_bcs(bcs: UseBComm, index: usize, evaluations: Vec) -> Self { + Self { + use_bcs: bcs, + index, + evaluations, + _marker: PhantomData, + } + } + + fn generate_witness(&mut self) -> Vec> { + self.set_commited_value(); + let mut witness = vec![]; + self.use_bcs.evaluations_bc.iter().rev().for_each(|bc| { + witness.append(&mut bc.witness()); + }); + + witness.append(&mut self.use_bcs.index_bc.witness()); + witness + } + + fn set_commited_value(&mut self) { + self.use_bcs + .index_bc + .set_commit_value((self.index as u32).into()); + self.use_bcs + .evaluations_bc + .iter_mut() + .enumerate() + .for_each(|(index, bc)| { + bc.set_commit_value(self.evaluations[index].as_u32_vec().into()); + }); + } + + fn generate_script(&mut self) -> ScriptBuf { + self.set_commited_value(); + let mut exec_scripts = script! { + {self.use_bcs.index_bc.locking_script_with_type(CompressType::U32).compile() } + {self.index} + OP_EQUALVERIFY + }; + + self.use_bcs + .evaluations_bc + .iter() + .enumerate() + .for_each(|(index, bc)| { + let values = self.evaluations[index].as_u32_vec(); + exec_scripts = script! { + {exec_scripts.clone()} + { bc.locking_script_with_type(CompressType::U32).compile() } + for i in (0..values.len()).rev() { + {values[i]} + OP_EQUALVERIFY + } + }; + }); + + script! { + {exec_scripts} + OP_1 + } + } +} + +impl, SG: SecretGen, BC: BCommitOperator, B: BCommitWithSecret> + PolyTCS for TCS +{ + fn new(manager: SyncBcManager) -> Self { + Self { + bc_manager: manager, + _marker: PhantomData, + } + } + + + fn commit_polys(&self, leaves: Vec>) -> CommitedData { + let commit_type = match F::U32_SIZE { + 1 => CommitType::U32, + 4 => CommitType::U128, + _ => { + panic!("only support 1 or 4"); + } + }; + + let leaf_ys = self.padding_matrix(leaves.iter()); + + let first_width = leaf_ys[0].len(); + let max_height = leaf_ys.len(); + // assign bc here + let index_bc = self.bc_manager.assign_bc(CommitType::U32); + let evaluations_bc: Vec = (0..first_width) + .map(|_index| self.bc_manager.assign_bc(commit_type.clone())) + .collect(); + let use_bcs = UseBComm { + index_bc, + evaluations_bc, + _marker: PhantomData, + }; + let mut leaves_script = vec![]; + let mut commited_leaves = vec![]; + + for index in 0..max_height { + if !leaf_ys[index].is_empty() { + //println!("index:{:?}, ys:{:?}", index, leaf_ys[index]); + let mut to_commit_leaf = + CommitedLeaf::new_with_bcs(use_bcs.clone(), index, leaf_ys[index].clone()); + leaves_script.push(to_commit_leaf.generate_script()); + commited_leaves.push(to_commit_leaf); + } + } + + // generate commit taptree + let commit_tree = CompleteTaptree::new_with_scripts(leaves_script); + CommitedData { + leaves, + commit_leaves: commited_leaves, + commit_taptree: commit_tree, + use_bcs, + } + } + + fn commit_poly_with_query_times( + &self, + polys: Vec>, + total_query_times: usize, + ) -> Vec> { + (0..total_query_times) + .map(|_| self.commit_polys(polys.clone())) + .collect() + } + + fn open( + &self, + index: usize, + prover_data: &CommitedData, + ) -> (CommitedProof, Vec) { + let leaves_evals = self.padding_matrix(prover_data.leaves.iter()); + (prover_data.query_proof(index), leaves_evals[index].clone()) + } + + fn open_with_query_times( + &self, + indices: Vec, + prover_datas: &Vec>, + query_times: usize, + ) -> (Vec>, Vec>) { + assert_eq!(indices.len(), query_times); + assert_eq!(prover_datas.len(), query_times); + + let proofs = (0..query_times) + .zip(indices.clone()) + .map(|(query_times_index, query_index)| { + prover_datas[query_times_index].query_proof(query_index) + }) + .collect(); + + let leaves_evals = self.padding_matrix(prover_datas[0].leaves.iter()); + let opening_values: Vec> = indices + .iter() + .map(|query_index| leaves_evals[*query_index].clone()) + .collect(); + + (proofs, opening_values) + } +} + +// polynomial Taptree Commitment Scheme +pub trait PolyTCS< + BM: BCManager, + SG: SecretGen, + BC: BCommitOperator, + B: BCommitWithSecret, +> +{ + fn new(manager: SyncBcManager) -> Self; + + fn padding_matrix( + &self, + leaves: Iter<'_, p3_matrix::dense::DenseMatrix>, + ) -> Vec> { + //evaluations sorted by height + let mut leaves_largest_first = leaves.sorted_by_key(|l| Reverse(l.height())).peekable(); + let max_height = leaves_largest_first.peek().unwrap().height(); + let log_max_height = log2_ceil_usize(max_height); + //println!("max height:{:?}", max_height); + let mut leaf_ys = vec![vec![]; max_height]; + + for log_height in (0..log_max_height + 1).rev() { + let matrices = leaves_largest_first + .peeking_take_while(|m| log2_ceil_usize(m.height()) == log_height) + .collect_vec(); + if !matrices.is_empty() { + let curr_height = matrices[0].height(); + for matrix in matrices.iter() { + let width = matrix.width(); + for index in 0..curr_height { + //find which leaf to store + let curr_index = index << (log_max_height - log_height); + let next_index = (index + 1) << (log_max_height - log_height); + for i in 0..width { + for leaf_index in curr_index..next_index { + leaf_ys[leaf_index].push(matrix.values[index * matrix.width() + i]); + } + } + } + } + } + } + + // check the leaf_ys has the same width + let frist_width = leaf_ys[0].len(); + leaf_ys.iter().for_each(|ys| { + assert_eq!(frist_width, ys.len()); + }); + leaf_ys + } + // only use for prover + // different leaf use the same bit-comm set within the Polynomial-Commitment-Scheme-Taptree + // index use a unique bit-comm to simulate the open-index + // each evalutaion corresponding to each unique bitcomm within one leaf + // the sequences of bcs: vec, vec + // return the pair (polynomial index, query_times index) which uses to as the key of the polynomial taptree + fn commit_polys(&self, poly: Vec>) -> CommitedData; + + // only use for prover + // different leaf use the same bit-comm set within the Polynomial-Commitment-Scheme-Taptree + // index use a unique bit-comm to simulate the open-index + // each evalutaion corresponding to each unique bitcomm within one leaf + // the sequences of bcs: index-bitcomm, eval1-bitcomm, eval2-bitcomm ... + // return the polynomial index which uses to as the key of the polynomial taptree + fn commit_poly_with_query_times( + &self, + polys: Vec>, + total_query_times: usize, + ) -> Vec>; + + fn open( + &self, + query_index: usize, + prover_data: &CommitedData, + ) -> (CommitedProof, Vec); + + fn open_with_one_query( + &self, + query_times_index: usize, + query_index: usize, + prover_data: &Vec>, + query_times: usize, + ) -> (CommitedProof, Vec) { + assert_eq!(prover_data.len(), query_times); + self.open(query_index, &prover_data[query_times_index]) + } + + fn open_with_query_times( + &self, + indices: Vec, + prover_data: &Vec>, + query_times: usize, + ) -> (Vec>, Vec>); + + fn verify( + &self, + root: TapNodeHash, + proof: &CommitedProof, + opening_values: Vec, + ) -> bool { + // genreate the witness by constrcting the CommitedLeaf + let mut commited_leaf = proof.clone().to_commited_leaf(opening_values); + + verify_proof(root, &proof.leaf, commited_leaf.generate_witness()) + } + + fn verify_with_query_times( + &self, + root: Vec, + proofs: &Vec>, + opening_values: Vec>, + query_times: usize, + ) -> bool { + let mut success = true; + for query_times_index in 0..query_times { + if !success { + return false; + } + success = self.verify( + root[query_times_index], + &proofs[query_times_index], + opening_values[query_times_index].clone(), + ); + } + success + } + // each poly only support one query + // return the taptree_root,the tapleaf which should be opened, the merklepath for the opening tapleaf, and the bcs set +} + +trait TaptreeConcater { + fn new_with_scripts(scripts: Vec) -> Self; + + fn combine_other_script(&mut self, slash_scripts: Vec) -> Self; + + fn combine(&self, other: impl TaptreeConcater) -> Self; + + fn get_indices(&self) -> &Vec; + + fn leaf_count(&self) -> usize; + + fn get_root(&self) -> &NodeInfo; + + // + fn get_leaf_proof(&self, index: usize) -> (LeafNode, TaprootMerkleBranch); +} + +trait FinalTaptree { + fn to_taproot(&self) -> TapNodeHash; +} + +pub fn combine_two_nodes(a: NodeInfo, b: NodeInfo) -> Result<(NodeInfo, bool), TCSError> { + let parent = NodeInfo::combine_with_order(a, b)?; + Ok(parent) +} + +trait ScriptToEmbbed { + fn prefix_concat(&self) -> ScriptBuf { + ScriptBuf::new() + } + + fn suffix_concat(&self) -> ScriptBuf { + ScriptBuf::new() + } + + fn origin_script(&self) -> ScriptBuf; + + fn compelte_script(&self) -> ScriptBuf { + script! { + {self.prefix_concat()} + {self.origin_script()} + {self.suffix_concat()} + } + } +} + +impl ScriptToEmbbed for ScriptBuf { + fn origin_script(&self) -> ScriptBuf { + self.clone() + } +} + +#[cfg(test)] +mod tests { + use p3_baby_bear::BabyBear; + use p3_field::AbstractField; + use p3_matrix::dense::RowMajorMatrix; + + use super::*; + type F = BabyBear; + + #[test] + fn test_taptree_mmcs() { + // mat_1 = [ + // 0 1 + // 2 1 + // 2 2 + // 1 0 + // ] + let mat_1 = RowMajorMatrix::new( + vec![ + F::zero(), + F::one(), + F::two(), + F::one(), + F::two(), + F::two(), + F::one(), + F::zero(), + ], + 2, + ); + + // mat_2 = [ + // 0 1 2 1 + // 2 2 1 0 + // 0 1 2 1 + // 2 2 1 0 + // ] + let mat_2 = RowMajorMatrix::new( + vec![ + F::zero(), + F::one(), + F::two(), + F::one(), + F::two(), + F::two(), + F::one(), + F::zero(), + F::zero(), + F::one(), + F::two(), + F::one(), + F::two(), + F::two(), + F::one(), + F::zero(), + ], + 4, + ); + + // mat_3 = [ + // 0 + // 1 + // 2 + // 1 + // 2 + // 2 + // 1 + // 0 + // ] + let mat_3 = RowMajorMatrix::new( + vec![ + F::zero(), + F::one(), + F::two(), + F::one(), + F::two(), + F::two(), + F::one(), + F::zero(), + ], + 1, + ); + + // we get pointleafs like: + // index:0, ys:[0, 0, 1, 0, 1, 2, 1] + // index:1, ys:[1, 0, 1, 0, 1, 2, 1] + // index:2, ys:[2, 2, 1, 2, 2, 1, 0] + // index:3, ys:[1, 2, 1, 2, 2, 1, 0] + // index:4, ys:[2, 2, 2, 0, 1, 2, 1] + // index:5, ys:[2, 2, 2, 0, 1, 2, 1] + // index:6, ys:[1, 1, 0, 2, 2, 1, 0] + // index:7, ys:[0, 1, 0, 2, 2, 1, 0] + + let manager = DefaultSyncBcManager::new(); + let inputs = vec![mat_1, mat_2, mat_3]; + let tcs = TCS::new(manager); + let commit_data = tcs.commit_polys(inputs); + + (0..7).for_each(|index| { + let (proof, opening) = tcs.open(index, &commit_data); + assert!(tcs.verify(commit_data.commit_taptree.root().hash, &proof, opening)); + }) + } + + #[test] + fn test_taptree_mmcs_with_multi_query() { + // mat_1 = [ + // 0 1 + // 2 1 + // 2 2 + // 1 0 + // ] + let mat_1 = RowMajorMatrix::new( + vec![ + F::zero(), + F::one(), + F::two(), + F::one(), + F::two(), + F::two(), + F::one(), + F::zero(), + ], + 2, + ); + + // mat_2 = [ + // 0 1 2 1 + // 2 2 1 0 + // 0 1 2 1 + // 2 2 1 0 + // ] + let mat_2 = RowMajorMatrix::new( + vec![ + F::zero(), + F::one(), + F::two(), + F::one(), + F::two(), + F::two(), + F::one(), + F::zero(), + F::zero(), + F::one(), + F::two(), + F::one(), + F::two(), + F::two(), + F::one(), + F::zero(), + ], + 4, + ); + + // mat_3 = [ + // 0 + // 1 + // 2 + // 1 + // 2 + // 2 + // 1 + // 0 + // ] + let mat_3 = RowMajorMatrix::new( + vec![ + F::zero(), + F::one(), + F::two(), + F::one(), + F::two(), + F::two(), + F::one(), + F::zero(), + ], + 1, + ); + + // we get pointleafs like: + // index:0, ys:[0, 0, 1, 0, 1, 2, 1] + // index:1, ys:[1, 0, 1, 0, 1, 2, 1] + // index:2, ys:[2, 2, 1, 2, 2, 1, 0] + // index:3, ys:[1, 2, 1, 2, 2, 1, 0] + // index:4, ys:[2, 2, 2, 0, 1, 2, 1] + // index:5, ys:[2, 2, 2, 0, 1, 2, 1] + // index:6, ys:[1, 1, 0, 2, 2, 1, 0] + // index:7, ys:[0, 1, 0, 2, 2, 1, 0] + + let manager = DefaultSyncBcManager::new(); + let inputs = vec![mat_1, mat_2, mat_3]; + let tcs = TCS::new(manager); + let query_times = 8; + let commit_data = tcs.commit_poly_with_query_times::(inputs, query_times); + + let roots: Vec = commit_data + .iter() + .map(|data| data.commit_taptree.root().hash) + .collect(); + + (0..7).for_each(|index| { + let (proof, opening) = tcs.open_with_query_times::( + vec![index; query_times], + &commit_data, + query_times, + ); + assert!(tcs.verify_with_query_times(roots.clone(), &proof, opening, query_times)); + }) + } +} diff --git a/common/Cargo.toml b/common/Cargo.toml new file mode 100644 index 0000000..a188bcb --- /dev/null +++ b/common/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "common" +version = "0.1.0" +edition = "2021" + +[dependencies] +p3-field = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-baby-bear = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } \ No newline at end of file diff --git a/common/src/lib.rs b/common/src/lib.rs new file mode 100644 index 0000000..baeb757 --- /dev/null +++ b/common/src/lib.rs @@ -0,0 +1,35 @@ +pub use p3_baby_bear::BabyBear; +pub use p3_field::extension::BinomialExtensionField; +pub use p3_field::{AbstractExtensionField, AbstractField, PrimeField32, TwoAdicField}; + +pub trait AsU32Vec { + fn bc_as_u32_vec(&self) -> Vec; + // fn u32_clone(&self) -> Self; +} + +impl AsU32Vec for u32 { + fn bc_as_u32_vec(&self) -> Vec { + vec![*self] + } +} + +impl AsU32Vec for BinomialExtensionField { + fn bc_as_u32_vec(&self) -> Vec { + self.as_base_slice() + .iter() + .map(|babybear: &BabyBear| babybear.as_canonical_u32()) + .collect() + } +} + +impl AsU32Vec for BabyBear { + fn bc_as_u32_vec(&self) -> Vec { + vec![self.as_canonical_u32()] + } +} + +impl AsU32Vec for Vec { + fn bc_as_u32_vec(&self) -> Vec { + self.clone() + } +} diff --git a/doc/TapSTARK.pdf b/doc/TapSTARK.pdf new file mode 100644 index 0000000..d99543c Binary files /dev/null and b/doc/TapSTARK.pdf differ diff --git a/fri/Cargo.toml b/fri/Cargo.toml index ab7aabf..2de772d 100644 --- a/fri/Cargo.toml +++ b/fri/Cargo.toml @@ -5,41 +5,40 @@ edition = "2021" license = "MIT OR Apache-2.0" [dependencies] -bitcoin-script = { git = "https://github.com/cyl19970726/rust-bitcoin-script", rev = "eda97c5" } -bitcoin = { git = "https://github.com/cyl19970726/rust-bitcoin", rev = "ffad6f3" } -bitcoin-scriptexec = { git = "https://github.com/cyl19970726/rust-bitcoin-scriptexec",rev = "09c601e" } +bitcoin-script = { git = "https://github.com/bitlayer-org/rust-bitcoin-script" } +bitcoin = { git = "https://github.com/bitlayer-org/rust-bitcoin", branch = "bitvm" } +bitcoin-scriptexec = { git = "https://github.com/bitlayer-org/rust-bitcoin-scriptexec", branch = "bitvm"} +bitcoin-script-stack = {git = "https://github.com/bitlayer-org/rust-bitcoin-script-stack.git", branch = "bitvm"} - -p3-challenger = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-dft = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-field = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-interpolation = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-matrix = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-maybe-rayon = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-util = { git = "https://github.com/Plonky3/Plonky3.git" } +p3-commit ={ git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a"} +p3-challenger = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-dft = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-field = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-interpolation = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-matrix = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-maybe-rayon = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-util = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } itertools = "0.12.0" tracing = "0.1.37" tracing-subscriber = { version = "0.3.17", features = ["std", "env-filter"] } serde = { version = "1.0", default-features = false, features = ["derive", "alloc"] } - +script_expr ={ path = "../script_expr" } rand = "0.8.5" - - scripts = { path = "../scripts"} -primitives = {path = "../primitives"} -p3-baby-bear = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-symmetric = { git = "https://github.com/Plonky3/Plonky3.git" } +basic = {path = "../basic"} + +p3-baby-bear = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-symmetric = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } [dev-dependencies] -p3-baby-bear = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-dft = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-goldilocks = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-mersenne-31 = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-mds = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-merkle-tree = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-blake3 = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-keccak = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-interpolation = { git = "https://github.com/Plonky3/Plonky3.git" } +p3-baby-bear = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-goldilocks = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-mersenne-31 = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-mds = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-merkle-tree = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-blake3 = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-keccak = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } +p3-interpolation = { git = "https://github.com/Plonky3/Plonky3.git", rev = "72b2fc162738df459619488a98bb06eaf64e5b4a" } criterion = "0.5.1" rand = "0.8.5" rand_chacha = "0.3.1" diff --git a/fri/benches/fold_even_odd.rs b/fri/benches/fold_even_odd.rs index d17f4fd..e8ffd4f 100644 --- a/fri/benches/fold_even_odd.rs +++ b/fri/benches/fold_even_odd.rs @@ -1,7 +1,7 @@ use std::any::type_name; -use fri::fold_even_odd; use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; +use fri::fold_even_odd; use itertools::Itertools; use p3_baby_bear::BabyBear; use p3_field::extension::Complex; diff --git a/fri/src/config.rs b/fri/src/config.rs index d0ece0b..3ea0b33 100644 --- a/fri/src/config.rs +++ b/fri/src/config.rs @@ -1,3 +1,13 @@ +use alloc::vec::Vec; +use core::fmt::Debug; +use std::sync::MutexGuard; + +use basic::field::BfField; +use p3_field::Field; +use p3_matrix::Matrix; +use script_expr::{Dsl, InputManager}; + +#[derive(Debug)] pub struct FriConfig { pub log_blowup: usize, pub num_queries: usize, @@ -10,3 +20,42 @@ impl FriConfig { 1 << self.log_blowup } } + +/// Whereas `FriConfig` encompasses parameters the end user can set, `FriGenericConfig` is +/// set by the PCS calling FRI, and abstracts over implementation details of the PCS. +pub trait FriGenericConfig { + type InputProof; + type InputError: Debug; + + /// We can ask FRI to sample extra query bits (LSB) for our own purposes. + /// They will be passed to our callbacks, but ignored (shifted off) by FRI. + fn extra_query_index_bits(&self) -> usize; + + /// Fold a row, returning a single column. + /// Right now the input row will always be 2 columns wide, + /// but we may support higher folding arity in the future. + fn fold_row( + &self, + index: usize, + log_height: usize, + beta: F, + evals: impl Iterator, + ) -> F; + + /// Same as applying fold_row to every row, possibly faster. + fn fold_matrix>(&self, beta: F, m: M) -> Vec; +} + +pub trait FriGenericConfigWithExpr: FriGenericConfig { + fn fold_row_with_expr( + &self, + folded_eval: Dsl, + sibling_eval: Dsl, + x: Dsl, // x = x^2 ; neg_x = x * val::two_adic_generator(1); // xs[index%2] = x, xs[index%2+1] = neg_x + x_hint: F, + point_index: usize, + index_sibling: usize, + beta: Dsl, + manager: MutexGuard>, + ) -> Dsl; +} diff --git a/fri/src/error.rs b/fri/src/error.rs index d4d95a6..e5598f2 100644 --- a/fri/src/error.rs +++ b/fri/src/error.rs @@ -1,16 +1,4 @@ -use bitcoin::taproot::TaprootBuilderError; -#[derive(Debug, PartialEq, Eq, Clone)] -pub enum BfError { - TaprootBuilderError(TaprootBuilderError), - TaprootError, - TapLeafError, - TapTreeError, - EvaluationLeafError, - ExecuteScriptError, - InvalidMerkleProof, - IndexWithEmptyLeaf(u32, u32), -} - +use basic::mmcs::error::BfError; #[derive(Debug, PartialEq, Eq, Clone)] pub enum SVError { VerifyCalNegXScriptError, @@ -23,20 +11,15 @@ pub enum SVError { InvalidWitness, } -impl From for BfError { - fn from(error: TaprootBuilderError) -> Self { - BfError::TaprootBuilderError(error) - } -} - -impl From for FriError { +impl From for FriError { fn from(error: BfError) -> Self { - FriError::::BFError(error) + FriError::::BFError(error) } } #[derive(Debug, PartialEq, Eq, Clone)] -pub enum FriError { +pub enum FriError { + InputError(InputErr), InvalidProofShape, CommitPhaseMmcsError(CommitMmcsErr), ScriptVerifierError(SVError), diff --git a/fri/src/fold_even_odd.rs b/fri/src/fold_even_odd.rs index e776a96..0e0151c 100644 --- a/fri/src/fold_even_odd.rs +++ b/fri/src/fold_even_odd.rs @@ -54,15 +54,14 @@ pub fn fold_even_odd(poly: Vec, beta: F) -> Vec { #[cfg(test)] mod tests { - use crate::fri_scripts::verify_folding::fold_degree; - use scripts::{execute_script, ext_fold_degree1, BabyBear4}; - use primitives::field::BfField; + use itertools::izip; use p3_baby_bear::BabyBear; use p3_dft::{Radix2Dit, TwoAdicSubgroupDft}; - use p3_field::extension::BinomialExtensionField; - use p3_field::AbstractExtensionField; + + use rand::{thread_rng, Rng}; + use super::*; @@ -98,116 +97,4 @@ mod tests { assert_eq!(expected, folded); } - - #[test] - fn test_fold_even_odd_1() { - type F = BabyBear; - - let log_n = 4; - let n = 1 << log_n; - let coeffs = (0..n).map(|i: u32| F::from_u32(i)).collect::>(); - - let dft = Radix2Dit::default(); - let evals = dft.dft(coeffs.clone()); - - let even_coeffs = coeffs.iter().cloned().step_by(2).collect_vec(); - let even_evals = dft.dft(even_coeffs); - - let odd_coeffs = coeffs.iter().cloned().skip(1).step_by(2).collect_vec(); - let odd_evals = dft.dft(odd_coeffs); - - let beta = F::from_u32(2); - let expected = izip!(even_evals, odd_evals) - .map(|(even, odd)| even + beta * odd) - .collect::>(); - - print!("{:?}", expected); - print!("{:?}", evals); - // fold_even_odd takes and returns in bitrev order. - let mut folded = evals; - reverse_slice_index_bits(&mut folded); - folded = fold_even_odd(folded, beta); - reverse_slice_index_bits(&mut folded); - - assert_eq!(expected, folded); - } - - #[test] - fn test_fold_bitcoin_script() { - use p3_field::AbstractField; - type AF = BabyBear; - type F = BinomialExtensionField; - - let mut rng = thread_rng(); - let log_n = 4; - let n = 1 << log_n; - let coeffs = (0..n) - .map(|i: u32| F::from_base_fn(|_i| rng.gen::())) - .collect::>(); - - let dft = Radix2Dit::default(); - let evals = dft.dft(coeffs.clone()); - - let even_coeffs = coeffs.iter().cloned().step_by(2).collect_vec(); - let even_evals = dft.dft(even_coeffs); - - let odd_coeffs = coeffs.iter().cloned().skip(1).step_by(2).collect_vec(); - let odd_evals = dft.dft(odd_coeffs); - - let beta = F::from_base_slice(vec![AF::from_canonical_u32(2); 4].as_slice()); - let expected = izip!(even_evals, odd_evals) - .map(|(even, odd)| even + beta * odd) - .collect::>(); - - // println!("{:?}", evals); - // println!("------- folding -------"); - // println!("{:?}", expected); - - // fold_even_odd takes and returns in bitrev order. - let mut folded = evals.clone(); - reverse_slice_index_bits(&mut folded); - folded = fold_even_odd(folded, beta); - reverse_slice_index_bits(&mut folded); - - assert_eq!(expected, folded); - - for (_index, log_n) in vec![4].iter().enumerate() { - let n = 1 << log_n; - let y0 = evals.clone(); - let y1 = expected.clone(); - - let subgroup_generator = F::two_adic_generator(*log_n); - - for j in 0..n as usize { - let x_index = j; - let x_nge_index = (n / 2 + x_index) % n; - let x = subgroup_generator.exp_u64(x_index as u64); - let y0_x = y0[x_index]; - let y0_neg_x = y0[x_nge_index]; - let y_1_x_quare = y1[x_index % (n / 2)]; - - let with_input_script = fold_degree::( - x.as_u32_vec(), - y0_x.as_u32_vec(), - y0_neg_x.as_u32_vec(), - beta.as_u32_vec(), - y_1_x_quare.as_u32_vec(), - true, - ); - let result = execute_script(with_input_script); - assert!(result.success); - - let script = fold_degree::( - x.as_u32_vec(), - y0_x.as_u32_vec(), - y0_neg_x.as_u32_vec(), - beta.as_u32_vec(), - y_1_x_quare.as_u32_vec(), - false, - ); - let result = execute_script(script); - assert!(result.success); - } - } - } } diff --git a/fri/src/fri_scripts/fiat_shamir_subtree.rs b/fri/src/fri_scripts/fiat_shamir_subtree.rs deleted file mode 100644 index 6b75279..0000000 --- a/fri/src/fri_scripts/fiat_shamir_subtree.rs +++ /dev/null @@ -1,876 +0,0 @@ -use std::usize; - -use bitcoin::opcodes::{ - OP_2SWAP, OP_DROP, OP_ENDIF, OP_EQUALVERIFY, OP_FROMALTSTACK, OP_GREATERTHAN, - OP_GREATERTHANOREQUAL, OP_LESSTHAN, OP_LESSTHANOREQUAL, OP_PICK, OP_RESERVED2, OP_SUB, OP_SWAP, - OP_TOALTSTACK, -}; -use bitcoin::script::{self, scriptint_vec}; -use bitcoin::ScriptBuf as Script; -use bitcoin_script::{define_pushable, script}; -use itertools::Itertools; -use primitives::challenger::{BfChallenger, BitExtractor, Blake3Permutation}; -use primitives::challenger::chan_field::{PermutationField, U32}; -use p3_field::PrimeField32; - -use scripts::bit_comm_u32::*; -use primitives::bit_comm::BitCommitment; -use scripts::blake3; -use scripts::pseudo::{OP_4DROP, OP_4FROMALTSTACK, OP_4TOALTSTACK}; -use scripts::u32_rrot::{u32_rrot, u8_extract_hbit}; -use scripts::u32_std::{u32_compress, u32_equal, u32_equalverify, u32_push}; -use primitives::bit_comm::BCAssignment; -use primitives::field::BfField; -use scripts::BabyBearU31; - -/// fiat shamir subtree contains a series script leafs and coressponding -trait SubTree { - fn locking_leafs(&self) -> Vec