impl integer gadget tests. test u32

This commit is contained in:
collin 2020-06-05 15:34:06 -07:00
parent c5868b430a
commit c72cf61ad2
12 changed files with 275 additions and 4 deletions

View File

@ -236,6 +236,10 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
right: ConstrainedValue<F, G>,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
let result = num_1.ge(&num_2);
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
}
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
let result = fe_1.ge(&fe_2);
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
@ -261,6 +265,10 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
right: ConstrainedValue<F, G>,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
let result = num_1.gt(&num_2);
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
}
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
let result = fe_1.gt(&fe_2);
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
@ -286,6 +294,10 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
right: ConstrainedValue<F, G>,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
let result = num_1.le(&num_2);
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
}
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
let result = fe_1.le(&fe_2);
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
@ -311,6 +323,10 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
right: ConstrainedValue<F, G>,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
let result = num_1.lt(&num_2);
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
}
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
let result = fe_1.lt(&fe_2);
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))

View File

@ -34,7 +34,7 @@ pub struct Variable {
}
/// An integer type enum wrapping the integer value. Used only in expressions.
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)]
pub enum Integer {
U8(UInt8),
U16(UInt16),

View File

@ -127,7 +127,7 @@ macro_rules! test_uint {
let r1: $_type = rand::random();
let r2: $_type = rand::random();
let sum = r1.wrapping_pow(r2);
let sum = r1.wrapping_pow(r2 as u32);
let cs = TestConstraintSystem::<Fq>::new();
let sum_allocated = <$gadget>::alloc(cs, || Ok(sum)).unwrap();
@ -141,6 +141,207 @@ macro_rules! test_uint {
output_expected_allocated(program, sum_allocated);
}
}
fn test_eq() {
for _ in 0..10 {
let r1: $_type = rand::random();
// test equal
let mut program = compile_program($directory, "eq.leo").unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as usize)),
Some(InputValue::Integer(r1 as usize)),
]);
output_true(program);
// test not equal
let r2: $_type = rand::random();
let result = r1.eq(&r2);
let mut program = compile_program($directory, "eq.leo").unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as usize)),
Some(InputValue::Integer(r2 as usize)),
]);
output_expected_boolean(program, result);
}
}
fn test_ge() {
for _ in 0..10 {
let r1: $_type = rand::random();
// test equal
let mut program = compile_program($directory, "ge.leo").unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as usize)),
Some(InputValue::Integer(r1 as usize)),
]);
output_true(program);
// test not equal
let r2: $_type = rand::random();
let result = r1.ge(&r2);
let mut program = compile_program($directory, "ge.leo").unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as usize)),
Some(InputValue::Integer(r2 as usize)),
]);
output_expected_boolean(program, result);
}
}
fn test_gt() {
for _ in 0..10 {
let r1: $_type = rand::random();
// test equal
let mut program = compile_program($directory, "gt.leo").unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as usize)),
Some(InputValue::Integer(r1 as usize)),
]);
output_false(program);
// test not equal
let r2: $_type = rand::random();
let result = r1.gt(&r2);
let mut program = compile_program($directory, "gt.leo").unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as usize)),
Some(InputValue::Integer(r2 as usize)),
]);
output_expected_boolean(program, result);
}
}
fn test_le() {
for _ in 0..10 {
let r1: $_type = rand::random();
// test equal
let mut program = compile_program($directory, "le.leo").unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as usize)),
Some(InputValue::Integer(r1 as usize)),
]);
output_true(program);
// test not equal
let r2: $_type = rand::random();
let result = r1.le(&r2);
let mut program = compile_program($directory, "le.leo").unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as usize)),
Some(InputValue::Integer(r2 as usize)),
]);
output_expected_boolean(program, result);
}
}
fn test_lt() {
for _ in 0..10 {
let r1: $_type = rand::random();
// test equal
let mut program = compile_program($directory, "lt.leo").unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as usize)),
Some(InputValue::Integer(r1 as usize)),
]);
output_false(program);
// test not equal
let r2: $_type = rand::random();
let result = r1.lt(&r2);
let mut program = compile_program($directory, "lt.leo").unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as usize)),
Some(InputValue::Integer(r2 as usize)),
]);
output_expected_boolean(program, result);
}
}
fn test_assert_eq() {
for _ in 0..10 {
let r1: $_type = rand::random();
// test equal
let mut program = compile_program($directory, "assert_eq.leo").unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as usize)),
Some(InputValue::Integer(r1 as usize)),
]);
let _ = get_output(program);
// test not equal
let r2: $_type = rand::random();
if r1 == r2 {
continue;
}
let mut program = compile_program($directory, "assert_eq.leo").unwrap();
program.set_inputs(vec![
Some(InputValue::Integer(r1 as usize)),
Some(InputValue::Integer(r2 as usize)),
]);
let mut cs = TestConstraintSystem::<Fq>::new();
let _ = program.compile_constraints(&mut cs).unwrap();
assert!(!cs.is_satisfied());
}
}
fn test_ternary() {
let r1: $_type = rand::random();
let r2: $_type = rand::random();
let g1 = <$gadget>::constant(r1);
let g2 = <$gadget>::constant(r2);
let mut program_1 = compile_program($directory, "ternary.leo").unwrap();
let mut program_2 = program_1.clone();
// true -> field 1
program_1.set_inputs(vec![
Some(InputValue::Boolean(true)),
Some(InputValue::Integer(r1 as usize)),
Some(InputValue::Integer(r2 as usize)),
]);
output_expected_allocated(program_1, g1);
// false -> field 2
program_2.set_inputs(vec![
Some(InputValue::Boolean(false)),
Some(InputValue::Integer(r1 as usize)),
Some(InputValue::Integer(r2 as usize)),
]);
output_expected_allocated(program_2, g2);
}
}
};
}

