wip groups

This commit is contained in:
collin 2020-05-12 19:07:15 -07:00
parent ab4a9c6058
commit 97272fa9d7
24 changed files with 466 additions and 395 deletions

View File

@ -11,29 +11,40 @@ use snarkos_models::{
curves::{Field, PrimeField},
gadgets::r1cs::{ConstraintSynthesizer, ConstraintSystem},
};
use snarkos_models::curves::Group;
use std::{
fs,
marker::PhantomData,
time::{Duration, Instant},
};
use std::str::FromStr;
use snarkos_curves::edwards_bls12::EdwardsProjective;
#[derive(Clone)]
pub struct Benchmark<F: Field + PrimeField> {
pub struct Benchmark<F: Field + PrimeField, G: Group> {
program: Program<F>,
parameters: Vec<Option<InputValue<F>>>,
_group: PhantomData<G>,
_engine: PhantomData<F>,
}
impl<F: Field + PrimeField> Benchmark<F> {
impl<F: Field + PrimeField, G: Group> Benchmark<F, G> {
pub fn new() -> Self {
Self {
program: Program::new(),
parameters: vec![],
_group: PhantomData,
_engine: PhantomData,
}
}
pub fn evaluate_program(&mut self) -> Result<(), CompilerError> {
let scalar = G::ScalarField::from_str("2325446546544").unwrap_or_default();
println!("{}", scalar);
let other = G::default().mul(&G::ScalarField::one());
println!("{}", other);
assert_eq!(G::default(), G::default().double());
// Read in file as string
let unparsed_file = fs::read_to_string("simple.leo").expect("cannot read file");
@ -54,7 +65,7 @@ impl<F: Field + PrimeField> Benchmark<F> {
}
}
impl<F: Field + PrimeField> ConstraintSynthesizer<F> for Benchmark<F> {
impl<F: Field + PrimeField, G: Group> ConstraintSynthesizer<F> for Benchmark<F, G> {
fn generate_constraints<CS: ConstraintSystem<F>>(
self,
cs: &mut CS,
@ -79,7 +90,7 @@ fn main() {
let start = Instant::now();
// Load and compile program
let mut program = Benchmark::<Fr>::new();
let mut program = Benchmark::<Fr, EdwardsProjective>::new();
program.evaluate_program().unwrap();
// Generate proof parameters

View File

@ -159,6 +159,13 @@ pub struct FieldType<'ast> {
pub span: Span<'ast>,
}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_group))]
pub struct GroupType<'ast> {
#[pest_ast(outer())]
pub span: Span<'ast>,
}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::type_bool))]
pub struct BooleanType<'ast> {
@ -179,6 +186,7 @@ pub struct StructType<'ast> {
pub enum BasicType<'ast> {
Integer(IntegerType),
Field(FieldType<'ast>),
Group(GroupType<'ast>),
Boolean(BooleanType<'ast>),
}
@ -251,7 +259,6 @@ impl<'ast> fmt::Display for Integer<'ast> {
#[pest_ast(rule(Rule::value_field))]
pub struct Field<'ast> {
pub number: Number<'ast>,
pub _type: FieldType<'ast>,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
@ -262,6 +269,20 @@ impl<'ast> fmt::Display for Field<'ast> {
}
}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::value_group))]
pub struct Group<'ast> {
pub number: Number<'ast>,
#[pest_ast(outer())]
pub span: Span<'ast>,
}
impl<'ast> fmt::Display for Group<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.number)
}
}
#[derive(Clone, Debug, FromPest, PartialEq)]
#[pest_ast(rule(Rule::value_boolean))]
pub struct Boolean<'ast> {
@ -282,6 +303,7 @@ impl<'ast> fmt::Display for Boolean<'ast> {
pub enum Value<'ast> {
Integer(Integer<'ast>),
Field(Field<'ast>),
Group(Group<'ast>),
Boolean(Boolean<'ast>),
}
@ -290,6 +312,7 @@ impl<'ast> Value<'ast> {
match self {
Value::Integer(value) => &value.span,
Value::Field(value) => &value.span,
Value::Group(value) => &value.span,
Value::Boolean(value) => &value.span,
}
}
@ -300,6 +323,7 @@ impl<'ast> fmt::Display for Value<'ast> {
match *self {
Value::Integer(ref value) => write!(f, "{}", value),
Value::Field(ref value) => write!(f, "{}", value),
Value::Group(ref value) => write!(f, "{}", value),
Value::Boolean(ref value) => write!(f, "{}", value),
}
}

View File

@ -9,7 +9,7 @@ use crate::{
use snarkos_errors::gadgets::SynthesisError;
use snarkos_models::{
curves::{Field, PrimeField},
curves::{Group, Field, PrimeField},
gadgets::r1cs::{ConstraintSynthesizer, ConstraintSystem},
};
@ -18,16 +18,16 @@ use sha2::{Digest, Sha256};
use std::{fs, marker::PhantomData, path::PathBuf};
#[derive(Clone)]
pub struct Compiler<F: Field + PrimeField> {
pub struct Compiler<G: Group, F: Field + PrimeField> {
package_name: String,
main_file_path: PathBuf,
program: Program<F>,
program_inputs: Vec<Option<InputValue<F>>>,
output: Option<ConstrainedValue<F>>,
program: Program<G, F>,
program_inputs: Vec<Option<InputValue<G, F>>>,
output: Option<ConstrainedValue<G, F>>,
_engine: PhantomData<F>,
}
impl<F: Field + PrimeField> Compiler<F> {
impl<G: Group, F: Field + PrimeField> Compiler<G, F> {
pub fn init(package_name: String, main_file_path: PathBuf) -> Self {
Self {
package_name,
@ -82,7 +82,7 @@ impl<F: Field + PrimeField> Compiler<F> {
// Build program from abstract syntax tree
let package_name = self.package_name.clone();
self.program = Program::<F>::from(syntax_tree, package_name);
self.program = Program::<G, F>::from(syntax_tree, package_name);
self.program_inputs = vec![None; self.program.num_parameters];
log::debug!("Compilation complete\n{:#?}", self.program);
@ -91,7 +91,7 @@ impl<F: Field + PrimeField> Compiler<F> {
}
}
impl<F: Field + PrimeField> ConstraintSynthesizer<F> for Compiler<F> {
impl<G: Group, F: Field + PrimeField> ConstraintSynthesizer<F> for Compiler<G, F> {
fn generate_constraints<CS: ConstraintSystem<F>>(
self,
cs: &mut CS,

View File

@ -8,20 +8,20 @@ use crate::{
use snarkos_errors::gadgets::SynthesisError;
use snarkos_models::{
curves::{Field, PrimeField},
curves::{Group, Field, PrimeField},
gadgets::{
r1cs::ConstraintSystem,
utilities::{alloc::AllocGadget, boolean::Boolean, eq::EqGadget},
},
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<G: Group, F: Field + PrimeField, CS: ConstraintSystem<G>> ConstrainedProgram<G, F, CS> {
pub(crate) fn bool_from_input(
&mut self,
cs: &mut CS,
input_model: InputModel<F>,
input_value: Option<InputValue<F>>,
) -> Result<ConstrainedValue<F>, BooleanError> {
input_model: InputModel<G, F>,
input_value: Option<InputValue<G, F>>,
) -> Result<ConstrainedValue<G, F>, BooleanError> {
// Check that the input value is the correct type
let bool_value = match input_value {
Some(input) => {
@ -49,13 +49,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<G, F> {
ConstrainedValue::Boolean(bool)
}
pub(crate) fn evaluate_not(
value: ConstrainedValue<F>,
) -> Result<ConstrainedValue<F>, BooleanError> {
value: ConstrainedValue<G, F>,
) -> Result<ConstrainedValue<G, F>, BooleanError> {
match value {
ConstrainedValue::Boolean(boolean) => Ok(ConstrainedValue::Boolean(boolean.not())),
value => Err(BooleanError::CannotEvaluate(format!("!{}", value))),
@ -65,9 +65,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<G, F>,
right: ConstrainedValue<G, F>,
) -> Result<ConstrainedValue<G, F>, BooleanError> {
match (left, right) {
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => Ok(
ConstrainedValue::Boolean(Boolean::or(cs, &left_bool, &right_bool)?),
@ -82,9 +82,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<G, F>,
right: ConstrainedValue<G, F>,
) -> Result<ConstrainedValue<G, F>, BooleanError> {
match (left, right) {
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => Ok(
ConstrainedValue::Boolean(Boolean::and(cs, &left_bool, &right_bool)?),
@ -96,7 +96,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<G, F> {
ConstrainedValue::Boolean(Boolean::Constant(left.eq(&right)))
}

View File

@ -10,17 +10,17 @@ use crate::{
};
use snarkos_models::{
curves::{Field, PrimeField},
curves::{Group, Field, PrimeField},
gadgets::{r1cs::ConstraintSystem, utilities::boolean::Boolean},
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<G: Group, F: Field + PrimeField, CS: ConstraintSystem<G>> ConstrainedProgram<G, F, CS> {
/// Enforce a variable expression by getting the resolved value
pub(crate) fn enforce_variable(
&mut self,
scope: String,
unresolved_variable: Variable<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
unresolved_variable: Variable<G, F>,
) -> Result<ConstrainedValue<G, F>, ExpressionError> {
// Evaluate the variable name in the current function scope
let variable_name = new_scope_from_variable(scope, &unresolved_variable);
@ -41,9 +41,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<G, F>,
right: ConstrainedValue<G, F>,
) -> Result<ConstrainedValue<G, F>, ExpressionError> {
Ok(match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
Self::enforce_integer_add(cs, num_1, num_2)?
@ -63,9 +63,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<G, F>,
right: ConstrainedValue<G, F>,
) -> Result<ConstrainedValue<G, F>, ExpressionError> {
Ok(match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
Self::enforce_integer_sub(cs, num_1, num_2)?
@ -85,9 +85,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<G, F>,
right: ConstrainedValue<G, F>,
) -> Result<ConstrainedValue<G, F>, ExpressionError> {
Ok(match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
Self::enforce_integer_mul(cs, num_1, num_2)?
@ -107,9 +107,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<G, F>,
right: ConstrainedValue<G, F>,
) -> Result<ConstrainedValue<G, F>, ExpressionError> {
Ok(match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
Self::enforce_integer_div(cs, num_1, num_2)?
@ -128,9 +128,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<G, F>,
right: ConstrainedValue<G, F>,
) -> Result<ConstrainedValue<G, F>, ExpressionError> {
Ok(match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
Self::enforce_integer_pow(cs, num_1, num_2)?
@ -153,9 +153,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<G, F>,
right: ConstrainedValue<G, F>,
) -> Result<ConstrainedValue<G, F>, ExpressionError> {
Ok(match (left, right) {
(ConstrainedValue::Boolean(bool_1), ConstrainedValue::Boolean(bool_2)) => {
Self::boolean_eq(bool_1, bool_2)
@ -177,9 +177,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<G, F>,
right: ConstrainedValue<G, F>,
) -> Result<ConstrainedValue<G, F>, ExpressionError> {
match (left, right) {
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
// Self::field_geq(fe_1, fe_2)
@ -193,9 +193,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<G, F>,
right: ConstrainedValue<G, F>,
) -> Result<ConstrainedValue<G, F>, ExpressionError> {
match (left, right) {
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
// Self::field_gt(fe_1, fe_2)
@ -209,9 +209,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<G, F>,
right: ConstrainedValue<G, F>,
) -> Result<ConstrainedValue<G, F>, ExpressionError> {
match (left, right) {
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
// Self::field_leq(fe_1, fe_2)
@ -225,9 +225,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<G, F>,
right: ConstrainedValue<G, F>,
) -> Result<ConstrainedValue<G, F>, ExpressionError> {
match (left, right) {
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
// Self::field_lt(fe_1, fe_2)
@ -245,8 +245,8 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
file_scope: String,
function_scope: String,
array: Vec<Box<SpreadOrExpression<F>>>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
array: Vec<Box<SpreadOrExpression<G, F>>>,
) -> Result<ConstrainedValue<G, F>, ExpressionError> {
let mut result = vec![];
for element in array.into_iter() {
match *element {
@ -283,7 +283,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
file_scope: String,
function_scope: String,
index: Expression<F>,
index: Expression<G, F>,
) -> Result<usize, ExpressionError> {
match self.enforce_expression(cs, file_scope, function_scope, index)? {
ConstrainedValue::Integer(number) => Ok(number.to_usize()),
@ -296,9 +296,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
file_scope: String,
function_scope: String,
array: Box<Expression<F>>,
index: RangeOrExpression<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
array: Box<Expression<G, F>>,
index: RangeOrExpression<G, F>,
) -> Result<ConstrainedValue<G, F>, ExpressionError> {
match self.enforce_expression(cs, file_scope.clone(), function_scope.clone(), *array)? {
ConstrainedValue::Array(array) => {
match index {
@ -331,9 +331,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
file_scope: String,
function_scope: String,
variable: Variable<F>,
members: Vec<StructMember<F>>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
variable: Variable<G, F>,
members: Vec<StructMember<G, F>>,
) -> Result<ConstrainedValue<G, F>, ExpressionError> {
let struct_name = new_variable_from_variable(file_scope.clone(), &variable);
if let Some(ConstrainedValue::StructDefinition(struct_definition)) =
@ -380,9 +380,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
file_scope: String,
function_scope: String,
struct_variable: Box<Expression<F>>,
struct_member: Variable<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
struct_variable: Box<Expression<G, F>>,
struct_member: Variable<G, F>,
) -> Result<ConstrainedValue<G, F>, ExpressionError> {
match self.enforce_expression(cs, file_scope, function_scope, *struct_variable)? {
ConstrainedValue::StructExpression(_name, members) => {
let matched_member = members.into_iter().find(|member| member.0 == struct_member);
@ -402,9 +402,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
file_scope: String,
function_scope: String,
function: Variable<F>,
arguments: Vec<Expression<F>>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
function: Variable<G, F>,
arguments: Vec<Expression<G, F>>,
) -> Result<ConstrainedValue<G, F>, ExpressionError> {
let function_name = new_variable_from_variable(file_scope.clone(), &function);
let function_call = match self.get(&function_name.to_string()) {
Some(ConstrainedValue::Function(function)) => function.clone(),
@ -429,8 +429,8 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
file_scope: String,
function_scope: String,
expression: Expression<F>,
) -> Result<ConstrainedValue<F>, ExpressionError> {
expression: Expression<G, F>,
) -> Result<ConstrainedValue<G, F>, ExpressionError> {
match expression {
// Variables
Expression::Variable(unresolved_variable) => {

View File

@ -8,17 +8,17 @@ use crate::{
use snarkos_errors::gadgets::SynthesisError;
use snarkos_models::{
curves::{Field, PrimeField},
curves::{Group, Field, PrimeField},
gadgets::r1cs::{ConstraintSystem, LinearCombination, Variable as R1CSVariable},
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<G: Group, F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<G, F, CS> {
pub(crate) fn field_element_from_input(
&mut self,
cs: &mut CS,
input_model: InputModel<F>,
input_value: Option<InputValue<F>>,
) -> Result<ConstrainedValue<F>, FieldElementError> {
input_model: InputModel<G, F>,
input_value: Option<InputValue<G, F>>,
) -> Result<ConstrainedValue<G, F>, FieldElementError> {
// Check that the parameter value is the correct type
let field_option = match input_value {
Some(input) => {
@ -51,7 +51,7 @@ 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<G, F> {
ConstrainedValue::FieldElement(fe)
}
@ -124,7 +124,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<G, F>, 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 +201,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<G, F>, 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 +278,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<G, F>, 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 +355,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<G, F>, 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 +443,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<G, F>, FieldElementError> {
Ok(match fe_1 {
// if both constants, then return a constant result
FieldElement::Constant(fe_1_constant) => ConstrainedValue::FieldElement(

View File

@ -13,11 +13,11 @@ use crate::{
};
use snarkos_models::{
curves::{Field, PrimeField},
curves::{Group, Field, PrimeField},
gadgets::r1cs::ConstraintSystem,
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<G: Group, F: Field + PrimeField, CS: ConstraintSystem<G>> ConstrainedProgram<G, F, CS> {
fn check_inputs_length(expected: usize, actual: usize) -> Result<(), FunctionError> {
// Make sure we are given the correct number of arguments
if expected != actual {
@ -33,8 +33,8 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
scope: String,
caller_scope: String,
function_name: String,
input: Expression<F>,
) -> Result<ConstrainedValue<F>, FunctionError> {
input: Expression<G, F>,
) -> Result<ConstrainedValue<G, F>, FunctionError> {
match input {
Expression::Variable(variable) => Ok(self.enforce_variable(caller_scope, variable)?),
expression => Ok(self.enforce_expression(cs, scope, function_name, expression)?),
@ -46,9 +46,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
scope: String,
caller_scope: String,
function: Function<F>,
inputs: Vec<Expression<F>>,
) -> Result<ConstrainedValue<F>, FunctionError> {
function: Function<G, F>,
inputs: Vec<Expression<G, F>>,
) -> Result<ConstrainedValue<G, F>, FunctionError> {
let function_name = new_scope(scope.clone(), function.get_name());
// Make sure we are given the correct number of inputs
@ -99,12 +99,12 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
fn allocate_array(
&mut self,
cs: &mut CS,
array_name: Variable<F>,
array_name: Variable<G, F>,
array_private: bool,
array_type: Type<F>,
array_type: Type<G, F>,
array_dimensions: Vec<usize>,
input_value: Option<InputValue<F>>,
) -> Result<ConstrainedValue<F>, FunctionError> {
input_value: Option<InputValue<G, F>>,
) -> Result<ConstrainedValue<G, F>, FunctionError> {
let expected_length = array_dimensions[0];
let mut array_value = vec![];
@ -163,9 +163,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
fn allocate_main_function_input(
&mut self,
cs: &mut CS,
input_model: InputModel<F>,
input_value: Option<InputValue<F>>,
) -> Result<ConstrainedValue<F>, FunctionError> {
input_model: InputModel<G, F>,
input_value: Option<InputValue<G, F>>,
) -> Result<ConstrainedValue<G, F>, FunctionError> {
match input_model._type {
Type::IntegerType(ref _integer_type) => {
Ok(self.integer_from_parameter(cs, input_model, input_value)?)
@ -190,9 +190,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
&mut self,
cs: &mut CS,
scope: String,
function: Function<F>,
inputs: Vec<Option<InputValue<F>>>,
) -> Result<ConstrainedValue<F>, FunctionError> {
function: Function<G, F>,
inputs: Vec<Option<InputValue<G, F>>>,
) -> Result<ConstrainedValue<G, F>, FunctionError> {
let function_name = new_scope(scope.clone(), function.get_name());
// Make sure we are given the correct number of inputs
@ -218,7 +218,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
pub(crate) fn resolve_definitions(
&mut self,
cs: &mut CS,
program: Program<F>,
program: Program<G, F>,
) -> Result<(), ImportError> {
let program_name = program.name.clone();

View File

@ -8,18 +8,18 @@ use crate::{
use from_pest::FromPest;
use snarkos_models::{
curves::{Field, PrimeField},
curves::{Group, Field, PrimeField},
gadgets::r1cs::ConstraintSystem,
};
use std::fs;
use std::path::Path;
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<G: Group, F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<G, F, CS> {
pub fn enforce_import(
&mut self,
cs: &mut CS,
scope: String,
import: Import<F>,
import: Import<F, G>,
) -> Result<(), ImportError> {
// Resolve program file path
let unparsed_file = fs::read_to_string(Path::new(&import.path_string_full()))

View File

@ -8,19 +8,19 @@ use crate::{
};
use snarkos_models::{
curves::{Field, PrimeField},
curves::{Group, Field, PrimeField},
gadgets::{r1cs::ConstraintSystem, utilities::boolean::Boolean},
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
pub(crate) fn get_integer_constant(integer: Integer) -> ConstrainedValue<F> {
impl<G: Group, F: Field + PrimeField, CS: ConstraintSystem<G>> ConstrainedProgram<G, F, CS> {
pub(crate) fn get_integer_constant(integer: Integer) -> ConstrainedValue<G, F> {
ConstrainedValue::Integer(integer)
}
pub(crate) fn evaluate_integer_eq(
left: Integer,
right: Integer,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<G, F>, IntegerError> {
Ok(ConstrainedValue::Boolean(Boolean::Constant(
match (left, right) {
(Integer::U8(left_u8), Integer::U8(right_u8)) => left_u8.eq(&right_u8),
@ -41,9 +41,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
pub(crate) fn integer_from_parameter(
&mut self,
cs: &mut CS,
integer_model: InputModel<F>,
integer_value: Option<InputValue<F>>,
) -> Result<ConstrainedValue<F>, IntegerError> {
integer_model: InputModel<G, F>,
integer_value: Option<InputValue<G, F>>,
) -> Result<ConstrainedValue<G, F>, IntegerError> {
let integer_type = match &integer_model._type {
Type::IntegerType(integer_type) => integer_type,
_type => return Err(IntegerError::InvalidType(_type.to_string())),
@ -107,7 +107,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
left: Integer,
right: Integer,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<G, F>, 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)?)
@ -133,7 +133,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
left: Integer,
right: Integer,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<G, F>, 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)?)
@ -159,7 +159,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
left: Integer,
right: Integer,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<G, F>, 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)?)
@ -185,7 +185,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
left: Integer,
right: Integer,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<G, F>, 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)?)
@ -211,7 +211,7 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
left: Integer,
right: Integer,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<G, F>, 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

@ -8,20 +8,20 @@ use crate::{
use snarkos_errors::gadgets::SynthesisError;
use snarkos_models::{
curves::{Field, PrimeField},
curves::{Group, Field, PrimeField},
gadgets::{
r1cs::ConstraintSystem,
utilities::{alloc::AllocGadget, eq::EqGadget, uint128::UInt128},
},
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<G: Group, F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<G, F, CS> {
pub(crate) fn u128_from_integer(
&mut self,
cs: &mut CS,
parameter_model: InputModel<F>,
parameter_model: InputModel<G, F>,
integer_option: Option<usize>,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<G, F>, 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

@ -8,20 +8,20 @@ use crate::{
use snarkos_errors::gadgets::SynthesisError;
use snarkos_models::{
curves::{Field, PrimeField},
curves::{Group, Field, PrimeField},
gadgets::{
r1cs::ConstraintSystem,
utilities::{alloc::AllocGadget, eq::EqGadget, uint16::UInt16},
},
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<G: Group, F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<G, F, CS> {
pub(crate) fn u16_from_input(
&mut self,
cs: &mut CS,
parameter_model: InputModel<F>,
parameter_model: InputModel<G, F>,
integer_option: Option<usize>,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<G, F>, 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

@ -8,20 +8,20 @@ use crate::{
use snarkos_errors::gadgets::SynthesisError;
use snarkos_models::{
curves::{Field, PrimeField},
curves::{Group, Field, PrimeField},
gadgets::{
r1cs::ConstraintSystem,
utilities::{alloc::AllocGadget, eq::EqGadget, uint32::UInt32},
},
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<G: Group, F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<G, F, CS> {
pub(crate) fn u32_from_input(
&mut self,
cs: &mut CS,
parameter_model: InputModel<F>,
parameter_model: InputModel<G, F>,
integer_option: Option<usize>,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<G, F>, IntegerError> {
// Type cast to u32 in rust.
// If this fails should we return our own error?
let u32_option = integer_option.map(|integer| integer as u32);

View File

@ -8,20 +8,20 @@ use crate::{
use snarkos_errors::gadgets::SynthesisError;
use snarkos_models::{
curves::{Field, PrimeField},
curves::{Group, Field, PrimeField},
gadgets::{
r1cs::ConstraintSystem,
utilities::{alloc::AllocGadget, eq::EqGadget, uint64::UInt64},
},
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<G: Group, F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<G, F, CS> {
pub(crate) fn u64_from_input(
&mut self,
cs: &mut CS,
parameter_model: InputModel<F>,
parameter_model: InputModel<G, F>,
integer_option: Option<usize>,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<G, F>, 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

@ -8,20 +8,20 @@ use crate::{
use snarkos_errors::gadgets::SynthesisError;
use snarkos_models::{
curves::{Field, PrimeField},
curves::{Group, Field, PrimeField},
gadgets::{
r1cs::ConstraintSystem,
utilities::{alloc::AllocGadget, eq::EqGadget, uint8::UInt8},
},
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<G: Group, F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<G, F, CS> {
pub(crate) fn u8_from_input(
&mut self,
cs: &mut CS,
parameter_model: InputModel<F>,
parameter_model: InputModel<G, F>,
integer_option: Option<usize>,
) -> Result<ConstrainedValue<F>, IntegerError> {
) -> Result<ConstrainedValue<G, F>, 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,15 +33,15 @@ use crate::{
};
use snarkos_models::{
curves::{Field, PrimeField},
curves::{Group, Field, PrimeField},
gadgets::r1cs::ConstraintSystem,
};
pub fn generate_constraints<F: Field + PrimeField, CS: ConstraintSystem<F>>(
pub fn generate_constraints<G: Group, F: Field + PrimeField, CS: ConstraintSystem<F>>(
cs: &mut CS,
program: Program<F>,
parameters: Vec<Option<InputValue<F>>>,
) -> Result<ConstrainedValue<F>, CompilerError> {
program: Program<G, F>,
parameters: Vec<Option<InputValue<G, F>>>,
) -> Result<ConstrainedValue<G, F>, 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

@ -3,13 +3,13 @@
use crate::{constraints::ConstrainedValue, types::Variable};
use snarkos_models::{
curves::{Field, PrimeField},
curves::{Group, Field, PrimeField},
gadgets::r1cs::ConstraintSystem,
};
use std::{collections::HashMap, marker::PhantomData};
pub struct ConstrainedProgram<F: Field + PrimeField, CS: ConstraintSystem<F>> {
pub resolved_names: HashMap<String, ConstrainedValue<F>>,
pub struct ConstrainedProgram<G: Group, F: Field + PrimeField, CS: ConstraintSystem<F>> {
pub resolved_names: HashMap<String, ConstrainedValue<F, G>>,
pub _cs: PhantomData<CS>,
}
@ -17,34 +17,36 @@ pub fn new_scope(outer: String, inner: String) -> String {
format!("{}_{}", outer, inner)
}
pub fn new_scope_from_variable<F: Field + PrimeField>(
pub fn new_scope_from_variable<F: Field + PrimeField, G: Group>(
outer: String,
inner: &Variable<F>,
inner: &Variable<F, G>,
) -> String {
new_scope(outer, inner.name.clone())
}
pub fn new_variable_from_variable<F: Field + PrimeField>(
pub fn new_variable_from_variable<F: Field + PrimeField, G: Group>(
outer: String,
inner: &Variable<F>,
) -> Variable<F> {
inner: &Variable<F, G>,
) -> Variable<F, G> {
Variable {
name: new_scope_from_variable(outer, inner),
_field: PhantomData::<F>,
_engine: PhantomData::<F>,
_group: PhantomData::<G>
}
}
pub fn new_variable_from_variables<F: Field + PrimeField>(
outer: &Variable<F>,
inner: &Variable<F>,
) -> Variable<F> {
pub fn new_variable_from_variables<F: Field + PrimeField, G: Group>(
outer: &Variable<F, G>,
inner: &Variable<F, G>,
) -> Variable<F, G> {
Variable {
name: new_scope_from_variable(outer.name.clone(), inner),
_field: PhantomData::<F>,
_engine: PhantomData::<F>,
_group: PhantomData::<G>,
}
}
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
impl<G: Group, F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<G, F, CS> {
pub fn new() -> Self {
Self {
resolved_names: HashMap::new(),
@ -52,11 +54,11 @@ 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<F, G>) {
self.resolved_names.insert(name, value);
}
pub(crate) fn store_variable(&mut self, variable: Variable<F>, value: ConstrainedValue<F>) {
pub(crate) fn store_variable(&mut self, variable: Variable<F, G>, value: ConstrainedValue<F, G>) {
self.store(variable.name, value);
}
@ -64,22 +66,22 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
self.resolved_names.contains_key(name)
}
pub(crate) fn contains_variable(&self, variable: &Variable<F>) -> bool {
pub(crate) fn contains_variable(&self, variable: &Variable<F, G>) -> bool {
self.contains_name(&variable.name)
}
pub(crate) fn get(&self, name: &String) -> Option<&ConstrainedValue<F>> {
pub(crate) fn get(&self, name: &String) -> Option<&ConstrainedValue<F, G>> {
self.resolved_names.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<F, G>> {
self.resolved_names.get_mut(name)
}
pub(crate) fn get_mut_variable(
&mut self,
variable: &Variable<F>,
) -> Option<&mut ConstrainedValue<F>> {
variable: &Variable<F, G>,
) -> Option<&mut ConstrainedValue<F, G>> {
self.get_mut(&variable.name)
}
}

View File

@ -10,12 +10,12 @@ use crate::{
};
use snarkos_models::{
curves::{Field, PrimeField},
curves::{Group, Field, PrimeField},
gadgets::{r1cs::ConstraintSystem, utilities::boolean::Boolean, utilities::uint32::UInt32},
};
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
fn resolve_assignee(&mut self, scope: String, assignee: Assignee<F>) -> String {
impl<G: Group, F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<G, F, CS> {
fn resolve_assignee(&mut self, scope: String, assignee: Assignee<F, G>) -> String {
match assignee {
Assignee::Variable(name) => new_scope_from_variable(scope, &name),
Assignee::Array(array, _index) => self.resolve_assignee(scope, *array),
@ -30,8 +30,8 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
file_scope: String,
function_scope: String,
assignee: Assignee<F>,
return_value: &mut ConstrainedValue<F>,
assignee: Assignee<F, G>,
return_value: &mut ConstrainedValue<F, G>,
) -> Result<(), StatementError> {
match assignee {
Assignee::Variable(name) => {
@ -125,8 +125,8 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
file_scope: String,
function_scope: String,
assignee: Assignee<F>,
expression: Expression<F>,
assignee: Assignee<F, G>,
expression: Expression<F, G>,
) -> Result<(), StatementError> {
// Check that assignee exists
let name = self.resolve_assignee(function_scope.clone(), assignee.clone());
@ -151,9 +151,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
file_scope: String,
function_scope: String,
assignee: Assignee<F>,
ty: Option<Type<F>>,
expression: Expression<F>,
assignee: Assignee<F, G>,
ty: Option<Type<F, G>>,
expression: Expression<F, G>,
) -> Result<(), StatementError> {
let result_value = &mut self.enforce_expression(
cs,
@ -178,8 +178,8 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
file_scope: String,
function_scope: String,
assignees: Vec<Assignee<F>>,
function: Expression<F>,
assignees: Vec<Assignee<F, G>>,
function: Expression<F, G>,
) -> Result<(), StatementError> {
// Expect return values from function
let return_values = match self.enforce_expression(
@ -217,9 +217,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
file_scope: String,
function_scope: String,
expressions: Vec<Expression<F>>,
return_types: Vec<Type<F>>,
) -> Result<ConstrainedValue<F>, StatementError> {
expressions: Vec<Expression<F, G>>,
return_types: Vec<Type<F, G>>,
) -> Result<ConstrainedValue<F, G>, StatementError> {
// Make sure we return the correct number of values
if return_types.len() != expressions.len() {
return Err(StatementError::InvalidNumberOfReturns(
@ -249,9 +249,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
file_scope: String,
function_scope: String,
statements: Vec<Statement<F>>,
return_types: Vec<Type<F>>,
) -> Result<Option<ConstrainedValue<F>>, StatementError> {
statements: Vec<Statement<F, G>>,
return_types: Vec<Type<F, G>>,
) -> Result<Option<ConstrainedValue<F, G>>, StatementError> {
let mut res = None;
// Evaluate statements and possibly return early
for statement in statements.iter() {
@ -275,9 +275,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
file_scope: String,
function_scope: String,
statement: ConditionalStatement<F>,
return_types: Vec<Type<F>>,
) -> Result<Option<ConstrainedValue<F>>, StatementError> {
statement: ConditionalStatement<F, G>,
return_types: Vec<Type<F, G>>,
) -> Result<Option<ConstrainedValue<F, G>>, StatementError> {
let condition = match self.enforce_expression(
cs,
file_scope.clone(),
@ -325,12 +325,12 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
file_scope: String,
function_scope: String,
index: Variable<F>,
index: Variable<F, G>,
start: Integer,
stop: Integer,
statements: Vec<Statement<F>>,
return_types: Vec<Type<F>>,
) -> Result<Option<ConstrainedValue<F>>, StatementError> {
statements: Vec<Statement<F, G>>,
return_types: Vec<Type<F, G>>,
) -> Result<Option<ConstrainedValue<F, G>>, StatementError> {
let mut res = None;
for i in start.to_usize()..stop.to_usize() {
@ -361,8 +361,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<F, G>,
right: ConstrainedValue<F, G>,
) -> Result<(), StatementError> {
Ok(match (left, right) {
(ConstrainedValue::Boolean(bool_1), ConstrainedValue::Boolean(bool_2)) => {
@ -398,9 +398,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
cs: &mut CS,
file_scope: String,
function_scope: String,
statement: Statement<F>,
return_types: Vec<Type<F>>,
) -> Result<Option<ConstrainedValue<F>>, StatementError> {
statement: Statement<F, G>,
return_types: Vec<Type<F, G>>,
) -> Result<Option<ConstrainedValue<F, G>>, StatementError> {
let mut res = None;
match statement {
Statement::Return(expressions) => {

View File

@ -7,33 +7,35 @@ use crate::{
};
use snarkos_models::{
curves::{Field, PrimeField},
curves::{Group, Field, PrimeField},
gadgets::utilities::boolean::Boolean,
};
use std::fmt;
#[derive(Clone, PartialEq, Eq)]
pub struct ConstrainedStructMember<F: Field + PrimeField>(pub Variable<F>, pub ConstrainedValue<F>);
pub struct ConstrainedStructMember<F: Field + PrimeField, G: Group>(pub Variable<F, G>, pub ConstrainedValue<F, G>);
#[derive(Clone, PartialEq, Eq)]
pub enum ConstrainedValue<F: Field + PrimeField> {
pub enum ConstrainedValue<F: Field + PrimeField, G: Group> {
Integer(Integer),
FieldElement(FieldElement<F>),
GroupElement(G),
Boolean(Boolean),
Array(Vec<ConstrainedValue<F>>),
StructDefinition(Struct<F>),
StructExpression(Variable<F>, Vec<ConstrainedStructMember<F>>),
Function(Function<F>),
Return(Vec<ConstrainedValue<F>>), // add Null for function returns
Array(Vec<ConstrainedValue<F, G>>),
StructDefinition(Struct<F, G>),
StructExpression(Variable<F, G>, Vec<ConstrainedStructMember<F, G>>),
Function(Function<F, G>),
Return(Vec<ConstrainedValue<F, G>>), // add Null for function returns
}
impl<F: Field + PrimeField> ConstrainedValue<F> {
pub(crate) fn expect_type(&self, _type: &Type<F>) -> Result<(), ValueError> {
impl<F: Field + PrimeField, G: Group> ConstrainedValue<F, G> {
pub(crate) fn expect_type(&self, _type: &Type<F, G>) -> Result<(), ValueError> {
match (self, _type) {
(ConstrainedValue::Integer(ref integer), Type::IntegerType(ref _type)) => {
integer.expect_type(_type)?;
}
(ConstrainedValue::FieldElement(ref _f), Type::FieldElement) => {}
(ConstrainedValue::GroupElement(ref _g), Type::GroupElement) => {}
(ConstrainedValue::Boolean(ref _b), Type::Boolean) => {}
(ConstrainedValue::Array(ref arr), Type::Array(ref _type, ref dimensions)) => {
// check array lengths are equal
@ -80,11 +82,12 @@ impl<F: Field + PrimeField> ConstrainedValue<F> {
}
}
impl<F: Field + PrimeField> fmt::Display for ConstrainedValue<F> {
impl<F: Field + PrimeField, G: Group> fmt::Display for ConstrainedValue<F, G> {
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::GroupElement(ref value) => write!(f, "{}", value),
ConstrainedValue::Boolean(ref value) => write!(f, "{}", value.get_value().unwrap()),
ConstrainedValue::Array(ref array) => {
write!(f, "[")?;
@ -124,7 +127,7 @@ impl<F: Field + PrimeField> fmt::Display for ConstrainedValue<F> {
}
}
impl<F: Field + PrimeField> fmt::Debug for ConstrainedValue<F> {
impl<F: Field + PrimeField, G: Group> fmt::Debug for ConstrainedValue<F, G> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self)
}

View File

@ -2,23 +2,23 @@
use crate::Variable;
use snarkos_models::curves::{Field, PrimeField};
use snarkos_models::curves::{Field, PrimeField, Group};
use std::fmt;
#[derive(Clone)]
pub struct ImportSymbol<F: Field + PrimeField> {
pub symbol: Variable<F>,
pub alias: Option<Variable<F>>,
pub struct ImportSymbol<F: Field + PrimeField, G: Group> {
pub symbol: Variable<F, G>,
pub alias: Option<Variable<F, G>>,
}
#[derive(Clone)]
pub struct Import<F: Field + PrimeField> {
pub struct Import<F: Field + PrimeField, G: Group> {
pub path_string: String,
pub symbols: Vec<ImportSymbol<F>>,
pub symbols: Vec<ImportSymbol<F, G>>,
}
impl<F: Field + PrimeField> Import<F> {
pub fn new(source: String, symbols: Vec<ImportSymbol<F>>) -> Import<F> {
impl<F: Field + PrimeField, G: Group> Import<F, G> {
pub fn new(source: String, symbols: Vec<ImportSymbol<F, G>>) -> Import<F, G> {
Import {
path_string: source,
symbols,
@ -51,7 +51,7 @@ impl<F: Field + PrimeField> Import<F> {
}
}
impl<F: Field + PrimeField> fmt::Display for ImportSymbol<F> {
impl<F: Field + PrimeField, G: Group> fmt::Display for ImportSymbol<F, G> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.alias.is_some() {
write!(f, "\t{} as {}", self.symbol, self.alias.as_ref().unwrap())
@ -61,13 +61,13 @@ impl<F: Field + PrimeField> fmt::Display for ImportSymbol<F> {
}
}
impl<'ast, F: Field + PrimeField> fmt::Display for Import<F> {
impl<'ast, F: Field + PrimeField, G: Group> fmt::Display for Import<F, G> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.format(f)
}
}
impl<'ast, F: Field + PrimeField> fmt::Debug for Import<F> {
impl<'ast, F: Field + PrimeField, G: Group> fmt::Debug for Import<F, G> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.format(f)
}

View File

@ -69,9 +69,10 @@ type_integer = {
| type_u128
}
type_field = {"fe"}
type_field = {"field"}
type_group = {"group"}
type_bool = {"bool"}
type_basic = { type_integer | type_field | type_bool }
type_basic = { type_integer | type_field | type_group | type_bool }
type_struct = { variable }
type_basic_or_struct = {type_basic | type_struct }
type_array = {type_basic ~ ("[" ~ value ~ "]")+ }
@ -82,7 +83,8 @@ type_list = _{(_type ~ ("," ~ _type)*)?}
value_number = @{ "0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT* }
value_integer = { value_number ~ type_integer? }
value_field = { value_number ~ type_field }
value_field = { value_number ~ "fe" }
value_group = { value_number ~ "gr" }
value_boolean = { "true" | "false" }
value = { value_field | value_boolean | value_integer }

View File

@ -4,7 +4,7 @@
use crate::{errors::IntegerError, Import};
use crate::errors::ValueError;
use snarkos_models::curves::{Field, PrimeField};
use snarkos_models::curves::{Field, PrimeField, Group};
use snarkos_models::gadgets::{
r1cs::Variable as R1CSVariable,
utilities::{
@ -17,16 +17,18 @@ use std::marker::PhantomData;
/// A variable in a constraint system.
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct Variable<F: Field + PrimeField> {
pub struct Variable<G: Group, F: Field + PrimeField> {
pub name: String,
pub(crate) _field: PhantomData<F>,
pub(crate) _group: PhantomData<G>,
pub(crate) _engine: PhantomData<F>,
}
impl<F: Field + PrimeField> Variable<F> {
impl<G: Group, F: Field + PrimeField> Variable<G, F> {
pub fn new(name: String) -> Self {
Self {
name,
_field: PhantomData::<F>,
_group: PhantomData::<G>,
_engine: PhantomData::<F>,
}
}
}
@ -82,69 +84,77 @@ pub enum FieldElement<F: Field + PrimeField> {
Allocated(Option<F>, R1CSVariable),
}
// /// A constant or allocated element in the field
// #[derive(Clone, PartialEq, Eq)]
// pub enum GroupElement<G: Field + PrimeField> {
// Constant(G),
// Allocated(Option<G>, R1CSVariable),
// }
/// Range or expression enum
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum RangeOrExpression<F: Field + PrimeField> {
pub enum RangeOrExpression<G: Group, F: Field + PrimeField> {
Range(Option<Integer>, Option<Integer>),
Expression(Expression<F>),
Expression(Expression<G, F>),
}
/// Spread or expression
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SpreadOrExpression<F: Field + PrimeField> {
Spread(Expression<F>),
Expression(Expression<F>),
pub enum SpreadOrExpression<G: Group, F: Field + PrimeField> {
Spread(Expression<G, F>),
Expression(Expression<G, F>),
}
/// Expression that evaluates to a value
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Expression<F: Field + PrimeField> {
pub enum Expression<G: Group, F: Field + PrimeField> {
// Variable
Variable(Variable<F>),
Variable(Variable<G, F>),
// Values
Integer(Integer),
FieldElement(FieldElement<F>),
GroupElement(G),
Boolean(Boolean),
// Number operations
Add(Box<Expression<F>>, Box<Expression<F>>),
Sub(Box<Expression<F>>, Box<Expression<F>>),
Mul(Box<Expression<F>>, Box<Expression<F>>),
Div(Box<Expression<F>>, Box<Expression<F>>),
Pow(Box<Expression<F>>, Box<Expression<F>>),
Add(Box<Expression<G, F>>, Box<Expression<G, F>>),
Sub(Box<Expression<G, F>>, Box<Expression<G, F>>),
Mul(Box<Expression<G, F>>, Box<Expression<G, F>>),
Div(Box<Expression<G, F>>, Box<Expression<G, F>>),
Pow(Box<Expression<G, F>>, Box<Expression<G, F>>),
// Boolean operations
Not(Box<Expression<F>>),
Or(Box<Expression<F>>, Box<Expression<F>>),
And(Box<Expression<F>>, Box<Expression<F>>),
Eq(Box<Expression<F>>, Box<Expression<F>>),
Geq(Box<Expression<F>>, Box<Expression<F>>),
Gt(Box<Expression<F>>, Box<Expression<F>>),
Leq(Box<Expression<F>>, Box<Expression<F>>),
Lt(Box<Expression<F>>, Box<Expression<F>>),
Not(Box<Expression<G, F>>),
Or(Box<Expression<G, F>>, Box<Expression<G, F>>),
And(Box<Expression<G, F>>, Box<Expression<G, F>>),
Eq(Box<Expression<G, F>>, Box<Expression<G, F>>),
Geq(Box<Expression<G, F>>, Box<Expression<G, F>>),
Gt(Box<Expression<G, F>>, Box<Expression<G, F>>),
Leq(Box<Expression<G, F>>, Box<Expression<G, F>>),
Lt(Box<Expression<G, F>>, Box<Expression<G, F>>),
// Conditionals
IfElse(Box<Expression<F>>, Box<Expression<F>>, Box<Expression<F>>),
IfElse(Box<Expression<G, F>>, Box<Expression<G, F>>, Box<Expression<G, F>>),
// Arrays
Array(Vec<Box<SpreadOrExpression<F>>>),
ArrayAccess(Box<Expression<F>>, Box<RangeOrExpression<F>>), // (array name, range)
Array(Vec<Box<SpreadOrExpression<G, F>>>),
ArrayAccess(Box<Expression<G, F>>, Box<RangeOrExpression<G, F>>), // (array name, range)
// Structs
Struct(Variable<F>, Vec<StructMember<F>>),
StructMemberAccess(Box<Expression<F>>, Variable<F>), // (struct name, struct member name)
Struct(Variable<G, F>, Vec<StructMember<G, F>>),
StructMemberAccess(Box<Expression<G, F>>, Variable<G, F>), // (struct name, struct member name)
// Functions
FunctionCall(Variable<F>, Vec<Expression<F>>),
FunctionCall(Variable<G, F>, Vec<Expression<G, F>>),
}
/// Definition assignee: v, arr[0..2], Point p.x
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Assignee<F: Field + PrimeField> {
Variable(Variable<F>),
Array(Box<Assignee<F>>, RangeOrExpression<F>),
StructMember(Box<Assignee<F>>, Variable<F>),
pub enum Assignee<G: Group, F: Field + PrimeField> {
Variable(Variable<G, F>),
Array(Box<Assignee<G, F>>, RangeOrExpression<G, F>),
StructMember(Box<Assignee<G, F>>, Variable<G, F>),
}
/// Explicit integer type
@ -159,15 +169,16 @@ pub enum IntegerType {
/// Explicit type used for defining a variable or expression type
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Type<F: Field + PrimeField> {
pub enum Type<G: Group, F: Field + PrimeField> {
IntegerType(IntegerType),
FieldElement,
GroupElement,
Boolean,
Array(Box<Type<F>>, Vec<usize>),
Struct(Variable<F>),
Array(Box<Type<G, F>>, Vec<usize>),
Struct(Variable<G, F>),
}
impl<F: Field + PrimeField> Type<F> {
impl<G: Group, F: Field + PrimeField> Type<G, F> {
pub fn next_dimension(&self, dimensions: &Vec<usize>) -> Self {
let _type = self.clone();
@ -183,61 +194,61 @@ impl<F: Field + PrimeField> Type<F> {
}
#[derive(Clone, PartialEq, Eq)]
pub enum ConditionalNestedOrEnd<F: Field + PrimeField> {
Nested(Box<ConditionalStatement<F>>),
End(Vec<Statement<F>>),
pub enum ConditionalNestedOrEnd<G: Group, F: Field + PrimeField> {
Nested(Box<ConditionalStatement<G, F>>),
End(Vec<Statement<G, F>>),
}
#[derive(Clone, PartialEq, Eq)]
pub struct ConditionalStatement<F: Field + PrimeField> {
pub condition: Expression<F>,
pub statements: Vec<Statement<F>>,
pub next: Option<ConditionalNestedOrEnd<F>>,
pub struct ConditionalStatement<G: Group, F: Field + PrimeField> {
pub condition: Expression<G, F>,
pub statements: Vec<Statement<G, F>>,
pub next: Option<ConditionalNestedOrEnd<G, F>>,
}
/// Program statement that defines some action (or expression) to be carried out.
#[derive(Clone, PartialEq, Eq)]
pub enum Statement<F: Field + PrimeField> {
pub enum Statement<G: Group, F: Field + PrimeField> {
// Declaration(Variable),
Return(Vec<Expression<F>>),
Definition(Assignee<F>, Option<Type<F>>, Expression<F>),
Assign(Assignee<F>, Expression<F>),
MultipleAssign(Vec<Assignee<F>>, Expression<F>),
Conditional(ConditionalStatement<F>),
For(Variable<F>, Integer, Integer, Vec<Statement<F>>),
AssertEq(Expression<F>, Expression<F>),
Expression(Expression<F>),
Return(Vec<Expression<G, F>>),
Definition(Assignee<G, F>, Option<Type<G, F>>, Expression<G, F>),
Assign(Assignee<G, F>, Expression<G, F>),
MultipleAssign(Vec<Assignee<G, F>>, Expression<G, F>),
Conditional(ConditionalStatement<G, F>),
For(Variable<G, F>, Integer, Integer, Vec<Statement<G, F>>),
AssertEq(Expression<G, F>, Expression<G, F>),
Expression(Expression<G, F>),
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct StructMember<F: Field + PrimeField> {
pub variable: Variable<F>,
pub expression: Expression<F>,
pub struct StructMember<G: Group, F: Field + PrimeField> {
pub variable: Variable<G, F>,
pub expression: Expression<G, F>,
}
#[derive(Clone, PartialEq, Eq)]
pub struct StructField<F: Field + PrimeField> {
pub variable: Variable<F>,
pub _type: Type<F>,
pub struct StructField<G: Group, F: Field + PrimeField> {
pub variable: Variable<G, F>,
pub _type: Type<G, F>,
}
#[derive(Clone, PartialEq, Eq)]
pub struct Struct<F: Field + PrimeField> {
pub variable: Variable<F>,
pub fields: Vec<StructField<F>>,
pub struct Struct<G: Group, F: Field + PrimeField> {
pub variable: Variable<G, F>,
pub fields: Vec<StructField<G, F>>,
}
/// Function parameters
#[derive(Clone, PartialEq, Eq)]
pub struct InputModel<F: Field + PrimeField> {
pub struct InputModel<G: Group, F: Field + PrimeField> {
pub private: bool,
pub _type: Type<F>,
pub variable: Variable<F>,
pub _type: Type<G, F>,
pub variable: Variable<G, F>,
}
impl<F: Field + PrimeField> InputModel<F> {
pub fn inner_type(&self) -> Result<Type<F>, ValueError> {
impl<G: Group, F: Field + PrimeField> InputModel<G, F> {
pub fn inner_type(&self) -> Result<Type<G, F>, ValueError> {
match &self._type {
Type::Array(ref _type, _length) => Ok(*_type.clone()),
ref _type => Err(ValueError::ArrayModel(_type.to_string())),
@ -246,11 +257,11 @@ impl<F: Field + PrimeField> InputModel<F> {
}
#[derive(Clone, PartialEq, Eq)]
pub enum InputValue<F: Field + PrimeField> {
pub enum InputValue<G: Group, F: Field + PrimeField> {
Integer(usize),
Field(F),
Boolean(bool),
Array(Vec<InputValue<F>>),
Array(Vec<InputValue<G, F>>),
}
/// The given name for a defined function in the program.
@ -258,14 +269,14 @@ pub enum InputValue<F: Field + PrimeField> {
pub struct FunctionName(pub String);
#[derive(Clone, PartialEq, Eq)]
pub struct Function<F: Field + PrimeField> {
pub struct Function<G: Group, F: Field + PrimeField> {
pub function_name: FunctionName,
pub inputs: Vec<InputModel<F>>,
pub returns: Vec<Type<F>>,
pub statements: Vec<Statement<F>>,
pub inputs: Vec<InputModel<G, F>>,
pub returns: Vec<Type<G, F>>,
pub statements: Vec<Statement<G, F>>,
}
impl<F: Field + PrimeField> Function<F> {
impl<G: Group, F: Field + PrimeField> Function<G, F> {
pub fn get_name(&self) -> String {
self.function_name.0.clone()
}
@ -273,20 +284,21 @@ impl<F: Field + PrimeField> Function<F> {
/// A simple program with statement expressions, program arguments and program returns.
#[derive(Debug, Clone)]
pub struct Program<F: Field + PrimeField> {
pub name: Variable<F>,
pub struct Program<G: Group, F: Field + PrimeField> {
pub name: Variable<G, F>,
pub num_parameters: usize,
pub imports: Vec<Import<F>>,
pub structs: HashMap<Variable<F>, Struct<F>>,
pub functions: HashMap<FunctionName, Function<F>>,
pub imports: Vec<Import<G, F>>,
pub structs: HashMap<Variable<G, F>, Struct<G, F>>,
pub functions: HashMap<FunctionName, Function<G, F>>,
}
impl<'ast, F: Field + PrimeField> Program<F> {
impl<'ast, G: Group, F: Field + PrimeField> Program<G, F> {
pub fn new() -> Self {
Self {
name: Variable {
name: "".into(),
_field: PhantomData::<F>,
_group: PhantomData::<G>,
_engine: PhantomData::<F>,
},
num_parameters: 0,
imports: vec![],
@ -302,7 +314,8 @@ impl<'ast, F: Field + PrimeField> Program<F> {
pub fn name(mut self, name: String) -> Self {
self.name = Variable {
name,
_field: PhantomData::<F>,
_group: PhantomData::<G>,
_engine: PhantomData::<F>,
};
self
}

View File

@ -6,15 +6,15 @@ use crate::{
SpreadOrExpression, Statement, Struct, StructField, Type, Variable,
};
use snarkos_models::curves::{Field, PrimeField};
use snarkos_models::curves::{Group, Field, PrimeField};
use std::fmt;
impl<F: Field + PrimeField> fmt::Display for Variable<F> {
impl<G: Group, F: Field + PrimeField> fmt::Display for Variable<G, F> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name)
}
}
impl<F: Field + PrimeField> fmt::Debug for Variable<F> {
impl<G: Group, F: Field + PrimeField> fmt::Debug for Variable<G, F> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name)
}
@ -53,7 +53,7 @@ impl<F: Field + PrimeField> fmt::Debug for FieldElement<F> {
}
}
impl<'ast, F: Field + PrimeField> fmt::Display for RangeOrExpression<F> {
impl<'ast, G: Group, F: Field + PrimeField> fmt::Display for RangeOrExpression<G, F> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
RangeOrExpression::Range(ref from, ref to) => write!(
@ -71,7 +71,7 @@ impl<'ast, F: Field + PrimeField> fmt::Display for RangeOrExpression<F> {
}
}
impl<F: Field + PrimeField> fmt::Display for SpreadOrExpression<F> {
impl<G: Group, F: Field + PrimeField> fmt::Display for SpreadOrExpression<G, F> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
SpreadOrExpression::Spread(ref spread) => write!(f, "...{}", spread),
@ -80,7 +80,7 @@ impl<F: Field + PrimeField> fmt::Display for SpreadOrExpression<F> {
}
}
impl<'ast, F: Field + PrimeField> fmt::Display for Expression<F> {
impl<'ast, G: Group, F: Field + PrimeField> fmt::Display for Expression<G, F> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
// Variables
@ -89,6 +89,7 @@ impl<'ast, F: Field + PrimeField> fmt::Display for Expression<F> {
// Values
Expression::Integer(ref integer) => write!(f, "{}", integer),
Expression::FieldElement(ref fe) => write!(f, "{}", fe),
Expression::GroupElement(ref gr) => write!(f, "{}", gr),
Expression::Boolean(ref bool) => write!(f, "{}", bool.get_value().unwrap()),
// Number operations
@ -156,7 +157,7 @@ impl<'ast, F: Field + PrimeField> fmt::Display for Expression<F> {
}
}
impl<F: Field + PrimeField> fmt::Display for Assignee<F> {
impl<G: Group, F: Field + PrimeField> fmt::Display for Assignee<G, F> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Assignee::Variable(ref variable) => write!(f, "{}", variable),
@ -168,7 +169,7 @@ impl<F: Field + PrimeField> fmt::Display for Assignee<F> {
}
}
impl<F: Field + PrimeField> fmt::Display for ConditionalNestedOrEnd<F> {
impl<G: Group, F: Field + PrimeField> fmt::Display for ConditionalNestedOrEnd<G, F> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ConditionalNestedOrEnd::Nested(ref nested) => write!(f, "else {}", nested),
@ -183,7 +184,7 @@ impl<F: Field + PrimeField> fmt::Display for ConditionalNestedOrEnd<F> {
}
}
impl<F: Field + PrimeField> fmt::Display for ConditionalStatement<F> {
impl<G: Group, F: Field + PrimeField> fmt::Display for ConditionalStatement<G, F> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "if ({}) {{\n", self.condition)?;
for statement in self.statements.iter() {
@ -196,7 +197,7 @@ impl<F: Field + PrimeField> fmt::Display for ConditionalStatement<F> {
}
}
impl<F: Field + PrimeField> fmt::Display for Statement<F> {
impl<G: Group, F: Field + PrimeField> fmt::Display for Statement<G, F> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Statement::Return(ref statements) => {
@ -254,11 +255,12 @@ impl fmt::Display for IntegerType {
}
}
impl<F: Field + PrimeField> fmt::Display for Type<F> {
impl<G: Group, F: Field + PrimeField> fmt::Display for Type<G, F> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Type::IntegerType(ref integer_type) => write!(f, "{}", integer_type),
Type::FieldElement => write!(f, "fe"),
Type::FieldElement => write!(f, "field"),
Type::GroupElement => write!(f, "group"),
Type::Boolean => write!(f, "bool"),
Type::Struct(ref variable) => write!(f, "{}", variable),
Type::Array(ref array, ref dimensions) => {
@ -272,13 +274,13 @@ impl<F: Field + PrimeField> fmt::Display for Type<F> {
}
}
impl<F: Field + PrimeField> fmt::Display for StructField<F> {
impl<G: Group, F: Field + PrimeField> fmt::Display for StructField<G, F> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}: {}", self.variable, self._type)
}
}
impl<F: Field + PrimeField> Struct<F> {
impl<G: Group, F: Field + PrimeField> Struct<G, F> {
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "struct {} {{ \n", self.variable)?;
for field in self.fields.iter() {
@ -288,26 +290,26 @@ impl<F: Field + PrimeField> Struct<F> {
}
}
// impl<F: Field + PrimeField> fmt::Display for Struct<F> {// uncomment when we no longer print out Program
// impl<G: Group, F: Field + PrimeField> fmt::Display for Struct<G, F> {// uncomment when we no longer print out Program
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// self.format(f)
// }
// }
impl<F: Field + PrimeField> fmt::Debug for Struct<F> {
impl<G: Group, F: Field + PrimeField> fmt::Debug for Struct<G, F> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.format(f)
}
}
impl<F: Field + PrimeField> fmt::Display for InputModel<F> {
impl<G: Group, F: Field + PrimeField> fmt::Display for InputModel<G, F> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let visibility = if self.private { "private" } else { "public" };
write!(f, "{}: {} {}", self.variable, visibility, self._type,)
}
}
impl<F: Field + PrimeField> fmt::Display for InputValue<F> {
impl<G: Group, F: Field + PrimeField> fmt::Display for InputValue<G, F> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
InputValue::Integer(ref integer) => write!(f, "{}", integer),
@ -345,7 +347,7 @@ impl fmt::Debug for FunctionName {
}
}
impl<F: Field + PrimeField> Function<F> {
impl<G: Group, F: Field + PrimeField> Function<G, F> {
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "function {}", self.function_name)?;
let parameters = self
@ -376,13 +378,13 @@ impl<F: Field + PrimeField> Function<F> {
}
}
// impl<F: Field + PrimeField> fmt::Display for Function<F> {// uncomment when we no longer print out Program
// impl<G: Group, F: Field + PrimeField> fmt::Display for Function<G, F> {// uncomment when we no longer print out Program
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// self.format(f)
// }
// }
impl<F: Field + PrimeField> fmt::Debug for Function<F> {
impl<G: Group, F: Field + PrimeField> fmt::Debug for Function<G, F> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.format(f)
}

View File

@ -2,7 +2,7 @@
use crate::{ast, types, Import, ImportSymbol};
use snarkos_models::curves::{Field, PrimeField};
use snarkos_models::curves::{Field, PrimeField, Group};
use snarkos_models::gadgets::utilities::{
boolean::Boolean, uint128::UInt128, uint16::UInt16, uint32::UInt32, uint64::UInt64,
uint8::UInt8,
@ -11,16 +11,17 @@ use std::{collections::HashMap, marker::PhantomData};
/// pest ast -> types::Variable
impl<'ast, F: Field + PrimeField> From<ast::Variable<'ast>> for types::Variable<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::Variable<'ast>> for types::Variable<G, F> {
fn from(variable: ast::Variable<'ast>) -> Self {
types::Variable {
name: variable.value,
_field: PhantomData::<F>,
_engine: PhantomData::<F>,
_group: PhantomData::<G>,
}
}
}
impl<'ast, F: Field + PrimeField> From<ast::Variable<'ast>> for types::Expression<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::Variable<'ast>> for types::Expression<G, F> {
fn from(variable: ast::Variable<'ast>) -> Self {
types::Expression::Variable(types::Variable::from(variable))
}
@ -49,7 +50,7 @@ impl<'ast> types::Integer {
}
}
impl<'ast, F: Field + PrimeField> From<ast::Integer<'ast>> for types::Expression<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::Integer<'ast>> for types::Expression<G, F> {
fn from(field: ast::Integer<'ast>) -> Self {
types::Expression::Integer(match field._type {
Some(_type) => types::Integer::from(field.number, _type),
@ -65,21 +66,21 @@ impl<'ast, F: Field + PrimeField> From<ast::Integer<'ast>> for types::Expression
}
}
impl<'ast, F: Field + PrimeField> From<ast::RangeOrExpression<'ast>>
for types::RangeOrExpression<F>
impl<'ast, G: Group, F: Field + PrimeField> From<ast::RangeOrExpression<'ast>>
for types::RangeOrExpression<G, F>
{
fn from(range_or_expression: ast::RangeOrExpression<'ast>) -> Self {
match range_or_expression {
ast::RangeOrExpression::Range(range) => {
let from = range
.from
.map(|from| match types::Expression::<F>::from(from.0) {
.map(|from| match types::Expression::<G, F>::from(from.0) {
types::Expression::Integer(number) => number,
expression => {
unimplemented!("Range bounds should be integers, found {}", expression)
}
});
let to = range.to.map(|to| match types::Expression::<F>::from(to.0) {
let to = range.to.map(|to| match types::Expression::<G, F>::from(to.0) {
types::Expression::Integer(number) => number,
expression => {
unimplemented!("Range bounds should be integers, found {}", expression)
@ -95,9 +96,9 @@ impl<'ast, F: Field + PrimeField> From<ast::RangeOrExpression<'ast>>
}
}
/// pest ast -> types::FieldExpression
/// pest ast -> types::Field
impl<'ast, F: Field + PrimeField> From<ast::Field<'ast>> for types::Expression<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::Field<'ast>> for types::Expression<G, F> {
fn from(field: ast::Field<'ast>) -> Self {
types::Expression::FieldElement(types::FieldElement::Constant(
F::from_str(&field.number.value).unwrap_or_default(),
@ -105,9 +106,17 @@ impl<'ast, F: Field + PrimeField> From<ast::Field<'ast>> for types::Expression<F
}
}
/// pest ast -> types::Group
impl<'ast, G: Group, F: Field + PrimeField> From<ast::Group<'ast>> for types::Expression<G, F> {
fn from(_group: ast::Group<'ast>) -> Self {
types::Expression::GroupElement(G::zero())
}
}
/// pest ast -> types::Boolean
impl<'ast, F: Field + PrimeField> From<ast::Boolean<'ast>> for types::Expression<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::Boolean<'ast>> for types::Expression<G, F> {
fn from(boolean: ast::Boolean<'ast>) -> Self {
types::Expression::Boolean(Boolean::Constant(
boolean
@ -120,24 +129,25 @@ impl<'ast, F: Field + PrimeField> From<ast::Boolean<'ast>> for types::Expression
/// pest ast -> types::Expression
impl<'ast, F: Field + PrimeField> From<ast::Value<'ast>> for types::Expression<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::Value<'ast>> for types::Expression<G, F> {
fn from(value: ast::Value<'ast>) -> Self {
match value {
ast::Value::Integer(num) => types::Expression::from(num),
ast::Value::Field(fe) => types::Expression::from(fe),
ast::Value::Group(group) => unimplemented!("no groups yet"),
ast::Value::Boolean(bool) => types::Expression::from(bool),
}
}
}
impl<'ast, F: Field + PrimeField> From<ast::NotExpression<'ast>> for types::Expression<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::NotExpression<'ast>> for types::Expression<G, F> {
fn from(expression: ast::NotExpression<'ast>) -> Self {
types::Expression::Not(Box::new(types::Expression::from(*expression.expression)))
}
}
impl<'ast, F: Field + PrimeField> From<ast::SpreadOrExpression<'ast>>
for types::SpreadOrExpression<F>
impl<'ast, G: Group, F: Field + PrimeField> From<ast::SpreadOrExpression<'ast>>
for types::SpreadOrExpression<G, F>
{
fn from(s_or_e: ast::SpreadOrExpression<'ast>) -> Self {
match s_or_e {
@ -151,7 +161,7 @@ impl<'ast, F: Field + PrimeField> From<ast::SpreadOrExpression<'ast>>
}
}
impl<'ast, F: Field + PrimeField> From<ast::BinaryExpression<'ast>> for types::Expression<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::BinaryExpression<'ast>> for types::Expression<G, F> {
fn from(expression: ast::BinaryExpression<'ast>) -> Self {
match expression.operation {
// Boolean operations
@ -211,7 +221,7 @@ impl<'ast, F: Field + PrimeField> From<ast::BinaryExpression<'ast>> for types::E
}
}
impl<'ast, F: Field + PrimeField> From<ast::TernaryExpression<'ast>> for types::Expression<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::TernaryExpression<'ast>> for types::Expression<G, F> {
fn from(expression: ast::TernaryExpression<'ast>) -> Self {
types::Expression::IfElse(
Box::new(types::Expression::from(*expression.first)),
@ -221,7 +231,7 @@ impl<'ast, F: Field + PrimeField> From<ast::TernaryExpression<'ast>> for types::
}
}
impl<'ast, F: Field + PrimeField> From<ast::ArrayInlineExpression<'ast>> for types::Expression<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::ArrayInlineExpression<'ast>> for types::Expression<G, F> {
fn from(array: ast::ArrayInlineExpression<'ast>) -> Self {
types::Expression::Array(
array
@ -232,18 +242,18 @@ impl<'ast, F: Field + PrimeField> From<ast::ArrayInlineExpression<'ast>> for typ
)
}
}
impl<'ast, F: Field + PrimeField> From<ast::ArrayInitializerExpression<'ast>>
for types::Expression<F>
impl<'ast, G: Group, F: Field + PrimeField> From<ast::ArrayInitializerExpression<'ast>>
for types::Expression<G, F>
{
fn from(array: ast::ArrayInitializerExpression<'ast>) -> Self {
let count = types::Expression::<F>::get_count(array.count);
let count = types::Expression::<G, F>::get_count(array.count);
let expression = Box::new(types::SpreadOrExpression::from(*array.expression));
types::Expression::Array(vec![expression; count])
}
}
impl<'ast, F: Field + PrimeField> From<ast::InlineStructMember<'ast>> for types::StructMember<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::InlineStructMember<'ast>> for types::StructMember<G, F> {
fn from(member: ast::InlineStructMember<'ast>) -> Self {
types::StructMember {
variable: types::Variable::from(member.variable),
@ -252,20 +262,20 @@ impl<'ast, F: Field + PrimeField> From<ast::InlineStructMember<'ast>> for types:
}
}
impl<'ast, F: Field + PrimeField> From<ast::StructInlineExpression<'ast>> for types::Expression<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::StructInlineExpression<'ast>> for types::Expression<G, F> {
fn from(expression: ast::StructInlineExpression<'ast>) -> Self {
let variable = types::Variable::from(expression.variable);
let members = expression
.members
.into_iter()
.map(|member| types::StructMember::from(member))
.collect::<Vec<types::StructMember<F>>>();
.collect::<Vec<types::StructMember<G, F>>>();
types::Expression::Struct(variable, members)
}
}
impl<'ast, F: Field + PrimeField> From<ast::PostfixExpression<'ast>> for types::Expression<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::PostfixExpression<'ast>> for types::Expression<G, F> {
fn from(expression: ast::PostfixExpression<'ast>) -> Self {
let variable = types::Expression::Variable(types::Variable::from(expression.variable));
@ -302,7 +312,7 @@ impl<'ast, F: Field + PrimeField> From<ast::PostfixExpression<'ast>> for types::
}
}
impl<'ast, F: Field + PrimeField> From<ast::Expression<'ast>> for types::Expression<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::Expression<'ast>> for types::Expression<G, F> {
fn from(expression: ast::Expression<'ast>) -> Self {
match expression {
ast::Expression::Value(value) => types::Expression::from(value),
@ -318,7 +328,7 @@ impl<'ast, F: Field + PrimeField> From<ast::Expression<'ast>> for types::Express
}
}
impl<'ast, F: Field + PrimeField> types::Expression<F> {
impl<'ast, G: Group, F: Field + PrimeField> types::Expression<G, F> {
fn get_count(count: ast::Value<'ast>) -> usize {
match count {
ast::Value::Integer(f) => f
@ -332,7 +342,7 @@ impl<'ast, F: Field + PrimeField> types::Expression<F> {
}
// ast::Assignee -> types::Expression for operator assign statements
impl<'ast, F: Field + PrimeField> From<ast::Assignee<'ast>> for types::Expression<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::Assignee<'ast>> for types::Expression<G, F> {
fn from(assignee: ast::Assignee<'ast>) -> Self {
let variable = types::Expression::Variable(types::Variable::from(assignee.variable));
@ -357,13 +367,13 @@ impl<'ast, F: Field + PrimeField> From<ast::Assignee<'ast>> for types::Expressio
/// pest ast -> types::Assignee
impl<'ast, F: Field + PrimeField> From<ast::Variable<'ast>> for types::Assignee<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::Variable<'ast>> for types::Assignee<G, F> {
fn from(variable: ast::Variable<'ast>) -> Self {
types::Assignee::Variable(types::Variable::from(variable))
}
}
impl<'ast, F: Field + PrimeField> From<ast::Assignee<'ast>> for types::Assignee<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::Assignee<'ast>> for types::Assignee<G, F> {
fn from(assignee: ast::Assignee<'ast>) -> Self {
let variable = types::Assignee::from(assignee.variable);
@ -386,7 +396,7 @@ impl<'ast, F: Field + PrimeField> From<ast::Assignee<'ast>> for types::Assignee<
/// pest ast -> types::Statement
impl<'ast, F: Field + PrimeField> From<ast::ReturnStatement<'ast>> for types::Statement<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::ReturnStatement<'ast>> for types::Statement<G, F> {
fn from(statement: ast::ReturnStatement<'ast>) -> Self {
types::Statement::Return(
statement
@ -398,17 +408,17 @@ impl<'ast, F: Field + PrimeField> From<ast::ReturnStatement<'ast>> for types::St
}
}
impl<'ast, F: Field + PrimeField> From<ast::DefinitionStatement<'ast>> for types::Statement<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::DefinitionStatement<'ast>> for types::Statement<G, F> {
fn from(statement: ast::DefinitionStatement<'ast>) -> Self {
types::Statement::Definition(
types::Assignee::from(statement.variable),
statement._type.map(|_type| types::Type::<F>::from(_type)),
statement._type.map(|_type| types::Type::<G, F>::from(_type)),
types::Expression::from(statement.expression),
)
}
}
impl<'ast, F: Field + PrimeField> From<ast::AssignStatement<'ast>> for types::Statement<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::AssignStatement<'ast>> for types::Statement<G, F> {
fn from(statement: ast::AssignStatement<'ast>) -> Self {
match statement.assign {
ast::OperationAssign::Assign(ref _assign) => types::Statement::Assign(
@ -464,8 +474,8 @@ impl<'ast, F: Field + PrimeField> From<ast::AssignStatement<'ast>> for types::St
}
}
impl<'ast, F: Field + PrimeField> From<ast::MultipleAssignmentStatement<'ast>>
for types::Statement<F>
impl<'ast, G: Group, F: Field + PrimeField> From<ast::MultipleAssignmentStatement<'ast>>
for types::Statement<G, F>
{
fn from(statement: ast::MultipleAssignmentStatement<'ast>) -> Self {
let assignees = statement
@ -488,8 +498,8 @@ impl<'ast, F: Field + PrimeField> From<ast::MultipleAssignmentStatement<'ast>>
}
}
impl<'ast, F: Field + PrimeField> From<ast::ConditionalNestedOrEnd<'ast>>
for types::ConditionalNestedOrEnd<F>
impl<'ast, G: Group, F: Field + PrimeField> From<ast::ConditionalNestedOrEnd<'ast>>
for types::ConditionalNestedOrEnd<G, F>
{
fn from(statement: ast::ConditionalNestedOrEnd<'ast>) -> Self {
match statement {
@ -506,8 +516,8 @@ impl<'ast, F: Field + PrimeField> From<ast::ConditionalNestedOrEnd<'ast>>
}
}
impl<'ast, F: Field + PrimeField> From<ast::ConditionalStatement<'ast>>
for types::ConditionalStatement<F>
impl<'ast, G: Group, F: Field + PrimeField> From<ast::ConditionalStatement<'ast>>
for types::ConditionalStatement<G, F>
{
fn from(statement: ast::ConditionalStatement<'ast>) -> Self {
types::ConditionalStatement {
@ -525,13 +535,13 @@ impl<'ast, F: Field + PrimeField> From<ast::ConditionalStatement<'ast>>
}
}
impl<'ast, F: Field + PrimeField> From<ast::ForStatement<'ast>> for types::Statement<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::ForStatement<'ast>> for types::Statement<G, F> {
fn from(statement: ast::ForStatement<'ast>) -> Self {
let from = match types::Expression::<F>::from(statement.start) {
let from = match types::Expression::<G, F>::from(statement.start) {
types::Expression::Integer(number) => number,
expression => unimplemented!("Range bounds should be integers, found {}", expression),
};
let to = match types::Expression::<F>::from(statement.stop) {
let to = match types::Expression::<G, F>::from(statement.stop) {
types::Expression::Integer(number) => number,
expression => unimplemented!("Range bounds should be integers, found {}", expression),
};
@ -549,7 +559,7 @@ impl<'ast, F: Field + PrimeField> From<ast::ForStatement<'ast>> for types::State
}
}
impl<'ast, F: Field + PrimeField> From<ast::AssertStatement<'ast>> for types::Statement<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::AssertStatement<'ast>> for types::Statement<G, F> {
fn from(statement: ast::AssertStatement<'ast>) -> Self {
match statement {
ast::AssertStatement::AssertEq(assert_eq) => types::Statement::AssertEq(
@ -560,13 +570,13 @@ impl<'ast, F: Field + PrimeField> From<ast::AssertStatement<'ast>> for types::St
}
}
impl<'ast, F: Field + PrimeField> From<ast::ExpressionStatement<'ast>> for types::Statement<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::ExpressionStatement<'ast>> for types::Statement<G, F> {
fn from(statement: ast::ExpressionStatement<'ast>) -> Self {
types::Statement::Expression(types::Expression::from(statement.expression))
}
}
impl<'ast, F: Field + PrimeField> From<ast::Statement<'ast>> for types::Statement<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::Statement<'ast>> for types::Statement<G, F> {
fn from(statement: ast::Statement<'ast>) -> Self {
match statement {
ast::Statement::Return(statement) => types::Statement::from(statement),
@ -597,36 +607,37 @@ impl From<ast::IntegerType> for types::IntegerType {
}
}
impl<'ast, F: Field + PrimeField> From<ast::BasicType<'ast>> for types::Type<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::BasicType<'ast>> for types::Type<G, F> {
fn from(basic_type: ast::BasicType<'ast>) -> Self {
match basic_type {
ast::BasicType::Integer(ty) => types::Type::IntegerType(types::IntegerType::from(ty)),
ast::BasicType::Field(_ty) => types::Type::FieldElement,
ast::BasicType::Boolean(_ty) => types::Type::Boolean,
ast::BasicType::Integer(_type) => types::Type::IntegerType(types::IntegerType::from(_type)),
ast::BasicType::Field(_type) => types::Type::FieldElement,
ast::BasicType::Group(_type) => unimplemented!(),
ast::BasicType::Boolean(_type) => types::Type::Boolean,
}
}
}
impl<'ast, F: Field + PrimeField> From<ast::ArrayType<'ast>> for types::Type<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::ArrayType<'ast>> for types::Type<G, F> {
fn from(array_type: ast::ArrayType<'ast>) -> Self {
let element_type = Box::new(types::Type::from(array_type._type));
let dimensions = array_type
.dimensions
.into_iter()
.map(|row| types::Expression::<F>::get_count(row))
.map(|row| types::Expression::<G, F>::get_count(row))
.collect();
types::Type::Array(element_type, dimensions)
}
}
impl<'ast, F: Field + PrimeField> From<ast::StructType<'ast>> for types::Type<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::StructType<'ast>> for types::Type<G, F> {
fn from(struct_type: ast::StructType<'ast>) -> Self {
types::Type::Struct(types::Variable::from(struct_type.variable))
}
}
impl<'ast, F: Field + PrimeField> From<ast::Type<'ast>> for types::Type<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::Type<'ast>> for types::Type<G, F> {
fn from(_type: ast::Type<'ast>) -> Self {
match _type {
ast::Type::Basic(_type) => types::Type::from(_type),
@ -638,7 +649,7 @@ impl<'ast, F: Field + PrimeField> From<ast::Type<'ast>> for types::Type<F> {
/// pest ast -> types::Struct
impl<'ast, F: Field + PrimeField> From<ast::StructField<'ast>> for types::StructField<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::StructField<'ast>> for types::StructField<G, F> {
fn from(struct_field: ast::StructField<'ast>) -> Self {
types::StructField {
variable: types::Variable::from(struct_field.variable),
@ -647,7 +658,7 @@ impl<'ast, F: Field + PrimeField> From<ast::StructField<'ast>> for types::Struct
}
}
impl<'ast, F: Field + PrimeField> From<ast::Struct<'ast>> for types::Struct<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::Struct<'ast>> for types::Struct<G, F> {
fn from(struct_definition: ast::Struct<'ast>) -> Self {
let variable = types::Variable::from(struct_definition.variable);
let fields = struct_definition
@ -662,7 +673,7 @@ impl<'ast, F: Field + PrimeField> From<ast::Struct<'ast>> for types::Struct<F> {
/// pest ast -> function types::Parameters
impl<'ast, F: Field + PrimeField> From<ast::Parameter<'ast>> for types::InputModel<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::Parameter<'ast>> for types::InputModel<G, F> {
fn from(parameter: ast::Parameter<'ast>) -> Self {
let _type = types::Type::from(parameter._type);
let variable = types::Variable::from(parameter.variable);
@ -695,7 +706,7 @@ impl<'ast> From<ast::FunctionName<'ast>> for types::FunctionName {
}
}
impl<'ast, F: Field + PrimeField> From<ast::Function<'ast>> for types::Function<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::Function<'ast>> for types::Function<G, F> {
fn from(function_definition: ast::Function<'ast>) -> Self {
let function_name = types::FunctionName::from(function_definition.function_name);
let parameters = function_definition
@ -725,7 +736,7 @@ impl<'ast, F: Field + PrimeField> From<ast::Function<'ast>> for types::Function<
/// pest ast -> Import
impl<'ast, F: Field + PrimeField> From<ast::ImportSymbol<'ast>> for ImportSymbol<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::ImportSymbol<'ast>> for ImportSymbol<G, F> {
fn from(symbol: ast::ImportSymbol<'ast>) -> Self {
ImportSymbol {
symbol: types::Variable::from(symbol.value),
@ -734,7 +745,7 @@ impl<'ast, F: Field + PrimeField> From<ast::ImportSymbol<'ast>> for ImportSymbol
}
}
impl<'ast, F: Field + PrimeField> From<ast::Import<'ast>> for Import<F> {
impl<'ast, G: Group, F: Field + PrimeField> From<ast::Import<'ast>> for Import<G, F> {
fn from(import: ast::Import<'ast>) -> Self {
Import {
path_string: import.source.value,
@ -749,14 +760,14 @@ impl<'ast, F: Field + PrimeField> From<ast::Import<'ast>> for Import<F> {
/// pest ast -> types::Program
impl<'ast, F: Field + PrimeField> types::Program<F> {
impl<'ast, G: Group, F: Field + PrimeField> types::Program<G, F> {
pub fn from(file: ast::File<'ast>, name: String) -> Self {
// Compiled ast -> aleo program representation
let imports = file
.imports
.into_iter()
.map(|import| Import::from(import))
.collect::<Vec<Import<F>>>();
.collect::<Vec<Import<G, F>>>();
let mut structs = HashMap::new();
let mut functions = HashMap::new();
@ -782,7 +793,8 @@ impl<'ast, F: Field + PrimeField> types::Program<F> {
types::Program {
name: types::Variable {
name,
_field: PhantomData::<F>,
_group: PhantomData::<G>,
_engine: PhantomData::<F>,
},
num_parameters,
imports,

View File

@ -0,0 +1,2 @@
// 3 bit Pedersen hash function
fn main() ->