add new testing methods. add boolean tests.

This commit is contained in:
collin 2020-05-19 15:45:40 -07:00
parent e5fea1e468
commit 9a9e37e0f4
33 changed files with 480 additions and 116 deletions

View File

@ -23,7 +23,7 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
private: bool,
integer_option: Option<usize>,
) -> Result<ConstrainedValue<F, G>, IntegerError> {
// Type cast to u32 in rust.
// Type cast to integers.u32 in rust.
// If this fails should we return our own error?
let u32_option = integer_option.map(|integer| integer as u32);
@ -46,7 +46,7 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
left: UInt32,
right: UInt32,
) -> Result<(), IntegerError> {
Ok(left.enforce_equal(cs.ns(|| format!("enforce u32 equal")), &right)?)
Ok(left.enforce_equal(cs.ns(|| format!("enforce integers.u32 equal")), &right)?)
}
pub(crate) fn enforce_u32_add(

View File

@ -6,12 +6,6 @@ pub enum BooleanError {
#[error("{}", _0)]
ValueError(ValueError),
#[error("Expected boolean array parameter, got {}", _0)]
InvalidArray(String),
#[error("Expected boolean array with length {}, got length {}", _0, _1)]
InvalidArrayLength(usize, usize),
#[error("Expected boolean parameter, got {}", _0)]
InvalidBoolean(String),

View File

@ -267,7 +267,7 @@ impl fmt::Display for IntegerType {
match *self {
IntegerType::U8 => write!(f, "u8"),
IntegerType::U16 => write!(f, "u16"),
IntegerType::U32 => write!(f, "u32"),
IntegerType::U32 => write!(f, "integers.u32"),
IntegerType::U64 => write!(f, "u64"),
IntegerType::U128 => write!(f, "u128"),
}

View File

@ -51,7 +51,10 @@ impl<'ast> types::Integer {
number.value.parse::<u16>().expect("unable to parse u16"),
)),
ast::IntegerType::U32Type(_u32) => types::Integer::U32(UInt32::constant(
number.value.parse::<u32>().expect("unable to parse u32"),
number
.value
.parse::<u32>()
.expect("unable to parse integers.u32"),
)),
ast::IntegerType::U64Type(_u64) => types::Integer::U64(UInt64::constant(
number.value.parse::<u64>().expect("unable to parse u64"),

View File

@ -0,0 +1,8 @@
// !(true && (false || true))
function main() -> bool {
let a = true;
let b = false || a;
let c = !(true && b);
return c
}

View File

@ -0,0 +1,3 @@
function main() -> bool {
return false
}

View File

@ -0,0 +1,3 @@
function main() -> bool {
return false && false
}

View File

@ -0,0 +1,3 @@
function main() -> bool {
return false || false
}

View File

@ -0,0 +1,146 @@
use crate::{compile_program, get_error, get_output};
use leo_compiler::errors::{BooleanError, ExpressionError};
use leo_compiler::{
compiler::Compiler,
errors::{CompilerError, FunctionError, StatementError},
ConstrainedValue,
};
use snarkos_curves::{bls12_377::Fr, edwards_bls12::EdwardsProjective};
use snarkos_models::gadgets::utilities::boolean::Boolean;
const DIRECTORY_NAME: &str = "tests/boolean/";
fn output_true(program: Compiler<Fr, EdwardsProjective>) {
let output = get_output(program);
assert_eq!(
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Boolean(
Boolean::Constant(true)
)]),
output
);
}
fn output_false(program: Compiler<Fr, EdwardsProjective>) {
let output = get_output(program);
assert_eq!(
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Boolean(
Boolean::Constant(false)
)]),
output
);
}
fn fail_evaluate(program: Compiler<Fr, EdwardsProjective>) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::ExpressionError(ExpressionError::BooleanError(
BooleanError::CannotEvaluate(_string),
)),
)) => {}
error => panic!("Expected evaluate error, got {}", error),
}
}
fn fail_enforce(program: Compiler<Fr, EdwardsProjective>) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::ExpressionError(ExpressionError::BooleanError(
BooleanError::CannotEnforce(_string),
)),
)) => {}
error => panic!("Expected evaluate error, got {}", error),
}
}
#[test]
fn test_true() {
let program = compile_program(DIRECTORY_NAME, "true.leo").unwrap();
output_true(program);
}
#[test]
fn test_false() {
let program = compile_program(DIRECTORY_NAME, "false.leo").unwrap();
output_false(program);
}
// Boolean not !
#[test]
fn test_not_true() {
let program = compile_program(DIRECTORY_NAME, "not_true.leo").unwrap();
output_false(program);
}
#[test]
fn test_not_false() {
let program = compile_program(DIRECTORY_NAME, "not_false.leo").unwrap();
output_true(program);
}
#[test]
fn test_not_u32() {
let program = compile_program(DIRECTORY_NAME, "not_u32.leo").unwrap();
fail_evaluate(program);
}
// Boolean or ||
#[test]
fn test_true_or_true() {
let program = compile_program(DIRECTORY_NAME, "true_||_true.leo").unwrap();
output_true(program);
}
#[test]
fn test_true_or_false() {
let program = compile_program(DIRECTORY_NAME, "true_||_false.leo").unwrap();
output_true(program);
}
#[test]
fn test_false_or_false() {
let program = compile_program(DIRECTORY_NAME, "false_||_false.leo").unwrap();
output_false(program);
}
#[test]
fn test_true_or_u32() {
let program = compile_program(DIRECTORY_NAME, "true_||_u32.leo").unwrap();
fail_enforce(program);
}
// Boolean and &&
#[test]
fn test_true_and_true() {
let program = compile_program(DIRECTORY_NAME, "true_&&_true.leo").unwrap();
output_true(program);
}
#[test]
fn test_true_and_false() {
let program = compile_program(DIRECTORY_NAME, "true_&&_false.leo").unwrap();
output_false(program);
}
#[test]
fn test_false_and_false() {
let program = compile_program(DIRECTORY_NAME, "false_&&_false.leo").unwrap();
output_false(program);
}
#[test]
fn test_true_and_u32() {
let program = compile_program(DIRECTORY_NAME, "true_&&_u32.leo").unwrap();
fail_enforce(program);
}
// All
#[test]
fn test_all() {
let program = compile_program(DIRECTORY_NAME, "all.leo").unwrap();
output_false(program);
}

