Merge branch 'develop' into add-sharound
* develop: (53 commits) move book snippets to files in test folder, link to them from md handle case where path is a directory update cargo.lock update tests to use relative paths resolve cargo.lock conflict WASM crate import depends on the presence of the `wasm` feature Insert missing fi at the end of if statement change test to check flattening of 1-sized array is identical to flattening of single value implement variable access to ifelse array add support for ifelse array access, clean up semantic treatment recommend setting /Users/obit/sides/zokrates/zokrates_stdlib/stdlib if it is not already add /Users/obit/sides/zokrates/zokrates_stdlib/stdlib to Dockerfiles, add stdlib with dummy file remove commented out old serialization branch based on first path component base decision on first character of path fallback to /Users/obit/.zokrates when importing source files Run the tests with WASM enabled Fix build after rebase Fix warning Move wasm plugin generation to a different repo ... # Conflicts: # zokrates_book/src/sha256example.md
This commit is contained in:
commit
00147b3917
46 changed files with 1466 additions and 309 deletions
|
@ -18,6 +18,9 @@ jobs:
|
|||
- run:
|
||||
name: Check format
|
||||
command: rustup component add rustfmt-preview; cargo fmt --all -- --check
|
||||
- run:
|
||||
name: Download wasm32 target
|
||||
command: rustup target add wasm32-unknown-unknown
|
||||
- run:
|
||||
name: Build libsnark
|
||||
command: LIBSNARK_SOURCE_PATH=$HOME/libsnark ./build_libsnark.sh
|
||||
|
@ -27,6 +30,9 @@ jobs:
|
|||
- run:
|
||||
name: Run tests
|
||||
command: WITH_LIBSNARK=1 LIBSNARK_SOURCE_PATH=$HOME/libsnark RUSTFLAGS="-D warnings" cargo test --release -- --test-threads=1
|
||||
- run:
|
||||
name: Run tests with WASM enabled
|
||||
command: cd zokrates_core && cargo test --release --features wasm -- --test-threads=1
|
||||
- run:
|
||||
name: Run integration tests
|
||||
command: WITH_LIBSNARK=1 LIBSNARK_SOURCE_PATH=$HOME/libsnark RUSTFLAGS="-D warnings" cargo test --release -- --ignored
|
||||
|
|
314
Cargo.lock
generated
314
Cargo.lock
generated
|
@ -3,7 +3,7 @@ name = "aho-corasick"
|
|||
version = "0.6.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -31,7 +31,7 @@ dependencies = [
|
|||
"difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"skeptic 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -40,14 +40,14 @@ name = "atty"
|
|||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
@ -55,10 +55,10 @@ name = "backtrace"
|
|||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -69,7 +69,7 @@ version = "0.1.28"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -82,9 +82,9 @@ name = "bincode"
|
|||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -99,7 +99,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.2.7"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
@ -109,9 +109,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -141,6 +141,14 @@ dependencies = [
|
|||
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.35"
|
||||
|
@ -255,17 +263,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.46"
|
||||
version = "0.2.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.1.2"
|
||||
version = "2.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -273,6 +280,11 @@ name = "memoffset"
|
|||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "memory_units"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "nodrop"
|
||||
version = "0.1.13"
|
||||
|
@ -297,6 +309,16 @@ dependencies = [
|
|||
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.39"
|
||||
|
@ -332,12 +354,28 @@ name = "num_cpus"
|
|||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parity-wasm"
|
||||
version = "0.31.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parity-wasm"
|
||||
version = "0.35.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.24"
|
||||
version = "0.4.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -353,10 +391,10 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.6.10"
|
||||
version = "0.6.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -365,17 +403,89 @@ version = "0.4.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_os 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_isaac"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_os"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_pcg"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.0.3"
|
||||
|
@ -393,7 +503,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -407,7 +517,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.50"
|
||||
version = "0.1.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
@ -415,7 +525,7 @@ name = "redox_termios"
|
|||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -429,7 +539,7 @@ version = "0.2.11"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -456,6 +566,19 @@ name = "rustc-demangle"
|
|||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hex"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "0.2.7"
|
||||
|
@ -480,7 +603,7 @@ version = "0.9.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -490,27 +613,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.84"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.84"
|
||||
name = "serde_bytes"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.35"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -523,7 +654,7 @@ dependencies = [
|
|||
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -535,11 +666,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.15.24"
|
||||
version = "0.15.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -552,13 +683,26 @@ dependencies = [
|
|||
"remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termion"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -603,11 +747,6 @@ name = "vec_map"
|
|||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.2.7"
|
||||
|
@ -618,6 +757,16 @@ dependencies = [
|
|||
"winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmi"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.6"
|
||||
|
@ -654,9 +803,9 @@ dependencies = [
|
|||
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"zokrates_core 0.3.3",
|
||||
"zokrates_field 0.3.0",
|
||||
"zokrates_field 0.3.1",
|
||||
"zokrates_fs_resolver 0.3.2",
|
||||
]
|
||||
|
||||
|
@ -671,32 +820,41 @@ dependencies = [
|
|||
"cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.35.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"reduce 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"zokrates_field 0.3.0",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmi 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"zokrates_field 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zokrates_field"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
dependencies = [
|
||||
"bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zokrates_fs_resolver"
|
||||
version = "0.3.2"
|
||||
dependencies = [
|
||||
"tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[metadata]
|
||||
"checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e"
|
||||
|
@ -704,18 +862,19 @@ version = "0.3.2"
|
|||
"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71"
|
||||
"checksum assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "72342c21057a3cb5f7c2d849bf7999a83795434dd36d74fa8c24680581bd1930"
|
||||
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
|
||||
"checksum autocfg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4e5f34df7a019573fb8bdc7e24a2bfebe51a2a1d6bfdbaeccedb3c41fc574727"
|
||||
"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799"
|
||||
"checksum backtrace 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b5b493b66e03090ebc4343eb02f94ff944e0cbc9ac6571491d170ba026741eb5"
|
||||
"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6"
|
||||
"checksum bimap 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6b282b982237078bfac61a948a2198f185aceea8b9a6e794b70b96fd31923d3d"
|
||||
"checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e"
|
||||
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
||||
"checksum bytecount 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b92204551573580e078dc80017f36a213eb77a0450e4ddd8cfa0f3f2d1f0178f"
|
||||
"checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d"
|
||||
"checksum byteorder 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60f0b0d4c0a382d2734228fd12b5a6b5dac185c60e938026fd31b265b94f9bd2"
|
||||
"checksum cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d1b4d380e1bab994591a24c2bdd1b054f64b60bef483a8c598c7c345bc3bbe"
|
||||
"checksum cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4a8b715cb4597106ea87c7c84b2f1d452c7492033765df7f32651e66fcf749"
|
||||
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
|
||||
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
|
||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
"checksum cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec65ee4f9c9d16f335091d23693457ed4928657ba4982289d7fafee03bc614a"
|
||||
"checksum colored 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e9a455e156a4271e12fd0246238c380b1e223e3736663c7a18ed8b6362028a9"
|
||||
"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
|
||||
|
@ -732,44 +891,59 @@ version = "0.3.2"
|
|||
"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
|
||||
"checksum lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "cf186d1a8aa5f5bee5fd662bc9c1b949e0259e1bcc379d1f006847b0080c7417"
|
||||
"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
|
||||
"checksum libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)" = "023a4cd09b2ff695f9734c1934145a315594b7986398496841c7031a5a1bbdbd"
|
||||
"checksum memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "db4c41318937f6e76648f42826b1d9ade5c09cafb5aef7e351240a70f39206e9"
|
||||
"checksum libc 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)" = "48450664a984b25d5b479554c29cc04e3150c97aa4c01da5604a2d4ed9151476"
|
||||
"checksum memchr 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e1dd4eaac298c32ce07eb6ed9242eda7d82955b9170b7d6db59b2e02cc63fcb8"
|
||||
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
|
||||
"checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882"
|
||||
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
|
||||
"checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e"
|
||||
"checksum num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1"
|
||||
"checksum num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "57450397855d951f1a41305e54851b1a7b8f5d2e349543a02a2effe25459f718"
|
||||
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
|
||||
"checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124"
|
||||
"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
|
||||
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
|
||||
"checksum num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5a69d464bdc213aaaff628444e99578ede64e9c854025aa43b9796530afa9238"
|
||||
"checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09"
|
||||
"checksum parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "511379a8194230c2395d2f5fa627a5a7e108a9f976656ce723ae68fca4097bfc"
|
||||
"checksum parity-wasm 0.35.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3e1e076c4e01399b6cd0793a8df42f90bba3ae424671ef421d1608a943155d93"
|
||||
"checksum proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)" = "38fddd23d98b2144d197c0eca5705632d4fe2667d14a6be5df8934f8d74f1978"
|
||||
"checksum pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eef52fac62d0ea7b9b4dc7da092aa64ea7ec3d90af6679422d3d7e0e14b6ee15"
|
||||
"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
|
||||
"checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1"
|
||||
"checksum rand 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dee497e66d8d76bf08ce20c8d36e16f93749ab0bf89975b4f8ae5cee660c2da2"
|
||||
"checksum rand 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3906503e80ac6cbcacb2c2973fa8e473f24d7e2747c8c92bb230c2441cad96b5"
|
||||
"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
||||
"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db"
|
||||
"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
|
||||
"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
|
||||
"checksum rand_os 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f46fbd5550acf75b0c2730f5dd1873751daf9beb8f11b44027778fae50d7feca"
|
||||
"checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05"
|
||||
"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
||||
"checksum rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "373814f27745b2686b350dd261bfd24576a6fb0e2c5919b3a2b6005f820b0473"
|
||||
"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356"
|
||||
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
"checksum redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)" = "52ee9a534dc1301776eff45b4fa92d2c39b1d8c3d3357e6eb593e0d795506fc2"
|
||||
"checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85"
|
||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||
"checksum reduce 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f77b717415291f4d7929a111402316b272c566ae9d4b75a61507dba88ecbd89"
|
||||
"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384"
|
||||
"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7"
|
||||
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
|
||||
"checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619"
|
||||
"checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e"
|
||||
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7"
|
||||
"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267"
|
||||
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
|
||||
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
"checksum serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)" = "0e732ed5a5592c17d961555e3b552985baf98d50ce418b7b655f31f6ba7eb1b7"
|
||||
"checksum serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d6115a3ca25c224e409185325afc16a0d5aaaabc15c42b09587d6f1ba39a5b"
|
||||
"checksum serde_json 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "dfb1277d4d0563e4593e0b8b5d23d744d277b55d2bc0bf1c38d0d8a6589d38aa"
|
||||
"checksum serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)" = "534b8b91a95e0f71bca3ed5824752d558da048d4248c91af873b63bd60519752"
|
||||
"checksum serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "adb6e51a6b3696b301bc221d785f898b4457c619b51d7ce195a6d20baecb37b3"
|
||||
"checksum serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)" = "a915306b0f1ac5607797697148c223bedeaa36bcc2e28a01441cd638cc6567b4"
|
||||
"checksum serde_json 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)" = "574378d957d6dcdf1bbb5d562a15cbd5e644159432f84634b94e485267abbcc7"
|
||||
"checksum skeptic 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fb8ed853fdc19ce09752d63f3a2e5b5158aeb261520cd75eb618bd60305165"
|
||||
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
|
||||
"checksum syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)" = "734ecc29cd36e8123850d9bf21dfd62ef8300aaa8f879aabaa899721808be37c"
|
||||
"checksum syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9"
|
||||
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
|
||||
"checksum tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7e91405c14320e5c79b3d148e1c86f40749a36e490642202a31689cb1a3452b2"
|
||||
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
||||
"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
|
||||
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
||||
|
@ -778,8 +952,8 @@ version = "0.3.2"
|
|||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
|
||||
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
||||
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
|
||||
"checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1"
|
||||
"checksum wasmi 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21ef487a11df1ed468cf613c78798c26282da5c30e9d49f824872d4c77b47d1d"
|
||||
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab"
|
||||
|
|
|
@ -8,6 +8,7 @@ ARG RUST_TOOLCHAIN=nightly-2019-01-01
|
|||
ARG LIBSNARK_COMMIT=f7c87b88744ecfd008126d415494d9b34c4c1b20
|
||||
ENV LIBSNARK_SOURCE_PATH=/home/zokrates/libsnark-$LIBSNARK_COMMIT
|
||||
ENV WITH_LIBSNARK=1
|
||||
ENV ZOKRATES_HOME=/home/zokrates/.zokrates
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
|
@ -34,10 +35,13 @@ WORKDIR /home/zokrates
|
|||
|
||||
COPY --chown=zokrates:zokrates . src
|
||||
|
||||
RUN mkdir $ZOKRATES_HOME
|
||||
|
||||
RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain $RUST_TOOLCHAIN -y \
|
||||
&& export PATH=/home/zokrates/.cargo/bin:$PATH \
|
||||
&& (cd src;./build_release.sh) \
|
||||
&& mv ./src/target/release/zokrates . \
|
||||
&& mv ./src/zokrates_cli/examples . \
|
||||
&& mv ./src/stdlib/* $ZOKRATES_HOME \
|
||||
&& rustup self uninstall -y \
|
||||
&& rm -rf $LIBSNARK_SOURCE_PATH src
|
|
@ -8,6 +8,7 @@ ARG RUST_TOOLCHAIN=nightly-2019-01-01
|
|||
ARG LIBSNARK_COMMIT=f7c87b88744ecfd008126d415494d9b34c4c1b20
|
||||
ENV LIBSNARK_SOURCE_PATH=/home/zokrates/libsnark-$LIBSNARK_COMMIT
|
||||
ENV WITH_LIBSNARK=1
|
||||
ENV ZOKRATES_HOME=/home/zokrates/ZoKrates/stdlib/
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
build-essential \
|
||||
|
|
4
stdlib/fortytwo.code
Normal file
4
stdlib/fortytwo.code
Normal file
|
@ -0,0 +1,4 @@
|
|||
// just as an example, to be removed
|
||||
|
||||
def main() -> (field):
|
||||
return 42
|
9
tools/zokrates_wasm_plugin/Cargo.toml
Normal file
9
tools/zokrates_wasm_plugin/Cargo.toml
Normal file
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "zokrates_wasm_plugin"
|
||||
version = "0.1.0"
|
||||
authors = ["Guillaume Ballet <gballet@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
parity-wasm = "0.35.3"
|
||||
clap = "2.32.0"
|
|
@ -3,8 +3,5 @@
|
|||
Comments can be added with double-slashes.
|
||||
|
||||
```zokrates
|
||||
def main() -> (field):
|
||||
field a = 42 // this is an end of line comment
|
||||
// this is a full line comment
|
||||
return a
|
||||
{{#include ../../../zokrates_cli/examples/book/comments.code}}
|
||||
```
|
|
@ -9,38 +9,27 @@ Function calls can help make programs clearer and more modular. However, using f
|
|||
Arguments are passed by value.
|
||||
|
||||
```zokrates
|
||||
def incr(field a) -> (field)
|
||||
a = a + 1
|
||||
return 1
|
||||
|
||||
def main() -> (field):
|
||||
field x = 1
|
||||
field res = incr(x)
|
||||
x == 1 // x has not changed
|
||||
return 1
|
||||
{{#include ../../../zokrates_cli/examples/book/side_effects.code}}
|
||||
```
|
||||
|
||||
### If expressions
|
||||
|
||||
An if expression allows you to branch your code depending on conditions.
|
||||
An if expression allows you to branch your code depending on a condition.
|
||||
|
||||
```zokrates
|
||||
def main(field x) -> (field):
|
||||
field y = if x + 2 == 3 then 1 else 5 fi
|
||||
return y
|
||||
{{#include ../../../zokrates_cli/examples/book/if_else.code}}
|
||||
```
|
||||
|
||||
The condition supports `<`, `<=`, `>`, `>=`, `==`, which can be combined with the boolean operators `&&`, `||` and `!`.
|
||||
|
||||
>When it comes to inequality checks, there is a caveat: when executing `a < b`, both `a` and `b` will be asserted to be strictly lower than the biggest power of 2 lower than `p/2`. This means that `a` and `b` are both asserted to be between `0` and `2**252 - 1`. The same applies to other inequality checks.
|
||||
|
||||
### For loops
|
||||
|
||||
For loops are available with the following syntax:
|
||||
|
||||
```zokrates
|
||||
def main() -> (field):
|
||||
field res = 0
|
||||
for field i in 0..4 do
|
||||
res = res + i
|
||||
endfor
|
||||
return res
|
||||
{{#include ../../../zokrates_cli/examples/book/for.code}}
|
||||
```
|
||||
|
||||
The bounds have to be known at compile time, so only constants are allowed.
|
||||
|
|
|
@ -3,19 +3,14 @@
|
|||
A function has to be declared at the top level before it is called.
|
||||
|
||||
```zokrates
|
||||
def foo() -> (field):
|
||||
return 1
|
||||
|
||||
def bar() -> (field):
|
||||
return foo()
|
||||
{{#include ../../../zokrates_cli/examples/book/function_declaration.code}}
|
||||
```
|
||||
|
||||
A function's signature has to be explicitly provided.
|
||||
Functions can return many values by providing them as a comma-separated list.
|
||||
|
||||
```zokrates
|
||||
def main() -> (field, field[3]):
|
||||
return 1, [2, 3, 4]
|
||||
{{#include ../../../zokrates_cli/examples/book/multi_return.code}}
|
||||
```
|
||||
|
||||
### Inference
|
||||
|
@ -23,24 +18,11 @@ def main() -> (field, field[3]):
|
|||
When defining a variable as the return value of a function, types are optional:
|
||||
|
||||
```zokrates
|
||||
def foo() -> (field, field):
|
||||
return 21, 42
|
||||
|
||||
def main() -> (field):
|
||||
a, b = foo()
|
||||
return 1
|
||||
{{#include ../../../zokrates_cli/examples/book/multi_def.code}}
|
||||
```
|
||||
|
||||
If there is an ambiguity, providing the types of some of the assigned variables is necessary.
|
||||
|
||||
```zokrates
|
||||
def foo() -> (field, field[3]):
|
||||
return 1, [2, 3, 4]
|
||||
|
||||
def foo() -> (field, field):
|
||||
return 1, 2
|
||||
|
||||
def main() -> (field):
|
||||
a, field[3] b = foo()
|
||||
return 1
|
||||
{{#include ../../../zokrates_cli/examples/book/type_annotations.code}}
|
||||
```
|
|
@ -11,10 +11,7 @@ The prime `p` is set to `2188824287183927522224640574525727508854836440041603434
|
|||
While `field` values mostly behave like unsigned integers, one should keep in mind that they overflow at `p` and not some power of 2 and underflow at 0, so that we have:
|
||||
|
||||
```zokrates
|
||||
def main() -> (field):
|
||||
field p_minus_one = 21888242871839275222246405745257275088548364400416034343698204186575808495616
|
||||
0 - 1 == p_minus_one
|
||||
return 1
|
||||
{{#include ../../../zokrates_cli/examples/book/field_overflow.code}}
|
||||
```
|
||||
|
||||
### `bool`
|
||||
|
@ -30,8 +27,5 @@ Note that while equality checks are cheap, inequality checks should be use wisel
|
|||
Static arrays of `field` can be instantiated with a constant size, and their elements can be accessed and updated:
|
||||
|
||||
```zokrates
|
||||
def main() -> (field):
|
||||
field[3] a = [1, 2, 3]
|
||||
a[2] = 4
|
||||
return a[0] + a[2]
|
||||
{{#include ../../../zokrates_cli/examples/book/array.code}}
|
||||
```
|
|
@ -29,9 +29,7 @@ cd ZoKrates/target/release
|
|||
First, create the text-file `root.code` and implement your program. In this example, we will prove knowledge of the square root `a` of a number `b`:
|
||||
|
||||
```zokrates
|
||||
def main(private field a, field b) -> (field):
|
||||
field result = if a * a == b then 1 else 0
|
||||
return result
|
||||
{{#include ../../zokrates_cli/examples/book/factorize.code}}
|
||||
```
|
||||
|
||||
Some observations:
|
||||
|
@ -53,4 +51,4 @@ Then run the different phases of the protocol:
|
|||
./zokrates export-verifier
|
||||
```
|
||||
|
||||
The CLI commands are explained in more detail in the [CLI reference](reference/cli.html).
|
||||
The CLI commands are explained in more detail in the [CLI reference](reference/cli.html).
|
||||
|
|
|
@ -16,11 +16,7 @@ We will start this tutorial by using ZoKrates to compute the hash for an arbitra
|
|||
First, make sure that the `zokrates` binary is located in the `ZoKrates` directory. Then, we create a new file named `hashexample.code` with the following content:
|
||||
|
||||
```zokrates
|
||||
import "./stdlib/sha256/512_packed.code" as sha256packed
|
||||
|
||||
def main(private field a, private field b, private field c, private field d) -> (field, field):
|
||||
h0, h1 = sha256packed(a, b, c, d)
|
||||
return h0, h1
|
||||
{{#include ../../zokrates_cli/examples/book/hashexample.code}}
|
||||
```
|
||||
|
||||
The first line imports the `sha256packed` function from the ZoKrates standard library.
|
||||
|
@ -74,6 +70,7 @@ To make it work, the two parties have to follow their roles in the protocol:
|
|||
First, Victor has to specify what hash he is interested in. Therefore, we have to adjust the zkSNARK circuit, compiled by ZoKrates, such that in addition to computing the digest, it also validates it against the digest of interest, provided by Victor. This leads to the following update for `hashexample.code`:
|
||||
|
||||
```zokrates
|
||||
<<<<<<< HEAD
|
||||
import "./stdlib/sha256/512_packed.code" as sha256packed
|
||||
|
||||
def main(private field a, private field b, private field c, private field d) -> (field):
|
||||
|
@ -81,6 +78,9 @@ def main(private field a, private field b, private field c, private field d) ->
|
|||
h0 == 263561599766550617289250058199814760685
|
||||
h1 == 65303172752238645975888084098459749904
|
||||
return 1
|
||||
=======
|
||||
{{#include ../../zokrates_cli/examples/book/hashexample_updated.code}}
|
||||
>>>>>>> develop
|
||||
```
|
||||
|
||||
Note that we now compare the result of `sha256packed` with the hard-coded correct solution defined by Victor. The lines which we added are treated as assertions: the verifier will not accept a proof where these constraints were not satisfied. Clearly, this program only returns 1 if all of the computed bits are equal.
|
||||
|
|
2
zokrates_cli/examples/arrays/if_eq.code
Normal file
2
zokrates_cli/examples/arrays/if_eq.code
Normal file
|
@ -0,0 +1,2 @@
|
|||
def main(field[2] a, field[2] b, field condition) -> (field[2]):
|
||||
return if condition == 1 then a else b fi
|
4
zokrates_cli/examples/book/array.code
Normal file
4
zokrates_cli/examples/book/array.code
Normal file
|
@ -0,0 +1,4 @@
|
|||
def main() -> (field):
|
||||
field[3] a = [1, 2, 3]
|
||||
a[2] = 4
|
||||
return a[0] + a[2]
|
4
zokrates_cli/examples/book/comments.code
Normal file
4
zokrates_cli/examples/book/comments.code
Normal file
|
@ -0,0 +1,4 @@
|
|||
def main() -> (field):
|
||||
field a = 42 // this is an end of line comment
|
||||
// this is a full line comment
|
||||
return a
|
3
zokrates_cli/examples/book/factorize.code
Normal file
3
zokrates_cli/examples/book/factorize.code
Normal file
|
@ -0,0 +1,3 @@
|
|||
def main(private field a, field b) -> (field):
|
||||
field result = if a * a == b then 1 else 0 fi
|
||||
return result
|
4
zokrates_cli/examples/book/field_overflow.code
Normal file
4
zokrates_cli/examples/book/field_overflow.code
Normal file
|
@ -0,0 +1,4 @@
|
|||
def main() -> (field):
|
||||
field pMinusOne = 21888242871839275222246405745257275088548364400416034343698204186575808495616
|
||||
0 - 1 == pMinusOne
|
||||
return 1
|
6
zokrates_cli/examples/book/for.code
Normal file
6
zokrates_cli/examples/book/for.code
Normal file
|
@ -0,0 +1,6 @@
|
|||
def main() -> (field):
|
||||
field res = 0
|
||||
for field i in 0..4 do
|
||||
res = res + i
|
||||
endfor
|
||||
return res
|
5
zokrates_cli/examples/book/function_declaration.code
Normal file
5
zokrates_cli/examples/book/function_declaration.code
Normal file
|
@ -0,0 +1,5 @@
|
|||
def foo() -> (field):
|
||||
return 1
|
||||
|
||||
def main() -> (field):
|
||||
return foo()
|
5
zokrates_cli/examples/book/hashexample.code
Normal file
5
zokrates_cli/examples/book/hashexample.code
Normal file
|
@ -0,0 +1,5 @@
|
|||
import "LIBSNARK/sha256packed"
|
||||
|
||||
def main(private field a, private field b, private field c, private field d) -> (field, field):
|
||||
h0, h1 = sha256packed(a, b, c, d)
|
||||
return h0, h1
|
7
zokrates_cli/examples/book/hashexample_updated.code
Normal file
7
zokrates_cli/examples/book/hashexample_updated.code
Normal file
|
@ -0,0 +1,7 @@
|
|||
import "LIBSNARK/sha256packed"
|
||||
|
||||
def main(private field a, private field b, private field c, private field d) -> (field):
|
||||
h0, h1 = sha256packed(a, b, c, d)
|
||||
h0 == 263561599766550617289250058199814760685
|
||||
h1 == 65303172752238645975888084098459749904
|
||||
return 1
|
3
zokrates_cli/examples/book/if_else.code
Normal file
3
zokrates_cli/examples/book/if_else.code
Normal file
|
@ -0,0 +1,3 @@
|
|||
def main(field x) -> (field):
|
||||
field y = if x + 2 == 3 then 1 else 5 fi
|
||||
return y
|
6
zokrates_cli/examples/book/multi_def.code
Normal file
6
zokrates_cli/examples/book/multi_def.code
Normal file
|
@ -0,0 +1,6 @@
|
|||
def foo() -> (field, field):
|
||||
return 21, 42
|
||||
|
||||
def main() -> (field):
|
||||
a, b = foo()
|
||||
return 1
|
2
zokrates_cli/examples/book/multi_return.code
Normal file
2
zokrates_cli/examples/book/multi_return.code
Normal file
|
@ -0,0 +1,2 @@
|
|||
def main() -> (field, field[3]):
|
||||
return 1, [2, 3, 4]
|
9
zokrates_cli/examples/book/side_effects.code
Normal file
9
zokrates_cli/examples/book/side_effects.code
Normal file
|
@ -0,0 +1,9 @@
|
|||
def incr(field a) -> (field):
|
||||
a = a + 1
|
||||
return a
|
||||
|
||||
def main() -> (field):
|
||||
field x = 1
|
||||
field res = incr(x)
|
||||
x == 1 // x has not changed
|
||||
return 1
|
9
zokrates_cli/examples/book/type_annotations.code
Normal file
9
zokrates_cli/examples/book/type_annotations.code
Normal file
|
@ -0,0 +1,9 @@
|
|||
def foo() -> (field, field[3]):
|
||||
return 1, [2, 3, 4]
|
||||
|
||||
def foo() -> (field, field):
|
||||
return 1, 2
|
||||
|
||||
def main() -> (field):
|
||||
a, field[3] b = foo()
|
||||
return 1
|
|
@ -649,6 +649,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn examples_with_input_failure() {
|
||||
//these examples should compile but not run
|
||||
for p in glob("./examples/runtime_errors/*.code").expect("Failed to read glob pattern") {
|
||||
|
@ -675,12 +676,9 @@ mod tests {
|
|||
|
||||
let (..) = r1cs_program(program_flattened.clone());
|
||||
|
||||
let result = std::panic::catch_unwind(|| {
|
||||
let _ = program_flattened
|
||||
.execute(&vec![FieldPrime::from(0)])
|
||||
.unwrap();
|
||||
});
|
||||
assert!(result.is_err());
|
||||
let _ = program_flattened
|
||||
.execute(&vec![FieldPrime::from(0)])
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ build = "build.rs"
|
|||
[features]
|
||||
default = []
|
||||
libsnark = []
|
||||
wasm = []
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2.0"
|
||||
|
@ -20,10 +21,14 @@ reduce = "0.1.1"
|
|||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
serde_json = "1.0"
|
||||
serde_bytes = "0.10"
|
||||
bincode = "0.8.0"
|
||||
regex = "0.2"
|
||||
bimap = "0.1"
|
||||
zokrates_field = { version = "0.3.0", path = "../zokrates_field" }
|
||||
wasmi = "0.4.2"
|
||||
parity-wasm = "0.35.3"
|
||||
rustc-hex = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
glob = "0.2.11"
|
||||
|
@ -31,4 +36,5 @@ assert_cli = "0.5"
|
|||
|
||||
[build-dependencies]
|
||||
cc = { version = "1.0", features = ["parallel"] }
|
||||
cmake = "0.1.31"
|
||||
cmake = "0.1.31"
|
||||
parity-wasm = "0.35.3"
|
||||
|
|
|
@ -169,7 +169,7 @@ impl Flattener {
|
|||
// add a directive to get the bits
|
||||
statements_flattened.push(FlatStatement::Directive(DirectiveStatement::new(
|
||||
lhs_bits.clone(),
|
||||
Helper::Rust(RustHelper::Bits),
|
||||
Helper::bits(),
|
||||
vec![lhs_id],
|
||||
)));
|
||||
|
||||
|
@ -216,7 +216,7 @@ impl Flattener {
|
|||
// add a directive to get the bits
|
||||
statements_flattened.push(FlatStatement::Directive(DirectiveStatement::new(
|
||||
rhs_bits.clone(),
|
||||
Helper::Rust(RustHelper::Bits),
|
||||
Helper::bits(),
|
||||
vec![rhs_id],
|
||||
)));
|
||||
|
||||
|
@ -250,22 +250,17 @@ impl Flattener {
|
|||
));
|
||||
}
|
||||
|
||||
// sym = (lhs * 2) - (rhs * 2)
|
||||
let subtraction_result_id = self.use_sym();
|
||||
|
||||
statements_flattened.push(FlatStatement::Definition(
|
||||
subtraction_result_id,
|
||||
FlatExpression::Sub(
|
||||
box FlatExpression::Mult(
|
||||
box FlatExpression::Number(T::from(2)),
|
||||
box FlatExpression::Identifier(lhs_id),
|
||||
),
|
||||
box FlatExpression::Mult(
|
||||
box FlatExpression::Number(T::from(2)),
|
||||
box FlatExpression::Identifier(rhs_id),
|
||||
),
|
||||
// sym := (lhs * 2) - (rhs * 2)
|
||||
let subtraction_result = FlatExpression::Sub(
|
||||
box FlatExpression::Mult(
|
||||
box FlatExpression::Number(T::from(2)),
|
||||
box FlatExpression::Identifier(lhs_id),
|
||||
),
|
||||
));
|
||||
box FlatExpression::Mult(
|
||||
box FlatExpression::Number(T::from(2)),
|
||||
box FlatExpression::Identifier(rhs_id),
|
||||
),
|
||||
);
|
||||
|
||||
// define variables for the bits
|
||||
let sub_bits: Vec<FlatVariable> = (0..self.bits).map(|_| self.use_sym()).collect();
|
||||
|
@ -273,8 +268,8 @@ impl Flattener {
|
|||
// add a directive to get the bits
|
||||
statements_flattened.push(FlatStatement::Directive(DirectiveStatement::new(
|
||||
sub_bits.clone(),
|
||||
Helper::Rust(RustHelper::Bits),
|
||||
vec![subtraction_result_id],
|
||||
Helper::bits(),
|
||||
vec![subtraction_result.clone()],
|
||||
)));
|
||||
|
||||
// bitness checks
|
||||
|
@ -301,10 +296,7 @@ impl Flattener {
|
|||
);
|
||||
}
|
||||
|
||||
statements_flattened.push(FlatStatement::Condition(
|
||||
FlatExpression::Identifier(subtraction_result_id),
|
||||
expr,
|
||||
));
|
||||
statements_flattened.push(FlatStatement::Condition(subtraction_result, expr));
|
||||
|
||||
FlatExpression::Identifier(sub_bits[0])
|
||||
}
|
||||
|
@ -319,10 +311,8 @@ impl Flattener {
|
|||
// Y == X * M
|
||||
// 0 == (1-Y) * X
|
||||
|
||||
let name_x = self.use_sym();
|
||||
let name_y = self.use_sym();
|
||||
let name_m = self.use_sym();
|
||||
let name_1_y = self.use_sym();
|
||||
|
||||
let x = self.flatten_field_expression(
|
||||
functions_flattened,
|
||||
|
@ -331,35 +321,27 @@ impl Flattener {
|
|||
FieldElementExpression::Sub(box lhs, box rhs),
|
||||
);
|
||||
|
||||
statements_flattened.push(FlatStatement::Definition(name_x, x));
|
||||
statements_flattened.push(FlatStatement::Directive(DirectiveStatement::new(
|
||||
vec![name_y, name_m],
|
||||
Helper::Rust(RustHelper::ConditionEq),
|
||||
vec![name_x],
|
||||
vec![x.clone()],
|
||||
)));
|
||||
statements_flattened.push(FlatStatement::Condition(
|
||||
FlatExpression::Identifier(name_y),
|
||||
FlatExpression::Mult(
|
||||
box FlatExpression::Identifier(name_x),
|
||||
box FlatExpression::Identifier(name_m),
|
||||
),
|
||||
));
|
||||
statements_flattened.push(FlatStatement::Definition(
|
||||
name_1_y,
|
||||
FlatExpression::Sub(
|
||||
box FlatExpression::Number(T::one()),
|
||||
box FlatExpression::Identifier(name_y),
|
||||
),
|
||||
));
|
||||
statements_flattened.push(FlatStatement::Condition(
|
||||
FlatExpression::Number(T::zero()),
|
||||
FlatExpression::Mult(
|
||||
box FlatExpression::Identifier(name_1_y),
|
||||
box FlatExpression::Identifier(name_x),
|
||||
),
|
||||
FlatExpression::Mult(box x.clone(), box FlatExpression::Identifier(name_m)),
|
||||
));
|
||||
|
||||
FlatExpression::Identifier(name_1_y)
|
||||
let res = FlatExpression::Sub(
|
||||
box FlatExpression::Number(T::one()),
|
||||
box FlatExpression::Identifier(name_y),
|
||||
);
|
||||
|
||||
statements_flattened.push(FlatStatement::Condition(
|
||||
FlatExpression::Number(T::zero()),
|
||||
FlatExpression::Mult(box res.clone(), box x),
|
||||
));
|
||||
|
||||
res
|
||||
}
|
||||
BooleanExpression::Le(box lhs, box rhs) => {
|
||||
let lt = self.flatten_boolean_expression(
|
||||
|
@ -647,6 +629,7 @@ impl Flattener {
|
|||
statements_flattened,
|
||||
right,
|
||||
);
|
||||
|
||||
let new_left = if left_flattened.is_linear() {
|
||||
left_flattened
|
||||
} else {
|
||||
|
@ -661,6 +644,7 @@ impl Flattener {
|
|||
statements_flattened.push(FlatStatement::Definition(id, right_flattened));
|
||||
FlatExpression::Identifier(id)
|
||||
};
|
||||
|
||||
FlatExpression::Sub(box new_left, box new_right)
|
||||
}
|
||||
FieldElementExpression::Mult(box left, box right) => {
|
||||
|
@ -677,26 +661,14 @@ impl Flattener {
|
|||
right,
|
||||
);
|
||||
let new_left = if left_flattened.is_linear() {
|
||||
if let FlatExpression::Sub(..) = left_flattened {
|
||||
let id = self.use_sym();
|
||||
statements_flattened.push(FlatStatement::Definition(id, left_flattened));
|
||||
FlatExpression::Identifier(id)
|
||||
} else {
|
||||
left_flattened
|
||||
}
|
||||
left_flattened
|
||||
} else {
|
||||
let id = self.use_sym();
|
||||
statements_flattened.push(FlatStatement::Definition(id, left_flattened));
|
||||
FlatExpression::Identifier(id)
|
||||
};
|
||||
let new_right = if right_flattened.is_linear() {
|
||||
if let FlatExpression::Sub(..) = right_flattened {
|
||||
let id = self.use_sym();
|
||||
statements_flattened.push(FlatStatement::Definition(id, right_flattened));
|
||||
FlatExpression::Identifier(id)
|
||||
} else {
|
||||
right_flattened
|
||||
}
|
||||
right_flattened
|
||||
} else {
|
||||
let id = self.use_sym();
|
||||
statements_flattened.push(FlatStatement::Definition(id, right_flattened));
|
||||
|
@ -864,6 +836,30 @@ impl Flattener {
|
|||
FieldElementArrayExpression::FunctionCall(..) => {
|
||||
unimplemented!("please use intermediate variables for now")
|
||||
}
|
||||
FieldElementArrayExpression::IfElse(
|
||||
condition,
|
||||
consequence,
|
||||
alternative,
|
||||
) => {
|
||||
// [if cond then [a, b] else [c, d]][1] == if cond then [a, b][1] else [c, d][1]
|
||||
self.flatten_field_expression(
|
||||
functions_flattened,
|
||||
arguments_flattened,
|
||||
statements_flattened,
|
||||
FieldElementExpression::IfElse(
|
||||
condition,
|
||||
box FieldElementExpression::Select(
|
||||
consequence,
|
||||
box FieldElementExpression::Number(n.clone()),
|
||||
),
|
||||
box FieldElementExpression::Select(
|
||||
alternative,
|
||||
box FieldElementExpression::Number(n),
|
||||
),
|
||||
),
|
||||
)
|
||||
.apply_recursive_substitution(&self.substitution)
|
||||
}
|
||||
},
|
||||
e => {
|
||||
let size = array.size();
|
||||
|
@ -921,6 +917,21 @@ impl Flattener {
|
|||
"please use intermediate variables for now"
|
||||
)
|
||||
}
|
||||
FieldElementArrayExpression::IfElse(
|
||||
condition,
|
||||
consequence,
|
||||
alternative,
|
||||
) => FieldElementExpression::IfElse(
|
||||
condition,
|
||||
box FieldElementExpression::Select(
|
||||
consequence,
|
||||
box FieldElementExpression::Number(T::from(i)),
|
||||
),
|
||||
box FieldElementExpression::Select(
|
||||
alternative,
|
||||
box FieldElementExpression::Number(T::from(i)),
|
||||
),
|
||||
),
|
||||
},
|
||||
box FieldElementExpression::Number(T::from(0)),
|
||||
)
|
||||
|
@ -984,6 +995,36 @@ impl Flattener {
|
|||
assert!(exprs_flattened.expressions.len() == size); // outside of MultipleDefinition, FunctionCalls must return a single value
|
||||
exprs_flattened.expressions
|
||||
}
|
||||
FieldElementArrayExpression::IfElse(
|
||||
ref condition,
|
||||
ref consequence,
|
||||
ref alternative,
|
||||
) => {
|
||||
let size = match consequence.get_type() {
|
||||
Type::FieldElementArray(n) => n,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
(0..size)
|
||||
.map(|i| {
|
||||
self.flatten_field_expression(
|
||||
functions_flattened,
|
||||
arguments_flattened,
|
||||
statements_flattened,
|
||||
FieldElementExpression::IfElse(
|
||||
condition.clone(),
|
||||
box FieldElementExpression::Select(
|
||||
consequence.clone(),
|
||||
box FieldElementExpression::Number(T::from(i)),
|
||||
),
|
||||
box FieldElementExpression::Select(
|
||||
alternative.clone(),
|
||||
box FieldElementExpression::Number(T::from(i)),
|
||||
),
|
||||
),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2333,6 +2374,75 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn array_if() {
|
||||
// if 1 == 1 then [1] else [3] fi
|
||||
|
||||
let with_arrays = {
|
||||
let mut flattener = Flattener::new(FieldPrime::get_required_bits());
|
||||
let mut functions_flattened = vec![];
|
||||
flattener.load_corelib(&mut functions_flattened);
|
||||
let arguments_flattened = vec![];
|
||||
let mut statements_flattened = vec![];
|
||||
|
||||
let e = FieldElementArrayExpression::IfElse(
|
||||
box BooleanExpression::Eq(
|
||||
box FieldElementExpression::Number(FieldPrime::from(1)),
|
||||
box FieldElementExpression::Number(FieldPrime::from(1)),
|
||||
),
|
||||
box FieldElementArrayExpression::Value(
|
||||
1,
|
||||
vec![FieldElementExpression::Number(FieldPrime::from(1))],
|
||||
),
|
||||
box FieldElementArrayExpression::Value(
|
||||
1,
|
||||
vec![FieldElementExpression::Number(FieldPrime::from(3))],
|
||||
),
|
||||
);
|
||||
|
||||
(
|
||||
flattener.flatten_field_array_expression(
|
||||
&mut functions_flattened,
|
||||
&arguments_flattened,
|
||||
&mut statements_flattened,
|
||||
e,
|
||||
)[0]
|
||||
.clone(),
|
||||
statements_flattened,
|
||||
)
|
||||
};
|
||||
|
||||
let without_arrays = {
|
||||
let mut flattener = Flattener::new(FieldPrime::get_required_bits());
|
||||
let mut functions_flattened = vec![];
|
||||
flattener.load_corelib(&mut functions_flattened);
|
||||
let arguments_flattened = vec![];
|
||||
let mut statements_flattened = vec![];
|
||||
|
||||
// if 1 == 1 then 1 else 3 fi
|
||||
let e = FieldElementExpression::IfElse(
|
||||
box BooleanExpression::Eq(
|
||||
box FieldElementExpression::Number(FieldPrime::from(1)),
|
||||
box FieldElementExpression::Number(FieldPrime::from(1)),
|
||||
),
|
||||
box FieldElementExpression::Number(FieldPrime::from(1)),
|
||||
box FieldElementExpression::Number(FieldPrime::from(3)),
|
||||
);
|
||||
|
||||
(
|
||||
flattener.flatten_field_expression(
|
||||
&mut functions_flattened,
|
||||
&arguments_flattened,
|
||||
&mut statements_flattened,
|
||||
e,
|
||||
),
|
||||
statements_flattened,
|
||||
)
|
||||
};
|
||||
|
||||
assert_eq!(with_arrays, without_arrays);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn next_variable() {
|
||||
let mut flattener = Flattener::new(FieldPrime::get_required_bits());
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
#[cfg(feature = "libsnark")]
|
||||
mod libsnark_gadget;
|
||||
mod rust;
|
||||
#[cfg(feature = "wasm")]
|
||||
mod wasm;
|
||||
|
||||
#[cfg(feature = "libsnark")]
|
||||
pub use self::libsnark_gadget::LibsnarkGadgetHelper;
|
||||
pub use self::rust::RustHelper;
|
||||
#[cfg(feature = "wasm")]
|
||||
pub use self::wasm::WasmHelper;
|
||||
use flat_absy::{FlatExpression, FlatVariable};
|
||||
use std::fmt;
|
||||
use zokrates_field::field::Field;
|
||||
|
@ -58,6 +62,30 @@ pub enum Helper {
|
|||
#[cfg(feature = "libsnark")]
|
||||
LibsnarkGadget(LibsnarkGadgetHelper),
|
||||
Rust(RustHelper),
|
||||
#[cfg(feature = "wasm")]
|
||||
Wasm(WasmHelper),
|
||||
}
|
||||
|
||||
#[cfg(feature = "wasm")]
|
||||
impl Helper {
|
||||
pub fn identity() -> Self {
|
||||
Helper::Wasm(WasmHelper::from_hex(WasmHelper::IDENTITY_WASM))
|
||||
}
|
||||
|
||||
pub fn bits() -> Self {
|
||||
Helper::Wasm(WasmHelper::from(WasmHelper::BITS_WASM))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "wasm"))]
|
||||
impl Helper {
|
||||
pub fn identity() -> Self {
|
||||
Helper::Rust(RustHelper::Identity)
|
||||
}
|
||||
|
||||
pub fn bits() -> Self {
|
||||
Helper::Rust(RustHelper::Bits)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Helper {
|
||||
|
@ -66,6 +94,8 @@ impl fmt::Display for Helper {
|
|||
#[cfg(feature = "libsnark")]
|
||||
Helper::LibsnarkGadget(ref h) => write!(f, "LibsnarkGadget::{}", h),
|
||||
Helper::Rust(ref h) => write!(f, "Rust::{}", h),
|
||||
#[cfg(feature = "wasm")]
|
||||
Helper::Wasm(ref h) => write!(f, "Wasm::{}", h),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,6 +117,8 @@ impl<T: Field> Executable<T> for Helper {
|
|||
#[cfg(feature = "libsnark")]
|
||||
Helper::LibsnarkGadget(helper) => helper.execute(inputs),
|
||||
Helper::Rust(helper) => helper.execute(inputs),
|
||||
#[cfg(feature = "wasm")]
|
||||
Helper::Wasm(helper) => helper.execute(inputs),
|
||||
};
|
||||
|
||||
match result {
|
||||
|
@ -107,6 +139,8 @@ impl Signed for Helper {
|
|||
#[cfg(feature = "libsnark")]
|
||||
Helper::LibsnarkGadget(helper) => helper.get_signature(),
|
||||
Helper::Rust(helper) => helper.get_signature(),
|
||||
#[cfg(feature = "wasm")]
|
||||
Helper::Wasm(helper) => helper.get_signature(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
581
zokrates_core/src/helpers/wasm.rs
Normal file
581
zokrates_core/src/helpers/wasm.rs
Normal file
|
@ -0,0 +1,581 @@
|
|||
use helpers::{Executable, Signed};
|
||||
use std::fmt;
|
||||
|
||||
use rustc_hex::FromHex;
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use std::rc::Rc;
|
||||
use wasmi::{ImportsBuilder, ModuleInstance, ModuleRef, NopExternals};
|
||||
use zokrates_field::field::Field;
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
pub struct WasmHelper(
|
||||
#[serde(skip)] std::rc::Rc<ModuleRef>,
|
||||
#[serde(serialize_with = "serde_bytes::serialize")] Vec<u8>,
|
||||
);
|
||||
|
||||
impl WasmHelper {
|
||||
// Hand-coded assembly for identity.
|
||||
// Source available at https://gist.github.com/gballet/f14d11053d8f846bfbb3687581b0eecb#file-identity-wast
|
||||
pub const IDENTITY_WASM: &'static str = "0061736d010000000105016000017f030302000005030100010615047f0041010b7f0041010b7f0041200b7f0141000b074b06066d656d6f727902000e6765745f696e707574735f6f6666000105736f6c766500000a6d696e5f696e7075747303000b6d696e5f6f75747075747303010a6669656c645f73697a6503020a2c0225000340412023036a410023036a280200360200230341016a240323032302470d000b41200b040041000b0b4b020041000b20ffffffff000000000000000000000000ffffffff0000000000000000000000000041200b20deadbeef000000000000000000000000deadbeef000000000000000000000000";
|
||||
// Generated from C code, normalized and cleaned up by hand.
|
||||
// Source available at https://gist.github.com/gballet/f14d11053d8f846bfbb3687581b0eecb#file-bits_v2-c
|
||||
pub const BITS_WASM: &'static [u8] = &[
|
||||
0, 97, 115, 109, 1, 0, 0, 0, 1, 8, 2, 96, 0, 0, 96, 0, 1, 127, 3, 5, 4, 0, 1, 1, 1, 4, 5,
|
||||
1, 112, 1, 1, 1, 5, 3, 1, 0, 2, 6, 38, 6, 127, 1, 65, 240, 199, 4, 11, 127, 0, 65, 240,
|
||||
199, 4, 11, 127, 0, 65, 240, 199, 0, 11, 127, 0, 65, 32, 11, 127, 0, 65, 1, 11, 127, 0, 65,
|
||||
254, 1, 11, 7, 109, 9, 6, 109, 101, 109, 111, 114, 121, 2, 0, 11, 95, 95, 104, 101, 97,
|
||||
112, 95, 98, 97, 115, 101, 3, 1, 10, 95, 95, 100, 97, 116, 97, 95, 101, 110, 100, 3, 2, 14,
|
||||
103, 101, 116, 95, 105, 110, 112, 117, 116, 115, 95, 111, 102, 102, 0, 1, 5, 115, 111, 108,
|
||||
118, 101, 0, 2, 4, 109, 97, 105, 110, 0, 3, 10, 102, 105, 101, 108, 100, 95, 115, 105, 122,
|
||||
101, 3, 3, 10, 109, 105, 110, 95, 105, 110, 112, 117, 116, 115, 3, 4, 11, 109, 105, 110,
|
||||
95, 111, 117, 116, 112, 117, 116, 115, 3, 5, 9, 1, 0, 10, 85, 4, 3, 0, 1, 11, 5, 0, 65,
|
||||
144, 8, 11, 68, 1, 2, 127, 65, 253, 1, 33, 0, 65, 176, 8, 33, 1, 3, 64, 32, 1, 65, 1, 32,
|
||||
0, 65, 7, 113, 116, 32, 0, 65, 3, 118, 65, 144, 8, 106, 45, 0, 0, 113, 65, 0, 71, 58, 0, 0,
|
||||
32, 1, 65, 32, 106, 33, 1, 32, 0, 65, 127, 106, 34, 0, 65, 127, 71, 13, 0, 11, 65, 176, 8,
|
||||
11, 4, 0, 65, 0, 11, 11, 19, 1, 0, 65, 128, 8, 11, 12, 32, 0, 0, 0, 1, 0, 0, 0, 254, 0, 0,
|
||||
0,
|
||||
];
|
||||
|
||||
pub fn from_hex<U: Into<String>>(u: U) -> Self {
|
||||
let code_hex = u.into();
|
||||
let code = FromHex::from_hex(&code_hex[..])
|
||||
.expect(format!("invalid bytecode: {}", code_hex).as_str());
|
||||
WasmHelper::from(code)
|
||||
}
|
||||
}
|
||||
|
||||
impl<U: Into<Vec<u8>>> From<U> for WasmHelper {
|
||||
fn from(code: U) -> Self {
|
||||
let code_vec = code.into();
|
||||
let module = wasmi::Module::from_buffer(code_vec.clone()).expect("Error decoding buffer");
|
||||
let modinst = ModuleInstance::new(&module, &ImportsBuilder::default())
|
||||
.expect("Failed to instantiate module")
|
||||
.assert_no_start();
|
||||
WasmHelper(Rc::new(modinst), code_vec)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for WasmHelper {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let hex: Vec<u8> = serde_bytes::deserialize(deserializer)?;
|
||||
Ok(WasmHelper::from(hex))
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for WasmHelper {
|
||||
fn eq(&self, other: &WasmHelper) -> bool {
|
||||
self.1 == other.1
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for WasmHelper {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Hex(\"{:?}\")", &self.1[..])
|
||||
}
|
||||
}
|
||||
|
||||
fn get_export<T: wasmi::FromRuntimeValue>(varname: &str, modref: &ModuleRef) -> Result<T, String> {
|
||||
modref
|
||||
.export_by_name(varname)
|
||||
.ok_or(&format!("Could not find exported symbol `{}` in module", varname)[..])?
|
||||
.as_global()
|
||||
.ok_or(format!(
|
||||
"Error getting {} from the list of globals",
|
||||
varname
|
||||
))?
|
||||
.get()
|
||||
.try_into::<T>()
|
||||
.ok_or(format!("Error converting `{}` to i32", varname))
|
||||
}
|
||||
|
||||
impl Signed for WasmHelper {
|
||||
fn get_signature(&self) -> (usize, usize) {
|
||||
// Check that the module has the following exports:
|
||||
// * min_inputs = the (minimum) number of inputs
|
||||
// * min_outputs = the (minimum) number of outputs
|
||||
let ni = get_export::<i32>("min_inputs", self.0.as_ref()).unwrap();
|
||||
let no = get_export::<i32>("min_outputs", self.0.as_ref()).unwrap();
|
||||
|
||||
(ni as usize, no as usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Field> Executable<T> for WasmHelper {
|
||||
fn execute(&self, inputs: &Vec<T>) -> Result<Vec<T>, String> {
|
||||
let field_size = get_export::<i32>("field_size", self.0.as_ref())? as usize;
|
||||
let ninputs = get_export::<i32>("min_inputs", self.0.as_ref())? as usize;
|
||||
|
||||
if ninputs != inputs.len() {
|
||||
return Err(format!(
|
||||
"`solve` expected {} inputs, received {}",
|
||||
ninputs,
|
||||
inputs.len()
|
||||
));
|
||||
}
|
||||
|
||||
/* Prepare the inputs */
|
||||
let input_offset = self
|
||||
.0
|
||||
.invoke_export("get_inputs_off", &[], &mut NopExternals)
|
||||
.map_err(|e| format!("Error getting the input offset: {}", e.to_string()))?
|
||||
.ok_or("`get_inputs_off` did not return any value")?
|
||||
.try_into::<i32>()
|
||||
.ok_or("`get_inputs_off` returned the wrong type")?;
|
||||
|
||||
let mem = self
|
||||
.0
|
||||
.as_ref()
|
||||
.export_by_name("memory")
|
||||
.ok_or("Module didn't export its memory section")?
|
||||
.as_memory()
|
||||
.unwrap()
|
||||
.clone();
|
||||
|
||||
for (index, input) in inputs.iter().enumerate() {
|
||||
// Get the field's bytes and check they correspond to
|
||||
// the value that the module expects.
|
||||
let mut bv = input.into_byte_vector();
|
||||
if bv.len() > field_size {
|
||||
return Err(format!(
|
||||
"Input #{} is stored on {} bytes which is greater than the field size of {}",
|
||||
index,
|
||||
bv.len(),
|
||||
field_size
|
||||
));
|
||||
} else {
|
||||
bv.resize(field_size, 0);
|
||||
}
|
||||
|
||||
let addr = (input_offset as u32) + (index as u32) * (field_size as u32);
|
||||
mem.set(addr, &bv[..])
|
||||
.map_err(|_e| format!("Could not write at memory address {}", addr))?;
|
||||
}
|
||||
|
||||
let output_offset = self
|
||||
.0
|
||||
.as_ref()
|
||||
.invoke_export("solve", &[], &mut NopExternals)
|
||||
.map_err(|e| format!("Error solving the problem: {}", e.to_string()))?
|
||||
.ok_or("`solve` did not return any value")?
|
||||
.try_into::<i32>()
|
||||
.ok_or("`solve returned the wrong type`")?;
|
||||
|
||||
// NOTE: The question regarding the way that an error code is
|
||||
// returned is still open.
|
||||
//
|
||||
// The current model considers that 2GB is more than enough
|
||||
// to store the output data.
|
||||
//
|
||||
// This being said this approach is tacky and I am considering
|
||||
// others at this point:
|
||||
//
|
||||
// 1. Use a 64 bit return code, values greater than 32-bits
|
||||
// are considered error codes.
|
||||
// 2. Export an extra global called `errno` which contains
|
||||
// the error code.
|
||||
// 3. 32-bit alignment gives a 2-bit error field
|
||||
// 4. Return a pointer to a structure that contains
|
||||
// the error code just before the output data.
|
||||
//
|
||||
// Experimenting with other languages will help decide what
|
||||
// is the better approach.
|
||||
if output_offset > 0 {
|
||||
let mut outputs = Vec::new();
|
||||
let noutputs = get_export::<i32>("min_outputs", self.0.as_ref())?;
|
||||
for i in 0..noutputs {
|
||||
let index = i as u32;
|
||||
let fs = field_size as u32;
|
||||
let value = mem
|
||||
.get(output_offset as u32 + fs * index, field_size)
|
||||
.map_err(|e| format!("Could not retrieve the output offset: {}", e))?;
|
||||
|
||||
outputs.push(T::from_byte_vector(value));
|
||||
}
|
||||
|
||||
Ok(outputs)
|
||||
} else {
|
||||
Err(format!("`solve` returned error code {}", output_offset))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use parity_wasm::builder::*;
|
||||
use parity_wasm::elements::{Instruction, Instructions, ValueType};
|
||||
use std::panic;
|
||||
use zokrates_field::field::FieldPrime;
|
||||
|
||||
fn remove_export(code: &str, symbol: &str) -> Vec<u8> {
|
||||
let code = FromHex::from_hex(code).unwrap();
|
||||
let mut idmod: parity_wasm::elements::Module = parity_wasm::deserialize_buffer(&code[..])
|
||||
.expect("Could not deserialize Identity module");
|
||||
idmod
|
||||
.export_section_mut()
|
||||
.expect("Could not get export section")
|
||||
.entries_mut()
|
||||
.retain(|ref export| export.field() != symbol);
|
||||
parity_wasm::serialize(idmod).expect("Could not serialize buffer")
|
||||
}
|
||||
|
||||
fn replace_function(
|
||||
code: &str,
|
||||
symbol: &str,
|
||||
params: Vec<ValueType>,
|
||||
ret: Option<ValueType>,
|
||||
instr: Vec<Instruction>,
|
||||
) -> Vec<u8> {
|
||||
/* Deserialize to parity_wasm format */
|
||||
let code = FromHex::from_hex(code).unwrap();
|
||||
let mut pwmod: parity_wasm::elements::Module = parity_wasm::deserialize_buffer(&code[..])
|
||||
.expect("Could not deserialize Identity module");
|
||||
|
||||
/* Remove export, if it exists */
|
||||
pwmod
|
||||
.export_section_mut()
|
||||
.expect("Could not get export section")
|
||||
.entries_mut()
|
||||
.retain(|ref export| export.field() != symbol);
|
||||
|
||||
/* Add a new function and give it the export name */
|
||||
let wmod: parity_wasm::elements::Module = from_module(pwmod)
|
||||
.function()
|
||||
.signature()
|
||||
.with_params(params)
|
||||
.with_return_type(ret)
|
||||
.build()
|
||||
.body()
|
||||
.with_instructions(Instructions::new(instr))
|
||||
.build()
|
||||
.build()
|
||||
.export()
|
||||
.field(symbol)
|
||||
.internal()
|
||||
.func(2)
|
||||
.build()
|
||||
.build();
|
||||
parity_wasm::serialize(wmod).expect("Could not serialize buffer")
|
||||
}
|
||||
|
||||
fn replace_global(code: &str, symbol: &str, value: i32) -> Vec<u8> {
|
||||
/* Deserialize to parity_wasm format */
|
||||
let code = FromHex::from_hex(code).unwrap();
|
||||
let mut pwmod: parity_wasm::elements::Module = parity_wasm::deserialize_buffer(&code[..])
|
||||
.expect("Could not deserialize Identity module");
|
||||
|
||||
/* Remove export, if it exists */
|
||||
pwmod
|
||||
.export_section_mut()
|
||||
.expect("Could not get export section")
|
||||
.entries_mut()
|
||||
.retain(|ref export| export.field() != symbol);
|
||||
|
||||
/* Add a new function and give it the export name */
|
||||
let wmod: parity_wasm::elements::Module = from_module(pwmod)
|
||||
.global()
|
||||
.value_type()
|
||||
.i32()
|
||||
.init_expr(Instruction::I32Const(value))
|
||||
.build()
|
||||
.export()
|
||||
.field(symbol)
|
||||
.internal()
|
||||
.global(4)
|
||||
.build()
|
||||
.build();
|
||||
parity_wasm::serialize(wmod).expect("Could not serialize buffer")
|
||||
}
|
||||
|
||||
fn replace_global_type(code: &str, symbol: &str) -> Vec<u8> {
|
||||
/* Deserialize to parity_wasm format */
|
||||
let code = FromHex::from_hex(code).unwrap();
|
||||
let mut pwmod: parity_wasm::elements::Module = parity_wasm::deserialize_buffer(&code[..])
|
||||
.expect("Could not deserialize Identity module");
|
||||
|
||||
/* Remove export, if it exists */
|
||||
pwmod
|
||||
.export_section_mut()
|
||||
.expect("Could not get export section")
|
||||
.entries_mut()
|
||||
.retain(|ref export| export.field() != symbol);
|
||||
|
||||
/* Add a new function and give it the export name */
|
||||
let wmod: parity_wasm::elements::Module = from_module(pwmod)
|
||||
.global()
|
||||
.value_type()
|
||||
.f32()
|
||||
.init_expr(Instruction::F32Const(0))
|
||||
.build()
|
||||
.export()
|
||||
.field(symbol)
|
||||
.internal()
|
||||
.global(4)
|
||||
.build()
|
||||
.build();
|
||||
parity_wasm::serialize(wmod).expect("Could not serialize buffer")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_signatures() {
|
||||
let h1 = WasmHelper::from_hex(WasmHelper::IDENTITY_WASM);
|
||||
assert_eq!(h1.get_signature(), (1, 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(
|
||||
expected = "invalid bytecode: invalid bytecode: Invalid character 'i' at position 0"
|
||||
)]
|
||||
fn check_invalid_bytecode_fails() {
|
||||
WasmHelper::from_hex("invalid bytecode");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "Error decoding buffer: Validation(\"I/O Error: UnexpectedEof\")")]
|
||||
fn check_truncated_bytecode_fails() {
|
||||
WasmHelper::from_hex(&WasmHelper::IDENTITY_WASM[..20]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validate_exports() {
|
||||
/* Test identity without the `solve` export */
|
||||
let id = WasmHelper::from(remove_export(WasmHelper::IDENTITY_WASM, "solve"));
|
||||
let input = vec![FieldPrime::from(1)];
|
||||
let outputs = id.execute(&input);
|
||||
assert_eq!(
|
||||
outputs,
|
||||
Err(String::from(
|
||||
"Error solving the problem: Function: Module doesn\'t have export solve",
|
||||
))
|
||||
);
|
||||
|
||||
/* Test identity, without the `get_inputs_off` export */
|
||||
let id = WasmHelper::from(remove_export(WasmHelper::IDENTITY_WASM, "get_inputs_off"));
|
||||
let input = vec![FieldPrime::from(1)];
|
||||
let outputs = id.execute(&input);
|
||||
assert_eq!(
|
||||
outputs,
|
||||
Err(String::from(
|
||||
"Error getting the input offset: Function: Module doesn\'t have export get_inputs_off",
|
||||
))
|
||||
);
|
||||
|
||||
/* Test identity, without the `min_inputs` export */
|
||||
let id = WasmHelper::from(remove_export(WasmHelper::IDENTITY_WASM, "min_inputs"));
|
||||
let input = vec![FieldPrime::from(1)];
|
||||
let outputs = id.execute(&input);
|
||||
assert_eq!(
|
||||
outputs,
|
||||
Err(String::from(
|
||||
"Could not find exported symbol `min_inputs` in module",
|
||||
))
|
||||
);
|
||||
|
||||
/* Test identity, without the `min_outputs` export */
|
||||
let id = WasmHelper::from(remove_export(WasmHelper::IDENTITY_WASM, "min_outputs"));
|
||||
let input = vec![FieldPrime::from(1)];
|
||||
let outputs = id.execute(&input);
|
||||
assert_eq!(
|
||||
outputs,
|
||||
Err(String::from(
|
||||
"Could not find exported symbol `min_outputs` in module",
|
||||
))
|
||||
);
|
||||
|
||||
/* Test identity, without the `field_size` export */
|
||||
let id = WasmHelper::from(remove_export(WasmHelper::IDENTITY_WASM, "field_size"));
|
||||
let input = vec![FieldPrime::from(1)];
|
||||
let outputs = id.execute(&input);
|
||||
assert_eq!(
|
||||
outputs,
|
||||
Err(String::from(
|
||||
"Could not find exported symbol `field_size` in module",
|
||||
))
|
||||
);
|
||||
|
||||
/* Test identity, without the `memory` export */
|
||||
let id = WasmHelper::from(remove_export(WasmHelper::IDENTITY_WASM, "memory"));
|
||||
let input = vec![FieldPrime::from(1)];
|
||||
let outputs = id.execute(&input);
|
||||
assert_eq!(
|
||||
outputs,
|
||||
Err(String::from("Module didn\'t export its memory section"))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_invalid_function_type() {
|
||||
/* Test identity, with a different function return type */
|
||||
let id = WasmHelper::from(replace_function(
|
||||
WasmHelper::IDENTITY_WASM,
|
||||
"get_inputs_off",
|
||||
Vec::new(),
|
||||
Some(ValueType::I64),
|
||||
vec![Instruction::I64Const(0), Instruction::End],
|
||||
));
|
||||
let input = vec![FieldPrime::from(1)];
|
||||
let outputs = id.execute(&input);
|
||||
assert_eq!(
|
||||
outputs,
|
||||
Err(String::from("`get_inputs_off` returned the wrong type"))
|
||||
);
|
||||
|
||||
/* Test identity, with no return type for function */
|
||||
let id = WasmHelper::from(replace_function(
|
||||
WasmHelper::IDENTITY_WASM,
|
||||
"get_inputs_off",
|
||||
Vec::new(),
|
||||
None,
|
||||
vec![Instruction::Nop, Instruction::End],
|
||||
));
|
||||
let input = vec![FieldPrime::from(1)];
|
||||
let outputs = id.execute(&input);
|
||||
assert_eq!(
|
||||
outputs,
|
||||
Err(String::from("`get_inputs_off` did not return any value"))
|
||||
);
|
||||
|
||||
/* Test identity, with extra parameter for function */
|
||||
let id = WasmHelper::from(replace_function(
|
||||
WasmHelper::IDENTITY_WASM,
|
||||
"get_inputs_off",
|
||||
vec![ValueType::I64],
|
||||
Some(ValueType::I32),
|
||||
vec![Instruction::I32Const(0), Instruction::End],
|
||||
));
|
||||
let input = vec![FieldPrime::from(1)];
|
||||
let outputs = id.execute(&input);
|
||||
assert_eq!(
|
||||
outputs,
|
||||
Err(String::from(
|
||||
"Error getting the input offset: Trap: Trap { kind: UnexpectedSignature }",
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_invalid_field_size() {
|
||||
/* Test identity, with 1-byte filed size */
|
||||
let id = WasmHelper::from(replace_global(WasmHelper::IDENTITY_WASM, "field_size", 1));
|
||||
let input = vec![FieldPrime::from(65536)];
|
||||
let outputs = id.execute(&input);
|
||||
assert_eq!(
|
||||
outputs,
|
||||
Err(String::from(
|
||||
"Input #0 is stored on 3 bytes which is greater than the field size of 1",
|
||||
))
|
||||
);
|
||||
|
||||
/* Test identity, tweaked so that field_size is a f32 */
|
||||
let id = WasmHelper::from(replace_global_type(WasmHelper::IDENTITY_WASM, "field_size"));
|
||||
let input = vec![FieldPrime::from(65536)];
|
||||
let outputs = id.execute(&input);
|
||||
assert_eq!(
|
||||
outputs,
|
||||
Err(String::from("Error converting `field_size` to i32"))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_identity() {
|
||||
let id = WasmHelper::from_hex(WasmHelper::IDENTITY_WASM);
|
||||
let input = vec![FieldPrime::from(1)];
|
||||
let outputs = id.execute(&input).expect("Identity call failed");
|
||||
assert_eq!(outputs, input);
|
||||
|
||||
let id = WasmHelper::from_hex(WasmHelper::IDENTITY_WASM);
|
||||
let input = vec![FieldPrime::from(0)];
|
||||
let outputs = id.execute(&input).expect("Identity call failed");
|
||||
assert_eq!(outputs, input);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_identity_3_bytes() {
|
||||
let id = WasmHelper::from_hex(WasmHelper::IDENTITY_WASM);
|
||||
let input = vec![FieldPrime::from(16777216)];
|
||||
let outputs = id.execute(&input).expect("Identity call failed");
|
||||
assert_eq!(outputs, input);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_invalid_arg_number() {
|
||||
let id = WasmHelper::from_hex(WasmHelper::IDENTITY_WASM);
|
||||
let input = vec![FieldPrime::from(1)];
|
||||
let outputs = id.execute(&input).expect("Identity call failed");
|
||||
assert_eq!(outputs, input);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_memory_boundaries() {
|
||||
// Check that input writes are boundary-checked: same as identity, but
|
||||
// get_inputs_off returns an OOB offset.
|
||||
let id = WasmHelper::from(replace_function(
|
||||
WasmHelper::IDENTITY_WASM,
|
||||
"get_inputs_off",
|
||||
Vec::new(),
|
||||
Some(ValueType::I32),
|
||||
vec![Instruction::I32Const(65536), Instruction::End],
|
||||
));
|
||||
let input = vec![FieldPrime::from(65536)];
|
||||
let outputs = id.execute(&input);
|
||||
assert_eq!(
|
||||
outputs,
|
||||
Err(String::from("Could not write at memory address 65536"))
|
||||
);
|
||||
|
||||
/* Check that output writes are boundary-checked */
|
||||
// Check that input writes are boundary-checked: same as identity, but
|
||||
// solve returns an OOB offset.
|
||||
let id = WasmHelper::from(replace_function(
|
||||
WasmHelper::IDENTITY_WASM,
|
||||
"solve",
|
||||
Vec::new(),
|
||||
Some(ValueType::I32),
|
||||
vec![Instruction::I32Const(65536), Instruction::End],
|
||||
));
|
||||
let input = vec![FieldPrime::from(65536)];
|
||||
let outputs = id.execute(&input);
|
||||
assert_eq!(
|
||||
outputs,
|
||||
Err(String::from(
|
||||
"Could not retrieve the output offset: Memory: trying to access region [65536..65568] in memory [0..64]",
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_negative_output_value() {
|
||||
/* Same as identity, but `solve` returns -1 */
|
||||
let id = WasmHelper::from(replace_function(
|
||||
WasmHelper::IDENTITY_WASM,
|
||||
"solve",
|
||||
Vec::new(),
|
||||
Some(ValueType::I32),
|
||||
vec![Instruction::I32Const(-1), Instruction::End],
|
||||
));
|
||||
let input = vec![FieldPrime::from(1)];
|
||||
let outputs = id.execute(&input);
|
||||
assert_eq!(outputs, Err(String::from("`solve` returned error code -1")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_bits() {
|
||||
let bits = WasmHelper::from(WasmHelper::BITS_WASM);
|
||||
let input = vec![FieldPrime::from(0xdeadbeef as u32)];
|
||||
let outputs = bits.execute(&input).unwrap();
|
||||
|
||||
assert_eq!(254, outputs.len());
|
||||
|
||||
for i in 0..32 {
|
||||
let bitval = (0xdeadbeef as i64 >> i) & 1;
|
||||
assert_eq!(outputs[(253 - i) as usize], FieldPrime::from(bitval as i32));
|
||||
}
|
||||
|
||||
for i in 32..254 {
|
||||
assert_eq!(outputs[(253 - i) as usize], FieldPrime::from(0));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,12 +8,14 @@ pub type ExecutionResult<T> = Result<Witness<T>, Error>;
|
|||
pub struct Witness<T: Field>(BTreeMap<FlatVariable, T>);
|
||||
|
||||
impl<T: Field> Witness<T> {
|
||||
pub fn return_values(&self) -> Vec<T> {
|
||||
self.0
|
||||
.clone()
|
||||
.into_iter()
|
||||
pub fn return_values(&self) -> Vec<&T> {
|
||||
let out = self
|
||||
.0
|
||||
.iter()
|
||||
.filter(|(k, _)| k.is_output())
|
||||
.map(|(_, v)| v)
|
||||
.collect::<HashMap<_, _>>();
|
||||
(0..out.len())
|
||||
.map(|i| *out.get(&FlatVariable::public(i)).unwrap())
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,15 @@ extern crate serde_json;
|
|||
extern crate serde_derive;
|
||||
extern crate bimap;
|
||||
extern crate bincode;
|
||||
#[cfg(feature = "wasm")]
|
||||
extern crate parity_wasm;
|
||||
extern crate regex;
|
||||
#[cfg(feature = "wasm")]
|
||||
extern crate rustc_hex;
|
||||
#[cfg(feature = "wasm")]
|
||||
extern crate serde_bytes;
|
||||
#[cfg(feature = "wasm")]
|
||||
extern crate wasmi;
|
||||
extern crate zokrates_field;
|
||||
|
||||
mod flatten;
|
||||
|
|
|
@ -540,25 +540,32 @@ impl Checker {
|
|||
let consequence_checked = self.check_expression(&consequence)?;
|
||||
let alternative_checked = self.check_expression(&alternative)?;
|
||||
|
||||
match (condition_checked, consequence_checked, alternative_checked) {
|
||||
(TypedExpression::Boolean(condition), TypedExpression::FieldElement(consequence), TypedExpression::FieldElement(alternative)) => {
|
||||
Ok(FieldElementExpression::IfElse(box condition, box consequence, box alternative).into())
|
||||
},
|
||||
(condition, consequence, alternative) =>
|
||||
Err(
|
||||
Error {
|
||||
message:
|
||||
format!("if {{condition}} then {{consequence}} else {{alternative}} should have types {}, {}, {}, found {}, {}, {}",
|
||||
Type::Boolean,
|
||||
Type::FieldElement,
|
||||
Type::FieldElement,
|
||||
condition.get_type(),
|
||||
consequence.get_type(),
|
||||
alternative.get_type(),
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
match condition_checked {
|
||||
TypedExpression::Boolean(condition) => {
|
||||
let consequence_type = consequence_checked.get_type();
|
||||
let alternative_type = alternative_checked.get_type();
|
||||
match consequence_type == alternative_type {
|
||||
true => match (consequence_checked, alternative_checked) {
|
||||
(TypedExpression::FieldElement(consequence), TypedExpression::FieldElement(alternative)) => {
|
||||
Ok(FieldElementExpression::IfElse(box condition, box consequence, box alternative).into())
|
||||
},
|
||||
(TypedExpression::FieldElementArray(consequence), TypedExpression::FieldElementArray(alternative)) => {
|
||||
Ok(FieldElementArrayExpression::IfElse(box condition, box consequence, box alternative).into())
|
||||
},
|
||||
_ => unimplemented!()
|
||||
}
|
||||
false => Err(Error {
|
||||
message: format!("{{consequence}} and {{alternative}} in `if/else` expression should have the same type, found {}, {}", consequence_type, alternative_type)
|
||||
})
|
||||
}
|
||||
}
|
||||
c => Err(Error {
|
||||
message: format!(
|
||||
"{{condition}} after `if` should be a boolean, found {}",
|
||||
c.get_type()
|
||||
),
|
||||
}),
|
||||
}
|
||||
}
|
||||
&Expression::Number(ref n) => Ok(FieldElementExpression::Number(n.clone()).into()),
|
||||
&Expression::FunctionCall(ref fun_id, ref arguments) => {
|
||||
|
|
|
@ -147,6 +147,13 @@ pub fn fold_field_array_expression<T: Field, F: Folder<T>>(
|
|||
let exps = exps.into_iter().map(|e| f.fold_expression(e)).collect();
|
||||
FieldElementArrayExpression::FunctionCall(size, id, exps)
|
||||
}
|
||||
FieldElementArrayExpression::IfElse(box condition, box consequence, box alternative) => {
|
||||
FieldElementArrayExpression::IfElse(
|
||||
box f.fold_boolean_expression(condition),
|
||||
box f.fold_field_array_expression(consequence),
|
||||
box f.fold_field_array_expression(alternative),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -300,17 +300,18 @@ impl<T: Field> Typed for TypedExpression<T> {
|
|||
match *self {
|
||||
TypedExpression::Boolean(_) => Type::Boolean,
|
||||
TypedExpression::FieldElement(_) => Type::FieldElement,
|
||||
TypedExpression::FieldElementArray(FieldElementArrayExpression::Identifier(n, _)) => {
|
||||
Type::FieldElementArray(n)
|
||||
}
|
||||
TypedExpression::FieldElementArray(FieldElementArrayExpression::Value(n, _)) => {
|
||||
Type::FieldElementArray(n)
|
||||
}
|
||||
TypedExpression::FieldElementArray(FieldElementArrayExpression::FunctionCall(
|
||||
n,
|
||||
_,
|
||||
_,
|
||||
)) => Type::FieldElementArray(n),
|
||||
TypedExpression::FieldElementArray(ref e) => e.get_type(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Field> Typed for FieldElementArrayExpression<T> {
|
||||
fn get_type(&self) -> Type {
|
||||
match *self {
|
||||
FieldElementArrayExpression::Identifier(n, _) => Type::FieldElementArray(n),
|
||||
FieldElementArrayExpression::Value(n, _) => Type::FieldElementArray(n),
|
||||
FieldElementArrayExpression::FunctionCall(n, _, _) => Type::FieldElementArray(n),
|
||||
FieldElementArrayExpression::IfElse(_, ref consequence, _) => consequence.get_type(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -403,6 +404,11 @@ pub enum FieldElementArrayExpression<T: Field> {
|
|||
Identifier(usize, String),
|
||||
Value(usize, Vec<FieldElementExpression<T>>),
|
||||
FunctionCall(usize, String, Vec<TypedExpression<T>>),
|
||||
IfElse(
|
||||
Box<BooleanExpression<T>>,
|
||||
Box<FieldElementArrayExpression<T>>,
|
||||
Box<FieldElementArrayExpression<T>>,
|
||||
),
|
||||
}
|
||||
|
||||
impl<T: Field> FieldElementArrayExpression<T> {
|
||||
|
@ -411,6 +417,7 @@ impl<T: Field> FieldElementArrayExpression<T> {
|
|||
FieldElementArrayExpression::Identifier(s, _)
|
||||
| FieldElementArrayExpression::Value(s, _)
|
||||
| FieldElementArrayExpression::FunctionCall(s, ..) => s,
|
||||
FieldElementArrayExpression::IfElse(_, ref consequence, _) => consequence.size(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -487,6 +494,13 @@ impl<T: Field> fmt::Display for FieldElementArrayExpression<T> {
|
|||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
FieldElementArrayExpression::IfElse(ref condition, ref consequent, ref alternative) => {
|
||||
write!(
|
||||
f,
|
||||
"if {} then {} else {} fi",
|
||||
condition, consequent, alternative
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -538,6 +552,13 @@ impl<T: Field> fmt::Debug for FieldElementArrayExpression<T> {
|
|||
try!(f.debug_list().entries(p.iter()).finish());
|
||||
write!(f, ")")
|
||||
}
|
||||
FieldElementArrayExpression::IfElse(ref condition, ref consequent, ref alternative) => {
|
||||
write!(
|
||||
f,
|
||||
"IfElse({:?}, {:?}, {:?})",
|
||||
condition, consequent, alternative
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use bimap::BiMap;
|
|||
use flat_absy::flat_parameter::FlatParameter;
|
||||
use flat_absy::flat_variable::FlatVariable;
|
||||
use flat_absy::*;
|
||||
use helpers::{DirectiveStatement, Helper, RustHelper};
|
||||
use helpers::{DirectiveStatement, Helper};
|
||||
use reduce::Reduce;
|
||||
use types::constraints::Constraint;
|
||||
use types::signature::Signature;
|
||||
|
@ -85,7 +85,7 @@ pub fn unpack<T: Field>(nbits: usize) -> FlatProg<T> {
|
|||
.map(|index| use_variable(&mut bijection, format!("o{}", index), &mut counter))
|
||||
.collect();
|
||||
|
||||
let helper = Helper::Rust(RustHelper::Bits);
|
||||
let helper = Helper::bits();
|
||||
|
||||
let signature = Signature {
|
||||
inputs: vec![Type::FieldElement],
|
||||
|
@ -253,8 +253,8 @@ pub fn cast<T: Field>(from: &Type, to: &Type) -> FlatFunction<T> {
|
|||
.collect();
|
||||
|
||||
let helper = match (from, to) {
|
||||
(Type::Boolean, Type::FieldElement) => Helper::Rust(RustHelper::Identity),
|
||||
(Type::FieldElement, Type::Boolean) => Helper::Rust(RustHelper::Identity),
|
||||
(Type::Boolean, Type::FieldElement) => Helper::identity(),
|
||||
(Type::FieldElement, Type::Boolean) => Helper::identity(),
|
||||
_ => panic!(format!("can't cast {} to {}", from, to)),
|
||||
};
|
||||
|
||||
|
@ -313,7 +313,7 @@ mod tests {
|
|||
f2b.statements[0],
|
||||
FlatStatement::Directive(DirectiveStatement::new(
|
||||
vec![FlatVariable::new(1)],
|
||||
Helper::Rust(RustHelper::Identity),
|
||||
Helper::identity(),
|
||||
vec![FlatVariable::new(0)]
|
||||
))
|
||||
);
|
||||
|
@ -339,7 +339,7 @@ mod tests {
|
|||
b2f.statements[0],
|
||||
FlatStatement::Directive(DirectiveStatement::new(
|
||||
vec![FlatVariable::new(1)],
|
||||
Helper::Rust(RustHelper::Identity),
|
||||
Helper::identity(),
|
||||
vec![FlatVariable::new(0)]
|
||||
))
|
||||
);
|
||||
|
@ -376,7 +376,7 @@ mod tests {
|
|||
(0..FieldPrime::get_required_bits())
|
||||
.map(|i| FlatVariable::new(i + 1))
|
||||
.collect(),
|
||||
Helper::Rust(RustHelper::Bits),
|
||||
Helper::bits(),
|
||||
vec![FlatVariable::new(0)]
|
||||
))
|
||||
);
|
||||
|
|
2
zokrates_core/tests/bench/array_if.code
Normal file
2
zokrates_core/tests/bench/array_if.code
Normal file
|
@ -0,0 +1,2 @@
|
|||
def main(field[2] a, field[2] b, field condition) -> (field[2]):
|
||||
return if condition == 1 then a else b fi
|
24
zokrates_core/tests/bench/array_if.json
Normal file
24
zokrates_core/tests/bench/array_if.json
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": ["1", "2", "3", "4", "1"]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"values": ["1", "2"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"input": {
|
||||
"values": ["1", "2", "3", "4", "2"]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"values": ["3", "4"]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
extern crate serde_json;
|
||||
extern crate zokrates_core;
|
||||
extern crate zokrates_field;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
extern crate zokrates_core;
|
||||
extern crate zokrates_field;
|
||||
|
||||
#[macro_use]
|
||||
mod utils;
|
||||
|
@ -10,4 +10,5 @@ mod utils;
|
|||
zokrates_test! {
|
||||
add,
|
||||
assert_one,
|
||||
array_if,
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
extern crate serde_json;
|
||||
extern crate zokrates_field;
|
||||
|
||||
use std::io;
|
||||
use zokrates_core::compile::{compile as generic_compile, CompileError};
|
||||
|
@ -35,7 +36,7 @@ type Val = String;
|
|||
|
||||
impl From<ir::ExecutionResult<FieldPrime>> for ComparableResult {
|
||||
fn from(r: ir::ExecutionResult<FieldPrime>) -> ComparableResult {
|
||||
ComparableResult(r.map(|v| v.return_values()))
|
||||
ComparableResult(r.map(|v| v.return_values().iter().map(|&x| x.clone()).collect()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,7 +91,7 @@ macro_rules! zokrates_test {
|
|||
#[test]
|
||||
fn $name() {
|
||||
|
||||
use zokrates_field::field::{FieldPrime, Field};
|
||||
use zokrates_field::field::{Field, FieldPrime};
|
||||
|
||||
let code_string = $crate::utils::read_file(&format!("./{}.code", stringify!($name)));
|
||||
let test_string = $crate::utils::read_file(&format!("./{}.json", stringify!($name)));
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
[package]
|
||||
name = "zokrates_field"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
authors = ["Guillaume Ballet <gballet@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
lazy_static = "0.1.*"
|
||||
num = {version = "0.1.36", default-features = false}
|
||||
num-bigint = {version = "0.1.36", default-features = false}
|
||||
bincode = "0.8.0"
|
||||
bincode = "0.8.0"
|
||||
serde_json = "1.0"
|
||||
num-traits = "0.2"
|
||||
num-integer = "0.1"
|
||||
|
||||
[dependencies.num-bigint]
|
||||
version = "0.2"
|
||||
features = ["serde"]
|
|
@ -4,10 +4,11 @@
|
|||
// @author Jacob Eberhardt <jacob.eberhardt@tu-berlin.de>
|
||||
// @date 2017
|
||||
|
||||
use num::{Integer, Num, One, Zero};
|
||||
use lazy_static::lazy_static;
|
||||
use num_bigint::{BigInt, BigUint, Sign, ToBigInt};
|
||||
use serde::de::{Deserialize, Deserializer, Visitor};
|
||||
use serde::{Serialize, Serializer};
|
||||
use num_integer::Integer;
|
||||
use num_traits::{Num, One, Zero};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::convert::From;
|
||||
use std::fmt;
|
||||
use std::fmt::{Debug, Display};
|
||||
|
@ -71,7 +72,7 @@ pub trait Field:
|
|||
fn get_required_bits() -> usize;
|
||||
}
|
||||
|
||||
#[derive(PartialEq, PartialOrd, Clone, Eq, Ord, Hash)]
|
||||
#[derive(PartialEq, PartialOrd, Clone, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
pub struct FieldPrime {
|
||||
value: BigInt,
|
||||
}
|
||||
|
@ -323,49 +324,6 @@ impl<'a> Pow<&'a FieldPrime> for FieldPrime {
|
|||
}
|
||||
}
|
||||
|
||||
// custom serde serialization
|
||||
impl Serialize for FieldPrime {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
// serializer.serialize_bytes(&(*self.value.to_biguint().to_bytes_le().as_slice()))
|
||||
serializer.serialize_bytes(&(*self.into_byte_vector().as_slice()))
|
||||
}
|
||||
}
|
||||
|
||||
// custom serde deserialization
|
||||
|
||||
struct FieldPrimeVisitor;
|
||||
|
||||
impl FieldPrimeVisitor {
|
||||
fn new() -> Self {
|
||||
FieldPrimeVisitor {}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Visitor<'de> for FieldPrimeVisitor {
|
||||
type Value = FieldPrime;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("struct FieldPrime")
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> {
|
||||
let val = BigUint::from_bytes_le(v).to_bigint().unwrap();
|
||||
Ok(FieldPrime { value: val })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for FieldPrime {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_bytes(FieldPrimeVisitor::new())
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculates the gcd using an iterative implementation of the extended euclidian algorithm.
|
||||
/// Returning `(d, s, t)` so that `d = s * a + t * b`
|
||||
///
|
||||
|
@ -633,6 +591,13 @@ mod tests {
|
|||
assert_eq!(FieldPrime::from("11"), deserialized);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serde_json_ser_deser() {
|
||||
let serialized = serde_json::to_string(&FieldPrime::from("11")).unwrap();
|
||||
let deserialized = serde_json::from_str(&serialized).unwrap();
|
||||
assert_eq!(FieldPrime::from("11"), deserialized);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bytes_ser_deser() {
|
||||
let fp = FieldPrime::from("101");
|
||||
|
|
|
@ -1,7 +1 @@
|
|||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
extern crate num;
|
||||
extern crate num_bigint;
|
||||
extern crate serde;
|
||||
|
||||
pub mod field;
|
||||
|
|
|
@ -10,5 +10,6 @@ default = []
|
|||
[dependencies]
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3"
|
||||
|
||||
[lib]
|
|
@ -1,7 +1,9 @@
|
|||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::BufReader;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Component, PathBuf};
|
||||
|
||||
const ZOKRATES_HOME: &str = &"ZOKRATES_HOME";
|
||||
|
||||
pub fn resolve(
|
||||
location: &Option<String>,
|
||||
|
@ -18,7 +20,23 @@ fn resolve_with_location(
|
|||
location: &String,
|
||||
source: &String,
|
||||
) -> Result<(BufReader<File>, String, String), io::Error> {
|
||||
let path = PathBuf::from(location).join(PathBuf::from(source));
|
||||
let source = PathBuf::from(source);
|
||||
|
||||
// paths starting with `./` or `../` are interpreted relative to the current file
|
||||
// other paths `abc/def.code` are interpreted relative to $ZOKRATES_HOME
|
||||
let base = match source.components().next() {
|
||||
Some(Component::CurDir) | Some(Component::ParentDir) => PathBuf::from(location),
|
||||
_ => PathBuf::from(
|
||||
std::env::var(ZOKRATES_HOME).expect("$ZOKRATES_HOME is not set, please set it"),
|
||||
),
|
||||
};
|
||||
|
||||
let path = base.join(PathBuf::from(source));
|
||||
|
||||
if path.is_dir() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "Not a file"));
|
||||
}
|
||||
|
||||
let (next_location, alias) = generate_next_parameters(&path)?;
|
||||
|
||||
File::open(path).and_then(|f| Ok((BufReader::new(f), next_location, alias)))
|
||||
|
@ -41,7 +59,7 @@ mod tests {
|
|||
#[test]
|
||||
fn valid_path_with_location() {
|
||||
let (_, next_location, alias) =
|
||||
resolve(&Some(String::from("./src")), &String::from("lib.rs")).unwrap();
|
||||
resolve(&Some(String::from("./src")), &String::from("./lib.rs")).unwrap();
|
||||
assert_eq!(next_location, String::from("./src"));
|
||||
assert_eq!(alias, String::from("lib"));
|
||||
}
|
||||
|
@ -54,13 +72,16 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn non_existing_file() {
|
||||
let res = resolve(&Some(String::from("./src")), &String::from("rubbish.rs"));
|
||||
let res = resolve(&Some(String::from("./src")), &String::from("./rubbish.rs"));
|
||||
assert!(res.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_location() {
|
||||
let res = resolve(&Some(String::from(",8!-$2abc")), &String::from("foo.code"));
|
||||
let res = resolve(
|
||||
&Some(String::from(",8!-$2abc")),
|
||||
&String::from("./foo.code"),
|
||||
);
|
||||
assert!(res.is_err());
|
||||
}
|
||||
|
||||
|
@ -72,7 +93,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn not_a_file() {
|
||||
let res = resolve(&Some(String::from(".")), &String::from("/src/"));
|
||||
let res = resolve(&Some(String::from(".")), &String::from("./src/"));
|
||||
assert!(res.is_err());
|
||||
}
|
||||
|
||||
|
@ -87,4 +108,147 @@ mod tests {
|
|||
let res = resolve(&Some(String::from(".")), &String::from(""));
|
||||
assert!(res.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn treat_relative_as_local() {
|
||||
use std::io::BufRead;
|
||||
use std::io::Write;
|
||||
|
||||
// create a HOME folder with a code file
|
||||
let zokrates_home_folder = tempfile::tempdir().unwrap();
|
||||
let file_path = zokrates_home_folder.path().join("bar.code");
|
||||
let mut file = File::create(file_path).unwrap();
|
||||
writeln!(file, "<stdlib code>").unwrap();
|
||||
|
||||
// create a user folder with a code file
|
||||
let source_folder = tempfile::tempdir().unwrap();
|
||||
let file_path = source_folder.path().join("bar.code");
|
||||
let mut file = File::create(file_path).unwrap();
|
||||
writeln!(file, "<user code>").unwrap();
|
||||
|
||||
// assign HOME folder to ZOKRATES_HOME
|
||||
std::env::set_var(ZOKRATES_HOME, zokrates_home_folder.path());
|
||||
|
||||
let result = resolve(
|
||||
&Some(
|
||||
source_folder
|
||||
.path()
|
||||
.to_path_buf()
|
||||
.to_string_lossy()
|
||||
.to_string(),
|
||||
),
|
||||
&"./bar.code".to_string(),
|
||||
);
|
||||
assert!(result.is_ok());
|
||||
let mut code = String::new();
|
||||
result.unwrap().0.read_line(&mut code).unwrap();
|
||||
// the imported file should be the user's
|
||||
assert_eq!(code, "<user code>\n".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn treat_absolute_as_std() {
|
||||
use std::io::BufRead;
|
||||
use std::io::Write;
|
||||
|
||||
// create a HOME folder with a code file
|
||||
let zokrates_home_folder = tempfile::tempdir().unwrap();
|
||||
let file_path = zokrates_home_folder.path().join("bar.code");
|
||||
let mut file = File::create(file_path).unwrap();
|
||||
writeln!(file, "<stdlib code>").unwrap();
|
||||
|
||||
// create a user folder with a code file
|
||||
let source_folder = tempfile::tempdir().unwrap();
|
||||
let file_path = source_folder.path().join("bar.code");
|
||||
let mut file = File::create(file_path).unwrap();
|
||||
writeln!(file, "<user code>").unwrap();
|
||||
|
||||
// assign HOME folder to ZOKRATES_HOME
|
||||
std::env::set_var(ZOKRATES_HOME, zokrates_home_folder.path());
|
||||
|
||||
let result = resolve(
|
||||
&Some(
|
||||
source_folder
|
||||
.path()
|
||||
.to_path_buf()
|
||||
.to_string_lossy()
|
||||
.to_string(),
|
||||
),
|
||||
&"bar.code".to_string(),
|
||||
);
|
||||
assert!(result.is_ok());
|
||||
let mut code = String::new();
|
||||
result.unwrap().0.read_line(&mut code).unwrap();
|
||||
// the imported file should be the user's
|
||||
assert_eq!(code, "<stdlib code>\n".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn navigate_up() {
|
||||
use std::io::BufRead;
|
||||
use std::io::Write;
|
||||
|
||||
// create a user folder with a code file
|
||||
let source_folder = tempfile::tempdir().unwrap();
|
||||
let source_subfolder = tempfile::tempdir_in(&source_folder).unwrap();
|
||||
let file_path = source_folder.path().join("bar.code");
|
||||
let mut file = File::create(file_path).unwrap();
|
||||
writeln!(file, "<user code>").unwrap();
|
||||
|
||||
let result = resolve(
|
||||
&Some(
|
||||
source_subfolder
|
||||
.path()
|
||||
.to_path_buf()
|
||||
.to_string_lossy()
|
||||
.to_string(),
|
||||
),
|
||||
&"../bar.code".to_string(),
|
||||
);
|
||||
assert!(result.is_ok());
|
||||
let mut code = String::new();
|
||||
result.unwrap().0.read_line(&mut code).unwrap();
|
||||
// the imported file should be the user's
|
||||
assert_eq!(code, "<user code>\n".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dont_fallback_to_std() {
|
||||
use std::io::Write;
|
||||
|
||||
// create a HOME folder
|
||||
let zokrates_home_folder = tempfile::tempdir().unwrap();
|
||||
let file_path = zokrates_home_folder.path().join("bar.code");
|
||||
let mut file = File::create(file_path).unwrap();
|
||||
writeln!(file, "<stdlib code>").unwrap();
|
||||
|
||||
// assign HOME folder to ZOKRATES_HOME
|
||||
std::env::set_var(ZOKRATES_HOME, zokrates_home_folder.path());
|
||||
|
||||
let result = resolve(
|
||||
&Some("/path/to/user/folder".to_string()),
|
||||
&"./bar.code".to_string(),
|
||||
);
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fail_if_not_found_in_std() {
|
||||
std::env::set_var(ZOKRATES_HOME, "");
|
||||
let result = resolve(
|
||||
&Some("/path/to/source".to_string()),
|
||||
&"bar.code".to_string(),
|
||||
);
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn panic_if_home_not_set() {
|
||||
std::env::remove_var(ZOKRATES_HOME);
|
||||
let _ = resolve(
|
||||
&Some("/path/to/source".to_string()),
|
||||
&"bar.code".to_string(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue