From 64f99d75fbe15e0975fc847c61ec07a1988177b5 Mon Sep 17 00:00:00 2001 From: schaeff Date: Wed, 6 Apr 2022 15:40:16 +0200 Subject: [PATCH 1/5] detect unconstrained variables --- zokrates_core/src/ir/serialize.rs | 15 +++++- zokrates_core/src/lib.rs | 2 +- zokrates_core/src/static_analysis/mod.rs | 2 + .../src/static_analysis/unconstrained_vars.rs | 47 +++++++++++++++++++ 4 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 zokrates_core/src/static_analysis/unconstrained_vars.rs diff --git a/zokrates_core/src/ir/serialize.rs b/zokrates_core/src/ir/serialize.rs index 897c8804..a702bef2 100644 --- a/zokrates_core/src/ir/serialize.rs +++ b/zokrates_core/src/ir/serialize.rs @@ -1,4 +1,7 @@ -use crate::ir::{ProgIterator, Statement}; +use crate::{ + ir::{ProgIterator, Statement}, + static_analysis::UnconstrainedVariableDetector, +}; use serde_cbor::{self, StreamDeserializer}; use std::io::{Read, Write}; use zokrates_field::*; @@ -49,6 +52,8 @@ impl>> ProgIterator { /// serialize a program iterator, returning the number of constraints serialized /// Note that we only return constraints, not other statements such as directives pub fn serialize(self, mut w: W) -> Result { + use crate::ir::folder::Folder; + w.write_all(ZOKRATES_MAGIC)?; w.write_all(ZOKRATES_VERSION_2)?; w.write_all(&T::id())?; @@ -56,6 +61,8 @@ impl>> ProgIterator { serde_cbor::to_writer(&mut w, &self.arguments)?; serde_cbor::to_writer(&mut w, &self.return_count)?; + let mut unconstrained_variable_detector = UnconstrainedVariableDetector::new(&self); + let statements = self.statements.into_iter(); let mut count = 0; @@ -63,10 +70,14 @@ impl>> ProgIterator { if matches!(s, Statement::Constraint(..)) { count += 1; } + let s = unconstrained_variable_detector.fold_statement(s); serde_cbor::to_writer(&mut w, &s)?; } - Ok(count) + unconstrained_variable_detector + .finalize() + .map(|_| count) + .map_err(|count| format!("Error: Found {} unconstrained variable(s)", count).into()) } } diff --git a/zokrates_core/src/lib.rs b/zokrates_core/src/lib.rs index 955218a2..ce7715af 100644 --- a/zokrates_core/src/lib.rs +++ b/zokrates_core/src/lib.rs @@ -16,7 +16,7 @@ mod optimizer; mod parser; mod semantics; mod solvers; -mod static_analysis; +pub mod static_analysis; mod zir; pub mod absy; diff --git a/zokrates_core/src/static_analysis/mod.rs b/zokrates_core/src/static_analysis/mod.rs index eb188cfe..ed362863 100644 --- a/zokrates_core/src/static_analysis/mod.rs +++ b/zokrates_core/src/static_analysis/mod.rs @@ -15,6 +15,7 @@ mod propagation; mod reducer; mod struct_concretizer; mod uint_optimizer; +mod unconstrained_vars; mod variable_write_remover; mod zir_propagation; @@ -34,6 +35,7 @@ use crate::static_analysis::zir_propagation::ZirPropagator; use crate::typed_absy::{abi::Abi, TypedProgram}; use crate::zir::ZirProgram; use std::fmt; +pub use unconstrained_vars::UnconstrainedVariableDetector; use zokrates_field::Field; #[derive(Debug)] diff --git a/zokrates_core/src/static_analysis/unconstrained_vars.rs b/zokrates_core/src/static_analysis/unconstrained_vars.rs new file mode 100644 index 00000000..807ceae4 --- /dev/null +++ b/zokrates_core/src/static_analysis/unconstrained_vars.rs @@ -0,0 +1,47 @@ +use crate::flat_absy::FlatParameter; +use crate::flat_absy::FlatVariable; +use crate::ir::folder::Folder; +use crate::ir::Directive; +use crate::ir::ProgIterator; +use crate::ir::Statement; +use std::collections::HashSet; +use zokrates_field::Field; + +#[derive(Debug)] +pub struct UnconstrainedVariableDetector { + pub(self) variables: HashSet, +} + +impl UnconstrainedVariableDetector { + pub fn new>>(p: &ProgIterator) -> Self { + UnconstrainedVariableDetector { + variables: p + .arguments + .iter() + .filter(|p| p.private) + .map(|p| p.id) + .collect(), + } + } + + pub fn finalize(self) -> Result<(), usize> { + if self.variables.is_empty() { + return Ok(()); + } + Err(self.variables.len()) + } +} + +impl Folder for UnconstrainedVariableDetector { + fn fold_argument(&mut self, p: FlatParameter) -> FlatParameter { + p + } + fn fold_variable(&mut self, v: FlatVariable) -> FlatVariable { + self.variables.remove(&v); + v + } + fn fold_directive(&mut self, d: Directive) -> Directive { + self.variables.extend(d.outputs.iter()); + d + } +} From a5d86f9cb09ca9a59c92126e348173569a41da76 Mon Sep 17 00:00:00 2001 From: schaeff Date: Wed, 6 Apr 2022 15:42:28 +0200 Subject: [PATCH 2/5] changelog --- changelogs/unreleased/1020-schaeff | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/1020-schaeff diff --git a/changelogs/unreleased/1020-schaeff b/changelogs/unreleased/1020-schaeff new file mode 100644 index 00000000..32214382 --- /dev/null +++ b/changelogs/unreleased/1020-schaeff @@ -0,0 +1 @@ +Handle unconstrained variables gracefully \ No newline at end of file From 6c4423b5291107b46fcfcb7abdf9325f419ff902 Mon Sep 17 00:00:00 2001 From: schaeff Date: Wed, 6 Apr 2022 15:57:31 +0200 Subject: [PATCH 3/5] rename changelog --- changelogs/unreleased/{1020-schaeff => 1120-schaeff} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelogs/unreleased/{1020-schaeff => 1120-schaeff} (100%) diff --git a/changelogs/unreleased/1020-schaeff b/changelogs/unreleased/1120-schaeff similarity index 100% rename from changelogs/unreleased/1020-schaeff rename to changelogs/unreleased/1120-schaeff From 03a533af2c7a30f3523bee528caf0913d1fc19b3 Mon Sep 17 00:00:00 2001 From: schaeff Date: Thu, 7 Apr 2022 10:53:16 +0200 Subject: [PATCH 4/5] fix serialization --- zokrates_core/src/ir/serialize.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/zokrates_core/src/ir/serialize.rs b/zokrates_core/src/ir/serialize.rs index a702bef2..589ddbb1 100644 --- a/zokrates_core/src/ir/serialize.rs +++ b/zokrates_core/src/ir/serialize.rs @@ -71,7 +71,9 @@ impl>> ProgIterator { count += 1; } let s = unconstrained_variable_detector.fold_statement(s); - serde_cbor::to_writer(&mut w, &s)?; + for s in s { + serde_cbor::to_writer(&mut w, &s)?; + } } unconstrained_variable_detector From bc237d1df0064f257f981a7d424ba826db950825 Mon Sep 17 00:00:00 2001 From: schaeff Date: Thu, 7 Apr 2022 18:30:35 +0200 Subject: [PATCH 5/5] make static analysis private --- zokrates_core/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zokrates_core/src/lib.rs b/zokrates_core/src/lib.rs index ce7715af..955218a2 100644 --- a/zokrates_core/src/lib.rs +++ b/zokrates_core/src/lib.rs @@ -16,7 +16,7 @@ mod optimizer; mod parser; mod semantics; mod solvers; -pub mod static_analysis; +mod static_analysis; mod zir; pub mod absy;