diff --git a/zokrates_core/src/flatten/mod.rs b/zokrates_core/src/flatten/mod.rs index af43d473..2f607ef7 100644 --- a/zokrates_core/src/flatten/mod.rs +++ b/zokrates_core/src/flatten/mod.rs @@ -628,7 +628,13 @@ impl<'ast, T: Field> Flattener<'ast, T> { let c = c - T::one(); let c_bit_width = c.bits() as usize; - let e_bits_be = self.get_bits(&e, c_bit_width, c_bit_width, statements_flattened); + let e_bits_be = self.get_bits( + &e, + c_bit_width, + c_bit_width, + statements_flattened, + error.clone(), + ); let c_bits_be = c.to_bits_be(); self.enforce_constant_le_check( @@ -659,7 +665,13 @@ impl<'ast, T: Field> Flattener<'ast, T> { let e_id = FlatExpression::Identifier(e_var); let bitwidth = T::get_required_bits(); - let e_bits_be = self.get_bits(&e_id, bitwidth, bitwidth, statements_flattened); + let e_bits_be = self.get_bits( + &e_id, + bitwidth, + bitwidth, + statements_flattened, + RuntimeError::ConstantLtSum, + ); // check that this decomposition does not overflow the field self.enforce_constant_le_check( @@ -1334,6 +1346,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { target_bitwidth, target_bitwidth, statements_flattened, + RuntimeError::Sum, ); // r in range @@ -1342,6 +1355,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { target_bitwidth, target_bitwidth, statements_flattened, + RuntimeError::Sum, ); // r < d <=> r - d + 2**w < 2**w @@ -1353,6 +1367,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { target_bitwidth, target_bitwidth, statements_flattened, + RuntimeError::Sum, ); // q*d == n - r @@ -1826,6 +1841,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { actual_bitwidth, target_bitwidth.to_usize(), statements_flattened, + RuntimeError::Sum, ), }; @@ -1862,6 +1878,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { from: usize, to: usize, statements_flattened: &mut FlatStatements, + error: RuntimeError, ) -> Vec> { assert!(from <= T::get_required_bits()); assert!(to <= T::get_required_bits()); @@ -1915,7 +1932,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { statements_flattened.push_back(FlatStatement::Condition( e.clone(), sum.clone(), - RuntimeError::Sum, + error, )); // truncate to the `to` lowest bits @@ -2355,8 +2372,13 @@ impl<'ast, T: Field> Flattener<'ast, T> { match (lhs, rhs) { (e, FlatExpression::Number(constant)) => { let bitwidth = constant.bits() as usize; - let e_bits_be = - self.get_bits(&e, bitwidth, bitwidth, statements_flattened); + let e_bits_be = self.get_bits( + &e, + bitwidth, + bitwidth, + statements_flattened, + error.clone().into(), + ); self.enforce_constant_le_check( statements_flattened, @@ -2370,8 +2392,13 @@ impl<'ast, T: Field> Flattener<'ast, T> { let constant = T::max_value() - constant; let bitwidth = constant.bits() as usize; - let e_bits_be = - self.get_bits(&e, bitwidth, bitwidth, statements_flattened); + let e_bits_be = self.get_bits( + &e, + bitwidth, + bitwidth, + statements_flattened, + error.clone().into(), + ); self.enforce_constant_le_check( statements_flattened, @@ -2615,6 +2642,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { bitwidth.to_usize(), bitwidth.to_usize(), statements_flattened, + RuntimeError::Sum, ); } Type::Boolean => { diff --git a/zokrates_core_test/tests/tests/range_check/assert_ge.json b/zokrates_core_test/tests/tests/range_check/assert_ge.json new file mode 100644 index 00000000..0569b4b3 --- /dev/null +++ b/zokrates_core_test/tests/tests/range_check/assert_ge.json @@ -0,0 +1,55 @@ +{ + "entry_point": "./tests/tests/range_check/assert_ge.zok", + "max_constraint_count": 509, + "curves": ["Bn128"], + "tests": [ + { + "input": { + "values": ["0"] + }, + "output": { + "Err": { + "UnsatisfiedConstraint": { + "error": { + "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_ge.zok:2:5" + } + } + } + } + }, + { + "input": { + "values": ["1"] + }, + "output": { + "Err": { + "UnsatisfiedConstraint": { + "error": { + "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_ge.zok:2:5" + } + } + } + } + }, + { + "input": { + "values": ["2"] + }, + "output": { + "Ok": { + "values": [] + } + } + }, + { + "input": { + "values": ["15"] + }, + "output": { + "Ok": { + "values": [] + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/range_check/assert_ge.zok b/zokrates_core_test/tests/tests/range_check/assert_ge.zok new file mode 100644 index 00000000..aa011152 --- /dev/null +++ b/zokrates_core_test/tests/tests/range_check/assert_ge.zok @@ -0,0 +1,3 @@ +def main(field x): + assert(x >= 2) + return \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/range_check/assert_gt.json b/zokrates_core_test/tests/tests/range_check/assert_gt.json new file mode 100644 index 00000000..631eca10 --- /dev/null +++ b/zokrates_core_test/tests/tests/range_check/assert_gt.json @@ -0,0 +1,59 @@ +{ + "entry_point": "./tests/tests/range_check/assert_gt.zok", + "max_constraint_count": 508, + "curves": ["Bn128"], + "tests": [ + { + "input": { + "values": ["0"] + }, + "output": { + "Err": { + "UnsatisfiedConstraint": { + "error": { + "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_gt.zok:2:5" + } + } + } + } + }, + { + "input": { + "values": ["1"] + }, + "output": { + "Err": { + "UnsatisfiedConstraint": { + "error": { + "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_gt.zok:2:5" + } + } + } + } + }, + { + "input": { + "values": ["2"] + }, + "output": { + "Err": { + "UnsatisfiedConstraint": { + "error": { + "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_gt.zok:2:5" + } + } + } + } + }, + { + "input": { + "values": ["15"] + }, + "output": { + "Ok": { + "values": [] + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/range_check/assert_gt.zok b/zokrates_core_test/tests/tests/range_check/assert_gt.zok new file mode 100644 index 00000000..8286e022 --- /dev/null +++ b/zokrates_core_test/tests/tests/range_check/assert_gt.zok @@ -0,0 +1,3 @@ +def main(field x): + assert(x > 2) + return \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/range_check/assert_gt_big_constant.json b/zokrates_core_test/tests/tests/range_check/assert_gt_big_constant.json new file mode 100644 index 00000000..bcb6c603 --- /dev/null +++ b/zokrates_core_test/tests/tests/range_check/assert_gt_big_constant.json @@ -0,0 +1,45 @@ +{ + "entry_point": "./tests/tests/range_check/assert_gt_big_constant.zok", + "max_constraint_count": 3, + "curves": ["Bn128"], + "tests": [ + { + "input": { + "values": ["0"] + }, + "output": { + "Err": { + "UnsatisfiedConstraint": { + "error": { + "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_gt_big_constant.zok:4:5" + } + } + } + } + }, + { + "input": { + "values": ["21888242871839275222246405745257275088548364400416034343698204186575808495615"] + }, + "output": { + "Err": { + "UnsatisfiedConstraint": { + "error": { + "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_gt_big_constant.zok:4:5" + } + } + } + } + }, + { + "input": { + "values": ["21888242871839275222246405745257275088548364400416034343698204186575808495616"] + }, + "output": { + "Ok": { + "values": [] + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/range_check/assert_gt_big_constant.zok b/zokrates_core_test/tests/tests/range_check/assert_gt_big_constant.zok new file mode 100644 index 00000000..f6732e43 --- /dev/null +++ b/zokrates_core_test/tests/tests/range_check/assert_gt_big_constant.zok @@ -0,0 +1,5 @@ +from "field" import FIELD_MAX + +def main(field x): + assert(x > FIELD_MAX - 1) + return \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/range_check/assert_le.json b/zokrates_core_test/tests/tests/range_check/assert_le.json new file mode 100644 index 00000000..76ebbdeb --- /dev/null +++ b/zokrates_core_test/tests/tests/range_check/assert_le.json @@ -0,0 +1,55 @@ +{ + "entry_point": "./tests/tests/range_check/assert_le.zok", + "max_constraint_count": 5, + "curves": ["Bn128"], + "tests": [ + { + "input": { + "values": ["1"] + }, + "output": { + "Ok": { + "values": [] + } + } + }, + { + "input": { + "values": ["2"] + }, + "output": { + "Ok": { + "values": [] + } + } + }, + { + "input": { + "values": ["3"] + }, + "output": { + "Err": { + "UnsatisfiedConstraint": { + "error": { + "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_le.zok:2:5" + } + } + } + } + }, + { + "input": { + "values": ["15"] + }, + "output": { + "Err": { + "UnsatisfiedConstraint": { + "error": { + "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_le.zok:2:5" + } + } + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/range_check/assert_le.zok b/zokrates_core_test/tests/tests/range_check/assert_le.zok new file mode 100644 index 00000000..9033600e --- /dev/null +++ b/zokrates_core_test/tests/tests/range_check/assert_le.zok @@ -0,0 +1,3 @@ +def main(field x): + assert(x <= 2) + return \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/range_check/assert_lt.json b/zokrates_core_test/tests/tests/range_check/assert_lt.json new file mode 100644 index 00000000..9bbf8aa7 --- /dev/null +++ b/zokrates_core_test/tests/tests/range_check/assert_lt.json @@ -0,0 +1,55 @@ +{ + "entry_point": "./tests/tests/range_check/assert_lt.zok", + "max_constraint_count": 4, + "curves": ["Bn128"], + "tests": [ + { + "input": { + "values": ["0"] + }, + "output": { + "Ok": { + "values": [] + } + } + }, + { + "input": { + "values": ["1"] + }, + "output": { + "Ok": { + "values": [] + } + } + }, + { + "input": { + "values": ["2"] + }, + "output": { + "Err": { + "UnsatisfiedConstraint": { + "error": { + "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_lt.zok:2:5" + } + } + } + } + }, + { + "input": { + "values": ["15"] + }, + "output": { + "Err": { + "UnsatisfiedConstraint": { + "error": { + "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_lt.zok:2:5" + } + } + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/range_check/assert_lt.zok b/zokrates_core_test/tests/tests/range_check/assert_lt.zok new file mode 100644 index 00000000..44b4d4ce --- /dev/null +++ b/zokrates_core_test/tests/tests/range_check/assert_lt.zok @@ -0,0 +1,3 @@ +def main(field x): + assert(x < 2) + return \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/range_check/assert_lt_big_constant.json b/zokrates_core_test/tests/tests/range_check/assert_lt_big_constant.json new file mode 100644 index 00000000..1a62c5a8 --- /dev/null +++ b/zokrates_core_test/tests/tests/range_check/assert_lt_big_constant.json @@ -0,0 +1,41 @@ +{ + "entry_point": "./tests/tests/range_check/assert_lt_big_constant.zok", + "max_constraint_count": 509, + "curves": ["Bn128"], + "tests": [ + { + "input": { + "values": ["0"] + }, + "output": { + "Ok": { + "values": [] + } + } + }, + { + "input": { + "values": ["21888242871839275222246405745257275088548364400416034343698204186575808495614"] + }, + "output": { + "Ok": { + "values": [] + } + } + }, + { + "input": { + "values": ["21888242871839275222246405745257275088548364400416034343698204186575808495615"] + }, + "output": { + "Err": { + "UnsatisfiedConstraint": { + "error": { + "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_lt_big_constant.zok:4:5" + } + } + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/range_check/assert_lt_big_constant.zok b/zokrates_core_test/tests/tests/range_check/assert_lt_big_constant.zok new file mode 100644 index 00000000..ba9fcb15 --- /dev/null +++ b/zokrates_core_test/tests/tests/range_check/assert_lt_big_constant.zok @@ -0,0 +1,5 @@ +from "field" import FIELD_MAX + +def main(field x): + assert(x < FIELD_MAX - 1) + return \ No newline at end of file