View File

@ -0,0 +1,3 @@
function main() -> bool {
return !false
}

View File

@ -0,0 +1,3 @@
function main() -> bool {
return !true
}

View File

@ -0,0 +1,3 @@
function main() -> bool {
return !1u32
}

View File

@ -0,0 +1,3 @@
function main() -> bool {
return true
}

View File

@ -0,0 +1,3 @@
function main() -> bool {
return true && false
}

View File

@ -0,0 +1,3 @@
function main() -> bool {
return true && true
}

View File

@ -0,0 +1,3 @@
function main() -> bool {
return true && 1u32
}

View File

@ -0,0 +1,3 @@
function main() -> bool {
return true || false
}

View File

@ -0,0 +1,3 @@
function main() -> bool {
return true || true
}

View File

@ -0,0 +1,3 @@
function main() -> bool {
return true || 1u32
}

View File

@ -0,0 +1,169 @@
pub mod u32;
// use crate::compile_program;
//
// use leo_compiler::{
// ConstrainedValue,
// compiler::Compiler,
// errors::{
// CompilerError,
// FunctionError,
// StatementError
// }
// };
// use snarkos_curves::{bls12_377::Fr, edwards_bls12::EdwardsProjective};
// use snarkos_models::gadgets::{
// r1cs::TestConstraintSystem
// };
// use snarkos_models::gadgets::utilities::boolean::Boolean;
// use leo_compiler::errors::{ExpressionError, BooleanError};
//
// const DIRECTORY_NAME: &str = "tests/integers/";
//
// fn get_output(program: Compiler<Fr, EdwardsProjective>) -> ConstrainedValue<Fr, EdwardsProjective>{
// let mut cs = TestConstraintSystem::<Fr>::new();
// let output = program.compile_constraints(&mut cs).unwrap();
// assert!(cs.is_satisfied());
// output
// }
//
// fn output_true(program: Compiler<Fr, EdwardsProjective>) {
// let output = get_output(program);
// assert_eq!(
// ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Boolean(
// Boolean::Constant(true)
// )]),
// output
// );
// }
//
// fn output_false(program: Compiler<Fr, EdwardsProjective>) {
// let output = get_output(program);
// assert_eq!(
// ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Boolean(
// Boolean::Constant(false)
// )]),
// output
// );
// }
//
// fn get_error(program: Compiler<Fr, EdwardsProjective>) -> CompilerError {
// let mut cs = TestConstraintSystem::<Fr>::new();
// program.compile_constraints(&mut cs).unwrap_err()
// }
//
// fn fail_evaluate(program: Compiler<Fr, EdwardsProjective>) {
// match get_error(program) {
// CompilerError::FunctionError(
// FunctionError::StatementError(
// StatementError::ExpressionError(
// ExpressionError::BooleanError(
// BooleanError::CannotEvaluate(_string))))) => {},
// error => panic!("Expected evaluate error, got {}", error),
// }
// }
//
// fn fail_enforce(program: Compiler<Fr, EdwardsProjective>) {
// match get_error(program) {
// CompilerError::FunctionError(
// FunctionError::StatementError(
// StatementError::ExpressionError(
// ExpressionError::BooleanError(
// BooleanError::CannotEnforce(_string))))) => {},
// error => panic!("Expected evaluate error, got {}", error),
// }
// }
//
// #[test]
// fn test_true() {
// let program = compile_program(DIRECTORY_NAME, "true.leo").unwrap();
// output_true(program);
// }
//
// #[test]
// fn test_false() {
// let program = compile_program(DIRECTORY_NAME, "false.leo").unwrap();
// output_false(program);
// }
//
// // Boolean not !
//
// #[test]
// fn test_not_true() {
// let program = compile_program(DIRECTORY_NAME, "not_true.leo").unwrap();
// output_false(program);
// }
//
// #[test]
// fn test_not_false() {
// let program = compile_program(DIRECTORY_NAME, "not_false.leo").unwrap();
// output_true(program);
// }
//
// #[test]
// fn test_not_u32() {
// let program = compile_program(DIRECTORY_NAME, "not_u32.leo").unwrap();
// fail_evaluate(program);
// }
//
// // Boolean or ||
//
// #[test]
// fn test_true_or_true() {
// let program = compile_program(DIRECTORY_NAME, "true_||_true.leo").unwrap();
// output_true(program);
// }
//
// #[test]
// fn test_true_or_false() {
// let program = compile_program(DIRECTORY_NAME, "true_||_false.leo").unwrap();
// output_true(program);
// }
//
// #[test]
// fn test_false_or_false() {
// let program = compile_program(DIRECTORY_NAME, "false_||_false.leo").unwrap();
// output_false(program);
// }
//
// #[test]
// fn test_true_or_u32() {
// let program = compile_program(DIRECTORY_NAME, "true_||_u32.leo").unwrap();
// fail_enforce(program);
// }
//
// // Boolean and &&
//
// #[test]
// fn test_true_and_true() {
// let program = compile_program(DIRECTORY_NAME, "true_&&_true.leo").unwrap();
// output_true(program);
// }
//
// #[test]
// fn test_true_and_false() {
// let program = compile_program(DIRECTORY_NAME, "true_&&_false.leo").unwrap();
// output_false(program);
// }
//
// #[test]
// fn test_false_and_false() {
// let program = compile_program(DIRECTORY_NAME, "false_&&_false.leo").unwrap();
// output_false(program);
// }
//
// #[test]
// fn test_true_and_u32() {
// let program = compile_program(DIRECTORY_NAME, "true_&&_u32.leo").unwrap();
// fail_enforce(program);
// }
//
// // All
//
// #[test]
// fn test_all() {
// let program = compile_program(DIRECTORY_NAME, "all.leo").unwrap();
// output_false(program);
// }
//
//

