mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-11 01:45:48 +03:00
add manual main input method for testing. fix field tests
This commit is contained in:
parent
61f7c54858
commit
a4448cdd12
30
Cargo.lock
generated
30
Cargo.lock
generated
@ -597,7 +597,6 @@ dependencies = [
|
|||||||
"snarkos-models",
|
"snarkos-models",
|
||||||
"snarkos-objects",
|
"snarkos-objects",
|
||||||
"snarkos-utilities",
|
"snarkos-utilities",
|
||||||
"tempfile",
|
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -953,12 +952,6 @@ dependencies = [
|
|||||||
"num_cpus",
|
"num_cpus",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "redox_syscall"
|
|
||||||
version = "0.1.57"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.3.9"
|
version = "1.3.9"
|
||||||
@ -977,15 +970,6 @@ version = "0.6.18"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
|
checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "remove_dir_all"
|
|
||||||
version = "0.5.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
|
|
||||||
dependencies = [
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.16"
|
version = "0.1.16"
|
||||||
@ -1296,20 +1280,6 @@ dependencies = [
|
|||||||
"unicode-xid 0.2.0",
|
"unicode-xid 0.2.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tempfile"
|
|
||||||
version = "3.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"libc",
|
|
||||||
"rand",
|
|
||||||
"redox_syscall",
|
|
||||||
"remove_dir_all",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -30,5 +30,4 @@ sha2 = { version = "0.9" }
|
|||||||
thiserror = { version = "1.0" }
|
thiserror = { version = "1.0" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
num-bigint = { version = "0.3" }
|
num-bigint = { version = "0.3" }
|
||||||
tempfile = { version = "3.1.0" }
|
|
@ -10,7 +10,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use leo_ast::LeoParser;
|
use leo_ast::LeoParser;
|
||||||
use leo_inputs::LeoInputsParser;
|
use leo_inputs::LeoInputsParser;
|
||||||
use leo_types::{Inputs, Program};
|
use leo_types::{Inputs, MainInputs, Program};
|
||||||
|
|
||||||
use snarkos_errors::gadgets::SynthesisError;
|
use snarkos_errors::gadgets::SynthesisError;
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
@ -114,6 +114,11 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
|||||||
Ok(LeoParser::load_file(&self.main_file_path)?)
|
Ok(LeoParser::load_file(&self.main_file_path)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Manually sets main function inputs
|
||||||
|
pub fn set_main_inputs(&mut self, inputs: MainInputs) {
|
||||||
|
self.program_inputs.set_main_inputs(inputs);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn checksum(&self) -> Result<String, CompilerError> {
|
pub fn checksum(&self) -> Result<String, CompilerError> {
|
||||||
// Read in the main file as string
|
// Read in the main file as string
|
||||||
let unparsed_file = fs::read_to_string(&self.main_file_path)
|
let unparsed_file = fs::read_to_string(&self.main_file_path)
|
||||||
|
@ -1,21 +1,13 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
assert_satisfied,
|
assert_satisfied,
|
||||||
fail_enforce,
|
|
||||||
get_compiler_error,
|
get_compiler_error,
|
||||||
get_outputs,
|
get_outputs,
|
||||||
get_synthesis_error,
|
get_synthesis_error,
|
||||||
parse_program,
|
parse_program,
|
||||||
parse_program_with_inputs,
|
parse_program_with_inputs,
|
||||||
EdwardsConstrainedValue,
|
|
||||||
EdwardsTestCompiler,
|
EdwardsTestCompiler,
|
||||||
};
|
};
|
||||||
use leo_compiler::{
|
use leo_compiler::errors::{BooleanError, CompilerError, ExpressionError, FunctionError, StatementError};
|
||||||
errors::{BooleanError, CompilerError, ExpressionError, FunctionError, StatementError},
|
|
||||||
ConstrainedValue,
|
|
||||||
};
|
|
||||||
use leo_types::InputValue;
|
|
||||||
|
|
||||||
use snarkos_models::gadgets::utilities::boolean::Boolean;
|
|
||||||
|
|
||||||
pub fn output_true(program: EdwardsTestCompiler) {
|
pub fn output_true(program: EdwardsTestCompiler) {
|
||||||
let expected = include_bytes!("outputs/register_true.out");
|
let expected = include_bytes!("outputs/register_true.out");
|
||||||
@ -31,13 +23,6 @@ pub fn output_false(program: EdwardsTestCompiler) {
|
|||||||
assert_eq!(expected, actual.bytes().as_slice());
|
assert_eq!(expected, actual.bytes().as_slice());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fail_boolean(program: EdwardsTestCompiler) {
|
|
||||||
match get_compiler_error(program) {
|
|
||||||
CompilerError::FunctionError(FunctionError::BooleanError(BooleanError::Error(_))) => {}
|
|
||||||
error => panic!("Expected boolean error, got {}", error),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fail_boolean_statement(program: EdwardsTestCompiler) {
|
fn fail_boolean_statement(program: EdwardsTestCompiler) {
|
||||||
match get_compiler_error(program) {
|
match get_compiler_error(program) {
|
||||||
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
|
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
|
||||||
@ -60,7 +45,7 @@ fn test_input_pass() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_input_fail() {
|
fn test_input_fail() {
|
||||||
let program_bytes = include_bytes!("assert_eq_input.leo");
|
let program_bytes = include_bytes!("assert_eq_input.leo");
|
||||||
let input_bytes = include_bytes!("inputs/false_false.in");
|
let input_bytes = include_bytes!("inputs/true_false.in");
|
||||||
|
|
||||||
let program = parse_program_with_inputs(program_bytes, input_bytes).unwrap();
|
let program = parse_program_with_inputs(program_bytes, input_bytes).unwrap();
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
function main(a: field, b: field) -> field {
|
function main(a: field, b: field, c: field) {
|
||||||
return a + b
|
assert_eq!(a + b, c);
|
||||||
}
|
}
|
@ -1,3 +1,3 @@
|
|||||||
function main(a: field, b: field) -> field {
|
function main(a: field, b: field, c: field) {
|
||||||
return a / b
|
assert_eq!(a / b, c);
|
||||||
}
|
}
|
@ -1,3 +1,3 @@
|
|||||||
function main(a: field, b: field) -> bool {
|
function main(a: field, b: field, c: bool) {
|
||||||
return a == b
|
assert_eq!(a == b, c);
|
||||||
}
|
}
|
@ -1,3 +0,0 @@
|
|||||||
function main(f: field) -> field{
|
|
||||||
return f
|
|
||||||
}
|
|
2
compiler/tests/field/inputs/register_one.in
Normal file
2
compiler/tests/field/inputs/register_one.in
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[registers]
|
||||||
|
r: field = 1;
|
2
compiler/tests/field/inputs/register_zero.in
Normal file
2
compiler/tests/field/inputs/register_zero.in
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[registers]
|
||||||
|
r: field = 0;
|
@ -1,112 +1,26 @@
|
|||||||
use crate::{
|
use crate::{assert_satisfied, generate_main_inputs, get_synthesis_error, parse_program};
|
||||||
boolean::{output_expected_boolean, output_true},
|
|
||||||
get_error,
|
|
||||||
get_output,
|
|
||||||
parse_program,
|
|
||||||
EdwardsConstrainedValue,
|
|
||||||
EdwardsTestCompiler,
|
|
||||||
};
|
|
||||||
use leo_compiler::{
|
|
||||||
errors::{CompilerError, FieldError, FunctionError},
|
|
||||||
ConstrainedValue,
|
|
||||||
FieldType,
|
|
||||||
};
|
|
||||||
use leo_types::InputValue;
|
use leo_types::InputValue;
|
||||||
|
|
||||||
|
use snarkos_curves::edwards_bls12::Fq;
|
||||||
|
use snarkos_utilities::bytes::ToBytes;
|
||||||
|
|
||||||
use num_bigint::BigUint;
|
use num_bigint::BigUint;
|
||||||
use rand::{Rng, SeedableRng};
|
use rand::{Rng, SeedableRng};
|
||||||
use rand_xorshift::XorShiftRng;
|
use rand_xorshift::XorShiftRng;
|
||||||
use snarkos_curves::edwards_bls12::Fq;
|
|
||||||
use snarkos_gadgets::curves::edwards_bls12::FqGadget;
|
|
||||||
use snarkos_models::{
|
|
||||||
curves::{One, PrimeField, Zero},
|
|
||||||
gadgets::{
|
|
||||||
curves::field::FieldGadget,
|
|
||||||
r1cs::{ConstraintSystem, TestConstraintSystem},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
use snarkos_utilities::{biginteger::BigInteger256, bytes::ToBytes};
|
|
||||||
|
|
||||||
fn output_expected_constant(program: EdwardsTestCompiler, expected: Fq) {
|
// Helper function to convert field element into decimal base 10 string
|
||||||
let output = get_output(program);
|
fn field_to_decimal_string(f: Fq) -> String {
|
||||||
assert_eq!(
|
// write field to buffer
|
||||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Field(FieldType::Constant(expected))]).to_string(),
|
|
||||||
output.to_string()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn output_expected_allocated(program: EdwardsTestCompiler, expected: FqGadget) {
|
let mut buf = Vec::new();
|
||||||
let output = get_output(program);
|
|
||||||
|
|
||||||
match output {
|
f.write(&mut buf).unwrap();
|
||||||
EdwardsConstrainedValue::Return(vec) => match vec.as_slice() {
|
|
||||||
[ConstrainedValue::Field(FieldType::Allocated(fp_gadget))] => assert_eq!(*fp_gadget, expected as FqGadget),
|
|
||||||
_ => panic!("program output unknown return value"),
|
|
||||||
},
|
|
||||||
_ => panic!("program output unknown return value"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn output_zero(program: EdwardsTestCompiler) {
|
// convert to big integer
|
||||||
output_expected_constant(program, Fq::zero())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn output_one(program: EdwardsTestCompiler) {
|
let f_bigint = BigUint::from_bytes_le(&buf);
|
||||||
output_expected_constant(program, Fq::one())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fail_field(program: EdwardsTestCompiler) {
|
f_bigint.to_str_radix(10)
|
||||||
match get_error(program) {
|
|
||||||
CompilerError::FunctionError(FunctionError::FieldError(FieldError::Error(_string))) => {}
|
|
||||||
error => panic!("Expected invalid field error, got {}", error),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_zero() {
|
|
||||||
let bytes = include_bytes!("zero.leo");
|
|
||||||
let program = parse_program(bytes).unwrap();
|
|
||||||
|
|
||||||
output_zero(program);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_one() {
|
|
||||||
let bytes = include_bytes!("one.leo");
|
|
||||||
let program = parse_program(bytes).unwrap();
|
|
||||||
|
|
||||||
output_one(program);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_input_pass() {
|
|
||||||
let bytes = include_bytes!("input.leo");
|
|
||||||
let mut program = parse_program(bytes).unwrap();
|
|
||||||
|
|
||||||
program.set_main_inputs(vec![Some(InputValue::Field("1".into()))]);
|
|
||||||
|
|
||||||
let cs = TestConstraintSystem::<Fq>::new();
|
|
||||||
let expected = FqGadget::one(cs).unwrap();
|
|
||||||
|
|
||||||
output_expected_allocated(program, expected)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_input_fail_bool() {
|
|
||||||
let bytes = include_bytes!("input.leo");
|
|
||||||
let mut program = parse_program(bytes).unwrap();
|
|
||||||
|
|
||||||
program.set_main_inputs(vec![Some(InputValue::Boolean(true))]);
|
|
||||||
fail_field(program);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_input_fail_none() {
|
|
||||||
let bytes = include_bytes!("input.leo");
|
|
||||||
let mut program = parse_program(bytes).unwrap();
|
|
||||||
|
|
||||||
program.set_main_inputs(vec![None]);
|
|
||||||
fail_field(program);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -116,32 +30,25 @@ fn test_add() {
|
|||||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||||
|
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
let r1: Fq = rng.gen();
|
let a: Fq = rng.gen();
|
||||||
let r2: Fq = rng.gen();
|
let b: Fq = rng.gen();
|
||||||
|
let c = a.add(&b);
|
||||||
|
|
||||||
let mut r1_buf = Vec::new();
|
let a_string = field_to_decimal_string(a);
|
||||||
let mut r2_buf = Vec::new();
|
let b_string = field_to_decimal_string(b);
|
||||||
|
let c_string = field_to_decimal_string(c);
|
||||||
r1.write(&mut r1_buf).unwrap();
|
|
||||||
r2.write(&mut r2_buf).unwrap();
|
|
||||||
|
|
||||||
let r1_bigint = BigUint::from_bytes_le(&r1_buf);
|
|
||||||
let r2_bigint = BigUint::from_bytes_le(&r2_buf);
|
|
||||||
|
|
||||||
let sum = r1.add(&r2);
|
|
||||||
|
|
||||||
let cs = TestConstraintSystem::<Fq>::new();
|
|
||||||
let sum_allocated = FqGadget::from(cs, &sum);
|
|
||||||
|
|
||||||
let bytes = include_bytes!("add.leo");
|
let bytes = include_bytes!("add.leo");
|
||||||
let mut program = parse_program(bytes).unwrap();
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
program.set_main_inputs(vec![
|
let main_inputs = generate_main_inputs(vec![
|
||||||
Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
("a", Some(InputValue::Field(a_string))),
|
||||||
Some(InputValue::Field(r2_bigint.to_str_radix(10))),
|
("b", Some(InputValue::Field(b_string))),
|
||||||
|
("c", Some(InputValue::Field(c_string))),
|
||||||
]);
|
]);
|
||||||
|
program.set_main_inputs(main_inputs);
|
||||||
|
|
||||||
output_expected_allocated(program, sum_allocated);
|
assert_satisfied(program)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,68 +59,25 @@ fn test_sub() {
|
|||||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||||
|
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
let r1: Fq = rng.gen();
|
let a: Fq = rng.gen();
|
||||||
let r2: Fq = rng.gen();
|
let b: Fq = rng.gen();
|
||||||
|
let c = a.sub(&b);
|
||||||
|
|
||||||
let mut r1_buf = Vec::new();
|
let a_string = field_to_decimal_string(a);
|
||||||
let mut r2_buf = Vec::new();
|
let b_string = field_to_decimal_string(b);
|
||||||
|
let c_string = field_to_decimal_string(c);
|
||||||
r1.write(&mut r1_buf).unwrap();
|
|
||||||
r2.write(&mut r2_buf).unwrap();
|
|
||||||
|
|
||||||
let r1_bigint = BigUint::from_bytes_le(&r1_buf);
|
|
||||||
let r2_bigint = BigUint::from_bytes_le(&r2_buf);
|
|
||||||
|
|
||||||
let difference = r1.sub(&r2);
|
|
||||||
|
|
||||||
let cs = TestConstraintSystem::<Fq>::new();
|
|
||||||
let difference_allocated = FqGadget::from(cs, &difference);
|
|
||||||
|
|
||||||
let bytes = include_bytes!("sub.leo");
|
let bytes = include_bytes!("sub.leo");
|
||||||
let mut program = parse_program(bytes).unwrap();
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
program.set_main_inputs(vec![
|
let main_inputs = generate_main_inputs(vec![
|
||||||
Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
("a", Some(InputValue::Field(a_string))),
|
||||||
Some(InputValue::Field(r2_bigint.to_str_radix(10))),
|
("b", Some(InputValue::Field(b_string))),
|
||||||
|
("c", Some(InputValue::Field(c_string))),
|
||||||
]);
|
]);
|
||||||
|
program.set_main_inputs(main_inputs);
|
||||||
|
|
||||||
output_expected_allocated(program, difference_allocated);
|
assert_satisfied(program)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_mul() {
|
|
||||||
use std::ops::Mul;
|
|
||||||
|
|
||||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|
||||||
|
|
||||||
for _ in 0..10 {
|
|
||||||
let r1: Fq = rng.gen();
|
|
||||||
let r2: Fq = rng.gen();
|
|
||||||
|
|
||||||
let mut r1_buf = Vec::new();
|
|
||||||
let mut r2_buf = Vec::new();
|
|
||||||
|
|
||||||
r1.write(&mut r1_buf).unwrap();
|
|
||||||
r2.write(&mut r2_buf).unwrap();
|
|
||||||
|
|
||||||
let r1_bigint = BigUint::from_bytes_le(&r1_buf);
|
|
||||||
let r2_bigint = BigUint::from_bytes_le(&r2_buf);
|
|
||||||
|
|
||||||
let product = r1.mul(&r2);
|
|
||||||
|
|
||||||
let cs = TestConstraintSystem::<Fq>::new();
|
|
||||||
let product_allocated = FqGadget::from(cs, &product);
|
|
||||||
|
|
||||||
let bytes = include_bytes!("mul.leo");
|
|
||||||
let mut program = parse_program(bytes).unwrap();
|
|
||||||
|
|
||||||
program.set_main_inputs(vec![
|
|
||||||
Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
|
||||||
Some(InputValue::Field(r2_bigint.to_str_radix(10))),
|
|
||||||
]);
|
|
||||||
|
|
||||||
output_expected_allocated(program, product_allocated);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,32 +88,55 @@ fn test_div() {
|
|||||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||||
|
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
let r1: Fq = rng.gen();
|
let a: Fq = rng.gen();
|
||||||
let r2: Fq = rng.gen();
|
let b: Fq = rng.gen();
|
||||||
|
let c = a.div(&b);
|
||||||
|
|
||||||
let mut r1_buf = Vec::new();
|
let a_string = field_to_decimal_string(a);
|
||||||
let mut r2_buf = Vec::new();
|
let b_string = field_to_decimal_string(b);
|
||||||
|
let c_string = field_to_decimal_string(c);
|
||||||
r1.write(&mut r1_buf).unwrap();
|
|
||||||
r2.write(&mut r2_buf).unwrap();
|
|
||||||
|
|
||||||
let r1_bigint = BigUint::from_bytes_le(&r1_buf);
|
|
||||||
let r2_bigint = BigUint::from_bytes_le(&r2_buf);
|
|
||||||
|
|
||||||
let quotient = r1.div(&r2);
|
|
||||||
|
|
||||||
let cs = TestConstraintSystem::<Fq>::new();
|
|
||||||
let quotient_allocated = FqGadget::from(cs, "ient);
|
|
||||||
|
|
||||||
let bytes = include_bytes!("div.leo");
|
let bytes = include_bytes!("div.leo");
|
||||||
let mut program = parse_program(bytes).unwrap();
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
program.set_main_inputs(vec![
|
let main_inputs = generate_main_inputs(vec![
|
||||||
Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
("a", Some(InputValue::Field(a_string))),
|
||||||
Some(InputValue::Field(r2_bigint.to_str_radix(10))),
|
("b", Some(InputValue::Field(b_string))),
|
||||||
|
("c", Some(InputValue::Field(c_string))),
|
||||||
|
]);
|
||||||
|
program.set_main_inputs(main_inputs);
|
||||||
|
|
||||||
|
assert_satisfied(program)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mul() {
|
||||||
|
use std::ops::Mul;
|
||||||
|
|
||||||
|
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||||
|
|
||||||
|
for _ in 0..10 {
|
||||||
|
let a: Fq = rng.gen();
|
||||||
|
let b: Fq = rng.gen();
|
||||||
|
let c = a.mul(&b);
|
||||||
|
|
||||||
|
let a_string = field_to_decimal_string(a);
|
||||||
|
let b_string = field_to_decimal_string(b);
|
||||||
|
let c_string = field_to_decimal_string(c);
|
||||||
|
|
||||||
|
let bytes = include_bytes!("mul.leo");
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
let main_inputs = generate_main_inputs(vec![
|
||||||
|
("a", Some(InputValue::Field(a_string))),
|
||||||
|
("b", Some(InputValue::Field(b_string))),
|
||||||
|
("c", Some(InputValue::Field(c_string))),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
output_expected_allocated(program, quotient_allocated);
|
program.set_main_inputs(main_inputs);
|
||||||
|
|
||||||
|
assert_satisfied(program)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,42 +145,42 @@ fn test_eq() {
|
|||||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||||
|
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
let r1: Fq = rng.gen();
|
let a: Fq = rng.gen();
|
||||||
let r2: Fq = rng.gen();
|
let b: Fq = rng.gen();
|
||||||
|
|
||||||
let mut r1_buf = Vec::new();
|
let a_string = field_to_decimal_string(a);
|
||||||
let mut r2_buf = Vec::new();
|
let b_string = field_to_decimal_string(b);
|
||||||
|
|
||||||
r1.write(&mut r1_buf).unwrap();
|
|
||||||
r2.write(&mut r2_buf).unwrap();
|
|
||||||
|
|
||||||
let r1_bigint = BigUint::from_bytes_le(&r1_buf);
|
|
||||||
let r2_bigint = BigUint::from_bytes_le(&r2_buf);
|
|
||||||
|
|
||||||
// test equal
|
// test equal
|
||||||
|
|
||||||
let bytes = include_bytes!("eq.leo");
|
let bytes = include_bytes!("eq.leo");
|
||||||
let mut program = parse_program(bytes).unwrap();
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
program.set_main_inputs(vec![
|
let main_inputs = generate_main_inputs(vec![
|
||||||
Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
("a", Some(InputValue::Field(a_string.clone()))),
|
||||||
Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
("b", Some(InputValue::Field(a_string.clone()))),
|
||||||
|
("c", Some(InputValue::Boolean(true))),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
output_true(program);
|
program.set_main_inputs(main_inputs);
|
||||||
|
|
||||||
|
assert_satisfied(program);
|
||||||
|
|
||||||
// test not equal
|
// test not equal
|
||||||
|
|
||||||
let result = r1.eq(&r2);
|
let c = a.eq(&b);
|
||||||
|
|
||||||
let mut program = parse_program(bytes).unwrap();
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
program.set_main_inputs(vec![
|
let main_inputs = generate_main_inputs(vec![
|
||||||
Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
("a", Some(InputValue::Field(a_string))),
|
||||||
Some(InputValue::Field(r2_bigint.to_str_radix(10))),
|
("b", Some(InputValue::Field(b_string))),
|
||||||
|
("c", Some(InputValue::Boolean(c))),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
output_expected_boolean(program, result)
|
program.set_main_inputs(main_inputs);
|
||||||
|
|
||||||
|
assert_satisfied(program);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,20 +189,21 @@ fn test_assert_eq_pass() {
|
|||||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||||
|
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
let r1: Fq = rng.gen();
|
let a: Fq = rng.gen();
|
||||||
let mut r1_buf = Vec::new();
|
|
||||||
r1.write(&mut r1_buf).unwrap();
|
let a_string = field_to_decimal_string(a);
|
||||||
let r1_bigint = BigUint::from_bytes_le(&r1_buf);
|
|
||||||
|
|
||||||
let bytes = include_bytes!("assert_eq.leo");
|
let bytes = include_bytes!("assert_eq.leo");
|
||||||
let mut program = parse_program(bytes).unwrap();
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
program.set_main_inputs(vec![
|
let main_inputs = generate_main_inputs(vec![
|
||||||
Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
("a", Some(InputValue::Field(a_string.clone()))),
|
||||||
Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
("b", Some(InputValue::Field(a_string))),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let _ = get_output(program);
|
program.set_main_inputs(main_inputs);
|
||||||
|
|
||||||
|
assert_satisfied(program);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,68 +212,98 @@ fn test_assert_eq_fail() {
|
|||||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||||
|
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
let r1: Fq = rng.gen();
|
let a: Fq = rng.gen();
|
||||||
let r2: Fq = rng.gen();
|
let b: Fq = rng.gen();
|
||||||
|
|
||||||
let mut r1_buf = Vec::new();
|
if a == b {
|
||||||
let mut r2_buf = Vec::new();
|
|
||||||
r1.write(&mut r1_buf).unwrap();
|
|
||||||
r2.write(&mut r2_buf).unwrap();
|
|
||||||
let r1_bigint = BigUint::from_bytes_le(&r1_buf);
|
|
||||||
let r2_bigint = BigUint::from_bytes_le(&r2_buf);
|
|
||||||
|
|
||||||
if r1 == r2 {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let a_string = field_to_decimal_string(a);
|
||||||
|
let b_string = field_to_decimal_string(b);
|
||||||
|
|
||||||
let bytes = include_bytes!("assert_eq.leo");
|
let bytes = include_bytes!("assert_eq.leo");
|
||||||
let mut program = parse_program(bytes).unwrap();
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
program.set_main_inputs(vec![
|
let main_inputs = generate_main_inputs(vec![
|
||||||
Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
("a", Some(InputValue::Field(a_string))),
|
||||||
Some(InputValue::Field(r2_bigint.to_str_radix(10))),
|
("b", Some(InputValue::Field(b_string))),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let mut cs = TestConstraintSystem::<Fq>::new();
|
program.set_main_inputs(main_inputs);
|
||||||
let _ = program.compile_constraints(&mut cs).unwrap();
|
|
||||||
assert!(!cs.is_satisfied());
|
get_synthesis_error(program);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ternary() {
|
fn test_ternary() {
|
||||||
let r1: u64 = rand::random();
|
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||||
let r2: u64 = rand::random();
|
|
||||||
|
|
||||||
let b1 = BigInteger256::from(r1);
|
let a: Fq = rng.gen();
|
||||||
let b2 = BigInteger256::from(r2);
|
let b: Fq = rng.gen();
|
||||||
|
|
||||||
let f1: Fq = Fq::from_repr(b1);
|
let a_string = field_to_decimal_string(a);
|
||||||
let f2: Fq = Fq::from_repr(b2);
|
let b_string = field_to_decimal_string(b);
|
||||||
|
|
||||||
let mut cs = TestConstraintSystem::<Fq>::new();
|
|
||||||
let g1 = FqGadget::from(cs.ns(|| "g1"), &f1);
|
|
||||||
let g2 = FqGadget::from(cs.ns(|| "g2"), &f2);
|
|
||||||
|
|
||||||
let bytes = include_bytes!("ternary.leo");
|
let bytes = include_bytes!("ternary.leo");
|
||||||
let mut program_1 = parse_program(bytes).unwrap();
|
let mut program = parse_program(bytes).unwrap();
|
||||||
let mut program_2 = program_1.clone();
|
|
||||||
|
|
||||||
// true -> field 1
|
// true -> field a
|
||||||
program_1.set_main_inputs(vec![
|
let main_inputs = generate_main_inputs(vec![
|
||||||
Some(InputValue::Boolean(true)),
|
("s", Some(InputValue::Boolean(true))),
|
||||||
Some(InputValue::Field(r1.to_string())),
|
("a", Some(InputValue::Field(a_string.clone()))),
|
||||||
Some(InputValue::Field(r2.to_string())),
|
("b", Some(InputValue::Field(b_string.clone()))),
|
||||||
|
("c", Some(InputValue::Field(a_string.clone()))),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
output_expected_allocated(program_1, g1);
|
program.set_main_inputs(main_inputs);
|
||||||
|
|
||||||
// false -> field 2
|
assert_satisfied(program);
|
||||||
program_2.set_main_inputs(vec![
|
|
||||||
Some(InputValue::Boolean(false)),
|
let mut program = parse_program(bytes).unwrap();
|
||||||
Some(InputValue::Field(r1.to_string())),
|
|
||||||
Some(InputValue::Field(r2.to_string())),
|
// false -> field b
|
||||||
|
let main_inputs = generate_main_inputs(vec![
|
||||||
|
("s", Some(InputValue::Boolean(false))),
|
||||||
|
("a", Some(InputValue::Field(a_string))),
|
||||||
|
("b", Some(InputValue::Field(b_string.clone()))),
|
||||||
|
("c", Some(InputValue::Field(b_string))),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
output_expected_allocated(program_2, g2);
|
program.set_main_inputs(main_inputs);
|
||||||
|
|
||||||
|
assert_satisfied(program);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// pub fn output_one(program: EdwardsTestCompiler) {
|
||||||
|
// let expected = include_bytes!("outputs/register_one.out");
|
||||||
|
// let actual = get_outputs(program);
|
||||||
|
//
|
||||||
|
// assert_eq!(expected, actual.bytes().as_slice());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// pub fn output_zero(program: EdwardsTestCompiler) {
|
||||||
|
// let expected = include_bytes!("outputs/register_zero.out");
|
||||||
|
// let actual = get_outputs(program);
|
||||||
|
//
|
||||||
|
// assert_eq!(expected, actual.bytes().as_slice());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// #[test]
|
||||||
|
// fn test_registers() {
|
||||||
|
// let program_bytes = include_bytes!("output_register.leo");
|
||||||
|
// let one_input_bytes = include_bytes!("inputs/register_one.in");
|
||||||
|
// let zero_input_bytes = include_bytes!("inputs/register_zero.in");
|
||||||
|
//
|
||||||
|
// // test 1field input register => 1field output register
|
||||||
|
// let program = parse_program_with_inputs(program_bytes, one_input_bytes).unwrap();
|
||||||
|
//
|
||||||
|
// output_one(program);
|
||||||
|
//
|
||||||
|
// // test 0field input register => 0field output register
|
||||||
|
// let program = parse_program_with_inputs(program_bytes, zero_input_bytes).unwrap();
|
||||||
|
//
|
||||||
|
// output_zero(program);
|
||||||
|
// }
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
function main(a: field, b: field) -> field {
|
function main(a: field, b: field, c: field) {
|
||||||
return a * b
|
assert_eq!(a * b, c);
|
||||||
}
|
}
|
@ -1,3 +0,0 @@
|
|||||||
function main() -> field {
|
|
||||||
return 1field
|
|
||||||
}
|
|
3
compiler/tests/field/output_register.leo
Normal file
3
compiler/tests/field/output_register.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main(registers) -> field {
|
||||||
|
return registers.r
|
||||||
|
}
|
@ -1,3 +1,3 @@
|
|||||||
function main(a: field, b: field) -> field {
|
function main(a: field, b: field, c: field) {
|
||||||
return a - b
|
assert_eq!(a - b, c);
|
||||||
}
|
}
|
@ -1,3 +1,5 @@
|
|||||||
function main(b: bool, f1: field, f2: field) -> field {
|
function main(s: bool, a: field, b: field, c: field) {
|
||||||
return if b ? f1 : f2
|
let r = if s ? a : b;
|
||||||
|
|
||||||
|
assert_eq!(r, c);
|
||||||
}
|
}
|
@ -1,3 +0,0 @@
|
|||||||
function main() -> field {
|
|
||||||
return 0field
|
|
||||||
}
|
|
@ -2,7 +2,7 @@
|
|||||||
// pub mod array;
|
// pub mod array;
|
||||||
pub mod boolean;
|
pub mod boolean;
|
||||||
// pub mod circuits;
|
// pub mod circuits;
|
||||||
// pub mod field;
|
pub mod field;
|
||||||
// pub mod function;
|
// pub mod function;
|
||||||
// pub mod group;
|
// pub mod group;
|
||||||
// pub mod import;
|
// pub mod import;
|
||||||
@ -15,8 +15,7 @@ pub mod boolean;
|
|||||||
|
|
||||||
use leo_compiler::{
|
use leo_compiler::{
|
||||||
compiler::Compiler,
|
compiler::Compiler,
|
||||||
constraints::generate_constraints,
|
errors::CompilerError,
|
||||||
errors::{CompilerError, FunctionError, StatementError},
|
|
||||||
group::targets::edwards_bls12::EdwardsGroupType,
|
group::targets::edwards_bls12::EdwardsGroupType,
|
||||||
ConstrainedValue,
|
ConstrainedValue,
|
||||||
OutputBytes,
|
OutputBytes,
|
||||||
@ -24,13 +23,12 @@ use leo_compiler::{
|
|||||||
use leo_types::{InputValue, MainInputs};
|
use leo_types::{InputValue, MainInputs};
|
||||||
|
|
||||||
use snarkos_curves::edwards_bls12::Fq;
|
use snarkos_curves::edwards_bls12::Fq;
|
||||||
use snarkos_models::gadgets::r1cs::{ConstraintSynthesizer, TestConstraintSystem};
|
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
||||||
|
|
||||||
use std::{env::temp_dir, fs::File, io::Read, path::PathBuf};
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub const TEST_OUTPUTS_DIRECTORY: &str = "/outputs/";
|
pub const TEST_OUTPUTS_DIRECTORY: &str = "/outputs/";
|
||||||
pub const TEST_OUTPUTS_FILE_NAME: &str = "/outputs/test.out";
|
pub const TEST_OUTPUTS_FILE_NAME: &str = "/outputs/test.out";
|
||||||
|
|
||||||
const EMPTY_FILE: &str = "";
|
const EMPTY_FILE: &str = "";
|
||||||
|
|
||||||
pub type EdwardsTestCompiler = Compiler<Fq, EdwardsGroupType>;
|
pub type EdwardsTestCompiler = Compiler<Fq, EdwardsGroupType>;
|
||||||
@ -54,11 +52,9 @@ pub fn parse_program_with_inputs(
|
|||||||
fn new_compiler() -> EdwardsTestCompiler {
|
fn new_compiler() -> EdwardsTestCompiler {
|
||||||
let program_name = "test".to_string();
|
let program_name = "test".to_string();
|
||||||
let path = PathBuf::from("/test/src/main.leo");
|
let path = PathBuf::from("/test/src/main.leo");
|
||||||
// create temporary output directory
|
let outputs_dir = PathBuf::from(TEST_OUTPUTS_DIRECTORY);
|
||||||
let outputs_directory = temp_dir();
|
|
||||||
let mut compiler = EdwardsTestCompiler::new(program_name, path, outputs_directory);
|
|
||||||
|
|
||||||
compiler
|
EdwardsTestCompiler::new(program_name, path, outputs_dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn parse_program(bytes: &[u8]) -> Result<EdwardsTestCompiler, CompilerError> {
|
pub(crate) fn parse_program(bytes: &[u8]) -> Result<EdwardsTestCompiler, CompilerError> {
|
||||||
@ -70,14 +66,14 @@ pub(crate) fn parse_program(bytes: &[u8]) -> Result<EdwardsTestCompiler, Compile
|
|||||||
Ok(compiler)
|
Ok(compiler)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn parse_inputs(bytes: &[u8]) -> Result<EdwardsTestCompiler, CompilerError> {
|
// pub(crate) fn parse_inputs(bytes: &[u8]) -> Result<EdwardsTestCompiler, CompilerError> {
|
||||||
let mut compiler = new_compiler();
|
// let mut compiler = new_compiler();
|
||||||
let inputs_string = String::from_utf8_lossy(bytes);
|
// let inputs_string = String::from_utf8_lossy(bytes);
|
||||||
|
//
|
||||||
compiler.parse_inputs(&inputs_string, "")?;
|
// compiler.parse_inputs(&inputs_string, "")?;
|
||||||
|
//
|
||||||
Ok(compiler)
|
// Ok(compiler)
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub(crate) fn get_outputs(program: EdwardsTestCompiler) -> OutputBytes {
|
pub(crate) fn get_outputs(program: EdwardsTestCompiler) -> OutputBytes {
|
||||||
// synthesize the circuit on the test constraint system
|
// synthesize the circuit on the test constraint system
|
||||||
@ -110,9 +106,19 @@ pub(crate) fn get_synthesis_error(program: EdwardsTestCompiler) {
|
|||||||
assert!(!cs.is_satisfied());
|
assert!(!cs.is_satisfied());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fail_enforce(program: EdwardsTestCompiler) {
|
// pub(crate) fn fail_enforce(program: EdwardsTestCompiler) {
|
||||||
match get_compiler_error(program) {
|
// match get_compiler_error(program) {
|
||||||
CompilerError::FunctionError(FunctionError::StatementError(StatementError::Error(_))) => {}
|
// CompilerError::FunctionError(FunctionError::StatementError(StatementError::Error(_))) => {}
|
||||||
error => panic!("Expected evaluate error, got {}", error),
|
// error => panic!("Expected evaluate error, got {}", error),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
pub(crate) fn generate_main_inputs(inputs: Vec<(&str, Option<InputValue>)>) -> MainInputs {
|
||||||
|
let mut main_inputs = MainInputs::new();
|
||||||
|
|
||||||
|
for (name, value) in inputs {
|
||||||
|
main_inputs.insert(name.to_string(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main_inputs
|
||||||
}
|
}
|
||||||
|
@ -28,13 +28,17 @@ impl MainInputs {
|
|||||||
self.inputs.len()
|
self.inputs.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn insert(&mut self, key: String, value: Option<InputValue>) {
|
||||||
|
self.inputs.insert(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
/// Parses main input definitions and stores them in `self`.
|
/// Parses main input definitions and stores them in `self`.
|
||||||
pub fn parse(&mut self, definitions: Vec<Definition>) -> Result<(), InputParserError> {
|
pub fn parse(&mut self, definitions: Vec<Definition>) -> Result<(), InputParserError> {
|
||||||
for definition in definitions {
|
for definition in definitions {
|
||||||
let name = definition.parameter.variable.value;
|
let name = definition.parameter.variable.value;
|
||||||
let value = InputValue::from_expression(definition.parameter.type_, definition.expression)?;
|
let value = InputValue::from_expression(definition.parameter.type_, definition.expression)?;
|
||||||
|
|
||||||
self.inputs.insert(name, Some(value));
|
self.insert(name, Some(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user