mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-24 07:48:04 +03:00
fix tests
This commit is contained in:
parent
d30d72d76e
commit
bfda4bb95c
@ -50,10 +50,6 @@ impl fmt::Display for Integer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Integer {
|
impl Integer {
|
||||||
pub fn from_implicit(number: String) -> Self {
|
|
||||||
Integer::U128(UInt128::constant(number.parse::<u128>().expect("unable to parse u128")))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_constant(integer_type: &IntegerType, string: String, span: Span) -> Result<Self, IntegerError> {
|
pub fn new_constant(integer_type: &IntegerType, string: String, span: Span) -> Result<Self, IntegerError> {
|
||||||
match integer_type {
|
match integer_type {
|
||||||
IntegerType::U8 => {
|
IntegerType::U8 => {
|
||||||
@ -130,6 +126,11 @@ impl Integer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_bits(&self) -> Vec<Boolean> {
|
||||||
|
let integer = self;
|
||||||
|
match_integer!(integer => integer.get_bits())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_value(&self) -> Option<String> {
|
pub fn get_value(&self) -> Option<String> {
|
||||||
let integer = self;
|
let integer = self;
|
||||||
match_integer!(integer => integer.get_value())
|
match_integer!(integer => integer.get_value())
|
||||||
@ -143,11 +144,6 @@ impl Integer {
|
|||||||
Ok(value_usize)
|
Ok(value_usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_bits_le(&self) -> Vec<Boolean> {
|
|
||||||
let integer = self;
|
|
||||||
match_integer!(integer => integer.get_bits())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_type(&self) -> IntegerType {
|
pub fn get_type(&self) -> IntegerType {
|
||||||
match self {
|
match self {
|
||||||
Integer::U8(_u8) => IntegerType::U8,
|
Integer::U8(_u8) => IntegerType::U8,
|
||||||
@ -449,15 +445,15 @@ impl<F: Field + PrimeField> EvaluateEqGadget<F> for Integer {
|
|||||||
|
|
||||||
impl<F: Field + PrimeField> EvaluateLtGadget<F> for Integer {
|
impl<F: Field + PrimeField> EvaluateLtGadget<F> for Integer {
|
||||||
fn less_than<CS: ConstraintSystem<F>>(&self, mut cs: CS, other: &Self) -> Result<Boolean, SynthesisError> {
|
fn less_than<CS: ConstraintSystem<F>>(&self, mut cs: CS, other: &Self) -> Result<Boolean, SynthesisError> {
|
||||||
if self.to_bits_le().len() != other.to_bits_le().len() {
|
if self.get_bits().len() != other.get_bits().len() {
|
||||||
return Err(SynthesisError::Unsatisfiable);
|
return Err(SynthesisError::Unsatisfiable);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, (self_bit, other_bit)) in self
|
for (i, (self_bit, other_bit)) in self
|
||||||
.to_bits_le()
|
.get_bits()
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.zip(other.to_bits_le().iter().rev())
|
.zip(other.get_bits().iter().rev())
|
||||||
.enumerate()
|
.enumerate()
|
||||||
{
|
{
|
||||||
// is_greater = a & !b
|
// is_greater = a & !b
|
||||||
@ -472,7 +468,7 @@ impl<F: Field + PrimeField> EvaluateLtGadget<F> for Integer {
|
|||||||
return Ok(is_greater.not());
|
return Ok(is_greater.not());
|
||||||
} else if is_less.get_value().unwrap() {
|
} else if is_less.get_value().unwrap() {
|
||||||
return Ok(is_less);
|
return Ok(is_less);
|
||||||
} else if i == self.to_bits_le().len() - 1 {
|
} else if i == self.get_bits().len() - 1 {
|
||||||
return Ok(is_less);
|
return Ok(is_less);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ fn fail_array(program: EdwardsTestCompiler) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn input_value_u32_one() -> InputValue {
|
pub(crate) fn input_value_u32_one() -> InputValue {
|
||||||
InputValue::Integer(IntegerType::U32Type(U32Type {}), 1)
|
InputValue::Integer(IntegerType::U32Type(U32Type {}), 1.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expressions
|
// Expressions
|
||||||
|
3
compiler/tests/integers/i8/add.leo
Normal file
3
compiler/tests/integers/i8/add.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main(a: i8, b: i8) -> i8 {
|
||||||
|
return a + b
|
||||||
|
}
|
3
compiler/tests/integers/i8/assert_eq.leo
Normal file
3
compiler/tests/integers/i8/assert_eq.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main(a: i8, b: i8) {
|
||||||
|
assert_eq!(a, b);
|
||||||
|
}
|
3
compiler/tests/integers/i8/div.leo
Normal file
3
compiler/tests/integers/i8/div.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main(a: i8, b: i8) -> i8 {
|
||||||
|
return a / b
|
||||||
|
}
|
3
compiler/tests/integers/i8/eq.leo
Normal file
3
compiler/tests/integers/i8/eq.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main(a: i8, b: i8) -> bool {
|
||||||
|
return a == b
|
||||||
|
}
|
3
compiler/tests/integers/i8/ge.leo
Normal file
3
compiler/tests/integers/i8/ge.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main(a: i8, b: i8) -> bool {
|
||||||
|
return a >= b
|
||||||
|
}
|
3
compiler/tests/integers/i8/gt.leo
Normal file
3
compiler/tests/integers/i8/gt.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main(a: i8, b: i8) -> bool {
|
||||||
|
return a > b
|
||||||
|
}
|
3
compiler/tests/integers/i8/input.leo
Normal file
3
compiler/tests/integers/i8/input.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main(x: i8) -> i8 {
|
||||||
|
return x
|
||||||
|
}
|
3
compiler/tests/integers/i8/le.leo
Normal file
3
compiler/tests/integers/i8/le.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main(a: i8, b: i8) -> bool {
|
||||||
|
return a <= b
|
||||||
|
}
|
3
compiler/tests/integers/i8/lt.leo
Normal file
3
compiler/tests/integers/i8/lt.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main(a: i8, b: i8) -> bool {
|
||||||
|
return a < b
|
||||||
|
}
|
3
compiler/tests/integers/i8/max.leo
Normal file
3
compiler/tests/integers/i8/max.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main() -> i8 {
|
||||||
|
return 255
|
||||||
|
}
|
3
compiler/tests/integers/i8/min.leo
Normal file
3
compiler/tests/integers/i8/min.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main() -> i8 {
|
||||||
|
return 0
|
||||||
|
}
|
107
compiler/tests/integers/i8/mod.rs
Normal file
107
compiler/tests/integers/i8/mod.rs
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
use crate::{
|
||||||
|
boolean::{output_expected_boolean, output_false, output_true},
|
||||||
|
get_error,
|
||||||
|
get_output,
|
||||||
|
integers::{fail_integer, IntegerTester},
|
||||||
|
parse_program,
|
||||||
|
EdwardsConstrainedValue,
|
||||||
|
EdwardsTestCompiler,
|
||||||
|
};
|
||||||
|
use leo_compiler::{ConstrainedValue, Integer};
|
||||||
|
use leo_inputs::types::{IntegerType, i8Type};
|
||||||
|
use leo_types::InputValue;
|
||||||
|
|
||||||
|
use snarkos_curves::edwards_bls12::Fq;
|
||||||
|
use snarkos_models::gadgets::{
|
||||||
|
r1cs::TestConstraintSystem,
|
||||||
|
utilities::{alloc::AllocGadget, uint::UInt8},
|
||||||
|
};
|
||||||
|
|
||||||
|
fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt8) {
|
||||||
|
let output = get_output(program);
|
||||||
|
|
||||||
|
match output {
|
||||||
|
EdwardsConstrainedValue::Return(vec) => match vec.as_slice() {
|
||||||
|
[ConstrainedValue::Integer(Integer::i8(actual))] => assert_eq!(*actual, expected),
|
||||||
|
_ => panic!("program output unknown return value"),
|
||||||
|
},
|
||||||
|
_ => panic!("program output unknown return value"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test_int!(Testi8, i8, IntegerType::i8Type(i8Type {}), UInt8);
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_i8_min() {
|
||||||
|
Testi8::test_min(std::i8::MIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_i8_max() {
|
||||||
|
Testi8::test_max(std::i8::MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_i8_input() {
|
||||||
|
Testi8::test_input();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_i8_add() {
|
||||||
|
Testi8::test_add();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_i8_sub() {
|
||||||
|
Testi8::test_sub();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_i8_mul() {
|
||||||
|
Testi8::test_mul();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_i8_div() {
|
||||||
|
Testi8::test_div();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_i8_pow() {
|
||||||
|
Testi8::test_pow();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_i8_eq() {
|
||||||
|
Testi8::test_eq();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_i8_ge() {
|
||||||
|
Testi8::test_ge();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_i8_gt() {
|
||||||
|
Testi8::test_gt();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_i8_le() {
|
||||||
|
Testi8::test_le();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_i8_lt() {
|
||||||
|
Testi8::test_lt();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_i8_assert_eq() {
|
||||||
|
Testi8::test_assert_eq();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_i8_ternary() {
|
||||||
|
Testi8::test_ternary();
|
||||||
|
}
|
3
compiler/tests/integers/i8/mul.leo
Normal file
3
compiler/tests/integers/i8/mul.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main(a: i8, b: i8) -> i8 {
|
||||||
|
return a * b
|
||||||
|
}
|
3
compiler/tests/integers/i8/one.leo
Normal file
3
compiler/tests/integers/i8/one.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main() -> i8 {
|
||||||
|
return 1
|
||||||
|
}
|
3
compiler/tests/integers/i8/pow.leo
Normal file
3
compiler/tests/integers/i8/pow.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main(a: i8, b: i8) -> i8 {
|
||||||
|
return a ** b
|
||||||
|
}
|
3
compiler/tests/integers/i8/sub.leo
Normal file
3
compiler/tests/integers/i8/sub.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main(a: i8, b: i8) -> i8 {
|
||||||
|
return a - b
|
||||||
|
}
|
3
compiler/tests/integers/i8/ternary.leo
Normal file
3
compiler/tests/integers/i8/ternary.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main(b: bool, x: i8, y: i8) -> i8 {
|
||||||
|
return if b ? x : y
|
||||||
|
}
|
3
compiler/tests/integers/i8/zero.leo
Normal file
3
compiler/tests/integers/i8/zero.leo
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function main() -> i8 {
|
||||||
|
return 0
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
macro_rules! test_uint {
|
macro_rules! test_int {
|
||||||
($name: ident, $_type: ty, $integer_type: expr, $gadget: ty) => {
|
($name: ident, $_type: ty, $integer_type: expr, $gadget: ty) => {
|
||||||
pub struct $name {}
|
pub struct $name {}
|
||||||
|
|
||||||
@ -52,7 +52,10 @@ macro_rules! test_uint {
|
|||||||
let r1: $_type = rand::random();
|
let r1: $_type = rand::random();
|
||||||
let r2: $_type = rand::random();
|
let r2: $_type = rand::random();
|
||||||
|
|
||||||
let sum = r1.wrapping_add(r2);
|
let sum = match r1.checked_add(r2) {
|
||||||
|
Some(valid) => valid,
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
|
||||||
let cs = TestConstraintSystem::<Fq>::new();
|
let cs = TestConstraintSystem::<Fq>::new();
|
||||||
let sum_allocated = <$gadget>::alloc(cs, || Ok(sum)).unwrap();
|
let sum_allocated = <$gadget>::alloc(cs, || Ok(sum)).unwrap();
|
||||||
@ -99,7 +102,10 @@ macro_rules! test_uint {
|
|||||||
let r1: $_type = rand::random();
|
let r1: $_type = rand::random();
|
||||||
let r2: $_type = rand::random();
|
let r2: $_type = rand::random();
|
||||||
|
|
||||||
let product = r1.wrapping_mul(r2);
|
let product = match r1.checked_mul(r2) {
|
||||||
|
Some(valid) => valid,
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
|
||||||
let cs = TestConstraintSystem::<Fq>::new();
|
let cs = TestConstraintSystem::<Fq>::new();
|
||||||
let product_allocated = <$gadget>::alloc(cs, || Ok(product)).unwrap();
|
let product_allocated = <$gadget>::alloc(cs, || Ok(product)).unwrap();
|
||||||
@ -134,7 +140,11 @@ macro_rules! test_uint {
|
|||||||
let _err = get_error(program);
|
let _err = get_error(program);
|
||||||
} else {
|
} else {
|
||||||
let cs = TestConstraintSystem::<Fq>::new();
|
let cs = TestConstraintSystem::<Fq>::new();
|
||||||
let quotient = r1.wrapping_div(r2);
|
|
||||||
|
let quotient = match r1.checked_div(r2) {
|
||||||
|
Some(valid) => valid,
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
let quotient_allocated = <$gadget>::alloc(cs, || Ok(quotient)).unwrap();
|
let quotient_allocated = <$gadget>::alloc(cs, || Ok(quotient)).unwrap();
|
||||||
|
|
||||||
output_expected_allocated(program, quotient_allocated);
|
output_expected_allocated(program, quotient_allocated);
|
||||||
@ -148,7 +158,10 @@ macro_rules! test_uint {
|
|||||||
let r2: $_type = rand::random();
|
let r2: $_type = rand::random();
|
||||||
let r2 = r2 as u32; // we cast to u32 here because of rust pow() requirements
|
let r2 = r2 as u32; // we cast to u32 here because of rust pow() requirements
|
||||||
|
|
||||||
let result = r1.wrapping_pow(r2);
|
let result = match r1.checked_pow(r2) {
|
||||||
|
Some(valid) => valid,
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
|
||||||
let cs = TestConstraintSystem::<Fq>::new();
|
let cs = TestConstraintSystem::<Fq>::new();
|
||||||
let result_allocated = <$gadget>::alloc(cs, || Ok(result)).unwrap();
|
let result_allocated = <$gadget>::alloc(cs, || Ok(result)).unwrap();
|
50
compiler/tests/integers/integer_tester.rs
Normal file
50
compiler/tests/integers/integer_tester.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use crate::{get_error, EdwardsTestCompiler};
|
||||||
|
use leo_compiler::errors::{CompilerError, FunctionError, IntegerError};
|
||||||
|
|
||||||
|
pub trait IntegerTester {
|
||||||
|
/// Tests use of the integer in a function input
|
||||||
|
fn test_input();
|
||||||
|
|
||||||
|
/// Tests a wrapping addition
|
||||||
|
fn test_add();
|
||||||
|
|
||||||
|
/// Tests a wrapping subtraction
|
||||||
|
fn test_sub();
|
||||||
|
|
||||||
|
/// Tests a wrapping multiplication
|
||||||
|
fn test_mul();
|
||||||
|
|
||||||
|
/// Tests a non-wrapping division
|
||||||
|
fn test_div();
|
||||||
|
|
||||||
|
/// 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fail_integer(program: EdwardsTestCompiler) {
|
||||||
|
match get_error(program) {
|
||||||
|
CompilerError::FunctionError(FunctionError::IntegerError(IntegerError::Error(_string))) => {}
|
||||||
|
error => panic!("Expected invalid boolean error, got {}", error),
|
||||||
|
}
|
||||||
|
}
|
@ -1,56 +1,9 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod macros;
|
// pub mod int_macro;
|
||||||
|
pub mod uint_macro;
|
||||||
|
|
||||||
use crate::{get_error, EdwardsTestCompiler};
|
pub mod integer_tester;
|
||||||
use leo_compiler::errors::{CompilerError, FunctionError, IntegerError};
|
pub use self::integer_tester::*;
|
||||||
|
|
||||||
pub trait IntegerTester {
|
|
||||||
/// Tests use of the integer in a function input
|
|
||||||
fn test_input();
|
|
||||||
|
|
||||||
/// Tests a wrapping addition
|
|
||||||
fn test_add();
|
|
||||||
|
|
||||||
/// Tests a wrapping subtraction
|
|
||||||
fn test_sub();
|
|
||||||
|
|
||||||
/// Tests a wrapping multiplication
|
|
||||||
fn test_mul();
|
|
||||||
|
|
||||||
/// Tests a non-wrapping division
|
|
||||||
fn test_div();
|
|
||||||
|
|
||||||
/// 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn fail_integer(program: EdwardsTestCompiler) {
|
|
||||||
match get_error(program) {
|
|
||||||
CompilerError::FunctionError(FunctionError::IntegerError(IntegerError::Error(_string))) => {}
|
|
||||||
error => panic!("Expected invalid boolean error, got {}", error),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// must be below macro definitions!
|
// must be below macro definitions!
|
||||||
pub mod u128;
|
pub mod u128;
|
||||||
@ -58,3 +11,5 @@ pub mod u16;
|
|||||||
pub mod u32;
|
pub mod u32;
|
||||||
pub mod u64;
|
pub mod u64;
|
||||||
pub mod u8;
|
pub mod u8;
|
||||||
|
|
||||||
|
// pub mod i8;
|
||||||
|
390
compiler/tests/integers/uint_macro.rs
Normal file
390
compiler/tests/integers/uint_macro.rs
Normal file
@ -0,0 +1,390 @@
|
|||||||
|
macro_rules! test_uint {
|
||||||
|
($name: ident, $_type: ty, $integer_type: expr, $gadget: ty) => {
|
||||||
|
pub struct $name {}
|
||||||
|
|
||||||
|
impl $name {
|
||||||
|
fn test_min(min: $_type) {
|
||||||
|
let min_allocated = <$gadget>::constant(min);
|
||||||
|
|
||||||
|
let bytes = include_bytes!("min.leo");
|
||||||
|
let program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
output_expected_allocated(program, min_allocated);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_max(max: $_type) {
|
||||||
|
let max_allocated = <$gadget>::constant(max);
|
||||||
|
|
||||||
|
let bytes = include_bytes!("max.leo");
|
||||||
|
let program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
output_expected_allocated(program, max_allocated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntegerTester for $name {
|
||||||
|
fn test_input() {
|
||||||
|
// valid input
|
||||||
|
let num: $_type = rand::random();
|
||||||
|
let expected = <$gadget>::constant(num);
|
||||||
|
|
||||||
|
let bytes = include_bytes!("input.leo");
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
program.set_inputs(vec![Some(InputValue::Integer($integer_type, num.to_string()))]);
|
||||||
|
|
||||||
|
output_expected_allocated(program, expected);
|
||||||
|
|
||||||
|
// invalid input
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
program.set_inputs(vec![Some(InputValue::Boolean(true))]);
|
||||||
|
fail_integer(program);
|
||||||
|
|
||||||
|
// None input
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
program.set_inputs(vec![None]);
|
||||||
|
fail_integer(program);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_add() {
|
||||||
|
for _ in 0..10 {
|
||||||
|
let r1: $_type = rand::random();
|
||||||
|
let r2: $_type = rand::random();
|
||||||
|
|
||||||
|
let sum = r1.wrapping_add(r2);
|
||||||
|
|
||||||
|
let cs = TestConstraintSystem::<Fq>::new();
|
||||||
|
let sum_allocated = <$gadget>::alloc(cs, || Ok(sum)).unwrap();
|
||||||
|
|
||||||
|
let bytes = include_bytes!("add.leo");
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
program.set_inputs(vec![
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
Some(InputValue::Integer($integer_type, r2.to_string())),
|
||||||
|
]);
|
||||||
|
|
||||||
|
output_expected_allocated(program, sum_allocated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_sub() {
|
||||||
|
for _ in 0..10 {
|
||||||
|
let r1: $_type = rand::random();
|
||||||
|
let r2: $_type = rand::random();
|
||||||
|
|
||||||
|
let difference = match r1.checked_sub(r2) {
|
||||||
|
Some(valid) => valid,
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
|
||||||
|
let cs = TestConstraintSystem::<Fq>::new();
|
||||||
|
let difference_allocated = <$gadget>::alloc(cs, || Ok(difference)).unwrap();
|
||||||
|
|
||||||
|
let bytes = include_bytes!("sub.leo");
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
program.set_inputs(vec![
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
Some(InputValue::Integer($integer_type, r2.to_string())),
|
||||||
|
]);
|
||||||
|
|
||||||
|
output_expected_allocated(program, difference_allocated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_mul() {
|
||||||
|
for _ in 0..10 {
|
||||||
|
let r1: $_type = rand::random();
|
||||||
|
let r2: $_type = rand::random();
|
||||||
|
|
||||||
|
let product = r1.wrapping_mul(r2);
|
||||||
|
|
||||||
|
let cs = TestConstraintSystem::<Fq>::new();
|
||||||
|
let product_allocated = <$gadget>::alloc(cs, || Ok(product)).unwrap();
|
||||||
|
|
||||||
|
let bytes = include_bytes!("mul.leo");
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
program.set_inputs(vec![
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
Some(InputValue::Integer($integer_type, r2.to_string())),
|
||||||
|
]);
|
||||||
|
|
||||||
|
output_expected_allocated(program, product_allocated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_div() {
|
||||||
|
for _ in 0..10 {
|
||||||
|
let r1: $_type = rand::random();
|
||||||
|
let r2: $_type = rand::random();
|
||||||
|
|
||||||
|
let bytes = include_bytes!("div.leo");
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
program.set_inputs(vec![
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
Some(InputValue::Integer($integer_type, r2.to_string())),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// expect an error when dividing by zero
|
||||||
|
if r2 == 0 {
|
||||||
|
let _err = get_error(program);
|
||||||
|
} else {
|
||||||
|
let cs = TestConstraintSystem::<Fq>::new();
|
||||||
|
let quotient = r1.wrapping_div(r2);
|
||||||
|
let quotient_allocated = <$gadget>::alloc(cs, || Ok(quotient)).unwrap();
|
||||||
|
|
||||||
|
output_expected_allocated(program, quotient_allocated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_pow() {
|
||||||
|
// for _ in 0..10 {// these loops take an excessive amount of time
|
||||||
|
let r1: $_type = rand::random();
|
||||||
|
let r2: $_type = rand::random();
|
||||||
|
let r2 = r2 as u32; // we cast to u32 here because of rust pow() requirements
|
||||||
|
|
||||||
|
let result = r1.wrapping_pow(r2);
|
||||||
|
|
||||||
|
let cs = TestConstraintSystem::<Fq>::new();
|
||||||
|
let result_allocated = <$gadget>::alloc(cs, || Ok(result)).unwrap();
|
||||||
|
|
||||||
|
let bytes = include_bytes!("pow.leo");
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
program.set_inputs(vec![
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
Some(InputValue::Integer($integer_type, r2.to_string())),
|
||||||
|
]);
|
||||||
|
|
||||||
|
output_expected_allocated(program, result_allocated);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_eq() {
|
||||||
|
for _ in 0..10 {
|
||||||
|
let r1: $_type = rand::random();
|
||||||
|
|
||||||
|
// test equal
|
||||||
|
let bytes = include_bytes!("eq.leo");
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
program.set_inputs(vec![
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
]);
|
||||||
|
|
||||||
|
output_true(program);
|
||||||
|
|
||||||
|
// test not equal
|
||||||
|
let r2: $_type = rand::random();
|
||||||
|
|
||||||
|
let result = r1.eq(&r2);
|
||||||
|
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
program.set_inputs(vec![
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
Some(InputValue::Integer($integer_type, r2.to_string())),
|
||||||
|
]);
|
||||||
|
|
||||||
|
output_expected_boolean(program, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_ge() {
|
||||||
|
for _ in 0..10 {
|
||||||
|
let r1: $_type = rand::random();
|
||||||
|
|
||||||
|
// test equal
|
||||||
|
let bytes = include_bytes!("ge.leo");
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
program.set_inputs(vec![
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
]);
|
||||||
|
|
||||||
|
output_true(program);
|
||||||
|
|
||||||
|
// test not equal
|
||||||
|
let r2: $_type = rand::random();
|
||||||
|
|
||||||
|
let result = r1.ge(&r2);
|
||||||
|
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
program.set_inputs(vec![
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
Some(InputValue::Integer($integer_type, r2.to_string())),
|
||||||
|
]);
|
||||||
|
|
||||||
|
output_expected_boolean(program, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_gt() {
|
||||||
|
for _ in 0..10 {
|
||||||
|
let r1: $_type = rand::random();
|
||||||
|
|
||||||
|
// test equal
|
||||||
|
let bytes = include_bytes!("gt.leo");
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
program.set_inputs(vec![
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
]);
|
||||||
|
|
||||||
|
output_false(program);
|
||||||
|
|
||||||
|
// test not equal
|
||||||
|
let r2: $_type = rand::random();
|
||||||
|
|
||||||
|
let result = r1.gt(&r2);
|
||||||
|
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
program.set_inputs(vec![
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
Some(InputValue::Integer($integer_type, r2.to_string())),
|
||||||
|
]);
|
||||||
|
|
||||||
|
output_expected_boolean(program, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_le() {
|
||||||
|
for _ in 0..10 {
|
||||||
|
let r1: $_type = rand::random();
|
||||||
|
|
||||||
|
// test equal
|
||||||
|
let bytes = include_bytes!("le.leo");
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
program.set_inputs(vec![
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
]);
|
||||||
|
|
||||||
|
output_true(program);
|
||||||
|
|
||||||
|
// test not equal
|
||||||
|
let r2: $_type = rand::random();
|
||||||
|
|
||||||
|
let result = r1.le(&r2);
|
||||||
|
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
program.set_inputs(vec![
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
Some(InputValue::Integer($integer_type, r2.to_string())),
|
||||||
|
]);
|
||||||
|
|
||||||
|
output_expected_boolean(program, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_lt() {
|
||||||
|
for _ in 0..10 {
|
||||||
|
let r1: $_type = rand::random();
|
||||||
|
|
||||||
|
// test equal
|
||||||
|
let bytes = include_bytes!("lt.leo");
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
program.set_inputs(vec![
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
]);
|
||||||
|
|
||||||
|
output_false(program);
|
||||||
|
|
||||||
|
// test not equal
|
||||||
|
let r2: $_type = rand::random();
|
||||||
|
|
||||||
|
let result = r1.lt(&r2);
|
||||||
|
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
program.set_inputs(vec![
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
Some(InputValue::Integer($integer_type, r2.to_string())),
|
||||||
|
]);
|
||||||
|
|
||||||
|
output_expected_boolean(program, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_assert_eq() {
|
||||||
|
for _ in 0..10 {
|
||||||
|
let r1: $_type = rand::random();
|
||||||
|
|
||||||
|
// test equal
|
||||||
|
let bytes = include_bytes!("assert_eq.leo");
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
program.set_inputs(vec![
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
]);
|
||||||
|
|
||||||
|
let _ = get_output(program);
|
||||||
|
|
||||||
|
// test not equal
|
||||||
|
let r2: $_type = rand::random();
|
||||||
|
|
||||||
|
if r1 == r2 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut program = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
program.set_inputs(vec![
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
Some(InputValue::Integer($integer_type, r2.to_string())),
|
||||||
|
]);
|
||||||
|
|
||||||
|
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 bytes = include_bytes!("ternary.leo");
|
||||||
|
let mut program_1 = parse_program(bytes).unwrap();
|
||||||
|
|
||||||
|
let mut program_2 = program_1.clone();
|
||||||
|
|
||||||
|
// true -> field 1
|
||||||
|
program_1.set_inputs(vec![
|
||||||
|
Some(InputValue::Boolean(true)),
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
Some(InputValue::Integer($integer_type, r2.to_string())),
|
||||||
|
]);
|
||||||
|
|
||||||
|
output_expected_allocated(program_1, g1);
|
||||||
|
|
||||||
|
// false -> field 2
|
||||||
|
program_2.set_inputs(vec![
|
||||||
|
Some(InputValue::Boolean(false)),
|
||||||
|
Some(InputValue::Integer($integer_type, r1.to_string())),
|
||||||
|
Some(InputValue::Integer($integer_type, r2.to_string())),
|
||||||
|
]);
|
||||||
|
|
||||||
|
output_expected_allocated(program_2, g2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -35,17 +35,26 @@ fn test_assert() {
|
|||||||
|
|
||||||
// Check that an input value of 1 satisfies the constraint system
|
// Check that an input value of 1 satisfies the constraint system
|
||||||
|
|
||||||
program_1_pass.set_inputs(vec![Some(InputValue::Integer(IntegerType::U32Type(U32Type {}), 1))]);
|
program_1_pass.set_inputs(vec![Some(InputValue::Integer(
|
||||||
|
IntegerType::U32Type(U32Type {}),
|
||||||
|
1.to_string(),
|
||||||
|
))]);
|
||||||
empty_output_satisfied(program_1_pass);
|
empty_output_satisfied(program_1_pass);
|
||||||
|
|
||||||
// Check that an input value of 0 satisfies the constraint system
|
// Check that an input value of 0 satisfies the constraint system
|
||||||
|
|
||||||
program_0_pass.set_inputs(vec![Some(InputValue::Integer(IntegerType::U32Type(U32Type {}), 0))]);
|
program_0_pass.set_inputs(vec![Some(InputValue::Integer(
|
||||||
|
IntegerType::U32Type(U32Type {}),
|
||||||
|
0.to_string(),
|
||||||
|
))]);
|
||||||
empty_output_satisfied(program_0_pass);
|
empty_output_satisfied(program_0_pass);
|
||||||
|
|
||||||
// Check that an input value of 2 does not satisfy the constraint system
|
// Check that an input value of 2 does not satisfy the constraint system
|
||||||
|
|
||||||
program_2_fail.set_inputs(vec![Some(InputValue::Integer(IntegerType::U32Type(U32Type {}), 2))]);
|
program_2_fail.set_inputs(vec![Some(InputValue::Integer(
|
||||||
|
IntegerType::U32Type(U32Type {}),
|
||||||
|
2.to_string(),
|
||||||
|
))]);
|
||||||
let mut cs = TestConstraintSystem::<Fq>::new();
|
let mut cs = TestConstraintSystem::<Fq>::new();
|
||||||
let _output = program_2_fail.compile_constraints(&mut cs).unwrap();
|
let _output = program_2_fail.compile_constraints(&mut cs).unwrap();
|
||||||
assert!(!cs.is_satisfied());
|
assert!(!cs.is_satisfied());
|
||||||
@ -59,12 +68,18 @@ fn test_mutate() {
|
|||||||
|
|
||||||
// Check that an input value of 1 satisfies the constraint system
|
// Check that an input value of 1 satisfies the constraint system
|
||||||
|
|
||||||
program_1_true.set_inputs(vec![Some(InputValue::Integer(IntegerType::U32Type(U32Type {}), 1))]);
|
program_1_true.set_inputs(vec![Some(InputValue::Integer(
|
||||||
|
IntegerType::U32Type(U32Type {}),
|
||||||
|
1.to_string(),
|
||||||
|
))]);
|
||||||
output_one(program_1_true);
|
output_one(program_1_true);
|
||||||
|
|
||||||
// Check that an input value of 0 satisfies the constraint system
|
// Check that an input value of 0 satisfies the constraint system
|
||||||
|
|
||||||
program_0_pass.set_inputs(vec![Some(InputValue::Integer(IntegerType::U32Type(U32Type {}), 0))]);
|
program_0_pass.set_inputs(vec![Some(InputValue::Integer(
|
||||||
|
IntegerType::U32Type(U32Type {}),
|
||||||
|
0.to_string(),
|
||||||
|
))]);
|
||||||
output_zero(program_0_pass);
|
output_zero(program_0_pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,15 +108,24 @@ fn test_chain() {
|
|||||||
let mut program_2_3 = program_1_1.clone();
|
let mut program_2_3 = program_1_1.clone();
|
||||||
|
|
||||||
// Check that an input of 1 outputs true
|
// Check that an input of 1 outputs true
|
||||||
program_1_1.set_inputs(vec![Some(InputValue::Integer(IntegerType::U32Type(U32Type {}), 1))]);
|
program_1_1.set_inputs(vec![Some(InputValue::Integer(
|
||||||
|
IntegerType::U32Type(U32Type {}),
|
||||||
|
1.to_string(),
|
||||||
|
))]);
|
||||||
output_number(program_1_1, 1u32);
|
output_number(program_1_1, 1u32);
|
||||||
|
|
||||||
// Check that an input of 0 outputs true
|
// Check that an input of 0 outputs true
|
||||||
program_2_2.set_inputs(vec![Some(InputValue::Integer(IntegerType::U32Type(U32Type {}), 2))]);
|
program_2_2.set_inputs(vec![Some(InputValue::Integer(
|
||||||
|
IntegerType::U32Type(U32Type {}),
|
||||||
|
2.to_string(),
|
||||||
|
))]);
|
||||||
output_number(program_2_2, 2u32);
|
output_number(program_2_2, 2u32);
|
||||||
|
|
||||||
// Check that an input of 0 outputs true
|
// Check that an input of 0 outputs true
|
||||||
program_2_3.set_inputs(vec![Some(InputValue::Integer(IntegerType::U32Type(U32Type {}), 5))]);
|
program_2_3.set_inputs(vec![Some(InputValue::Integer(
|
||||||
|
IntegerType::U32Type(U32Type {}),
|
||||||
|
5.to_string(),
|
||||||
|
))]);
|
||||||
output_number(program_2_3, 3u32);
|
output_number(program_2_3, 3u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user