View File

@ -0,0 +1,3 @@
function main() -> u32 {
return 1 + 1
}

View File

@ -0,0 +1,3 @@
function main() -> u32 {
return 1 - 1
}

View File

@ -1,4 +1,4 @@
// This program should panic at compilation.
function main() -> (u32) {
function main() -> u32 {
return 1 - 2
}

View File

@ -0,0 +1,73 @@
use crate::{
compile_program,
// get_error,
get_output,
};
use leo_compiler::{compiler::Compiler, types::Integer, ConstrainedValue};
use snarkos_curves::{bls12_377::Fr, edwards_bls12::EdwardsProjective};
use snarkos_models::gadgets::utilities::uint32::UInt32;
const DIRECTORY_NAME: &str = "tests/integers/u32/";
fn output_zero(program: Compiler<Fr, EdwardsProjective>) {
let output = get_output(program);
assert_eq!(
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Integer(
Integer::U32(UInt32::constant(0u32))
)]),
output
)
}
fn output_one(program: Compiler<Fr, EdwardsProjective>) {
let output = get_output(program);
assert_eq!(
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Integer(
Integer::U32(UInt32::constant(1u32))
)]),
output
)
}
fn output_two(program: Compiler<Fr, EdwardsProjective>) {
let output = get_output(program);
assert_eq!(
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Integer(
Integer::U32(UInt32::constant(2u32))
)]),
output
)
}
#[test]
fn test_zero() {
let program = compile_program(DIRECTORY_NAME, "zero.leo").unwrap();
output_zero(program);
}
#[test]
fn test_one() {
let program = compile_program(DIRECTORY_NAME, "one.leo").unwrap();
output_one(program);
}
#[test]
fn test_1_plus_1() {
let program = compile_program(DIRECTORY_NAME, "1+1.leo").unwrap();
output_two(program);
}
#[test]
fn test_1_minus_1() {
let program = compile_program(DIRECTORY_NAME, "1-1.leo").unwrap();
output_zero(program)
}
// #[test] // Todo: Catch subtraction overflow error in gadget
// fn test_1_minus_2() {
// let program = compile_program(DIRECTORY_NAME, "1-2.leo").unwrap();
// let error = get_error(program);
// println!("{}", error);
// }

View File

