1
0
Fork 0
mirror of synced 2025-09-23 04:08:33 +00:00

solve conflict

This commit is contained in:
schaeff 2019-01-28 10:18:27 +01:00
commit b731a7c296
46 changed files with 1460 additions and 316 deletions

View file

@ -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
View file

@ -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"

View file

@ -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

View file

@ -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
View file

@ -0,0 +1,4 @@
// just as an example, to be removed
def main() -> (field):
return 42

View 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"

View file

@ -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}}
```

View file

@ -9,15 +9,7 @@ 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
@ -25,9 +17,7 @@ def main() -> (field):
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 `!`.
@ -39,12 +29,7 @@ The condition supports `<`, `<=`, `>`, `>=`, `==`, which can be combined with th
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.

View file

@ -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}}
```

View file

@ -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}}
```

View file

@ -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).

View file

@ -16,11 +16,7 @@ We will start this tutorial by using ZoKrates to compute the hash for an arbitra
First, we create a new file named `hashexample.code` with the following content:
```zokrates
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
{{#include ../../zokrates_cli/examples/book/hashexample.code}}
```
The first line imports the `sha256packed` function from the ZoKrates standard library.
@ -74,13 +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
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
{{#include ../../zokrates_cli/examples/book/hashexample_updated.code}}
```
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.

View 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

View file

@ -0,0 +1,4 @@
def main() -> (field):
field[3] a = [1, 2, 3]
a[2] = 4
return a[0] + a[2]

View 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

View 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

View file

@ -0,0 +1,4 @@
def main() -> (field):
field pMinusOne = 21888242871839275222246405745257275088548364400416034343698204186575808495616
0 - 1 == pMinusOne
return 1

View file

@ -0,0 +1,6 @@
def main() -> (field):
field res = 0
for field i in 0..4 do
res = res + i
endfor
return res

View file

@ -0,0 +1,5 @@
def foo() -> (field):
return 1
def main() -> (field):
return foo()

View 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

View 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

View file

@ -0,0 +1,3 @@
def main(field x) -> (field):
field y = if x + 2 == 3 then 1 else 5 fi
return y

View file

@ -0,0 +1,6 @@
def foo() -> (field, field):
return 21, 42
def main() -> (field):
a, b = foo()
return 1

View file

@ -0,0 +1,2 @@
def main() -> (field, field[3]):
return 1, [2, 3, 4]

View 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

View 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

View file

@ -652,6 +652,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") {
@ -678,12 +679,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();
}
}
}

View file

@ -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"

View file

@ -167,7 +167,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],
)));
@ -214,7 +214,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],
)));
@ -248,22 +248,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();
@ -271,8 +266,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
@ -299,10 +294,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])
}
@ -317,10 +309,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,
@ -329,35 +319,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(
@ -645,6 +627,7 @@ impl Flattener {
statements_flattened,
right,
);
let new_left = if left_flattened.is_linear() {
left_flattened
} else {
@ -659,6 +642,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) => {
@ -675,26 +659,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));
@ -862,6 +834,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();
@ -919,6 +915,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)),
)
@ -982,6 +993,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()
}
}
}
@ -2331,6 +2372,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());

View file

@ -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(),
}
}
}

View 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));
}
}
}

View file

@ -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()
}

View file

@ -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;

View file

@ -622,26 +622,34 @@ 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 {
pos: Some(expr.pos()),
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 {
pos: Some(alternative.pos()),
message: format!("{{consequence}} and {{alternative}} in `if/else` expression should have the same type, found {}, {}", consequence_type, alternative_type)
})
}
}
c => Err(Error {
pos: Some(condition.pos()),
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) => {

View file

@ -146,6 +146,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),
)
}
}
}

View file

@ -302,17 +302,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(),
}
}
}
@ -405,6 +406,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> {
@ -413,6 +419,7 @@ impl<T: Field> FieldElementArrayExpression<T> {
FieldElementArrayExpression::Identifier(s, _)
| FieldElementArrayExpression::Value(s, _)
| FieldElementArrayExpression::FunctionCall(s, ..) => s,
FieldElementArrayExpression::IfElse(_, ref consequence, _) => consequence.size(),
}
}
}
@ -489,6 +496,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
)
}
}
}
}
@ -540,6 +554,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
)
}
}
}
}

View file

@ -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)]
))
);

View 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

View 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"]
}
}
}
]
}

View file

@ -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,
}

View file

@ -1,4 +1,5 @@
extern crate serde_json;
extern crate zokrates_field;
use std::io;
use zokrates_core::compile::{compile as generic_compile, CompileErrors};
@ -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)));

View file

@ -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"]

View file

@ -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");

View file

@ -1,7 +1 @@
#[macro_use]
extern crate lazy_static;
extern crate num;
extern crate num_bigint;
extern crate serde;
pub mod field;

View file

@ -10,5 +10,6 @@ default = []
[dependencies]
[dev-dependencies]
tempfile = "3"
[lib]

View file

@ -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(),
);
}
}