View File

@ -20,7 +20,29 @@ pub trait IntegerTester {
/// Tests a wrapping exponentiation
fn test_pow();
/// Tests == evaluation
fn test_eq();
/// Tests >= evaluation
fn test_ge();
/// Tests > evaluation
fn test_gt();
/// Tests <= evaluation
fn test_le();
/// Tests < evaluation
fn test_lt();
/// Test assert equals constraint keyword
fn test_assert_eq();
/// Test ternary if bool ? num_1 : num_2;
fn test_ternary();
}
// must be below macro definitions!
// pub mod u8;
pub mod u32;

View File

@ -0,0 +1,3 @@
function main(a: u32, b: u32) {
assert_eq!(a, b);
}

View File

@ -0,0 +1,3 @@
function main(a: u32, b: u32) -> bool {
return a == b
}

View File

@ -0,0 +1,3 @@
function main(a: u32, b: u32) -> bool {
return a >= b
}

View File

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

View File

@ -0,0 +1,3 @@
function main(a: u32, b: u32) -> bool {
return a <= b
}

View File

@ -0,0 +1,3 @@
function main(a: u32, b: u32) -> bool {
return a < b
}

View File

@ -1,6 +1,8 @@
use crate::{
compile_program, get_error, get_output, integer::IntegerTester, EdwardsConstrainedValue,
EdwardsTestCompiler,
boolean::{output_expected_boolean, output_false, output_true},
compile_program, get_error, get_output,
integer::IntegerTester,
EdwardsConstrainedValue, EdwardsTestCompiler,
};
use leo_compiler::{
errors::{CompilerError, FunctionError, IntegerError},
@ -80,6 +82,15 @@ fn test_u32() {
TestU32::test_mul();
TestU32::test_div();
TestU32::test_pow();
TestU32::test_eq();
TestU32::test_ge();
TestU32::test_gt();
TestU32::test_le();
TestU32::test_gt();
TestU32::test_assert_eq();
TestU32::test_ternary();
}
#[test]

View File

@ -0,0 +1,3 @@
function main(b: bool, x: u32, y: u32) -> u32 {
return if b ? x : y
}