Skip to content

Commit

Permalink
Merge pull request #33 from QED-it/fix-simul
Browse files Browse the repository at this point in the history
fix-simul: unified validator and simulator interface, streaming only,…
  • Loading branch information
naure authored Oct 21, 2020
2 parents f94a190 + b0e9876 commit 5eb619b
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 79 deletions.
7 changes: 7 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# Version v1.3.2, 2020-10, Improve simulator

Rust:
- Fix a bug when using simulate from stdin.
- Simplify and unify the interface of Validator and Simulator.
- Method `CircuitHeader.list_witness_ids()`.

# Version v1.3.1, 2020-10, Rust streaming

Rust:
Expand Down
2 changes: 1 addition & 1 deletion rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "zkinterface"
version = "1.3.1"
version = "1.3.2"
authors = ["Aurélien Nicolas <[email protected]>"]
license = "MIT"
build = "build.rs"
Expand Down
32 changes: 18 additions & 14 deletions rust/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,32 +195,36 @@ fn main_explain(reader: &Reader) -> Result<()> {
fn main_validate(ws: &Workspace) -> Result<()> {
// Validate semantics as verifier.
let mut validator = Validator::new_as_verifier();
validator.ingest_workspace(ws);
print_violations(&validator.get_violations())
for msg in ws.iter_messages() {
validator.ingest_message(&msg);
}
print_violations(&validator.get_violations(), "COMPLIANT with the specification")
}

fn main_simulate(ws: &Workspace) -> Result<()> {
// Validate semantics as prover.
let mut validator = Validator::new_as_prover();
validator.ingest_workspace(ws);
print_violations(&validator.get_violations())?;

// Check whether the statement is true.
let ok = Simulator::default().simulate_workspace(ws);
match ok {
Err(_) => eprintln!("The statement is NOT TRUE!"),
Ok(_) => eprintln!("The statement is TRUE!"),
let mut simulator = Simulator::default();

// Must validate and simulate in parallel to support stdin.
for msg in ws.iter_messages() {
validator.ingest_message(&msg);
simulator.ingest_message(&msg);
}
ok

let result_val = print_violations(&validator.get_violations(), "COMPLIANT with the specification");
print_violations(&simulator.get_violations(), "TRUE")?;
result_val
}

fn print_violations(errors: &[String]) -> Result<()> {
fn print_violations(errors: &[String], what_it_is_supposed_to_be: &str) -> Result<()> {
if errors.len() > 0 {
eprintln!("The statement is NOT COMPLIANT with the specification!");
eprintln!("The statement is NOT {}!", what_it_is_supposed_to_be);
eprintln!("Violations:\n- {}\n", errors.join("\n- "));
Err(format!("Found {} violations of the specification.", errors.len()).into())
Err(format!("Found {} violations.", errors.len()).into())
} else {
eprintln!("The statement is COMPLIANT with the specification!");
eprintln!("The statement is {}!", what_it_is_supposed_to_be);
Ok(())
}
}
Expand Down
54 changes: 29 additions & 25 deletions rust/src/consumers/simulator.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{Result, CircuitHeader, Witness, ConstraintSystem, Messages, Variables, Workspace, Message};
use crate::{Result, CircuitHeader, Witness, ConstraintSystem, Variables, Message};
use crate::structs::constraints::BilinearConstraint;

use std::collections::HashMap;
Expand All @@ -13,38 +13,38 @@ pub struct Simulator {
values: HashMap<Var, Field>,
modulus: Field,

violations: Vec<String>,
verified_at_least_one_constraint: bool,
found_error: Option<String>,
}

impl Simulator {
pub fn simulate(&mut self, messages: &Messages) -> Result<()> {
for header in &messages.circuit_headers {
self.ingest_header(header)?;
pub fn get_violations(self) -> Vec<String> {
let mut violations = vec![];
if !self.verified_at_least_one_constraint {
violations.push("Did not receive any constraint to verify.".to_string());
}
for witness in &messages.witnesses {
self.ingest_witness(witness)?;
if let Some(err) = self.found_error {
violations.push(err);
}
for cs in &messages.constraint_systems {
self.ingest_constraint_system(cs)?;
violations
}

pub fn ingest_message(&mut self, msg: &Message) {
if self.found_error.is_some() { return; }

match self.ingest_message_(msg) {
Err(err) => self.found_error = Some(err.to_string()),
Ok(()) => {}
}
Ok(())
}

pub fn simulate_workspace(&mut self, ws: &Workspace) -> Result<()> {
for msg in ws.iter_messages() {
match msg {
Message::Header(header) => {
self.ingest_header(&header)?;
}
Message::ConstraintSystem(cs) => {
self.ingest_constraint_system(&cs)?;
}
Message::Witness(witness) => {
self.ingest_witness(&witness)?;
}
Message::Command(_) => {}
Message::Err(_) => {}
}
fn ingest_message_(&mut self, msg: &Message) -> Result<()> {
match msg {
Message::Header(h) => self.ingest_header(&h)?,
Message::ConstraintSystem(cs) => self.ingest_constraint_system(&cs)?,
Message::Witness(w) => self.ingest_witness(&w)?,
Message::Command(_) => {}
Message::Err(_) => {}
}
Ok(())
}
Expand Down Expand Up @@ -76,6 +76,10 @@ impl Simulator {
pub fn ingest_constraint_system(&mut self, system: &ConstraintSystem) -> Result<()> {
self.ensure_header()?;

if system.constraints.len() > 0 {
self.verified_at_least_one_constraint = true;
}

for constraint in &system.constraints {
self.verify_constraint(constraint)?;
}
Expand Down
51 changes: 13 additions & 38 deletions rust/src/consumers/validator.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{CircuitHeader, Witness, ConstraintSystem, Messages, Variables, Message, Workspace};
use crate::{CircuitHeader, Witness, ConstraintSystem, Variables, Message};

use std::collections::HashMap;
use num_bigint::BigUint;
Expand Down Expand Up @@ -37,40 +37,6 @@ impl Validator {
Validator { as_prover: true, ..Self::default() }
}

pub fn ingest_messages(&mut self, messages: &Messages) {
for header in &messages.circuit_headers {
self.ingest_header(header);
}
if self.as_prover {
for witness in &messages.witnesses {
self.ingest_witness(witness);
}
}
for cs in &messages.constraint_systems {
self.ingest_constraint_system(cs);
}
}

pub fn ingest_workspace(&mut self, ws: &Workspace) {
for msg in ws.iter_messages() {
match msg {
Message::Header(header) => {
self.ingest_header(&header);
}
Message::ConstraintSystem(cs) => {
self.ingest_constraint_system(&cs);
}
Message::Witness(witness) => {
if self.as_prover {
self.ingest_witness(&witness);
}
}
Message::Command(_) => {}
Message::Err(err) => self.violate(err.to_string()),
}
}
}

pub fn get_violations(mut self) -> Vec<String> {
self.ensure_all_variables_used();
if !self.got_header {
Expand All @@ -79,6 +45,16 @@ impl Validator {
self.violations
}

pub fn ingest_message(&mut self, msg: &Message) {
match msg {
Message::Header(h) => self.ingest_header(&h),
Message::ConstraintSystem(cs) => self.ingest_constraint_system(&cs),
Message::Witness(w) => self.ingest_witness(&w),
Message::Command(_) => {}
Message::Err(err) => self.violate(err.to_string()),
}
}

pub fn ingest_header(&mut self, header: &CircuitHeader) {
if self.got_header {
self.violate("Multiple headers.");
Expand Down Expand Up @@ -107,10 +83,9 @@ impl Validator {
}

pub fn ingest_witness(&mut self, witness: &Witness) {
if !self.as_prover { return; }

self.ensure_header();
if !self.as_prover {
self.violate("As verifier, got an unexpected Witness message.");
}

for var in witness.assigned_variables.get_variables() {
self.define(var.id, var.value, || format!("value of the witness variable_{}", var.id));
Expand Down
18 changes: 18 additions & 0 deletions rust/src/structs/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use super::keyvalue::KeyValue;
use crate::Result;
use std::convert::TryFrom;
use std::error::Error;
use std::collections::HashSet;


#[derive(Clone, Default, Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct CircuitHeader {
Expand Down Expand Up @@ -45,6 +47,22 @@ impl<'a> TryFrom<&'a [u8]> for CircuitHeader {
}

impl CircuitHeader {
/// Enumerate the IDs of witness variables based on a header.
/// # Example
/// ```
/// use zkinterface_bellman::export::list_witness_ids;
/// let header = zkinterface::producers::examples::example_circuit_header();
/// let witness_ids = list_witness_ids(&header);
/// assert_eq!(witness_ids, vec![4, 5]);
/// ```
pub fn list_witness_ids(&self) -> Vec<u64> {
let instance_ids = self.instance_variables.variable_ids.iter().cloned().collect::<HashSet<u64>>();

(1..self.free_variable_id)
.filter(|id| !instance_ids.contains(id))
.collect()
}

pub fn with_instance_values(mut self, vars: Variables) -> Result<Self> {
if self.instance_variables.variable_ids != vars.variable_ids {
return Err(format!("The provided instance variables do not match.\nGot : {:?}\nExpected:{:?}", vars.variable_ids, self.instance_variables.variable_ids).into());
Expand Down

0 comments on commit 5eb619b

Please sign in to comment.