1
0
Fork 0
mirror of synced 2025-09-24 04:40:05 +00:00

Merge branch 'develop' of github.com:Zokrates/ZoKrates into add-magic-square

This commit is contained in:
schaeff 2022-09-02 10:45:29 +02:00
commit 4cef8756fd
39 changed files with 970 additions and 523 deletions

178
Cargo.lock generated
View file

@ -323,7 +323,7 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8dd4e5f0bf8285d5ed538d27fab7411f3e297908fd93c62195de8bee3f199e82" checksum = "8dd4e5f0bf8285d5ed538d27fab7411f3e297908fd93c62195de8bee3f199e82"
dependencies = [ dependencies = [
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
] ]
@ -402,7 +402,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a8c1df849285fbacd587de7818cc7d13be6cd2cbcd47a04fb1801b0e2706e33" checksum = "8a8c1df849285fbacd587de7818cc7d13be6cd2cbcd47a04fb1801b0e2706e33"
dependencies = [ dependencies = [
"proc-macro-error 1.0.4", "proc-macro-error 1.0.4",
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
] ]
@ -415,9 +415,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]] [[package]]
name = "backtrace" name = "backtrace"
version = "0.3.66" version = "0.3.65"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61"
dependencies = [ dependencies = [
"addr2line", "addr2line",
"cc", "cc",
@ -470,9 +470,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "bitvec" name = "bitvec"
version = "1.0.1" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" checksum = "1489fcb93a5bb47da0462ca93ad252ad6af2145cce58d10d46a83931ba9f016b"
dependencies = [ dependencies = [
"funty", "funty",
"radium", "radium",
@ -614,9 +614,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]] [[package]]
name = "bytes" name = "bytes"
version = "1.2.0" version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0b3de4a0c5e67e16066a0715723abd91edc2f9001d09c46e1dca929351e130e" checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
[[package]] [[package]]
name = "camino" name = "camino"
@ -708,7 +708,7 @@ checksum = "c6dd675567eb3e35787bd2583d129e85fabc7503b0a093d08c51198a307e2091"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro-error 0.4.12", "proc-macro-error 0.4.12",
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
] ]
@ -838,9 +838,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]] [[package]]
name = "crypto-common" name = "crypto-common"
version = "0.1.6" version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" checksum = "5999502d32b9c48d492abe66392408144895020ec4709e549e840799f3bb74c0"
dependencies = [ dependencies = [
"generic-array 0.14.5", "generic-array 0.14.5",
"typenum", "typenum",
@ -904,7 +904,7 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
dependencies = [ dependencies = [
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
] ]
@ -1084,7 +1084,7 @@ version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
dependencies = [ dependencies = [
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
"synstructure", "synstructure",
@ -1098,9 +1098,9 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
[[package]] [[package]]
name = "fastrand" name = "fastrand"
version = "1.8.0" version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
dependencies = [ dependencies = [
"instant", "instant",
] ]
@ -1126,7 +1126,7 @@ dependencies = [
"num-bigint 0.2.6", "num-bigint 0.2.6",
"num-integer", "num-integer",
"num-traits 0.2.15", "num-traits 0.2.15",
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
] ]
@ -1283,9 +1283,9 @@ dependencies = [
[[package]] [[package]]
name = "gimli" name = "gimli"
version = "0.26.2" version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
[[package]] [[package]]
name = "glob" name = "glob"
@ -1322,9 +1322,9 @@ dependencies = [
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.12.3" version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3"
dependencies = [ dependencies = [
"ahash", "ahash",
] ]
@ -1417,7 +1417,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb"
dependencies = [ dependencies = [
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
] ]
@ -1473,9 +1473,9 @@ checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.59" version = "0.3.58"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27"
dependencies = [ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
@ -1692,16 +1692,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce"
dependencies = [ dependencies = [
"proc-macro-crate", "proc-macro-crate",
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
] ]
[[package]] [[package]]
name = "object" name = "object"
version = "0.29.0" version = "0.28.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@ -1765,7 +1765,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9299338969a3d2f491d65f140b00ddec470858402f888af98e8642fb5e8965cd" checksum = "9299338969a3d2f491d65f140b00ddec470858402f888af98e8642fb5e8965cd"
dependencies = [ dependencies = [
"proc-macro-crate", "proc-macro-crate",
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
] ]
@ -1816,7 +1816,7 @@ checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
dependencies = [ dependencies = [
"pest", "pest",
"pest_meta", "pest_meta",
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
] ]
@ -1920,7 +1920,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18f33027081eba0a6d8aba6d1b1c3a3be58cbb12106341c2d5759fcd9b5277e7" checksum = "18f33027081eba0a6d8aba6d1b1c3a3be58cbb12106341c2d5759fcd9b5277e7"
dependencies = [ dependencies = [
"proc-macro-error-attr 0.4.12", "proc-macro-error-attr 0.4.12",
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
"version_check", "version_check",
@ -1933,7 +1933,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [ dependencies = [
"proc-macro-error-attr 1.0.4", "proc-macro-error-attr 1.0.4",
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
"version_check", "version_check",
@ -1945,7 +1945,7 @@ version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a5b4b77fdb63c1eca72173d68d24501c54ab1269409f6b672c85deb18af69de" checksum = "8a5b4b77fdb63c1eca72173d68d24501c54ab1269409f6b672c85deb18af69de"
dependencies = [ dependencies = [
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
"syn-mid", "syn-mid",
@ -1958,7 +1958,7 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [ dependencies = [
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"version_check", "version_check",
] ]
@ -1980,9 +1980,9 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.42" version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c278e965f1d8cf32d6e0e96de3d3e79712178ae67986d9cf9151f51e95aac89b" checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -2013,7 +2013,7 @@ version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
dependencies = [ dependencies = [
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
] ]
[[package]] [[package]]
@ -2091,9 +2091,9 @@ dependencies = [
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.2.15" version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "534cfe58d6a18cc17120fbf4635d53d14691c1fe4d951064df9bd326178d7d5a" checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
dependencies = [ dependencies = [
"bitflags", "bitflags",
] ]
@ -2171,14 +2171,14 @@ dependencies = [
[[package]] [[package]]
name = "revm" name = "revm"
version = "1.7.0" version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "455988f0a9920c91f192268ee31d79fcb980006058514d1e6b543af3d71670f3" checksum = "b60030444003ac25474f5281e7e91f15e8475c173b729aac1c10aced56b3adac"
dependencies = [ dependencies = [
"arrayref", "arrayref",
"auto_impl", "auto_impl",
"bytes", "bytes",
"hashbrown 0.12.3", "hashbrown 0.12.1",
"num_enum", "num_enum",
"primitive-types", "primitive-types",
"revm_precompiles", "revm_precompiles",
@ -2188,9 +2188,9 @@ dependencies = [
[[package]] [[package]]
name = "revm_precompiles" name = "revm_precompiles"
version = "1.1.0" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af88e7e9feb30cc4ed64645f09b966e84a1f6be56551ce5f1691105def45705d" checksum = "cd6aae8f44783ef6ff39fc22c9c999dfa0e17b79d663b752730c02a025935185"
dependencies = [ dependencies = [
"bytes", "bytes",
"num 0.4.0", "num 0.4.0",
@ -2288,18 +2288,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]] [[package]]
name = "secp256k1" name = "secp256k1"
version = "0.23.4" version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ece73253dd9e1fb540ff324eae554113a31c25fb598d22fd13b088a6a03f90d" checksum = "26947345339603ae8395f68e2f3d85a6b0a8ddfe6315818e80b8504415099db0"
dependencies = [ dependencies = [
"secp256k1-sys", "secp256k1-sys",
] ]
[[package]] [[package]]
name = "secp256k1-sys" name = "secp256k1-sys"
version = "0.6.0" version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7058dc8eaf3f2810d7828680320acda0b25a288f6d288e19278e249bbf74226b" checksum = "152e20a0fd0519390fc43ab404663af8a0b794273d2a91d60ad4a39f13ffe110"
dependencies = [ dependencies = [
"cc", "cc",
] ]
@ -2333,9 +2333,9 @@ dependencies = [
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.140" version = "1.0.138"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03" checksum = "1578c6245786b9d168c5447eeacfb96856573ca56c9d68fdcf394be134882a47"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
@ -2352,11 +2352,11 @@ dependencies = [
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.140" version = "1.0.138"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da" checksum = "023e9b1467aef8a10fb88f25611870ada9800ef7e22afce356bb0d2387b6f27c"
dependencies = [ dependencies = [
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
] ]
@ -2432,9 +2432,9 @@ dependencies = [
[[package]] [[package]]
name = "single" name = "single"
version = "1.0.1" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9db45bb685b486eec37e0271dcc0dac76eae5e893125f8a4f0511d0a1d29543b" checksum = "bd5add732a1ab689845591a1b50339cf5310b563e08dc5813c65991f30369ea2"
dependencies = [ dependencies = [
"failure", "failure",
] ]
@ -2456,12 +2456,9 @@ dependencies = [
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.7" version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "solc" name = "solc"
@ -2538,7 +2535,7 @@ version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
dependencies = [ dependencies = [
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"unicode-ident", "unicode-ident",
] ]
@ -2549,7 +2546,7 @@ version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baa8e7560a164edb1621a55d18a0c59abf49d360f47aa7b821061dd7eea7fac9" checksum = "baa8e7560a164edb1621a55d18a0c59abf49d360f47aa7b821061dd7eea7fac9"
dependencies = [ dependencies = [
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
] ]
@ -2560,7 +2557,7 @@ version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
dependencies = [ dependencies = [
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
"unicode-xid 0.2.3", "unicode-xid 0.2.3",
@ -2629,7 +2626,7 @@ version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
dependencies = [ dependencies = [
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
] ]
@ -2679,7 +2676,7 @@ version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2"
dependencies = [ dependencies = [
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
] ]
@ -2737,9 +2734,9 @@ dependencies = [
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.2" version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7" checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
[[package]] [[package]]
name = "unicode-segmentation" name = "unicode-segmentation"
@ -2808,9 +2805,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.82" version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"serde", "serde",
@ -2820,14 +2817,14 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-backend" name = "wasm-bindgen-backend"
version = "0.2.82" version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"lazy_static",
"log", "log",
"once_cell", "proc-macro2 1.0.40",
"proc-macro2 1.0.42",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
"wasm-bindgen-shared", "wasm-bindgen-shared",
@ -2835,9 +2832,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-futures" name = "wasm-bindgen-futures"
version = "0.4.32" version = "0.4.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad" checksum = "de9a9cec1733468a8c657e57fa2413d2ae2c0129b95e87c5b72b8ace4d13f31f"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"js-sys", "js-sys",
@ -2847,9 +2844,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro" name = "wasm-bindgen-macro"
version = "0.2.82" version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa"
dependencies = [ dependencies = [
"quote 1.0.20", "quote 1.0.20",
"wasm-bindgen-macro-support", "wasm-bindgen-macro-support",
@ -2857,11 +2854,11 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro-support" name = "wasm-bindgen-macro-support"
version = "0.2.82" version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048"
dependencies = [ dependencies = [
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
"wasm-bindgen-backend", "wasm-bindgen-backend",
@ -2870,15 +2867,15 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-shared" name = "wasm-bindgen-shared"
version = "0.2.82" version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be"
[[package]] [[package]]
name = "wasm-bindgen-test" name = "wasm-bindgen-test"
version = "0.3.32" version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "513df541345bb9fcc07417775f3d51bbb677daf307d8035c0afafd87dc2e6599" checksum = "68b30cf2cba841a812f035c40c50f53eb9c56181192a9dd2c71b65e6a87a05ba"
dependencies = [ dependencies = [
"console_error_panic_hook", "console_error_panic_hook",
"js-sys", "js-sys",
@ -2890,19 +2887,19 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-test-macro" name = "wasm-bindgen-test-macro"
version = "0.3.32" version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6150d36a03e90a3cf6c12650be10626a9902d70c5270fd47d7a47e5389a10d56" checksum = "88ad594bf33e73cafcac2ae9062fc119d4f75f9c77e25022f91c9a64bd5b6463"
dependencies = [ dependencies = [
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
] ]
[[package]] [[package]]
name = "web-sys" name = "web-sys"
version = "0.3.59" version = "0.3.58"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1" checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90"
dependencies = [ dependencies = [
"js-sys", "js-sys",
"wasm-bindgen", "wasm-bindgen",
@ -2950,9 +2947,9 @@ dependencies = [
[[package]] [[package]]
name = "zeroize" name = "zeroize"
version = "1.5.7" version = "1.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" checksum = "20b578acffd8516a6c3f2a1bdefc1ec37e547bb4e0fb8b6b01a4cafc886b4442"
dependencies = [ dependencies = [
"zeroize_derive", "zeroize_derive",
] ]
@ -2963,7 +2960,7 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17"
dependencies = [ dependencies = [
"proc-macro2 1.0.42", "proc-macro2 1.0.40",
"quote 1.0.20", "quote 1.0.20",
"syn 1.0.98", "syn 1.0.98",
"synstructure", "synstructure",
@ -3090,6 +3087,7 @@ dependencies = [
"hex 0.3.2", "hex 0.3.2",
"lazy_static", "lazy_static",
"log", "log",
"pretty_assertions 1.2.1",
"primitive-types", "primitive-types",
"rand 0.4.6", "rand 0.4.6",
"rand 0.8.5", "rand 0.8.5",

View file

@ -51,5 +51,5 @@ We enforce strict formatting of `.{js,json,ts}` files in CI. This check is not i
``` ```
npm i -g prettier npm i -g prettier
prettier --write ./**/*.{js,ts,json} prettier --write "./**/*.{js,ts,json}"
``` ```

View file

@ -0,0 +1 @@
Introduce dead code elimination

View file

@ -0,0 +1 @@
Make return statement optional if no returns are expected

View file

@ -16,13 +16,11 @@ pub enum RuntimeError {
BranchIsolation, BranchIsolation,
ConstantLtBitness, ConstantLtBitness,
ConstantLtSum, ConstantLtSum,
LtBitness,
LtSum,
LtFinalBitness,
LtFinalSum, LtFinalSum,
LtSymetric, LtSymetric,
Or, Or,
Xor, Xor,
IncompleteDynamicRange,
Inverse, Inverse,
Euclidean, Euclidean,
ShaXor, ShaXor,
@ -37,6 +35,10 @@ impl From<crate::zir::RuntimeError> for RuntimeError {
match error { match error {
crate::zir::RuntimeError::SourceAssertion(s) => RuntimeError::SourceAssertion(s), crate::zir::RuntimeError::SourceAssertion(s) => RuntimeError::SourceAssertion(s),
crate::zir::RuntimeError::SelectRangeCheck => RuntimeError::SelectRangeCheck, crate::zir::RuntimeError::SelectRangeCheck => RuntimeError::SelectRangeCheck,
crate::zir::RuntimeError::DivisionByZero => RuntimeError::Inverse,
crate::zir::RuntimeError::IncompleteDynamicRange => {
RuntimeError::IncompleteDynamicRange
}
} }
} }
} }
@ -47,7 +49,11 @@ impl RuntimeError {
!matches!( !matches!(
self, self,
SourceAssertion(_) | Inverse | LtSum | SelectRangeCheck | ArgumentBitness SourceAssertion(_)
| Inverse
| SelectRangeCheck
| ArgumentBitness
| IncompleteDynamicRange
) )
} }
} }
@ -70,13 +76,13 @@ impl fmt::Display for RuntimeError {
BranchIsolation => "Branch isolation failed", BranchIsolation => "Branch isolation failed",
ConstantLtBitness => "Bitness check failed in constant Lt check", ConstantLtBitness => "Bitness check failed in constant Lt check",
ConstantLtSum => "Sum check failed in constant Lt check", ConstantLtSum => "Sum check failed in constant Lt check",
LtBitness => "Bitness check failed in Lt check",
LtSum => "Sum check failed in Lt check",
LtFinalBitness => "Bitness check failed in final Lt check",
LtFinalSum => "Sum check failed in final Lt check", LtFinalSum => "Sum check failed in final Lt check",
LtSymetric => "Symetrical check failed in Lt check", LtSymetric => "Symetrical check failed in Lt check",
Or => "Or check failed", Or => "Or check failed",
Xor => "Xor check failed", Xor => "Xor check failed",
IncompleteDynamicRange => {
"Failed to compare field elements because dynamic comparison is incomplete"
}
Inverse => "Division by zero", Inverse => "Division by zero",
Euclidean => "Euclidean check failed", Euclidean => "Euclidean check failed",
ShaXor => "Internal Sha check failed", ShaXor => "Internal Sha check failed",

View file

@ -188,15 +188,6 @@ impl<T: Field> fmt::Display for Prog<T> {
for s in &self.statements { for s in &self.statements {
writeln!(f, "\t{}", s)?; writeln!(f, "\t{}", s)?;
} }
writeln!(
f,
"\treturn {}",
(0..self.return_count)
.map(Variable::public)
.map(|e| format!("{}", e))
.collect::<Vec<_>>()
.join(", ")
)?;
writeln!(f, "\treturn {}", returns)?; writeln!(f, "\treturn {}", returns)?;
writeln!(f, "}}") writeln!(f, "}}")

View file

@ -264,6 +264,10 @@ pub trait Folder<'ast, T: Field>: Sized {
fold_statement(self, s) fold_statement(self, s)
} }
fn fold_definition_rhs(&mut self, rhs: DefinitionRhs<'ast, T>) -> DefinitionRhs<'ast, T> {
fold_definition_rhs(self, rhs)
}
fn fold_embed_call(&mut self, e: EmbedCall<'ast, T>) -> EmbedCall<'ast, T> { fn fold_embed_call(&mut self, e: EmbedCall<'ast, T>) -> EmbedCall<'ast, T> {
fold_embed_call(self, e) fold_embed_call(self, e)
} }
@ -491,6 +495,16 @@ pub fn fold_constant_symbol_declaration<'ast, T: Field, F: Folder<'ast, T>>(
} }
} }
pub fn fold_definition_rhs<'ast, T: Field, F: Folder<'ast, T>>(
f: &mut F,
rhs: DefinitionRhs<'ast, T>,
) -> DefinitionRhs<'ast, T> {
match rhs {
DefinitionRhs::EmbedCall(c) => DefinitionRhs::EmbedCall(f.fold_embed_call(c)),
DefinitionRhs::Expression(e) => DefinitionRhs::Expression(f.fold_expression(e)),
}
}
pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>( pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>(
f: &mut F, f: &mut F,
s: TypedStatement<'ast, T>, s: TypedStatement<'ast, T>,
@ -498,7 +512,7 @@ pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>(
let res = match s { let res = match s {
TypedStatement::Return(e) => TypedStatement::Return(f.fold_expression(e)), TypedStatement::Return(e) => TypedStatement::Return(f.fold_expression(e)),
TypedStatement::Definition(a, e) => { TypedStatement::Definition(a, e) => {
TypedStatement::Definition(f.fold_assignee(a), f.fold_expression(e)) TypedStatement::Definition(f.fold_assignee(a), f.fold_definition_rhs(e))
} }
TypedStatement::Assertion(e, error) => { TypedStatement::Assertion(e, error) => {
TypedStatement::Assertion(f.fold_boolean_expression(e), error) TypedStatement::Assertion(f.fold_boolean_expression(e), error)
@ -515,12 +529,6 @@ pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>(
TypedStatement::Log(s, e) => { TypedStatement::Log(s, e) => {
TypedStatement::Log(s, e.into_iter().map(|e| f.fold_expression(e)).collect()) TypedStatement::Log(s, e.into_iter().map(|e| f.fold_expression(e)).collect())
} }
TypedStatement::EmbedCallDefinition(assignee, embed_call) => {
TypedStatement::EmbedCallDefinition(
f.fold_assignee(assignee),
f.fold_embed_call(embed_call),
)
}
s => s, s => s,
}; };
vec![res] vec![res]

View file

@ -588,6 +588,7 @@ impl fmt::Display for AssertionMetadata {
pub enum RuntimeError { pub enum RuntimeError {
SourceAssertion(AssertionMetadata), SourceAssertion(AssertionMetadata),
SelectRangeCheck, SelectRangeCheck,
DivisionByZero,
} }
impl fmt::Display for RuntimeError { impl fmt::Display for RuntimeError {
@ -595,6 +596,7 @@ impl fmt::Display for RuntimeError {
match self { match self {
RuntimeError::SourceAssertion(metadata) => write!(f, "{}", metadata), RuntimeError::SourceAssertion(metadata) => write!(f, "{}", metadata),
RuntimeError::SelectRangeCheck => write!(f, "Range check on array access"), RuntimeError::SelectRangeCheck => write!(f, "Range check on array access"),
RuntimeError::DivisionByZero => write!(f, "Division by zero"),
} }
} }
} }
@ -646,12 +648,39 @@ impl<'ast, T: fmt::Display> fmt::Display for EmbedCall<'ast, T> {
} }
} }
#[derive(Clone, PartialEq, Debug, Hash, Eq, PartialOrd, Ord)]
pub enum DefinitionRhs<'ast, T> {
Expression(TypedExpression<'ast, T>),
EmbedCall(EmbedCall<'ast, T>),
}
impl<'ast, T> From<TypedExpression<'ast, T>> for DefinitionRhs<'ast, T> {
fn from(e: TypedExpression<'ast, T>) -> Self {
Self::Expression(e)
}
}
impl<'ast, T> From<EmbedCall<'ast, T>> for DefinitionRhs<'ast, T> {
fn from(c: EmbedCall<'ast, T>) -> Self {
Self::EmbedCall(c)
}
}
impl<'ast, T: fmt::Display> fmt::Display for DefinitionRhs<'ast, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
DefinitionRhs::EmbedCall(c) => write!(f, "{}", c),
DefinitionRhs::Expression(e) => write!(f, "{}", e),
}
}
}
/// A statement in a `TypedFunction` /// A statement in a `TypedFunction`
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
#[derive(Clone, PartialEq, Debug, Hash, Eq, PartialOrd, Ord)] #[derive(Clone, PartialEq, Debug, Hash, Eq, PartialOrd, Ord)]
pub enum TypedStatement<'ast, T> { pub enum TypedStatement<'ast, T> {
Return(TypedExpression<'ast, T>), Return(TypedExpression<'ast, T>),
Definition(TypedAssignee<'ast, T>, TypedExpression<'ast, T>), Definition(TypedAssignee<'ast, T>, DefinitionRhs<'ast, T>),
Assertion(BooleanExpression<'ast, T>, RuntimeError), Assertion(BooleanExpression<'ast, T>, RuntimeError),
For( For(
Variable<'ast, T>, Variable<'ast, T>,
@ -660,7 +689,6 @@ pub enum TypedStatement<'ast, T> {
Vec<TypedStatement<'ast, T>>, Vec<TypedStatement<'ast, T>>,
), ),
Log(FormatString, Vec<TypedExpression<'ast, T>>), Log(FormatString, Vec<TypedExpression<'ast, T>>),
EmbedCallDefinition(TypedAssignee<'ast, T>, EmbedCall<'ast, T>),
// Aux // Aux
PushCallLog( PushCallLog(
DeclarationFunctionKey<'ast, T>, DeclarationFunctionKey<'ast, T>,
@ -669,6 +697,16 @@ pub enum TypedStatement<'ast, T> {
PopCallLog, PopCallLog,
} }
impl<'ast, T> TypedStatement<'ast, T> {
pub fn definition(a: TypedAssignee<'ast, T>, e: TypedExpression<'ast, T>) -> Self {
Self::Definition(a, e.into())
}
pub fn embed_call_definition(a: TypedAssignee<'ast, T>, c: EmbedCall<'ast, T>) -> Self {
Self::Definition(a, c.into())
}
}
impl<'ast, T: fmt::Display> TypedStatement<'ast, T> { impl<'ast, T: fmt::Display> TypedStatement<'ast, T> {
fn fmt_indented(&self, f: &mut fmt::Formatter, depth: usize) -> fmt::Result { fn fmt_indented(&self, f: &mut fmt::Formatter, depth: usize) -> fmt::Result {
match self { match self {
@ -710,9 +748,6 @@ impl<'ast, T: fmt::Display> fmt::Display for TypedStatement<'ast, T> {
} }
write!(f, "\t}}") write!(f, "\t}}")
} }
TypedStatement::EmbedCallDefinition(ref lhs, ref rhs) => {
write!(f, "{} = {};", lhs, rhs)
}
TypedStatement::Log(ref l, ref expressions) => write!( TypedStatement::Log(ref l, ref expressions) => write!(
f, f,
"log({}, {})", "log({}, {})",
@ -752,6 +787,12 @@ pub enum TypedExpression<'ast, T> {
Int(IntExpression<'ast, T>), Int(IntExpression<'ast, T>),
} }
impl<'ast, T> TypedExpression<'ast, T> {
pub fn empty_tuple() -> TypedExpression<'ast, T> {
TypedExpression::Tuple(TupleExpressionInner::Value(vec![]).annotate(TupleType::new(vec![])))
}
}
impl<'ast, T> From<BooleanExpression<'ast, T>> for TypedExpression<'ast, T> { impl<'ast, T> From<BooleanExpression<'ast, T>> for TypedExpression<'ast, T> {
fn from(e: BooleanExpression<'ast, T>) -> TypedExpression<T> { fn from(e: BooleanExpression<'ast, T>) -> TypedExpression<T> {
TypedExpression::Boolean(e) TypedExpression::Boolean(e)
@ -909,7 +950,7 @@ impl<E> EqExpression<E> {
impl<E: fmt::Display> fmt::Display for EqExpression<E> { impl<E: fmt::Display> fmt::Display for EqExpression<E> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} == {}", self.left, self.right) write!(f, "({} == {})", self.left, self.right)
} }
} }
@ -1659,22 +1700,22 @@ impl<'ast, T: fmt::Display> fmt::Display for BooleanExpression<'ast, T> {
match *self { match *self {
BooleanExpression::Block(ref block) => write!(f, "{}", block,), BooleanExpression::Block(ref block) => write!(f, "{}", block,),
BooleanExpression::Identifier(ref var) => write!(f, "{}", var), BooleanExpression::Identifier(ref var) => write!(f, "{}", var),
BooleanExpression::FieldLt(ref lhs, ref rhs) => write!(f, "{} < {}", lhs, rhs), BooleanExpression::FieldLt(ref lhs, ref rhs) => write!(f, "({} < {})", lhs, rhs),
BooleanExpression::FieldLe(ref lhs, ref rhs) => write!(f, "{} <= {}", lhs, rhs), BooleanExpression::FieldLe(ref lhs, ref rhs) => write!(f, "({} <= {})", lhs, rhs),
BooleanExpression::FieldGe(ref lhs, ref rhs) => write!(f, "{} >= {}", lhs, rhs), BooleanExpression::FieldGe(ref lhs, ref rhs) => write!(f, "({} >= {})", lhs, rhs),
BooleanExpression::FieldGt(ref lhs, ref rhs) => write!(f, "{} > {}", lhs, rhs), BooleanExpression::FieldGt(ref lhs, ref rhs) => write!(f, "({} > {})", lhs, rhs),
BooleanExpression::UintLt(ref lhs, ref rhs) => write!(f, "{} < {}", lhs, rhs), BooleanExpression::UintLt(ref lhs, ref rhs) => write!(f, "({} < {})", lhs, rhs),
BooleanExpression::UintLe(ref lhs, ref rhs) => write!(f, "{} <= {}", lhs, rhs), BooleanExpression::UintLe(ref lhs, ref rhs) => write!(f, "({} <= {})", lhs, rhs),
BooleanExpression::UintGe(ref lhs, ref rhs) => write!(f, "{} >= {}", lhs, rhs), BooleanExpression::UintGe(ref lhs, ref rhs) => write!(f, "({} >= {})", lhs, rhs),
BooleanExpression::UintGt(ref lhs, ref rhs) => write!(f, "{} > {}", lhs, rhs), BooleanExpression::UintGt(ref lhs, ref rhs) => write!(f, "({} > {})", lhs, rhs),
BooleanExpression::FieldEq(ref e) => write!(f, "{}", e), BooleanExpression::FieldEq(ref e) => write!(f, "{}", e),
BooleanExpression::BoolEq(ref e) => write!(f, "{}", e), BooleanExpression::BoolEq(ref e) => write!(f, "{}", e),
BooleanExpression::ArrayEq(ref e) => write!(f, "{}", e), BooleanExpression::ArrayEq(ref e) => write!(f, "{}", e),
BooleanExpression::StructEq(ref e) => write!(f, "{}", e), BooleanExpression::StructEq(ref e) => write!(f, "{}", e),
BooleanExpression::TupleEq(ref e) => write!(f, "{}", e), BooleanExpression::TupleEq(ref e) => write!(f, "{}", e),
BooleanExpression::UintEq(ref e) => write!(f, "{}", e), BooleanExpression::UintEq(ref e) => write!(f, "{}", e),
BooleanExpression::Or(ref lhs, ref rhs) => write!(f, "{} || {}", lhs, rhs), BooleanExpression::Or(ref lhs, ref rhs) => write!(f, "({} || {})", lhs, rhs),
BooleanExpression::And(ref lhs, ref rhs) => write!(f, "{} && {}", lhs, rhs), BooleanExpression::And(ref lhs, ref rhs) => write!(f, "({} && {})", lhs, rhs),
BooleanExpression::Not(ref exp) => write!(f, "!{}", exp), BooleanExpression::Not(ref exp) => write!(f, "!{}", exp),
BooleanExpression::Value(b) => write!(f, "{}", b), BooleanExpression::Value(b) => write!(f, "{}", b),
BooleanExpression::FunctionCall(ref function_call) => write!(f, "{}", function_call), BooleanExpression::FunctionCall(ref function_call) => write!(f, "{}", function_call),

View file

@ -385,6 +385,13 @@ pub trait ResultFolder<'ast, T: Field>: Sized {
fold_statement(self, s) fold_statement(self, s)
} }
fn fold_definition_rhs(
&mut self,
rhs: DefinitionRhs<'ast, T>,
) -> Result<DefinitionRhs<'ast, T>, Self::Error> {
fold_definition_rhs(self, rhs)
}
fn fold_embed_call( fn fold_embed_call(
&mut self, &mut self,
e: EmbedCall<'ast, T>, e: EmbedCall<'ast, T>,
@ -508,7 +515,7 @@ pub fn fold_statement<'ast, T: Field, F: ResultFolder<'ast, T>>(
let res = match s { let res = match s {
TypedStatement::Return(e) => TypedStatement::Return(f.fold_expression(e)?), TypedStatement::Return(e) => TypedStatement::Return(f.fold_expression(e)?),
TypedStatement::Definition(a, e) => { TypedStatement::Definition(a, e) => {
TypedStatement::Definition(f.fold_assignee(a)?, f.fold_expression(e)?) TypedStatement::Definition(f.fold_assignee(a)?, f.fold_definition_rhs(e)?)
} }
TypedStatement::Assertion(e, error) => { TypedStatement::Assertion(e, error) => {
TypedStatement::Assertion(f.fold_boolean_expression(e)?, error) TypedStatement::Assertion(f.fold_boolean_expression(e)?, error)
@ -531,17 +538,21 @@ pub fn fold_statement<'ast, T: Field, F: ResultFolder<'ast, T>>(
.map(|e| f.fold_expression(e)) .map(|e| f.fold_expression(e))
.collect::<Result<Vec<_>, _>>()?, .collect::<Result<Vec<_>, _>>()?,
), ),
TypedStatement::EmbedCallDefinition(assignee, embed_call) => {
TypedStatement::EmbedCallDefinition(
f.fold_assignee(assignee)?,
f.fold_embed_call(embed_call)?,
)
}
s => s, s => s,
}; };
Ok(vec![res]) Ok(vec![res])
} }
pub fn fold_definition_rhs<'ast, T: Field, F: ResultFolder<'ast, T>>(
f: &mut F,
rhs: DefinitionRhs<'ast, T>,
) -> Result<DefinitionRhs<'ast, T>, F::Error> {
Ok(match rhs {
DefinitionRhs::EmbedCall(c) => DefinitionRhs::EmbedCall(f.fold_embed_call(c)?),
DefinitionRhs::Expression(e) => DefinitionRhs::Expression(f.fold_expression(e)?),
})
}
pub fn fold_embed_call<'ast, T: Field, F: ResultFolder<'ast, T>>( pub fn fold_embed_call<'ast, T: Field, F: ResultFolder<'ast, T>>(
f: &mut F, f: &mut F,
e: EmbedCall<'ast, T>, e: EmbedCall<'ast, T>,

View file

@ -895,6 +895,10 @@ impl<S> GType<S> {
pub fn uint<W: Into<UBitwidth>>(b: W) -> Self { pub fn uint<W: Into<UBitwidth>>(b: W) -> Self {
GType::Uint(b.into()) GType::Uint(b.into())
} }
pub fn is_empty_tuple(&self) -> bool {
matches!(self, GType::Tuple(ty) if ty.elements.is_empty())
}
} }
impl<'ast, T: fmt::Display + PartialEq + fmt::Debug> Type<'ast, T> { impl<'ast, T: fmt::Display + PartialEq + fmt::Debug> Type<'ast, T> {

View file

@ -92,6 +92,8 @@ pub type ZirAssignee<'ast> = Variable<'ast>;
pub enum RuntimeError { pub enum RuntimeError {
SourceAssertion(String), SourceAssertion(String),
SelectRangeCheck, SelectRangeCheck,
DivisionByZero,
IncompleteDynamicRange,
} }
impl fmt::Display for RuntimeError { impl fmt::Display for RuntimeError {
@ -99,6 +101,8 @@ impl fmt::Display for RuntimeError {
match self { match self {
RuntimeError::SourceAssertion(message) => write!(f, "{}", message), RuntimeError::SourceAssertion(message) => write!(f, "{}", message),
RuntimeError::SelectRangeCheck => write!(f, "Range check on array access"), RuntimeError::SelectRangeCheck => write!(f, "Range check on array access"),
RuntimeError::DivisionByZero => write!(f, "Division by zero"),
RuntimeError::IncompleteDynamicRange => write!(f, "Dynamic comparison is incomplete"),
} }
} }
} }
@ -716,7 +720,6 @@ impl<'ast, T> Conditional<'ast, T> for UExpression<'ast, T> {
.annotate(bitwidth) .annotate(bitwidth)
} }
} }
pub trait Select<'ast, T>: Sized { pub trait Select<'ast, T>: Sized {
fn select(array: Vec<Self>, index: UExpression<'ast, T>) -> Self; fn select(array: Vec<Self>, index: UExpression<'ast, T>) -> Self;
} }
@ -745,7 +748,6 @@ impl<'ast, T> Select<'ast, T> for UExpression<'ast, T> {
UExpressionInner::Select(SelectExpression::new(array, index)).annotate(bitwidth) UExpressionInner::Select(SelectExpression::new(array, index)).annotate(bitwidth)
} }
} }
pub trait IntoType { pub trait IntoType {
fn into_type(self) -> Type; fn into_type(self) -> Type;
} }

View file

@ -1,13 +1,15 @@
## Functions ## Functions
Functions are declared using the `def` keyword. A function's signature has to be explicitly provided.
Its arguments are type annotated, just like variables, and, if the function returns a value,
the return type must be specified after an arrow `->`.
A function has to be declared at the top level before it is called. A function has to be declared at the top level before it is called.
```zokrates ```zokrates
{{#include ../../../zokrates_cli/examples/book/function_declaration.zok}} {{#include ../../../zokrates_cli/examples/book/function_declaration.zok}}
``` ```
A function's signature has to be explicitly provided.
A function can be generic over any number of values of type `u32`. A function can be generic over any number of values of type `u32`.
```zokrates ```zokrates
@ -19,3 +21,9 @@ The generic parameters can be provided explicitly, especially when they cannot b
```zokrates ```zokrates
{{#include ../../../zokrates_cli/examples/book/explicit_generic_parameters.zok}} {{#include ../../../zokrates_cli/examples/book/explicit_generic_parameters.zok}}
``` ```
If the return type of a function is the empty tuple `()`, the return type as well as the return statement can be omitted.
```zokrates
{{#include ../../../zokrates_cli/examples/book/no_return.zok}}
```

View file

@ -50,6 +50,7 @@ zokrates_solidity_test = { version = "0.1", path = "../zokrates_solidity_test",
ethabi = "17.0.0" ethabi = "17.0.0"
primitive-types = { version = "0.11", features = ["rlp"] } primitive-types = { version = "0.11", features = ["rlp"] }
fs_extra = "1.1.0" fs_extra = "1.1.0"
pretty_assertions = "1.2.1"
[build-dependencies] [build-dependencies]
fs_extra = "1.1.0" fs_extra = "1.1.0"

View file

@ -0,0 +1 @@
def main() {}

View file

@ -1,5 +1 @@
def foo() {} def main() -> field {}
def main() {
return;
}

View file

@ -4,9 +4,10 @@ from "field" import FIELD_SIZE_IN_BITS;
// It should not work for the maxvalue = 2^(pbits - 2) - 1 augmented by one // It should not work for the maxvalue = 2^(pbits - 2) - 1 augmented by one
// /!\ should be called with a = 0 // /!\ should be called with a = 0
def main(field a) -> bool { def main(field a) {
u32 pbits = FIELD_SIZE_IN_BITS; u32 pbits = FIELD_SIZE_IN_BITS;
// we added a = 0 to prevent the condition to be evaluated at compile time // we added a = 0 to prevent the condition to be evaluated at compile time
field maxvalue = a + (2**(pbits - 2) - 1); field maxvalue = a + (2**(pbits - 2) - 1);
return a < maxvalue + 1; bool c = a < maxvalue + 1;
return;
} }

View file

@ -4,9 +4,10 @@ from "field" import FIELD_SIZE_IN_BITS;
// It should not work for the maxvalue = 2^(pbits - 2) - 1 augmented by one // It should not work for the maxvalue = 2^(pbits - 2) - 1 augmented by one
// /!\ should be called with a = 0 // /!\ should be called with a = 0
def main(field a) -> bool { def main(field a) {
u32 pbits = FIELD_SIZE_IN_BITS; u32 pbits = FIELD_SIZE_IN_BITS;
// we added a = 0 to prevent the condition to be evaluated at compile time // we added a = 0 to prevent the condition to be evaluated at compile time
field maxvalue = a + (2**(pbits - 2) - 1); field maxvalue = a + (2**(pbits - 2) - 1);
return maxvalue + 1 < a; bool c = maxvalue + 1 < a;
return;
} }

View file

@ -523,7 +523,7 @@
(= (mod (* (+ (* |~one| 14651237294507013008273219182214280847718990358813499091232105186081237893121) (* |_0| 1) (* |_1| 21888242871839275222246405745257275088548364400416034343698204186575808495616)) (* |_258| 1)) |~prime|) (mod (* |_257| 1) |~prime|)) (= (mod (* (+ (* |~one| 14651237294507013008273219182214280847718990358813499091232105186081237893121) (* |_0| 1) (* |_1| 21888242871839275222246405745257275088548364400416034343698204186575808495616)) (* |_258| 1)) |~prime|) (mod (* |_257| 1) |~prime|))
(= (mod (* (+ (* |~one| 1) (* |_257| 21888242871839275222246405745257275088548364400416034343698204186575808495616)) (+ (* |~one| 14651237294507013008273219182214280847718990358813499091232105186081237893121) (* |_0| 1) (* |_1| 21888242871839275222246405745257275088548364400416034343698204186575808495616))) |~prime|) (mod 0 |~prime|)) (= (mod (* (+ (* |~one| 1) (* |_257| 21888242871839275222246405745257275088548364400416034343698204186575808495616)) (+ (* |~one| 14651237294507013008273219182214280847718990358813499091232105186081237893121) (* |_0| 1) (* |_1| 21888242871839275222246405745257275088548364400416034343698204186575808495616))) |~prime|) (mod 0 |~prime|))
(= (mod (* (* |~one| 1) 0) |~prime|) (mod (+ (* |~one| 1) (* |_257| 21888242871839275222246405745257275088548364400416034343698204186575808495616)) |~prime|)) (= (mod (* (* |~one| 1) (* |~one| 1)) |~prime|) (mod (* |_257| 1) |~prime|))
(= (mod (* (* |_2| 1) (+ (* |_0| 21888242871839275222246405745257275088548364400416034343698204186575808495616) (* |_1| 1))) |~prime|) (mod (* |_264| 1) |~prime|)) (= (mod (* (* |_2| 1) (+ (* |_0| 21888242871839275222246405745257275088548364400416034343698204186575808495616) (* |_1| 1))) |~prime|) (mod (* |_264| 1) |~prime|))
(= (mod (* (* |~one| 1) (* |_264| 1)) |~prime|) (mod (* |~out_0| 1) |~prime|)) (= (mod (* (* |~one| 1) (* |_264| 1)) |~prime|) (mod (* |~out_0| 1) |~prime|))
)) ))

View file

@ -10,6 +10,7 @@ extern crate zokrates_solidity_test;
mod integration { mod integration {
use fs_extra::copy_items; use fs_extra::copy_items;
use fs_extra::dir::CopyOptions; use fs_extra::dir::CopyOptions;
use pretty_assertions::assert_eq;
use primitive_types::U256; use primitive_types::U256;
use serde_json::from_reader; use serde_json::from_reader;
use std::fs; use std::fs;
@ -452,6 +453,8 @@ mod integration {
program_path: &Path, program_path: &Path,
expected_smtlib2_path: &Path, expected_smtlib2_path: &Path,
) { ) {
println!("test smtlib2 for {}", program_path.display());
let tmp_dir = TempDir::new(program_name).unwrap(); let tmp_dir = TempDir::new(program_name).unwrap();
let tmp_base = tmp_dir.path(); let tmp_base = tmp_dir.path();
let test_case_path = tmp_base.join(program_name); let test_case_path = tmp_base.join(program_name);

View file

@ -280,9 +280,29 @@ impl<'ast, T: Field> Flattener<'ast, T> {
a: &[FlatExpression<T>], a: &[FlatExpression<T>],
b: &[bool], b: &[bool],
) -> Vec<FlatExpression<T>> { ) -> Vec<FlatExpression<T>> {
let len = b.len();
assert_eq!(a.len(), b.len()); assert_eq!(a.len(), b.len());
let is_power_of_two_minus_one = b.iter().all(|b| *b);
// if `b` is all ones, then the check is always verified because that's the maximum possible value
if is_power_of_two_minus_one {
let statements: Vec<_> = a
.iter()
.map(|e| {
let e_id = self.define(e.clone(), statements_flattened);
FlatStatement::Condition(
e_id.into(),
FlatExpression::Mult(box e_id.into(), box e_id.into()),
RuntimeError::Bitness,
)
})
.collect();
statements_flattened.extend(statements);
return vec![];
}
let len = b.len();
let mut is_not_smaller_run = vec![]; let mut is_not_smaller_run = vec![];
let mut size_unknown = vec![]; let mut size_unknown = vec![];
@ -778,66 +798,17 @@ impl<'ast, T: Field> Flattener<'ast, T> {
let sub_width = bit_width + 1; let sub_width = bit_width + 1;
// define variables for the bits let shifted_sub_bits_be = self.get_bits_unchecked(
let shifted_sub_bits_be: Vec<Variable> = &FlatUExpression::with_field(shifted_sub),
(0..sub_width).map(|_| self.use_sym()).collect(); sub_width,
sub_width,
// add a directive to get the bits
statements_flattened.push_back(FlatStatement::Directive(FlatDirective::new(
shifted_sub_bits_be.clone(),
Solver::bits(sub_width),
vec![shifted_sub.clone()],
)));
// bitness checks
for bit in shifted_sub_bits_be.iter() {
statements_flattened.push_back(FlatStatement::Condition(
FlatExpression::Identifier(*bit),
FlatExpression::Mult(
box FlatExpression::Identifier(*bit),
box FlatExpression::Identifier(*bit),
),
RuntimeError::LtFinalBitness,
));
}
// sum(sym_b{i} * 2**i)
let mut expr = FlatExpression::Number(T::from(0));
for (i, bit) in shifted_sub_bits_be.iter().take(sub_width).enumerate() {
expr = FlatExpression::Add(
box expr,
box FlatExpression::Mult(
box FlatExpression::Identifier(*bit),
box FlatExpression::Number(T::from(2).pow(sub_width - i - 1)),
),
);
}
statements_flattened.push_back(FlatStatement::Condition(
shifted_sub,
expr,
RuntimeError::LtFinalSum,
));
// to make this check symetric, we ban the value `a - b == -2**N`, as the value `a - b == 2**N` is already banned
let fail = self.eq_check(
statements_flattened, statements_flattened,
FlatExpression::Sub( RuntimeError::IncompleteDynamicRange,
box FlatExpression::Identifier(rhs_id),
box FlatExpression::Identifier(lhs_id),
),
FlatExpression::Number(T::from(2).pow(bit_width)),
); );
statements_flattened.push_back(FlatStatement::Condition(
fail,
FlatExpression::Number(T::from(0)),
RuntimeError::LtSymetric,
));
FlatExpression::Sub( FlatExpression::Sub(
box FlatExpression::Number(T::one()), box FlatExpression::Number(T::one()),
box FlatExpression::Identifier(shifted_sub_bits_be[0]), box shifted_sub_bits_be[0].clone(),
) )
} }
} }
@ -1351,24 +1322,7 @@ impl<'ast, T: Field> Flattener<'ast, T> {
FlatExpression::Identifier(id) FlatExpression::Identifier(id)
}; };
// first check that the d is not 0 by giving its inverse // introduce the quotient and remainder
let invd = self.use_sym();
// # invd = 1/d
statements_flattened.push_back(FlatStatement::Directive(FlatDirective::new(
vec![invd],
Solver::Div,
vec![FlatExpression::Number(T::one()), d.clone()],
)));
// assert(invd * d == 1)
statements_flattened.push_back(FlatStatement::Condition(
FlatExpression::Number(T::one()),
FlatExpression::Mult(box invd.into(), box d.clone()),
RuntimeError::Inverse,
));
// now introduce the quotient and remainder
let q = self.use_sym(); let q = self.use_sym();
let r = self.use_sym(); let r = self.use_sym();
@ -2163,23 +2117,11 @@ impl<'ast, T: Field> Flattener<'ast, T> {
id.into() id.into()
}; };
let invb = self.use_sym(); // `right` is assumed to already be non-zero so this is an unchecked division
// TODO: we could save one constraint here by reusing the inverse of `right` computed earlier
let inverse = self.use_sym(); let inverse = self.use_sym();
// # invb = 1/b
statements_flattened.push_back(FlatStatement::Directive(FlatDirective::new(
vec![invb],
Solver::Div,
vec![FlatExpression::Number(T::one()), new_right.clone()],
)));
// assert(invb * b == 1)
statements_flattened.push_back(FlatStatement::Condition(
FlatExpression::Number(T::one()),
FlatExpression::Mult(box invb.into(), box new_right.clone()),
RuntimeError::Inverse,
));
// # c = a/b // # c = a/b
statements_flattened.push_back(FlatStatement::Directive(FlatDirective::new( statements_flattened.push_back(FlatStatement::Directive(FlatDirective::new(
vec![inverse], vec![inverse],
@ -2458,6 +2400,40 @@ impl<'ast, T: Field> Flattener<'ast, T> {
} }
} }
} }
BooleanExpression::UintLe(box lhs, box rhs) => {
let lhs = self
.flatten_uint_expression(statements_flattened, lhs)
.get_field_unchecked();
let rhs = self
.flatten_uint_expression(statements_flattened, rhs)
.get_field_unchecked();
match (lhs, rhs) {
(e, FlatExpression::Number(c)) => self.enforce_constant_le_check(
statements_flattened,
e,
c,
error.into(),
),
// c <= e <=> p - 1 - e <= p - 1 - c
(FlatExpression::Number(c), e) => self.enforce_constant_le_check(
statements_flattened,
FlatExpression::Sub(box T::max_value().into(), box e),
T::max_value() - c,
error.into(),
),
(lhs, rhs) => {
let bit_width = T::get_required_bits();
let safe_width = bit_width - 2; // dynamic comparison is not complete
let e = self.le_check(statements_flattened, lhs, rhs, safe_width);
statements_flattened.push_back(FlatStatement::Condition(
e,
FlatExpression::Number(T::one()),
error.into(),
));
}
}
}
BooleanExpression::UintEq(box lhs, box rhs) => { BooleanExpression::UintEq(box lhs, box rhs) => {
let lhs = self let lhs = self
.flatten_uint_expression(statements_flattened, lhs) .flatten_uint_expression(statements_flattened, lhs)
@ -2484,6 +2460,80 @@ impl<'ast, T: Field> Flattener<'ast, T> {
error.into(), error.into(),
) )
} }
// `!(x == 0)` can be asserted by giving the inverse of `x`
BooleanExpression::Not(box BooleanExpression::UintEq(
box UExpression {
inner: UExpressionInner::Value(0),
..
},
box x,
))
| BooleanExpression::Not(box BooleanExpression::UintEq(
box x,
box UExpression {
inner: UExpressionInner::Value(0),
..
},
)) => {
let x = self
.flatten_uint_expression(statements_flattened, x)
.get_field_unchecked();
// introduce intermediate variable
let x_id = self.define(x, statements_flattened);
// check that `x` is not 0 by giving its inverse
let invx = self.use_sym();
// # invx = 1/x
statements_flattened.push_back(FlatStatement::Directive(
FlatDirective::new(
vec![invx],
Solver::Div,
vec![FlatExpression::Number(T::one()), x_id.into()],
),
));
// assert(invx * x == 1)
statements_flattened.push_back(FlatStatement::Condition(
FlatExpression::Number(T::one()),
FlatExpression::Mult(box invx.into(), box x_id.into()),
RuntimeError::Inverse,
));
}
// `!(x == 0)` can be asserted by giving the inverse of `x`
BooleanExpression::Not(box BooleanExpression::FieldEq(
box FieldElementExpression::Number(zero),
box x,
))
| BooleanExpression::Not(box BooleanExpression::FieldEq(
box x,
box FieldElementExpression::Number(zero),
)) if zero == T::from(0) => {
let x = self.flatten_field_expression(statements_flattened, x);
// introduce intermediate variable
let x_id = self.define(x, statements_flattened);
// check that `x` is not 0 by giving its inverse
let invx = self.use_sym();
// # invx = 1/x
statements_flattened.push_back(FlatStatement::Directive(
FlatDirective::new(
vec![invx],
Solver::Div,
vec![FlatExpression::Number(T::one()), x_id.into()],
),
));
// assert(invx * x == 1)
statements_flattened.push_back(FlatStatement::Condition(
FlatExpression::Number(T::one()),
FlatExpression::Mult(box invx.into(), box x_id.into()),
RuntimeError::Inverse,
));
}
e => { e => {
// naive approach: flatten the boolean to a single field element and constrain it to 1 // naive approach: flatten the boolean to a single field element and constrain it to 1
let e = self.flatten_boolean_expression(statements_flattened, e); let e = self.flatten_boolean_expression(statements_flattened, e);
@ -3580,18 +3630,14 @@ mod tests {
// define new wires for members of Div // define new wires for members of Div
let five = Variable::new(1); let five = Variable::new(1);
let b0 = Variable::new(2); let b0 = Variable::new(2);
// Define inverse of denominator to prevent div by 0
let invb0 = Variable::new(3);
// Define inverse // Define inverse
let sym_0 = Variable::new(4); let sym_0 = Variable::new(3);
// Define result, which is first member to next Div // Define result, which is first member to next Div
let sym_1 = Variable::new(5); let sym_1 = Variable::new(4);
// Define second member // Define second member
let b1 = Variable::new(6); let b1 = Variable::new(5);
// Define inverse of denominator to prevent div by 0
let invb1 = Variable::new(7);
// Define inverse // Define inverse
let sym_2 = Variable::new(8); let sym_2 = Variable::new(6);
assert_eq!( assert_eq!(
statements_flattened, statements_flattened,
@ -3600,17 +3646,6 @@ mod tests {
// inputs to first div (5/b) // inputs to first div (5/b)
FlatStatement::Definition(five, FlatExpression::Number(Bn128Field::from(5))), FlatStatement::Definition(five, FlatExpression::Number(Bn128Field::from(5))),
FlatStatement::Definition(b0, b.into()), FlatStatement::Definition(b0, b.into()),
// check div by 0
FlatStatement::Directive(FlatDirective::new(
vec![invb0],
Solver::Div,
vec![FlatExpression::Number(Bn128Field::from(1)), b0.into()]
)),
FlatStatement::Condition(
FlatExpression::Number(Bn128Field::from(1)),
FlatExpression::Mult(box invb0.into(), box b0.into()),
RuntimeError::Inverse,
),
// execute div // execute div
FlatStatement::Directive(FlatDirective::new( FlatStatement::Directive(FlatDirective::new(
vec![sym_0], vec![sym_0],
@ -3625,17 +3660,6 @@ mod tests {
// inputs to second div (res/b) // inputs to second div (res/b)
FlatStatement::Definition(sym_1, sym_0.into()), FlatStatement::Definition(sym_1, sym_0.into()),
FlatStatement::Definition(b1, b.into()), FlatStatement::Definition(b1, b.into()),
// check div by 0
FlatStatement::Directive(FlatDirective::new(
vec![invb1],
Solver::Div,
vec![FlatExpression::Number(Bn128Field::from(1)), b1.into()]
)),
FlatStatement::Condition(
FlatExpression::Number(Bn128Field::from(1)),
FlatExpression::Mult(box invb1.into(), box b1.into()),
RuntimeError::Inverse
),
// execute div // execute div
FlatStatement::Directive(FlatDirective::new( FlatStatement::Directive(FlatDirective::new(
vec![sym_2], vec![sym_2],

View file

@ -1204,10 +1204,16 @@ impl<'ast, T: Field> Checker<'ast, T> {
} }
if !found_return { if !found_return {
errors.push(ErrorInner { match (&*s.output).is_empty_tuple() {
pos: Some(pos), true => statements_checked
message: "Expected a return statement".to_string(), .push(TypedStatement::Return(TypedExpression::empty_tuple())),
}); false => {
errors.push(ErrorInner {
pos: Some(pos),
message: "Expected a return statement".to_string(),
});
}
}
} }
signature = Some(s); signature = Some(s);
@ -1843,11 +1849,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
} }
.map_err(|e| vec![e]) .map_err(|e| vec![e])
}) })
.unwrap_or_else(|| { .unwrap_or_else(|| Ok(TypedExpression::empty_tuple()))?;
Ok(TupleExpressionInner::Value(vec![])
.annotate(TupleType::new(vec![]))
.into())
})?;
let res = match TypedExpression::align_to_type(e_checked.clone(), &return_type) let res = match TypedExpression::align_to_type(e_checked.clone(), &return_type)
.map_err(|e| { .map_err(|e| {
@ -1939,7 +1941,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
var_ty var_ty
), ),
}) })
.map(|e| TypedStatement::Definition(var.into(), e)) .map(|e| TypedStatement::Definition(var.into(), e.into()))
.map_err(|e| vec![e]) .map_err(|e| vec![e])
} }
Statement::Assignment(assignee, expr) => { Statement::Assignment(assignee, expr) => {
@ -1986,7 +1988,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
assignee_ty assignee_ty
), ),
}) })
.map(|e| TypedStatement::Definition(assignee, e)) .map(|e| TypedStatement::Definition(assignee, e.into()))
.map_err(|e| vec![e]) .map_err(|e| vec![e])
} }
Statement::Assertion(e, message) => { Statement::Assertion(e, message) => {
@ -4483,7 +4485,7 @@ mod tests {
checker.enter_scope(); checker.enter_scope();
assert_eq!( assert_eq!(
checker.check_statement(statement, &*MODULE_ID, &TypeMap::new()), checker.check_statement(statement, &*MODULE_ID, &TypeMap::new()),
Ok(TypedStatement::Definition( Ok(TypedStatement::definition(
typed::Variable::field_element("a").into(), typed::Variable::field_element("a").into(),
FieldElementExpression::Identifier("b".into()).into() FieldElementExpression::Identifier("b".into()).into()
)) ))
@ -4712,7 +4714,7 @@ mod tests {
Statement::Return(None).mock(), Statement::Return(None).mock(),
]; ];
let for_statements_checked = vec![TypedStatement::Definition( let for_statements_checked = vec![TypedStatement::definition(
typed::Variable::uint( typed::Variable::uint(
CoreIdentifier::Source(ShadowedIdentifier::shadow("a", 1)), CoreIdentifier::Source(ShadowedIdentifier::shadow("a", 1)),
UBitwidth::B32, UBitwidth::B32,
@ -4735,11 +4737,7 @@ mod tests {
10u32.into(), 10u32.into(),
for_statements_checked, for_statements_checked,
), ),
TypedStatement::Return( TypedStatement::Return(TypedExpression::empty_tuple()),
TupleExpressionInner::Value(vec![])
.annotate(TupleType::new(vec![]))
.into(),
),
]; ];
let foo = Function { let foo = Function {
@ -5334,7 +5332,7 @@ mod tests {
]; ];
let expected = vec![ let expected = vec![
TypedStatement::Definition( TypedStatement::definition(
typed::Variable::new( typed::Variable::new(
CoreIdentifier::from(ShadowedIdentifier::shadow("a", 0)), CoreIdentifier::from(ShadowedIdentifier::shadow("a", 0)),
Type::FieldElement, Type::FieldElement,
@ -5352,7 +5350,7 @@ mod tests {
0u32.into(), 0u32.into(),
0u32.into(), 0u32.into(),
vec![ vec![
TypedStatement::Definition( TypedStatement::definition(
typed::Variable::new( typed::Variable::new(
CoreIdentifier::from(ShadowedIdentifier::shadow("a", 0)), CoreIdentifier::from(ShadowedIdentifier::shadow("a", 0)),
Type::FieldElement, Type::FieldElement,
@ -5361,7 +5359,7 @@ mod tests {
.into(), .into(),
FieldElementExpression::Number(3.into()).into(), FieldElementExpression::Number(3.into()).into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
typed::Variable::new( typed::Variable::new(
CoreIdentifier::from(ShadowedIdentifier::shadow("a", 1)), CoreIdentifier::from(ShadowedIdentifier::shadow("a", 1)),
Type::FieldElement, Type::FieldElement,
@ -5372,7 +5370,7 @@ mod tests {
), ),
], ],
), ),
TypedStatement::Definition( TypedStatement::definition(
typed::Variable::new( typed::Variable::new(
CoreIdentifier::from(ShadowedIdentifier::shadow("a", 0)), CoreIdentifier::from(ShadowedIdentifier::shadow("a", 0)),
Type::FieldElement, Type::FieldElement,

View file

@ -1,7 +1,7 @@
use zokrates_ast::typed::{ use zokrates_ast::typed::{
folder::*, BlockExpression, BooleanExpression, Conditional, ConditionalExpression, folder::*, BlockExpression, BooleanExpression, Conditional, ConditionalExpression,
ConditionalOrExpression, CoreIdentifier, Expr, Identifier, Type, TypedProgram, TypedStatement, ConditionalOrExpression, CoreIdentifier, Expr, Identifier, Type, TypedExpression, TypedProgram,
Variable, TypedStatement, Variable,
}; };
use zokrates_field::Field; use zokrates_field::Field;
@ -65,9 +65,9 @@ impl<'ast, T: Field> Folder<'ast, T> for ConditionRedefiner<'ast, T> {
| condition @ BooleanExpression::Identifier(_) => condition, | condition @ BooleanExpression::Identifier(_) => condition,
condition => { condition => {
let condition_id = Identifier::from(CoreIdentifier::Condition(self.index)); let condition_id = Identifier::from(CoreIdentifier::Condition(self.index));
self.buffer.push(TypedStatement::Definition( self.buffer.push(TypedStatement::definition(
Variable::immutable(condition_id.clone(), Type::Boolean).into(), Variable::immutable(condition_id.clone(), Type::Boolean).into(),
condition.into(), TypedExpression::from(condition),
)); ));
self.index += 1; self.index += 1;
BooleanExpression::Identifier(condition_id) BooleanExpression::Identifier(condition_id)
@ -99,7 +99,7 @@ mod tests {
// field foo = if true { 1 } else { 2 }; // field foo = if true { 1 } else { 2 };
// should be left unchanged // should be left unchanged
let s = TypedStatement::Definition( let s = TypedStatement::definition(
Variable::field_element("foo").into(), Variable::field_element("foo").into(),
FieldElementExpression::conditional( FieldElementExpression::conditional(
BooleanExpression::Value(true), BooleanExpression::Value(true),
@ -120,7 +120,7 @@ mod tests {
// field foo = if c { 1 } else { 2 }; // field foo = if c { 1 } else { 2 };
// should be left unchanged // should be left unchanged
let s = TypedStatement::Definition( let s = TypedStatement::definition(
Variable::field_element("foo").into(), Variable::field_element("foo").into(),
FieldElementExpression::conditional( FieldElementExpression::conditional(
BooleanExpression::Identifier("c".into()), BooleanExpression::Identifier("c".into()),
@ -148,7 +148,7 @@ mod tests {
box BooleanExpression::Identifier("d".into()), box BooleanExpression::Identifier("d".into()),
); );
let s = TypedStatement::Definition( let s = TypedStatement::definition(
Variable::field_element("foo").into(), Variable::field_element("foo").into(),
FieldElementExpression::conditional( FieldElementExpression::conditional(
condition.clone(), condition.clone(),
@ -163,12 +163,12 @@ mod tests {
let expected = vec![ let expected = vec![
// define condition // define condition
TypedStatement::Definition( TypedStatement::definition(
Variable::immutable(CoreIdentifier::Condition(0), Type::Boolean).into(), Variable::immutable(CoreIdentifier::Condition(0), Type::Boolean).into(),
condition.into(), condition.into(),
), ),
// rewrite statement // rewrite statement
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element("foo").into(), Variable::field_element("foo").into(),
FieldElementExpression::conditional( FieldElementExpression::conditional(
BooleanExpression::Identifier(CoreIdentifier::Condition(0).into()), BooleanExpression::Identifier(CoreIdentifier::Condition(0).into()),
@ -212,7 +212,7 @@ mod tests {
box BooleanExpression::Identifier("f".into()), box BooleanExpression::Identifier("f".into()),
); );
let s = TypedStatement::Definition( let s = TypedStatement::definition(
Variable::field_element("foo").into(), Variable::field_element("foo").into(),
FieldElementExpression::conditional( FieldElementExpression::conditional(
condition_0.clone(), condition_0.clone(),
@ -232,16 +232,16 @@ mod tests {
let expected = vec![ let expected = vec![
// define conditions // define conditions
TypedStatement::Definition( TypedStatement::definition(
Variable::immutable(CoreIdentifier::Condition(0), Type::Boolean).into(), Variable::immutable(CoreIdentifier::Condition(0), Type::Boolean).into(),
condition_0.into(), condition_0.into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::immutable(CoreIdentifier::Condition(1), Type::Boolean).into(), Variable::immutable(CoreIdentifier::Condition(1), Type::Boolean).into(),
condition_1.into(), condition_1.into(),
), ),
// rewrite statement // rewrite statement
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element("foo").into(), Variable::field_element("foo").into(),
FieldElementExpression::conditional( FieldElementExpression::conditional(
BooleanExpression::Identifier(CoreIdentifier::Condition(0).into()), BooleanExpression::Identifier(CoreIdentifier::Condition(0).into()),
@ -303,12 +303,12 @@ mod tests {
let condition_id_1 = BooleanExpression::Identifier(CoreIdentifier::Condition(1).into()); let condition_id_1 = BooleanExpression::Identifier(CoreIdentifier::Condition(1).into());
let condition_id_2 = BooleanExpression::Identifier(CoreIdentifier::Condition(2).into()); let condition_id_2 = BooleanExpression::Identifier(CoreIdentifier::Condition(2).into());
let s = TypedStatement::Definition( let s = TypedStatement::definition(
Variable::field_element("foo").into(), Variable::field_element("foo").into(),
FieldElementExpression::conditional( FieldElementExpression::conditional(
condition_0.clone(), condition_0.clone(),
FieldElementExpression::block( FieldElementExpression::block(
vec![TypedStatement::Definition( vec![TypedStatement::definition(
Variable::field_element("a").into(), Variable::field_element("a").into(),
FieldElementExpression::Number(Bn128Field::from(1)).into(), FieldElementExpression::Number(Bn128Field::from(1)).into(),
)], )],
@ -320,7 +320,7 @@ mod tests {
), ),
), ),
FieldElementExpression::block( FieldElementExpression::block(
vec![TypedStatement::Definition( vec![TypedStatement::definition(
Variable::field_element("b").into(), Variable::field_element("b").into(),
FieldElementExpression::Number(Bn128Field::from(2)).into(), FieldElementExpression::Number(Bn128Field::from(2)).into(),
)], )],
@ -340,22 +340,22 @@ mod tests {
let expected = vec![ let expected = vec![
// define conditions // define conditions
TypedStatement::Definition( TypedStatement::definition(
Variable::immutable(CoreIdentifier::Condition(0), Type::Boolean).into(), Variable::immutable(CoreIdentifier::Condition(0), Type::Boolean).into(),
condition_0.into(), condition_0.into(),
), ),
// rewrite statement // rewrite statement
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element("foo").into(), Variable::field_element("foo").into(),
FieldElementExpression::conditional( FieldElementExpression::conditional(
condition_id_0.clone(), condition_id_0.clone(),
FieldElementExpression::block( FieldElementExpression::block(
vec![ vec![
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element("a").into(), Variable::field_element("a").into(),
FieldElementExpression::Number(Bn128Field::from(1)).into(), FieldElementExpression::Number(Bn128Field::from(1)).into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::immutable(CoreIdentifier::Condition(1), Type::Boolean) Variable::immutable(CoreIdentifier::Condition(1), Type::Boolean)
.into(), .into(),
condition_1.into(), condition_1.into(),
@ -370,11 +370,11 @@ mod tests {
), ),
FieldElementExpression::block( FieldElementExpression::block(
vec![ vec![
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element("b").into(), Variable::field_element("b").into(),
FieldElementExpression::Number(Bn128Field::from(2)).into(), FieldElementExpression::Number(Bn128Field::from(2)).into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::immutable(CoreIdentifier::Condition(2), Type::Boolean) Variable::immutable(CoreIdentifier::Condition(2), Type::Boolean)
.into(), .into(),
condition_2.into(), condition_2.into(),

View file

@ -1,11 +1,11 @@
use std::fmt; use std::fmt;
use zokrates_ast::common::FlatEmbed; use zokrates_ast::common::FlatEmbed;
use zokrates_ast::typed::TypedProgram;
use zokrates_ast::typed::{ use zokrates_ast::typed::{
result_folder::ResultFolder, result_folder::ResultFolder,
result_folder::{fold_statement, fold_uint_expression_inner}, result_folder::{fold_statement, fold_uint_expression_inner},
Constant, EmbedCall, TypedStatement, UBitwidth, UExpressionInner, Constant, EmbedCall, TypedStatement, UBitwidth, UExpressionInner,
}; };
use zokrates_ast::typed::{DefinitionRhs, TypedProgram};
use zokrates_field::Field; use zokrates_field::Field;
pub struct ConstantArgumentChecker; pub struct ConstantArgumentChecker;
@ -33,37 +33,41 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ConstantArgumentChecker {
s: TypedStatement<'ast, T>, s: TypedStatement<'ast, T>,
) -> Result<Vec<TypedStatement<'ast, T>>, Self::Error> { ) -> Result<Vec<TypedStatement<'ast, T>>, Self::Error> {
match s { match s {
TypedStatement::EmbedCallDefinition(assignee, embed_call) => match embed_call { TypedStatement::Definition(assignee, DefinitionRhs::EmbedCall(embed_call)) => {
EmbedCall { match embed_call {
embed: FlatEmbed::BitArrayLe, EmbedCall {
.. embed: FlatEmbed::BitArrayLe,
} => { ..
let arguments = embed_call } => {
.arguments let arguments = embed_call
.into_iter() .arguments
.map(|a| self.fold_expression(a)) .into_iter()
.collect::<Result<Vec<_>, _>>()?; .map(|a| self.fold_expression(a))
.collect::<Result<Vec<_>, _>>()?;
if arguments[1].is_constant() { if arguments[1].is_constant() {
Ok(vec![TypedStatement::EmbedCallDefinition( Ok(vec![TypedStatement::Definition(
assignee, assignee,
EmbedCall { EmbedCall {
embed: FlatEmbed::BitArrayLe, embed: FlatEmbed::BitArrayLe,
generics: embed_call.generics, generics: embed_call.generics,
arguments, arguments,
}, }
)]) .into(),
} else { )])
Err(Error(format!( } else {
"Cannot compare to a variable value, found `{}`", Err(Error(format!(
arguments[1] "Cannot compare to a variable value, found `{}`",
))) arguments[1]
)))
}
} }
embed_call => Ok(vec![TypedStatement::Definition(
assignee,
embed_call.into(),
)]),
} }
embed_call => Ok(vec![TypedStatement::EmbedCallDefinition( }
assignee, embed_call,
)]),
},
s => fold_statement(self, s), s => fold_statement(self, s),
} }
} }

View file

@ -0,0 +1,68 @@
use std::collections::HashSet;
use zokrates_ast::zir::{folder::*, Identifier, ZirFunction, ZirProgram, ZirStatement};
use zokrates_field::Field;
#[derive(Default)]
pub struct DeadCodeEliminator<'ast> {
used: HashSet<Identifier<'ast>>,
}
impl<'ast> DeadCodeEliminator<'ast> {
pub fn eliminate<T: Field>(p: ZirProgram<'ast, T>) -> ZirProgram<'ast, T> {
Self::default().fold_program(p)
}
}
impl<'ast, T: Field> Folder<'ast, T> for DeadCodeEliminator<'ast> {
fn fold_function(&mut self, f: ZirFunction<'ast, T>) -> ZirFunction<'ast, T> {
// iterate on the statements starting from the end, as we want to see usage before definition
let mut statements: Vec<_> = f
.statements
.into_iter()
.rev()
.flat_map(|s| self.fold_statement(s))
.collect();
statements.reverse();
ZirFunction { statements, ..f }
}
fn fold_statement(&mut self, s: ZirStatement<'ast, T>) -> Vec<ZirStatement<'ast, T>> {
match s {
ZirStatement::Definition(v, e) => {
// if the lhs is used later in the program
if self.used.remove(&v.id) {
// include this statement
fold_statement(self, ZirStatement::Definition(v, e))
} else {
// otherwise remove it
vec![]
}
}
ZirStatement::IfElse(condition, consequence, alternative) => {
let condition = self.fold_boolean_expression(condition);
let mut consequence: Vec<_> = consequence
.into_iter()
.rev()
.flat_map(|e| self.fold_statement(e))
.collect();
consequence.reverse();
let mut alternative: Vec<_> = alternative
.into_iter()
.rev()
.flat_map(|e| self.fold_statement(e))
.collect();
alternative.reverse();
vec![ZirStatement::IfElse(condition, consequence, alternative)]
}
s => fold_statement(self, s),
}
}
fn fold_name(&mut self, n: Identifier<'ast>) -> Identifier<'ast> {
self.used.insert(n.clone());
n
}
}

View file

@ -402,7 +402,7 @@ fn fold_statement<'ast, T: Field>(
typed::TypedStatement::Return(expression) => vec![zir::ZirStatement::Return( typed::TypedStatement::Return(expression) => vec![zir::ZirStatement::Return(
f.fold_expression(statements_buffer, expression), f.fold_expression(statements_buffer, expression),
)], )],
typed::TypedStatement::Definition(a, e) => { typed::TypedStatement::Definition(a, typed::DefinitionRhs::Expression(e)) => {
let a = f.fold_assignee(a); let a = f.fold_assignee(a);
let e = f.fold_expression(statements_buffer, e); let e = f.fold_expression(statements_buffer, e);
assert_eq!(a.len(), e.len()); assert_eq!(a.len(), e.len());
@ -418,10 +418,14 @@ fn fold_statement<'ast, T: Field>(
zir::RuntimeError::SourceAssertion(metadata.to_string()) zir::RuntimeError::SourceAssertion(metadata.to_string())
} }
typed::RuntimeError::SelectRangeCheck => zir::RuntimeError::SelectRangeCheck, typed::RuntimeError::SelectRangeCheck => zir::RuntimeError::SelectRangeCheck,
typed::RuntimeError::DivisionByZero => zir::RuntimeError::DivisionByZero,
}; };
vec![zir::ZirStatement::Assertion(e, error)] vec![zir::ZirStatement::Assertion(e, error)]
} }
typed::TypedStatement::EmbedCallDefinition(assignee, embed_call) => { typed::TypedStatement::Definition(
assignee,
typed::DefinitionRhs::EmbedCall(embed_call),
) => {
vec![zir::ZirStatement::MultipleDefinition( vec![zir::ZirStatement::MultipleDefinition(
f.fold_assignee(assignee), f.fold_assignee(assignee),
zir::ZirExpressionList::EmbedCall( zir::ZirExpressionList::EmbedCall(

View file

@ -8,10 +8,12 @@ mod branch_isolator;
mod condition_redefiner; mod condition_redefiner;
mod constant_argument_checker; mod constant_argument_checker;
mod constant_resolver; mod constant_resolver;
mod dead_code;
mod flat_propagation; mod flat_propagation;
mod flatten_complex_types; mod flatten_complex_types;
mod log_ignorer; mod log_ignorer;
mod out_of_bounds; mod out_of_bounds;
mod panic_extractor;
mod propagation; mod propagation;
mod reducer; mod reducer;
mod struct_concretizer; mod struct_concretizer;
@ -32,6 +34,8 @@ use self::uint_optimizer::UintOptimizer;
use self::variable_write_remover::VariableWriteRemover; use self::variable_write_remover::VariableWriteRemover;
use crate::compile::CompileConfig; use crate::compile::CompileConfig;
use crate::static_analysis::constant_resolver::ConstantResolver; use crate::static_analysis::constant_resolver::ConstantResolver;
use crate::static_analysis::dead_code::DeadCodeEliminator;
use crate::static_analysis::panic_extractor::PanicExtractor;
use crate::static_analysis::zir_propagation::ZirPropagator; use crate::static_analysis::zir_propagation::ZirPropagator;
use std::fmt; use std::fmt;
use zokrates_ast::typed::{abi::Abi, TypedProgram}; use zokrates_ast::typed::{abi::Abi, TypedProgram};
@ -172,6 +176,14 @@ pub fn analyse<'ast, T: Field>(
let zir = ZirPropagator::propagate(zir).map_err(Error::from)?; let zir = ZirPropagator::propagate(zir).map_err(Error::from)?;
log::trace!("\n{}", zir); log::trace!("\n{}", zir);
log::debug!("Static analyser: Extract panics");
let zir = PanicExtractor::extract(zir);
log::trace!("\n{}", zir);
log::debug!("Static analyser: Remove dead code");
let zir = DeadCodeEliminator::eliminate(zir);
log::trace!("\n{}", zir);
// optimize uint expressions // optimize uint expressions
log::debug!("Static analyser: Optimize uints"); log::debug!("Static analyser: Optimize uints");
let zir = UintOptimizer::optimize(zir); let zir = UintOptimizer::optimize(zir);

View file

@ -0,0 +1,190 @@
use zokrates_ast::zir::{
folder::*, BooleanExpression, Conditional, ConditionalExpression, ConditionalOrExpression,
FieldElementExpression, RuntimeError, UBitwidth, UExpressionInner, ZirProgram, ZirStatement,
};
use zokrates_field::Field;
// a static analyser pass to extract the failure modes into separate assert statements, so that a statement can panic iff it's an assertion
#[derive(Default)]
pub struct PanicExtractor<'ast, T> {
panic_buffer: Vec<ZirStatement<'ast, T>>,
}
impl<'ast, T: Field> PanicExtractor<'ast, T> {
pub fn extract(p: ZirProgram<'ast, T>) -> ZirProgram<'ast, T> {
Self::default().fold_program(p)
}
}
impl<'ast, T: Field> Folder<'ast, T> for PanicExtractor<'ast, T> {
fn fold_statement(&mut self, s: ZirStatement<'ast, T>) -> Vec<ZirStatement<'ast, T>> {
match s {
ZirStatement::IfElse(condition, consequence, alternative) => {
let condition = self.fold_boolean_expression(condition);
let mut consequence_extractor = Self::default();
let consequence = consequence
.into_iter()
.flat_map(|s| consequence_extractor.fold_statement(s))
.collect();
assert!(consequence_extractor.panic_buffer.is_empty());
let mut alternative_extractor = Self::default();
let alternative = alternative
.into_iter()
.flat_map(|s| alternative_extractor.fold_statement(s))
.collect();
assert!(alternative_extractor.panic_buffer.is_empty());
self.panic_buffer
.drain(..)
.chain(std::iter::once(ZirStatement::IfElse(
condition,
consequence,
alternative,
)))
.collect()
}
s => {
let s = fold_statement(self, s);
self.panic_buffer.drain(..).chain(s).collect()
}
}
}
fn fold_field_expression(
&mut self,
e: FieldElementExpression<'ast, T>,
) -> FieldElementExpression<'ast, T> {
match e {
FieldElementExpression::Div(box n, box d) => {
let n = self.fold_field_expression(n);
let d = self.fold_field_expression(d);
self.panic_buffer.push(ZirStatement::Assertion(
BooleanExpression::Not(box BooleanExpression::FieldEq(
box d.clone(),
box FieldElementExpression::Number(T::zero()),
)),
RuntimeError::DivisionByZero,
));
FieldElementExpression::Div(box n, box d)
}
e => fold_field_expression(self, e),
}
}
fn fold_conditional_expression<
E: zokrates_ast::zir::Expr<'ast, T> + Fold<'ast, T> + Conditional<'ast, T>,
>(
&mut self,
_: &E::Ty,
e: ConditionalExpression<'ast, T, E>,
) -> ConditionalOrExpression<'ast, T, E> {
let condition = self.fold_boolean_expression(*e.condition);
let mut consequence_extractor = Self::default();
let consequence = e.consequence.fold(&mut consequence_extractor);
let mut alternative_extractor = Self::default();
let alternative = e.alternative.fold(&mut alternative_extractor);
let consequence_panics: Vec<_> = consequence_extractor.panic_buffer.drain(..).collect();
let alternative_panics: Vec<_> = alternative_extractor.panic_buffer.drain(..).collect();
if !(consequence_panics.is_empty() && alternative_panics.is_empty()) {
self.panic_buffer.push(ZirStatement::IfElse(
condition.clone(),
consequence_panics,
alternative_panics,
));
}
ConditionalOrExpression::Conditional(ConditionalExpression::new(
condition,
consequence,
alternative,
))
}
fn fold_uint_expression_inner(
&mut self,
b: UBitwidth,
e: UExpressionInner<'ast, T>,
) -> UExpressionInner<'ast, T> {
match e {
UExpressionInner::Div(box n, box d) => {
let n = self.fold_uint_expression(n);
let d = self.fold_uint_expression(d);
self.panic_buffer.push(ZirStatement::Assertion(
BooleanExpression::Not(box BooleanExpression::UintEq(
box d.clone(),
box UExpressionInner::Value(0).annotate(b),
)),
RuntimeError::DivisionByZero,
));
UExpressionInner::Div(box n, box d)
}
e => fold_uint_expression_inner(self, b, e),
}
}
fn fold_boolean_expression(
&mut self,
e: BooleanExpression<'ast, T>,
) -> BooleanExpression<'ast, T> {
match e {
// constant range checks are complete, so no panic needs to be extracted
e @ BooleanExpression::FieldLt(box FieldElementExpression::Number(_), _)
| e @ BooleanExpression::FieldLt(_, box FieldElementExpression::Number(_)) => {
fold_boolean_expression(self, e)
}
BooleanExpression::FieldLt(box left, box right) => {
let left = self.fold_field_expression(left);
let right = self.fold_field_expression(right);
let bit_width = T::get_required_bits();
let safe_width = bit_width - 2; // dynamic comparison is not complete, it only applies to field elements whose difference is strictly smaller than 2**(bitwidth - 2)
let offset = FieldElementExpression::Number(T::from(2).pow(safe_width));
let max = FieldElementExpression::Number(T::from(2).pow(safe_width + 1));
// `|left - right|` must be of bitwidth at most `safe_bitwidth`
// this means we need to guarantee the following: `-2**(safe_width) < left - right < 2**(safe_width)`
// adding an offset of `2**(safe_width)` we turn this into:
// require `0 < 2**(safe_width) + left - right < 2**(safe_width + 1)`
// we split this check in two:
// `2**(safe_width) + left - right < 2**(safe_width + 1)`
self.panic_buffer.push(ZirStatement::Assertion(
BooleanExpression::FieldLt(
box FieldElementExpression::Add(
box offset.clone(),
box FieldElementExpression::Sub(box left.clone(), box right.clone()),
),
box max,
),
RuntimeError::IncompleteDynamicRange,
));
// and
// `2**(safe_width) + left - right != 0`
self.panic_buffer.push(ZirStatement::Assertion(
BooleanExpression::Not(box BooleanExpression::FieldEq(
box FieldElementExpression::Sub(box right.clone(), box left.clone()),
box offset,
)),
RuntimeError::IncompleteDynamicRange,
));
// NOTE:
// instead of splitting the check in two, we could have used a single `Lt` here, by simply subtracting 1 from all sides:
// `let x = 2**(safe_width) + left - right`
// `0 <= x - 1 < 2**(safe_width + 1) - 1` which is a single constant `Lt`
// however, the *result* of `left < right` requires knowing the bits of `x`
// if we use `x - 1` here, we end up having to calculate the bits of both `x` and `x - 1`, which is expensive
// by splitting, we can reuse the bits of `x` needed for this completeness check when computing the result
BooleanExpression::FieldLt(box left, box right)
}
e => fold_boolean_expression(self, e),
}
}
}

View file

@ -221,9 +221,9 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
) -> Result<Vec<TypedStatement<'ast, T>>, Error> { ) -> Result<Vec<TypedStatement<'ast, T>>, Error> {
match s { match s {
// propagation to the defined variable if rhs is a constant // propagation to the defined variable if rhs is a constant
TypedStatement::Definition(assignee, expr) => { TypedStatement::Definition(assignee, DefinitionRhs::Expression(expr)) => {
let expr = self.fold_expression(expr)?;
let assignee = self.fold_assignee(assignee)?; let assignee = self.fold_assignee(assignee)?;
let expr = self.fold_expression(expr)?;
if let (Ok(a), Ok(e)) = ( if let (Ok(a), Ok(e)) = (
ConcreteType::try_from(assignee.get_type()), ConcreteType::try_from(assignee.get_type()),
@ -255,10 +255,10 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
// invalidate the cache for this identifier, and define the latest // invalidate the cache for this identifier, and define the latest
// version of the constant in the program, if any // version of the constant in the program, if any
Some(c) => Ok(vec![ Some(c) => Ok(vec![
TypedStatement::Definition(v.clone().into(), c), TypedStatement::Definition(v.clone().into(), c.into()),
TypedStatement::Definition(assignee, expr), TypedStatement::Definition(assignee, expr.into()),
]), ]),
None => Ok(vec![TypedStatement::Definition(assignee, expr)]), None => Ok(vec![TypedStatement::Definition(assignee, expr.into())]),
}, },
}, },
} }
@ -271,10 +271,10 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
match self.constants.remove(&v.id) { match self.constants.remove(&v.id) {
Some(c) => Ok(vec![ Some(c) => Ok(vec![
TypedStatement::Definition(v.clone().into(), c), TypedStatement::Definition(v.clone().into(), c.into()),
TypedStatement::Definition(assignee, expr), TypedStatement::Definition(assignee, expr.into()),
]), ]),
None => Ok(vec![TypedStatement::Definition(assignee, expr)]), None => Ok(vec![TypedStatement::Definition(assignee, expr.into())]),
} }
} }
} }
@ -285,7 +285,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
Ok(vec![TypedStatement::For(v, from, to, statements)]) Ok(vec![TypedStatement::For(v, from, to, statements)])
} }
TypedStatement::EmbedCallDefinition(assignee, embed_call) => { TypedStatement::Definition(assignee, DefinitionRhs::EmbedCall(embed_call)) => {
let assignee = self.fold_assignee(assignee)?; let assignee = self.fold_assignee(assignee)?;
let embed_call = self.fold_embed_call(embed_call)?; let embed_call = self.fold_embed_call(embed_call)?;
@ -299,37 +299,37 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
let argument = argument.into_canonical_constant(); let argument = argument.into_canonical_constant();
match ArrayExpression::try_from(argument) match ArrayExpression::try_from(argument)
.unwrap() .unwrap()
.into_inner() .into_inner()
{ {
ArrayExpressionInner::Value(v) => ArrayExpressionInner::Value(v) =>
UExpressionInner::Value( UExpressionInner::Value(
v.into_iter() v.into_iter()
.map(|v| match v { .map(|v| match v {
TypedExpressionOrSpread::Expression( TypedExpressionOrSpread::Expression(
TypedExpression::Boolean( TypedExpression::Boolean(
BooleanExpression::Value(v), BooleanExpression::Value(v),
), ),
) => v, ) => v,
_ => unreachable!("Should be a constant boolean expression. Spreads are not expected here, as in their presence the argument isn't constant"), _ => unreachable!("Should be a constant boolean expression. Spreads are not expected here, as in their presence the argument isn't constant"),
}) })
.enumerate() .enumerate()
.fold(0, |acc, (i, v)| { .fold(0, |acc, (i, v)| {
if v { if v {
acc + 2u128.pow( acc + 2u128.pow(
(bitwidth.to_usize() - i - 1) (bitwidth.to_usize() - i - 1)
.try_into() .try_into()
.unwrap(), .unwrap(),
) )
} else { } else {
acc acc
} }
}), }),
) )
.annotate(bitwidth) .annotate(bitwidth)
.into(), .into(),
_ => unreachable!("should be an array value"), _ => unreachable!("should be an array value"),
} }
} }
fn process_u_to_bits<'ast, T: Field>( fn process_u_to_bits<'ast, T: Field>(
@ -471,11 +471,11 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
} }
Err(v) => match self.constants.remove(&v.id) { Err(v) => match self.constants.remove(&v.id) {
Some(c) => vec![ Some(c) => vec![
TypedStatement::Definition(v.clone().into(), c), TypedStatement::Definition(v.clone().into(), c.into()),
TypedStatement::Definition(assignee, expr), TypedStatement::Definition(assignee, expr.into()),
], ],
None => { None => {
vec![TypedStatement::Definition(assignee, expr)] vec![TypedStatement::Definition(assignee, expr.into())]
} }
}, },
}, },
@ -491,11 +491,12 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
match self.constants.remove(&v.id) { match self.constants.remove(&v.id) {
Some(c) => vec![ Some(c) => vec![
TypedStatement::Definition(v.clone().into(), c), TypedStatement::Definition(v.clone().into(), c.into()),
TypedStatement::EmbedCallDefinition(assignee, embed_call), TypedStatement::Definition(assignee, embed_call.into()),
], ],
None => vec![TypedStatement::EmbedCallDefinition( None => vec![TypedStatement::Definition(
assignee, embed_call, assignee,
embed_call.into(),
)], )],
} }
} }
@ -504,7 +505,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
false => { false => {
// if the function arguments are not constant, invalidate the cache // if the function arguments are not constant, invalidate the cache
// for the return assignees // for the return assignees
let def = TypedStatement::EmbedCallDefinition(assignee.clone(), embed_call); let def = TypedStatement::Definition(assignee.clone(), embed_call.into());
let v = self let v = self
.try_get_constant_mut(&assignee) .try_get_constant_mut(&assignee)
@ -513,7 +514,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
Ok(match self.constants.remove(&v.id) { Ok(match self.constants.remove(&v.id) {
Some(c) => { Some(c) => {
vec![TypedStatement::Definition(v.clone().into(), c), def] vec![TypedStatement::Definition(v.clone().into(), c.into()), def]
} }
None => vec![def], None => vec![def],
}) })
@ -524,9 +525,10 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
let e_str = e.to_string(); let e_str = e.to_string();
let expr = self.fold_boolean_expression(e)?; let expr = self.fold_boolean_expression(e)?;
match expr { match expr {
BooleanExpression::Value(v) if !v => { BooleanExpression::Value(false) => {
Err(Error::AssertionFailed(format!("{}: ({})", ty, e_str))) Err(Error::AssertionFailed(format!("{}: ({})", ty, e_str)))
} }
BooleanExpression::Value(true) => Ok(vec![]),
_ => Ok(vec![TypedStatement::Assertion(expr, ty)]), _ => Ok(vec![TypedStatement::Assertion(expr, ty)]),
} }
} }

View file

@ -177,7 +177,7 @@ pub fn inline_call<'a, 'ast, T: Field, E: Expr<'ast, T>>(
.zip(inferred_signature.inputs.clone()) .zip(inferred_signature.inputs.clone())
.map(|(p, t)| ConcreteVariable::new(p.id.id, t, false)) .map(|(p, t)| ConcreteVariable::new(p.id.id, t, false))
.zip(arguments.clone()) .zip(arguments.clone())
.map(|(v, a)| TypedStatement::Definition(Variable::from(v).into(), a)) .map(|(v, a)| TypedStatement::definition(Variable::from(v).into(), a))
.collect(); .collect();
let (statements, mut returns): (Vec<_>, Vec<_>) = ssa_f let (statements, mut returns): (Vec<_>, Vec<_>) = ssa_f
@ -205,7 +205,7 @@ pub fn inline_call<'a, 'ast, T: Field, E: Expr<'ast, T>>(
let expression = TypedExpression::from(Variable::from(v.clone())); let expression = TypedExpression::from(Variable::from(v.clone()));
let output_binding = TypedStatement::Definition(Variable::from(v).into(), return_expression); let output_binding = TypedStatement::definition(Variable::from(v).into(), return_expression);
let pop_log = TypedStatement::PopCallLog; let pop_log = TypedStatement::PopCallLog;

View file

@ -278,7 +278,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> {
let v = var.clone().into(); let v = var.clone().into();
self.statement_buffer self.statement_buffer
.push(TypedStatement::EmbedCallDefinition( .push(TypedStatement::embed_call_definition(
v, v,
EmbedCall::new(embed, generics, arguments), EmbedCall::new(embed, generics, arguments),
)); ));
@ -352,7 +352,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> {
for index in *from..*to { for index in *from..*to {
let statements: Vec<TypedStatement<_>> = let statements: Vec<TypedStatement<_>> =
std::iter::once(TypedStatement::Definition( std::iter::once(TypedStatement::definition(
v.clone().into(), v.clone().into(),
UExpression::from(index as u32).into(), UExpression::from(index as u32).into(),
)) ))
@ -611,21 +611,21 @@ mod tests {
let main: TypedFunction<Bn128Field> = TypedFunction { let main: TypedFunction<Bn128Field> = TypedFunction {
arguments: vec![DeclarationVariable::field_element("a").into()], arguments: vec![DeclarationVariable::field_element("a").into()],
statements: vec![ statements: vec![
TypedStatement::Definition( TypedStatement::definition(
Variable::uint("n", UBitwidth::B32).into(), Variable::uint("n", UBitwidth::B32).into(),
TypedExpression::Uint(42u32.into()), TypedExpression::Uint(42u32.into()),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::uint("n", UBitwidth::B32).into(), Variable::uint("n", UBitwidth::B32).into(),
UExpressionInner::Identifier("n".into()) UExpressionInner::Identifier("n".into())
.annotate(UBitwidth::B32) .annotate(UBitwidth::B32)
.into(), .into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element("a").into(), Variable::field_element("a").into(),
FieldElementExpression::Identifier("a".into()).into(), FieldElementExpression::Identifier("a".into()).into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element("a").into(), Variable::field_element("a").into(),
FieldElementExpression::function_call( FieldElementExpression::function_call(
DeclarationFunctionKey::with_location("main", "foo").signature( DeclarationFunctionKey::with_location("main", "foo").signature(
@ -638,7 +638,7 @@ mod tests {
) )
.into(), .into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::uint("n", UBitwidth::B32).into(), Variable::uint("n", UBitwidth::B32).into(),
UExpressionInner::Identifier("n".into()) UExpressionInner::Identifier("n".into())
.annotate(UBitwidth::B32) .annotate(UBitwidth::B32)
@ -687,7 +687,7 @@ mod tests {
let expected_main = TypedFunction { let expected_main = TypedFunction {
arguments: vec![DeclarationVariable::field_element("a").into()], arguments: vec![DeclarationVariable::field_element("a").into()],
statements: vec![ statements: vec![
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element(Identifier::from("a").version(1)).into(), Variable::field_element(Identifier::from("a").version(1)).into(),
FieldElementExpression::Identifier("a".into()).into(), FieldElementExpression::Identifier("a".into()).into(),
), ),
@ -699,17 +699,17 @@ mod tests {
), ),
GGenericsAssignment::default(), GGenericsAssignment::default(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element(Identifier::from("a").version(3)).into(), Variable::field_element(Identifier::from("a").version(3)).into(),
FieldElementExpression::Identifier(Identifier::from("a").version(1)).into(), FieldElementExpression::Identifier(Identifier::from("a").version(1)).into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element(Identifier::from(CoreIdentifier::Call(0)).version(0)) Variable::field_element(Identifier::from(CoreIdentifier::Call(0)).version(0))
.into(), .into(),
FieldElementExpression::Identifier(Identifier::from("a").version(3)).into(), FieldElementExpression::Identifier(Identifier::from("a").version(3)).into(),
), ),
TypedStatement::PopCallLog, TypedStatement::PopCallLog,
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element(Identifier::from("a").version(2)).into(), Variable::field_element(Identifier::from("a").version(2)).into(),
FieldElementExpression::Identifier( FieldElementExpression::Identifier(
Identifier::from(CoreIdentifier::Call(0)).version(0), Identifier::from(CoreIdentifier::Call(0)).version(0),
@ -804,17 +804,17 @@ mod tests {
let main: TypedFunction<Bn128Field> = TypedFunction { let main: TypedFunction<Bn128Field> = TypedFunction {
arguments: vec![DeclarationVariable::field_element("a").into()], arguments: vec![DeclarationVariable::field_element("a").into()],
statements: vec![ statements: vec![
TypedStatement::Definition( TypedStatement::definition(
Variable::uint("n", UBitwidth::B32).into(), Variable::uint("n", UBitwidth::B32).into(),
TypedExpression::Uint(42u32.into()), TypedExpression::Uint(42u32.into()),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::uint("n", UBitwidth::B32).into(), Variable::uint("n", UBitwidth::B32).into(),
UExpressionInner::Identifier("n".into()) UExpressionInner::Identifier("n".into())
.annotate(UBitwidth::B32) .annotate(UBitwidth::B32)
.into(), .into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::array("b", Type::FieldElement, 1u32).into(), Variable::array("b", Type::FieldElement, 1u32).into(),
ArrayExpressionInner::Value( ArrayExpressionInner::Value(
vec![FieldElementExpression::Identifier("a".into()).into()].into(), vec![FieldElementExpression::Identifier("a".into()).into()].into(),
@ -822,7 +822,7 @@ mod tests {
.annotate(Type::FieldElement, 1u32) .annotate(Type::FieldElement, 1u32)
.into(), .into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::array("b", Type::FieldElement, 1u32).into(), Variable::array("b", Type::FieldElement, 1u32).into(),
ArrayExpression::function_call( ArrayExpression::function_call(
DeclarationFunctionKey::with_location("main", "foo") DeclarationFunctionKey::with_location("main", "foo")
@ -835,7 +835,7 @@ mod tests {
.annotate(Type::FieldElement, 1u32) .annotate(Type::FieldElement, 1u32)
.into(), .into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::uint("n", UBitwidth::B32).into(), Variable::uint("n", UBitwidth::B32).into(),
UExpressionInner::Identifier("n".into()) UExpressionInner::Identifier("n".into())
.annotate(UBitwidth::B32) .annotate(UBitwidth::B32)
@ -889,7 +889,7 @@ mod tests {
let expected_main = TypedFunction { let expected_main = TypedFunction {
arguments: vec![DeclarationVariable::field_element("a").into()], arguments: vec![DeclarationVariable::field_element("a").into()],
statements: vec![ statements: vec![
TypedStatement::Definition( TypedStatement::definition(
Variable::array("b", Type::FieldElement, 1u32).into(), Variable::array("b", Type::FieldElement, 1u32).into(),
ArrayExpressionInner::Value( ArrayExpressionInner::Value(
vec![FieldElementExpression::Identifier("a".into()).into()].into(), vec![FieldElementExpression::Identifier("a".into()).into()].into(),
@ -906,14 +906,14 @@ mod tests {
.collect(), .collect(),
), ),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::array(Identifier::from("a").version(1), Type::FieldElement, 1u32) Variable::array(Identifier::from("a").version(1), Type::FieldElement, 1u32)
.into(), .into(),
ArrayExpressionInner::Identifier("b".into()) ArrayExpressionInner::Identifier("b".into())
.annotate(Type::FieldElement, 1u32) .annotate(Type::FieldElement, 1u32)
.into(), .into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::array( Variable::array(
Identifier::from(CoreIdentifier::Call(0)).version(0), Identifier::from(CoreIdentifier::Call(0)).version(0),
Type::FieldElement, Type::FieldElement,
@ -925,7 +925,7 @@ mod tests {
.into(), .into(),
), ),
TypedStatement::PopCallLog, TypedStatement::PopCallLog,
TypedStatement::Definition( TypedStatement::definition(
Variable::array(Identifier::from("b").version(1), Type::FieldElement, 1u32) Variable::array(Identifier::from("b").version(1), Type::FieldElement, 1u32)
.into(), .into(),
ArrayExpressionInner::Identifier( ArrayExpressionInner::Identifier(
@ -1028,17 +1028,17 @@ mod tests {
let main: TypedFunction<Bn128Field> = TypedFunction { let main: TypedFunction<Bn128Field> = TypedFunction {
arguments: vec![DeclarationVariable::field_element("a").into()], arguments: vec![DeclarationVariable::field_element("a").into()],
statements: vec![ statements: vec![
TypedStatement::Definition( TypedStatement::definition(
Variable::uint("n", UBitwidth::B32).into(), Variable::uint("n", UBitwidth::B32).into(),
TypedExpression::Uint(2u32.into()), TypedExpression::Uint(2u32.into()),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::uint("n", UBitwidth::B32).into(), Variable::uint("n", UBitwidth::B32).into(),
UExpressionInner::Identifier("n".into()) UExpressionInner::Identifier("n".into())
.annotate(UBitwidth::B32) .annotate(UBitwidth::B32)
.into(), .into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::array( Variable::array(
"b", "b",
Type::FieldElement, Type::FieldElement,
@ -1055,7 +1055,7 @@ mod tests {
.annotate(Type::FieldElement, 1u32) .annotate(Type::FieldElement, 1u32)
.into(), .into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::array("b", Type::FieldElement, 1u32).into(), Variable::array("b", Type::FieldElement, 1u32).into(),
ArrayExpression::function_call( ArrayExpression::function_call(
DeclarationFunctionKey::with_location("main", "foo") DeclarationFunctionKey::with_location("main", "foo")
@ -1068,7 +1068,7 @@ mod tests {
.annotate(Type::FieldElement, 1u32) .annotate(Type::FieldElement, 1u32)
.into(), .into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::uint("n", UBitwidth::B32).into(), Variable::uint("n", UBitwidth::B32).into(),
UExpressionInner::Identifier("n".into()) UExpressionInner::Identifier("n".into())
.annotate(UBitwidth::B32) .annotate(UBitwidth::B32)
@ -1122,7 +1122,7 @@ mod tests {
let expected_main = TypedFunction { let expected_main = TypedFunction {
arguments: vec![DeclarationVariable::field_element("a").into()], arguments: vec![DeclarationVariable::field_element("a").into()],
statements: vec![ statements: vec![
TypedStatement::Definition( TypedStatement::definition(
Variable::array("b", Type::FieldElement, 1u32).into(), Variable::array("b", Type::FieldElement, 1u32).into(),
ArrayExpressionInner::Value( ArrayExpressionInner::Value(
vec![FieldElementExpression::Identifier("a".into()).into()].into(), vec![FieldElementExpression::Identifier("a".into()).into()].into(),
@ -1139,14 +1139,14 @@ mod tests {
.collect(), .collect(),
), ),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::array(Identifier::from("a").version(1), Type::FieldElement, 1u32) Variable::array(Identifier::from("a").version(1), Type::FieldElement, 1u32)
.into(), .into(),
ArrayExpressionInner::Identifier("b".into()) ArrayExpressionInner::Identifier("b".into())
.annotate(Type::FieldElement, 1u32) .annotate(Type::FieldElement, 1u32)
.into(), .into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::array( Variable::array(
Identifier::from(CoreIdentifier::Call(0)).version(0), Identifier::from(CoreIdentifier::Call(0)).version(0),
Type::FieldElement, Type::FieldElement,
@ -1158,7 +1158,7 @@ mod tests {
.into(), .into(),
), ),
TypedStatement::PopCallLog, TypedStatement::PopCallLog,
TypedStatement::Definition( TypedStatement::definition(
Variable::array(Identifier::from("b").version(1), Type::FieldElement, 1u32) Variable::array(Identifier::from("b").version(1), Type::FieldElement, 1u32)
.into(), .into(),
ArrayExpressionInner::Identifier( ArrayExpressionInner::Identifier(
@ -1254,7 +1254,7 @@ mod tests {
) )
.into()], .into()],
statements: vec![ statements: vec![
TypedStatement::Definition( TypedStatement::definition(
Variable::array( Variable::array(
"ret", "ret",
Type::FieldElement, Type::FieldElement,
@ -1333,7 +1333,7 @@ mod tests {
let main: TypedFunction<Bn128Field> = TypedFunction { let main: TypedFunction<Bn128Field> = TypedFunction {
arguments: vec![], arguments: vec![],
statements: vec![ statements: vec![
TypedStatement::Definition( TypedStatement::definition(
Variable::array("b", Type::FieldElement, 1u32).into(), Variable::array("b", Type::FieldElement, 1u32).into(),
ArrayExpression::function_call( ArrayExpression::function_call(
DeclarationFunctionKey::with_location("main", "foo") DeclarationFunctionKey::with_location("main", "foo")
@ -1485,7 +1485,7 @@ mod tests {
let main: TypedFunction<Bn128Field> = TypedFunction { let main: TypedFunction<Bn128Field> = TypedFunction {
arguments: vec![], arguments: vec![],
statements: vec![ statements: vec![
TypedStatement::Definition( TypedStatement::definition(
Variable::array("b", Type::FieldElement, 1u32).into(), Variable::array("b", Type::FieldElement, 1u32).into(),
ArrayExpression::function_call( ArrayExpression::function_call(
DeclarationFunctionKey::with_location("main", "foo") DeclarationFunctionKey::with_location("main", "foo")

View file

@ -106,7 +106,7 @@ impl<'ast, 'a> ShallowTransformer<'ast, 'a> {
.clone() .clone()
.into_iter() .into_iter()
.map(|(g, v)| { .map(|(g, v)| {
TypedStatement::Definition( TypedStatement::definition(
Variable::new(CoreIdentifier::from(g), Type::Uint(UBitwidth::B32), false) Variable::new(CoreIdentifier::from(g), Type::Uint(UBitwidth::B32), false)
.into(), .into(),
UExpression::from(v as u32).into(), UExpression::from(v as u32).into(),
@ -126,7 +126,7 @@ impl<'ast, 'a> ShallowTransformer<'ast, 'a> {
impl<'ast, 'a, T: Field> Folder<'ast, T> for ShallowTransformer<'ast, 'a> { impl<'ast, 'a, T: Field> Folder<'ast, T> for ShallowTransformer<'ast, 'a> {
fn fold_statement(&mut self, s: TypedStatement<'ast, T>) -> Vec<TypedStatement<'ast, T>> { fn fold_statement(&mut self, s: TypedStatement<'ast, T>) -> Vec<TypedStatement<'ast, T>> {
match s { match s {
TypedStatement::Definition(a, e) => { TypedStatement::Definition(a, DefinitionRhs::Expression(e)) => {
let e = self.fold_expression(e); let e = self.fold_expression(e);
let a = match a { let a = match a {
@ -137,9 +137,9 @@ impl<'ast, 'a, T: Field> Folder<'ast, T> for ShallowTransformer<'ast, 'a> {
a => fold_assignee(self, a), a => fold_assignee(self, a),
}; };
vec![TypedStatement::Definition(a, e)] vec![TypedStatement::definition(a, e)]
} }
TypedStatement::EmbedCallDefinition(assignee, embed_call) => { TypedStatement::Definition(assignee, DefinitionRhs::EmbedCall(embed_call)) => {
let assignee = match assignee { let assignee = match assignee {
TypedAssignee::Identifier(v) => { TypedAssignee::Identifier(v) => {
let v = self.issue_next_ssa_variable(v); let v = self.issue_next_ssa_variable(v);
@ -148,7 +148,7 @@ impl<'ast, 'a, T: Field> Folder<'ast, T> for ShallowTransformer<'ast, 'a> {
a => fold_assignee(self, a), a => fold_assignee(self, a),
}; };
let embed_call = self.fold_embed_call(embed_call); let embed_call = self.fold_embed_call(embed_call);
vec![TypedStatement::EmbedCallDefinition(assignee, embed_call)] vec![TypedStatement::embed_call_definition(assignee, embed_call)]
} }
TypedStatement::For(v, from, to, stats) => { TypedStatement::For(v, from, to, stats) => {
let from = self.fold_uint_expression(from); let from = self.fold_uint_expression(from);
@ -236,13 +236,13 @@ mod tests {
let mut u = ShallowTransformer::with_versions(&mut versions); let mut u = ShallowTransformer::with_versions(&mut versions);
let s = TypedStatement::Definition( let s = TypedStatement::definition(
TypedAssignee::Identifier(Variable::field_element("a")), TypedAssignee::Identifier(Variable::field_element("a")),
FieldElementExpression::Number(Bn128Field::from(5)).into(), FieldElementExpression::Number(Bn128Field::from(5)).into(),
); );
assert_eq!( assert_eq!(
u.fold_statement(s), u.fold_statement(s),
vec![TypedStatement::Definition( vec![TypedStatement::definition(
TypedAssignee::Identifier(Variable::field_element( TypedAssignee::Identifier(Variable::field_element(
Identifier::from("a").version(0) Identifier::from("a").version(0)
)), )),
@ -250,13 +250,13 @@ mod tests {
)] )]
); );
let s = TypedStatement::Definition( let s = TypedStatement::definition(
TypedAssignee::Identifier(Variable::field_element("a")), TypedAssignee::Identifier(Variable::field_element("a")),
FieldElementExpression::Number(Bn128Field::from(6)).into(), FieldElementExpression::Number(Bn128Field::from(6)).into(),
); );
assert_eq!( assert_eq!(
u.fold_statement(s), u.fold_statement(s),
vec![TypedStatement::Definition( vec![TypedStatement::definition(
TypedAssignee::Identifier(Variable::field_element( TypedAssignee::Identifier(Variable::field_element(
Identifier::from("a").version(1) Identifier::from("a").version(1)
)), )),
@ -286,13 +286,13 @@ mod tests {
let mut u = ShallowTransformer::with_versions(&mut versions); let mut u = ShallowTransformer::with_versions(&mut versions);
let s = TypedStatement::Definition( let s = TypedStatement::definition(
TypedAssignee::Identifier(Variable::field_element("a")), TypedAssignee::Identifier(Variable::field_element("a")),
FieldElementExpression::Number(Bn128Field::from(5)).into(), FieldElementExpression::Number(Bn128Field::from(5)).into(),
); );
assert_eq!( assert_eq!(
u.fold_statement(s), u.fold_statement(s),
vec![TypedStatement::Definition( vec![TypedStatement::definition(
TypedAssignee::Identifier(Variable::field_element( TypedAssignee::Identifier(Variable::field_element(
Identifier::from("a").version(0) Identifier::from("a").version(0)
)), )),
@ -300,7 +300,7 @@ mod tests {
)] )]
); );
let s = TypedStatement::Definition( let s = TypedStatement::definition(
TypedAssignee::Identifier(Variable::field_element("a")), TypedAssignee::Identifier(Variable::field_element("a")),
FieldElementExpression::Add( FieldElementExpression::Add(
box FieldElementExpression::Identifier("a".into()), box FieldElementExpression::Identifier("a".into()),
@ -310,7 +310,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
u.fold_statement(s), u.fold_statement(s),
vec![TypedStatement::Definition( vec![TypedStatement::definition(
TypedAssignee::Identifier(Variable::field_element( TypedAssignee::Identifier(Variable::field_element(
Identifier::from("a").version(1) Identifier::from("a").version(1)
)), )),
@ -337,13 +337,13 @@ mod tests {
let mut u = ShallowTransformer::with_versions(&mut versions); let mut u = ShallowTransformer::with_versions(&mut versions);
let s = TypedStatement::Definition( let s = TypedStatement::definition(
TypedAssignee::Identifier(Variable::field_element("a")), TypedAssignee::Identifier(Variable::field_element("a")),
FieldElementExpression::Number(Bn128Field::from(2)).into(), FieldElementExpression::Number(Bn128Field::from(2)).into(),
); );
assert_eq!( assert_eq!(
u.fold_statement(s), u.fold_statement(s),
vec![TypedStatement::Definition( vec![TypedStatement::definition(
TypedAssignee::Identifier(Variable::field_element( TypedAssignee::Identifier(Variable::field_element(
Identifier::from("a").version(0) Identifier::from("a").version(0)
)), )),
@ -351,7 +351,7 @@ mod tests {
)] )]
); );
let s: TypedStatement<Bn128Field> = TypedStatement::Definition( let s: TypedStatement<Bn128Field> = TypedStatement::definition(
Variable::field_element("a").into(), Variable::field_element("a").into(),
FieldElementExpression::function_call( FieldElementExpression::function_call(
DeclarationFunctionKey::with_location("main", "foo").signature( DeclarationFunctionKey::with_location("main", "foo").signature(
@ -366,7 +366,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
u.fold_statement(s), u.fold_statement(s),
vec![TypedStatement::Definition( vec![TypedStatement::definition(
Variable::field_element(Identifier::from("a").version(1)).into(), Variable::field_element(Identifier::from("a").version(1)).into(),
FieldElementExpression::function_call( FieldElementExpression::function_call(
DeclarationFunctionKey::with_location("main", "foo").signature( DeclarationFunctionKey::with_location("main", "foo").signature(
@ -398,7 +398,7 @@ mod tests {
let mut u = ShallowTransformer::with_versions(&mut versions); let mut u = ShallowTransformer::with_versions(&mut versions);
let s = TypedStatement::Definition( let s = TypedStatement::definition(
TypedAssignee::Identifier(Variable::array("a", Type::FieldElement, 2u32)), TypedAssignee::Identifier(Variable::array("a", Type::FieldElement, 2u32)),
ArrayExpressionInner::Value( ArrayExpressionInner::Value(
vec![ vec![
@ -413,7 +413,7 @@ mod tests {
assert_eq!( assert_eq!(
u.fold_statement(s), u.fold_statement(s),
vec![TypedStatement::Definition( vec![TypedStatement::definition(
TypedAssignee::Identifier(Variable::array( TypedAssignee::Identifier(Variable::array(
Identifier::from("a").version(0), Identifier::from("a").version(0),
Type::FieldElement, Type::FieldElement,
@ -431,7 +431,7 @@ mod tests {
)] )]
); );
let s: TypedStatement<Bn128Field> = TypedStatement::Definition( let s: TypedStatement<Bn128Field> = TypedStatement::definition(
TypedAssignee::Select( TypedAssignee::Select(
box TypedAssignee::Identifier(Variable::array("a", Type::FieldElement, 2u32)), box TypedAssignee::Identifier(Variable::array("a", Type::FieldElement, 2u32)),
box UExpression::from(1u32), box UExpression::from(1u32),
@ -457,7 +457,7 @@ mod tests {
let array_of_array_ty = Type::array((Type::array((Type::FieldElement, 2u32)), 2u32)); let array_of_array_ty = Type::array((Type::array((Type::FieldElement, 2u32)), 2u32));
let s = TypedStatement::Definition( let s = TypedStatement::definition(
TypedAssignee::Identifier(Variable::new("a", array_of_array_ty.clone(), true)), TypedAssignee::Identifier(Variable::new("a", array_of_array_ty.clone(), true)),
ArrayExpressionInner::Value( ArrayExpressionInner::Value(
vec![ vec![
@ -488,7 +488,7 @@ mod tests {
assert_eq!( assert_eq!(
u.fold_statement(s), u.fold_statement(s),
vec![TypedStatement::Definition( vec![TypedStatement::definition(
TypedAssignee::Identifier(Variable::new( TypedAssignee::Identifier(Variable::new(
Identifier::from("a").version(0), Identifier::from("a").version(0),
array_of_array_ty.clone(), array_of_array_ty.clone(),
@ -522,7 +522,7 @@ mod tests {
)] )]
); );
let s: TypedStatement<Bn128Field> = TypedStatement::Definition( let s: TypedStatement<Bn128Field> = TypedStatement::definition(
TypedAssignee::Select( TypedAssignee::Select(
box TypedAssignee::Identifier(Variable::new( box TypedAssignee::Identifier(Variable::new(
"a", "a",
@ -588,17 +588,17 @@ mod tests {
let f: TypedFunction<Bn128Field> = TypedFunction { let f: TypedFunction<Bn128Field> = TypedFunction {
arguments: vec![DeclarationVariable::field_element("a").into()], arguments: vec![DeclarationVariable::field_element("a").into()],
statements: vec![ statements: vec![
TypedStatement::Definition( TypedStatement::definition(
Variable::uint("n", UBitwidth::B32).into(), Variable::uint("n", UBitwidth::B32).into(),
TypedExpression::Uint(42u32.into()), TypedExpression::Uint(42u32.into()),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::uint("n", UBitwidth::B32).into(), Variable::uint("n", UBitwidth::B32).into(),
UExpressionInner::Identifier("n".into()) UExpressionInner::Identifier("n".into())
.annotate(UBitwidth::B32) .annotate(UBitwidth::B32)
.into(), .into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element("a").into(), Variable::field_element("a").into(),
FieldElementExpression::Identifier("a".into()).into(), FieldElementExpression::Identifier("a".into()).into(),
), ),
@ -607,12 +607,12 @@ mod tests {
UExpressionInner::Identifier("n".into()).annotate(UBitwidth::B32), UExpressionInner::Identifier("n".into()).annotate(UBitwidth::B32),
UExpressionInner::Identifier("n".into()).annotate(UBitwidth::B32) UExpressionInner::Identifier("n".into()).annotate(UBitwidth::B32)
* UExpressionInner::Identifier("n".into()).annotate(UBitwidth::B32), * UExpressionInner::Identifier("n".into()).annotate(UBitwidth::B32),
vec![TypedStatement::Definition( vec![TypedStatement::definition(
Variable::field_element("a").into(), Variable::field_element("a").into(),
FieldElementExpression::Identifier("a".into()).into(), FieldElementExpression::Identifier("a".into()).into(),
)], )],
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element("a").into(), Variable::field_element("a").into(),
FieldElementExpression::Identifier("a".into()).into(), FieldElementExpression::Identifier("a".into()).into(),
), ),
@ -621,12 +621,12 @@ mod tests {
UExpressionInner::Identifier("n".into()).annotate(UBitwidth::B32), UExpressionInner::Identifier("n".into()).annotate(UBitwidth::B32),
UExpressionInner::Identifier("n".into()).annotate(UBitwidth::B32) UExpressionInner::Identifier("n".into()).annotate(UBitwidth::B32)
* UExpressionInner::Identifier("n".into()).annotate(UBitwidth::B32), * UExpressionInner::Identifier("n".into()).annotate(UBitwidth::B32),
vec![TypedStatement::Definition( vec![TypedStatement::definition(
Variable::field_element("a").into(), Variable::field_element("a").into(),
FieldElementExpression::Identifier("a".into()).into(), FieldElementExpression::Identifier("a".into()).into(),
)], )],
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element("a").into(), Variable::field_element("a").into(),
FieldElementExpression::Identifier("a".into()).into(), FieldElementExpression::Identifier("a".into()).into(),
), ),
@ -655,21 +655,21 @@ mod tests {
let expected = TypedFunction { let expected = TypedFunction {
arguments: vec![DeclarationVariable::field_element("a").into()], arguments: vec![DeclarationVariable::field_element("a").into()],
statements: vec![ statements: vec![
TypedStatement::Definition( TypedStatement::definition(
Variable::uint("K", UBitwidth::B32).into(), Variable::uint("K", UBitwidth::B32).into(),
TypedExpression::Uint(1u32.into()), TypedExpression::Uint(1u32.into()),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::uint("n", UBitwidth::B32).into(), Variable::uint("n", UBitwidth::B32).into(),
TypedExpression::Uint(42u32.into()), TypedExpression::Uint(42u32.into()),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::uint(Identifier::from("n").version(1), UBitwidth::B32).into(), Variable::uint(Identifier::from("n").version(1), UBitwidth::B32).into(),
UExpressionInner::Identifier("n".into()) UExpressionInner::Identifier("n".into())
.annotate(UBitwidth::B32) .annotate(UBitwidth::B32)
.into(), .into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element(Identifier::from("a").version(1)).into(), Variable::field_element(Identifier::from("a").version(1)).into(),
FieldElementExpression::Identifier("a".into()).into(), FieldElementExpression::Identifier("a".into()).into(),
), ),
@ -681,12 +681,12 @@ mod tests {
.annotate(UBitwidth::B32) .annotate(UBitwidth::B32)
* UExpressionInner::Identifier(Identifier::from("n").version(1)) * UExpressionInner::Identifier(Identifier::from("n").version(1))
.annotate(UBitwidth::B32), .annotate(UBitwidth::B32),
vec![TypedStatement::Definition( vec![TypedStatement::definition(
Variable::field_element("a").into(), Variable::field_element("a").into(),
FieldElementExpression::Identifier("a".into()).into(), FieldElementExpression::Identifier("a".into()).into(),
)], )],
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element(Identifier::from("a").version(3)).into(), Variable::field_element(Identifier::from("a").version(3)).into(),
FieldElementExpression::Identifier(Identifier::from("a").version(2)).into(), FieldElementExpression::Identifier(Identifier::from("a").version(2)).into(),
), ),
@ -698,12 +698,12 @@ mod tests {
.annotate(UBitwidth::B32) .annotate(UBitwidth::B32)
* UExpressionInner::Identifier(Identifier::from("n").version(2)) * UExpressionInner::Identifier(Identifier::from("n").version(2))
.annotate(UBitwidth::B32), .annotate(UBitwidth::B32),
vec![TypedStatement::Definition( vec![TypedStatement::definition(
Variable::field_element("a").into(), Variable::field_element("a").into(),
FieldElementExpression::Identifier("a".into()).into(), FieldElementExpression::Identifier("a".into()).into(),
)], )],
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element(Identifier::from("a").version(5)).into(), Variable::field_element(Identifier::from("a").version(5)).into(),
FieldElementExpression::Identifier(Identifier::from("a").version(4)).into(), FieldElementExpression::Identifier(Identifier::from("a").version(4)).into(),
), ),
@ -766,11 +766,11 @@ mod tests {
let f: TypedFunction<Bn128Field> = TypedFunction { let f: TypedFunction<Bn128Field> = TypedFunction {
arguments: vec![DeclarationVariable::field_element("a").into()], arguments: vec![DeclarationVariable::field_element("a").into()],
statements: vec![ statements: vec![
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element("a").into(), Variable::field_element("a").into(),
TypedExpression::Uint(42u32.into()), TypedExpression::Uint(42u32.into()),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::boolean("a").into(), Variable::boolean("a").into(),
BooleanExpression::Value(true).into(), BooleanExpression::Value(true).into(),
), ),
@ -788,11 +788,11 @@ mod tests {
let expected: TypedFunction<Bn128Field> = TypedFunction { let expected: TypedFunction<Bn128Field> = TypedFunction {
arguments: vec![DeclarationVariable::field_element("a").into()], arguments: vec![DeclarationVariable::field_element("a").into()],
statements: vec![ statements: vec![
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element(Identifier::from("a").version(1)).into(), Variable::field_element(Identifier::from("a").version(1)).into(),
TypedExpression::Uint(42u32.into()), TypedExpression::Uint(42u32.into()),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::boolean(Identifier::from("a").version(2)).into(), Variable::boolean(Identifier::from("a").version(2)).into(),
BooleanExpression::Value(true).into(), BooleanExpression::Value(true).into(),
), ),
@ -844,11 +844,11 @@ mod tests {
0u32.into(), 0u32.into(),
1u32.into(), 1u32.into(),
vec![ vec![
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element(Identifier::from("a")).into(), Variable::field_element(Identifier::from("a")).into(),
FieldElementExpression::Identifier("a".into()).into(), FieldElementExpression::Identifier("a".into()).into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element(Identifier::from("a")).into(), Variable::field_element(Identifier::from("a")).into(),
FieldElementExpression::Number(42usize.into()).into(), FieldElementExpression::Number(42usize.into()).into(),
), ),
@ -877,11 +877,11 @@ mod tests {
0u32.into(), 0u32.into(),
1u32.into(), 1u32.into(),
vec![ vec![
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element(Identifier::from("a")).into(), Variable::field_element(Identifier::from("a")).into(),
FieldElementExpression::Identifier(Identifier::from("a")).into(), FieldElementExpression::Identifier(Identifier::from("a")).into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element(Identifier::from("a")).into(), Variable::field_element(Identifier::from("a")).into(),
FieldElementExpression::Number(42usize.into()).into(), FieldElementExpression::Number(42usize.into()).into(),
), ),
@ -945,21 +945,21 @@ mod tests {
let f: TypedFunction<Bn128Field> = TypedFunction { let f: TypedFunction<Bn128Field> = TypedFunction {
arguments: vec![DeclarationVariable::field_element("a").into()], arguments: vec![DeclarationVariable::field_element("a").into()],
statements: vec![ statements: vec![
TypedStatement::Definition( TypedStatement::definition(
Variable::uint("n", UBitwidth::B32).into(), Variable::uint("n", UBitwidth::B32).into(),
TypedExpression::Uint(42u32.into()), TypedExpression::Uint(42u32.into()),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::uint("n", UBitwidth::B32).into(), Variable::uint("n", UBitwidth::B32).into(),
UExpressionInner::Identifier("n".into()) UExpressionInner::Identifier("n".into())
.annotate(UBitwidth::B32) .annotate(UBitwidth::B32)
.into(), .into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element("a").into(), Variable::field_element("a").into(),
FieldElementExpression::Identifier("a".into()).into(), FieldElementExpression::Identifier("a".into()).into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element("a").into(), Variable::field_element("a").into(),
FieldElementExpression::function_call( FieldElementExpression::function_call(
DeclarationFunctionKey::with_location("main", "foo"), DeclarationFunctionKey::with_location("main", "foo"),
@ -970,13 +970,13 @@ mod tests {
) )
.into(), .into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::uint("n", UBitwidth::B32).into(), Variable::uint("n", UBitwidth::B32).into(),
UExpressionInner::Identifier("n".into()) UExpressionInner::Identifier("n".into())
.annotate(UBitwidth::B32) .annotate(UBitwidth::B32)
.into(), .into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element("a").into(), Variable::field_element("a").into(),
(FieldElementExpression::Identifier("a".into()) (FieldElementExpression::Identifier("a".into())
* FieldElementExpression::function_call( * FieldElementExpression::function_call(
@ -1014,25 +1014,25 @@ mod tests {
let expected = TypedFunction { let expected = TypedFunction {
arguments: vec![DeclarationVariable::field_element("a").into()], arguments: vec![DeclarationVariable::field_element("a").into()],
statements: vec![ statements: vec![
TypedStatement::Definition( TypedStatement::definition(
Variable::uint("K", UBitwidth::B32).into(), Variable::uint("K", UBitwidth::B32).into(),
TypedExpression::Uint(1u32.into()), TypedExpression::Uint(1u32.into()),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::uint("n", UBitwidth::B32).into(), Variable::uint("n", UBitwidth::B32).into(),
TypedExpression::Uint(42u32.into()), TypedExpression::Uint(42u32.into()),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::uint(Identifier::from("n").version(1), UBitwidth::B32).into(), Variable::uint(Identifier::from("n").version(1), UBitwidth::B32).into(),
UExpressionInner::Identifier("n".into()) UExpressionInner::Identifier("n".into())
.annotate(UBitwidth::B32) .annotate(UBitwidth::B32)
.into(), .into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element(Identifier::from("a").version(1)).into(), Variable::field_element(Identifier::from("a").version(1)).into(),
FieldElementExpression::Identifier("a".into()).into(), FieldElementExpression::Identifier("a".into()).into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element(Identifier::from("a").version(2)).into(), Variable::field_element(Identifier::from("a").version(2)).into(),
FieldElementExpression::function_call( FieldElementExpression::function_call(
DeclarationFunctionKey::with_location("main", "foo"), DeclarationFunctionKey::with_location("main", "foo"),
@ -1047,13 +1047,13 @@ mod tests {
) )
.into(), .into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::uint(Identifier::from("n").version(2), UBitwidth::B32).into(), Variable::uint(Identifier::from("n").version(2), UBitwidth::B32).into(),
UExpressionInner::Identifier(Identifier::from("n").version(1)) UExpressionInner::Identifier(Identifier::from("n").version(1))
.annotate(UBitwidth::B32) .annotate(UBitwidth::B32)
.into(), .into(),
), ),
TypedStatement::Definition( TypedStatement::definition(
Variable::field_element(Identifier::from("a").version(3)).into(), Variable::field_element(Identifier::from("a").version(3)).into(),
(FieldElementExpression::Identifier(Identifier::from("a").version(2)) (FieldElementExpression::Identifier(Identifier::from("a").version(2))
* FieldElementExpression::function_call( * FieldElementExpression::function_call(

View file

@ -457,11 +457,11 @@ fn is_constant<T>(assignee: &TypedAssignee<T>) -> bool {
impl<'ast, T: Field> Folder<'ast, T> for VariableWriteRemover { impl<'ast, T: Field> Folder<'ast, T> for VariableWriteRemover {
fn fold_statement(&mut self, s: TypedStatement<'ast, T>) -> Vec<TypedStatement<'ast, T>> { fn fold_statement(&mut self, s: TypedStatement<'ast, T>) -> Vec<TypedStatement<'ast, T>> {
match s { match s {
TypedStatement::Definition(assignee, expr) => { TypedStatement::Definition(assignee, DefinitionRhs::Expression(expr)) => {
let expr = self.fold_expression(expr); let expr = self.fold_expression(expr);
if is_constant(&assignee) { if is_constant(&assignee) {
vec![TypedStatement::Definition(assignee, expr)] vec![TypedStatement::definition(assignee, expr)]
} else { } else {
// Note: here we redefine the whole object, ideally we would only redefine some of it // Note: here we redefine the whole object, ideally we would only redefine some of it
// Example: `a[0][i] = 42` we redefine `a` but we could redefine just `a[0]` // Example: `a[0][i] = 42` we redefine `a` but we could redefine just `a[0]`
@ -511,7 +511,7 @@ impl<'ast, T: Field> Folder<'ast, T> for VariableWriteRemover {
range_checks range_checks
.into_iter() .into_iter()
.chain(std::iter::once(TypedStatement::Definition( .chain(std::iter::once(TypedStatement::definition(
TypedAssignee::Identifier(variable), TypedAssignee::Identifier(variable),
e, e,
))) )))

View file

@ -1,18 +1,10 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt; use std::fmt;
use zokrates_ast::zir::result_folder::fold_boolean_expression;
use zokrates_ast::zir::result_folder::fold_field_expression;
use zokrates_ast::zir::result_folder::fold_statement;
use zokrates_ast::zir::result_folder::fold_uint_expression_inner;
use zokrates_ast::zir::result_folder::ResultFold;
use zokrates_ast::zir::result_folder::ResultFolder;
use zokrates_ast::zir::types::UBitwidth; use zokrates_ast::zir::types::UBitwidth;
use zokrates_ast::zir::Conditional; use zokrates_ast::zir::{
use zokrates_ast::zir::ConditionalExpression; result_folder::*, Conditional, ConditionalExpression, ConditionalOrExpression, Expr,
use zokrates_ast::zir::ConditionalOrExpression; SelectExpression, SelectOrExpression,
use zokrates_ast::zir::Expr; };
use zokrates_ast::zir::SelectExpression;
use zokrates_ast::zir::SelectOrExpression;
use zokrates_ast::zir::{ use zokrates_ast::zir::{
BooleanExpression, FieldElementExpression, Identifier, RuntimeError, UExpression, BooleanExpression, FieldElementExpression, Identifier, RuntimeError, UExpression,
UExpressionInner, ZirExpression, ZirProgram, ZirStatement, UExpressionInner, ZirExpression, ZirProgram, ZirStatement,
@ -667,6 +659,7 @@ mod tests {
#[cfg(test)] #[cfg(test)]
mod field { mod field {
use zokrates_ast::zir::Conditional;
use zokrates_ast::zir::Select; use zokrates_ast::zir::Select;
use super::*; use super::*;
@ -868,6 +861,7 @@ mod tests {
#[cfg(test)] #[cfg(test)]
mod bool { mod bool {
use zokrates_ast::zir::Conditional;
use zokrates_ast::zir::Select; use zokrates_ast::zir::Select;
use super::*; use super::*;
@ -1174,6 +1168,8 @@ mod tests {
#[cfg(test)] #[cfg(test)]
mod uint { mod uint {
use zokrates_ast::zir::Conditional;
use super::*; use super::*;
#[test] #[test]

View file

@ -0,0 +1,65 @@
{
"entry_point": "./tests/tests/div.zok",
"max_constraint_count": 3,
"curves": ["Bn128", "Bls12_381", "Bls12_377", "Bw6_761"],
"tests": [
{
"input": {
"values": ["0", "0"]
},
"output": {
"Err": {
"UnsatisfiedConstraint": {
"left": "4",
"right": "2",
"error": "Inverse"
}
}
}
},
{
"input": {
"values": ["1", "0"]
},
"output": {
"Err": {
"UnsatisfiedConstraint": {
"left": "4",
"right": "2",
"error": "Inverse"
}
}
}
},
{
"input": {
"values": ["0", "1"]
},
"output": {
"Ok": {
"value": "0"
}
}
},
{
"input": {
"values": ["2", "2"]
},
"output": {
"Ok": {
"value": "1"
}
}
},
{
"input": {
"values": ["4", "2"]
},
"output": {
"Ok": {
"value": "2"
}
}
}
]
}

View file

@ -0,0 +1,3 @@
def main(field x, field y) -> field {
return x / y;
}

View file

@ -0,0 +1,4 @@
{
"entry_point": "./tests/tests/no_return.zok",
"tests": []
}

View file

@ -0,0 +1,9 @@
def foo() {
return;
}
def bar() {
return foo();
}
def main() {}

View file

@ -1,15 +1,15 @@
{ {
"entry_point": "./tests/tests/shadowing.zok", "entry_point": "./tests/tests/shadowing.zok",
"tests": [ "tests": [
{ {
"input": { "input": {
"values": [] "values": []
}, },
"output": { "output": {
"Ok": { "Ok": {
"value": ["2", "84"] "value": ["2", "84"]
}
}
} }
] }
}
]
} }

View file

@ -76,10 +76,7 @@ impl Evm {
pub fn create_account(&mut self, address: &Address, balance: impl Into<U256>) { pub fn create_account(&mut self, address: &Address, balance: impl Into<U256>) {
let acc = AccountInfo::from_balance(balance.into()); let acc = AccountInfo::from_balance(balance.into());
self.vm self.vm.db().unwrap().insert_cache(*address.as_ref(), acc);
.db()
.unwrap()
.insert_account_info(*address.as_ref(), acc);
} }
pub fn set_account_balance( pub fn set_account_balance(
@ -89,10 +86,7 @@ impl Evm {
) -> Result<(), Error> { ) -> Result<(), Error> {
let mut acc = self.vm.db().unwrap().basic(*address.as_ref()); let mut acc = self.vm.db().unwrap().basic(*address.as_ref());
acc.balance = balance.into(); acc.balance = balance.into();
self.vm self.vm.db().unwrap().insert_cache(*address.as_ref(), acc);
.db()
.unwrap()
.insert_account_info(*address.as_ref(), acc);
Ok(()) Ok(())
} }