diff --git a/Cargo.lock b/Cargo.lock index 8bdbd8bed9..6cbc50c5b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2248,7 +2248,7 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "p3-air" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "p3-field", "p3-matrix", @@ -2257,7 +2257,7 @@ dependencies = [ [[package]] name = "p3-baby-bear" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "num-bigint 0.4.4", "p3-field", @@ -2271,7 +2271,7 @@ dependencies = [ [[package]] name = "p3-blake3" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "blake3", "p3-symmetric", @@ -2280,7 +2280,7 @@ dependencies = [ [[package]] name = "p3-bn254-fr" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "ff 0.13.0", "num-bigint 0.4.4", @@ -2294,7 +2294,7 @@ dependencies = [ [[package]] name = "p3-challenger" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "p3-field", "p3-maybe-rayon", @@ -2306,7 +2306,7 @@ dependencies = [ [[package]] name = "p3-commit" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "itertools 0.12.1", "p3-challenger", @@ -2319,7 +2319,7 @@ dependencies = [ [[package]] name = "p3-dft" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "p3-field", "p3-matrix", @@ -2331,7 +2331,7 @@ dependencies = [ [[package]] name = "p3-field" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "itertools 0.12.1", "num-bigint 0.4.4", @@ -2344,7 +2344,7 @@ dependencies = [ [[package]] name = "p3-fri" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "itertools 0.12.1", "p3-challenger", @@ -2362,7 +2362,7 @@ dependencies = [ [[package]] name = "p3-goldilocks" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "num-bigint 0.4.4", "p3-dft", @@ -2378,7 +2378,7 @@ dependencies = [ [[package]] name = "p3-interpolation" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "p3-field", "p3-matrix", @@ -2388,7 +2388,7 @@ dependencies = [ [[package]] name = "p3-keccak" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "p3-symmetric", "tiny-keccak", @@ -2397,7 +2397,7 @@ dependencies = [ [[package]] name = "p3-keccak-air" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "p3-air", "p3-field", @@ -2409,7 +2409,7 @@ dependencies = [ [[package]] name = "p3-matrix" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "itertools 0.12.1", "p3-field", @@ -2423,7 +2423,7 @@ dependencies = [ [[package]] name = "p3-maybe-rayon" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "rayon", ] @@ -2431,7 +2431,7 @@ dependencies = [ [[package]] name = "p3-mds" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "itertools 0.11.0", "p3-dft", @@ -2445,7 +2445,7 @@ dependencies = [ [[package]] name = "p3-merkle-tree" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "itertools 0.12.1", "p3-commit", @@ -2461,7 +2461,7 @@ dependencies = [ [[package]] name = "p3-poseidon2" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "gcd", "p3-field", @@ -2473,7 +2473,7 @@ dependencies = [ [[package]] name = "p3-symmetric" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "itertools 0.12.1", "p3-field", @@ -2483,7 +2483,7 @@ dependencies = [ [[package]] name = "p3-uni-stark" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "itertools 0.12.1", "p3-air", @@ -2501,7 +2501,7 @@ dependencies = [ [[package]] name = "p3-util" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git#cbbcbe1c1353f742782323676af55e59b4318d94" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "serde", ] diff --git a/Cargo.toml b/Cargo.toml index 9158e8aa92..76c1caae79 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,28 +28,28 @@ debug = true debug-assertions = true [workspace.dependencies] -p3-air = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-field = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-commit = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-matrix = { git = "https://github.com/Plonky3/Plonky3.git" } +p3-air = { git = "https://github.com/Plonky3/Plonky3.git", branch = "sp1" } +p3-field = { git = "https://github.com/Plonky3/Plonky3.git", branch = "sp1" } +p3-commit = { git = "https://github.com/Plonky3/Plonky3.git", branch = "sp1" } +p3-matrix = { git = "https://github.com/Plonky3/Plonky3.git", branch = "sp1" } p3-baby-bear = { git = "https://github.com/Plonky3/Plonky3.git", features = [ "nightly-features", -] } -p3-util = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-challenger = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-dft = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-fri = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-goldilocks = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-keccak = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-keccak-air = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-blake3 = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-mds = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-merkle-tree = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-poseidon2 = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-symmetric = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-uni-stark = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-maybe-rayon = { git = "https://github.com/Plonky3/Plonky3.git" } -p3-bn254-fr = { git = "https://github.com/Plonky3/Plonky3.git" } +], branch = "sp1" } +p3-util = { git = "https://github.com/Plonky3/Plonky3.git", branch = "sp1" } +p3-challenger = { git = "https://github.com/Plonky3/Plonky3.git", branch = "sp1" } +p3-dft = { git = "https://github.com/Plonky3/Plonky3.git", branch = "sp1" } +p3-fri = { git = "https://github.com/Plonky3/Plonky3.git", branch = "sp1" } +p3-goldilocks = { git = "https://github.com/Plonky3/Plonky3.git", branch = "sp1" } +p3-keccak = { git = "https://github.com/Plonky3/Plonky3.git", branch = "sp1" } +p3-keccak-air = { git = "https://github.com/Plonky3/Plonky3.git", branch = "sp1" } +p3-blake3 = { git = "https://github.com/Plonky3/Plonky3.git", branch = "sp1" } +p3-mds = { git = "https://github.com/Plonky3/Plonky3.git", branch = "sp1" } +p3-merkle-tree = { git = "https://github.com/Plonky3/Plonky3.git", branch = "sp1" } +p3-poseidon2 = { git = "https://github.com/Plonky3/Plonky3.git", branch = "sp1" } +p3-symmetric = { git = "https://github.com/Plonky3/Plonky3.git", branch = "sp1" } +p3-uni-stark = { git = "https://github.com/Plonky3/Plonky3.git", branch = "sp1" } +p3-maybe-rayon = { git = "https://github.com/Plonky3/Plonky3.git", branch = "sp1" } +p3-bn254-fr = { git = "https://github.com/Plonky3/Plonky3.git", branch = "sp1" } # For local development. diff --git a/examples/fibonacci-io/script/Cargo.lock b/examples/fibonacci-io/script/Cargo.lock index fce1feb876..a003b7b672 100644 --- a/examples/fibonacci-io/script/Cargo.lock +++ b/examples/fibonacci-io/script/Cargo.lock @@ -535,9 +535,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.0.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f711ade317dd348950a9910f81c5947e3d8907ebd2b83f76203ff1807e6a2bc2" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" dependencies = [ "cfg-if", "cpufeatures", @@ -760,9 +760,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.1.20" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" +checksum = "c007b1ae3abe1cb6f85a16305acd418b7ca6343b953633fee2b76d8f108b830f" [[package]] name = "fibonacci-io-script" @@ -915,6 +915,12 @@ dependencies = [ "slab", ] +[[package]] +name = "gcd" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" + [[package]] name = "generic-array" version = "0.14.7" @@ -1757,7 +1763,7 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "p3-air" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#7e4f7afedeffbc49c9c123e21f29e0eb1a9b2227" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "p3-field", "p3-matrix", @@ -1766,7 +1772,7 @@ dependencies = [ [[package]] name = "p3-baby-bear" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#7e4f7afedeffbc49c9c123e21f29e0eb1a9b2227" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "num-bigint", "p3-field", @@ -1780,7 +1786,7 @@ dependencies = [ [[package]] name = "p3-blake3" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#7e4f7afedeffbc49c9c123e21f29e0eb1a9b2227" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "blake3", "p3-symmetric", @@ -1789,7 +1795,7 @@ dependencies = [ [[package]] name = "p3-challenger" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#7e4f7afedeffbc49c9c123e21f29e0eb1a9b2227" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "p3-field", "p3-maybe-rayon", @@ -1801,7 +1807,7 @@ dependencies = [ [[package]] name = "p3-commit" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#7e4f7afedeffbc49c9c123e21f29e0eb1a9b2227" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "itertools 0.12.1", "p3-challenger", @@ -1814,7 +1820,7 @@ dependencies = [ [[package]] name = "p3-dft" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#7e4f7afedeffbc49c9c123e21f29e0eb1a9b2227" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "p3-field", "p3-matrix", @@ -1826,7 +1832,7 @@ dependencies = [ [[package]] name = "p3-field" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#7e4f7afedeffbc49c9c123e21f29e0eb1a9b2227" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "itertools 0.12.1", "num-bigint", @@ -1839,7 +1845,7 @@ dependencies = [ [[package]] name = "p3-fri" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#7e4f7afedeffbc49c9c123e21f29e0eb1a9b2227" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "itertools 0.12.1", "p3-challenger", @@ -1857,7 +1863,7 @@ dependencies = [ [[package]] name = "p3-goldilocks" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#7e4f7afedeffbc49c9c123e21f29e0eb1a9b2227" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "num-bigint", "p3-dft", @@ -1873,7 +1879,7 @@ dependencies = [ [[package]] name = "p3-interpolation" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#7e4f7afedeffbc49c9c123e21f29e0eb1a9b2227" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "p3-field", "p3-matrix", @@ -1883,7 +1889,7 @@ dependencies = [ [[package]] name = "p3-keccak" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#7e4f7afedeffbc49c9c123e21f29e0eb1a9b2227" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "p3-symmetric", "tiny-keccak", @@ -1892,7 +1898,7 @@ dependencies = [ [[package]] name = "p3-keccak-air" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#7e4f7afedeffbc49c9c123e21f29e0eb1a9b2227" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "p3-air", "p3-field", @@ -1904,7 +1910,7 @@ dependencies = [ [[package]] name = "p3-matrix" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#7e4f7afedeffbc49c9c123e21f29e0eb1a9b2227" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "itertools 0.12.1", "p3-field", @@ -1918,7 +1924,7 @@ dependencies = [ [[package]] name = "p3-maybe-rayon" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#7e4f7afedeffbc49c9c123e21f29e0eb1a9b2227" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "rayon", ] @@ -1926,7 +1932,7 @@ dependencies = [ [[package]] name = "p3-mds" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#7e4f7afedeffbc49c9c123e21f29e0eb1a9b2227" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "itertools 0.11.0", "p3-dft", @@ -1940,7 +1946,7 @@ dependencies = [ [[package]] name = "p3-merkle-tree" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#7e4f7afedeffbc49c9c123e21f29e0eb1a9b2227" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "itertools 0.12.1", "p3-commit", @@ -1956,9 +1962,11 @@ dependencies = [ [[package]] name = "p3-poseidon2" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#7e4f7afedeffbc49c9c123e21f29e0eb1a9b2227" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ + "gcd", "p3-field", + "p3-mds", "p3-symmetric", "rand", ] @@ -1966,7 +1974,7 @@ dependencies = [ [[package]] name = "p3-symmetric" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#7e4f7afedeffbc49c9c123e21f29e0eb1a9b2227" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "itertools 0.12.1", "p3-field", @@ -1976,7 +1984,7 @@ dependencies = [ [[package]] name = "p3-uni-stark" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#7e4f7afedeffbc49c9c123e21f29e0eb1a9b2227" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "itertools 0.12.1", "p3-air", @@ -1994,7 +2002,7 @@ dependencies = [ [[package]] name = "p3-util" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#7e4f7afedeffbc49c9c123e21f29e0eb1a9b2227" +source = "git+https://github.com/Plonky3/Plonky3.git?branch=sp1#cbbcbe1c1353f742782323676af55e59b4318d94" dependencies = [ "serde", ] diff --git a/examples/fibonacci-io/script/src/main.rs b/examples/fibonacci-io/script/src/main.rs index 72d377ebe8..ef4b9803a5 100644 --- a/examples/fibonacci-io/script/src/main.rs +++ b/examples/fibonacci-io/script/src/main.rs @@ -35,7 +35,7 @@ fn main() { println!("b: {}", b); // Verify proof and public values - SP1Verifier::verify(ELF, &proof).expect("verification failed"s); + SP1Verifier::verify(ELF, &proof).expect("verification failed"); let mut pv_hasher = Sha256::new(); pv_hasher.update(n.to_le_bytes()); diff --git a/recursion/circuit/src/challenger.rs b/recursion/circuit/src/challenger.rs index 0620d2a62d..f6fb1e05d9 100644 --- a/recursion/circuit/src/challenger.rs +++ b/recursion/circuit/src/challenger.rs @@ -97,7 +97,7 @@ impl MultiField32ChallengerVariable { pub fn sample_bits(&mut self, builder: &mut Builder, bits: usize) -> Var { let rand_f = self.sample(builder); let rand_f_bits = builder.num2bits_f_circuit(rand_f); - builder.bits_to_num_var_circuit(&rand_f_bits[0..bits]) + builder.bits2num_v_circuit(&rand_f_bits[0..bits]) } pub fn check_witness(&mut self, builder: &mut Builder, bits: usize, witness: Felt) { @@ -112,7 +112,7 @@ pub fn reduce_32(builder: &mut Builder, vals: &[Felt]) -> Va let result: Var = builder.eval(C::N::zero()); for val in vals.iter() { let bits = builder.num2bits_f_circuit(*val); - let val = builder.bits_to_num_var_circuit(&bits); + let val = builder.bits2num_v_circuit(&bits); builder.assign(result, result + val * power); power *= C::N::from_canonical_usize(1usize << 32); } diff --git a/recursion/circuit/src/constraints.rs b/recursion/circuit/src/constraints.rs index 1acb9d66aa..aeaf9da9c8 100644 --- a/recursion/circuit/src/constraints.rs +++ b/recursion/circuit/src/constraints.rs @@ -323,14 +323,14 @@ mod tests { quotient_chunk_domains_vals, proof.opened_values.chips.iter(), ) { - let opening = builder.eval_const(values_vals.clone()); + let opening = builder.constant(values_vals.clone()); let alpha = builder.eval(alpha_val.cons()); let zeta = builder.eval(zeta_val.cons()); - let trace_domain = builder.eval_const(trace_domain_val); - let public_values = builder.eval_const(proof.public_values); + let trace_domain = builder.constant(trace_domain_val); + let public_values = builder.constant(proof.public_values); let qc_domains = qc_domains_vals .iter() - .map(|domain| builder.eval_const(*domain)) + .map(|domain| builder.constant(*domain)) .collect::>(); let permutation_challenges = permutation_challenges diff --git a/recursion/circuit/src/domain.rs b/recursion/circuit/src/domain.rs index 7c83dc23e6..31b549277b 100644 --- a/recursion/circuit/src/domain.rs +++ b/recursion/circuit/src/domain.rs @@ -34,7 +34,7 @@ where { type Constant = TwoAdicMultiplicativeCoset; - fn eval_const(value: Self::Constant, _: &mut Builder) -> Self { + fn constant(value: Self::Constant, _: &mut Builder) -> Self { let g_val = C::F::two_adic_generator(value.log_n); TwoAdicMultiplicativeCosetVariable:: { log_n: value.log_n, diff --git a/recursion/circuit/src/fri.rs b/recursion/circuit/src/fri.rs index 073182adce..8b44dff894 100644 --- a/recursion/circuit/src/fri.rs +++ b/recursion/circuit/src/fri.rs @@ -112,7 +112,7 @@ pub fn verify_two_adic_pcs( let two_adic_generator: Felt<_> = builder.eval(C::F::two_adic_generator(log_height)); let two_adic_generator_exp = - builder.exp_usize_f_bits(two_adic_generator, rev_reduced_index); + builder.exp_f_bits(two_adic_generator, rev_reduced_index); let x: Felt<_> = builder.eval(g * two_adic_generator_exp); for (z, ps_at_z) in izip!(mat_points, mat_values) { @@ -181,7 +181,7 @@ pub fn verify_query( ))); let index_bits = builder.num2bits_v_circuit(index, 256); let rev_reduced_index = builder.reverse_bits_len_circuit(index_bits.clone(), log_max_height); - let mut x = builder.exp_usize_ef_bits(two_adic_generator, rev_reduced_index); + let mut x = builder.exp_e_bits(two_adic_generator, rev_reduced_index); let mut offset = 0; for (log_folded_height, commit, step, beta) in izip!( diff --git a/recursion/circuit/src/stark.rs b/recursion/circuit/src/stark.rs index ee1671d37d..565dc201de 100644 --- a/recursion/circuit/src/stark.rs +++ b/recursion/circuit/src/stark.rs @@ -98,7 +98,7 @@ where let index = sorted_indices[chip_idx]; let opening = &opened_values.chips[index]; - let domain_var: TwoAdicMultiplicativeCosetVariable<_> = builder.eval_const(*domain); + let domain_var: TwoAdicMultiplicativeCosetVariable<_> = builder.constant(*domain); let mut trace_points = Vec::new(); let zeta_next = domain_var.next_point(builder, zeta); @@ -274,7 +274,7 @@ pub(crate) mod tests { { // Set up the public values. let public_values: PublicValuesVariable = - builder.eval_const(proof.public_values); + builder.constant(proof.public_values); // Set up the commitments. let main_commit: [Bn254Fr; 1] = proof.commitment.main_commit.into(); @@ -293,7 +293,7 @@ pub(crate) mod tests { // Set up the opened values. let mut opened_values = Vec::new(); for values in proof.opened_values.chips.iter() { - let values: ChipOpenedValuesVariable<_> = builder.eval_const(values.clone()); + let values: ChipOpenedValuesVariable<_> = builder.constant(values.clone()); opened_values.push(values); } let opened_values = RecursionShardOpenedValuesVariable { diff --git a/recursion/circuit/src/types.rs b/recursion/circuit/src/types.rs index 36ea0ca924..1c4ff8703b 100644 --- a/recursion/circuit/src/types.rs +++ b/recursion/circuit/src/types.rs @@ -101,10 +101,10 @@ pub struct AirOpenedValuesVariable { impl FromConstant for AirOpenedValuesVariable { type Constant = AirOpenedValues; - fn eval_const(value: Self::Constant, builder: &mut Builder) -> Self { + fn constant(value: Self::Constant, builder: &mut Builder) -> Self { AirOpenedValuesVariable { - local: value.local.iter().map(|x| builder.eval_const(*x)).collect(), - next: value.next.iter().map(|x| builder.eval_const(*x)).collect(), + local: value.local.iter().map(|x| builder.constant(*x)).collect(), + next: value.next.iter().map(|x| builder.constant(*x)).collect(), } } } @@ -112,15 +112,15 @@ impl FromConstant for AirOpenedValuesVariable { impl FromConstant for ChipOpenedValuesVariable { type Constant = ChipOpenedValues; - fn eval_const(value: Self::Constant, builder: &mut Builder) -> Self { + fn constant(value: Self::Constant, builder: &mut Builder) -> Self { ChipOpenedValuesVariable { - preprocessed: builder.eval_const(value.preprocessed), - main: builder.eval_const(value.main), - permutation: builder.eval_const(value.permutation), + preprocessed: builder.constant(value.preprocessed), + main: builder.constant(value.main), + permutation: builder.constant(value.permutation), quotient: value .quotient .iter() - .map(|x| x.iter().map(|y| builder.eval_const(*y)).collect()) + .map(|x| x.iter().map(|y| builder.constant(*y)).collect()) .collect(), cumulative_sum: builder.eval(value.cumulative_sum.cons()), log_degree: value.log_degree, diff --git a/recursion/compiler/Cargo.toml b/recursion/compiler/Cargo.toml index a097810a4e..abbfbfe631 100644 --- a/recursion/compiler/Cargo.toml +++ b/recursion/compiler/Cargo.toml @@ -22,11 +22,10 @@ serde_json = "1.0.115" p3-bn254-fr = { workspace = true } p3-baby-bear = { workspace = true } serial_test = "3.0.0" +p3-poseidon2 = { workspace = true } [dev-dependencies] p3-challenger = { workspace = true } -p3-symmetric = { workspace = true } p3-dft = { workspace = true } p3-merkle-tree = { workspace = true } -p3-poseidon2 = { workspace = true } rand = "0.8.4" diff --git a/recursion/compiler/src/asm/compiler.rs b/recursion/compiler/src/asm/compiler.rs index 8047044aa3..abb4b49eb3 100644 --- a/recursion/compiler/src/asm/compiler.rs +++ b/recursion/compiler/src/asm/compiler.rs @@ -46,7 +46,7 @@ pub struct AsmCompiler { function_labels: BTreeMap, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub struct AsmConfig(PhantomData<(F, EF)>); impl + TwoAdicField> Config @@ -146,13 +146,13 @@ impl + TwoAdicField> AsmCo } for op in operations.clone() { match op { - DslIR::Imm(dst, src) => { + DslIR::ImmV(dst, src) => { self.push(AsmInstruction::IMM(dst.fp(), src)); } - DslIR::ImmFelt(dst, src) => { + DslIR::ImmF(dst, src) => { self.push(AsmInstruction::IMM(dst.fp(), src)); } - DslIR::ImmExt(dst, src) => { + DslIR::ImmE(dst, src) => { self.push(AsmInstruction::EIMM(dst.fp(), src)); } DslIR::AddV(dst, lhs, rhs) => { diff --git a/recursion/compiler/src/constraints/mod.rs b/recursion/compiler/src/constraints/mod.rs index 2b61b6152c..4dcd3a4e9a 100644 --- a/recursion/compiler/src/constraints/mod.rs +++ b/recursion/compiler/src/constraints/mod.rs @@ -112,15 +112,15 @@ impl ConstraintBackend { let mut constraints: Vec = Vec::new(); for instruction in operations { match instruction { - DslIR::Imm(a, b) => constraints.push(Constraint { + DslIR::ImmV(a, b) => constraints.push(Constraint { opcode: ConstraintOpcode::ImmV, args: vec![vec![a.id()], vec![b.as_canonical_biguint().to_string()]], }), - DslIR::ImmFelt(a, b) => constraints.push(Constraint { + DslIR::ImmF(a, b) => constraints.push(Constraint { opcode: ConstraintOpcode::ImmF, args: vec![vec![a.id()], vec![b.as_canonical_biguint().to_string()]], }), - DslIR::ImmExt(a, b) => constraints.push(Constraint { + DslIR::ImmE(a, b) => constraints.push(Constraint { opcode: ConstraintOpcode::ImmE, args: vec![ vec![a.id()], @@ -377,9 +377,9 @@ mod tests { #[serial] fn test_imm() { let program = vec![ - DslIR::Imm(Var::new(0), Bn254Fr::zero()), - DslIR::ImmFelt(Felt::new(1), BabyBear::one()), - DslIR::ImmExt(Ext::new(2), BinomialExtensionField::::one()), + DslIR::ImmV(Var::new(0), Bn254Fr::zero()), + DslIR::ImmF(Felt::new(1), BabyBear::one()), + DslIR::ImmE(Ext::new(2), BinomialExtensionField::::one()), DslIR::PrintV(Var::new(0)), DslIR::PrintF(Felt::new(1)), DslIR::PrintE(Ext::new(2)), diff --git a/recursion/compiler/src/ir/bits.rs b/recursion/compiler/src/ir/bits.rs new file mode 100644 index 0000000000..588d32ffcc --- /dev/null +++ b/recursion/compiler/src/ir/bits.rs @@ -0,0 +1,150 @@ +use p3_field::AbstractField; +use sp1_recursion_core::runtime::NUM_BITS; + +use super::{Array, Builder, Config, DslIR, Usize, Var}; +use crate::prelude::Felt; + +impl Builder { + /// Converts a variable to bits. + pub fn num2bits_v(&mut self, num: Var) -> Array> { + let output = self.dyn_array::>(NUM_BITS); + self.operations.push(DslIR::HintBitsV(output.clone(), num)); + + let sum: Var<_> = self.eval(C::N::zero()); + for i in 0..NUM_BITS { + let bit = self.get(&output, i); + self.assert_var_eq(bit * (bit - C::N::one()), C::N::zero()); + self.assign(sum, sum + bit * C::N::from_canonical_u32(1 << i)); + } + + self.assert_var_eq(sum, num); + output + } + + /// Converts a variable to bits inside a circuit. + pub fn num2bits_v_circuit(&mut self, num: Var, bits: usize) -> Vec> { + let mut output = Vec::new(); + for _ in 0..bits { + output.push(self.uninit()); + } + + self.operations + .push(DslIR::CircuitNum2BitsV(num, bits, output.clone())); + + output + } + + /// Converts a felt to bits. + pub fn num2bits_f(&mut self, num: Felt) -> Array> { + let output = self.dyn_array::>(NUM_BITS); + self.operations.push(DslIR::HintBitsF(output.clone(), num)); + + let sum: Felt<_> = self.eval(C::F::zero()); + for i in 0..NUM_BITS { + let bit = self.get(&output, i); + self.assert_var_eq(bit * (bit - C::N::one()), C::N::zero()); + self.if_eq(bit, C::N::one()).then(|builder| { + builder.assign(sum, sum + C::F::from_canonical_u32(1 << i)); + }); + } + + // self.assert_felt_eq(sum, num); + + output + } + + /// Converts a felt to bits inside a circuit. + pub fn num2bits_f_circuit(&mut self, num: Felt) -> Vec> { + let mut output = Vec::new(); + for _ in 0..32 { + output.push(self.uninit()); + } + + self.operations + .push(DslIR::CircuitNum2BitsF(num, output.clone())); + + output + } + + /// Convert bits to a variable. + pub fn bits2num_v(&mut self, bits: &Array>) -> Var { + let num: Var<_> = self.eval(C::N::zero()); + let power: Var<_> = self.eval(C::N::one()); + self.range(0, bits.len()).for_each(|i, builder| { + let bit = builder.get(bits, i); + builder.assign(num, num + bit * power); + builder.assign(power, power * C::N::from_canonical_u32(2)); + }); + num + } + + /// Convert bits to a variable inside a circuit. + pub fn bits2num_v_circuit(&mut self, bits: &[Var]) -> Var { + let result: Var<_> = self.eval(C::N::zero()); + for i in 0..bits.len() { + self.assign(result, result + bits[i] * C::N::from_canonical_u32(1 << i)); + } + result + } + + /// Convert bits to a felt. + pub fn bits2num_f(&mut self, bits: &Array>) -> Felt { + let num: Felt<_> = self.eval(C::F::zero()); + for i in 0..NUM_BITS { + let bit = self.get(bits, i); + // Add `bit * 2^i` to the sum. + self.if_eq(bit, C::N::one()).then(|builder| { + builder.assign(num, num + C::F::from_canonical_u32(1 << i)); + }); + } + num + } + + /// Reverse a list of bits. + /// + /// SAFETY: calling this function with `bit_len` greater [`NUM_BITS`] will result in undefined + /// behavior. + /// + /// Reference: [p3_util::reverse_bits_len] + pub fn reverse_bits_len( + &mut self, + index_bits: &Array>, + bit_len: impl Into>, + ) -> Array> { + let bit_len = bit_len.into(); + + let mut result_bits = self.dyn_array::>(NUM_BITS); + self.range(0, bit_len).for_each(|i, builder| { + let index: Var = builder.eval(bit_len - i - C::N::one()); + let entry = builder.get(index_bits, index); + builder.set_value(&mut result_bits, i, entry); + }); + + let zero = self.eval(C::N::zero()); + self.range(bit_len, NUM_BITS).for_each(|i, builder| { + builder.set_value(&mut result_bits, i, zero); + }); + + result_bits + } + + /// Reverse a list of bits inside a circuit. + /// + /// SAFETY: calling this function with `bit_len` greater [`NUM_BITS`] will result in undefined + /// behavior. + /// + /// Reference: [p3_util::reverse_bits_len] + pub fn reverse_bits_len_circuit( + &mut self, + index_bits: Vec>, + bit_len: usize, + ) -> Vec> { + assert!(bit_len <= NUM_BITS); + let mut result_bits = Vec::new(); + for i in 0..bit_len { + let idx = bit_len - i - 1; + result_bits.push(index_bits[idx]); + } + result_bits + } +} diff --git a/recursion/compiler/src/ir/builder.rs b/recursion/compiler/src/ir/builder.rs index 61d254e8c1..b61f263fa9 100644 --- a/recursion/compiler/src/ir/builder.rs +++ b/recursion/compiler/src/ir/builder.rs @@ -1,16 +1,14 @@ -use std::ops::{Add, Mul}; +use p3_field::AbstractField; use super::{ - Array, Config, DslIR, Ext, ExtConst, FromConstant, SymbolicExt, SymbolicFelt, SymbolicUsize, - Usize, + Array, Config, DslIR, Ext, Felt, FromConstant, SymbolicExt, SymbolicFelt, SymbolicUsize, + SymbolicVar, Usize, Var, Variable, }; -use super::{Felt, Var}; -use super::{SymbolicVar, Variable}; -use p3_field::AbstractExtensionField; -use p3_field::AbstractField; -use sp1_recursion_core::runtime::{DIGEST_SIZE, HASH_RATE, NUM_BITS, PERMUTATION_WIDTH}; -#[derive(Debug, Clone)] +/// A builder for the DSL. +/// +/// Can compile to both assembly and a set of constraints. +#[derive(Debug, Clone, Default)] pub struct Builder { pub(crate) felt_count: u32, pub(crate) ext_count: u32, @@ -18,18 +16,8 @@ pub struct Builder { pub operations: Vec>, } -impl Default for Builder { - fn default() -> Self { - Self { - felt_count: 0, - ext_count: 0, - var_count: 0, - operations: Vec::new(), - } - } -} - impl Builder { + /// Creates a new builder with a given number of counts for each type. pub fn new(var_count: u32, felt_count: u32, ext_count: u32) -> Self { Self { felt_count, @@ -39,28 +27,34 @@ impl Builder { } } + /// Pushes an operation to the builder. pub fn push(&mut self, op: DslIR) { self.operations.push(op); } + /// Creates an uninitialized variable. pub fn uninit>(&mut self) -> V { V::uninit(self) } - pub fn eval_const>(&mut self, value: V::Constant) -> V { - V::eval_const(value, self) + /// Evaluates an expression and returns a variable. + pub fn eval, E: Into>(&mut self, expr: E) -> V { + let dst = V::uninit(self); + dst.assign(expr.into(), self); + dst } - pub fn assign, E: Into>(&mut self, dst: V, expr: E) { - dst.assign(expr.into(), self); + /// Evaluates a constant expression and returns a variable. + pub fn constant>(&mut self, value: V::Constant) -> V { + V::constant(value, self) } - pub fn eval, E: Into>(&mut self, expr: E) -> V { - let dst = V::uninit(self); + /// Assigns an expression to a variable. + pub fn assign, E: Into>(&mut self, dst: V, expr: E) { dst.assign(expr.into(), self); - dst } + /// Asserts that two expressions are equal. pub fn assert_eq>( &mut self, lhs: impl Into, @@ -69,6 +63,7 @@ impl Builder { V::assert_eq(lhs, rhs, self); } + /// Asserts that two expressions are not equal. pub fn assert_ne>( &mut self, lhs: impl Into, @@ -77,6 +72,7 @@ impl Builder { V::assert_ne(lhs, rhs, self); } + /// Assert that two vars are equal. pub fn assert_var_eq>, RhsExpr: Into>>( &mut self, lhs: LhsExpr, @@ -85,6 +81,7 @@ impl Builder { self.assert_eq::>(lhs, rhs); } + /// Assert that two vars are not equal. pub fn assert_var_ne>, RhsExpr: Into>>( &mut self, lhs: LhsExpr, @@ -93,6 +90,7 @@ impl Builder { self.assert_ne::>(lhs, rhs); } + /// Assert that two felts are equal. pub fn assert_felt_eq>, RhsExpr: Into>>( &mut self, lhs: LhsExpr, @@ -101,6 +99,7 @@ impl Builder { self.assert_eq::>(lhs, rhs); } + /// Assert that two felts are not equal. pub fn assert_felt_ne>, RhsExpr: Into>>( &mut self, lhs: LhsExpr, @@ -109,6 +108,7 @@ impl Builder { self.assert_ne::>(lhs, rhs); } + /// Assert that two usizes are equal. pub fn assert_usize_eq< LhsExpr: Into>, RhsExpr: Into>, @@ -120,10 +120,12 @@ impl Builder { self.assert_eq::>(lhs, rhs); } + /// Assert that two usizes are not equal. pub fn assert_usize_ne(&mut self, lhs: SymbolicUsize, rhs: SymbolicUsize) { self.assert_ne::>(lhs, rhs); } + /// Assert that two exts are equal. pub fn assert_ext_eq< LhsExpr: Into>, RhsExpr: Into>, @@ -135,6 +137,7 @@ impl Builder { self.assert_eq::>(lhs, rhs); } + /// Assert that two exts are not equal. pub fn assert_ext_ne< LhsExpr: Into>, RhsExpr: Into>, @@ -146,6 +149,7 @@ impl Builder { self.assert_ne::>(lhs, rhs); } + /// Evaluate a block of operations if two expressions are equal. pub fn if_eq>, RhsExpr: Into>>( &mut self, lhs: LhsExpr, @@ -159,6 +163,7 @@ impl Builder { } } + /// Evaluate a block of operations if two expressions are not equal. pub fn if_ne>, RhsExpr: Into>>( &mut self, lhs: LhsExpr, @@ -172,6 +177,7 @@ impl Builder { } } + /// Evaluate a block of operations over a range from start to end. pub fn range( &mut self, start: impl Into>, @@ -185,489 +191,34 @@ impl Builder { } } + /// Break out of a loop. pub fn break_loop(&mut self) { self.operations.push(DslIR::Break); } + /// Print a variable. pub fn print_v(&mut self, dst: Var) { self.operations.push(DslIR::PrintV(dst)); } + /// Print a felt. pub fn print_f(&mut self, dst: Felt) { self.operations.push(DslIR::PrintF(dst)); } + /// Print an ext. pub fn print_e(&mut self, dst: Ext) { self.operations.push(DslIR::PrintE(dst)); } - pub fn ext_from_base_slice(&mut self, arr: &[Felt]) -> Ext { - assert!(arr.len() <= >::D); - let mut res = SymbolicExt::Const(C::EF::zero()); - for i in 0..arr.len() { - res += arr[i] * SymbolicExt::Const(C::EF::monomial(i)); - } - self.eval(res) - } - - pub fn ext2felt(&mut self, value: Ext) -> Array> { - let result = self.dyn_array(4); - self.operations.push(DslIR::Ext2Felt(result.clone(), value)); - result - } - - pub fn ext2felt_circuit(&mut self, value: Ext) -> [Felt; 4] { - let a = self.uninit(); - let b = self.uninit(); - let c = self.uninit(); - let d = self.uninit(); - self.operations - .push(DslIR::CircuitExt2Felt([a, b, c, d], value)); - [a, b, c, d] - } - - /// Throws an error. - pub fn error(&mut self) { - self.operations.push(DslIR::Error()); - } - - /// Converts a usize to a fixed length of bits. - pub fn num2bits_usize(&mut self, num: impl Into>) -> Array> { - // TODO: A separate function for a circuit backend. - - let num = num.into(); - // Allocate an array for the output. - let output = self.dyn_array::>(NUM_BITS); - // Hint the bits of the number to the output array. - self.operations.push(DslIR::HintBitsU(output.clone(), num)); - - // Assert that the entries are bits, compute the sum, and compare it to the original number. - // If the number does not fit in `NUM_BITS`, we will get an error. - let sum: Var<_> = self.eval(C::N::zero()); - for i in 0..NUM_BITS { - // Get the bit. - let bit = self.get(&output, i); - // Assert that the bit is either 0 or 1. - self.assert_var_eq(bit * (bit - C::N::one()), C::N::zero()); - // Add `bit * 2^i` to the sum. - self.assign(sum, sum + bit * C::N::from_canonical_u32(1 << i)); - } - // Finally, assert that the sum is equal to the original number. - self.assert_eq::>(sum, num); - - output - } - - /// Converts a var to a fixed length of bits. - pub fn num2bits_v(&mut self, num: Var) -> Array> { - // TODO: A separate function for a circuit backend. - - // Allocate an array for the output. - let output = self.dyn_array::>(NUM_BITS); - // Hint the bits of the number to the output array. - self.operations.push(DslIR::HintBitsV(output.clone(), num)); - - // Assert that the entries are bits, compute the sum, and compare it to the original number. - // If the number does not fit in `NUM_BITS`, we will get an error. - let sum: Var<_> = self.eval(C::N::zero()); - for i in 0..NUM_BITS { - // Get the bit. - let bit = self.get(&output, i); - // Assert that the bit is either 0 or 1. - self.assert_var_eq(bit * (bit - C::N::one()), C::N::zero()); - // Add `bit * 2^i` to the sum. - self.assign(sum, sum + bit * C::N::from_canonical_u32(1 << i)); - } - // Finally, assert that the sum is equal to the original number. - self.assert_var_eq(sum, num); - - output - } - - /// Converts a felt to a fixed length of bits. - pub fn num2bits_f(&mut self, num: Felt) -> Array> { - // TODO: A separate function for a circuit backend. - - // Allocate an array for the output. - let output = self.dyn_array::>(NUM_BITS); - // Hint the bits of the number to the output array. - self.operations.push(DslIR::HintBitsF(output.clone(), num)); - - // Assert that the entries are bits, compute the sum, and compare it to the original number. - // If the number does not fit in `NUM_BITS`, we will get an error. - let sum: Felt<_> = self.eval(C::F::zero()); - for i in 0..NUM_BITS { - // Get the bit. - let bit = self.get(&output, i); - // Assert that the bit is either 0 or 1. - self.assert_var_eq(bit * (bit - C::N::one()), C::N::zero()); - // Add `bit * 2^i` to the sum. - self.if_eq(bit, C::N::one()).then(|builder| { - builder.assign(sum, sum + C::F::from_canonical_u32(1 << i)); - }); - } - // // Finally, assert that the sum is equal to the original number. - // self.assert_felt_eq(sum, num); - - output - } - - pub fn bits_to_num_felt(&mut self, bits: &Array>) -> Felt { - let num: Felt<_> = self.eval(C::F::zero()); - for i in 0..NUM_BITS { - let bit = self.get(bits, i); - // Add `bit * 2^i` to the sum. - self.if_eq(bit, C::N::one()).then(|builder| { - builder.assign(num, num + C::F::from_canonical_u32(1 << i)); - }); - } - num - } - - pub fn bits_to_num_var(&mut self, bits: &Array>) -> Var { - let num: Var<_> = self.eval(C::N::zero()); - let power: Var<_> = self.eval(C::N::one()); - self.range(0, bits.len()).for_each(|i, builder| { - let bit = builder.get(bits, i); - builder.assign(num, num + bit * power); - builder.assign(power, power * C::N::from_canonical_u32(2)); - }); - num - } - - pub fn bits_to_num_usize(&mut self, bits: &Array>) -> Usize { - self.bits_to_num_var(bits).into() - } - - /// Applies the Poseidon2 permutation to the given array. - /// - /// Reference: https://github.com/Plonky3/Plonky3/blob/4809fa7bedd9ba8f6f5d3267b1592618e3776c57/poseidon2/src/lib.rs#L119 - pub fn poseidon2_permute(&mut self, array: &Array>) -> Array> { - let output = match array { - Array::Fixed(values) => { - assert_eq!(values.len(), PERMUTATION_WIDTH); - self.array::>(Usize::Const(PERMUTATION_WIDTH)) - } - Array::Dyn(_, len) => self.array::>(*len), - }; - self.operations.push(DslIR::Poseidon2PermuteBabyBear( - output.clone(), - array.clone(), - )); - output - } - - /// Applies the Poseidon2 permutation to the given array. - /// - /// Reference: https://github.com/Plonky3/Plonky3/blob/4809fa7bedd9ba8f6f5d3267b1592618e3776c57/poseidon2/src/lib.rs#L119 - pub fn poseidon2_permute_mut(&mut self, array: &Array>) { - self.operations.push(DslIR::Poseidon2PermuteBabyBear( - array.clone(), - array.clone(), - )); - } - - /// Applies the Poseidon2 permutation to the given array. - /// - /// Reference: https://github.com/Plonky3/Plonky3/blob/4809fa7bedd9ba8f6f5d3267b1592618e3776c57/poseidon2/src/lib.rs#L119 - pub fn poseidon2_compress_x( - &mut self, - result: &mut Array>, - left: &Array>, - right: &Array>, - ) { - self.operations.push(DslIR::Poseidon2CompressBabyBear( - result.clone(), - left.clone(), - right.clone(), - )); - } - - /// Applies the Poseidon2 permutation to the given array. - /// - /// Reference: https://github.com/Plonky3/Plonky3/blob/4809fa7bedd9ba8f6f5d3267b1592618e3776c57/poseidon2/src/lib.rs#L119 - pub fn poseidon2_hash(&mut self, array: &Array>) -> Array> { - let mut state: Array> = self.dyn_array(PERMUTATION_WIDTH); - - let break_flag: Var<_> = self.eval(C::N::zero()); - let last_index: Usize<_> = self.eval(array.len() - 1); - self.range(0, array.len()) - .step_by(HASH_RATE) - .for_each(|i, builder| { - builder.if_eq(break_flag, C::N::one()).then(|builder| { - builder.break_loop(); - }); - // Insert elements of the chunk. - builder.range(0, HASH_RATE).for_each(|j, builder| { - let index: Var<_> = builder.eval(i + j); - let element = builder.get(array, index); - builder.set_value(&mut state, j, element); - builder.if_eq(index, last_index).then(|builder| { - builder.assign(break_flag, C::N::one()); - builder.break_loop(); - }); - }); - builder.poseidon2_permute_mut(&state); - }); - - state.truncate(self, Usize::Const(DIGEST_SIZE)); - state - } - - /// Applies the Poseidon2 compression function to the given array. - /// - /// Assumes we are doing a 2-1 compression function with 8 element chunks. - /// - /// Reference: https://github.com/Plonky3/Plonky3/blob/4809fa7bedd9ba8f6f5d3267b1592618e3776c57/symmetric/src/compression.rs#L35 - pub fn poseidon2_compress( - &mut self, - left: &Array>, - right: &Array>, - ) -> Array> { - let mut input = self.dyn_array(PERMUTATION_WIDTH); - for i in 0..DIGEST_SIZE { - let a = self.get(left, i); - let b = self.get(right, i); - self.set(&mut input, i, a); - self.set(&mut input, i + DIGEST_SIZE, b); - } - self.poseidon2_permute_mut(&input); - input - } - - /// Materializes a usize into a variable. - pub fn materialize(&mut self, num: Usize) -> Var { - match num { - Usize::Const(num) => self.eval(C::N::from_canonical_usize(num)), - Usize::Var(num) => num, - } - } - - /// Reference: https://github.com/Plonky3/Plonky3/blob/4809fa7bedd9ba8f6f5d3267b1592618e3776c57/baby-bear/src/baby_bear.rs#L306 - pub fn generator(&mut self) -> Felt { - self.eval(C::F::from_canonical_u32(31)) - } - - /// Reference: https://github.com/Plonky3/Plonky3/blob/4809fa7bedd9ba8f6f5d3267b1592618e3776c57/util/src/lib.rs#L59 - /// - /// *Safety* calling this function with `bit_len` greater [`NUM_BITS`] will result in undefined - /// behavior. - pub fn reverse_bits_len_circuit( - &mut self, - index_bits: Vec>, - bit_len: usize, - ) -> Vec> { - let mut result_bits = Vec::new(); - for i in 0..bit_len { - let idx = bit_len - i - 1; - result_bits.push(index_bits[idx]); - } - result_bits - } - - /// Reference: https://github.com/Plonky3/Plonky3/blob/4809fa7bedd9ba8f6f5d3267b1592618e3776c57/util/src/lib.rs#L59 - /// - /// *Safety* calling this function with `bit_len` greater [`NUM_BITS`] will result in undefined - /// behavior. - pub fn reverse_bits_len( - &mut self, - index_bits: &Array>, - bit_len: impl Into>, - ) -> Array> { - // Compute the reverse bits. - let bit_len = bit_len.into(); - let mut result_bits = self.dyn_array::>(NUM_BITS); - // let bit_len = self.materialize(bit_len); - self.range(0, bit_len).for_each(|i, builder| { - let index: Var = builder.eval(bit_len - i - C::N::one()); - let entry = builder.get(index_bits, index); - builder.set_value(&mut result_bits, i, entry); - }); - - let zero = self.eval(C::N::zero()); - self.range(bit_len, NUM_BITS).for_each(|i, builder| { - builder.set_value(&mut result_bits, i, zero); - }); - - result_bits - } - - #[allow(unused_variables)] - pub fn exp_usize_ef(&mut self, x: Ext, power: Usize) -> Ext { - let result = self.eval(C::F::one()); - let power_f: Ext<_, _> = self.eval(x); - let bits = self.num2bits_usize(power); - self.range(0, bits.len()).for_each(|i, builder| { - let bit = builder.get(&bits, i); - builder - .if_eq(bit, C::N::one()) - .then(|builder| builder.assign(result, result * power_f)); - builder.assign(power_f, power_f * power_f); - }); - result - } - - /// Reference: https://github.com/Plonky3/Plonky3/blob/4809fa7bedd9ba8f6f5d3267b1592618e3776c57/field/src/field.rs#L79 - #[allow(unused_variables)] - pub fn exp_usize_f_bits(&mut self, x: Felt, power_bits: Vec>) -> Felt { - let mut result = self.eval(C::F::one()); - let mut power_f: Felt<_> = self.eval(x); - for i in 0..power_bits.len() { - let bit = power_bits[i]; - let tmp = self.eval(result * power_f); - result = self.select_f(bit, tmp, result); - power_f = self.eval(power_f * power_f); - } - result - } - - /// Reference: https://github.com/Plonky3/Plonky3/blob/4809fa7bedd9ba8f6f5d3267b1592618e3776c57/field/src/field.rs#L79 - #[allow(unused_variables)] - pub fn exp_usize_ef_bits( - &mut self, - x: Ext, - power_bits: Vec>, - ) -> Ext { - let mut result = self.eval(SymbolicExt::Const(C::EF::one())); - let mut power_f: Ext<_, _> = self.eval(x); - for i in 0..power_bits.len() { - let bit = power_bits[i]; - let tmp = self.eval(result * power_f); - result = self.select_ef(bit, tmp, result); - power_f = self.eval(power_f * power_f); - } - result - } - - pub fn exp_bits>(&mut self, x: V, power_bits: &Array>) -> V - where - V::Expression: AbstractField, - V: Copy + Mul, - { - let result = self.eval(V::Expression::one()); - let power_f: V = self.eval(x); - self.range(0, power_bits.len()).for_each(|i, builder| { - let bit = builder.get(power_bits, i); - builder - .if_eq(bit, C::N::one()) - .then(|builder| builder.assign(result, result * power_f)); - builder.assign(power_f, power_f * power_f); - }); - result - } - - // Reference: https://github.com/Plonky3/Plonky3/blob/4809fa7bedd9ba8f6f5d3267b1592618e3776c57/util/src/lib.rs#L59 - pub fn exp_reverse_bits_len>( - &mut self, - x: V, - power_bits: &Array>, - bit_len: impl Into>, - ) -> V - where - V::Expression: AbstractField, - V: Copy + Mul, - { - let result = self.eval(V::Expression::one()); - let power_f: V = self.eval(x); - let bit_len = bit_len.into(); - self.range(0, bit_len).for_each(|i, builder| { - let index: Var = builder.eval(bit_len - i - C::N::one()); - let bit = builder.get(power_bits, index); - builder - .if_eq(bit, C::N::one()) - .then(|builder| builder.assign(result, result * power_f)); - builder.assign(power_f, power_f * power_f); - }); - result - } - - /// Reference: https://github.com/Plonky3/Plonky3/blob/4809fa7bedd9ba8f6f5d3267b1592618e3776c57/field/src/field.rs#L79 - #[allow(unused_variables)] - pub fn exp(&mut self, x: V, power: impl Into>) -> V - where - V::Expression: AbstractField, - V: Variable + Copy + Mul, - { - let power = power.into(); - let result = self.eval(V::Expression::one()); - self.range(0, power).for_each(|_, builder| { - builder.assign(result, result * x); - }); - result - } - - pub fn exp_power_of_2_v( - &mut self, - base: impl Into, - power_log: impl Into>, - ) -> V - where - V: Variable + Copy + Mul, - { - let mut result: V = self.eval(base); - let power_log: Usize<_> = power_log.into(); - match power_log { - Usize::Var(power_log) => { - self.range(0, power_log) - .for_each(|_, builder| builder.assign(result, result * result)); - } - Usize::Const(power_log) => { - for _ in 0..power_log { - result = self.eval(result * result); - } - } - } - result - } - - pub fn exp_power_of_2_v_circuit>( - &mut self, - base: impl Into, - power_log: usize, - ) -> V - where - V: Copy + Mul, - { - let mut result: V = self.eval(base); - for _ in 0..power_log { - result = self.eval(result * result) - } - result - } - - /// Multiplies `base` by `2^{log_power}`. - pub fn sll(&mut self, base: impl Into, shift: Usize) -> V - where - V: Variable + Copy + Add, - { - let result: V = self.eval(base); - self.range(0, shift) - .for_each(|_, builder| builder.assign(result, result + result)); - result - } - - pub fn power_of_two_usize(&mut self, power: Usize) -> Usize { - self.sll(Usize::Const(1), power) - } - - pub fn power_of_two_var(&mut self, power: Usize) -> Var { - self.sll(C::N::one(), power) - } - - pub fn power_of_two_felt(&mut self, power: Usize) -> Felt { - self.sll(C::F::one(), power) - } - - pub fn power_of_two_expr(&mut self, power: Usize) -> Ext { - self.sll(C::EF::one().cons(), power) - } - + /// Hint the length of the next vector of variables. pub fn hint_len(&mut self) -> Var { let len = self.uninit(); self.operations.push(DslIR::HintLen(len)); len } + /// Hint a single variable. pub fn hint_var(&mut self) -> Var { let len = self.hint_len(); let arr = self.dyn_array(len); @@ -675,6 +226,7 @@ impl Builder { self.get(&arr, 0) } + /// Hint a single felt. pub fn hint_felt(&mut self) -> Felt { let len = self.hint_len(); let arr = self.dyn_array(len); @@ -682,6 +234,7 @@ impl Builder { self.get(&arr, 0) } + /// Hint a single ext. pub fn hint_ext(&mut self) -> Ext { let len = self.hint_len(); let arr = self.dyn_array(len); @@ -689,6 +242,7 @@ impl Builder { self.get(&arr, 0) } + /// Hint a vector of variables. pub fn hint_vars(&mut self) -> Array> { let len = self.hint_len(); self.print_v(len); @@ -697,6 +251,7 @@ impl Builder { arr } + /// Hint a vector of felts. pub fn hint_felts(&mut self) -> Array> { let len = self.hint_len(); let arr = self.dyn_array(len); @@ -704,14 +259,29 @@ impl Builder { arr } + /// Hint a vector of exts. pub fn hint_exts(&mut self) -> Array> { let len = self.hint_len(); let arr = self.dyn_array(len); self.operations.push(DslIR::HintExts(arr.clone())); arr } + + /// Throws an error. + pub fn error(&mut self) { + self.operations.push(DslIR::Error()); + } + + /// Materializes a usize into a variable. + pub fn materialize(&mut self, num: Usize) -> Var { + match num { + Usize::Const(num) => self.eval(C::N::from_canonical_usize(num)), + Usize::Var(num) => num, + } + } } +/// A builder for the DSL that handles if statements. pub struct IfBuilder<'a, C: Config> { lhs: SymbolicVar, rhs: SymbolicVar, @@ -719,7 +289,8 @@ pub struct IfBuilder<'a, C: Config> { pub(crate) builder: &'a mut Builder, } -enum Condition { +/// A set of conditions that if statements can be based on. +enum IfCondition { EqConst(N, N), NeConst(N, N), Eq(Var, Var), @@ -744,29 +315,29 @@ impl<'a, C: Config> IfBuilder<'a, C> { // Dispatch instructions to the correct conditional block. match condition { - Condition::EqConst(lhs, rhs) => { + IfCondition::EqConst(lhs, rhs) => { if lhs == rhs { self.builder.operations.extend(then_instructions); } } - Condition::NeConst(lhs, rhs) => { + IfCondition::NeConst(lhs, rhs) => { if lhs != rhs { self.builder.operations.extend(then_instructions); } } - Condition::Eq(lhs, rhs) => { + IfCondition::Eq(lhs, rhs) => { let op = DslIR::IfEq(lhs, rhs, then_instructions, Vec::new()); self.builder.operations.push(op); } - Condition::EqI(lhs, rhs) => { + IfCondition::EqI(lhs, rhs) => { let op = DslIR::IfEqI(lhs, rhs, then_instructions, Vec::new()); self.builder.operations.push(op); } - Condition::Ne(lhs, rhs) => { + IfCondition::Ne(lhs, rhs) => { let op = DslIR::IfNe(lhs, rhs, then_instructions, Vec::new()); self.builder.operations.push(op); } - Condition::NeI(lhs, rhs) => { + IfCondition::NeI(lhs, rhs) => { let op = DslIR::IfNeI(lhs, rhs, then_instructions, Vec::new()); self.builder.operations.push(op); } @@ -800,105 +371,106 @@ impl<'a, C: Config> IfBuilder<'a, C> { // Dispatch instructions to the correct conditional block. match condition { - Condition::EqConst(lhs, rhs) => { + IfCondition::EqConst(lhs, rhs) => { if lhs == rhs { self.builder.operations.extend(then_instructions); } else { self.builder.operations.extend(else_instructions); } } - Condition::NeConst(lhs, rhs) => { + IfCondition::NeConst(lhs, rhs) => { if lhs != rhs { self.builder.operations.extend(then_instructions); } else { self.builder.operations.extend(else_instructions); } } - Condition::Eq(lhs, rhs) => { + IfCondition::Eq(lhs, rhs) => { let op = DslIR::IfEq(lhs, rhs, then_instructions, else_instructions); self.builder.operations.push(op); } - Condition::EqI(lhs, rhs) => { + IfCondition::EqI(lhs, rhs) => { let op = DslIR::IfEqI(lhs, rhs, then_instructions, else_instructions); self.builder.operations.push(op); } - Condition::Ne(lhs, rhs) => { + IfCondition::Ne(lhs, rhs) => { let op = DslIR::IfNe(lhs, rhs, then_instructions, else_instructions); self.builder.operations.push(op); } - Condition::NeI(lhs, rhs) => { + IfCondition::NeI(lhs, rhs) => { let op = DslIR::IfNeI(lhs, rhs, then_instructions, else_instructions); self.builder.operations.push(op); } } } - fn condition(&mut self) -> Condition { + fn condition(&mut self) -> IfCondition { match (self.lhs.clone(), self.rhs.clone(), self.is_eq) { (SymbolicVar::Const(lhs), SymbolicVar::Const(rhs), true) => { - Condition::EqConst(lhs, rhs) + IfCondition::EqConst(lhs, rhs) } (SymbolicVar::Const(lhs), SymbolicVar::Const(rhs), false) => { - Condition::NeConst(lhs, rhs) + IfCondition::NeConst(lhs, rhs) } - (SymbolicVar::Const(lhs), SymbolicVar::Val(rhs), true) => Condition::EqI(rhs, lhs), - (SymbolicVar::Const(lhs), SymbolicVar::Val(rhs), false) => Condition::NeI(rhs, lhs), + (SymbolicVar::Const(lhs), SymbolicVar::Val(rhs), true) => IfCondition::EqI(rhs, lhs), + (SymbolicVar::Const(lhs), SymbolicVar::Val(rhs), false) => IfCondition::NeI(rhs, lhs), (SymbolicVar::Const(lhs), rhs, true) => { let rhs: Var = self.builder.eval(rhs); - Condition::EqI(rhs, lhs) + IfCondition::EqI(rhs, lhs) } (SymbolicVar::Const(lhs), rhs, false) => { let rhs: Var = self.builder.eval(rhs); - Condition::NeI(rhs, lhs) + IfCondition::NeI(rhs, lhs) } (SymbolicVar::Val(lhs), SymbolicVar::Const(rhs), true) => { let lhs: Var = self.builder.eval(lhs); - Condition::EqI(lhs, rhs) + IfCondition::EqI(lhs, rhs) } (SymbolicVar::Val(lhs), SymbolicVar::Const(rhs), false) => { let lhs: Var = self.builder.eval(lhs); - Condition::NeI(lhs, rhs) + IfCondition::NeI(lhs, rhs) } (lhs, SymbolicVar::Const(rhs), true) => { let lhs: Var = self.builder.eval(lhs); - Condition::EqI(lhs, rhs) + IfCondition::EqI(lhs, rhs) } (lhs, SymbolicVar::Const(rhs), false) => { let lhs: Var = self.builder.eval(lhs); - Condition::NeI(lhs, rhs) + IfCondition::NeI(lhs, rhs) } - (SymbolicVar::Val(lhs), SymbolicVar::Val(rhs), true) => Condition::Eq(lhs, rhs), - (SymbolicVar::Val(lhs), SymbolicVar::Val(rhs), false) => Condition::Ne(lhs, rhs), + (SymbolicVar::Val(lhs), SymbolicVar::Val(rhs), true) => IfCondition::Eq(lhs, rhs), + (SymbolicVar::Val(lhs), SymbolicVar::Val(rhs), false) => IfCondition::Ne(lhs, rhs), (SymbolicVar::Val(lhs), rhs, true) => { let rhs: Var = self.builder.eval(rhs); - Condition::Eq(lhs, rhs) + IfCondition::Eq(lhs, rhs) } (SymbolicVar::Val(lhs), rhs, false) => { let rhs: Var = self.builder.eval(rhs); - Condition::Ne(lhs, rhs) + IfCondition::Ne(lhs, rhs) } (lhs, SymbolicVar::Val(rhs), true) => { let lhs: Var = self.builder.eval(lhs); - Condition::Eq(lhs, rhs) + IfCondition::Eq(lhs, rhs) } (lhs, SymbolicVar::Val(rhs), false) => { let lhs: Var = self.builder.eval(lhs); - Condition::Ne(lhs, rhs) + IfCondition::Ne(lhs, rhs) } (lhs, rhs, true) => { let lhs: Var = self.builder.eval(lhs); let rhs: Var = self.builder.eval(rhs); - Condition::Eq(lhs, rhs) + IfCondition::Eq(lhs, rhs) } (lhs, rhs, false) => { let lhs: Var = self.builder.eval(lhs); let rhs: Var = self.builder.eval(rhs); - Condition::Ne(lhs, rhs) + IfCondition::Ne(lhs, rhs) } } } } +/// A builder for the DSL that handles for loops. pub struct RangeBuilder<'a, C: Config> { start: Usize, end: Usize, @@ -935,112 +507,3 @@ impl<'a, C: Config> RangeBuilder<'a, C> { self.builder.operations.push(op); } } - -#[cfg(test)] -mod tests { - use p3_field::PrimeField32; - use p3_util::reverse_bits_len; - use rand::{thread_rng, Rng}; - use sp1_core::{stark::StarkGenericConfig, utils::BabyBearPoseidon2}; - use sp1_recursion_core::runtime::{Runtime, NUM_BITS}; - - use p3_field::AbstractField; - - use crate::{ - asm::VmBuilder, - prelude::{Felt, Usize, Var}, - }; - - #[test] - fn test_num2bits() { - type SC = BabyBearPoseidon2; - type F = ::Val; - type EF = ::Challenge; - - let mut rng = thread_rng(); - let config = SC::default(); - - // Initialize a builder. - let mut builder = VmBuilder::::default(); - - // Get a random var with `NUM_BITS` bits. - let num_val: F = rng.gen(); - - // Materialize the number as a var - let num: Var<_> = builder.eval(num_val); - // Materialize the number as a felt - let num_felt: Felt<_> = builder.eval(num_val); - // Materialize the number as a usize - let num_usize: Usize<_> = builder.eval(num_val.as_canonical_u32() as usize); - - // Get the bits. - let bits = builder.num2bits_v(num); - let bits_felt = builder.num2bits_f(num_felt); - let bits_usize = builder.num2bits_usize(num_usize); - - // Compare the expected bits with the actual bits. - for i in 0..NUM_BITS { - // Get the i-th bit of the number. - let expected_bit = F::from_canonical_u32((num_val.as_canonical_u32() >> i) & 1); - // Compare the expected bit of the var with the actual bit. - let bit = builder.get(&bits, i); - builder.assert_var_eq(bit, expected_bit); - // Compare the expected bit of the felt with the actual bit. - let bit_felt = builder.get(&bits_felt, i); - builder.assert_var_eq(bit_felt, expected_bit); - // Compare the expected bit of the usize with the actual bit. - let bit_usize = builder.get(&bits_usize, i); - builder.assert_var_eq(bit_usize, expected_bit); - } - - // Test the conversion back to a number. - let num_back = builder.bits_to_num_var(&bits); - builder.assert_var_eq(num_back, num); - let num_felt_back = builder.bits_to_num_felt(&bits_felt); - builder.assert_felt_eq(num_felt_back, num_felt); - let num_usize_back = builder.bits_to_num_usize(&bits_usize); - builder.assert_usize_eq(num_usize_back, num_usize); - - let program = builder.compile(); - - let mut runtime = Runtime::::new(&program, config.perm.clone()); - runtime.run(); - } - - #[test] - fn test_reverse_bits_len() { - type SC = BabyBearPoseidon2; - type F = ::Val; - type EF = ::Challenge; - - let mut rng = thread_rng(); - let config = SC::default(); - - // Initialize a builder. - let mut builder = VmBuilder::::default(); - - // Get a random var with `NUM_BITS` bits. - let x_val: F = rng.gen(); - - // Materialize the number as a var - let x: Var<_> = builder.eval(x_val); - let x_bits = builder.num2bits_v(x); - - for i in 1..NUM_BITS { - // Get the reference value. - let expected_value = reverse_bits_len(x_val.as_canonical_u32() as usize, i); - let value_bits = builder.reverse_bits_len(&x_bits, i); - let value = builder.bits_to_num_var(&value_bits); - builder.assert_usize_eq(value, expected_value); - let var_i: Var<_> = builder.eval(F::from_canonical_usize(i)); - let value_var_bits = builder.reverse_bits_len(&x_bits, var_i); - let value_var = builder.bits_to_num_var(&value_var_bits); - builder.assert_usize_eq(value_var, expected_value); - } - - let program = builder.compile(); - - let mut runtime = Runtime::::new(&program, config.perm.clone()); - runtime.run(); - } -} diff --git a/recursion/compiler/src/ir/collections.rs b/recursion/compiler/src/ir/collections.rs index d434a563aa..a262119da7 100644 --- a/recursion/compiler/src/ir/collections.rs +++ b/recursion/compiler/src/ir/collections.rs @@ -1,14 +1,9 @@ -use super::{Builder, Config, FromConstant, MemIndex, MemVariable, Ptr, Usize, Var, Variable}; use itertools::Itertools; use p3_field::AbstractField; -use super::Ext; -use super::{DslIR, Felt}; +use super::{Builder, Config, FromConstant, MemIndex, MemVariable, Ptr, Usize, Var, Variable}; /// An array that is either of static or dynamic size. -/// -/// If the target is a circuit-based system, then the arrays must be static. Other targets can -/// theoretically support both types of arrays.. #[derive(Debug, Clone)] pub enum Array { Fixed(Vec), @@ -32,22 +27,7 @@ impl> Array { } } - /// Gets the fixed length of the fixed-size array. - pub fn static_len(&self) -> usize { - match self { - Self::Fixed(vec) => vec.len(), - _ => panic!("cannot get the static length of a dynamic array"), - } - } - - /// Gets the n'th elment. - pub fn static_get(&self, index: usize) -> V { - match self { - Self::Fixed(vec) => vec[index].clone(), - _ => panic!("cannot get the n'th element of a dynamic array"), - } - } - + /// Shifts the array by `shift` elements. pub fn shift(&self, builder: &mut Builder, shift: Var) -> Array { match self { Self::Fixed(_) => { @@ -66,6 +46,7 @@ impl> Array { } } + /// Truncates the array to `len` elements. pub fn truncate(&self, builder: &mut Builder, len: Usize) { match self { Self::Fixed(_) => { @@ -84,33 +65,12 @@ impl Builder { self.dyn_array(len) } + /// Creates an array from a vector. pub fn vec>(&mut self, v: Vec) -> Array { Array::Fixed(v) } - pub fn select_v(&mut self, cond: Var, a: Var, b: Var) -> Var { - let c = self.uninit(); - self.operations.push(DslIR::CircuitSelectV(cond, a, b, c)); - c - } - - pub fn select_f(&mut self, cond: Var, a: Felt, b: Felt) -> Felt { - let c = self.uninit(); - self.operations.push(DslIR::CircuitSelectF(cond, a, b, c)); - c - } - - pub fn select_ef( - &mut self, - cond: Var, - a: Ext, - b: Ext, - ) -> Ext { - let c = self.uninit(); - self.operations.push(DslIR::CircuitSelectE(cond, a, b, c)); - c - } - + /// Creates a dynamic array for a length. pub fn dyn_array>(&mut self, len: impl Into>) -> Array { let len = match len.into() { Usize::Const(len) => self.eval(C::N::from_canonical_usize(len)), @@ -121,20 +81,6 @@ impl Builder { Array::Dyn(ptr, len) } - pub fn array_to_dyn>(&mut self, array: Array) -> Array { - match array { - Array::Fixed(v) => { - let mut dyn_array = self.dyn_array(v.len()); - - for (i, value) in v.into_iter().enumerate() { - self.set(&mut dyn_array, i, value); - } - dyn_array - } - Array::Dyn(ptr, len) => Array::Dyn(ptr, len), - } - } - pub fn get, I: Into>>( &mut self, slice: &Array, @@ -329,11 +275,10 @@ impl> MemVariable for Array { impl + MemVariable> FromConstant for Array { type Constant = Vec; - fn eval_const(value: Self::Constant, builder: &mut Builder) -> Self { + fn constant(value: Self::Constant, builder: &mut Builder) -> Self { let mut array = builder.dyn_array(value.len()); - // Assign each element. for (i, val) in value.into_iter().enumerate() { - let val = V::eval_const(val, builder); + let val = V::constant(val, builder); builder.set(&mut array, i, val); } array diff --git a/recursion/compiler/src/ir/instructions.rs b/recursion/compiler/src/ir/instructions.rs index 772f87fe4f..d0266e2285 100644 --- a/recursion/compiler/src/ir/instructions.rs +++ b/recursion/compiler/src/ir/instructions.rs @@ -1,14 +1,14 @@ use super::{Array, FriFoldInput, MemIndex, Ptr}; - use super::{Config, Ext, Felt, Usize, Var}; #[derive(Debug, Clone)] pub enum DslIR { - Imm(Var, C::N), - ImmFelt(Felt, C::F), - ImmExt(Ext, C::EF), + // Immediates. + ImmV(Var, C::N), + ImmF(Felt, C::F), + ImmE(Ext, C::EF), - // Arithmetic instructions. + // Additions. AddV(Var, Var, Var), AddVI(Var, Var, C::N), AddF(Felt, Felt, Felt), @@ -18,14 +18,8 @@ pub enum DslIR { AddEFI(Ext, Ext, C::F), AddEFFI(Ext, Felt, C::EF), AddEF(Ext, Ext, Felt), - MulV(Var, Var, Var), - MulVI(Var, Var, C::N), - MulF(Felt, Felt, Felt), - MulFI(Felt, Felt, C::F), - MulE(Ext, Ext, Ext), - MulEI(Ext, Ext, C::EF), - MulEFI(Ext, Ext, C::F), - MulEF(Ext, Ext, Felt), + + // Subtractions. SubV(Var, Var, Var), SubVI(Var, Var, C::N), SubVIN(Var, C::N, Var), @@ -37,6 +31,18 @@ pub enum DslIR { SubEIN(Ext, C::EF, Ext), SubEFI(Ext, Ext, C::F), SubEF(Ext, Ext, Felt), + + // Multiplications. + MulV(Var, Var, Var), + MulVI(Var, Var, C::N), + MulF(Felt, Felt, Felt), + MulFI(Felt, Felt, C::F), + MulE(Ext, Ext, Ext), + MulEI(Ext, Ext, C::EF), + MulEFI(Ext, Ext, C::F), + MulEF(Ext, Ext, Felt), + + // Divisions. DivF(Felt, Felt, Felt), DivFI(Felt, Felt, C::F), DivFIN(Felt, C::F, Felt), @@ -46,6 +52,8 @@ pub enum DslIR { DivEFI(Ext, Ext, C::F), DivEFIN(Ext, C::F, Ext), DivEF(Ext, Ext, Felt), + + // Negations. NegV(Var, Var), NegF(Felt, Felt), NegE(Ext, Ext), @@ -53,7 +61,7 @@ pub enum DslIR { InvF(Felt, Felt), InvE(Ext, Ext), - // Control flow instructions. + // Control flow. For(Usize, Usize, C::N, Var, Vec>), IfEq(Var, Var, Vec>, Vec>), IfNe(Var, Var, Vec>, Vec>), @@ -61,7 +69,7 @@ pub enum DslIR { IfNeI(Var, C::N, Vec>, Vec>), Break, - // Assertions + // Assertions. AssertEqV(Var, Var), AssertNeV(Var, Var), AssertEqF(Felt, Felt), @@ -91,40 +99,39 @@ pub enum DslIR { /// Store extension field at adress StoreE(Ptr, Ext, MemIndex), - // Miscellaneous instructions. - PrintV(Var), - PrintF(Felt), - PrintE(Ext), - Error(), + // Bits. Num2BitsV(Array>, Usize), Num2BitsF(Array>, Felt), + CircuitNum2BitsV(Var, usize, Vec>), + CircuitNum2BitsF(Felt, Vec>), + ReverseBitsLen(Usize, Usize, Usize), - HintBitsU(Array>, Usize), - HintBitsV(Array>, Var), - HintBitsF(Array>, Felt), + // Hashing. Poseidon2PermuteBabyBear(Array>, Array>), Poseidon2CompressBabyBear( Array>, Array>, Array>, ), + CircuitPoseidon2Permute([Var; 3]), + + // Miscellaneous instructions. + HintBitsU(Array>, Usize), + HintBitsV(Array>, Var), + HintBitsF(Array>, Felt), + PrintV(Var), + PrintF(Felt), + PrintE(Ext), + Error(), TwoAdicGenerator(Felt, Usize), - ReverseBitsLen(Usize, Usize, Usize), ExpUsizeV(Var, Var, Usize), ExpUsizeF(Felt, Felt, Usize), Ext2Felt(Array>, Ext), - HintLen(Var), HintVars(Array>), HintFelts(Array>), HintExts(Array>), - // FRI specific instructions. FriFold(Var, Array>), - - // Circuit-specific instructions. - CircuitPoseidon2Permute([Var; 3]), - CircuitNum2BitsV(Var, usize, Vec>), - CircuitNum2BitsF(Felt, Vec>), CircuitSelectV(Var, Var, Var, Var), CircuitSelectF(Var, Felt, Felt, Felt), CircuitSelectE( diff --git a/recursion/compiler/src/ir/mod.rs b/recursion/compiler/src/ir/mod.rs index b2d3e014eb..c0098c7932 100644 --- a/recursion/compiler/src/ir/mod.rs +++ b/recursion/compiler/src/ir/mod.rs @@ -1,9 +1,11 @@ use p3_field::{ExtensionField, PrimeField, TwoAdicField}; +mod bits; mod builder; mod collections; mod fold; mod instructions; +mod poseidon; mod ptr; mod symbolic; mod types; @@ -19,7 +21,7 @@ pub use symbolic::*; pub use types::*; pub use var::*; -pub trait Config: Clone { +pub trait Config: Clone + Default { type N: PrimeField; type F: PrimeField + TwoAdicField; type EF: ExtensionField + TwoAdicField; diff --git a/recursion/compiler/src/ir/poseidon.rs b/recursion/compiler/src/ir/poseidon.rs new file mode 100644 index 0000000000..62b9a0ad60 --- /dev/null +++ b/recursion/compiler/src/ir/poseidon.rs @@ -0,0 +1,101 @@ +use p3_field::AbstractField; +use sp1_recursion_core::runtime::{DIGEST_SIZE, HASH_RATE, PERMUTATION_WIDTH}; + +use super::{Array, Builder, Config, DslIR, Usize, Var}; +use crate::prelude::Felt; + +impl Builder { + /// Applies the Poseidon2 permutation to the given array. + /// + /// Reference: [p3_poseidon2::Poseidon2] + pub fn poseidon2_permute(&mut self, array: &Array>) -> Array> { + let output = match array { + Array::Fixed(values) => { + assert_eq!(values.len(), PERMUTATION_WIDTH); + self.array::>(Usize::Const(PERMUTATION_WIDTH)) + } + Array::Dyn(_, len) => self.array::>(*len), + }; + self.operations.push(DslIR::Poseidon2PermuteBabyBear( + output.clone(), + array.clone(), + )); + output + } + + /// Applies the Poseidon2 permutation to the given array. + /// + /// Reference: [p3_poseidon2::Poseidon2] + pub fn poseidon2_permute_mut(&mut self, array: &Array>) { + self.operations.push(DslIR::Poseidon2PermuteBabyBear( + array.clone(), + array.clone(), + )); + } + + /// Applies the Poseidon2 compression function to the given array. + /// + /// Reference: [p3_symmetric::TruncatedPermutation] + pub fn poseidon2_compress( + &mut self, + left: &Array>, + right: &Array>, + ) -> Array> { + let mut input = self.dyn_array(PERMUTATION_WIDTH); + for i in 0..DIGEST_SIZE { + let a = self.get(left, i); + let b = self.get(right, i); + self.set(&mut input, i, a); + self.set(&mut input, i + DIGEST_SIZE, b); + } + self.poseidon2_permute_mut(&input); + input + } + + /// Applies the Poseidon2 compression to the given array. + /// + /// Reference: [p3_symmetric::TruncatedPermutation] + pub fn poseidon2_compress_x( + &mut self, + result: &mut Array>, + left: &Array>, + right: &Array>, + ) { + self.operations.push(DslIR::Poseidon2CompressBabyBear( + result.clone(), + left.clone(), + right.clone(), + )); + } + + /// Applies the Poseidon2 permutation to the given array. + /// + /// Reference: [p3_symmetric::PaddingFreeSponge] + pub fn poseidon2_hash(&mut self, array: &Array>) -> Array> { + let mut state: Array> = self.dyn_array(PERMUTATION_WIDTH); + + let break_flag: Var<_> = self.eval(C::N::zero()); + let last_index: Usize<_> = self.eval(array.len() - 1); + self.range(0, array.len()) + .step_by(HASH_RATE) + .for_each(|i, builder| { + builder.if_eq(break_flag, C::N::one()).then(|builder| { + builder.break_loop(); + }); + // Insert elements of the chunk. + builder.range(0, HASH_RATE).for_each(|j, builder| { + let index: Var<_> = builder.eval(i + j); + let element = builder.get(array, index); + builder.set_value(&mut state, j, element); + builder.if_eq(index, last_index).then(|builder| { + builder.assign(break_flag, C::N::one()); + builder.break_loop(); + }); + }); + builder.poseidon2_permute_mut(&state); + }); + + state.truncate(self, Usize::Const(DIGEST_SIZE)); + state + } +} diff --git a/recursion/compiler/src/ir/ptr.rs b/recursion/compiler/src/ir/ptr.rs index 21da925829..e0d6fffe70 100644 --- a/recursion/compiler/src/ir/ptr.rs +++ b/recursion/compiler/src/ir/ptr.rs @@ -1,8 +1,10 @@ +use core::ops::{Add, Sub}; + use p3_field::Field; use super::{Builder, Config, DslIR, MemIndex, MemVariable, SymbolicVar, Usize, Var, Variable}; -use core::ops::{Add, Sub}; +/// A point to a location in memory. #[derive(Debug, Clone, Copy)] pub struct Ptr { pub address: Var, @@ -13,16 +15,19 @@ pub struct SymbolicPtr { } impl Builder { + /// Allocates an array on the heap. pub(crate) fn alloc(&mut self, len: Usize, size: usize) -> Ptr { let ptr = Ptr::uninit(self); self.push(DslIR::Alloc(ptr, len, size)); ptr } + /// Loads a value from memory. pub fn load>(&mut self, var: V, ptr: Ptr, index: MemIndex) { var.load(ptr, index, self); } + /// Stores a value to memory. pub fn store>(&mut self, ptr: Ptr, index: MemIndex, value: V) { value.store(ptr, index, self); } diff --git a/recursion/compiler/src/ir/symbolic.rs b/recursion/compiler/src/ir/symbolic.rs index d888550d44..dae5377a3e 100644 --- a/recursion/compiler/src/ir/symbolic.rs +++ b/recursion/compiler/src/ir/symbolic.rs @@ -1,15 +1,17 @@ -use super::Usize; -use super::{Ext, Felt, Var}; use alloc::rc::Rc; use core::any::Any; use core::ops::{Add, Div, Mul, Neg, Sub}; -use p3_field::Field; -use p3_field::{AbstractField, ExtensionField}; use std::any::TypeId; use std::iter::{Product, Sum}; use std::mem; use std::ops::{AddAssign, DivAssign, MulAssign, SubAssign}; +use p3_field::Field; +use p3_field::{AbstractField, ExtensionField}; + +use super::Usize; +use super::{Ext, Felt, Var}; + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum SymbolicVar { Const(N), diff --git a/recursion/compiler/src/ir/types.rs b/recursion/compiler/src/ir/types.rs index 8ae389c9ca..1c3eaf3214 100644 --- a/recursion/compiler/src/ir/types.rs +++ b/recursion/compiler/src/ir/types.rs @@ -1,14 +1,14 @@ use alloc::format; +use core::marker::PhantomData; +use std::collections::HashMap; +use std::hash::Hash; + use p3_field::AbstractField; use p3_field::ExtensionField; use p3_field::Field; use serde::Deserialize; use serde::Serialize; -use core::marker::PhantomData; -use std::collections::HashMap; -use std::hash::Hash; - use super::ExtConst; use super::FromConstant; use super::MemIndex; @@ -17,15 +17,25 @@ use super::Ptr; use super::SymbolicUsize; use super::{Builder, Config, DslIR, SymbolicExt, SymbolicFelt, SymbolicVar, Variable}; +/// A variable that represents a native field element. +/// +/// Used for counters, simple loops, etc. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Var(pub u32, pub PhantomData); +/// A variable that represents an emulated field element. +/// +/// Used to do field arithmetic for recursive verification. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct Felt(pub u32, pub PhantomData); +/// A variable that represents an emulated extension field element. +/// +/// Used to do extension field arithmetic for recursive verification. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct Ext(pub u32, pub PhantomData<(F, EF)>); +/// A variable that represents either a constant or variable counter. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum Usize { Const(usize), @@ -202,7 +212,7 @@ impl Var { } match src { SymbolicVar::Const(c) => { - builder.operations.push(DslIR::Imm(*self, c)); + builder.operations.push(DslIR::ImmV(*self, c)); } SymbolicVar::Val(v) => { builder @@ -212,7 +222,7 @@ impl Var { SymbolicVar::Add(lhs, rhs) => match (&*lhs, &*rhs) { (SymbolicVar::Const(lhs), SymbolicVar::Const(rhs)) => { let sum = *lhs + *rhs; - builder.operations.push(DslIR::Imm(*self, sum)); + builder.operations.push(DslIR::ImmV(*self, sum)); } (SymbolicVar::Const(lhs), SymbolicVar::Val(rhs)) => { builder.operations.push(DslIR::AddVI(*self, *rhs, *lhs)); @@ -256,7 +266,7 @@ impl Var { SymbolicVar::Mul(lhs, rhs) => match (&*lhs, &*rhs) { (SymbolicVar::Const(lhs), SymbolicVar::Const(rhs)) => { let product = *lhs * *rhs; - builder.push(DslIR::Imm(*self, product)); + builder.push(DslIR::ImmV(*self, product)); } (SymbolicVar::Const(lhs), SymbolicVar::Val(rhs)) => { builder.push(DslIR::MulVI(*self, *rhs, *lhs)); @@ -304,7 +314,7 @@ impl Var { SymbolicVar::Sub(lhs, rhs) => match (&*lhs, &*rhs) { (SymbolicVar::Const(lhs), SymbolicVar::Const(rhs)) => { let difference = *lhs - *rhs; - builder.push(DslIR::Imm(*self, difference)); + builder.push(DslIR::ImmV(*self, difference)); } (SymbolicVar::Const(lhs), SymbolicVar::Val(rhs)) => { builder.push(DslIR::SubVIN(*self, *lhs, *rhs)); @@ -352,7 +362,7 @@ impl Var { SymbolicVar::Neg(operand) => match &*operand { SymbolicVar::Const(operand) => { let negated = -*operand; - builder.push(DslIR::Imm(*self, negated)); + builder.push(DslIR::ImmV(*self, negated)); } SymbolicVar::Val(operand) => { builder.push(DslIR::SubVIN(*self, C::N::zero(), *operand)); @@ -493,7 +503,7 @@ impl Felt { } match src { SymbolicFelt::Const(c) => { - builder.operations.push(DslIR::ImmFelt(*self, c)); + builder.operations.push(DslIR::ImmF(*self, c)); } SymbolicFelt::Val(v) => { builder @@ -503,7 +513,7 @@ impl Felt { SymbolicFelt::Add(lhs, rhs) => match (&*lhs, &*rhs) { (SymbolicFelt::Const(lhs), SymbolicFelt::Const(rhs)) => { let sum = *lhs + *rhs; - builder.operations.push(DslIR::ImmFelt(*self, sum)); + builder.operations.push(DslIR::ImmF(*self, sum)); } (SymbolicFelt::Const(lhs), SymbolicFelt::Val(rhs)) => { builder.operations.push(DslIR::AddFI(*self, *rhs, *lhs)); @@ -551,7 +561,7 @@ impl Felt { SymbolicFelt::Mul(lhs, rhs) => match (&*lhs, &*rhs) { (SymbolicFelt::Const(lhs), SymbolicFelt::Const(rhs)) => { let product = *lhs * *rhs; - builder.push(DslIR::ImmFelt(*self, product)); + builder.push(DslIR::ImmF(*self, product)); } (SymbolicFelt::Const(lhs), SymbolicFelt::Val(rhs)) => { builder.push(DslIR::MulFI(*self, *rhs, *lhs)); @@ -599,7 +609,7 @@ impl Felt { SymbolicFelt::Sub(lhs, rhs) => match (&*lhs, &*rhs) { (SymbolicFelt::Const(lhs), SymbolicFelt::Const(rhs)) => { let difference = *lhs - *rhs; - builder.push(DslIR::ImmFelt(*self, difference)); + builder.push(DslIR::ImmF(*self, difference)); } (SymbolicFelt::Const(lhs), SymbolicFelt::Val(rhs)) => { builder.push(DslIR::SubFIN(*self, *lhs, *rhs)); @@ -647,7 +657,7 @@ impl Felt { SymbolicFelt::Div(lhs, rhs) => match (&*lhs, &*rhs) { (SymbolicFelt::Const(lhs), SymbolicFelt::Const(rhs)) => { let quotient = *lhs / *rhs; - builder.push(DslIR::ImmFelt(*self, quotient)); + builder.push(DslIR::ImmF(*self, quotient)); } (SymbolicFelt::Const(lhs), SymbolicFelt::Val(rhs)) => { builder.push(DslIR::DivFIN(*self, *lhs, *rhs)); @@ -695,7 +705,7 @@ impl Felt { SymbolicFelt::Neg(operand) => match &*operand { SymbolicFelt::Const(operand) => { let negated = -*operand; - builder.push(DslIR::ImmFelt(*self, negated)); + builder.push(DslIR::ImmF(*self, negated)); } SymbolicFelt::Val(operand) => { builder.push(DslIR::SubFIN(*self, C::F::zero(), *operand)); @@ -841,7 +851,7 @@ impl> Ext { SymbolicFelt::Const(c) => { builder .operations - .push(DslIR::ImmExt(*self, C::EF::from_base(*c))); + .push(DslIR::ImmE(*self, C::EF::from_base(*c))); } SymbolicFelt::Val(v) => { builder @@ -855,7 +865,7 @@ impl> Ext { } }, SymbolicExt::Const(c) => { - builder.operations.push(DslIR::ImmExt(*self, c)); + builder.operations.push(DslIR::ImmE(*self, c)); } SymbolicExt::Val(v) => { builder @@ -865,7 +875,7 @@ impl> Ext { SymbolicExt::Add(lhs, rhs) => match (&*lhs, &*rhs) { (SymbolicExt::Const(lhs), SymbolicExt::Const(rhs)) => { let sum = *lhs + *rhs; - builder.operations.push(DslIR::ImmExt(*self, sum)); + builder.operations.push(DslIR::ImmE(*self, sum)); } (SymbolicExt::Const(lhs), SymbolicExt::Val(rhs)) => { builder.operations.push(DslIR::AddEI(*self, *rhs, *lhs)); @@ -874,7 +884,7 @@ impl> Ext { match rhs.as_ref() { SymbolicFelt::Const(rhs) => { let sum = *lhs + C::EF::from_base(*rhs); - builder.operations.push(DslIR::ImmExt(*self, sum)); + builder.operations.push(DslIR::ImmE(*self, sum)); } SymbolicFelt::Val(rhs) => { builder.operations.push(DslIR::AddEFFI(*self, *rhs, *lhs)); @@ -945,7 +955,7 @@ impl> Ext { SymbolicExt::Mul(lhs, rhs) => match (&*lhs, &*rhs) { (SymbolicExt::Const(lhs), SymbolicExt::Const(rhs)) => { let product = *lhs * *rhs; - builder.push(DslIR::ImmExt(*self, product)); + builder.push(DslIR::ImmE(*self, product)); } (SymbolicExt::Const(lhs), SymbolicExt::Val(rhs)) => { builder.push(DslIR::MulEI(*self, *rhs, *lhs)); @@ -993,7 +1003,7 @@ impl> Ext { SymbolicExt::Sub(lhs, rhs) => match (&*lhs, &*rhs) { (SymbolicExt::Const(lhs), SymbolicExt::Const(rhs)) => { let difference = *lhs - *rhs; - builder.push(DslIR::ImmExt(*self, difference)); + builder.push(DslIR::ImmE(*self, difference)); } (SymbolicExt::Const(lhs), SymbolicExt::Val(rhs)) => { builder.push(DslIR::SubEIN(*self, *lhs, *rhs)); @@ -1040,7 +1050,7 @@ impl> Ext { SymbolicExt::Div(lhs, rhs) => match (&*lhs, &*rhs) { (SymbolicExt::Const(lhs), SymbolicExt::Const(rhs)) => { let quotient = *lhs / *rhs; - builder.push(DslIR::ImmExt(*self, quotient)); + builder.push(DslIR::ImmE(*self, quotient)); } (SymbolicExt::Const(lhs), SymbolicExt::Val(rhs)) => { builder.push(DslIR::DivEIN(*self, *lhs, *rhs)); @@ -1088,7 +1098,7 @@ impl> Ext { SymbolicExt::Neg(operand) => match &*operand { SymbolicExt::Const(operand) => { let negated = -*operand; - builder.push(DslIR::ImmExt(*self, negated)); + builder.push(DslIR::ImmE(*self, negated)); } SymbolicExt::Val(operand) => { builder.push(DslIR::NegE(*self, *operand)); @@ -1222,7 +1232,7 @@ impl MemVariable for Ext { impl FromConstant for Var { type Constant = C::N; - fn eval_const(value: Self::Constant, builder: &mut Builder) -> Self { + fn constant(value: Self::Constant, builder: &mut Builder) -> Self { builder.eval(value) } } @@ -1230,7 +1240,7 @@ impl FromConstant for Var { impl FromConstant for Felt { type Constant = C::F; - fn eval_const(value: Self::Constant, builder: &mut Builder) -> Self { + fn constant(value: Self::Constant, builder: &mut Builder) -> Self { builder.eval(value) } } @@ -1238,7 +1248,7 @@ impl FromConstant for Felt { impl FromConstant for Ext { type Constant = C::EF; - fn eval_const(value: Self::Constant, builder: &mut Builder) -> Self { + fn constant(value: Self::Constant, builder: &mut Builder) -> Self { builder.eval(value.cons()) } } diff --git a/recursion/compiler/src/ir/utils.rs b/recursion/compiler/src/ir/utils.rs index 99a66a45bb..ca16e1fd14 100644 --- a/recursion/compiler/src/ir/utils.rs +++ b/recursion/compiler/src/ir/utils.rs @@ -1,9 +1,43 @@ -use p3_field::AbstractField; -use std::ops::MulAssign; +use p3_field::{AbstractExtensionField, AbstractField}; +use std::ops::{Add, Mul, MulAssign}; -use super::{Builder, Config, DslIR, Felt, Var, Variable}; +use super::{Array, Builder, Config, DslIR, Ext, Felt, SymbolicExt, Usize, Var, Variable}; impl Builder { + /// The generator for the field. + /// + /// Reference: [p3_baby_bear::BabyBear] + pub fn generator(&mut self) -> Felt { + self.eval(C::F::from_canonical_u32(31)) + } + + /// Select a variable based on a condition. + pub fn select_v(&mut self, cond: Var, a: Var, b: Var) -> Var { + let c = self.uninit(); + self.operations.push(DslIR::CircuitSelectV(cond, a, b, c)); + c + } + + /// Select a felt based on a condition. + pub fn select_f(&mut self, cond: Var, a: Felt, b: Felt) -> Felt { + let c = self.uninit(); + self.operations.push(DslIR::CircuitSelectF(cond, a, b, c)); + c + } + + /// Select an extension based on a condition. + pub fn select_ef( + &mut self, + cond: Var, + a: Ext, + b: Ext, + ) -> Ext { + let c = self.uninit(); + self.operations.push(DslIR::CircuitSelectE(cond, a, b, c)); + c + } + + /// Exponentiates a variable to a power of two. pub fn exp_power_of_2, E: Into>( &mut self, e: E, @@ -19,35 +53,259 @@ impl Builder { self.eval(e) } - pub fn num2bits_v_circuit(&mut self, num: Var, bits: usize) -> Vec> { - let mut output = Vec::new(); - for _ in 0..bits { - output.push(self.uninit()); + /// Exponentializes a variable to an array of bits in little endian. + pub fn exp_bits>(&mut self, x: V, power_bits: &Array>) -> V + where + V::Expression: AbstractField, + V: Copy + Mul, + { + let result = self.eval(V::Expression::one()); + let power_f: V = self.eval(x); + self.range(0, power_bits.len()).for_each(|i, builder| { + let bit = builder.get(power_bits, i); + builder + .if_eq(bit, C::N::one()) + .then(|builder| builder.assign(result, result * power_f)); + builder.assign(power_f, power_f * power_f); + }); + result + } + + /// Exponentiates a felt to a list of bits in little endian. + pub fn exp_f_bits(&mut self, x: Felt, power_bits: Vec>) -> Felt { + let mut result = self.eval(C::F::one()); + let mut power_f: Felt<_> = self.eval(x); + for i in 0..power_bits.len() { + let bit = power_bits[i]; + let tmp = self.eval(result * power_f); + result = self.select_f(bit, tmp, result); + power_f = self.eval(power_f * power_f); } + result + } - self.operations - .push(DslIR::CircuitNum2BitsV(num, bits, output.clone())); + /// Exponentiates a extension to a list of bits in little endian. + pub fn exp_e_bits( + &mut self, + x: Ext, + power_bits: Vec>, + ) -> Ext { + let mut result = self.eval(SymbolicExt::Const(C::EF::one())); + let mut power_f: Ext<_, _> = self.eval(x); + for i in 0..power_bits.len() { + let bit = power_bits[i]; + let tmp = self.eval(result * power_f); + result = self.select_ef(bit, tmp, result); + power_f = self.eval(power_f * power_f); + } + result + } - output + /// Exponetiates a varibale to a list of reversed bits with a given length. + /// + /// Reference: [p3_util::reverse_bits_len] + pub fn exp_reverse_bits_len>( + &mut self, + x: V, + power_bits: &Array>, + bit_len: impl Into>, + ) -> V + where + V::Expression: AbstractField, + V: Copy + Mul, + { + let result = self.eval(V::Expression::one()); + let power_f: V = self.eval(x); + let bit_len = bit_len.into(); + self.range(0, bit_len).for_each(|i, builder| { + let index: Var = builder.eval(bit_len - i - C::N::one()); + let bit = builder.get(power_bits, index); + builder + .if_eq(bit, C::N::one()) + .then(|builder| builder.assign(result, result * power_f)); + builder.assign(power_f, power_f * power_f); + }); + result } - pub fn num2bits_f_circuit(&mut self, num: Felt) -> Vec> { - let mut output = Vec::new(); - for _ in 0..32 { - output.push(self.uninit()); + /// Exponentiates a variable to a list of bits in little endian. + pub fn exp_power_of_2_v( + &mut self, + base: impl Into, + power_log: impl Into>, + ) -> V + where + V: Variable + Copy + Mul, + { + let mut result: V = self.eval(base); + let power_log: Usize<_> = power_log.into(); + match power_log { + Usize::Var(power_log) => { + self.range(0, power_log) + .for_each(|_, builder| builder.assign(result, result * result)); + } + Usize::Const(power_log) => { + for _ in 0..power_log { + result = self.eval(result * result); + } + } } + result + } - self.operations - .push(DslIR::CircuitNum2BitsF(num, output.clone())); + /// Exponentiates a variable to a list of bits in little endian insid a circuit. + pub fn exp_power_of_2_v_circuit>( + &mut self, + base: impl Into, + power_log: usize, + ) -> V + where + V: Copy + Mul, + { + let mut result: V = self.eval(base); + for _ in 0..power_log { + result = self.eval(result * result) + } + result + } - output + /// Multiplies `base` by `2^{log_power}`. + pub fn sll(&mut self, base: impl Into, shift: Usize) -> V + where + V: Variable + Copy + Add, + { + let result: V = self.eval(base); + self.range(0, shift) + .for_each(|_, builder| builder.assign(result, result + result)); + result } - pub fn bits_to_num_var_circuit(&mut self, bits: &[Var]) -> Var { - let result: Var<_> = self.eval(C::N::zero()); - for i in 0..bits.len() { - self.assign(result, result + bits[i] * C::N::from_canonical_u32(1 << i)); + /// Creates an ext from a slice of felts. + pub fn ext_from_base_slice(&mut self, arr: &[Felt]) -> Ext { + assert!(arr.len() <= >::D); + let mut res = SymbolicExt::Const(C::EF::zero()); + for i in 0..arr.len() { + res += arr[i] * SymbolicExt::Const(C::EF::monomial(i)); } + self.eval(res) + } + + /// Converts an ext to a slice of felts. + pub fn ext2felt(&mut self, value: Ext) -> Array> { + let result = self.dyn_array(4); + self.operations.push(DslIR::Ext2Felt(result.clone(), value)); result } + + /// Converts an ext to a slice of felts inside a circuit. + pub fn ext2felt_circuit(&mut self, value: Ext) -> [Felt; 4] { + let a = self.uninit(); + let b = self.uninit(); + let c = self.uninit(); + let d = self.uninit(); + self.operations + .push(DslIR::CircuitExt2Felt([a, b, c, d], value)); + [a, b, c, d] + } +} + +#[cfg(test)] +mod tests { + use p3_field::PrimeField32; + use p3_util::reverse_bits_len; + use rand::{thread_rng, Rng}; + use sp1_core::{stark::StarkGenericConfig, utils::BabyBearPoseidon2}; + use sp1_recursion_core::runtime::{Runtime, NUM_BITS}; + + use p3_field::AbstractField; + + use crate::{ + asm::VmBuilder, + prelude::{Felt, Var}, + }; + + #[test] + fn test_num2bits() { + type SC = BabyBearPoseidon2; + type F = ::Val; + type EF = ::Challenge; + + let mut rng = thread_rng(); + let config = SC::default(); + + // Initialize a builder. + let mut builder = VmBuilder::::default(); + + // Get a random var with `NUM_BITS` bits. + let num_val: F = rng.gen(); + + // Materialize the number as a var + let num: Var<_> = builder.eval(num_val); + // Materialize the number as a felt + let num_felt: Felt<_> = builder.eval(num_val); + + // Get the bits. + let bits = builder.num2bits_v(num); + let bits_felt = builder.num2bits_f(num_felt); + + // Compare the expected bits with the actual bits. + for i in 0..NUM_BITS { + // Get the i-th bit of the number. + let expected_bit = F::from_canonical_u32((num_val.as_canonical_u32() >> i) & 1); + // Compare the expected bit of the var with the actual bit. + let bit = builder.get(&bits, i); + builder.assert_var_eq(bit, expected_bit); + // Compare the expected bit of the felt with the actual bit. + let bit_felt = builder.get(&bits_felt, i); + builder.assert_var_eq(bit_felt, expected_bit); + } + + // Test the conversion back to a number. + let num_back = builder.bits2num_v(&bits); + builder.assert_var_eq(num_back, num); + let num_felt_back = builder.bits2num_f(&bits_felt); + builder.assert_felt_eq(num_felt_back, num_felt); + + let program = builder.compile(); + + let mut runtime = Runtime::::new(&program, config.perm.clone()); + runtime.run(); + } + + #[test] + fn test_reverse_bits_len() { + type SC = BabyBearPoseidon2; + type F = ::Val; + type EF = ::Challenge; + + let mut rng = thread_rng(); + let config = SC::default(); + + // Initialize a builder. + let mut builder = VmBuilder::::default(); + + // Get a random var with `NUM_BITS` bits. + let x_val: F = rng.gen(); + + // Materialize the number as a var + let x: Var<_> = builder.eval(x_val); + let x_bits = builder.num2bits_v(x); + + for i in 1..NUM_BITS { + // Get the reference value. + let expected_value = reverse_bits_len(x_val.as_canonical_u32() as usize, i); + let value_bits = builder.reverse_bits_len(&x_bits, i); + let value = builder.bits2num_v(&value_bits); + builder.assert_usize_eq(value, expected_value); + let var_i: Var<_> = builder.eval(F::from_canonical_usize(i)); + let value_var_bits = builder.reverse_bits_len(&x_bits, var_i); + let value_var = builder.bits2num_v(&value_var_bits); + builder.assert_usize_eq(value_var, expected_value); + } + + let program = builder.compile(); + + let mut runtime = Runtime::::new(&program, config.perm.clone()); + runtime.run(); + } } diff --git a/recursion/compiler/src/ir/var.rs b/recursion/compiler/src/ir/var.rs index 80fc15e9a4..0c332cb24e 100644 --- a/recursion/compiler/src/ir/var.rs +++ b/recursion/compiler/src/ir/var.rs @@ -36,5 +36,5 @@ pub trait MemVariable: Variable { pub trait FromConstant { type Constant; - fn eval_const(value: Self::Constant, builder: &mut Builder) -> Self; + fn constant(value: Self::Constant, builder: &mut Builder) -> Self; } diff --git a/recursion/compiler/src/lib.rs b/recursion/compiler/src/lib.rs index 45c821688f..132657760c 100644 --- a/recursion/compiler/src/lib.rs +++ b/recursion/compiler/src/lib.rs @@ -2,13 +2,14 @@ #![allow(clippy::needless_range_loop)] #![allow(clippy::type_complexity)] +extern crate alloc; + use asm::AsmConfig; use p3_baby_bear::BabyBear; use p3_bn254_fr::Bn254Fr; use p3_field::extension::BinomialExtensionField; use prelude::Config; use sp1_recursion_core::stark::config::{InnerChallenge, InnerVal}; -extern crate alloc; pub mod asm; pub mod constraints; diff --git a/recursion/program/src/compress.rs b/recursion/program/src/compress.rs index 3de001c593..7262a91649 100644 --- a/recursion/program/src/compress.rs +++ b/recursion/program/src/compress.rs @@ -72,8 +72,7 @@ pub fn const_fri_config( log_n: i, shift: Val::one(), }; - let domain_value: TwoAdicMultiplicativeCosetVariable<_> = - builder.eval_const(constant_domain); + let domain_value: TwoAdicMultiplicativeCosetVariable<_> = builder.constant(constant_domain); builder.set(&mut subgroups, i, domain_value); } FriConfigVariable { @@ -108,7 +107,7 @@ pub fn build_compress( let mut challenger = DuplexChallengerVariable::new(&mut builder); let preprocessed_commit_val: [F; DIGEST_SIZE] = vk.commit.into(); - let preprocessed_commit: Array = builder.eval_const(preprocessed_commit_val.to_vec()); + let preprocessed_commit: Array = builder.constant(preprocessed_commit_val.to_vec()); challenger.observe(&mut builder, preprocessed_commit); let mut witness_stream = Vec::new(); diff --git a/recursion/program/src/constraints.rs b/recursion/program/src/constraints.rs index 5b5ef6c402..13770c07fb 100644 --- a/recursion/program/src/constraints.rs +++ b/recursion/program/src/constraints.rs @@ -353,14 +353,13 @@ mod tests { ); // Compute the folded constraints value in the DSL. - let values_var: ChipOpenedValuesVariable<_> = - builder.eval_const(values_vals.clone()); + let values_var: ChipOpenedValuesVariable<_> = builder.constant(values_vals.clone()); let values = ChipOpening::from_variable(&mut builder, chip, &values_var); let alpha = builder.eval(alpha_val.cons()); let zeta = builder.eval(zeta_val.cons()); let trace_domain: TwoAdicMultiplicativeCosetVariable<_> = - builder.eval_const(trace_domain_val); + builder.constant(trace_domain_val); let sels = trace_domain.selectors_at_point(&mut builder, zeta); let permutation_challenges = permutation_challenges @@ -387,7 +386,7 @@ mod tests { let qc_domains = qc_domains_vals .iter() .map(|domain| { - builder.eval_const::>(*domain) + builder.constant::>(*domain) }) .collect::>(); let quotient = StarkVerifier::<_, SC>::recompute_quotient( @@ -464,14 +463,14 @@ mod tests { quotient_chunk_domains_vals, proof.opened_values.chips.iter(), ) { - let opening = builder.eval_const(values_vals.clone()); + let opening = builder.constant(values_vals.clone()); let alpha = builder.eval(alpha_val.cons()); let zeta = builder.eval(zeta_val.cons()); - let trace_domain = builder.eval_const(trace_domain_val); - let public_values = builder.eval_const(proof.public_values); + let trace_domain = builder.constant(trace_domain_val); + let public_values = builder.constant(proof.public_values); let qc_domains = qc_domains_vals .iter() - .map(|domain| builder.eval_const(*domain)) + .map(|domain| builder.constant(*domain)) .collect::>(); let permutation_challenges = permutation_challenges diff --git a/recursion/program/src/fri/domain.rs b/recursion/program/src/fri/domain.rs index 2d4e671b82..f2b93b0968 100644 --- a/recursion/program/src/fri/domain.rs +++ b/recursion/program/src/fri/domain.rs @@ -35,7 +35,7 @@ where { type Constant = TwoAdicMultiplicativeCoset; - fn eval_const(value: Self::Constant, builder: &mut Builder) -> Self { + fn constant(value: Self::Constant, builder: &mut Builder) -> Self { let log_d_val = value.log_n as u32; let g_val = C::F::two_adic_generator(value.log_n); // Initialize a domain. @@ -99,7 +99,7 @@ where fn split_domains(&self, builder: &mut Builder, log_num_chunks: usize) -> Vec { let num_chunks = 1 << log_num_chunks; let log_n: Var<_> = builder.eval(self.log_n - C::N::from_canonical_usize(log_num_chunks)); - let size = builder.power_of_two_var(Usize::Var(log_n)); + let size = builder.sll(C::N::one(), Usize::Var(log_n)); let g_dom = self.gen(); @@ -202,7 +202,7 @@ pub(crate) mod tests { // Initialize a reference doamin. let domain_val = natural_domain_for_degree(1 << log_d_val); - let domain = builder.eval_const(domain_val); + let domain = builder.constant(domain_val); // builder.assert_felt_eq(domain.shift, domain_val.shift); let zeta_val = rng.gen::(); domain_assertions(&mut builder, &domain, &domain_val, zeta_val); @@ -210,7 +210,7 @@ pub(crate) mod tests { // Try a shifted domain. let disjoint_domain_val = domain_val.create_disjoint_domain(1 << (log_d_val + log_quotient_degree)); - let disjoint_domain = builder.eval_const(disjoint_domain_val); + let disjoint_domain = builder.constant(disjoint_domain_val); domain_assertions( &mut builder, &disjoint_domain, @@ -231,7 +231,7 @@ pub(crate) mod tests { // Now try splited domains let qc_domains_val = disjoint_domain_val.split_domains(1 << log_quotient_degree); for dom_val in qc_domains_val.iter() { - let dom = builder.eval_const(*dom_val); + let dom = builder.constant(*dom_val); domain_assertions(&mut builder, &dom, dom_val, zeta_val); } diff --git a/recursion/program/src/fri/mod.rs b/recursion/program/src/fri/mod.rs index 4b3be08c3c..e28ee67a42 100644 --- a/recursion/program/src/fri/mod.rs +++ b/recursion/program/src/fri/mod.rs @@ -172,9 +172,8 @@ where builder.set_value(&mut evals, 1, folded_eval); builder.set_value(&mut evals, index_sibling_mod_2, step.sibling_value); - let two: Var = builder.eval(C::N::from_canonical_u32(2)); let dims = DimensionsVariable:: { - height: builder.exp(two, log_folded_height), + height: builder.sll(C::N::one(), Usize::Var(log_folded_height)), }; let mut dims_slice: Array> = builder.array(1); builder.set_value(&mut dims_slice, 0, dims); diff --git a/recursion/program/src/fri/two_adic_pcs.rs b/recursion/program/src/fri/two_adic_pcs.rs index 6699376a34..10e767418b 100644 --- a/recursion/program/src/fri/two_adic_pcs.rs +++ b/recursion/program/src/fri/two_adic_pcs.rs @@ -168,7 +168,7 @@ where Vec<(TwoAdicMultiplicativeCoset, Vec<(C::EF, Vec)>)>, ); - fn eval_const(value: Self::Constant, builder: &mut Builder) -> Self { + fn constant(value: Self::Constant, builder: &mut Builder) -> Self { let (commit_val, domains_and_openings_val) = value; // Allocate the commitment. @@ -182,7 +182,7 @@ where builder.dyn_array::>(domains_and_openings_val.len()); for (i, (domain, openning)) in domains_and_openings_val.into_iter().enumerate() { - let domain = builder.eval_const::>(domain); + let domain = builder.constant::>(domain); let points_val = openning.iter().map(|(p, _)| *p).collect::>(); let values_val = openning.iter().map(|(_, v)| v.clone()).collect::>(); @@ -313,7 +313,7 @@ pub(crate) mod tests { shift: InnerVal::one(), }; let domain_value: TwoAdicMultiplicativeCosetVariable<_> = - builder.eval_const(constant_domain); + builder.constant(constant_domain); builder.set(&mut subgroups, i, domain_value); } FriConfigVariable { @@ -391,7 +391,7 @@ pub(crate) mod tests { let config = const_fri_config(&mut builder, inner_fri_config()); let pcs = TwoAdicFriPcsVariable { config }; let rounds = - builder.eval_const::>>(vec![(commit, os.clone())]); + builder.constant::>>(vec![(commit, os.clone())]); // Test natural domain for degree. for log_d_val in log_degrees.iter() { @@ -405,7 +405,7 @@ pub(crate) mod tests { ); let expected_domain: TwoAdicMultiplicativeCosetVariable<_> = - builder.eval_const(domain_val); + builder.constant(domain_val); builder.assert_eq::>(domain, expected_domain); } @@ -414,7 +414,7 @@ pub(crate) mod tests { let proofvar = InnerPcsProof::read(&mut builder); let mut challenger = DuplexChallengerVariable::new(&mut builder); let commit = <[InnerVal; DIGEST_SIZE]>::from(commit).to_vec(); - let commit = builder.eval_const::>(commit); + let commit = builder.constant::>(commit); challenger.observe(&mut builder, commit); challenger.sample_ext(&mut builder); pcs.verify(&mut builder, rounds, proofvar, &mut challenger); @@ -524,14 +524,14 @@ pub(crate) mod tests { let mut builder = Builder::::default(); let config = const_fri_config(&mut builder, inner_fri_config()); let pcs = TwoAdicFriPcsVariable { config }; - let rounds = builder.eval_const::>>(rounds_val); + let rounds = builder.constant::>>(rounds_val); // // Test proof verification. let proofvar = InnerPcsProof::read(&mut builder); let mut challenger = DuplexChallengerVariable::new(&mut builder); for commit in batches_commits { let commit: [InnerVal; DIGEST_SIZE] = commit.into(); - let commit = builder.eval_const::>(commit.to_vec()); + let commit = builder.constant::>(commit.to_vec()); challenger.observe(&mut builder, commit); } challenger.sample_ext(&mut builder); diff --git a/recursion/program/src/stark.rs b/recursion/program/src/stark.rs index c6ae9b0950..a015c681bd 100644 --- a/recursion/program/src/stark.rs +++ b/recursion/program/src/stark.rs @@ -117,7 +117,7 @@ where let index = builder.get(&sorted_indices, chip_idx); let opening = builder.get(&opened_values.chips, index); - let domain: TwoAdicMultiplicativeCosetVariable<_> = builder.eval_const(*domain); + let domain: TwoAdicMultiplicativeCosetVariable<_> = builder.constant(*domain); let mut trace_points = builder.dyn_array::>(2); let zeta_next = domain.next_point(builder, zeta); @@ -198,7 +198,7 @@ where // Create the pcs rounds. let mut rounds = builder.dyn_array::>(4); let prep_commit_val: [SC::Val; DIGEST_SIZE] = vk.commit.clone().into(); - let prep_commit = builder.eval_const(prep_commit_val.to_vec()); + let prep_commit = builder.constant(prep_commit_val.to_vec()); let prep_round = TwoAdicPcsRoundVariable { batch_commit: prep_commit, mats: prep_mats, @@ -334,7 +334,7 @@ pub(crate) mod tests { let mut challenger = DuplexChallengerVariable::new(&mut builder); let preprocessed_commit_val: [F; DIGEST_SIZE] = vk.commit.into(); - let preprocessed_commit: Array = builder.eval_const(preprocessed_commit_val.to_vec()); + let preprocessed_commit: Array = builder.constant(preprocessed_commit_val.to_vec()); challenger.observe(&mut builder, preprocessed_commit); let mut witness_stream = Vec::new(); @@ -405,7 +405,7 @@ pub(crate) mod tests { let mut challenger = DuplexChallengerVariable::new(&mut builder); let preprocessed_commit_val: [F; DIGEST_SIZE] = vk.commit.into(); - let preprocessed_commit: Array = builder.eval_const(preprocessed_commit_val.to_vec()); + let preprocessed_commit: Array = builder.constant(preprocessed_commit_val.to_vec()); challenger.observe(&mut builder, preprocessed_commit); let mut witness_stream = Vec::new(); diff --git a/recursion/program/src/types.rs b/recursion/program/src/types.rs index 5f69a753fb..0b6fcaa9f5 100644 --- a/recursion/program/src/types.rs +++ b/recursion/program/src/types.rs @@ -42,7 +42,7 @@ impl PublicValuesVariable { impl FromConstant for PublicValuesVariable { type Constant = PublicValues; - fn eval_const(value: Self::Constant, builder: &mut Builder) -> Self { + fn constant(value: Self::Constant, builder: &mut Builder) -> Self { let pv_shard = builder.eval(C::F::from_canonical_u32(value.shard)); let pv_start_pc = builder.eval(C::F::from_canonical_u32(value.start_pc)); let pv_next_pc = builder.eval(C::F::from_canonical_u32(value.next_pc)); @@ -189,10 +189,10 @@ impl ChipOpening { impl FromConstant for AirOpenedValuesVariable { type Constant = AirOpenedValues; - fn eval_const(value: Self::Constant, builder: &mut Builder) -> Self { + fn constant(value: Self::Constant, builder: &mut Builder) -> Self { AirOpenedValuesVariable { - local: builder.eval_const(value.local), - next: builder.eval_const(value.next), + local: builder.constant(value.local), + next: builder.constant(value.next), } } } @@ -200,12 +200,12 @@ impl FromConstant for AirOpenedValuesVariable { impl FromConstant for ChipOpenedValuesVariable { type Constant = ChipOpenedValues; - fn eval_const(value: Self::Constant, builder: &mut Builder) -> Self { + fn constant(value: Self::Constant, builder: &mut Builder) -> Self { ChipOpenedValuesVariable { - preprocessed: builder.eval_const(value.preprocessed), - main: builder.eval_const(value.main), - permutation: builder.eval_const(value.permutation), - quotient: builder.eval_const(value.quotient), + preprocessed: builder.constant(value.preprocessed), + main: builder.constant(value.main), + permutation: builder.constant(value.permutation), + quotient: builder.constant(value.quotient), cumulative_sum: builder.eval(value.cumulative_sum.cons()), log_degree: builder.eval(C::N::from_canonical_usize(value.log_degree)), }