From ecb2dd40de6c89e29e6518af4a2dbf6e142a42be Mon Sep 17 00:00:00 2001 From: schaeff Date: Tue, 8 Jun 2021 19:19:50 +0200 Subject: [PATCH 01/16] wip --- zokrates_core/src/semantics.rs | 16 ++- .../src/static_analysis/constant_inliner.rs | 86 ++----------- .../static_analysis/flatten_complex_types.rs | 116 ++++++++---------- .../src/static_analysis/propagation.rs | 45 ++----- .../static_analysis/variable_write_remover.rs | 22 ++-- zokrates_core/src/typed_absy/folder.rs | 49 +++++++- zokrates_core/src/typed_absy/mod.rs | 85 +++++++++---- zokrates_core/src/typed_absy/result_folder.rs | 52 ++++++-- zokrates_core/src/typed_absy/types.rs | 27 ++-- zokrates_core/src/typed_absy/uint.rs | 4 +- zokrates_core/src/typed_absy/variable.rs | 2 +- 11 files changed, 264 insertions(+), 240 deletions(-) diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index 05428046b..db7150464 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -1715,19 +1715,17 @@ impl<'ast, T: Field> Checker<'ast, T> { // check that `id` is defined in the scope match self.get_scope(&name) { Some(v) => match v.id.get_type() { - Type::Boolean => Ok(BooleanExpression::Identifier(name.into()).into()), - Type::Uint(bitwidth) => Ok(UExpressionInner::Identifier(name.into()) + Type::Boolean => Ok(BooleanExpression::identifier(name.into()).into()), + Type::Uint(bitwidth) => Ok(UExpression::identifier(name.into()) .annotate(bitwidth) .into()), Type::FieldElement => { - Ok(FieldElementExpression::Identifier(name.into()).into()) + Ok(FieldElementExpression::identifier(name.into()).into()) } - Type::Array(array_type) => { - Ok(ArrayExpressionInner::Identifier(name.into()) - .annotate(*array_type.ty, array_type.size) - .into()) - } - Type::Struct(members) => Ok(StructExpressionInner::Identifier(name.into()) + Type::Array(array_type) => Ok(ArrayExpression::identifier(name.into()) + .annotate(*array_type.ty, array_type.size) + .into()), + Type::Struct(members) => Ok(StructExpression::identifier(name.into()) .annotate(members) .into()), Type::Int => unreachable!(), diff --git a/zokrates_core/src/static_analysis/constant_inliner.rs b/zokrates_core/src/static_analysis/constant_inliner.rs index b6f22cce4..a15ca7cec 100644 --- a/zokrates_core/src/static_analysis/constant_inliner.rs +++ b/zokrates_core/src/static_analysis/constant_inliner.rs @@ -126,7 +126,7 @@ impl<'ast, 'a, T: Field> Folder<'ast, T> for ConstantInliner<'ast, 'a, T> { use self::GType::*; match t { Array(ref array_type) => match &array_type.size.inner { - UExpressionInner::Identifier(v) => match self.get_constant(v) { + UExpressionInner::Identifier(v) => match self.get_constant(&v.id) { Some(tc) => { let expression: UExpression<'ast, T> = tc.expression.try_into().unwrap(); Type::array(GArrayType::new( @@ -158,80 +158,18 @@ impl<'ast, 'a, T: Field> Folder<'ast, T> for ConstantInliner<'ast, 'a, T> { TypedConstantSymbol::Here(tc) } - fn fold_field_expression( + fn fold_identifier_expression< + E: Expr<'ast, T> + Id<'ast, T> + From>, + >( &mut self, - e: FieldElementExpression<'ast, T>, - ) -> FieldElementExpression<'ast, T> { - match e { - FieldElementExpression::Identifier(ref id) => match self.get_constant(id) { - Some(c) => self.fold_constant(c).try_into().unwrap(), - None => fold_field_expression(self, e), - }, - e => fold_field_expression(self, e), - } - } - - fn fold_boolean_expression( - &mut self, - e: BooleanExpression<'ast, T>, - ) -> BooleanExpression<'ast, T> { - match e { - BooleanExpression::Identifier(ref id) => match self.get_constant(id) { - Some(c) => self.fold_constant(c).try_into().unwrap(), - None => fold_boolean_expression(self, e), - }, - e => fold_boolean_expression(self, e), - } - } - - fn fold_uint_expression_inner( - &mut self, - size: UBitwidth, - e: UExpressionInner<'ast, T>, - ) -> UExpressionInner<'ast, T> { - match e { - UExpressionInner::Identifier(ref id) => match self.get_constant(id) { - Some(c) => { - let e: UExpression<'ast, T> = self.fold_constant(c).try_into().unwrap(); - e.into_inner() - } - None => fold_uint_expression_inner(self, size, e), - }, - e => fold_uint_expression_inner(self, size, e), - } - } - - fn fold_array_expression_inner( - &mut self, - ty: &ArrayType<'ast, T>, - e: ArrayExpressionInner<'ast, T>, - ) -> ArrayExpressionInner<'ast, T> { - match e { - ArrayExpressionInner::Identifier(ref id) => match self.get_constant(id) { - Some(c) => { - let e: ArrayExpression<'ast, T> = self.fold_constant(c).try_into().unwrap(); - e.into_inner() - } - None => fold_array_expression_inner(self, ty, e), - }, - e => fold_array_expression_inner(self, ty, e), - } - } - - fn fold_struct_expression_inner( - &mut self, - ty: &StructType<'ast, T>, - e: StructExpressionInner<'ast, T>, - ) -> StructExpressionInner<'ast, T> { - match e { - StructExpressionInner::Identifier(ref id) => match self.get_constant(id) { - Some(c) => { - let e: StructExpression<'ast, T> = self.fold_constant(c).try_into().unwrap(); - e.into_inner() - } - None => fold_struct_expression_inner(self, ty, e), - }, - e => fold_struct_expression_inner(self, ty, e), + _: &E::Ty, + e: IdentifierExpression<'ast, E>, + ) -> IdentifierOrExpression<'ast, T, E> { + match self.get_constant(&e.id) { + Some(c) => IdentifierOrExpression::Expression( + E::from(self.fold_constant(c).expression).into_inner(), + ), + None => IdentifierOrExpression::Identifier(e), } } } diff --git a/zokrates_core/src/static_analysis/flatten_complex_types.rs b/zokrates_core/src/static_analysis/flatten_complex_types.rs index cff22ee9c..2e03338b1 100644 --- a/zokrates_core/src/static_analysis/flatten_complex_types.rs +++ b/zokrates_core/src/static_analysis/flatten_complex_types.rs @@ -244,6 +244,15 @@ impl<'ast, T: Field> Flattener { } } + fn fold_identifier_expression>( + &mut self, + statements_buffer: &mut Vec>, + ty: &E::ConcreteTy, + e: typed_absy::IdentifierExpression<'ast, E>, + ) -> Vec> { + fold_identifier_expression::(self, statements_buffer, ty, e) + } + fn fold_array_expression( &mut self, statements_buffer: &mut Vec>, @@ -339,11 +348,10 @@ impl<'ast, T: Field> Flattener { fn fold_array_expression_inner( &mut self, statements_buffer: &mut Vec>, - ty: &typed_absy::types::ConcreteType, - size: usize, + ty: &typed_absy::types::ConcreteArrayType, e: typed_absy::ArrayExpressionInner<'ast, T>, ) -> Vec> { - fold_array_expression_inner(self, statements_buffer, ty, size, e) + fold_array_expression_inner(self, statements_buffer, ty, e) } fn fold_struct_expression_inner( &mut self, @@ -403,8 +411,7 @@ fn fold_statement<'ast, T: Field>( fn fold_array_expression_inner<'ast, T: Field>( f: &mut Flattener, statements_buffer: &mut Vec>, - ty: &typed_absy::types::ConcreteType, - size: usize, + ty: &typed_absy::types::ConcreteArrayType, array: typed_absy::ArrayExpressionInner<'ast, T>, ) -> Vec> { match array { @@ -416,20 +423,7 @@ fn fold_array_expression_inner<'ast, T: Field>( f.fold_array_expression(statements_buffer, *block.value) } typed_absy::ArrayExpressionInner::Identifier(id) => { - let variables = flatten_identifier_rec( - f.fold_name(id), - &typed_absy::types::ConcreteType::array((ty.clone(), size)), - ); - variables - .into_iter() - .map(|v| match v._type { - zir::Type::FieldElement => zir::FieldElementExpression::Identifier(v.id).into(), - zir::Type::Boolean => zir::BooleanExpression::Identifier(v.id).into(), - zir::Type::Uint(bitwidth) => zir::UExpressionInner::Identifier(v.id) - .annotate(bitwidth) - .into(), - }) - .collect() + f.fold_identifier_expression(statements_buffer, ty, id) } typed_absy::ArrayExpressionInner::Value(exprs) => { let exprs: Vec<_> = exprs @@ -437,7 +431,7 @@ fn fold_array_expression_inner<'ast, T: Field>( .flat_map(|e| f.fold_expression_or_spread(statements_buffer, e)) .collect(); - assert_eq!(exprs.len(), size * ty.get_primitive_count()); + assert_eq!(exprs.len(), ty.size * ty.ty.get_primitive_count()); exprs } @@ -458,9 +452,9 @@ fn fold_array_expression_inner<'ast, T: Field>( match (from.into_inner(), to.into_inner()) { (zir::UExpressionInner::Value(from), zir::UExpressionInner::Value(to)) => { - assert_eq!(size, to.saturating_sub(from) as usize); + assert_eq!(ty.size, to.saturating_sub(from) as usize); - let element_size = ty.get_primitive_count(); + let element_size = ty.ty.get_primitive_count(); let start = from as usize * element_size; let end = to as usize * element_size; array[start..end].to_vec() @@ -497,20 +491,7 @@ fn fold_struct_expression_inner<'ast, T: Field>( f.fold_struct_expression(statements_buffer, *block.value) } typed_absy::StructExpressionInner::Identifier(id) => { - let variables = flatten_identifier_rec( - f.fold_name(id), - &typed_absy::types::ConcreteType::struc(ty.clone()), - ); - variables - .into_iter() - .map(|v| match v._type { - zir::Type::FieldElement => zir::FieldElementExpression::Identifier(v.id).into(), - zir::Type::Boolean => zir::BooleanExpression::Identifier(v.id).into(), - zir::Type::Uint(bitwidth) => zir::UExpressionInner::Identifier(v.id) - .annotate(bitwidth) - .into(), - }) - .collect() + f.fold_identifier_expression(statements_buffer, ty, id) } typed_absy::StructExpressionInner::Value(exprs) => exprs .into_iter() @@ -629,6 +610,19 @@ fn fold_if_else_expression<'ast, T: Field, E: Flatten<'ast, T>>( .collect() } +fn fold_identifier_expression<'ast, T: Field, E: Expr<'ast, T>>( + f: &mut Flattener, + statements_buffer: &mut Vec>, + ty: &E::ConcreteTy, + e: typed_absy::IdentifierExpression<'ast, E>, +) -> Vec> { + unimplemented!() + // flatten_identifier_rec( + // f.fold_name(e.id), + // ty.clone(), + // ) +} + fn fold_field_expression<'ast, T: Field>( f: &mut Flattener, statements_buffer: &mut Vec>, @@ -636,17 +630,16 @@ fn fold_field_expression<'ast, T: Field>( ) -> zir::FieldElementExpression<'ast, T> { match e { typed_absy::FieldElementExpression::Number(n) => zir::FieldElementExpression::Number(n), - typed_absy::FieldElementExpression::Identifier(id) => { - zir::FieldElementExpression::Identifier( - flatten_identifier_rec( - f.fold_name(id), - &typed_absy::types::ConcreteType::FieldElement, - ) - .pop() - .unwrap() - .id, + typed_absy::FieldElementExpression::Identifier(id) => f + .fold_identifier_expression( + statements_buffer, + &typed_absy::ConcreteType::FieldElement, + id, ) - } + .pop() + .unwrap() + .try_into() + .unwrap(), typed_absy::FieldElementExpression::Add(box e1, box e2) => { let e1 = f.fold_field_expression(statements_buffer, e1); let e2 = f.fold_field_expression(statements_buffer, e2); @@ -726,12 +719,12 @@ fn fold_boolean_expression<'ast, T: Field>( f.fold_boolean_expression(statements_buffer, *block.value) } typed_absy::BooleanExpression::Value(v) => zir::BooleanExpression::Value(v), - typed_absy::BooleanExpression::Identifier(id) => zir::BooleanExpression::Identifier( - flatten_identifier_rec(f.fold_name(id), &typed_absy::types::ConcreteType::Boolean) - .pop() - .unwrap() - .id, - ), + typed_absy::BooleanExpression::Identifier(id) => f + .fold_identifier_expression(statements_buffer, &typed_absy::ConcreteType::Boolean, id) + .pop() + .unwrap() + .try_into() + .unwrap(), typed_absy::BooleanExpression::FieldEq(box e1, box e2) => { let e1 = f.fold_field_expression(statements_buffer, e1); let e2 = f.fold_field_expression(statements_buffer, e2); @@ -905,15 +898,13 @@ fn fold_uint_expression_inner<'ast, T: Field>( .into_inner() } typed_absy::UExpressionInner::Value(v) => zir::UExpressionInner::Value(v), - typed_absy::UExpressionInner::Identifier(id) => zir::UExpressionInner::Identifier( - flatten_identifier_rec( - f.fold_name(id), - &typed_absy::types::ConcreteType::Uint(bitwidth), - ) - .pop() - .unwrap() - .id, - ), + typed_absy::UExpressionInner::Identifier(id) => zir::UExpression::try_from( + f.fold_identifier_expression(statements_buffer, &bitwidth, id) + .pop() + .unwrap(), + ) + .unwrap() + .into_inner(), typed_absy::UExpressionInner::Add(box left, box right) => { let left = f.fold_uint_expression(statements_buffer, left); let right = f.fold_uint_expression(statements_buffer, right); @@ -1066,8 +1057,7 @@ fn fold_array_expression<'ast, T: Field>( } as usize; f.fold_array_expression_inner( statements_buffer, - &typed_absy::types::ConcreteType::try_from(e.inner_type().clone()).unwrap(), - size, + &typed_absy::types::ConcreteArrayType::try_from(e.ty().clone()).unwrap(), e.into_inner(), ) } diff --git a/zokrates_core/src/static_analysis/propagation.rs b/zokrates_core/src/static_analysis/propagation.rs index 2438971c0..d602f2851 100644 --- a/zokrates_core/src/static_analysis/propagation.rs +++ b/zokrates_core/src/static_analysis/propagation.rs @@ -747,13 +747,6 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { e: UExpressionInner<'ast, T>, ) -> Result, Error> { match e { - UExpressionInner::Identifier(id) => match self.constants.get(&id) { - Some(e) => match e { - TypedExpression::Uint(e) => Ok(e.as_inner().clone()), - _ => unreachable!("constant stored for a uint should be a uint"), - }, - None => Ok(UExpressionInner::Identifier(id)), - }, UExpressionInner::Add(box e1, box e2) => match ( self.fold_uint_expression(e1)?.into_inner(), self.fold_uint_expression(e2)?.into_inner(), @@ -977,15 +970,6 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { e: FieldElementExpression<'ast, T>, ) -> Result, Error> { match e { - FieldElementExpression::Identifier(id) => match self.constants.get(&id) { - Some(e) => match e { - TypedExpression::FieldElement(e) => Ok(e.clone()), - _ => unreachable!( - "constant stored for a field element should be a field element" - ), - }, - None => Ok(FieldElementExpression::Identifier(id)), - }, FieldElementExpression::Add(box e1, box e2) => match ( self.fold_field_expression(e1)?, self.fold_field_expression(e2)?, @@ -1117,7 +1101,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { } } (ArrayExpressionInner::Identifier(id), UExpressionInner::Value(n)) => { - match self.constants.get(&id) { + match self.constants.get(&id.id) { Some(a) => match a { TypedExpression::Array(a) => match a.as_inner() { ArrayExpressionInner::Value(v) => { @@ -1163,7 +1147,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { e: ArrayExpressionInner<'ast, T>, ) -> Result, Error> { match e { - ArrayExpressionInner::Identifier(id) => match self.constants.get(&id) { + ArrayExpressionInner::Identifier(id) => match self.constants.get(&id.id) { Some(e) => match e { TypedExpression::Array(e) => Ok(e.as_inner().clone()), _ => panic!("constant stored for an array should be an array"), @@ -1180,13 +1164,6 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { e: StructExpressionInner<'ast, T>, ) -> Result, Error> { match e { - StructExpressionInner::Identifier(id) => match self.constants.get(&id) { - Some(e) => match e { - TypedExpression::Struct(e) => Ok(e.as_inner().clone()), - _ => panic!("constant stored for an array should be an array"), - }, - None => Ok(StructExpressionInner::Identifier(id)), - }, StructExpressionInner::Value(v) => { let v = v.into_iter().zip(ty.iter()).map(|(v, member)| match self.fold_expression(v) { @@ -1207,6 +1184,17 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { } } + fn fold_identifier_expression + Id<'ast, T> + ResultFold<'ast, T>>( + &mut self, + _: &E::Ty, + id: IdentifierExpression<'ast, E>, + ) -> Result, Self::Error> { + match self.constants.get(&id.id).cloned() { + Some(e) => Ok(IdentifierOrExpression::Expression(E::from(e).into_inner())), + None => Ok(IdentifierOrExpression::Identifier(id)), + } + } + fn fold_boolean_expression( &mut self, e: BooleanExpression<'ast, T>, @@ -1217,13 +1205,6 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { // These kind of reduction rules are easier to apply later in the process, when we have canonical representations // of expressions, ie `a + a` would always be written `2 * a` match e { - BooleanExpression::Identifier(id) => match self.constants.get(&id) { - Some(e) => match e { - TypedExpression::Boolean(e) => Ok(e.clone()), - _ => panic!("constant stored for a boolean should be a boolean"), - }, - None => Ok(BooleanExpression::Identifier(id)), - }, BooleanExpression::FieldEq(box e1, box e2) => { let e1 = self.fold_field_expression(e1)?; let e2 = self.fold_field_expression(e2)?; diff --git a/zokrates_core/src/static_analysis/variable_write_remover.rs b/zokrates_core/src/static_analysis/variable_write_remover.rs index 82cc206ec..23da225e6 100644 --- a/zokrates_core/src/static_analysis/variable_write_remover.rs +++ b/zokrates_core/src/static_analysis/variable_write_remover.rs @@ -323,22 +323,18 @@ impl<'ast, T: Field> Folder<'ast, T> for VariableWriteRemover { let base = match variable.get_type() { Type::Int => unreachable!(), Type::FieldElement => { - FieldElementExpression::Identifier(variable.id.clone()).into() + FieldElementExpression::identifier(variable.id.clone()).into() } - Type::Boolean => BooleanExpression::Identifier(variable.id.clone()).into(), - Type::Uint(bitwidth) => UExpressionInner::Identifier(variable.id.clone()) + Type::Boolean => BooleanExpression::identifier(variable.id.clone()).into(), + Type::Uint(bitwidth) => UExpression::identifier(variable.id.clone()) .annotate(bitwidth) .into(), - Type::Array(array_type) => { - ArrayExpressionInner::Identifier(variable.id.clone()) - .annotate(*array_type.ty, array_type.size) - .into() - } - Type::Struct(members) => { - StructExpressionInner::Identifier(variable.id.clone()) - .annotate(members) - .into() - } + Type::Array(array_type) => ArrayExpression::identifier(variable.id.clone()) + .annotate(*array_type.ty, array_type.size) + .into(), + Type::Struct(members) => StructExpression::identifier(variable.id.clone()) + .annotate(members) + .into(), }; let base = self.fold_expression(base); diff --git a/zokrates_core/src/typed_absy/folder.rs b/zokrates_core/src/typed_absy/folder.rs index 90300f50b..fe8c92a64 100644 --- a/zokrates_core/src/typed_absy/folder.rs +++ b/zokrates_core/src/typed_absy/folder.rs @@ -217,6 +217,16 @@ pub trait Folder<'ast, T: Field>: Sized { fold_member_expression(self, ty, e) } + fn fold_identifier_expression< + E: Expr<'ast, T> + Id<'ast, T> + From>, + >( + &mut self, + ty: &E::Ty, + e: IdentifierExpression<'ast, E>, + ) -> IdentifierOrExpression<'ast, T, E> { + fold_identifier_expression(self, ty, e) + } + fn fold_function_call_expression< E: Id<'ast, T> + From> + Expr<'ast, T> + FunctionCall<'ast, T>, >( @@ -365,6 +375,19 @@ pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>( vec![res] } +pub fn fold_identifier_expression< + 'ast, + T: Field, + E: Expr<'ast, T> + Id<'ast, T> + From>, + F: Folder<'ast, T>, +>( + f: &mut F, + _: &E::Ty, + e: IdentifierExpression<'ast, E>, +) -> IdentifierOrExpression<'ast, T, E> { + IdentifierOrExpression::Identifier(IdentifierExpression::new(f.fold_name(e.id))) +} + pub fn fold_array_expression_inner<'ast, T: Field, F: Folder<'ast, T>>( f: &mut F, ty: &ArrayType<'ast, T>, @@ -374,7 +397,10 @@ pub fn fold_array_expression_inner<'ast, T: Field, F: Folder<'ast, T>>( ArrayExpressionInner::Block(block) => { ArrayExpressionInner::Block(f.fold_block_expression(block)) } - ArrayExpressionInner::Identifier(id) => ArrayExpressionInner::Identifier(f.fold_name(id)), + ArrayExpressionInner::Identifier(id) => match f.fold_identifier_expression(ty, id) { + IdentifierOrExpression::Identifier(i) => ArrayExpressionInner::Identifier(i), + IdentifierOrExpression::Expression(u) => u, + }, ArrayExpressionInner::Value(exprs) => ArrayExpressionInner::Value( exprs .into_iter() @@ -424,7 +450,10 @@ pub fn fold_struct_expression_inner<'ast, T: Field, F: Folder<'ast, T>>( StructExpressionInner::Block(block) => { StructExpressionInner::Block(f.fold_block_expression(block)) } - StructExpressionInner::Identifier(id) => StructExpressionInner::Identifier(f.fold_name(id)), + StructExpressionInner::Identifier(id) => match f.fold_identifier_expression(ty, id) { + IdentifierOrExpression::Identifier(i) => StructExpressionInner::Identifier(i), + IdentifierOrExpression::Expression(u) => u, + }, StructExpressionInner::Value(exprs) => { StructExpressionInner::Value(exprs.into_iter().map(|e| f.fold_expression(e)).collect()) } @@ -461,7 +490,10 @@ pub fn fold_field_expression<'ast, T: Field, F: Folder<'ast, T>>( } FieldElementExpression::Number(n) => FieldElementExpression::Number(n), FieldElementExpression::Identifier(id) => { - FieldElementExpression::Identifier(f.fold_name(id)) + match f.fold_identifier_expression(&Type::FieldElement, id) { + IdentifierOrExpression::Identifier(i) => FieldElementExpression::Identifier(i), + IdentifierOrExpression::Expression(u) => u, + } } FieldElementExpression::Add(box e1, box e2) => { let e1 = f.fold_field_expression(e1); @@ -589,7 +621,11 @@ pub fn fold_boolean_expression<'ast, T: Field, F: Folder<'ast, T>>( match e { BooleanExpression::Block(block) => BooleanExpression::Block(f.fold_block_expression(block)), BooleanExpression::Value(v) => BooleanExpression::Value(v), - BooleanExpression::Identifier(id) => BooleanExpression::Identifier(f.fold_name(id)), + BooleanExpression::Identifier(id) => match f.fold_identifier_expression(&Type::Boolean, id) + { + IdentifierOrExpression::Identifier(i) => BooleanExpression::Identifier(i), + IdentifierOrExpression::Expression(u) => u, + }, BooleanExpression::FieldEq(box e1, box e2) => { let e1 = f.fold_field_expression(e1); let e2 = f.fold_field_expression(e2); @@ -711,7 +747,10 @@ pub fn fold_uint_expression_inner<'ast, T: Field, F: Folder<'ast, T>>( match e { UExpressionInner::Block(block) => UExpressionInner::Block(f.fold_block_expression(block)), UExpressionInner::Value(v) => UExpressionInner::Value(v), - UExpressionInner::Identifier(id) => UExpressionInner::Identifier(f.fold_name(id)), + UExpressionInner::Identifier(id) => match f.fold_identifier_expression(&ty, id) { + IdentifierOrExpression::Identifier(i) => UExpressionInner::Identifier(i), + IdentifierOrExpression::Expression(u) => u, + }, UExpressionInner::Add(box left, box right) => { let left = f.fold_uint_expression(left); let right = f.fold_uint_expression(right); diff --git a/zokrates_core/src/typed_absy/mod.rs b/zokrates_core/src/typed_absy/mod.rs index 7ca72fcd1..8e4dad5be 100644 --- a/zokrates_core/src/typed_absy/mod.rs +++ b/zokrates_core/src/typed_absy/mod.rs @@ -19,9 +19,10 @@ mod variable; pub use self::identifier::CoreIdentifier; pub use self::parameter::{DeclarationParameter, GParameter}; pub use self::types::{ - ConcreteFunctionKey, ConcreteSignature, ConcreteType, DeclarationFunctionKey, - DeclarationSignature, DeclarationType, GArrayType, GStructType, GType, GenericIdentifier, - IntoTypes, Signature, StructType, Type, Types, UBitwidth, + ConcreteArrayType, ConcreteFunctionKey, ConcreteSignature, ConcreteStructType, ConcreteType, + ConcreteTypes, DeclarationFunctionKey, DeclarationSignature, DeclarationType, GArrayType, + GStructType, GType, GenericIdentifier, IntoTypes, Signature, StructType, Type, Types, + UBitwidth, }; use crate::typed_absy::types::ConcreteGenericsAssignment; @@ -740,6 +741,27 @@ impl<'ast, T, E> BlockExpression<'ast, T, E> { } } +#[derive(Clone, PartialEq, Debug, Hash, Eq)] +pub struct IdentifierExpression<'ast, E> { + pub id: Identifier<'ast>, + ty: PhantomData, +} + +impl<'ast, E> IdentifierExpression<'ast, E> { + pub fn new(id: Identifier<'ast>) -> Self { + IdentifierExpression { + id, + ty: PhantomData, + } + } +} + +impl<'ast, E> fmt::Display for IdentifierExpression<'ast, E> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.id) + } +} + #[derive(Clone, PartialEq, Debug, Hash, Eq)] pub struct MemberExpression<'ast, T, E> { pub struc: Box>, @@ -870,7 +892,7 @@ impl<'ast, T: fmt::Display, E> fmt::Display for FunctionCallExpression<'ast, T, pub enum FieldElementExpression<'ast, T> { Block(BlockExpression<'ast, T, Self>), Number(T), - Identifier(Identifier<'ast>), + Identifier(IdentifierExpression<'ast, Self>), Add( Box>, Box>, @@ -946,7 +968,7 @@ impl<'ast, T> From for FieldElementExpression<'ast, T> { #[derive(Clone, PartialEq, Debug, Hash, Eq)] pub enum BooleanExpression<'ast, T> { Block(BlockExpression<'ast, T, Self>), - Identifier(Identifier<'ast>), + Identifier(IdentifierExpression<'ast, Self>), Value(bool), FieldLt( Box>, @@ -1095,7 +1117,7 @@ impl<'ast, T> std::iter::FromIterator> for Arra #[derive(Clone, PartialEq, Debug, Hash, Eq)] pub enum ArrayExpressionInner<'ast, T> { Block(BlockExpression<'ast, T, ArrayExpression<'ast, T>>), - Identifier(Identifier<'ast>), + Identifier(IdentifierExpression<'ast, ArrayExpression<'ast, T>>), Value(ArrayValue<'ast, T>), FunctionCall(FunctionCallExpression<'ast, T, ArrayExpression<'ast, T>>), IfElse(IfElseExpression<'ast, T, ArrayExpression<'ast, T>>), @@ -1196,7 +1218,7 @@ impl<'ast, T> StructExpression<'ast, T> { #[derive(Clone, PartialEq, Debug, Hash, Eq)] pub enum StructExpressionInner<'ast, T> { Block(BlockExpression<'ast, T, StructExpression<'ast, T>>), - Identifier(Identifier<'ast>), + Identifier(IdentifierExpression<'ast, StructExpression<'ast, T>>), Value(Vec>), FunctionCall(FunctionCallExpression<'ast, T, StructExpression<'ast, T>>), IfElse(IfElseExpression<'ast, T, StructExpression<'ast, T>>), @@ -1476,13 +1498,19 @@ impl<'ast, T: fmt::Display> fmt::Display for TypedExpressionListInner<'ast, T> { impl<'ast, T: Field> From> for TypedExpression<'ast, T> { fn from(v: Variable<'ast, T>) -> Self { match v.get_type() { - Type::FieldElement => FieldElementExpression::Identifier(v.id).into(), - Type::Boolean => BooleanExpression::Identifier(v.id).into(), - Type::Array(ty) => ArrayExpressionInner::Identifier(v.id) + Type::FieldElement => { + FieldElementExpression::Identifier(IdentifierExpression::new(v.id)).into() + } + Type::Boolean => BooleanExpression::Identifier(IdentifierExpression::new(v.id)).into(), + Type::Array(ty) => ArrayExpressionInner::Identifier(IdentifierExpression::new(v.id)) .annotate(*ty.ty, ty.size) .into(), - Type::Struct(ty) => StructExpressionInner::Identifier(v.id).annotate(ty).into(), - Type::Uint(w) => UExpressionInner::Identifier(v.id).annotate(w).into(), + Type::Struct(ty) => StructExpressionInner::Identifier(IdentifierExpression::new(v.id)) + .annotate(ty) + .into(), + Type::Uint(w) => UExpressionInner::Identifier(IdentifierExpression::new(v.id)) + .annotate(w) + .into(), Type::Int => unreachable!(), } } @@ -1493,6 +1521,7 @@ impl<'ast, T: Field> From> for TypedExpression<'ast, T> { pub trait Expr<'ast, T>: From> { type Inner; type Ty: Clone + IntoTypes<'ast, T>; + type ConcreteTy: Clone; fn into_inner(self) -> Self::Inner; @@ -1502,6 +1531,7 @@ pub trait Expr<'ast, T>: From> { impl<'ast, T: Clone> Expr<'ast, T> for FieldElementExpression<'ast, T> { type Inner = Self; type Ty = Type<'ast, T>; + type ConcreteTy = ConcreteType; fn into_inner(self) -> Self::Inner { self @@ -1515,6 +1545,7 @@ impl<'ast, T: Clone> Expr<'ast, T> for FieldElementExpression<'ast, T> { impl<'ast, T: Clone> Expr<'ast, T> for BooleanExpression<'ast, T> { type Inner = Self; type Ty = Type<'ast, T>; + type ConcreteTy = ConcreteType; fn into_inner(self) -> Self::Inner { self @@ -1528,6 +1559,7 @@ impl<'ast, T: Clone> Expr<'ast, T> for BooleanExpression<'ast, T> { impl<'ast, T: Clone> Expr<'ast, T> for UExpression<'ast, T> { type Inner = UExpressionInner<'ast, T>; type Ty = UBitwidth; + type ConcreteTy = UBitwidth; fn into_inner(self) -> Self::Inner { self.inner @@ -1541,6 +1573,7 @@ impl<'ast, T: Clone> Expr<'ast, T> for UExpression<'ast, T> { impl<'ast, T: Clone> Expr<'ast, T> for StructExpression<'ast, T> { type Inner = StructExpressionInner<'ast, T>; type Ty = StructType<'ast, T>; + type ConcreteTy = ConcreteStructType; fn into_inner(self) -> Self::Inner { self.inner @@ -1554,6 +1587,7 @@ impl<'ast, T: Clone> Expr<'ast, T> for StructExpression<'ast, T> { impl<'ast, T: Clone> Expr<'ast, T> for ArrayExpression<'ast, T> { type Inner = ArrayExpressionInner<'ast, T>; type Ty = ArrayType<'ast, T>; + type ConcreteTy = ConcreteArrayType; fn into_inner(self) -> Self::Inner { self.inner @@ -1567,6 +1601,7 @@ impl<'ast, T: Clone> Expr<'ast, T> for ArrayExpression<'ast, T> { impl<'ast, T: Clone> Expr<'ast, T> for IntExpression<'ast, T> { type Inner = Self; type Ty = Type<'ast, T>; + type ConcreteTy = ConcreteType; fn into_inner(self) -> Self::Inner { self @@ -1580,6 +1615,7 @@ impl<'ast, T: Clone> Expr<'ast, T> for IntExpression<'ast, T> { impl<'ast, T: Clone> Expr<'ast, T> for TypedExpressionList<'ast, T> { type Inner = TypedExpressionListInner<'ast, T>; type Ty = Types<'ast, T>; + type ConcreteTy = ConcreteTypes; fn into_inner(self) -> Self::Inner { self.inner @@ -1606,6 +1642,11 @@ pub enum MemberOrExpression<'ast, T, E: Expr<'ast, T>> { Expression(E::Inner), } +pub enum IdentifierOrExpression<'ast, T, E: Expr<'ast, T>> { + Identifier(IdentifierExpression<'ast, E>), + Expression(E::Inner), +} + pub enum IfElseOrExpression<'ast, T, E: Expr<'ast, T>> { IfElse(IfElseExpression<'ast, T, E>), Expression(E::Inner), @@ -1814,33 +1855,33 @@ pub trait Id<'ast, T>: Expr<'ast, T> { fn identifier(id: Identifier<'ast>) -> Self::Inner; } -impl<'ast, T: Field> Id<'ast, T> for FieldElementExpression<'ast, T> { +impl<'ast, T: Clone> Id<'ast, T> for FieldElementExpression<'ast, T> { fn identifier(id: Identifier<'ast>) -> Self::Inner { - FieldElementExpression::Identifier(id) + FieldElementExpression::Identifier(IdentifierExpression::new(id)) } } -impl<'ast, T: Field> Id<'ast, T> for BooleanExpression<'ast, T> { +impl<'ast, T: Clone> Id<'ast, T> for BooleanExpression<'ast, T> { fn identifier(id: Identifier<'ast>) -> Self::Inner { - BooleanExpression::Identifier(id) + BooleanExpression::Identifier(IdentifierExpression::new(id)) } } -impl<'ast, T: Field> Id<'ast, T> for UExpression<'ast, T> { +impl<'ast, T: Clone> Id<'ast, T> for UExpression<'ast, T> { fn identifier(id: Identifier<'ast>) -> Self::Inner { - UExpressionInner::Identifier(id) + UExpressionInner::Identifier(IdentifierExpression::new(id)) } } -impl<'ast, T: Field> Id<'ast, T> for ArrayExpression<'ast, T> { +impl<'ast, T: Clone> Id<'ast, T> for ArrayExpression<'ast, T> { fn identifier(id: Identifier<'ast>) -> Self::Inner { - ArrayExpressionInner::Identifier(id) + ArrayExpressionInner::Identifier(IdentifierExpression::new(id)) } } -impl<'ast, T: Field> Id<'ast, T> for StructExpression<'ast, T> { +impl<'ast, T: Clone> Id<'ast, T> for StructExpression<'ast, T> { fn identifier(id: Identifier<'ast>) -> Self::Inner { - StructExpressionInner::Identifier(id) + StructExpressionInner::Identifier(IdentifierExpression::new(id)) } } diff --git a/zokrates_core/src/typed_absy/result_folder.rs b/zokrates_core/src/typed_absy/result_folder.rs index 19c2c4258..fae58c1ea 100644 --- a/zokrates_core/src/typed_absy/result_folder.rs +++ b/zokrates_core/src/typed_absy/result_folder.rs @@ -159,6 +159,14 @@ pub trait ResultFolder<'ast, T: Field>: Sized { fold_block_expression(self, block) } + fn fold_identifier_expression + Id<'ast, T> + ResultFold<'ast, T>>( + &mut self, + ty: &E::Ty, + id: IdentifierExpression<'ast, E>, + ) -> Result, Self::Error> { + fold_identifier_expression(self, ty, id) + } + fn fold_member_expression< E: Expr<'ast, T> + Member<'ast, T> + From>, >( @@ -412,7 +420,10 @@ pub fn fold_array_expression_inner<'ast, T: Field, F: ResultFolder<'ast, T>>( ArrayExpressionInner::Block(block) => { ArrayExpressionInner::Block(f.fold_block_expression(block)?) } - ArrayExpressionInner::Identifier(id) => ArrayExpressionInner::Identifier(f.fold_name(id)?), + ArrayExpressionInner::Identifier(id) => match f.fold_identifier_expression(ty, id)? { + IdentifierOrExpression::Identifier(i) => ArrayExpressionInner::Identifier(i), + IdentifierOrExpression::Expression(u) => u, + }, ArrayExpressionInner::Value(exprs) => ArrayExpressionInner::Value( exprs .into_iter() @@ -461,9 +472,10 @@ pub fn fold_struct_expression_inner<'ast, T: Field, F: ResultFolder<'ast, T>>( StructExpressionInner::Block(block) => { StructExpressionInner::Block(f.fold_block_expression(block)?) } - StructExpressionInner::Identifier(id) => { - StructExpressionInner::Identifier(f.fold_name(id)?) - } + StructExpressionInner::Identifier(id) => match f.fold_identifier_expression(ty, id)? { + IdentifierOrExpression::Identifier(i) => StructExpressionInner::Identifier(i), + IdentifierOrExpression::Expression(u) => u, + }, StructExpressionInner::Value(exprs) => StructExpressionInner::Value( exprs .into_iter() @@ -502,7 +514,10 @@ pub fn fold_field_expression<'ast, T: Field, F: ResultFolder<'ast, T>>( } FieldElementExpression::Number(n) => FieldElementExpression::Number(n), FieldElementExpression::Identifier(id) => { - FieldElementExpression::Identifier(f.fold_name(id)?) + match f.fold_identifier_expression(&Type::FieldElement, id)? { + IdentifierOrExpression::Identifier(i) => FieldElementExpression::Identifier(i), + IdentifierOrExpression::Expression(u) => u, + } } FieldElementExpression::Add(box e1, box e2) => { let e1 = f.fold_field_expression(e1)?; @@ -630,6 +645,21 @@ pub fn fold_member_expression< ))) } +pub fn fold_identifier_expression< + 'ast, + T: Field, + E: Expr<'ast, T> + Id<'ast, T> + From>, + F: ResultFolder<'ast, T>, +>( + f: &mut F, + _: &E::Ty, + e: IdentifierExpression<'ast, E>, +) -> Result, F::Error> { + Ok(IdentifierOrExpression::Identifier( + IdentifierExpression::new(f.fold_name(e.id)?), + )) +} + pub fn fold_select_expression< 'ast, T: Field, @@ -678,7 +708,12 @@ pub fn fold_boolean_expression<'ast, T: Field, F: ResultFolder<'ast, T>>( BooleanExpression::Block(f.fold_block_expression(block)?) } BooleanExpression::Value(v) => BooleanExpression::Value(v), - BooleanExpression::Identifier(id) => BooleanExpression::Identifier(f.fold_name(id)?), + BooleanExpression::Identifier(id) => { + match f.fold_identifier_expression(&Type::Boolean, id)? { + IdentifierOrExpression::Identifier(i) => BooleanExpression::Identifier(i), + IdentifierOrExpression::Expression(u) => u, + } + } BooleanExpression::FieldEq(box e1, box e2) => { let e1 = f.fold_field_expression(e1)?; let e2 = f.fold_field_expression(e2)?; @@ -800,7 +835,10 @@ pub fn fold_uint_expression_inner<'ast, T: Field, F: ResultFolder<'ast, T>>( let e = match e { UExpressionInner::Block(block) => UExpressionInner::Block(f.fold_block_expression(block)?), UExpressionInner::Value(v) => UExpressionInner::Value(v), - UExpressionInner::Identifier(id) => UExpressionInner::Identifier(f.fold_name(id)?), + UExpressionInner::Identifier(id) => match f.fold_identifier_expression(&ty, id)? { + IdentifierOrExpression::Identifier(i) => UExpressionInner::Identifier(i), + IdentifierOrExpression::Expression(u) => u, + }, UExpressionInner::Add(box left, box right) => { let left = f.fold_uint_expression(left)?; let right = f.fold_uint_expression(right)?; diff --git a/zokrates_core/src/typed_absy/types.rs b/zokrates_core/src/typed_absy/types.rs index 4b6453eb1..9db6bbd62 100644 --- a/zokrates_core/src/typed_absy/types.rs +++ b/zokrates_core/src/typed_absy/types.rs @@ -1,4 +1,4 @@ -use crate::typed_absy::{Identifier, OwnedTypedModuleId, UExpression, UExpressionInner}; +use crate::typed_absy::{Id, Identifier, OwnedTypedModuleId, UExpression, UExpressionInner}; use crate::typed_absy::{TryFrom, TryInto}; use serde::{de::Error, ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer}; use std::collections::BTreeMap; @@ -57,6 +57,11 @@ impl<'ast, T> Types<'ast, T> { } } +#[derive(Debug, Clone, PartialEq, Hash, Eq)] +pub struct ConcreteTypes { + pub inner: Vec, +} + #[derive(Debug, Clone, Eq, Ord)] pub struct GenericIdentifier<'ast> { pub name: &'ast str, @@ -142,15 +147,13 @@ impl<'ast, T> From for UExpression<'ast, T> { } } -impl<'ast, T> From> for UExpression<'ast, T> { +impl<'ast, T: Clone> From> for UExpression<'ast, T> { fn from(c: Constant<'ast>) -> Self { match c { - Constant::Generic(i) => { - UExpressionInner::Identifier(i.name.into()).annotate(UBitwidth::B32) - } + Constant::Generic(i) => UExpression::identifier(i.name.into()).annotate(UBitwidth::B32), Constant::Concrete(v) => UExpressionInner::Value(v as u128).annotate(UBitwidth::B32), Constant::Identifier(v, size) => { - UExpressionInner::Identifier(Identifier::from(v)).annotate(UBitwidth::from(size)) + UExpression::identifier(Identifier::from(v)).annotate(UBitwidth::from(size)) } } } @@ -229,7 +232,7 @@ impl<'ast> From for DeclarationStructMember<'ast> { } } -impl<'ast, T> From> for StructMember<'ast, T> { +impl<'ast, T: Clone> From> for StructMember<'ast, T> { fn from(t: DeclarationStructMember<'ast>) -> Self { try_from_g_struct_member(t).unwrap() } @@ -334,7 +337,7 @@ impl<'ast> From for DeclarationArrayType<'ast> { } } -impl<'ast, T> From> for ArrayType<'ast, T> { +impl<'ast, T: Clone> From> for ArrayType<'ast, T> { fn from(t: DeclarationArrayType<'ast>) -> Self { try_from_g_array_type(t).unwrap() } @@ -401,7 +404,7 @@ impl<'ast> From for DeclarationStructType<'ast> { } } -impl<'ast, T> From> for StructType<'ast, T> { +impl<'ast, T: Clone> From> for StructType<'ast, T> { fn from(t: DeclarationStructType<'ast>) -> Self { try_from_g_struct_type(t).unwrap() } @@ -637,7 +640,7 @@ impl<'ast> From for DeclarationType<'ast> { } } -impl<'ast, T> From> for Type<'ast, T> { +impl<'ast, T: Clone> From> for Type<'ast, T> { fn from(t: DeclarationType<'ast>) -> Self { try_from_g_type(t).unwrap() } @@ -852,7 +855,7 @@ impl<'ast> From> for DeclarationFunctionKey<'ast> { } } -impl<'ast, T> From> for FunctionKey<'ast, T> { +impl<'ast, T: Clone> From> for FunctionKey<'ast, T> { fn from(k: DeclarationFunctionKey<'ast>) -> Self { try_from_g_function_key(k).unwrap() } @@ -1165,7 +1168,7 @@ pub mod signature { } } - impl<'ast, T> From> for Signature<'ast, T> { + impl<'ast, T: Clone> From> for Signature<'ast, T> { fn from(s: DeclarationSignature<'ast>) -> Self { try_from_g_signature(s).unwrap() } diff --git a/zokrates_core/src/typed_absy/uint.rs b/zokrates_core/src/typed_absy/uint.rs index 4620dd7cf..8d2d89e7c 100644 --- a/zokrates_core/src/typed_absy/uint.rs +++ b/zokrates_core/src/typed_absy/uint.rs @@ -129,7 +129,7 @@ impl<'ast, T: Field> From for UExpressionInner<'ast, T> { impl<'ast, T: Field> From<&'ast str> for UExpressionInner<'ast, T> { fn from(e: &'ast str) -> Self { - UExpressionInner::Identifier(e.into()) + UExpressionInner::Identifier(IdentifierExpression::new(e.into())) } } @@ -176,7 +176,7 @@ impl<'ast, T> PartialEq for UExpression<'ast, T> { #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub enum UExpressionInner<'ast, T> { Block(BlockExpression<'ast, T, UExpression<'ast, T>>), - Identifier(Identifier<'ast>), + Identifier(IdentifierExpression<'ast, UExpression<'ast, T>>), Value(u128), Add(Box>, Box>), Sub(Box>, Box>), diff --git a/zokrates_core/src/typed_absy/variable.rs b/zokrates_core/src/typed_absy/variable.rs index 9151dfdcd..f8653fc4b 100644 --- a/zokrates_core/src/typed_absy/variable.rs +++ b/zokrates_core/src/typed_absy/variable.rs @@ -43,7 +43,7 @@ impl<'ast, T> From> for Variable<'ast, T> { } } -impl<'ast, T> From> for Variable<'ast, T> { +impl<'ast, T: Clone> From> for Variable<'ast, T> { fn from(v: DeclarationVariable<'ast>) -> Self { let _type = v._type.into(); From 4d09fe1c1958292fc6bd889af327f5010b8d4a23 Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 5 Sep 2022 19:31:40 +0200 Subject: [PATCH 02/16] disallow the use of the private keyword on non-entry point functions --- .../compile_errors/non_main_private_args.zok | 8 +++ zokrates_core/src/semantics.rs | 65 ++++++++++++------- 2 files changed, 49 insertions(+), 24 deletions(-) create mode 100644 zokrates_cli/examples/compile_errors/non_main_private_args.zok diff --git a/zokrates_cli/examples/compile_errors/non_main_private_args.zok b/zokrates_cli/examples/compile_errors/non_main_private_args.zok new file mode 100644 index 000000000..9a2c28fc5 --- /dev/null +++ b/zokrates_cli/examples/compile_errors/non_main_private_args.zok @@ -0,0 +1,8 @@ +def mul(private field a) -> field { // `private` should not be allowed here + return a * a; +} + +def main(private field a, field b) { + assert(mul(a) == b); + return; +} \ No newline at end of file diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index 8e27f27fd..661ee9e9c 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -89,6 +89,7 @@ type ConstantMap<'ast, T> = /// The global state of the program during semantic checks #[derive(Debug)] struct State<'ast, T> { + main_id: OwnedModuleId, /// The modules yet to be checked, which we consume as we explore the dependency tree modules: Modules<'ast>, /// The already checked modules, which we're returning at the end @@ -166,8 +167,9 @@ impl<'ast, T: std::cmp::Ord> SymbolUnifier<'ast, T> { } impl<'ast, T: Field> State<'ast, T> { - fn new(modules: Modules<'ast>) -> Self { + fn new(modules: Modules<'ast>, main_id: OwnedModuleId) -> Self { State { + main_id, modules, typed_modules: BTreeMap::new(), types: BTreeMap::new(), @@ -340,12 +342,13 @@ impl<'ast, T: Field> Checker<'ast, T> { &mut self, program: Program<'ast>, ) -> Result, Vec> { - let mut state = State::new(program.modules); + let main_id = program.main.clone(); + let mut state = State::new(program.modules, main_id.clone()); let mut errors = vec![]; // recursively type-check modules starting with `main` - match self.check_module(&program.main, &mut state) { + match self.check_module(&main_id, &mut state) { Ok(()) => {} Err(e) => errors.extend(e), }; @@ -354,9 +357,7 @@ impl<'ast, T: Field> Checker<'ast, T> { return Err(errors); } - let main_id = program.main.clone(); - - Checker::check_single_main(state.typed_modules.get(&program.main).unwrap()).map_err( + Checker::check_single_main(state.typed_modules.get(&main_id).unwrap()).map_err( |inner| { vec![Error { inner, @@ -762,24 +763,40 @@ impl<'ast, T: Field> Checker<'ast, T> { true => {} }; - self.functions.insert( - DeclarationFunctionKey::with_location( - module_id.to_path_buf(), - declaration.id, - ) - .signature(funct.signature.clone()), - ); - symbols.push( - TypedFunctionSymbolDeclaration::new( - DeclarationFunctionKey::with_location( - module_id.to_path_buf(), - declaration.id, - ) - .signature(funct.signature.clone()), - TypedFunctionSymbol::Here(funct), - ) - .into(), - ); + // parameters defined on a non-entrypoint function should not be set as private + match (state.main_id != module_id || declaration.id != "main") + && funct.arguments.iter().any(|a| a.private) + { + true => { + errors.push( + ErrorInner { + pos: Some(pos), + message: "Private argument(s) are only allowed on the entrypoint function".into(), + } + .in_file(module_id), + ); + } + false => { + self.functions.insert( + DeclarationFunctionKey::with_location( + module_id.to_path_buf(), + declaration.id, + ) + .signature(funct.signature.clone()), + ); + symbols.push( + TypedFunctionSymbolDeclaration::new( + DeclarationFunctionKey::with_location( + module_id.to_path_buf(), + declaration.id, + ) + .signature(funct.signature.clone()), + TypedFunctionSymbol::Here(funct), + ) + .into(), + ); + } + } } Err(e) => { errors.extend(e.into_iter().map(|inner| inner.in_file(module_id))); From 880a1ae95c6172163c364cde0d13efe4f280b267 Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 6 Sep 2022 12:57:06 +0200 Subject: [PATCH 03/16] add changelog --- changelogs/unreleased/1224-dark64 | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/1224-dark64 diff --git a/changelogs/unreleased/1224-dark64 b/changelogs/unreleased/1224-dark64 new file mode 100644 index 000000000..d1820feb8 --- /dev/null +++ b/changelogs/unreleased/1224-dark64 @@ -0,0 +1 @@ +Disallow the use of the `private` keyword on non-entrypoint functions \ No newline at end of file From 57ce308f975bbfb72adfd127dc9d41be010eaf4a Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 6 Sep 2022 13:50:40 +0200 Subject: [PATCH 04/16] fix tests --- zokrates_core/src/semantics.rs | 96 ++++++++++++------- .../stdlib/signatures/verifyEddsa.zok | 2 +- 2 files changed, 62 insertions(+), 36 deletions(-) diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index 661ee9e9c..f49b99741 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -3772,10 +3772,9 @@ mod tests { fn function1() -> FunctionNode<'static> { let statements = vec![Statement::Return(None).mock()]; - let arguments = vec![untyped::Parameter { - id: untyped::Variable::immutable("a", UnresolvedType::FieldElement.mock()).mock(), - is_private: true, - } + let arguments = vec![untyped::Parameter::public( + untyped::Variable::immutable("a", UnresolvedType::FieldElement.mock()).mock(), + ) .mock()]; let signature = @@ -3902,6 +3901,7 @@ mod tests { vec![("foo".into(), foo), ("bar".into(), bar)] .into_iter() .collect(), + (*MODULE_ID).clone(), ); let mut checker: Checker = Checker::default(); @@ -3956,6 +3956,7 @@ mod tests { let mut state = State::::new( vec![((*MODULE_ID).clone(), module)].into_iter().collect(), + (*MODULE_ID).clone(), ); let mut checker: Checker = Checker::default(); @@ -3969,10 +3970,10 @@ mod tests { #[test] fn duplicate_function_declaration_generic() { - // def foo

(private field[P] a) { + // def foo

(field[P] a) { // return; // } - // def foo(private field[3] a) { + // def foo(field[3] a) { // return; // } // @@ -3980,7 +3981,7 @@ mod tests { let mut f0 = function0(); - f0.value.arguments = vec![untyped::Parameter::private( + f0.value.arguments = vec![untyped::Parameter::public( untyped::Variable::immutable( "a", UnresolvedType::array( @@ -4002,7 +4003,7 @@ mod tests { let mut f1 = function0(); - f1.value.arguments = vec![untyped::Parameter::private( + f1.value.arguments = vec![untyped::Parameter::public( untyped::Variable::immutable( "a", UnresolvedType::array( @@ -4035,7 +4036,10 @@ mod tests { ], }; - let mut state = State::new(vec![((*MODULE_ID).clone(), module)].into_iter().collect()); + let mut state = State::new( + vec![((*MODULE_ID).clone(), module)].into_iter().collect(), + (*MODULE_ID).clone(), + ); let mut checker: Checker = Checker::default(); assert!(checker.check_module(&*MODULE_ID, &mut state).is_ok()); @@ -4074,8 +4078,10 @@ mod tests { ], }; - let mut state = - State::new(vec![((*MODULE_ID).clone(), module)].into_iter().collect()); + let mut state = State::new( + vec![((*MODULE_ID).clone(), module)].into_iter().collect(), + (*MODULE_ID).clone(), + ); let mut checker: Checker = Checker::default(); assert!(checker.check_module(&*MODULE_ID, &mut state).is_ok()); @@ -4128,8 +4134,10 @@ mod tests { ], }; - let mut state = - State::new(vec![((*MODULE_ID).clone(), module)].into_iter().collect()); + let mut state = State::new( + vec![((*MODULE_ID).clone(), module)].into_iter().collect(), + (*MODULE_ID).clone(), + ); let mut checker: Checker = Checker::default(); assert_eq!( @@ -4169,6 +4177,7 @@ mod tests { let mut state = State::::new( vec![((*MODULE_ID).clone(), module)].into_iter().collect(), + (*MODULE_ID).clone(), ); let mut checker: Checker = Checker::default(); @@ -4218,6 +4227,7 @@ mod tests { let mut state = State::::new( vec![((*MODULE_ID).clone(), module)].into_iter().collect(), + (*MODULE_ID).clone(), ); let mut checker: Checker = Checker::default(); @@ -4261,6 +4271,7 @@ mod tests { let mut state = State::::new( vec![((*MODULE_ID).clone(), module)].into_iter().collect(), + (*MODULE_ID).clone(), ); let mut checker: Checker = Checker::default(); @@ -4312,6 +4323,7 @@ mod tests { vec![((*MODULE_ID).clone(), main), ("bar".into(), bar)] .into_iter() .collect(), + (*MODULE_ID).clone(), ); let mut checker: Checker = Checker::default(); @@ -4360,6 +4372,7 @@ mod tests { vec![((*MODULE_ID).clone(), main), ("bar".into(), bar)] .into_iter() .collect(), + (*MODULE_ID).clone(), ); let mut checker: Checker = Checker::default(); @@ -4390,7 +4403,7 @@ mod tests { #[test] fn undeclared_generic() { let modules = Modules::new(); - let state = State::new(modules); + let state = State::new(modules, (*MODULE_ID).clone()); let signature = UnresolvedSignature::new().inputs(vec![UnresolvedType::Array( box UnresolvedType::FieldElement.mock(), @@ -4410,7 +4423,7 @@ mod tests { fn success() { // (field[L][K]) -> field[L][K] let modules = Modules::new(); - let state = State::new(modules); + let state = State::new(modules, (*MODULE_ID).clone()); let signature = UnresolvedSignature::new() .generics(vec!["K".mock(), "L".mock(), "M".mock()]) @@ -4563,8 +4576,10 @@ mod tests { ]; let module = Module { symbols }; - let mut state = - State::::new(vec![((*MODULE_ID).clone(), module)].into_iter().collect()); + let mut state = State::::new( + vec![((*MODULE_ID).clone(), module)].into_iter().collect(), + (*MODULE_ID).clone(), + ); let mut checker: Checker = Checker::default(); assert_eq!( @@ -4658,8 +4673,10 @@ mod tests { ]; let module = Module { symbols }; - let mut state = - State::::new(vec![((*MODULE_ID).clone(), module)].into_iter().collect()); + let mut state = State::::new( + vec![((*MODULE_ID).clone(), module)].into_iter().collect(), + (*MODULE_ID).clone(), + ); let mut checker: Checker = Checker::default(); assert!(checker.check_module(&*MODULE_ID, &mut state).is_ok()); @@ -4692,7 +4709,7 @@ mod tests { .mock(); let modules = Modules::new(); - let state = State::new(modules); + let state = State::new(modules, (*MODULE_ID).clone()); let mut checker: Checker = Checker::default(); assert_eq!( @@ -4771,7 +4788,7 @@ mod tests { }; let modules = Modules::new(); - let state = State::new(modules); + let state = State::new(modules, (*MODULE_ID).clone()); let mut checker: Checker = Checker::default(); assert_eq!( @@ -4818,7 +4835,7 @@ mod tests { .mock(); let modules = Modules::new(); - let state = State::new(modules); + let state = State::new(modules, (*MODULE_ID).clone()); let mut checker: Checker = new_with_args(Scope::default(), functions); assert_eq!( @@ -4857,7 +4874,7 @@ mod tests { .mock(); let modules = Modules::new(); - let state = State::new(modules); + let state = State::new(modules, (*MODULE_ID).clone()); let mut checker: Checker = new_with_args(Scope::default(), HashSet::new()); assert_eq!( @@ -4929,8 +4946,10 @@ mod tests { ], }; - let mut state = - State::::new(vec![((*MODULE_ID).clone(), module)].into_iter().collect()); + let mut state = State::::new( + vec![((*MODULE_ID).clone(), module)].into_iter().collect(), + (*MODULE_ID).clone(), + ); let mut checker: Checker = new_with_args(Scope::default(), HashSet::new()); assert_eq!( @@ -5025,8 +5044,10 @@ mod tests { ], }; - let mut state = - State::::new(vec![((*MODULE_ID).clone(), module)].into_iter().collect()); + let mut state = State::::new( + vec![((*MODULE_ID).clone(), module)].into_iter().collect(), + (*MODULE_ID).clone(), + ); let mut checker: Checker = new_with_args(Scope::default(), HashSet::new()); assert!(checker.check_module(&*MODULE_ID, &mut state).is_ok()); @@ -5066,7 +5087,7 @@ mod tests { .mock(); let modules = Modules::new(); - let state = State::new(modules); + let state = State::new(modules, (*MODULE_ID).clone()); let mut checker: Checker = new_with_args(Scope::default(), HashSet::new()); assert_eq!( @@ -5099,7 +5120,7 @@ mod tests { .mock(); let modules = Modules::new(); - let state = State::new(modules); + let state = State::new(modules, (*MODULE_ID).clone()); let mut checker: Checker = new_with_args(Scope::default(), HashSet::new()); assert_eq!( @@ -5136,7 +5157,7 @@ mod tests { ]); let modules = Modules::new(); - let state = State::new(modules); + let state = State::new(modules, (*MODULE_ID).clone()); let mut checker: Checker = new_with_args(Scope::default(), HashSet::new()); assert_eq!( @@ -5430,6 +5451,7 @@ mod tests { let mut state = State::::new( vec![((*MODULE_ID).clone(), module)].into_iter().collect(), + (*MODULE_ID).clone(), ); let mut checker: Checker = Checker::default(); @@ -5447,7 +5469,7 @@ mod tests { fn empty_def() { // an empty struct should be allowed to be defined let modules = Modules::new(); - let state = State::new(modules); + let state = State::new(modules, (*MODULE_ID).clone()); let declaration: StructDefinitionNode = StructDefinition { generics: vec![], @@ -5473,7 +5495,7 @@ mod tests { fn valid_def() { // a valid struct should be allowed to be defined let modules = Modules::new(); - let state = State::new(modules); + let state = State::new(modules, (*MODULE_ID).clone()); let declaration: StructDefinitionNode = StructDefinition { generics: vec![], @@ -5517,7 +5539,7 @@ mod tests { fn duplicate_member_def() { // definition of a struct with a duplicate member should be rejected let modules = Modules::new(); - let state = State::new(modules); + let state = State::new(modules, (*MODULE_ID).clone()); let declaration: StructDefinitionNode = StructDefinition { generics: vec![], @@ -5594,6 +5616,7 @@ mod tests { let mut state = State::::new( vec![((*MODULE_ID).clone(), module)].into_iter().collect(), + (*MODULE_ID).clone(), ); assert!(Checker::default() @@ -5653,6 +5676,7 @@ mod tests { let mut state = State::::new( vec![((*MODULE_ID).clone(), module)].into_iter().collect(), + (*MODULE_ID).clone(), ); assert!(Checker::default() @@ -5686,6 +5710,7 @@ mod tests { let mut state = State::::new( vec![((*MODULE_ID).clone(), module)].into_iter().collect(), + (*MODULE_ID).clone(), ); assert!(Checker::default() @@ -5737,6 +5762,7 @@ mod tests { let mut state = State::::new( vec![((*MODULE_ID).clone(), module)].into_iter().collect(), + (*MODULE_ID).clone(), ); assert!(Checker::default() @@ -6153,7 +6179,7 @@ mod tests { let mut foo_field = function0(); - foo_field.value.arguments = vec![untyped::Parameter::private( + foo_field.value.arguments = vec![untyped::Parameter::public( untyped::Variable::immutable("a", UnresolvedType::FieldElement.mock()).mock(), ) .mock()]; @@ -6165,7 +6191,7 @@ mod tests { let mut foo_u32 = function0(); - foo_u32.value.arguments = vec![untyped::Parameter::private( + foo_u32.value.arguments = vec![untyped::Parameter::public( untyped::Variable::immutable("a", UnresolvedType::Uint(32).mock()).mock(), ) .mock()]; diff --git a/zokrates_stdlib/stdlib/signatures/verifyEddsa.zok b/zokrates_stdlib/stdlib/signatures/verifyEddsa.zok index 18a3969db..e6e2f8069 100644 --- a/zokrates_stdlib/stdlib/signatures/verifyEddsa.zok +++ b/zokrates_stdlib/stdlib/signatures/verifyEddsa.zok @@ -29,7 +29,7 @@ import "utils/casts/u32_8_to_bool_256"; /// /// Returns: /// Return true for S being a valid EdDSA Signature, false otherwise. -def main(private field[2] R, private field S, field[2] A, u32[8] M0, u32[8] M1, BabyJubJubParams context) -> bool { +def main(field[2] R, field S, field[2] A, u32[8] M0, u32[8] M1, BabyJubJubParams context) -> bool { field[2] G = [context.Gu, context.Gv]; // Check if R is on curve and if it is not in a small subgroup. A is public input and can be checked offline From e005515bcce906eb1a8f346091fde8bd09c65a89 Mon Sep 17 00:00:00 2001 From: schaeff Date: Tue, 6 Sep 2022 22:05:22 +0200 Subject: [PATCH 05/16] fix warning --- .../static_analysis/flatten_complex_types.rs | 36 +++++++------------ 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/zokrates_core/src/static_analysis/flatten_complex_types.rs b/zokrates_core/src/static_analysis/flatten_complex_types.rs index c9ff962fc..2764ab0a9 100644 --- a/zokrates_core/src/static_analysis/flatten_complex_types.rs +++ b/zokrates_core/src/static_analysis/flatten_complex_types.rs @@ -271,11 +271,10 @@ impl<'ast, T: Field> Flattener { fn fold_identifier_expression>( &mut self, - statements_buffer: &mut Vec>, ty: &E::ConcreteTy, e: typed::IdentifierExpression<'ast, E>, ) -> Vec> { - fold_identifier_expression::(self, statements_buffer, ty, e) + fold_identifier_expression::(self, ty, e) } fn fold_array_expression( @@ -482,11 +481,9 @@ fn fold_array_expression_inner<'ast, T: Field>( .for_each(|s| f.fold_statement(statements_buffer, s)); f.fold_array_expression(statements_buffer, *block.value) } - typed::ArrayExpressionInner::Identifier(id) => f.fold_identifier_expression( - statements_buffer, - &ConcreteArrayType::new(ty.clone(), size), - id, - ), + typed::ArrayExpressionInner::Identifier(id) => { + f.fold_identifier_expression(&ConcreteArrayType::new(ty.clone(), size), id) + } typed::ArrayExpressionInner::Value(exprs) => { let exprs: Vec<_> = exprs .into_iter() @@ -553,9 +550,7 @@ fn fold_struct_expression_inner<'ast, T: Field>( .for_each(|s| f.fold_statement(statements_buffer, s)); f.fold_struct_expression(statements_buffer, *block.value) } - typed::StructExpressionInner::Identifier(id) => { - f.fold_identifier_expression(statements_buffer, ty, id) - } + typed::StructExpressionInner::Identifier(id) => f.fold_identifier_expression(ty, id), typed::StructExpressionInner::Value(exprs) => exprs .into_iter() .flat_map(|e| f.fold_expression(statements_buffer, e)) @@ -588,9 +583,7 @@ fn fold_tuple_expression_inner<'ast, T: Field>( .for_each(|s| f.fold_statement(statements_buffer, s)); f.fold_tuple_expression(statements_buffer, *block.value) } - typed::TupleExpressionInner::Identifier(id) => { - f.fold_identifier_expression(statements_buffer, ty, id) - } + typed::TupleExpressionInner::Identifier(id) => f.fold_identifier_expression(ty, id), typed::TupleExpressionInner::Value(exprs) => exprs .into_iter() .flat_map(|e| f.fold_expression(statements_buffer, e)) @@ -802,7 +795,6 @@ fn fold_conditional_expression<'ast, T: Field, E: Flatten<'ast, T>>( fn fold_identifier_expression<'ast, T: Field, E: Expr<'ast, T>>( f: &mut Flattener, - statements_buffer: &mut Vec>, ty: &E::ConcreteTy, e: typed::IdentifierExpression<'ast, E>, ) -> Vec> { @@ -820,7 +812,7 @@ fn fold_field_expression<'ast, T: Field>( match e { typed::FieldElementExpression::Number(n) => zir::FieldElementExpression::Number(n), typed::FieldElementExpression::Identifier(id) => f - .fold_identifier_expression(statements_buffer, &typed::ConcreteType::FieldElement, id) + .fold_identifier_expression(&typed::ConcreteType::FieldElement, id) .pop() .unwrap() .try_into() @@ -950,7 +942,7 @@ fn fold_boolean_expression<'ast, T: Field>( } typed::BooleanExpression::Value(v) => zir::BooleanExpression::Value(v), typed::BooleanExpression::Identifier(id) => f - .fold_identifier_expression(statements_buffer, &typed::ConcreteType::Boolean, id) + .fold_identifier_expression(&typed::ConcreteType::Boolean, id) .pop() .unwrap() .try_into() @@ -1068,13 +1060,11 @@ fn fold_uint_expression_inner<'ast, T: Field>( .into_inner() } typed::UExpressionInner::Value(v) => zir::UExpressionInner::Value(v), - typed::UExpressionInner::Identifier(id) => zir::UExpression::try_from( - f.fold_identifier_expression(statements_buffer, &bitwidth, id) - .pop() - .unwrap(), - ) - .unwrap() - .into_inner(), + typed::UExpressionInner::Identifier(id) => { + zir::UExpression::try_from(f.fold_identifier_expression(&bitwidth, id).pop().unwrap()) + .unwrap() + .into_inner() + } typed::UExpressionInner::Add(box left, box right) => { let left = f.fold_uint_expression(statements_buffer, left); let right = f.fold_uint_expression(statements_buffer, right); From 418713be01d40b66ce4841f9f6934eb174791f28 Mon Sep 17 00:00:00 2001 From: schaeff Date: Wed, 7 Sep 2022 00:08:52 +0200 Subject: [PATCH 06/16] clippy, clean --- zokrates_ast/src/typed/mod.rs | 2 +- zokrates_ast/src/typed/types.rs | 49 +-------------------------------- zokrates_ast/src/typed/uint.rs | 6 ---- 3 files changed, 2 insertions(+), 55 deletions(-) diff --git a/zokrates_ast/src/typed/mod.rs b/zokrates_ast/src/typed/mod.rs index 20c91c541..3998da1b4 100644 --- a/zokrates_ast/src/typed/mod.rs +++ b/zokrates_ast/src/typed/mod.rs @@ -1958,7 +1958,7 @@ impl<'ast, T: Field> 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_ast/src/typed/types.rs b/zokrates_ast/src/typed/types.rs index 88c69ac6e..f983ed4f2 100644 --- a/zokrates_ast/src/typed/types.rs +++ b/zokrates_ast/src/typed/types.rs @@ -56,11 +56,6 @@ impl<'ast> From> for CoreIdentifier<'ast> { } } -#[derive(Debug, Clone, PartialEq, Hash, Eq)] -pub struct ConcreteTypes { - pub inner: Vec, -} - impl<'ast> GenericIdentifier<'ast> { pub fn without_name() -> Self { Self { @@ -323,18 +318,6 @@ impl<'ast, T> From for StructMember<'ast, T> { } } -impl<'ast, T: Field> From for DeclarationStructMember<'ast, T> { - fn from(t: ConcreteStructMember) -> Self { - try_from_g_struct_member(t).unwrap() - } -} - -impl<'ast, T: Field> From> for StructMember<'ast, T> { - fn from(t: DeclarationStructMember<'ast, T>) -> Self { - try_from_g_struct_member(t).unwrap() - } -} - #[allow(clippy::derive_hash_xor_eq)] #[derive(Clone, Eq, Hash, Serialize, Deserialize, PartialOrd, Ord, Debug)] pub struct GArrayType { @@ -494,12 +477,6 @@ impl<'ast, T> From for DeclarationArrayType<'ast, T> { } } -impl<'ast, T: Field> From> for ArrayType<'ast, T> { - fn from(t: DeclarationArrayType<'ast, T>) -> Self { - try_from_g_array_type(t).unwrap() - } -} - #[derive(Debug, Clone, Serialize, Deserialize, PartialOrd, Ord)] pub struct GStructType { #[serde(flatten)] @@ -579,12 +556,6 @@ impl<'ast, T> From for DeclarationStructType<'ast, T> { } } -impl<'ast, T: Field> From> for StructType<'ast, T> { - fn from(t: DeclarationStructType<'ast, T>) -> Self { - try_from_g_struct_type(t).unwrap() - } -} - impl GStructType { pub fn new( module: PathBuf, @@ -841,12 +812,6 @@ impl<'ast, T> From for DeclarationType<'ast, T> { } } -impl<'ast, T: Field> From> for Type<'ast, T> { - fn from(t: DeclarationType<'ast, T>) -> Self { - try_from_g_type(t).unwrap() - } -} - impl> From<(GType, U)> for GArrayType { fn from(tup: (GType, U)) -> Self { GArrayType { @@ -1075,12 +1040,6 @@ impl<'ast, T> From> for DeclarationFunctionKey<'ast, T } } -impl<'ast, T: Field> From> for FunctionKey<'ast, T> { - fn from(k: DeclarationFunctionKey<'ast, T>) -> Self { - try_from_g_function_key(k).unwrap() - } -} - impl<'ast, S> GFunctionKey<'ast, S> { pub fn with_location, U: Into>>( module: T, @@ -1181,7 +1140,7 @@ pub fn check_type<'ast, T, S: Clone + PartialEq + PartialEq>( impl<'ast, T: Field> From> for UExpression<'ast, T> { fn from(c: CanonicalConstantIdentifier<'ast>) -> Self { - UExpression::identifier(Identifier::from(CoreIdentifier::Constant(c)).into()) + UExpression::identifier(Identifier::from(CoreIdentifier::Constant(c))) .annotate(UBitwidth::B32) } } @@ -1458,12 +1417,6 @@ pub mod signature { } } - impl<'ast, T: Field> From> for Signature<'ast, T> { - fn from(s: DeclarationSignature<'ast, T>) -> Self { - try_from_g_signature(s).unwrap() - } - } - impl fmt::Display for GSignature { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if !self.generics.is_empty() { diff --git a/zokrates_ast/src/typed/uint.rs b/zokrates_ast/src/typed/uint.rs index eb4f028f2..c2120fc6f 100644 --- a/zokrates_ast/src/typed/uint.rs +++ b/zokrates_ast/src/typed/uint.rs @@ -127,12 +127,6 @@ impl<'ast, T: Field> From for UExpressionInner<'ast, T> { } } -impl<'ast, T: Field> From<&'ast str> for UExpressionInner<'ast, T> { - fn from(e: &'ast str) -> Self { - UExpressionInner::Identifier(IdentifierExpression::new(e.into())) - } -} - #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct UMetadata { pub bitwidth: Option, From c3f01f8ed01c2354715cdc2d25cee27eeb2e4a7a Mon Sep 17 00:00:00 2001 From: schaeff Date: Wed, 7 Sep 2022 14:00:50 +0200 Subject: [PATCH 07/16] clean --- .../src/static_analysis/constant_inliner.rs | 871 ------------------ .../static_analysis/flatten_complex_types.rs | 34 +- 2 files changed, 17 insertions(+), 888 deletions(-) delete mode 100644 zokrates_core/src/static_analysis/constant_inliner.rs diff --git a/zokrates_core/src/static_analysis/constant_inliner.rs b/zokrates_core/src/static_analysis/constant_inliner.rs deleted file mode 100644 index 0da69115b..000000000 --- a/zokrates_core/src/static_analysis/constant_inliner.rs +++ /dev/null @@ -1,871 +0,0 @@ -use crate::static_analysis::Propagator; -use crate::typed_absy::folder::*; -use crate::typed_absy::result_folder::ResultFolder; -use crate::typed_absy::types::DeclarationConstant; -use crate::typed_absy::*; -use std::collections::HashMap; -use std::convert::TryInto; -use zokrates_field::Field; - -type ProgramConstants<'ast, T> = - HashMap, TypedExpression<'ast, T>>>; - -pub struct ConstantInliner<'ast, T> { - modules: TypedModules<'ast, T>, - location: OwnedTypedModuleId, - constants: ProgramConstants<'ast, T>, -} - -impl<'ast, 'a, T: Field> ConstantInliner<'ast, T> { - pub fn new( - modules: TypedModules<'ast, T>, - location: OwnedTypedModuleId, - constants: ProgramConstants<'ast, T>, - ) -> Self { - ConstantInliner { - modules, - location, - constants, - } - } - pub fn inline(p: TypedProgram<'ast, T>) -> TypedProgram<'ast, T> { - let constants = ProgramConstants::new(); - let mut inliner = ConstantInliner::new(p.modules.clone(), p.main.clone(), constants); - inliner.fold_program(p) - } - - fn change_location(&mut self, location: OwnedTypedModuleId) -> OwnedTypedModuleId { - let prev = self.location.clone(); - self.location = location; - self.constants.entry(self.location.clone()).or_default(); - prev - } - - fn treated(&self, id: &TypedModuleId) -> bool { - self.constants.contains_key(id) - } - - fn get_constant( - &self, - id: &CanonicalConstantIdentifier<'ast>, - ) -> Option> { - self.constants - .get(&id.module) - .and_then(|constants| constants.get(&id.id.into())) - .cloned() - } - - fn get_constant_for_identifier( - &self, - id: &Identifier<'ast>, - ) -> Option> { - self.constants - .get(&self.location) - .and_then(|constants| constants.get(&id)) - .cloned() - } -} - -impl<'ast, T: Field> Folder<'ast, T> for ConstantInliner<'ast, T> { - fn fold_program(&mut self, p: TypedProgram<'ast, T>) -> TypedProgram<'ast, T> { - self.fold_module_id(p.main.clone()); - - TypedProgram { - modules: std::mem::take(&mut self.modules), - ..p - } - } - - fn fold_module_id(&mut self, id: OwnedTypedModuleId) -> OwnedTypedModuleId { - // anytime we encounter a module id, visit the corresponding module if it hasn't been done yet - if !self.treated(&id) { - let current_m_id = self.change_location(id.clone()); - let m = self.modules.remove(&id).unwrap(); - let m = self.fold_module(m); - self.modules.insert(id.clone(), m); - self.change_location(current_m_id); - } - id - } - - fn fold_module(&mut self, m: TypedModule<'ast, T>) -> TypedModule<'ast, T> { - TypedModule { - constants: m - .constants - .into_iter() - .map(|(id, tc)| { - let constant = match tc { - TypedConstantSymbol::There(imported_id) => { - // visit the imported symbol. This triggers visiting the corresponding module if needed - let imported_id = self.fold_canonical_constant_identifier(imported_id); - // after that, the constant must have been defined defined in the global map. It is already reduced - // to a literal, so running propagation isn't required - self.get_constant(&imported_id).unwrap() - } - TypedConstantSymbol::Here(c) => { - let non_propagated_constant = fold_constant(self, c).expression; - // folding the constant above only reduces it to an expression containing only literals, not to a single literal. - // propagating with an empty map of constants reduces it to a single literal - Propagator::with_constants(&mut HashMap::default()) - .fold_expression(non_propagated_constant) - .unwrap() - } - }; - - // add to the constant map. The value added is always a single litteral - self.constants - .get_mut(&self.location) - .unwrap() - .insert(id.id.into(), constant.clone()); - - ( - id, - TypedConstantSymbol::Here(TypedConstant { - expression: constant, - }), - ) - }) - .collect(), - functions: m - .functions - .into_iter() - .map(|(key, fun)| { - ( - self.fold_declaration_function_key(key), - self.fold_function_symbol(fun), - ) - }) - .collect(), - } - } - - fn fold_declaration_constant( - &mut self, - c: DeclarationConstant<'ast>, - ) -> DeclarationConstant<'ast> { - match c { - // replace constants by their concrete value in declaration types - DeclarationConstant::Constant(id) => { - let id = CanonicalConstantIdentifier { - module: self.fold_module_id(id.module), - ..id - }; - - DeclarationConstant::Concrete(match self.get_constant(&id).unwrap() { - TypedExpression::Uint(UExpression { - inner: UExpressionInner::Value(v), - .. - }) => v as u32, - _ => unreachable!("all constants found in declaration types should be reduceable to u32 literals"), - }) - } - c => c, - } - } - - fn fold_identifier_expression< - E: Expr<'ast, T> + Id<'ast, T> + From>, - >( - &mut self, - _: &E::Ty, - e: IdentifierExpression<'ast, E>, - ) -> IdentifierOrExpression<'ast, T, E> { - match self.get_constant_for_identifier(&e.id) { - Some(c) => IdentifierOrExpression::Expression(E::from(c).into_inner()), - None => IdentifierOrExpression::Identifier(e), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::typed_absy::types::DeclarationSignature; - use crate::typed_absy::{ - DeclarationArrayType, DeclarationFunctionKey, DeclarationType, FieldElementExpression, - GType, Identifier, TypedConstant, TypedExpression, TypedFunction, TypedFunctionSymbol, - TypedStatement, - }; - use zokrates_field::Bn128Field; - - #[test] - fn inline_const_field() { - // const field a = 1 - // - // def main() -> field: - // return a - - let const_id = "a"; - let main: TypedFunction = TypedFunction { - arguments: vec![], - statements: vec![TypedStatement::Return(vec![ - FieldElementExpression::Identifier(Identifier::from(const_id)).into(), - ])], - signature: DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::FieldElement]), - }; - - let constants: TypedConstantSymbols<_> = vec![( - CanonicalConstantIdentifier::new( - const_id, - "main".into(), - DeclarationType::FieldElement, - ), - TypedConstantSymbol::Here(TypedConstant::new(TypedExpression::FieldElement( - FieldElementExpression::Number(Bn128Field::from(1)), - ))), - )] - .into_iter() - .collect(); - - let program = TypedProgram { - main: "main".into(), - modules: vec![( - "main".into(), - TypedModule { - functions: vec![( - DeclarationFunctionKey::with_location("main", "main").signature( - DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::FieldElement]), - ), - TypedFunctionSymbol::Here(main), - )] - .into_iter() - .collect(), - constants: constants.clone(), - }, - )] - .into_iter() - .collect(), - }; - - let program = ConstantInliner::inline(program); - - let expected_main = TypedFunction { - arguments: vec![], - statements: vec![TypedStatement::Return(vec![ - FieldElementExpression::Number(Bn128Field::from(1)).into(), - ])], - signature: DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::FieldElement]), - }; - - let expected_program: TypedProgram = TypedProgram { - main: "main".into(), - modules: vec![( - "main".into(), - TypedModule { - functions: vec![( - DeclarationFunctionKey::with_location("main", "main").signature( - DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::FieldElement]), - ), - TypedFunctionSymbol::Here(expected_main), - )] - .into_iter() - .collect(), - constants, - }, - )] - .into_iter() - .collect(), - }; - - assert_eq!(program, expected_program) - } - - #[test] - fn inline_const_boolean() { - // const bool a = true - // - // def main() -> bool: - // return a - - let const_id = "a"; - let main: TypedFunction = TypedFunction { - arguments: vec![], - statements: vec![TypedStatement::Return(vec![BooleanExpression::Identifier( - Identifier::from(const_id), - ) - .into()])], - signature: DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::Boolean]), - }; - - let constants: TypedConstantSymbols<_> = vec![( - CanonicalConstantIdentifier::new(const_id, "main".into(), DeclarationType::Boolean), - TypedConstantSymbol::Here(TypedConstant::new(TypedExpression::Boolean( - BooleanExpression::Value(true), - ))), - )] - .into_iter() - .collect(); - - let program = TypedProgram { - main: "main".into(), - modules: vec![( - "main".into(), - TypedModule { - functions: vec![( - DeclarationFunctionKey::with_location("main", "main").signature( - DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::Boolean]), - ), - TypedFunctionSymbol::Here(main), - )] - .into_iter() - .collect(), - constants: constants.clone(), - }, - )] - .into_iter() - .collect(), - }; - - let program = ConstantInliner::inline(program); - - let expected_main = TypedFunction { - arguments: vec![], - statements: vec![TypedStatement::Return(vec![ - BooleanExpression::Value(true).into() - ])], - signature: DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::Boolean]), - }; - - let expected_program: TypedProgram = TypedProgram { - main: "main".into(), - modules: vec![( - "main".into(), - TypedModule { - functions: vec![( - DeclarationFunctionKey::with_location("main", "main").signature( - DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::Boolean]), - ), - TypedFunctionSymbol::Here(expected_main), - )] - .into_iter() - .collect(), - constants, - }, - )] - .into_iter() - .collect(), - }; - - assert_eq!(program, expected_program) - } - - #[test] - fn inline_const_uint() { - // const u32 a = 0x00000001 - // - // def main() -> u32: - // return a - - let const_id = "a"; - let main: TypedFunction = TypedFunction { - arguments: vec![], - statements: vec![TypedStatement::Return(vec![UExpressionInner::Identifier( - Identifier::from(const_id), - ) - .annotate(UBitwidth::B32) - .into()])], - signature: DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::Uint(UBitwidth::B32)]), - }; - - let constants: TypedConstantSymbols<_> = vec![( - CanonicalConstantIdentifier::new( - const_id, - "main".into(), - DeclarationType::Uint(UBitwidth::B32), - ), - TypedConstantSymbol::Here(TypedConstant::new( - UExpressionInner::Value(1u128) - .annotate(UBitwidth::B32) - .into(), - )), - )] - .into_iter() - .collect(); - - let program = TypedProgram { - main: "main".into(), - modules: vec![( - "main".into(), - TypedModule { - functions: vec![( - DeclarationFunctionKey::with_location("main", "main").signature( - DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::Uint(UBitwidth::B32)]), - ), - TypedFunctionSymbol::Here(main), - )] - .into_iter() - .collect(), - constants: constants.clone(), - }, - )] - .into_iter() - .collect(), - }; - - let program = ConstantInliner::inline(program); - - let expected_main = TypedFunction { - arguments: vec![], - statements: vec![TypedStatement::Return(vec![UExpressionInner::Value(1u128) - .annotate(UBitwidth::B32) - .into()])], - signature: DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::Uint(UBitwidth::B32)]), - }; - - let expected_program: TypedProgram = TypedProgram { - main: "main".into(), - modules: vec![( - "main".into(), - TypedModule { - functions: vec![( - DeclarationFunctionKey::with_location("main", "main").signature( - DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::Uint(UBitwidth::B32)]), - ), - TypedFunctionSymbol::Here(expected_main), - )] - .into_iter() - .collect(), - constants, - }, - )] - .into_iter() - .collect(), - }; - - assert_eq!(program, expected_program) - } - - #[test] - fn inline_const_field_array() { - // const field[2] a = [2, 2] - // - // def main() -> field: - // return a[0] + a[1] - - let const_id = "a"; - let main: TypedFunction = TypedFunction { - arguments: vec![], - statements: vec![TypedStatement::Return(vec![FieldElementExpression::Add( - FieldElementExpression::select( - ArrayExpressionInner::Identifier(Identifier::from(const_id)) - .annotate(GType::FieldElement, 2usize), - UExpressionInner::Value(0u128).annotate(UBitwidth::B32), - ) - .into(), - FieldElementExpression::select( - ArrayExpressionInner::Identifier(Identifier::from(const_id)) - .annotate(GType::FieldElement, 2usize), - UExpressionInner::Value(1u128).annotate(UBitwidth::B32), - ) - .into(), - ) - .into()])], - signature: DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::FieldElement]), - }; - - let constants: TypedConstantSymbols<_> = vec![( - CanonicalConstantIdentifier::new( - const_id, - "main".into(), - DeclarationType::Array(DeclarationArrayType::new( - DeclarationType::FieldElement, - 2u32, - )), - ), - TypedConstantSymbol::Here(TypedConstant::new(TypedExpression::Array( - ArrayExpressionInner::Value( - vec![ - FieldElementExpression::Number(Bn128Field::from(2)).into(), - FieldElementExpression::Number(Bn128Field::from(2)).into(), - ] - .into(), - ) - .annotate(GType::FieldElement, 2usize), - ))), - )] - .into_iter() - .collect(); - - let program = TypedProgram { - main: "main".into(), - modules: vec![( - "main".into(), - TypedModule { - functions: vec![( - DeclarationFunctionKey::with_location("main", "main").signature( - DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::FieldElement]), - ), - TypedFunctionSymbol::Here(main), - )] - .into_iter() - .collect(), - constants: constants.clone(), - }, - )] - .into_iter() - .collect(), - }; - - let program = ConstantInliner::inline(program); - - let expected_main = TypedFunction { - arguments: vec![], - statements: vec![TypedStatement::Return(vec![FieldElementExpression::Add( - FieldElementExpression::select( - ArrayExpressionInner::Value( - vec![ - FieldElementExpression::Number(Bn128Field::from(2)).into(), - FieldElementExpression::Number(Bn128Field::from(2)).into(), - ] - .into(), - ) - .annotate(GType::FieldElement, 2usize), - UExpressionInner::Value(0u128).annotate(UBitwidth::B32), - ) - .into(), - FieldElementExpression::select( - ArrayExpressionInner::Value( - vec![ - FieldElementExpression::Number(Bn128Field::from(2)).into(), - FieldElementExpression::Number(Bn128Field::from(2)).into(), - ] - .into(), - ) - .annotate(GType::FieldElement, 2usize), - UExpressionInner::Value(1u128).annotate(UBitwidth::B32), - ) - .into(), - ) - .into()])], - signature: DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::FieldElement]), - }; - - let expected_program: TypedProgram = TypedProgram { - main: "main".into(), - modules: vec![( - "main".into(), - TypedModule { - functions: vec![( - DeclarationFunctionKey::with_location("main", "main").signature( - DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::FieldElement]), - ), - TypedFunctionSymbol::Here(expected_main), - )] - .into_iter() - .collect(), - constants, - }, - )] - .into_iter() - .collect(), - }; - - assert_eq!(program, expected_program) - } - - #[test] - fn inline_nested_const_field() { - // const field a = 1 - // const field b = a + 1 - // - // def main() -> field: - // return b - - let const_a_id = "a"; - let const_b_id = "b"; - - let main: TypedFunction = TypedFunction { - arguments: vec![], - statements: vec![TypedStatement::Return(vec![ - FieldElementExpression::Identifier(Identifier::from(const_b_id)).into(), - ])], - signature: DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::FieldElement]), - }; - - let program = TypedProgram { - main: "main".into(), - modules: vec![( - "main".into(), - TypedModule { - functions: vec![( - DeclarationFunctionKey::with_location("main", "main").signature( - DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::FieldElement]), - ), - TypedFunctionSymbol::Here(main), - )] - .into_iter() - .collect(), - constants: vec![ - ( - CanonicalConstantIdentifier::new( - const_a_id, - "main".into(), - DeclarationType::FieldElement, - ), - TypedConstantSymbol::Here(TypedConstant::new( - TypedExpression::FieldElement(FieldElementExpression::Number( - Bn128Field::from(1), - )), - )), - ), - ( - CanonicalConstantIdentifier::new( - const_b_id, - "main".into(), - DeclarationType::FieldElement, - ), - TypedConstantSymbol::Here(TypedConstant::new( - TypedExpression::FieldElement(FieldElementExpression::Add( - box FieldElementExpression::Identifier(Identifier::from( - const_a_id, - )), - box FieldElementExpression::Number(Bn128Field::from(1)), - )), - )), - ), - ] - .into_iter() - .collect(), - }, - )] - .into_iter() - .collect(), - }; - - let program = ConstantInliner::inline(program); - - let expected_main = TypedFunction { - arguments: vec![], - statements: vec![TypedStatement::Return(vec![ - FieldElementExpression::Number(Bn128Field::from(2)).into(), - ])], - signature: DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::FieldElement]), - }; - - let expected_program: TypedProgram = TypedProgram { - main: "main".into(), - modules: vec![( - "main".into(), - TypedModule { - functions: vec![( - DeclarationFunctionKey::with_location("main", "main").signature( - DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::FieldElement]), - ), - TypedFunctionSymbol::Here(expected_main), - )] - .into_iter() - .collect(), - constants: vec![ - ( - CanonicalConstantIdentifier::new( - const_a_id, - "main".into(), - DeclarationType::FieldElement, - ), - TypedConstantSymbol::Here(TypedConstant::new( - TypedExpression::FieldElement(FieldElementExpression::Number( - Bn128Field::from(1), - )), - )), - ), - ( - CanonicalConstantIdentifier::new( - const_b_id, - "main".into(), - DeclarationType::FieldElement, - ), - TypedConstantSymbol::Here(TypedConstant::new( - TypedExpression::FieldElement(FieldElementExpression::Number( - Bn128Field::from(2), - )), - )), - ), - ] - .into_iter() - .collect(), - }, - )] - .into_iter() - .collect(), - }; - - assert_eq!(program, expected_program) - } - - #[test] - fn inline_imported_constant() { - // --------------------- - // module `foo` - // -------------------- - // const field FOO = 42 - // - // def main(): - // return - // - // --------------------- - // module `main` - // --------------------- - // from "foo" import FOO - // - // def main() -> field: - // return FOO - - let foo_const_id = "FOO"; - let foo_module = TypedModule { - functions: vec![( - DeclarationFunctionKey::with_location("main", "main") - .signature(DeclarationSignature::new().inputs(vec![]).outputs(vec![])), - TypedFunctionSymbol::Here(TypedFunction { - arguments: vec![], - statements: vec![], - signature: DeclarationSignature::new().inputs(vec![]).outputs(vec![]), - }), - )] - .into_iter() - .collect(), - constants: vec![( - CanonicalConstantIdentifier::new( - foo_const_id, - "foo".into(), - DeclarationType::FieldElement, - ), - TypedConstantSymbol::Here(TypedConstant::new(TypedExpression::FieldElement( - FieldElementExpression::Number(Bn128Field::from(42)), - ))), - )] - .into_iter() - .collect(), - }; - - let main_module = TypedModule { - functions: vec![( - DeclarationFunctionKey::with_location("main", "main").signature( - DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::FieldElement]), - ), - TypedFunctionSymbol::Here(TypedFunction { - arguments: vec![], - statements: vec![TypedStatement::Return(vec![ - FieldElementExpression::Identifier(Identifier::from(foo_const_id)).into(), - ])], - signature: DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::FieldElement]), - }), - )] - .into_iter() - .collect(), - constants: vec![( - CanonicalConstantIdentifier::new( - foo_const_id, - "main".into(), - DeclarationType::FieldElement, - ), - TypedConstantSymbol::There(CanonicalConstantIdentifier::new( - foo_const_id, - "foo".into(), - DeclarationType::FieldElement, - )), - )] - .into_iter() - .collect(), - }; - - let program = TypedProgram { - main: "main".into(), - modules: vec![ - ("main".into(), main_module), - ("foo".into(), foo_module.clone()), - ] - .into_iter() - .collect(), - }; - - let program = ConstantInliner::inline(program); - let expected_main_module = TypedModule { - functions: vec![( - DeclarationFunctionKey::with_location("main", "main").signature( - DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::FieldElement]), - ), - TypedFunctionSymbol::Here(TypedFunction { - arguments: vec![], - statements: vec![TypedStatement::Return(vec![ - FieldElementExpression::Number(Bn128Field::from(42)).into(), - ])], - signature: DeclarationSignature::new() - .inputs(vec![]) - .outputs(vec![DeclarationType::FieldElement]), - }), - )] - .into_iter() - .collect(), - constants: vec![( - CanonicalConstantIdentifier::new( - foo_const_id, - "main".into(), - DeclarationType::FieldElement, - ), - TypedConstantSymbol::Here(TypedConstant::new(TypedExpression::FieldElement( - FieldElementExpression::Number(Bn128Field::from(42)), - ))), - )] - .into_iter() - .collect(), - }; - - let expected_program: TypedProgram = TypedProgram { - main: "main".into(), - modules: vec![ - ("main".into(), expected_main_module), - ("foo".into(), foo_module), - ] - .into_iter() - .collect(), - }; - - assert_eq!(program, expected_program) - } -} diff --git a/zokrates_core/src/static_analysis/flatten_complex_types.rs b/zokrates_core/src/static_analysis/flatten_complex_types.rs index 2764ab0a9..4b67041a9 100644 --- a/zokrates_core/src/static_analysis/flatten_complex_types.rs +++ b/zokrates_core/src/static_analysis/flatten_complex_types.rs @@ -271,10 +271,10 @@ impl<'ast, T: Field> Flattener { fn fold_identifier_expression>( &mut self, - ty: &E::ConcreteTy, + ty: E::ConcreteTy, e: typed::IdentifierExpression<'ast, E>, ) -> Vec> { - fold_identifier_expression::(self, ty, e) + fold_identifier_expression(self, ty, e) } fn fold_array_expression( @@ -375,7 +375,7 @@ impl<'ast, T: Field> Flattener { fn fold_array_expression_inner( &mut self, statements_buffer: &mut Vec>, - ty: &typed::types::ConcreteType, + ty: typed::types::ConcreteType, size: u32, e: typed::ArrayExpressionInner<'ast, T>, ) -> Vec> { @@ -385,7 +385,7 @@ impl<'ast, T: Field> Flattener { fn fold_struct_expression_inner( &mut self, statements_buffer: &mut Vec>, - ty: &typed::types::ConcreteStructType, + ty: typed::types::ConcreteStructType, e: typed::StructExpressionInner<'ast, T>, ) -> Vec> { fold_struct_expression_inner(self, statements_buffer, ty, e) @@ -394,7 +394,7 @@ impl<'ast, T: Field> Flattener { fn fold_tuple_expression_inner( &mut self, statements_buffer: &mut Vec>, - ty: &typed::types::ConcreteTupleType, + ty: typed::types::ConcreteTupleType, e: typed::TupleExpressionInner<'ast, T>, ) -> Vec> { fold_tuple_expression_inner(self, statements_buffer, ty, e) @@ -469,7 +469,7 @@ fn fold_statement<'ast, T: Field>( fn fold_array_expression_inner<'ast, T: Field>( f: &mut Flattener, statements_buffer: &mut Vec>, - ty: &typed::types::ConcreteType, + ty: typed::types::ConcreteType, size: u32, array: typed::ArrayExpressionInner<'ast, T>, ) -> Vec> { @@ -482,7 +482,7 @@ fn fold_array_expression_inner<'ast, T: Field>( f.fold_array_expression(statements_buffer, *block.value) } typed::ArrayExpressionInner::Identifier(id) => { - f.fold_identifier_expression(&ConcreteArrayType::new(ty.clone(), size), id) + f.fold_identifier_expression(ConcreteArrayType::new(ty, size), id) } typed::ArrayExpressionInner::Value(exprs) => { let exprs: Vec<_> = exprs @@ -539,7 +539,7 @@ fn fold_array_expression_inner<'ast, T: Field>( fn fold_struct_expression_inner<'ast, T: Field>( f: &mut Flattener, statements_buffer: &mut Vec>, - ty: &typed::types::ConcreteStructType, + ty: typed::types::ConcreteStructType, struc: typed::StructExpressionInner<'ast, T>, ) -> Vec> { match struc { @@ -572,7 +572,7 @@ fn fold_struct_expression_inner<'ast, T: Field>( fn fold_tuple_expression_inner<'ast, T: Field>( f: &mut Flattener, statements_buffer: &mut Vec>, - ty: &typed::types::ConcreteTupleType, + ty: typed::types::ConcreteTupleType, tuple: typed::TupleExpressionInner<'ast, T>, ) -> Vec> { match tuple { @@ -795,10 +795,10 @@ fn fold_conditional_expression<'ast, T: Field, E: Flatten<'ast, T>>( fn fold_identifier_expression<'ast, T: Field, E: Expr<'ast, T>>( f: &mut Flattener, - ty: &E::ConcreteTy, + ty: E::ConcreteTy, e: typed::IdentifierExpression<'ast, E>, ) -> Vec> { - flatten_identifier_rec(f.fold_name(e.id), &ty.clone().into_type()) + flatten_identifier_rec(f.fold_name(e.id), &ty.into_type()) .into_iter() .map(|v| v.into()) .collect() @@ -812,7 +812,7 @@ fn fold_field_expression<'ast, T: Field>( match e { typed::FieldElementExpression::Number(n) => zir::FieldElementExpression::Number(n), typed::FieldElementExpression::Identifier(id) => f - .fold_identifier_expression(&typed::ConcreteType::FieldElement, id) + .fold_identifier_expression(typed::ConcreteType::FieldElement, id) .pop() .unwrap() .try_into() @@ -942,7 +942,7 @@ fn fold_boolean_expression<'ast, T: Field>( } typed::BooleanExpression::Value(v) => zir::BooleanExpression::Value(v), typed::BooleanExpression::Identifier(id) => f - .fold_identifier_expression(&typed::ConcreteType::Boolean, id) + .fold_identifier_expression(typed::ConcreteType::Boolean, id) .pop() .unwrap() .try_into() @@ -1061,7 +1061,7 @@ fn fold_uint_expression_inner<'ast, T: Field>( } typed::UExpressionInner::Value(v) => zir::UExpressionInner::Value(v), typed::UExpressionInner::Identifier(id) => { - zir::UExpression::try_from(f.fold_identifier_expression(&bitwidth, id).pop().unwrap()) + zir::UExpression::try_from(f.fold_identifier_expression(bitwidth, id).pop().unwrap()) .unwrap() .into_inner() } @@ -1225,7 +1225,7 @@ fn fold_array_expression<'ast, T: Field>( let size: u32 = e.size().try_into().unwrap(); f.fold_array_expression_inner( statements_buffer, - &typed::types::ConcreteType::try_from(e.inner_type().clone()).unwrap(), + typed::types::ConcreteType::try_from(e.inner_type().clone()).unwrap(), size, e.into_inner(), ) @@ -1238,7 +1238,7 @@ fn fold_struct_expression<'ast, T: Field>( ) -> Vec> { f.fold_struct_expression_inner( statements_buffer, - &typed::types::ConcreteStructType::try_from(e.ty().clone()).unwrap(), + typed::types::ConcreteStructType::try_from(e.ty().clone()).unwrap(), e.into_inner(), ) } @@ -1250,7 +1250,7 @@ fn fold_tuple_expression<'ast, T: Field>( ) -> Vec> { f.fold_tuple_expression_inner( statements_buffer, - &typed::types::ConcreteTupleType::try_from(e.ty().clone()).unwrap(), + typed::types::ConcreteTupleType::try_from(e.ty().clone()).unwrap(), e.into_inner(), ) } From f2cc850fc07a4ff16eea76df1864fcf2ccbe7f60 Mon Sep 17 00:00:00 2001 From: schaeff Date: Wed, 7 Sep 2022 14:34:07 +0200 Subject: [PATCH 08/16] flatten identifier to expression --- zokrates_ast/src/zir/mod.rs | 10 ---- .../static_analysis/flatten_complex_types.rs | 55 +++++++++++++++++-- 2 files changed, 51 insertions(+), 14 deletions(-) diff --git a/zokrates_ast/src/zir/mod.rs b/zokrates_ast/src/zir/mod.rs index 0ece26f5f..d2cbf6330 100644 --- a/zokrates_ast/src/zir/mod.rs +++ b/zokrates_ast/src/zir/mod.rs @@ -44,16 +44,6 @@ pub struct ZirFunction<'ast, T> { pub signature: Signature, } -impl<'ast, T: Field> From> for ZirExpression<'ast, T> { - fn from(v: Variable<'ast>) -> Self { - match v._type { - Type::FieldElement => FieldElementExpression::Identifier(v.id).into(), - Type::Boolean => BooleanExpression::Identifier(v.id).into(), - Type::Uint(bitwidth) => UExpressionInner::Identifier(v.id).annotate(bitwidth).into(), - } - } -} - impl<'ast, T: fmt::Display> fmt::Display for ZirFunction<'ast, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { writeln!( diff --git a/zokrates_core/src/static_analysis/flatten_complex_types.rs b/zokrates_core/src/static_analysis/flatten_complex_types.rs index 4b67041a9..39acb1684 100644 --- a/zokrates_core/src/static_analysis/flatten_complex_types.rs +++ b/zokrates_core/src/static_analysis/flatten_complex_types.rs @@ -57,6 +57,56 @@ fn flatten_identifier_rec<'ast>( } } +fn flatten_identifier_to_expression_rec<'ast, T: Field>( + id: zir::SourceIdentifier<'ast>, + ty: &typed::types::ConcreteType, +) -> Vec> { + match ty { + typed::ConcreteType::Int => unreachable!(), + typed::ConcreteType::FieldElement => { + vec![zir::FieldElementExpression::Identifier(zir::Identifier::Source(id)).into()] + } + typed::ConcreteType::Boolean => { + vec![zir::BooleanExpression::Identifier(zir::Identifier::Source(id)).into()] + } + typed::ConcreteType::Uint(bitwidth) => { + vec![ + zir::UExpressionInner::Identifier(zir::Identifier::Source(id)) + .annotate(bitwidth.to_usize()) + .into(), + ] + } + typed::ConcreteType::Array(array_type) => (0..*array_type.size) + .flat_map(|i| { + flatten_identifier_to_expression_rec( + zir::SourceIdentifier::Select(box id.clone(), i), + &array_type.ty, + ) + }) + .collect(), + typed::types::ConcreteType::Struct(members) => members + .iter() + .flat_map(|struct_member| { + flatten_identifier_to_expression_rec( + zir::SourceIdentifier::Member(box id.clone(), struct_member.id.clone()), + &struct_member.ty, + ) + }) + .collect(), + typed::types::ConcreteType::Tuple(tuple_ty) => tuple_ty + .elements + .iter() + .enumerate() + .flat_map(|(i, ty)| { + flatten_identifier_to_expression_rec( + zir::SourceIdentifier::Element(box id.clone(), i as u32), + ty, + ) + }) + .collect(), + } +} + trait Flatten<'ast, T: Field> { fn flatten( self, @@ -798,10 +848,7 @@ fn fold_identifier_expression<'ast, T: Field, E: Expr<'ast, T>>( ty: E::ConcreteTy, e: typed::IdentifierExpression<'ast, E>, ) -> Vec> { - flatten_identifier_rec(f.fold_name(e.id), &ty.into_type()) - .into_iter() - .map(|v| v.into()) - .collect() + flatten_identifier_to_expression_rec(f.fold_name(e.id), &ty.into_type()) } fn fold_field_expression<'ast, T: Field>( From dcb52a5581396755a179dafbf0aa463db510cb4d Mon Sep 17 00:00:00 2001 From: dark64 Date: Fri, 9 Sep 2022 16:03:46 +0200 Subject: [PATCH 09/16] refactor --- zokrates_ast/src/untyped/from_ast.rs | 16 ++-- zokrates_ast/src/untyped/parameter.rs | 15 ++-- zokrates_core/src/semantics.rs | 109 +++++++++++++------------- 3 files changed, 71 insertions(+), 69 deletions(-) diff --git a/zokrates_ast/src/untyped/from_ast.rs b/zokrates_ast/src/untyped/from_ast.rs index 349a03dc4..6526e7c65 100644 --- a/zokrates_ast/src/untyped/from_ast.rs +++ b/zokrates_ast/src/untyped/from_ast.rs @@ -223,13 +223,10 @@ impl<'ast> From> for untyped::ParameterNode<'ast> { fn from(param: pest::Parameter<'ast>) -> untyped::ParameterNode<'ast> { use crate::untyped::NodeValue; - let is_private = param - .visibility - .map(|v| match v { - pest::Visibility::Private(_) => true, - pest::Visibility::Public(_) => false, - }) - .unwrap_or(false); + let is_private = param.visibility.map(|v| match v { + pest::Visibility::Private(_) => true, + pest::Visibility::Public(_) => false, + }); let is_mutable = param.mutable.is_some(); @@ -949,9 +946,10 @@ mod tests { .into(), ) .into(), - untyped::Parameter::public( + untyped::Parameter::new( untyped::Variable::mutable("b", UnresolvedType::Boolean.mock()) - .into(), + .mock(), + None, ) .into(), ], diff --git a/zokrates_ast/src/untyped/parameter.rs b/zokrates_ast/src/untyped/parameter.rs index af6e4ae57..8cce7bea1 100644 --- a/zokrates_ast/src/untyped/parameter.rs +++ b/zokrates_ast/src/untyped/parameter.rs @@ -4,20 +4,20 @@ use std::fmt; #[derive(Clone, PartialEq)] pub struct Parameter<'ast> { pub id: VariableNode<'ast>, - pub is_private: bool, + pub is_private: Option, } impl<'ast> Parameter<'ast> { - pub fn new(v: VariableNode<'ast>, is_private: bool) -> Self { + pub fn new(v: VariableNode<'ast>, is_private: Option) -> Self { Parameter { id: v, is_private } } pub fn private(v: VariableNode<'ast>) -> Self { - Self::new(v, true) + Self::new(v, Some(true)) } pub fn public(v: VariableNode<'ast>) -> Self { - Self::new(v, false) + Self::new(v, Some(false)) } } @@ -25,7 +25,12 @@ pub type ParameterNode<'ast> = Node>; impl<'ast> fmt::Display for Parameter<'ast> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let visibility = if self.is_private { "private " } else { "" }; + let visibility = if let Some(true) = self.is_private { + "private " + } else { + "" + }; + write!( f, "{}{} {}", diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index f49b99741..aab997c11 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -745,7 +745,7 @@ impl<'ast, T: Field> Checker<'ast, T> { } } Symbol::Here(SymbolDefinition::Function(f)) => { - match self.check_function(f, module_id, state) { + match self.check_function(declaration.id, f, module_id, state) { Ok(funct) => { match symbol_unifier .insert_function(declaration.id, funct.signature.clone()) @@ -763,40 +763,24 @@ impl<'ast, T: Field> Checker<'ast, T> { true => {} }; - // parameters defined on a non-entrypoint function should not be set as private - match (state.main_id != module_id || declaration.id != "main") - && funct.arguments.iter().any(|a| a.private) - { - true => { - errors.push( - ErrorInner { - pos: Some(pos), - message: "Private argument(s) are only allowed on the entrypoint function".into(), - } - .in_file(module_id), - ); - } - false => { - self.functions.insert( - DeclarationFunctionKey::with_location( - module_id.to_path_buf(), - declaration.id, - ) - .signature(funct.signature.clone()), - ); - symbols.push( - TypedFunctionSymbolDeclaration::new( - DeclarationFunctionKey::with_location( - module_id.to_path_buf(), - declaration.id, - ) - .signature(funct.signature.clone()), - TypedFunctionSymbol::Here(funct), - ) - .into(), - ); - } - } + self.functions.insert( + DeclarationFunctionKey::with_location( + module_id.to_path_buf(), + declaration.id, + ) + .signature(funct.signature.clone()), + ); + symbols.push( + TypedFunctionSymbolDeclaration::new( + DeclarationFunctionKey::with_location( + module_id.to_path_buf(), + declaration.id, + ) + .signature(funct.signature.clone()), + TypedFunctionSymbol::Here(funct), + ) + .into(), + ); } Err(e) => { errors.extend(e.into_iter().map(|inner| inner.in_file(module_id))); @@ -1112,6 +1096,7 @@ impl<'ast, T: Field> Checker<'ast, T> { fn check_function( &mut self, + id: Identifier<'ast>, funct_node: FunctionNode<'ast>, module_id: &ModuleId, state: &State<'ast, T>, @@ -1160,6 +1145,16 @@ impl<'ast, T: Field> Checker<'ast, T> { let arg = arg.value; + // parameters defined on a non-entrypoint function should not have visibility modifiers + if (state.main_id != module_id || id != "main") && arg.is_private.is_some() { + errors.push(ErrorInner { + pos: Some(pos), + message: + "Visibility modifiers on arguments are only allowed on the entrypoint function" + .into(), + }); + } + let decl_v = DeclarationVariable::new( self.id_in_this_scope(arg.id.value.id), decl_ty.clone(), @@ -1190,7 +1185,7 @@ impl<'ast, T: Field> Checker<'ast, T> { arguments_checked.push(DeclarationParameter { id: decl_v, - private: arg.is_private, + private: arg.is_private.unwrap_or(false), }); } @@ -3768,12 +3763,13 @@ mod tests { .mock() } - /// Helper function to create: (private field a) { return; } + /// Helper function to create: (field a) { return; } fn function1() -> FunctionNode<'static> { let statements = vec![Statement::Return(None).mock()]; - let arguments = vec![untyped::Parameter::public( + let arguments = vec![untyped::Parameter::new( untyped::Variable::immutable("a", UnresolvedType::FieldElement.mock()).mock(), + None, ) .mock()]; @@ -3981,7 +3977,7 @@ mod tests { let mut f0 = function0(); - f0.value.arguments = vec![untyped::Parameter::public( + f0.value.arguments = vec![untyped::Parameter::new( untyped::Variable::immutable( "a", UnresolvedType::array( @@ -3991,6 +3987,7 @@ mod tests { .mock(), ) .mock(), + None, ) .mock()]; f0.value.signature = UnresolvedSignature::new() @@ -4003,7 +4000,7 @@ mod tests { let mut f1 = function0(); - f1.value.arguments = vec![untyped::Parameter::public( + f1.value.arguments = vec![untyped::Parameter::new( untyped::Variable::immutable( "a", UnresolvedType::array( @@ -4013,6 +4010,7 @@ mod tests { .mock(), ) .mock(), + None, ) .mock()]; f1.value.signature = UnresolvedSignature::new().inputs(vec![UnresolvedType::array( @@ -4154,7 +4152,7 @@ mod tests { // def foo() { // return; // } - // def foo(a) { + // def foo(field a) { // return; // } // @@ -4713,7 +4711,7 @@ mod tests { let mut checker: Checker = Checker::default(); assert_eq!( - checker.check_function(foo, &*MODULE_ID, &state), + checker.check_function("foo", foo, &*MODULE_ID, &state), Err(vec![ErrorInner { pos: Some((Position::mock(), Position::mock())), message: "Identifier \"i\" is undefined".into() @@ -4792,7 +4790,7 @@ mod tests { let mut checker: Checker = Checker::default(); assert_eq!( - checker.check_function(foo, &*MODULE_ID, &state), + checker.check_function("foo", foo, &*MODULE_ID, &state), Ok(foo_checked) ); } @@ -4839,7 +4837,7 @@ mod tests { let mut checker: Checker = new_with_args(Scope::default(), functions); assert_eq!( - checker.check_function(bar, &*MODULE_ID, &state), + checker.check_function("bar", bar, &*MODULE_ID, &state), Err(vec![ErrorInner { pos: Some((Position::mock(), Position::mock())), message: @@ -4878,7 +4876,7 @@ mod tests { let mut checker: Checker = new_with_args(Scope::default(), HashSet::new()); assert_eq!( - checker.check_function(bar, &*MODULE_ID, &state), + checker.check_function("bar", bar, &*MODULE_ID, &state), Err(vec![ErrorInner { pos: Some((Position::mock(), Position::mock())), @@ -5091,7 +5089,7 @@ mod tests { let mut checker: Checker = new_with_args(Scope::default(), HashSet::new()); assert_eq!( - checker.check_function(bar, &*MODULE_ID, &state), + checker.check_function("bar", bar, &*MODULE_ID, &state), Err(vec![ErrorInner { pos: Some((Position::mock(), Position::mock())), @@ -5124,7 +5122,7 @@ mod tests { let mut checker: Checker = new_with_args(Scope::default(), HashSet::new()); assert_eq!( - checker.check_function(bar, &*MODULE_ID, &state), + checker.check_function("bar", bar, &*MODULE_ID, &state), Err(vec![ErrorInner { pos: Some((Position::mock(), Position::mock())), message: "Identifier \"a\" is undefined".into() @@ -5162,7 +5160,7 @@ mod tests { let mut checker: Checker = new_with_args(Scope::default(), HashSet::new()); assert_eq!( checker - .check_function(f, &*MODULE_ID, &state) + .check_function("main", f, &*MODULE_ID, &state) .unwrap_err()[0] .message, "Duplicate name in function definition: `a` was previously declared as an argument, a generic parameter or a constant" @@ -5171,7 +5169,7 @@ mod tests { #[test] fn duplicate_main_function() { - // def main(a) -> field { + // def main(field a) -> field { // return 1; // } // def main() -> field { @@ -5182,10 +5180,9 @@ mod tests { let main1_statements: Vec = vec![Statement::Return(Some(Expression::IntConstant(1usize.into()).mock())).mock()]; - let main1_arguments = vec![zokrates_ast::untyped::Parameter { - id: untyped::Variable::immutable("a", UnresolvedType::FieldElement.mock()).mock(), - is_private: false, - } + let main1_arguments = vec![zokrates_ast::untyped::Parameter::public( + untyped::Variable::immutable("a", UnresolvedType::FieldElement.mock()).mock(), + ) .mock()]; let main2_statements: Vec = @@ -6179,8 +6176,9 @@ mod tests { let mut foo_field = function0(); - foo_field.value.arguments = vec![untyped::Parameter::public( + foo_field.value.arguments = vec![untyped::Parameter::new( untyped::Variable::immutable("a", UnresolvedType::FieldElement.mock()).mock(), + None, ) .mock()]; foo_field.value.statements = @@ -6191,8 +6189,9 @@ mod tests { let mut foo_u32 = function0(); - foo_u32.value.arguments = vec![untyped::Parameter::public( + foo_u32.value.arguments = vec![untyped::Parameter::new( untyped::Variable::immutable("a", UnresolvedType::Uint(32).mock()).mock(), + None, ) .mock()]; foo_u32.value.statements = From 97df0ac599188aba91b30e98a70ef3c46dbf930f Mon Sep 17 00:00:00 2001 From: schaeff Date: Tue, 13 Sep 2022 20:27:28 +0200 Subject: [PATCH 10/16] ignore message in hash, add test --- Cargo.lock | 3 ++- zokrates_ast/Cargo.toml | 5 +---- zokrates_ast/src/ir/mod.rs | 21 ++++++++++++++++--- zokrates_core/src/optimizer/duplicate.rs | 1 + zokrates_core_test/tests/tests/duplicate.json | 7 +++++++ zokrates_core_test/tests/tests/duplicate.zok | 4 ++++ 6 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 zokrates_core_test/tests/tests/duplicate.json create mode 100644 zokrates_core_test/tests/tests/duplicate.zok diff --git a/Cargo.lock b/Cargo.lock index 7e67221af..b30d0e257 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3031,6 +3031,7 @@ dependencies = [ "ark-bls12-377", "cfg-if 0.1.10", "csv", + "derivative", "num-bigint 0.2.6", "pairing_ce", "serde", @@ -3215,7 +3216,7 @@ dependencies = [ [[package]] name = "zokrates_js" -version = "1.1.2" +version = "1.1.3" dependencies = [ "console_error_panic_hook", "indexmap", diff --git a/zokrates_ast/Cargo.toml b/zokrates_ast/Cargo.toml index 46b068ef7..187e6a2da 100644 --- a/zokrates_ast/Cargo.toml +++ b/zokrates_ast/Cargo.toml @@ -20,7 +20,4 @@ serde_json = { version = "1.0", features = ["preserve_order"] } zokrates_embed = { version = "0.1.0", path = "../zokrates_embed", default-features = false } pairing_ce = { version = "^0.21", optional = true } ark-bls12-377 = { version = "^0.3.0", features = ["curve"], default-features = false, optional = true } - - - - +derivative = "2.2.0" \ No newline at end of file diff --git a/zokrates_ast/src/ir/mod.rs b/zokrates_ast/src/ir/mod.rs index bd068b891..36d01d758 100644 --- a/zokrates_ast/src/ir/mod.rs +++ b/zokrates_ast/src/ir/mod.rs @@ -1,5 +1,6 @@ use crate::common::FormatString; use crate::typed::ConcreteType; +use derivative::Derivative; use serde::{Deserialize, Serialize}; use std::collections::BTreeSet; use std::fmt; @@ -25,9 +26,14 @@ pub use crate::common::Variable; pub use self::witness::Witness; -#[derive(Debug, Serialize, Deserialize, Clone, Hash, PartialEq, Eq)] +#[derive(Debug, Serialize, Deserialize, Clone, Derivative)] +#[derivative(Hash, PartialEq, Eq)] pub enum Statement { - Constraint(QuadComb, LinComb, Option), + Constraint( + QuadComb, + LinComb, + #[derivative(Hash = "ignore")] Option, + ), Directive(Directive), Log(FormatString, Vec<(ConcreteType, Vec>)>), } @@ -74,7 +80,16 @@ impl fmt::Display for Directive { impl fmt::Display for Statement { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - Statement::Constraint(ref quad, ref lin, _) => write!(f, "{} == {}", quad, lin), + Statement::Constraint(ref quad, ref lin, ref error) => write!( + f, + "{} == {}{}", + quad, + lin, + error + .as_ref() + .map(|e| format!(" // {}", e)) + .unwrap_or_else(|| "".to_string()) + ), Statement::Directive(ref s) => write!(f, "{}", s), Statement::Log(ref s, ref expressions) => write!( f, diff --git a/zokrates_core/src/optimizer/duplicate.rs b/zokrates_core/src/optimizer/duplicate.rs index 68c954096..d51aeb3db 100644 --- a/zokrates_core/src/optimizer/duplicate.rs +++ b/zokrates_core/src/optimizer/duplicate.rs @@ -39,6 +39,7 @@ impl Folder for DuplicateOptimizer { } fn fold_statement(&mut self, s: Statement) -> Vec> { + println!("{}", s); let hashed = hash(&s); let result = match self.seen.get(&hashed) { Some(_) => vec![], diff --git a/zokrates_core_test/tests/tests/duplicate.json b/zokrates_core_test/tests/tests/duplicate.json new file mode 100644 index 000000000..f9555bdad --- /dev/null +++ b/zokrates_core_test/tests/tests/duplicate.json @@ -0,0 +1,7 @@ +{ + "entry_point": "./tests/tests/duplicate.zok", + "max_constraint_count": 1, + "curves": ["Bn128"], + "tests": [] + } + \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/duplicate.zok b/zokrates_core_test/tests/tests/duplicate.zok new file mode 100644 index 000000000..5baa72b5b --- /dev/null +++ b/zokrates_core_test/tests/tests/duplicate.zok @@ -0,0 +1,4 @@ +def main(field a) { + assert(a == 0); + assert(a == 0); +} \ No newline at end of file From 30b369676838034b9d8c9135634d20882d489ee6 Mon Sep 17 00:00:00 2001 From: schaeff Date: Tue, 13 Sep 2022 20:32:42 +0200 Subject: [PATCH 11/16] changelog --- changelogs/unreleased/1226-schaeff | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/1226-schaeff diff --git a/changelogs/unreleased/1226-schaeff b/changelogs/unreleased/1226-schaeff new file mode 100644 index 000000000..ef2ac9b7f --- /dev/null +++ b/changelogs/unreleased/1226-schaeff @@ -0,0 +1 @@ +Fix duplicate constraint optimiser \ No newline at end of file From 21e318656f1708921c2543e0fbff6c7644658817 Mon Sep 17 00:00:00 2001 From: schaeff Date: Tue, 13 Sep 2022 20:33:52 +0200 Subject: [PATCH 12/16] prettier --- zokrates_core_test/tests/tests/duplicate.json | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/zokrates_core_test/tests/tests/duplicate.json b/zokrates_core_test/tests/tests/duplicate.json index f9555bdad..93223b67d 100644 --- a/zokrates_core_test/tests/tests/duplicate.json +++ b/zokrates_core_test/tests/tests/duplicate.json @@ -1,7 +1,6 @@ { - "entry_point": "./tests/tests/duplicate.zok", - "max_constraint_count": 1, - "curves": ["Bn128"], - "tests": [] - } - \ No newline at end of file + "entry_point": "./tests/tests/duplicate.zok", + "max_constraint_count": 1, + "curves": ["Bn128"], + "tests": [] +} From bc37a2292fd2d736ec88e0afd97b04487305e25d Mon Sep 17 00:00:00 2001 From: schaeff Date: Tue, 13 Sep 2022 21:21:15 +0200 Subject: [PATCH 13/16] remove println --- zokrates_core/src/optimizer/duplicate.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/zokrates_core/src/optimizer/duplicate.rs b/zokrates_core/src/optimizer/duplicate.rs index d51aeb3db..68c954096 100644 --- a/zokrates_core/src/optimizer/duplicate.rs +++ b/zokrates_core/src/optimizer/duplicate.rs @@ -39,7 +39,6 @@ impl Folder for DuplicateOptimizer { } fn fold_statement(&mut self, s: Statement) -> Vec> { - println!("{}", s); let hashed = hash(&s); let result = match self.seen.get(&hashed) { Some(_) => vec![], From e48afb678ca075c9580b4c4958b6c48b4344f9af Mon Sep 17 00:00:00 2001 From: dark64 Date: Wed, 21 Sep 2022 14:54:37 +0200 Subject: [PATCH 14/16] add test for public, update changelog --- changelogs/unreleased/1224-dark64 | 2 +- .../examples/compile_errors/non_main_public_args.zok | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 zokrates_cli/examples/compile_errors/non_main_public_args.zok diff --git a/changelogs/unreleased/1224-dark64 b/changelogs/unreleased/1224-dark64 index d1820feb8..8977675b4 100644 --- a/changelogs/unreleased/1224-dark64 +++ b/changelogs/unreleased/1224-dark64 @@ -1 +1 @@ -Disallow the use of the `private` keyword on non-entrypoint functions \ No newline at end of file +Disallow the use of the `private` and `public` keywords on non-entrypoint functions \ No newline at end of file diff --git a/zokrates_cli/examples/compile_errors/non_main_public_args.zok b/zokrates_cli/examples/compile_errors/non_main_public_args.zok new file mode 100644 index 000000000..b55082d65 --- /dev/null +++ b/zokrates_cli/examples/compile_errors/non_main_public_args.zok @@ -0,0 +1,8 @@ +def mul(public field a) -> field { // `public` should not be allowed here + return a * a; +} + +def main(field a, field b) { + assert(mul(a) == b); + return; +} \ No newline at end of file From 9ca495eb7197acb26e88309911cca67b8929fa0f Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 10 Oct 2022 18:00:35 +0200 Subject: [PATCH 15/16] update changelog, bump versions --- CHANGELOG.md | 9 +++++++++ Cargo.lock | 8 ++++---- changelogs/unreleased/1224-dark64 | 1 - changelogs/unreleased/1226-schaeff | 1 - zokrates_ast/Cargo.toml | 2 +- zokrates_cli/Cargo.toml | 2 +- zokrates_js/Cargo.toml | 2 +- zokrates_js/package-lock.json | 2 +- zokrates_js/package.json | 2 +- zokrates_stdlib/Cargo.toml | 2 +- 10 files changed, 19 insertions(+), 12 deletions(-) delete mode 100644 changelogs/unreleased/1224-dark64 delete mode 100644 changelogs/unreleased/1226-schaeff diff --git a/CHANGELOG.md b/CHANGELOG.md index 42f323d30..156c0ed3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file. ## [Unreleased] https://github.com/Zokrates/ZoKrates/compare/latest...develop +## [0.8.3] - 2022-10-10 + +### Release +- https://github.com/Zokrates/ZoKrates/releases/tag/0.8.3 + +### Changes +- Disallow the use of the `private` and `public` keywords on non-entrypoint functions (#1224, @dark64) +- Fix duplicate constraint optimiser (#1226, @schaeff) + ## [0.8.2] - 2022-09-05 ### Release diff --git a/Cargo.lock b/Cargo.lock index b30d0e257..4153148de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3026,7 +3026,7 @@ dependencies = [ [[package]] name = "zokrates_ast" -version = "0.1.2" +version = "0.1.3" dependencies = [ "ark-bls12-377", "cfg-if 0.1.10", @@ -3073,7 +3073,7 @@ dependencies = [ [[package]] name = "zokrates_cli" -version = "0.8.2" +version = "0.8.3" dependencies = [ "assert_cli", "blake2 0.8.1", @@ -3216,7 +3216,7 @@ dependencies = [ [[package]] name = "zokrates_js" -version = "1.1.3" +version = "1.1.4" dependencies = [ "console_error_panic_hook", "indexmap", @@ -3294,7 +3294,7 @@ dependencies = [ [[package]] name = "zokrates_stdlib" -version = "0.3.2" +version = "0.3.3" dependencies = [ "fs_extra", "zokrates_test", diff --git a/changelogs/unreleased/1224-dark64 b/changelogs/unreleased/1224-dark64 deleted file mode 100644 index 8977675b4..000000000 --- a/changelogs/unreleased/1224-dark64 +++ /dev/null @@ -1 +0,0 @@ -Disallow the use of the `private` and `public` keywords on non-entrypoint functions \ No newline at end of file diff --git a/changelogs/unreleased/1226-schaeff b/changelogs/unreleased/1226-schaeff deleted file mode 100644 index ef2ac9b7f..000000000 --- a/changelogs/unreleased/1226-schaeff +++ /dev/null @@ -1 +0,0 @@ -Fix duplicate constraint optimiser \ No newline at end of file diff --git a/zokrates_ast/Cargo.toml b/zokrates_ast/Cargo.toml index 187e6a2da..a41269c22 100644 --- a/zokrates_ast/Cargo.toml +++ b/zokrates_ast/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zokrates_ast" -version = "0.1.2" +version = "0.1.3" edition = "2021" [features] diff --git a/zokrates_cli/Cargo.toml b/zokrates_cli/Cargo.toml index 81e9a7472..0aa946334 100644 --- a/zokrates_cli/Cargo.toml +++ b/zokrates_cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zokrates_cli" -version = "0.8.2" +version = "0.8.3" authors = ["Jacob Eberhardt ", "Dennis Kuhnert ", "Thibaut Schaeffer "] repository = "https://github.com/Zokrates/ZoKrates.git" edition = "2018" diff --git a/zokrates_js/Cargo.toml b/zokrates_js/Cargo.toml index 59b20e610..feb949d17 100644 --- a/zokrates_js/Cargo.toml +++ b/zokrates_js/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zokrates_js" -version = "1.1.3" +version = "1.1.4" authors = ["Darko Macesic"] edition = "2018" diff --git a/zokrates_js/package-lock.json b/zokrates_js/package-lock.json index 74772fd07..1e3c42f27 100644 --- a/zokrates_js/package-lock.json +++ b/zokrates_js/package-lock.json @@ -1,6 +1,6 @@ { "name": "zokrates-js", - "version": "1.1.1", + "version": "1.1.4", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/zokrates_js/package.json b/zokrates_js/package.json index 6ddcb0c84..ce404bacd 100644 --- a/zokrates_js/package.json +++ b/zokrates_js/package.json @@ -1,6 +1,6 @@ { "name": "zokrates-js", - "version": "1.1.3", + "version": "1.1.4", "module": "index.js", "main": "node/index.js", "description": "JavaScript bindings for ZoKrates", diff --git a/zokrates_stdlib/Cargo.toml b/zokrates_stdlib/Cargo.toml index d70995209..24763e3f2 100644 --- a/zokrates_stdlib/Cargo.toml +++ b/zokrates_stdlib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zokrates_stdlib" -version = "0.3.2" +version = "0.3.3" authors = ["Stefan Deml ", "schaeff "] edition = "2018" From 6bb1d86917cdf107e9d4253aa7742e42331596f4 Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 11 Oct 2022 01:53:33 +0200 Subject: [PATCH 16/16] bump zokrates_core_test --- CHANGELOG.md | 2 +- Cargo.lock | 2 +- zokrates_core_test/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 156c0ed3f..e589ac990 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. ## [Unreleased] https://github.com/Zokrates/ZoKrates/compare/latest...develop -## [0.8.3] - 2022-10-10 +## [0.8.3] - 2022-10-11 ### Release - https://github.com/Zokrates/ZoKrates/releases/tag/0.8.3 diff --git a/Cargo.lock b/Cargo.lock index 4153148de..28b50a995 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3143,7 +3143,7 @@ dependencies = [ [[package]] name = "zokrates_core_test" -version = "0.2.8" +version = "0.2.9" dependencies = [ "zokrates_test", "zokrates_test_derive", diff --git a/zokrates_core_test/Cargo.toml b/zokrates_core_test/Cargo.toml index cb0214bb2..40c31f338 100644 --- a/zokrates_core_test/Cargo.toml +++ b/zokrates_core_test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zokrates_core_test" -version = "0.2.8" +version = "0.2.9" authors = ["schaeff "] edition = "2018"