From 66b54f509a4760aecc298bbdc78626fb9ccbe73f Mon Sep 17 00:00:00 2001 From: schaeff Date: Tue, 20 Nov 2018 19:25:47 +0100 Subject: [PATCH 01/15] add dummy file --- REMOVEME.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 REMOVEME.txt diff --git a/REMOVEME.txt b/REMOVEME.txt new file mode 100644 index 00000000..ab594303 --- /dev/null +++ b/REMOVEME.txt @@ -0,0 +1 @@ +dummy file to troubleshoot CI, TO BE REMOVED BEFORE MERGE \ No newline at end of file From a768a416909524176ad071036269876d04295570 Mon Sep 17 00:00:00 2001 From: Thibaut Schaeffer Date: Thu, 22 Nov 2018 23:21:34 +0100 Subject: [PATCH 02/15] Clean readme links, add contributor line --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7ec29708..f569c109 100644 --- a/README.md +++ b/README.md @@ -14,12 +14,12 @@ _This is a proof-of-concept implementation. It has not been tested for productio ## Getting Started -Have a look at the documentation [zokrates.github.io](https://zokrates.github.io/) for more informations about using Zokrates. +Have a look at the [documentation](https://zokrates.github.io/) for more informations about using Zokrates. A getting started tutorial can be found [here](https://zokrates.github.io/sha256example.html). ## Getting Help -If you run into problems, Zokrates has a Gitter room. You can come ask for help at [gitter.im/ZoKrates/Lobby](https://gitter.im/ZoKrates/Lobby). +If you run into problems, Zokrates has a Gitter room. You can come ask for help on [Gitter](https://gitter.im/ZoKrates/Lobby). ## License @@ -27,4 +27,6 @@ ZoKrates is released under the GNU Lesser General Public License v3. ## Contributing +We happily welcome contributions. You can either pick an existing issue, or reach out on [Gitter](https://gitter.im/ZoKrates/Lobby). + Unless you explicitly state otherwise, any contribution you intentionally submit for inclusion in the work shall be licensed as above, without any additional terms or conditions. From dc17427808682f446f4b695ff420629c0fa86697 Mon Sep 17 00:00:00 2001 From: schaeff Date: Fri, 23 Nov 2018 00:21:50 +0100 Subject: [PATCH 03/15] add backtrace --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 78e4d63c..274442bd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -26,7 +26,7 @@ jobs: command: WITH_LIBSNARK=1 LIBSNARK_SOURCE_PATH=$HOME/libsnark RUSTFLAGS="-D warnings" ./build.sh - run: name: Run tests - command: WITH_LIBSNARK=1 LIBSNARK_SOURCE_PATH=$HOME/libsnark RUSTFLAGS="-D warnings" cargo test --release + command: WITH_LIBSNARK=1 LIBSNARK_SOURCE_PATH=$HOME/libsnark RUST_BACKTRACE=1 RUSTFLAGS="-D warnings" cargo test --release - run: name: Run integration tests command: WITH_LIBSNARK=1 LIBSNARK_SOURCE_PATH=$HOME/libsnark RUSTFLAGS="-D warnings" cargo test --release -- --ignored From c167039ac000cc27e72920231c2b0aaeb8c884fc Mon Sep 17 00:00:00 2001 From: schaeff Date: Fri, 23 Nov 2018 00:26:24 +0100 Subject: [PATCH 04/15] limit thread number on tests --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 274442bd..9d4ca794 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -26,7 +26,7 @@ jobs: command: WITH_LIBSNARK=1 LIBSNARK_SOURCE_PATH=$HOME/libsnark RUSTFLAGS="-D warnings" ./build.sh - run: name: Run tests - command: WITH_LIBSNARK=1 LIBSNARK_SOURCE_PATH=$HOME/libsnark RUST_BACKTRACE=1 RUSTFLAGS="-D warnings" cargo test --release + command: WITH_LIBSNARK=1 LIBSNARK_SOURCE_PATH=$HOME/libsnark RUSTFLAGS="-D warnings" cargo test --release -- --test-threads=1 - run: name: Run integration tests command: WITH_LIBSNARK=1 LIBSNARK_SOURCE_PATH=$HOME/libsnark RUSTFLAGS="-D warnings" cargo test --release -- --ignored From e15c5f39ffb840d86f064fb23108074b6b65d976 Mon Sep 17 00:00:00 2001 From: schaeff Date: Fri, 23 Nov 2018 00:52:30 +0100 Subject: [PATCH 05/15] remove dummy file --- REMOVEME.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 REMOVEME.txt diff --git a/REMOVEME.txt b/REMOVEME.txt deleted file mode 100644 index ab594303..00000000 --- a/REMOVEME.txt +++ /dev/null @@ -1 +0,0 @@ -dummy file to troubleshoot CI, TO BE REMOVED BEFORE MERGE \ No newline at end of file From 4bbca45d1d524ff8ff0eeae87db3c1883aafb73c Mon Sep 17 00:00:00 2001 From: JacobEberhardt Date: Fri, 23 Nov 2018 13:31:36 +0100 Subject: [PATCH 06/15] ZoKrates spelling + typo fix. --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f569c109..25505365 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,25 @@ -# Zokrates +# ZoKrates [![Join the chat at https://gitter.im/ZoKrates/Lobby](https://badges.gitter.im/ZoKrates/Lobby.svg)](https://gitter.im/ZoKrates/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ![Jenkins](https://img.shields.io/jenkins/s/https/jenkins.kyroy.com/job/ZoKrates/job/master.svg?label=master) ![Jenkins](https://img.shields.io/jenkins/s/https/jenkins.kyroy.com/job/ZoKrates/job/develop.svg?label=develop) -Zokrates is a toolbox for zkSNARKs on Ethereum. +ZoKrates is a toolbox for zkSNARKs on Ethereum. _This is a proof-of-concept implementation. It has not been tested for production._ ## Getting Started -Have a look at the [documentation](https://zokrates.github.io/) for more informations about using Zokrates. +Have a look at the [documentation](https://zokrates.github.io/) for more information about using ZoKrates. A getting started tutorial can be found [here](https://zokrates.github.io/sha256example.html). ## Getting Help -If you run into problems, Zokrates has a Gitter room. You can come ask for help on [Gitter](https://gitter.im/ZoKrates/Lobby). +If you run into problems, ZoKrates has a Gitter room. You can come ask for help on [Gitter](https://gitter.im/ZoKrates/Lobby). ## License From ab159321deeea148f0b9092d435f610a12f3d000 Mon Sep 17 00:00:00 2001 From: schaeff Date: Fri, 23 Nov 2018 18:02:21 +0100 Subject: [PATCH 07/15] factor identifiers fcalls and selects, produce terms outside of parse_expr --- zokrates_core/src/parser/parse/expression.rs | 211 +++++++++++++++++-- zokrates_core/src/parser/parse/statement.rs | 167 +++++++++------ 2 files changed, 296 insertions(+), 82 deletions(-) diff --git a/zokrates_core/src/parser/parse/expression.rs b/zokrates_core/src/parser/parse/expression.rs index 9247def9..2df658c3 100644 --- a/zokrates_core/src/parser/parse/expression.rs +++ b/zokrates_core/src/parser/parse/expression.rs @@ -240,6 +240,19 @@ fn parse_factor1( } } +// parse an identifier or select or function call +fn parse_identified1( + x: String, + input: String, + position: Position, +) -> Result<(Expression, String, Position), Error> { + match next_token::(&input, &position) { + (Token::Open, s1, p1) => parse_function_call(x, s1, p1), + (Token::LeftBracket, s1, p1) => parse_array_select(x, s1, p1), + _ => Ok((Expression::Identifier(x), input, position)), + } +} + fn parse_factor( input: &String, pos: &Position, @@ -257,10 +270,9 @@ fn parse_factor( }, Err(err) => Err(err), }, - (Token::Ide(x), s1, p1) => match next_token::(&s1, &p1) { - (Token::Open, s2, p2) => parse_function_call(x, s2, p2), - (Token::LeftBracket, s2, p2) => parse_array_select(x, s2, p2), - _ => parse_factor1(Expression::Identifier(x), s1, p1), + (Token::Ide(x), s1, p1) => match parse_identified1(x, s1, p1) { + Ok((e2, s2, p2)) => parse_factor1(e2, s2, p2), + e => e, }, (Token::Num(x), s1, p1) => parse_factor1(Expression::Number(x), s1, p1), (t1, _, p1) => Err(Error { @@ -338,10 +350,7 @@ pub fn parse_function_call( match next_token::(&s, &p) { // no arguments (Token::Close, s1, p1) => { - match parse_term1(Expression::FunctionCall(ide, args), s1, p1) { - Ok((e2, s2, p2)) => return parse_expr1(e2, s2, p2), - Err(err) => return Err(err), - } + return parse_term1(Expression::FunctionCall(ide, args), s1, p1); } // at least one argument (_, _, _) => match parse_expr(&s, &p) { @@ -353,10 +362,7 @@ pub fn parse_function_call( p = p2; } (Token::Close, s2, p2) => { - match parse_term1(Expression::FunctionCall(ide, args), s2, p2) { - Ok((e3, s3, p3)) => return parse_expr1(e3, s3, p3), - Err(err) => return Err(err), - } + return parse_term1(Expression::FunctionCall(ide, args), s2, p2) } (t2, _, p2) => { return Err(Error { @@ -430,14 +436,11 @@ pub fn parse_array_select( match next_token::(&input, &pos) { (_, _, _) => match parse_expr(&input, &pos) { Ok((e1, s1, p1)) => match next_token::(&s1, &p1) { - (Token::RightBracket, s2, p2) => match parse_term1( + (Token::RightBracket, s2, p2) => parse_term1( Expression::Select(box Expression::Identifier(ide), box e1), s2, p2, - ) { - Ok((e3, s3, p3)) => parse_expr1(e3, s3, p3), - Err(err) => Err(err), - }, + ), (t2, _, p2) => Err(Error { expected: vec![Token::RightBracket], got: t2, @@ -469,13 +472,12 @@ pub fn parse_expr( }, Err(err) => Err(err), }, - (Token::Ide(x), s1, p1) => match next_token::(&s1, &p1) { - (Token::Open, s2, p2) => parse_function_call(x, s2, p2), - (Token::LeftBracket, s2, p2) => parse_array_select(x, s2, p2), - _ => match parse_term1(Expression::Identifier(x), s1, p1) { - Ok((e2, s2, p2)) => parse_expr1(e2, s2, p2), - Err(err) => Err(err), + (Token::Ide(x), s1, p1) => match parse_identified1(x, s1, p1) { + Ok((e2, s2, p2)) => match parse_term1(e2, s2, p2) { + Ok((e3, s3, p3)) => parse_expr1(e3, s3, p3), + e => e, }, + e => e, }, (Token::Num(x), s1, p1) => match parse_term1(Expression::Number(x), s1, p1) { Ok((e2, s2, p2)) => parse_expr1(e2, s2, p2), @@ -495,6 +497,169 @@ mod tests { use super::*; use field::FieldPrime; + mod terms { + use super::*; + + #[test] + fn parse_number_sum() { + let pos = Position { line: 45, col: 121 }; + let string = String::from("1 + 2 + 3"); + let expr = Expression::Add( + box Expression::Add( + box Expression::Number(FieldPrime::from(1)), + box Expression::Number(FieldPrime::from(2)), + ), + box Expression::Number(FieldPrime::from(3)), + ); + assert_eq!( + Ok((expr, String::from(""), pos.col(string.len() as isize))), + parse_expr(&string, &pos) + ); + } + + #[test] + fn parse_number_sub() { + let pos = Position { line: 45, col: 121 }; + let string = String::from("1 - 2 - 3"); + let expr = Expression::Sub( + box Expression::Sub( + box Expression::Number(FieldPrime::from(1)), + box Expression::Number(FieldPrime::from(2)), + ), + box Expression::Number(FieldPrime::from(3)), + ); + assert_eq!( + Ok((expr, String::from(""), pos.col(string.len() as isize))), + parse_expr(&string, &pos) + ); + } + + #[test] + fn parse_function_call_single_sub() { + let pos = Position { line: 45, col: 121 }; + let string = String::from("1 - f(a)"); + let expr = Expression::Sub( + box Expression::Number(FieldPrime::from(1)), + box Expression::FunctionCall( + String::from("f"), + vec![Expression::Identifier(String::from("a"))], + ), + ); + assert_eq!( + Ok((expr, String::from(""), pos.col(string.len() as isize))), + parse_expr(&string, &pos) + ); + } + + #[test] + fn parse_function_call_sub() { + let pos = Position { line: 45, col: 121 }; + let string = String::from("1 - f() - 3"); + let expr = Expression::Sub( + box Expression::Sub( + box Expression::Number(FieldPrime::from(1)), + box Expression::FunctionCall(String::from("f"), vec![]), + ), + box Expression::Number(FieldPrime::from(3)), + ); + assert_eq!( + Ok((expr, String::from(""), pos.col(string.len() as isize))), + parse_expr(&string, &pos) + ); + } + + #[test] + fn parse_function_call_add() { + let pos = Position { line: 45, col: 121 }; + let string = String::from("1 + f() + 3"); + let expr = Expression::Add( + box Expression::Add( + box Expression::Number(FieldPrime::from(1)), + box Expression::FunctionCall(String::from("f"), vec![]), + ), + box Expression::Number(FieldPrime::from(3)), + ); + assert_eq!( + Ok((expr, String::from(""), pos.col(string.len() as isize))), + parse_expr(&string, &pos) + ); + } + + #[test] + fn parse_select_sub() { + let pos = Position { line: 45, col: 121 }; + let string = String::from("1 - f[2] - 3"); + let expr = Expression::Sub( + box Expression::Sub( + box Expression::Number(FieldPrime::from(1)), + box Expression::Select( + box Expression::Identifier(String::from("f")), + box Expression::Number(FieldPrime::from(2)), + ), + ), + box Expression::Number(FieldPrime::from(3)), + ); + assert_eq!( + Ok((expr, String::from(""), pos.col(string.len() as isize))), + parse_expr(&string, &pos) + ); + } + + #[test] + fn parse_select_add() { + let pos = Position { line: 45, col: 121 }; + let string = String::from("1 + f[2] + 3"); + let expr = Expression::Add( + box Expression::Add( + box Expression::Number(FieldPrime::from(1)), + box Expression::Select( + box Expression::Identifier(String::from("f")), + box Expression::Number(FieldPrime::from(2)), + ), + ), + box Expression::Number(FieldPrime::from(3)), + ); + assert_eq!( + Ok((expr, String::from(""), pos.col(string.len() as isize))), + parse_expr(&string, &pos) + ); + } + + #[test] + fn parse_identifier_sub() { + let pos = Position { line: 45, col: 121 }; + let string = String::from("1 - f - 3"); + let expr = Expression::Sub( + box Expression::Sub( + box Expression::Number(FieldPrime::from(1)), + box Expression::Identifier(String::from("f")), + ), + box Expression::Number(FieldPrime::from(3)), + ); + assert_eq!( + Ok((expr, String::from(""), pos.col(string.len() as isize))), + parse_expr(&string, &pos) + ); + } + + #[test] + fn parse_identifier_add() { + let pos = Position { line: 45, col: 121 }; + let string = String::from("1 + f + 3"); + let expr = Expression::Add( + box Expression::Add( + box Expression::Number(FieldPrime::from(1)), + box Expression::Identifier(String::from("f")), + ), + box Expression::Number(FieldPrime::from(3)), + ); + assert_eq!( + Ok((expr, String::from(""), pos.col(string.len() as isize))), + parse_expr(&string, &pos) + ); + } + } + #[test] fn parse_if_then_else_ok() { let pos = Position { line: 45, col: 121 }; diff --git a/zokrates_core/src/parser/parse/statement.rs b/zokrates_core/src/parser/parse/statement.rs index 51d8e991..b5612b72 100644 --- a/zokrates_core/src/parser/parse/statement.rs +++ b/zokrates_core/src/parser/parse/statement.rs @@ -389,73 +389,79 @@ fn parse_statement1( Err(err) => Err(err), }, (Token::Open, s1, p1) => match parse_function_call(ide, s1, p1) { - Ok((e3, s3, p3)) => match next_token(&s3, &p3) { - (Token::Eqeq, s4, p4) => match parse_expr(&s4, &p4) { - Ok((e5, s5, p5)) => match next_token(&s5, &p5) { - (Token::InlineComment(_), ref s6, _) => { - assert_eq!(s6, ""); - Ok((vec![Statement::Condition(e3, e5)], s5, p5)) - } - (Token::Unknown(ref t6), ref s6, _) if t6 == "" => { - assert_eq!(s6, ""); - Ok((vec![Statement::Condition(e3, e5)], s5, p5)) - } - (t6, _, p6) => Err(Error { - expected: vec![ - Token::Add, - Token::Sub, - Token::Pow, - Token::Mult, - Token::Div, - Token::Unknown("".to_string()), - ], - got: t6, - pos: p6, - }), + Ok((e3, s3, p3)) => match parse_expr1(e3, s3, p3) { + Ok((e4, s4, p4)) => match next_token(&s4, &p4) { + (Token::Eqeq, s5, p5) => match parse_expr(&s5, &p5) { + Ok((e6, s6, p6)) => match next_token(&s6, &p6) { + (Token::InlineComment(_), ref s7, _) => { + assert_eq!(s7, ""); + Ok((vec![Statement::Condition(e4, e6)], s6, p6)) + } + (Token::Unknown(ref t7), ref s7, _) if t7 == "" => { + assert_eq!(s7, ""); + Ok((vec![Statement::Condition(e4, e6)], s6, p6)) + } + (t7, _, p7) => Err(Error { + expected: vec![ + Token::Add, + Token::Sub, + Token::Pow, + Token::Mult, + Token::Div, + Token::Unknown("".to_string()), + ], + got: t7, + pos: p7, + }), + }, + Err(err) => Err(err), }, - Err(err) => Err(err), + (t4, _, p4) => Err(Error { + expected: vec![Token::Eqeq], + got: t4, + pos: p4, + }), }, - (t4, _, p4) => Err(Error { - expected: vec![Token::Eqeq], - got: t4, - pos: p4, - }), + Err(err) => Err(err), }, Err(err) => Err(err), }, (Token::LeftBracket, s1, p1) => match parse_array_select(ide, s1, p1) { - Ok((e3, s3, p3)) => match next_token(&s3, &p3) { - (Token::Eqeq, s4, p4) => match parse_expr(&s4, &p4) { - Ok((e5, s5, p5)) => match next_token(&s5, &p5) { - (Token::InlineComment(_), ref s6, _) => { - assert_eq!(s6, ""); - Ok((vec![Statement::Condition(e3, e5)], s5, p5)) - } - (Token::Unknown(ref t6), ref s6, _) if t6 == "" => { - assert_eq!(s6, ""); - Ok((vec![Statement::Condition(e3, e5)], s5, p5)) - } - (t6, _, p6) => Err(Error { - expected: vec![ - Token::Add, - Token::Sub, - Token::Pow, - Token::Mult, - Token::Div, - Token::Unknown("".to_string()), - ], - got: t6, - pos: p6, - }), + Ok((e3, s3, p3)) => match parse_expr1(e3, s3, p3) { + Ok((e4, s4, p4)) => match next_token(&s4, &p4) { + (Token::Eqeq, s5, p5) => match parse_expr(&s5, &p5) { + Ok((e6, s6, p6)) => match next_token(&s6, &p6) { + (Token::InlineComment(_), ref s7, _) => { + assert_eq!(s7, ""); + Ok((vec![Statement::Condition(e4, e6)], s6, p6)) + } + (Token::Unknown(ref t7), ref s7, _) if t7 == "" => { + assert_eq!(s7, ""); + Ok((vec![Statement::Condition(e4, e6)], s6, p6)) + } + (t7, _, p7) => Err(Error { + expected: vec![ + Token::Add, + Token::Sub, + Token::Pow, + Token::Mult, + Token::Div, + Token::Unknown("".to_string()), + ], + got: t7, + pos: p7, + }), + }, + Err(err) => Err(err), }, - Err(err) => Err(err), + (Token::Eq, s5, p5) => parse_definition1(Assignee::from(e4), s5, p5), + (t4, _, p4) => Err(Error { + expected: vec![Token::Eqeq], + got: t4, + pos: p4, + }), }, - (Token::Eq, s4, p4) => parse_definition1(Assignee::from(e3), s4, p4), - (t4, _, p4) => Err(Error { - expected: vec![Token::Eqeq], - got: t4, - pos: p4, - }), + Err(err) => Err(err), }, Err(err) => Err(err), }, @@ -580,5 +586,48 @@ mod tests { parse_statement1(String::from("foo"), string, pos) ); } + + #[test] + fn left_call_in_assertion2() { + let pos = Position { line: 45, col: 121 }; + let string = String::from("() - g() - 1 == 1"); + let cond = Statement::Condition( + Expression::Sub( + box Expression::Sub( + box Expression::FunctionCall(String::from("foo"), vec![]), + box Expression::FunctionCall(String::from("g"), vec![]), + ), + box Expression::Number(FieldPrime::from(1)), + ), + Expression::Number(FieldPrime::from(1)), + ); + assert_eq!( + Ok((vec![cond], String::from(""), pos.col(string.len() as isize))), + parse_statement1(String::from("foo"), string, pos) + ); + } + + #[test] + fn left_select_in_assertion2() { + let pos = Position { line: 45, col: 121 }; + let string = String::from("[3] - g() - 1 == 1"); + let cond = Statement::Condition( + Expression::Sub( + box Expression::Sub( + box Expression::Select( + box Expression::Identifier(String::from("foo")), + box Expression::Number(FieldPrime::from(3)), + ), + box Expression::FunctionCall(String::from("g"), vec![]), + ), + box Expression::Number(FieldPrime::from(1)), + ), + Expression::Number(FieldPrime::from(1)), + ); + assert_eq!( + Ok((vec![cond], String::from(""), pos.col(string.len() as isize))), + parse_statement1(String::from("foo"), string, pos) + ); + } } } From e2acdbff378ace4667933c356de9573e4e576057 Mon Sep 17 00:00:00 2001 From: Kendrick Tan Date: Sun, 25 Nov 2018 00:14:21 +0000 Subject: [PATCH 08/15] fixed hashexample.code example --- zokrates_book/src/sha256example.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zokrates_book/src/sha256example.md b/zokrates_book/src/sha256example.md index eec971b4..dbf6d368 100644 --- a/zokrates_book/src/sha256example.md +++ b/zokrates_book/src/sha256example.md @@ -76,7 +76,7 @@ First, Victor has to specify what hash he is interested in. Therefore, we have t ```zokrates import "LIBSNARK/sha256packed" -def main(field a, field b, field c, field d) -> (field): +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 @@ -135,4 +135,4 @@ At this point, you’ve successfully ran you first zkSNARK on the Ethereum block > >In general, multiple parties may be interested in verifying the correctness of Alice's statement. For example, in the zero-knowledge based cryptocurrency Zcash, each node needs to be able to validate the correctness of transactions. In order to generalize the setup phase to these multi-party use-cases a tricky process, commonly referred to as “trusted setup” or "ceremony" needs to be conducted. > ->ZoKrates would welcome ideas to add support for such ceremonies! \ No newline at end of file +>ZoKrates would welcome ideas to add support for such ceremonies! From 96b7cca1012a2ef88ef3c36feb7e2cf7f5bc9081 Mon Sep 17 00:00:00 2001 From: schaeff Date: Tue, 27 Nov 2018 01:08:57 +0100 Subject: [PATCH 09/15] remove div from flatast, refactor Div flattening to use flat mult --- zokrates_core/src/flat_absy/mod.rs | 28 ++-- zokrates_core/src/flatten/mod.rs | 123 +++++++++++++++++- zokrates_core/src/helpers/mod.rs | 11 +- zokrates_core/src/helpers/rust.rs | 4 + zokrates_core/src/r1cs.rs | 77 ----------- .../src/static_analysis/flat_propagation.rs | 21 --- 6 files changed, 140 insertions(+), 124 deletions(-) diff --git a/zokrates_core/src/flat_absy/mod.rs b/zokrates_core/src/flat_absy/mod.rs index 18373806..b163434d 100644 --- a/zokrates_core/src/flat_absy/mod.rs +++ b/zokrates_core/src/flat_absy/mod.rs @@ -272,7 +272,6 @@ pub enum FlatExpression { Identifier(FlatVariable), Add(Box>, Box>), Sub(Box>, Box>), - Div(Box>, Box>), Mult(Box>, Box>), } @@ -313,10 +312,6 @@ impl FlatExpression { box e1.apply_substitution(substitution, should_fallback), box e2.apply_substitution(substitution, should_fallback), ), - FlatExpression::Div(e1, e2) => FlatExpression::Div( - box e1.apply_substitution(substitution, should_fallback), - box e2.apply_substitution(substitution, should_fallback), - ), } } @@ -330,7 +325,6 @@ impl FlatExpression { FlatExpression::Add(ref x, ref y) => x.solve(inputs) + y.solve(inputs), FlatExpression::Sub(ref x, ref y) => x.solve(inputs) - y.solve(inputs), FlatExpression::Mult(ref x, ref y) => x.solve(inputs) * y.solve(inputs), - FlatExpression::Div(ref x, ref y) => x.solve(inputs) / y.solve(inputs), } } @@ -340,14 +334,12 @@ impl FlatExpression { FlatExpression::Add(ref x, ref y) | FlatExpression::Sub(ref x, ref y) => { x.is_linear() && y.is_linear() } - FlatExpression::Mult(ref x, ref y) | FlatExpression::Div(ref x, ref y) => { - match (x.clone(), y.clone()) { - (box FlatExpression::Number(_), box FlatExpression::Number(_)) - | (box FlatExpression::Number(_), box FlatExpression::Identifier(_)) - | (box FlatExpression::Identifier(_), box FlatExpression::Number(_)) => true, - _ => false, - } - } + FlatExpression::Mult(ref x, ref y) => match (x.clone(), y.clone()) { + (box FlatExpression::Number(_), box FlatExpression::Number(_)) + | (box FlatExpression::Number(_), box FlatExpression::Identifier(_)) + | (box FlatExpression::Identifier(_), box FlatExpression::Number(_)) => true, + _ => false, + }, } } } @@ -360,7 +352,6 @@ impl fmt::Display for FlatExpression { FlatExpression::Add(ref lhs, ref rhs) => write!(f, "({} + {})", lhs, rhs), FlatExpression::Sub(ref lhs, ref rhs) => write!(f, "({} - {})", lhs, rhs), FlatExpression::Mult(ref lhs, ref rhs) => write!(f, "({} * {})", lhs, rhs), - FlatExpression::Div(ref lhs, ref rhs) => write!(f, "({} / {})", lhs, rhs), } } } @@ -373,11 +364,16 @@ impl fmt::Debug for FlatExpression { FlatExpression::Add(ref lhs, ref rhs) => write!(f, "Add({:?}, {:?})", lhs, rhs), FlatExpression::Sub(ref lhs, ref rhs) => write!(f, "Sub({:?}, {:?})", lhs, rhs), FlatExpression::Mult(ref lhs, ref rhs) => write!(f, "Mult({:?}, {:?})", lhs, rhs), - FlatExpression::Div(ref lhs, ref rhs) => write!(f, "Div({:?}, {:?})", lhs, rhs), } } } +impl From for FlatExpression { + fn from(v: FlatVariable) -> FlatExpression { + FlatExpression::Identifier(v) + } +} + #[derive(Clone, PartialEq, Serialize, Deserialize)] pub struct FlatExpressionList { pub expressions: Vec>, diff --git a/zokrates_core/src/flatten/mod.rs b/zokrates_core/src/flatten/mod.rs index 9226390e..4471ce1e 100644 --- a/zokrates_core/src/flatten/mod.rs +++ b/zokrates_core/src/flatten/mod.rs @@ -692,17 +692,33 @@ impl Flattener { statements_flattened, right, ); - let new_left = { + let new_left: FlatExpression = { let id = self.use_sym(); statements_flattened.push(FlatStatement::Definition(id, left_flattened)); - FlatExpression::Identifier(id) + id.into() }; - let new_right = { + let new_right: FlatExpression = { let id = self.use_sym(); statements_flattened.push(FlatStatement::Definition(id, right_flattened)); - FlatExpression::Identifier(id) + id.into() }; - FlatExpression::Div(box new_left, box new_right) + + let inverse = self.use_sym(); + + // # c = 1/b + statements_flattened.push(FlatStatement::Directive(DirectiveStatement::new( + vec![inverse], + Helper::Rust(RustHelper::Inverse), + vec![new_right.clone()], + ))); + + // assert(c * b == 1) + statements_flattened.push(FlatStatement::Condition( + FlatExpression::Number(T::from(1)), + FlatExpression::Mult(box new_right, box inverse.into()), + )); + + FlatExpression::Mult(box new_left, box inverse.into()) } FieldElementExpression::Pow(box base, box exponent) => { match exponent { @@ -1935,6 +1951,103 @@ mod tests { flattener.flatten_field_expression(&functions_flattened, &vec![], &mut vec![], expression); } + #[test] + fn div() { + // a = 5 / b / b + let mut flattener = Flattener::new(FieldPrime::get_required_bits()); + let mut functions_flattened = vec![]; + let arguments_flattened = vec![]; + let mut statements_flattened = vec![]; + + let definition = TypedStatement::Definition( + TypedAssignee::Identifier(Variable::field_element("b")), + FieldElementExpression::Number(FieldPrime::from(42)).into(), + ); + + let statement = TypedStatement::Definition( + TypedAssignee::Identifier(Variable::field_element("a")), + FieldElementExpression::Div( + box FieldElementExpression::Div( + box FieldElementExpression::Number(FieldPrime::from(5)), + box FieldElementExpression::Identifier(String::from("b")), + ), + box FieldElementExpression::Identifier(String::from("b")), + ) + .into(), + ); + + flattener.flatten_statement( + &mut functions_flattened, + &arguments_flattened, + &mut statements_flattened, + definition, + ); + + flattener.flatten_statement( + &mut functions_flattened, + &arguments_flattened, + &mut statements_flattened, + statement, + ); + + // define b + let b = FlatVariable::new(0); + // define new wires for members of Div + let five = FlatVariable::new(1); + let b0 = FlatVariable::new(2); + // Define inverse + let sym_0 = FlatVariable::new(3); + // Define result, which is first member to next Div + let sym_1 = FlatVariable::new(4); + // Define second member + let b1 = FlatVariable::new(5); + // Define inverse + let sym_2 = FlatVariable::new(6); + // Define left hand side + let a = FlatVariable::new(7); + + assert_eq!( + statements_flattened, + vec![ + FlatStatement::Definition(b, FlatExpression::Number(FieldPrime::from(42))), + // inputs to first div (5/b) + FlatStatement::Definition(five, FlatExpression::Number(FieldPrime::from(5))), + FlatStatement::Definition(b0, b.into()), + // execute div + FlatStatement::Directive(DirectiveStatement::new( + vec![sym_0], + Helper::Rust(RustHelper::Inverse), + vec![b0] + )), + FlatStatement::Condition( + FlatExpression::Number(FieldPrime::from(1)), + FlatExpression::Mult(box b0.into(), box sym_0.into()), + ), + // inputs to second div (res/b) + FlatStatement::Definition( + sym_1, + FlatExpression::Mult(box five.into(), box sym_0.into()) + ), + FlatStatement::Definition(b1, b.into()), + // execute div + FlatStatement::Directive(DirectiveStatement::new( + vec![sym_2], + Helper::Rust(RustHelper::Inverse), + vec![b1] + )), + FlatStatement::Condition( + FlatExpression::Number(FieldPrime::from(1)), + FlatExpression::Mult(box b1.into(), box sym_2.into()), + ), + // result + FlatStatement::Definition( + a, + FlatExpression::Mult(box sym_1.into(), box sym_2.into()) + ), + ] + ); + } + #[test] fn field_array() { // foo = [ , , ] diff --git a/zokrates_core/src/helpers/mod.rs b/zokrates_core/src/helpers/mod.rs index e7de0a23..a939174e 100644 --- a/zokrates_core/src/helpers/mod.rs +++ b/zokrates_core/src/helpers/mod.rs @@ -17,16 +17,17 @@ pub struct DirectiveStatement { } impl DirectiveStatement { - pub fn new(outputs: Vec, helper: Helper, inputs: Vec) -> Self { + pub fn new>>( + outputs: Vec, + helper: Helper, + inputs: Vec, + ) -> Self { let (in_len, out_len) = helper.get_signature(); assert_eq!(in_len, inputs.len()); assert_eq!(out_len, outputs.len()); DirectiveStatement { helper, - inputs: inputs - .into_iter() - .map(|i| FlatExpression::Identifier(i)) - .collect(), + inputs: inputs.into_iter().map(|i| i.into()).collect(), outputs, } } diff --git a/zokrates_core/src/helpers/rust.rs b/zokrates_core/src/helpers/rust.rs index 254e86b2..5e4553d6 100644 --- a/zokrates_core/src/helpers/rust.rs +++ b/zokrates_core/src/helpers/rust.rs @@ -7,6 +7,7 @@ pub enum RustHelper { Identity, ConditionEq, Bits, + Inverse, } impl fmt::Display for RustHelper { @@ -15,6 +16,7 @@ impl fmt::Display for RustHelper { RustHelper::Identity => write!(f, "Identity"), RustHelper::ConditionEq => write!(f, "ConditionEq"), RustHelper::Bits => write!(f, "Bits"), + RustHelper::Inverse => write!(f, "Inverse"), } } } @@ -25,6 +27,7 @@ impl Signed for RustHelper { RustHelper::Identity => (1, 1), RustHelper::ConditionEq => (1, 2), RustHelper::Bits => (1, 254), + RustHelper::Inverse => (1, 1), } } } @@ -52,6 +55,7 @@ impl Executable for RustHelper { assert_eq!(num, T::zero()); Ok(res) } + RustHelper::Inverse => Ok(vec![T::one() / inputs[0].clone()]), } } } diff --git a/zokrates_core/src/r1cs.rs b/zokrates_core/src/r1cs.rs index 5aef0582..c4bcc298 100644 --- a/zokrates_core/src/r1cs.rs +++ b/zokrates_core/src/r1cs.rs @@ -193,51 +193,6 @@ fn r1cs_expression( c_row.push((provide_variable_idx(variables, &key), value)); } } - Div(lhs, rhs) => { - // a / b = c --> c * b = a - match lhs { - box Number(x) => c_row.push((0, x)), - box Identifier(x) => c_row.push((provide_variable_idx(variables, &x), T::one())), - box e @ Add(..) => { - for (key, value) in count_variables_add(&e) { - c_row.push((provide_variable_idx(variables, &key), value)); - } - } - box e @ Sub(..) => { - return r1cs_expression( - Mult(box linear_expr, rhs), - e, - variables, - a_row, - b_row, - c_row, - ) - } - box Mult(box Number(ref x1), box Number(ref x2)) => { - c_row.push((0, x1.clone() * x2)) - } - box Mult(box Number(ref x), box Identifier(ref v)) - | box Mult(box Identifier(ref v), box Number(ref x)) => { - c_row.push((provide_variable_idx(variables, v), x.clone())) - } - e @ _ => panic!("(lhs) not supported: {:?}", e), - }; - match rhs { - box Number(x) => b_row.push((0, x)), - box Identifier(x) => b_row.push((provide_variable_idx(variables, &x), T::one())), - box Mult(box Number(ref x1), box Number(ref x2)) => { - b_row.push((0, x1.clone() * x2)) - } - box Mult(box Number(ref x), box Identifier(ref v)) - | box Mult(box Identifier(ref v), box Number(ref x)) => { - b_row.push((provide_variable_idx(variables, v), x.clone())) - } - e @ _ => panic!("(rhs) not supported: {:?}", e), - }; - for (key, value) in count_variables_add(&linear_expr) { - a_row.push((provide_variable_idx(variables, &key), value)); - } - } Identifier(var) => { a_row.push((provide_variable_idx(variables, &var), T::one())); b_row.push((0, T::one())); @@ -659,37 +614,5 @@ mod tests { c_row ); } - - #[test] - fn div() { - // x = (3 * x) / (y * 6) --> x * (y * 6) = 3 * x - - let one = FlatVariable::one(); - let x = FlatVariable::new(0); - let y = FlatVariable::new(1); - - let lhs = Identifier(x); - let rhs = Div( - box Mult(box Number(FieldPrime::from(3)), box Identifier(x)), - box Mult(box Identifier(y), box Number(FieldPrime::from(6))), - ); - - let mut a_row = Vec::new(); - let mut b_row = Vec::new(); - let mut c_row = Vec::new(); - - let mut variables: HashMap = HashMap::new(); - variables.insert(one, 0); - variables.insert(x, 1); - variables.insert(y, 2); - - r1cs_expression(lhs, rhs, &mut variables, &mut a_row, &mut b_row, &mut c_row); - a_row.sort_by(sort_tup); - b_row.sort_by(sort_tup); - c_row.sort_by(sort_tup); - assert_eq!(vec![(1, FieldPrime::from(1))], a_row); // x - assert_eq!(vec![(2, FieldPrime::from(6))], b_row); // y * 6 - assert_eq!(vec![(1, FieldPrime::from(3))], c_row); // 3 * x - } } } diff --git a/zokrates_core/src/static_analysis/flat_propagation.rs b/zokrates_core/src/static_analysis/flat_propagation.rs index a57c9aee..f936fbfc 100644 --- a/zokrates_core/src/static_analysis/flat_propagation.rs +++ b/zokrates_core/src/static_analysis/flat_propagation.rs @@ -49,14 +49,6 @@ impl PropagateWithContext for FlatExpression { (e1, e2) => FlatExpression::Mult(box e1, box e2), } } - FlatExpression::Div(box e1, box e2) => { - match (e1.propagate(constants), e2.propagate(constants)) { - (FlatExpression::Number(n1), FlatExpression::Number(n2)) => { - FlatExpression::Number(n1 / n2) - } - (e1, e2) => FlatExpression::Div(box e1, box e2), - } - } } } } @@ -173,19 +165,6 @@ mod tests { FlatExpression::Number(FieldPrime::from(6)) ); } - - #[test] - fn div() { - let e = FlatExpression::Div( - box FlatExpression::Number(FieldPrime::from(6)), - box FlatExpression::Number(FieldPrime::from(2)), - ); - - assert_eq!( - e.propagate(&mut HashMap::new()), - FlatExpression::Number(FieldPrime::from(3)) - ); - } } } } From 3778f22004c048c21b20bfd1df34e75aaf0cbd8e Mon Sep 17 00:00:00 2001 From: schaeff Date: Tue, 27 Nov 2018 13:54:57 +0100 Subject: [PATCH 10/15] implement div rather than inverse --- zokrates_core/src/flatten/mod.rs | 34 +++++++++++++------------------ zokrates_core/src/helpers/rust.rs | 8 ++++---- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/zokrates_core/src/flatten/mod.rs b/zokrates_core/src/flatten/mod.rs index 4471ce1e..e6a15603 100644 --- a/zokrates_core/src/flatten/mod.rs +++ b/zokrates_core/src/flatten/mod.rs @@ -705,20 +705,20 @@ impl Flattener { let inverse = self.use_sym(); - // # c = 1/b + // # c = a/b statements_flattened.push(FlatStatement::Directive(DirectiveStatement::new( vec![inverse], - Helper::Rust(RustHelper::Inverse), - vec![new_right.clone()], + Helper::Rust(RustHelper::Div), + vec![new_left.clone(), new_right.clone()], ))); - // assert(c * b == 1) + // assert(c * b == a) statements_flattened.push(FlatStatement::Condition( - FlatExpression::Number(T::from(1)), + new_left.into(), FlatExpression::Mult(box new_right, box inverse.into()), )); - FlatExpression::Mult(box new_left, box inverse.into()) + inverse.into() } FieldElementExpression::Pow(box base, box exponent) => { match exponent { @@ -2016,34 +2016,28 @@ mod tests { // execute div FlatStatement::Directive(DirectiveStatement::new( vec![sym_0], - Helper::Rust(RustHelper::Inverse), - vec![b0] + Helper::Rust(RustHelper::Div), + vec![five, b0] )), FlatStatement::Condition( - FlatExpression::Number(FieldPrime::from(1)), + five.into(), FlatExpression::Mult(box b0.into(), box sym_0.into()), ), // inputs to second div (res/b) - FlatStatement::Definition( - sym_1, - FlatExpression::Mult(box five.into(), box sym_0.into()) - ), + FlatStatement::Definition(sym_1, sym_0.into()), FlatStatement::Definition(b1, b.into()), // execute div FlatStatement::Directive(DirectiveStatement::new( vec![sym_2], - Helper::Rust(RustHelper::Inverse), - vec![b1] + Helper::Rust(RustHelper::Div), + vec![sym_1, b1] )), FlatStatement::Condition( - FlatExpression::Number(FieldPrime::from(1)), + sym_1.into(), FlatExpression::Mult(box b1.into(), box sym_2.into()), ), // result - FlatStatement::Definition( - a, - FlatExpression::Mult(box sym_1.into(), box sym_2.into()) - ), + FlatStatement::Definition(a, sym_2.into()), ] ); } diff --git a/zokrates_core/src/helpers/rust.rs b/zokrates_core/src/helpers/rust.rs index 5e4553d6..016e94b5 100644 --- a/zokrates_core/src/helpers/rust.rs +++ b/zokrates_core/src/helpers/rust.rs @@ -7,7 +7,7 @@ pub enum RustHelper { Identity, ConditionEq, Bits, - Inverse, + Div, } impl fmt::Display for RustHelper { @@ -16,7 +16,7 @@ impl fmt::Display for RustHelper { RustHelper::Identity => write!(f, "Identity"), RustHelper::ConditionEq => write!(f, "ConditionEq"), RustHelper::Bits => write!(f, "Bits"), - RustHelper::Inverse => write!(f, "Inverse"), + RustHelper::Div => write!(f, "Div"), } } } @@ -27,7 +27,7 @@ impl Signed for RustHelper { RustHelper::Identity => (1, 1), RustHelper::ConditionEq => (1, 2), RustHelper::Bits => (1, 254), - RustHelper::Inverse => (1, 1), + RustHelper::Div => (2, 1), } } } @@ -55,7 +55,7 @@ impl Executable for RustHelper { assert_eq!(num, T::zero()); Ok(res) } - RustHelper::Inverse => Ok(vec![T::one() / inputs[0].clone()]), + RustHelper::Div => Ok(vec![inputs[0].clone() / inputs[1].clone()]), } } } From 648a78601ab9ef25cd1d08b5dcf4070ce6900ba8 Mon Sep 17 00:00:00 2001 From: schaeff Date: Fri, 30 Nov 2018 17:10:30 +0100 Subject: [PATCH 11/15] bump patch --- Cargo.lock | 10 +++++----- zokrates_cli/Cargo.toml | 2 +- zokrates_cli/examples/jubjub/add.code | 2 ++ zokrates_cli/src/bin.rs | 2 +- zokrates_core/Cargo.toml | 2 +- zokrates_fs_resolver/Cargo.toml | 2 +- 6 files changed, 11 insertions(+), 9 deletions(-) create mode 100644 zokrates_cli/examples/jubjub/add.code diff --git a/Cargo.lock b/Cargo.lock index 93001cb3..8a6103c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -623,7 +623,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "zokrates_cli" -version = "0.3.1" +version = "0.3.2" dependencies = [ "assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -631,13 +631,13 @@ dependencies = [ "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.33 (registry+https://github.com/rust-lang/crates.io-index)", - "zokrates_core 0.3.1", - "zokrates_fs_resolver 0.3.1", + "zokrates_core 0.3.2", + "zokrates_fs_resolver 0.3.2", ] [[package]] name = "zokrates_core" -version = "0.3.1" +version = "0.3.2" dependencies = [ "assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "bimap 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -658,7 +658,7 @@ dependencies = [ [[package]] name = "zokrates_fs_resolver" -version = "0.3.1" +version = "0.3.2" [metadata] "checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e" diff --git a/zokrates_cli/Cargo.toml b/zokrates_cli/Cargo.toml index 8fc4e2ce..e996099e 100644 --- a/zokrates_cli/Cargo.toml +++ b/zokrates_cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zokrates_cli" -version = "0.3.1" +version = "0.3.2" authors = ["Jacob Eberhardt ", "Dennis Kuhnert ", "Thibaut Schaeffer "] repository = "https://github.com/JacobEberhardt/ZoKrates.git" diff --git a/zokrates_cli/examples/jubjub/add.code b/zokrates_cli/examples/jubjub/add.code new file mode 100644 index 00000000..cf0d39ac --- /dev/null +++ b/zokrates_cli/examples/jubjub/add.code @@ -0,0 +1,2 @@ +def main(field x) -> (field): + return 1/x \ No newline at end of file diff --git a/zokrates_cli/src/bin.rs b/zokrates_cli/src/bin.rs index b2825994..6836db5b 100644 --- a/zokrates_cli/src/bin.rs +++ b/zokrates_cli/src/bin.rs @@ -39,7 +39,7 @@ fn main() { // cli specification using clap library let matches = App::new("ZoKrates") .setting(AppSettings::SubcommandRequiredElseHelp) - .version("0.3.1") + .version("0.3.2") .author("Jacob Eberhardt, Thibaut Schaeffer, Dennis Kuhnert") .about("Supports generation of zkSNARKs from high level language code including Smart Contracts for proof verification on the Ethereum Blockchain.\n'I know that I show nothing!'") .subcommand(SubCommand::with_name("compile") diff --git a/zokrates_core/Cargo.toml b/zokrates_core/Cargo.toml index 6ba8d14d..5c8a9899 100644 --- a/zokrates_core/Cargo.toml +++ b/zokrates_core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zokrates_core" -version = "0.3.1" +version = "0.3.2" authors = ["Jacob Eberhardt ", "Dennis Kuhnert "] repository = "https://github.com/JacobEberhardt/ZoKrates" readme = "README.md" diff --git a/zokrates_fs_resolver/Cargo.toml b/zokrates_fs_resolver/Cargo.toml index 51179550..1a654ebe 100644 --- a/zokrates_fs_resolver/Cargo.toml +++ b/zokrates_fs_resolver/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zokrates_fs_resolver" -version = "0.3.1" +version = "0.3.2" authors = ["Thibaut Schaeffer "] repository = "https://github.com/JacobEberhardt/ZoKrates.git" From 1e33f8b5640a7f2c31dcc5df7ba9fda02c673838 Mon Sep 17 00:00:00 2001 From: schaeff Date: Fri, 30 Nov 2018 17:21:05 +0100 Subject: [PATCH 12/15] remove example --- zokrates_cli/examples/jubjub/add.code | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 zokrates_cli/examples/jubjub/add.code diff --git a/zokrates_cli/examples/jubjub/add.code b/zokrates_cli/examples/jubjub/add.code deleted file mode 100644 index cf0d39ac..00000000 --- a/zokrates_cli/examples/jubjub/add.code +++ /dev/null @@ -1,2 +0,0 @@ -def main(field x) -> (field): - return 1/x \ No newline at end of file From 64e3c5268ba1a3c27bb76bb4e689f131306b7dcd Mon Sep 17 00:00:00 2001 From: schaeff Date: Mon, 3 Dec 2018 11:59:36 +0100 Subject: [PATCH 13/15] add non-zero check for division --- zokrates_core/src/flatten/mod.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/zokrates_core/src/flatten/mod.rs b/zokrates_core/src/flatten/mod.rs index e6a15603..7517c327 100644 --- a/zokrates_core/src/flatten/mod.rs +++ b/zokrates_core/src/flatten/mod.rs @@ -703,8 +703,23 @@ impl Flattener { id.into() }; + let invb = self.use_sym(); let inverse = self.use_sym(); + + // # invb = 1/b + statements_flattened.push(FlatStatement::Directive(DirectiveStatement::new( + vec![invb], + Helper::Rust(RustHelper::Div), + vec![FlatExpression::Number(T::one()), new_right.clone()], + ))); + + // assert(invb * b == 1) + statements_flattened.push(FlatStatement::Condition( + FlatExpression::Number(T::one()), + FlatExpression::Mult(box invb.into(), box new_right.clone().into()), + )); + // # c = a/b statements_flattened.push(FlatStatement::Directive(DirectiveStatement::new( vec![inverse], From 76602166726194b2cf879deb99f0ba72026652b0 Mon Sep 17 00:00:00 2001 From: schaeff Date: Mon, 3 Dec 2018 12:01:28 +0100 Subject: [PATCH 14/15] fmt --- zokrates_core/src/flatten/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/zokrates_core/src/flatten/mod.rs b/zokrates_core/src/flatten/mod.rs index 7517c327..9d4a7cf5 100644 --- a/zokrates_core/src/flatten/mod.rs +++ b/zokrates_core/src/flatten/mod.rs @@ -706,7 +706,6 @@ impl Flattener { let invb = self.use_sym(); let inverse = self.use_sym(); - // # invb = 1/b statements_flattened.push(FlatStatement::Directive(DirectiveStatement::new( vec![invb], From 024d81bf995cb62be76a24e3e7423f44665994bc Mon Sep 17 00:00:00 2001 From: schaeff Date: Mon, 3 Dec 2018 12:17:09 +0100 Subject: [PATCH 15/15] adjust div test --- zokrates_core/src/flatten/mod.rs | 34 +++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/zokrates_core/src/flatten/mod.rs b/zokrates_core/src/flatten/mod.rs index 9d4a7cf5..b542f516 100644 --- a/zokrates_core/src/flatten/mod.rs +++ b/zokrates_core/src/flatten/mod.rs @@ -2009,16 +2009,20 @@ mod tests { // define new wires for members of Div let five = FlatVariable::new(1); let b0 = FlatVariable::new(2); + // Define inverse of denominator to prevent div by 0 + let invb0 = FlatVariable::new(3); // Define inverse - let sym_0 = FlatVariable::new(3); + let sym_0 = FlatVariable::new(4); // Define result, which is first member to next Div - let sym_1 = FlatVariable::new(4); + let sym_1 = FlatVariable::new(5); // Define second member - let b1 = FlatVariable::new(5); + let b1 = FlatVariable::new(6); + // Define inverse of denominator to prevent div by 0 + let invb1 = FlatVariable::new(7); // Define inverse - let sym_2 = FlatVariable::new(6); + let sym_2 = FlatVariable::new(8); // Define left hand side - let a = FlatVariable::new(7); + let a = FlatVariable::new(9); assert_eq!( statements_flattened, @@ -2027,6 +2031,16 @@ mod tests { // inputs to first div (5/b) FlatStatement::Definition(five, FlatExpression::Number(FieldPrime::from(5))), FlatStatement::Definition(b0, b.into()), + // check div by 0 + FlatStatement::Directive(DirectiveStatement::new( + vec![invb0], + Helper::Rust(RustHelper::Div), + vec![FlatExpression::Number(FieldPrime::from(1)), b0.into()] + )), + FlatStatement::Condition( + FlatExpression::Number(FieldPrime::from(1)), + FlatExpression::Mult(box invb0.into(), box b0.into()), + ), // execute div FlatStatement::Directive(DirectiveStatement::new( vec![sym_0], @@ -2040,6 +2054,16 @@ mod tests { // inputs to second div (res/b) FlatStatement::Definition(sym_1, sym_0.into()), FlatStatement::Definition(b1, b.into()), + // check div by 0 + FlatStatement::Directive(DirectiveStatement::new( + vec![invb1], + Helper::Rust(RustHelper::Div), + vec![FlatExpression::Number(FieldPrime::from(1)), b1.into()] + )), + FlatStatement::Condition( + FlatExpression::Number(FieldPrime::from(1)), + FlatExpression::Mult(box invb1.into(), box b1.into()), + ), // execute div FlatStatement::Directive(DirectiveStatement::new( vec![sym_2],