mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-09-11 05:45:30 +03:00
commit
74b9a27735
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -478,7 +478,6 @@ dependencies = [
|
||||
"clap",
|
||||
"colored",
|
||||
"env_logger",
|
||||
"failure",
|
||||
"from-pest",
|
||||
"leo-compiler",
|
||||
"log",
|
||||
@ -493,6 +492,7 @@ dependencies = [
|
||||
"snarkos-models",
|
||||
"snarkos-utilities",
|
||||
"structopt",
|
||||
"thiserror",
|
||||
"toml",
|
||||
]
|
||||
|
||||
|
@ -28,7 +28,6 @@ snarkos-utilities = { path = "../snarkOS/utilities", version = "0.8.0" }
|
||||
clap = { version = "2.33.0" }
|
||||
colored = { version = "1.9" }
|
||||
env_logger = { version = "0.7" }
|
||||
failure = { version = "0.1.5" }
|
||||
from-pest = { version = "0.3.1" }
|
||||
log = { version = "0.4" }
|
||||
rand = { version = "0.7" }
|
||||
@ -37,3 +36,4 @@ serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = { version = "1.0" }
|
||||
structopt = { version = "0.3.14" }
|
||||
toml = { version = "0.5" }
|
||||
thiserror = { version = "1.0" }
|
||||
|
@ -1,17 +1,3 @@
|
||||
struct Foo {
|
||||
b: u32
|
||||
}
|
||||
|
||||
function main() {
|
||||
let a = 1u8 + 1u8;
|
||||
let c = 1u16 + 1u16;
|
||||
let b = 1u32 + 1;
|
||||
let d = 1u64 + 1u64;
|
||||
let e = 1u128 + 1u128;
|
||||
let f = true && false;
|
||||
let g = 5fe + 10fe;
|
||||
let h: u32[2] = [1, 2];
|
||||
|
||||
let i = Foo { b: 5 };
|
||||
let j = [1, 4, 5];
|
||||
let g = 0group;
|
||||
}
|
@ -6,7 +6,9 @@ use snarkos_algorithms::snark::{
|
||||
create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof,
|
||||
};
|
||||
use snarkos_curves::bls12_377::{Bls12_377, Fr};
|
||||
use snarkos_curves::edwards_bls12::EdwardsProjective;
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::curves::Group;
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::r1cs::{ConstraintSynthesizer, ConstraintSystem},
|
||||
@ -18,17 +20,19 @@ use std::{
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Benchmark<F: Field + PrimeField> {
|
||||
program: Program<F>,
|
||||
parameters: Vec<Option<InputValue<F>>>,
|
||||
pub struct Benchmark<F: Field + PrimeField, G: Group> {
|
||||
program: Program<F, G>,
|
||||
parameters: Vec<Option<InputValue<F, G>>>,
|
||||
_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,
|
||||
}
|
||||
}
|
||||
@ -42,10 +46,9 @@ impl<F: Field + PrimeField> Benchmark<F> {
|
||||
|
||||
// Build the abstract syntax tree
|
||||
let syntax_tree = ast::File::from_pest(&mut file).expect("infallible");
|
||||
// println!("{:#?}", syntax_tree);
|
||||
|
||||
// Build a leo program from the syntax tree
|
||||
self.program = Program::<F>::from(syntax_tree, "simple".into());
|
||||
self.program = Program::<F, G>::from(syntax_tree, "simple".into());
|
||||
self.parameters = vec![None; self.program.num_parameters];
|
||||
|
||||
println!(" compiled: {:#?}\n", self.program);
|
||||
@ -54,13 +57,12 @@ 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,
|
||||
) -> Result<(), SynthesisError> {
|
||||
let _res =
|
||||
leo_compiler::generate_constraints(cs, self.program, self.parameters).unwrap();
|
||||
let _res = leo_compiler::generate_constraints(cs, self.program, self.parameters).unwrap();
|
||||
println!(" Result: {}", _res);
|
||||
|
||||
// Write results to file or something
|
||||
@ -79,7 +81,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
|
||||
@ -92,7 +94,12 @@ fn main() {
|
||||
let start = Instant::now();
|
||||
|
||||
// Set main function arguments in compiled program
|
||||
// let argument = Some(ParameterValue::Field(Fr::one()));
|
||||
// let argument = Some(InputValue::Field(Fr::one()));
|
||||
|
||||
// let bool_true = InputValue::Boolean(true);
|
||||
// let array = InputValue::Array(vec![bool_true.clone(), bool_true.clone(), bool_true.clone()]);
|
||||
// let argument = Some(array);
|
||||
//
|
||||
// program.parameters = vec![argument];
|
||||
|
||||
// Generate proof
|
||||
|
@ -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>),
|
||||
}
|
||||
|
||||
@ -193,7 +201,7 @@ pub enum BasicOrStructType<'ast> {
|
||||
#[pest_ast(rule(Rule::type_array))]
|
||||
pub struct ArrayType<'ast> {
|
||||
pub _type: BasicType<'ast>,
|
||||
pub count: Value<'ast>,
|
||||
pub dimensions: Vec<Value<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
@ -262,6 +270,21 @@ 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>,
|
||||
pub _type: GroupType<'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 +305,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 +314,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 +325,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),
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ use crate::{
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
curves::{Field, Group, 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<F: Field + PrimeField, G: Group> {
|
||||
package_name: String,
|
||||
main_file_path: PathBuf,
|
||||
program: Program<F>,
|
||||
program_inputs: Vec<Option<InputValue<F>>>,
|
||||
output: Option<ConstrainedValue<F>>,
|
||||
program: Program<F, G>,
|
||||
program_inputs: Vec<Option<InputValue<F, G>>>,
|
||||
output: Option<ConstrainedValue<F, G>>,
|
||||
_engine: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField> Compiler<F> {
|
||||
impl<F: Field + PrimeField, G: Group> Compiler<F, G> {
|
||||
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::<F, G>::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<F: Field + PrimeField, G: Group> ConstraintSynthesizer<F> for Compiler<F, G> {
|
||||
fn generate_constraints<CS: ConstraintSystem<F>>(
|
||||
self,
|
||||
cs: &mut CS,
|
||||
|
@ -1,43 +1,42 @@
|
||||
//! Methods to enforce constraints on booleans in a resolved Leo program.
|
||||
|
||||
use crate::{
|
||||
constraints::{new_variable_from_variable, ConstrainedProgram, ConstrainedValue},
|
||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
||||
errors::BooleanError,
|
||||
types::{InputModel, InputValue, Variable},
|
||||
types::{InputModel, InputValue},
|
||||
};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
curves::{Field, Group, PrimeField},
|
||||
gadgets::{
|
||||
r1cs::ConstraintSystem,
|
||||
utilities::{alloc::AllocGadget, boolean::Boolean, eq::EqGadget},
|
||||
},
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
pub(crate) fn bool_from_parameter(
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn bool_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
scope: String,
|
||||
parameter_model: InputModel<F>,
|
||||
parameter_value: Option<InputValue<F>>,
|
||||
) -> Result<Variable<F>, BooleanError> {
|
||||
// Check that the parameter value is the correct type
|
||||
let bool_value = match parameter_value {
|
||||
Some(parameter) => {
|
||||
if let InputValue::Boolean(bool) = parameter {
|
||||
input_model: InputModel<F, G>,
|
||||
input_value: Option<InputValue<F, G>>,
|
||||
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||
// Check that the input value is the correct type
|
||||
let bool_value = match input_value {
|
||||
Some(input) => {
|
||||
if let InputValue::Boolean(bool) = input {
|
||||
Some(bool)
|
||||
} else {
|
||||
return Err(BooleanError::InvalidBoolean(parameter.to_string()));
|
||||
return Err(BooleanError::InvalidBoolean(input.to_string()));
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
// Check visibility of parameter
|
||||
let name = parameter_model.variable.name.clone();
|
||||
let number = if parameter_model.private {
|
||||
// Check visibility of input
|
||||
let name = input_model.variable.name.clone();
|
||||
let number = if input_model.private {
|
||||
Boolean::alloc(cs.ns(|| name), || {
|
||||
bool_value.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?
|
||||
@ -47,54 +46,16 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
})?
|
||||
};
|
||||
|
||||
let parameter_variable = new_variable_from_variable(scope, ¶meter_model.variable);
|
||||
|
||||
// store each argument as variable in resolved program
|
||||
self.store_variable(
|
||||
parameter_variable.clone(),
|
||||
ConstrainedValue::Boolean(number),
|
||||
);
|
||||
|
||||
Ok(parameter_variable)
|
||||
Ok(ConstrainedValue::Boolean(number))
|
||||
}
|
||||
|
||||
pub(crate) fn boolean_array_from_parameter(
|
||||
&mut self,
|
||||
_cs: &mut CS,
|
||||
_scope: String,
|
||||
_parameter_model: InputModel<F>,
|
||||
_parameter_value: Option<InputValue<F>>,
|
||||
) -> Result<Variable<F>, BooleanError> {
|
||||
unimplemented!("Cannot enforce boolean array as parameter")
|
||||
// // Check visibility of parameter
|
||||
// let mut array_value = vec![];
|
||||
// let name = parameter.variable.name.clone();
|
||||
// for argument in argument_array {
|
||||
// let number = if parameter.private {
|
||||
// Boolean::alloc(cs.ns(|| name), ||bool_value.ok_or(SynthesisError::AssignmentMissing).unwrap()
|
||||
// } else {
|
||||
// Boolean::alloc_input(cs.ns(|| name), || Ok(argument)).unwrap()
|
||||
// };
|
||||
//
|
||||
// array_value.push(number);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// let parameter_variable = new_variable_from_variable(scope, ¶meter.variable);
|
||||
//
|
||||
// // store array as variable in resolved program
|
||||
// self.store_variable(parameter_variable.clone(), ResolvedValue::BooleanArray(array_value));
|
||||
//
|
||||
// parameter_variable
|
||||
}
|
||||
|
||||
pub(crate) fn get_boolean_constant(bool: Boolean) -> ConstrainedValue<F> {
|
||||
pub(crate) fn get_boolean_constant(bool: Boolean) -> ConstrainedValue<F, G> {
|
||||
ConstrainedValue::Boolean(bool)
|
||||
}
|
||||
|
||||
pub(crate) fn evaluate_not(
|
||||
value: ConstrainedValue<F>,
|
||||
) -> Result<ConstrainedValue<F>, BooleanError> {
|
||||
value: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||
match value {
|
||||
ConstrainedValue::Boolean(boolean) => Ok(ConstrainedValue::Boolean(boolean.not())),
|
||||
value => Err(BooleanError::CannotEvaluate(format!("!{}", value))),
|
||||
@ -104,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<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||
match (left, right) {
|
||||
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => Ok(
|
||||
ConstrainedValue::Boolean(Boolean::or(cs, &left_bool, &right_bool)?),
|
||||
@ -121,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<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||
match (left, right) {
|
||||
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => Ok(
|
||||
ConstrainedValue::Boolean(Boolean::and(cs, &left_bool, &right_bool)?),
|
||||
@ -135,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<F, G> {
|
||||
ConstrainedValue::Boolean(Boolean::Constant(left.eq(&right)))
|
||||
}
|
||||
|
||||
|
@ -10,17 +10,17 @@ use crate::{
|
||||
};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
curves::{Field, Group, PrimeField},
|
||||
gadgets::{r1cs::ConstraintSystem, utilities::boolean::Boolean},
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, 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<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, 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<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
Ok(match (left, right) {
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
Self::enforce_integer_add(cs, num_1, num_2)?
|
||||
@ -51,6 +51,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
(ConstrainedValue::FieldElement(fe_1), ConstrainedValue::FieldElement(fe_2)) => {
|
||||
self.enforce_field_add(cs, fe_1, fe_2)?
|
||||
}
|
||||
(ConstrainedValue::GroupElement(ge_1), ConstrainedValue::GroupElement(ge_2)) => {
|
||||
Self::evaluate_group_add(ge_1, ge_2)
|
||||
}
|
||||
(val_1, val_2) => {
|
||||
return Err(ExpressionError::IncompatibleTypes(format!(
|
||||
"{} + {}",
|
||||
@ -63,9 +66,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<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
Ok(match (left, right) {
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
Self::enforce_integer_sub(cs, num_1, num_2)?
|
||||
@ -73,6 +76,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
(ConstrainedValue::FieldElement(fe_1), ConstrainedValue::FieldElement(fe_2)) => {
|
||||
self.enforce_field_sub(cs, fe_1, fe_2)?
|
||||
}
|
||||
(ConstrainedValue::GroupElement(ge_1), ConstrainedValue::GroupElement(ge_2)) => {
|
||||
Self::evaluate_group_sub(ge_1, ge_2)
|
||||
}
|
||||
(val_1, val_2) => {
|
||||
return Err(ExpressionError::IncompatibleTypes(format!(
|
||||
"{} - {}",
|
||||
@ -85,9 +91,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<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
Ok(match (left, right) {
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
Self::enforce_integer_mul(cs, num_1, num_2)?
|
||||
@ -107,9 +113,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<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
Ok(match (left, right) {
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
Self::enforce_integer_div(cs, num_1, num_2)?
|
||||
@ -128,9 +134,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<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
Ok(match (left, right) {
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
Self::enforce_integer_pow(cs, num_1, num_2)?
|
||||
@ -153,9 +159,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<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
Ok(match (left, right) {
|
||||
(ConstrainedValue::Boolean(bool_1), ConstrainedValue::Boolean(bool_2)) => {
|
||||
Self::boolean_eq(bool_1, bool_2)
|
||||
@ -166,6 +172,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
|
||||
// Self::field_eq(fe_1, fe_2)
|
||||
// }
|
||||
(ConstrainedValue::GroupElement(ge_1), ConstrainedValue::GroupElement(ge_2)) => {
|
||||
Self::evaluate_group_eq(ge_1, ge_2)
|
||||
}
|
||||
(val_1, val_2) => {
|
||||
return Err(ExpressionError::IncompatibleTypes(format!(
|
||||
"{} == {}",
|
||||
@ -177,9 +186,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<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match (left, right) {
|
||||
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
|
||||
// Self::field_geq(fe_1, fe_2)
|
||||
@ -193,9 +202,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<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match (left, right) {
|
||||
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
|
||||
// Self::field_gt(fe_1, fe_2)
|
||||
@ -209,9 +218,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<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match (left, right) {
|
||||
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
|
||||
// Self::field_leq(fe_1, fe_2)
|
||||
@ -225,9 +234,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<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match (left, right) {
|
||||
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
|
||||
// Self::field_lt(fe_1, fe_2)
|
||||
@ -245,8 +254,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<F, G>>>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
let mut result = vec![];
|
||||
for element in array.into_iter() {
|
||||
match *element {
|
||||
@ -283,7 +292,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<F, G>,
|
||||
) -> Result<usize, ExpressionError> {
|
||||
match self.enforce_expression(cs, file_scope, function_scope, index)? {
|
||||
ConstrainedValue::Integer(number) => Ok(number.to_usize()),
|
||||
@ -296,9 +305,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<F, G>>,
|
||||
index: RangeOrExpression<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match self.enforce_expression(cs, file_scope.clone(), function_scope.clone(), *array)? {
|
||||
ConstrainedValue::Array(array) => {
|
||||
match index {
|
||||
@ -331,9 +340,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<F, G>,
|
||||
members: Vec<StructMember<F, G>>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
let struct_name = new_variable_from_variable(file_scope.clone(), &variable);
|
||||
|
||||
if let Some(ConstrainedValue::StructDefinition(struct_definition)) =
|
||||
@ -360,6 +369,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
member.expression,
|
||||
)?;
|
||||
|
||||
// Check member types
|
||||
member_value.expect_type(&field._type)?;
|
||||
|
||||
resolved_members.push(ConstrainedStructMember(member.variable, member_value))
|
||||
}
|
||||
|
||||
@ -377,9 +389,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<F, G>>,
|
||||
struct_member: Variable<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, 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);
|
||||
@ -399,9 +411,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<F, G>,
|
||||
arguments: Vec<Expression<F, G>>,
|
||||
) -> Result<ConstrainedValue<F, G>, 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(),
|
||||
@ -426,8 +438,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<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match expression {
|
||||
// Variables
|
||||
Expression::Variable(unresolved_variable) => {
|
||||
@ -437,6 +449,7 @@ 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::GroupElement(gr) => Ok(ConstrainedValue::GroupElement(gr)),
|
||||
Expression::Boolean(bool) => Ok(Self::get_boolean_constant(bool)),
|
||||
|
||||
// Binary operations
|
||||
|
@ -1,40 +1,39 @@
|
||||
//! Methods to enforce constraints on field elements in a resolved Leo program.
|
||||
|
||||
use crate::{
|
||||
constraints::{new_variable_from_variable, ConstrainedProgram, ConstrainedValue},
|
||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
||||
errors::FieldElementError,
|
||||
types::{FieldElement, InputModel, InputValue, Integer, Variable},
|
||||
types::{FieldElement, InputModel, InputValue, Integer},
|
||||
};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
curves::{Field, Group, PrimeField},
|
||||
gadgets::r1cs::{ConstraintSystem, LinearCombination, Variable as R1CSVariable},
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
pub(crate) fn field_element_from_parameter(
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn field_element_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
scope: String,
|
||||
parameter_model: InputModel<F>,
|
||||
parameter_value: Option<InputValue<F>>,
|
||||
) -> Result<Variable<F>, FieldElementError> {
|
||||
input_model: InputModel<F, G>,
|
||||
input_value: Option<InputValue<F, G>>,
|
||||
) -> Result<ConstrainedValue<F, G>, FieldElementError> {
|
||||
// Check that the parameter value is the correct type
|
||||
let field_option = match parameter_value {
|
||||
Some(parameter) => {
|
||||
if let InputValue::Field(fe) = parameter {
|
||||
let field_option = match input_value {
|
||||
Some(input) => {
|
||||
if let InputValue::Field(fe) = input {
|
||||
Some(fe)
|
||||
} else {
|
||||
return Err(FieldElementError::InvalidField(parameter.to_string()));
|
||||
return Err(FieldElementError::InvalidField(input.to_string()));
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
// Check visibility of parameter
|
||||
let name = parameter_model.variable.name.clone();
|
||||
let field_value = if parameter_model.private {
|
||||
let name = input_model.variable.name.clone();
|
||||
let field_value = if input_model.private {
|
||||
cs.alloc(
|
||||
|| name,
|
||||
|| field_option.ok_or(SynthesisError::AssignmentMissing),
|
||||
@ -46,46 +45,13 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
)?
|
||||
};
|
||||
|
||||
let parameter_variable = new_variable_from_variable(scope, ¶meter_model.variable);
|
||||
|
||||
// Store parameter as variable in resolved program
|
||||
self.store_variable(
|
||||
parameter_variable.clone(),
|
||||
ConstrainedValue::FieldElement(FieldElement::Allocated(field_option, field_value)),
|
||||
);
|
||||
|
||||
Ok(parameter_variable)
|
||||
Ok(ConstrainedValue::FieldElement(FieldElement::Allocated(
|
||||
field_option,
|
||||
field_value,
|
||||
)))
|
||||
}
|
||||
|
||||
pub(crate) fn field_element_array_from_parameter(
|
||||
&mut self,
|
||||
_cs: &mut CS,
|
||||
_scope: String,
|
||||
_parameter_model: InputModel<F>,
|
||||
_parameter_value: Option<InputValue<F>>,
|
||||
) -> Result<Variable<F>, FieldElementError> {
|
||||
unimplemented!("Cannot enforce field element array as parameter")
|
||||
// // Check visibility of parameter
|
||||
// let mut array_value = vec![];
|
||||
// let name = parameter.variable.name.clone();
|
||||
// for argument in argument_array {
|
||||
// if parameter.private {
|
||||
// cs.alloc(|| name, || Ok(argument.clone())).unwrap();
|
||||
// } else {
|
||||
// cs.alloc_input(|| name, || Ok(argument.clone())).unwrap();
|
||||
// };
|
||||
// }
|
||||
//
|
||||
//
|
||||
// let parameter_variable = new_variable_from_variable(scope, ¶meter.variable);
|
||||
//
|
||||
// // store array as variable in resolved program
|
||||
// self.store_variable(parameter_variable.clone(), ResolvedValue::FieldElementArray(argument_array));
|
||||
//
|
||||
// parameter_variable
|
||||
}
|
||||
|
||||
pub(crate) fn get_field_element_constant(fe: FieldElement<F>) -> ConstrainedValue<F> {
|
||||
pub(crate) fn get_field_element_constant(fe: FieldElement<F>) -> ConstrainedValue<F, G> {
|
||||
ConstrainedValue::FieldElement(fe)
|
||||
}
|
||||
|
||||
@ -158,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<F, G>, 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)) => {
|
||||
@ -235,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<F, G>, 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)) => {
|
||||
@ -312,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<F, G>, 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)) => {
|
||||
@ -389,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<F, G>, 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)) => {
|
||||
@ -477,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<F, G>, FieldElementError> {
|
||||
Ok(match fe_1 {
|
||||
// if both constants, then return a constant result
|
||||
FieldElement::Constant(fe_1_constant) => ConstrainedValue::FieldElement(
|
||||
|
@ -7,15 +7,17 @@ use crate::{
|
||||
ConstrainedValue,
|
||||
},
|
||||
errors::{FunctionError, ImportError},
|
||||
new_variable_from_variable,
|
||||
types::{Expression, Function, InputValue, Program, Type},
|
||||
InputModel, Variable,
|
||||
};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
curves::{Field, Group, PrimeField},
|
||||
gadgets::r1cs::ConstraintSystem,
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
fn check_inputs_length(expected: usize, actual: usize) -> Result<(), FunctionError> {
|
||||
// Make sure we are given the correct number of arguments
|
||||
if expected != actual {
|
||||
@ -31,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<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||
match input {
|
||||
Expression::Variable(variable) => Ok(self.enforce_variable(caller_scope, variable)?),
|
||||
expression => Ok(self.enforce_expression(cs, scope, function_name, expression)?),
|
||||
@ -44,95 +46,34 @@ 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<F, G>,
|
||||
inputs: Vec<Expression<F, G>>,
|
||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||
let function_name = new_scope(scope.clone(), function.get_name());
|
||||
|
||||
// Make sure we are given the correct number of arguments
|
||||
// Make sure we are given the correct number of inputs
|
||||
Self::check_inputs_length(function.inputs.len(), inputs.len())?;
|
||||
|
||||
// Store argument values as new variables in resolved program
|
||||
// Store input values as new variables in resolved program
|
||||
for (input_model, input_expression) in
|
||||
function.inputs.clone().iter().zip(inputs.into_iter())
|
||||
{
|
||||
// Check that argument is correct type
|
||||
match input_model._type.clone() {
|
||||
Type::IntegerType(integer_type) => {
|
||||
match self.enforce_input(
|
||||
cs,
|
||||
scope.clone(),
|
||||
caller_scope.clone(),
|
||||
function_name.clone(),
|
||||
input_expression,
|
||||
)? {
|
||||
ConstrainedValue::Integer(number) => {
|
||||
number.expect_type(&integer_type)?;
|
||||
// Store argument as variable with {function_name}_{parameter name}
|
||||
let variable_name = new_scope_from_variable(
|
||||
function_name.clone(),
|
||||
&input_model.variable,
|
||||
);
|
||||
self.store(variable_name, ConstrainedValue::Integer(number));
|
||||
}
|
||||
argument => {
|
||||
return Err(FunctionError::InvalidInput(
|
||||
integer_type.to_string(),
|
||||
argument.to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
Type::FieldElement => {
|
||||
match self.enforce_input(
|
||||
cs,
|
||||
scope.clone(),
|
||||
caller_scope.clone(),
|
||||
function_name.clone(),
|
||||
input_expression,
|
||||
)? {
|
||||
ConstrainedValue::FieldElement(fe) => {
|
||||
// Store argument as variable with {function_name}_{parameter name}
|
||||
let variable_name = new_scope_from_variable(
|
||||
function_name.clone(),
|
||||
&input_model.variable,
|
||||
);
|
||||
self.store(variable_name, ConstrainedValue::FieldElement(fe));
|
||||
}
|
||||
argument => {
|
||||
return Err(FunctionError::InvalidInput(
|
||||
Type::<F>::FieldElement.to_string(),
|
||||
argument.to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
Type::Boolean => {
|
||||
match self.enforce_input(
|
||||
cs,
|
||||
scope.clone(),
|
||||
caller_scope.clone(),
|
||||
function_name.clone(),
|
||||
input_expression,
|
||||
)? {
|
||||
ConstrainedValue::Boolean(bool) => {
|
||||
// Store argument as variable with {function_name}_{parameter name}
|
||||
let variable_name = new_scope_from_variable(
|
||||
function_name.clone(),
|
||||
&input_model.variable,
|
||||
);
|
||||
self.store(variable_name, ConstrainedValue::Boolean(bool));
|
||||
}
|
||||
argument => {
|
||||
return Err(FunctionError::InvalidInput(
|
||||
Type::<F>::Boolean.to_string(),
|
||||
argument.to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
ty => return Err(FunctionError::UndefinedInput(ty.to_string())),
|
||||
}
|
||||
// First evaluate input expression
|
||||
let input_value = self.enforce_input(
|
||||
cs,
|
||||
scope.clone(),
|
||||
caller_scope.clone(),
|
||||
function_name.clone(),
|
||||
input_expression,
|
||||
)?;
|
||||
|
||||
// Check that input is correct type
|
||||
input_value.expect_type(&input_model._type)?;
|
||||
|
||||
// Store input as variable with {function_name}_{input_name}
|
||||
let variable_name =
|
||||
new_scope_from_variable(function_name.clone(), &input_model.variable);
|
||||
self.store(variable_name, input_value);
|
||||
}
|
||||
|
||||
// Evaluate function statements
|
||||
@ -155,16 +96,106 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
Ok(return_values)
|
||||
}
|
||||
|
||||
fn allocate_array(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
array_name: Variable<F, G>,
|
||||
array_private: bool,
|
||||
array_type: Type<F, G>,
|
||||
array_dimensions: Vec<usize>,
|
||||
input_value: Option<InputValue<F, G>>,
|
||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||
let expected_length = array_dimensions[0];
|
||||
let mut array_value = vec![];
|
||||
|
||||
match input_value {
|
||||
Some(InputValue::Array(arr)) => {
|
||||
// Check the dimension of the array
|
||||
Self::check_inputs_length(expected_length, arr.len())?;
|
||||
|
||||
// Allocate each value in the current row
|
||||
for (i, value) in arr.into_iter().enumerate() {
|
||||
let array_input_model = InputModel {
|
||||
private: array_private,
|
||||
_type: array_type.next_dimension(&array_dimensions),
|
||||
variable: new_variable_from_variables(
|
||||
&array_name,
|
||||
&Variable::new(i.to_string()),
|
||||
),
|
||||
};
|
||||
|
||||
array_value.push(self.allocate_main_function_input(
|
||||
cs,
|
||||
array_input_model,
|
||||
Some(value),
|
||||
)?)
|
||||
}
|
||||
}
|
||||
None => {
|
||||
// Allocate all row values as none
|
||||
for i in 0..expected_length {
|
||||
let array_input_model = InputModel {
|
||||
private: array_private,
|
||||
_type: array_type.next_dimension(&array_dimensions),
|
||||
variable: new_variable_from_variables(
|
||||
&array_name,
|
||||
&Variable::new(i.to_string()),
|
||||
),
|
||||
};
|
||||
|
||||
array_value.push(self.allocate_main_function_input(
|
||||
cs,
|
||||
array_input_model,
|
||||
None,
|
||||
)?);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(FunctionError::InvalidArray(
|
||||
input_value.unwrap().to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ConstrainedValue::Array(array_value))
|
||||
}
|
||||
|
||||
fn allocate_main_function_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
input_model: InputModel<F, G>,
|
||||
input_value: Option<InputValue<F, G>>,
|
||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||
match input_model._type {
|
||||
Type::IntegerType(ref _integer_type) => {
|
||||
Ok(self.integer_from_parameter(cs, input_model, input_value)?)
|
||||
}
|
||||
Type::FieldElement => {
|
||||
Ok(self.field_element_from_input(cs, input_model, input_value)?)
|
||||
}
|
||||
Type::Boolean => Ok(self.bool_from_input(cs, input_model, input_value)?),
|
||||
Type::Array(_type, dimensions) => self.allocate_array(
|
||||
cs,
|
||||
input_model.variable,
|
||||
input_model.private,
|
||||
*_type,
|
||||
dimensions,
|
||||
input_value,
|
||||
),
|
||||
_ => unimplemented!("main function input not implemented for type"),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn enforce_main_function(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
scope: String,
|
||||
function: Function<F>,
|
||||
inputs: Vec<Option<InputValue<F>>>,
|
||||
) -> Result<ConstrainedValue<F>, FunctionError> {
|
||||
function: Function<F, G>,
|
||||
inputs: Vec<Option<InputValue<F, G>>>,
|
||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||
let function_name = new_scope(scope.clone(), function.get_name());
|
||||
|
||||
// Make sure we are given the correct number of arguments
|
||||
// Make sure we are given the correct number of inputs
|
||||
Self::check_inputs_length(function.inputs.len(), inputs.len())?;
|
||||
|
||||
// Iterate over main function inputs and allocate new passed-by variable values
|
||||
@ -172,46 +203,11 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
for (input_model, input_value) in
|
||||
function.inputs.clone().into_iter().zip(inputs.into_iter())
|
||||
{
|
||||
// append each variable to inputs vector
|
||||
let variable = match input_model._type {
|
||||
Type::IntegerType(ref _integer_type) => self.integer_from_parameter(
|
||||
cs,
|
||||
function_name.clone(),
|
||||
input_model,
|
||||
input_value,
|
||||
)?,
|
||||
Type::FieldElement => self.field_element_from_parameter(
|
||||
cs,
|
||||
function_name.clone(),
|
||||
input_model,
|
||||
input_value,
|
||||
)?,
|
||||
Type::Boolean => {
|
||||
self.bool_from_parameter(cs, function_name.clone(), input_model, input_value)?
|
||||
}
|
||||
Type::Array(ref ty, _length) => match *ty.clone() {
|
||||
Type::IntegerType(_type) => self.integer_array_from_parameter(
|
||||
cs,
|
||||
function_name.clone(),
|
||||
input_model,
|
||||
input_value,
|
||||
)?,
|
||||
Type::FieldElement => self.field_element_array_from_parameter(
|
||||
cs,
|
||||
function_name.clone(),
|
||||
input_model,
|
||||
input_value,
|
||||
)?,
|
||||
Type::Boolean => self.boolean_array_from_parameter(
|
||||
cs,
|
||||
function_name.clone(),
|
||||
input_model,
|
||||
input_value,
|
||||
)?,
|
||||
_type => return Err(FunctionError::UndefinedInput(_type.to_string())),
|
||||
},
|
||||
_type => return Err(FunctionError::UndefinedInput(_type.to_string())),
|
||||
};
|
||||
let variable = new_variable_from_variable(scope.clone(), &input_model.variable);
|
||||
let value = self.allocate_main_function_input(cs, input_model, input_value)?;
|
||||
|
||||
// store a new variable for every allocated main function input
|
||||
self.store_variable(variable.clone(), value);
|
||||
|
||||
input_variables.push(Expression::Variable(variable));
|
||||
}
|
||||
@ -222,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<F, G>,
|
||||
) -> Result<(), ImportError> {
|
||||
let program_name = program.name.clone();
|
||||
|
||||
|
20
compiler/src/constraints/group_element.rs
Normal file
20
compiler/src/constraints/group_element.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use crate::{ConstrainedProgram, ConstrainedValue};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, Group, PrimeField},
|
||||
gadgets::{r1cs::ConstraintSystem, utilities::boolean::Boolean},
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub fn evaluate_group_eq(group_element_1: G, group_element_2: G) -> ConstrainedValue<F, G> {
|
||||
ConstrainedValue::Boolean(Boolean::constant(group_element_1.eq(&group_element_2)))
|
||||
}
|
||||
|
||||
pub fn evaluate_group_add(group_element_1: G, group_element_2: G) -> ConstrainedValue<F, G> {
|
||||
ConstrainedValue::GroupElement(group_element_1.add(&group_element_2))
|
||||
}
|
||||
|
||||
pub fn evaluate_group_sub(group_element_1: G, group_element_2: G) -> ConstrainedValue<F, G> {
|
||||
ConstrainedValue::GroupElement(group_element_1.sub(&group_element_2))
|
||||
}
|
||||
}
|
@ -8,18 +8,18 @@ use crate::{
|
||||
|
||||
use from_pest::FromPest;
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
curves::{Field, Group, PrimeField},
|
||||
gadgets::r1cs::ConstraintSystem,
|
||||
};
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, 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()))
|
||||
|
@ -3,24 +3,24 @@
|
||||
use crate::{
|
||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
||||
errors::IntegerError,
|
||||
types::{InputModel, InputValue, Integer, Type, Variable},
|
||||
types::{InputModel, InputValue, Integer, Type},
|
||||
IntegerType,
|
||||
};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
curves::{Field, Group, 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<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn get_integer_constant(integer: Integer) -> ConstrainedValue<F, G> {
|
||||
ConstrainedValue::Integer(integer)
|
||||
}
|
||||
|
||||
pub(crate) fn evaluate_integer_eq(
|
||||
left: Integer,
|
||||
right: Integer,
|
||||
) -> Result<ConstrainedValue<F>, IntegerError> {
|
||||
) -> Result<ConstrainedValue<F, G>, IntegerError> {
|
||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(
|
||||
match (left, right) {
|
||||
(Integer::U8(left_u8), Integer::U8(right_u8)) => left_u8.eq(&right_u8),
|
||||
@ -41,23 +41,22 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
pub(crate) fn integer_from_parameter(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
scope: String,
|
||||
parameter_model: InputModel<F>,
|
||||
parameter_value: Option<InputValue<F>>,
|
||||
) -> Result<Variable<F>, IntegerError> {
|
||||
let integer_type = match ¶meter_model._type {
|
||||
integer_model: InputModel<F, G>,
|
||||
integer_value: Option<InputValue<F, G>>,
|
||||
) -> Result<ConstrainedValue<F, G>, IntegerError> {
|
||||
let integer_type = match &integer_model._type {
|
||||
Type::IntegerType(integer_type) => integer_type,
|
||||
_type => return Err(IntegerError::InvalidType(_type.to_string())),
|
||||
};
|
||||
|
||||
// Check that the parameter value is the correct type
|
||||
let integer_option = match parameter_value {
|
||||
let integer_option = match integer_value {
|
||||
Some(parameter) => {
|
||||
if let InputValue::Integer(integer) = parameter {
|
||||
Some(integer)
|
||||
} else {
|
||||
return Err(IntegerError::InvalidInteger(
|
||||
parameter_model._type.to_string(),
|
||||
integer_model._type.to_string(),
|
||||
parameter.to_string(),
|
||||
));
|
||||
}
|
||||
@ -66,46 +65,14 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
};
|
||||
|
||||
match integer_type {
|
||||
IntegerType::U8 => self.u8_from_parameter(cs, scope, parameter_model, integer_option),
|
||||
IntegerType::U16 => self.u16_from_parameter(cs, scope, parameter_model, integer_option),
|
||||
IntegerType::U32 => self.u32_from_parameter(cs, scope, parameter_model, integer_option),
|
||||
IntegerType::U64 => self.u64_from_parameter(cs, scope, parameter_model, integer_option),
|
||||
IntegerType::U128 => {
|
||||
self.u128_from_parameter(cs, scope, parameter_model, integer_option)
|
||||
}
|
||||
IntegerType::U8 => self.u8_from_input(cs, integer_model, integer_option),
|
||||
IntegerType::U16 => self.u16_from_input(cs, integer_model, integer_option),
|
||||
IntegerType::U32 => self.u32_from_input(cs, integer_model, integer_option),
|
||||
IntegerType::U64 => self.u64_from_input(cs, integer_model, integer_option),
|
||||
IntegerType::U128 => self.u128_from_integer(cs, integer_model, integer_option),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn integer_array_from_parameter(
|
||||
&mut self,
|
||||
_cs: &mut CS,
|
||||
_scope: String,
|
||||
_parameter_model: InputModel<F>,
|
||||
_parameter_value: Option<InputValue<F>>,
|
||||
) -> Result<Variable<F>, IntegerError> {
|
||||
unimplemented!("Cannot enforce integer array as parameter")
|
||||
// // Check visibility of parameter
|
||||
// let mut array_value = vec![];
|
||||
// let name = parameter.variable.name.clone();
|
||||
// for argument in argument_array {
|
||||
// let number = if parameter.private {
|
||||
// UInt32::alloc(cs.ns(|| name), Some(argument)).unwrap()
|
||||
// } else {
|
||||
// UInt32::alloc_input(cs.ns(|| name), Some(argument)).unwrap()
|
||||
// };
|
||||
//
|
||||
// array_value.push(number);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// let parameter_variable = new_variable_from_variable(scope, ¶meter.variable);
|
||||
//
|
||||
// // store array as variable in resolved program
|
||||
// self.store_variable(parameter_variable.clone(), ResolvedValue::U32Array(array_value));
|
||||
//
|
||||
// parameter_variable
|
||||
}
|
||||
|
||||
pub(crate) fn enforce_integer_eq(
|
||||
cs: &mut CS,
|
||||
left: Integer,
|
||||
@ -140,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<F, G>, 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)?)
|
||||
@ -166,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<F, G>, 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)?)
|
||||
@ -192,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<F, G>, 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)?)
|
||||
@ -218,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<F, G>, 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)?)
|
||||
@ -244,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<F, G>, 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)?)
|
||||
|
@ -1,35 +1,34 @@
|
||||
//! Methods to enforce constraints on uint128s in a resolved Leo program.
|
||||
|
||||
use crate::{
|
||||
constraints::{new_variable_from_variable, ConstrainedProgram, ConstrainedValue},
|
||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
||||
errors::IntegerError,
|
||||
types::{InputModel, Integer, Variable},
|
||||
types::{InputModel, Integer},
|
||||
};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
curves::{Field, Group, PrimeField},
|
||||
gadgets::{
|
||||
r1cs::ConstraintSystem,
|
||||
utilities::{alloc::AllocGadget, eq::EqGadget, uint128::UInt128},
|
||||
},
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
pub(crate) fn u128_from_parameter(
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn u128_from_integer(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
scope: String,
|
||||
parameter_model: InputModel<F>,
|
||||
parameter_model: InputModel<F, G>,
|
||||
integer_option: Option<usize>,
|
||||
) -> Result<Variable<F>, IntegerError> {
|
||||
) -> Result<ConstrainedValue<F, G>, 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);
|
||||
|
||||
// Check visibility of parameter
|
||||
let name = parameter_model.variable.name.clone();
|
||||
let integer = if parameter_model.private {
|
||||
let integer_value = if parameter_model.private {
|
||||
UInt128::alloc(cs.ns(|| name), || {
|
||||
u128_option.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?
|
||||
@ -39,47 +38,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
})?
|
||||
};
|
||||
|
||||
let parameter_variable = new_variable_from_variable(scope, ¶meter_model.variable);
|
||||
|
||||
// store each argument as variable in resolved program
|
||||
self.store_variable(
|
||||
parameter_variable.clone(),
|
||||
ConstrainedValue::Integer(Integer::U128(integer)),
|
||||
);
|
||||
|
||||
Ok(parameter_variable)
|
||||
Ok(ConstrainedValue::Integer(Integer::U128(integer_value)))
|
||||
}
|
||||
|
||||
// pub(crate) fn u128_array_from_parameter(
|
||||
// &mut self,
|
||||
// _cs: &mut CS,
|
||||
// _scope: String,
|
||||
// _parameter_model: ParameterModel<F>,
|
||||
// _parameter_value: Option<ParameterValue<F>>,
|
||||
// ) -> Result<Variable<F>, IntegerError> {
|
||||
// unimplemented!("Cannot enforce integer array as parameter")
|
||||
// // // Check visibility of parameter
|
||||
// // let mut array_value = vec![];
|
||||
// // let name = parameter.variable.name.clone();
|
||||
// // for argument in argument_array {
|
||||
// // let number = if parameter.private {
|
||||
// // UInt32::alloc(cs.ns(|| name), Some(argument)).unwrap()
|
||||
// // } else {
|
||||
// // UInt32::alloc_input(cs.ns(|| name), Some(argument)).unwrap()
|
||||
// // };
|
||||
// //
|
||||
// // array_value.push(number);
|
||||
// // }
|
||||
// //
|
||||
// //
|
||||
// // let parameter_variable = new_variable_from_variable(scope, ¶meter.variable);
|
||||
// //
|
||||
// // // store array as variable in resolved program
|
||||
// // self.store_variable(parameter_variable.clone(), ResolvedValue::U32Array(array_value));
|
||||
// //
|
||||
// // parameter_variable
|
||||
// }
|
||||
|
||||
pub(crate) fn enforce_u128_eq(
|
||||
cs: &mut CS,
|
||||
left: UInt128,
|
||||
|
@ -1,35 +1,34 @@
|
||||
//! Methods to enforce constraints on uint16s in a resolved Leo program.
|
||||
|
||||
use crate::{
|
||||
constraints::{new_variable_from_variable, ConstrainedProgram, ConstrainedValue},
|
||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
||||
errors::IntegerError,
|
||||
types::{InputModel, Integer, Variable},
|
||||
types::{InputModel, Integer},
|
||||
};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
curves::{Field, Group, PrimeField},
|
||||
gadgets::{
|
||||
r1cs::ConstraintSystem,
|
||||
utilities::{alloc::AllocGadget, eq::EqGadget, uint16::UInt16},
|
||||
},
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
pub(crate) fn u16_from_parameter(
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn u16_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
scope: String,
|
||||
parameter_model: InputModel<F>,
|
||||
parameter_model: InputModel<F, G>,
|
||||
integer_option: Option<usize>,
|
||||
) -> Result<Variable<F>, IntegerError> {
|
||||
) -> Result<ConstrainedValue<F, G>, 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);
|
||||
|
||||
// Check visibility of parameter
|
||||
let name = parameter_model.variable.name.clone();
|
||||
let integer = if parameter_model.private {
|
||||
let integer_value = if parameter_model.private {
|
||||
UInt16::alloc(cs.ns(|| name), || {
|
||||
u16_option.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?
|
||||
@ -39,47 +38,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
})?
|
||||
};
|
||||
|
||||
let parameter_variable = new_variable_from_variable(scope, ¶meter_model.variable);
|
||||
|
||||
// store each argument as variable in resolved program
|
||||
self.store_variable(
|
||||
parameter_variable.clone(),
|
||||
ConstrainedValue::Integer(Integer::U16(integer)),
|
||||
);
|
||||
|
||||
Ok(parameter_variable)
|
||||
Ok(ConstrainedValue::Integer(Integer::U16(integer_value)))
|
||||
}
|
||||
|
||||
// pub(crate) fn u16_array_from_parameter(
|
||||
// &mut self,
|
||||
// _cs: &mut CS,
|
||||
// _scope: String,
|
||||
// _parameter_model: ParameterModel<F>,
|
||||
// _parameter_value: Option<ParameterValue<F>>,
|
||||
// ) -> Result<Variable<F>, IntegerError> {
|
||||
// unimplemented!("Cannot enforce integer array as parameter")
|
||||
// // // Check visibility of parameter
|
||||
// // let mut array_value = vec![];
|
||||
// // let name = parameter.variable.name.clone();
|
||||
// // for argument in argument_array {
|
||||
// // let number = if parameter.private {
|
||||
// // UInt32::alloc(cs.ns(|| name), Some(argument)).unwrap()
|
||||
// // } else {
|
||||
// // UInt32::alloc_input(cs.ns(|| name), Some(argument)).unwrap()
|
||||
// // };
|
||||
// //
|
||||
// // array_value.push(number);
|
||||
// // }
|
||||
// //
|
||||
// //
|
||||
// // let parameter_variable = new_variable_from_variable(scope, ¶meter.variable);
|
||||
// //
|
||||
// // // store array as variable in resolved program
|
||||
// // self.store_variable(parameter_variable.clone(), ResolvedValue::U32Array(array_value));
|
||||
// //
|
||||
// // parameter_variable
|
||||
// }
|
||||
|
||||
pub(crate) fn enforce_u16_eq(
|
||||
cs: &mut CS,
|
||||
left: UInt16,
|
||||
|
@ -1,35 +1,34 @@
|
||||
//! Methods to enforce constraints on uint32s in a resolved Leo program.
|
||||
|
||||
use crate::{
|
||||
constraints::{new_variable_from_variable, ConstrainedProgram, ConstrainedValue},
|
||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
||||
errors::IntegerError,
|
||||
types::{InputModel, Integer, Variable},
|
||||
types::{InputModel, Integer},
|
||||
};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
curves::{Field, Group, PrimeField},
|
||||
gadgets::{
|
||||
r1cs::ConstraintSystem,
|
||||
utilities::{alloc::AllocGadget, eq::EqGadget, uint32::UInt32},
|
||||
},
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
pub(crate) fn u32_from_parameter(
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn u32_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
scope: String,
|
||||
parameter_model: InputModel<F>,
|
||||
parameter_model: InputModel<F, G>,
|
||||
integer_option: Option<usize>,
|
||||
) -> Result<Variable<F>, IntegerError> {
|
||||
) -> Result<ConstrainedValue<F, G>, 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);
|
||||
|
||||
// Check visibility of parameter
|
||||
let name = parameter_model.variable.name.clone();
|
||||
let integer = if parameter_model.private {
|
||||
let integer_value = if parameter_model.private {
|
||||
UInt32::alloc(cs.ns(|| name), || {
|
||||
u32_option.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?
|
||||
@ -39,47 +38,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
})?
|
||||
};
|
||||
|
||||
let parameter_variable = new_variable_from_variable(scope, ¶meter_model.variable);
|
||||
|
||||
// store each argument as variable in resolved program
|
||||
self.store_variable(
|
||||
parameter_variable.clone(),
|
||||
ConstrainedValue::Integer(Integer::U32(integer)),
|
||||
);
|
||||
|
||||
Ok(parameter_variable)
|
||||
Ok(ConstrainedValue::Integer(Integer::U32(integer_value)))
|
||||
}
|
||||
|
||||
// pub(crate) fn u32_array_from_parameter(
|
||||
// &mut self,
|
||||
// _cs: &mut CS,
|
||||
// _scope: String,
|
||||
// _parameter_model: ParameterModel<F>,
|
||||
// _parameter_value: Option<ParameterValue<F>>,
|
||||
// ) -> Result<Variable<F>, IntegerError> {
|
||||
// unimplemented!("Cannot enforce integer array as parameter")
|
||||
// // // Check visibility of parameter
|
||||
// // let mut array_value = vec![];
|
||||
// // let name = parameter.variable.name.clone();
|
||||
// // for argument in argument_array {
|
||||
// // let number = if parameter.private {
|
||||
// // UInt32::alloc(cs.ns(|| name), Some(argument)).unwrap()
|
||||
// // } else {
|
||||
// // UInt32::alloc_input(cs.ns(|| name), Some(argument)).unwrap()
|
||||
// // };
|
||||
// //
|
||||
// // array_value.push(number);
|
||||
// // }
|
||||
// //
|
||||
// //
|
||||
// // let parameter_variable = new_variable_from_variable(scope, ¶meter.variable);
|
||||
// //
|
||||
// // // store array as variable in resolved program
|
||||
// // self.store_variable(parameter_variable.clone(), ResolvedValue::U32Array(array_value));
|
||||
// //
|
||||
// // parameter_variable
|
||||
// }
|
||||
|
||||
pub(crate) fn enforce_u32_eq(
|
||||
cs: &mut CS,
|
||||
left: UInt32,
|
||||
|
@ -1,35 +1,34 @@
|
||||
//! Methods to enforce constraints on uint64s in a resolved Leo program.
|
||||
|
||||
use crate::{
|
||||
constraints::{new_variable_from_variable, ConstrainedProgram, ConstrainedValue},
|
||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
||||
errors::IntegerError,
|
||||
types::{InputModel, Integer, Variable},
|
||||
types::{InputModel, Integer},
|
||||
};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
curves::{Field, Group, PrimeField},
|
||||
gadgets::{
|
||||
r1cs::ConstraintSystem,
|
||||
utilities::{alloc::AllocGadget, eq::EqGadget, uint64::UInt64},
|
||||
},
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
pub(crate) fn u64_from_parameter(
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn u64_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
scope: String,
|
||||
parameter_model: InputModel<F>,
|
||||
parameter_model: InputModel<F, G>,
|
||||
integer_option: Option<usize>,
|
||||
) -> Result<Variable<F>, IntegerError> {
|
||||
) -> Result<ConstrainedValue<F, G>, 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);
|
||||
|
||||
// Check visibility of parameter
|
||||
let name = parameter_model.variable.name.clone();
|
||||
let integer = if parameter_model.private {
|
||||
let integer_value = if parameter_model.private {
|
||||
UInt64::alloc(cs.ns(|| name), || {
|
||||
u64_option.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?
|
||||
@ -39,47 +38,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
})?
|
||||
};
|
||||
|
||||
let parameter_variable = new_variable_from_variable(scope, ¶meter_model.variable);
|
||||
|
||||
// store each argument as variable in resolved program
|
||||
self.store_variable(
|
||||
parameter_variable.clone(),
|
||||
ConstrainedValue::Integer(Integer::U64(integer)),
|
||||
);
|
||||
|
||||
Ok(parameter_variable)
|
||||
Ok(ConstrainedValue::Integer(Integer::U64(integer_value)))
|
||||
}
|
||||
|
||||
// pub(crate) fn u64_array_from_parameter(
|
||||
// &mut self,
|
||||
// _cs: &mut CS,
|
||||
// _scope: String,
|
||||
// _parameter_model: ParameterModel<F>,
|
||||
// _parameter_value: Option<ParameterValue<F>>,
|
||||
// ) -> Result<Variable<F>, IntegerError> {
|
||||
// unimplemented!("Cannot enforce integer array as parameter")
|
||||
// // // Check visibility of parameter
|
||||
// // let mut array_value = vec![];
|
||||
// // let name = parameter.variable.name.clone();
|
||||
// // for argument in argument_array {
|
||||
// // let number = if parameter.private {
|
||||
// // UInt32::alloc(cs.ns(|| name), Some(argument)).unwrap()
|
||||
// // } else {
|
||||
// // UInt32::alloc_input(cs.ns(|| name), Some(argument)).unwrap()
|
||||
// // };
|
||||
// //
|
||||
// // array_value.push(number);
|
||||
// // }
|
||||
// //
|
||||
// //
|
||||
// // let parameter_variable = new_variable_from_variable(scope, ¶meter.variable);
|
||||
// //
|
||||
// // // store array as variable in resolved program
|
||||
// // self.store_variable(parameter_variable.clone(), ResolvedValue::U32Array(array_value));
|
||||
// //
|
||||
// // parameter_variable
|
||||
// }
|
||||
|
||||
pub(crate) fn enforce_u64_eq(
|
||||
cs: &mut CS,
|
||||
left: UInt64,
|
||||
|
@ -1,28 +1,27 @@
|
||||
//! Methods to enforce constraints on uint8s in a resolved Leo program.
|
||||
|
||||
use crate::{
|
||||
constraints::{new_variable_from_variable, ConstrainedProgram, ConstrainedValue},
|
||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
||||
errors::IntegerError,
|
||||
types::{InputModel, Integer, Variable},
|
||||
types::{InputModel, Integer},
|
||||
};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
curves::{Field, Group, PrimeField},
|
||||
gadgets::{
|
||||
r1cs::ConstraintSystem,
|
||||
utilities::{alloc::AllocGadget, eq::EqGadget, uint8::UInt8},
|
||||
},
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
pub(crate) fn u8_from_parameter(
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn u8_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
scope: String,
|
||||
parameter_model: InputModel<F>,
|
||||
parameter_model: InputModel<F, G>,
|
||||
integer_option: Option<usize>,
|
||||
) -> Result<Variable<F>, IntegerError> {
|
||||
) -> Result<ConstrainedValue<F, G>, 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);
|
||||
@ -39,47 +38,9 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
})?
|
||||
};
|
||||
|
||||
let parameter_variable = new_variable_from_variable(scope, ¶meter_model.variable);
|
||||
|
||||
// store each argument as variable in resolved program
|
||||
self.store_variable(
|
||||
parameter_variable.clone(),
|
||||
ConstrainedValue::Integer(Integer::U8(integer_value)),
|
||||
);
|
||||
|
||||
Ok(parameter_variable)
|
||||
Ok(ConstrainedValue::Integer(Integer::U8(integer_value)))
|
||||
}
|
||||
|
||||
// pub(crate) fn u8_array_from_parameter(
|
||||
// &mut self,
|
||||
// _cs: &mut CS,
|
||||
// _scope: String,
|
||||
// _parameter_model: ParameterModel<F>,
|
||||
// _parameter_value: Option<ParameterValue<F>>,
|
||||
// ) -> Result<Variable<F>, IntegerError> {
|
||||
// unimplemented!("Cannot enforce integer array as parameter")
|
||||
// // // Check visibility of parameter
|
||||
// // let mut array_value = vec![];
|
||||
// // let name = parameter.variable.name.clone();
|
||||
// // for argument in argument_array {
|
||||
// // let number = if parameter.private {
|
||||
// // UInt32::alloc(cs.ns(|| name), Some(argument)).unwrap()
|
||||
// // } else {
|
||||
// // UInt32::alloc_input(cs.ns(|| name), Some(argument)).unwrap()
|
||||
// // };
|
||||
// //
|
||||
// // array_value.push(number);
|
||||
// // }
|
||||
// //
|
||||
// //
|
||||
// // let parameter_variable = new_variable_from_variable(scope, ¶meter.variable);
|
||||
// //
|
||||
// // // store array as variable in resolved program
|
||||
// // self.store_variable(parameter_variable.clone(), ResolvedValue::U32Array(array_value));
|
||||
// //
|
||||
// // parameter_variable
|
||||
// }
|
||||
|
||||
pub(crate) fn enforce_u8_eq(
|
||||
cs: &mut CS,
|
||||
left: UInt8,
|
||||
|
@ -18,6 +18,9 @@ pub use integer::*;
|
||||
pub mod field_element;
|
||||
pub use field_element::*;
|
||||
|
||||
pub mod group_element;
|
||||
pub use group_element::*;
|
||||
|
||||
pub mod program;
|
||||
pub use program::*;
|
||||
|
||||
@ -33,15 +36,15 @@ use crate::{
|
||||
};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
curves::{Field, Group, PrimeField},
|
||||
gadgets::r1cs::ConstraintSystem,
|
||||
};
|
||||
|
||||
pub fn generate_constraints<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
||||
pub fn generate_constraints<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>>(
|
||||
cs: &mut CS,
|
||||
program: Program<F>,
|
||||
parameters: Vec<Option<InputValue<F>>>,
|
||||
) -> Result<ConstrainedValue<F>, CompilerError> {
|
||||
program: Program<F, G>,
|
||||
parameters: Vec<Option<InputValue<F, G>>>,
|
||||
) -> Result<ConstrainedValue<F, G>, CompilerError> {
|
||||
let mut resolved_program = ConstrainedProgram::new();
|
||||
let program_name = program.get_name();
|
||||
let main_function_name = new_scope(program_name.clone(), "main".into());
|
||||
|
@ -3,13 +3,13 @@
|
||||
use crate::{constraints::ConstrainedValue, types::Variable};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
curves::{Field, Group, 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<F: Field + PrimeField, G: Group, 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<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
resolved_names: HashMap::new(),
|
||||
@ -52,11 +54,15 @@ 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 +70,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)
|
||||
}
|
||||
}
|
||||
|
@ -10,12 +10,12 @@ use crate::{
|
||||
};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
curves::{Field, Group, 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<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, 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)) => {
|
||||
@ -374,11 +374,21 @@ impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ConstrainedProgram<F, CS> {
|
||||
(ConstrainedValue::FieldElement(fe_1), ConstrainedValue::FieldElement(fe_2)) => {
|
||||
self.enforce_field_eq(cs, fe_1, fe_2)
|
||||
}
|
||||
(ConstrainedValue::Array(arr_1), ConstrainedValue::Array(arr_2)) => {
|
||||
for (left, right) in arr_1.into_iter().zip(arr_2.into_iter()) {
|
||||
self.enforce_assert_eq_statement(cs, left, right)?;
|
||||
}
|
||||
}
|
||||
(val_1, val_2) => {
|
||||
return Err(StatementError::AssertEq(
|
||||
val_1.to_string(),
|
||||
val_2.to_string(),
|
||||
))
|
||||
unimplemented!(
|
||||
"assert eq not supported for given types {} == {}",
|
||||
val_1,
|
||||
val_2
|
||||
)
|
||||
// return Err(StatementError::AssertEq(
|
||||
// val_1.to_string(),
|
||||
// val_2.to_string(),
|
||||
// ))
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -388,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) => {
|
||||
|
@ -7,45 +7,54 @@ use crate::{
|
||||
};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
curves::{Field, Group, 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 ty, ref len)) => {
|
||||
(ConstrainedValue::Array(ref arr), Type::Array(ref _type, ref dimensions)) => {
|
||||
// check array lengths are equal
|
||||
if arr.len() != *len {
|
||||
if arr.len() != dimensions[0] {
|
||||
return Err(ValueError::ArrayLength(format!(
|
||||
"Expected array {:?} to be length {}",
|
||||
arr, len
|
||||
"Expected array {:?} to be length {:?}",
|
||||
arr, dimensions[0]
|
||||
)));
|
||||
}
|
||||
|
||||
// get next dimension of array if nested
|
||||
let next_type = _type.next_dimension(dimensions);
|
||||
|
||||
// check each value in array matches
|
||||
for value in arr {
|
||||
value.expect_type(ty)?;
|
||||
value.expect_type(&next_type)?;
|
||||
}
|
||||
}
|
||||
(
|
||||
@ -59,9 +68,9 @@ impl<F: Field + PrimeField> ConstrainedValue<F> {
|
||||
)));
|
||||
}
|
||||
}
|
||||
(ConstrainedValue::Return(ref values), ty) => {
|
||||
(ConstrainedValue::Return(ref values), _type) => {
|
||||
for value in values {
|
||||
value.expect_type(ty)?;
|
||||
value.expect_type(_type)?;
|
||||
}
|
||||
}
|
||||
(value, _type) => {
|
||||
@ -76,11 +85,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, "[")?;
|
||||
@ -120,7 +130,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)
|
||||
}
|
||||
|
@ -5,9 +5,6 @@ use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum CompilerError {
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
|
||||
#[error("creating: {}", _0)]
|
||||
Creating(io::Error),
|
||||
|
||||
@ -39,12 +36,6 @@ pub enum CompilerError {
|
||||
Writing(io::Error),
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for CompilerError {
|
||||
fn from(error: std::io::Error) -> Self {
|
||||
CompilerError::Crate("std::io", format!("{}", error))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ImportError> for CompilerError {
|
||||
fn from(error: ImportError) -> Self {
|
||||
CompilerError::ImportError(error)
|
||||
|
@ -1,9 +1,16 @@
|
||||
use crate::errors::ValueError;
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum BooleanError {
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
#[error("{}", _0)]
|
||||
ValueError(ValueError),
|
||||
|
||||
#[error("Expected boolean array parameter, got {}", _0)]
|
||||
InvalidArray(String),
|
||||
|
||||
#[error("Expected boolean array with length {}, got length {}", _0, _1)]
|
||||
InvalidArrayLength(usize, usize),
|
||||
|
||||
#[error("Expected boolean parameter, got {}", _0)]
|
||||
InvalidBoolean(String),
|
||||
@ -18,14 +25,14 @@ pub enum BooleanError {
|
||||
SynthesisError(SynthesisError),
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for BooleanError {
|
||||
fn from(error: std::io::Error) -> Self {
|
||||
BooleanError::Crate("std::io", format!("{}", error))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SynthesisError> for BooleanError {
|
||||
fn from(error: SynthesisError) -> Self {
|
||||
BooleanError::SynthesisError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ValueError> for BooleanError {
|
||||
fn from(error: ValueError) -> Self {
|
||||
BooleanError::ValueError(error)
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,7 @@
|
||||
use crate::errors::{BooleanError, FieldElementError, FunctionError, IntegerError};
|
||||
use crate::errors::{BooleanError, FieldElementError, FunctionError, IntegerError, ValueError};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ExpressionError {
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
|
||||
// Variables
|
||||
#[error("Variable \"{}\" not found", _0)]
|
||||
UndefinedVariable(String),
|
||||
@ -13,6 +10,9 @@ pub enum ExpressionError {
|
||||
#[error("{}", _0)]
|
||||
IncompatibleTypes(String),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ValueError(ValueError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
IntegerError(IntegerError),
|
||||
|
||||
@ -75,9 +75,9 @@ pub enum ExpressionError {
|
||||
IfElseConditional(String),
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for ExpressionError {
|
||||
fn from(error: std::io::Error) -> Self {
|
||||
ExpressionError::Crate("std::io", format!("{}", error))
|
||||
impl From<ValueError> for ExpressionError {
|
||||
fn from(error: ValueError) -> Self {
|
||||
ExpressionError::ValueError(error)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,9 +2,6 @@ use snarkos_errors::gadgets::SynthesisError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum FieldElementError {
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
|
||||
#[error("Expected field element parameter, got {}", _0)]
|
||||
InvalidField(String),
|
||||
|
||||
@ -12,12 +9,6 @@ pub enum FieldElementError {
|
||||
SynthesisError(SynthesisError),
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for FieldElementError {
|
||||
fn from(error: std::io::Error) -> Self {
|
||||
FieldElementError::Crate("std::io", format!("{}", error))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SynthesisError> for FieldElementError {
|
||||
fn from(error: SynthesisError) -> Self {
|
||||
FieldElementError::SynthesisError(error)
|
||||
|
@ -1,12 +1,9 @@
|
||||
use crate::errors::{
|
||||
BooleanError, ExpressionError, FieldElementError, IntegerError, StatementError,
|
||||
BooleanError, ExpressionError, FieldElementError, IntegerError, StatementError, ValueError,
|
||||
};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum FunctionError {
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
|
||||
#[error("Function expected {} inputs, got {}", _0, _1)]
|
||||
InputsLength(usize, usize),
|
||||
|
||||
@ -16,6 +13,15 @@ pub enum FunctionError {
|
||||
#[error("Function expected input type {}, got {}", _0, _1)]
|
||||
InvalidInput(String, String),
|
||||
|
||||
#[error("Expected function input array, got {}", _0)]
|
||||
InvalidArray(String),
|
||||
|
||||
#[error("Expected function input array length {}, got length {}", _0, _1)]
|
||||
InvalidArrayLength(usize, usize),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ValueError(ValueError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
IntegerError(IntegerError),
|
||||
|
||||
@ -32,9 +38,9 @@ pub enum FunctionError {
|
||||
StatementError(StatementError),
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for FunctionError {
|
||||
fn from(error: std::io::Error) -> Self {
|
||||
FunctionError::Crate("std::io", format!("{}", error))
|
||||
impl From<ValueError> for FunctionError {
|
||||
fn from(error: ValueError) -> Self {
|
||||
FunctionError::ValueError(error)
|
||||
}
|
||||
}
|
||||
|
||||
|
2
compiler/src/errors/constraints/group_element.rs
Normal file
2
compiler/src/errors/constraints/group_element.rs
Normal file
@ -0,0 +1,2 @@
|
||||
#[derive(Debug, Error)]
|
||||
pub enum GroupElementError {}
|
@ -1,8 +1,5 @@
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ImportError {
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
|
||||
#[error("Cannot read from the provided file path - {}", _0)]
|
||||
FileReadError(String),
|
||||
|
||||
@ -12,9 +9,3 @@ pub enum ImportError {
|
||||
#[error("Unable to construct abstract syntax tree")]
|
||||
SyntaxTreeError,
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for ImportError {
|
||||
fn from(error: std::io::Error) -> Self {
|
||||
ImportError::Crate("std::io", format!("{}", error))
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,6 @@ use snarkos_errors::gadgets::SynthesisError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum IntegerError {
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
|
||||
#[error("expected integer parameter type, got {}", _0)]
|
||||
InvalidType(String),
|
||||
|
||||
@ -21,12 +18,6 @@ pub enum IntegerError {
|
||||
SynthesisError(SynthesisError),
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for IntegerError {
|
||||
fn from(error: std::io::Error) -> Self {
|
||||
IntegerError::Crate("std::io", format!("{}", error))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SynthesisError> for IntegerError {
|
||||
fn from(error: SynthesisError) -> Self {
|
||||
IntegerError::SynthesisError(error)
|
||||
|
@ -18,6 +18,9 @@ pub use integer::*;
|
||||
pub mod field_element;
|
||||
pub use field_element::*;
|
||||
|
||||
pub mod group_element;
|
||||
pub use group_element::*;
|
||||
|
||||
pub mod value;
|
||||
pub use value::*;
|
||||
|
||||
|
@ -2,9 +2,6 @@ use crate::errors::{BooleanError, ExpressionError, FieldElementError, IntegerErr
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum StatementError {
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
|
||||
#[error("Attempted to assign to unknown variable {}", _0)]
|
||||
UndefinedVariable(String),
|
||||
|
||||
@ -51,12 +48,6 @@ pub enum StatementError {
|
||||
Unassigned(String),
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for StatementError {
|
||||
fn from(error: std::io::Error) -> Self {
|
||||
StatementError::Crate("std::io", format!("{}", error))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ExpressionError> for StatementError {
|
||||
fn from(error: ExpressionError) -> Self {
|
||||
StatementError::ExpressionError(error)
|
||||
|
@ -6,8 +6,8 @@ pub enum ValueError {
|
||||
#[error("{}", _0)]
|
||||
ArrayLength(String),
|
||||
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
#[error("Expected type array, got {}", _0)]
|
||||
ArrayModel(String),
|
||||
|
||||
#[error("{}", _0)]
|
||||
IntegerError(IntegerError),
|
||||
@ -21,12 +21,6 @@ pub enum ValueError {
|
||||
TypeError(String),
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for ValueError {
|
||||
fn from(error: std::io::Error) -> Self {
|
||||
ValueError::Crate("std::io", format!("{}", error))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<IntegerError> for ValueError {
|
||||
fn from(error: IntegerError) -> Self {
|
||||
ValueError::IntegerError(error)
|
||||
|
@ -2,23 +2,23 @@
|
||||
|
||||
use crate::Variable;
|
||||
|
||||
use snarkos_models::curves::{Field, PrimeField};
|
||||
use snarkos_models::curves::{Field, Group, PrimeField};
|
||||
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)
|
||||
}
|
||||
|
@ -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_field | type_group | type_bool | type_integer }
|
||||
type_struct = { variable }
|
||||
type_basic_or_struct = {type_basic | type_struct }
|
||||
type_array = {type_basic ~ ("[" ~ value ~ "]")+ }
|
||||
@ -83,8 +84,9 @@ 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_group = { value_number ~ type_group }
|
||||
value_boolean = { "true" | "false" }
|
||||
value = { value_field | value_boolean | value_integer }
|
||||
value = { value_field | value_group | value_boolean | value_integer }
|
||||
|
||||
/// Variables
|
||||
|
||||
@ -174,7 +176,7 @@ statement_return = { "return" ~ expression_tuple }
|
||||
statement_definition = { "let" ~ variable ~ (":" ~ _type)? ~ "=" ~ expression }
|
||||
statement_assign = { assignee ~ operation_assign ~ expression }
|
||||
statement_multiple_assignment = { "let" ~ "(" ~ optionally_typed_variable_tuple ~ ")" ~ "=" ~ variable ~ "(" ~ expression_tuple ~ ")" }
|
||||
statement_conditional = {"if" ~ "(" ~ expression ~ ")" ~ "{" ~ NEWLINE* ~ statement+ ~ "}" ~ ("else" ~ conditional_nested_or_end)?}
|
||||
statement_conditional = {"if" ~ (expression | "(" ~ expression ~ ")") ~ "{" ~ NEWLINE* ~ statement+ ~ "}" ~ ("else" ~ conditional_nested_or_end)?}
|
||||
statement_for = { "for" ~ variable ~ "in" ~ expression ~ ".." ~ expression ~ "{" ~ NEWLINE* ~ statement+ ~ "}"}
|
||||
statement_assert = {
|
||||
assert_eq
|
||||
|
@ -3,7 +3,8 @@
|
||||
|
||||
use crate::{errors::IntegerError, Import};
|
||||
|
||||
use snarkos_models::curves::{Field, PrimeField};
|
||||
use crate::errors::ValueError;
|
||||
use snarkos_models::curves::{Field, Group, PrimeField};
|
||||
use snarkos_models::gadgets::{
|
||||
r1cs::Variable as R1CSVariable,
|
||||
utilities::{
|
||||
@ -16,9 +17,20 @@ use std::marker::PhantomData;
|
||||
|
||||
/// A variable in a constraint system.
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Variable<F: Field + PrimeField> {
|
||||
pub struct Variable<F: Field + PrimeField, G: Group> {
|
||||
pub name: String,
|
||||
pub(crate) _field: PhantomData<F>,
|
||||
pub(crate) _group: PhantomData<G>,
|
||||
pub(crate) _engine: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> Variable<F, G> {
|
||||
pub fn new(name: String) -> Self {
|
||||
Self {
|
||||
name,
|
||||
_group: PhantomData::<G>,
|
||||
_engine: PhantomData::<F>,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An integer type enum wrapping the integer value. Used only in expressions.
|
||||
@ -72,69 +84,81 @@ 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<F: Field + PrimeField, G: Group> {
|
||||
Range(Option<Integer>, Option<Integer>),
|
||||
Expression(Expression<F>),
|
||||
Expression(Expression<F, G>),
|
||||
}
|
||||
|
||||
/// Spread or expression
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum SpreadOrExpression<F: Field + PrimeField> {
|
||||
Spread(Expression<F>),
|
||||
Expression(Expression<F>),
|
||||
pub enum SpreadOrExpression<F: Field + PrimeField, G: Group> {
|
||||
Spread(Expression<F, G>),
|
||||
Expression(Expression<F, G>),
|
||||
}
|
||||
|
||||
/// Expression that evaluates to a value
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Expression<F: Field + PrimeField> {
|
||||
pub enum Expression<F: Field + PrimeField, G: Group> {
|
||||
// Variable
|
||||
Variable(Variable<F>),
|
||||
Variable(Variable<F, G>),
|
||||
|
||||
// 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<F, G>>, Box<Expression<F, G>>),
|
||||
Sub(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
Mul(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
Div(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
Pow(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
|
||||
// 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<F, G>>),
|
||||
Or(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
And(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
Eq(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
Geq(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
Gt(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
Leq(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
Lt(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
|
||||
// Conditionals
|
||||
IfElse(Box<Expression<F>>, Box<Expression<F>>, Box<Expression<F>>),
|
||||
IfElse(
|
||||
Box<Expression<F, G>>,
|
||||
Box<Expression<F, G>>,
|
||||
Box<Expression<F, G>>,
|
||||
),
|
||||
|
||||
// Arrays
|
||||
Array(Vec<Box<SpreadOrExpression<F>>>),
|
||||
ArrayAccess(Box<Expression<F>>, Box<RangeOrExpression<F>>), // (array name, range)
|
||||
Array(Vec<Box<SpreadOrExpression<F, G>>>),
|
||||
ArrayAccess(Box<Expression<F, G>>, Box<RangeOrExpression<F, G>>), // (array name, range)
|
||||
|
||||
// Structs
|
||||
Struct(Variable<F>, Vec<StructMember<F>>),
|
||||
StructMemberAccess(Box<Expression<F>>, Variable<F>), // (struct name, struct member name)
|
||||
Struct(Variable<F, G>, Vec<StructMember<F, G>>),
|
||||
StructMemberAccess(Box<Expression<F, G>>, Variable<F, G>), // (struct name, struct member name)
|
||||
|
||||
// Functions
|
||||
FunctionCall(Variable<F>, Vec<Expression<F>>),
|
||||
FunctionCall(Variable<F, G>, Vec<Expression<F, G>>),
|
||||
}
|
||||
|
||||
/// 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<F: Field + PrimeField, G: Group> {
|
||||
Variable(Variable<F, G>),
|
||||
Array(Box<Assignee<F, G>>, RangeOrExpression<F, G>),
|
||||
StructMember(Box<Assignee<F, G>>, Variable<F, G>),
|
||||
}
|
||||
|
||||
/// Explicit integer type
|
||||
@ -149,73 +173,100 @@ 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<F: Field + PrimeField, G: Group> {
|
||||
IntegerType(IntegerType),
|
||||
FieldElement,
|
||||
GroupElement,
|
||||
Boolean,
|
||||
Array(Box<Type<F>>, usize),
|
||||
Struct(Variable<F>),
|
||||
Array(Box<Type<F, G>>, Vec<usize>),
|
||||
Struct(Variable<F, G>),
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> Type<F, G> {
|
||||
pub fn next_dimension(&self, dimensions: &Vec<usize>) -> Self {
|
||||
let _type = self.clone();
|
||||
|
||||
if dimensions.len() > 1 {
|
||||
let mut next = vec![];
|
||||
next.extend_from_slice(&dimensions[1..]);
|
||||
|
||||
return Type::Array(Box::new(_type), next);
|
||||
}
|
||||
|
||||
_type
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub enum ConditionalNestedOrEnd<F: Field + PrimeField> {
|
||||
Nested(Box<ConditionalStatement<F>>),
|
||||
End(Vec<Statement<F>>),
|
||||
pub enum ConditionalNestedOrEnd<F: Field + PrimeField, G: Group> {
|
||||
Nested(Box<ConditionalStatement<F, G>>),
|
||||
End(Vec<Statement<F, G>>),
|
||||
}
|
||||
|
||||
#[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<F: Field + PrimeField, G: Group> {
|
||||
pub condition: Expression<F, G>,
|
||||
pub statements: Vec<Statement<F, G>>,
|
||||
pub next: Option<ConditionalNestedOrEnd<F, G>>,
|
||||
}
|
||||
|
||||
/// 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<F: Field + PrimeField, G: Group> {
|
||||
// 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<F, G>>),
|
||||
Definition(Assignee<F, G>, Option<Type<F, G>>, Expression<F, G>),
|
||||
Assign(Assignee<F, G>, Expression<F, G>),
|
||||
MultipleAssign(Vec<Assignee<F, G>>, Expression<F, G>),
|
||||
Conditional(ConditionalStatement<F, G>),
|
||||
For(Variable<F, G>, Integer, Integer, Vec<Statement<F, G>>),
|
||||
AssertEq(Expression<F, G>, Expression<F, G>),
|
||||
Expression(Expression<F, G>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct StructMember<F: Field + PrimeField> {
|
||||
pub variable: Variable<F>,
|
||||
pub expression: Expression<F>,
|
||||
pub struct StructMember<F: Field + PrimeField, G: Group> {
|
||||
pub variable: Variable<F, G>,
|
||||
pub expression: Expression<F, G>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct StructField<F: Field + PrimeField> {
|
||||
pub variable: Variable<F>,
|
||||
pub _type: Type<F>,
|
||||
pub struct StructField<F: Field + PrimeField, G: Group> {
|
||||
pub variable: Variable<F, G>,
|
||||
pub _type: Type<F, G>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct Struct<F: Field + PrimeField> {
|
||||
pub variable: Variable<F>,
|
||||
pub fields: Vec<StructField<F>>,
|
||||
pub struct Struct<F: Field + PrimeField, G: Group> {
|
||||
pub variable: Variable<F, G>,
|
||||
pub fields: Vec<StructField<F, G>>,
|
||||
}
|
||||
|
||||
/// Function parameters
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct InputModel<F: Field + PrimeField> {
|
||||
pub struct InputModel<F: Field + PrimeField, G: Group> {
|
||||
pub private: bool,
|
||||
pub _type: Type<F>,
|
||||
pub variable: Variable<F>,
|
||||
pub _type: Type<F, G>,
|
||||
pub variable: Variable<F, G>,
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> InputModel<F, G> {
|
||||
pub fn inner_type(&self) -> Result<Type<F, G>, ValueError> {
|
||||
match &self._type {
|
||||
Type::Array(ref _type, _length) => Ok(*_type.clone()),
|
||||
ref _type => Err(ValueError::ArrayModel(_type.to_string())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub enum InputValue<F: Field + PrimeField> {
|
||||
pub enum InputValue<F: Field + PrimeField, G: Group> {
|
||||
Integer(usize),
|
||||
Field(F),
|
||||
Group(G),
|
||||
Boolean(bool),
|
||||
Array(Vec<InputValue<F, G>>),
|
||||
}
|
||||
|
||||
/// The given name for a defined function in the program.
|
||||
@ -223,14 +274,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<F: Field + PrimeField, G: Group> {
|
||||
pub function_name: FunctionName,
|
||||
pub inputs: Vec<InputModel<F>>,
|
||||
pub returns: Vec<Type<F>>,
|
||||
pub statements: Vec<Statement<F>>,
|
||||
pub inputs: Vec<InputModel<F, G>>,
|
||||
pub returns: Vec<Type<F, G>>,
|
||||
pub statements: Vec<Statement<F, G>>,
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField> Function<F> {
|
||||
impl<F: Field + PrimeField, G: Group> Function<F, G> {
|
||||
pub fn get_name(&self) -> String {
|
||||
self.function_name.0.clone()
|
||||
}
|
||||
@ -238,20 +289,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<F: Field + PrimeField, G: Group> {
|
||||
pub name: Variable<F, G>,
|
||||
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<F, G>>,
|
||||
pub structs: HashMap<Variable<F, G>, Struct<F, G>>,
|
||||
pub functions: HashMap<FunctionName, Function<F, G>>,
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> Program<F> {
|
||||
impl<'ast, F: Field + PrimeField, G: Group> Program<F, G> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
name: Variable {
|
||||
name: "".into(),
|
||||
_field: PhantomData::<F>,
|
||||
_group: PhantomData::<G>,
|
||||
_engine: PhantomData::<F>,
|
||||
},
|
||||
num_parameters: 0,
|
||||
imports: vec![],
|
||||
@ -267,7 +319,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
|
||||
}
|
||||
|
@ -6,15 +6,15 @@ use crate::{
|
||||
SpreadOrExpression, Statement, Struct, StructField, Type, Variable,
|
||||
};
|
||||
|
||||
use snarkos_models::curves::{Field, PrimeField};
|
||||
use snarkos_models::curves::{Field, Group, PrimeField};
|
||||
use std::fmt;
|
||||
|
||||
impl<F: Field + PrimeField> fmt::Display for Variable<F> {
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Display for Variable<F, G> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.name)
|
||||
}
|
||||
}
|
||||
impl<F: Field + PrimeField> fmt::Debug for Variable<F> {
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Debug for Variable<F, G> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.name)
|
||||
}
|
||||
@ -34,7 +34,7 @@ impl<F: Field + PrimeField> FieldElement<F> {
|
||||
if option.is_some() {
|
||||
write!(f, "{}", option.unwrap())
|
||||
} else {
|
||||
write!(f, "allocated fe")
|
||||
write!(f, "allocated field")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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, F: Field + PrimeField, G: Group> fmt::Display for RangeOrExpression<F, G> {
|
||||
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<F: Field + PrimeField, G: Group> fmt::Display for SpreadOrExpression<F, G> {
|
||||
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, F: Field + PrimeField, G: Group> fmt::Display for Expression<F, G> {
|
||||
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<F: Field + PrimeField, G: Group> fmt::Display for Assignee<F, G> {
|
||||
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<F: Field + PrimeField, G: Group> fmt::Display for ConditionalNestedOrEnd<F, G> {
|
||||
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<F: Field + PrimeField, G: Group> fmt::Display for ConditionalStatement<F, G> {
|
||||
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<F: Field + PrimeField, G: Group> fmt::Display for Statement<F, G> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Statement::Return(ref statements) => {
|
||||
@ -254,25 +255,32 @@ impl fmt::Display for IntegerType {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField> fmt::Display for Type<F> {
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Display for Type<F, G> {
|
||||
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 count) => write!(f, "[{}; {}]", array, count),
|
||||
Type::Array(ref array, ref dimensions) => {
|
||||
write!(f, "{}", *array)?;
|
||||
for row in dimensions {
|
||||
write!(f, "[{}]", row)?;
|
||||
}
|
||||
write!(f, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField> fmt::Display for StructField<F> {
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Display for StructField<F, G> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}: {}", self.variable, self._type)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField> Struct<F> {
|
||||
impl<F: Field + PrimeField, G: Group> Struct<F, G> {
|
||||
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "struct {} {{ \n", self.variable)?;
|
||||
for field in self.fields.iter() {
|
||||
@ -282,31 +290,42 @@ impl<F: Field + PrimeField> Struct<F> {
|
||||
}
|
||||
}
|
||||
|
||||
// impl<F: Field + PrimeField> fmt::Display for Struct<F> {// uncomment when we no longer print out Program
|
||||
// impl<F: Field + PrimeField, G: Group> fmt::Display for Struct<F, G> {// 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<F: Field + PrimeField, G: Group> fmt::Debug for Struct<F, G> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField> fmt::Display for InputModel<F> {
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Display for InputModel<F, G> {
|
||||
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<F: Field + PrimeField, G: Group> fmt::Display for InputValue<F, G> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
InputValue::Integer(ref integer) => write!(f, "{}", integer),
|
||||
InputValue::Field(ref field) => write!(f, "{}", field),
|
||||
InputValue::Group(ref group) => write!(f, "{}", group),
|
||||
InputValue::Boolean(ref bool) => write!(f, "{}", bool),
|
||||
InputValue::Array(ref array) => {
|
||||
write!(f, "[")?;
|
||||
for (i, e) in array.iter().enumerate() {
|
||||
write!(f, "{}", e)?;
|
||||
if i < array.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, "]")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -329,7 +348,7 @@ impl fmt::Debug for FunctionName {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField> Function<F> {
|
||||
impl<F: Field + PrimeField, G: Group> Function<F, G> {
|
||||
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "function {}", self.function_name)?;
|
||||
let parameters = self
|
||||
@ -360,13 +379,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<F: Field + PrimeField, G: Group> fmt::Display for Function<F, G> {// 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<F: Field + PrimeField, G: Group> fmt::Debug for Function<F, G> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use crate::{ast, types, Import, ImportSymbol};
|
||||
|
||||
use snarkos_models::curves::{Field, PrimeField};
|
||||
use snarkos_models::curves::{Field, Group, PrimeField};
|
||||
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, F: Field + PrimeField, G: Group> From<ast::Variable<'ast>> for types::Variable<F, G> {
|
||||
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, F: Field + PrimeField, G: Group> From<ast::Variable<'ast>> for types::Expression<F, G> {
|
||||
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, F: Field + PrimeField, G: Group> From<ast::Integer<'ast>> for types::Expression<F, G> {
|
||||
fn from(field: ast::Integer<'ast>) -> Self {
|
||||
types::Expression::Integer(match field._type {
|
||||
Some(_type) => types::Integer::from(field.number, _type),
|
||||
@ -65,26 +66,28 @@ 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, F: Field + PrimeField, G: Group> From<ast::RangeOrExpression<'ast>>
|
||||
for types::RangeOrExpression<F, G>
|
||||
{
|
||||
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::<F, G>::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, G>::from(to.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) {
|
||||
types::Expression::Integer(number) => number,
|
||||
expression => {
|
||||
unimplemented!("Range bounds should be integers, found {}", expression)
|
||||
}
|
||||
});
|
||||
|
||||
types::RangeOrExpression::Range(from, to)
|
||||
}
|
||||
@ -95,9 +98,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, F: Field + PrimeField, G: Group> From<ast::Field<'ast>> for types::Expression<F, G> {
|
||||
fn from(field: ast::Field<'ast>) -> Self {
|
||||
types::Expression::FieldElement(types::FieldElement::Constant(
|
||||
F::from_str(&field.number.value).unwrap_or_default(),
|
||||
@ -105,9 +108,17 @@ impl<'ast, F: Field + PrimeField> From<ast::Field<'ast>> for types::Expression<F
|
||||
}
|
||||
}
|
||||
|
||||
/// pest ast -> types::Group
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::Group<'ast>> for types::Expression<F, G> {
|
||||
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, F: Field + PrimeField, G: Group> From<ast::Boolean<'ast>> for types::Expression<F, G> {
|
||||
fn from(boolean: ast::Boolean<'ast>) -> Self {
|
||||
types::Expression::Boolean(Boolean::Constant(
|
||||
boolean
|
||||
@ -120,24 +131,27 @@ 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, F: Field + PrimeField, G: Group> From<ast::Value<'ast>> for types::Expression<F, G> {
|
||||
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::Field(field) => types::Expression::from(field),
|
||||
ast::Value::Group(group) => types::Expression::from(group),
|
||||
ast::Value::Boolean(bool) => types::Expression::from(bool),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::NotExpression<'ast>> for types::Expression<F> {
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::NotExpression<'ast>>
|
||||
for types::Expression<F, G>
|
||||
{
|
||||
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, F: Field + PrimeField, G: Group> From<ast::SpreadOrExpression<'ast>>
|
||||
for types::SpreadOrExpression<F, G>
|
||||
{
|
||||
fn from(s_or_e: ast::SpreadOrExpression<'ast>) -> Self {
|
||||
match s_or_e {
|
||||
@ -151,7 +165,9 @@ impl<'ast, F: Field + PrimeField> From<ast::SpreadOrExpression<'ast>>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::BinaryExpression<'ast>> for types::Expression<F> {
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::BinaryExpression<'ast>>
|
||||
for types::Expression<F, G>
|
||||
{
|
||||
fn from(expression: ast::BinaryExpression<'ast>) -> Self {
|
||||
match expression.operation {
|
||||
// Boolean operations
|
||||
@ -211,7 +227,9 @@ 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, F: Field + PrimeField, G: Group> From<ast::TernaryExpression<'ast>>
|
||||
for types::Expression<F, G>
|
||||
{
|
||||
fn from(expression: ast::TernaryExpression<'ast>) -> Self {
|
||||
types::Expression::IfElse(
|
||||
Box::new(types::Expression::from(*expression.first)),
|
||||
@ -221,7 +239,9 @@ 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, F: Field + PrimeField, G: Group> From<ast::ArrayInlineExpression<'ast>>
|
||||
for types::Expression<F, G>
|
||||
{
|
||||
fn from(array: ast::ArrayInlineExpression<'ast>) -> Self {
|
||||
types::Expression::Array(
|
||||
array
|
||||
@ -232,18 +252,20 @@ 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, F: Field + PrimeField, G: Group> From<ast::ArrayInitializerExpression<'ast>>
|
||||
for types::Expression<F, G>
|
||||
{
|
||||
fn from(array: ast::ArrayInitializerExpression<'ast>) -> Self {
|
||||
let count = types::Expression::<F>::get_count(array.count);
|
||||
let count = types::Expression::<F, G>::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, F: Field + PrimeField, G: Group> From<ast::InlineStructMember<'ast>>
|
||||
for types::StructMember<F, G>
|
||||
{
|
||||
fn from(member: ast::InlineStructMember<'ast>) -> Self {
|
||||
types::StructMember {
|
||||
variable: types::Variable::from(member.variable),
|
||||
@ -252,20 +274,24 @@ 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, F: Field + PrimeField, G: Group> From<ast::StructInlineExpression<'ast>>
|
||||
for types::Expression<F, G>
|
||||
{
|
||||
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<F, G>>>();
|
||||
|
||||
types::Expression::Struct(variable, members)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::PostfixExpression<'ast>> for types::Expression<F> {
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::PostfixExpression<'ast>>
|
||||
for types::Expression<F, G>
|
||||
{
|
||||
fn from(expression: ast::PostfixExpression<'ast>) -> Self {
|
||||
let variable = types::Expression::Variable(types::Variable::from(expression.variable));
|
||||
|
||||
@ -302,7 +328,9 @@ 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, F: Field + PrimeField, G: Group> From<ast::Expression<'ast>>
|
||||
for types::Expression<F, G>
|
||||
{
|
||||
fn from(expression: ast::Expression<'ast>) -> Self {
|
||||
match expression {
|
||||
ast::Expression::Value(value) => types::Expression::from(value),
|
||||
@ -318,7 +346,7 @@ impl<'ast, F: Field + PrimeField> From<ast::Expression<'ast>> for types::Express
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> types::Expression<F> {
|
||||
impl<'ast, F: Field + PrimeField, G: Group> types::Expression<F, G> {
|
||||
fn get_count(count: ast::Value<'ast>) -> usize {
|
||||
match count {
|
||||
ast::Value::Integer(f) => f
|
||||
@ -332,7 +360,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, F: Field + PrimeField, G: Group> From<ast::Assignee<'ast>> for types::Expression<F, G> {
|
||||
fn from(assignee: ast::Assignee<'ast>) -> Self {
|
||||
let variable = types::Expression::Variable(types::Variable::from(assignee.variable));
|
||||
|
||||
@ -357,13 +385,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, F: Field + PrimeField, G: Group> From<ast::Variable<'ast>> for types::Assignee<F, G> {
|
||||
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, F: Field + PrimeField, G: Group> From<ast::Assignee<'ast>> for types::Assignee<F, G> {
|
||||
fn from(assignee: ast::Assignee<'ast>) -> Self {
|
||||
let variable = types::Assignee::from(assignee.variable);
|
||||
|
||||
@ -386,7 +414,9 @@ 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, F: Field + PrimeField, G: Group> From<ast::ReturnStatement<'ast>>
|
||||
for types::Statement<F, G>
|
||||
{
|
||||
fn from(statement: ast::ReturnStatement<'ast>) -> Self {
|
||||
types::Statement::Return(
|
||||
statement
|
||||
@ -398,17 +428,23 @@ 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, F: Field + PrimeField, G: Group> From<ast::DefinitionStatement<'ast>>
|
||||
for types::Statement<F, G>
|
||||
{
|
||||
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::<F, G>::from(_type)),
|
||||
types::Expression::from(statement.expression),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::AssignStatement<'ast>> for types::Statement<F> {
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::AssignStatement<'ast>>
|
||||
for types::Statement<F, G>
|
||||
{
|
||||
fn from(statement: ast::AssignStatement<'ast>) -> Self {
|
||||
match statement.assign {
|
||||
ast::OperationAssign::Assign(ref _assign) => types::Statement::Assign(
|
||||
@ -464,8 +500,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, F: Field + PrimeField, G: Group> From<ast::MultipleAssignmentStatement<'ast>>
|
||||
for types::Statement<F, G>
|
||||
{
|
||||
fn from(statement: ast::MultipleAssignmentStatement<'ast>) -> Self {
|
||||
let assignees = statement
|
||||
@ -488,8 +524,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, F: Field + PrimeField, G: Group> From<ast::ConditionalNestedOrEnd<'ast>>
|
||||
for types::ConditionalNestedOrEnd<F, G>
|
||||
{
|
||||
fn from(statement: ast::ConditionalNestedOrEnd<'ast>) -> Self {
|
||||
match statement {
|
||||
@ -506,8 +542,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, F: Field + PrimeField, G: Group> From<ast::ConditionalStatement<'ast>>
|
||||
for types::ConditionalStatement<F, G>
|
||||
{
|
||||
fn from(statement: ast::ConditionalStatement<'ast>) -> Self {
|
||||
types::ConditionalStatement {
|
||||
@ -525,13 +561,15 @@ impl<'ast, F: Field + PrimeField> From<ast::ConditionalStatement<'ast>>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::ForStatement<'ast>> for types::Statement<F> {
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::ForStatement<'ast>>
|
||||
for types::Statement<F, G>
|
||||
{
|
||||
fn from(statement: ast::ForStatement<'ast>) -> Self {
|
||||
let from = match types::Expression::<F>::from(statement.start) {
|
||||
let from = match types::Expression::<F, G>::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::<F, G>::from(statement.stop) {
|
||||
types::Expression::Integer(number) => number,
|
||||
expression => unimplemented!("Range bounds should be integers, found {}", expression),
|
||||
};
|
||||
@ -549,7 +587,9 @@ 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, F: Field + PrimeField, G: Group> From<ast::AssertStatement<'ast>>
|
||||
for types::Statement<F, G>
|
||||
{
|
||||
fn from(statement: ast::AssertStatement<'ast>) -> Self {
|
||||
match statement {
|
||||
ast::AssertStatement::AssertEq(assert_eq) => types::Statement::AssertEq(
|
||||
@ -560,13 +600,15 @@ 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, F: Field + PrimeField, G: Group> From<ast::ExpressionStatement<'ast>>
|
||||
for types::Statement<F, G>
|
||||
{
|
||||
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, F: Field + PrimeField, G: Group> From<ast::Statement<'ast>> for types::Statement<F, G> {
|
||||
fn from(statement: ast::Statement<'ast>) -> Self {
|
||||
match statement {
|
||||
ast::Statement::Return(statement) => types::Statement::from(statement),
|
||||
@ -597,32 +639,39 @@ impl From<ast::IntegerType> for types::IntegerType {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::BasicType<'ast>> for types::Type<F> {
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::BasicType<'ast>> for types::Type<F, G> {
|
||||
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, F: Field + PrimeField, G: Group> From<ast::ArrayType<'ast>> for types::Type<F, G> {
|
||||
fn from(array_type: ast::ArrayType<'ast>) -> Self {
|
||||
let element_type = Box::new(types::Type::from(array_type._type));
|
||||
let count = types::Expression::<F>::get_count(array_type.count);
|
||||
let dimensions = array_type
|
||||
.dimensions
|
||||
.into_iter()
|
||||
.map(|row| types::Expression::<F, G>::get_count(row))
|
||||
.collect();
|
||||
|
||||
types::Type::Array(element_type, count)
|
||||
types::Type::Array(element_type, dimensions)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField> From<ast::StructType<'ast>> for types::Type<F> {
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::StructType<'ast>> for types::Type<F, G> {
|
||||
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, F: Field + PrimeField, G: Group> From<ast::Type<'ast>> for types::Type<F, G> {
|
||||
fn from(_type: ast::Type<'ast>) -> Self {
|
||||
match _type {
|
||||
ast::Type::Basic(_type) => types::Type::from(_type),
|
||||
@ -634,7 +683,9 @@ 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, F: Field + PrimeField, G: Group> From<ast::StructField<'ast>>
|
||||
for types::StructField<F, G>
|
||||
{
|
||||
fn from(struct_field: ast::StructField<'ast>) -> Self {
|
||||
types::StructField {
|
||||
variable: types::Variable::from(struct_field.variable),
|
||||
@ -643,7 +694,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, F: Field + PrimeField, G: Group> From<ast::Struct<'ast>> for types::Struct<F, G> {
|
||||
fn from(struct_definition: ast::Struct<'ast>) -> Self {
|
||||
let variable = types::Variable::from(struct_definition.variable);
|
||||
let fields = struct_definition
|
||||
@ -658,7 +709,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, F: Field + PrimeField, G: Group> From<ast::Parameter<'ast>> for types::InputModel<F, G> {
|
||||
fn from(parameter: ast::Parameter<'ast>) -> Self {
|
||||
let _type = types::Type::from(parameter._type);
|
||||
let variable = types::Variable::from(parameter.variable);
|
||||
@ -691,7 +742,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, F: Field + PrimeField, G: Group> From<ast::Function<'ast>> for types::Function<F, G> {
|
||||
fn from(function_definition: ast::Function<'ast>) -> Self {
|
||||
let function_name = types::FunctionName::from(function_definition.function_name);
|
||||
let parameters = function_definition
|
||||
@ -721,7 +772,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, F: Field + PrimeField, G: Group> From<ast::ImportSymbol<'ast>> for ImportSymbol<F, G> {
|
||||
fn from(symbol: ast::ImportSymbol<'ast>) -> Self {
|
||||
ImportSymbol {
|
||||
symbol: types::Variable::from(symbol.value),
|
||||
@ -730,7 +781,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, F: Field + PrimeField, G: Group> From<ast::Import<'ast>> for Import<F, G> {
|
||||
fn from(import: ast::Import<'ast>) -> Self {
|
||||
Import {
|
||||
path_string: import.source.value,
|
||||
@ -745,14 +796,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, F: Field + PrimeField, G: Group> types::Program<F, G> {
|
||||
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<F, G>>>();
|
||||
|
||||
let mut structs = HashMap::new();
|
||||
let mut functions = HashMap::new();
|
||||
@ -778,7 +829,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,
|
||||
|
@ -6,7 +6,10 @@ use crate::{cli::*, cli_types::*};
|
||||
use leo_compiler::compiler::Compiler;
|
||||
|
||||
use snarkos_algorithms::snark::KeypairAssembly;
|
||||
use snarkos_curves::bls12_377::{Bls12_377, Fr};
|
||||
use snarkos_curves::{
|
||||
bls12_377::{Bls12_377, Fr},
|
||||
edwards_bls12::EdwardsProjective
|
||||
};
|
||||
|
||||
use clap::ArgMatches;
|
||||
use std::convert::TryFrom;
|
||||
@ -17,7 +20,7 @@ pub struct BuildCommand;
|
||||
|
||||
impl CLI for BuildCommand {
|
||||
type Options = ();
|
||||
type Output = (Compiler<Fr>, bool);
|
||||
type Output = (Compiler<Fr, EdwardsProjective>, bool);
|
||||
|
||||
const NAME: NameType = "build";
|
||||
const ABOUT: AboutType = "Compile the current package";
|
||||
@ -61,7 +64,7 @@ impl CLI for BuildCommand {
|
||||
main_file_path.push(MAIN_FILE_NAME);
|
||||
|
||||
// Compute the current program checksum
|
||||
let mut program = Compiler::<Fr>::init(package_name.clone(), main_file_path.clone());
|
||||
let mut program = Compiler::<Fr, EdwardsProjective>::init(package_name.clone(), main_file_path.clone());
|
||||
let checksum = program.checksum()?;
|
||||
|
||||
// If a checksum file exists, check if it differs from the new checksum
|
||||
@ -88,8 +91,8 @@ impl CLI for BuildCommand {
|
||||
// bt: vec![],
|
||||
// ct: vec![],
|
||||
// };
|
||||
program.evaluate_program::<KeypairAssembly::<Bls12_377>>()?;
|
||||
}
|
||||
program.evaluate_program::<KeypairAssembly::<Bls12_377>>()?;
|
||||
|
||||
log::info!("Compiled program in {:?}", main_file_path);
|
||||
|
||||
|
@ -8,7 +8,10 @@ use leo_compiler::compiler::Compiler;
|
||||
use snarkos_algorithms::snark::{
|
||||
generate_random_parameters, prepare_verifying_key, Parameters, PreparedVerifyingKey,
|
||||
};
|
||||
use snarkos_curves::bls12_377::{Bls12_377, Fr};
|
||||
use snarkos_curves::{
|
||||
bls12_377::{Bls12_377, Fr},
|
||||
edwards_bls12::EdwardsProjective
|
||||
};
|
||||
use snarkos_utilities::bytes::ToBytes;
|
||||
|
||||
use clap::ArgMatches;
|
||||
@ -23,7 +26,7 @@ pub struct SetupCommand;
|
||||
impl CLI for SetupCommand {
|
||||
type Options = ();
|
||||
type Output = (
|
||||
Compiler<Fr>,
|
||||
Compiler<Fr, EdwardsProjective>,
|
||||
Parameters<Bls12_377>,
|
||||
PreparedVerifyingKey<Bls12_377>,
|
||||
);
|
||||
|
@ -1,47 +1,47 @@
|
||||
use crate::errors::*;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum CLIError {
|
||||
#[fail(display = "{}", _0)]
|
||||
#[error("{}", _0)]
|
||||
BuildError(BuildError),
|
||||
|
||||
#[fail(display = "{}: {}", _0, _1)]
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
#[error("{}", _0)]
|
||||
ChecksumFileError(ChecksumFileError),
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
#[error("{}", _0)]
|
||||
InitError(InitError),
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
#[error("{}", _0)]
|
||||
InputsDirectoryError(InputsDirectoryError),
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
#[error("{}", _0)]
|
||||
MainFileError(MainFileError),
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
#[error("{}", _0)]
|
||||
ManifestError(ManifestError),
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
#[error("{}", _0)]
|
||||
NewError(NewError),
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
#[error("{}", _0)]
|
||||
OutputsDirectoryError(OutputsDirectoryError),
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
#[error("{}", _0)]
|
||||
ProofFileError(ProofFileError),
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
#[error("{}", _0)]
|
||||
ProvingKeyFileError(ProvingKeyFileError),
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
#[error("{}", _0)]
|
||||
RunError(RunError),
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
#[error("{}", _0)]
|
||||
SourceDirectoryError(SourceDirectoryError),
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
#[error("{}", _0)]
|
||||
VerificationKeyFileError(VerificationKeyFileError),
|
||||
}
|
||||
|
||||
|
@ -2,12 +2,12 @@ use crate::errors::ManifestError;
|
||||
|
||||
use std::ffi::OsString;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum BuildError {
|
||||
#[fail(display = "main file {:?} does not exist", _0)]
|
||||
#[error("main file {:?} does not exist", _0)]
|
||||
MainFileDoesNotExist(OsString),
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
#[error("{}", _0)]
|
||||
ManifestError(ManifestError),
|
||||
}
|
||||
|
||||
|
@ -3,21 +3,21 @@ use crate::errors::ManifestError;
|
||||
use std::ffi::OsString;
|
||||
use std::io;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum InitError {
|
||||
#[fail(display = "root directory {:?} creating: {}", _0, _1)]
|
||||
#[error("root directory {:?} creating: {}", _0, _1)]
|
||||
CreatingRootDirectory(OsString, io::Error),
|
||||
|
||||
#[fail(display = "directory {:?} does not exist", _0)]
|
||||
#[error("directory {:?} does not exist", _0)]
|
||||
DirectoryDoesNotExist(OsString),
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
#[error("{}", _0)]
|
||||
ManifestError(ManifestError),
|
||||
|
||||
#[fail(display = "package at path {:?} already exists", _0)]
|
||||
#[error("package at path {:?} already exists", _0)]
|
||||
PackageAlreadyExists(OsString),
|
||||
|
||||
#[fail(display = "package name is missing - {:?}", _0)]
|
||||
#[error("package name is missing - {:?}", _0)]
|
||||
ProjectNameInvalid(OsString),
|
||||
}
|
||||
|
||||
|
@ -3,21 +3,21 @@ use crate::errors::ManifestError;
|
||||
use std::ffi::OsString;
|
||||
use std::io;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum NewError {
|
||||
#[fail(display = "root directory {:?} creating: {}", _0, _1)]
|
||||
#[error("root directory {:?} creating: {}", _0, _1)]
|
||||
CreatingRootDirectory(OsString, io::Error),
|
||||
|
||||
#[fail(display = "directory {:?} already exists", _0)]
|
||||
#[error("directory {:?} already exists", _0)]
|
||||
DirectoryAlreadyExists(OsString),
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
#[error("{}", _0)]
|
||||
ManifestError(ManifestError),
|
||||
|
||||
#[fail(display = "package at path {:?} already exists", _0)]
|
||||
#[error("package at path {:?} already exists", _0)]
|
||||
PackageAlreadyExists(OsString),
|
||||
|
||||
#[fail(display = "package name is missing - {:?}", _0)]
|
||||
#[error("package name is missing - {:?}", _0)]
|
||||
ProjectNameInvalid(OsString),
|
||||
}
|
||||
|
||||
|
@ -2,12 +2,12 @@ use crate::errors::ManifestError;
|
||||
|
||||
use std::ffi::OsString;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum RunError {
|
||||
#[fail(display = "main file {:?} does not exist", _0)]
|
||||
#[error("main file {:?} does not exist", _0)]
|
||||
MainFileDoesNotExist(OsString),
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
#[error("{}", _0)]
|
||||
ManifestError(ManifestError),
|
||||
}
|
||||
|
||||
|
@ -1,25 +1,25 @@
|
||||
use std::{ffi::OsString, fs::FileType, io};
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum InputsDirectoryError {
|
||||
#[fail(display = "creating: {}", _0)]
|
||||
#[error("creating: {}", _0)]
|
||||
Creating(io::Error),
|
||||
|
||||
#[fail(display = "file entry getting: {}", _0)]
|
||||
#[error("file entry getting: {}", _0)]
|
||||
GettingFileEntry(io::Error),
|
||||
|
||||
#[fail(display = "file {:?} extension getting", _0)]
|
||||
#[error("file {:?} extension getting", _0)]
|
||||
GettingFileExtension(OsString),
|
||||
|
||||
#[fail(display = "file {:?} type getting: {}", _0, _1)]
|
||||
#[error("file {:?} type getting: {}", _0, _1)]
|
||||
GettingFileType(OsString, io::Error),
|
||||
|
||||
#[fail(display = "invalid file {:?} extension: {:?}", _0, _1)]
|
||||
#[error("invalid file {:?} extension: {:?}", _0, _1)]
|
||||
InvalidFileExtension(OsString, OsString),
|
||||
|
||||
#[fail(display = "invalid file {:?} type: {:?}", _0, _1)]
|
||||
#[error("invalid file {:?} type: {:?}", _0, _1)]
|
||||
InvalidFileType(OsString, FileType),
|
||||
|
||||
#[fail(display = "reading: {}", _0)]
|
||||
#[error("reading: {}", _0)]
|
||||
Reading(io::Error),
|
||||
}
|
||||
|
@ -1,28 +1,28 @@
|
||||
use std::{ffi::OsString, fs::FileType, io};
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum OutputsDirectoryError {
|
||||
#[fail(display = "creating: {}", _0)]
|
||||
#[error("creating: {}", _0)]
|
||||
Creating(io::Error),
|
||||
|
||||
#[fail(display = "file entry getting: {}", _0)]
|
||||
#[error("file entry getting: {}", _0)]
|
||||
GettingFileEntry(io::Error),
|
||||
|
||||
#[fail(display = "file {:?} extension getting", _0)]
|
||||
#[error("file {:?} extension getting", _0)]
|
||||
GettingFileExtension(OsString),
|
||||
|
||||
#[fail(display = "file {:?} type getting: {}", _0, _1)]
|
||||
#[error("file {:?} type getting: {}", _0, _1)]
|
||||
GettingFileType(OsString, io::Error),
|
||||
|
||||
#[fail(display = "invalid file {:?} extension: {:?}", _0, _1)]
|
||||
#[error("invalid file {:?} extension: {:?}", _0, _1)]
|
||||
InvalidFileExtension(OsString, OsString),
|
||||
|
||||
#[fail(display = "invalid file {:?} type: {:?}", _0, _1)]
|
||||
#[error("invalid file {:?} type: {:?}", _0, _1)]
|
||||
InvalidFileType(OsString, FileType),
|
||||
|
||||
#[fail(display = "reading: {}", _0)]
|
||||
#[error("reading: {}", _0)]
|
||||
Reading(io::Error),
|
||||
|
||||
#[fail(display = "removing: {}", _0)]
|
||||
#[error("removing: {}", _0)]
|
||||
Removing(io::Error),
|
||||
}
|
||||
|
@ -1,25 +1,25 @@
|
||||
use std::{ffi::OsString, fs::FileType, io};
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SourceDirectoryError {
|
||||
#[fail(display = "creating: {}", _0)]
|
||||
#[error("creating: {}", _0)]
|
||||
Creating(io::Error),
|
||||
|
||||
#[fail(display = "file entry getting: {}", _0)]
|
||||
#[error("file entry getting: {}", _0)]
|
||||
GettingFileEntry(io::Error),
|
||||
|
||||
#[fail(display = "file {:?} extension getting", _0)]
|
||||
#[error("file {:?} extension getting", _0)]
|
||||
GettingFileExtension(OsString),
|
||||
|
||||
#[fail(display = "file {:?} type getting: {}", _0, _1)]
|
||||
#[error("file {:?} type getting: {}", _0, _1)]
|
||||
GettingFileType(OsString, io::Error),
|
||||
|
||||
#[fail(display = "invalid file {:?} extension: {:?}", _0, _1)]
|
||||
#[error("invalid file {:?} extension: {:?}", _0, _1)]
|
||||
InvalidFileExtension(OsString, OsString),
|
||||
|
||||
#[fail(display = "invalid file {:?} type: {:?}", _0, _1)]
|
||||
#[error("invalid file {:?} type: {:?}", _0, _1)]
|
||||
InvalidFileType(OsString, FileType),
|
||||
|
||||
#[fail(display = "reading: {}", _0)]
|
||||
#[error("reading: {}", _0)]
|
||||
Reading(io::Error),
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ChecksumFileError {
|
||||
#[fail(display = "{}: {}", _0, _1)]
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
|
||||
#[fail(display = "creating: {}", _0)]
|
||||
#[error("creating: {}", _0)]
|
||||
Creating(io::Error),
|
||||
|
||||
#[fail(display = "Cannot read from the provided file path - {:?}", _0)]
|
||||
#[error("Cannot read from the provided file path - {:?}", _0)]
|
||||
FileReadError(PathBuf),
|
||||
|
||||
#[fail(display = "writing: {}", _0)]
|
||||
#[error("writing: {}", _0)]
|
||||
Writing(io::Error),
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
use std::io;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum MainFileError {
|
||||
#[fail(display = "{}: {}", _0, _1)]
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
|
||||
#[fail(display = "creating: {}", _0)]
|
||||
#[error("creating: {}", _0)]
|
||||
Creating(io::Error),
|
||||
|
||||
#[fail(display = "writing: {}", _0)]
|
||||
#[error("writing: {}", _0)]
|
||||
Writing(io::Error),
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ProofFileError {
|
||||
#[fail(display = "{}: {}", _0, _1)]
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
|
||||
#[fail(display = "creating: {}", _0)]
|
||||
#[error("creating: {}", _0)]
|
||||
Creating(io::Error),
|
||||
|
||||
#[fail(display = "Cannot read from the provided file path - {:?}", _0)]
|
||||
#[error("Cannot read from the provided file path - {:?}", _0)]
|
||||
FileReadError(PathBuf),
|
||||
|
||||
#[fail(display = "writing: {}", _0)]
|
||||
#[error("writing: {}", _0)]
|
||||
Writing(io::Error),
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ProvingKeyFileError {
|
||||
#[fail(display = "{}: {}", _0, _1)]
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
|
||||
#[fail(display = "creating: {}", _0)]
|
||||
#[error("creating: {}", _0)]
|
||||
Creating(io::Error),
|
||||
|
||||
#[fail(display = "Cannot read from the provided file path - {:?}", _0)]
|
||||
#[error("Cannot read from the provided file path - {:?}", _0)]
|
||||
FileReadError(PathBuf),
|
||||
|
||||
#[fail(display = "writing: {}", _0)]
|
||||
#[error("writing: {}", _0)]
|
||||
Writing(io::Error),
|
||||
}
|
||||
|
||||
|
@ -1,21 +1,21 @@
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum VerificationKeyFileError {
|
||||
#[fail(display = "{}: {}", _0, _1)]
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
|
||||
#[fail(display = "creating: {}", _0)]
|
||||
#[error("creating: {}", _0)]
|
||||
Creating(io::Error),
|
||||
|
||||
#[fail(display = "Cannot read from the provided file path - {:?}", _0)]
|
||||
#[error("Cannot read from the provided file path - {:?}", _0)]
|
||||
FileReadError(PathBuf),
|
||||
|
||||
#[fail(display = "Verification key file was corrupted")]
|
||||
#[error("Verification key file was corrupted")]
|
||||
IncorrectVerificationKey,
|
||||
|
||||
#[fail(display = "writing: {}", _0)]
|
||||
#[error("writing: {}", _0)]
|
||||
Writing(io::Error),
|
||||
}
|
||||
|
||||
|
@ -1,22 +1,22 @@
|
||||
use std::io;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ManifestError {
|
||||
#[fail(display = "`{}` creating: {}", _0, _1)]
|
||||
#[error("`{}` creating: {}", _0, _1)]
|
||||
Creating(&'static str, io::Error),
|
||||
|
||||
#[fail(display = "`{}` metadata: {}", _0, _1)]
|
||||
#[error("`{}` metadata: {}", _0, _1)]
|
||||
Metadata(&'static str, io::Error),
|
||||
|
||||
#[fail(display = "`{}` opening: {}", _0, _1)]
|
||||
#[error("`{}` opening: {}", _0, _1)]
|
||||
Opening(&'static str, io::Error),
|
||||
|
||||
#[fail(display = "`{}` parsing: {}", _0, _1)]
|
||||
#[error("`{}` parsing: {}", _0, _1)]
|
||||
Parsing(&'static str, toml::de::Error),
|
||||
|
||||
#[fail(display = "`{}` reading: {}", _0, _1)]
|
||||
#[error("`{}` reading: {}", _0, _1)]
|
||||
Reading(&'static str, io::Error),
|
||||
|
||||
#[fail(display = "`{}` writing: {}", _0, _1)]
|
||||
#[error("`{}` writing: {}", _0, _1)]
|
||||
Writing(&'static str, io::Error),
|
||||
}
|
||||
|
@ -49,8 +49,8 @@ impl MainFile {
|
||||
fn template(&self) -> String {
|
||||
format!(
|
||||
r#"// The '{}' main function.
|
||||
function main() -> (u32) {{
|
||||
a = 1 + 1;
|
||||
function main() -> u32 {{
|
||||
let a = 1 + 1;
|
||||
return a
|
||||
}}
|
||||
"#,
|
||||
|
@ -1,5 +1,5 @@
|
||||
#[macro_use]
|
||||
extern crate failure;
|
||||
extern crate thiserror;
|
||||
|
||||
#[cfg_attr(tarpaulin, skip)]
|
||||
pub mod cli;
|
||||
|
Loading…
Reference in New Issue
Block a user