add field gadget tests

This commit is contained in:
collin 2020-06-02 16:06:25 -07:00
parent 91e8febffe
commit b4c163ce4f
6 changed files with 162 additions and 42 deletions

View File

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

View File

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

View File

@ -1,3 +1,4 @@
use crate::boolean::{output_false, output_true};
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler}; use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
use leo_compiler::{ use leo_compiler::{
errors::{CompilerError, FieldError, FunctionError}, errors::{CompilerError, FieldError, FunctionError},
@ -7,7 +8,10 @@ use leo_compiler::{
use snarkos_curves::edwards_bls12::Fq; use snarkos_curves::edwards_bls12::Fq;
use snarkos_gadgets::curves::edwards_bls12::FqGadget; use snarkos_gadgets::curves::edwards_bls12::FqGadget;
use snarkos_models::curves::{Field, PrimeField}; use snarkos_models::curves::{Field, PrimeField};
use snarkos_models::gadgets::{curves::field::FieldGadget, r1cs::TestConstraintSystem}; use snarkos_models::gadgets::{
curves::field::FieldGadget,
r1cs::{ConstraintSystem, TestConstraintSystem},
};
use snarkos_utilities::biginteger::BigInteger256; use snarkos_utilities::biginteger::BigInteger256;
const DIRECTORY_NAME: &str = "tests/field/"; const DIRECTORY_NAME: &str = "tests/field/";
@ -141,10 +145,10 @@ fn test_sub() {
let f1: Fq = Fq::from_repr(b1); let f1: Fq = Fq::from_repr(b1);
let f2: Fq = Fq::from_repr(b2); let f2: Fq = Fq::from_repr(b2);
let sum = f1.sub(&f2); let difference = f1.sub(&f2);
let cs = TestConstraintSystem::<Fq>::new(); let cs = TestConstraintSystem::<Fq>::new();
let sum_allocated = FqGadget::from(cs, &sum); let difference_allocated = FqGadget::from(cs, &difference);
let mut program = compile_program(DIRECTORY_NAME, "sub.leo").unwrap(); let mut program = compile_program(DIRECTORY_NAME, "sub.leo").unwrap();
program.set_inputs(vec![ program.set_inputs(vec![
@ -152,7 +156,7 @@ fn test_sub() {
Some(InputValue::Field(r2.to_string())), Some(InputValue::Field(r2.to_string())),
]); ]);
output_expected_allocated(program, sum_allocated); output_expected_allocated(program, difference_allocated);
} }
} }
@ -170,10 +174,10 @@ fn test_mul() {
let f1: Fq = Fq::from_repr(b1); let f1: Fq = Fq::from_repr(b1);
let f2: Fq = Fq::from_repr(b2); let f2: Fq = Fq::from_repr(b2);
let sum = f1.mul(&f2); let product = f1.mul(&f2);
let cs = TestConstraintSystem::<Fq>::new(); let cs = TestConstraintSystem::<Fq>::new();
let sum_allocated = FqGadget::from(cs, &sum); let product_allocated = FqGadget::from(cs, &product);
let mut program = compile_program(DIRECTORY_NAME, "mul.leo").unwrap(); let mut program = compile_program(DIRECTORY_NAME, "mul.leo").unwrap();
program.set_inputs(vec![ program.set_inputs(vec![
@ -181,7 +185,7 @@ fn test_mul() {
Some(InputValue::Field(r2.to_string())), Some(InputValue::Field(r2.to_string())),
]); ]);
output_expected_allocated(program, sum_allocated); output_expected_allocated(program, product_allocated);
} }
} }
@ -199,10 +203,10 @@ fn test_div() {
let f1: Fq = Fq::from_repr(b1); let f1: Fq = Fq::from_repr(b1);
let f2: Fq = Fq::from_repr(b2); let f2: Fq = Fq::from_repr(b2);
let sum = f1.div(&f2); let quotient = f1.div(&f2);
let cs = TestConstraintSystem::<Fq>::new(); let cs = TestConstraintSystem::<Fq>::new();
let sum_allocated = FqGadget::from(cs, &sum); let quotient_allocated = FqGadget::from(cs, &quotient);
let mut program = compile_program(DIRECTORY_NAME, "div.leo").unwrap(); let mut program = compile_program(DIRECTORY_NAME, "div.leo").unwrap();
program.set_inputs(vec![ program.set_inputs(vec![
@ -210,6 +214,115 @@ fn test_div() {
Some(InputValue::Field(r2.to_string())), Some(InputValue::Field(r2.to_string())),
]); ]);
output_expected_allocated(program, sum_allocated); output_expected_allocated(program, quotient_allocated);
} }
} }
#[test]
fn test_eq_true() {
for _ in 0..10 {
let r1: u64 = rand::random();
let mut program = compile_program(DIRECTORY_NAME, "eq.leo").unwrap();
program.set_inputs(vec![
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r1.to_string())),
]);
output_true(program)
}
}
#[test]
fn test_eq_false() {
for _ in 0..10 {
let r1: u64 = rand::random();
let r2: u64 = rand::random();
if r1 == r2 {
continue;
}
let mut program = compile_program(DIRECTORY_NAME, "eq.leo").unwrap();
program.set_inputs(vec![
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r2.to_string())),
]);
output_false(program)
}
}
#[test]
fn test_assert_eq_pass() {
for _ in 0..10 {
let r1: u64 = rand::random();
let mut program = compile_program(DIRECTORY_NAME, "assert_eq.leo").unwrap();
program.set_inputs(vec![
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r1.to_string())),
]);
let _ = get_output(program);
}
}
#[test]
fn test_assert_eq_fail() {
for _ in 0..10 {
let r1: u64 = rand::random();
let r2: u64 = rand::random();
if r1 == r2 {
continue;
}
let mut program = compile_program(DIRECTORY_NAME, "assert_eq.leo").unwrap();
program.set_inputs(vec![
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r2.to_string())),
]);
let mut cs = TestConstraintSystem::<Fq>::new();
let _ = program.compile_constraints(&mut cs).unwrap();
assert!(!cs.is_satisfied());
}
}
#[test]
fn test_ternary() {
let r1: u64 = rand::random();
let r2: u64 = rand::random();
let b1 = BigInteger256::from(r1);
let b2 = BigInteger256::from(r2);
let f1: Fq = Fq::from_repr(b1);
let f2: Fq = Fq::from_repr(b2);
let mut cs = TestConstraintSystem::<Fq>::new();
let g1 = FqGadget::from(cs.ns(|| "g1"), &f1);
let g2 = FqGadget::from(cs.ns(|| "g2"), &f2);
let mut program_1 = compile_program(DIRECTORY_NAME, "ternary.leo").unwrap();
let mut program_2 = program_1.clone();
// true -> field 1
program_1.set_inputs(vec![
Some(InputValue::Boolean(true)),
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r2.to_string())),
]);
output_expected_allocated(program_1, g1);
// false -> field 2
program_2.set_inputs(vec![
Some(InputValue::Boolean(false)),
Some(InputValue::Field(r1.to_string())),
Some(InputValue::Field(r2.to_string())),
]);
output_expected_allocated(program_2, g2);
}

