merge dev
This commit is contained in:
commit
0d0d9e04a3
70 changed files with 1122 additions and 836 deletions
|
@ -305,4 +305,4 @@ workflows:
|
|||
- wasm_test
|
||||
- integration_test
|
||||
- zokrates_js_build
|
||||
- zokrates_js_test
|
||||
- zokrates_js_test
|
||||
|
|
363
Cargo.lock
generated
363
Cargo.lock
generated
|
@ -4,9 +4,9 @@ version = 3
|
|||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.15.2"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7a2e47a1fbe209ee101dd6d61285226744c6c8d3c21c8dc878ba6cb9f467f3a"
|
||||
checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
|||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.7.4"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98"
|
||||
checksum = "991984e3fd003e7ba02eb724f87a0f997b78677c46c0e91f8424ad7394c9886a"
|
||||
dependencies = [
|
||||
"getrandom 0.2.3",
|
||||
"once_cell",
|
||||
|
@ -145,8 +145,8 @@ version = "0.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e8cb28c2137af1ef058aa59616db3f7df67dbb70bf2be4ee6920008cc30d98c"
|
||||
dependencies = [
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.73",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -155,10 +155,10 @@ version = "0.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b9c256a93a10ed9708c16a517d6dcfaba3d215c0d7fab44d29a9affefb5eeb8"
|
||||
dependencies = [
|
||||
"num-bigint 0.4.0",
|
||||
"num-bigint 0.4.2",
|
||||
"num-traits 0.2.14",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.73",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -208,7 +208,7 @@ dependencies = [
|
|||
"ark-relations",
|
||||
"ark-std",
|
||||
"derivative",
|
||||
"num-bigint 0.4.0",
|
||||
"num-bigint 0.4.2",
|
||||
"num-integer",
|
||||
"num-traits 0.2.14",
|
||||
"tracing",
|
||||
|
@ -254,7 +254,7 @@ dependencies = [
|
|||
"ark-relations",
|
||||
"ark-std",
|
||||
"derivative",
|
||||
"num-bigint 0.4.0",
|
||||
"num-bigint 0.4.2",
|
||||
"num-traits 0.2.14",
|
||||
"tracing",
|
||||
]
|
||||
|
@ -286,9 +286,9 @@ version = "0.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ac3d78c750b01f5df5b2e76d106ed31487a93b3868f14a7f0eb3a74f45e1d8a"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.27",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.73",
|
||||
"proc-macro2 1.0.29",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -354,9 +354,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
|||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.60"
|
||||
version = "0.3.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7815ea54e4d821e791162e078acbebfd6d8c8939cd559c9335dceb1c8ca7282"
|
||||
checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
|
@ -403,15 +403,15 @@ checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
|
|||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "blake2"
|
||||
version = "0.9.1"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10a5720225ef5daecf08657f23791354e1685a8c91a4c60c7f3d3b2892f978f4"
|
||||
checksum = "0a4e37d16930f5459780f5621038b6382b9bb37c19016f39fb6b5808d831f174"
|
||||
dependencies = [
|
||||
"crypto-mac",
|
||||
"digest 0.9.0",
|
||||
|
@ -461,9 +461,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "0.2.16"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279"
|
||||
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"memchr",
|
||||
|
@ -473,9 +473,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.7.0"
|
||||
version = "3.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631"
|
||||
checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538"
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
|
@ -497,9 +497,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
|||
|
||||
[[package]]
|
||||
name = "cargo-platform"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0226944a63d1bf35a3b5f948dd7c59e263db83695c9e8bffc4037de02e30f1d7"
|
||||
checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
@ -519,9 +519,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.68"
|
||||
version = "1.0.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787"
|
||||
checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
]
|
||||
|
@ -575,11 +575,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "console_error_panic_hook"
|
||||
version = "0.1.6"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
|
||||
checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
|
@ -591,9 +591,9 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
|||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.1.5"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef"
|
||||
checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
@ -624,9 +624,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.7.3"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
|
||||
checksum = "c20ff29ded3204c5106278a81a38f4b482636ed4fa1e6cfbeef193291beb29ed"
|
||||
dependencies = [
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
|
@ -710,12 +710,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.1.20"
|
||||
version = "0.1.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e98e2ad1a782e33928b96fc3948e7c355e5af34ba4de7670fe8bac2a3b2006d"
|
||||
checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa"
|
||||
dependencies = [
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.73",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -724,9 +724,9 @@ version = "2.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.27",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.73",
|
||||
"proc-macro2 1.0.29",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -838,9 +838,9 @@ version = "0.1.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.27",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.73",
|
||||
"proc-macro2 1.0.29",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
@ -882,9 +882,9 @@ dependencies = [
|
|||
"num-bigint 0.2.6",
|
||||
"num-integer",
|
||||
"num-traits 0.2.14",
|
||||
"proc-macro2 1.0.27",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.73",
|
||||
"proc-macro2 1.0.29",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -921,9 +921,9 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
|||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.15"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27"
|
||||
checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
@ -936,9 +936,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.15"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2"
|
||||
checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
|
@ -946,15 +946,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.15"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1"
|
||||
checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.15"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "badaa6a909fac9e7236d0620a2f57f7664640c56575b71a7552fbd68deafab79"
|
||||
checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
|
@ -964,27 +964,27 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.15"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1"
|
||||
checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377"
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.15"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282"
|
||||
checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.15"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae"
|
||||
checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.15"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967"
|
||||
checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"futures-channel",
|
||||
|
@ -1043,15 +1043,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e4075386626662786ddb0ec9081e7c7eeb1ba31951f447ca780ef9f5d568189"
|
||||
checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7"
|
||||
|
||||
[[package]]
|
||||
name = "git2"
|
||||
version = "0.13.20"
|
||||
version = "0.13.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9831e983241f8c5591ed53f17d874833e2fa82cac2625f3888c50cbfe136cba"
|
||||
checksum = "2a8057932925d3a9d9e4434ea016570d37420ddb1ceed45a174d577f24ed6700"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
|
@ -1126,24 +1126,24 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.7"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
||||
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.22"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "972f5ae5d1cb9c6ae417789196c803205313edde988685da5e3aae0827b9e7fd"
|
||||
checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.51"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062"
|
||||
checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
@ -1156,15 +1156,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.98"
|
||||
version = "0.2.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
|
||||
checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
|
||||
|
||||
[[package]]
|
||||
name = "libgit2-sys"
|
||||
version = "0.12.21+1.1.0"
|
||||
version = "0.12.24+1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86271bacd72b2b9e854c3dcfb82efd538f15f870e4c11af66900effb462f6825"
|
||||
checksum = "ddbd6021eef06fb289a8f54b3c2acfdd85ff2a585dfbb24b8576325373d2152c"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
|
@ -1176,9 +1176,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "libssh2-sys"
|
||||
version = "0.2.21"
|
||||
version = "0.2.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0186af0d8f171ae6b9c4c90ec51898bad5d08a2d5e470903a50d9ad8959cbee"
|
||||
checksum = "b094a36eb4b8b8c8a7b4b8ae43b2944502be3e59cd87687595cf6b0a71b3f4ca"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
|
@ -1217,9 +1217,9 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
|
|||
|
||||
[[package]]
|
||||
name = "matches"
|
||||
version = "0.1.8"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
||||
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
||||
|
||||
[[package]]
|
||||
name = "maybe-uninit"
|
||||
|
@ -1229,9 +1229,9 @@ checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
|
|||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.0"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
|
@ -1283,9 +1283,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.0"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e0d047c1062aa51e256408c560894e5251f08925980e53cf1aa5bd00eec6512"
|
||||
checksum = "74e768dff5fb39a41b3bcd30bb25cf989706c90d028d1ad71971987aa309d535"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
|
@ -1343,9 +1343,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.25.3"
|
||||
version = "0.26.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a38f2be3697a57b4060074ff41b44c16870d916ad7877c17696e063257482bc7"
|
||||
checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
@ -1376,9 +1376,9 @@ checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a"
|
|||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.65"
|
||||
version = "0.9.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a7907e3bfa08bb85105209cdfcb6c63d109f8f6c1ed6ca318fff5c1853fbc1d"
|
||||
checksum = "69df2d8dfc6ce3aaf44b40dec6f487d5a886516cf6879c49e98e0710f310a058"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
|
@ -1453,9 +1453,9 @@ checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
|
|||
dependencies = [
|
||||
"pest",
|
||||
"pest_meta",
|
||||
"proc-macro2 1.0.27",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.73",
|
||||
"proc-macro2 1.0.29",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1483,9 +1483,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
|||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.19"
|
||||
version = "0.3.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
|
||||
checksum = "7c9b1041b4387893b91ee6746cddfc28516aff326a3519fb2adf820932c5e6cb"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
|
@ -1516,9 +1516,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.27"
|
||||
version = "1.0.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
|
||||
checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d"
|
||||
dependencies = [
|
||||
"unicode-xid 0.2.2",
|
||||
]
|
||||
|
@ -1545,11 +1545,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.9"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.27",
|
||||
"proc-macro2 1.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1681,9 +1681,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.9"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee"
|
||||
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
@ -1760,9 +1760,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.20"
|
||||
version = "0.1.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49"
|
||||
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
|
@ -1838,29 +1838,29 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.126"
|
||||
version = "1.0.130"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
|
||||
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.126"
|
||||
version = "1.0.130"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
|
||||
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.27",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.73",
|
||||
"proc-macro2 1.0.29",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.64"
|
||||
version = "1.0.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
|
||||
checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -1893,9 +1893,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.9.5"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12"
|
||||
checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa"
|
||||
dependencies = [
|
||||
"block-buffer 0.9.0",
|
||||
"cfg-if 1.0.0",
|
||||
|
@ -1930,9 +1930,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.3"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527"
|
||||
checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
|
@ -1942,9 +1942,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
|||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.4.0"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2"
|
||||
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
|
@ -1959,24 +1959,24 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.73"
|
||||
version = "1.0.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7"
|
||||
checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.27",
|
||||
"quote 1.0.9",
|
||||
"proc-macro2 1.0.29",
|
||||
"quote 1.0.10",
|
||||
"unicode-xid 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.12.4"
|
||||
version = "0.12.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
|
||||
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.27",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.73",
|
||||
"proc-macro2 1.0.29",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
"unicode-xid 0.2.2",
|
||||
]
|
||||
|
||||
|
@ -2042,9 +2042,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.2.0"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342"
|
||||
checksum = "f83b2a3d4d9091d0abd7eba4dc2710b1718583bd4d8992e2190720ea38f391f7"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
@ -2057,9 +2057,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
|||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.26"
|
||||
version = "0.1.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d"
|
||||
checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"pin-project-lite",
|
||||
|
@ -2069,20 +2069,20 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.15"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2"
|
||||
checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.27",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.73",
|
||||
"proc-macro2 1.0.29",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.18"
|
||||
version = "0.1.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052"
|
||||
checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4"
|
||||
|
||||
[[package]]
|
||||
name = "typed-arena"
|
||||
|
@ -2092,9 +2092,9 @@ checksum = "a9b2228007eba4120145f785df0f6c92ea538f5a3635a612ecf4e334c8c1446d"
|
|||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.13.0"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
|
||||
checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec"
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
|
@ -2119,12 +2119,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.5"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0"
|
||||
dependencies = [
|
||||
"matches",
|
||||
]
|
||||
checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
|
@ -2137,9 +2134,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.8"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
|
||||
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
|
@ -2220,9 +2217,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.74"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
|
||||
checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen-macro",
|
||||
|
@ -2230,24 +2227,24 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.74"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
|
||||
checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2 1.0.27",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.73",
|
||||
"proc-macro2 1.0.29",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.24"
|
||||
version = "0.4.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fba7978c679d53ce2d0ac80c8c175840feb849a161664365d1287b41f2e67f1"
|
||||
checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
|
@ -2257,38 +2254,38 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.74"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
|
||||
checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
|
||||
dependencies = [
|
||||
"quote 1.0.9",
|
||||
"quote 1.0.10",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.74"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
|
||||
checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.27",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.73",
|
||||
"proc-macro2 1.0.29",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.74"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
|
||||
checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test"
|
||||
version = "0.3.24"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cab416a9b970464c2882ed92d55b0c33046b08e0bdc9d59b3b718acd4e1bae8"
|
||||
checksum = "96f1aa7971fdf61ef0f353602102dbea75a56e225ed036c1e3740564b91e6b7e"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"js-sys",
|
||||
|
@ -2300,19 +2297,19 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test-macro"
|
||||
version = "0.3.24"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd4543fc6cf3541ef0d98bf720104cc6bd856d7eba449fd2aa365ef4fed0e782"
|
||||
checksum = "6006f79628dfeb96a86d4db51fbf1344cd7fd8408f06fc9aa3c84913a4789688"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.27",
|
||||
"quote 1.0.9",
|
||||
"proc-macro2 1.0.29",
|
||||
"quote 1.0.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.51"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582"
|
||||
checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
|
@ -2351,22 +2348,22 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.3.0"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd"
|
||||
checksum = "bf68b08513768deaa790264a7fac27a58cbf2705cfcdc9448362229217d7e970"
|
||||
dependencies = [
|
||||
"zeroize_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize_derive"
|
||||
version = "1.1.0"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2c1e130bebaeab2f23886bf9acbaca14b092408c452543c857f66399cd6dab1"
|
||||
checksum = "bdff2024a851a322b08f179173ae2ba620445aef1e838f0c196820eade4ae0c7"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.27",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.73",
|
||||
"proc-macro2 1.0.29",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
@ -2445,7 +2442,7 @@ dependencies = [
|
|||
"regex 0.2.11",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.9.5",
|
||||
"sha2 0.9.8",
|
||||
"typed-arena",
|
||||
"wasm-bindgen-test",
|
||||
"zokrates_common",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
FROM ubuntu:18.04
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
|
||||
ARG RUST_VERSION=nightly
|
||||
|
||||
ENV RUSTUP_HOME=/usr/local/rustup \
|
||||
CARGO_HOME=/usr/local/cargo \
|
||||
PATH=/usr/local/cargo/bin:$PATH
|
||||
|
@ -29,7 +31,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain none -y \
|
||||
&& rustup toolchain install nightly --allow-downgrade --profile minimal --component rustfmt clippy \
|
||||
&& rustup toolchain install $RUST_VERSION --allow-downgrade --profile minimal --component rustfmt clippy \
|
||||
&& cargo install --git https://github.com/rustwasm/wasm-pack \
|
||||
&& rm -rf /usr/local/cargo/registry \
|
||||
&& curl -sL https://deb.nodesource.com/setup_lts.x | bash - && apt-get install -y nodejs && npm i -g solc \
|
||||
|
|
1
changelogs/unreleased/1012-dark64
Normal file
1
changelogs/unreleased/1012-dark64
Normal file
|
@ -0,0 +1 @@
|
|||
Add optional message to assert statement
|
1
changelogs/unreleased/1030-schaeff
Normal file
1
changelogs/unreleased/1030-schaeff
Normal file
|
@ -0,0 +1 @@
|
|||
Allow more postfix expressions, exit gracefully when trying to call anything else than an identifier
|
1
changelogs/unreleased/1032-schaeff
Normal file
1
changelogs/unreleased/1032-schaeff
Normal file
|
@ -0,0 +1 @@
|
|||
Fail at compile time when complex types are known not to be equal
|
1
changelogs/unreleased/1034-schaeff
Normal file
1
changelogs/unreleased/1034-schaeff
Normal file
|
@ -0,0 +1 @@
|
|||
Add Marlin proving scheme to the backend table in the book
|
1
changelogs/unreleased/997-dark64
Normal file
1
changelogs/unreleased/997-dark64
Normal file
|
@ -0,0 +1 @@
|
|||
Make field to uint casts truncate values bigger than uint max
|
|
@ -1 +0,0 @@
|
|||
nightly-2021-04-25
|
|
@ -1,2 +1,2 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2021-04-25"
|
||||
channel = "nightly-2021-08-01"
|
||||
|
|
|
@ -49,7 +49,7 @@ ZoKrates supports multiple backends. The options are the following:
|
|||
| ---- | -------- | --------------- | ------ |
|
||||
| Bellman | `--backend bellman` | G16 | ALTBN_128, BLS12_381 |
|
||||
| Libsnark | `--backend libsnark` | GM17, PGHR13 | ALTBN_128 |
|
||||
| Ark | `--backend ark` | GM17 | ALTBN_128, BLS12_377, BW6_761 |
|
||||
| Ark | `--backend ark` | GM17, MARLIN | ALTBN_128, BLS12_377, BW6_761 |
|
||||
|
||||
Default: `bellman`
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
def main():
|
||||
assert([1f] == [2f])
|
||||
return
|
|
@ -0,0 +1,5 @@
|
|||
from "EMBED" import unpack
|
||||
|
||||
def main():
|
||||
bool[2] bits = unpack(4) // we need 3 bits to unpack 4
|
||||
return
|
|
@ -0,0 +1,2 @@
|
|||
def main(field[3] a) -> field:
|
||||
return [...a][0] + [a[0]][0] + [a[0]; 1][0]
|
|
@ -195,7 +195,7 @@ mod tests {
|
|||
let interpreter = ir::Interpreter::default();
|
||||
|
||||
let _ = interpreter
|
||||
.execute(&artifacts.prog(), &[Bn128Field::from(0)])
|
||||
.execute(artifacts.prog(), &[Bn128Field::from(0)])
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ mod tests {
|
|||
|
||||
let interpreter = ir::Interpreter::default();
|
||||
|
||||
let res = interpreter.execute(&artifacts.prog(), &[Bn128Field::from(0)]);
|
||||
let res = interpreter.execute(artifacts.prog(), &[Bn128Field::from(0)]);
|
||||
|
||||
assert!(res.is_err());
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ fn cli_export_verifier<T: SolidityCompatibleField, S: SolidityCompatibleScheme<T
|
|||
let mut writer = BufWriter::new(output_file);
|
||||
|
||||
writer
|
||||
.write_all(&verifier.as_bytes())
|
||||
.write_all(verifier.as_bytes())
|
||||
.map_err(|_| "Failed writing output to file".to_string())?;
|
||||
|
||||
println!("Verifier exported to '{}'", output_path.display());
|
||||
|
|
|
@ -64,5 +64,5 @@ zokrates_fs_resolver = { version = "0.5", path = "../zokrates_fs_resolver"}
|
|||
|
||||
[build-dependencies]
|
||||
cc = { version = "1.0", features = ["parallel"], optional = true }
|
||||
cmake = { version = "0.1.31", optional = true }
|
||||
cmake = { version = "=0.1.45", optional = true }
|
||||
git2 = { version = "0.13.1", optional = true }
|
||||
|
|
|
@ -346,8 +346,11 @@ impl<'ast> From<pest::AssertionStatement<'ast>> for absy::StatementNode<'ast> {
|
|||
fn from(statement: pest::AssertionStatement<'ast>) -> absy::StatementNode<'ast> {
|
||||
use crate::absy::NodeValue;
|
||||
|
||||
absy::Statement::Assertion(absy::ExpressionNode::from(statement.expression))
|
||||
.span(statement.span)
|
||||
absy::Statement::Assertion(
|
||||
absy::ExpressionNode::from(statement.expression),
|
||||
statement.message.map(|m| m.value),
|
||||
)
|
||||
.span(statement.span)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -614,17 +617,17 @@ impl<'ast> From<pest::PostfixExpression<'ast>> for absy::ExpressionNode<'ast> {
|
|||
fn from(expression: pest::PostfixExpression<'ast>) -> absy::ExpressionNode<'ast> {
|
||||
use crate::absy::NodeValue;
|
||||
|
||||
let id_str = expression.id.span.as_str();
|
||||
let id = absy::ExpressionNode::from(expression.id);
|
||||
let base = absy::ExpressionNode::from(*expression.base);
|
||||
|
||||
// pest::PostFixExpression contains an array of "accesses": `a(34)[42]` is represented as `[a, [Call(34), Select(42)]]`, but absy::ExpressionNode
|
||||
// is recursive, so it is `Select(Call(a, 34), 42)`. We apply this transformation here
|
||||
|
||||
// we start with the id, and we fold the array of accesses by wrapping the current value
|
||||
expression.accesses.into_iter().fold(id, |acc, a| match a {
|
||||
pest::Access::Call(a) => match acc.value {
|
||||
absy::Expression::Identifier(_) => absy::Expression::FunctionCall(
|
||||
&id_str,
|
||||
// we start with the base, and we fold the array of accesses by wrapping the current value
|
||||
expression
|
||||
.accesses
|
||||
.into_iter()
|
||||
.fold(base, |acc, a| match a {
|
||||
pest::Access::Call(a) => absy::Expression::FunctionCall(
|
||||
Box::new(acc),
|
||||
a.explicit_generics.map(|explicit_generics| {
|
||||
explicit_generics
|
||||
.values
|
||||
|
@ -645,18 +648,17 @@ impl<'ast> From<pest::PostfixExpression<'ast>> for absy::ExpressionNode<'ast> {
|
|||
.into_iter()
|
||||
.map(absy::ExpressionNode::from)
|
||||
.collect(),
|
||||
),
|
||||
e => unimplemented!("only identifiers are callable, found \"{}\"", e),
|
||||
}
|
||||
.span(a.span),
|
||||
pest::Access::Select(a) => {
|
||||
absy::Expression::Select(box acc, box absy::RangeOrExpression::from(a.expression))
|
||||
.span(a.span)
|
||||
}
|
||||
pest::Access::Member(m) => {
|
||||
absy::Expression::Member(box acc, box m.id.span.as_str()).span(m.span)
|
||||
}
|
||||
})
|
||||
)
|
||||
.span(a.span),
|
||||
pest::Access::Select(a) => absy::Expression::Select(
|
||||
box acc,
|
||||
box absy::RangeOrExpression::from(a.expression),
|
||||
)
|
||||
.span(a.span),
|
||||
pest::Access::Member(m) => {
|
||||
absy::Expression::Member(box acc, box m.id.span.as_str()).span(m.span)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -667,7 +669,7 @@ impl<'ast> From<pest::DecimalLiteralExpression<'ast>> for absy::ExpressionNode<'
|
|||
match expression.suffix {
|
||||
Some(suffix) => match suffix {
|
||||
pest::DecimalSuffix::Field(_) => absy::Expression::FieldConstant(
|
||||
BigUint::parse_bytes(&expression.value.span.as_str().as_bytes(), 10).unwrap(),
|
||||
BigUint::parse_bytes(expression.value.span.as_str().as_bytes(), 10).unwrap(),
|
||||
),
|
||||
pest::DecimalSuffix::U64(_) => {
|
||||
absy::Expression::U64Constant(expression.value.span.as_str().parse().unwrap())
|
||||
|
@ -684,7 +686,7 @@ impl<'ast> From<pest::DecimalLiteralExpression<'ast>> for absy::ExpressionNode<'
|
|||
}
|
||||
.span(expression.span),
|
||||
None => absy::Expression::IntConstant(
|
||||
BigUint::parse_bytes(&expression.value.span.as_str().as_bytes(), 10).unwrap(),
|
||||
BigUint::parse_bytes(expression.value.span.as_str().as_bytes(), 10).unwrap(),
|
||||
)
|
||||
.span(expression.span),
|
||||
}
|
||||
|
@ -697,16 +699,16 @@ impl<'ast> From<pest::HexLiteralExpression<'ast>> for absy::ExpressionNode<'ast>
|
|||
|
||||
match expression.value {
|
||||
pest::HexNumberExpression::U64(e) => {
|
||||
absy::Expression::U64Constant(u64::from_str_radix(&e.span.as_str(), 16).unwrap())
|
||||
absy::Expression::U64Constant(u64::from_str_radix(e.span.as_str(), 16).unwrap())
|
||||
}
|
||||
pest::HexNumberExpression::U32(e) => {
|
||||
absy::Expression::U32Constant(u32::from_str_radix(&e.span.as_str(), 16).unwrap())
|
||||
absy::Expression::U32Constant(u32::from_str_radix(e.span.as_str(), 16).unwrap())
|
||||
}
|
||||
pest::HexNumberExpression::U16(e) => {
|
||||
absy::Expression::U16Constant(u16::from_str_radix(&e.span.as_str(), 16).unwrap())
|
||||
absy::Expression::U16Constant(u16::from_str_radix(e.span.as_str(), 16).unwrap())
|
||||
}
|
||||
pest::HexNumberExpression::U8(e) => {
|
||||
absy::Expression::U8Constant(u8::from_str_radix(&e.span.as_str(), 16).unwrap())
|
||||
absy::Expression::U8Constant(u8::from_str_radix(e.span.as_str(), 16).unwrap())
|
||||
}
|
||||
}
|
||||
.span(expression.span)
|
||||
|
@ -853,7 +855,7 @@ mod tests {
|
|||
#[test]
|
||||
fn return_forty_two() {
|
||||
let source = "def main() -> field: return 42";
|
||||
let ast = pest::generate_ast(&source).unwrap();
|
||||
let ast = pest::generate_ast(source).unwrap();
|
||||
let expected: absy::Module = absy::Module {
|
||||
symbols: vec![absy::SymbolDeclaration {
|
||||
id: &source[4..8],
|
||||
|
@ -884,7 +886,7 @@ mod tests {
|
|||
#[test]
|
||||
fn return_true() {
|
||||
let source = "def main() -> bool: return true";
|
||||
let ast = pest::generate_ast(&source).unwrap();
|
||||
let ast = pest::generate_ast(source).unwrap();
|
||||
let expected: absy::Module = absy::Module {
|
||||
symbols: vec![absy::SymbolDeclaration {
|
||||
id: &source[4..8],
|
||||
|
@ -913,7 +915,7 @@ mod tests {
|
|||
#[test]
|
||||
fn arguments() {
|
||||
let source = "def main(private field a, bool b) -> field: return 42";
|
||||
let ast = pest::generate_ast(&source).unwrap();
|
||||
let ast = pest::generate_ast(source).unwrap();
|
||||
|
||||
let expected: absy::Module = absy::Module {
|
||||
symbols: vec![absy::SymbolDeclaration {
|
||||
|
@ -1097,7 +1099,7 @@ mod tests {
|
|||
"a(3)[4]",
|
||||
absy::Expression::Select(
|
||||
box absy::Expression::FunctionCall(
|
||||
"a",
|
||||
box absy::Expression::Identifier("a").mock(),
|
||||
None,
|
||||
vec![absy::Expression::IntConstant(3usize.into()).into()],
|
||||
)
|
||||
|
@ -1112,7 +1114,7 @@ mod tests {
|
|||
absy::Expression::Select(
|
||||
box absy::Expression::Select(
|
||||
box absy::Expression::FunctionCall(
|
||||
"a",
|
||||
box absy::Expression::Identifier("a").mock(),
|
||||
None,
|
||||
vec![absy::Expression::IntConstant(3usize.into()).into()],
|
||||
)
|
||||
|
@ -1138,28 +1140,52 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn call_array_element() {
|
||||
// a call after an array access should be rejected
|
||||
// a call after an array access should be accepted
|
||||
let source = "def main(): return a[2](3)";
|
||||
let ast = pest::generate_ast(&source).unwrap();
|
||||
absy::Module::from(ast);
|
||||
let ast = pest::generate_ast(source).unwrap();
|
||||
assert_eq!(
|
||||
absy::Module::from(ast),
|
||||
wrap(absy::Expression::FunctionCall(
|
||||
box absy::Expression::Select(
|
||||
box absy::Expression::Identifier("a").mock(),
|
||||
box absy::RangeOrExpression::Expression(
|
||||
absy::Expression::IntConstant(2u32.into()).mock()
|
||||
)
|
||||
)
|
||||
.mock(),
|
||||
None,
|
||||
vec![absy::Expression::IntConstant(3u32.into()).mock()],
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn call_call_result() {
|
||||
// a call after a call should be rejected
|
||||
// a call after a call should be accepted
|
||||
let source = "def main(): return a(2)(3)";
|
||||
let ast = pest::generate_ast(&source).unwrap();
|
||||
absy::Module::from(ast);
|
||||
|
||||
let ast = pest::generate_ast(source).unwrap();
|
||||
assert_eq!(
|
||||
absy::Module::from(ast),
|
||||
wrap(absy::Expression::FunctionCall(
|
||||
box absy::Expression::FunctionCall(
|
||||
box absy::Expression::Identifier("a").mock(),
|
||||
None,
|
||||
vec![absy::Expression::IntConstant(2u32.into()).mock()]
|
||||
)
|
||||
.mock(),
|
||||
None,
|
||||
vec![absy::Expression::IntConstant(3u32.into()).mock()],
|
||||
))
|
||||
);
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn declarations() {
|
||||
use self::pest::Span;
|
||||
|
||||
let span = Span::new(&"", 0, 0).unwrap();
|
||||
let span = Span::new("", 0, 0).unwrap();
|
||||
|
||||
// For different definitions, we generate declarations
|
||||
// Case 1: `id = expr` where `expr` is not a function call
|
||||
|
@ -1178,7 +1204,7 @@ mod tests {
|
|||
expression: pest::Expression::Literal(pest::LiteralExpression::DecimalLiteral(
|
||||
pest::DecimalLiteralExpression {
|
||||
value: pest::DecimalNumber {
|
||||
span: Span::new(&"1", 0, 1).unwrap(),
|
||||
span: Span::new("1", 0, 1).unwrap(),
|
||||
},
|
||||
suffix: None,
|
||||
span: span.clone(),
|
||||
|
@ -1210,10 +1236,10 @@ mod tests {
|
|||
span: span.clone(),
|
||||
})],
|
||||
expression: pest::Expression::Postfix(pest::PostfixExpression {
|
||||
id: pest::IdentifierExpression {
|
||||
base: box pest::Expression::Identifier(pest::IdentifierExpression {
|
||||
value: String::from("foo"),
|
||||
span: span.clone(),
|
||||
},
|
||||
}),
|
||||
accesses: vec![pest::Access::Call(pest::CallAccess {
|
||||
explicit_generics: None,
|
||||
arguments: pest::Arguments {
|
||||
|
@ -1263,10 +1289,10 @@ mod tests {
|
|||
}),
|
||||
],
|
||||
expression: pest::Expression::Postfix(pest::PostfixExpression {
|
||||
id: pest::IdentifierExpression {
|
||||
base: box pest::Expression::Identifier(pest::IdentifierExpression {
|
||||
value: String::from("foo"),
|
||||
span: span.clone(),
|
||||
},
|
||||
}),
|
||||
accesses: vec![pest::Access::Call(pest::CallAccess {
|
||||
explicit_generics: None,
|
||||
arguments: pest::Arguments {
|
||||
|
|
|
@ -13,7 +13,7 @@ pub mod variable;
|
|||
|
||||
pub use crate::absy::node::{Node, NodeValue};
|
||||
pub use crate::absy::parameter::{Parameter, ParameterNode};
|
||||
use crate::absy::types::{FunctionIdentifier, UnresolvedSignature, UnresolvedType, UserTypeId};
|
||||
use crate::absy::types::{UnresolvedSignature, UnresolvedType, UserTypeId};
|
||||
pub use crate::absy::variable::{Variable, VariableNode};
|
||||
use crate::embed::FlatEmbed;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
@ -337,7 +337,7 @@ pub enum Statement<'ast> {
|
|||
Return(ExpressionListNode<'ast>),
|
||||
Declaration(VariableNode<'ast>),
|
||||
Definition(AssigneeNode<'ast>, ExpressionNode<'ast>),
|
||||
Assertion(ExpressionNode<'ast>),
|
||||
Assertion(ExpressionNode<'ast>, Option<String>),
|
||||
For(
|
||||
VariableNode<'ast>,
|
||||
ExpressionNode<'ast>,
|
||||
|
@ -355,7 +355,13 @@ impl<'ast> fmt::Display for Statement<'ast> {
|
|||
Statement::Return(ref expr) => write!(f, "return {}", expr),
|
||||
Statement::Declaration(ref var) => write!(f, "{}", var),
|
||||
Statement::Definition(ref lhs, ref rhs) => write!(f, "{} = {}", lhs, rhs),
|
||||
Statement::Assertion(ref e) => write!(f, "assert({})", e),
|
||||
Statement::Assertion(ref e, ref message) => {
|
||||
write!(f, "assert({}", e)?;
|
||||
match message {
|
||||
Some(m) => write!(f, ", \"{}\")", m),
|
||||
None => write!(f, ")"),
|
||||
}
|
||||
}
|
||||
Statement::For(ref var, ref start, ref stop, ref list) => {
|
||||
writeln!(f, "for {} in {}..{} do", var, start, stop)?;
|
||||
for l in list {
|
||||
|
@ -486,7 +492,7 @@ pub enum Expression<'ast> {
|
|||
ConditionalKind,
|
||||
),
|
||||
FunctionCall(
|
||||
FunctionIdentifier<'ast>,
|
||||
Box<ExpressionNode<'ast>>,
|
||||
Option<Vec<Option<ExpressionNode<'ast>>>>,
|
||||
Vec<ExpressionNode<'ast>>,
|
||||
),
|
||||
|
|
|
@ -56,8 +56,6 @@ impl<'ast> UnresolvedType<'ast> {
|
|||
}
|
||||
}
|
||||
|
||||
pub type FunctionIdentifier<'ast> = &'ast str;
|
||||
|
||||
pub use self::signature::UnresolvedSignature;
|
||||
|
||||
mod signature {
|
||||
|
|
|
@ -243,7 +243,7 @@ fn check_with_arena<'ast, T: Field, E: Into<imports::Error>>(
|
|||
|
||||
log::debug!("Parse program with entry file {}", location.display());
|
||||
|
||||
let compiled = parse_program::<T, E>(source, location, resolver, &arena)?;
|
||||
let compiled = parse_program::<T, E>(source, location, resolver, arena)?;
|
||||
|
||||
log::debug!("Check semantics");
|
||||
|
||||
|
@ -271,7 +271,7 @@ pub fn parse_program<'ast, T: Field, E: Into<imports::Error>>(
|
|||
) -> Result<Program<'ast>, CompileErrors> {
|
||||
let mut modules = HashMap::new();
|
||||
|
||||
let main = parse_module::<T, E>(&source, location.clone(), resolver, &mut modules, &arena)?;
|
||||
let main = parse_module::<T, E>(source, location.clone(), resolver, &mut modules, arena)?;
|
||||
|
||||
modules.insert(location.clone(), main);
|
||||
|
||||
|
@ -290,7 +290,7 @@ pub fn parse_module<'ast, T: Field, E: Into<imports::Error>>(
|
|||
) -> Result<Module<'ast>, CompileErrors> {
|
||||
log::debug!("Generate pest AST for {}", location.display());
|
||||
|
||||
let ast = pest::generate_ast(&source)
|
||||
let ast = pest::generate_ast(source)
|
||||
.map_err(|e| CompileErrors::from(CompileErrorInner::from(e).in_file(&location)))?;
|
||||
|
||||
log::debug!("Process macros for {}", location.display());
|
||||
|
@ -309,7 +309,7 @@ pub fn parse_module<'ast, T: Field, E: Into<imports::Error>>(
|
|||
location.clone(),
|
||||
resolver,
|
||||
modules,
|
||||
&arena,
|
||||
arena,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -43,18 +43,18 @@ pub enum RuntimeError {
|
|||
Euclidean,
|
||||
ShaXor,
|
||||
Division,
|
||||
Source,
|
||||
SourceAssertion(String),
|
||||
ArgumentBitness,
|
||||
SelectRangeCheck,
|
||||
}
|
||||
|
||||
impl RuntimeError {
|
||||
fn is_malicious(&self) -> bool {
|
||||
pub(crate) fn is_malicious(&self) -> bool {
|
||||
use RuntimeError::*;
|
||||
|
||||
!matches!(
|
||||
self,
|
||||
Source | Inverse | LtSum | SelectRangeCheck | ArgumentBitness
|
||||
SourceAssertion(_) | Inverse | LtSum | SelectRangeCheck | ArgumentBitness
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -87,19 +87,12 @@ impl fmt::Display for RuntimeError {
|
|||
Euclidean => "Euclidean check failed",
|
||||
ShaXor => "Internal Sha check failed",
|
||||
Division => "Division check failed",
|
||||
Source => "User assertion failed",
|
||||
SourceAssertion(m) => m.as_str(),
|
||||
ArgumentBitness => "Argument bitness check failed",
|
||||
SelectRangeCheck => "Out of bounds array access",
|
||||
};
|
||||
|
||||
write!(f, "{}", msg)?;
|
||||
|
||||
if self.is_malicious() {
|
||||
writeln!(f)?;
|
||||
write!(f, "The default ZoKrates interpreter should not yield this error. Please open an issue")?;
|
||||
}
|
||||
|
||||
write!(f, "")
|
||||
write!(f, "{}", msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::ir::Interpreter;
|
|||
|
||||
use crate::compile::CompileConfig;
|
||||
use crate::embed::FlatEmbed;
|
||||
use crate::flat_absy::*;
|
||||
use crate::flat_absy::{RuntimeError, *};
|
||||
use crate::solvers::Solver;
|
||||
use crate::zir::types::{Type, UBitwidth};
|
||||
use crate::zir::*;
|
||||
|
@ -146,6 +146,15 @@ impl<T: Field> FlatUExpression<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<crate::zir::RuntimeError> for RuntimeError {
|
||||
fn from(error: crate::zir::RuntimeError) -> Self {
|
||||
match error {
|
||||
crate::zir::RuntimeError::SourceAssertion(s) => RuntimeError::SourceAssertion(s),
|
||||
crate::zir::RuntimeError::SelectRangeCheck => RuntimeError::SelectRangeCheck,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Flattener<'ast, T> {
|
||||
pub fn flatten(p: ZirProgram<'ast, T>, config: &CompileConfig) -> FlatProg<T> {
|
||||
Flattener::new(config).flatten_program(p)
|
||||
|
@ -2202,7 +2211,10 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
|
||||
// convert the exponent to bytes, big endian
|
||||
let ebytes_be = e.to_be_bytes();
|
||||
|
||||
// convert the bytes to bits, remove leading zeroes (we only need powers up to the highest non-zero bit)
|
||||
#[allow(clippy::needless_collect)]
|
||||
// collecting is required as we then reverse
|
||||
let ebits_be: Vec<_> = ebytes_be
|
||||
.iter()
|
||||
.flat_map(|byte| (0..8).rev().map(move |i| byte & (1 << i) != 0)) // byte to bit, big endian
|
||||
|
@ -2367,13 +2379,13 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
.insert(FlatExpression::Identifier(var), bits);
|
||||
}
|
||||
}
|
||||
ZirStatement::Assertion(e) => {
|
||||
ZirStatement::Assertion(e, error) => {
|
||||
match e {
|
||||
BooleanExpression::And(..) => {
|
||||
for boolean in e.into_conjunction_iterator() {
|
||||
self.flatten_statement(
|
||||
statements_flattened,
|
||||
ZirStatement::Assertion(boolean),
|
||||
ZirStatement::Assertion(boolean, error.clone()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -2381,7 +2393,12 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
let lhs = self.flatten_field_expression(statements_flattened, lhs);
|
||||
let rhs = self.flatten_field_expression(statements_flattened, rhs);
|
||||
|
||||
self.flatten_equality_assertion(statements_flattened, lhs, rhs)
|
||||
self.flatten_equality_assertion(
|
||||
statements_flattened,
|
||||
lhs,
|
||||
rhs,
|
||||
error.into(),
|
||||
)
|
||||
}
|
||||
BooleanExpression::UintEq(box lhs, box rhs) => {
|
||||
let lhs = self
|
||||
|
@ -2391,13 +2408,23 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
.flatten_uint_expression(statements_flattened, rhs)
|
||||
.get_field_unchecked();
|
||||
|
||||
self.flatten_equality_assertion(statements_flattened, lhs, rhs)
|
||||
self.flatten_equality_assertion(
|
||||
statements_flattened,
|
||||
lhs,
|
||||
rhs,
|
||||
error.into(),
|
||||
)
|
||||
}
|
||||
BooleanExpression::BoolEq(box lhs, box rhs) => {
|
||||
let lhs = self.flatten_boolean_expression(statements_flattened, lhs);
|
||||
let rhs = self.flatten_boolean_expression(statements_flattened, rhs);
|
||||
|
||||
self.flatten_equality_assertion(statements_flattened, lhs, rhs)
|
||||
self.flatten_equality_assertion(
|
||||
statements_flattened,
|
||||
lhs,
|
||||
rhs,
|
||||
error.into(),
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
// naive approach: flatten the boolean to a single field element and constrain it to 1
|
||||
|
@ -2407,14 +2434,14 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
statements_flattened.push(FlatStatement::Condition(
|
||||
e,
|
||||
FlatExpression::Number(T::from(1)),
|
||||
RuntimeError::Source,
|
||||
error.into(),
|
||||
));
|
||||
} else {
|
||||
// swap so that left side is linear
|
||||
statements_flattened.push(FlatStatement::Condition(
|
||||
FlatExpression::Number(T::from(1)),
|
||||
e,
|
||||
RuntimeError::Source,
|
||||
error.into(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -2526,6 +2553,7 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
statements_flattened: &mut FlatStatements<T>,
|
||||
lhs: FlatExpression<T>,
|
||||
rhs: FlatExpression<T>,
|
||||
error: RuntimeError,
|
||||
) {
|
||||
let (lhs, rhs) = match (lhs, rhs) {
|
||||
(FlatExpression::Mult(box x, box y), z) | (z, FlatExpression::Mult(box x, box y)) => (
|
||||
|
@ -2543,7 +2571,7 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
),
|
||||
),
|
||||
};
|
||||
statements_flattened.push(FlatStatement::Condition(lhs, rhs, RuntimeError::Source));
|
||||
statements_flattened.push(FlatStatement::Condition(lhs, rhs, error));
|
||||
}
|
||||
|
||||
/// Identifies a non-linear expression by assigning it to a new identifier.
|
||||
|
@ -2650,6 +2678,7 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::zir;
|
||||
use crate::zir::types::Signature;
|
||||
use crate::zir::types::Type;
|
||||
use zokrates_field::Bn128Field;
|
||||
|
@ -2676,10 +2705,13 @@ mod tests {
|
|||
Variable::boolean("y".into()),
|
||||
BooleanExpression::Value(true).into(),
|
||||
),
|
||||
ZirStatement::Assertion(BooleanExpression::BoolEq(
|
||||
box BooleanExpression::Identifier("x".into()),
|
||||
box BooleanExpression::Identifier("y".into()),
|
||||
)),
|
||||
ZirStatement::Assertion(
|
||||
BooleanExpression::BoolEq(
|
||||
box BooleanExpression::Identifier("x".into()),
|
||||
box BooleanExpression::Identifier("y".into()),
|
||||
),
|
||||
zir::RuntimeError::mock(),
|
||||
),
|
||||
],
|
||||
signature: Signature {
|
||||
inputs: vec![],
|
||||
|
@ -2708,7 +2740,7 @@ mod tests {
|
|||
box FlatExpression::Identifier(FlatVariable::new(0)),
|
||||
box FlatExpression::Number(Bn128Field::from(1)),
|
||||
),
|
||||
RuntimeError::Source,
|
||||
zir::RuntimeError::mock().into(),
|
||||
),
|
||||
],
|
||||
};
|
||||
|
@ -2738,13 +2770,16 @@ mod tests {
|
|||
Variable::field_element("y"),
|
||||
FieldElementExpression::Number(Bn128Field::from(2)).into(),
|
||||
),
|
||||
ZirStatement::Assertion(BooleanExpression::FieldEq(
|
||||
box FieldElementExpression::Add(
|
||||
box FieldElementExpression::Identifier("x".into()),
|
||||
box FieldElementExpression::Number(Bn128Field::from(1)),
|
||||
ZirStatement::Assertion(
|
||||
BooleanExpression::FieldEq(
|
||||
box FieldElementExpression::Add(
|
||||
box FieldElementExpression::Identifier("x".into()),
|
||||
box FieldElementExpression::Number(Bn128Field::from(1)),
|
||||
),
|
||||
box FieldElementExpression::Identifier("y".into()),
|
||||
),
|
||||
box FieldElementExpression::Identifier("y".into()),
|
||||
)),
|
||||
zir::RuntimeError::mock(),
|
||||
),
|
||||
],
|
||||
signature: Signature {
|
||||
inputs: vec![],
|
||||
|
@ -2776,7 +2811,7 @@ mod tests {
|
|||
),
|
||||
box FlatExpression::Number(Bn128Field::from(1)),
|
||||
),
|
||||
RuntimeError::Source,
|
||||
zir::RuntimeError::mock().into(),
|
||||
),
|
||||
],
|
||||
};
|
||||
|
@ -2808,12 +2843,15 @@ mod tests {
|
|||
.metadata(metadata.clone()),
|
||||
),
|
||||
),
|
||||
ZirStatement::Assertion(BooleanExpression::UintEq(
|
||||
box UExpressionInner::Identifier("x".into())
|
||||
.annotate(32)
|
||||
.metadata(metadata.clone()),
|
||||
box UExpressionInner::Value(42).annotate(32).metadata(metadata),
|
||||
)),
|
||||
ZirStatement::Assertion(
|
||||
BooleanExpression::UintEq(
|
||||
box UExpressionInner::Identifier("x".into())
|
||||
.annotate(32)
|
||||
.metadata(metadata.clone()),
|
||||
box UExpressionInner::Value(42).annotate(32).metadata(metadata),
|
||||
),
|
||||
zir::RuntimeError::mock(),
|
||||
),
|
||||
],
|
||||
signature: Signature {
|
||||
inputs: vec![],
|
||||
|
@ -2838,7 +2876,7 @@ mod tests {
|
|||
box FlatExpression::Identifier(FlatVariable::new(0)),
|
||||
box FlatExpression::Number(Bn128Field::from(1)),
|
||||
),
|
||||
RuntimeError::Source,
|
||||
zir::RuntimeError::mock().into(),
|
||||
),
|
||||
],
|
||||
};
|
||||
|
@ -2868,10 +2906,13 @@ mod tests {
|
|||
Variable::field_element("y"),
|
||||
FieldElementExpression::Number(Bn128Field::from(2)).into(),
|
||||
),
|
||||
ZirStatement::Assertion(BooleanExpression::FieldEq(
|
||||
box FieldElementExpression::Identifier("x".into()),
|
||||
box FieldElementExpression::Identifier("y".into()),
|
||||
)),
|
||||
ZirStatement::Assertion(
|
||||
BooleanExpression::FieldEq(
|
||||
box FieldElementExpression::Identifier("x".into()),
|
||||
box FieldElementExpression::Identifier("y".into()),
|
||||
),
|
||||
zir::RuntimeError::mock(),
|
||||
),
|
||||
],
|
||||
signature: Signature {
|
||||
inputs: vec![],
|
||||
|
@ -2900,7 +2941,7 @@ mod tests {
|
|||
box FlatExpression::Identifier(FlatVariable::new(0)),
|
||||
box FlatExpression::Number(Bn128Field::from(1)),
|
||||
),
|
||||
RuntimeError::Source,
|
||||
zir::RuntimeError::mock().into(),
|
||||
),
|
||||
],
|
||||
};
|
||||
|
@ -2936,13 +2977,16 @@ mod tests {
|
|||
Variable::field_element("z"),
|
||||
FieldElementExpression::Number(Bn128Field::from(4)).into(),
|
||||
),
|
||||
ZirStatement::Assertion(BooleanExpression::FieldEq(
|
||||
box FieldElementExpression::Mult(
|
||||
box FieldElementExpression::Identifier("x".into()),
|
||||
box FieldElementExpression::Identifier("y".into()),
|
||||
ZirStatement::Assertion(
|
||||
BooleanExpression::FieldEq(
|
||||
box FieldElementExpression::Mult(
|
||||
box FieldElementExpression::Identifier("x".into()),
|
||||
box FieldElementExpression::Identifier("y".into()),
|
||||
),
|
||||
box FieldElementExpression::Identifier("z".into()),
|
||||
),
|
||||
box FieldElementExpression::Identifier("z".into()),
|
||||
)),
|
||||
zir::RuntimeError::mock(),
|
||||
),
|
||||
],
|
||||
signature: Signature {
|
||||
inputs: vec![],
|
||||
|
@ -2975,7 +3019,7 @@ mod tests {
|
|||
box FlatExpression::Identifier(FlatVariable::new(0)),
|
||||
box FlatExpression::Identifier(FlatVariable::new(1)),
|
||||
),
|
||||
RuntimeError::Source,
|
||||
zir::RuntimeError::mock().into(),
|
||||
),
|
||||
],
|
||||
};
|
||||
|
@ -3011,13 +3055,16 @@ mod tests {
|
|||
Variable::field_element("z"),
|
||||
FieldElementExpression::Number(Bn128Field::from(4)).into(),
|
||||
),
|
||||
ZirStatement::Assertion(BooleanExpression::FieldEq(
|
||||
box FieldElementExpression::Identifier("z".into()),
|
||||
box FieldElementExpression::Mult(
|
||||
box FieldElementExpression::Identifier("x".into()),
|
||||
box FieldElementExpression::Identifier("y".into()),
|
||||
ZirStatement::Assertion(
|
||||
BooleanExpression::FieldEq(
|
||||
box FieldElementExpression::Identifier("z".into()),
|
||||
box FieldElementExpression::Mult(
|
||||
box FieldElementExpression::Identifier("x".into()),
|
||||
box FieldElementExpression::Identifier("y".into()),
|
||||
),
|
||||
),
|
||||
)),
|
||||
zir::RuntimeError::mock(),
|
||||
),
|
||||
],
|
||||
signature: Signature {
|
||||
inputs: vec![],
|
||||
|
@ -3050,7 +3097,7 @@ mod tests {
|
|||
box FlatExpression::Identifier(FlatVariable::new(0)),
|
||||
box FlatExpression::Identifier(FlatVariable::new(1)),
|
||||
),
|
||||
RuntimeError::Source,
|
||||
zir::RuntimeError::mock().into(),
|
||||
),
|
||||
],
|
||||
};
|
||||
|
@ -3093,16 +3140,19 @@ mod tests {
|
|||
Variable::field_element("t"),
|
||||
FieldElementExpression::Number(Bn128Field::from(2)).into(),
|
||||
),
|
||||
ZirStatement::Assertion(BooleanExpression::FieldEq(
|
||||
box FieldElementExpression::Mult(
|
||||
box FieldElementExpression::Identifier("x".into()),
|
||||
box FieldElementExpression::Identifier("y".into()),
|
||||
ZirStatement::Assertion(
|
||||
BooleanExpression::FieldEq(
|
||||
box FieldElementExpression::Mult(
|
||||
box FieldElementExpression::Identifier("x".into()),
|
||||
box FieldElementExpression::Identifier("y".into()),
|
||||
),
|
||||
box FieldElementExpression::Mult(
|
||||
box FieldElementExpression::Identifier("z".into()),
|
||||
box FieldElementExpression::Identifier("t".into()),
|
||||
),
|
||||
),
|
||||
box FieldElementExpression::Mult(
|
||||
box FieldElementExpression::Identifier("z".into()),
|
||||
box FieldElementExpression::Identifier("t".into()),
|
||||
),
|
||||
)),
|
||||
zir::RuntimeError::mock(),
|
||||
),
|
||||
],
|
||||
signature: Signature {
|
||||
inputs: vec![],
|
||||
|
@ -3146,7 +3196,7 @@ mod tests {
|
|||
box FlatExpression::Identifier(FlatVariable::new(0)),
|
||||
box FlatExpression::Identifier(FlatVariable::new(1)),
|
||||
),
|
||||
RuntimeError::Source,
|
||||
zir::RuntimeError::mock().into(),
|
||||
),
|
||||
],
|
||||
};
|
||||
|
|
|
@ -231,7 +231,7 @@ impl Importer {
|
|||
new_location.clone(),
|
||||
resolver,
|
||||
modules,
|
||||
&arena,
|
||||
arena,
|
||||
)?;
|
||||
|
||||
assert!(modules.insert(new_location.clone(), compiled).is_none());
|
||||
|
@ -239,7 +239,7 @@ impl Importer {
|
|||
};
|
||||
|
||||
SymbolDeclaration {
|
||||
id: &alias,
|
||||
id: alias,
|
||||
symbol: Symbol::There(
|
||||
SymbolImport::with_id_in_module(symbol.id, new_location)
|
||||
.start_end(pos.0, pos.1),
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::flat_absy::flat_variable::FlatVariable;
|
||||
use crate::flat_absy::RuntimeError;
|
||||
use crate::ir::{LinComb, Prog, QuadComb, Statement, Witness};
|
||||
use crate::solvers::Solver;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -10,20 +11,13 @@ pub type ExecutionResult<T> = Result<Witness<T>, Error>;
|
|||
|
||||
impl<T: Field> Prog<T> {}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Interpreter {
|
||||
/// Whether we should try to give out-of-range bit decompositions when the input is not a single summand.
|
||||
/// Used to do targetted testing of `<` flattening, making sure the bit decomposition we base the result on is unique.
|
||||
should_try_out_of_range: bool,
|
||||
}
|
||||
|
||||
impl Default for Interpreter {
|
||||
fn default() -> Interpreter {
|
||||
Interpreter {
|
||||
should_try_out_of_range: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Interpreter {
|
||||
pub fn try_out_of_range() -> Interpreter {
|
||||
Interpreter {
|
||||
|
@ -34,7 +28,7 @@ impl Interpreter {
|
|||
|
||||
impl Interpreter {
|
||||
pub fn execute<T: Field>(&self, program: &Prog<T>, inputs: &[T]) -> ExecutionResult<T> {
|
||||
self.check_inputs(&program, &inputs)?;
|
||||
self.check_inputs(program, inputs)?;
|
||||
let mut witness = BTreeMap::new();
|
||||
witness.insert(FlatVariable::one(), T::one());
|
||||
|
||||
|
@ -44,7 +38,7 @@ impl Interpreter {
|
|||
|
||||
for statement in program.statements.iter() {
|
||||
match statement {
|
||||
Statement::Constraint(quad, lin, message) => match lin.is_assignee(&witness) {
|
||||
Statement::Constraint(quad, lin, error) => match lin.is_assignee(&witness) {
|
||||
true => {
|
||||
let val = quad.evaluate(&witness).unwrap();
|
||||
witness.insert(lin.0.get(0).unwrap().0, val);
|
||||
|
@ -54,12 +48,7 @@ impl Interpreter {
|
|||
let rhs_value = lin.evaluate(&witness).unwrap();
|
||||
if lhs_value != rhs_value {
|
||||
return Err(Error::UnsatisfiedConstraint {
|
||||
left: lhs_value.to_dec_string(),
|
||||
right: rhs_value.to_dec_string(),
|
||||
message: message
|
||||
.as_ref()
|
||||
.map(|m| m.to_string())
|
||||
.unwrap_or_else(|| "Unknown".to_string()),
|
||||
error: error.to_owned(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -274,34 +263,40 @@ impl<T: Field> LinComb<T> {
|
|||
|
||||
impl<T: Field> QuadComb<T> {
|
||||
pub fn evaluate(&self, witness: &BTreeMap<FlatVariable, T>) -> Result<T, EvaluationError> {
|
||||
let left = self.left.evaluate(&witness)?;
|
||||
let right = self.right.evaluate(&witness)?;
|
||||
let left = self.left.evaluate(witness)?;
|
||||
let right = self.right.evaluate(witness)?;
|
||||
Ok(left * right)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Serialize, Deserialize, Clone)]
|
||||
pub enum Error {
|
||||
UnsatisfiedConstraint {
|
||||
left: String,
|
||||
right: String,
|
||||
message: String,
|
||||
},
|
||||
UnsatisfiedConstraint { error: Option<RuntimeError> },
|
||||
Solver,
|
||||
WrongInputCount {
|
||||
expected: usize,
|
||||
received: usize,
|
||||
},
|
||||
WrongInputCount { expected: usize, received: usize },
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::UnsatisfiedConstraint {
|
||||
ref left,
|
||||
ref right,
|
||||
ref message,
|
||||
} => write!(f, "{}: expected {} to equal {}", message, left, right),
|
||||
Error::UnsatisfiedConstraint { ref error } => {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
error
|
||||
.as_ref()
|
||||
.map(|m| m.to_string())
|
||||
.expect("Found an unsatisfied constraint without an attached error.")
|
||||
)?;
|
||||
|
||||
match error {
|
||||
Some(e) if e.is_malicious() => {
|
||||
writeln!(f)?;
|
||||
write!(f, "The default ZoKrates interpreter should not yield this error. Please open an issue.")
|
||||
}
|
||||
_ => write!(f, ""),
|
||||
}
|
||||
}
|
||||
Error::Solver => write!(f, ""),
|
||||
Error::WrongInputCount { expected, received } => write!(
|
||||
f,
|
||||
|
|
|
@ -191,7 +191,7 @@ impl<T: Field> Folder<T> for RedefinitionOptimizer<T> {
|
|||
match lc
|
||||
.0
|
||||
.iter()
|
||||
.any(|(variable, _)| self.substitution.get(&variable).is_some())
|
||||
.any(|(variable, _)| self.substitution.get(variable).is_some())
|
||||
{
|
||||
true =>
|
||||
// for each summand, check if it is equal to a linear term in our substitution, otherwise keep it as is
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::fmt;
|
||||
|
||||
#[derive(Clone, PartialEq, Copy)]
|
||||
#[derive(Clone, PartialEq, Eq, Copy, Hash, Default, PartialOrd, Ord)]
|
||||
pub struct Position {
|
||||
pub line: usize,
|
||||
pub col: usize,
|
||||
|
|
|
@ -126,7 +126,7 @@ impl NonUniversalBackend<Bw6_761Field, GM17> for Ark {
|
|||
.vk
|
||||
.query
|
||||
.iter()
|
||||
.map(|g1| parse_g1::<Bw6_761Field>(g1))
|
||||
.map(parse_g1::<Bw6_761Field>)
|
||||
.collect(),
|
||||
};
|
||||
|
||||
|
|
|
@ -228,8 +228,8 @@ mod parse {
|
|||
let raw_e = e.to_string();
|
||||
let captures = G1_REGEX.captures(&raw_e).unwrap();
|
||||
G1Affine(
|
||||
captures.name(&"x").unwrap().as_str().to_string(),
|
||||
captures.name(&"y").unwrap().as_str().to_string(),
|
||||
captures.name("x").unwrap().as_str().to_string(),
|
||||
captures.name("y").unwrap().as_str().to_string(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -240,12 +240,12 @@ mod parse {
|
|||
let captures = G2_REGEX.captures(&raw_e).unwrap();
|
||||
G2Affine(
|
||||
(
|
||||
captures.name(&"x0").unwrap().as_str().to_string(),
|
||||
captures.name(&"x1").unwrap().as_str().to_string(),
|
||||
captures.name("x0").unwrap().as_str().to_string(),
|
||||
captures.name("x1").unwrap().as_str().to_string(),
|
||||
),
|
||||
(
|
||||
captures.name(&"y0").unwrap().as_str().to_string(),
|
||||
captures.name(&"y1").unwrap().as_str().to_string(),
|
||||
captures.name("y0").unwrap().as_str().to_string(),
|
||||
captures.name("y1").unwrap().as_str().to_string(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ mod parse {
|
|||
pub fn parse_fr<T: BellmanFieldExtensions>(e: &<T::BellmanEngine as ScalarEngine>::Fr) -> Fr {
|
||||
let raw_e = e.to_string();
|
||||
let captures = FR_REGEX.captures(&raw_e).unwrap();
|
||||
captures.name(&"x").unwrap().as_str().to_string()
|
||||
captures.name("x").unwrap().as_str().to_string()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -233,7 +233,7 @@ impl<'ast, T: Field> FunctionQuery<'ast, T> {
|
|||
.inputs
|
||||
.iter()
|
||||
.zip(func.signature.inputs.iter())
|
||||
.all(|(input_ty, sig_ty)| input_ty.can_be_specialized_to(&sig_ty))
|
||||
.all(|(input_ty, sig_ty)| input_ty.can_be_specialized_to(sig_ty))
|
||||
&& self.outputs.len() == func.signature.outputs.len()
|
||||
&& self
|
||||
.outputs
|
||||
|
@ -242,7 +242,7 @@ impl<'ast, T: Field> FunctionQuery<'ast, T> {
|
|||
.all(|(output_ty, sig_ty)| {
|
||||
output_ty
|
||||
.as_ref()
|
||||
.map(|output_ty| output_ty.can_be_specialized_to(&sig_ty))
|
||||
.map(|output_ty| output_ty.can_be_specialized_to(sig_ty))
|
||||
.unwrap_or(true)
|
||||
})
|
||||
}
|
||||
|
@ -378,7 +378,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
let ty = self.check_declaration_type(
|
||||
c.value.ty.clone(),
|
||||
module_id,
|
||||
&state,
|
||||
state,
|
||||
&BTreeMap::default(),
|
||||
&mut HashSet::default(),
|
||||
)?;
|
||||
|
@ -396,11 +396,10 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
UExpression::try_from_typed(checked_expr, &bitwidth).map(TypedExpression::from)
|
||||
}
|
||||
DeclarationType::Array(ref array_ty) => {
|
||||
ArrayExpression::try_from_typed(checked_expr, &array_ty).map(TypedExpression::from)
|
||||
ArrayExpression::try_from_typed(checked_expr, array_ty).map(TypedExpression::from)
|
||||
}
|
||||
DeclarationType::Struct(ref struct_ty) => {
|
||||
StructExpression::try_from_typed(checked_expr, &struct_ty)
|
||||
.map(TypedExpression::from)
|
||||
StructExpression::try_from_typed(checked_expr, struct_ty).map(TypedExpression::from)
|
||||
}
|
||||
DeclarationType::Int => Err(checked_expr), // Integers cannot be assigned
|
||||
}
|
||||
|
@ -1734,13 +1733,20 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
.map(|rhs| TypedStatement::Definition(var, rhs))
|
||||
.map_err(|e| vec![e])
|
||||
}
|
||||
Statement::Assertion(e) => {
|
||||
Statement::Assertion(e, message) => {
|
||||
let e = self
|
||||
.check_expression(e, module_id, types)
|
||||
.map_err(|e| vec![e])?;
|
||||
|
||||
match e {
|
||||
TypedExpression::Boolean(e) => Ok(TypedStatement::Assertion(e)),
|
||||
TypedExpression::Boolean(e) => Ok(TypedStatement::Assertion(
|
||||
e,
|
||||
RuntimeError::SourceAssertion(AssertionMetadata {
|
||||
file: module_id.display().to_string(),
|
||||
position: pos.0,
|
||||
message,
|
||||
}),
|
||||
)),
|
||||
e => Err(ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: format!(
|
||||
|
@ -1764,7 +1770,19 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
Statement::MultipleDefinition(assignees, rhs) => {
|
||||
match rhs.value {
|
||||
// Right side has to be a function call
|
||||
Expression::FunctionCall(fun_id, generics, arguments) => {
|
||||
Expression::FunctionCall(fun_id_expression, generics, arguments) => {
|
||||
|
||||
let fun_id = match fun_id_expression.value {
|
||||
Expression::Identifier(id) => Ok(id),
|
||||
e => Err(vec![ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: format!(
|
||||
"Expected function in function call to be an identifier, found {}",
|
||||
e
|
||||
),
|
||||
}])
|
||||
}?;
|
||||
|
||||
// check the generic arguments, if any
|
||||
let generics_checked: Option<Vec<Option<UExpression<'ast, T>>>> = generics
|
||||
.map(|generics|
|
||||
|
@ -1810,7 +1828,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
let arguments_types: Vec<_> =
|
||||
arguments_checked.iter().map(|a| a.get_type()).collect();
|
||||
|
||||
let query = FunctionQuery::new(&fun_id, &generics_checked, &arguments_types, &assignee_types);
|
||||
let query = FunctionQuery::new(fun_id, &generics_checked, &arguments_types, &assignee_types);
|
||||
|
||||
let functions = self.find_functions(&query);
|
||||
|
||||
|
@ -1856,7 +1874,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
let pos = assignee.pos();
|
||||
// check that the assignee is declared
|
||||
match assignee.value {
|
||||
Assignee::Identifier(variable_name) => match self.get_key_value_scope(&variable_name) {
|
||||
Assignee::Identifier(variable_name) => match self.get_key_value_scope(variable_name) {
|
||||
Some((id, ty)) => match id.is_constant() {
|
||||
true => Err(ErrorInner {
|
||||
pos: Some(assignee.pos()),
|
||||
|
@ -1992,7 +2010,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
Expression::Identifier(name) => {
|
||||
// check that `id` is defined in the scope
|
||||
match self
|
||||
.get_key_value_scope(&name)
|
||||
.get_key_value_scope(name)
|
||||
.map(|(x, y)| (x.clone(), y.clone()))
|
||||
{
|
||||
Some((id, ty)) => match ty {
|
||||
|
@ -2327,7 +2345,18 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
Expression::U16Constant(n) => Ok(UExpressionInner::Value(n.into()).annotate(16).into()),
|
||||
Expression::U32Constant(n) => Ok(UExpressionInner::Value(n.into()).annotate(32).into()),
|
||||
Expression::U64Constant(n) => Ok(UExpressionInner::Value(n.into()).annotate(64).into()),
|
||||
Expression::FunctionCall(fun_id, generics, arguments) => {
|
||||
Expression::FunctionCall(fun_id_expression, generics, arguments) => {
|
||||
let fun_id = match fun_id_expression.value {
|
||||
Expression::Identifier(id) => Ok(id),
|
||||
e => Err(ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: format!(
|
||||
"Expected function in function call to be an identifier, found `{}`",
|
||||
e
|
||||
),
|
||||
}),
|
||||
}?;
|
||||
|
||||
// check the generic arguments, if any
|
||||
let generics_checked: Option<Vec<Option<UExpression<'ast, T>>>> = generics
|
||||
.map(|generics| {
|
||||
|
@ -2370,7 +2399,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
// outside of multidef, function calls must have a single return value
|
||||
// we use type inference to determine the type of the return, so we don't specify it
|
||||
let query =
|
||||
FunctionQuery::new(&fun_id, &generics_checked, &arguments_types, &[None]);
|
||||
FunctionQuery::new(fun_id, &generics_checked, &arguments_types, &[None]);
|
||||
|
||||
let functions = self.find_functions(&query);
|
||||
|
||||
|
@ -2383,7 +2412,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
|
||||
let signature = f.signature;
|
||||
|
||||
let arguments_checked = arguments_checked.into_iter().zip(signature.inputs.iter()).map(|(a, t)| TypedExpression::align_to_type(a, &t)).collect::<Result<Vec<_>, _>>().map_err(|e| ErrorInner {
|
||||
let arguments_checked = arguments_checked.into_iter().zip(signature.inputs.iter()).map(|(a, t)| TypedExpression::align_to_type(a, t)).collect::<Result<Vec<_>, _>>().map_err(|e| ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: format!("Expected function call argument to be of type {}, found {}", e.1, e.0)
|
||||
})?;
|
||||
|
@ -3332,7 +3361,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
fn exit_scope(&mut self) {
|
||||
let current_level = self.level;
|
||||
self.scope
|
||||
.retain(|ref scoped_variable, _| scoped_variable.level < current_level);
|
||||
.retain(|scoped_variable, _| scoped_variable.level < current_level);
|
||||
self.level -= 1;
|
||||
}
|
||||
}
|
||||
|
@ -3859,22 +3888,20 @@ mod tests {
|
|||
.get(&*MODULE_ID)
|
||||
.unwrap()
|
||||
.functions_iter()
|
||||
.find(|d| d.key
|
||||
.any(|d| d.key
|
||||
== DeclarationFunctionKey::with_location((*MODULE_ID).clone(), "foo")
|
||||
.signature(DeclarationSignature::new()))
|
||||
.is_some());
|
||||
.signature(DeclarationSignature::new())));
|
||||
|
||||
assert!(state
|
||||
.typed_modules
|
||||
.get(&*MODULE_ID)
|
||||
.unwrap()
|
||||
.functions_iter()
|
||||
.find(|d| d.key
|
||||
.any(|d| d.key
|
||||
== DeclarationFunctionKey::with_location((*MODULE_ID).clone(), "foo")
|
||||
.signature(
|
||||
DeclarationSignature::new().inputs(vec![DeclarationType::FieldElement])
|
||||
))
|
||||
.is_some());
|
||||
)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -4525,7 +4552,8 @@ mod tests {
|
|||
.mock(),
|
||||
Statement::MultipleDefinition(
|
||||
vec![Assignee::Identifier("a").mock()],
|
||||
Expression::FunctionCall("foo", None, vec![]).mock(),
|
||||
Expression::FunctionCall(box Expression::Identifier("foo").mock(), None, vec![])
|
||||
.mock(),
|
||||
)
|
||||
.mock(),
|
||||
Statement::Return(
|
||||
|
@ -4582,9 +4610,15 @@ mod tests {
|
|||
Statement::Assertion(
|
||||
Expression::Eq(
|
||||
box Expression::IntConstant(2usize.into()).mock(),
|
||||
box Expression::FunctionCall("foo", None, vec![]).mock(),
|
||||
box Expression::FunctionCall(
|
||||
box Expression::Identifier("foo").mock(),
|
||||
None,
|
||||
vec![],
|
||||
)
|
||||
.mock(),
|
||||
)
|
||||
.mock(),
|
||||
None,
|
||||
)
|
||||
.mock(),
|
||||
Statement::Return(
|
||||
|
@ -4641,7 +4675,8 @@ mod tests {
|
|||
.mock(),
|
||||
Statement::MultipleDefinition(
|
||||
vec![Assignee::Identifier("a").mock()],
|
||||
Expression::FunctionCall("foo", None, vec![]).mock(),
|
||||
Expression::FunctionCall(box Expression::Identifier("foo").mock(), None, vec![])
|
||||
.mock(),
|
||||
)
|
||||
.mock(),
|
||||
Statement::Return(
|
||||
|
@ -4726,8 +4761,12 @@ mod tests {
|
|||
Assignee::Identifier("a").mock(),
|
||||
Assignee::Identifier("b").mock(),
|
||||
],
|
||||
Expression::FunctionCall("foo", None, vec![Expression::Identifier("x").mock()])
|
||||
.mock(),
|
||||
Expression::FunctionCall(
|
||||
box Expression::Identifier("foo").mock(),
|
||||
None,
|
||||
vec![Expression::Identifier("x").mock()],
|
||||
)
|
||||
.mock(),
|
||||
)
|
||||
.mock(),
|
||||
Statement::Return(
|
||||
|
@ -4815,7 +4854,8 @@ mod tests {
|
|||
Assignee::Identifier("a").mock(),
|
||||
Assignee::Identifier("b").mock(),
|
||||
],
|
||||
Expression::FunctionCall("foo", None, vec![]).mock(),
|
||||
Expression::FunctionCall(box Expression::Identifier("foo").mock(), None, vec![])
|
||||
.mock(),
|
||||
)
|
||||
.mock(),
|
||||
Statement::Return(
|
||||
|
@ -4930,7 +4970,8 @@ mod tests {
|
|||
),
|
||||
)
|
||||
.mock()],
|
||||
Expression::FunctionCall("foo", None, vec![]).mock(),
|
||||
Expression::FunctionCall(box Expression::Identifier("foo").mock(), None, vec![])
|
||||
.mock(),
|
||||
)
|
||||
.mock(),
|
||||
Statement::Return(
|
||||
|
@ -4982,9 +5023,15 @@ mod tests {
|
|||
Statement::Assertion(
|
||||
Expression::Eq(
|
||||
box Expression::IntConstant(1usize.into()).mock(),
|
||||
box Expression::FunctionCall("foo", None, vec![]).mock(),
|
||||
box Expression::FunctionCall(
|
||||
box Expression::Identifier("foo").mock(),
|
||||
None,
|
||||
vec![],
|
||||
)
|
||||
.mock(),
|
||||
)
|
||||
.mock(),
|
||||
None,
|
||||
)
|
||||
.mock(),
|
||||
Statement::Return(
|
||||
|
@ -5080,7 +5127,8 @@ mod tests {
|
|||
Assignee::Identifier("a").mock(),
|
||||
Assignee::Identifier("b").mock(),
|
||||
],
|
||||
Expression::FunctionCall("foo", None, vec![]).mock(),
|
||||
Expression::FunctionCall(box Expression::Identifier("foo").mock(), None, vec![])
|
||||
.mock(),
|
||||
)
|
||||
.mock(),
|
||||
Statement::Return(
|
||||
|
@ -6137,7 +6185,7 @@ mod tests {
|
|||
main.value.statements = vec![Statement::Return(
|
||||
ExpressionList {
|
||||
expressions: vec![Expression::FunctionCall(
|
||||
"foo",
|
||||
box Expression::Identifier("foo").mock(),
|
||||
None,
|
||||
vec![Expression::IntConstant(0usize.into()).mock()],
|
||||
)
|
||||
|
|
|
@ -379,9 +379,15 @@ fn fold_statement<'ast, T: Field>(
|
|||
typed_absy::TypedStatement::Declaration(..) => {
|
||||
unreachable!()
|
||||
}
|
||||
typed_absy::TypedStatement::Assertion(e) => {
|
||||
typed_absy::TypedStatement::Assertion(e, error) => {
|
||||
let e = f.fold_boolean_expression(statements_buffer, e);
|
||||
vec![zir::ZirStatement::Assertion(e)]
|
||||
let error = match error {
|
||||
typed_absy::RuntimeError::SourceAssertion(metadata) => {
|
||||
zir::RuntimeError::SourceAssertion(metadata.to_string())
|
||||
}
|
||||
typed_absy::RuntimeError::SelectRangeCheck => zir::RuntimeError::SelectRangeCheck,
|
||||
};
|
||||
vec![zir::ZirStatement::Assertion(e, error)]
|
||||
}
|
||||
typed_absy::TypedStatement::For(..) => unreachable!(),
|
||||
typed_absy::TypedStatement::MultipleDefinition(variables, elist) => {
|
||||
|
|
|
@ -22,6 +22,7 @@ pub type Constants<'ast, T> = HashMap<Identifier<'ast>, TypedExpression<'ast, T>
|
|||
pub enum Error {
|
||||
Type(String),
|
||||
AssertionFailed(String),
|
||||
ValueTooLarge(String),
|
||||
OutOfBounds(u128, u128),
|
||||
NonConstantExponent(String),
|
||||
}
|
||||
|
@ -31,6 +32,7 @@ impl fmt::Display for Error {
|
|||
match self {
|
||||
Error::Type(s) => write!(f, "{}", s),
|
||||
Error::AssertionFailed(s) => write!(f, "{}", s),
|
||||
Error::ValueTooLarge(s) => write!(f, "{}", s),
|
||||
Error::OutOfBounds(index, size) => write!(
|
||||
f,
|
||||
"Out of bounds index ({} >= {}) found during static analysis",
|
||||
|
@ -79,7 +81,7 @@ impl<'ast, 'a, T: Field> Propagator<'ast, 'a, T> {
|
|||
.map(|c| Ok((var, c)))
|
||||
.unwrap_or(Err(var)),
|
||||
TypedAssignee::Select(box assignee, box index) => {
|
||||
match self.try_get_constant_mut(&assignee) {
|
||||
match self.try_get_constant_mut(assignee) {
|
||||
Ok((variable, constant)) => match index.as_inner() {
|
||||
UExpressionInner::Value(n) => match constant {
|
||||
TypedExpression::Array(a) => match a.as_inner_mut() {
|
||||
|
@ -101,7 +103,7 @@ impl<'ast, 'a, T: Field> Propagator<'ast, 'a, T> {
|
|||
e => e,
|
||||
}
|
||||
}
|
||||
TypedAssignee::Member(box assignee, m) => match self.try_get_constant_mut(&assignee) {
|
||||
TypedAssignee::Member(box assignee, m) => match self.try_get_constant_mut(assignee) {
|
||||
Ok((v, c)) => {
|
||||
let ty = assignee.get_type();
|
||||
|
||||
|
@ -381,47 +383,47 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
match arguments.iter().all(|a| a.is_constant()) {
|
||||
true => {
|
||||
let r: Option<TypedExpression<'ast, T>> = match embed {
|
||||
FlatEmbed::BitArrayLe => None, // todo
|
||||
FlatEmbed::U64FromBits => Some(process_u_from_bits(
|
||||
FlatEmbed::BitArrayLe => Ok(None), // todo
|
||||
FlatEmbed::U64FromBits => Ok(Some(process_u_from_bits(
|
||||
assignees.clone(),
|
||||
arguments.clone(),
|
||||
UBitwidth::B64,
|
||||
)),
|
||||
FlatEmbed::U32FromBits => Some(process_u_from_bits(
|
||||
))),
|
||||
FlatEmbed::U32FromBits => Ok(Some(process_u_from_bits(
|
||||
assignees.clone(),
|
||||
arguments.clone(),
|
||||
UBitwidth::B32,
|
||||
)),
|
||||
FlatEmbed::U16FromBits => Some(process_u_from_bits(
|
||||
))),
|
||||
FlatEmbed::U16FromBits => Ok(Some(process_u_from_bits(
|
||||
assignees.clone(),
|
||||
arguments.clone(),
|
||||
UBitwidth::B16,
|
||||
)),
|
||||
FlatEmbed::U8FromBits => Some(process_u_from_bits(
|
||||
))),
|
||||
FlatEmbed::U8FromBits => Ok(Some(process_u_from_bits(
|
||||
assignees.clone(),
|
||||
arguments.clone(),
|
||||
UBitwidth::B8,
|
||||
)),
|
||||
FlatEmbed::U64ToBits => Some(process_u_to_bits(
|
||||
))),
|
||||
FlatEmbed::U64ToBits => Ok(Some(process_u_to_bits(
|
||||
assignees.clone(),
|
||||
arguments.clone(),
|
||||
UBitwidth::B64,
|
||||
)),
|
||||
FlatEmbed::U32ToBits => Some(process_u_to_bits(
|
||||
))),
|
||||
FlatEmbed::U32ToBits => Ok(Some(process_u_to_bits(
|
||||
assignees.clone(),
|
||||
arguments.clone(),
|
||||
UBitwidth::B32,
|
||||
)),
|
||||
FlatEmbed::U16ToBits => Some(process_u_to_bits(
|
||||
))),
|
||||
FlatEmbed::U16ToBits => Ok(Some(process_u_to_bits(
|
||||
assignees.clone(),
|
||||
arguments.clone(),
|
||||
UBitwidth::B16,
|
||||
)),
|
||||
FlatEmbed::U8ToBits => Some(process_u_to_bits(
|
||||
))),
|
||||
FlatEmbed::U8ToBits => Ok(Some(process_u_to_bits(
|
||||
assignees.clone(),
|
||||
arguments.clone(),
|
||||
UBitwidth::B8,
|
||||
)),
|
||||
))),
|
||||
FlatEmbed::Unpack => {
|
||||
assert_eq!(assignees.len(), 1);
|
||||
assert_eq!(arguments.len(), 1);
|
||||
|
@ -429,46 +431,55 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
|
||||
let bit_width = generics[0];
|
||||
|
||||
match FieldElementExpression::try_from(arguments[0].clone())
|
||||
.unwrap()
|
||||
match FieldElementExpression::<T>::try_from(
|
||||
arguments[0].clone(),
|
||||
)
|
||||
.unwrap()
|
||||
{
|
||||
FieldElementExpression::Number(num) => {
|
||||
let mut num = num;
|
||||
let mut acc = num.clone();
|
||||
let mut res = vec![];
|
||||
|
||||
for i in (0..bit_width as usize).rev() {
|
||||
if T::from(2).pow(i) <= num {
|
||||
num = num - T::from(2).pow(i);
|
||||
if T::from(2).pow(i) <= acc {
|
||||
acc = acc - T::from(2).pow(i);
|
||||
res.push(true);
|
||||
} else {
|
||||
res.push(false);
|
||||
}
|
||||
}
|
||||
assert_eq!(num, T::zero());
|
||||
|
||||
Some(
|
||||
ArrayExpressionInner::Value(
|
||||
res.into_iter()
|
||||
.map(|v| {
|
||||
BooleanExpression::Value(v).into()
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
)
|
||||
.annotate(Type::Boolean, bit_width)
|
||||
.into(),
|
||||
)
|
||||
if acc != T::zero() {
|
||||
Err(Error::ValueTooLarge(format!(
|
||||
"Cannot unpack `{}` to `{}`: value is too large",
|
||||
num, assignees.first().unwrap().get_type()
|
||||
)))
|
||||
} else {
|
||||
Ok(Some(
|
||||
ArrayExpressionInner::Value(
|
||||
res.into_iter()
|
||||
.map(|v| {
|
||||
BooleanExpression::Value(v)
|
||||
.into()
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
)
|
||||
.annotate(Type::Boolean, bit_width)
|
||||
.into(),
|
||||
))
|
||||
}
|
||||
}
|
||||
_ => unreachable!("should be a field value"),
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "bellman")]
|
||||
FlatEmbed::Sha256Round => None,
|
||||
FlatEmbed::Sha256Round => Ok(None),
|
||||
#[cfg(feature = "ark")]
|
||||
FlatEmbed::SnarkVerifyBls12377 => None,
|
||||
};
|
||||
FlatEmbed::SnarkVerifyBls12377 => Ok(None),
|
||||
}?;
|
||||
|
||||
match r {
|
||||
Ok(match r {
|
||||
// if the function call returns a constant
|
||||
Some(expr) => {
|
||||
let mut assignees = assignees;
|
||||
|
@ -494,9 +505,11 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
assignee, expr,
|
||||
),
|
||||
],
|
||||
None => vec![TypedStatement::Definition(
|
||||
assignee, expr,
|
||||
)],
|
||||
None => {
|
||||
vec![TypedStatement::Definition(
|
||||
assignee, expr,
|
||||
)]
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -534,7 +547,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
)],
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
false => {
|
||||
// if the function arguments are not constant, invalidate the cache
|
||||
|
@ -548,7 +561,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
|
||||
let invalidations = assignees.iter().flat_map(|assignee| {
|
||||
let v = self
|
||||
.try_get_constant_mut(&assignee)
|
||||
.try_get_constant_mut(assignee)
|
||||
.map(|(v, _)| v)
|
||||
.unwrap_or_else(|v| v);
|
||||
match self.constants.remove(&v.id) {
|
||||
|
@ -559,7 +572,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
}
|
||||
});
|
||||
|
||||
invalidations.chain(std::iter::once(def)).collect()
|
||||
Ok(invalidations.chain(std::iter::once(def)).collect())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -590,7 +603,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
|
||||
let invalidations = assignees.iter().flat_map(|assignee| {
|
||||
let v = self
|
||||
.try_get_constant_mut(&assignee)
|
||||
.try_get_constant_mut(assignee)
|
||||
.map(|(v, _)| v)
|
||||
.unwrap_or_else(|v| v);
|
||||
match self.constants.remove(&v.id) {
|
||||
|
@ -601,21 +614,20 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
}
|
||||
});
|
||||
|
||||
invalidations.chain(std::iter::once(def)).collect()
|
||||
Ok(invalidations.chain(std::iter::once(def)).collect())
|
||||
}
|
||||
};
|
||||
}?;
|
||||
|
||||
Ok(statements)
|
||||
}
|
||||
TypedStatement::Assertion(e) => {
|
||||
TypedStatement::Assertion(e, ty) => {
|
||||
let e_str = e.to_string();
|
||||
let expr = self.fold_boolean_expression(e)?;
|
||||
match expr {
|
||||
BooleanExpression::Value(v) if !v => Err(Error::AssertionFailed(format!(
|
||||
"Assertion failed on expression `{}`",
|
||||
e_str
|
||||
))),
|
||||
_ => Ok(vec![TypedStatement::Assertion(expr)]),
|
||||
BooleanExpression::Value(v) if !v => {
|
||||
Err(Error::AssertionFailed(format!("{}: ({})", ty, e_str)))
|
||||
}
|
||||
_ => Ok(vec![TypedStatement::Assertion(expr, ty)]),
|
||||
}
|
||||
}
|
||||
s @ TypedStatement::PushCallLog(..) => Ok(vec![s]),
|
||||
|
@ -971,7 +983,10 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
}
|
||||
|
||||
fn fold_select_expression<
|
||||
E: Expr<'ast, T> + Select<'ast, T> + From<TypedExpression<'ast, T>>,
|
||||
E: Expr<'ast, T>
|
||||
+ Select<'ast, T>
|
||||
+ From<TypedExpression<'ast, T>>
|
||||
+ Into<TypedExpression<'ast, T>>,
|
||||
>(
|
||||
&mut self,
|
||||
_: &E::Ty,
|
||||
|
@ -988,12 +1003,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
(ArrayExpressionInner::Value(v), UExpressionInner::Value(n)) => {
|
||||
if n < size {
|
||||
Ok(SelectOrExpression::Expression(
|
||||
E::from(
|
||||
v.expression_at::<StructExpression<'ast, T>>(n as usize)
|
||||
.unwrap()
|
||||
.clone(),
|
||||
)
|
||||
.into_inner(),
|
||||
v.expression_at::<E>(n as usize).unwrap().into_inner(),
|
||||
))
|
||||
} else {
|
||||
Err(Error::OutOfBounds(n, size))
|
||||
|
@ -1005,14 +1015,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
TypedExpression::Array(a) => match a.as_inner() {
|
||||
ArrayExpressionInner::Value(v) => {
|
||||
Ok(SelectOrExpression::Expression(
|
||||
E::from(
|
||||
v.expression_at::<StructExpression<'ast, T>>(
|
||||
n as usize,
|
||||
)
|
||||
.unwrap()
|
||||
.clone(),
|
||||
)
|
||||
.into_inner(),
|
||||
v.expression_at::<E>(n as usize).unwrap().into_inner(),
|
||||
))
|
||||
}
|
||||
_ => unreachable!("should be an array value"),
|
||||
|
|
|
@ -69,7 +69,7 @@ fn get_canonical_function<'ast, T: Field>(
|
|||
.unwrap();
|
||||
|
||||
match &s.symbol {
|
||||
TypedFunctionSymbol::There(key) => get_canonical_function(key.clone(), &program),
|
||||
TypedFunctionSymbol::There(key) => get_canonical_function(key.clone(), program),
|
||||
_ => s.clone(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -161,7 +161,7 @@ fn register<'ast>(
|
|||
) {
|
||||
for (id, key, value) in substitute
|
||||
.iter()
|
||||
.filter_map(|(id, version)| with.get(&id).map(|to| (id, version, to)))
|
||||
.filter_map(|(id, version)| with.get(id).map(|to| (id, version, to)))
|
||||
.filter(|(_, key, value)| key != value)
|
||||
{
|
||||
let sub = substitutions.0.entry(id.clone()).or_default();
|
||||
|
@ -235,8 +235,8 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> {
|
|||
generics,
|
||||
arguments,
|
||||
ty,
|
||||
&self.program,
|
||||
&mut self.versions,
|
||||
self.program,
|
||||
self.versions,
|
||||
);
|
||||
|
||||
match res {
|
||||
|
@ -354,8 +354,8 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> {
|
|||
generics,
|
||||
arguments,
|
||||
&types,
|
||||
&self.program,
|
||||
&mut self.versions,
|
||||
self.program,
|
||||
self.versions,
|
||||
) {
|
||||
Ok(Output::Complete((statements, expressions))) => {
|
||||
assert_eq!(v.len(), expressions.len());
|
||||
|
@ -420,7 +420,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> {
|
|||
self.versions.values_mut().for_each(|v| *v += 1);
|
||||
|
||||
// add this set of versions to the substitution, pointing to the versions before the loop
|
||||
register(&mut self.substitutions, &self.versions, &versions_before);
|
||||
register(self.substitutions, self.versions, &versions_before);
|
||||
|
||||
// the versions after the loop are found by applying an offset of 2 to the versions before the loop
|
||||
let versions_after = versions_before
|
||||
|
@ -429,7 +429,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> {
|
|||
.map(|(k, v)| (k, v + 2))
|
||||
.collect();
|
||||
|
||||
let mut transformer = ShallowTransformer::with_versions(&mut self.versions);
|
||||
let mut transformer = ShallowTransformer::with_versions(self.versions);
|
||||
|
||||
if to - from > MAX_FOR_LOOP_SIZE {
|
||||
return Err(Error::LoopTooLarge(to.saturating_sub(*from)));
|
||||
|
@ -454,7 +454,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> {
|
|||
|
||||
// we know the final versions of the variables after full unrolling of the loop
|
||||
// the versions after the loop need to point to these, so we add to the substitutions
|
||||
register(&mut self.substitutions, &versions_after, &self.versions);
|
||||
register(self.substitutions, &versions_after, self.versions);
|
||||
|
||||
// we may have found new for loops when unrolling this one, which means new backed up versions
|
||||
// we insert these in our backup list and update our cursor
|
||||
|
@ -573,7 +573,7 @@ fn reduce_function<'ast, T: Field>(
|
|||
|
||||
loop {
|
||||
let mut reducer = Reducer::new(
|
||||
&program,
|
||||
program,
|
||||
&mut versions,
|
||||
&mut substitutions,
|
||||
for_loop_versions,
|
||||
|
|
|
@ -531,7 +531,7 @@ impl<'ast, T: Field> Folder<'ast, T> for UintOptimizer<'ast, T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
ZirStatement::Assertion(BooleanExpression::UintEq(box left, box right)) => {
|
||||
ZirStatement::Assertion(BooleanExpression::UintEq(box left, box right), metadata) => {
|
||||
let left = self.fold_uint_expression(left);
|
||||
let right = self.fold_uint_expression(right);
|
||||
|
||||
|
@ -539,9 +539,10 @@ impl<'ast, T: Field> Folder<'ast, T> for UintOptimizer<'ast, T> {
|
|||
let left = force_reduce(left);
|
||||
let right = force_reduce(right);
|
||||
|
||||
vec![ZirStatement::Assertion(BooleanExpression::UintEq(
|
||||
box left, box right,
|
||||
))]
|
||||
vec![ZirStatement::Assertion(
|
||||
BooleanExpression::UintEq(box left, box right),
|
||||
metadata,
|
||||
)]
|
||||
}
|
||||
s => fold_statement(self, s),
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ impl fmt::Display for Error {
|
|||
impl UnconstrainedVariableDetector {
|
||||
pub fn detect<T: Field>(p: &Prog<T>) -> Result<(), Error> {
|
||||
let mut instance = Self::default();
|
||||
instance.visit_module(&p);
|
||||
instance.visit_module(p);
|
||||
|
||||
if instance.variables.is_empty() {
|
||||
Ok(())
|
||||
|
@ -118,39 +118,39 @@ mod tests {
|
|||
// (1 * ~one) * (1 * ~one + (-1) * _1) == 1 * ~out_0
|
||||
// return ~out_0
|
||||
|
||||
let _0 = FlatParameter::private(FlatVariable::new(0));
|
||||
let _1 = FlatVariable::new(1);
|
||||
let _2 = FlatVariable::new(2);
|
||||
let v_0 = FlatParameter::private(FlatVariable::new(0));
|
||||
let v_1 = FlatVariable::new(1);
|
||||
let v_2 = FlatVariable::new(2);
|
||||
|
||||
let out_0 = FlatVariable::public(0);
|
||||
let one = FlatVariable::one();
|
||||
|
||||
let p: Prog<Bn128Field> = Prog {
|
||||
arguments: vec![_0],
|
||||
arguments: vec![v_0],
|
||||
statements: vec![
|
||||
Statement::Directive(Directive {
|
||||
inputs: vec![(LinComb::summand(-42, one) + LinComb::summand(1, _0.id)).into()],
|
||||
outputs: vec![_1, _2],
|
||||
inputs: vec![(LinComb::summand(-42, one) + LinComb::summand(1, v_0.id)).into()],
|
||||
outputs: vec![v_1, v_2],
|
||||
solver: Solver::ConditionEq,
|
||||
}),
|
||||
Statement::constraint(
|
||||
QuadComb::from_linear_combinations(
|
||||
LinComb::summand(-42, one) + LinComb::summand(1, _0.id),
|
||||
LinComb::summand(1, _2),
|
||||
LinComb::summand(-42, one) + LinComb::summand(1, v_0.id),
|
||||
LinComb::summand(1, v_2),
|
||||
),
|
||||
LinComb::summand(1, _1),
|
||||
LinComb::summand(1, v_1),
|
||||
),
|
||||
Statement::constraint(
|
||||
QuadComb::from_linear_combinations(
|
||||
LinComb::summand(1, one) + LinComb::summand(-1, _1),
|
||||
LinComb::summand(-42, one) + LinComb::summand(1, _0.id),
|
||||
LinComb::summand(1, one) + LinComb::summand(-1, v_1),
|
||||
LinComb::summand(-42, one) + LinComb::summand(1, v_0.id),
|
||||
),
|
||||
LinComb::zero(),
|
||||
),
|
||||
Statement::constraint(
|
||||
QuadComb::from_linear_combinations(
|
||||
LinComb::summand(1, one),
|
||||
LinComb::summand(1, one) + LinComb::summand(-1, _1),
|
||||
LinComb::summand(1, one) + LinComb::summand(-1, v_1),
|
||||
),
|
||||
LinComb::summand(1, out_0),
|
||||
),
|
||||
|
|
|
@ -49,6 +49,7 @@ impl<'ast> VariableWriteRemover {
|
|||
Access::Select(head) => {
|
||||
statements.insert(TypedStatement::Assertion(
|
||||
BooleanExpression::UintLt(box head.clone(), box size.into()),
|
||||
RuntimeError::SelectRangeCheck,
|
||||
));
|
||||
|
||||
ArrayExpressionInner::Value(
|
||||
|
|
|
@ -2,8 +2,8 @@ use crate::zir::result_folder::fold_statement;
|
|||
use crate::zir::result_folder::ResultFolder;
|
||||
use crate::zir::types::UBitwidth;
|
||||
use crate::zir::{
|
||||
BooleanExpression, FieldElementExpression, Identifier, UExpression, UExpressionInner,
|
||||
ZirExpression, ZirProgram, ZirStatement,
|
||||
BooleanExpression, FieldElementExpression, Identifier, RuntimeError, UExpression,
|
||||
UExpressionInner, ZirExpression, ZirProgram, ZirStatement,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
|
@ -15,6 +15,7 @@ type Constants<'ast, T> = HashMap<Identifier<'ast>, ZirExpression<'ast, T>>;
|
|||
pub enum Error {
|
||||
OutOfBounds(u128, u128),
|
||||
DivisionByZero,
|
||||
AssertionFailed(RuntimeError),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
|
@ -28,6 +29,7 @@ impl fmt::Display for Error {
|
|||
Error::DivisionByZero => {
|
||||
write!(f, "Division by zero detected in zir during static analysis",)
|
||||
}
|
||||
Error::AssertionFailed(err) => write!(f, "{}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,9 +53,10 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> {
|
|||
s: ZirStatement<'ast, T>,
|
||||
) -> Result<Vec<ZirStatement<'ast, T>>, Self::Error> {
|
||||
match s {
|
||||
ZirStatement::Assertion(e) => match self.fold_boolean_expression(e)? {
|
||||
ZirStatement::Assertion(e, error) => match self.fold_boolean_expression(e)? {
|
||||
BooleanExpression::Value(true) => Ok(vec![]),
|
||||
e => Ok(vec![ZirStatement::Assertion(e)]),
|
||||
BooleanExpression::Value(false) => Err(Error::AssertionFailed(error)),
|
||||
e => Ok(vec![ZirStatement::Assertion(e, error)]),
|
||||
},
|
||||
ZirStatement::Definition(a, e) => {
|
||||
let e = self.fold_expression(e)?;
|
||||
|
@ -654,21 +657,31 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::zir::RuntimeError;
|
||||
use zokrates_field::Bn128Field;
|
||||
|
||||
impl RuntimeError {
|
||||
pub fn mock() -> Self {
|
||||
RuntimeError::SourceAssertion(String::default())
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn propagation() {
|
||||
// assert([x, 1] == [y, 1])
|
||||
let statements = vec![ZirStatement::Assertion(BooleanExpression::And(
|
||||
box BooleanExpression::FieldEq(
|
||||
box FieldElementExpression::Identifier("x".into()),
|
||||
box FieldElementExpression::Identifier("y".into()),
|
||||
let statements = vec![ZirStatement::Assertion(
|
||||
BooleanExpression::And(
|
||||
box BooleanExpression::FieldEq(
|
||||
box FieldElementExpression::Identifier("x".into()),
|
||||
box FieldElementExpression::Identifier("y".into()),
|
||||
),
|
||||
box BooleanExpression::FieldEq(
|
||||
box FieldElementExpression::Number(Bn128Field::from(1)),
|
||||
box FieldElementExpression::Number(Bn128Field::from(1)),
|
||||
),
|
||||
),
|
||||
box BooleanExpression::FieldEq(
|
||||
box FieldElementExpression::Number(Bn128Field::from(1)),
|
||||
box FieldElementExpression::Number(Bn128Field::from(1)),
|
||||
),
|
||||
))];
|
||||
RuntimeError::mock(),
|
||||
)];
|
||||
|
||||
let mut propagator = ZirPropagator::default();
|
||||
let statements: Vec<ZirStatement<_>> = statements
|
||||
|
@ -682,10 +695,13 @@ mod tests {
|
|||
|
||||
assert_eq!(
|
||||
statements,
|
||||
vec![ZirStatement::Assertion(BooleanExpression::FieldEq(
|
||||
box FieldElementExpression::Identifier("x".into()),
|
||||
box FieldElementExpression::Identifier("y".into()),
|
||||
))]
|
||||
vec![ZirStatement::Assertion(
|
||||
BooleanExpression::FieldEq(
|
||||
box FieldElementExpression::Identifier("x".into()),
|
||||
box FieldElementExpression::Identifier("y".into()),
|
||||
),
|
||||
RuntimeError::mock()
|
||||
)]
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -461,7 +461,9 @@ pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
TypedStatement::Definition(f.fold_assignee(a), f.fold_expression(e))
|
||||
}
|
||||
TypedStatement::Declaration(v) => TypedStatement::Declaration(f.fold_variable(v)),
|
||||
TypedStatement::Assertion(e) => TypedStatement::Assertion(f.fold_boolean_expression(e)),
|
||||
TypedStatement::Assertion(e, error) => {
|
||||
TypedStatement::Assertion(f.fold_boolean_expression(e), error)
|
||||
}
|
||||
TypedStatement::For(v, from, to, statements) => TypedStatement::For(
|
||||
f.fold_variable(v),
|
||||
f.fold_uint_expression(from),
|
||||
|
|
|
@ -600,7 +600,7 @@ impl<'ast, T: Field> ArrayExpression<'ast, T> {
|
|||
inline_array
|
||||
.into_iter()
|
||||
.map(|v| {
|
||||
TypedExpressionOrSpread::align_to_type(v, &target_array_ty).map_err(
|
||||
TypedExpressionOrSpread::align_to_type(v, target_array_ty).map_err(
|
||||
|(e, _)| match e {
|
||||
TypedExpressionOrSpread::Expression(e) => e,
|
||||
TypedExpressionOrSpread::Spread(a) => {
|
||||
|
@ -623,7 +623,7 @@ impl<'ast, T: Field> ArrayExpression<'ast, T> {
|
|||
GType::Int => Ok(ArrayExpressionInner::Repeat(box e, box count)
|
||||
.annotate(Type::Int, array_ty.size)),
|
||||
// try to align the repeated element to the target type
|
||||
t => TypedExpression::align_to_type(e, &t)
|
||||
t => TypedExpression::align_to_type(e, t)
|
||||
.map(|e| {
|
||||
let ty = e.get_type().clone();
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ pub use self::types::{
|
|||
DeclarationSignature, DeclarationStructType, DeclarationType, GArrayType, GStructType, GType,
|
||||
GenericIdentifier, IntoTypes, Signature, StructType, Type, Types, UBitwidth,
|
||||
};
|
||||
use crate::parser::Position;
|
||||
use crate::typed_absy::types::ConcreteGenericsAssignment;
|
||||
|
||||
pub use self::variable::{ConcreteVariable, DeclarationVariable, GVariable, Variable};
|
||||
|
@ -263,7 +264,7 @@ impl<'ast, T: Field> TypedFunctionSymbol<'ast, T> {
|
|||
.find(|d| d.key == *key)
|
||||
.unwrap()
|
||||
.symbol
|
||||
.signature(&modules),
|
||||
.signature(modules),
|
||||
TypedFunctionSymbol::Flat(flat_fun) => flat_fun.typed_signature(),
|
||||
}
|
||||
}
|
||||
|
@ -575,6 +576,38 @@ impl<'ast, T: fmt::Display> fmt::Display for TypedAssignee<'ast, T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Hash, Eq, Default, PartialOrd, Ord)]
|
||||
pub struct AssertionMetadata {
|
||||
pub file: String,
|
||||
pub position: Position,
|
||||
pub message: Option<String>,
|
||||
}
|
||||
|
||||
impl fmt::Display for AssertionMetadata {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Assertion failed at {}:{}", self.file, self.position)?;
|
||||
match &self.message {
|
||||
Some(m) => write!(f, ": \"{}\"", m),
|
||||
None => write!(f, ""),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Hash, Eq, PartialOrd, Ord)]
|
||||
pub enum RuntimeError {
|
||||
SourceAssertion(AssertionMetadata),
|
||||
SelectRangeCheck,
|
||||
}
|
||||
|
||||
impl fmt::Display for RuntimeError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
RuntimeError::SourceAssertion(metadata) => write!(f, "{}", metadata),
|
||||
RuntimeError::SelectRangeCheck => write!(f, "Range check on array access"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A statement in a `TypedFunction`
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[derive(Clone, PartialEq, Debug, Hash, Eq, PartialOrd, Ord)]
|
||||
|
@ -582,7 +615,7 @@ pub enum TypedStatement<'ast, T> {
|
|||
Return(Vec<TypedExpression<'ast, T>>),
|
||||
Definition(TypedAssignee<'ast, T>, TypedExpression<'ast, T>),
|
||||
Declaration(Variable<'ast, T>),
|
||||
Assertion(BooleanExpression<'ast, T>),
|
||||
Assertion(BooleanExpression<'ast, T>, RuntimeError),
|
||||
For(
|
||||
Variable<'ast, T>,
|
||||
UExpression<'ast, T>,
|
||||
|
@ -630,7 +663,16 @@ impl<'ast, T: fmt::Display> fmt::Display for TypedStatement<'ast, T> {
|
|||
}
|
||||
TypedStatement::Declaration(ref var) => write!(f, "{}", var),
|
||||
TypedStatement::Definition(ref lhs, ref rhs) => write!(f, "{} = {}", lhs, rhs),
|
||||
TypedStatement::Assertion(ref e) => write!(f, "assert({})", e),
|
||||
TypedStatement::Assertion(ref e, ref error) => {
|
||||
write!(f, "assert({}", e)?;
|
||||
match error {
|
||||
RuntimeError::SourceAssertion(metadata) => match &metadata.message {
|
||||
Some(m) => write!(f, ", \"{}\")", m),
|
||||
None => write!(f, ")"),
|
||||
},
|
||||
error => write!(f, ") // {}", error),
|
||||
}
|
||||
}
|
||||
TypedStatement::For(ref var, ref start, ref stop, ref list) => {
|
||||
writeln!(f, "for {} in {}..{} do", var, start, stop)?;
|
||||
for l in list {
|
||||
|
@ -1161,31 +1203,29 @@ impl<'ast, T> IntoIterator for ArrayValue<'ast, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Clone> ArrayValue<'ast, T> {
|
||||
fn expression_at_aux<U: Select<'ast, T> + Into<TypedExpression<'ast, T>>>(
|
||||
impl<'ast, T: Clone + fmt::Debug> ArrayValue<'ast, T> {
|
||||
fn expression_at_aux<
|
||||
U: Select<'ast, T> + Into<TypedExpression<'ast, T>> + From<TypedExpression<'ast, T>>,
|
||||
>(
|
||||
v: TypedExpressionOrSpread<'ast, T>,
|
||||
) -> Vec<Option<TypedExpression<'ast, T>>> {
|
||||
) -> Vec<Option<U>> {
|
||||
match v {
|
||||
TypedExpressionOrSpread::Expression(e) => vec![Some(e.clone())],
|
||||
TypedExpressionOrSpread::Expression(e) => vec![Some(e.into())],
|
||||
TypedExpressionOrSpread::Spread(s) => match s.array.size().into_inner() {
|
||||
UExpressionInner::Value(size) => {
|
||||
let array_ty = s.array.ty().clone();
|
||||
|
||||
match s.array.into_inner() {
|
||||
ArrayExpressionInner::Value(v) => v
|
||||
.into_iter()
|
||||
.flat_map(Self::expression_at_aux::<U>)
|
||||
.collect(),
|
||||
ArrayExpressionInner::Value(v) => {
|
||||
v.into_iter().flat_map(Self::expression_at_aux).collect()
|
||||
}
|
||||
a => (0..size)
|
||||
.map(|i| {
|
||||
Some(
|
||||
U::select(
|
||||
a.clone()
|
||||
.annotate(*array_ty.ty.clone(), array_ty.size.clone()),
|
||||
i as u32,
|
||||
)
|
||||
.into(),
|
||||
)
|
||||
Some(U::select(
|
||||
a.clone()
|
||||
.annotate(*array_ty.ty.clone(), array_ty.size.clone()),
|
||||
i as u32,
|
||||
))
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
|
@ -1195,13 +1235,15 @@ impl<'ast, T: Clone> ArrayValue<'ast, T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn expression_at<U: Select<'ast, T> + Into<TypedExpression<'ast, T>>>(
|
||||
pub fn expression_at<
|
||||
U: Select<'ast, T> + Into<TypedExpression<'ast, T>> + From<TypedExpression<'ast, T>>,
|
||||
>(
|
||||
&self,
|
||||
index: usize,
|
||||
) -> Option<TypedExpression<'ast, T>> {
|
||||
) -> Option<U> {
|
||||
self.0
|
||||
.iter()
|
||||
.map(|v| Self::expression_at_aux::<U>(v.clone()))
|
||||
.map(|v| Self::expression_at_aux(v.clone()))
|
||||
.flatten()
|
||||
.take_while(|e| e.is_some())
|
||||
.map(|e| e.unwrap())
|
||||
|
@ -1608,7 +1650,7 @@ impl<'ast, T: Clone> Expr<'ast, T> for FieldElementExpression<'ast, T> {
|
|||
}
|
||||
|
||||
fn as_inner(&self) -> &Self::Inner {
|
||||
&self
|
||||
self
|
||||
}
|
||||
|
||||
fn as_inner_mut(&mut self) -> &mut Self::Inner {
|
||||
|
@ -1629,7 +1671,7 @@ impl<'ast, T: Clone> Expr<'ast, T> for BooleanExpression<'ast, T> {
|
|||
}
|
||||
|
||||
fn as_inner(&self) -> &Self::Inner {
|
||||
&self
|
||||
self
|
||||
}
|
||||
|
||||
fn as_inner_mut(&mut self) -> &mut Self::Inner {
|
||||
|
@ -1713,7 +1755,7 @@ impl<'ast, T: Clone> Expr<'ast, T> for IntExpression<'ast, T> {
|
|||
}
|
||||
|
||||
fn as_inner(&self) -> &Self::Inner {
|
||||
&self
|
||||
self
|
||||
}
|
||||
|
||||
fn as_inner_mut(&mut self) -> &mut Self::Inner {
|
||||
|
|
|
@ -212,7 +212,10 @@ pub trait ResultFolder<'ast, T: Field>: Sized {
|
|||
}
|
||||
|
||||
fn fold_select_expression<
|
||||
E: Expr<'ast, T> + Select<'ast, T> + From<TypedExpression<'ast, T>>,
|
||||
E: Expr<'ast, T>
|
||||
+ Select<'ast, T>
|
||||
+ From<TypedExpression<'ast, T>>
|
||||
+ Into<TypedExpression<'ast, T>>,
|
||||
>(
|
||||
&mut self,
|
||||
ty: &E::Ty,
|
||||
|
@ -455,7 +458,9 @@ pub fn fold_statement<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
|||
TypedStatement::Definition(f.fold_assignee(a)?, f.fold_expression(e)?)
|
||||
}
|
||||
TypedStatement::Declaration(v) => TypedStatement::Declaration(f.fold_variable(v)?),
|
||||
TypedStatement::Assertion(e) => TypedStatement::Assertion(f.fold_boolean_expression(e)?),
|
||||
TypedStatement::Assertion(e, error) => {
|
||||
TypedStatement::Assertion(f.fold_boolean_expression(e)?, error)
|
||||
}
|
||||
TypedStatement::For(v, from, to, statements) => TypedStatement::For(
|
||||
f.fold_variable(v)?,
|
||||
f.fold_uint_expression(from)?,
|
||||
|
@ -727,7 +732,10 @@ pub fn fold_member_expression<
|
|||
pub fn fold_select_expression<
|
||||
'ast,
|
||||
T: Field,
|
||||
E: Expr<'ast, T> + Select<'ast, T> + From<TypedExpression<'ast, T>>,
|
||||
E: Expr<'ast, T>
|
||||
+ Select<'ast, T>
|
||||
+ From<TypedExpression<'ast, T>>
|
||||
+ Into<TypedExpression<'ast, T>>,
|
||||
F: ResultFolder<'ast, T>,
|
||||
>(
|
||||
f: &mut F,
|
||||
|
|
|
@ -301,7 +301,7 @@ impl<S: fmt::Display> fmt::Display for GArrayType<S> {
|
|||
) -> fmt::Result {
|
||||
acc.push(&t.size);
|
||||
match &*t.ty {
|
||||
GType::Array(array_type) => fmt_aux(f, &array_type, acc),
|
||||
GType::Array(array_type) => fmt_aux(f, array_type, acc),
|
||||
t => {
|
||||
write!(f, "{}", t)?;
|
||||
for i in acc {
|
||||
|
@ -314,7 +314,7 @@ impl<S: fmt::Display> fmt::Display for GArrayType<S> {
|
|||
|
||||
let acc = vec![];
|
||||
|
||||
fmt_aux(f, &self, acc)
|
||||
fmt_aux(f, self, acc)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -458,7 +458,7 @@ impl<S> GStructType<S> {
|
|||
}
|
||||
|
||||
fn location(&self) -> &StructLocation {
|
||||
&self.location.as_ref().unwrap_or(&self.canonical_location)
|
||||
self.location.as_ref().unwrap_or(&self.canonical_location)
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
|
@ -1009,7 +1009,7 @@ pub fn specialize_declaration_type<
|
|||
Ok(match decl_ty {
|
||||
DeclarationType::Int => unreachable!(),
|
||||
DeclarationType::Array(t0) => {
|
||||
let ty = box specialize_declaration_type(*t0.ty, &generics)?;
|
||||
let ty = box specialize_declaration_type(*t0.ty, generics)?;
|
||||
let size = match t0.size {
|
||||
DeclarationConstant::Generic(s) => generics.0.get(&s).cloned().ok_or(s),
|
||||
DeclarationConstant::Concrete(s) => Ok(s.into()),
|
||||
|
@ -1085,7 +1085,7 @@ pub mod signature {
|
|||
|
||||
impl<S: Ord> Ord for GSignature<S> {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.partial_cmp(&other).unwrap()
|
||||
self.partial_cmp(other).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -115,7 +115,9 @@ pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
.flat_map(|e| f.fold_statement(e))
|
||||
.collect(),
|
||||
),
|
||||
ZirStatement::Assertion(e) => ZirStatement::Assertion(f.fold_boolean_expression(e)),
|
||||
ZirStatement::Assertion(e, error) => {
|
||||
ZirStatement::Assertion(f.fold_boolean_expression(e), error)
|
||||
}
|
||||
ZirStatement::MultipleDefinition(variables, elist) => ZirStatement::MultipleDefinition(
|
||||
variables.into_iter().map(|v| f.fold_variable(v)).collect(),
|
||||
f.fold_expression_list(elist),
|
||||
|
|
|
@ -19,7 +19,6 @@ use std::fmt;
|
|||
use zokrates_field::Field;
|
||||
|
||||
pub use self::folder::Folder;
|
||||
|
||||
pub use self::identifier::{Identifier, SourceIdentifier};
|
||||
|
||||
/// A typed program as a collection of modules, one of them being the main
|
||||
|
@ -86,8 +85,23 @@ impl<'ast, T: fmt::Debug> fmt::Debug for ZirFunction<'ast, T> {
|
|||
|
||||
pub type ZirAssignee<'ast> = Variable<'ast>;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Hash, Eq)]
|
||||
pub enum RuntimeError {
|
||||
SourceAssertion(String),
|
||||
SelectRangeCheck,
|
||||
}
|
||||
|
||||
impl fmt::Display for RuntimeError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
RuntimeError::SourceAssertion(message) => write!(f, "{}", message),
|
||||
RuntimeError::SelectRangeCheck => write!(f, "Range check on array access"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A statement in a `ZirFunction`
|
||||
#[derive(Clone, PartialEq, Hash, Eq)]
|
||||
#[derive(Clone, PartialEq, Hash, Eq, Debug)]
|
||||
pub enum ZirStatement<'ast, T> {
|
||||
Return(Vec<ZirExpression<'ast, T>>),
|
||||
Definition(ZirAssignee<'ast>, ZirExpression<'ast, T>),
|
||||
|
@ -96,37 +110,10 @@ pub enum ZirStatement<'ast, T> {
|
|||
Vec<ZirStatement<'ast, T>>,
|
||||
Vec<ZirStatement<'ast, T>>,
|
||||
),
|
||||
Assertion(BooleanExpression<'ast, T>),
|
||||
Assertion(BooleanExpression<'ast, T>, RuntimeError),
|
||||
MultipleDefinition(Vec<ZirAssignee<'ast>>, ZirExpressionList<'ast, T>),
|
||||
}
|
||||
|
||||
impl<'ast, T: fmt::Debug> fmt::Debug for ZirStatement<'ast, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
ZirStatement::Return(ref exprs) => {
|
||||
write!(f, "Return(")?;
|
||||
for (i, expr) in exprs.iter().enumerate() {
|
||||
write!(f, "{:?}", expr)?;
|
||||
if i < exprs.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
ZirStatement::Definition(ref consequence, ref alternative) => {
|
||||
write!(f, "Definition({:?}, {:?})", consequence, alternative)
|
||||
}
|
||||
ZirStatement::IfElse(ref condition, ref lhs, ref rhs) => {
|
||||
write!(f, "IfElse({:?}, {:?}, {:?})", condition, lhs, rhs)
|
||||
}
|
||||
ZirStatement::Assertion(ref e) => write!(f, "Assertion({:?})", e),
|
||||
ZirStatement::MultipleDefinition(ref lhs, ref rhs) => {
|
||||
write!(f, "MultipleDefinition({:?}, {:?})", lhs, rhs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: fmt::Display> fmt::Display for ZirStatement<'ast, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
|
@ -158,7 +145,13 @@ impl<'ast, T: fmt::Display> fmt::Display for ZirStatement<'ast, T> {
|
|||
.join("\n")
|
||||
)
|
||||
}
|
||||
ZirStatement::Assertion(ref e) => write!(f, "assert({})", e),
|
||||
ZirStatement::Assertion(ref e, ref error) => {
|
||||
write!(f, "assert({}", e)?;
|
||||
match error {
|
||||
RuntimeError::SourceAssertion(message) => write!(f, ", \"{}\")", message),
|
||||
error => write!(f, ") // {}", error),
|
||||
}
|
||||
}
|
||||
ZirStatement::MultipleDefinition(ref ids, ref rhs) => {
|
||||
for (i, id) in ids.iter().enumerate() {
|
||||
write!(f, "{}", id)?;
|
||||
|
|
|
@ -137,7 +137,9 @@ pub fn fold_statement<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
|||
.flatten()
|
||||
.collect(),
|
||||
),
|
||||
ZirStatement::Assertion(e) => ZirStatement::Assertion(f.fold_boolean_expression(e)?),
|
||||
ZirStatement::Assertion(e, error) => {
|
||||
ZirStatement::Assertion(f.fold_boolean_expression(e)?, error)
|
||||
}
|
||||
ZirStatement::MultipleDefinition(variables, elist) => ZirStatement::MultipleDefinition(
|
||||
variables
|
||||
.into_iter()
|
||||
|
|
|
@ -38,7 +38,7 @@ fn lt_field() {
|
|||
|
||||
assert!(interpreter
|
||||
.execute(
|
||||
&res.prog(),
|
||||
res.prog(),
|
||||
&[Bn128Field::from(10000), Bn128Field::from(5555)]
|
||||
)
|
||||
.is_err());
|
||||
|
@ -70,7 +70,7 @@ fn lt_uint() {
|
|||
|
||||
assert!(interpreter
|
||||
.execute(
|
||||
&res.prog(),
|
||||
res.prog(),
|
||||
&[Bn128Field::from(10000), Bn128Field::from(5555)]
|
||||
)
|
||||
.is_err());
|
||||
|
@ -112,7 +112,7 @@ fn unpack256() {
|
|||
let interpreter = Interpreter::try_out_of_range();
|
||||
|
||||
assert!(interpreter
|
||||
.execute(&res.prog(), &[Bn128Field::from(0)])
|
||||
.execute(res.prog(), &[Bn128Field::from(0)])
|
||||
.is_err());
|
||||
}
|
||||
|
||||
|
@ -152,6 +152,6 @@ fn unpack256_unchecked() {
|
|||
let interpreter = Interpreter::try_out_of_range();
|
||||
|
||||
assert!(interpreter
|
||||
.execute(&res.prog(), &[Bn128Field::from(0)])
|
||||
.execute(res.prog(), &[Bn128Field::from(0)])
|
||||
.is_ok());
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
"UnsatisfiedConstraint": {
|
||||
"left": "4",
|
||||
"right": "2",
|
||||
"message": "Argument bitness check failed"
|
||||
"error": "ArgumentBitness"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
"UnsatisfiedConstraint": {
|
||||
"left": "1",
|
||||
"right": "0",
|
||||
"message": "Out of bounds array access"
|
||||
"error": "SelectRangeCheck"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
32
zokrates_core_test/tests/tests/assert_array_equality.json
Normal file
32
zokrates_core_test/tests/tests/assert_array_equality.json
Normal file
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/assert_array_equality.zok",
|
||||
"curves": ["Bn128", "Bls12_381", "Bls12_377", "Bw6_761"],
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": ["1", "2"]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"values": []
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"input": {
|
||||
"values": ["1", "1"]
|
||||
},
|
||||
"output": {
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "0",
|
||||
"right": "1",
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/assert_array_equality.zok:2:2"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
3
zokrates_core_test/tests/tests/assert_array_equality.zok
Normal file
3
zokrates_core_test/tests/tests/assert_array_equality.zok
Normal file
|
@ -0,0 +1,3 @@
|
|||
def main(field[2] a):
|
||||
assert(a == [1, 2])
|
||||
return
|
|
@ -1,20 +1,22 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/assert_one.zok",
|
||||
"curves": ["Bn128", "Bls12_381", "Bls12_377", "Bw6_761"],
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": ["0"]
|
||||
},
|
||||
"output": {
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "0",
|
||||
"right": "1",
|
||||
"message": "User assertion failed"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
"entry_point": "./tests/tests/assert_one.zok",
|
||||
"curves": ["Bn128", "Bls12_381", "Bls12_377", "Bw6_761"],
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": ["0"]
|
||||
},
|
||||
"output": {
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "0",
|
||||
"right": "1",
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/assert_one.zok:2:2"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/panics/conditional_bound_throw.zok",
|
||||
"curves": ["Bn128"],
|
||||
"tests": [
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": [
|
||||
|
@ -9,13 +9,15 @@
|
|||
]
|
||||
},
|
||||
"output": {
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "0",
|
||||
"right": "1",
|
||||
"message": "User assertion failed"
|
||||
}
|
||||
}
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "0",
|
||||
"right": "1",
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/panics/conditional_bound_throw.zok:2:5"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -25,13 +27,15 @@
|
|||
]
|
||||
},
|
||||
"output": {
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "1",
|
||||
"right": "0",
|
||||
"message": "User assertion failed"
|
||||
}
|
||||
}
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "1",
|
||||
"right": "0",
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/panics/conditional_bound_throw.zok:2:5"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -41,13 +45,15 @@
|
|||
]
|
||||
},
|
||||
"output": {
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "2",
|
||||
"right": "0",
|
||||
"message": "User assertion failed"
|
||||
}
|
||||
}
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "2",
|
||||
"right": "0",
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/panics/conditional_bound_throw.zok:2:5"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/panics/deep_branch.zok",
|
||||
"curves": ["Bn128"],
|
||||
"tests": [
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": [
|
||||
|
@ -9,13 +9,15 @@
|
|||
]
|
||||
},
|
||||
"output": {
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "0",
|
||||
"right": "1",
|
||||
"message": "User assertion failed"
|
||||
}
|
||||
}
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "0",
|
||||
"right": "1",
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/panics/deep_branch.zok:2:5"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/panics/internal_panic.zok",
|
||||
"curves": ["Bn128"],
|
||||
"tests": [
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": [
|
||||
|
@ -9,9 +9,9 @@
|
|||
]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"values": ["1"]
|
||||
}
|
||||
"Ok": {
|
||||
"values": ["1"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -21,13 +21,13 @@
|
|||
]
|
||||
},
|
||||
"output": {
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "0",
|
||||
"right": "1",
|
||||
"message": "Division by zero"
|
||||
}
|
||||
}
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "0",
|
||||
"right": "1",
|
||||
"error": "Inverse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/panics/loop_bound.zok",
|
||||
"curves": ["Bn128", "Bls12_381", "Bls12_377", "Bw6_761"],
|
||||
"tests": [
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": [
|
||||
|
@ -9,13 +9,15 @@
|
|||
]
|
||||
},
|
||||
"output": {
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "0",
|
||||
"right": "1",
|
||||
"message": "User assertion failed"
|
||||
}
|
||||
}
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "0",
|
||||
"right": "1",
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/panics/loop_bound.zok:2:3"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -25,9 +27,9 @@
|
|||
]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"values": []
|
||||
}
|
||||
"Ok": {
|
||||
"values": []
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"isolate_branches": true
|
||||
},
|
||||
"curves": ["Bn128"],
|
||||
"tests": [
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": [
|
||||
|
@ -16,13 +16,15 @@
|
|||
]
|
||||
},
|
||||
"output": {
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "1",
|
||||
"right": "21888242871839275222246405745257275088548364400416034343698204186575808495577",
|
||||
"message": "User assertion failed"
|
||||
}
|
||||
}
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "1",
|
||||
"right": "21888242871839275222246405745257275088548364400416034343698204186575808495577",
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/panics/panic_isolation.zok:18:5"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -35,14 +37,14 @@
|
|||
]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"values": [
|
||||
"Ok": {
|
||||
"values": [
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"1"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -55,14 +57,14 @@
|
|||
]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"values": [
|
||||
"Ok": {
|
||||
"values": [
|
||||
"0",
|
||||
"2",
|
||||
"2",
|
||||
"0"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"isolate_branches": false
|
||||
},
|
||||
"curves": ["Bn128"],
|
||||
"tests": [
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": [
|
||||
|
@ -16,13 +16,15 @@
|
|||
]
|
||||
},
|
||||
"output": {
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "1",
|
||||
"right": "0",
|
||||
"message": "User assertion failed"
|
||||
}
|
||||
}
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"left": "1",
|
||||
"right": "0",
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/panics/panic_isolation.zok:14:5"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
"UnsatisfiedConstraint": {
|
||||
"left": "9",
|
||||
"right": "3",
|
||||
"message": "Argument bitness check failed"
|
||||
"error": "ArgumentBitness"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ pub fn generate_verify_constraints(
|
|||
let num_instance_variables = cs.num_instance_variables();
|
||||
let input_indices = fp_vars
|
||||
.iter()
|
||||
.map(|f| var_to_index(&f, 0))
|
||||
.map(|f| var_to_index(f, 0))
|
||||
.collect::<Vec<usize>>();
|
||||
|
||||
let proof_indices: Vec<usize> = vec![
|
||||
|
|
|
@ -3,13 +3,14 @@ file = { SOI ~ NEWLINE* ~ pragma? ~ NEWLINE* ~ symbol_declaration* ~ EOI }
|
|||
|
||||
pragma = { "#pragma" ~ "curve" ~ curve }
|
||||
curve = @{ (ASCII_ALPHANUMERIC | "_") * }
|
||||
string = @{(!"\"" ~ ANY)*}
|
||||
quoted_string = _{ "\"" ~ string ~ "\"" }
|
||||
|
||||
symbol_declaration = { (import_directive | ty_struct_definition | const_definition | function_definition) ~ NEWLINE* }
|
||||
|
||||
import_directive = { main_import_directive | from_import_directive }
|
||||
from_import_directive = { "from" ~ "\"" ~ import_source ~ "\"" ~ "import" ~ import_symbol_list ~ NEWLINE* }
|
||||
main_import_directive = { "import" ~ "\"" ~ import_source ~ "\"" ~ ("as" ~ identifier)? ~ NEWLINE+ }
|
||||
import_source = @{(!"\"" ~ ANY)*}
|
||||
from_import_directive = { "from" ~ quoted_string ~ "import" ~ import_symbol_list ~ NEWLINE* }
|
||||
main_import_directive = { "import" ~ quoted_string ~ ("as" ~ identifier)? ~ NEWLINE+ }
|
||||
import_symbol = { identifier ~ ("as" ~ identifier)? }
|
||||
import_symbol_list = _{ import_symbol ~ ("," ~ import_symbol)* }
|
||||
function_definition = {"def" ~ identifier ~ constant_generics_declaration? ~ "(" ~ parameter_list ~ ")" ~ return_types ~ ":" ~ NEWLINE* ~ statement* }
|
||||
|
@ -55,7 +56,7 @@ statement = { (return_statement // does not require subsequent newline
|
|||
iteration_statement = { "for" ~ ty ~ identifier ~ "in" ~ expression ~ ".." ~ expression ~ "do" ~ NEWLINE* ~ statement* ~ "endfor"}
|
||||
return_statement = { "return" ~ expression_list}
|
||||
definition_statement = { typed_identifier_or_assignee_list ~ "=" ~ expression } // declare and assign, so only identifiers are allowed, unlike `assignment_statement`
|
||||
expression_statement = {"assert" ~ "(" ~ expression ~ ")"}
|
||||
expression_statement = {"assert" ~ "(" ~ expression ~ ("," ~ quoted_string)? ~ ")"}
|
||||
|
||||
typed_identifier_or_assignee_list = _{ typed_identifier_or_assignee ~ ("," ~ typed_identifier_or_assignee)* }
|
||||
typed_identifier_or_assignee = { typed_identifier | assignee } // we don't use { ty? ~ identifier } as with a single token, it gets parsed as `ty` but we want `identifier`
|
||||
|
@ -65,8 +66,9 @@ expression_list = _{(expression ~ ("," ~ expression)*)?}
|
|||
|
||||
expression = { unaried_term ~ (op_binary ~ unaried_term)* }
|
||||
unaried_term = { op_unary? ~ powered_term }
|
||||
powered_term = { term ~ (op_pow ~ exponent_expression)? }
|
||||
term = { ("(" ~ expression ~ ")") | inline_struct_expression | if_else_expression | postfix_expression | primary_expression | inline_array_expression | array_initializer_expression }
|
||||
powered_term = { postfixed_term ~ (op_pow ~ exponent_expression)? }
|
||||
postfixed_term = { term ~ access* }
|
||||
term = { ("(" ~ expression ~ ")") | inline_struct_expression | if_else_expression | primary_expression | inline_array_expression | array_initializer_expression }
|
||||
spread = { "..." ~ expression }
|
||||
range = { from_expression? ~ ".." ~ to_expression? }
|
||||
from_expression = { expression }
|
||||
|
@ -74,7 +76,6 @@ to_expression = { expression }
|
|||
|
||||
if_else_expression = { "if" ~ expression ~ "then" ~ expression ~ "else" ~ expression ~ "fi"}
|
||||
|
||||
postfix_expression = { identifier ~ access+ } // we force there to be at least one access, otherwise this matches single identifiers
|
||||
access = { array_access | call_access | member_access }
|
||||
array_access = { "[" ~ range_or_expression ~ "]" }
|
||||
call_access = { ("::" ~ explicit_generics)? ~ "(" ~ arguments ~ ")" }
|
||||
|
|
|
@ -13,12 +13,12 @@ pub use ast::{
|
|||
CallAccess, ConstantDefinition, ConstantGenericValue, DecimalLiteralExpression, DecimalNumber,
|
||||
DecimalSuffix, DefinitionStatement, ExplicitGenerics, Expression, FieldType, File,
|
||||
FromExpression, FunctionDefinition, HexLiteralExpression, HexNumberExpression,
|
||||
IdentifierExpression, IfElseExpression, ImportDirective, ImportSource, ImportSymbol,
|
||||
InlineArrayExpression, InlineStructExpression, InlineStructMember, IterationStatement,
|
||||
LiteralExpression, Parameter, PostfixExpression, Range, RangeOrExpression, ReturnStatement,
|
||||
Span, Spread, SpreadOrExpression, Statement, StructDefinition, StructField, SymbolDeclaration,
|
||||
TernaryExpression, ToExpression, Type, TypedIdentifier, TypedIdentifierOrAssignee,
|
||||
UnaryExpression, UnaryOperator, Underscore, Visibility,
|
||||
IdentifierExpression, IfElseExpression, ImportDirective, ImportSymbol, InlineArrayExpression,
|
||||
InlineStructExpression, InlineStructMember, IterationStatement, LiteralExpression, Parameter,
|
||||
PostfixExpression, Range, RangeOrExpression, ReturnStatement, Span, Spread, SpreadOrExpression,
|
||||
Statement, StructDefinition, StructField, SymbolDeclaration, TernaryExpression, ToExpression,
|
||||
Type, TypedIdentifier, TypedIdentifierOrAssignee, UnaryExpression, UnaryOperator, Underscore,
|
||||
Visibility,
|
||||
};
|
||||
|
||||
mod ast {
|
||||
|
@ -201,7 +201,7 @@ mod ast {
|
|||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::main_import_directive))]
|
||||
pub struct MainImportDirective<'ast> {
|
||||
pub source: ImportSource<'ast>,
|
||||
pub source: AnyString<'ast>,
|
||||
pub alias: Option<IdentifierExpression<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
|
@ -219,21 +219,12 @@ mod ast {
|
|||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::from_import_directive))]
|
||||
pub struct FromImportDirective<'ast> {
|
||||
pub source: ImportSource<'ast>,
|
||||
pub source: AnyString<'ast>,
|
||||
pub symbols: Vec<ImportSymbol<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::import_source))]
|
||||
pub struct ImportSource<'ast> {
|
||||
#[pest_ast(outer(with(span_into_str)))]
|
||||
pub value: String,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::ty))]
|
||||
pub enum Type<'ast> {
|
||||
|
@ -364,10 +355,20 @@ mod ast {
|
|||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::string))]
|
||||
pub struct AnyString<'ast> {
|
||||
#[pest_ast(outer(with(span_into_str)))]
|
||||
pub value: String,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::expression_statement))]
|
||||
pub struct AssertionStatement<'ast> {
|
||||
pub expression: Expression<'ast>,
|
||||
pub message: Option<AnyString<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
@ -435,16 +436,47 @@ mod ast {
|
|||
Expression(Expression<'ast>),
|
||||
InlineStruct(InlineStructExpression<'ast>),
|
||||
IfElse(IfElseExpression<'ast>),
|
||||
Postfix(PostfixExpression<'ast>),
|
||||
Primary(PrimaryExpression<'ast>),
|
||||
InlineArray(InlineArrayExpression<'ast>),
|
||||
ArrayInitializer(ArrayInitializerExpression<'ast>),
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::postfixed_term))]
|
||||
pub struct PostfixedTerm<'ast> {
|
||||
pub base: Term<'ast>,
|
||||
pub accesses: Vec<Access<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct PostfixExpression<'ast> {
|
||||
pub base: Box<Expression<'ast>>,
|
||||
pub accesses: Vec<Access<'ast>>,
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> From<PostfixedTerm<'ast>> for Expression<'ast> {
|
||||
fn from(t: PostfixedTerm<'ast>) -> Self {
|
||||
let base = Expression::from(t.base);
|
||||
let accesses = t.accesses;
|
||||
if accesses.is_empty() {
|
||||
base
|
||||
} else {
|
||||
Expression::Postfix(PostfixExpression {
|
||||
base: Box::new(base),
|
||||
accesses,
|
||||
span: t.span,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::powered_term))]
|
||||
struct PoweredTerm<'ast> {
|
||||
base: Term<'ast>,
|
||||
base: PostfixedTerm<'ast>,
|
||||
op: Option<PowOperator>,
|
||||
exponent: Option<ExponentExpression<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
|
@ -520,7 +552,6 @@ mod ast {
|
|||
match t {
|
||||
Term::Expression(e) => e,
|
||||
Term::IfElse(e) => Expression::IfElse(e),
|
||||
Term::Postfix(e) => Expression::Postfix(e),
|
||||
Term::Primary(e) => e.into(),
|
||||
Term::InlineArray(e) => Expression::InlineArray(e),
|
||||
Term::InlineStruct(e) => Expression::InlineStruct(e),
|
||||
|
@ -600,15 +631,6 @@ mod ast {
|
|||
#[pest_ast(rule(Rule::to_expression))]
|
||||
pub struct ToExpression<'ast>(pub Expression<'ast>);
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::postfix_expression))]
|
||||
pub struct PostfixExpression<'ast> {
|
||||
pub id: IdentifierExpression<'ast>,
|
||||
pub accesses: Vec<Access<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::inline_array_expression))]
|
||||
pub struct InlineArrayExpression<'ast> {
|
||||
|
@ -812,7 +834,7 @@ mod ast {
|
|||
match self {
|
||||
Expression::Binary(b) => &b.span,
|
||||
Expression::Identifier(i) => &i.span,
|
||||
Expression::Literal(c) => &c.span(),
|
||||
Expression::Literal(c) => c.span(),
|
||||
Expression::Ternary(t) => &t.span,
|
||||
Expression::IfElse(ie) => &ie.span,
|
||||
Expression::Postfix(p) => &p.span,
|
||||
|
@ -1088,57 +1110,57 @@ mod tests {
|
|||
def main() -> (field): return 1 + 1
|
||||
"#;
|
||||
assert_eq!(
|
||||
generate_ast(&source),
|
||||
generate_ast(source),
|
||||
Ok(File {
|
||||
pragma: None,
|
||||
declarations: vec![
|
||||
SymbolDeclaration::Import(ImportDirective::Main(MainImportDirective {
|
||||
source: ImportSource {
|
||||
source: AnyString {
|
||||
value: String::from("foo"),
|
||||
span: Span::new(&source, 8, 11).unwrap()
|
||||
span: Span::new(source, 8, 11).unwrap()
|
||||
},
|
||||
alias: None,
|
||||
span: Span::new(&source, 0, 29).unwrap()
|
||||
span: Span::new(source, 0, 29).unwrap()
|
||||
})),
|
||||
SymbolDeclaration::Function(FunctionDefinition {
|
||||
generics: vec![],
|
||||
id: IdentifierExpression {
|
||||
value: String::from("main"),
|
||||
span: Span::new(&source, 33, 37).unwrap()
|
||||
span: Span::new(source, 33, 37).unwrap()
|
||||
},
|
||||
parameters: vec![],
|
||||
returns: vec![Type::Basic(BasicType::Field(FieldType {
|
||||
span: Span::new(&source, 44, 49).unwrap()
|
||||
span: Span::new(source, 44, 49).unwrap()
|
||||
}))],
|
||||
statements: vec![Statement::Return(ReturnStatement {
|
||||
expressions: vec![Expression::add(
|
||||
Expression::Literal(LiteralExpression::DecimalLiteral(
|
||||
DecimalLiteralExpression {
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 59, 60).unwrap()
|
||||
span: Span::new(source, 59, 60).unwrap()
|
||||
},
|
||||
suffix: None,
|
||||
span: Span::new(&source, 59, 60).unwrap()
|
||||
span: Span::new(source, 59, 60).unwrap()
|
||||
}
|
||||
)),
|
||||
Expression::Literal(LiteralExpression::DecimalLiteral(
|
||||
DecimalLiteralExpression {
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 63, 64).unwrap()
|
||||
span: Span::new(source, 63, 64).unwrap()
|
||||
},
|
||||
suffix: None,
|
||||
span: Span::new(&source, 63, 64).unwrap()
|
||||
span: Span::new(source, 63, 64).unwrap()
|
||||
}
|
||||
)),
|
||||
Span::new(&source, 59, 64).unwrap()
|
||||
Span::new(source, 59, 64).unwrap()
|
||||
)],
|
||||
span: Span::new(&source, 52, 64).unwrap(),
|
||||
span: Span::new(source, 52, 64).unwrap(),
|
||||
})],
|
||||
span: Span::new(&source, 29, source.len()).unwrap(),
|
||||
span: Span::new(source, 29, source.len()).unwrap(),
|
||||
})
|
||||
],
|
||||
eoi: EOI {},
|
||||
span: Span::new(&source, 0, 65).unwrap()
|
||||
span: Span::new(source, 0, 65).unwrap()
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -1149,27 +1171,27 @@ mod tests {
|
|||
def main() -> (field): return 1 + 2 * 3 ** 4
|
||||
"#;
|
||||
assert_eq!(
|
||||
generate_ast(&source),
|
||||
generate_ast(source),
|
||||
Ok(File {
|
||||
pragma: None,
|
||||
declarations: vec![
|
||||
SymbolDeclaration::Import(ImportDirective::Main(MainImportDirective {
|
||||
source: ImportSource {
|
||||
source: AnyString {
|
||||
value: String::from("foo"),
|
||||
span: Span::new(&source, 8, 11).unwrap()
|
||||
span: Span::new(source, 8, 11).unwrap()
|
||||
},
|
||||
alias: None,
|
||||
span: Span::new(&source, 0, 29).unwrap()
|
||||
span: Span::new(source, 0, 29).unwrap()
|
||||
})),
|
||||
SymbolDeclaration::Function(FunctionDefinition {
|
||||
generics: vec![],
|
||||
id: IdentifierExpression {
|
||||
value: String::from("main"),
|
||||
span: Span::new(&source, 33, 37).unwrap()
|
||||
span: Span::new(source, 33, 37).unwrap()
|
||||
},
|
||||
parameters: vec![],
|
||||
returns: vec![Type::Basic(BasicType::Field(FieldType {
|
||||
span: Span::new(&source, 44, 49).unwrap()
|
||||
span: Span::new(source, 44, 49).unwrap()
|
||||
}))],
|
||||
statements: vec![Statement::Return(ReturnStatement {
|
||||
expressions: vec![Expression::add(
|
||||
|
@ -1177,9 +1199,9 @@ mod tests {
|
|||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 59, 60).unwrap()
|
||||
span: Span::new(source, 59, 60).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 59, 60).unwrap()
|
||||
span: Span::new(source, 59, 60).unwrap()
|
||||
}
|
||||
)),
|
||||
Expression::mul(
|
||||
|
@ -1187,9 +1209,9 @@ mod tests {
|
|||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 63, 64).unwrap()
|
||||
span: Span::new(source, 63, 64).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 63, 64).unwrap()
|
||||
span: Span::new(source, 63, 64).unwrap()
|
||||
}
|
||||
)),
|
||||
Expression::pow(
|
||||
|
@ -1197,33 +1219,33 @@ mod tests {
|
|||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 67, 68).unwrap()
|
||||
span: Span::new(source, 67, 68).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 67, 68).unwrap()
|
||||
span: Span::new(source, 67, 68).unwrap()
|
||||
}
|
||||
)),
|
||||
Expression::Literal(LiteralExpression::DecimalLiteral(
|
||||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 72, 73).unwrap()
|
||||
span: Span::new(source, 72, 73).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 72, 73).unwrap()
|
||||
span: Span::new(source, 72, 73).unwrap()
|
||||
}
|
||||
)),
|
||||
Span::new(&source, 67, 73).unwrap()
|
||||
Span::new(source, 67, 73).unwrap()
|
||||
),
|
||||
Span::new(&source, 63, 73).unwrap()
|
||||
Span::new(source, 63, 73).unwrap()
|
||||
),
|
||||
Span::new(&source, 59, 73).unwrap()
|
||||
Span::new(source, 59, 73).unwrap()
|
||||
)],
|
||||
span: Span::new(&source, 52, 73).unwrap(),
|
||||
span: Span::new(source, 52, 73).unwrap(),
|
||||
})],
|
||||
span: Span::new(&source, 29, 74).unwrap(),
|
||||
span: Span::new(source, 29, 74).unwrap(),
|
||||
})
|
||||
],
|
||||
eoi: EOI {},
|
||||
span: Span::new(&source, 0, 74).unwrap()
|
||||
span: Span::new(source, 0, 74).unwrap()
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -1234,27 +1256,27 @@ mod tests {
|
|||
def main() -> (field): return if 1 then 2 else 3 fi
|
||||
"#;
|
||||
assert_eq!(
|
||||
generate_ast(&source),
|
||||
generate_ast(source),
|
||||
Ok(File {
|
||||
pragma: None,
|
||||
declarations: vec![
|
||||
SymbolDeclaration::Import(ImportDirective::Main(MainImportDirective {
|
||||
source: ImportSource {
|
||||
source: AnyString {
|
||||
value: String::from("foo"),
|
||||
span: Span::new(&source, 8, 11).unwrap()
|
||||
span: Span::new(source, 8, 11).unwrap()
|
||||
},
|
||||
alias: None,
|
||||
span: Span::new(&source, 0, 29).unwrap()
|
||||
span: Span::new(source, 0, 29).unwrap()
|
||||
})),
|
||||
SymbolDeclaration::Function(FunctionDefinition {
|
||||
generics: vec![],
|
||||
id: IdentifierExpression {
|
||||
value: String::from("main"),
|
||||
span: Span::new(&source, 33, 37).unwrap()
|
||||
span: Span::new(source, 33, 37).unwrap()
|
||||
},
|
||||
parameters: vec![],
|
||||
returns: vec![Type::Basic(BasicType::Field(FieldType {
|
||||
span: Span::new(&source, 44, 49).unwrap()
|
||||
span: Span::new(source, 44, 49).unwrap()
|
||||
}))],
|
||||
statements: vec![Statement::Return(ReturnStatement {
|
||||
expressions: vec![Expression::if_else(
|
||||
|
@ -1262,38 +1284,38 @@ mod tests {
|
|||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 62, 63).unwrap()
|
||||
span: Span::new(source, 62, 63).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 62, 63).unwrap()
|
||||
span: Span::new(source, 62, 63).unwrap()
|
||||
}
|
||||
))),
|
||||
Box::new(Expression::Literal(LiteralExpression::DecimalLiteral(
|
||||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 69, 70).unwrap()
|
||||
span: Span::new(source, 69, 70).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 69, 70).unwrap()
|
||||
span: Span::new(source, 69, 70).unwrap()
|
||||
}
|
||||
))),
|
||||
Box::new(Expression::Literal(LiteralExpression::DecimalLiteral(
|
||||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 76, 77).unwrap()
|
||||
span: Span::new(source, 76, 77).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 76, 77).unwrap()
|
||||
span: Span::new(source, 76, 77).unwrap()
|
||||
}
|
||||
))),
|
||||
Span::new(&source, 59, 80).unwrap()
|
||||
)],
|
||||
span: Span::new(&source, 52, 80).unwrap(),
|
||||
span: Span::new(source, 52, 80).unwrap(),
|
||||
})],
|
||||
span: Span::new(&source, 29, 81).unwrap(),
|
||||
span: Span::new(source, 29, 81).unwrap(),
|
||||
})
|
||||
],
|
||||
eoi: EOI {},
|
||||
span: Span::new(&source, 0, 81).unwrap()
|
||||
span: Span::new(source, 0, 81).unwrap()
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -1303,35 +1325,35 @@ mod tests {
|
|||
let source = r#"def main() -> (field): return (1)
|
||||
"#;
|
||||
assert_eq!(
|
||||
generate_ast(&source),
|
||||
generate_ast(source),
|
||||
Ok(File {
|
||||
pragma: None,
|
||||
declarations: vec![SymbolDeclaration::Function(FunctionDefinition {
|
||||
generics: vec![],
|
||||
id: IdentifierExpression {
|
||||
value: String::from("main"),
|
||||
span: Span::new(&source, 4, 8).unwrap()
|
||||
span: Span::new(source, 4, 8).unwrap()
|
||||
},
|
||||
parameters: vec![],
|
||||
returns: vec![Type::Basic(BasicType::Field(FieldType {
|
||||
span: Span::new(&source, 15, 20).unwrap()
|
||||
span: Span::new(source, 15, 20).unwrap()
|
||||
}))],
|
||||
statements: vec![Statement::Return(ReturnStatement {
|
||||
expressions: vec![Expression::Literal(LiteralExpression::DecimalLiteral(
|
||||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 31, 32).unwrap()
|
||||
span: Span::new(source, 31, 32).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 31, 32).unwrap()
|
||||
span: Span::new(source, 31, 32).unwrap()
|
||||
}
|
||||
))],
|
||||
span: Span::new(&source, 23, 33).unwrap(),
|
||||
span: Span::new(source, 23, 33).unwrap(),
|
||||
})],
|
||||
span: Span::new(&source, 0, 34).unwrap(),
|
||||
span: Span::new(source, 0, 34).unwrap(),
|
||||
})],
|
||||
eoi: EOI {},
|
||||
span: Span::new(&source, 0, 34).unwrap()
|
||||
span: Span::new(source, 0, 34).unwrap()
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -1341,45 +1363,45 @@ mod tests {
|
|||
let source = r#"def main() -> (field): field a, b = foo(1, 2 + 3)
|
||||
"#;
|
||||
assert_eq!(
|
||||
generate_ast(&source),
|
||||
generate_ast(source),
|
||||
Ok(File {
|
||||
pragma: None,
|
||||
declarations: vec![SymbolDeclaration::Function(FunctionDefinition {
|
||||
generics: vec![],
|
||||
id: IdentifierExpression {
|
||||
value: String::from("main"),
|
||||
span: Span::new(&source, 4, 8).unwrap()
|
||||
span: Span::new(source, 4, 8).unwrap()
|
||||
},
|
||||
parameters: vec![],
|
||||
returns: vec![Type::Basic(BasicType::Field(FieldType {
|
||||
span: Span::new(&source, 15, 20).unwrap()
|
||||
span: Span::new(source, 15, 20).unwrap()
|
||||
}))],
|
||||
statements: vec![Statement::Definition(DefinitionStatement {
|
||||
lhs: vec![
|
||||
TypedIdentifierOrAssignee::TypedIdentifier(TypedIdentifier {
|
||||
ty: Type::Basic(BasicType::Field(FieldType {
|
||||
span: Span::new(&source, 23, 28).unwrap()
|
||||
span: Span::new(source, 23, 28).unwrap()
|
||||
})),
|
||||
identifier: IdentifierExpression {
|
||||
value: String::from("a"),
|
||||
span: Span::new(&source, 29, 30).unwrap(),
|
||||
span: Span::new(source, 29, 30).unwrap(),
|
||||
},
|
||||
span: Span::new(&source, 23, 30).unwrap()
|
||||
span: Span::new(source, 23, 30).unwrap()
|
||||
}),
|
||||
TypedIdentifierOrAssignee::Assignee(Assignee {
|
||||
id: IdentifierExpression {
|
||||
value: String::from("b"),
|
||||
span: Span::new(&source, 32, 33).unwrap(),
|
||||
span: Span::new(source, 32, 33).unwrap(),
|
||||
},
|
||||
accesses: vec![],
|
||||
span: Span::new(&source, 32, 34).unwrap()
|
||||
span: Span::new(source, 32, 34).unwrap()
|
||||
}),
|
||||
],
|
||||
expression: Expression::Postfix(PostfixExpression {
|
||||
id: IdentifierExpression {
|
||||
base: Box::new(Expression::Identifier(IdentifierExpression {
|
||||
value: String::from("foo"),
|
||||
span: Span::new(&source, 36, 39).unwrap()
|
||||
},
|
||||
span: Span::new(source, 36, 39).unwrap()
|
||||
})),
|
||||
accesses: vec![Access::Call(CallAccess {
|
||||
explicit_generics: None,
|
||||
arguments: Arguments {
|
||||
|
@ -1388,9 +1410,9 @@ mod tests {
|
|||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 40, 41).unwrap()
|
||||
span: Span::new(source, 40, 41).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 40, 41).unwrap()
|
||||
span: Span::new(source, 40, 41).unwrap()
|
||||
}
|
||||
)),
|
||||
Expression::add(
|
||||
|
@ -1398,35 +1420,35 @@ mod tests {
|
|||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 43, 44).unwrap()
|
||||
span: Span::new(source, 43, 44).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 43, 44).unwrap()
|
||||
span: Span::new(source, 43, 44).unwrap()
|
||||
}
|
||||
)),
|
||||
Expression::Literal(LiteralExpression::DecimalLiteral(
|
||||
DecimalLiteralExpression {
|
||||
suffix: None,
|
||||
value: DecimalNumber {
|
||||
span: Span::new(&source, 47, 48).unwrap()
|
||||
span: Span::new(source, 47, 48).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 47, 48).unwrap()
|
||||
span: Span::new(source, 47, 48).unwrap()
|
||||
}
|
||||
)),
|
||||
Span::new(&source, 43, 48).unwrap()
|
||||
Span::new(source, 43, 48).unwrap()
|
||||
),
|
||||
],
|
||||
span: Span::new(&source, 40, 48).unwrap()
|
||||
span: Span::new(source, 40, 48).unwrap()
|
||||
},
|
||||
span: Span::new(&source, 39, 49).unwrap()
|
||||
span: Span::new(source, 39, 49).unwrap()
|
||||
})],
|
||||
span: Span::new(&source, 36, 49).unwrap(),
|
||||
span: Span::new(source, 36, 49).unwrap(),
|
||||
}),
|
||||
span: Span::new(&source, 23, 49).unwrap()
|
||||
span: Span::new(source, 23, 49).unwrap()
|
||||
})],
|
||||
span: Span::new(&source, 0, 50).unwrap(),
|
||||
span: Span::new(source, 0, 50).unwrap(),
|
||||
})],
|
||||
eoi: EOI {},
|
||||
span: Span::new(&source, 0, 50).unwrap()
|
||||
span: Span::new(source, 0, 50).unwrap()
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -1449,8 +1471,8 @@ mod tests {
|
|||
assert(a.member == 1)
|
||||
return a
|
||||
"#;
|
||||
let res = generate_ast(&source);
|
||||
println!("{:#?}", generate_ast(&source));
|
||||
let res = generate_ast(source);
|
||||
println!("{:#?}", generate_ast(source));
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
from "EMBED" import unpack, u16_from_bits
|
||||
from "field" import FIELD_SIZE_IN_BITS
|
||||
import "utils/pack/bool/unpack"
|
||||
import "utils/casts/u16_from_bits"
|
||||
|
||||
def main(field i) -> u16:
|
||||
bool[16] bits = unpack(i)
|
||||
return u16_from_bits(bits)
|
||||
def main(field input) -> u16:
|
||||
bool[FIELD_SIZE_IN_BITS] bits = unpack(input)
|
||||
return u16_from_bits(bits[FIELD_SIZE_IN_BITS-16..])
|
|
@ -1,5 +1,7 @@
|
|||
from "EMBED" import unpack, u32_from_bits
|
||||
from "field" import FIELD_SIZE_IN_BITS
|
||||
import "utils/pack/bool/unpack"
|
||||
import "utils/casts/u32_from_bits"
|
||||
|
||||
def main(field i) -> u32:
|
||||
bool[32] bits = unpack(i)
|
||||
return u32_from_bits(bits)
|
||||
def main(field input) -> u32:
|
||||
bool[FIELD_SIZE_IN_BITS] bits = unpack(input)
|
||||
return u32_from_bits(bits[FIELD_SIZE_IN_BITS-32..])
|
|
@ -1,5 +1,7 @@
|
|||
from "EMBED" import unpack, u64_from_bits
|
||||
from "field" import FIELD_SIZE_IN_BITS
|
||||
import "utils/pack/bool/unpack"
|
||||
import "utils/casts/u64_from_bits"
|
||||
|
||||
def main(field i) -> u64:
|
||||
bool[64] bits = unpack(i)
|
||||
return u64_from_bits(bits)
|
||||
def main(field input) -> u64:
|
||||
bool[FIELD_SIZE_IN_BITS] bits = unpack(input)
|
||||
return u64_from_bits(bits[FIELD_SIZE_IN_BITS-64..])
|
|
@ -1,5 +1,7 @@
|
|||
from "EMBED" import unpack, u8_from_bits
|
||||
from "field" import FIELD_SIZE_IN_BITS
|
||||
import "utils/pack/bool/unpack"
|
||||
import "utils/casts/u8_from_bits"
|
||||
|
||||
def main(field i) -> u8:
|
||||
bool[8] bits = unpack(i)
|
||||
return u8_from_bits(bits)
|
||||
def main(field input) -> u8:
|
||||
bool[FIELD_SIZE_IN_BITS] bits = unpack(input)
|
||||
return u8_from_bits(bits[FIELD_SIZE_IN_BITS-8..])
|
|
@ -4,11 +4,11 @@
|
|||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": ["0", "1", "18446744073709551615", "42", "0", "1", "4294967295", "42", "0", "1", "65535", "42", "0", "1", "255", "42"]
|
||||
"values": ["0", "1", "18446744073709551615", "18446744073709551616", "18446744073709551658", "0", "1", "4294967295", "4294967296", "4294967338", "0", "1", "65535", "65536", "65578", "0", "1", "255", "256", "298"]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"values": ["0", "1", "18446744073709551615", "42", "0", "1", "4294967295", "42", "0", "1", "65535", "42", "0", "1", "255", "42"]
|
||||
"values": ["0", "1", "18446744073709551615", "0", "42", "0", "1", "4294967295", "0", "42", "0", "1", "65535", "0", "42", "0", "1", "255", "0", "42"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,13 +3,13 @@ import "utils/casts/field_to_u32"
|
|||
import "utils/casts/field_to_u16"
|
||||
import "utils/casts/field_to_u8"
|
||||
|
||||
def main(field[4] a, field[4] b, field[4] c, field[4] d) -> (u64[4], u32[4], u16[4], u8[4]):
|
||||
u64[4] e = [0; 4]
|
||||
u32[4] f = [0; 4]
|
||||
u16[4] g = [0; 4]
|
||||
u8[4] h = [0; 4]
|
||||
def main(field[5] a, field[5] b, field[5] c, field[5] d) -> (u64[5], u32[5], u16[5], u8[5]):
|
||||
u64[5] e = [0; 5]
|
||||
u32[5] f = [0; 5]
|
||||
u16[5] g = [0; 5]
|
||||
u8[5] h = [0; 5]
|
||||
|
||||
for u32 i in 0..4 do
|
||||
for u32 i in 0..5 do
|
||||
e[i] = field_to_u64(a[i])
|
||||
f[i] = field_to_u32(b[i])
|
||||
g[i] = field_to_u16(c[i])
|
||||
|
|
|
@ -157,15 +157,14 @@ fn compile_and_run<T: Field>(t: Tests) {
|
|||
if let Some(target_count) = t.max_constraint_count {
|
||||
let count = bin.constraint_count();
|
||||
|
||||
if count > target_count {
|
||||
panic!(
|
||||
"{} exceeded max constraint count (actual={}, max={}, p={:.2}% of max)",
|
||||
entry_point.display(),
|
||||
count,
|
||||
target_count,
|
||||
(count as f32) / (target_count as f32) * 100_f32
|
||||
);
|
||||
}
|
||||
assert!(
|
||||
count <= target_count,
|
||||
"{} exceeded max constraint count (actual={}, max={}, p={:.2}% of max)",
|
||||
entry_point.display(),
|
||||
count,
|
||||
target_count,
|
||||
(count as f32) / (target_count as f32) * 100_f32
|
||||
);
|
||||
};
|
||||
|
||||
let interpreter = zokrates_core::ir::Interpreter::default();
|
||||
|
|
|
@ -13,7 +13,7 @@ pub fn write_tests(base: &str) {
|
|||
let mut writer = BufWriter::new(test_file);
|
||||
|
||||
for p in glob(base.join("**/*.json").to_str().unwrap()).unwrap() {
|
||||
write_test(&mut writer, &p.unwrap(), &base);
|
||||
write_test(&mut writer, &p.unwrap(), base);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue