diff --git a/CHANGELOG.md b/CHANGELOG.md index 32eb70d36c..273cbb9dd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,8 @@ - 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) - [BREAKING] The `run` and the `prove` commands in the cli will accept `--trace` flag instead of `--tracing` (#1502) - +- Migrated to new padding rule for RPO (#1343). +- Migrated to `miden-crypto` v0.11.0 (#1343). #### Fixes @@ -26,13 +27,9 @@ - Fixed a bug in the block stack table (#1511) (#1512) - Fixed the construction of the chiplets virtual table (#1514) - Fixed the construction of the chiplets bus (#1516) (#1525) - -#### Fixes - - Decorators are now allowed in empty basic blocks (#1466) - -## 0.10.6 (2024-09-12) - `miden-processor` crate only. +## 0.10.6 (2024-09-12) - `miden-processor` crate only #### Enhancements @@ -159,6 +156,8 @@ #### Stdlib - Added `init_no_padding` procedure to `std::crypto::hashes::native` (#1313). +- [BREAKING] `native` module was renamed to the `rpo`, `hash_memory` procedure was renamed to the `hash_memory_words` (#1368). +- Added `hash_memory` procedure to `std::crypto::hashes::rpo` (#1368). #### VM Internals diff --git a/Cargo.lock b/Cargo.lock index 2fb9a2eef8..314f8ec42b 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" @@ -129,23 +129,23 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[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]] @@ -219,7 +219,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" dependencies = [ "memchr", - "regex-automata 0.4.7", + "regex-automata 0.4.8", "serde", ] @@ -243,9 +243,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.15" +version = "1.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" +checksum = "9540e661f81799159abee814118cc139a2004b3a3aa3ea37724a1b66530b90e0" dependencies = [ "jobserver", "libc", @@ -287,9 +287,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.16" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" +checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3" dependencies = [ "clap_builder", "clap_derive", @@ -297,9 +297,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b" dependencies = [ "anstream", "anstyle", @@ -309,9 +309,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck", "proc-macro2", @@ -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", @@ -870,7 +870,7 @@ dependencies = [ "lalrpop-util", "petgraph", "regex", - "regex-syntax 0.8.4", + "regex-syntax 0.8.5", "string_cache", "term", "tiny-keccak", @@ -892,9 +892,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.158" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libm" @@ -1052,9 +1052,9 @@ dependencies = [ [[package]] name = "miden-crypto" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6fad06fc3af260ed3c4235821daa2132813d993f96d446856036ae97e9606dd" +checksum = "1e0ca714c8242f329b9ea6f1a5bf0e93f1490f348f982e3a606d91b884254308" dependencies = [ "blake3", "cc", @@ -1259,11 +1259,11 @@ dependencies = [ [[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,18 +1405,21 @@ 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", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" +dependencies = [ + "portable-atomic", +] [[package]] name = "oorandom" @@ -1432,9 +1435,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 +1501,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 +1514,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", ] @@ -1530,6 +1533,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" +[[package]] +name = "portable-atomic" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" + [[package]] name = "ppv-lite86" version = "0.2.20" @@ -1577,9 +1586,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", @@ -1608,7 +1617,7 @@ dependencies = [ "rand", "rand_chacha", "rand_xorshift", - "regex-syntax 0.8.4", + "regex-syntax 0.8.5", "rusty-fork", "tempfile", "unarray", @@ -1690,9 +1699,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags 2.6.0", ] @@ -1710,14 +1719,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.6" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", + "regex-automata 0.4.8", + "regex-syntax 0.8.5", ] [[package]] @@ -1731,13 +1740,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.4", + "regex-syntax 0.8.5", ] [[package]] @@ -1748,9 +1757,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustc-demangle" @@ -1778,9 +1787,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 +1885,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 +1905,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", @@ -1908,9 +1917,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -2011,9 +2020,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 +2041,9 @@ checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" [[package]] name = "syn" -version = "2.0.76" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -2043,9 +2052,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.12.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if", "fastrand", @@ -2136,18 +2145,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", @@ -2206,9 +2215,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.20" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap", "serde", @@ -2320,9 +2329,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,21 +2341,21 @@ 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" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-xid" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "utf8parse" @@ -2727,9 +2736,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] @@ -2772,9 +2781,9 @@ dependencies = [ [[package]] name = "winter-math" -version = "0.9.0" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "004f85bb051ce986ec0b9a2bd90aaf81b83e3c67464becfdf7db31f14c1019ba" +checksum = "5b0e685b3b872d82e58a86519294a814b7bc7a4d3cd2c93570a7d80c0c5a1aba" dependencies = [ "winter-utils", ] @@ -2817,9 +2826,9 @@ dependencies = [ [[package]] name = "winter-utils" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0568612a95bcae3c94fb14da2686f8279ca77723dbdf1e97cf3673798faf6485" +checksum = "961e81e9388877a25db1c034ba38253de2055f569633ae6a665d857a0556391b" dependencies = [ "rayon", ] @@ -2839,9 +2848,9 @@ dependencies = [ [[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/Cargo.toml b/Cargo.toml index ac69f241ed..30d5cdbdff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ resolver = "2" [workspace.package] edition = "2021" -rust-version = "1.80" +rust-version = "1.82" license = "MIT" readme = "README.md" authors = ["Miden contributors"] diff --git a/assembly/src/assembler/instruction/crypto_ops.rs b/assembly/src/assembler/instruction/crypto_ops.rs index 0031f1a79d..54e6a2acff 100644 --- a/assembly/src/assembler/instruction/crypto_ops.rs +++ b/assembly/src/assembler/instruction/crypto_ops.rs @@ -1,4 +1,4 @@ -use vm_core::{AdviceInjector, Operation::*}; +use vm_core::{AdviceInjector, Felt, Operation::*}; use super::BasicBlockBuilder; use crate::AssemblyError; @@ -16,10 +16,10 @@ use crate::AssemblyError; /// To perform the operation we do the following: /// 1. Prepare the stack with 12 elements for HPERM by pushing 4 more elements for the capacity, /// then reordering the stack and pushing an additional 4 elements so that the stack looks like: -/// [0, 0, 0, 1, a3, a2, a1, a0, 0, 0, 0, 1, ...]. The first capacity element is set to ONE as -/// we are hashing a number of elements which is not a multiple of the rate width. We also set -/// the next element in the rate after `A` to ONE. All other capacity and rate elements are set -/// to ZERO, in accordance with the RPO rules. +/// [0, 0, 0, 0, a3, a2, a1, a0, 0, 0, 0, 4, ...]. The first capacity element is set to Felt(4) +/// as we are hashing a number of elements which is equal to 4 modulo the rate width, while the +/// other capacity elements are set to ZERO. A sequence of 4 ZERO elements is used as padding. +/// The padding rule used follows the one described in this [work](https://eprint.iacr.org/2023/1045). /// 2. Append the HPERM operation, which performs a permutation of RPO on the top 12 elements and /// leaves the an output of [D, C, B, ...] on the stack. C is our 1-to-1 has result. /// 3. Drop D and B to achieve our result [C, ...] @@ -28,14 +28,15 @@ use crate::AssemblyError; pub(super) fn hash(block_builder: &mut BasicBlockBuilder) { #[rustfmt::skip] let ops = [ - // add 4 elements to the stack to be used as the capacity elements for the RPO permutation - Pad, Incr, Pad, Pad, Pad, + // add 4 elements to the stack to be used as the capacity elements for the RPO permutation. + // Since we are hashing 4 field elements, the first capacity element is set to 4. + Push(Felt::from(4_u32)), Pad, Pad, Pad, // swap capacity elements such that they are below the elements to be hashed SwapW, - // Duplicate capacity elements in the rate portion of the stack - Dup7, Dup7, Dup7, Dup7, + // add 4 ZERO elements for the second half of the rate portion + Pad, Dup7, Dup7, Dup7, // Apply a hashing permutation on the top 12 elements in the stack HPerm, diff --git a/assembly/src/ast/instruction/print.rs b/assembly/src/ast/instruction/print.rs index a76239f70e..b7ca11c37c 100644 --- a/assembly/src/ast/instruction/print.rs +++ b/assembly/src/ast/instruction/print.rs @@ -427,7 +427,7 @@ mod tests { let target = InvocationTarget::MastRoot(Span::unknown(digest)); let instruction = format!("{}", Instruction::Exec(target)); assert_eq!( - "exec.0x03b49d98981575360dd1f8c8b5a7feefcadadd56ec2a33e3e43edae3577de150", + "exec.0x90b3926941061b28638b6cc0bbdb3bcb335e834dc9ab8044250875055202d2fe", instruction ); } diff --git a/core/Cargo.toml b/core/Cargo.toml index ae7da5c505..aa23ce30d1 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -34,7 +34,7 @@ std = [ lock_api = { version = "0.4", features = ["arc_lock"] } math = { package = "winter-math", version = "0.9", default-features = false } memchr = { version = "2.7", default-features = false } -miden-crypto = { version = "0.10", default-features = false } +miden-crypto = { version = "0.11", 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", diff --git a/processor/src/chiplets/mod.rs b/processor/src/chiplets/mod.rs index b098a57606..63a463141d 100644 --- a/processor/src/chiplets/mod.rs +++ b/processor/src/chiplets/mod.rs @@ -74,6 +74,7 @@ mod tests; /// - columns 3-17: unused columns padded with ZERO /// /// The following is a pictorial representation of the chiplet module: +/// ```text /// +---+-------------------------------------------------------+-------------+ /// | 0 | | |-------------| /// | . | Hash chiplet | Hash chiplet |-------------| @@ -111,6 +112,7 @@ mod tests; /// | . | . | . | . |---------------------------------------------------------| /// | 1 | 1 | 1 | 1 |---------------------------------------------------------| /// +---+---+---+---+---------------------------------------------------------+ +/// ``` pub struct Chiplets { /// Current clock cycle of the VM. clk: RowIndex, diff --git a/prover/src/gpu/metal/mod.rs b/prover/src/gpu/metal/mod.rs index 27e124e3ce..930253b5fc 100644 --- a/prover/src/gpu/metal/mod.rs +++ b/prover/src/gpu/metal/mod.rs @@ -688,7 +688,7 @@ where E: FieldElement, I: IntoIterator>; -impl Iterator for SegmentIterator<'_, '_, E, I, N> +impl Iterator for SegmentIterator where E: FieldElement, I: IntoIterator>, diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 11ec1f8414..a1c01e0415 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,5 +1,5 @@ [toolchain] -channel = "1.80" +channel = "1.82" components = ["rustfmt", "rust-src", "clippy"] targets = ["wasm32-unknown-unknown"] profile = "minimal" diff --git a/stdlib/asm/collections/mmr.masm b/stdlib/asm/collections/mmr.masm index 3f50adfb09..4ed948fc62 100644 --- a/stdlib/asm/collections/mmr.masm +++ b/stdlib/asm/collections/mmr.masm @@ -1,5 +1,5 @@ use.std::mem -use.std::crypto::hashes::native +use.std::crypto::hashes::rpo use.std::math::u64 #! Loads the leaf at the absolute `pos` in the MMR. @@ -165,7 +165,7 @@ export.unpack # => [C, B, A, mmr_ptr+17, HASH, ...] # drop anything but the hash result, word B (11 cycles) - dropw swapw dropw movup.4 drop + exec.rpo::squeeze_digest movup.4 drop # => [B, HASH, ...] # assert on the resulting hash (11 cycles) @@ -196,8 +196,8 @@ export.pack # hash the memory contents (25 + 3 * num_peaks) padw padw padw - exec.native::hash_memory_even - exec.native::state_to_digest + exec.rpo::absorb_double_words_from_memory + exec.rpo::squeeze_digest # => [HASH, peaks_end, peaks_end, mmr_ptr, ...] # prepare stack for adv.insert_mem (4 cycles) diff --git a/stdlib/asm/crypto/dsa/rpo_falcon512.masm b/stdlib/asm/crypto/dsa/rpo_falcon512.masm index 5cb418dce3..637f490bf9 100644 --- a/stdlib/asm/crypto/dsa/rpo_falcon512.masm +++ b/stdlib/asm/crypto/dsa/rpo_falcon512.masm @@ -1,3 +1,5 @@ +use.std::crypto::hashes::rpo + # CONSTANTS # ================================================================================================= @@ -224,7 +226,7 @@ export.load_h_s2_and_product.1 end # 6) Return the challenge point and the incremented pointer - dropw swapw dropw + exec.rpo::squeeze_digest drop drop #=> [tau1, tau0, ptr + 512] end diff --git a/stdlib/asm/crypto/hashes/native.masm b/stdlib/asm/crypto/hashes/native.masm deleted file mode 100644 index 1cd8ac3355..0000000000 --- a/stdlib/asm/crypto/hashes/native.masm +++ /dev/null @@ -1,102 +0,0 @@ -#! Prepares the top of the stack with the hasher initial state. -#! -#! This procedures does not handle padding, therefore, the user is expected to -#! consume an amount of data which is a multiple of the rate (2 words). -#! -#! Input: [] -#! Ouptut: [PERM, PERM, PERM, ...] -#! Cycles: 12 -export.init_no_padding - padw padw padw -end - -#! Given the hasher state, returns the hash output -#! -#! Input: [C, B, A, ...] -#! Ouptut: [HASH, ...] -#! Where: For the native RPO hasher HASH is B. -#! Cycles: 9 -export.state_to_digest - # drop the first rate word (4 cycles) - dropw - - # save the hash result (1 cycles) - swapw - - # drop the capacity word (4 cycles) - dropw -end - -#! Hashes the memory `start_addr` to `end_addr`. -#! -#! This requires that `end_addr=start_addr + 2n + 1`, otherwise the procedure will enter an infinite -#! loop. `end_addr` is not inclusive. -#! -#! Stack transition: -#! Input: [C, B, A, start_addr, end_addr, ...] -#! Output: [C', B', A', end_addr, end_addr ...] -#! Cycles: 4 + 3 * words, where `words` is the `start_addr - end_addr - 1` -#! -#! Where `A` is the capacity word that will be used by the hashing function, and `B'` the hash output. -export.hash_memory_even - dup.13 dup.13 neq # (4 cycles ) - while.true - mem_stream hperm # (2 cycles) - dup.13 dup.13 neq # (4 cycles ) - end -end - -#! Hashes the memory `start_addr` to `end_addr`, handles odd number of elements. -#! -#! Requires `start_addr < end_addr`, `end_addr` is not inclusive. -#! -#! Stack transition: -#! Input: [start_addr, end_addr, ...] -#! Output: [H, ...] -#! Cycles: -#! even words: 48 cycles + 3 * words -#! odd words: 60 cycles + 3 * words -export.hash_memory - # enforce `start_addr < end_addr` - dup.1 dup.1 u32assert2 u32gt assert - - # figure out if the range is for an odd number of words (9 cycles) - dup.1 dup.1 sub is_odd - # stack: [is_odd, start_addr, end_addr, ...] - - # make the start/end range even (4 cycles) - movup.2 dup.1 sub - # stack: [end_addr, is_odd, start_addr, ...] - - # move start_addr to the right stack position (1 cycles) - movup.2 - # stack: [start_addr, end_addr, is_odd, ...] - - # prepare hasher state (12 cycles) - dup.2 push.0.0.0 padw padw - # stack: [C, B, A, start_addr, end_addr, is_odd, ...] - - # (4 + 3 * words cycles) - exec.hash_memory_even - - # (1 cycles) - movup.14 - - # handle the odd element, if any (12 cycles) - if.true - # start_addr and end_addr are equal after calling `hash_memory_even`, and both point - # to the last element. Load the last word (2 cycles) - dup.13 mem_loadw - - # set the padding (9 cycles) - swapw dropw push.1.0.0.0 - - # (1 cycles) - hperm - end - - exec.state_to_digest - - # drop start_addr/end_addr (4 cycles) - movup.4 drop movup.4 drop -end diff --git a/stdlib/asm/crypto/hashes/rpo.masm b/stdlib/asm/crypto/hashes/rpo.masm new file mode 100644 index 0000000000..1035fa464d --- /dev/null +++ b/stdlib/asm/crypto/hashes/rpo.masm @@ -0,0 +1,266 @@ +#! Prepares the top of the stack with the hasher initial state. +#! +#! This procedures does not handle padding, therefore, the user is expected to +#! consume an amount of data which is a multiple of the rate (2 words). +#! +#! Input: [] +#! Ouptut: [PERM, PERM, PERM, ...] +#! +#! Cycles: 12 +export.init_no_padding + padw padw padw +end + +#! Given the hasher state, returns the hash output. +#! +#! Input: [C, B, A, ...] +#! Ouptut: [HASH, ...] +#! +#! Where : +#! - `A` is the capacity word that will be used by the hashing function. +#! - `B` is the hash output. +#! +#! Cycles: 9 +export.squeeze_digest + # drop the first rate word (4 cycles) + dropw + + # save the hash result (1 cycles) + swapw + + # drop the capacity word (4 cycles) + dropw +end + +#! Hashes the memory `start_addr` to `end_addr` given an RPO state specified by 3 words. +#! +#! This requires that `end_addr = start_addr + 2n` where n = {0, 1, 2 ...}, otherwise the procedure +#! will enter an infinite loop. +#! +#! Input: [C, B, A, start_addr, end_addr, ...] +#! Output: [C', B', A', end_addr, end_addr ...] +#! +#! Where : +#! - `A` is the capacity word that will be used by the hashing function. +#! - `B` is the hash output. +#! +#! Cycles: 4 + 3 * words, where `words` is the `start_addr - end_addr` +export.absorb_double_words_from_memory + dup.13 dup.13 neq # (4 cycles ) + while.true + mem_stream hperm # (2 cycles) + dup.13 dup.13 neq # (4 cycles ) + end +end + +#! Hashes the memory `start_addr` to `end_addr`, handles odd number of elements. +#! +#! Requires `start_addr ≤ end_addr`, `end_addr` is not inclusive. +#! +#! Input: [start_addr, end_addr, ...] +#! Output: [H, ...] +#! +#! Cycles: +#! - even words: 49 cycles + 3 * words +#! - odd words: 61 cycles + 3 * words +#! where `words` is the `start_addr - end_addr - 1` +export.hash_memory_words + # enforce `start_addr ≤ end_addr` + dup.1 dup.1 u32assert2 u32gte assert + + # figure out if the range is for an odd number of words (9 cycles) + dup.1 dup.1 sub is_odd + # => [is_odd, start_addr, end_addr, ...] + + # make the start/end range even (4 cycles) + movup.2 dup.1 sub + # => [end_addr, is_odd, start_addr, ...] + + # move start_addr to the right stack position (1 cycles) + movup.2 + # => [start_addr, end_addr, is_odd, ...] + + # prepare hasher state (14 cycles) + dup.2 mul.4 push.0.0.0 padw padw + # => [C, B, A, start_addr, end_addr, is_odd, ...] + + # (4 + 3 * words cycles) + exec.absorb_double_words_from_memory + # => [C', B', A', end_addr, end_addr, is_odd, ...] + + # (1 cycles) + movup.14 + # => [is_odd, C', B', A', end_addr, end_addr, ...] + + # handle the odd element, if any (12 cycles) + if.true + # start_addr and end_addr are equal after calling `absorb_double_words_from_memory`, and both + # point to the last element. Load the last word (6 cycles) + dropw dup.9 mem_loadw + # => [D, A', end_addr, end_addr, ...] + + # set the padding and compute the permutation (5 cycles) + padw hperm + end + + exec.squeeze_digest + # => [HASH, end_addr, end_addr, ...] + + # drop start_addr/end_addr (4 cycles) + movup.4 drop movup.4 drop + # => [HASH] +end + +#! Computes hash of Felt values starting at the specified memory address. +#! +#! This procedure divides the hashing process into two parts: hashing pairs of words using +#! `absorb_double_words_from_memory` procedure and hashing the remaining values using the `hperm` +#! instruction. +#! +#! Inputs: [ptr, num_elements] +#! Outputs: [HASH] +#! +#! Cycles: +#! - If number of elements divides by 8: 47 cycles + 3 * words +#! - Else: 180 cycles + 3 * words +#! where `words` is the number of quads of input values. +export.hash_memory + # move number of inputs to the top of the stack + swap + # => [num_elements, ptr] + + # get the number of double words + u32divmod.8 swap + # => [num_elements/8, num_elements%8, ptr] + + # get the end_addr for hash_memory_even procedure (end address for pairs of words) + mul.2 dup.2 add movup.2 + # => [ptr, end_addr, num_elements%8] + + # get the capacity element which is equal to num_elements%8 + dup.2 + # => [capacity, ptr, end_addr, num_elements%8] + + # prepare hasher state for RPO permutation + push.0.0.0 padw padw + # => [C, B, A, ptr, end_addr, num_elements%8] + + # hash every pair of words + exec.absorb_double_words_from_memory + # => [C', B', A', ptr', end_addr, num_elements%8] where ptr' = end_addr + + # hash remaining input values if there are any left + # if num_elements%8 is ZERO and there are no elements to hash + dup.14 eq.0 + if.true + # clean the stack + exec.squeeze_digest + swapw drop drop drop movdn.4 + # => [B'] + else + # load the remaining double word + mem_stream + # => [E, D, A', ptr'+2, end_addr, num_elements%8] + + # clean the stack + movup.12 drop movup.12 drop + # => [E, D, A', num_elements%8] + + # get the number of elements we need to drop + # notice that drop_counter could be any number from 1 to 7 + push.8 movup.13 sub movdn.12 + # => [E, D, A', drop_counter] + + ### 0th value ######################################################## + + # we need to drop first value anyway, since number of values is not divisible by 8 + # push the padding 0 on to the stack and move it down to the 6th position + drop push.0 movdn.6 + # => [e_2, e_1, e_0, d_3, d_2, d_1, 0, d_0, A', drop_counter] + + ### 1st value ######################################################## + + # prepare the second element of the E Word for cdrop instruction + push.0 swap + # => [e_2, 0, e_1, e_0, d_3, d_2, d_1, 0, d_0, A', drop_counter] + + # push latch variable onto the stack; this will be the control for the cdrop instruction + push.0 + # => [latch = 0, e_2, 0, e_1, e_0, d_3, d_2, d_1, 0, d_0, A', drop_counter] + + # get the flag whether the drop counter is equal 1 + dup.14 eq.1 + # => [drop_counter == 1, latch = 0, e_2, 0, e_1, e_0, d_3, d_2, d_1, 0, d_0, A', drop_counter] + + # update the latch: if drop_counter == 1, latch will become 1 + or + # => [latch', e_2, 0, e_1, e_0, d_3, d_2, d_1, 0, d_0, A', drop_counter] + + # save the latch value + dup movdn.14 + # => [latch', e_2, 0, e_1, e_0, d_3, d_2, d_1, 0, d_0, A', latch', drop_counter] + + # if latch == 1, drop 0; otherwise drop e_1 + cdrop + # => [e_2_or_0, e_1, e_0, d_3, d_2, d_1, 0, d_0, A', latch', drop_counter] + + # move the calculated value down the stack + movdn.6 + # => [e_1, e_0, d_3, d_2, d_1, 0, e_2_or_0, d_0, A', latch', drop_counter] + + ### 2nd value ######################################################## + + # repeat the above process but now compare drop_counter to 2 + push.0 swap + movup.13 dup.14 eq.2 or + dup movdn.14 + cdrop movdn.6 + # => [e_0, d_3, d_2, d_1, 0, e_2_or_0, e_1_or_0, d_0, A', latch', drop_counter] + + ### 3rd value ######################################################## + + # repeat the above process but now compare drop_counter to 3 + push.0 swap + movup.13 dup.14 eq.3 or + dup movdn.14 + cdrop movdn.6 + # => [d_3, d_2, d_1, 0, e_2_or_0, e_1_or_0, e_0_or_0, d_0, A', latch', drop_counter] + + ### 4th value ######################################################## + + # repeat the above process but now compare drop_counter to 4 + push.0 swap + movup.13 dup.14 eq.4 or + dup movdn.14 + cdrop movdn.6 + # => [d_2, d_1, 0, e_2_or_0, e_1_or_0, e_0_or_0, d_3_or_0, d_0, A', latch', drop_counter] + + ### 5th value ######################################################## + + # repeat the above process but now compare drop_counter to 5 + push.0 swap + movup.13 dup.14 eq.5 or + dup movdn.14 + cdrop movdn.6 + # => [d_1, 0, e_2_or_0, e_1_or_0, e_0_or_0, d_3_or_0, d_2_or_0, d_0, A', latch', drop_counter] + + ### 6th value ######################################################## + + # repeat the above process but now compare drop_counter to 6 + push.0 swap + movup.13 movup.14 eq.6 or + cdrop movdn.6 + # => [0, e_2_or_0, e_1_or_0, e_0_or_0, d_3_or_0, d_2_or_0, d_1_or_0, d_0, A'] + # or in other words + # => [C, B, A', ... ] + # notice that we don't need to check the d_0 value: entering the else branch means that + # we have number of elements not divisible by 8, so we will have at least one element to + # hash here (which turns out to be d_0) + + hperm + # => [F, E, D] + + exec.squeeze_digest + # => [E] + end +end diff --git a/stdlib/asm/crypto/stark/ood_frames.masm b/stdlib/asm/crypto/stark/ood_frames.masm index c6b9e50f26..bb3fabc1bc 100644 --- a/stdlib/asm/crypto/stark/ood_frames.masm +++ b/stdlib/asm/crypto/stark/ood_frames.masm @@ -1,4 +1,5 @@ use.std::crypto::stark::constants +use.std::crypto::hashes::rpo #! Loads OOD evaluation frame, with current and next rows interleaved, into memory. This ouputs @@ -105,7 +106,7 @@ export.load_constraint_evaluations hperm - dropw swapw dropw + exec.rpo::squeeze_digest end #! Computes the H(z) evaluation of the constraint composition polynomial at the OOD element z. diff --git a/stdlib/asm/crypto/stark/random_coin.masm b/stdlib/asm/crypto/stark/random_coin.masm index e66b024a40..07f431cb22 100644 --- a/stdlib/asm/crypto/stark/random_coin.masm +++ b/stdlib/asm/crypto/stark/random_coin.masm @@ -1,6 +1,6 @@ use.std::crypto::stark::constants use.std::crypto::stark::utils - +use.std::crypto::hashes::rpo #! Helper procedure to compute addition of two words component-wise. #! Input: [b3, b2, b1, b0, a3, a2, a1, a0] @@ -665,7 +665,7 @@ export.generate_list_indices exec.get_rate_2 hperm - dropw swapw dropw + exec.rpo::squeeze_digest #=> [R1, query_ptr, mask, depth, num_queries, ...] @@ -698,7 +698,7 @@ export.generate_list_indices exec.get_rate_2 hperm - dropw swapw dropw + exec.rpo::squeeze_digest #=> [R1, query_ptr, mask, depth, num_queries, ...] movup.7 sub.1 dup movdn.8 push.0 neq diff --git a/stdlib/asm/mem.masm b/stdlib/asm/mem.masm index f81508faf4..b420ab944a 100644 --- a/stdlib/asm/mem.masm +++ b/stdlib/asm/mem.masm @@ -1,3 +1,5 @@ +use.std::crypto::hashes::rpo + # ===== MEMORY FUNCTIONS ========================================================================== #! Copies `n` words from `read_ptr` to `write_ptr`. @@ -82,10 +84,10 @@ end #! Copies an arbitrary number of words from the advice stack to memory #! #! Input: [num_words, write_ptr, ...] -#! Output: [HASH, write_ptr', ...] +#! Output: [C, B, A, write_ptr', ...] #! Cycles: -#! even num_words: 48 + 9 * num_words / 2 -#! odd num_words: 65 + 9 * round_down(num_words / 2) +#! even num_words: 41 + 9 * num_words / 2 +#! odd num_words: 58 + 9 * round_down(num_words / 2) export.pipe_words_to_memory.0 # check if there is an odd number of words (6 cycles) dup is_odd @@ -99,10 +101,11 @@ export.pipe_words_to_memory.0 sub dup.1 add swap # => [write_ptr, end_ptr, needs_padding, ...] - # Prepare the capacity word. For rescue prime optimized the first element is - # set to `1` when padding is used and `0` otherwse, this is determined by the - # `needs_padding` flag. (4 cycles) - dup.2 push.0.0.0 + # Prepare the capacity word. We use the padding rule which sets the first capacity + # element to `len % 8` where `len` is the length of the hashed sequence. Since `len % 8` + # is either equal to 0 or 4, this is determined by the `needs_padding` flag multiplied + # by 4. (6 cycles) + dup.2 mul.4 push.0.0.0 # => [A, write_ptr, end_ptr, needs_padding, ...] # set initial hasher state (8 cycles) @@ -141,17 +144,13 @@ export.pipe_words_to_memory.0 # => [B', A, write_ptr+1, ...] # Push padding word (4 cycles) - push.1.0.0.0 + padw # => [C, B', A, write_ptr+1, ...] # Run RPO permutation (1 cycles) hperm # => [C', B', A', write_ptr+1, ...] end - - # The RPO result is word B, discard the unused portion of the rate and the capacity. (9 cycles) - dropw swapw dropw - # => [rpo_hash, write_ptr', ...] end #! Moves an arbitrary number of words from the advice stack to memory and asserts it matches the commitment. @@ -159,12 +158,16 @@ end #! Input: [num_words, write_ptr, COM, ...] #! Output: [write_ptr', ...] #! Cycles: -#! even num_words: 58 + 9 * num_words / 2 -#! odd num_words: 75 + 9 * round_down(num_words / 2) +#! even num_words: 62 + 9 * num_words / 2 +#! odd num_words: 79 + 9 * round_down(num_words / 2) export.pipe_preimage_to_memory.0 # Copies the advice stack data to memory exec.pipe_words_to_memory - # => [HASH, write_ptr', COM, ...] + # => [C, B, A, write_ptr', COM, ...] + + # Leave only the digest on the stack + exec.rpo::squeeze_digest + # => [B, write_ptr', COM, ...] # Save the write_ptr (2 cycles) movup.4 movdn.8 diff --git a/stdlib/docs/crypto/hashes/native.md b/stdlib/docs/crypto/hashes/native.md deleted file mode 100644 index db8dc41628..0000000000 --- a/stdlib/docs/crypto/hashes/native.md +++ /dev/null @@ -1,7 +0,0 @@ -Prepares the top of the stack with the hasher initial state.

This procedures does not handle padding, therefore, the user is expected to
consume an amount of data which is a multiple of the rate (2 words).

Input: []
Ouptut: [PERM, PERM, PERM, ...]
Cycles: 12
-## std::crypto::hashes::native -| Procedure | Description | -| ----------- | ------------- | -| state_to_digest | Given the hasher state, returns the hash output

Input: [C, B, A, ...]
Ouptut: [HASH, ...]
Where: For the native RPO hasher HASH is B.
Cycles: 9
| -| hash_memory_even | Hashes the memory `start_addr` to `end_addr`.

This requires that `end_addr=start_addr + 2n + 1`, otherwise the procedure will enter an infinite
loop. `end_addr` is not inclusive.

Stack transition:
Input: [C, B, A, start_addr, end_addr, ...]
Output: [C', B', A', end_addr, end_addr ...]
Cycles: 4 + 3 * words, where `words` is the `start_addr - end_addr - 1`

Where `A` is the capacity word that will be used by the hashing function, and `B'` the hash output.
| -| hash_memory | Hashes the memory `start_addr` to `end_addr`, handles odd number of elements.

Requires `start_addr < end_addr`, `end_addr` is not inclusive.

Stack transition:
Input: [start_addr, end_addr, ...]
Output: [H, ...]
Cycles:
even words: 48 cycles + 3 * words
odd words: 60 cycles + 3 * words
| diff --git a/stdlib/docs/crypto/hashes/rpo.md b/stdlib/docs/crypto/hashes/rpo.md new file mode 100644 index 0000000000..da22de54cc --- /dev/null +++ b/stdlib/docs/crypto/hashes/rpo.md @@ -0,0 +1,8 @@ +Prepares the top of the stack with the hasher initial state.

This procedures does not handle padding, therefore, the user is expected to
consume an amount of data which is a multiple of the rate (2 words).

Input: []
Ouptut: [PERM, PERM, PERM, ...]
Cycles: 12
+## std::crypto::hashes::rpo +| Procedure | Description | +| ----------- | ------------- | +| squeeze_digest | Given the hasher state, returns the hash output.

Input: [C, B, A, ...]
Ouptut: [HASH, ...]
where: For the native RPO hasher HASH is B.
Cycles: 9
| +| absorb_double_words_from_memory | Hashes the memory `start_addr` to `end_addr` given an RPO state specified by 3 words.

This requires that `end_addr=start_addr + 2n + 1`, otherwise the procedure will enter an infinite
loop. `end_addr` is not inclusive.

Stack transition:
Input: [C, B, A, start_addr, end_addr, ...]
Output: [C', B', A', end_addr, end_addr ...]
Cycles: 4 + 3 * words, where `words` is the `start_addr - end_addr - 1`

Where `A` is the capacity word that will be used by the hashing function, and `B'` the hash output.
| +| hash_memory_words | Hashes the memory `start_addr` to `end_addr`, handles odd number of elements.

Requires `start_addr < end_addr`, `end_addr` is not inclusive.

Stack transition:
Input: [start_addr, end_addr, ...]
Output: [H, ...]
Cycles:
even words: 49 cycles + 3 * words
odd words: 61 cycles + 3 * words
| +| hash_memory | Computes hash of Felt values starting at the specified memory address.

This procedure divides the hashing process into two parts: hashing pairs of words using
`absorb_double_words_from_memory` procedure and hashing the remaining values using the `hperm`
instruction.

Inputs: [ptr, num_elements]
Outputs: [HASH]
Cycles:
- If number of elements divides by 8: 47 cycles + 3 * words
- Else: 180 cycles + 3 * words

Panics if number of inputs equals 0.
| diff --git a/stdlib/docs/mem.md b/stdlib/docs/mem.md index 4aa67c46b7..84fdb8134e 100644 --- a/stdlib/docs/mem.md +++ b/stdlib/docs/mem.md @@ -4,5 +4,5 @@ | ----------- | ------------- | | memcopy | Copies `n` words from `read_ptr` to `write_ptr`.

Stack transition looks as follows:
[n, read_ptr, write_ptr, ...] -> [...]
cycles: 15 + 16n
| | pipe_double_words_to_memory | Copies an even number of words from the advice_stack to memory.

Input: [C, B, A, write_ptr, end_ptr, ...]
Output: [C, B, A, write_ptr, ...]

Where:
- The words C, B, and A are the RPO hasher state
- A is the capacity
- C,B are the rate portion of the state
- The value `words = end_ptr - write_ptr` must be positive and even

Cycles: 10 + 9 * word_pairs
| -| pipe_words_to_memory | Copies an arbitrary number of words from the advice stack to memory

Input: [num_words, write_ptr, ...]
Output: [HASH, write_ptr', ...]
Cycles:
even num_words: 48 + 9 * num_words / 2
odd num_words: 65 + 9 * round_down(num_words / 2)
| -| pipe_preimage_to_memory | Moves an arbitrary number of words from the advice stack to memory and asserts it matches the commitment.

Input: [num_words, write_ptr, COM, ...]
Output: [write_ptr', ...]
Cycles:
even num_words: 58 + 9 * num_words / 2
odd num_words: 75 + 9 * round_down(num_words / 2)
| +| pipe_words_to_memory | Copies an arbitrary number of words from the advice stack to memory

Input: [num_words, write_ptr, ...]
Output: [C, B, A, write_ptr', ...]
Cycles:
even num_words: 41 + 9 * num_words / 2
odd num_words: 58 + 9 * round_down(num_words / 2)
| +| pipe_preimage_to_memory | Moves an arbitrary number of words from the advice stack to memory and asserts it matches the commitment.

Input: [num_words, write_ptr, COM, ...]
Output: [write_ptr', ...]
Cycles:
even num_words: 62 + 9 * num_words / 2
odd num_words: 79 + 9 * round_down(num_words / 2)
| diff --git a/stdlib/tests/collections/mmr.rs b/stdlib/tests/collections/mmr.rs index 4f514eee3a..36fe1c5486 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/mod.rs b/stdlib/tests/crypto/mod.rs index 848b9e1f62..e68dbc291e 100644 --- a/stdlib/tests/crypto/mod.rs +++ b/stdlib/tests/crypto/mod.rs @@ -6,6 +6,6 @@ mod ecdsa_secp256k1; mod elgamal; mod fri; mod keccak256; -mod native; +mod rpo; mod sha256; mod stark; diff --git a/stdlib/tests/crypto/native.rs b/stdlib/tests/crypto/rpo.rs similarity index 54% rename from stdlib/tests/crypto/native.rs rename to stdlib/tests/crypto/rpo.rs index 94323f5f42..48721c4e6a 100644 --- a/stdlib/tests/crypto/native.rs +++ b/stdlib/tests/crypto/rpo.rs @@ -5,34 +5,13 @@ use test_utils::{build_expected_hash, build_expected_perm, expect_exec_error}; fn test_invalid_end_addr() { // end_addr can not be smaller than start_addr let empty_range = " - use.std::crypto::hashes::native + use.std::crypto::hashes::rpo begin push.0999 # end address push.1000 # start address - exec.native::hash_memory - end - "; - let test = build_test!(empty_range, &[]); - expect_exec_error!( - test, - ExecutionError::FailedAssertion { - clk: 18.into(), - err_code: 0, - err_msg: None, - } - ); - - // address range can not contain zero elements - let empty_range = " - use.std::crypto::hashes::native - - begin - push.1000 # end address - push.1000 # start address - - exec.native::hash_memory + exec.rpo::hash_memory_words end "; let test = build_test!(empty_range, &[]); @@ -50,13 +29,18 @@ fn test_invalid_end_addr() { fn test_hash_empty() { // computes the hash for 8 consecutive zeros using mem_stream directly let two_zeros_mem_stream = " + use.std::crypto::hashes::rpo + begin # mem_stream state push.1000 padw padw padw mem_stream hperm # drop everything except the hash - dropw swapw.3 dropw dropw dropw + exec.rpo::squeeze_digest movup.4 drop + + # truncate stack + swapw dropw end "; @@ -67,15 +51,17 @@ fn test_hash_empty() { ]).into_iter().map(|e| e.as_int()).collect(); build_test!(two_zeros_mem_stream, &[]).expect_stack(&zero_hash); - // checks the hash compute from 8 zero elements is the same when using hash_memory + // checks the hash compute from 8 zero elements is the same when using hash_memory_words let two_zeros = " - use.std::crypto::hashes::native + use.std::crypto::hashes::rpo begin push.1002 # end address push.1000 # start address - exec.native::hash_memory + exec.rpo::hash_memory_words + + # truncate stack swapw dropw end "; @@ -87,6 +73,8 @@ fn test_hash_empty() { fn test_single_iteration() { // computes the hash of 1 using mem_stream let one_memstream = " + use.std::crypto::hashes::rpo + begin # insert 1 to memory push.1.1000 mem_store @@ -96,7 +84,10 @@ fn test_single_iteration() { mem_stream hperm # drop everything except the hash - dropw swapw.3 dropw dropw dropw + exec.rpo::squeeze_digest movup.4 drop + + # truncate stack + swapw dropw end "; @@ -107,11 +98,11 @@ fn test_single_iteration() { ]).into_iter().map(|e| e.as_int()).collect(); build_test!(one_memstream, &[]).expect_stack(&one_hash); - // checks the hash of 1 is the same when using hash_memory + // checks the hash of 1 is the same when using hash_memory_words // Note: This is testing the hashing of two words, so no padding is added // here let one_element = " - use.std::crypto::hashes::native + use.std::crypto::hashes::rpo begin # insert 1 to memory @@ -120,7 +111,9 @@ fn test_single_iteration() { push.1002 # end address push.1000 # start address - exec.native::hash_memory + exec.rpo::hash_memory_words + + # truncate stack swapw dropw end "; @@ -139,9 +132,9 @@ fn test_hash_one_word() { 1, 0, 0, 0, ]).into_iter().map(|e| e.as_int()).collect(); - // checks the hash of 1 is the same when using hash_memory + // checks the hash of 1 is the same when using hash_memory_words let one_element = " - use.std::crypto::hashes::native + use.std::crypto::hashes::rpo begin push.1.1000 mem_store # push data to memory @@ -149,7 +142,9 @@ fn test_hash_one_word() { push.1001 # end address push.1000 # start address - exec.native::hash_memory + exec.rpo::hash_memory_words + + # truncate stack swapw dropw end "; @@ -161,7 +156,7 @@ fn test_hash_one_word() { fn test_hash_even_words() { // checks the hash of two words let even_words = " - use.std::crypto::hashes::native + use.std::crypto::hashes::rpo begin push.1.0.0.0.1000 mem_storew dropw @@ -170,7 +165,9 @@ fn test_hash_even_words() { push.1002 # end address push.1000 # start address - exec.native::hash_memory + exec.rpo::hash_memory_words + + # truncate stack swapw dropw end "; @@ -187,7 +184,7 @@ fn test_hash_even_words() { fn test_hash_odd_words() { // checks the hash of three words let odd_words = " - use.std::crypto::hashes::native + use.std::crypto::hashes::rpo begin push.1.0.0.0.1000 mem_storew dropw @@ -197,7 +194,9 @@ fn test_hash_odd_words() { push.1003 # end address push.1000 # start address - exec.native::hash_memory + exec.rpo::hash_memory_words + + # truncate stack swapw dropw end "; @@ -212,10 +211,10 @@ fn test_hash_odd_words() { } #[test] -fn test_hash_memory_even() { +fn test_absorb_double_words_from_memory() { let even_words = " - use.std::crypto::hashes::native use.std::sys + use.std::crypto::hashes::rpo begin push.1.0.0.0.1000 mem_storew dropw @@ -224,8 +223,9 @@ fn test_hash_memory_even() { push.1002 # end address push.1000 # start address padw padw padw # hasher state - exec.native::hash_memory_even + exec.rpo::absorb_double_words_from_memory + # truncate stack exec.sys::truncate_stack end "; @@ -245,9 +245,9 @@ fn test_hash_memory_even() { } #[test] -fn test_state_to_digest() { +fn test_squeeze_digest() { let even_words = " - use.std::crypto::hashes::native + use.std::crypto::hashes::rpo begin push.1.0.0.0.1000 mem_storew dropw @@ -258,9 +258,11 @@ fn test_state_to_digest() { push.1004 # end address push.1000 # start address padw padw padw # hasher state - exec.native::hash_memory_even + exec.rpo::absorb_double_words_from_memory - exec.native::state_to_digest + exec.rpo::squeeze_digest + + # truncate stack swapdw dropw dropw end "; @@ -279,3 +281,149 @@ fn test_state_to_digest() { build_test!(even_words, &[]).expect_stack(&even_hash); } + +#[test] +fn test_hash_memory() { + // hash fewer than 8 elements + let compute_inputs_hash_5 = " + use.std::crypto::hashes::rpo + + begin + push.1.2.3.4.1000 mem_storew dropw + push.5.0.0.0.1001 mem_storew dropw + push.11 + + push.5.1000 + + exec.rpo::hash_memory + + # truncate stack + swapdw dropw dropw + end + "; + + #[rustfmt::skip] + let mut expected_hash: Vec = build_expected_hash(&[ + 1, 2, 3, 4, 5 + ]).into_iter().map(|e| e.as_int()).collect(); + // make sure that value `11` stays unchanged + expected_hash.push(11); + build_test!(compute_inputs_hash_5, &[]).expect_stack(&expected_hash); + + // hash exactly 8 elements + let compute_inputs_hash_8 = " + use.std::crypto::hashes::rpo + + begin + push.1.2.3.4.1000 mem_storew dropw + push.5.6.7.8.1001 mem_storew dropw + push.11 + + push.8.1000 + + exec.rpo::hash_memory + + # truncate stack + swapdw dropw dropw + end + "; + + #[rustfmt::skip] + let mut expected_hash: Vec = build_expected_hash(&[ + 1, 2, 3, 4, 5, 6, 7, 8 + ]).into_iter().map(|e| e.as_int()).collect(); + // make sure that value `11` stays unchanged + expected_hash.push(11); + build_test!(compute_inputs_hash_8, &[]).expect_stack(&expected_hash); + + // hash more than 8 elements + let compute_inputs_hash_15 = " + use.std::crypto::hashes::rpo + + begin + push.1.2.3.4.1000 mem_storew dropw + push.5.6.7.8.1001 mem_storew dropw + push.9.10.11.12.1002 mem_storew dropw + push.13.14.15.0.1003 mem_storew dropw + push.11 + + push.15.1000 + + exec.rpo::hash_memory + + # truncate stack + swapdw dropw dropw + end + "; + + #[rustfmt::skip] + let mut expected_hash: Vec = build_expected_hash(&[ + 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15 + ]).into_iter().map(|e| e.as_int()).collect(); + // make sure that value `11` stays unchanged + expected_hash.push(11); + build_test!(compute_inputs_hash_15, &[]).expect_stack(&expected_hash); +} + +#[test] +fn test_hash_memory_empty() { + // absorb_double_words_from_memory + let source = " + use.std::sys + use.std::crypto::hashes::rpo + + begin + push.1000 # end address + push.1000 # start address + padw padw padw # hasher state + + exec.rpo::absorb_double_words_from_memory + + # truncate stack + exec.sys::truncate_stack + end + "; + + let mut expected_stack = vec![0; 12]; + expected_stack.push(1000); + expected_stack.push(1000); + + build_test!(source, &[]).expect_stack(&expected_stack); + + // hash_memory_words + let source = " + use.std::crypto::hashes::rpo + + begin + push.1000 # end address + push.1000 # start address + + exec.rpo::hash_memory_words + + # truncate stack + swapw dropw + end + "; + + build_test!(source, &[]).expect_stack(&[0; 4]); + + // hash_memory + let source = " + use.std::crypto::hashes::rpo + + begin + push.0 # number of elements to hash + push.1000 # start address + + exec.rpo::hash_memory + + # truncate stack + swapw dropw + end + "; + + build_test!(source, &[]).expect_stack(&[0; 16]); +} diff --git a/stdlib/tests/mem/mod.rs b/stdlib/tests/mem/mod.rs index 0d32c1a8c0..61c3836f9d 100644 --- a/stdlib/tests/mem/mod.rs +++ b/stdlib/tests/mem/mod.rs @@ -130,13 +130,18 @@ fn test_pipe_double_words_to_memory() { fn test_pipe_words_to_memory() { let mem_addr = 1000; let one_word = format!( - "use.std::mem + " + use.std::mem + use.std::crypto::hashes::rpo begin push.{} # target address push.1 # number of words exec.mem::pipe_words_to_memory + exec.rpo::squeeze_digest + + # truncate stack swapdw dropw dropw end", mem_addr @@ -153,13 +158,18 @@ fn test_pipe_words_to_memory() { ); let three_words = format!( - "use.std::mem + " + use.std::mem + use.std::crypto::hashes::rpo begin push.{} # target address push.3 # number of words exec.mem::pipe_words_to_memory + exec.rpo::squeeze_digest + + # truncate stack swapdw dropw dropw end", mem_addr