diff --git a/Cargo.lock b/Cargo.lock index 515ec88034..5242f17bdd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -584,6 +584,10 @@ dependencies = [ "pest", "pest-ast", "pest_derive", + "rand 0.7.3", + "snarkos-algorithms", + "snarkos-curves", + "snarkos-errors", "snarkos-gadgets", "snarkos-models", ] diff --git a/Cargo.toml b/Cargo.toml index 38769dc8ae..8056347752 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,10 @@ lazy_static = "1.3.0" pest = "2.0" pest_derive = "2.0" pest-ast = "0.3.3" +rand = { version = "0.7" } +snarkos-algorithms = { path = "../snarkOS/algorithms" } +snarkos-curves = { path = "../snarkOS/curves" } +snarkos-errors = { path = "../snarkOS/errors" } snarkos-gadgets = { path = "../snarkOS/gadgets" } snarkos-models = { path = "../snarkOS/models" } diff --git a/simple.program b/simple.program index 54358ba0ec..252a712080 100644 --- a/simple.program +++ b/simple.program @@ -1 +1 @@ -return a == 1 \ No newline at end of file +return a + 1 \ No newline at end of file diff --git a/src/aleo_program/constraints.rs b/src/aleo_program/constraints.rs new file mode 100644 index 0000000000..954d83ea6a --- /dev/null +++ b/src/aleo_program/constraints.rs @@ -0,0 +1,186 @@ +use crate::aleo_program::{ + BooleanExpression, Expression, FieldExpression, Program, Statement, Variable, +}; + +use snarkos_models::curves::Field; +use snarkos_models::gadgets::utilities::eq::EqGadget; +use snarkos_models::gadgets::{ + r1cs::ConstraintSystem, + utilities::{alloc::AllocGadget, boolean::Boolean, eq::ConditionalEqGadget, uint32::UInt32}, +}; + +fn bool_from_variable>( + cs: &mut CS, + variable: Variable, +) -> Boolean { + // let argument = std::env::args() + // .nth(1) + // .unwrap_or("true".into()) + // .parse::() + // .unwrap(); + // + // println!(" argument passed to command line a = {:?}", argument); + let a = true; + Boolean::alloc(cs.ns(|| variable.0), || Ok(a)).unwrap() +} + +fn u32_from_variable>(cs: &mut CS, variable: Variable) -> UInt32 { + // let argument = std::env::args() + // .nth(1) + // .unwrap_or("1".into()) + // .parse::() + // .unwrap(); + // + // println!(" argument passed to command line a = {:?}", argument); + + let a = 1; + UInt32::alloc(cs.ns(|| variable.0), Some(a)).unwrap() +} + +fn get_bool_value>( + cs: &mut CS, + expression: BooleanExpression, +) -> Boolean { + match expression { + BooleanExpression::Variable(variable) => bool_from_variable(cs, variable), + BooleanExpression::Value(value) => Boolean::Constant(value), + _ => unimplemented!(), + } +} + +fn get_u32_value>( + cs: &mut CS, + expression: FieldExpression, +) -> UInt32 { + match expression { + FieldExpression::Variable(variable) => u32_from_variable(cs, variable), + FieldExpression::Number(number) => UInt32::constant(number), + _ => unimplemented!(), // FieldExpression::Add(left, right) => + } +} + +fn enforce_or>( + cs: &mut CS, + left: BooleanExpression, + right: BooleanExpression, +) { + let left = get_bool_value(cs, left); + let right = get_bool_value(cs, right); + + let _result = Boolean::or(cs, &left, &right).unwrap(); +} + +fn enforce_and>( + cs: &mut CS, + left: BooleanExpression, + right: BooleanExpression, +) { + let left = get_bool_value(cs, left); + let right = get_bool_value(cs, right); + + let _result = Boolean::and(cs, &left, &right).unwrap(); +} + +fn enforce_bool_equality>( + cs: &mut CS, + left: BooleanExpression, + right: BooleanExpression, +) { + let left = get_bool_value(cs, left); + let right = get_bool_value(cs, right); + + left.enforce_equal(cs.ns(|| format!("enforce bool equal")), &right) + .unwrap(); +} + +fn enforce_field_equality>( + cs: &mut CS, + left: FieldExpression, + right: FieldExpression, +) { + let left = get_u32_value(cs, left); + let right = get_u32_value(cs, right); + + left.conditional_enforce_equal( + cs.ns(|| format!("enforce field equal")), + &right, + &Boolean::Constant(true), + ) + .unwrap(); +} + +fn enforce_boolean_expression>( + cs: &mut CS, + expression: BooleanExpression, +) { + match expression { + BooleanExpression::Or(left, right) => { + enforce_or(cs, *left, *right); + } + BooleanExpression::And(left, right) => { + enforce_and(cs, *left, *right); + } + BooleanExpression::BoolEq(left, right) => { + enforce_bool_equality(cs, *left, *right); + } + BooleanExpression::FieldEq(left, right) => { + enforce_field_equality(cs, *left, *right); + } + _ => unimplemented!(), + } +} + +fn enforce_add>( + cs: &mut CS, + left: FieldExpression, + right: FieldExpression, +) { + let left = get_u32_value(cs, left); + let right = get_u32_value(cs, right); + + // let _r = UInt32::addmany(cs.ns(|| "addition"), &[left, right]).unwrap(); +} + +fn enforce_field_expression>( + cs: &mut CS, + expression: FieldExpression, +) { + match expression { + FieldExpression::Add(left, right) => { + enforce_add(cs, *left, *right); + } + _ => unimplemented!(), + } +} + +pub fn generate_constraints>(cs: &mut CS, program: Program) { + program + .statements + .into_iter() + .for_each(|statement| match statement { + Statement::Return(statements) => { + statements + .into_iter() + .for_each(|expression| match expression { + Expression::Boolean(boolean_expression) => { + enforce_boolean_expression(cs, boolean_expression); + } + Expression::FieldElement(field_expression) => { + enforce_field_expression(cs, field_expression); + } + _ => unimplemented!(), + }); + } + _ => unimplemented!(), + }); +} + +// impl Program { +// pub fn setup(&self) { +// self.statements +// .iter() +// .for_each(|statement| { +// +// }) +// } +// } diff --git a/src/aleo_program/mod.rs b/src/aleo_program/mod.rs index b498569a76..fa5dcbb1f4 100644 --- a/src/aleo_program/mod.rs +++ b/src/aleo_program/mod.rs @@ -7,8 +7,8 @@ pub mod types; pub use self::types::*; -pub mod setup; -pub use self::setup::*; +pub mod constraints; +pub use self::constraints::*; pub mod types_display; pub use self::types_display::*; diff --git a/src/aleo_program/setup.rs b/src/aleo_program/setup.rs deleted file mode 100644 index 99899effe1..0000000000 --- a/src/aleo_program/setup.rs +++ /dev/null @@ -1,15 +0,0 @@ -// use crate::{ -// aleo_program::program::{ -// Program, -// }, -// }; - -// impl Program { -// pub fn setup(&self) { -// self.statements -// .iter() -// .for_each(|statement| { -// -// }) -// } -// } diff --git a/src/aleo_program/types_display.rs b/src/aleo_program/types_display.rs index 588d095b3d..292eade165 100644 --- a/src/aleo_program/types_display.rs +++ b/src/aleo_program/types_display.rs @@ -66,16 +66,11 @@ impl fmt::Display for Statement { }); write!(f, "") } - _ => unimplemented!(), // Statement::Constraint(ref quadratic, ref linear) => { - // let a = (quadratic.0).0[0].value.clone(); - // let b = (quadratic.1).0[0].value.clone(); - // let c = linear.0[0].value.clone(); - // - // write!(f, "constraint {} * {} = {}", a, b, c) - // } + _ => unimplemented!(), } } } + impl fmt::Debug for Statement { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { @@ -85,27 +80,7 @@ impl fmt::Debug for Statement { }); write!(f, "") } - _ => unimplemented!(), // Statement::Constraint(ref quadratic, ref linear) => { - // let a = (quadratic.0).0[0].value.clone(); - // let b = (quadratic.1).0[0].value.clone(); - // let c = linear.0[0].value.clone(); - // - // write!(f, "constraint {} * {} = {}", a, b, c) - // } + _ => unimplemented!(), } } } - -// impl fmt::Debug for Statement { -// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { -// match *self { -// Statement::Constraint(ref quadratic, ref linear) => { -// let a = (quadratic.0).0[0].value.clone(); -// let b = (quadratic.1).0[0].value.clone(); -// let c = linear.0[0].value.clone(); -// -// write!(f, "constraint {} * {} = {}", a, b, c) -// } -// } -// } -// } diff --git a/src/aleo_program/types_from.rs b/src/aleo_program/types_from.rs index 83dd16f9ca..90033b4074 100644 --- a/src/aleo_program/types_from.rs +++ b/src/aleo_program/types_from.rs @@ -5,69 +5,13 @@ //! @author Collin Chin //! @date 2020 -use crate::aleo_program::{BooleanExpression, Expression, FieldExpression}; +use crate::aleo_program::BooleanExpression; use crate::{aleo_program::types, ast}; -// use crate::{ -// ast, -// aleo_program::{program, types, NodeValue}, -// }; -// -// impl<'ast> From> for types::ExpressionNode<'ast> { -// fn from(boolean: ast::Boolean<'ast>) -> Self { -// types::Expression::Boolean( -// boolean -// .value -// .parse::() -// .expect("unable to parse boolean"), -// ) -// .span(boolean.span) -// } -// } -// -// impl<'ast> From> for types::ExpressionNode<'ast> { -// fn from(field: ast::Field<'ast>) -> Self { -// types::Expression::Field(field.span.as_str()).span(field.span) -// } -// } -// -// impl<'ast> From> for types::ExpressionNode<'ast> { -// fn from(value: ast::Value<'ast>) -> Self { -// match value { -// ast::Value::Boolean(boolean) => types::ExpressionNode::from(boolean), -// ast::Value::Field(field) => types::ExpressionNode::from(field), -// } -// } -// } -// -// impl<'ast> From> for types::VariableNode<'ast> { -// fn from(variable: ast::Variable<'ast>) -> Self { -// types::Variable { -// id: variable.span.as_str(), -// } -// .span(variable.span) -// } -// } -// -// impl<'ast> From> for types::ExpressionNode<'ast> { -// fn from(variable: ast::Variable<'ast>) -> Self { -// types::Expression::Variable(types::VariableNode::from(variable.clone())).span(variable.span) -// } -// } -// -// impl<'ast> From> for types::ExpressionNode<'ast> { -// fn from(expression: ast::NotExpression<'ast>) -> Self { -// types::Expression::Not(Box::new(types::ExpressionNode::from( -// *expression.expression, -// ))) -// .span(expression.span) -// } -// } - impl<'ast> From> for types::FieldExpression { fn from(field: ast::Field<'ast>) -> Self { let number = field.value.parse::().expect("unable to unwrap field"); - FieldExpression::Number(number) + types::FieldExpression::Number(number) } } @@ -77,28 +21,32 @@ impl<'ast> From> for types::BooleanExpression { .value .parse::() .expect("unable to unwrap boolean"); - BooleanExpression::Value(boolean) + types::BooleanExpression::Value(boolean) } } impl<'ast> From> for types::Expression { fn from(value: ast::Value<'ast>) -> Self { match value { - ast::Value::Boolean(value) => Expression::Boolean(BooleanExpression::from(value)), - ast::Value::Field(value) => Expression::FieldElement(FieldExpression::from(value)), + ast::Value::Boolean(value) => { + types::Expression::Boolean(types::BooleanExpression::from(value)) + } + ast::Value::Field(value) => { + types::Expression::FieldElement(types::FieldExpression::from(value)) + } } } } impl<'ast> From> for types::FieldExpression { fn from(variable: ast::Variable<'ast>) -> Self { - FieldExpression::Variable(types::Variable(variable.value)) + types::FieldExpression::Variable(types::Variable(variable.value)) } } impl<'ast> From> for types::BooleanExpression { fn from(variable: ast::Variable<'ast>) -> Self { - BooleanExpression::Variable(types::Variable(variable.value)) + types::BooleanExpression::Variable(types::Variable(variable.value)) } } @@ -108,6 +56,40 @@ impl<'ast> From> for types::Expression { } } +impl<'ast> From> for types::Expression { + fn from(expression: ast::NotExpression<'ast>) -> Self { + types::Expression::Boolean(BooleanExpression::Not(Box::new( + types::BooleanExpression::from(*expression.expression), + ))) + } +} + +impl<'ast> From> for types::BooleanExpression { + fn from(expression: ast::Expression<'ast>) -> Self { + match types::Expression::from(expression) { + types::Expression::Boolean(boolean_expression) => boolean_expression, + types::Expression::Variable(variable) => types::BooleanExpression::Variable(variable), + types::Expression::FieldElement(field_expression) => unimplemented!( + "cannot compare field expression {} in boolean expression", + field_expression + ), + } + } +} + +impl<'ast> From> for types::FieldExpression { + fn from(expression: ast::Expression<'ast>) -> Self { + match types::Expression::from(expression) { + types::Expression::FieldElement(field_expression) => field_expression, + types::Expression::Variable(variable) => types::FieldExpression::Variable(variable), + types::Expression::Boolean(boolean_expression) => unimplemented!( + "cannot compare boolean expression {} in field expression", + boolean_expression + ), + } + } +} + impl<'ast> types::BooleanExpression { /// Find out which types we are comparing and output the corresponding expression. fn from_eq(expression: ast::BinaryExpression<'ast>) -> Self { @@ -117,51 +99,112 @@ impl<'ast> types::BooleanExpression { // When matching a variable, look at the opposite side to see what we are comparing to and assume that variable type match (left, right) { // Boolean equality - (Expression::Boolean(lhs), Expression::Boolean(rhs)) => { - BooleanExpression::BoolEq(Box::new(lhs), Box::new(rhs)) + (types::Expression::Boolean(lhs), types::Expression::Boolean(rhs)) => { + types::BooleanExpression::BoolEq(Box::new(lhs), Box::new(rhs)) } - (Expression::Boolean(lhs), Expression::Variable(rhs)) => { - BooleanExpression::BoolEq(Box::new(lhs), Box::new(BooleanExpression::Variable(rhs))) + (types::Expression::Boolean(lhs), types::Expression::Variable(rhs)) => { + types::BooleanExpression::BoolEq( + Box::new(lhs), + Box::new(types::BooleanExpression::Variable(rhs)), + ) } - (Expression::Variable(lhs), Expression::Boolean(rhs)) => { - BooleanExpression::BoolEq(Box::new(BooleanExpression::Variable(lhs)), Box::new(rhs)) + (types::Expression::Variable(lhs), types::Expression::Boolean(rhs)) => { + types::BooleanExpression::BoolEq( + Box::new(types::BooleanExpression::Variable(lhs)), + Box::new(rhs), + ) } // Field equality - (Expression::FieldElement(lhs), Expression::FieldElement(rhs)) => { - BooleanExpression::FieldEq(Box::new(lhs), Box::new(rhs)) + (types::Expression::FieldElement(lhs), types::Expression::FieldElement(rhs)) => { + types::BooleanExpression::FieldEq(Box::new(lhs), Box::new(rhs)) } - (Expression::FieldElement(lhs), Expression::Variable(rhs)) => { - BooleanExpression::FieldEq(Box::new(lhs), Box::new(FieldExpression::Variable(rhs))) + (types::Expression::FieldElement(lhs), types::Expression::Variable(rhs)) => { + types::BooleanExpression::FieldEq( + Box::new(lhs), + Box::new(types::FieldExpression::Variable(rhs)), + ) } - (Expression::Variable(lhs), Expression::FieldElement(rhs)) => { - BooleanExpression::FieldEq(Box::new(FieldExpression::Variable(lhs)), Box::new(rhs)) + (types::Expression::Variable(lhs), types::Expression::FieldElement(rhs)) => { + types::BooleanExpression::FieldEq( + Box::new(types::FieldExpression::Variable(lhs)), + Box::new(rhs), + ) } - (_, _) => unimplemented!(), + (lhs, rhs) => unimplemented!("pattern {} == {} unimplemented", lhs, rhs), } } + + fn from_neq(expression: ast::BinaryExpression<'ast>) -> Self { + types::BooleanExpression::Not(Box::new(Self::from_eq(expression))) + } } impl<'ast> From> for types::Expression { fn from(expression: ast::BinaryExpression<'ast>) -> Self { match expression.operation { // Boolean operations - ast::BinaryOperator::Or => unimplemented!(), - ast::BinaryOperator::And => unimplemented!(), + ast::BinaryOperator::Or => types::Expression::Boolean(types::BooleanExpression::Or( + Box::new(types::BooleanExpression::from(*expression.left)), + Box::new(types::BooleanExpression::from(*expression.right)), + )), + ast::BinaryOperator::And => types::Expression::Boolean(types::BooleanExpression::And( + Box::new(types::BooleanExpression::from(*expression.left)), + Box::new(types::BooleanExpression::from(*expression.right)), + )), ast::BinaryOperator::Eq => { - types::Expression::Boolean(BooleanExpression::from_eq(expression)) + types::Expression::Boolean(types::BooleanExpression::from_eq(expression)) } - ast::BinaryOperator::Neq => unimplemented!(), - ast::BinaryOperator::Geq => unimplemented!(), - ast::BinaryOperator::Gt => unimplemented!(), - ast::BinaryOperator::Leq => unimplemented!(), - ast::BinaryOperator::Lt => unimplemented!(), + ast::BinaryOperator::Neq => { + types::Expression::Boolean(types::BooleanExpression::from_neq(expression)) + } + ast::BinaryOperator::Geq => types::Expression::Boolean(types::BooleanExpression::Geq( + Box::new(types::FieldExpression::from(*expression.left)), + Box::new(types::FieldExpression::from(*expression.right)), + )), + ast::BinaryOperator::Gt => types::Expression::Boolean(types::BooleanExpression::Gt( + Box::new(types::FieldExpression::from(*expression.left)), + Box::new(types::FieldExpression::from(*expression.right)), + )), + ast::BinaryOperator::Leq => types::Expression::Boolean(types::BooleanExpression::Leq( + Box::new(types::FieldExpression::from(*expression.left)), + Box::new(types::FieldExpression::from(*expression.right)), + )), + ast::BinaryOperator::Lt => types::Expression::Boolean(types::BooleanExpression::Lt( + Box::new(types::FieldExpression::from(*expression.left)), + Box::new(types::FieldExpression::from(*expression.right)), + )), // Field operations - ast::BinaryOperator::Add => unimplemented!(), - ast::BinaryOperator::Sub => unimplemented!(), - ast::BinaryOperator::Mul => unimplemented!(), - ast::BinaryOperator::Div => unimplemented!(), - ast::BinaryOperator::Pow => unimplemented!(), + ast::BinaryOperator::Add => { + types::Expression::FieldElement(types::FieldExpression::Add( + Box::new(types::FieldExpression::from(*expression.left)), + Box::new(types::FieldExpression::from(*expression.right)), + )) + } + ast::BinaryOperator::Sub => { + types::Expression::FieldElement(types::FieldExpression::Sub( + Box::new(types::FieldExpression::from(*expression.left)), + Box::new(types::FieldExpression::from(*expression.right)), + )) + } + ast::BinaryOperator::Mul => { + types::Expression::FieldElement(types::FieldExpression::Mul( + Box::new(types::FieldExpression::from(*expression.left)), + Box::new(types::FieldExpression::from(*expression.right)), + )) + } + ast::BinaryOperator::Div => { + types::Expression::FieldElement(types::FieldExpression::Div( + Box::new(types::FieldExpression::from(*expression.left)), + Box::new(types::FieldExpression::from(*expression.right)), + )) + } + ast::BinaryOperator::Pow => { + types::Expression::FieldElement(types::FieldExpression::Pow( + Box::new(types::FieldExpression::from(*expression.left)), + Box::new(types::FieldExpression::from(*expression.right)), + )) + } } } } @@ -171,7 +214,7 @@ impl<'ast> From> for types::Expression { match expression { ast::Expression::Value(value) => types::Expression::from(value), ast::Expression::Variable(variable) => types::Expression::from(variable), - ast::Expression::Not(_expression) => unimplemented!(), + ast::Expression::Not(expression) => types::Expression::from(expression), ast::Expression::Binary(expression) => types::Expression::from(expression), } } @@ -224,102 +267,3 @@ impl<'ast> From> for types::Program { } } } - -// #[cfg(test)] -// mod tests { -// use super::*; -// -// #[test] -// fn test_file() { -// -// } -// } - -// impl<'ast> From> for types::LinearCombination { -// fn from(variable: ast::Variable<'ast>) -> Self { -// LinearCombination(vec![Variable { id: 1, value: variable.value }]) -// } -// } -// -// impl<'ast> From> for types::LinearCombination { -// fn from(boolean: ast::Boolean<'ast>) -> Self { -// LinearCombination(vec![Variable { id: -1, value: boolean.value }]) -// } -// } -// -// impl<'ast> From> for types::LinearCombination { -// fn from(field: ast::Field<'ast>) -> Self { -// LinearCombination(vec![Variable { id: 0, value: field.value }]) -// } -// } -// impl<'ast> From> for types::LinearCombination { -// fn from(value: ast::Value<'ast>) -> Self { -// match value { -// ast::Value::Boolean(boolean) => types::LinearCombination::from(boolean), -// ast::Value::Field(field) => types::LinearCombination::from(field), -// } -// } -// } -// -// impl<'ast> From> for types::LinearCombination { -// fn from(expression: ast::Expression<'ast>) -> Self { -// match expression { -// ast::Expression::Value(value) => types::LinearCombination::from(value), -// ast::Expression::Variable(variable) => types::LinearCombination::from(variable), -// ast::Expression::Not(_) => unimplemented!(), -// ast::Expression::Binary(_) => unimplemented!(), -// } -// } -// } -// -// impl<'ast> types::Expression { -// fn unwrap_expression(expression: ast::Expression<'ast>) -> Vec { -// match expression { -// ast::Expression::Value(value) => unimplemented!(), -// ast::Expression::Variable(variable) => unimplemented!(), -// ast::Expression::Not(expression) => unimplemented!(), -// ast::Expression::Binary(expression) => Self::unwrap_binary(expression), -// } -// } -// -// fn unwrap_binary(expression: ast::BinaryExpression<'ast>) -> Vec { -// match expression.operation { -// ast::BinaryOperator::Eq => , -// _ => unimplemented!() -// } -// } -// -// fn unwrap_eq(expression: ast::BinaryExpression<'ast>) -> Vec { -// -// } -// } -// -// impl<'ast> types::Statement { -// fn unwrap_statement(statement: ast::Statement<'ast>) -> Self { -// match statement { -// ast::Statement::Assign(statement) => unimplemented!(), -// ast::Statement::Return(statement) => Self::unwrap_return(statement), -// } -// } -// -// fn unwrap_return(statement: ast::ReturnStatement<'ast>) -> Self { -// let mut expressions: Vec = vec![]; -// -// statement -// .expressions -// .into_iter() -// .map(|expression| { -// expressions.extend_from_slice(&types::Expression::unwrap_expression(expression)) -// }); -// -// types::Statement::Return(expressions) -// } -// } -// -// impl<'ast> From> for types::Statement { -// fn from(statement: ast::Statement<'ast>) -> Self { -// match statement { -// ast::Statement::Assign(statement) => unimplemented!() -// } -// } -// } diff --git a/src/main.rs b/src/main.rs index ed065c628a..d35b7f445a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,169 +1,106 @@ use language::*; use from_pest::FromPest; -use std::fs; +use std::{ + fs, + marker::PhantomData, + time::{Duration, Instant}, +}; + +use snarkos_curves::bls12_377::{Bls12_377, Fr}; +use snarkos_errors::gadgets::SynthesisError; +use snarkos_models::curves::Field; +use snarkos_models::gadgets::r1cs::{ConstraintSynthesizer, ConstraintSystem}; + +use snarkos_algorithms::snark::{ + create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof, +}; + +use rand::thread_rng; + // use std::env; +pub struct Benchmark { + _engine: PhantomData, +} + +impl Benchmark { + pub fn new() -> Self { + Self { + _engine: PhantomData, + } + } +} + +impl ConstraintSynthesizer for Benchmark { + fn generate_constraints>( + self, + cs: &mut CS, + ) -> Result<(), SynthesisError> { + // Read in file as string + let unparsed_file = fs::read_to_string("simple.program").expect("cannot read file"); + + // Parse the file using langauge.pest + let mut file = ast::parse(&unparsed_file).expect("unsuccessful parse"); + + // Build the abstract syntax tree + let syntax_tree = ast::File::from_pest(&mut file).expect("infallible"); + // println!("{:#?}", syntax_tree); + + let program = aleo_program::Program::from(syntax_tree); + println!(" compiled: {:#?}", program); + + aleo_program::generate_constraints(cs, program); + + Ok(()) + } +} + fn main() { - // use snarkos_gadgets::curves::edwards_bls12::FqGadget; - use snarkos_models::gadgets::{ - r1cs::{ConstraintSystem, Fr, TestConstraintSystem}, - utilities::{ - alloc::AllocGadget, boolean::Boolean, eq::ConditionalEqGadget, uint32::UInt32, - }, + let mut setup = Duration::new(0, 0); + let mut proving = Duration::new(0, 0); + let mut verifying = Duration::new(0, 0); + + let rng = &mut thread_rng(); + + let start = Instant::now(); + + let params = { + let c = Benchmark::::new(); + generate_random_parameters::(c, rng).unwrap() }; - // Read in file as string - let unparsed_file = fs::read_to_string("simple.program").expect("cannot read file"); + let prepared_verifying_key = prepare_verifying_key(¶ms.vk); - // Parse the file using langauge.pest - let mut file = ast::parse(&unparsed_file).expect("unsuccessful parse"); + setup += start.elapsed(); - // Build the abstract syntax tree - let syntax_tree = ast::File::from_pest(&mut file).expect("infallible"); - // println!("{:#?}", syntax_tree); + let start = Instant::now(); + let proof = { + let c = Benchmark::new(); + create_random_proof(c, ¶ms, rng).unwrap() + }; - let program = aleo_program::Program::from(syntax_tree); - println!(" compiled: {:#?}", program); + proving += start.elapsed(); - let mut cs = TestConstraintSystem::::new(); - let argument = std::env::args() - .nth(1) - .unwrap_or("1".into()) - .parse::() - .unwrap(); + // let _inputs: Vec<_> = [1u32; 1].to_vec(); - println!(" argument passed to command line a = {:?}", argument); + let start = Instant::now(); - program - .statements - .into_iter() - .for_each(|statement| match statement { - aleo_program::Statement::Return(statements) => { - statements - .into_iter() - .for_each(|expression| match expression { - aleo_program::Expression::Boolean(operation) => match operation { - aleo_program::BooleanExpression::FieldEq(lhs, rhs) => match *lhs { - aleo_program::FieldExpression::Variable(variable) => { - let left_variable = - UInt32::alloc(cs.ns(|| variable.0), Some(argument)) - .unwrap(); - match *rhs { - aleo_program::FieldExpression::Number(number) => { - let right_number = UInt32::constant(number); + let _ = verify_proof(&prepared_verifying_key, &proof, &[]).unwrap(); - let bool = Boolean::alloc( - cs.ns(|| format!("boolean")), - || Ok(true), - ) - .unwrap(); - left_variable - .conditional_enforce_equal( - cs.ns(|| format!("enforce equal")), - &right_number, - &bool, - ) - .unwrap(); - } - _ => unimplemented!(), - } - } - _ => unimplemented!(), - }, - _ => unimplemented!(), - }, - _ => unimplemented!(), - }); - } - _ => unimplemented!(), - }); + verifying += start.elapsed(); - // program - // .statements - // .into_iter() - // .for_each(|statement| { - // match statement { - // aleo_program::Statement::Constraint(quadratic, linear) => { - // let a_var = (quadratic.0).0[0].clone(); - // assert!(a_var.id > 0); + println!("\n Setup time: {:?} seconds", setup.as_secs()); + println!(" Proving time: {:?} seconds", proving.as_secs()); + println!(" Verifying time: {:?} seconds", verifying.as_secs()); + + // let mut cs = TestConstraintSystem::::new(); // - // let c_var = linear.0[0].clone(); - // let c_value = c_var.value.parse::().unwrap(); + // println!("\n satisfied: {:?}", cs.is_satisfied()); // - // let a_bit = UInt32::alloc(cs.ns(|| "a_bit"), Some(argument)).unwrap(); - // let c_bit = UInt32::constant(c_value); - // let bool = Boolean::alloc(cs.ns(|| format!("boolean")), || Ok(true)).unwrap(); + // println!( + // "\n number of constraints for input: {}", + // cs.num_constraints() + // ); // - // a_bit.conditional_enforce_equal(cs.ns(|| format!("enforce equal")), &c_bit, &bool).unwrap(); - // } - // } - // }); - - // let program = zokrates_program::Program::from(syntax_tree); - - // println!("{:#?}", program); - - // // Use this code when proving - // let left_u32 = left_string.parse::().unwrap(); - // let right_u32 = right_string.parse::().unwrap(); - // - // println!("left u32 value: {:#?}", left_u32); - // println!("right u32 value: {:#?}", right_u32); - // - // let left_constraint = UInt32::alloc(cs.ns(|| "left variable"), Some(left_u32)).unwrap(); - // let right_constraint = UInt32::constant(right_u32); - // - // let bool = Boolean::alloc(cs.ns(|| format!("boolean")), || Ok(true)).unwrap(); - // - // left_constraint.conditional_enforce_equal(cs.ns(|| format!("enforce left == right")), &right_constraint, &bool).unwrap(); - - // Constraint testing - // let bool = Boolean::alloc(cs.ns(|| format!("boolean")), || Ok(true)).unwrap(); - // let a_bit = UInt32::alloc(cs.ns(|| "a_bit"), Some(4u32)).unwrap(); - // let b_bit = UInt32::constant(4u32); - // - // a_bit.conditional_enforce_equal(cs.ns(|| format!("enforce equal")), &b_bit, &bool).unwrap(); - - println!("\n satisfied: {:?}", cs.is_satisfied()); - - println!( - "\n number of constraints for input: {}", - cs.num_constraints() - ); - - // for token in file.into_inner() { - // match token.as_rule() { - // Rule::statement => println!("{:?}", token.into_inner()), - // Rule::EOI => println!("END"), - // _ => println!("{:?}", token.into_inner()), - // } - // // println!("{:?}", token); - // } - - // let mut field_sum: f64 = 0.0; - // let mut record_count: u64 = 0; - // - // for record in file.into_inner() { - // match record.as_rule() { - // Rule::record => { - // record_count += 1; - // - // for field in record.into_inner() { - // field_sum += field.as_str().parse::().unwrap(); - // } - // } - // Rule::EOI => (), - // _ => unreachable!(), - // } - // } - - // println!("Sum of fields: {}", field_sum); - // println!("Number of records: {}", record_count); - - // let successful_parse = LanguageParser::parse(Rule::value, "-273"); - // println!("{:?}", successful_parse); - - // let unsuccessful_parse = CSVParser::parse(Rule::field, "this is not a number"); - // println!("{:?}", unsuccessful_parse); }