View File

@ -0,0 +1,3 @@
function main(b: bool, f1: field, f2: field) -> field {
return if b ? f1 : f2
}

View File

@ -1,12 +1,8 @@
use crate::{ use crate::{
boolean::{output_false, output_true}, boolean::{output_false, output_true},
compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler, compile_program, fail_enforce, get_output, EdwardsConstrainedValue, EdwardsTestCompiler,
};
use leo_compiler::{
errors::{CompilerError, FunctionError, StatementError},
group::edwards_bls12::EdwardsGroupType,
ConstrainedValue, InputValue,
}; };
use leo_compiler::{group::edwards_bls12::EdwardsGroupType, ConstrainedValue, InputValue};
use snarkos_curves::edwards_bls12::{EdwardsAffine, Fq}; use snarkos_curves::edwards_bls12::{EdwardsAffine, Fq};
use snarkos_gadgets::curves::edwards_bls12::EdwardsBlsGadget; use snarkos_gadgets::curves::edwards_bls12::EdwardsBlsGadget;
@ -50,15 +46,6 @@ fn output_zero(program: EdwardsTestCompiler) {
output_expected_constant(program, EdwardsAffine::zero()) output_expected_constant(program, EdwardsAffine::zero())
} }
fn fail_enforce(program: EdwardsTestCompiler) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::SynthesisError(_),
)) => {}
error => panic!("Expected evaluate error, got {}", error),
}
}
#[test] #[test]
fn test_zero() { fn test_zero() {
let program = compile_program(DIRECTORY_NAME, "zero.leo").unwrap(); let program = compile_program(DIRECTORY_NAME, "zero.leo").unwrap();
@ -72,6 +59,20 @@ fn test_point() {
output_expected_constant(program, point); output_expected_constant(program, point);
} }
#[test]
fn test_input() {
let mut program = compile_program(DIRECTORY_NAME, "input.leo").unwrap();
program.set_inputs(vec![Some(InputValue::Group(TEST_POINT_1.into()))]);
let mut cs = TestConstraintSystem::<Fq>::new();
let constant_point = EdwardsAffine::from_str(TEST_POINT_1).unwrap();
let allocated_point =
<EdwardsBlsGadget as AllocGadget<EdwardsAffine, Fq>>::alloc(&mut cs, || Ok(constant_point))
.unwrap();
output_expected_allocated(program, allocated_point);
}
#[test] #[test]
fn test_add() { fn test_add() {
use std::ops::Add; use std::ops::Add;
@ -111,31 +112,17 @@ fn test_eq_false() {
} }
#[test] #[test]
fn test_assert_eq_true() { fn test_assert_eq_pass() {
let program = compile_program(DIRECTORY_NAME, "assert_eq_true.leo").unwrap(); let program = compile_program(DIRECTORY_NAME, "assert_eq_true.leo").unwrap();
let _res = get_output(program); let _res = get_output(program);
} }
#[test] #[test]
fn test_assert_eq_false() { fn test_assert_eq_fail() {
let program = compile_program(DIRECTORY_NAME, "assert_eq_false.leo").unwrap(); let program = compile_program(DIRECTORY_NAME, "assert_eq_false.leo").unwrap();
fail_enforce(program); fail_enforce(program);
} }
#[test]
fn test_input() {
let mut program = compile_program(DIRECTORY_NAME, "input.leo").unwrap();
program.set_inputs(vec![Some(InputValue::Group(TEST_POINT_1.into()))]);
let mut cs = TestConstraintSystem::<Fq>::new();
let constant_point = EdwardsAffine::from_str(TEST_POINT_1).unwrap();
let allocated_point =
<EdwardsBlsGadget as AllocGadget<EdwardsAffine, Fq>>::alloc(&mut cs, || Ok(constant_point))
.unwrap();
output_expected_allocated(program, allocated_point);
}
#[test] #[test]
fn test_ternary() { fn test_ternary() {
let mut program_1 = compile_program(DIRECTORY_NAME, "ternary.leo").unwrap(); let mut program_1 = compile_program(DIRECTORY_NAME, "ternary.leo").unwrap();

View File

@ -10,7 +10,9 @@ pub mod mutability;
pub mod statement; pub mod statement;
use leo_compiler::{ use leo_compiler::{
compiler::Compiler, errors::CompilerError, group::edwards_bls12::EdwardsGroupType, compiler::Compiler,
errors::{CompilerError, FunctionError, StatementError},
group::edwards_bls12::EdwardsGroupType,
ConstrainedValue, ConstrainedValue,
}; };
@ -33,6 +35,15 @@ pub(crate) fn get_error(program: EdwardsTestCompiler) -> CompilerError {
program.compile_constraints(&mut cs).unwrap_err() program.compile_constraints(&mut cs).unwrap_err()
} }
pub(crate) fn fail_enforce(program: EdwardsTestCompiler) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::SynthesisError(_),
)) => {}
error => panic!("Expected evaluate error, got {}", error),
}
}
pub(crate) fn compile_program( pub(crate) fn compile_program(
directory_name: &str, directory_name: &str,
file_name: &str, file_name: &str,