From 5b5a6e87a6ef5606b5180757eb3c569fa487c260 Mon Sep 17 00:00:00 2001 From: schaeff Date: Wed, 15 Aug 2018 17:17:02 +0200 Subject: [PATCH 01/11] remove path from zokrates_core, delegate alias and location responsibility to resolvers --- Cargo.lock | 45 ++++++++++++++++--------------- zokrates_cli/src/bin.rs | 12 ++++++--- zokrates_core/Cargo.toml | 6 ++++- zokrates_core/src/compile.rs | 23 ++++++++-------- zokrates_core/src/imports.rs | 47 +++++++++++++++++++++------------ zokrates_fs_resolver/src/lib.rs | 16 +++++++++-- 6 files changed, 92 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c991f350..6b89c82c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -222,14 +222,13 @@ dependencies = [ [[package]] name = "num" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" +version = "0.2.0-git" dependencies = [ - "num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", - "num-complex 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-complex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "num-rational 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -240,17 +239,23 @@ 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.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-bigint" +version = "0.2.0" +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.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-complex" -version = "0.1.43" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -272,13 +277,12 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.1.42" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.0 (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.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -379,11 +383,6 @@ name = "rustc-demangle" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "rustc-serialize" -version = "0.3.24" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "same-file" version = "1.0.2" @@ -589,7 +588,10 @@ dependencies = [ "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.42 (registry+https://github.com/rust-lang/crates.io-index)", - "num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num 0.2.0-git", + "num-bigint 0.1.44 (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.1.43 (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.70 (registry+https://github.com/rust-lang/crates.io-index)", @@ -633,12 +635,12 @@ version = "0.1.0" "checksum lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e6412c5e2ad9584b0b8e979393122026cdd6d2a80b933f890dcd694ddbe73739" "checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" -"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-complex 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "b288631d7878aaf59442cffd36910ea604ecd7745c36054328595114001c9656" +"checksum num-bigint 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3eceac7784c5dc97c2d6edf30259b4e153e6e2b42b3c85e9a6e9f45d06caef6e" +"checksum num-complex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "68de83578789e0fbda3fa923035be83cf8bfd3b30ccfdecd5aa89bf8601f408e" "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-rational 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "ee314c74bd753fc86b4780aa9475da469155f3848473a261d2d18e35245a784e" +"checksum num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4e96f040177bb3da242b5b1ecf3f54b5d5af3efbbfb18608977a5d2767b22f10" "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" "checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe" "checksum proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "effdb53b25cdad54f8f48843d67398f7ef2e14f12c1b4cb4effc549a6462a4d6" @@ -652,7 +654,6 @@ version = "0.1.0" "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.8 (registry+https://github.com/rust-lang/crates.io-index)" = "76d7ba1feafada44f2d38eed812bd2489a03c0f5abb975799251518b68848649" -"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637" "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" diff --git a/zokrates_cli/src/bin.rs b/zokrates_cli/src/bin.rs index 0b5dd001..220aedb3 100644 --- a/zokrates_cli/src/bin.rs +++ b/zokrates_cli/src/bin.rs @@ -195,7 +195,7 @@ fn main() { let path = PathBuf::from(sub_matches.value_of("input").unwrap()); - let location = path.parent().unwrap().to_path_buf(); + let location = path.parent().unwrap().to_path_buf().into_os_string().into_string().unwrap(); let should_optimize = sub_matches.occurrences_of("optimized") > 0; @@ -205,7 +205,7 @@ fn main() { let mut reader = BufReader::new(file); - let program_flattened: FlatProg = match compile(&mut reader, location, Some(fs_resolve), should_optimize, should_include_gadgets) { + let program_flattened: FlatProg = match compile(&mut reader, Some(location), Some(fs_resolve), should_optimize, should_include_gadgets) { Ok(p) => p, Err(why) => panic!("Compilation failed: {}", why) }; @@ -550,10 +550,12 @@ mod tests { let file = File::open(path.clone()).unwrap(); + let location = path.parent().unwrap().to_path_buf().into_os_string().into_string().unwrap(); + let mut reader = BufReader::new(file); let program_flattened: FlatProg = - compile(&mut reader, path, Some(fs_resolve), true, false).unwrap(); + compile(&mut reader, Some(location), Some(fs_resolve), true, false).unwrap(); let (..) = r1cs_program(&program_flattened); } @@ -570,10 +572,12 @@ mod tests { let file = File::open(path.clone()).unwrap(); + let location = path.parent().unwrap().to_path_buf().into_os_string().into_string().unwrap(); + let mut reader = BufReader::new(file); let program_flattened: FlatProg = - compile(&mut reader, path, Some(fs_resolve), true, false).unwrap(); + compile(&mut reader, Some(location), Some(fs_resolve), true, false).unwrap(); let (..) = r1cs_program(&program_flattened); let _ = program_flattened.get_witness(vec![FieldPrime::from(0)]).unwrap(); diff --git a/zokrates_core/Cargo.toml b/zokrates_core/Cargo.toml index 2802ccd1..a04a4df0 100644 --- a/zokrates_core/Cargo.toml +++ b/zokrates_core/Cargo.toml @@ -12,7 +12,6 @@ libsnark = [] [dependencies] libc = "0.2.0" -num = "0.1.36" lazy_static = "0.1.*" reduce = "0.1.1" # cli @@ -24,6 +23,11 @@ serde_json = "1.0" bincode = "0.8.0" regex = "0.2" +num = {path = "../../num"} +num-bigint = {version = "0.1", default-features = false} +num-traits = {version = "0.1", default-features = false} +num-integer = {version = "0.1", default-features = false} + [dev-dependencies] glob = "0.2.11" assert_cli = "0.5" diff --git a/zokrates_core/src/compile.rs b/zokrates_core/src/compile.rs index 2ae09ff0..9c53390d 100644 --- a/zokrates_core/src/compile.rs +++ b/zokrates_core/src/compile.rs @@ -5,7 +5,6 @@ //! @date 2018 use std::io::{BufRead}; use std::fmt; -use std::path::PathBuf; use field::{Field}; use absy::{Prog}; use flat_absy::{FlatProg}; @@ -60,7 +59,7 @@ impl fmt::Display for CompileError { } } -pub fn compile>(reader: &mut R, location: PathBuf, resolve_option: Option Result>, should_optimize: bool, should_include_gadgets: bool) -> Result, CompileError> { +pub fn compile>(reader: &mut R, location: Option, resolve_option: Option, &String) -> Result<(S, String, String), E>>, should_optimize: bool, should_include_gadgets: bool) -> Result, CompileError> { let compiled = compile_aux(reader, location, resolve_option, should_include_gadgets); @@ -73,7 +72,7 @@ pub fn compile>(reader } } -fn compile_aux>(reader: &mut R, location: PathBuf, resolve_option: Option Result>, should_include_gadgets: bool) -> Result, CompileError> { +fn compile_aux>(reader: &mut R, location: Option, resolve_option: Option, &String) -> Result<(S, String, String), E>>, should_include_gadgets: bool) -> Result, CompileError> { let program_ast_without_imports: Prog = parse_program(reader)?; let mut compiled_imports: Vec<(FlatProg, String)> = vec![]; @@ -83,12 +82,14 @@ fn compile_aux>(reader Some(resolve) => { // we have a resolver, pass each import through it for import in program_ast_without_imports.imports.iter() { - // find the absolute path for the import, based on the path of the file which imports it - let absolute_import_path = location.join(import.get_source()); - match resolve(&absolute_import_path) { - Ok(mut res) => { - let compiled = compile_aux(&mut res, absolute_import_path.parent().unwrap().to_path_buf(), resolve_option, should_include_gadgets)?; - compiled_imports.push((compiled, import.alias())); + match resolve(&location, import.get_source()) { + Ok((mut res, file_location, default_alias)) => { + let compiled = compile_aux(&mut res, Some(file_location), resolve_option, should_include_gadgets)?; + let alias = match import.get_alias() { + &Some(ref custom_alias) => custom_alias.clone(), + &None => default_alias + }; + compiled_imports.push((compiled, alias)); }, Err(err) => return Err(CompileError::ImportError(err.into())) } @@ -140,7 +141,7 @@ mod test { def main(): return foo() "#.as_bytes()); - let res: Result, CompileError> = compile(&mut r, PathBuf::from("./path/to/file"), None:: Result, io::Error>>, false, false); + let res: Result, CompileError> = compile(&mut r, Some(String::from("./path/to/file")), None::, &String) -> Result<(BufReader, String, String), io::Error>>, false, false); assert_eq!(format!("{}", res.unwrap_err()), "Import error: Can't resolve import without a resolver".to_string()); } @@ -150,7 +151,7 @@ mod test { def main(): return 1 "#.as_bytes()); - let res: Result, CompileError> = compile(&mut r, PathBuf::from("./path/to/file"), None:: Result, io::Error>>, false, false); + let res: Result, CompileError> = compile(&mut r, Some(String::from("./path/to/file")), None::, &String) -> Result<(BufReader, String, String), io::Error>>, false, false); assert!(res.is_ok()); } } \ No newline at end of file diff --git a/zokrates_core/src/imports.rs b/zokrates_core/src/imports.rs index f1733278..34d38904 100644 --- a/zokrates_core/src/imports.rs +++ b/zokrates_core/src/imports.rs @@ -8,7 +8,6 @@ use std::fmt; use absy::*; use flat_absy::*; use field::Field; -use std::path::PathBuf; use std::io; #[derive(PartialEq, Debug)] @@ -40,44 +39,58 @@ impl From for Error { #[derive(PartialEq, Clone, Serialize, Deserialize)] pub struct Import { - source: PathBuf, - alias: String, + source: String, + alias: Option, } impl Import { pub fn new(source: String) -> Import { Import { - source: PathBuf::from(source.clone()), - alias: PathBuf::from(source).file_stem().unwrap().to_os_string().to_string_lossy().to_string(), + source: source, + alias: None, } } - pub fn alias(&self) -> String { - self.alias.clone() + pub fn get_alias(&self) -> &Option { + &self.alias } pub fn new_with_alias(source: String, alias: &String) -> Import { Import { - source: PathBuf::from(source.clone()), - alias: alias.clone(), + source: source, + alias: Some(alias.clone()), } } - pub fn get_source(&self) -> &PathBuf { + pub fn get_source(&self) -> &String { &self.source } } impl fmt::Display for Import { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "import {} as {}", self.source.clone().into_os_string().into_string().unwrap(), self.alias) + match self.alias { + Some(ref alias) => { + write!(f, "import {} as {}", self.source, alias) + }, + None => { + write!(f, "import {}", self.source) + } + } } } impl fmt::Debug for Import { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "import(source: {}, alias: {})", self.source.clone().into_os_string().into_string().unwrap(), self.alias) - } + match self.alias { + Some(ref alias) => { + write!(f, "import(source: {}, alias: {})", self.source, alias) + }, + None => { + write!(f, "import(source: {})", self.source) + } + } + } } pub struct Importer { @@ -123,16 +136,16 @@ mod tests { #[test] fn create_with_no_alias() { assert_eq!(Import::new("./foo/bar/baz.code".to_string()), Import { - source: PathBuf::from("./foo/bar/baz.code"), - alias: "baz".to_string(), + source: String::from("./foo/bar/baz.code"), + alias: None, }); } #[test] fn create_with_alias() { assert_eq!(Import::new_with_alias("./foo/bar/baz.code".to_string(), &"myalias".to_string()), Import { - source: PathBuf::from("./foo/bar/baz.code"), - alias: "myalias".to_string(), + source: String::from("./foo/bar/baz.code"), + alias: Some("myalias".to_string()), }); } } \ No newline at end of file diff --git a/zokrates_fs_resolver/src/lib.rs b/zokrates_fs_resolver/src/lib.rs index 995b2392..12f85cda 100644 --- a/zokrates_fs_resolver/src/lib.rs +++ b/zokrates_fs_resolver/src/lib.rs @@ -3,6 +3,18 @@ use std::path::PathBuf; use std::fs::File; use std::io; -pub fn resolve(source: &PathBuf) -> Result, io::Error> { - File::open(source).and_then(|f| Ok(BufReader::new(f))) +pub fn resolve(location: &Option, source: &String) -> Result<(BufReader, String, String), io::Error> { + let path = match location { + Some(location) => { + PathBuf::from(location).join(PathBuf::from(source)) + }, + None => { + PathBuf::from(source) + } + }; + + let next_location = path.parent().unwrap().to_path_buf().into_os_string().into_string().unwrap(); + let alias = path.file_stem().unwrap().to_os_string().to_string_lossy().to_string(); + + File::open(path).and_then(|f| Ok((BufReader::new(f), next_location, alias))) } \ No newline at end of file From c226c3eb2a287be7e5994fb16785c9c3ebde701b Mon Sep 17 00:00:00 2001 From: schaeff Date: Wed, 15 Aug 2018 17:26:08 +0200 Subject: [PATCH 02/11] remove local num dependency --- Cargo.lock | 41 ++++---------------------------------- zokrates_core/Cargo.toml | 7 ++----- zokrates_core/src/field.rs | 2 +- zokrates_core/src/lib.rs | 1 + 4 files changed, 8 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b89c82c..f2fd2766 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -222,13 +222,11 @@ dependencies = [ [[package]] name = "num" -version = "0.2.0-git" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-bigint 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-complex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -241,23 +239,6 @@ dependencies = [ "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "num-bigint" -version = "0.2.0" -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.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-complex" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "num-integer" version = "0.1.39" @@ -275,16 +256,6 @@ dependencies = [ "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "num-rational" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-bigint 0.2.0 (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.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "num-traits" version = "0.1.43" @@ -588,10 +559,8 @@ dependencies = [ "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.42 (registry+https://github.com/rust-lang/crates.io-index)", - "num 0.2.0-git", + "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)", - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.43 (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.70 (registry+https://github.com/rust-lang/crates.io-index)", @@ -635,12 +604,10 @@ version = "0.1.0" "checksum lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e6412c5e2ad9584b0b8e979393122026cdd6d2a80b933f890dcd694ddbe73739" "checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" +"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.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3eceac7784c5dc97c2d6edf30259b4e153e6e2b42b3c85e9a6e9f45d06caef6e" -"checksum num-complex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "68de83578789e0fbda3fa923035be83cf8bfd3b30ccfdecd5aa89bf8601f408e" "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-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4e96f040177bb3da242b5b1ecf3f54b5d5af3efbbfb18608977a5d2767b22f10" "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" "checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe" "checksum proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "effdb53b25cdad54f8f48843d67398f7ef2e14f12c1b4cb4effc549a6462a4d6" diff --git a/zokrates_core/Cargo.toml b/zokrates_core/Cargo.toml index a04a4df0..626e5e90 100644 --- a/zokrates_core/Cargo.toml +++ b/zokrates_core/Cargo.toml @@ -12,6 +12,8 @@ libsnark = [] [dependencies] libc = "0.2.0" +num = {version = "0.1.36", default-features = false} +num-bigint = {version = "0.1.36", default-features = false} lazy_static = "0.1.*" reduce = "0.1.1" # cli @@ -23,11 +25,6 @@ serde_json = "1.0" bincode = "0.8.0" regex = "0.2" -num = {path = "../../num"} -num-bigint = {version = "0.1", default-features = false} -num-traits = {version = "0.1", default-features = false} -num-integer = {version = "0.1", default-features = false} - [dev-dependencies] glob = "0.2.11" assert_cli = "0.5" diff --git a/zokrates_core/src/field.rs b/zokrates_core/src/field.rs index aac4dea1..8e129e29 100644 --- a/zokrates_core/src/field.rs +++ b/zokrates_core/src/field.rs @@ -5,7 +5,7 @@ // @date 2017 use num::{Num, Integer, One, Zero}; -use num::bigint::{BigInt, BigUint, Sign, ToBigInt}; +use num_bigint::{BigInt, BigUint, Sign, ToBigInt}; use std::convert::From; use std::ops::{Add, Div, Mul, Sub}; use std::fmt; diff --git a/zokrates_core/src/lib.rs b/zokrates_core/src/lib.rs index 3fb1d3c6..27d11d55 100644 --- a/zokrates_core/src/lib.rs +++ b/zokrates_core/src/lib.rs @@ -3,6 +3,7 @@ #[macro_use] extern crate lazy_static; extern crate num; +extern crate num_bigint; extern crate reduce; // better reduce function than Iter.fold extern crate serde; // serialization deserialization extern crate serde_json; From 52858565e9c8030b394b546af82e2fafe1d9ea00 Mon Sep 17 00:00:00 2001 From: schaeff Date: Wed, 15 Aug 2018 17:47:33 +0200 Subject: [PATCH 03/11] fix test in libsnark module --- zokrates_core/src/libsnark.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zokrates_core/src/libsnark.rs b/zokrates_core/src/libsnark.rs index 39109d37..01423c35 100644 --- a/zokrates_core/src/libsnark.rs +++ b/zokrates_core/src/libsnark.rs @@ -215,7 +215,7 @@ fn vec_as_u8_32_array(vec: &Vec) -> [u8; 32] { mod tests { use super::*; use field::FieldPrime; - use num::bigint::BigUint; + use num_bigint::BigUint; use serde_json; use flat_absy::*; use standard; From e048001ce824a67014a66c60981a9daa8f2d5404 Mon Sep 17 00:00:00 2001 From: schaeff Date: Wed, 15 Aug 2018 18:30:33 +0200 Subject: [PATCH 04/11] adapt test to new compile API --- zokrates_cli/src/bin.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/zokrates_cli/src/bin.rs b/zokrates_cli/src/bin.rs index f4cf7f16..c6fbf1c8 100644 --- a/zokrates_cli/src/bin.rs +++ b/zokrates_cli/src/bin.rs @@ -597,10 +597,12 @@ mod tests { let file = File::open(path.clone()).unwrap(); + let location = path.parent().unwrap().to_path_buf().into_os_string().into_string().unwrap(); + let mut reader = BufReader::new(file); let program_flattened: FlatProg = - compile(&mut reader, path, Some(fs_resolve), true, false).unwrap(); + compile(&mut reader, Some(location), Some(fs_resolve), true, false).unwrap(); let (..) = r1cs_program(&program_flattened); From f9f1d00194842b3fc344d1536353958f5ccbced1 Mon Sep 17 00:00:00 2001 From: schaeff Date: Thu, 16 Aug 2018 10:49:08 +0200 Subject: [PATCH 05/11] add error handling to fs resolver --- zokrates_fs_resolver/src/lib.rs | 85 +++++++++++++++++++++++++++++---- 1 file changed, 75 insertions(+), 10 deletions(-) diff --git a/zokrates_fs_resolver/src/lib.rs b/zokrates_fs_resolver/src/lib.rs index 12f85cda..2bbf832e 100644 --- a/zokrates_fs_resolver/src/lib.rs +++ b/zokrates_fs_resolver/src/lib.rs @@ -4,17 +4,82 @@ use std::fs::File; use std::io; pub fn resolve(location: &Option, source: &String) -> Result<(BufReader, String, String), io::Error> { - let path = match location { - Some(location) => { - PathBuf::from(location).join(PathBuf::from(source)) - }, - None => { - PathBuf::from(source) - } - }; + // the fs resolver has to be provided a location, as it supports relative paths + match location { + Some(location) => resolve_with_location(location, source), + None => Err(io::Error::new(io::ErrorKind::Other, "No location provided")) + } +} - let next_location = path.parent().unwrap().to_path_buf().into_os_string().into_string().unwrap(); - let alias = path.file_stem().unwrap().to_os_string().to_string_lossy().to_string(); +fn resolve_with_location(location: &String, source: &String) -> Result<(BufReader, String, String), io::Error> { + let path = PathBuf::from(location).join(PathBuf::from(source)); + let (next_location, alias) = generate_next_parameters(&path)?; File::open(path).and_then(|f| Ok((BufReader::new(f), next_location, alias))) +} + +fn generate_next_parameters(path: &PathBuf) -> Result<(String, String), io::Error> { + match (path.parent(), path.file_stem()) { + (Some(parent), Some(stem)) => Ok( + ( + parent.to_path_buf().into_os_string().into_string().unwrap(), + stem.to_os_string().to_string_lossy().to_string() + ) + ), + _ => Err(io::Error::new(io::ErrorKind::Other, "Invalid path")) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn valid_path_with_location() { + let (_, next_location, alias) = resolve(&Some(String::from("./src")), &String::from("lib.rs")).unwrap(); + assert_eq!(next_location, String::from("./src")); + assert_eq!(alias, String::from("lib")); + } + + #[test] + fn valid_path_without_location() { + let res = resolve(&None, &String::from("./src/lib.rs")); + assert!(res.is_err()); + } + + #[test] + fn non_existing_file() { + 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")); + assert!(res.is_err()); + } + + #[test] + fn invalid_file() { + let res = resolve(&Some(String::from("./src")), &String::from(",8!-$2abc")); + assert!(res.is_err()); + } + + #[test] + fn not_a_file() { + let res = resolve(&Some(String::from(".")), &String::from("/src/")); + assert!(res.is_err()); + } + + #[test] + fn no_parent() { + let res = resolve(&Some(String::from(".")), &String::from(".")); + assert!(res.is_err()); + } + + #[test] + fn no_file_name() { + let res = resolve(&Some(String::from(".")), &String::from("")); + assert!(res.is_err()); + } } \ No newline at end of file From 040b5f6f0e676522fec819bcf7ceea5d87dbc827 Mon Sep 17 00:00:00 2001 From: schaeff Date: Thu, 23 Aug 2018 16:12:15 +0200 Subject: [PATCH 06/11] fewer clones --- zokrates_cli/src/bin.rs | 58 +++++++++---------- zokrates_core/src/flat_absy/flat_parameter.rs | 2 +- zokrates_core/src/flat_absy/mod.rs | 37 ++++++------ zokrates_core/src/flatten/mod.rs | 40 ++++++------- zokrates_core/src/optimizer.rs | 19 +++--- zokrates_core/src/semantics.rs | 3 +- zokrates_core/src/typed_absy/mod.rs | 55 +++++++++--------- 7 files changed, 105 insertions(+), 109 deletions(-) diff --git a/zokrates_cli/src/bin.rs b/zokrates_cli/src/bin.rs index 9c372fad..760190d2 100644 --- a/zokrates_cli/src/bin.rs +++ b/zokrates_cli/src/bin.rs @@ -210,42 +210,42 @@ fn main() { Err(why) => panic!("Compilation failed: {}", why) }; - // number of constraints the flattened program will translate to. - let num_constraints = &program_flattened.functions - .iter() - .find(|x| x.id == "main") - .unwrap().statements.len(); + // // number of constraints the flattened program will translate to. + // let num_constraints = &program_flattened.functions + // .iter() + // .find(|x| x.id == "main") + // .unwrap().statements.len(); - // serialize flattened program and write to binary file - let bin_output_path = Path::new(sub_matches.value_of("output").unwrap()); - let mut bin_output_file = match File::create(&bin_output_path) { - Ok(file) => file, - Err(why) => panic!("couldn't create {}: {}", bin_output_path.display(), why), - }; + // // serialize flattened program and write to binary file + // let bin_output_path = Path::new(sub_matches.value_of("output").unwrap()); + // let mut bin_output_file = match File::create(&bin_output_path) { + // Ok(file) => file, + // Err(why) => panic!("couldn't create {}: {}", bin_output_path.display(), why), + // }; - serialize_into(&mut bin_output_file, &program_flattened, Infinite).expect("Unable to write data to file."); + // serialize_into(&mut bin_output_file, &program_flattened, Infinite).expect("Unable to write data to file."); - // write human-readable output file - let hr_output_path = bin_output_path.to_path_buf().with_extension("code"); + // // write human-readable output file + // let hr_output_path = bin_output_path.to_path_buf().with_extension("code"); - let hr_output_file = match File::create(&hr_output_path) { - Ok(file) => file, - Err(why) => panic!("couldn't create {}: {}", hr_output_path.display(), why), - }; + // let hr_output_file = match File::create(&hr_output_path) { + // Ok(file) => file, + // Err(why) => panic!("couldn't create {}: {}", hr_output_path.display(), why), + // }; - let mut hrofb = BufWriter::new(hr_output_file); - write!(&mut hrofb, "{}\n", program_flattened).expect("Unable to write data to file."); - hrofb.flush().expect("Unable to flush buffer."); + // let mut hrofb = BufWriter::new(hr_output_file); + // write!(&mut hrofb, "{}\n", program_flattened).expect("Unable to write data to file."); + // hrofb.flush().expect("Unable to flush buffer."); - // debugging output - println!("Compiled program:\n{}", program_flattened); + // // debugging output + // println!("Compiled program:\n{}", program_flattened); - println!( - "Compiled code written to '{}', \nHuman readable code to '{}'. \nNumber of constraints: {}", - bin_output_path.display(), - hr_output_path.display(), - num_constraints - ); + // println!( + // "Compiled code written to '{}', \nHuman readable code to '{}'. \nNumber of constraints: {}", + // bin_output_path.display(), + // hr_output_path.display(), + // num_constraints + // ); } ("compute-witness", Some(sub_matches)) => { println!("Computing witness for:"); diff --git a/zokrates_core/src/flat_absy/flat_parameter.rs b/zokrates_core/src/flat_absy/flat_parameter.rs index 3991e0ce..4cf8c210 100644 --- a/zokrates_core/src/flat_absy/flat_parameter.rs +++ b/zokrates_core/src/flat_absy/flat_parameter.rs @@ -21,7 +21,7 @@ impl fmt::Debug for FlatParameter { } impl FlatParameter { - pub fn apply_substitution(&self, substitution: &Substitution) -> FlatParameter { + pub fn apply_substitution(self, substitution: &Substitution) -> FlatParameter { FlatParameter { id: substitution.get(&self.id).unwrap().to_string(), private: self.private diff --git a/zokrates_core/src/flat_absy/mod.rs b/zokrates_core/src/flat_absy/mod.rs index 8cbaa99b..49bae98d 100644 --- a/zokrates_core/src/flat_absy/mod.rs +++ b/zokrates_core/src/flat_absy/mod.rs @@ -211,20 +211,20 @@ impl fmt::Debug for FlatStatement { } impl FlatStatement { - pub fn apply_substitution(&self, substitution: &Substitution) -> FlatStatement { - match *self { - FlatStatement::Definition(ref id, ref x) => FlatStatement::Definition( - match substitution.get(id) { + pub fn apply_substitution(self, substitution: &Substitution) -> FlatStatement { + match self { + FlatStatement::Definition(id, x) => FlatStatement::Definition( + match substitution.get(&id) { Some(z) => z.clone(), None => id.clone() }, x.apply_substitution(substitution) ), - FlatStatement::Return(ref x) => FlatStatement::Return(x.apply_substitution(substitution)), - FlatStatement::Condition(ref x, ref y) => { + FlatStatement::Return(x) => FlatStatement::Return(x.apply_substitution(substitution)), + FlatStatement::Condition(x, y) => { FlatStatement::Condition(x.apply_substitution(substitution), y.apply_substitution(substitution)) }, - FlatStatement::Directive(ref d) => { + FlatStatement::Directive(d) => { let new_outputs = d.outputs.iter().map(|o| match substitution.get(o) { Some(z) => z.clone(), None => o.clone() @@ -234,7 +234,7 @@ impl FlatStatement { DirectiveStatement { outputs: new_outputs, inputs: new_inputs, - helper: d.helper.clone() + helper: d.helper } ) } @@ -253,10 +253,10 @@ pub enum FlatExpression { } impl FlatExpression { - pub fn apply_substitution(&self, substitution: &Substitution) -> FlatExpression { - match *self { - ref e @ FlatExpression::Number(_) => e.clone(), - FlatExpression::Identifier(ref v) => { + pub fn apply_substitution(self, substitution: &Substitution) -> FlatExpression { + match self { + e @ FlatExpression::Number(_) => e, + FlatExpression::Identifier(v) => { let mut new_name = v.to_string(); loop { match substitution.get(&new_name) { @@ -265,19 +265,19 @@ impl FlatExpression { } } } - FlatExpression::Add(ref e1, ref e2) => FlatExpression::Add( + FlatExpression::Add(e1, e2) => FlatExpression::Add( box e1.apply_substitution(substitution), box e2.apply_substitution(substitution), ), - FlatExpression::Sub(ref e1, ref e2) => FlatExpression::Sub( + FlatExpression::Sub(e1, e2) => FlatExpression::Sub( box e1.apply_substitution(substitution), box e2.apply_substitution(substitution), ), - FlatExpression::Mult(ref e1, ref e2) => FlatExpression::Mult( + FlatExpression::Mult(e1, e2) => FlatExpression::Mult( box e1.apply_substitution(substitution), box e2.apply_substitution(substitution), ), - FlatExpression::Div(ref e1, ref e2) => FlatExpression::Div( + FlatExpression::Div(e1, e2) => FlatExpression::Div( box e1.apply_substitution(substitution), box e2.apply_substitution(substitution), ) @@ -382,10 +382,9 @@ impl fmt::Display for FlatExpressionList { } impl FlatExpressionList { - pub fn apply_substitution(&self, substitution: &Substitution) -> FlatExpressionList { - let expressions: Vec> = self.expressions.iter().map(|e| e.apply_substitution(substitution)).collect(); + pub fn apply_substitution(self, substitution: &Substitution) -> FlatExpressionList { FlatExpressionList { - expressions: expressions + expressions: self.expressions.into_iter().map(|e| e.apply_substitution(substitution)).collect() } } } diff --git a/zokrates_core/src/flatten/mod.rs b/zokrates_core/src/flatten/mod.rs index 3f129119..caa9a9ad 100644 --- a/zokrates_core/src/flatten/mod.rs +++ b/zokrates_core/src/flatten/mod.rs @@ -391,7 +391,7 @@ impl Flattener { // Handle complex parameters and assign values: // Rename Parameters, assign them to values in call. Resolve complex expressions with definitions - for (i, param_expr) in param_expressions.iter().enumerate() { + for (i, param_expr) in param_expressions.clone().into_iter().enumerate() { let new_var; let param_expr = param_expr.apply_substitution(&self.substitution); @@ -710,12 +710,12 @@ impl Flattener { functions_flattened: &mut Vec>, arguments_flattened: &Vec, statements_flattened: &mut Vec>, - stat: &TypedStatement, + stat: TypedStatement, ) { - match *stat { - TypedStatement::Return(ref exprs) => { + match stat { + TypedStatement::Return(exprs) => { - let flat_expressions = exprs.iter().map(|expr| { + let flat_expressions = exprs.into_iter().map(|expr| { match expr { TypedExpression::FieldElement(e) => { let expr_subbed = e.apply_substitution(&self.substitution); @@ -738,7 +738,7 @@ impl Flattener { ) ); } - TypedStatement::Definition(ref v, ref expr) => { + TypedStatement::Definition(v, expr) => { // define n variables with n the number of primitive types for v_type // assign them to the n primitive types for expr @@ -764,7 +764,7 @@ impl Flattener { _ => panic!("Definitions must have type FieldElement") } } - TypedStatement::Condition(ref expr1, ref expr2) => { + TypedStatement::Condition(expr1, expr2) => { // flatten expr1 and expr2 to n flattened expressions with n the number of primitive types for expr1 // add n conditions to check equality of the n expressions @@ -813,14 +813,14 @@ impl Flattener { _ => panic!("Conditions (Assertions) must be applied to expressions of type FieldElement") } } - TypedStatement::For(ref var, ref start, ref end, ref statements) => { - let mut current = start.clone(); - while ¤t < end { + TypedStatement::For(var, start, end, statements) => { + let mut current = start; + while current < end { statements_flattened.push(FlatStatement::Definition( self.use_variable(&var.id), FlatExpression::Number(current.clone()), )); - for s in statements { + for s in statements.clone() { self.flatten_statement( functions_flattened, arguments_flattened, @@ -831,7 +831,7 @@ impl Flattener { current = T::one() + ¤t; } } - TypedStatement::MultipleDefinition(ref vars, ref rhs) => { + TypedStatement::MultipleDefinition(vars, rhs) => { // flatten the right side to p = sum(var_i.type.primitive_count) expressions // define p new variables to the right side expressions @@ -839,14 +839,14 @@ impl Flattener { let rhs_subbed = rhs.apply_substitution(&self.substitution); match rhs_subbed { - TypedExpressionList::FunctionCall(ref fun_id, ref exprs, ref types) => { + TypedExpressionList::FunctionCall(fun_id, exprs, types) => { let rhs_flattened = self.flatten_function_call( functions_flattened, arguments_flattened, statements_flattened, - fun_id, + &fun_id, vars.len(), - exprs, + &exprs, ); for (i, v) in vars.into_iter().enumerate() { @@ -907,12 +907,12 @@ impl Flattener { } } // flatten statements in functions and apply substitution - for stat in &funct.statements { + for stat in funct.statements { self.flatten_statement( functions_flattened, &arguments_flattened, &mut statements_flattened, - &stat, + stat, ); } @@ -1034,7 +1034,7 @@ mod multiple_definition { &mut functions_flattened, &arguments_flattened, &mut statements_flattened, - &statement, + statement, ); assert_eq!( @@ -1082,7 +1082,7 @@ mod multiple_definition { &mut functions_flattened, &arguments_flattened, &mut statements_flattened, - &statement, + statement, ); assert_eq!( @@ -1126,7 +1126,7 @@ mod multiple_definition { &mut functions_flattened, &arguments_flattened, &mut statements_flattened, - &statement, + statement, ); assert_eq!( diff --git a/zokrates_core/src/optimizer.rs b/zokrates_core/src/optimizer.rs index 501dee06..a0af5116 100644 --- a/zokrates_core/src/optimizer.rs +++ b/zokrates_core/src/optimizer.rs @@ -93,8 +93,8 @@ impl Optimizer { } // generate optimized statements by removing synonym declarations and renaming variables - let optimized_statements = funct.statements.iter().filter_map(|statement| { - match *statement { + let optimized_statements = funct.statements.into_iter().filter_map(|statement| { + match statement { // filter out synonyms definitions FlatStatement::Definition(_, FlatExpression::Identifier(_)) => { None @@ -107,15 +107,14 @@ impl Optimizer { }).collect(); // generate optimized arguments by renaming them - let optimized_arguments = funct.arguments.iter().map(|arg| arg.apply_substitution(&self.substitution)).collect(); + let optimized_arguments = funct.arguments.into_iter().map(|arg| arg.apply_substitution(&self.substitution)).collect(); - // clone function - let mut optimized_funct = funct.clone(); - // update statements with optimized ones - optimized_funct.statements = optimized_statements; - optimized_funct.arguments = optimized_arguments; - - optimized_funct + FlatFunction { + id: funct.id, + arguments: optimized_arguments, + statements: optimized_statements, + return_count: funct.return_count + } } } diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index 3f322db2..bc6474cf 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -76,6 +76,7 @@ impl Checker { signature: func.signature }); } + self.check_single_main()?; Ok(TypedProg { functions: checked_functions, @@ -85,7 +86,7 @@ impl Checker { } fn check_single_main(&mut self) -> Result<(), Error> { - match self.functions.clone().into_iter().filter(|fun| fun.id == "main").count() { + match self.functions.iter().filter(|fun| fun.id == "main").count() { 1 => Ok(()), 0 => Err(Error { message: format!("No main function found") }), n => Err(Error { message: format!("Only one main function allowed, found {}", n) }) diff --git a/zokrates_core/src/typed_absy/mod.rs b/zokrates_core/src/typed_absy/mod.rs index d954418b..3c91a688 100644 --- a/zokrates_core/src/typed_absy/mod.rs +++ b/zokrates_core/src/typed_absy/mod.rs @@ -295,10 +295,10 @@ pub enum BooleanExpression { } impl BooleanExpression { - fn apply_substitution(&self, substitution: &Substitution) -> BooleanExpression { - match *self { - BooleanExpression::Identifier(ref id) => { - let mut new_name = id.clone(); + fn apply_substitution(self, substitution: &Substitution) -> BooleanExpression { + match self { + BooleanExpression::Identifier(id) => { + let mut new_name = id; loop { match substitution.get(&new_name) { Some(x) => new_name = x.to_string(), @@ -306,23 +306,23 @@ impl BooleanExpression { } } }, - BooleanExpression::Lt(ref lhs, ref rhs) => BooleanExpression::Lt( + BooleanExpression::Lt(lhs, rhs) => BooleanExpression::Lt( box lhs.apply_substitution(substitution), box rhs.apply_substitution(substitution), ), - BooleanExpression::Le(ref lhs, ref rhs) => BooleanExpression::Le( + BooleanExpression::Le(lhs, rhs) => BooleanExpression::Le( box lhs.apply_substitution(substitution), box rhs.apply_substitution(substitution), ), - BooleanExpression::Eq(ref lhs, ref rhs) => BooleanExpression::Eq( + BooleanExpression::Eq(lhs, rhs) => BooleanExpression::Eq( box lhs.apply_substitution(substitution), box rhs.apply_substitution(substitution), ), - BooleanExpression::Ge(ref lhs, ref rhs) => BooleanExpression::Ge( + BooleanExpression::Ge(lhs, rhs) => BooleanExpression::Ge( box lhs.apply_substitution(substitution), box rhs.apply_substitution(substitution), ), - BooleanExpression::Gt(ref lhs, ref rhs) => BooleanExpression::Gt( + BooleanExpression::Gt(lhs, rhs) => BooleanExpression::Gt( box lhs.apply_substitution(substitution), box rhs.apply_substitution(substitution), ), @@ -331,10 +331,10 @@ impl BooleanExpression { } impl FieldElementExpression { - pub fn apply_substitution(&self, substitution: &Substitution) -> FieldElementExpression { - match *self { - ref e @ FieldElementExpression::Number(_) => e.clone(), - FieldElementExpression::Identifier(ref id) => { + pub fn apply_substitution(self, substitution: &Substitution) -> FieldElementExpression { + match self { + e @ FieldElementExpression::Number(_) => e, + FieldElementExpression::Identifier(id) => { let mut new_name = id.clone(); loop { match substitution.get(&new_name) { @@ -343,36 +343,33 @@ impl FieldElementExpression { } } } - FieldElementExpression::Add(ref e1, ref e2) => FieldElementExpression::Add( + FieldElementExpression::Add(e1, e2) => FieldElementExpression::Add( box e1.apply_substitution(substitution), box e2.apply_substitution(substitution), ), - FieldElementExpression::Sub(ref e1, ref e2) => FieldElementExpression::Sub( + FieldElementExpression::Sub(e1, e2) => FieldElementExpression::Sub( box e1.apply_substitution(substitution), box e2.apply_substitution(substitution), ), - FieldElementExpression::Mult(ref e1, ref e2) => FieldElementExpression::Mult( + FieldElementExpression::Mult(e1, e2) => FieldElementExpression::Mult( box e1.apply_substitution(substitution), box e2.apply_substitution(substitution), ), - FieldElementExpression::Div(ref e1, ref e2) => FieldElementExpression::Div( + FieldElementExpression::Div(e1, e2) => FieldElementExpression::Div( box e1.apply_substitution(substitution), box e2.apply_substitution(substitution), ), - FieldElementExpression::Pow(ref e1, ref e2) => FieldElementExpression::Pow( + FieldElementExpression::Pow(e1, e2) => FieldElementExpression::Pow( box e1.apply_substitution(substitution), box e2.apply_substitution(substitution), ), - FieldElementExpression::IfElse(ref c, ref e1, ref e2) => FieldElementExpression::IfElse( + FieldElementExpression::IfElse(c, e1, e2) => FieldElementExpression::IfElse( box c.apply_substitution(substitution), box e1.apply_substitution(substitution), box e2.apply_substitution(substitution), ), - FieldElementExpression::FunctionCall(ref i, ref p) => { - for param in p { - param.apply_substitution(substitution); - } - FieldElementExpression::FunctionCall(i.clone(), p.clone()) + FieldElementExpression::FunctionCall(i, p) => { + FieldElementExpression::FunctionCall(i, p.into_iter().map(|param| param.apply_substitution(substitution)).collect()) }, } } @@ -474,7 +471,7 @@ impl fmt::Debug for FieldElementExpression { impl TypedExpression { - pub fn apply_substitution(&self, substitution: &Substitution) -> TypedExpression { + pub fn apply_substitution(self, substitution: &Substitution) -> TypedExpression { match self { TypedExpression::Boolean(e) => e.apply_substitution(substitution).into(), TypedExpression::FieldElement(e) => e.apply_substitution(substitution).into(), @@ -483,10 +480,10 @@ impl TypedExpression { } impl TypedExpressionList { - pub fn apply_substitution(&self, substitution: &Substitution) -> TypedExpressionList { - match *self { - TypedExpressionList::FunctionCall(ref id, ref inputs, ref types) => { - TypedExpressionList::FunctionCall(id.clone(), inputs.iter().map(|i| i.apply_substitution(substitution)).collect(), types.clone()) + pub fn apply_substitution(self, substitution: &Substitution) -> TypedExpressionList { + match self { + TypedExpressionList::FunctionCall(id, inputs, types) => { + TypedExpressionList::FunctionCall(id, inputs.into_iter().map(|i| i.apply_substitution(substitution)).collect(), types) } } } From 6883632144d59291e8acfc230819d3894a126f35 Mon Sep 17 00:00:00 2001 From: schaeff Date: Thu, 23 Aug 2018 16:43:15 +0200 Subject: [PATCH 07/11] add light flag --- zokrates_cli/src/bin.rs | 70 ++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/zokrates_cli/src/bin.rs b/zokrates_cli/src/bin.rs index 760190d2..dff653c2 100644 --- a/zokrates_cli/src/bin.rs +++ b/zokrates_cli/src/bin.rs @@ -62,6 +62,10 @@ fn main() { .long("optimized") .help("perform optimization.") .required(false) + ).arg(Arg::with_name("light") + .long("light") + .help("Skip logs and human readable output") + .required(false) ).arg(Arg::with_name("gadgets") .long("gadgets") .help("include libsnark gadgets such as sha256") @@ -201,6 +205,12 @@ fn main() { let should_include_gadgets = sub_matches.occurrences_of("gadgets") > 0; + let light = sub_matches.occurrences_of("light") > 0; + + let bin_output_path = Path::new(sub_matches.value_of("output").unwrap()); + + let hr_output_path = bin_output_path.to_path_buf().with_extension("code"); + let file = File::open(path.clone()).unwrap(); let mut reader = BufReader::new(file); @@ -210,42 +220,44 @@ fn main() { Err(why) => panic!("Compilation failed: {}", why) }; - // // number of constraints the flattened program will translate to. - // let num_constraints = &program_flattened.functions - // .iter() - // .find(|x| x.id == "main") - // .unwrap().statements.len(); + // number of constraints the flattened program will translate to. + let num_constraints = &program_flattened.functions + .iter() + .find(|x| x.id == "main") + .unwrap().statements.len(); - // // serialize flattened program and write to binary file - // let bin_output_path = Path::new(sub_matches.value_of("output").unwrap()); - // let mut bin_output_file = match File::create(&bin_output_path) { - // Ok(file) => file, - // Err(why) => panic!("couldn't create {}: {}", bin_output_path.display(), why), - // }; + // serialize flattened program and write to binary file + let mut bin_output_file = match File::create(&bin_output_path) { + Ok(file) => file, + Err(why) => panic!("couldn't create {}: {}", bin_output_path.display(), why), + }; - // serialize_into(&mut bin_output_file, &program_flattened, Infinite).expect("Unable to write data to file."); + serialize_into(&mut bin_output_file, &program_flattened, Infinite).expect("Unable to write data to file."); - // // write human-readable output file - // let hr_output_path = bin_output_path.to_path_buf().with_extension("code"); + if !light { + // write human-readable output file + let hr_output_file = match File::create(&hr_output_path) { + Ok(file) => file, + Err(why) => panic!("couldn't create {}: {}", hr_output_path.display(), why), + }; - // let hr_output_file = match File::create(&hr_output_path) { - // Ok(file) => file, - // Err(why) => panic!("couldn't create {}: {}", hr_output_path.display(), why), - // }; + let mut hrofb = BufWriter::new(hr_output_file); + write!(&mut hrofb, "{}\n", program_flattened).expect("Unable to write data to file."); + hrofb.flush().expect("Unable to flush buffer."); + } - // let mut hrofb = BufWriter::new(hr_output_file); - // write!(&mut hrofb, "{}\n", program_flattened).expect("Unable to write data to file."); - // hrofb.flush().expect("Unable to flush buffer."); + if !light { + // debugging output + println!("Compiled program:\n{}", program_flattened); + } - // // debugging output - // println!("Compiled program:\n{}", program_flattened); + println!("Compiled code written to '{}'", bin_output_path.display()); - // println!( - // "Compiled code written to '{}', \nHuman readable code to '{}'. \nNumber of constraints: {}", - // bin_output_path.display(), - // hr_output_path.display(), - // num_constraints - // ); + if !light { + println!("Human readable code to '{}'", hr_output_path.display()); + } + + println!("Number of constraints: {}", num_constraints); } ("compute-witness", Some(sub_matches)) => { println!("Computing witness for:"); From a553dae84a81e9d13ce1984a8869dc6ad5c71922 Mon Sep 17 00:00:00 2001 From: schaeff Date: Fri, 31 Aug 2018 10:55:28 +0200 Subject: [PATCH 08/11] add breaking test, fix integration tests --- zokrates_cli/examples/taxation.code | 7 ++ .../tests/code/taxation.arguments.json | 1 + zokrates_cli/tests/code/taxation.code | 7 ++ .../tests/code/taxation.expected.witness | 1 + zokrates_cli/tests/integration.rs | 73 ++++++++++--------- 5 files changed, 53 insertions(+), 36 deletions(-) create mode 100644 zokrates_cli/examples/taxation.code create mode 100644 zokrates_cli/tests/code/taxation.arguments.json create mode 100644 zokrates_cli/tests/code/taxation.code create mode 100644 zokrates_cli/tests/code/taxation.expected.witness diff --git a/zokrates_cli/examples/taxation.code b/zokrates_cli/examples/taxation.code new file mode 100644 index 00000000..27429ff0 --- /dev/null +++ b/zokrates_cli/examples/taxation.code @@ -0,0 +1,7 @@ +def wtax(debt,wealth): + x = if wealth < debt then 0 else (wealth-debt) fi + return x + +def main(debt, wealth): + tax = wtax(debt,wealth) + return tax \ No newline at end of file diff --git a/zokrates_cli/tests/code/taxation.arguments.json b/zokrates_cli/tests/code/taxation.arguments.json new file mode 100644 index 00000000..ecb0a5bd --- /dev/null +++ b/zokrates_cli/tests/code/taxation.arguments.json @@ -0,0 +1 @@ +[15, 12] \ No newline at end of file diff --git a/zokrates_cli/tests/code/taxation.code b/zokrates_cli/tests/code/taxation.code new file mode 100644 index 00000000..27429ff0 --- /dev/null +++ b/zokrates_cli/tests/code/taxation.code @@ -0,0 +1,7 @@ +def wtax(debt,wealth): + x = if wealth < debt then 0 else (wealth-debt) fi + return x + +def main(debt, wealth): + tax = wtax(debt,wealth) + return tax \ No newline at end of file diff --git a/zokrates_cli/tests/code/taxation.expected.witness b/zokrates_cli/tests/code/taxation.expected.witness new file mode 100644 index 00000000..1e61044c --- /dev/null +++ b/zokrates_cli/tests/code/taxation.expected.witness @@ -0,0 +1 @@ +~out_0 1 \ No newline at end of file diff --git a/zokrates_cli/tests/integration.rs b/zokrates_cli/tests/integration.rs index edf1164c..5873bbf7 100644 --- a/zokrates_cli/tests/integration.rs +++ b/zokrates_cli/tests/integration.rs @@ -72,7 +72,7 @@ mod integration { compile.push("--optimized"); // we don't want to test libsnark integrations if libsnark is not available - #[cfg(feature = "nolibsnark")] + #[cfg(not(feature = "libsnark"))] return } @@ -81,7 +81,42 @@ mod integration { .succeeds() .unwrap(); - #[cfg(not(feature = "nolibsnark"))] + // COMPUTE_WITNESS + let arguments: Value = serde_json::from_reader(File::open(arguments_path).unwrap()).unwrap(); + + let arguments_str_list: Vec = arguments.as_array().unwrap().iter().map(|i| match *i { + Value::Number(ref n) => n.to_string(), + _ => panic!(format!("Cannot read arguments. Check {}", arguments_path.to_str().unwrap())) + }).collect(); + + let mut compute = vec!["../target/debug/zokrates", "compute-witness", + "-i", flattened_path.to_str().unwrap(), + "-o", witness_path.to_str().unwrap(), + "-a"]; + + for arg in arguments_str_list.iter() { + compute.push(arg); + } + + assert_cli::Assert::command(&compute) + .succeeds() + .unwrap(); + + // load the expected witness + let mut expected_witness_file = File::open(&expected_witness_path).unwrap(); + let mut expected_witness = String::new(); + expected_witness_file.read_to_string(&mut expected_witness).unwrap(); + + // load the actual witness + let mut witness_file = File::open(&witness_path).unwrap(); + let mut witness = String::new(); + witness_file.read_to_string(&mut witness).unwrap(); + + for line in expected_witness.as_str().split("\n") { + assert!(witness.contains(line), "Witness generation failed for {}\n\nLine \"{}\" not found in witness", program_path.to_str().unwrap(), line); + } + + #[cfg(feature = "libsnark")] { // SETUP assert_cli::Assert::command(&["../target/debug/zokrates", "setup", @@ -99,40 +134,6 @@ mod integration { .succeeds() .unwrap(); - // COMPUTE_WITNESS - let arguments: Value = serde_json::from_reader(File::open(arguments_path).unwrap()).unwrap(); - - let arguments_str_list: Vec = arguments.as_array().unwrap().iter().map(|i| match *i { - Value::Number(ref n) => n.to_string(), - _ => panic!(format!("Cannot read arguments. Check {}", arguments_path.to_str().unwrap())) - }).collect(); - - let mut compute = vec!["../target/debug/zokrates", "compute-witness", - "-i", flattened_path.to_str().unwrap(), - "-o", witness_path.to_str().unwrap(), - "-a"]; - - for arg in arguments_str_list.iter() { - compute.push(arg); - } - - assert_cli::Assert::command(&compute) - .succeeds() - .unwrap(); - - // load the expected witness - let mut expected_witness_file = File::open(&expected_witness_path).unwrap(); - let mut expected_witness = String::new(); - expected_witness_file.read_to_string(&mut expected_witness).unwrap(); - - // load the actual witness - let mut witness_file = File::open(&witness_path).unwrap(); - let mut witness = String::new(); - witness_file.read_to_string(&mut witness).unwrap(); - - for line in expected_witness.as_str().split("\n") { - assert!(witness.contains(line), "Witness generation failed for {}\n\nLine \"{}\" not found in witness", program_path.to_str().unwrap(), line); - } // GENERATE-PROOF assert_cli::Assert::command(&["../target/debug/zokrates", "generate-proof", "-w", witness_path.to_str().unwrap(), From 87ccd9b6692ddfc998b7e614746b441e368f1bbf Mon Sep 17 00:00:00 2001 From: schaeff Date: Fri, 31 Aug 2018 12:09:01 +0200 Subject: [PATCH 09/11] revert to using definitions to fix substitution --- zokrates_core/src/flatten/mod.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/zokrates_core/src/flatten/mod.rs b/zokrates_core/src/flatten/mod.rs index caa9a9ad..99c75469 100644 --- a/zokrates_core/src/flatten/mod.rs +++ b/zokrates_core/src/flatten/mod.rs @@ -180,8 +180,8 @@ impl Flattener { // bitness checks for i in 0..self.bits - 2 { let new_name = format!("{}{}{}", &lhs_name, BINARY_SEPARATOR, i); - statements_flattened.push(FlatStatement::Condition( - FlatExpression::Identifier(new_name.to_string()), + statements_flattened.push(FlatStatement::Definition( + new_name.to_string(), FlatExpression::Mult( box FlatExpression::Identifier(new_name.to_string()), box FlatExpression::Identifier(new_name.to_string()), @@ -203,8 +203,8 @@ impl Flattener { } statements_flattened - .push(FlatStatement::Condition( - FlatExpression::Identifier(lhs_name.clone()), + .push(FlatStatement::Definition( + lhs_name.clone(), lhs_sum ) ); @@ -215,8 +215,8 @@ impl Flattener { // bitness checks for i in 0..self.bits - 2 { let new_name = format!("{}{}{}", &rhs_name, BINARY_SEPARATOR, i); - statements_flattened.push(FlatStatement::Condition( - FlatExpression::Identifier(new_name.to_string()), + statements_flattened.push(FlatStatement::Definition( + new_name.to_string(), FlatExpression::Mult( box FlatExpression::Identifier(new_name.to_string()), box FlatExpression::Identifier(new_name.to_string()), @@ -238,8 +238,8 @@ impl Flattener { } statements_flattened - .push(FlatStatement::Condition( - FlatExpression::Identifier(rhs_name.clone()), + .push(FlatStatement::Definition( + rhs_name.clone(), rhs_sum ) ); @@ -260,8 +260,8 @@ impl Flattener { // sym_b{i} = sym_b{i}**2 (bitness checks) for i in 0..self.bits { let new_name = format!("{}{}{}", &subtraction_result, BINARY_SEPARATOR, i); - statements_flattened.push(FlatStatement::Condition( - FlatExpression::Identifier(new_name.to_string()), + statements_flattened.push(FlatStatement::Definition( + new_name.to_string(), FlatExpression::Mult( box FlatExpression::Identifier(new_name.to_string()), box FlatExpression::Identifier(new_name.to_string()), From 36f66194cc591f25aaff26a5cf982ee43a383c15 Mon Sep 17 00:00:00 2001 From: schaeff Date: Fri, 31 Aug 2018 13:41:13 +0200 Subject: [PATCH 10/11] use conditions for sum checks, fix example expected witness --- zokrates_cli/tests/code/taxation.expected.witness | 2 +- zokrates_core/src/flatten/mod.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/zokrates_cli/tests/code/taxation.expected.witness b/zokrates_cli/tests/code/taxation.expected.witness index 1e61044c..1b8f13fa 100644 --- a/zokrates_cli/tests/code/taxation.expected.witness +++ b/zokrates_cli/tests/code/taxation.expected.witness @@ -1 +1 @@ -~out_0 1 \ No newline at end of file +~out_0 0 \ No newline at end of file diff --git a/zokrates_core/src/flatten/mod.rs b/zokrates_core/src/flatten/mod.rs index 99c75469..c0ae56af 100644 --- a/zokrates_core/src/flatten/mod.rs +++ b/zokrates_core/src/flatten/mod.rs @@ -203,8 +203,8 @@ impl Flattener { } statements_flattened - .push(FlatStatement::Definition( - lhs_name.clone(), + .push(FlatStatement::Condition( + FlatExpression::Identifier(lhs_name.clone()), lhs_sum ) ); @@ -238,8 +238,8 @@ impl Flattener { } statements_flattened - .push(FlatStatement::Definition( - rhs_name.clone(), + .push(FlatStatement::Condition( + FlatExpression::Identifier(rhs_name.clone()), rhs_sum ) ); From f6c30a7377c05d91853b8556b5b2117e4e44f5f7 Mon Sep 17 00:00:00 2001 From: Dimitris Apostolou Date: Sun, 9 Sep 2018 13:35:33 +0300 Subject: [PATCH 11/11] Fix typos --- zokrates_cli/src/bin.rs | 2 +- zokrates_core/src/field.rs | 2 +- zokrates_core/src/r1cs.rs | 2 +- zokrates_core/src/standard.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/zokrates_cli/src/bin.rs b/zokrates_cli/src/bin.rs index 85d62ef8..a7943ffb 100644 --- a/zokrates_cli/src/bin.rs +++ b/zokrates_cli/src/bin.rs @@ -77,7 +77,7 @@ fn main() { .arg(Arg::with_name("input") .short("i") .long("input") - .help("path of comiled code.") + .help("path of compiled code.") .value_name("FILE") .takes_value(true) .required(false) diff --git a/zokrates_core/src/field.rs b/zokrates_core/src/field.rs index 8e129e29..8080b270 100644 --- a/zokrates_core/src/field.rs +++ b/zokrates_core/src/field.rs @@ -345,7 +345,7 @@ impl<'de> Deserialize<'de> for FieldPrime { } } -/// Calculates the gcd using a iterative implementation of the extended euclidian algorithm. +/// Calculates the gcd using an iterative implementation of the extended euclidian algorithm. /// Returning `(d, s, t)` so that `d = s * a + t * b` /// /// # Arguments diff --git a/zokrates_core/src/r1cs.rs b/zokrates_core/src/r1cs.rs index a2031ec8..7699a6af 100644 --- a/zokrates_core/src/r1cs.rs +++ b/zokrates_core/src/r1cs.rs @@ -43,7 +43,7 @@ fn get_summands(expr: &FlatExpression) -> Vec<&FlatExpression> { } } -/// Returns a `HashMap` containing variables and the number of occurences +/// Returns a `HashMap` containing variables and the number of occurrences /// /// # Arguments /// diff --git a/zokrates_core/src/standard.rs b/zokrates_core/src/standard.rs index 4782be0e..935303c9 100644 --- a/zokrates_core/src/standard.rs +++ b/zokrates_core/src/standard.rs @@ -7,7 +7,7 @@ use reduce::Reduce; use helpers::{DirectiveStatement, Helper, LibsnarkGadgetHelper}; // for r1cs import, can be moved. -// r1cs data strucutre reflecting JSON standard format: +// r1cs data structure reflecting JSON standard format: // { // input_count: count, // # of inputs to pass // outputs: [offset_42, offset_63, offset_55], // indices of the outputs in the witness