mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-09-11 05:45:30 +03:00
add groupType to compiler
This commit is contained in:
parent
1232481219
commit
31ec24670c
@ -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
|
||||
|
||||
|
@ -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)))
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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)?)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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) => {
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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),
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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> {
|
||||
|
@ -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>;
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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()),
|
||||
|
@ -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),
|
||||
|
@ -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(_)),
|
||||
|
@ -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),
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user