@ -0,0 +1,3 @@
function main() -> u32 {
return 1
}

View File

@ -0,0 +1,3 @@
function main() -> u32 {
return 0
}

View File

@ -1,12 +1,28 @@
pub mod boolean;
pub mod integers;
pub mod mutability;
pub mod u32;
use leo_compiler::{compiler::Compiler, errors::CompilerError};
use leo_compiler::{compiler::Compiler, errors::CompilerError, ConstrainedValue};
use snarkos_curves::{bls12_377::Fr, edwards_bls12::EdwardsProjective};
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
use std::env::current_dir;
pub(crate) fn get_output(
program: Compiler<Fr, EdwardsProjective>,
) -> ConstrainedValue<Fr, EdwardsProjective> {
let mut cs = TestConstraintSystem::<Fr>::new();
let output = program.compile_constraints(&mut cs).unwrap();
assert!(cs.is_satisfied());
output
}
pub(crate) fn get_error(program: Compiler<Fr, EdwardsProjective>) -> CompilerError {
let mut cs = TestConstraintSystem::<Fr>::new();
program.compile_constraints(&mut cs).unwrap_err()
}
pub(crate) fn compile_program(
directory_name: &str,
file_name: &str,

View File

@ -1,14 +1,13 @@
use crate::compile_program;
use leo_compiler::{types::Integer, ConstrainedValue, InputValue};
use leo_compiler::compiler::Compiler;
use leo_compiler::errors::CompilerError;
use leo_compiler::errors::FunctionError;
use leo_compiler::errors::StatementError;
use leo_compiler::{
compiler::Compiler,
errors::{CompilerError, FunctionError, StatementError},
types::{InputValue, Integer},
ConstrainedValue,
};
use snarkos_curves::{bls12_377::Fr, edwards_bls12::EdwardsProjective};
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
use snarkos_models::gadgets::utilities::uint32::UInt32;
use snarkos_models::gadgets::{r1cs::TestConstraintSystem, utilities::uint32::UInt32};
const DIRECTORY_NAME: &str = "tests/mutability/";

View File

@ -1,3 +0,0 @@
function main() -> (u32) {
return 1 + 1
}

View File

@ -1,3 +0,0 @@
function main() -> (u32) {
return 1 - 1
}

View File

@ -1,83 +0,0 @@
use crate::compile_program;
use leo_compiler::{types::Integer, ConstrainedValue};
use snarkos_curves::{bls12_377::Fr, edwards_bls12::EdwardsProjective};
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
use snarkos_models::gadgets::utilities::uint32::UInt32;
const DIRECTORY_NAME: &str = "tests/u32/";
#[test]
fn test_zero() {
let mut cs = TestConstraintSystem::<Fr>::new();
let program = compile_program(DIRECTORY_NAME, "zero.leo").unwrap();
let output = program.compile_constraints(&mut cs).unwrap();
println!("{}", output);
assert!(cs.is_satisfied());
assert_eq!(
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Integer(
Integer::U32(UInt32::constant(0))
)]),
output
);
}
#[test]
fn test_one() {
let mut cs = TestConstraintSystem::<Fr>::new();
let program = compile_program(DIRECTORY_NAME, "one.leo").unwrap();
let output = program.compile_constraints(&mut cs).unwrap();
println!("{}", output);
assert!(cs.is_satisfied());
assert_eq!(
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Integer(
Integer::U32(UInt32::constant(1))
)]),
output
);
}
#[test]
fn test_1_plus_1() {
let mut cs = TestConstraintSystem::<Fr>::new();
let program = compile_program(DIRECTORY_NAME, "1+1.leo").unwrap();
let output = program.compile_constraints(&mut cs).unwrap();
println!("{}", output);
assert!(cs.is_satisfied());
assert_eq!(
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Integer(
Integer::U32(UInt32::constant(2))
)]),
output
);
}
#[test]
fn test_1_minus_1() {
let mut cs = TestConstraintSystem::<Fr>::new();
let program = compile_program(DIRECTORY_NAME, "1-1.leo").unwrap();
let output = program.compile_constraints(&mut cs).unwrap();
println!("{}", output);
assert!(cs.is_satisfied());
assert_eq!(
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Integer(
Integer::U32(UInt32::constant(0))
)]),
output
);
}
// #[test]
// fn test_1_minus_2_should_fail() {
// // TODO (howardwu): Catch panic from subtraction overflow
//
// let mut cs = TestConstraintSystem::<Fr>::new();
// let program = compile_program(DIRECTORY_NAME, "1-2.leo").unwrap();
// let output = program.compile_constraints(&mut cs);
// assert!(output.is_err());
// }

View File

@ -1,3 +0,0 @@
function main() -> (u32) {
return 1
}

View File

@ -1,3 +0,0 @@
function main() -> (u32) {
return 0
}