add groupType to compiler

This commit is contained in:
collin 2020-05-29 16:43:39 -07:00
parent 1232481219
commit 31ec24670c
29 changed files with 425 additions and 214 deletions

View File

@ -4,7 +4,7 @@ use crate::{
ast,
constraints::{generate_constraints, ConstrainedValue},
errors::CompilerError,
InputValue, Program,
GroupType, InputValue, Program,
};
use snarkos_errors::gadgets::SynthesisError;
@ -18,16 +18,18 @@ use sha2::{Digest, Sha256};
use std::{fs, marker::PhantomData, path::PathBuf};
#[derive(Clone)]
pub struct Compiler<F: Field + PrimeField> {
pub struct Compiler<NativeF: Field, F: Field + PrimeField, GType: GroupType<NativeF, F>> {
package_name: String,
main_file_path: PathBuf,
program: Program<F>,
program_inputs: Vec<Option<InputValue<F>>>,
output: Option<ConstrainedValue<F>>,
output: Option<ConstrainedValue<NativeF, F, GType>>,
_engine: PhantomData<F>,
}
impl<F: Field + PrimeField> Compiler<F> {
impl<NativeF: Field, F: Field + PrimeField, GType: GroupType<NativeF, F>>
Compiler<NativeF, F, GType>
{
pub fn init(package_name: String, main_file_path: PathBuf) -> Result<Self, CompilerError> {
let mut program = Self {
package_name,
@ -64,7 +66,7 @@ impl<F: Field + PrimeField> Compiler<F> {
pub fn compile_constraints<CS: ConstraintSystem<F>>(
self,
cs: &mut CS,
) -> Result<ConstrainedValue<F>, CompilerError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, CompilerError> {
generate_constraints(cs, self.program, self.program_inputs)
}
@ -107,12 +109,16 @@ impl<F: Field + PrimeField> Compiler<F> {
}
}
impl<F: Field + PrimeField> ConstraintSynthesizer<F> for Compiler<F> {
impl<NativeF: Field, F: Field + PrimeField, GType: GroupType<NativeF, F>> ConstraintSynthesizer<F>
for Compiler<NativeF, F, GType>
{
fn generate_constraints<CS: ConstraintSystem<F>>(
self,
cs: &mut CS,
) -> Result<(), SynthesisError> {
let _result = generate_constraints(cs, self.program, self.program_inputs).unwrap();
let _result =
generate_constraints::<NativeF, _, GType, _>(cs, self.program, self.program_inputs)
.unwrap();
// Write results to file or something

View File

@ -4,6 +4,7 @@ use crate::{
constraints::{ConstrainedProgram, ConstrainedValue},
errors::BooleanError,
types::InputValue,
GroupType,
};
use snarkos_errors::gadgets::SynthesisError;
@ -15,14 +16,20 @@ use snarkos_models::{
},
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<
NativeF: Field,
F: Field + PrimeField,
GType: GroupType<NativeF, F>,
CS: ConstraintSystem<F>,
> ConstrainedProgram<NativeF, F, GType, CS>
{
pub(crate) fn bool_from_input(
&mut self,
cs: &mut CS,
name: String,
private: bool,
input_value: Option<InputValue<F>>,
) -> Result<ConstrainedValue<F>, BooleanError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, BooleanError> {
// Check that the input value is the correct type
let bool_value = match input_value {
Some(input) => {
@ -49,13 +56,13 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
Ok(ConstrainedValue::Boolean(number))
}
pub(crate) fn get_boolean_constant(bool: Boolean) -> ConstrainedValue<F> {
pub(crate) fn get_boolean_constant(bool: Boolean) -> ConstrainedValue<NativeF, F, GType> {
ConstrainedValue::Boolean(bool)
}
pub(crate) fn evaluate_not(
value: ConstrainedValue<F>,
) -> Result<ConstrainedValue<F>, BooleanError> {
value: ConstrainedValue<NativeF, F, GType>,
) -> Result<ConstrainedValue<NativeF, F, GType>, BooleanError> {
match value {
ConstrainedValue::Boolean(boolean) => Ok(ConstrainedValue::Boolean(boolean.not())),
value => Err(BooleanError::CannotEvaluate(format!("!{}", value))),
@ -65,9 +72,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
pub(crate) fn enforce_or(
&mut self,
cs: &mut CS,
left: ConstrainedValue<F>,
right: ConstrainedValue<F>,
) -> Result<ConstrainedValue<F>, BooleanError> {
left: ConstrainedValue<NativeF, F, GType>,
right: ConstrainedValue<NativeF, F, GType>,
) -> Result<ConstrainedValue<NativeF, F, GType>, BooleanError> {
match (left, right) {
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => Ok(
ConstrainedValue::Boolean(Boolean::or(cs, &left_bool, &right_bool)?),
@ -82,9 +89,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
pub(crate) fn enforce_and(
&mut self,
cs: &mut CS,
left: ConstrainedValue<F>,
right: ConstrainedValue<F>,
) -> Result<ConstrainedValue<F>, BooleanError> {
left: ConstrainedValue<NativeF, F, GType>,
right: ConstrainedValue<NativeF, F, GType>,
) -> Result<ConstrainedValue<NativeF, F, GType>, BooleanError> {
match (left, right) {
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => Ok(
ConstrainedValue::Boolean(Boolean::and(cs, &left_bool, &right_bool)?),
@ -96,7 +103,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
}
}
pub(crate) fn boolean_eq(left: Boolean, right: Boolean) -> ConstrainedValue<F> {
pub(crate) fn boolean_eq(left: Boolean, right: Boolean) -> ConstrainedValue<NativeF, F, GType> {
ConstrainedValue::Boolean(Boolean::Constant(left.eq(&right)))
}

View File

@ -8,7 +8,7 @@ use crate::{
CircuitFieldDefinition, CircuitMember, Expression, Identifier, RangeOrExpression,
SpreadOrExpression,
},
Integer, IntegerType, Type,
GroupType, Integer, IntegerType, Type,
};
use snarkos_models::{
@ -19,7 +19,13 @@ use snarkos_models::{
},
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<
NativeF: Field,
F: Field + PrimeField,
GType: GroupType<NativeF, F>,
CS: ConstraintSystem<F>,
> ConstrainedProgram<NativeF, F, GType, CS>
{
/// Enforce a variable expression by getting the resolved value
pub(crate) fn evaluate_identifier(
&mut self,
@ -27,7 +33,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
function_scope: String,
expected_types: &Vec<Type<F>>,
unresolved_identifier: Identifier<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
// Evaluate the identifier name in the current function scope
let variable_name = new_scope(function_scope, unresolved_identifier.to_string());
let identifier_name = new_scope(file_scope, unresolved_identifier.to_string());
@ -53,9 +59,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
fn enforce_add_expression(
&mut self,
cs: &mut CS,
left: ConstrainedValue<F>,
right: ConstrainedValue<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
left: ConstrainedValue<NativeF, F, GType>,
right: ConstrainedValue<NativeF, F, GType>,
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
Ok(Self::enforce_integer_add(cs, num_1, num_2)?)
@ -84,9 +90,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
fn enforce_sub_expression(
&mut self,
cs: &mut CS,
left: ConstrainedValue<F>,
right: ConstrainedValue<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
left: ConstrainedValue<NativeF, F, GType>,
right: ConstrainedValue<NativeF, F, GType>,
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
Ok(Self::enforce_integer_sub(cs, num_1, num_2)?)
@ -115,9 +121,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
fn enforce_mul_expression(
&mut self,
cs: &mut CS,
left: ConstrainedValue<F>,
right: ConstrainedValue<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
left: ConstrainedValue<NativeF, F, GType>,
right: ConstrainedValue<NativeF, F, GType>,
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
Ok(Self::enforce_integer_mul(cs, num_1, num_2)?)
@ -148,9 +154,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
fn enforce_div_expression(
&mut self,
cs: &mut CS,
left: ConstrainedValue<F>,
right: ConstrainedValue<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
left: ConstrainedValue<NativeF, F, GType>,
right: ConstrainedValue<NativeF, F, GType>,
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
Ok(Self::enforce_integer_div(cs, num_1, num_2)?)
@ -177,9 +183,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
fn enforce_pow_expression(
&mut self,
cs: &mut CS,
left: ConstrainedValue<F>,
right: ConstrainedValue<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
left: ConstrainedValue<NativeF, F, GType>,
right: ConstrainedValue<NativeF, F, GType>,
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
Ok(Self::enforce_integer_pow(cs, num_1, num_2)?)
@ -208,9 +214,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
/// Evaluate Boolean operations
fn evaluate_eq_expression(
&mut self,
left: ConstrainedValue<F>,
right: ConstrainedValue<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
left: ConstrainedValue<NativeF, F, GType>,
right: ConstrainedValue<NativeF, F, GType>,
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Boolean(bool_1), ConstrainedValue::Boolean(bool_2)) => {
Ok(Self::boolean_eq(bool_1, bool_2))
@ -241,9 +247,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
fn evaluate_geq_expression(
&mut self,
left: ConstrainedValue<F>,
right: ConstrainedValue<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
left: ConstrainedValue<NativeF, F, GType>,
right: ConstrainedValue<NativeF, F, GType>,
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
match (left, right) {
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
// Self::field_geq(fe_1, fe_2)
@ -265,9 +271,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
fn evaluate_gt_expression(
&mut self,
left: ConstrainedValue<F>,
right: ConstrainedValue<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
left: ConstrainedValue<NativeF, F, GType>,
right: ConstrainedValue<NativeF, F, GType>,
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
match (left, right) {
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
// Self::field_gt(fe_1, fe_2)
@ -289,9 +295,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
fn evaluate_leq_expression(
&mut self,
left: ConstrainedValue<F>,
right: ConstrainedValue<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
left: ConstrainedValue<NativeF, F, GType>,
right: ConstrainedValue<NativeF, F, GType>,
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
match (left, right) {
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
// Self::field_leq(fe_1, fe_2)
@ -313,9 +319,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
fn evaluate_lt_expression(
&mut self,
left: ConstrainedValue<F>,
right: ConstrainedValue<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
left: ConstrainedValue<NativeF, F, GType>,
right: ConstrainedValue<NativeF, F, GType>,
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
match (left, right) {
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
// Self::field_lt(fe_1, fe_2)
@ -345,7 +351,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
first: Expression<F>,
second: Expression<F>,
third: Expression<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
let resolved_first = match self.enforce_expression(
cs,
file_scope.clone(),
@ -394,7 +400,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
function_scope: String,
expected_types: &Vec<Type<F>>,
array: Vec<Box<SpreadOrExpression<F>>>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
// Check explicit array type dimension if given
let mut expected_types = expected_types.clone();
let expected_dimensions = vec![];
@ -479,7 +485,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
expected_types: &Vec<Type<F>>,
array: Box<Expression<F>>,
index: RangeOrExpression<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
let array = match self.enforce_branch(
cs,
file_scope.clone(),
@ -519,7 +525,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
function_scope: String,
identifier: Identifier<F>,
members: Vec<CircuitFieldDefinition<F>>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
let mut program_identifier = new_scope(file_scope.clone(), identifier.to_string());
if identifier.is_self() {
@ -594,7 +600,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
expected_types: &Vec<Type<F>>,
circuit_identifier: Box<Expression<F>>,
circuit_member: Identifier<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
let (circuit_name, members) = match self.enforce_branch(
cs,
file_scope.clone(),
@ -655,7 +661,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
expected_types: &Vec<Type<F>>,
circuit_identifier: Box<Expression<F>>,
circuit_member: Identifier<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
// Get defined circuit
let circuit = match self.enforce_expression(
cs,
@ -709,7 +715,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
expected_types: &Vec<Type<F>>,
function: Box<Expression<F>>,
arguments: Vec<Expression<F>>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
let function_value = self.enforce_expression(
cs,
file_scope.clone(),
@ -747,7 +753,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
pub(crate) fn enforce_number_implicit(
expected_types: &Vec<Type<F>>,
value: String,
) -> Result<ConstrainedValue<F>, ExpressionError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
if expected_types.len() == 1 {
return Ok(ConstrainedValue::from_type(value, &expected_types[0])?);
}
@ -765,7 +771,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
function_scope: String,
expected_types: &Vec<Type<F>>,
expression: Expression<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
let mut branch =
self.enforce_expression(cs, file_scope, function_scope, expected_types, expression)?;
@ -783,7 +789,13 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
expected_types: &Vec<Type<F>>,
left: Expression<F>,
right: Expression<F>,
) -> Result<(ConstrainedValue<F>, ConstrainedValue<F>), ExpressionError> {
) -> Result<
(
ConstrainedValue<NativeF, F, GType>,
ConstrainedValue<NativeF, F, GType>,
),
ExpressionError,
> {
let resolved_left = self.enforce_branch(
cs,
file_scope.clone(),
@ -809,7 +821,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
function_scope: String,
expected_types: &Vec<Type<F>>,
expression: Expression<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, ExpressionError> {
match expression {
// Variables
Expression::Identifier(unresolved_variable) => self.evaluate_identifier(
@ -822,7 +834,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
// Values
Expression::Integer(integer) => Ok(Self::get_integer_constant(integer)),
Expression::FieldElement(fe) => Ok(Self::get_field_element_constant(fe)),
Expression::Group(gr) => Ok(ConstrainedValue::Group(gr)),
Expression::Group(group_affine) => {
Ok(ConstrainedValue::Group(GType::constant(group_affine)?))
}
Expression::Boolean(bool) => Ok(Self::get_boolean_constant(bool)),
Expression::Implicit(value) => Self::enforce_number_implicit(expected_types, value),

View File

@ -4,6 +4,7 @@ use crate::{
constraints::{ConstrainedProgram, ConstrainedValue},
errors::FieldElementError,
types::{FieldElement, InputValue, Integer},
GroupType,
};
use snarkos_errors::gadgets::SynthesisError;
@ -12,14 +13,20 @@ use snarkos_models::{
gadgets::r1cs::{ConstraintSystem, LinearCombination, Variable as R1CSVariable},
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<
NativeF: Field,
F: Field + PrimeField,
GType: GroupType<NativeF, F>,
CS: ConstraintSystem<F>,
> ConstrainedProgram<NativeF, F, GType, CS>
{
pub(crate) fn field_element_from_input(
&mut self,
cs: &mut CS,
name: String,
private: bool,
input_value: Option<InputValue<F>>,
) -> Result<ConstrainedValue<F>, FieldElementError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, FieldElementError> {
// Check that the parameter value is the correct type
let field_option = match input_value {
Some(input) => {
@ -51,7 +58,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
)))
}
pub(crate) fn get_field_element_constant(fe: FieldElement<F>) -> ConstrainedValue<F> {
pub(crate) fn get_field_element_constant(
fe: FieldElement<F>,
) -> ConstrainedValue<NativeF, F, GType> {
ConstrainedValue::FieldElement(fe)
}
@ -124,7 +133,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
fe_1: FieldElement<F>,
fe_2: FieldElement<F>,
) -> Result<ConstrainedValue<F>, FieldElementError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, FieldElementError> {
Ok(match (fe_1, fe_2) {
// if both constants, then return a constant result
(FieldElement::Constant(fe_1_constant), FieldElement::Constant(fe_2_constant)) => {
@ -201,7 +210,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
fe_1: FieldElement<F>,
fe_2: FieldElement<F>,
) -> Result<ConstrainedValue<F>, FieldElementError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, FieldElementError> {
Ok(match (fe_1, fe_2) {
// if both constants, then return a constant result
(FieldElement::Constant(fe_1_constant), FieldElement::Constant(fe_2_constant)) => {
@ -278,7 +287,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
fe_1: FieldElement<F>,
fe_2: FieldElement<F>,
) -> Result<ConstrainedValue<F>, FieldElementError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, FieldElementError> {
Ok(match (fe_1, fe_2) {
// if both constants, then return a constant result
(FieldElement::Constant(fe_1_constant), FieldElement::Constant(fe_2_constant)) => {
@ -355,7 +364,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
fe_1: FieldElement<F>,
fe_2: FieldElement<F>,
) -> Result<ConstrainedValue<F>, FieldElementError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, FieldElementError> {
Ok(match (fe_1, fe_2) {
// if both constants, then return a constant result
(FieldElement::Constant(fe_1_constant), FieldElement::Constant(fe_2_constant)) => {
@ -443,7 +452,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
fe_1: FieldElement<F>,
num: Integer,
) -> Result<ConstrainedValue<F>, FieldElementError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, FieldElementError> {
Ok(match fe_1 {
// if both constants, then return a constant result
FieldElement::Constant(fe_1_constant) => ConstrainedValue::FieldElement(

View File

@ -5,6 +5,7 @@ use crate::{
constraints::{new_scope, ConstrainedProgram, ConstrainedValue},
errors::{FunctionError, ImportError},
types::{Expression, Function, Identifier, InputValue, Program, Type},
GroupType,
};
use snarkos_models::{
@ -12,7 +13,13 @@ use snarkos_models::{
gadgets::r1cs::ConstraintSystem,
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<
NativeF: Field,
F: Field + PrimeField,
GType: GroupType<NativeF, F>,
CS: ConstraintSystem<F>,
> ConstrainedProgram<NativeF, F, GType, CS>
{
fn check_arguments_length(expected: usize, actual: usize) -> Result<(), FunctionError> {
// Make sure we are given the correct number of arguments
if expected != actual {
@ -30,7 +37,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
function_name: String,
expected_types: Vec<Type<F>>,
input: Expression<F>,
) -> Result<ConstrainedValue<F>, FunctionError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, FunctionError> {
// Evaluate the function input value as pass by value from the caller or
// evaluate as an expression in the current function scope
match input {
@ -57,7 +64,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
caller_scope: String,
function: Function<F>,
inputs: Vec<Expression<F>>,
) -> Result<ConstrainedValue<F>, FunctionError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, FunctionError> {
let function_name = new_scope(scope.clone(), function.get_name());
// Make sure we are given the correct number of inputs
@ -119,7 +126,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
array_type: Type<F>,
array_dimensions: Vec<usize>,
input_value: Option<InputValue<F>>,
) -> Result<ConstrainedValue<F>, FunctionError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, FunctionError> {
let expected_length = array_dimensions[0];
let mut array_value = vec![];
@ -172,7 +179,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
name: String,
private: bool,
input_value: Option<InputValue<F>>,
) -> Result<ConstrainedValue<F>, FunctionError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, FunctionError> {
match _type {
Type::IntegerType(integer_type) => {
Ok(self.integer_from_parameter(cs, integer_type, name, private, input_value)?)
@ -197,7 +204,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
scope: String,
function: Function<F>,
inputs: Vec<Option<InputValue<F>>>,
) -> Result<ConstrainedValue<F>, FunctionError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, FunctionError> {
let function_name = new_scope(scope.clone(), function.get_name());
// Make sure we are given the correct number of inputs

View File

@ -4,7 +4,7 @@ use crate::{
errors::constraints::ImportError,
new_scope,
types::Program,
Import,
GroupType, Import,
};
use from_pest::FromPest;
@ -15,7 +15,13 @@ use snarkos_models::{
use std::env::current_dir;
use std::fs;
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<
NativeF: Field,
F: Field + PrimeField,
GType: GroupType<NativeF, F>,
CS: ConstraintSystem<F>,
> ConstrainedProgram<NativeF, F, GType, CS>
{
pub fn enforce_import(
&mut self,
cs: &mut CS,

View File

@ -4,7 +4,7 @@ use crate::{
constraints::{ConstrainedProgram, ConstrainedValue},
errors::IntegerError,
types::{InputValue, Integer},
IntegerType,
GroupType, IntegerType,
};
use snarkos_errors::gadgets::SynthesisError;
@ -73,15 +73,21 @@ impl<F: Field + PrimeField> CondSelectGadget<F> for Integer {
}
}
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
pub(crate) fn get_integer_constant(integer: Integer) -> ConstrainedValue<F> {
impl<
NativeF: Field,
F: Field + PrimeField,
GType: GroupType<NativeF, F>,
CS: ConstraintSystem<F>,
> ConstrainedProgram<NativeF, F, GType, CS>
{
pub(crate) fn get_integer_constant(integer: Integer) -> ConstrainedValue<NativeF, F, GType> {
ConstrainedValue::Integer(integer)
}
pub(crate) fn evaluate_integer_eq(
left: Integer,
right: Integer,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
Ok(ConstrainedValue::Boolean(Boolean::Constant(
match (left, right) {
(Integer::U8(left_u8), Integer::U8(right_u8)) => left_u8.eq(&right_u8),
@ -106,7 +112,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
name: String,
private: bool,
integer_value: Option<InputValue<F>>,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
// Check that the input value is the correct type
let integer_option = match integer_value {
Some(input) => {
@ -162,7 +168,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
left: Integer,
right: Integer,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
Ok(ConstrainedValue::Integer(match (left, right) {
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
Integer::U8(Self::enforce_u8_add(cs, left_u8, right_u8)?)
@ -188,7 +194,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
left: Integer,
right: Integer,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
Ok(ConstrainedValue::Integer(match (left, right) {
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
Integer::U8(Self::enforce_u8_sub(cs, left_u8, right_u8)?)
@ -214,7 +220,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
left: Integer,
right: Integer,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
Ok(ConstrainedValue::Integer(match (left, right) {
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
Integer::U8(Self::enforce_u8_mul(cs, left_u8, right_u8)?)
@ -240,7 +246,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
left: Integer,
right: Integer,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
Ok(ConstrainedValue::Integer(match (left, right) {
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
Integer::U8(Self::enforce_u8_div(cs, left_u8, right_u8)?)
@ -266,7 +272,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
left: Integer,
right: Integer,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
Ok(ConstrainedValue::Integer(match (left, right) {
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
Integer::U8(Self::enforce_u8_pow(cs, left_u8, right_u8)?)

View File

@ -4,6 +4,7 @@ use crate::{
constraints::{ConstrainedProgram, ConstrainedValue},
errors::IntegerError,
types::Integer,
GroupType,
};
use snarkos_errors::gadgets::SynthesisError;
@ -15,14 +16,20 @@ use snarkos_models::{
},
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<
NativeF: Field,
F: Field + PrimeField,
GType: GroupType<NativeF, F>,
CS: ConstraintSystem<F>,
> ConstrainedProgram<NativeF, F, GType, CS>
{
pub(crate) fn u128_from_input(
&mut self,
cs: &mut CS,
name: String,
private: bool,
integer_option: Option<usize>,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
// Type cast to u128 in rust.
// If this fails should we return our own error?
let u128_option = integer_option.map(|integer| integer as u128);

View File

@ -4,6 +4,7 @@ use crate::{
constraints::{ConstrainedProgram, ConstrainedValue},
errors::IntegerError,
types::Integer,
GroupType,
};
use snarkos_errors::gadgets::SynthesisError;
@ -15,14 +16,20 @@ use snarkos_models::{
},
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<
NativeF: Field,
F: Field + PrimeField,
GType: GroupType<NativeF, F>,
CS: ConstraintSystem<F>,
> ConstrainedProgram<NativeF, F, GType, CS>
{
pub(crate) fn u16_from_input(
&mut self,
cs: &mut CS,
name: String,
private: bool,
integer_option: Option<usize>,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
// Type cast to u16 in rust.
// If this fails should we return our own error?
let u16_option = integer_option.map(|integer| integer as u16);

View File

@ -4,6 +4,7 @@ use crate::{
constraints::{ConstrainedProgram, ConstrainedValue},
errors::IntegerError,
types::Integer,
GroupType,
};
use snarkos_errors::gadgets::SynthesisError;
@ -15,14 +16,20 @@ use snarkos_models::{
},
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<
NativeF: Field,
F: Field + PrimeField,
GType: GroupType<NativeF, F>,
CS: ConstraintSystem<F>,
> ConstrainedProgram<NativeF, F, GType, CS>
{
pub(crate) fn u32_from_input(
&mut self,
cs: &mut CS,
name: String,
private: bool,
integer_option: Option<usize>,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
// 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);

View File

@ -4,6 +4,7 @@ use crate::{
constraints::{ConstrainedProgram, ConstrainedValue},
errors::IntegerError,
types::Integer,
GroupType,
};
use snarkos_errors::gadgets::SynthesisError;
@ -15,14 +16,20 @@ use snarkos_models::{
},
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<
NativeF: Field,
F: Field + PrimeField,
GType: GroupType<NativeF, F>,
CS: ConstraintSystem<F>,
> ConstrainedProgram<NativeF, F, GType, CS>
{
pub(crate) fn u64_from_input(
&mut self,
cs: &mut CS,
name: String,
private: bool,
integer_option: Option<usize>,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
// Type cast to u64 in rust.
// If this fails should we return our own error?
let u64_option = integer_option.map(|integer| integer as u64);

View File

@ -4,6 +4,7 @@ use crate::{
constraints::{ConstrainedProgram, ConstrainedValue},
errors::IntegerError,
types::Integer,
GroupType,
};
use snarkos_errors::gadgets::SynthesisError;
@ -15,14 +16,20 @@ use snarkos_models::{
},
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<
NativeF: Field,
F: Field + PrimeField,
GType: GroupType<NativeF, F>,
CS: ConstraintSystem<F>,
> ConstrainedProgram<NativeF, F, GType, CS>
{
pub(crate) fn u8_from_input(
&mut self,
cs: &mut CS,
name: String,
private: bool,
integer_option: Option<usize>,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, IntegerError> {
// Type cast to u8 in rust.
// If this fails should we return our own error?
let u8_option = integer_option.map(|integer| integer as u8);

View File

@ -33,6 +33,7 @@ pub use statement::*;
use crate::{
errors::CompilerError,
types::{InputValue, Program},
GroupType,
};
use snarkos_models::{
@ -40,11 +41,16 @@ use snarkos_models::{
gadgets::r1cs::ConstraintSystem,
};
pub fn generate_constraints<F: Field + PrimeField, CS: ConstraintSystem<F>>(
pub fn generate_constraints<
NativeF: Field,
F: Field + PrimeField,
GType: GroupType<NativeF, F>,
CS: ConstraintSystem<F>,
>(
cs: &mut CS,
program: Program<F>,
parameters: Vec<Option<InputValue<F>>>,
) -> Result<ConstrainedValue<F>, CompilerError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, CompilerError> {
let mut resolved_program = ConstrainedProgram::new();
let program_name = program.get_name();
let main_function_name = new_scope(program_name.clone(), "main".into());

View File

@ -1,6 +1,7 @@
//! An in memory store to keep track of defined names when constraining a Leo program.
use crate::constraints::ConstrainedValue;
use crate::GroupType;
use snarkos_models::{
curves::{Field, PrimeField},
@ -8,8 +9,13 @@ use snarkos_models::{
};
use std::{collections::HashMap, marker::PhantomData};
pub struct ConstrainedProgram<F: Field + PrimeField, CS: ConstraintSystem<F>> {
pub identifiers: HashMap<String, ConstrainedValue<F>>,
pub struct ConstrainedProgram<
NativeF: Field,
F: Field + PrimeField,
GType: GroupType<NativeF, F>,
CS: ConstraintSystem<F>,
> {
pub identifiers: HashMap<String, ConstrainedValue<NativeF, F, GType>>,
pub _cs: PhantomData<CS>,
}
@ -17,7 +23,13 @@ pub fn new_scope(outer: String, inner: String) -> String {
format!("{}_{}", outer, inner)
}
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<
NativeF: Field,
F: Field + PrimeField,
GType: GroupType<NativeF, F>,
CS: ConstraintSystem<F>,
> ConstrainedProgram<NativeF, F, GType, CS>
{
pub fn new() -> Self {
Self {
identifiers: HashMap::new(),
@ -25,15 +37,18 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
}
}
pub(crate) fn store(&mut self, name: String, value: ConstrainedValue<F>) {
pub(crate) fn store(&mut self, name: String, value: ConstrainedValue<NativeF, F, GType>) {
self.identifiers.insert(name, value);
}
pub(crate) fn get(&self, name: &String) -> Option<&ConstrainedValue<F>> {
pub(crate) fn get(&self, name: &String) -> Option<&ConstrainedValue<NativeF, F, GType>> {
self.identifiers.get(name)
}
pub(crate) fn get_mut(&mut self, name: &String) -> Option<&mut ConstrainedValue<F>> {
pub(crate) fn get_mut(
&mut self,
name: &String,
) -> Option<&mut ConstrainedValue<NativeF, F, GType>> {
self.identifiers.get_mut(name)
}
}

View File

@ -8,7 +8,7 @@ use crate::{
Assignee, ConditionalNestedOrEnd, ConditionalStatement, Expression, Identifier, Integer,
RangeOrExpression, Statement, Type,
},
Variable,
GroupType, Variable,
};
use snarkos_models::{
@ -16,7 +16,13 @@ use snarkos_models::{
gadgets::{r1cs::ConstraintSystem, utilities::boolean::Boolean, utilities::uint32::UInt32},
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<
NativeF: Field,
F: Field + PrimeField,
GType: GroupType<NativeF, F>,
CS: ConstraintSystem<F>,
> ConstrainedProgram<NativeF, F, GType, CS>
{
fn resolve_assignee(&mut self, scope: String, assignee: Assignee<F>) -> String {
match assignee {
Assignee::Identifier(name) => new_scope(scope, name.to_string()),
@ -30,7 +36,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
fn get_mutable_assignee(
&mut self,
name: String,
) -> Result<&mut ConstrainedValue<F>, StatementError> {
) -> Result<&mut ConstrainedValue<NativeF, F, GType>, StatementError> {
// Check that assignee exists and is mutable
Ok(match self.get_mut(&name) {
Some(value) => match value {
@ -48,7 +54,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
function_scope: String,
name: String,
range_or_expression: RangeOrExpression<F>,
new_value: ConstrainedValue<F>,
new_value: ConstrainedValue<NativeF, F, GType>,
) -> Result<(), StatementError> {
// Resolve index so we know if we are assigning to a single value or a range of values
match range_or_expression {
@ -92,7 +98,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
&mut self,
circuit_name: String,
object_name: Identifier<F>,
new_value: ConstrainedValue<F>,
new_value: ConstrainedValue<NativeF, F, GType>,
) -> Result<(), StatementError> {
match self.get_mutable_assignee(circuit_name)? {
ConstrainedValue::CircuitExpression(_variable, members) => {
@ -171,7 +177,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
&mut self,
function_scope: String,
variable: Variable<F>,
mut value: ConstrainedValue<F>,
mut value: ConstrainedValue<NativeF, F, GType>,
) -> Result<(), StatementError> {
// Store with given mutability
if variable.mutable {
@ -258,7 +264,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
function_scope: String,
expressions: Vec<Expression<F>>,
return_types: Vec<Type<F>>,
) -> Result<ConstrainedValue<F>, StatementError> {
) -> Result<ConstrainedValue<NativeF, F, GType>, StatementError> {
// Make sure we return the correct number of values
if return_types.len() != expressions.len() {
return Err(StatementError::InvalidNumberOfReturns(
@ -291,7 +297,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
function_scope: String,
statements: Vec<Statement<F>>,
return_types: Vec<Type<F>>,
) -> Result<Option<ConstrainedValue<F>>, StatementError> {
) -> Result<Option<ConstrainedValue<NativeF, F, GType>>, StatementError> {
let mut res = None;
// Evaluate statements and possibly return early
for statement in statements.iter() {
@ -317,7 +323,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
function_scope: String,
statement: ConditionalStatement<F>,
return_types: Vec<Type<F>>,
) -> Result<Option<ConstrainedValue<F>>, StatementError> {
) -> Result<Option<ConstrainedValue<NativeF, F, GType>>, StatementError> {
let expected_types = vec![Type::Boolean];
let condition = match self.enforce_expression(
cs,
@ -372,7 +378,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
stop: Integer,
statements: Vec<Statement<F>>,
return_types: Vec<Type<F>>,
) -> Result<Option<ConstrainedValue<F>>, StatementError> {
) -> Result<Option<ConstrainedValue<NativeF, F, GType>>, StatementError> {
let mut res = None;
for i in start.to_usize()..stop.to_usize() {
@ -403,8 +409,8 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
fn enforce_assert_eq_statement(
&mut self,
cs: &mut CS,
left: ConstrainedValue<F>,
right: ConstrainedValue<F>,
left: ConstrainedValue<NativeF, F, GType>,
right: ConstrainedValue<NativeF, F, GType>,
) -> Result<(), StatementError> {
Ok(match (left, right) {
(ConstrainedValue::Boolean(bool_1), ConstrainedValue::Boolean(bool_2)) => {
@ -442,7 +448,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
function_scope: String,
statement: Statement<F>,
return_types: Vec<Type<F>>,
) -> Result<Option<ConstrainedValue<F>>, StatementError> {
) -> Result<Option<ConstrainedValue<NativeF, F, GType>>, StatementError> {
let mut res = None;
match statement {
Statement::Return(expressions) => {

View File

@ -3,6 +3,7 @@
use crate::{
errors::ValueError,
types::{Circuit, FieldElement, Function, Identifier, Integer, IntegerType, Type},
GroupType,
};
use snarkos_models::{
@ -13,37 +14,45 @@ use snarkos_models::{
},
};
use std::fmt;
use std::marker::PhantomData;
#[derive(Clone, PartialEq, Eq)]
pub struct ConstrainedCircuitMember<F: Field + PrimeField>(
pub Identifier<F>,
pub ConstrainedValue<F>,
);
pub struct ConstrainedCircuitMember<
NativeF: Field,
F: Field + PrimeField,
GType: GroupType<NativeF, F>,
>(pub Identifier<F>, pub ConstrainedValue<NativeF, F, GType>);
#[derive(Clone, PartialEq, Eq)]
pub enum ConstrainedValue<F: Field + PrimeField> {
pub enum ConstrainedValue<NativeF: Field, F: Field + PrimeField, GType: GroupType<NativeF, F>> {
Integer(Integer),
FieldElement(FieldElement<F>),
Group(String),
Group(GType),
Boolean(Boolean),
Array(Vec<ConstrainedValue<F>>),
Array(Vec<ConstrainedValue<NativeF, F, GType>>),
CircuitDefinition(Circuit<F>),
CircuitExpression(Identifier<F>, Vec<ConstrainedCircuitMember<F>>),
CircuitExpression(
Identifier<F>,
Vec<ConstrainedCircuitMember<NativeF, F, GType>>,
),
Function(Option<Identifier<F>>, Function<F>), // (optional circuit identifier, function definition)
Return(Vec<ConstrainedValue<F>>),
Return(Vec<ConstrainedValue<NativeF, F, GType>>),
Mutable(Box<ConstrainedValue<F>>),
Static(Box<ConstrainedValue<F>>),
Mutable(Box<ConstrainedValue<NativeF, F, GType>>),
Static(Box<ConstrainedValue<NativeF, F, GType>>),
Unresolved(String),
Void(PhantomData<NativeF>),
}
impl<F: Field + PrimeField> ConstrainedValue<F> {
impl<NativeF: Field, F: Field + PrimeField, GType: GroupType<NativeF, F>>
ConstrainedValue<NativeF, F, GType>
{
pub(crate) fn from_other(
value: String,
other: &ConstrainedValue<F>,
other: &ConstrainedValue<NativeF, F, GType>,
) -> Result<Self, ValueError> {
let other_type = other.to_type();
@ -62,7 +71,7 @@ impl<F: Field + PrimeField> ConstrainedValue<F> {
Type::FieldElement => Ok(ConstrainedValue::FieldElement(FieldElement::Constant(
F::from_str(&value).unwrap_or_default(),
))),
Type::Group => Ok(ConstrainedValue::Group(value)),
Type::Group => Ok(ConstrainedValue::Group(GType::constant(value)?)),
Type::Boolean => Ok(ConstrainedValue::Boolean(Boolean::Constant(
value.parse::<bool>()?,
))),
@ -98,12 +107,14 @@ impl<F: Field + PrimeField> ConstrainedValue<F> {
}
}
impl<F: Field + PrimeField> fmt::Display for ConstrainedValue<F> {
impl<NativeF: Field, F: Field + PrimeField, GType: GroupType<NativeF, F>> fmt::Display
for ConstrainedValue<NativeF, F, GType>
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ConstrainedValue::Integer(ref value) => write!(f, "{}", value),
ConstrainedValue::FieldElement(ref value) => write!(f, "{}", value),
ConstrainedValue::Group(ref value) => write!(f, "{}", value),
ConstrainedValue::Group(ref value) => write!(f, "{:?}", value),
ConstrainedValue::Boolean(ref value) => write!(f, "{}", value.get_value().unwrap()),
ConstrainedValue::Array(ref array) => {
write!(f, "[")?;
@ -144,11 +155,14 @@ impl<F: Field + PrimeField> fmt::Display for ConstrainedValue<F> {
ConstrainedValue::Mutable(ref value) => write!(f, "mut {}", value),
ConstrainedValue::Static(ref value) => write!(f, "static {}", value),
ConstrainedValue::Unresolved(ref value) => write!(f, "unresolved {}", value),
ConstrainedValue::Void(_) => unreachable!(),
}
}
}
impl<F: Field + PrimeField> fmt::Debug for ConstrainedValue<F> {
impl<NativeF: Field, F: Field + PrimeField, GType: GroupType<NativeF, F>> fmt::Debug
for ConstrainedValue<NativeF, F, GType>
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self)
}

View File

@ -1,4 +1,6 @@
use crate::errors::{BooleanError, FieldElementError, FunctionError, IntegerError, ValueError};
use crate::errors::{
BooleanError, FieldElementError, FunctionError, GroupError, IntegerError, ValueError,
};
use snarkos_errors::gadgets::SynthesisError;
use std::num::ParseIntError;
@ -28,6 +30,9 @@ pub enum ExpressionError {
#[error("{}", _0)]
FieldElementError(FieldElementError),
#[error("{}", _0)]
GroupError(#[from] GroupError),
#[error("{}", _0)]
BooleanError(BooleanError),

View File

@ -1,4 +1,4 @@
use crate::errors::IntegerError;
use crate::errors::{GroupError, IntegerError};
use std::num::ParseIntError;
use std::str::ParseBoolError;
@ -27,6 +27,9 @@ pub enum ValueError {
/// Unexpected type
#[error("{}", _0)]
TypeError(String),
#[error("{}", _0)]
GroupError(#[from] GroupError),
}
impl From<ParseIntError> for ValueError {

View File

@ -1,27 +1,23 @@
use crate::errors::GroupError;
use crate::GroupType;
use snarkos_curves::edwards_bls12::{EdwardsParameters, Fq};
use snarkos_curves::templates::twisted_edwards_extended::GroupAffine;
use snarkos_gadgets::curves::edwards_bls12::FqGadget;
use snarkos_gadgets::curves::templates::twisted_edwards::AffineGadget;
use snarkos_curves::edwards_bls12::{EdwardsAffine, EdwardsParameters, Fq};
use snarkos_gadgets::curves::edwards_bls12::EdwardsBlsGadget;
use snarkos_models::curves::ModelParameters;
use std::str::FromStr;
#[derive(Clone, Debug)]
pub enum EdwardsGroupType {
Constant(GroupAffine<EdwardsParameters>),
Allocated(AffineGadget<EdwardsParameters, Fq, FqGadget>),
Constant(EdwardsAffine),
Allocated(EdwardsBlsGadget),
}
impl GroupType<<EdwardsParameters as ModelParameters>::BaseField, Fq> for EdwardsGroupType {
fn constant(x: String, y: String) -> Result<Self, GroupError> {
let x = <EdwardsParameters as ModelParameters>::BaseField::from_str(&x)
.map_err(|_| GroupError::InvalidGroup(x))?;
let y = <EdwardsParameters as ModelParameters>::BaseField::from_str(&y)
.map_err(|_| GroupError::InvalidGroup(y))?;
fn constant(string: String) -> Result<Self, GroupError> {
let result =
EdwardsAffine::from_str(&string).map_err(|_| GroupError::InvalidGroup(string))?;
Ok(EdwardsGroupType::Constant(GroupAffine::new(x, y)))
Ok(EdwardsGroupType::Constant(result))
}
// fn add<CS: ConstraintSystem<Fq>>(&self, cs: CS, other: &Self) -> Result<Self, GroupElementError> {

View File

@ -5,5 +5,5 @@ use std::fmt::Debug;
pub mod edwards_bls12;
pub trait GroupType<NativeF: Field, F: Field>: Sized + Clone + Debug {
fn constant(x: String, y: String) -> Result<Self, GroupError>;
fn constant(string: String) -> Result<Self, GroupError>;
}

View File

@ -1,21 +1,25 @@
use crate::{compile_program, get_error, get_output};
use leo_compiler::errors::IntegerError;
use leo_compiler::group::edwards_bls12::EdwardsGroupType;
use leo_compiler::{
compiler::Compiler,
errors::{CompilerError, FunctionError},
ConstrainedValue, InputValue, Integer,
};
use snarkos_curves::bls12_377::Fr;
use snarkos_curves::edwards_bls12::{EdwardsParameters, Fq};
use snarkos_models::curves::ModelParameters;
use snarkos_models::gadgets::utilities::uint32::UInt32;
const DIRECTORY_NAME: &str = "tests/array/";
// [1, 1, 1]
fn output_ones(program: Compiler<Fr>) {
fn output_ones(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
let output = get_output(program);
assert_eq!(
ConstrainedValue::<Fr>::Return(vec![ConstrainedValue::Array(
ConstrainedValue::<Fq>::Return(vec![ConstrainedValue::Array(
vec![ConstrainedValue::Integer(Integer::U32(UInt32::constant(1u32))); 3]
)]),
output
@ -24,10 +28,12 @@ fn output_ones(program: Compiler<Fr>) {
// [[0, 0, 0],
// [0, 0, 0]]
fn output_multi(program: Compiler<Fr>) {
fn output_multi(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
let output = get_output(program);
assert_eq!(
ConstrainedValue::<Fr>::Return(vec![ConstrainedValue::Array(vec![
ConstrainedValue::<Fq>::Return(vec![ConstrainedValue::Array(vec![
ConstrainedValue::Array(
vec![ConstrainedValue::Integer(Integer::U32(UInt32::constant(0u32))); 3]
);
@ -37,14 +43,18 @@ fn output_multi(program: Compiler<Fr>) {
)
}
fn fail_array(program: Compiler<Fr>) {
fn fail_array(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::InvalidArray(_string)) => {}
error => panic!("Expected invalid array error, got {}", error),
}
}
fn fail_synthesis(program: Compiler<Fr>) {
fn fail_synthesis(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::IntegerError(
IntegerError::SynthesisError(_string),

View File

@ -1,33 +1,41 @@
use crate::{compile_program, get_error, get_output};
use leo_compiler::errors::{BooleanError, ExpressionError};
use leo_compiler::group::edwards_bls12::EdwardsGroupType;
use leo_compiler::{
compiler::Compiler,
errors::{CompilerError, FunctionError, StatementError},
ConstrainedValue, InputValue,
};
use snarkos_curves::bls12_377::Fr;
use snarkos_curves::edwards_bls12::{EdwardsParameters, Fq};
use snarkos_models::curves::ModelParameters;
use snarkos_models::gadgets::utilities::boolean::Boolean;
const DIRECTORY_NAME: &str = "tests/boolean/";
fn output_true(program: Compiler<Fr>) {
fn output_true(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
let output = get_output(program);
assert_eq!(
ConstrainedValue::<Fr>::Return(vec![ConstrainedValue::Boolean(Boolean::Constant(true))]),
ConstrainedValue::<Fq>::Return(vec![ConstrainedValue::Boolean(Boolean::Constant(true))]),
output
);
}
fn output_false(program: Compiler<Fr>) {
fn output_false(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
let output = get_output(program);
assert_eq!(
ConstrainedValue::<Fr>::Return(vec![ConstrainedValue::Boolean(Boolean::Constant(false))]),
ConstrainedValue::<Fq>::Return(vec![ConstrainedValue::Boolean(Boolean::Constant(false))]),
output
);
}
fn fail_evaluate(program: Compiler<Fr>) {
fn fail_evaluate(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::ExpressionError(ExpressionError::BooleanError(
@ -38,7 +46,9 @@ fn fail_evaluate(program: Compiler<Fr>) {
}
}
fn fail_enforce(program: Compiler<Fr>) {
fn fail_enforce(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::ExpressionError(ExpressionError::BooleanError(
@ -49,7 +59,9 @@ fn fail_enforce(program: Compiler<Fr>) {
}
}
fn fail_boolean(program: Compiler<Fr>) {
fn fail_boolean(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::BooleanError(
BooleanError::InvalidBoolean(_string),
@ -58,7 +70,9 @@ fn fail_boolean(program: Compiler<Fr>) {
}
}
fn fail_synthesis(program: Compiler<Fr>) {
fn fail_synthesis(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::BooleanError(
BooleanError::SynthesisError(_string),

View File

@ -6,22 +6,26 @@ use crate::{
// group_element::output_zero
};
use leo_compiler::group::edwards_bls12::EdwardsGroupType;
use leo_compiler::{
compiler::Compiler,
errors::{CompilerError, ExpressionError, FunctionError, StatementError},
ConstrainedCircuitMember, ConstrainedValue, Expression, Function, Identifier, Integer,
Statement, Type,
};
use snarkos_curves::bls12_377::Fr;
use snarkos_curves::edwards_bls12::{EdwardsParameters, Fq};
use snarkos_models::curves::ModelParameters;
use snarkos_models::gadgets::utilities::uint32::UInt32;
const DIRECTORY_NAME: &str = "tests/circuit/";
// Circ { x: 1u32 }
fn output_circuit(program: Compiler<Fr>) {
fn output_circuit(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
let output = get_output(program);
assert_eq!(
ConstrainedValue::<Fr>::Return(vec![ConstrainedValue::CircuitExpression(
ConstrainedValue::<Fq>::Return(vec![ConstrainedValue::CircuitExpression(
Identifier::new("Circ".into()),
vec![ConstrainedCircuitMember(
Identifier::new("x".into()),
@ -32,7 +36,9 @@ fn output_circuit(program: Compiler<Fr>) {
);
}
fn fail_expected_member(program: Compiler<Fr>) {
fn fail_expected_member(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::ExpressionError(ExpressionError::ExpectedCircuitMember(_string)),
@ -41,7 +47,9 @@ fn fail_expected_member(program: Compiler<Fr>) {
}
}
fn fail_undefined_member(program: Compiler<Fr>) {
fn fail_undefined_member(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::ExpressionError(ExpressionError::UndefinedMemberAccess(_, _)),
@ -151,7 +159,7 @@ fn test_self() {
// }
// }
assert_eq!(
ConstrainedValue::<Fr>::Return(vec![ConstrainedValue::CircuitExpression(
ConstrainedValue::<Fq>::Return(vec![ConstrainedValue::CircuitExpression(
Identifier::new("Circ".into()),
vec![ConstrainedCircuitMember(
Identifier::new("new".into()),

View File

@ -1,37 +1,44 @@
use crate::{compile_program, get_error, get_output};
use leo_compiler::errors::FieldElementError;
use leo_compiler::group::edwards_bls12::EdwardsGroupType;
use leo_compiler::{
compiler::Compiler,
errors::{CompilerError, FunctionError},
ConstrainedValue, FieldElement, InputValue,
};
use snarkos_curves::bls12_377::Fr;
use snarkos_models::curves::Field;
use snarkos_curves::edwards_bls12::{EdwardsParameters, Fq};
use snarkos_models::curves::{Field, ModelParameters};
const DIRECTORY_NAME: &str = "tests/field_element/";
fn output_zero(program: Compiler<Fr>) {
fn output_zero(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
let output = get_output(program);
assert_eq!(
ConstrainedValue::<Fr>::Return(vec![ConstrainedValue::FieldElement(
ConstrainedValue::<Fq>::Return(vec![ConstrainedValue::FieldElement(
FieldElement::Constant(Fr::zero())
)]),
output
);
}
fn output_one(program: Compiler<Fr>) {
fn output_one(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
let output = get_output(program);
assert_eq!(
ConstrainedValue::<Fr>::Return(vec![ConstrainedValue::FieldElement(
ConstrainedValue::<Fq>::Return(vec![ConstrainedValue::FieldElement(
FieldElement::Constant(Fr::one())
)]),
output
);
}
fn fail_field(program: Compiler<Fr>) {
fn fail_field(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::FieldElementError(
FieldElementError::InvalidField(_string),
@ -40,7 +47,9 @@ fn fail_field(program: Compiler<Fr>) {
}
}
fn fail_synthesis(program: Compiler<Fr>) {
fn fail_synthesis(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::FieldElementError(
FieldElementError::SynthesisError(_string),

View File

@ -1,25 +1,31 @@
use crate::{compile_program, get_error, get_output, integer::u32::output_one};
use leo_compiler::group::edwards_bls12::EdwardsGroupType;
use leo_compiler::{
compiler::Compiler,
errors::{CompilerError, ExpressionError, FunctionError, StatementError},
ConstrainedValue,
};
use snarkos_curves::bls12_377::Fr;
use snarkos_curves::edwards_bls12::{EdwardsParameters, Fq};
use snarkos_models::curves::ModelParameters;
use snarkos_models::gadgets::utilities::boolean::Boolean;
const DIRECTORY_NAME: &str = "tests/function/";
pub(crate) fn output_empty(program: Compiler<Fr>) {
pub(crate) fn output_empty(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
let output = get_output(program);
assert_eq!(ConstrainedValue::<Fr>::Return(vec![]), output);
assert_eq!(ConstrainedValue::<Fq>::Return(vec![]), output);
}
// (true, false)
pub(crate) fn output_multiple(program: Compiler<Fr>) {
pub(crate) fn output_multiple(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
let output = get_output(program);
assert_eq!(
ConstrainedValue::<Fr>::Return(vec![
ConstrainedValue::<Fq>::Return(vec![
ConstrainedValue::Boolean(Boolean::Constant(true)),
ConstrainedValue::Boolean(Boolean::Constant(false))
]),
@ -27,7 +33,9 @@ pub(crate) fn output_multiple(program: Compiler<Fr>) {
)
}
fn fail_undefined_identifier(program: Compiler<Fr>) {
fn fail_undefined_identifier(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(
StatementError::ExpressionError(ExpressionError::UndefinedIdentifier(_)),

View File

@ -3,42 +3,52 @@ use crate::{compile_program, get_error, get_output};
use leo_compiler::{compiler::Compiler, types::Integer, ConstrainedValue, InputValue};
use leo_compiler::errors::{CompilerError, FunctionError, IntegerError};
use snarkos_curves::bls12_377::Fr;
use leo_compiler::group::edwards_bls12::EdwardsGroupType;
use snarkos_curves::edwards_bls12::{EdwardsParameters, Fq};
use snarkos_models::curves::ModelParameters;
use snarkos_models::gadgets::utilities::uint32::UInt32;
const DIRECTORY_NAME: &str = "tests/integer/u32/";
pub(crate) fn output_zero(program: Compiler<Fr>) {
pub(crate) fn output_zero(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
let output = get_output(program);
assert_eq!(
ConstrainedValue::<Fr>::Return(vec![ConstrainedValue::Integer(Integer::U32(
ConstrainedValue::<Fq>::Return(vec![ConstrainedValue::Integer(Integer::U32(
UInt32::constant(0u32)
))]),
output
)
}
pub(crate) fn output_one(program: Compiler<Fr>) {
pub(crate) fn output_one(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
let output = get_output(program);
assert_eq!(
ConstrainedValue::<Fr>::Return(vec![ConstrainedValue::Integer(Integer::U32(
ConstrainedValue::<Fq>::Return(vec![ConstrainedValue::Integer(Integer::U32(
UInt32::constant(1u32)
))]),
output
)
}
fn output_two(program: Compiler<Fr>) {
fn output_two(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
let output = get_output(program);
assert_eq!(
ConstrainedValue::<Fr>::Return(vec![ConstrainedValue::Integer(Integer::U32(
ConstrainedValue::<Fq>::Return(vec![ConstrainedValue::Integer(Integer::U32(
UInt32::constant(2u32)
))]),
output
)
}
fn fail_integer(program: Compiler<Fr>) {
fn fail_integer(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::IntegerError(
IntegerError::InvalidInteger(_string),
@ -47,7 +57,9 @@ fn fail_integer(program: Compiler<Fr>) {
}
}
fn fail_synthesis(program: Compiler<Fr>) {
fn fail_synthesis(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
match get_error(program) {
CompilerError::FunctionError(FunctionError::IntegerError(
IntegerError::SynthesisError(_string),

View File

@ -11,26 +11,35 @@ pub mod statement;
use leo_compiler::{compiler::Compiler, errors::CompilerError, ConstrainedValue};
use snarkos_curves::bls12_377::Fr;
use leo_compiler::group::edwards_bls12::EdwardsGroupType;
use snarkos_curves::edwards_bls12::{EdwardsParameters, Fq};
use snarkos_models::curves::ModelParameters;
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
use std::env::current_dir;
pub(crate) fn get_output(program: Compiler<Fr>) -> ConstrainedValue<Fr> {
let mut cs = TestConstraintSystem::<Fr>::new();
pub(crate) fn get_output(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) -> ConstrainedValue<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType> {
let mut cs = TestConstraintSystem::<Fq>::new();
let output = program.compile_constraints(&mut cs).unwrap();
assert!(cs.is_satisfied());
output
}
pub(crate) fn get_error(program: Compiler<Fr>) -> CompilerError {
let mut cs = TestConstraintSystem::<Fr>::new();
pub(crate) fn get_error(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) -> CompilerError {
let mut cs = TestConstraintSystem::<Fq>::new();
program.compile_constraints(&mut cs).unwrap_err()
}
pub(crate) fn compile_program(
directory_name: &str,
file_name: &str,
) -> Result<Compiler<Fr>, CompilerError> {
) -> Result<
Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
CompilerError,
> {
let path = current_dir().map_err(|error| CompilerError::DirectoryError(error))?;
// Sanitize the package path to the test directory
@ -47,5 +56,5 @@ pub(crate) fn compile_program(
println!("Compiling file - {:?}", main_file_path);
// Compile from the main file path
Compiler::<Fr>::init(file_name.to_string(), main_file_path)
Compiler::<Fq>::init(file_name.to_string(), main_file_path)
}

View File

@ -1,31 +1,37 @@
use crate::compile_program;
use leo_compiler::group::edwards_bls12::EdwardsGroupType;
use leo_compiler::{
compiler::Compiler,
errors::{CompilerError, FunctionError, StatementError},
types::{InputValue, Integer},
ConstrainedValue,
};
use snarkos_curves::bls12_377::Fr;
use snarkos_curves::edwards_bls12::{EdwardsParameters, Fq};
use snarkos_models::curves::ModelParameters;
use snarkos_models::gadgets::{r1cs::TestConstraintSystem, utilities::uint32::UInt32};
const DIRECTORY_NAME: &str = "tests/mutability/";
fn mut_success(program: Compiler<Fr>) {
let mut cs = TestConstraintSystem::<Fr>::new();
fn mut_success(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
let mut cs = TestConstraintSystem::<Fq>::new();
let output = program.compile_constraints(&mut cs).unwrap();
assert!(cs.is_satisfied());
assert_eq!(
ConstrainedValue::<Fr>::Return(vec![ConstrainedValue::Integer(Integer::U32(
ConstrainedValue::<Fq>::Return(vec![ConstrainedValue::Integer(Integer::U32(
UInt32::constant(0)
))]),
output
);
}
fn mut_fail(program: Compiler<Fr>) {
let mut cs = TestConstraintSystem::<Fr>::new();
fn mut_fail(
program: Compiler<<EdwardsParameters as ModelParameters>::BaseField, Fq, EdwardsGroupType>,
) {
let mut cs = TestConstraintSystem::<Fq>::new();
let err = program.compile_constraints(&mut cs).unwrap_err();
// It would be ideal if assert_eq!(Error1, Error2) were possible but unfortunately it is not due to

View File

@ -3,7 +3,7 @@ use crate::{
integer::u32::{output_one, output_zero},
};
use leo_compiler::InputValue;
use snarkos_curves::bls12_377::Fr;
use snarkos_curves::edwards_bls12::{EdwardsParameters, Fq};
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
const DIRECTORY_NAME: &str = "tests/statement/";
@ -37,7 +37,7 @@ fn test_assertion_basic() {
let program = compile_program(DIRECTORY_NAME, "assertion_basic.leo").unwrap();
let mut program_input_true = program.clone();
let mut cs_satisfied = TestConstraintSystem::<Fr>::new();
let mut cs_satisfied = TestConstraintSystem::<Fq>::new();
program_input_true.set_inputs(vec![Some(InputValue::Boolean(true))]);
let _output = program_input_true
@ -47,7 +47,7 @@ fn test_assertion_basic() {
assert!(cs_satisfied.is_satisfied());
let mut program_input_false = program.clone();
let mut cs_unsatisfied = TestConstraintSystem::<Fr>::new();
let mut cs_unsatisfied = TestConstraintSystem::<Fq>::new();
program_input_false.set_inputs(vec![Some(InputValue::Boolean(false))]);
let _output = program_input_false