diff --git a/changelogs/unreleased/997-dark64 b/changelogs/unreleased/997-dark64 new file mode 100644 index 00000000..95d5971b --- /dev/null +++ b/changelogs/unreleased/997-dark64 @@ -0,0 +1 @@ +Make field to uint casts truncate values bigger than uint max \ No newline at end of file diff --git a/rust-toolchain b/rust-toolchain index 1cfd57a1..07734de2 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2021-04-25 \ No newline at end of file +nightly-2021-09-01 \ No newline at end of file diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 41d688e5..146e37bd 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "nightly-2021-04-25" \ No newline at end of file +channel = "nightly-2021-09-01" \ No newline at end of file diff --git a/zokrates_cli/examples/compile_errors/unpack_value_too_large.zok b/zokrates_cli/examples/compile_errors/unpack_value_too_large.zok new file mode 100644 index 00000000..c592d4a0 --- /dev/null +++ b/zokrates_cli/examples/compile_errors/unpack_value_too_large.zok @@ -0,0 +1,5 @@ +from "EMBED" import unpack + +def main(): + bool[2] bits = unpack(4) // we need 3 bits to unpack 4 + return \ No newline at end of file diff --git a/zokrates_cli/src/bin.rs b/zokrates_cli/src/bin.rs index c3bb2e05..5f40f344 100644 --- a/zokrates_cli/src/bin.rs +++ b/zokrates_cli/src/bin.rs @@ -195,7 +195,7 @@ mod tests { let interpreter = ir::Interpreter::default(); let _ = interpreter - .execute(&artifacts.prog(), &[Bn128Field::from(0)]) + .execute(artifacts.prog(), &[Bn128Field::from(0)]) .unwrap(); } } @@ -226,7 +226,7 @@ mod tests { let interpreter = ir::Interpreter::default(); - let res = interpreter.execute(&artifacts.prog(), &[Bn128Field::from(0)]); + let res = interpreter.execute(artifacts.prog(), &[Bn128Field::from(0)]); assert!(res.is_err()); } diff --git a/zokrates_cli/src/ops/export_verifier.rs b/zokrates_cli/src/ops/export_verifier.rs index 225c8dc6..8da06a76 100644 --- a/zokrates_cli/src/ops/export_verifier.rs +++ b/zokrates_cli/src/ops/export_verifier.rs @@ -99,7 +99,7 @@ fn cli_export_verifier From> for absy::ExpressionNode<'ast> { // pest::PostFixExpression contains an array of "accesses": `a(34)[42]` is represented as `[a, [Call(34), Select(42)]]`, but absy::ExpressionNode // is recursive, so it is `Select(Call(a, 34), 42)`. We apply this transformation here - // we start with the base, and we fold the array of accesses by wrapping the current value expression .accesses @@ -652,7 +651,7 @@ impl<'ast> From> for absy::ExpressionNode<' match expression.suffix { Some(suffix) => match suffix { pest::DecimalSuffix::Field(_) => absy::Expression::FieldConstant( - BigUint::parse_bytes(&expression.value.span.as_str().as_bytes(), 10).unwrap(), + BigUint::parse_bytes(expression.value.span.as_str().as_bytes(), 10).unwrap(), ), pest::DecimalSuffix::U64(_) => { absy::Expression::U64Constant(expression.value.span.as_str().parse().unwrap()) @@ -669,7 +668,7 @@ impl<'ast> From> for absy::ExpressionNode<' } .span(expression.span), None => absy::Expression::IntConstant( - BigUint::parse_bytes(&expression.value.span.as_str().as_bytes(), 10).unwrap(), + BigUint::parse_bytes(expression.value.span.as_str().as_bytes(), 10).unwrap(), ) .span(expression.span), } @@ -682,16 +681,16 @@ impl<'ast> From> for absy::ExpressionNode<'ast> match expression.value { pest::HexNumberExpression::U64(e) => { - absy::Expression::U64Constant(u64::from_str_radix(&e.span.as_str(), 16).unwrap()) + absy::Expression::U64Constant(u64::from_str_radix(e.span.as_str(), 16).unwrap()) } pest::HexNumberExpression::U32(e) => { - absy::Expression::U32Constant(u32::from_str_radix(&e.span.as_str(), 16).unwrap()) + absy::Expression::U32Constant(u32::from_str_radix(e.span.as_str(), 16).unwrap()) } pest::HexNumberExpression::U16(e) => { - absy::Expression::U16Constant(u16::from_str_radix(&e.span.as_str(), 16).unwrap()) + absy::Expression::U16Constant(u16::from_str_radix(e.span.as_str(), 16).unwrap()) } pest::HexNumberExpression::U8(e) => { - absy::Expression::U8Constant(u8::from_str_radix(&e.span.as_str(), 16).unwrap()) + absy::Expression::U8Constant(u8::from_str_radix(e.span.as_str(), 16).unwrap()) } } .span(expression.span) @@ -838,7 +837,7 @@ mod tests { #[test] fn return_forty_two() { let source = "def main() -> field: return 42"; - let ast = pest::generate_ast(&source).unwrap(); + let ast = pest::generate_ast(source).unwrap(); let expected: absy::Module = absy::Module { symbols: vec![absy::SymbolDeclaration { id: &source[4..8], @@ -869,7 +868,7 @@ mod tests { #[test] fn return_true() { let source = "def main() -> bool: return true"; - let ast = pest::generate_ast(&source).unwrap(); + let ast = pest::generate_ast(source).unwrap(); let expected: absy::Module = absy::Module { symbols: vec![absy::SymbolDeclaration { id: &source[4..8], @@ -898,7 +897,7 @@ mod tests { #[test] fn arguments() { let source = "def main(private field a, bool b) -> field: return 42"; - let ast = pest::generate_ast(&source).unwrap(); + let ast = pest::generate_ast(source).unwrap(); let expected: absy::Module = absy::Module { symbols: vec![absy::SymbolDeclaration { @@ -1126,7 +1125,7 @@ mod tests { fn call_array_element() { // a call after an array access should be accepted let source = "def main(): return a[2](3)"; - let ast = pest::generate_ast(&source).unwrap(); + let ast = pest::generate_ast(source).unwrap(); assert_eq!( absy::Module::from(ast), wrap(absy::Expression::FunctionCall( @@ -1147,7 +1146,8 @@ mod tests { fn call_call_result() { // a call after a call should be accepted let source = "def main(): return a(2)(3)"; - let ast = pest::generate_ast(&source).unwrap(); + + let ast = pest::generate_ast(source).unwrap(); assert_eq!( absy::Module::from(ast), wrap(absy::Expression::FunctionCall( @@ -1167,7 +1167,7 @@ mod tests { fn declarations() { use self::pest::Span; - let span = Span::new(&"", 0, 0).unwrap(); + let span = Span::new("", 0, 0).unwrap(); // For different definitions, we generate declarations // Case 1: `id = expr` where `expr` is not a function call @@ -1186,7 +1186,7 @@ mod tests { expression: pest::Expression::Literal(pest::LiteralExpression::DecimalLiteral( pest::DecimalLiteralExpression { value: pest::DecimalNumber { - span: Span::new(&"1", 0, 1).unwrap(), + span: Span::new("1", 0, 1).unwrap(), }, suffix: None, span: span.clone(), diff --git a/zokrates_core/src/compile.rs b/zokrates_core/src/compile.rs index 5b9d378f..86a9943e 100644 --- a/zokrates_core/src/compile.rs +++ b/zokrates_core/src/compile.rs @@ -243,7 +243,7 @@ fn check_with_arena<'ast, T: Field, E: Into>( log::debug!("Parse program with entry file {}", location.display()); - let compiled = parse_program::(source, location, resolver, &arena)?; + let compiled = parse_program::(source, location, resolver, arena)?; log::debug!("Check semantics"); @@ -271,7 +271,7 @@ pub fn parse_program<'ast, T: Field, E: Into>( ) -> Result, CompileErrors> { let mut modules = HashMap::new(); - let main = parse_module::(&source, location.clone(), resolver, &mut modules, &arena)?; + let main = parse_module::(source, location.clone(), resolver, &mut modules, arena)?; modules.insert(location.clone(), main); @@ -290,7 +290,7 @@ pub fn parse_module<'ast, T: Field, E: Into>( ) -> Result, CompileErrors> { log::debug!("Generate pest AST for {}", location.display()); - let ast = pest::generate_ast(&source) + let ast = pest::generate_ast(source) .map_err(|e| CompileErrors::from(CompileErrorInner::from(e).in_file(&location)))?; log::debug!("Process macros for {}", location.display()); @@ -309,7 +309,7 @@ pub fn parse_module<'ast, T: Field, E: Into>( location.clone(), resolver, modules, - &arena, + arena, ) } diff --git a/zokrates_core/src/flatten/mod.rs b/zokrates_core/src/flatten/mod.rs index 79d3948f..156c0851 100644 --- a/zokrates_core/src/flatten/mod.rs +++ b/zokrates_core/src/flatten/mod.rs @@ -2202,7 +2202,10 @@ impl<'ast, T: Field> Flattener<'ast, T> { // convert the exponent to bytes, big endian let ebytes_be = e.to_be_bytes(); + // convert the bytes to bits, remove leading zeroes (we only need powers up to the highest non-zero bit) + #[allow(clippy::needless_collect)] + // collecting is required as we then reverse let ebits_be: Vec<_> = ebytes_be .iter() .flat_map(|byte| (0..8).rev().map(move |i| byte & (1 << i) != 0)) // byte to bit, big endian diff --git a/zokrates_core/src/imports.rs b/zokrates_core/src/imports.rs index bd01796e..00814b74 100644 --- a/zokrates_core/src/imports.rs +++ b/zokrates_core/src/imports.rs @@ -231,7 +231,7 @@ impl Importer { new_location.clone(), resolver, modules, - &arena, + arena, )?; assert!(modules.insert(new_location.clone(), compiled).is_none()); @@ -239,7 +239,7 @@ impl Importer { }; SymbolDeclaration { - id: &alias, + id: alias, symbol: Symbol::There( SymbolImport::with_id_in_module(symbol.id, new_location) .start_end(pos.0, pos.1), diff --git a/zokrates_core/src/ir/interpreter.rs b/zokrates_core/src/ir/interpreter.rs index 8b071998..3e674f00 100644 --- a/zokrates_core/src/ir/interpreter.rs +++ b/zokrates_core/src/ir/interpreter.rs @@ -10,20 +10,13 @@ pub type ExecutionResult = Result, Error>; impl Prog {} +#[derive(Default)] pub struct Interpreter { /// Whether we should try to give out-of-range bit decompositions when the input is not a single summand. /// Used to do targetted testing of `<` flattening, making sure the bit decomposition we base the result on is unique. should_try_out_of_range: bool, } -impl Default for Interpreter { - fn default() -> Interpreter { - Interpreter { - should_try_out_of_range: false, - } - } -} - impl Interpreter { pub fn try_out_of_range() -> Interpreter { Interpreter { @@ -34,7 +27,7 @@ impl Interpreter { impl Interpreter { pub fn execute(&self, program: &Prog, inputs: &[T]) -> ExecutionResult { - self.check_inputs(&program, &inputs)?; + self.check_inputs(program, inputs)?; let mut witness = BTreeMap::new(); witness.insert(FlatVariable::one(), T::one()); @@ -274,8 +267,8 @@ impl LinComb { impl QuadComb { pub fn evaluate(&self, witness: &BTreeMap) -> Result { - let left = self.left.evaluate(&witness)?; - let right = self.right.evaluate(&witness)?; + let left = self.left.evaluate(witness)?; + let right = self.right.evaluate(witness)?; Ok(left * right) } } diff --git a/zokrates_core/src/optimizer/redefinition.rs b/zokrates_core/src/optimizer/redefinition.rs index 28bab99e..1080b5a5 100644 --- a/zokrates_core/src/optimizer/redefinition.rs +++ b/zokrates_core/src/optimizer/redefinition.rs @@ -191,7 +191,7 @@ impl Folder for RedefinitionOptimizer { match lc .0 .iter() - .any(|(variable, _)| self.substitution.get(&variable).is_some()) + .any(|(variable, _)| self.substitution.get(variable).is_some()) { true => // for each summand, check if it is equal to a linear term in our substitution, otherwise keep it as is diff --git a/zokrates_core/src/proof_system/ark/gm17.rs b/zokrates_core/src/proof_system/ark/gm17.rs index 4c54b261..59e77e94 100644 --- a/zokrates_core/src/proof_system/ark/gm17.rs +++ b/zokrates_core/src/proof_system/ark/gm17.rs @@ -126,7 +126,7 @@ impl NonUniversalBackend for Ark { .vk .query .iter() - .map(|g1| parse_g1::(g1)) + .map(parse_g1::) .collect(), }; diff --git a/zokrates_core/src/proof_system/bellman/mod.rs b/zokrates_core/src/proof_system/bellman/mod.rs index 84a63bab..4489fa98 100644 --- a/zokrates_core/src/proof_system/bellman/mod.rs +++ b/zokrates_core/src/proof_system/bellman/mod.rs @@ -228,8 +228,8 @@ mod parse { let raw_e = e.to_string(); let captures = G1_REGEX.captures(&raw_e).unwrap(); G1Affine( - captures.name(&"x").unwrap().as_str().to_string(), - captures.name(&"y").unwrap().as_str().to_string(), + captures.name("x").unwrap().as_str().to_string(), + captures.name("y").unwrap().as_str().to_string(), ) } @@ -240,12 +240,12 @@ mod parse { let captures = G2_REGEX.captures(&raw_e).unwrap(); G2Affine( ( - captures.name(&"x0").unwrap().as_str().to_string(), - captures.name(&"x1").unwrap().as_str().to_string(), + captures.name("x0").unwrap().as_str().to_string(), + captures.name("x1").unwrap().as_str().to_string(), ), ( - captures.name(&"y0").unwrap().as_str().to_string(), - captures.name(&"y1").unwrap().as_str().to_string(), + captures.name("y0").unwrap().as_str().to_string(), + captures.name("y1").unwrap().as_str().to_string(), ), ) } @@ -253,7 +253,7 @@ mod parse { pub fn parse_fr(e: &::Fr) -> Fr { let raw_e = e.to_string(); let captures = FR_REGEX.captures(&raw_e).unwrap(); - captures.name(&"x").unwrap().as_str().to_string() + captures.name("x").unwrap().as_str().to_string() } } diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index 008df9c4..a859b156 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -233,7 +233,7 @@ impl<'ast, T: Field> FunctionQuery<'ast, T> { .inputs .iter() .zip(func.signature.inputs.iter()) - .all(|(input_ty, sig_ty)| input_ty.can_be_specialized_to(&sig_ty)) + .all(|(input_ty, sig_ty)| input_ty.can_be_specialized_to(sig_ty)) && self.outputs.len() == func.signature.outputs.len() && self .outputs @@ -242,7 +242,7 @@ impl<'ast, T: Field> FunctionQuery<'ast, T> { .all(|(output_ty, sig_ty)| { output_ty .as_ref() - .map(|output_ty| output_ty.can_be_specialized_to(&sig_ty)) + .map(|output_ty| output_ty.can_be_specialized_to(sig_ty)) .unwrap_or(true) }) } @@ -378,7 +378,7 @@ impl<'ast, T: Field> Checker<'ast, T> { let ty = self.check_declaration_type( c.value.ty.clone(), module_id, - &state, + state, &BTreeMap::default(), &mut HashSet::default(), )?; @@ -396,11 +396,10 @@ impl<'ast, T: Field> Checker<'ast, T> { UExpression::try_from_typed(checked_expr, &bitwidth).map(TypedExpression::from) } DeclarationType::Array(ref array_ty) => { - ArrayExpression::try_from_typed(checked_expr, &array_ty).map(TypedExpression::from) + ArrayExpression::try_from_typed(checked_expr, array_ty).map(TypedExpression::from) } DeclarationType::Struct(ref struct_ty) => { - StructExpression::try_from_typed(checked_expr, &struct_ty) - .map(TypedExpression::from) + StructExpression::try_from_typed(checked_expr, struct_ty).map(TypedExpression::from) } DeclarationType::Int => Err(checked_expr), // Integers cannot be assigned } @@ -1822,7 +1821,7 @@ impl<'ast, T: Field> Checker<'ast, T> { let arguments_types: Vec<_> = arguments_checked.iter().map(|a| a.get_type()).collect(); - let query = FunctionQuery::new(&fun_id, &generics_checked, &arguments_types, &assignee_types); + let query = FunctionQuery::new(fun_id, &generics_checked, &arguments_types, &assignee_types); let functions = self.find_functions(&query); @@ -1868,7 +1867,7 @@ impl<'ast, T: Field> Checker<'ast, T> { let pos = assignee.pos(); // check that the assignee is declared match assignee.value { - Assignee::Identifier(variable_name) => match self.get_key_value_scope(&variable_name) { + Assignee::Identifier(variable_name) => match self.get_key_value_scope(variable_name) { Some((id, ty)) => match id.is_constant() { true => Err(ErrorInner { pos: Some(assignee.pos()), @@ -2004,7 +2003,7 @@ impl<'ast, T: Field> Checker<'ast, T> { Expression::Identifier(name) => { // check that `id` is defined in the scope match self - .get_key_value_scope(&name) + .get_key_value_scope(name) .map(|(x, y)| (x.clone(), y.clone())) { Some((id, ty)) => match ty { @@ -2384,7 +2383,7 @@ impl<'ast, T: Field> Checker<'ast, T> { // outside of multidef, function calls must have a single return value // we use type inference to determine the type of the return, so we don't specify it let query = - FunctionQuery::new(&fun_id, &generics_checked, &arguments_types, &[None]); + FunctionQuery::new(fun_id, &generics_checked, &arguments_types, &[None]); let functions = self.find_functions(&query); @@ -2397,7 +2396,7 @@ impl<'ast, T: Field> Checker<'ast, T> { let signature = f.signature; - let arguments_checked = arguments_checked.into_iter().zip(signature.inputs.iter()).map(|(a, t)| TypedExpression::align_to_type(a, &t)).collect::, _>>().map_err(|e| ErrorInner { + let arguments_checked = arguments_checked.into_iter().zip(signature.inputs.iter()).map(|(a, t)| TypedExpression::align_to_type(a, t)).collect::, _>>().map_err(|e| ErrorInner { pos: Some(pos), message: format!("Expected function call argument to be of type {}, found {}", e.1, e.0) })?; @@ -3346,7 +3345,7 @@ impl<'ast, T: Field> Checker<'ast, T> { fn exit_scope(&mut self) { let current_level = self.level; self.scope - .retain(|ref scoped_variable, _| scoped_variable.level < current_level); + .retain(|scoped_variable, _| scoped_variable.level < current_level); self.level -= 1; } } @@ -3873,22 +3872,20 @@ mod tests { .get(&*MODULE_ID) .unwrap() .functions_iter() - .find(|d| d.key + .any(|d| d.key == DeclarationFunctionKey::with_location((*MODULE_ID).clone(), "foo") - .signature(DeclarationSignature::new())) - .is_some()); + .signature(DeclarationSignature::new()))); assert!(state .typed_modules .get(&*MODULE_ID) .unwrap() .functions_iter() - .find(|d| d.key + .any(|d| d.key == DeclarationFunctionKey::with_location((*MODULE_ID).clone(), "foo") .signature( DeclarationSignature::new().inputs(vec![DeclarationType::FieldElement]) - )) - .is_some()); + ))); } #[test] diff --git a/zokrates_core/src/static_analysis/propagation.rs b/zokrates_core/src/static_analysis/propagation.rs index 337b2c34..3890c8c2 100644 --- a/zokrates_core/src/static_analysis/propagation.rs +++ b/zokrates_core/src/static_analysis/propagation.rs @@ -22,6 +22,7 @@ pub type Constants<'ast, T> = HashMap, TypedExpression<'ast, T> pub enum Error { Type(String), AssertionFailed(String), + ValueTooLarge(String), OutOfBounds(u128, u128), NonConstantExponent(String), } @@ -31,6 +32,7 @@ impl fmt::Display for Error { match self { Error::Type(s) => write!(f, "{}", s), Error::AssertionFailed(s) => write!(f, "{}", s), + Error::ValueTooLarge(s) => write!(f, "{}", s), Error::OutOfBounds(index, size) => write!( f, "Out of bounds index ({} >= {}) found during static analysis", @@ -79,7 +81,7 @@ impl<'ast, 'a, T: Field> Propagator<'ast, 'a, T> { .map(|c| Ok((var, c))) .unwrap_or(Err(var)), TypedAssignee::Select(box assignee, box index) => { - match self.try_get_constant_mut(&assignee) { + match self.try_get_constant_mut(assignee) { Ok((variable, constant)) => match index.as_inner() { UExpressionInner::Value(n) => match constant { TypedExpression::Array(a) => match a.as_inner_mut() { @@ -101,7 +103,7 @@ impl<'ast, 'a, T: Field> Propagator<'ast, 'a, T> { e => e, } } - TypedAssignee::Member(box assignee, m) => match self.try_get_constant_mut(&assignee) { + TypedAssignee::Member(box assignee, m) => match self.try_get_constant_mut(assignee) { Ok((v, c)) => { let ty = assignee.get_type(); @@ -381,47 +383,47 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { match arguments.iter().all(|a| a.is_constant()) { true => { let r: Option> = match embed { - FlatEmbed::BitArrayLe => None, // todo - FlatEmbed::U64FromBits => Some(process_u_from_bits( + FlatEmbed::BitArrayLe => Ok(None), // todo + FlatEmbed::U64FromBits => Ok(Some(process_u_from_bits( assignees.clone(), arguments.clone(), UBitwidth::B64, - )), - FlatEmbed::U32FromBits => Some(process_u_from_bits( + ))), + FlatEmbed::U32FromBits => Ok(Some(process_u_from_bits( assignees.clone(), arguments.clone(), UBitwidth::B32, - )), - FlatEmbed::U16FromBits => Some(process_u_from_bits( + ))), + FlatEmbed::U16FromBits => Ok(Some(process_u_from_bits( assignees.clone(), arguments.clone(), UBitwidth::B16, - )), - FlatEmbed::U8FromBits => Some(process_u_from_bits( + ))), + FlatEmbed::U8FromBits => Ok(Some(process_u_from_bits( assignees.clone(), arguments.clone(), UBitwidth::B8, - )), - FlatEmbed::U64ToBits => Some(process_u_to_bits( + ))), + FlatEmbed::U64ToBits => Ok(Some(process_u_to_bits( assignees.clone(), arguments.clone(), UBitwidth::B64, - )), - FlatEmbed::U32ToBits => Some(process_u_to_bits( + ))), + FlatEmbed::U32ToBits => Ok(Some(process_u_to_bits( assignees.clone(), arguments.clone(), UBitwidth::B32, - )), - FlatEmbed::U16ToBits => Some(process_u_to_bits( + ))), + FlatEmbed::U16ToBits => Ok(Some(process_u_to_bits( assignees.clone(), arguments.clone(), UBitwidth::B16, - )), - FlatEmbed::U8ToBits => Some(process_u_to_bits( + ))), + FlatEmbed::U8ToBits => Ok(Some(process_u_to_bits( assignees.clone(), arguments.clone(), UBitwidth::B8, - )), + ))), FlatEmbed::Unpack => { assert_eq!(assignees.len(), 1); assert_eq!(arguments.len(), 1); @@ -429,46 +431,55 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { let bit_width = generics[0]; - match FieldElementExpression::try_from(arguments[0].clone()) - .unwrap() + match FieldElementExpression::::try_from( + arguments[0].clone(), + ) + .unwrap() { FieldElementExpression::Number(num) => { - let mut num = num; + let mut acc = num.clone(); let mut res = vec![]; for i in (0..bit_width as usize).rev() { - if T::from(2).pow(i) <= num { - num = num - T::from(2).pow(i); + if T::from(2).pow(i) <= acc { + acc = acc - T::from(2).pow(i); res.push(true); } else { res.push(false); } } - assert_eq!(num, T::zero()); - Some( - ArrayExpressionInner::Value( - res.into_iter() - .map(|v| { - BooleanExpression::Value(v).into() - }) - .collect::>() - .into(), - ) - .annotate(Type::Boolean, bit_width) - .into(), - ) + if acc != T::zero() { + Err(Error::ValueTooLarge(format!( + "Cannot unpack `{}` to `{}`: value is too large", + num, assignees.first().unwrap().get_type() + ))) + } else { + Ok(Some( + ArrayExpressionInner::Value( + res.into_iter() + .map(|v| { + BooleanExpression::Value(v) + .into() + }) + .collect::>() + .into(), + ) + .annotate(Type::Boolean, bit_width) + .into(), + )) + } } _ => unreachable!("should be a field value"), } } #[cfg(feature = "bellman")] - FlatEmbed::Sha256Round => None, + FlatEmbed::Sha256Round => Ok(None), #[cfg(feature = "ark")] - FlatEmbed::SnarkVerifyBls12377 => None, - }; + FlatEmbed::SnarkVerifyBls12377 => Ok(None), + }?; - match r { + Ok(match r { // if the function call returns a constant Some(expr) => { let mut assignees = assignees; @@ -494,9 +505,11 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { assignee, expr, ), ], - None => vec![TypedStatement::Definition( - assignee, expr, - )], + None => { + vec![TypedStatement::Definition( + assignee, expr, + )] + } }, } } @@ -534,7 +547,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { )], } } - } + }) } false => { // if the function arguments are not constant, invalidate the cache @@ -548,7 +561,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { let invalidations = assignees.iter().flat_map(|assignee| { let v = self - .try_get_constant_mut(&assignee) + .try_get_constant_mut(assignee) .map(|(v, _)| v) .unwrap_or_else(|v| v); match self.constants.remove(&v.id) { @@ -559,7 +572,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { } }); - invalidations.chain(std::iter::once(def)).collect() + Ok(invalidations.chain(std::iter::once(def)).collect()) } } } @@ -590,7 +603,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { let invalidations = assignees.iter().flat_map(|assignee| { let v = self - .try_get_constant_mut(&assignee) + .try_get_constant_mut(assignee) .map(|(v, _)| v) .unwrap_or_else(|v| v); match self.constants.remove(&v.id) { @@ -601,9 +614,9 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { } }); - invalidations.chain(std::iter::once(def)).collect() + Ok(invalidations.chain(std::iter::once(def)).collect()) } - }; + }?; Ok(statements) } diff --git a/zokrates_core/src/static_analysis/reducer/inline.rs b/zokrates_core/src/static_analysis/reducer/inline.rs index d7132f81..51efdbdc 100644 --- a/zokrates_core/src/static_analysis/reducer/inline.rs +++ b/zokrates_core/src/static_analysis/reducer/inline.rs @@ -69,7 +69,7 @@ fn get_canonical_function<'ast, T: Field>( .unwrap(); match &s.symbol { - TypedFunctionSymbol::There(key) => get_canonical_function(key.clone(), &program), + TypedFunctionSymbol::There(key) => get_canonical_function(key.clone(), program), _ => s.clone(), } } diff --git a/zokrates_core/src/static_analysis/reducer/mod.rs b/zokrates_core/src/static_analysis/reducer/mod.rs index 401593c3..9c788023 100644 --- a/zokrates_core/src/static_analysis/reducer/mod.rs +++ b/zokrates_core/src/static_analysis/reducer/mod.rs @@ -161,7 +161,7 @@ fn register<'ast>( ) { for (id, key, value) in substitute .iter() - .filter_map(|(id, version)| with.get(&id).map(|to| (id, version, to))) + .filter_map(|(id, version)| with.get(id).map(|to| (id, version, to))) .filter(|(_, key, value)| key != value) { let sub = substitutions.0.entry(id.clone()).or_default(); @@ -235,8 +235,8 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> { generics, arguments, ty, - &self.program, - &mut self.versions, + self.program, + self.versions, ); match res { @@ -354,8 +354,8 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> { generics, arguments, &types, - &self.program, - &mut self.versions, + self.program, + self.versions, ) { Ok(Output::Complete((statements, expressions))) => { assert_eq!(v.len(), expressions.len()); @@ -420,7 +420,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> { self.versions.values_mut().for_each(|v| *v += 1); // add this set of versions to the substitution, pointing to the versions before the loop - register(&mut self.substitutions, &self.versions, &versions_before); + register(self.substitutions, self.versions, &versions_before); // the versions after the loop are found by applying an offset of 2 to the versions before the loop let versions_after = versions_before @@ -429,7 +429,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> { .map(|(k, v)| (k, v + 2)) .collect(); - let mut transformer = ShallowTransformer::with_versions(&mut self.versions); + let mut transformer = ShallowTransformer::with_versions(self.versions); if to - from > MAX_FOR_LOOP_SIZE { return Err(Error::LoopTooLarge(to.saturating_sub(*from))); @@ -454,7 +454,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> { // we know the final versions of the variables after full unrolling of the loop // the versions after the loop need to point to these, so we add to the substitutions - register(&mut self.substitutions, &versions_after, &self.versions); + register(self.substitutions, &versions_after, self.versions); // we may have found new for loops when unrolling this one, which means new backed up versions // we insert these in our backup list and update our cursor @@ -573,7 +573,7 @@ fn reduce_function<'ast, T: Field>( loop { let mut reducer = Reducer::new( - &program, + program, &mut versions, &mut substitutions, for_loop_versions, diff --git a/zokrates_core/src/static_analysis/unconstrained_vars.rs b/zokrates_core/src/static_analysis/unconstrained_vars.rs index 52793cec..516be73a 100644 --- a/zokrates_core/src/static_analysis/unconstrained_vars.rs +++ b/zokrates_core/src/static_analysis/unconstrained_vars.rs @@ -28,7 +28,7 @@ impl fmt::Display for Error { impl UnconstrainedVariableDetector { pub fn detect(p: &Prog) -> Result<(), Error> { let mut instance = Self::default(); - instance.visit_module(&p); + instance.visit_module(p); if instance.variables.is_empty() { Ok(()) @@ -118,39 +118,39 @@ mod tests { // (1 * ~one) * (1 * ~one + (-1) * _1) == 1 * ~out_0 // return ~out_0 - let _0 = FlatParameter::private(FlatVariable::new(0)); - let _1 = FlatVariable::new(1); - let _2 = FlatVariable::new(2); + let v_0 = FlatParameter::private(FlatVariable::new(0)); + let v_1 = FlatVariable::new(1); + let v_2 = FlatVariable::new(2); let out_0 = FlatVariable::public(0); let one = FlatVariable::one(); let p: Prog = Prog { - arguments: vec![_0], + arguments: vec![v_0], statements: vec![ Statement::Directive(Directive { - inputs: vec![(LinComb::summand(-42, one) + LinComb::summand(1, _0.id)).into()], - outputs: vec![_1, _2], + inputs: vec![(LinComb::summand(-42, one) + LinComb::summand(1, v_0.id)).into()], + outputs: vec![v_1, v_2], solver: Solver::ConditionEq, }), Statement::constraint( QuadComb::from_linear_combinations( - LinComb::summand(-42, one) + LinComb::summand(1, _0.id), - LinComb::summand(1, _2), + LinComb::summand(-42, one) + LinComb::summand(1, v_0.id), + LinComb::summand(1, v_2), ), - LinComb::summand(1, _1), + LinComb::summand(1, v_1), ), Statement::constraint( QuadComb::from_linear_combinations( - LinComb::summand(1, one) + LinComb::summand(-1, _1), - LinComb::summand(-42, one) + LinComb::summand(1, _0.id), + LinComb::summand(1, one) + LinComb::summand(-1, v_1), + LinComb::summand(-42, one) + LinComb::summand(1, v_0.id), ), LinComb::zero(), ), Statement::constraint( QuadComb::from_linear_combinations( LinComb::summand(1, one), - LinComb::summand(1, one) + LinComb::summand(-1, _1), + LinComb::summand(1, one) + LinComb::summand(-1, v_1), ), LinComb::summand(1, out_0), ), diff --git a/zokrates_core/src/typed_absy/integer.rs b/zokrates_core/src/typed_absy/integer.rs index b430f3a9..bd1b2444 100644 --- a/zokrates_core/src/typed_absy/integer.rs +++ b/zokrates_core/src/typed_absy/integer.rs @@ -597,7 +597,7 @@ impl<'ast, T: Field> ArrayExpression<'ast, T> { inline_array .into_iter() .map(|v| { - TypedExpressionOrSpread::align_to_type(v, &target_array_ty).map_err( + TypedExpressionOrSpread::align_to_type(v, target_array_ty).map_err( |(e, _)| match e { TypedExpressionOrSpread::Expression(e) => e, TypedExpressionOrSpread::Spread(a) => { @@ -620,7 +620,7 @@ impl<'ast, T: Field> ArrayExpression<'ast, T> { GType::Int => Ok(ArrayExpressionInner::Repeat(box e, box count) .annotate(Type::Int, array_ty.size)), // try to align the repeated element to the target type - t => TypedExpression::align_to_type(e, &t) + t => TypedExpression::align_to_type(e, t) .map(|e| { let ty = e.get_type().clone(); diff --git a/zokrates_core/src/typed_absy/mod.rs b/zokrates_core/src/typed_absy/mod.rs index 0dc8db34..64f7441f 100644 --- a/zokrates_core/src/typed_absy/mod.rs +++ b/zokrates_core/src/typed_absy/mod.rs @@ -263,7 +263,7 @@ impl<'ast, T: Field> TypedFunctionSymbol<'ast, T> { .find(|d| d.key == *key) .unwrap() .symbol - .signature(&modules), + .signature(modules), TypedFunctionSymbol::Flat(flat_fun) => flat_fun.typed_signature(), } } @@ -1588,7 +1588,7 @@ impl<'ast, T: Clone> Expr<'ast, T> for FieldElementExpression<'ast, T> { } fn as_inner(&self) -> &Self::Inner { - &self + self } fn as_inner_mut(&mut self) -> &mut Self::Inner { @@ -1609,7 +1609,7 @@ impl<'ast, T: Clone> Expr<'ast, T> for BooleanExpression<'ast, T> { } fn as_inner(&self) -> &Self::Inner { - &self + self } fn as_inner_mut(&mut self) -> &mut Self::Inner { @@ -1693,7 +1693,7 @@ impl<'ast, T: Clone> Expr<'ast, T> for IntExpression<'ast, T> { } fn as_inner(&self) -> &Self::Inner { - &self + self } fn as_inner_mut(&mut self) -> &mut Self::Inner { diff --git a/zokrates_core/src/typed_absy/types.rs b/zokrates_core/src/typed_absy/types.rs index 6efbaf4c..7fb2d30c 100644 --- a/zokrates_core/src/typed_absy/types.rs +++ b/zokrates_core/src/typed_absy/types.rs @@ -301,7 +301,7 @@ impl fmt::Display for GArrayType { ) -> fmt::Result { acc.push(&t.size); match &*t.ty { - GType::Array(array_type) => fmt_aux(f, &array_type, acc), + GType::Array(array_type) => fmt_aux(f, array_type, acc), t => { write!(f, "{}", t)?; for i in acc { @@ -314,7 +314,7 @@ impl fmt::Display for GArrayType { let acc = vec![]; - fmt_aux(f, &self, acc) + fmt_aux(f, self, acc) } } @@ -458,7 +458,7 @@ impl GStructType { } fn location(&self) -> &StructLocation { - &self.location.as_ref().unwrap_or(&self.canonical_location) + self.location.as_ref().unwrap_or(&self.canonical_location) } pub fn name(&self) -> &str { @@ -1009,7 +1009,7 @@ pub fn specialize_declaration_type< Ok(match decl_ty { DeclarationType::Int => unreachable!(), DeclarationType::Array(t0) => { - let ty = box specialize_declaration_type(*t0.ty, &generics)?; + let ty = box specialize_declaration_type(*t0.ty, generics)?; let size = match t0.size { DeclarationConstant::Generic(s) => generics.0.get(&s).cloned().ok_or(s), DeclarationConstant::Concrete(s) => Ok(s.into()), @@ -1085,7 +1085,7 @@ pub mod signature { impl Ord for GSignature { fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.partial_cmp(&other).unwrap() + self.partial_cmp(other).unwrap() } } diff --git a/zokrates_core/tests/out_of_range.rs b/zokrates_core/tests/out_of_range.rs index c27e2361..2e44a031 100644 --- a/zokrates_core/tests/out_of_range.rs +++ b/zokrates_core/tests/out_of_range.rs @@ -38,7 +38,7 @@ fn lt_field() { assert!(interpreter .execute( - &res.prog(), + res.prog(), &[Bn128Field::from(10000), Bn128Field::from(5555)] ) .is_err()); @@ -70,7 +70,7 @@ fn lt_uint() { assert!(interpreter .execute( - &res.prog(), + res.prog(), &[Bn128Field::from(10000), Bn128Field::from(5555)] ) .is_err()); @@ -112,7 +112,7 @@ fn unpack256() { let interpreter = Interpreter::try_out_of_range(); assert!(interpreter - .execute(&res.prog(), &[Bn128Field::from(0)]) + .execute(res.prog(), &[Bn128Field::from(0)]) .is_err()); } @@ -152,6 +152,6 @@ fn unpack256_unchecked() { let interpreter = Interpreter::try_out_of_range(); assert!(interpreter - .execute(&res.prog(), &[Bn128Field::from(0)]) + .execute(res.prog(), &[Bn128Field::from(0)]) .is_ok()); } diff --git a/zokrates_embed/src/ark.rs b/zokrates_embed/src/ark.rs index 47e14529..ff8826a3 100644 --- a/zokrates_embed/src/ark.rs +++ b/zokrates_embed/src/ark.rs @@ -111,7 +111,7 @@ pub fn generate_verify_constraints( let num_instance_variables = cs.num_instance_variables(); let input_indices = fp_vars .iter() - .map(|f| var_to_index(&f, 0)) + .map(|f| var_to_index(f, 0)) .collect::>(); let proof_indices: Vec = vec![ diff --git a/zokrates_pest_ast/src/lib.rs b/zokrates_pest_ast/src/lib.rs index cf41cd9c..331d869a 100644 --- a/zokrates_pest_ast/src/lib.rs +++ b/zokrates_pest_ast/src/lib.rs @@ -803,7 +803,7 @@ mod ast { match self { Expression::Binary(b) => &b.span, Expression::Identifier(i) => &i.span, - Expression::Literal(c) => &c.span(), + Expression::Literal(c) => c.span(), Expression::Ternary(t) => &t.span, Expression::Postfix(p) => &p.span, Expression::InlineArray(a) => &a.span, @@ -1092,57 +1092,57 @@ mod tests { def main() -> (field): return 1 + 1 "#; assert_eq!( - generate_ast(&source), + generate_ast(source), Ok(File { pragma: None, declarations: vec![ SymbolDeclaration::Import(ImportDirective::Main(MainImportDirective { source: ImportSource { value: String::from("foo"), - span: Span::new(&source, 8, 11).unwrap() + span: Span::new(source, 8, 11).unwrap() }, alias: None, - span: Span::new(&source, 0, 29).unwrap() + span: Span::new(source, 0, 29).unwrap() })), SymbolDeclaration::Function(FunctionDefinition { generics: vec![], id: IdentifierExpression { value: String::from("main"), - span: Span::new(&source, 33, 37).unwrap() + span: Span::new(source, 33, 37).unwrap() }, parameters: vec![], returns: vec![Type::Basic(BasicType::Field(FieldType { - span: Span::new(&source, 44, 49).unwrap() + span: Span::new(source, 44, 49).unwrap() }))], statements: vec![Statement::Return(ReturnStatement { expressions: vec![Expression::add( Expression::Literal(LiteralExpression::DecimalLiteral( DecimalLiteralExpression { value: DecimalNumber { - span: Span::new(&source, 59, 60).unwrap() + span: Span::new(source, 59, 60).unwrap() }, suffix: None, - span: Span::new(&source, 59, 60).unwrap() + span: Span::new(source, 59, 60).unwrap() } )), Expression::Literal(LiteralExpression::DecimalLiteral( DecimalLiteralExpression { value: DecimalNumber { - span: Span::new(&source, 63, 64).unwrap() + span: Span::new(source, 63, 64).unwrap() }, suffix: None, - span: Span::new(&source, 63, 64).unwrap() + span: Span::new(source, 63, 64).unwrap() } )), - Span::new(&source, 59, 64).unwrap() + Span::new(source, 59, 64).unwrap() )], - span: Span::new(&source, 52, 64).unwrap(), + span: Span::new(source, 52, 64).unwrap(), })], - span: Span::new(&source, 29, source.len()).unwrap(), + span: Span::new(source, 29, source.len()).unwrap(), }) ], eoi: EOI {}, - span: Span::new(&source, 0, 65).unwrap() + span: Span::new(source, 0, 65).unwrap() }) ); } @@ -1153,27 +1153,27 @@ mod tests { def main() -> (field): return 1 + 2 * 3 ** 4 "#; assert_eq!( - generate_ast(&source), + generate_ast(source), Ok(File { pragma: None, declarations: vec![ SymbolDeclaration::Import(ImportDirective::Main(MainImportDirective { source: ImportSource { value: String::from("foo"), - span: Span::new(&source, 8, 11).unwrap() + span: Span::new(source, 8, 11).unwrap() }, alias: None, - span: Span::new(&source, 0, 29).unwrap() + span: Span::new(source, 0, 29).unwrap() })), SymbolDeclaration::Function(FunctionDefinition { generics: vec![], id: IdentifierExpression { value: String::from("main"), - span: Span::new(&source, 33, 37).unwrap() + span: Span::new(source, 33, 37).unwrap() }, parameters: vec![], returns: vec![Type::Basic(BasicType::Field(FieldType { - span: Span::new(&source, 44, 49).unwrap() + span: Span::new(source, 44, 49).unwrap() }))], statements: vec![Statement::Return(ReturnStatement { expressions: vec![Expression::add( @@ -1181,9 +1181,9 @@ mod tests { DecimalLiteralExpression { suffix: None, value: DecimalNumber { - span: Span::new(&source, 59, 60).unwrap() + span: Span::new(source, 59, 60).unwrap() }, - span: Span::new(&source, 59, 60).unwrap() + span: Span::new(source, 59, 60).unwrap() } )), Expression::mul( @@ -1191,9 +1191,9 @@ mod tests { DecimalLiteralExpression { suffix: None, value: DecimalNumber { - span: Span::new(&source, 63, 64).unwrap() + span: Span::new(source, 63, 64).unwrap() }, - span: Span::new(&source, 63, 64).unwrap() + span: Span::new(source, 63, 64).unwrap() } )), Expression::pow( @@ -1201,33 +1201,33 @@ mod tests { DecimalLiteralExpression { suffix: None, value: DecimalNumber { - span: Span::new(&source, 67, 68).unwrap() + span: Span::new(source, 67, 68).unwrap() }, - span: Span::new(&source, 67, 68).unwrap() + span: Span::new(source, 67, 68).unwrap() } )), Expression::Literal(LiteralExpression::DecimalLiteral( DecimalLiteralExpression { suffix: None, value: DecimalNumber { - span: Span::new(&source, 72, 73).unwrap() + span: Span::new(source, 72, 73).unwrap() }, - span: Span::new(&source, 72, 73).unwrap() + span: Span::new(source, 72, 73).unwrap() } )), - Span::new(&source, 67, 73).unwrap() + Span::new(source, 67, 73).unwrap() ), - Span::new(&source, 63, 73).unwrap() + Span::new(source, 63, 73).unwrap() ), - Span::new(&source, 59, 73).unwrap() + Span::new(source, 59, 73).unwrap() )], - span: Span::new(&source, 52, 73).unwrap(), + span: Span::new(source, 52, 73).unwrap(), })], - span: Span::new(&source, 29, 74).unwrap(), + span: Span::new(source, 29, 74).unwrap(), }) ], eoi: EOI {}, - span: Span::new(&source, 0, 74).unwrap() + span: Span::new(source, 0, 74).unwrap() }) ); } @@ -1238,27 +1238,27 @@ mod tests { def main() -> (field): return if 1 then 2 else 3 fi "#; assert_eq!( - generate_ast(&source), + generate_ast(source), Ok(File { pragma: None, declarations: vec![ SymbolDeclaration::Import(ImportDirective::Main(MainImportDirective { source: ImportSource { value: String::from("foo"), - span: Span::new(&source, 8, 11).unwrap() + span: Span::new(source, 8, 11).unwrap() }, alias: None, - span: Span::new(&source, 0, 29).unwrap() + span: Span::new(source, 0, 29).unwrap() })), SymbolDeclaration::Function(FunctionDefinition { generics: vec![], id: IdentifierExpression { value: String::from("main"), - span: Span::new(&source, 33, 37).unwrap() + span: Span::new(source, 33, 37).unwrap() }, parameters: vec![], returns: vec![Type::Basic(BasicType::Field(FieldType { - span: Span::new(&source, 44, 49).unwrap() + span: Span::new(source, 44, 49).unwrap() }))], statements: vec![Statement::Return(ReturnStatement { expressions: vec![Expression::if_else( @@ -1266,38 +1266,38 @@ mod tests { DecimalLiteralExpression { suffix: None, value: DecimalNumber { - span: Span::new(&source, 62, 63).unwrap() + span: Span::new(source, 62, 63).unwrap() }, - span: Span::new(&source, 62, 63).unwrap() + span: Span::new(source, 62, 63).unwrap() } )), Expression::Literal(LiteralExpression::DecimalLiteral( DecimalLiteralExpression { suffix: None, value: DecimalNumber { - span: Span::new(&source, 69, 70).unwrap() + span: Span::new(source, 69, 70).unwrap() }, - span: Span::new(&source, 69, 70).unwrap() + span: Span::new(source, 69, 70).unwrap() } )), Expression::Literal(LiteralExpression::DecimalLiteral( DecimalLiteralExpression { suffix: None, value: DecimalNumber { - span: Span::new(&source, 76, 77).unwrap() + span: Span::new(source, 76, 77).unwrap() }, - span: Span::new(&source, 76, 77).unwrap() + span: Span::new(source, 76, 77).unwrap() } )), - Span::new(&source, 59, 80).unwrap() + Span::new(source, 59, 80).unwrap() )], - span: Span::new(&source, 52, 80).unwrap(), + span: Span::new(source, 52, 80).unwrap(), })], - span: Span::new(&source, 29, 81).unwrap(), + span: Span::new(source, 29, 81).unwrap(), }) ], eoi: EOI {}, - span: Span::new(&source, 0, 81).unwrap() + span: Span::new(source, 0, 81).unwrap() }) ); } @@ -1307,35 +1307,35 @@ mod tests { let source = r#"def main() -> (field): return (1) "#; assert_eq!( - generate_ast(&source), + generate_ast(source), Ok(File { pragma: None, declarations: vec![SymbolDeclaration::Function(FunctionDefinition { generics: vec![], id: IdentifierExpression { value: String::from("main"), - span: Span::new(&source, 4, 8).unwrap() + span: Span::new(source, 4, 8).unwrap() }, parameters: vec![], returns: vec![Type::Basic(BasicType::Field(FieldType { - span: Span::new(&source, 15, 20).unwrap() + span: Span::new(source, 15, 20).unwrap() }))], statements: vec![Statement::Return(ReturnStatement { expressions: vec![Expression::Literal(LiteralExpression::DecimalLiteral( DecimalLiteralExpression { suffix: None, value: DecimalNumber { - span: Span::new(&source, 31, 32).unwrap() + span: Span::new(source, 31, 32).unwrap() }, - span: Span::new(&source, 31, 32).unwrap() + span: Span::new(source, 31, 32).unwrap() } ))], - span: Span::new(&source, 23, 33).unwrap(), + span: Span::new(source, 23, 33).unwrap(), })], - span: Span::new(&source, 0, 34).unwrap(), + span: Span::new(source, 0, 34).unwrap(), })], eoi: EOI {}, - span: Span::new(&source, 0, 34).unwrap() + span: Span::new(source, 0, 34).unwrap() }) ); } @@ -1345,44 +1345,44 @@ mod tests { let source = r#"def main() -> (field): field a, b = foo(1, 2 + 3) "#; assert_eq!( - generate_ast(&source), + generate_ast(source), Ok(File { pragma: None, declarations: vec![SymbolDeclaration::Function(FunctionDefinition { generics: vec![], id: IdentifierExpression { value: String::from("main"), - span: Span::new(&source, 4, 8).unwrap() + span: Span::new(source, 4, 8).unwrap() }, parameters: vec![], returns: vec![Type::Basic(BasicType::Field(FieldType { - span: Span::new(&source, 15, 20).unwrap() + span: Span::new(source, 15, 20).unwrap() }))], statements: vec![Statement::Definition(DefinitionStatement { lhs: vec![ TypedIdentifierOrAssignee::TypedIdentifier(TypedIdentifier { ty: Type::Basic(BasicType::Field(FieldType { - span: Span::new(&source, 23, 28).unwrap() + span: Span::new(source, 23, 28).unwrap() })), identifier: IdentifierExpression { value: String::from("a"), - span: Span::new(&source, 29, 30).unwrap(), + span: Span::new(source, 29, 30).unwrap(), }, - span: Span::new(&source, 23, 30).unwrap() + span: Span::new(source, 23, 30).unwrap() }), TypedIdentifierOrAssignee::Assignee(Assignee { id: IdentifierExpression { value: String::from("b"), - span: Span::new(&source, 32, 33).unwrap(), + span: Span::new(source, 32, 33).unwrap(), }, accesses: vec![], - span: Span::new(&source, 32, 34).unwrap() + span: Span::new(source, 32, 34).unwrap() }), ], expression: Expression::Postfix(PostfixExpression { base: Box::new(Expression::Identifier(IdentifierExpression { value: String::from("foo"), - span: Span::new(&source, 36, 39).unwrap() + span: Span::new(source, 36, 39).unwrap() })), accesses: vec![Access::Call(CallAccess { explicit_generics: None, @@ -1392,9 +1392,9 @@ mod tests { DecimalLiteralExpression { suffix: None, value: DecimalNumber { - span: Span::new(&source, 40, 41).unwrap() + span: Span::new(source, 40, 41).unwrap() }, - span: Span::new(&source, 40, 41).unwrap() + span: Span::new(source, 40, 41).unwrap() } )), Expression::add( @@ -1402,35 +1402,35 @@ mod tests { DecimalLiteralExpression { suffix: None, value: DecimalNumber { - span: Span::new(&source, 43, 44).unwrap() + span: Span::new(source, 43, 44).unwrap() }, - span: Span::new(&source, 43, 44).unwrap() + span: Span::new(source, 43, 44).unwrap() } )), Expression::Literal(LiteralExpression::DecimalLiteral( DecimalLiteralExpression { suffix: None, value: DecimalNumber { - span: Span::new(&source, 47, 48).unwrap() + span: Span::new(source, 47, 48).unwrap() }, - span: Span::new(&source, 47, 48).unwrap() + span: Span::new(source, 47, 48).unwrap() } )), - Span::new(&source, 43, 48).unwrap() + Span::new(source, 43, 48).unwrap() ), ], - span: Span::new(&source, 40, 48).unwrap() + span: Span::new(source, 40, 48).unwrap() }, - span: Span::new(&source, 39, 49).unwrap() + span: Span::new(source, 39, 49).unwrap() })], - span: Span::new(&source, 36, 49).unwrap(), + span: Span::new(source, 36, 49).unwrap(), }), - span: Span::new(&source, 23, 49).unwrap() + span: Span::new(source, 23, 49).unwrap() })], - span: Span::new(&source, 0, 50).unwrap(), + span: Span::new(source, 0, 50).unwrap(), })], eoi: EOI {}, - span: Span::new(&source, 0, 50).unwrap() + span: Span::new(source, 0, 50).unwrap() }) ); } @@ -1453,8 +1453,8 @@ mod tests { assert(a.member == 1) return a "#; - let res = generate_ast(&source); - println!("{:#?}", generate_ast(&source)); + let res = generate_ast(source); + println!("{:#?}", generate_ast(source)); assert!(res.is_ok()); } } diff --git a/zokrates_stdlib/stdlib/utils/casts/field_to_u16.zok b/zokrates_stdlib/stdlib/utils/casts/field_to_u16.zok index 9f39cbc1..8febe4b2 100644 --- a/zokrates_stdlib/stdlib/utils/casts/field_to_u16.zok +++ b/zokrates_stdlib/stdlib/utils/casts/field_to_u16.zok @@ -1,5 +1,7 @@ -from "EMBED" import unpack, u16_from_bits +from "field" import FIELD_SIZE_IN_BITS +import "utils/pack/bool/unpack" +import "utils/casts/u16_from_bits" -def main(field i) -> u16: - bool[16] bits = unpack(i) - return u16_from_bits(bits) \ No newline at end of file +def main(field input) -> u16: + bool[FIELD_SIZE_IN_BITS] bits = unpack(input) + return u16_from_bits(bits[FIELD_SIZE_IN_BITS-16..]) \ No newline at end of file diff --git a/zokrates_stdlib/stdlib/utils/casts/field_to_u32.zok b/zokrates_stdlib/stdlib/utils/casts/field_to_u32.zok index cf14aa90..28577d79 100644 --- a/zokrates_stdlib/stdlib/utils/casts/field_to_u32.zok +++ b/zokrates_stdlib/stdlib/utils/casts/field_to_u32.zok @@ -1,5 +1,7 @@ -from "EMBED" import unpack, u32_from_bits +from "field" import FIELD_SIZE_IN_BITS +import "utils/pack/bool/unpack" +import "utils/casts/u32_from_bits" -def main(field i) -> u32: - bool[32] bits = unpack(i) - return u32_from_bits(bits) \ No newline at end of file +def main(field input) -> u32: + bool[FIELD_SIZE_IN_BITS] bits = unpack(input) + return u32_from_bits(bits[FIELD_SIZE_IN_BITS-32..]) \ No newline at end of file diff --git a/zokrates_stdlib/stdlib/utils/casts/field_to_u64.zok b/zokrates_stdlib/stdlib/utils/casts/field_to_u64.zok index 8433dd63..d614ebcf 100644 --- a/zokrates_stdlib/stdlib/utils/casts/field_to_u64.zok +++ b/zokrates_stdlib/stdlib/utils/casts/field_to_u64.zok @@ -1,5 +1,7 @@ -from "EMBED" import unpack, u64_from_bits +from "field" import FIELD_SIZE_IN_BITS +import "utils/pack/bool/unpack" +import "utils/casts/u64_from_bits" -def main(field i) -> u64: - bool[64] bits = unpack(i) - return u64_from_bits(bits) \ No newline at end of file +def main(field input) -> u64: + bool[FIELD_SIZE_IN_BITS] bits = unpack(input) + return u64_from_bits(bits[FIELD_SIZE_IN_BITS-64..]) \ No newline at end of file diff --git a/zokrates_stdlib/stdlib/utils/casts/field_to_u8.zok b/zokrates_stdlib/stdlib/utils/casts/field_to_u8.zok index 3045e302..99c795fd 100644 --- a/zokrates_stdlib/stdlib/utils/casts/field_to_u8.zok +++ b/zokrates_stdlib/stdlib/utils/casts/field_to_u8.zok @@ -1,5 +1,7 @@ -from "EMBED" import unpack, u8_from_bits +from "field" import FIELD_SIZE_IN_BITS +import "utils/pack/bool/unpack" +import "utils/casts/u8_from_bits" -def main(field i) -> u8: - bool[8] bits = unpack(i) - return u8_from_bits(bits) \ No newline at end of file +def main(field input) -> u8: + bool[FIELD_SIZE_IN_BITS] bits = unpack(input) + return u8_from_bits(bits[FIELD_SIZE_IN_BITS-8..]) \ No newline at end of file diff --git a/zokrates_stdlib/tests/tests/utils/casts/field_to_uint.json b/zokrates_stdlib/tests/tests/utils/casts/field_to_uint.json index 1c988f73..0e617ee3 100644 --- a/zokrates_stdlib/tests/tests/utils/casts/field_to_uint.json +++ b/zokrates_stdlib/tests/tests/utils/casts/field_to_uint.json @@ -4,11 +4,11 @@ "tests": [ { "input": { - "values": ["0", "1", "18446744073709551615", "42", "0", "1", "4294967295", "42", "0", "1", "65535", "42", "0", "1", "255", "42"] + "values": ["0", "1", "18446744073709551615", "18446744073709551616", "18446744073709551658", "0", "1", "4294967295", "4294967296", "4294967338", "0", "1", "65535", "65536", "65578", "0", "1", "255", "256", "298"] }, "output": { "Ok": { - "values": ["0", "1", "18446744073709551615", "42", "0", "1", "4294967295", "42", "0", "1", "65535", "42", "0", "1", "255", "42"] + "values": ["0", "1", "18446744073709551615", "0", "42", "0", "1", "4294967295", "0", "42", "0", "1", "65535", "0", "42", "0", "1", "255", "0", "42"] } } } diff --git a/zokrates_stdlib/tests/tests/utils/casts/field_to_uint.zok b/zokrates_stdlib/tests/tests/utils/casts/field_to_uint.zok index b8a3de76..4d5be3bb 100644 --- a/zokrates_stdlib/tests/tests/utils/casts/field_to_uint.zok +++ b/zokrates_stdlib/tests/tests/utils/casts/field_to_uint.zok @@ -3,13 +3,13 @@ import "utils/casts/field_to_u32" import "utils/casts/field_to_u16" import "utils/casts/field_to_u8" -def main(field[4] a, field[4] b, field[4] c, field[4] d) -> (u64[4], u32[4], u16[4], u8[4]): - u64[4] e = [0; 4] - u32[4] f = [0; 4] - u16[4] g = [0; 4] - u8[4] h = [0; 4] +def main(field[5] a, field[5] b, field[5] c, field[5] d) -> (u64[5], u32[5], u16[5], u8[5]): + u64[5] e = [0; 5] + u32[5] f = [0; 5] + u16[5] g = [0; 5] + u8[5] h = [0; 5] - for u32 i in 0..4 do + for u32 i in 0..5 do e[i] = field_to_u64(a[i]) f[i] = field_to_u32(b[i]) g[i] = field_to_u16(c[i]) diff --git a/zokrates_test/src/lib.rs b/zokrates_test/src/lib.rs index ca95920c..f3605f35 100644 --- a/zokrates_test/src/lib.rs +++ b/zokrates_test/src/lib.rs @@ -157,15 +157,14 @@ fn compile_and_run(t: Tests) { if let Some(target_count) = t.max_constraint_count { let count = bin.constraint_count(); - if count > target_count { - panic!( - "{} exceeded max constraint count (actual={}, max={}, p={:.2}% of max)", - entry_point.display(), - count, - target_count, - (count as f32) / (target_count as f32) * 100_f32 - ); - } + assert!( + count <= target_count, + "{} exceeded max constraint count (actual={}, max={}, p={:.2}% of max)", + entry_point.display(), + count, + target_count, + (count as f32) / (target_count as f32) * 100_f32 + ); }; let interpreter = zokrates_core::ir::Interpreter::default(); diff --git a/zokrates_test_derive/src/lib.rs b/zokrates_test_derive/src/lib.rs index 74b0fa24..4cfc8d07 100644 --- a/zokrates_test_derive/src/lib.rs +++ b/zokrates_test_derive/src/lib.rs @@ -13,7 +13,7 @@ pub fn write_tests(base: &str) { let mut writer = BufWriter::new(test_file); for p in glob(base.join("**/*.json").to_str().unwrap()).unwrap() { - write_test(&mut writer, &p.unwrap(), &base); + write_test(&mut writer, &p.unwrap(), base); } }