diff --git a/CHANGELOG.md b/CHANGELOG.md index a3338e212..f907d1940 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Added `miden_core::utils::sync::racy_lock` module (#1463). - Updated `miden_core::utils` to re-export `std::sync::LazyLock` and `racy_lock::RacyLock as LazyLock` for std and no_std environments, respectively (#1463). - Made the undocumented behavior of the VM with regard to undefined behavior of u32 operations, stricter (#1480) +- Offload the range checker auxiliary table to LogUp-GKR (#1493) - Introduced the `Emit` instruction (#1496) - Debug instructions can be enabled in the cli `run` command using `--debug` flag (#1502) - [BREAKING] ExecutionOptions::new constructor requires a boolean to explicitly set debug mode (#1502) diff --git a/Cargo.lock b/Cargo.lock index 2fb9a2eef..1c603deff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,18 +4,18 @@ version = 3 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aho-corasick" @@ -92,9 +92,9 @@ dependencies = [ [[package]] name = "arrayref" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" @@ -135,17 +135,17 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -243,9 +243,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.15" +version = "1.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" +checksum = "45bcde016d64c21da4be18b655631e5ab6d3107607e71a73a9f53eb48aae23fb" dependencies = [ "jobserver", "libc", @@ -287,9 +287,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.16" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" +checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" dependencies = [ "clap_builder", "clap_derive", @@ -297,9 +297,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" dependencies = [ "anstream", "anstyle", @@ -375,9 +375,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -556,9 +556,9 @@ dependencies = [ [[package]] name = "error-code" -version = "3.2.0" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b" +checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f" [[package]] name = "escargot" @@ -689,9 +689,9 @@ dependencies = [ [[package]] name = "generator" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "979f00864edc7516466d6b3157706e06c032f22715700ddd878228a91d02bc56" +checksum = "dbb949699c3e4df3a183b1d2142cb24277057055ed23c68ed58894f76c517223" dependencies = [ "cfg-if", "libc", @@ -723,9 +723,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" [[package]] name = "glob" @@ -775,9 +775,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown", @@ -1045,16 +1045,15 @@ dependencies = [ "num-traits", "parking_lot", "proptest", - "winter-math", + "winter-math 0.9.0 (git+https://github.com/facebook/winterfell?branch=logup-gkr)", "winter-rand-utils", - "winter-utils", + "winter-utils 0.9.1", ] [[package]] name = "miden-crypto" version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6fad06fc3af260ed3c4235821daa2132813d993f96d446856036ae97e9606dd" +source = "git+https://github.com/0xPolygonMiden/crypto?branch=al-update-degree-checks#d66b4a98b043e6b995052509f9d0cdbab95f48c6" dependencies = [ "blake3", "cc", @@ -1064,9 +1063,9 @@ dependencies = [ "rand", "rand_core", "sha3", - "winter-crypto", - "winter-math", - "winter-utils", + "winter-crypto 0.9.0 (git+https://github.com/facebook/winterfell?branch=logup-gkr)", + "winter-math 0.9.0 (git+https://github.com/facebook/winterfell?branch=logup-gkr)", + "winter-utils 0.9.1", ] [[package]] @@ -1086,7 +1085,7 @@ checksum = "ade33603aa2eaf78c6f06fd60f4dfe22b7ae1f5606698e386baf71eb9d246d50" dependencies = [ "metal", "once_cell", - "winter-math", + "winter-math 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1141,9 +1140,9 @@ dependencies = [ "miden-core", "miden-test-utils", "tracing", - "winter-fri", + "winter-fri 0.9.0 (git+https://github.com/facebook/winterfell?branch=logup-gkr)", "winter-prover", - "winter-utils", + "winter-utils 0.9.1", ] [[package]] @@ -1156,6 +1155,7 @@ dependencies = [ "miden-processor", "pollster", "tracing", + "winter-maybe-async", "winter-prover", ] @@ -1177,7 +1177,8 @@ dependencies = [ "sha2", "sha3", "winter-air", - "winter-fri", + "winter-crypto 0.9.0 (git+https://github.com/facebook/winterfell?branch=logup-gkr)", + "winter-fri 0.9.0 (git+https://github.com/facebook/winterfell?branch=logup-gkr)", ] [[package]] @@ -1254,16 +1255,16 @@ dependencies = [ "tracing", "tracing-forest", "tracing-subscriber", - "winter-fri", + "winter-fri 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] @@ -1405,9 +1406,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.3" +version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" dependencies = [ "memchr", ] @@ -1432,9 +1433,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "owo-colors" -version = "4.0.0" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3f" +checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" [[package]] name = "parking_lot" @@ -1498,9 +1499,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "plotters" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" dependencies = [ "num-traits", "plotters-backend", @@ -1511,15 +1512,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" [[package]] name = "plotters-svg" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" dependencies = [ "plotters-backend", ] @@ -1577,9 +1578,9 @@ dependencies = [ [[package]] name = "pretty_assertions" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" dependencies = [ "diff", "yansi", @@ -1690,9 +1691,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" dependencies = [ "bitflags 2.6.0", ] @@ -1705,7 +1706,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -1778,9 +1779,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.35" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags 2.6.0", "errno", @@ -1876,18 +1877,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", @@ -1896,9 +1897,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.127" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", "memchr", @@ -2011,9 +2012,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "supports-color" -version = "3.0.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9829b314621dfc575df4e409e79f9d6a66a3bd707ab73f23cb4aa3a854ac854f" +checksum = "8775305acf21c96926c900ad056abeef436701108518cf890020387236ac5a77" dependencies = [ "is_ci", ] @@ -2032,9 +2033,9 @@ checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" [[package]] name = "syn" -version = "2.0.76" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -2134,13 +2135,31 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.59" +source = "git+https://github.com/bitwalker/thiserror?branch=no-std#444c920234c683b73e1da67ba371a7084ae11725" +dependencies = [ + "thiserror-impl 1.0.59", +] + [[package]] name = "thiserror" version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.63", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.59" +source = "git+https://github.com/bitwalker/thiserror?branch=no-std#444c920234c683b73e1da67ba371a7084ae11725" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -2206,9 +2225,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.20" +version = "0.22.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf" dependencies = [ "indexmap", "serde", @@ -2257,7 +2276,7 @@ checksum = "ee40835db14ddd1e3ba414292272eddde9dad04d3d4b65509656414d1c42592f" dependencies = [ "ansi_term", "smallvec", - "thiserror", + "thiserror 1.0.63", "tracing", "tracing-subscriber", ] @@ -2320,9 +2339,9 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-linebreak" @@ -2332,9 +2351,9 @@ checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" @@ -2737,14 +2756,13 @@ dependencies = [ [[package]] name = "winter-air" version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b72f12b88ebb060b52c0e9aece9bb64a9fc38daf7ba689dd5ce63271b456c883" +source = "git+https://github.com/facebook/winterfell?branch=logup-gkr#8b95c8a10f05686db785e67ed0d3b467611e7066" dependencies = [ "libm", - "winter-crypto", - "winter-fri", - "winter-math", - "winter-utils", + "winter-crypto 0.9.0 (git+https://github.com/facebook/winterfell?branch=logup-gkr)", + "winter-fri 0.9.0 (git+https://github.com/facebook/winterfell?branch=logup-gkr)", + "winter-math 0.9.0 (git+https://github.com/facebook/winterfell?branch=logup-gkr)", + "winter-utils 0.9.1", ] [[package]] @@ -2755,8 +2773,19 @@ checksum = "00fbb724d2d9fbfd3aa16ea27f5e461d4fe1d74b0c9e0ed1bf79e9e2a955f4d5" dependencies = [ "blake3", "sha3", - "winter-math", - "winter-utils", + "winter-math 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winter-utils 0.9.2", +] + +[[package]] +name = "winter-crypto" +version = "0.9.0" +source = "git+https://github.com/facebook/winterfell?branch=logup-gkr#8b95c8a10f05686db785e67ed0d3b467611e7066" +dependencies = [ + "blake3", + "sha3", + "winter-math 0.9.0 (git+https://github.com/facebook/winterfell?branch=logup-gkr)", + "winter-utils 0.9.1", ] [[package]] @@ -2765,9 +2794,19 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ab6077cf4c23c0411f591f4ba29378e27f26acb8cef3c51cadd93daaf6080b3" dependencies = [ - "winter-crypto", - "winter-math", - "winter-utils", + "winter-crypto 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winter-math 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winter-utils 0.9.2", +] + +[[package]] +name = "winter-fri" +version = "0.9.0" +source = "git+https://github.com/facebook/winterfell?branch=logup-gkr#8b95c8a10f05686db785e67ed0d3b467611e7066" +dependencies = [ + "winter-crypto 0.9.0 (git+https://github.com/facebook/winterfell?branch=logup-gkr)", + "winter-math 0.9.0 (git+https://github.com/facebook/winterfell?branch=logup-gkr)", + "winter-utils 0.9.1", ] [[package]] @@ -2776,16 +2815,22 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "004f85bb051ce986ec0b9a2bd90aaf81b83e3c67464becfdf7db31f14c1019ba" dependencies = [ - "winter-utils", + "winter-utils 0.9.2", ] [[package]] -name = "winter-maybe-async" +name = "winter-math" version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ce0f4161cdde50de809b3869c1cb083a09e92e949428ea28f04c0d64045875c" +source = "git+https://github.com/facebook/winterfell?branch=logup-gkr#8b95c8a10f05686db785e67ed0d3b467611e7066" +dependencies = [ + "winter-utils 0.9.1", +] + +[[package]] +name = "winter-maybe-async" +version = "0.10.0" +source = "git+https://github.com/facebook/winterfell?branch=logup-gkr#8b95c8a10f05686db785e67ed0d3b467611e7066" dependencies = [ - "proc-macro2", "quote", "syn", ] @@ -2793,55 +2838,74 @@ dependencies = [ [[package]] name = "winter-prover" version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17e3dbae97050f58e01ed4f12906e247841575a0518632e052941a1c37468df" +source = "git+https://github.com/facebook/winterfell?branch=logup-gkr#8b95c8a10f05686db785e67ed0d3b467611e7066" dependencies = [ + "thiserror 1.0.59", "tracing", "winter-air", - "winter-crypto", - "winter-fri", - "winter-math", + "winter-crypto 0.9.0 (git+https://github.com/facebook/winterfell?branch=logup-gkr)", + "winter-fri 0.9.0 (git+https://github.com/facebook/winterfell?branch=logup-gkr)", + "winter-math 0.9.0 (git+https://github.com/facebook/winterfell?branch=logup-gkr)", "winter-maybe-async", - "winter-utils", + "winter-sumcheck", + "winter-utils 0.9.1", ] [[package]] name = "winter-rand-utils" version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b827c901ab0c316d89812858ff451d60855c0a5c7ae734b098c62a28624181" +source = "git+https://github.com/facebook/winterfell?branch=logup-gkr#8b95c8a10f05686db785e67ed0d3b467611e7066" dependencies = [ "rand", - "winter-utils", + "winter-utils 0.9.1", +] + +[[package]] +name = "winter-sumcheck" +version = "0.1.0" +source = "git+https://github.com/facebook/winterfell?branch=logup-gkr#8b95c8a10f05686db785e67ed0d3b467611e7066" +dependencies = [ + "smallvec", + "thiserror 1.0.59", + "winter-air", + "winter-crypto 0.9.0 (git+https://github.com/facebook/winterfell?branch=logup-gkr)", + "winter-math 0.9.0 (git+https://github.com/facebook/winterfell?branch=logup-gkr)", + "winter-utils 0.9.1", ] [[package]] name = "winter-utils" version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0568612a95bcae3c94fb14da2686f8279ca77723dbdf1e97cf3673798faf6485" +source = "git+https://github.com/facebook/winterfell?branch=logup-gkr#8b95c8a10f05686db785e67ed0d3b467611e7066" dependencies = [ "rayon", ] +[[package]] +name = "winter-utils" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d71ec2c97685c7e7460a30e27f955d26b8426e7c2db0ddb55a6e0537141f53" + [[package]] name = "winter-verifier" version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324002ade90f21e85599d51a232a80781efc8cb46f511f8bc89f9c5a4eb9cb65" +source = "git+https://github.com/facebook/winterfell?branch=logup-gkr#8b95c8a10f05686db785e67ed0d3b467611e7066" dependencies = [ + "thiserror 1.0.59", "winter-air", - "winter-crypto", - "winter-fri", - "winter-math", - "winter-utils", + "winter-crypto 0.9.0 (git+https://github.com/facebook/winterfell?branch=logup-gkr)", + "winter-fri 0.9.0 (git+https://github.com/facebook/winterfell?branch=logup-gkr)", + "winter-math 0.9.0 (git+https://github.com/facebook/winterfell?branch=logup-gkr)", + "winter-sumcheck", + "winter-utils 0.9.1", ] [[package]] name = "yansi" -version = "0.5.1" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "zerocopy" diff --git a/air/Cargo.toml b/air/Cargo.toml index 23c193713..29716d70d 100644 --- a/air/Cargo.toml +++ b/air/Cargo.toml @@ -33,10 +33,10 @@ testing = [] [dependencies] thiserror = { package = "miden-thiserror", version = "1.0", default-features = false } vm-core = { package = "miden-core", path = "../core", version = "0.10", default-features = false } -winter-air = { package = "winter-air", version = "0.9", default-features = false } -winter-prover = { package = "winter-prover", version = "0.9", default-features = false } +winter-air = { package = "winter-air", git = "https://github.com/facebook/winterfell", branch = "logup-gkr", default-features = false } +winter-prover = { package = "winter-prover", git = "https://github.com/facebook/winterfell", branch = "logup-gkr", default-features = false } [dev-dependencies] criterion = "0.5" proptest = "1.3" -rand-utils = { package = "winter-rand-utils", version = "0.9" } +rand-utils = { package = "winter-rand-utils", git = "https://github.com/facebook/winterfell", branch = "logup-gkr" } diff --git a/air/src/constraints/chiplets/mod.rs b/air/src/constraints/chiplets/mod.rs index ea950755f..8284fc8d8 100644 --- a/air/src/constraints/chiplets/mod.rs +++ b/air/src/constraints/chiplets/mod.rs @@ -183,19 +183,3 @@ impl EvaluationFrameExt for &EvaluationFrame { } } } - -// EXTERNAL ACCESSORS -// ================================================================================================ -/// Trait to allow other processors to easily access the chiplet values they need for constraint -/// calculations. -pub trait ChipletsFrameExt { - /// Flag to indicate whether the frame is in the memory chiplet. - fn chiplets_memory_flag(&self) -> E; -} - -impl ChipletsFrameExt for &EvaluationFrame { - #[inline(always)] - fn chiplets_memory_flag(&self) -> E { - self.memory_flag(true) - } -} diff --git a/air/src/constraints/mod.rs b/air/src/constraints/mod.rs index a376dc1fa..5d55b79a6 100644 --- a/air/src/constraints/mod.rs +++ b/air/src/constraints/mod.rs @@ -1,108 +1,3 @@ -use super::{EvaluationFrame, ExtensionOf, Felt, FieldElement}; -use crate::{ - trace::{ - chiplets::{MEMORY_D0_COL_IDX, MEMORY_D1_COL_IDX}, - decoder::{DECODER_OP_BITS_OFFSET, DECODER_USER_OP_HELPERS_OFFSET}, - }, - utils::binary_not, -}; - pub mod chiplets; pub mod range; pub mod stack; - -// ACCESSORS -// ================================================================================================ -/// Trait to allow other processors to easily access the column values they need for constraint -/// calculations. -pub trait MainFrameExt -where - F: FieldElement, - E: FieldElement + ExtensionOf, -{ - /// Returns true when a u32 stack operation that requires range checks is being performed. - fn u32_rc_op(&self) -> F; - - // --- Range check lookup accessors ----------------------------------------------------------- - - /// The value required for the first memory lookup when the memory chiplet requests range - /// checks. The value returned is the denominator used for including the value into the LogUp - /// lookup: (alpha - d0). The value d0 which is being range-checked is the lower 16-bits of the - /// delta value being tracked between two consecutive context IDs, addresses, or clock cycles in - /// the current row. - fn lookup_mv0(&self, alpha: E) -> E; - /// The value required for the second memory lookup when the memory chiplet requests range - /// checks. The value returned is the denominator used for including the value into the LogUp - /// lookup: (alpha - d1). The value d1 which is being range-checked is the upper 16-bits of the - /// delta value being tracked between two consecutive context IDs, addresses, or clock cycles in - /// the current row. - fn lookup_mv1(&self, alpha: E) -> E; - /// The value required for the first stack lookup when the stack requests range checks. The - /// value returned is the denominator used for including the value into the LogUp lookup: - /// (alpha - h0). The value h0 which is being range checked by the stack operation is stored in - /// the helper columns of the decoder section of the trace. - fn lookup_sv0(&self, alpha: E) -> E; - /// The value required for the second stack lookup when the stack requests range checks. The - /// value returned is the denominator used for including the value into the LogUp lookup: - /// (alpha - h1). The value h1 which is being range checked by the stack operation is stored in - /// the helper columns of the decoder section of the trace. - fn lookup_sv1(&self, alpha: E) -> E; - /// The value required for the third stack lookup when the stack requests range checks. The - /// value returned is the denominator used for including the value into the LogUp lookup: - /// (alpha - h2). The value h2 which is being range checked by the stack operation is stored in - /// the helper columns of the decoder section of the trace. - fn lookup_sv2(&self, alpha: E) -> E; - /// The value required for the fourth stack lookup when the stack requests range checks. The - /// value returned is the denominator used for including the value into the LogUp lookup: - /// (alpha - h3). The value h3 which is being range checked by the stack operation is stored in - /// the helper columns of the decoder section of the trace. - fn lookup_sv3(&self, alpha: E) -> E; -} - -impl MainFrameExt for EvaluationFrame -where - F: FieldElement, - E: FieldElement + ExtensionOf, -{ - /// Returns true when the stack operation is a u32 operation that requires range checks. - /// TODO: this is also defined in the op flags. It's redefined here to avoid computing all of - /// the op flags when this is the only one needed, but ideally this should only be defined once. - #[inline(always)] - fn u32_rc_op(&self) -> F { - let not_4 = binary_not(self.current()[DECODER_OP_BITS_OFFSET + 4]); - let not_5 = binary_not(self.current()[DECODER_OP_BITS_OFFSET + 5]); - self.current()[DECODER_OP_BITS_OFFSET + 6].mul(not_5).mul(not_4) - } - - // --- Intermediate values for LogUp lookups -------------------------------------------------- - - #[inline(always)] - fn lookup_mv0(&self, alpha: E) -> E { - alpha - self.current()[MEMORY_D0_COL_IDX].into() - } - - #[inline(always)] - fn lookup_mv1(&self, alpha: E) -> E { - alpha - self.current()[MEMORY_D1_COL_IDX].into() - } - - #[inline(always)] - fn lookup_sv0(&self, alpha: E) -> E { - alpha - self.current()[DECODER_USER_OP_HELPERS_OFFSET].into() - } - - #[inline(always)] - fn lookup_sv1(&self, alpha: E) -> E { - alpha - self.current()[DECODER_USER_OP_HELPERS_OFFSET + 1].into() - } - - #[inline(always)] - fn lookup_sv2(&self, alpha: E) -> E { - alpha - self.current()[DECODER_USER_OP_HELPERS_OFFSET + 2].into() - } - - #[inline(always)] - fn lookup_sv3(&self, alpha: E) -> E { - alpha - self.current()[DECODER_USER_OP_HELPERS_OFFSET + 3].into() - } -} diff --git a/air/src/constraints/range.rs b/air/src/constraints/range.rs index 76829acf7..2da74178c 100644 --- a/air/src/constraints/range.rs +++ b/air/src/constraints/range.rs @@ -1,13 +1,9 @@ use alloc::vec::Vec; -use vm_core::{ExtensionOf, ZERO}; +use vm_core::{Felt, ZERO}; use crate::{ - chiplets::ChipletsFrameExt, - constraints::MainFrameExt, - trace::range::{B_RANGE_COL_IDX, M_COL_IDX, V_COL_IDX}, - utils::are_equal, - Assertion, EvaluationFrame, Felt, FieldElement, TransitionConstraintDegree, + trace::range::V_COL_IDX, Assertion, EvaluationFrame, FieldElement, TransitionConstraintDegree, }; // CONSTANTS @@ -25,15 +21,6 @@ pub const CONSTRAINT_DEGREES: [usize; NUM_CONSTRAINTS] = [ 9, // Enforce values of column v transition. ]; -// --- Auxiliary column constraints for multiset checks ------------------------------------------- - -/// The number of auxiliary assertions for multiset checks. -pub const NUM_AUX_ASSERTIONS: usize = 2; -/// The number of transition constraints required by multiset checks for the Range Checker. -pub const NUM_AUX_CONSTRAINTS: usize = 1; -/// The degrees of the Range Checker's auxiliary column constraints, used for multiset checks. -pub const AUX_CONSTRAINT_DEGREES: [usize; NUM_AUX_CONSTRAINTS] = [9]; - // BOUNDARY CONSTRAINTS // ================================================================================================ @@ -50,19 +37,6 @@ pub fn get_assertions_last_step(result: &mut Vec>, step: usize) result.push(Assertion::single(V_COL_IDX, step, Felt::new(65535))); } -// --- AUXILIARY COLUMNS (FOR MULTISET CHECKS) ---------------------------------------------------- - -/// Returns the range checker's boundary assertions for auxiliary columns at the first step. -pub fn get_aux_assertions_first_step(result: &mut Vec>) { - let step = 0; - result.push(Assertion::single(B_RANGE_COL_IDX, step, E::ONE)); -} - -/// Returns the range checker's boundary assertions for auxiliary columns at the last step. -pub fn get_aux_assertions_last_step(result: &mut Vec>, step: usize) { - result.push(Assertion::single(B_RANGE_COL_IDX, step, E::ONE)); -} - // TRANSITION CONSTRAINTS // ================================================================================================ @@ -95,129 +69,12 @@ pub fn enforce_constraints(frame: &EvaluationFrame, result: * (frame.change(V_COL_IDX) - E::from(2187_u16)); } -// --- AUXILIARY COLUMNS (FOR MULTISET CHECKS) ---------------------------------------------------- - -/// Returns the transition constraint degrees for the range checker's auxiliary columns, used for -/// multiset checks. -pub fn get_aux_transition_constraint_degrees() -> Vec { - AUX_CONSTRAINT_DEGREES - .iter() - .map(|°ree| TransitionConstraintDegree::new(degree)) - .collect() -} - -/// Enforces constraints on the range checker's auxiliary columns. -pub fn enforce_aux_constraints( - main_frame: &EvaluationFrame, - aux_frame: &EvaluationFrame, - aux_rand_elements: &[E], - result: &mut [E], -) where - F: FieldElement, - E: FieldElement + ExtensionOf, -{ - // Get the first random element for this segment. - let alpha = aux_rand_elements[0]; - - // Enforce b_range. - enforce_b_range(main_frame, aux_frame, alpha, result); -} - -// TRANSITION CONSTRAINT HELPERS -// ================================================================================================ - -// --- AUXILIARY COLUMNS (FOR MULTISET CHECKS) ---------------------------------------------------- - -/// Ensures that the range checker bus is computed correctly. It enforces an implementation of the -/// LogUp lookup as a running sum "bus" column. All values in the range checker trace are saved -/// with their lookup multiplicity and the logarithmic derivatives are added to b_range. Values -/// for which lookups are requested from the stack and memory are each looked up with multiplicity -/// one, and the logarithmic derivatives are subtracted from b_range. -/// -/// Define the following variables: -/// - rc_value: the range checker value -/// - rc_multiplicity: the range checker multiplicity value -/// - flag_s: boolean flag indicating a stack operation with range checks. This flag is degree 3. -/// - sv0-sv3: stack value 0-3, the 4 values range-checked from the stack -/// - flag_m: boolean flag indicating the memory chiplet is active (i.e. range checks are required). -/// This flag is degree 3. -/// - mv0-mv1: memory value 0-1, the 2 values range-checked from the memory chiplet -/// -/// The constraint expression looks as follows: -/// b' = b + rc_multiplicity / (alpha - rc_value) -/// - flag_s / (alpha - sv0) - flag_s / (alpha - sv1) -/// - flag_s / (alpha - sv2) - flag_s / (alpha - sv3) -/// - flag_m / (alpha - mv0) - flag_m / (alpha - mv1) -/// -/// However, to enforce the constraint, all denominators are multiplied so that no divisions are -/// included in the actual constraint expression. -/// -/// Constraint degree: 9 -fn enforce_b_range( - main_frame: &EvaluationFrame, - aux_frame: &EvaluationFrame, - alpha: E, - result: &mut [E], -) where - F: FieldElement, - E: FieldElement + ExtensionOf, -{ - // The denominator values for the LogUp lookup. - let mv0: E = main_frame.lookup_mv0(alpha); - let mv1: E = main_frame.lookup_mv1(alpha); - let sv0: E = main_frame.lookup_sv0(alpha); - let sv1: E = main_frame.lookup_sv1(alpha); - let sv2: E = main_frame.lookup_sv2(alpha); - let sv3: E = main_frame.lookup_sv3(alpha); - let range_check: E = alpha - main_frame.v().into(); - let memory_lookups: E = mv0.mul(mv1); // degree 2 - let stack_lookups: E = sv0.mul(sv1).mul(sv2).mul(sv3); // degree 4 - let lookups = range_check.mul(stack_lookups).mul(memory_lookups); // degree 7 - - // An intermediate value required by all stack terms that includes the flag indicating a stack - // operation with range checks. This value has degree 6. - let sflag_rc_mem: E = range_check - .mul(memory_lookups) - .mul_base( as MainFrameExt>::u32_rc_op(main_frame)); - // An intermediate value required by all memory terms that includes the flag indicating the - // memory portion of the chiplets trace. This value has degree 8. - let mflag_rc_stack: E = - range_check.mul(stack_lookups).mul_base(main_frame.chiplets_memory_flag()); - - // The terms for the LogUp check after all denominators have been multiplied in. - let b_next_term = aux_frame.b_range_next().mul(lookups); // degree 8 - let b_term = aux_frame.b_range().mul(lookups); // degree 8 - let rc_term = stack_lookups.mul(memory_lookups).mul_base(main_frame.multiplicity()); // degree 7 - let s0_term = sflag_rc_mem.mul(sv1).mul(sv2).mul(sv3); // degree 9 - let s1_term = sflag_rc_mem.mul(sv0).mul(sv2).mul(sv3); // degree 9 - let s2_term = sflag_rc_mem.mul(sv0).mul(sv1).mul(sv3); // degree 9 - let s3_term = sflag_rc_mem.mul(sv0).mul(sv1).mul(sv2); // degree 9 - let m0_term = mflag_rc_stack.mul(mv1); // degree 9 - let m1_term = mflag_rc_stack.mul(mv0); // degree 9 - - result[0] = are_equal( - b_next_term, - b_term + rc_term - s0_term - s1_term - s2_term - s3_term - m0_term - m1_term, - ); -} - // RANGE CHECKER FRAME EXTENSION TRAIT // ================================================================================================ /// Trait to allow easy access to column values and intermediate variables used in constraint /// calculations for the Range Checker. trait EvaluationFrameExt { - // --- Column accessors ----------------------------------------------------------------------- - - /// The current value in the lookup multiplicity column. - fn multiplicity(&self) -> E; - /// The current value in column V. - fn v(&self) -> E; - /// The current value in auxiliary column b_range. - fn b_range(&self) -> E; - /// The next value in auxiliary column b_range. - fn b_range_next(&self) -> E; - // --- Intermediate variables & helpers ------------------------------------------------------- /// The change between the current value in the specified column and the next value, calculated @@ -226,28 +83,6 @@ trait EvaluationFrameExt { } impl EvaluationFrameExt for &EvaluationFrame { - // --- Column accessors ----------------------------------------------------------------------- - - #[inline(always)] - fn multiplicity(&self) -> E { - self.current()[M_COL_IDX] - } - - #[inline(always)] - fn v(&self) -> E { - self.current()[V_COL_IDX] - } - - #[inline(always)] - fn b_range(&self) -> E { - self.current()[B_RANGE_COL_IDX] - } - - #[inline(always)] - fn b_range_next(&self) -> E { - self.next()[B_RANGE_COL_IDX] - } - // --- Intermediate variables & helpers ------------------------------------------------------- #[inline(always)] diff --git a/air/src/lib.rs b/air/src/lib.rs index 43a8eac51..ba64bf4be 100644 --- a/air/src/lib.rs +++ b/air/src/lib.rs @@ -7,14 +7,16 @@ extern crate alloc; extern crate std; use alloc::vec::Vec; +use core::marker::PhantomData; +use decoder::{DECODER_OP_BITS_OFFSET, DECODER_USER_OP_HELPERS_OFFSET}; use vm_core::{ utils::{ByteReader, ByteWriter, Deserializable, Serializable}, ExtensionOf, ProgramInfo, StackInputs, StackOutputs, ONE, ZERO, }; use winter_air::{ - Air, AirContext, Assertion, EvaluationFrame, ProofOptions as WinterProofOptions, TraceInfo, - TransitionConstraintDegree, + Air, AirContext, Assertion, EvaluationFrame, LogUpGkrEvaluator, LogUpGkrOracle, + ProofOptions as WinterProofOptions, TraceInfo, TransitionConstraintDegree, }; use winter_prover::matrix::ColMatrix; @@ -24,7 +26,11 @@ use constraints::{chiplets, range}; pub mod trace; pub use trace::rows::RowIndex; -use trace::*; +use trace::{ + chiplets::{MEMORY_D0_COL_IDX, MEMORY_D1_COL_IDX}, + range::{M_COL_IDX, V_COL_IDX}, + *, +}; mod errors; mod options; @@ -48,7 +54,7 @@ pub use winter_air::{AuxRandElements, FieldExtension, LagrangeKernelEvaluationFr /// TODO: add docs pub struct ProcessorAir { - context: AirContext, + context: AirContext, stack_inputs: StackInputs, stack_outputs: StackOutputs, constraint_ranges: TransitionConstraintRange, @@ -62,8 +68,6 @@ impl ProcessorAir { } impl Air for ProcessorAir { - type GkrProof = (); - type GkrVerifier = (); type BaseField = Felt; type PublicInputs = PublicInputs; @@ -81,8 +85,6 @@ impl Air for ProcessorAir { let mut range_checker_degrees = range::get_transition_constraint_degrees(); main_degrees.append(&mut range_checker_degrees); - let aux_degrees = range::get_aux_transition_constraint_degrees(); - // --- chiplets (hasher, bitwise, memory) ------------------------- let mut chiplets_degrees = chiplets::get_transition_constraint_degrees(); main_degrees.append(&mut chiplets_degrees); @@ -100,17 +102,17 @@ impl Air for ProcessorAir { let num_main_assertions = 2 + stack::NUM_ASSERTIONS + range::NUM_ASSERTIONS; // Define the number of boundary constraints for the auxiliary execution trace segment. - let num_aux_assertions = stack::NUM_AUX_ASSERTIONS + range::NUM_AUX_ASSERTIONS; + let num_aux_assertions = stack::NUM_AUX_ASSERTIONS; // Create the context and set the number of transition constraint exemptions to two; this // allows us to inject random values into the last row of the execution trace. let context = AirContext::new_multi_segment( trace_info, + pub_inputs.clone(), main_degrees, - aux_degrees, + vec![], num_main_assertions, num_aux_assertions, - None, options, ) .set_num_transition_exemptions(2); @@ -165,7 +167,7 @@ impl Air for ProcessorAir { fn get_aux_assertions>( &self, - _aux_rand_elements: &[E], + _aux_rand_elements: &AuxRandElements, ) -> Vec> { let mut result: Vec> = Vec::new(); @@ -174,18 +176,12 @@ impl Air for ProcessorAir { // add initial assertions for the stack's auxiliary columns. stack::get_aux_assertions_first_step(&mut result); - // Add initial assertions for the range checker's auxiliary columns. - range::get_aux_assertions_first_step::(&mut result); - // --- set assertions for the last step --------------------------------------------------- let last_step = self.last_step(); // add the stack's auxiliary column assertions for the last step. stack::get_aux_assertions_last_step(&mut result, last_step); - // Add the range checker's auxiliary column assertions for the last step. - range::get_aux_assertions_last_step::(&mut result, last_step); - result } @@ -227,28 +223,33 @@ impl Air for ProcessorAir { fn evaluate_aux_transition( &self, - main_frame: &EvaluationFrame, - aux_frame: &EvaluationFrame, + _main_frame: &EvaluationFrame, + _aux_frame: &EvaluationFrame, _periodic_values: &[F], - aux_rand_elements: &[E], - result: &mut [E], + _aux_rand_elements: &AuxRandElements, + _result: &mut [E], ) where F: FieldElement, E: FieldElement + ExtensionOf, { - // --- range checker ---------------------------------------------------------------------- - range::enforce_aux_constraints::(main_frame, aux_frame, aux_rand_elements, result); } - fn context(&self) -> &AirContext { + fn context(&self) -> &AirContext { &self.context } + + fn get_logup_gkr_evaluator( + &self, + ) -> impl LogUpGkrEvaluator + { + MidenLogUpGkrEval::new() + } } // PUBLIC INPUTS // ================================================================================================ -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct PublicInputs { program_info: ProgramInfo, stack_inputs: StackInputs, @@ -302,3 +303,116 @@ impl Deserializable for PublicInputs { }) } } + +// LOGUP-GKR +// ================================================================================================ + +#[derive(Clone, Default)] +pub struct MidenLogUpGkrEval { + oracles: Vec, + _field: PhantomData, +} + +impl MidenLogUpGkrEval { + pub fn new() -> Self { + let oracles = (0..TRACE_WIDTH).map(LogUpGkrOracle::CurrentRow).collect(); + Self { oracles, _field: PhantomData } + } +} + +impl LogUpGkrEvaluator for MidenLogUpGkrEval { + type BaseField = Felt; + + type PublicInputs = PublicInputs; + + fn get_oracles(&self) -> &[LogUpGkrOracle] { + &self.oracles + } + + fn get_num_rand_values(&self) -> usize { + 1 + } + + fn get_num_fractions(&self) -> usize { + 8 + } + + fn max_degree(&self) -> usize { + 5 + } + + fn build_query(&self, frame: &EvaluationFrame, query: &mut [E]) + where + E: FieldElement, + { + query.iter_mut().zip(frame.current().iter()).for_each(|(q, f)| *q = *f) + } + + fn evaluate_query( + &self, + query: &[F], + _periodic_values: &[F], + rand_values: &[E], + numerator: &mut [E], + denominator: &mut [E], + ) where + F: FieldElement, + E: FieldElement + ExtensionOf, + { + assert_eq!(numerator.len(), 8); + assert_eq!(denominator.len(), 8); + assert_eq!(query.len(), TRACE_WIDTH); + + // numerators + let multiplicity = query[M_COL_IDX]; + let f_m = { + let mem_selec0 = query[CHIPLETS_OFFSET]; + let mem_selec1 = query[CHIPLETS_OFFSET + 1]; + let mem_selec2 = query[CHIPLETS_OFFSET + 2]; + mem_selec0 * mem_selec1 * (F::ONE - mem_selec2) + }; + + let f_rc = { + let op_bit_4 = query[DECODER_OP_BITS_OFFSET + 4]; + let op_bit_5 = query[DECODER_OP_BITS_OFFSET + 5]; + let op_bit_6 = query[DECODER_OP_BITS_OFFSET + 6]; + + (F::ONE - op_bit_4) * (F::ONE - op_bit_5) * op_bit_6 + }; + numerator[0] = E::from(multiplicity); + numerator[1] = E::from(f_m); + numerator[2] = E::from(f_m); + numerator[3] = E::from(f_rc); + numerator[4] = E::from(f_rc); + numerator[5] = E::from(f_rc); + numerator[6] = E::from(f_rc); + numerator[7] = E::ZERO; + + // denominators + let alpha = rand_values[0]; + + let table_denom = alpha - E::from(query[V_COL_IDX]); + let memory_denom_0 = -(alpha - E::from(query[MEMORY_D0_COL_IDX])); + let memory_denom_1 = -(alpha - E::from(query[MEMORY_D1_COL_IDX])); + let stack_value_denom_0 = -(alpha - E::from(query[DECODER_USER_OP_HELPERS_OFFSET])); + let stack_value_denom_1 = -(alpha - E::from(query[DECODER_USER_OP_HELPERS_OFFSET + 1])); + let stack_value_denom_2 = -(alpha - E::from(query[DECODER_USER_OP_HELPERS_OFFSET + 2])); + let stack_value_denom_3 = -(alpha - E::from(query[DECODER_USER_OP_HELPERS_OFFSET + 3])); + + denominator[0] = table_denom; + denominator[1] = memory_denom_0; + denominator[2] = memory_denom_1; + denominator[3] = stack_value_denom_0; + denominator[4] = stack_value_denom_1; + denominator[5] = stack_value_denom_2; + denominator[6] = stack_value_denom_3; + denominator[7] = E::ONE; + } + + fn compute_claim(&self, _inputs: &Self::PublicInputs, _rand_values: &[E]) -> E + where + E: FieldElement, + { + E::ZERO + } +} diff --git a/air/src/trace/mod.rs b/air/src/trace/mod.rs index 62c7a910f..bc93b193a 100644 --- a/air/src/trace/mod.rs +++ b/air/src/trace/mod.rs @@ -59,9 +59,9 @@ pub const TRACE_WIDTH: usize = CHIPLETS_OFFSET + CHIPLETS_WIDTH; // AUXILIARY COLUMNS LAYOUT // ------------------------------------------------------------------------------------------------ -// decoder stack range checks hasher chiplets -// (3 columns) (1 column) (1 column) (1 column) (1 column) -// ├───────────────┴──────────────┴──────────────┴───────────────┴───────────────┤ +// decoder stack hasher chiplets +// (3 columns) (1 column) (1 column) (1 column) +// ├───────────────┴──────────────┴─────────────────┴───────────────┤ // Decoder auxiliary columns pub const DECODER_AUX_TRACE_OFFSET: usize = 0; @@ -75,11 +75,11 @@ pub const STACK_AUX_TRACE_WIDTH: usize = 1; pub const STACK_AUX_TRACE_RANGE: Range = range(STACK_AUX_TRACE_OFFSET, STACK_AUX_TRACE_WIDTH); -// Range check auxiliary columns -pub const RANGE_CHECK_AUX_TRACE_OFFSET: usize = STACK_AUX_TRACE_RANGE.end; -pub const RANGE_CHECK_AUX_TRACE_WIDTH: usize = 1; -pub const RANGE_CHECK_AUX_TRACE_RANGE: Range = - range(RANGE_CHECK_AUX_TRACE_OFFSET, RANGE_CHECK_AUX_TRACE_WIDTH); +// Hasher auxiliary columns +pub const HASHER_AUX_TRACE_OFFSET: usize = STACK_AUX_TRACE_RANGE.end; +pub const HASHER_AUX_TRACE_WIDTH: usize = 1; +pub const HASHER_AUX_TRACE_RANGE: Range = + range(HASHER_AUX_TRACE_OFFSET, HASHER_AUX_TRACE_WIDTH); // Chiplets auxiliary columns pub const CHIPLETS_AUX_TRACE_OFFSET: usize = HASHER_AUX_TRACE_RANGE.end; @@ -87,12 +87,6 @@ pub const CHIPLETS_AUX_TRACE_WIDTH: usize = 1; pub const CHIPLETS_AUX_TRACE_RANGE: Range = range(CHIPLETS_AUX_TRACE_OFFSET, CHIPLETS_AUX_TRACE_WIDTH); -// Hasher auxiliary columns -pub const HASHER_AUX_TRACE_OFFSET: usize = RANGE_CHECK_AUX_TRACE_RANGE.end; -pub const HASHER_AUX_TRACE_WIDTH: usize = 1; -pub const HASHER_AUX_TRACE_RANGE: Range = - range(HASHER_AUX_TRACE_OFFSET, HASHER_AUX_TRACE_WIDTH); - pub const AUX_TRACE_WIDTH: usize = CHIPLETS_AUX_TRACE_RANGE.end; /// Number of random elements available to the prover after the commitment to the main trace diff --git a/air/src/trace/range.rs b/air/src/trace/range.rs index 3081bbe3a..218116451 100644 --- a/air/src/trace/range.rs +++ b/air/src/trace/range.rs @@ -1,4 +1,4 @@ -use super::{RANGE_CHECK_AUX_TRACE_OFFSET, RANGE_CHECK_TRACE_OFFSET}; +use super::RANGE_CHECK_TRACE_OFFSET; // CONSTANTS // ================================================================================================ @@ -9,9 +9,3 @@ use super::{RANGE_CHECK_AUX_TRACE_OFFSET, RANGE_CHECK_TRACE_OFFSET}; pub const M_COL_IDX: usize = RANGE_CHECK_TRACE_OFFSET; /// A column to hold the values being range-checked. pub const V_COL_IDX: usize = RANGE_CHECK_TRACE_OFFSET + 1; - -// --- Column accessors in the auxiliary columns -------------------------------------------------- - -/// The running product column used for verifying that the range check lookups performed in the -/// Stack and the Memory chiplet match the values checked in the Range Checker. -pub const B_RANGE_COL_IDX: usize = RANGE_CHECK_AUX_TRACE_OFFSET; diff --git a/core/Cargo.toml b/core/Cargo.toml index ae7da5c50..abd844d7c 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -32,9 +32,11 @@ std = [ [dependencies] lock_api = { version = "0.4", features = ["arc_lock"] } -math = { package = "winter-math", version = "0.9", default-features = false } +math = { package = "winter-math", git = "https://github.com/facebook/winterfell", branch = "logup-gkr", default-features = false } + memchr = { version = "2.7", default-features = false } -miden-crypto = { version = "0.10", default-features = false } +miden-crypto = { git = "https://github.com/0xPolygonMiden/crypto", branch = "al-update-degree-checks", default-features = false } + miden-formatting = { version = "0.1", default-features = false } miette = { package = "miden-miette", version = "7.1", default-features = false, features = [ "fancy-no-syscall", @@ -44,12 +46,13 @@ num-derive = { version = "0.4", default-features = false } num-traits = { version = "0.2", default-features = false } parking_lot = { version = "0.12", optional = true } thiserror = { package = "miden-thiserror", version = "1.0", default-features = false } -winter-utils = { package = "winter-utils", version = "0.9", default-features = false } +winter-utils = { package = "winter-utils", git = "https://github.com/facebook/winterfell", branch = "logup-gkr", default-features = false } +#thiserror = { version = "1.0", git = "https://github.com/bitwalker/thiserror", branch = "no-std", default-features = false } [dev-dependencies] loom = "0.7" proptest = "1.5" -rand_utils = { version = "0.9", package = "winter-rand-utils" } +rand_utils = { git = "https://github.com/facebook/winterfell", branch = "logup-gkr", package = "winter-rand-utils" } [target.'cfg(loom)'.dependencies] loom = "0.7" diff --git a/processor/Cargo.toml b/processor/Cargo.toml index b932d002c..facbce216 100644 --- a/processor/Cargo.toml +++ b/processor/Cargo.toml @@ -27,11 +27,11 @@ std = ["vm-core/std", "winter-prover/std"] miden-air = { package = "miden-air", path = "../air", version = "0.10", default-features = false } tracing = { version = "0.1", default-features = false, features = ["attributes"] } vm-core = { package = "miden-core", path = "../core", version = "0.10", default-features = false } -winter-prover = { package = "winter-prover", version = "0.9", default-features = false } +winter-prover = { package = "winter-prover", git = "https://github.com/facebook/winterfell", branch = "logup-gkr", default-features = false } [dev-dependencies] assembly = { package = "miden-assembly", path = "../assembly", version = "0.10", default-features = false } logtest = { version = "2.0", default-features = false } test-utils = { package = "miden-test-utils", path = "../test-utils" } -winter-fri = { package = "winter-fri", version = "0.9" } -winter-utils = { package = "winter-utils", version = "0.9" } +winter-fri = { package = "winter-fri", git = "https://github.com/facebook/winterfell", branch = "logup-gkr" } +winter-utils = { package = "winter-utils", git = "https://github.com/facebook/winterfell", branch = "logup-gkr" } diff --git a/processor/src/chiplets/mod.rs b/processor/src/chiplets/mod.rs index b098a5760..8cac6fc25 100644 --- a/processor/src/chiplets/mod.rs +++ b/processor/src/chiplets/mod.rs @@ -387,9 +387,9 @@ impl Chiplets { /// /// `num_rand_rows` indicates the number of rows at the end of the trace which will be /// overwritten with random values. - pub fn into_trace(self, trace_len: usize, num_rand_rows: usize) -> ChipletsTrace { + pub fn into_trace(self, trace_len: usize) -> ChipletsTrace { // make sure that only padding rows will be overwritten by random values - assert!(self.trace_len() + num_rand_rows <= trace_len, "target trace length too small"); + assert!(self.trace_len() <= trace_len, "target trace length too small"); // Allocate columns for the trace of the chiplets. let mut trace = (0..CHIPLETS_WIDTH) diff --git a/processor/src/chiplets/tests.rs b/processor/src/chiplets/tests.rs index a0eab0162..dd74963e7 100644 --- a/processor/src/chiplets/tests.rs +++ b/processor/src/chiplets/tests.rs @@ -126,7 +126,7 @@ fn build_trace( process.execute(&program).unwrap(); let (trace, ..) = ExecutionTrace::test_finalize_trace(process); - let trace_len = trace.num_rows() - ExecutionTrace::NUM_RAND_ROWS; + let trace_len = trace.num_rows(); ( trace diff --git a/processor/src/decoder/mod.rs b/processor/src/decoder/mod.rs index 92bb25e4a..9d2c830c1 100644 --- a/processor/src/decoder/mod.rs +++ b/processor/src/decoder/mod.rs @@ -676,10 +676,10 @@ impl Decoder { /// Returns an array of columns containing an execution trace of this decoder. /// /// Trace columns are extended to match the specified trace length. - pub fn into_trace(self, trace_len: usize, num_rand_rows: usize) -> super::DecoderTrace { + pub fn into_trace(self, trace_len: usize) -> super::DecoderTrace { let trace = self .trace - .into_vec(trace_len, num_rand_rows) + .into_vec(trace_len) .try_into() .expect("failed to convert vector to array"); let aux_builder = AuxTraceBuilder::default(); diff --git a/processor/src/decoder/tests.rs b/processor/src/decoder/tests.rs index b29886459..d00f185ca 100644 --- a/processor/src/decoder/tests.rs +++ b/processor/src/decoder/tests.rs @@ -1454,7 +1454,7 @@ fn build_trace(stack_inputs: &[u64], program: &Program) -> (DecoderTrace, usize) process.execute(program).unwrap(); let (trace, ..) = ExecutionTrace::test_finalize_trace(process); - let trace_len = trace.num_rows() - ExecutionTrace::NUM_RAND_ROWS; + let trace_len = trace.num_rows(); ( trace @@ -1474,7 +1474,7 @@ fn build_dyn_trace(stack_inputs: &[u64], program: &Program) -> (DecoderTrace, us process.execute(program).unwrap(); let (trace, ..) = ExecutionTrace::test_finalize_trace(process); - let trace_len = trace.num_rows() - ExecutionTrace::NUM_RAND_ROWS; + let trace_len = trace.num_rows(); ( trace @@ -1493,7 +1493,7 @@ fn build_call_trace(program: &Program, kernel: Kernel) -> (SystemTrace, DecoderT process.execute(program).unwrap(); let (trace, ..) = ExecutionTrace::test_finalize_trace(process); - let trace_len = trace.num_rows() - ExecutionTrace::NUM_RAND_ROWS; + let trace_len = trace.num_rows(); let sys_trace = trace .get_column_range(SYS_TRACE_RANGE) diff --git a/processor/src/decoder/trace.rs b/processor/src/decoder/trace.rs index 6842c504e..ad84dda0d 100644 --- a/processor/src/decoder/trace.rs +++ b/processor/src/decoder/trace.rs @@ -369,10 +369,10 @@ impl DecoderTrace { /// - The first 4 columns of the hasher state, where the unfilled rows are filled with the /// values from the last filled row. This is done so that the hash of the program is /// propagated to the last row. - pub fn into_vec(mut self, trace_len: usize, num_rand_rows: usize) -> Vec> { + pub fn into_vec(mut self, trace_len: usize) -> Vec> { let own_len = self.trace_len(); // make sure that only the duplicate rows will be overwritten with random values - assert!(own_len + num_rand_rows <= trace_len, "target trace length too small"); + assert!(own_len <= trace_len, "target trace length too small"); let mut trace = Vec::new(); diff --git a/processor/src/lib.rs b/processor/src/lib.rs index da55082a1..3b85c88f3 100644 --- a/processor/src/lib.rs +++ b/processor/src/lib.rs @@ -58,7 +58,7 @@ use chiplets::Chiplets; mod trace; use trace::TraceFragment; -pub use trace::{ChipletsLengths, ExecutionTrace, TraceLenSummary, NUM_RAND_ROWS}; +pub use trace::{ChipletsLengths, ExecutionTrace, TraceLenSummary}; mod errors; pub use errors::{ExecutionError, Ext2InttError}; @@ -107,7 +107,6 @@ pub struct StackTrace { pub struct RangeCheckTrace { trace: [Vec; RANGE_CHECK_TRACE_WIDTH], - aux_builder: range::AuxTraceBuilder, } pub struct ChipletsTrace { diff --git a/processor/src/range/aux_trace.rs b/processor/src/range/aux_trace.rs deleted file mode 100644 index 85870b1c2..000000000 --- a/processor/src/range/aux_trace.rs +++ /dev/null @@ -1,182 +0,0 @@ -use alloc::{collections::BTreeMap, vec::Vec}; - -use miden_air::{ - trace::{ - main_trace::MainTrace, - range::{M_COL_IDX, V_COL_IDX}, - }, - RowIndex, -}; - -use super::{uninit_vector, Felt, FieldElement, NUM_RAND_ROWS}; - -// AUXILIARY TRACE BUILDER -// ================================================================================================ - -/// Describes how to construct the execution trace of columns related to the range checker in the -/// auxiliary segment of the trace. These are used in multiset checks. -pub struct AuxTraceBuilder { - /// A list of the unique values for which range checks are performed. - lookup_values: Vec, - /// Range check lookups performed by all user operations, grouped and sorted by the clock cycle - /// at which they are requested. - cycle_lookups: BTreeMap>, - // The index of the first row of Range Checker's trace when the padded rows end and values to - // be range checked start. - values_start: usize, -} - -impl AuxTraceBuilder { - // CONSTRUCTOR - // -------------------------------------------------------------------------------------------- - pub fn new( - lookup_values: Vec, - cycle_lookups: BTreeMap>, - values_start: usize, - ) -> Self { - Self { - lookup_values, - cycle_lookups, - values_start, - } - } - - // AUX COLUMN BUILDERS - // -------------------------------------------------------------------------------------------- - - /// Builds and returns range checker auxiliary trace columns. Currently this consists of one - /// column: - /// - `b_range`: ensures that the range checks performed by the Range Checker match those - /// requested by the Stack and Memory processors. - pub fn build_aux_columns>( - &self, - main_trace: &MainTrace, - rand_elements: &[E], - ) -> Vec> { - let b_range = self.build_aux_col_b_range(main_trace, rand_elements); - vec![b_range] - } - - /// Builds the execution trace of the range check `b_range` column which ensure that the range - /// check lookups performed by user operations match those executed by the Range Checker. - fn build_aux_col_b_range>( - &self, - main_trace: &MainTrace, - rand_elements: &[E], - ) -> Vec { - // run batch inversion on the lookup values - let divisors = get_divisors(&self.lookup_values, rand_elements[0]); - - // allocate memory for the running sum column and set the initial value to ONE - let mut b_range = unsafe { uninit_vector(main_trace.num_rows()) }; - b_range[0] = E::ONE; - - // keep track of the last updated row in the `b_range` running sum column. `b_range` is - // filled with result values that are added to the next row after the operation's execution. - let mut b_range_idx = 0_usize; - - // the first half of the trace only includes values from the operations. - for (clk, range_checks) in - self.cycle_lookups.range(RowIndex::from(0)..RowIndex::from(self.values_start)) - { - let clk: usize = (*clk).into(); - - // if we skipped some cycles since the last update was processed, values in the last - // updated row should be copied over until the current cycle. - if b_range_idx < clk { - let last_value = b_range[b_range_idx]; - b_range[(b_range_idx + 1)..=clk].fill(last_value); - } - - // move the column pointer to the next row. - b_range_idx = clk + 1; - - b_range[b_range_idx] = b_range[clk]; - // include the operation lookups - for lookup in range_checks.iter() { - let value = divisors.get(lookup).expect("invalid lookup value {}"); - b_range[b_range_idx] -= *value; - } - } - - // if we skipped some cycles since the last update was processed, values in the last - // updated row should by copied over until the current cycle. - if b_range_idx < self.values_start { - let last_value = b_range[b_range_idx]; - b_range[(b_range_idx + 1)..=self.values_start].fill(last_value); - } - - // after the padded section of the range checker table, include the lookup value specified - // by the range checker into the running sum at each step, and remove lookups from user ops - // at any step where user ops were executed. - for (row_idx, (multiplicity, lookup)) in main_trace - .get_column(M_COL_IDX) - .iter() - .zip(main_trace.get_column(V_COL_IDX).iter()) - .enumerate() - .take(main_trace.num_rows() - NUM_RAND_ROWS) - .skip(self.values_start) - { - b_range_idx = row_idx + 1; - - if multiplicity.as_int() != 0 { - // add the value in the range checker: multiplicity / (alpha - lookup) - let value = divisors.get(&(lookup.as_int() as u16)).expect("invalid lookup value"); - b_range[b_range_idx] = b_range[row_idx] + value.mul_base(*multiplicity); - } else { - b_range[b_range_idx] = b_range[row_idx]; - } - - // subtract the range checks requested by operations - if let Some(range_checks) = self.cycle_lookups.get(&(row_idx as u32).into()) { - for lookup in range_checks.iter() { - let value = divisors.get(lookup).expect("invalid lookup value"); - b_range[b_range_idx] -= *value; - } - } - } - - // at this point, all range checks from user operations and the range checker should be - // matched - so, the last value must be ONE; - assert_eq!(b_range[b_range_idx], E::ONE); - - if b_range_idx < b_range.len() - 1 { - b_range[(b_range_idx + 1)..].fill(E::ONE); - } - - b_range - } -} - -/// Runs batch inversion on all range check lookup values and returns a map which maps each value -/// to the divisor used for including it in the LogUp lookup. In other words, the map contains -/// mappings of x to 1/(alpha - x). -fn get_divisors>( - lookup_values: &[u16], - alpha: E, -) -> BTreeMap { - // run batch inversion on the lookup values - let mut values = unsafe { uninit_vector(lookup_values.len()) }; - let mut inv_values = unsafe { uninit_vector(lookup_values.len()) }; - let mut log_values = BTreeMap::new(); - - let mut acc = E::ONE; - for (i, (value, inv_value)) in values.iter_mut().zip(inv_values.iter_mut()).enumerate() { - *inv_value = acc; - *value = alpha - E::from(lookup_values[i]); - acc *= *value; - } - - // invert the accumulated product - acc = acc.inv(); - - // multiply the accumulated product by the original values to compute the inverses, then - // build a map of inverses for the lookup values - for i in (0..lookup_values.len()).rev() { - inv_values[i] *= acc; - acc *= values[i]; - log_values.insert(lookup_values[i], inv_values[i]); - } - - log_values -} diff --git a/processor/src/range/mod.rs b/processor/src/range/mod.rs index 153ec6bf7..fb36b29c2 100644 --- a/processor/src/range/mod.rs +++ b/processor/src/range/mod.rs @@ -2,12 +2,9 @@ use alloc::{collections::BTreeMap, vec::Vec}; use miden_air::RowIndex; -use super::{trace::NUM_RAND_ROWS, Felt, FieldElement, RangeCheckTrace, ZERO}; +use super::{Felt, RangeCheckTrace, ZERO}; use crate::utils::uninit_vector; -mod aux_trace; -pub use aux_trace::AuxTraceBuilder; - #[cfg(test)] mod tests; @@ -107,18 +104,13 @@ impl RangeChecker { /// # Panics /// Panics if `target_len` is not a power of two or is smaller than the trace length needed /// to represent all lookups in this range checker. - pub fn into_trace_with_table( - self, - trace_len: usize, - target_len: usize, - num_rand_rows: usize, - ) -> RangeCheckTrace { + pub fn into_trace_with_table(self, trace_len: usize, target_len: usize) -> RangeCheckTrace { assert!(target_len.is_power_of_two(), "target trace length is not a power of two"); // determine the length of the trace required to support all the lookups in this range // checker, and make sure this length is smaller than or equal to the target trace length, // accounting for rows with random values. - assert!(trace_len + num_rand_rows <= target_len, "target trace length too small"); + assert!(trace_len <= target_len, "target trace length too small"); // allocated memory for the trace; this memory is un-initialized but this is not a problem // because we'll overwrite all values in it anyway. @@ -126,7 +118,7 @@ impl RangeChecker { // determine the number of padding rows needed to get to target trace length and pad the // table with the required number of rows. - let num_padding_rows = target_len - trace_len - num_rand_rows; + let num_padding_rows = target_len - trace_len; trace[0][..num_padding_rows].fill(ZERO); trace[1][..num_padding_rows].fill(ZERO); @@ -145,14 +137,7 @@ impl RangeChecker { // the "current" row of the main trace but placed into the "next" row of the bus column.) write_trace_row(&mut trace, &mut i, 0, (u16::MAX).into()); - RangeCheckTrace { - trace, - aux_builder: AuxTraceBuilder::new( - self.lookups.keys().cloned().collect(), - self.cycle_lookups, - num_padding_rows, - ), - } + RangeCheckTrace { trace } } // PUBLIC ACCESSORS @@ -194,9 +179,9 @@ impl RangeChecker { /// /// Wrapper for [`RangeChecker::into_trace_with_table`]. #[cfg(test)] - pub fn into_trace(self, target_len: usize, num_rand_rows: usize) -> RangeCheckTrace { + pub fn into_trace(self, target_len: usize) -> RangeCheckTrace { let table_len = self.get_number_range_checker_rows(); - self.into_trace_with_table(table_len, target_len, num_rand_rows) + self.into_trace_with_table(table_len, target_len) } } diff --git a/processor/src/range/tests.rs b/processor/src/range/tests.rs index d193f66f0..46bbafe1b 100644 --- a/processor/src/range/tests.rs +++ b/processor/src/range/tests.rs @@ -17,7 +17,7 @@ fn range_checks() { checker.add_value(value.as_int() as u16); } - let RangeCheckTrace { trace, aux_builder: _ } = checker.into_trace(64, 0); + let RangeCheckTrace { trace } = checker.into_trace(64); validate_trace(&trace, &values); // skip the padded rows @@ -56,7 +56,7 @@ fn range_checks_rand() { } let trace_len = checker.trace_len().next_power_of_two(); - let RangeCheckTrace { trace, aux_builder: _ } = checker.into_trace(trace_len, 0); + let RangeCheckTrace { trace } = checker.into_trace(trace_len); validate_trace(&trace, &values); } diff --git a/processor/src/stack/mod.rs b/processor/src/stack/mod.rs index 417c0a80a..6f2c57c25 100644 --- a/processor/src/stack/mod.rs +++ b/processor/src/stack/mod.rs @@ -280,10 +280,10 @@ impl Stack { /// `num_rand_rows` indicates the number of rows at the end of the trace which will be /// overwritten with random values. This parameter is unused because last rows are just /// duplicates of the prior rows and thus can be safely overwritten. - pub fn into_trace(self, trace_len: usize, num_rand_rows: usize) -> super::StackTrace { + pub fn into_trace(self, trace_len: usize) -> super::StackTrace { let clk = self.current_clk().as_usize(); // make sure that only the duplicate rows will be overwritten with random values - assert!(clk + num_rand_rows <= trace_len, "target trace length too small"); + assert!(clk <= trace_len, "target trace length too small"); // at the end of program execution we must be in the root context, and thus active and // full stack depth must be the same. diff --git a/processor/src/stack/tests.rs b/processor/src/stack/tests.rs index d8e16a810..7759f70ec 100644 --- a/processor/src/stack/tests.rs +++ b/processor/src/stack/tests.rs @@ -357,7 +357,7 @@ fn generate_trace() { stack.shift_left(1); stack.advance_clock(); - let trace = stack.into_trace(16, 1); + let trace = stack.into_trace(16); let trace = trace.trace; assert_eq!(read_stack_top(&trace, 0), build_stack(&[4, 3, 2, 1])); diff --git a/processor/src/system/mod.rs b/processor/src/system/mod.rs index f6b50d0ea..51931014b 100644 --- a/processor/src/system/mod.rs +++ b/processor/src/system/mod.rs @@ -237,10 +237,10 @@ impl System { /// `num_rand_rows` indicates the number of rows at the end of the trace which will be /// overwritten with random values. This parameter is unused because last rows are just /// duplicates of the prior rows and thus can be safely overwritten. - pub fn into_trace(mut self, trace_len: usize, num_rand_rows: usize) -> SysTrace { + pub fn into_trace(mut self, trace_len: usize) -> SysTrace { let clk: usize = self.clk().into(); // make sure that only the duplicate rows will be overwritten with random values - assert!(clk + num_rand_rows <= trace_len, "target trace length too small"); + assert!(clk <= trace_len, "target trace length too small"); // complete the clk column by filling in all values after the last clock cycle. The values // in the clk column are equal to the index of the row in the trace table. diff --git a/processor/src/trace/mod.rs b/processor/src/trace/mod.rs index df1e2c4af..d1d5556cf 100644 --- a/processor/src/trace/mod.rs +++ b/processor/src/trace/mod.rs @@ -7,12 +7,11 @@ use miden_air::trace::{ STACK_TRACE_OFFSET, TRACE_WIDTH, }; use vm_core::{stack::MIN_STACK_DEPTH, ProgramInfo, StackInputs, StackOutputs, ZERO}; -use winter_prover::{crypto::RandomCoin, EvaluationFrame, Trace, TraceInfo}; +use winter_prover::{EvaluationFrame, Trace, TraceInfo}; use super::{ - chiplets::AuxTraceBuilder as ChipletsAuxTraceBuilder, crypto::RpoRandomCoin, + chiplets::AuxTraceBuilder as ChipletsAuxTraceBuilder, decoder::AuxTraceBuilder as DecoderAuxTraceBuilder, - range::AuxTraceBuilder as RangeCheckerAuxTraceBuilder, stack::AuxTraceBuilder as StackAuxTraceBuilder, ColMatrix, Digest, Felt, FieldElement, Host, Process, }; @@ -22,14 +21,6 @@ pub use utils::{AuxColumnBuilder, ChipletsLengths, TraceFragment, TraceLenSummar #[cfg(test)] mod tests; -#[cfg(test)] -use super::EMPTY_WORD; - -// CONSTANTS -// ================================================================================================ - -/// Number of rows at the end of an execution trace which are injected with random values. -pub const NUM_RAND_ROWS: usize = 1; // VM EXECUTION TRACE // ================================================================================================ @@ -37,7 +28,6 @@ pub const NUM_RAND_ROWS: usize = 1; pub struct AuxTraceBuilders { pub(crate) decoder: DecoderAuxTraceBuilder, pub(crate) stack: StackAuxTraceBuilder, - pub(crate) range: RangeCheckerAuxTraceBuilder, pub(crate) chiplets: ChipletsAuxTraceBuilder, } @@ -59,12 +49,6 @@ pub struct ExecutionTrace { } impl ExecutionTrace { - // CONSTANTS - // -------------------------------------------------------------------------------------------- - - /// Number of rows at the end of an execution trace which are injected with random values. - pub const NUM_RAND_ROWS: usize = NUM_RAND_ROWS; - // CONSTRUCTOR // -------------------------------------------------------------------------------------------- /// Builds an execution trace for the provided process. @@ -72,23 +56,19 @@ impl ExecutionTrace { where H: Host, { - // use program hash to initialize random element generator; this generator will be used - // to inject random values at the end of the trace; using program hash here is OK because - // we are using random values only to stabilize constraint degrees, and not to achieve - // perfect zero knowledge. let program_hash = process.decoder.program_hash(); - let rng = RpoRandomCoin::new(program_hash); // create a new program info instance with the underlying kernel let kernel = process.kernel().clone(); let program_info = ProgramInfo::new(program_hash.into(), kernel); - let (main_trace, aux_trace_builders, trace_len_summary) = finalize_trace(process, rng); + let (main_trace, aux_trace_builders, trace_len_summary) = finalize_trace(process); let trace_info = TraceInfo::new_multi_segment( TRACE_WIDTH, AUX_TRACE_WIDTH, AUX_TRACE_RAND_ELEMENTS, main_trace.num_rows(), vec![], + true, ); Self { @@ -169,7 +149,7 @@ impl ExecutionTrace { /// Returns the index of the last row in the trace. fn last_step(&self) -> usize { - self.length() - NUM_RAND_ROWS - 1 + self.length() - 1 } // TEST HELPERS @@ -191,8 +171,7 @@ impl ExecutionTrace { where H: Host, { - let rng = RpoRandomCoin::new(EMPTY_WORD); - finalize_trace(process, rng) + finalize_trace(process) } pub fn build_aux_trace(&self, rand_elements: &[E]) -> Option> @@ -209,10 +188,6 @@ impl ExecutionTrace { let stack_aux_columns = self.aux_trace_builders.stack.build_aux_columns(&self.main_trace, rand_elements); - // add the range checker's running product columns - let range_aux_columns = - self.aux_trace_builders.range.build_aux_columns(&self.main_trace, rand_elements); - // add the running product columns for the chiplets let chiplets = self .aux_trace_builders @@ -220,21 +195,12 @@ impl ExecutionTrace { .build_aux_columns(&self.main_trace, rand_elements); // combine all auxiliary columns into a single vector - let mut aux_columns = decoder_aux_columns + let aux_columns = decoder_aux_columns .into_iter() .chain(stack_aux_columns) - .chain(range_aux_columns) .chain(chiplets) .collect::>(); - // inject random values into the last rows of the trace - let mut rng = RpoRandomCoin::new(self.program_hash().into()); - for i in self.length() - NUM_RAND_ROWS..self.length() { - for column in aux_columns.iter_mut() { - column[i] = rng.draw().expect("failed to draw a random value"); - } - } - Some(ColMatrix::new(aux_columns)) } } @@ -275,10 +241,7 @@ impl Trace for ExecutionTrace { /// - Inserting random values in the last row of all columns. This helps ensure that there are no /// repeating patterns in each column and each column contains a least two distinct values. This, /// in turn, ensures that polynomial degrees of all columns are stable. -fn finalize_trace( - process: Process, - mut rng: RpoRandomCoin, -) -> (MainTrace, AuxTraceBuilders, TraceLenSummary) +fn finalize_trace(process: Process) -> (MainTrace, AuxTraceBuilders, TraceLenSummary) where H: Host, { @@ -302,7 +265,7 @@ where // Pad the trace length to the next power of two and ensure that there is space for the // Rows to hold random values - let trace_len = (max_len + NUM_RAND_ROWS).next_power_of_two(); + let trace_len = max_len.next_power_of_two(); assert!( trace_len >= MIN_TRACE_LEN, "trace length must be at least {MIN_TRACE_LEN}, but was {trace_len}", @@ -313,15 +276,15 @@ where TraceLenSummary::new(clk.into(), range_table_len, ChipletsLengths::new(&chiplets)); // Combine all trace segments into the main trace - let system_trace = system.into_trace(trace_len, NUM_RAND_ROWS); - let decoder_trace = decoder.into_trace(trace_len, NUM_RAND_ROWS); - let stack_trace = stack.into_trace(trace_len, NUM_RAND_ROWS); - let chiplets_trace = chiplets.into_trace(trace_len, NUM_RAND_ROWS); + let system_trace = system.into_trace(trace_len); + let decoder_trace = decoder.into_trace(trace_len); + let stack_trace = stack.into_trace(trace_len); + let chiplets_trace = chiplets.into_trace(trace_len); // Combine the range trace segment using the support lookup table - let range_check_trace = range.into_trace_with_table(range_table_len, trace_len, NUM_RAND_ROWS); + let range_check_trace = range.into_trace_with_table(range_table_len, trace_len); - let mut trace = system_trace + let trace = system_trace .into_iter() .chain(decoder_trace.trace) .chain(stack_trace.trace) @@ -329,21 +292,13 @@ where .chain(chiplets_trace.trace) .collect::>(); - // Inject random values into the last rows of the trace - for i in trace_len - NUM_RAND_ROWS..trace_len { - for column in trace.iter_mut() { - column[i] = rng.draw().expect("failed to draw a random value"); - } - } - - let aux_trace_hints = AuxTraceBuilders { + let aux_trace_builders = AuxTraceBuilders { decoder: decoder_trace.aux_builder, stack: StackAuxTraceBuilder, - range: range_check_trace.aux_builder, chiplets: chiplets_trace.aux_builder, }; let main_trace = MainTrace::new(ColMatrix::new(trace), clk); - (main_trace, aux_trace_hints, trace_len_summary) + (main_trace, aux_trace_builders, trace_len_summary) } diff --git a/processor/src/trace/tests/chiplets/bitwise.rs b/processor/src/trace/tests/chiplets/bitwise.rs index 84abed625..67fecc359 100644 --- a/processor/src/trace/tests/chiplets/bitwise.rs +++ b/processor/src/trace/tests/chiplets/bitwise.rs @@ -8,7 +8,7 @@ use miden_air::{ use super::{ build_trace_from_ops, rand_array, rand_value, ExecutionTrace, Felt, FieldElement, Operation, - Trace, AUX_TRACE_RAND_ELEMENTS, CHIPLETS_AUX_TRACE_OFFSET, HASH_CYCLE_LEN, NUM_RAND_ROWS, ONE, + Trace, AUX_TRACE_RAND_ELEMENTS, CHIPLETS_AUX_TRACE_OFFSET, HASH_CYCLE_LEN, ONE, }; /// Tests the generation of the `b_chip` bus column when only bitwise lookups are included. It @@ -163,7 +163,7 @@ fn b_chip_trace_bitwise() { assert_eq!(expected, b_chip[response_3_row]); // The value in b_chip should be ONE now and for the rest of the trace. - for row in response_3_row..trace.length() - NUM_RAND_ROWS { + for row in response_3_row..trace.length() { assert_eq!(ONE, b_chip[row]); } } diff --git a/processor/src/trace/tests/chiplets/hasher.rs b/processor/src/trace/tests/chiplets/hasher.rs index 813b009d3..6b93c6bdf 100644 --- a/processor/src/trace/tests/chiplets/hasher.rs +++ b/processor/src/trace/tests/chiplets/hasher.rs @@ -28,7 +28,7 @@ use vm_core::{ use super::{ build_span_with_respan_ops, build_trace_from_ops_with_inputs, build_trace_from_program, init_state_from_words, rand_array, AdviceInputs, ExecutionTrace, Felt, FieldElement, Operation, - Trace, AUX_TRACE_RAND_ELEMENTS, CHIPLETS_AUX_TRACE_OFFSET, NUM_RAND_ROWS, ONE, ZERO, + Trace, AUX_TRACE_RAND_ELEMENTS, CHIPLETS_AUX_TRACE_OFFSET, ONE, ZERO, }; use crate::StackInputs; @@ -115,7 +115,7 @@ pub fn b_chip_span() { assert_eq!(expected, b_chip[HASH_CYCLE_LEN]); // The value in b_chip should be ONE now and for the rest of the trace. - for row in HASH_CYCLE_LEN..trace.length() - NUM_RAND_ROWS { + for row in HASH_CYCLE_LEN..trace.length() { assert_eq!(ONE, b_chip[row]); } } @@ -208,7 +208,7 @@ pub fn b_chip_span_with_respan() { assert_eq!(expected, b_chip[22]); // The value in b_chip should be ONE now and for the rest of the trace. - for row in 22..trace.length() - NUM_RAND_ROWS { + for row in 22..trace.length() { assert_eq!(ONE, b_chip[row]); } } @@ -323,7 +323,7 @@ pub fn b_chip_merge() { assert_eq!(expected, b_chip[16]); // The value in b_chip should be ONE now and for the rest of the trace. - for row in 16..trace.length() - NUM_RAND_ROWS { + for row in 16..trace.length() { assert_eq!(ONE, b_chip[row]); } } @@ -433,7 +433,7 @@ pub fn b_chip_permutation() { assert_eq!(expected, b_chip[16]); // The value in b_chip should be ONE now and for the rest of the trace. - for row in 16..trace.length() - NUM_RAND_ROWS { + for row in 16..trace.length() { assert_eq!(ONE, b_chip[row]); } } @@ -570,7 +570,7 @@ fn b_chip_mpverify() { assert_eq!(expected, b_chip[mp_verify_complete]); // The value in b_chip should be ONE now and for the rest of the trace. - for row in mp_verify_complete..trace.length() - NUM_RAND_ROWS { + for row in mp_verify_complete..trace.length() { assert_eq!(ONE, b_chip[row]); } } @@ -783,7 +783,7 @@ fn b_chip_mrupdate() { assert_eq!(expected, b_chip[mp_new_verify_complete]); // The value in b_chip should be ONE now and for the rest of the trace. - for row in (mp_new_verify_complete)..trace.length() - NUM_RAND_ROWS { + for row in (mp_new_verify_complete)..trace.length() { assert_eq!(ONE, b_chip[row]); } } diff --git a/processor/src/trace/tests/chiplets/memory.rs b/processor/src/trace/tests/chiplets/memory.rs index 5415a38de..b42d44585 100644 --- a/processor/src/trace/tests/chiplets/memory.rs +++ b/processor/src/trace/tests/chiplets/memory.rs @@ -9,7 +9,7 @@ use miden_air::{ use super::{ build_trace_from_ops, rand_array, ExecutionTrace, Felt, FieldElement, Operation, Trace, Word, - AUX_TRACE_RAND_ELEMENTS, CHIPLETS_AUX_TRACE_OFFSET, NUM_RAND_ROWS, ONE, ZERO, + AUX_TRACE_RAND_ELEMENTS, CHIPLETS_AUX_TRACE_OFFSET, ONE, ZERO, }; /// Tests the generation of the `b_chip` bus column when only memory lookups are included. It @@ -139,7 +139,7 @@ fn b_chip_trace_mem() { assert_eq!(expected, b_chip[15]); // The value in b_chip should be ONE now and for the rest of the trace. - for row in 15..trace.length() - NUM_RAND_ROWS { + for row in 15..trace.length() { assert_eq!(ONE, b_chip[row]); } } diff --git a/processor/src/trace/tests/chiplets/mod.rs b/processor/src/trace/tests/chiplets/mod.rs index 2fc243cfd..5c7ea47d2 100644 --- a/processor/src/trace/tests/chiplets/mod.rs +++ b/processor/src/trace/tests/chiplets/mod.rs @@ -4,7 +4,7 @@ use miden_air::trace::{ use test_utils::rand::rand_value; use super::{ - super::{utils::build_span_with_respan_ops, Trace, NUM_RAND_ROWS}, + super::{utils::build_span_with_respan_ops, Trace}, build_trace_from_ops, build_trace_from_ops_with_inputs, build_trace_from_program, init_state_from_words, rand_array, AdviceInputs, ExecutionTrace, Felt, FieldElement, Operation, Word, ONE, ZERO, diff --git a/processor/src/trace/tests/decoder.rs b/processor/src/trace/tests/decoder.rs index 021102dcc..2a28e1323 100644 --- a/processor/src/trace/tests/decoder.rs +++ b/processor/src/trace/tests/decoder.rs @@ -12,7 +12,6 @@ use super::{ super::{ tests::{build_trace_from_ops, build_trace_from_program}, utils::build_span_with_respan_ops, - NUM_RAND_ROWS, }, Felt, }; @@ -62,7 +61,7 @@ fn decoder_p1_span_with_respan() { // at cycle 22, the END operation is executed and the table is cleared let expected_value = expected_value * row_values[1].inv(); assert_eq!(expected_value, ONE); - for i in 22..(p1.len() - NUM_RAND_ROWS) { + for i in 22..p1.len() { assert_eq!(ONE, p1[i]); } } @@ -129,7 +128,7 @@ fn decoder_p1_join() { // at this point the table should be empty, and thus, all subsequent values must be ONE assert_eq!(expected_value, ONE); - for i in 9..(p1.len() - NUM_RAND_ROWS) { + for i in 9..p1.len() { assert_eq!(ONE, p1[i]); } } @@ -183,7 +182,7 @@ fn decoder_p1_split() { // at this point the table should be empty, and thus, all subsequent values must be ONE assert_eq!(expected_value, ONE); - for i in 6..(p1.len() - NUM_RAND_ROWS) { + for i in 6..p1.len() { assert_eq!(ONE, p1[i]); } } @@ -304,7 +303,7 @@ fn decoder_p1_loop_with_repeat() { // at this point the table should be empty, and thus, all subsequent values must be ONE assert_eq!(expected_value, ONE); - for i in 20..(p1.len() - NUM_RAND_ROWS) { + for i in 20..p1.len() { assert_eq!(ONE, p1[i]); } } @@ -345,7 +344,7 @@ fn decoder_p2_span_with_respan() { // at cycle 22, the END operation is executed and the table is cleared expected_value *= row_values[0].inv(); assert_eq!(expected_value, ONE); - for i in 22..(p2.len() - NUM_RAND_ROWS) { + for i in 22..p2.len() { assert_eq!(ONE, p2[i]); } } @@ -410,7 +409,7 @@ fn decoder_p2_join() { // at this point the table should be empty, and thus, all subsequent values must be ONE assert_eq!(expected_value, ONE); - for i in 9..(p2.len() - NUM_RAND_ROWS) { + for i in 9..p2.len() { assert_eq!(ONE, p2[i]); } } @@ -463,7 +462,7 @@ fn decoder_p2_split_true() { // at this point the table should be empty, and thus, all subsequent values must be ONE assert_eq!(expected_value, ONE); - for i in 6..(p2.len() - NUM_RAND_ROWS) { + for i in 6..p2.len() { assert_eq!(ONE, p2[i]); } } @@ -519,7 +518,7 @@ fn decoder_p2_split_false() { // at this point the table should be empty, and thus, all subsequent values must be ONE assert_eq!(expected_value, ONE); - for i in 6..(p2.len() - NUM_RAND_ROWS) { + for i in 6..p2.len() { assert_eq!(ONE, p2[i]); } } @@ -635,7 +634,7 @@ fn decoder_p2_loop_with_repeat() { // at this point the table should be empty, and thus, all subsequent values must be ONE assert_eq!(expected_value, ONE); - for i in 20..(p2.len() - NUM_RAND_ROWS) { + for i in 20..p2.len() { assert_eq!(ONE, p2[i]); } } @@ -655,7 +654,7 @@ fn decoder_p3_trace_empty_table() { // no rows should have been added or removed from the op group table, and thus, all values // in the column must be ONE let p3 = aux_columns.get_column(P3_COL_IDX); - for &value in p3.iter().take(p3.len() - NUM_RAND_ROWS) { + for &value in p3.iter().take(p3.len()) { assert_eq!(ONE, value); } } @@ -721,7 +720,7 @@ fn decoder_p3_trace_one_batch() { // at this point, the table should be empty and thus, running product should be ONE assert_eq!(expected_value, ONE); - for i in 11..(p3.len() - NUM_RAND_ROWS) { + for i in 11..p3.len() { assert_eq!(ONE, p3[i]); } } @@ -795,7 +794,7 @@ fn decoder_p3_trace_two_batches() { // at this point, the table should be empty and thus, running product should be ONE assert_eq!(expected_value, ONE); - for i in 20..(p3.len() - NUM_RAND_ROWS) { + for i in 20..p3.len() { assert_eq!(ONE, p3[i]); } } diff --git a/processor/src/trace/tests/hasher.rs b/processor/src/trace/tests/hasher.rs index 7197c925f..f35e17bd7 100644 --- a/processor/src/trace/tests/hasher.rs +++ b/processor/src/trace/tests/hasher.rs @@ -9,8 +9,7 @@ use vm_core::{ }; use super::{ - super::NUM_RAND_ROWS, build_trace_from_ops_with_inputs, rand_array, AdviceInputs, Felt, - Operation, Word, ONE, ZERO, + build_trace_from_ops_with_inputs, rand_array, AdviceInputs, Felt, Operation, Word, ONE, ZERO, }; use crate::StackInputs; @@ -42,7 +41,7 @@ fn hasher_p1_mp_verify() { // executing MPVERIFY does not affect the sibling table - so, all values in the column must be // ONE - for i in 0..(p1.len() - NUM_RAND_ROWS) { + for i in 0..p1.len() { assert_eq!(ONE, p1[i]); } } @@ -146,7 +145,7 @@ fn hasher_p1_mr_update() { // at this point the table should be empty again, and it should stay empty until the end assert_eq!(expected_value, ONE); - for i in 50..(p1.len() - NUM_RAND_ROWS) { + for i in 50..p1.len() { assert_eq!(ONE, p1[i]); } } diff --git a/processor/src/trace/tests/mod.rs b/processor/src/trace/tests/mod.rs index 42524d68f..54b8073fa 100644 --- a/processor/src/trace/tests/mod.rs +++ b/processor/src/trace/tests/mod.rs @@ -3,16 +3,12 @@ use alloc::vec::Vec; use test_utils::rand::rand_array; use vm_core::{mast::MastForest, Kernel, Operation, Program, StackOutputs, Word, ONE, ZERO}; -use super::{ - super::chiplets::init_state_from_words, ExecutionTrace, Felt, FieldElement, Process, Trace, - NUM_RAND_ROWS, -}; +use super::{super::chiplets::init_state_from_words, ExecutionTrace, Felt, FieldElement, Process}; use crate::{AdviceInputs, DefaultHost, ExecutionOptions, MemAdviceProvider, StackInputs}; mod chiplets; mod decoder; mod hasher; -mod range; mod stack; // TEST HELPERS diff --git a/processor/src/trace/tests/range.rs b/processor/src/trace/tests/range.rs deleted file mode 100644 index 3e3f901d7..000000000 --- a/processor/src/trace/tests/range.rs +++ /dev/null @@ -1,148 +0,0 @@ -use miden_air::trace::{ - chiplets::hasher::HASH_CYCLE_LEN, range::B_RANGE_COL_IDX, AUX_TRACE_RAND_ELEMENTS, -}; -use test_utils::rand::rand_array; -use vm_core::{ExtensionOf, Operation}; - -use super::{build_trace_from_ops, Felt, FieldElement, Trace, NUM_RAND_ROWS, ONE, ZERO}; - -/// This test checks that range check lookups from stack operations are balanced by the range checks -/// processed in the Range Checker. -/// -/// The `U32add` operation results in 4 16-bit range checks of 256, 0, 0, 0. -#[test] -fn b_range_trace_stack() { - let stack = [1, 255]; - let operations = vec![Operation::U32add]; - let trace = build_trace_from_ops(operations, &stack); - - let rand_elements = rand_array::(); - let alpha = rand_elements[0]; - let aux_columns = trace.build_aux_trace(&rand_elements).unwrap(); - let b_range = aux_columns.get_column(B_RANGE_COL_IDX); - - assert_eq!(trace.length(), b_range.len()); - - // --- Check the stack processor's range check lookups. --------------------------------------- - - // Before any range checks are executed, the value in b_range should be one. - assert_eq!(ONE, b_range[0]); - assert_eq!(ONE, b_range[1]); - - // The first range check lookup from the stack will happen when the add operation is executed, - // at cycle 1. (The trace begins by executing `span`). It must be subtracted out of `b_range`. - // The range-checked values are 0, 256, 0, 0, so the values to subtract are 3/(alpha - 0) and - // 1/(alpha - 256). - let lookups = alpha.inv().mul_base(Felt::new(3)) + (alpha - Felt::new(256)).inv(); - let mut expected = b_range[1] - lookups; - assert_eq!(expected, b_range[2]); - - // --- Check the range checker's lookups. ----------------------------------------------------- - - // 44 rows are needed for 0, 243, 252, 255, 256, ... 38 additional bridge rows of powers of - // 3 ..., 65535. (0 and 256 are range-checked. 65535 is the max, and the rest are "bridge" - // values.) An extra row is added to pad the u16::MAX value. - let len_16bit = 44 + 1; - // The start of the values in the range checker table. - let values_start = trace.length() - len_16bit - NUM_RAND_ROWS; - - // After the padded rows, the first value will be unchanged. - assert_eq!(expected, b_range[values_start]); - // We include 3 lookups of 0. - expected += alpha.inv().mul_base(Felt::new(3)); - assert_eq!(expected, b_range[values_start + 1]); - // Then we have 3 bridge rows between 0 and 255 where the value does not change - assert_eq!(expected, b_range[values_start + 2]); - assert_eq!(expected, b_range[values_start + 3]); - assert_eq!(expected, b_range[values_start + 4]); - // Then we include 1 lookup of 256, so it should be multiplied by alpha + 256. - expected += (alpha - Felt::new(256)).inv(); - assert_eq!(expected, b_range[values_start + 5]); - - // --- Check the last value of the b_range column is one -------------------------------------- - - let last_row = b_range.len() - NUM_RAND_ROWS - 1; - assert_eq!(ONE, b_range[last_row]); -} - -/// This test checks that range check lookups from memory operations are balanced by the -/// range checks processed in the Range Checker. -/// -/// The `StoreW` memory operation results in 2 16-bit range checks of 0, 0. -/// The `LoadW` memory operation results in 2 16-bit range checks of 0, 0. -#[test] -#[allow(clippy::needless_range_loop)] -fn b_range_trace_mem() { - let stack = [0, 1, 2, 3, 4, 0]; - let operations = vec![ - Operation::MStoreW, - Operation::Drop, - Operation::Drop, - Operation::Drop, - Operation::Drop, - Operation::MLoadW, - ]; - let trace = build_trace_from_ops(operations, &stack); - - let rand_elements = rand_array::(); - let alpha = rand_elements[0]; - let aux_columns = trace.build_aux_trace(&rand_elements).unwrap(); - let b_range = aux_columns.get_column(B_RANGE_COL_IDX); - - assert_eq!(trace.length(), b_range.len()); - - // The memory section of the chiplets trace starts after the span hash. - let memory_start = HASH_CYCLE_LEN; - - // 40 rows are needed for 0, 3, 4, ... 36 bridge additional bridge rows of powers of - // 3 ..., 65535. (0 and 4 are both range-checked. 65535 is the max, and the rest are "bridge" - // values.) An extra row is added to pad the u16::MAX value. - let len_16bit = 40 + 1; - let values_start = trace.length() - len_16bit - NUM_RAND_ROWS; - - // The value should start at ONE and be unchanged until the memory processor section begins. - let mut expected = ONE; - for row in 0..memory_start { - assert_eq!(expected, b_range[row]); - } - - // --- Check the memory processor's range check lookups. -------------------------------------- - - // There are two memory lookups. For each memory lookup, the context and address are unchanged, - // so the delta values indicated the clock cycle change i' - i - 1. - // StoreW is executed at cycle 1 (after the initial span), so i' - i - 1 = 0. - let (d0_store, d1_store) = (ZERO, ZERO); - // LoadW is executed at cycle 6, so i' - i - 1 = 6 - 1 - 1 = 4. - let (d0_load, d1_load) = (Felt::new(4), ZERO); - - // Include the lookups from the `MStoreW` operation at the next row. - expected -= (alpha - d0_store).inv() + (alpha - d1_store).inv(); - assert_eq!(expected, b_range[memory_start + 1]); - // Include the lookup from the `MLoadW` operation at the next row. - expected -= (alpha - d0_load).inv() + (alpha - d1_load).inv(); - assert_eq!(expected, b_range[memory_start + 2]); - - // The value should be unchanged until the range checker's lookups are included. - for row in memory_start + 2..=values_start { - assert_eq!(expected, b_range[row]); - } - - // --- Check the range checker's lookups. ----------------------------------------------------- - - // We include 3 lookups of ZERO in the next row. - expected += alpha.inv().mul_base(Felt::new(3)); - assert_eq!(expected, b_range[values_start + 1]); - - // then we have one bridge row between 0 and 4 where the value does not change. - assert_eq!(expected, b_range[values_start + 2]); - - // We include 1 lookup of 4 in the next row. - expected += (alpha - d0_load).inv(); - assert_eq!(expected, b_range[values_start + 3]); - - // --- The value should now be ONE for the rest of the trace. --------------------------------- - assert_eq!(expected, ONE); - for i in (values_start + 3)..(b_range.len() - NUM_RAND_ROWS) { - assert_eq!(ONE, b_range[i]); - } -} diff --git a/processor/src/trace/tests/stack.rs b/processor/src/trace/tests/stack.rs index 6bebcf73a..b12ea31dc 100644 --- a/processor/src/trace/tests/stack.rs +++ b/processor/src/trace/tests/stack.rs @@ -2,9 +2,7 @@ use alloc::vec::Vec; use miden_air::trace::{AUX_TRACE_RAND_ELEMENTS, STACK_AUX_TRACE_OFFSET}; -use super::{ - build_trace_from_ops, rand_array, Felt, FieldElement, Operation, NUM_RAND_ROWS, ONE, ZERO, -}; +use super::{build_trace_from_ops, rand_array, Felt, FieldElement, Operation, ONE, ZERO}; use crate::stack::OverflowTableRow; // CONSTANTS @@ -92,7 +90,7 @@ fn p1_trace() { // at this point the table should be empty again, and it should stay empty until the end assert_eq!(expected_value, ONE); - for i in 13..(p1.len() - NUM_RAND_ROWS) { + for i in 13..p1.len() { assert_eq!(ONE, p1[i]); } } diff --git a/processor/src/trace/utils.rs b/processor/src/trace/utils.rs index 70e7f79a7..219b6e457 100644 --- a/processor/src/trace/utils.rs +++ b/processor/src/trace/utils.rs @@ -5,7 +5,7 @@ use miden_air::{trace::main_trace::MainTrace, RowIndex}; #[cfg(test)] use vm_core::{utils::ToElements, Operation}; -use super::{Felt, FieldElement, NUM_RAND_ROWS}; +use super::{Felt, FieldElement}; use crate::{chiplets::Chiplets, utils::uninit_vector}; // TRACE FRAGMENT @@ -124,7 +124,7 @@ impl TraceLenSummary { /// Returns `trace_len` rounded up to the next power of two. pub fn padded_trace_len(&self) -> usize { - (self.trace_len() + NUM_RAND_ROWS).next_power_of_two() + self.trace_len().next_power_of_two() } /// Returns the percent (0 - 100) of the steps that were added to the trace to pad it to the diff --git a/prover/Cargo.toml b/prover/Cargo.toml index 07033045f..4a76de984 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -23,7 +23,8 @@ std = ["air/std", "processor/std", "winter-prover/std"] air = { package = "miden-air", path = "../air", version = "0.10", default-features = false } processor = { package = "miden-processor", path = "../processor", version = "0.10", default-features = false } tracing = { version = "0.1", default-features = false, features = ["attributes"] } -winter-prover = { package = "winter-prover", version = "0.9", default-features = false } +winter-prover = { package = "winter-prover", git = "https://github.com/facebook/winterfell", branch = "logup-gkr", default-features = false } +winter-maybe-async = { package = "winter-maybe-async", git = "https://github.com/facebook/winterfell", branch = "logup-gkr", default-features = false } [target.'cfg(all(target_arch = "aarch64", target_os = "macos"))'.dependencies] elsa = { version = "1.9", optional = true } diff --git a/prover/src/gpu/metal/mod.rs b/prover/src/gpu/metal/mod.rs index 27e124e3c..e5f638d87 100644 --- a/prover/src/gpu/metal/mod.rs +++ b/prover/src/gpu/metal/mod.rs @@ -21,7 +21,7 @@ use winter_prover::{ matrix::{get_evaluation_offsets, ColMatrix, RowMatrix, Segment}, proof::Queries, CompositionPoly, CompositionPolyTrace, ConstraintCommitment, ConstraintCompositionCoefficients, - DefaultConstraintEvaluator, EvaluationFrame, Prover, StarkDomain, TraceInfo, TraceLde, + EvaluationFrame, LogUpGkrConstraintEvaluator, Prover, StarkDomain, TraceInfo, TraceLde, TracePolyTable, }; @@ -138,7 +138,7 @@ where type RandomCoin = R; type TraceLde> = MetalTraceLde; type ConstraintEvaluator<'a, E: FieldElement> = - DefaultConstraintEvaluator<'a, ProcessorAir, E>; + LogUpGkrConstraintEvaluator<'a, ProcessorAir, E>; fn get_pub_inputs(&self, trace: &ExecutionTrace) -> PublicInputs { self.execution_prover.get_pub_inputs(trace) diff --git a/prover/src/lib.rs b/prover/src/lib.rs index 2525a3e8e..99204bca0 100644 --- a/prover/src/lib.rs +++ b/prover/src/lib.rs @@ -21,9 +21,9 @@ use processor::{ }; use tracing::instrument; use winter_prover::{ - matrix::ColMatrix, ConstraintCompositionCoefficients, DefaultConstraintEvaluator, - DefaultTraceLde, ProofOptions as WinterProofOptions, Prover, StarkDomain, TraceInfo, - TracePolyTable, + crypto::MerkleTree as MerkleTreeVC, matrix::ColMatrix, ConstraintCompositionCoefficients, + DefaultTraceLde, LogUpGkrConstraintEvaluator, ProofOptions as WinterProofOptions, Prover, + StarkDomain, TraceInfo, TracePolyTable, }; #[cfg(feature = "std")] use {std::time::Instant, winter_prover::Trace}; @@ -70,7 +70,7 @@ where tracing::event!( tracing::Level::INFO, "Generated execution trace of {} columns and {} steps ({}% padded) in {} ms", - trace.info().main_trace_width(), + trace.info().main_segment_width(), trace.trace_len_summary().padded_trace_len(), trace.trace_len_summary().padding_percentage(), now.elapsed().as_millis() @@ -174,7 +174,7 @@ where impl Prover for ExecutionProver where - H: ElementHasher, + H: ElementHasher + Sync, R: RandomCoin + Send, { type BaseField = Felt; @@ -182,9 +182,11 @@ where type Trace = ExecutionTrace; type HashFn = H; type RandomCoin = R; - type TraceLde> = DefaultTraceLde; + type TraceLde> = DefaultTraceLde; type ConstraintEvaluator<'a, E: FieldElement> = - DefaultConstraintEvaluator<'a, ProcessorAir, E>; + LogUpGkrConstraintEvaluator<'a, ProcessorAir, E>; + + type VC = MerkleTreeVC; fn options(&self) -> &WinterProofOptions { &self.options @@ -220,17 +222,17 @@ where aux_rand_elements: Option>, composition_coefficients: ConstraintCompositionCoefficients, ) -> Self::ConstraintEvaluator<'a, E> { - DefaultConstraintEvaluator::new(air, aux_rand_elements, composition_coefficients) + LogUpGkrConstraintEvaluator::new( + air, + aux_rand_elements.expect("should contain randomness"), + composition_coefficients, + ) } - fn build_aux_trace( - &self, - trace: &Self::Trace, - aux_rand_elements: &AuxRandElements, - ) -> ColMatrix + fn build_aux_trace(&self, trace: &Self::Trace, aux_rand_elements: &[E]) -> ColMatrix where E: FieldElement, { - trace.build_aux_trace(aux_rand_elements.rand_elements()).unwrap() + trace.build_aux_trace(aux_rand_elements).unwrap() } } diff --git a/stdlib/Cargo.toml b/stdlib/Cargo.toml index 170fed6a8..bffc69030 100644 --- a/stdlib/Cargo.toml +++ b/stdlib/Cargo.toml @@ -48,8 +48,9 @@ serde_json = "1.0" sha2 = "0.10" sha3 = "0.10" test-utils = { package = "miden-test-utils", path = "../test-utils" } -winter-air = { package = "winter-air", version = "0.9" } -winter-fri = { package = "winter-fri", version = "0.9" } +winter-air = { package = "winter-air", git = "https://github.com/facebook/winterfell", branch = "logup-gkr" } +winter-crypto = { package = "winter-crypto", git = "https://github.com/facebook/winterfell", branch = "logup-gkr" } +winter-fri = { package = "winter-fri", git = "https://github.com/facebook/winterfell", branch = "logup-gkr" } [build-dependencies] diff --git a/stdlib/tests/collections/mmr.rs b/stdlib/tests/collections/mmr.rs index 4f514eee3..36fe1c548 100644 --- a/stdlib/tests/collections/mmr.rs +++ b/stdlib/tests/collections/mmr.rs @@ -439,7 +439,7 @@ fn test_mmr_pack_roundtrip() { mmr.add(init_merkle_leaf(2).into()); mmr.add(init_merkle_leaf(3).into()); - let accumulator = mmr.peaks(mmr.forest()).unwrap(); + let accumulator = mmr.peaks(); let hash = accumulator.hash_peaks(); // Set up the VM stack with the MMR hash, and its target address @@ -577,7 +577,7 @@ fn test_mmr_two() { mmr.add([ONE, Felt::new(2), Felt::new(3), Felt::new(4)].into()); mmr.add([Felt::new(5), Felt::new(6), Felt::new(7), Felt::new(8)].into()); - let accumulator = mmr.peaks(mmr.forest()).unwrap(); + let accumulator = mmr.peaks(); let peak = accumulator.peaks()[0]; let num_leaves = accumulator.num_leaves() as u64; @@ -619,7 +619,7 @@ fn test_mmr_large() { mmr.add([ZERO, ZERO, ZERO, Felt::new(6)].into()); mmr.add([ZERO, ZERO, ZERO, Felt::new(7)].into()); - let accumulator = mmr.peaks(mmr.forest()).unwrap(); + let accumulator = mmr.peaks(); let num_leaves = accumulator.num_leaves() as u64; let mut expected_memory = vec![num_leaves, 0, 0, 0]; @@ -644,7 +644,7 @@ fn test_mmr_large_add_roundtrip() { [ZERO, ZERO, ZERO, Felt::new(7)].into(), ]); - let old_accumulator = mmr.peaks(mmr.forest()).unwrap(); + let old_accumulator = mmr.peaks(); let hash = old_accumulator.hash_peaks(); // Set up the VM stack with the MMR hash, and its target address @@ -685,7 +685,7 @@ fn test_mmr_large_add_roundtrip() { mmr.add([ZERO, ZERO, ZERO, Felt::new(8)].into()); - let new_accumulator = mmr.peaks(mmr.forest()).unwrap(); + let new_accumulator = mmr.peaks(); let num_leaves = new_accumulator.num_leaves() as u64; let mut expected_memory = vec![num_leaves, 0, 0, 0]; let mut new_peaks = new_accumulator.peaks().to_vec(); diff --git a/stdlib/tests/crypto/fri/channel.rs b/stdlib/tests/crypto/fri/channel.rs index fd10128bf..e3896ebfd 100644 --- a/stdlib/tests/crypto/fri/channel.rs +++ b/stdlib/tests/crypto/fri/channel.rs @@ -5,6 +5,7 @@ use test_utils::{ serde::DeserializationError, Felt, FieldElement, StarkField, }; +use winter_crypto::MerkleTree as MerkleTreeVC; use winter_fri::{FriProof, VerifierError}; pub trait UnBatch { @@ -25,8 +26,8 @@ pub struct MidenFriVerifierChannel MidenFriVerifierChannel where - E: FieldElement, - H: ElementHasher, + E: FieldElement, + H: ElementHasher + ElementHasher, { /// Builds a new verifier channel from the specified [FriProof]. /// @@ -40,7 +41,7 @@ where ) -> Result { let remainder = proof.parse_remainder()?; let (layer_queries, layer_proofs) = - proof.parse_layers::(domain_size, folding_factor)?; + proof.parse_layers::>(domain_size, folding_factor)?; Ok(MidenFriVerifierChannel { layer_commitments, diff --git a/stdlib/tests/crypto/fri/verifier_fri_e2f4.rs b/stdlib/tests/crypto/fri/verifier_fri_e2f4.rs index a8eef9b4e..a16d6b0f6 100644 --- a/stdlib/tests/crypto/fri/verifier_fri_e2f4.rs +++ b/stdlib/tests/crypto/fri/verifier_fri_e2f4.rs @@ -10,6 +10,7 @@ use test_utils::{ math::fft, Felt, FieldElement, QuadFelt as QuadExt, StarkField, EMPTY_WORD, }; +use winter_crypto::MerkleTree as MerkleTreeVC; use winter_fri::{ folding::fold_positions, DefaultProverChannel, FriOptions, FriProof, FriProver, VerifierError, }; @@ -63,10 +64,10 @@ pub fn fri_prove_verify_fold4_ext2(trace_length_e: usize) -> Result = build_evaluations(trace_length, lde_blowup); // instantiate the prover and generate the proof - let mut prover = FriProver::new(options.clone()); + let mut prover = FriProver::<_, _, _, MerkleTreeVC>::new(options.clone()); prover.build_layers(&mut channel, evaluations.clone()); let positions = channel.draw_query_positions(nonce); let proof = prover.build_proof(&positions); @@ -412,21 +413,18 @@ impl UnBatch for MidenFriVerifierChannel(query); + let leaves: Vec = + x.iter().map(|row| MidenHasher::hash_elements(row)).collect(); + let unbatched_proof = layer_proof.into_openings(&leaves, &folded_positions).unwrap(); + assert_eq!(x.len(), unbatched_proof.len()); - let nodes: Vec<[Felt; 4]> = unbatched_proof - .iter_mut() - .map(|list| { - let node = list.remove(0); - let node = node.as_elements().to_owned(); - [node[0], node[1], node[2], node[3]] - }) - .collect(); + let nodes: Vec<[Felt; 4]> = + leaves.iter().map(|leaf| [leaf[0], leaf[1], leaf[2], leaf[3]]).collect(); let paths: Vec = - unbatched_proof.into_iter().map(|list| list.into()).collect(); + unbatched_proof.into_iter().map(|list| list.1.into()).collect(); let iter_pos = folded_positions.iter_mut().map(|a| *a as u64); let nodes_tmp = nodes.clone(); diff --git a/stdlib/tests/crypto/stark/verifier_recursive/channel.rs b/stdlib/tests/crypto/stark/verifier_recursive/channel.rs index d52d5d57a..74e712b32 100644 --- a/stdlib/tests/crypto/stark/verifier_recursive/channel.rs +++ b/stdlib/tests/crypto/stark/verifier_recursive/channel.rs @@ -14,6 +14,7 @@ use winter_air::{ proof::{Proof, Queries, Table, TraceOodFrame}, Air, }; +use winter_crypto::MerkleTree as MerkleTreeVC; use winter_fri::{folding::fold_positions, VerifierChannel as FriVerifierChannel}; pub type QuadExt = QuadExtension; @@ -68,7 +69,7 @@ impl VerifierChannel { } let num_trace_segments = air.trace_info().num_segments(); - let main_trace_width = air.trace_info().main_trace_width(); + let main_trace_width = air.trace_info().main_segment_width(); let aux_trace_width = air.trace_info().aux_segment_width(); let lde_domain_size = air.lde_domain_size(); let fri_options = air.options().to_fri_options(); @@ -89,7 +90,10 @@ impl VerifierChannel { .parse_remainder() .map_err(|err| VerifierError::ProofDeserializationError(err.to_string()))?; let (fri_layer_queries, fri_layer_proofs) = fri_proof - .parse_layers::(lde_domain_size, fri_options.folding_factor()) + .parse_layers::>( + lde_domain_size, + fri_options.folding_factor(), + ) .map_err(|err| VerifierError::ProofDeserializationError(err.to_string()))?; // --- parse out-of-domain evaluation frame ----------------------------------------------- @@ -243,21 +247,15 @@ impl VerifierChannel { let layer_proof = layer_proofs.remove(0); - let mut unbatched_proof = layer_proof.into_paths(&folded_positions).unwrap(); let x = group_slice_elements::(query); - assert_eq!(x.len(), unbatched_proof.len()); + let leaves: Vec = x.iter().map(|row| Rpo256::hash_elements(row)).collect(); + let unbatched_proof = layer_proof.into_openings(&leaves, &folded_positions).unwrap(); - let nodes: Vec<[Felt; 4]> = unbatched_proof - .iter_mut() - .map(|list| { - let node = list.remove(0); - let node = node.as_elements().to_owned(); - [node[0], node[1], node[2], node[3]] - }) - .collect(); + let nodes: Vec<[Felt; 4]> = + leaves.iter().map(|leaf| [leaf[0], leaf[1], leaf[2], leaf[3]]).collect(); let paths: Vec = - unbatched_proof.into_iter().map(|list| list.into()).collect(); + unbatched_proof.into_iter().map(|list| list.1.into()).collect(); let iter_pos = folded_positions.iter_mut().map(|a| *a as u64); let nodes_tmp = nodes.clone(); @@ -292,6 +290,7 @@ impl VerifierChannel { impl FriVerifierChannel for VerifierChannel { type Hasher = Rpo256; + type VectorCommitment = MerkleTreeVC; fn read_fri_num_partitions(&self) -> usize { self.fri_num_partitions @@ -338,10 +337,14 @@ impl TraceQueries { ) -> Result { // parse main trace segment queries; parsing also validates that hashes of each table row // form the leaves of Merkle authentication paths in the proofs - let main_segment_width = air.trace_info().main_trace_width(); + let main_segment_width = air.trace_info().main_segment_width(); let main_segment_queries = queries.remove(0); let (main_segment_query_proofs, main_segment_states) = main_segment_queries - .parse::(air.lde_domain_size(), num_queries, main_segment_width) + .parse::>( + air.lde_domain_size(), + num_queries, + main_segment_width, + ) .map_err(|err| { VerifierError::ProofDeserializationError(format!( "main trace segment query deserialization failed: {err}" @@ -359,7 +362,11 @@ impl TraceQueries { let aux_segment_queries = queries.remove(0); let (segment_query_proof, segment_trace_states) = aux_segment_queries - .parse::(air.lde_domain_size(), num_queries, segment_width) + .parse::>( + air.lde_domain_size(), + num_queries, + segment_width, + ) .map_err(|err| { VerifierError::ProofDeserializationError(format!( "auxiliary trace segment query deserialization failed: {err}" @@ -401,7 +408,11 @@ impl ConstraintQueries { num_queries: usize, ) -> Result { let (query_proofs, evaluations) = queries - .parse::(air.lde_domain_size(), num_queries, air.ce_blowup_factor()) + .parse::>( + air.lde_domain_size(), + num_queries, + air.ce_blowup_factor(), + ) .map_err(|err| { VerifierError::ProofDeserializationError(format!( "constraint evaluation query deserialization failed: {err}" @@ -420,18 +431,14 @@ pub fn unbatch_to_partial_mt( queries: Vec>, proof: BatchMerkleProof, ) -> (PartialMerkleTree, Vec<(RpoDigest, Vec)>) { - let mut unbatched_proof = proof.into_paths(&positions).unwrap(); + let leaves: Vec = queries.iter().map(|row| Rpo256::hash_elements(row)).collect(); + + let unbatched_proof = proof.into_openings(&leaves, &positions).unwrap(); let mut adv_key_map = Vec::new(); - let nodes: Vec<[Felt; 4]> = unbatched_proof - .iter_mut() - .map(|list| { - let node = list.remove(0); - let node = node.as_elements().to_owned(); - [node[0], node[1], node[2], node[3]] - }) - .collect(); + let nodes: Vec<[Felt; 4]> = + queries.iter().map(|node| [node[0], node[1], node[2], node[3]]).collect(); - let paths: Vec = unbatched_proof.into_iter().map(|list| list.into()).collect(); + let paths: Vec = unbatched_proof.into_iter().map(|list| list.1.into()).collect(); let iter_pos = positions.iter_mut().map(|a| *a as u64); let nodes_tmp = nodes.clone(); diff --git a/test-utils/Cargo.toml b/test-utils/Cargo.toml index 0d6ac384b..bd2a0098b 100644 --- a/test-utils/Cargo.toml +++ b/test-utils/Cargo.toml @@ -35,7 +35,7 @@ prover = { package = "miden-prover", path = "../prover", version = "0.10", defau test-case = "3.2" verifier = { package = "miden-verifier", path = "../verifier", version = "0.10", default-features = false } vm-core = { package = "miden-core", path = "../core", version = "0.10", default-features = false } -winter-prover = { package = "winter-prover", version = "0.9", default-features = false } +winter-prover = { package = "winter-prover", git = "https://github.com/facebook/winterfell", branch = "logup-gkr", default-features = false } [target.'cfg(target_family = "wasm")'.dependencies] pretty_assertions = { version = "1.4", default-features = false, features = [ @@ -45,4 +45,4 @@ pretty_assertions = { version = "1.4", default-features = false, features = [ [target.'cfg(not(target_family = "wasm"))'.dependencies] pretty_assertions = "1.4" proptest = "1.4" -rand-utils = { package = "winter-rand-utils", version = "0.9" } +rand-utils = { package = "winter-rand-utils", git = "https://github.com/facebook/winterfell", branch = "logup-gkr" } diff --git a/verifier/Cargo.toml b/verifier/Cargo.toml index a52ef8293..f54633ae7 100644 --- a/verifier/Cargo.toml +++ b/verifier/Cargo.toml @@ -25,4 +25,4 @@ std = ["air/std", "vm-core/std", "winter-verifier/std"] air = { package = "miden-air", path = "../air", version = "0.10", default-features = false } tracing = { version = "0.1", default-features = false, features = ["attributes"] } vm-core = { package = "miden-core", path = "../core", version = "0.10", default-features = false } -winter-verifier = { package = "winter-verifier", version = "0.9", default-features = false } +winter-verifier = { package = "winter-verifier", git = "https://github.com/facebook/winterfell", branch = "logup-gkr", default-features = false } diff --git a/verifier/src/lib.rs b/verifier/src/lib.rs index e015f110a..0ccf8fda2 100644 --- a/verifier/src/lib.rs +++ b/verifier/src/lib.rs @@ -16,7 +16,7 @@ use vm_core::crypto::{ // EXPORTS // ================================================================================================ pub use vm_core::{chiplets::hasher::Digest, Kernel, ProgramInfo, StackInputs, StackOutputs, Word}; -use winter_verifier::verify as verify_proof; +use winter_verifier::{crypto::MerkleTree, verify as verify_proof}; pub use winter_verifier::{AcceptableOptions, VerifierError}; pub mod math { pub use vm_core::{Felt, FieldElement, StarkField}; @@ -69,25 +69,33 @@ pub fn verify( match hash_fn { HashFunction::Blake3_192 => { let opts = AcceptableOptions::OptionSet(vec![ProvingOptions::REGULAR_96_BITS]); - verify_proof::>(proof, pub_inputs, &opts) + verify_proof::, MerkleTree<_>>( + proof, pub_inputs, &opts, + ) }, HashFunction::Blake3_256 => { let opts = AcceptableOptions::OptionSet(vec![ProvingOptions::REGULAR_128_BITS]); - verify_proof::>(proof, pub_inputs, &opts) + verify_proof::, MerkleTree<_>>( + proof, pub_inputs, &opts, + ) }, HashFunction::Rpo256 => { let opts = AcceptableOptions::OptionSet(vec![ ProvingOptions::RECURSIVE_96_BITS, ProvingOptions::RECURSIVE_128_BITS, ]); - verify_proof::(proof, pub_inputs, &opts) + verify_proof::>( + proof, pub_inputs, &opts, + ) }, HashFunction::Rpx256 => { let opts = AcceptableOptions::OptionSet(vec![ ProvingOptions::RECURSIVE_96_BITS, ProvingOptions::RECURSIVE_128_BITS, ]); - verify_proof::(proof, pub_inputs, &opts) + verify_proof::>( + proof, pub_inputs, &opts, + ) }, } .map_err(VerificationError::VerifierError)?;