mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-26 11:45:00 +03:00
Merge pull request #73 from AleoHQ/feature/comparator
Feature/comparator
This commit is contained in:
commit
14adaaa820
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -607,7 +607,6 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"snarkos-errors",
|
"snarkos-errors",
|
||||||
"snarkos-models",
|
"snarkos-models",
|
||||||
"thiserror",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
28
compiler/src/constraints/comparator.rs
Normal file
28
compiler/src/constraints/comparator.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use snarkos_errors::gadgets::SynthesisError;
|
||||||
|
use snarkos_models::{
|
||||||
|
curves::Field,
|
||||||
|
gadgets::{r1cs::ConstraintSystem, utilities::boolean::Boolean},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub trait EvaluateLtGadget<F: Field> {
|
||||||
|
fn less_than<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Boolean, SynthesisError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// implementing `EvaluateLtGadget` will implement `ComparatorGadget`
|
||||||
|
pub trait ComparatorGadget<F: Field>
|
||||||
|
where
|
||||||
|
Self: EvaluateLtGadget<F>,
|
||||||
|
{
|
||||||
|
fn greater_than<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Boolean, SynthesisError> {
|
||||||
|
other.less_than(cs, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn less_than_or_equal<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Boolean, SynthesisError> {
|
||||||
|
let is_gt = self.greater_than(cs, other)?;
|
||||||
|
Ok(is_gt.not())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn greater_than_or_equal<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Boolean, SynthesisError> {
|
||||||
|
other.less_than_or_equal(cs, self)
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
//! Methods to enforce constraints on expressions in a resolved Leo program.
|
//! Methods to enforce constraints on expressions in a resolved Leo program.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
comparator::{ComparatorGadget, EvaluateLtGadget},
|
||||||
constraints::{
|
constraints::{
|
||||||
boolean::{enforce_and, enforce_or, evaluate_not, new_bool_constant},
|
boolean::{enforce_and, enforce_or, evaluate_not, new_bool_constant},
|
||||||
new_scope,
|
new_scope,
|
||||||
@ -11,13 +12,13 @@ use crate::{
|
|||||||
errors::ExpressionError,
|
errors::ExpressionError,
|
||||||
FieldType,
|
FieldType,
|
||||||
GroupType,
|
GroupType,
|
||||||
|
Integer,
|
||||||
};
|
};
|
||||||
use leo_types::{
|
use leo_types::{
|
||||||
CircuitFieldDefinition,
|
CircuitFieldDefinition,
|
||||||
CircuitMember,
|
CircuitMember,
|
||||||
Expression,
|
Expression,
|
||||||
Identifier,
|
Identifier,
|
||||||
Integer,
|
|
||||||
IntegerType,
|
IntegerType,
|
||||||
RangeOrExpression,
|
RangeOrExpression,
|
||||||
Span,
|
Span,
|
||||||
@ -76,11 +77,11 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||||
Ok(ConstrainedValue::Integer(num_1.add(cs, num_2, span)?))
|
Ok(ConstrainedValue::Integer(num_1.add(cs, num_2, span)?))
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
|
(ConstrainedValue::Field(field_1), ConstrainedValue::Field(field_2)) => {
|
||||||
Ok(ConstrainedValue::Field(fe_1.add(cs, &fe_2, span)?))
|
Ok(ConstrainedValue::Field(field_1.add(cs, &field_2, span)?))
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Group(ge_1), ConstrainedValue::Group(ge_2)) => {
|
(ConstrainedValue::Group(point_1), ConstrainedValue::Group(point_2)) => {
|
||||||
Ok(ConstrainedValue::Group(ge_1.add(cs, &ge_2, span)?))
|
Ok(ConstrainedValue::Group(point_1.add(cs, &point_2, span)?))
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||||
@ -108,11 +109,11 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||||
Ok(ConstrainedValue::Integer(num_1.sub(cs, num_2, span)?))
|
Ok(ConstrainedValue::Integer(num_1.sub(cs, num_2, span)?))
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
|
(ConstrainedValue::Field(field_1), ConstrainedValue::Field(field_2)) => {
|
||||||
Ok(ConstrainedValue::Field(fe_1.sub(cs, &fe_2, span)?))
|
Ok(ConstrainedValue::Field(field_1.sub(cs, &field_2, span)?))
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Group(ge_1), ConstrainedValue::Group(ge_2)) => {
|
(ConstrainedValue::Group(point_1), ConstrainedValue::Group(point_2)) => {
|
||||||
Ok(ConstrainedValue::Group(ge_1.sub(cs, &ge_2, span)?))
|
Ok(ConstrainedValue::Group(point_1.sub(cs, &point_2, span)?))
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||||
@ -140,8 +141,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||||
Ok(ConstrainedValue::Integer(num_1.mul(cs, num_2, span)?))
|
Ok(ConstrainedValue::Integer(num_1.mul(cs, num_2, span)?))
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
|
(ConstrainedValue::Field(field_1), ConstrainedValue::Field(field_2)) => {
|
||||||
Ok(ConstrainedValue::Field(fe_1.mul(cs, &fe_2, span)?))
|
Ok(ConstrainedValue::Field(field_1.mul(cs, &field_2, span)?))
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||||
@ -171,8 +172,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||||
Ok(ConstrainedValue::Integer(num_1.div(cs, num_2, span)?))
|
Ok(ConstrainedValue::Integer(num_1.div(cs, num_2, span)?))
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
|
(ConstrainedValue::Field(field_1), ConstrainedValue::Field(field_2)) => {
|
||||||
Ok(ConstrainedValue::Field(fe_1.div(cs, &fe_2, span)?))
|
Ok(ConstrainedValue::Field(field_1.div(cs, &field_2, span)?))
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||||
@ -233,11 +234,11 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||||
num_1.evaluate_equal(unique_namespace, &num_2)
|
num_1.evaluate_equal(unique_namespace, &num_2)
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
|
(ConstrainedValue::Field(field_1), ConstrainedValue::Field(field_2)) => {
|
||||||
fe_1.evaluate_equal(unique_namespace, &fe_2)
|
field_1.evaluate_equal(unique_namespace, &field_2)
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Group(ge_1), ConstrainedValue::Group(ge_2)) => {
|
(ConstrainedValue::Group(point_1), ConstrainedValue::Group(point_2)) => {
|
||||||
ge_1.evaluate_equal(unique_namespace, &ge_2)
|
point_1.evaluate_equal(unique_namespace, &point_2)
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||||
@ -256,133 +257,157 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let boolean =
|
let boolean =
|
||||||
constraint_result.map_err(|e| ExpressionError::cannot_enforce(format!("evaluate equals"), e, span))?;
|
constraint_result.map_err(|e| ExpressionError::cannot_enforce(format!("evaluate equal"), e, span))?;
|
||||||
|
|
||||||
Ok(ConstrainedValue::Boolean(boolean))
|
Ok(ConstrainedValue::Boolean(boolean))
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: unsafe for allocated values
|
fn evaluate_ge_expression<CS: ConstraintSystem<F>>(
|
||||||
fn evaluate_ge_expression(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
|
cs: &mut CS,
|
||||||
left: ConstrainedValue<F, G>,
|
left: ConstrainedValue<F, G>,
|
||||||
right: ConstrainedValue<F, G>,
|
right: ConstrainedValue<F, G>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||||
match (left, right) {
|
let mut unique_namespace = cs.ns(|| format!("evaluate {} >= {} {}:{}", left, right, span.line, span.start));
|
||||||
|
let constraint_result = match (left, right) {
|
||||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||||
let result = num_1.ge(&num_2);
|
num_1.greater_than_or_equal(unique_namespace, &num_2)
|
||||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
|
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
|
(ConstrainedValue::Field(field_1), ConstrainedValue::Field(field_2)) => {
|
||||||
let result = fe_1.ge(&fe_2);
|
field_1.greater_than_or_equal(unique_namespace, &field_2)
|
||||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
|
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||||
self.evaluate_ge_expression(val_1, val_2, span)
|
return self.evaluate_ge_expression(&mut unique_namespace, val_1, val_2, span);
|
||||||
}
|
}
|
||||||
(val_1, ConstrainedValue::Unresolved(string)) => {
|
(val_1, ConstrainedValue::Unresolved(string)) => {
|
||||||
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
||||||
self.evaluate_ge_expression(val_1, val_2, span)
|
return self.evaluate_ge_expression(&mut unique_namespace, val_1, val_2, span);
|
||||||
}
|
}
|
||||||
(val_1, val_2) => Err(ExpressionError::incompatible_types(
|
(val_1, val_2) => {
|
||||||
format!("{} >= {}", val_1, val_2),
|
return Err(ExpressionError::incompatible_types(
|
||||||
span,
|
format!("{} >= {}", val_1, val_2),
|
||||||
)),
|
span,
|
||||||
}
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let boolean = constraint_result
|
||||||
|
.map_err(|e| ExpressionError::cannot_enforce(format!("evaluate greater than or equal"), e, span))?;
|
||||||
|
|
||||||
|
Ok(ConstrainedValue::Boolean(boolean))
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: unsafe for allocated values
|
fn evaluate_gt_expression<CS: ConstraintSystem<F>>(
|
||||||
fn evaluate_gt_expression(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
|
cs: &mut CS,
|
||||||
left: ConstrainedValue<F, G>,
|
left: ConstrainedValue<F, G>,
|
||||||
right: ConstrainedValue<F, G>,
|
right: ConstrainedValue<F, G>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||||
match (left, right) {
|
let mut unique_namespace = cs.ns(|| format!("evaluate {} > {} {}:{}", left, right, span.line, span.start));
|
||||||
|
let constraint_result = match (left, right) {
|
||||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||||
let result = num_1.gt(&num_2);
|
num_1.greater_than(unique_namespace, &num_2)
|
||||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
|
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
|
(ConstrainedValue::Field(field_1), ConstrainedValue::Field(field_2)) => {
|
||||||
let result = fe_1.gt(&fe_2);
|
field_1.greater_than(unique_namespace, &field_2)
|
||||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
|
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||||
self.evaluate_gt_expression(val_1, val_2, span)
|
return self.evaluate_gt_expression(&mut unique_namespace, val_1, val_2, span);
|
||||||
}
|
}
|
||||||
(val_1, ConstrainedValue::Unresolved(string)) => {
|
(val_1, ConstrainedValue::Unresolved(string)) => {
|
||||||
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
||||||
self.evaluate_gt_expression(val_1, val_2, span)
|
return self.evaluate_gt_expression(&mut unique_namespace, val_1, val_2, span);
|
||||||
}
|
}
|
||||||
(val_1, val_2) => Err(ExpressionError::incompatible_types(
|
(val_1, val_2) => {
|
||||||
format!("{} > {}", val_1, val_2),
|
return Err(ExpressionError::incompatible_types(
|
||||||
span,
|
format!("{} > {}", val_1, val_2),
|
||||||
)),
|
span,
|
||||||
}
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let boolean = constraint_result
|
||||||
|
.map_err(|e| ExpressionError::cannot_enforce(format!("evaluate greater than"), e, span))?;
|
||||||
|
|
||||||
|
Ok(ConstrainedValue::Boolean(boolean))
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: unsafe for allocated values
|
fn evaluate_le_expression<CS: ConstraintSystem<F>>(
|
||||||
fn evaluate_le_expression(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
|
cs: &mut CS,
|
||||||
left: ConstrainedValue<F, G>,
|
left: ConstrainedValue<F, G>,
|
||||||
right: ConstrainedValue<F, G>,
|
right: ConstrainedValue<F, G>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||||
match (left, right) {
|
let mut unique_namespace = cs.ns(|| format!("evaluate {} <= {} {}:{}", left, right, span.line, span.start));
|
||||||
|
let constraint_result = match (left, right) {
|
||||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||||
let result = num_1.le(&num_2);
|
num_1.less_than_or_equal(unique_namespace, &num_2)
|
||||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
|
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
|
(ConstrainedValue::Field(field_1), ConstrainedValue::Field(field_2)) => {
|
||||||
let result = fe_1.le(&fe_2);
|
field_1.less_than_or_equal(unique_namespace, &field_2)
|
||||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
|
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||||
self.evaluate_le_expression(val_1, val_2, span)
|
return self.evaluate_le_expression(&mut unique_namespace, val_1, val_2, span);
|
||||||
}
|
}
|
||||||
(val_1, ConstrainedValue::Unresolved(string)) => {
|
(val_1, ConstrainedValue::Unresolved(string)) => {
|
||||||
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
||||||
self.evaluate_le_expression(val_1, val_2, span)
|
return self.evaluate_le_expression(&mut unique_namespace, val_1, val_2, span);
|
||||||
}
|
}
|
||||||
(val_1, val_2) => Err(ExpressionError::incompatible_types(
|
(val_1, val_2) => {
|
||||||
format!("{} <= {}", val_1, val_2),
|
return Err(ExpressionError::incompatible_types(
|
||||||
span,
|
format!("{} <= {}", val_1, val_2),
|
||||||
)),
|
span,
|
||||||
}
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let boolean = constraint_result
|
||||||
|
.map_err(|e| ExpressionError::cannot_enforce(format!("evaluate less than or equal"), e, span))?;
|
||||||
|
|
||||||
|
Ok(ConstrainedValue::Boolean(boolean))
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: unsafe for allocated values
|
fn evaluate_lt_expression<CS: ConstraintSystem<F>>(
|
||||||
fn evaluate_lt_expression(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
|
cs: &mut CS,
|
||||||
left: ConstrainedValue<F, G>,
|
left: ConstrainedValue<F, G>,
|
||||||
right: ConstrainedValue<F, G>,
|
right: ConstrainedValue<F, G>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||||
match (left, right) {
|
let mut unique_namespace = cs.ns(|| format!("evaluate {} < {} {}:{}", left, right, span.line, span.start));
|
||||||
|
let constraint_result = match (left, right) {
|
||||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||||
let result = num_1.lt(&num_2);
|
num_1.less_than(unique_namespace, &num_2)
|
||||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
|
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
|
(ConstrainedValue::Field(field_1), ConstrainedValue::Field(field_2)) => {
|
||||||
let result = fe_1.lt(&fe_2);
|
field_1.less_than(unique_namespace, &field_2)
|
||||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(result)))
|
|
||||||
}
|
}
|
||||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||||
self.evaluate_lt_expression(val_1, val_2, span)
|
return self.evaluate_lt_expression(&mut unique_namespace, val_1, val_2, span);
|
||||||
}
|
}
|
||||||
(val_1, ConstrainedValue::Unresolved(string)) => {
|
(val_1, ConstrainedValue::Unresolved(string)) => {
|
||||||
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
||||||
self.evaluate_lt_expression(val_1, val_2, span)
|
return self.evaluate_lt_expression(&mut unique_namespace, val_1, val_2, span);
|
||||||
}
|
}
|
||||||
(val_1, val_2) => Err(ExpressionError::incompatible_types(
|
(val_1, val_2) => {
|
||||||
format!("{} < {}", val_1, val_2,),
|
return Err(ExpressionError::incompatible_types(
|
||||||
span,
|
format!("{} < {}", val_1, val_2),
|
||||||
)),
|
span,
|
||||||
}
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let boolean =
|
||||||
|
constraint_result.map_err(|e| ExpressionError::cannot_enforce(format!("evaluate less than"), e, span))?;
|
||||||
|
|
||||||
|
Ok(ConstrainedValue::Boolean(boolean))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enforce ternary conditional expression
|
/// Enforce ternary conditional expression
|
||||||
@ -1029,7 +1054,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
span.clone(),
|
span.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(self.evaluate_ge_expression(resolved_left, resolved_right, span)?)
|
Ok(self.evaluate_ge_expression(cs, resolved_left, resolved_right, span)?)
|
||||||
}
|
}
|
||||||
Expression::Gt(left, right, span) => {
|
Expression::Gt(left, right, span) => {
|
||||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||||
@ -1042,7 +1067,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
span.clone(),
|
span.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(self.evaluate_gt_expression(resolved_left, resolved_right, span)?)
|
Ok(self.evaluate_gt_expression(cs, resolved_left, resolved_right, span)?)
|
||||||
}
|
}
|
||||||
Expression::Le(left, right, span) => {
|
Expression::Le(left, right, span) => {
|
||||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||||
@ -1055,7 +1080,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
span.clone(),
|
span.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(self.evaluate_le_expression(resolved_left, resolved_right, span)?)
|
Ok(self.evaluate_le_expression(cs, resolved_left, resolved_right, span)?)
|
||||||
}
|
}
|
||||||
Expression::Lt(left, right, span) => {
|
Expression::Lt(left, right, span) => {
|
||||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||||
@ -1068,7 +1093,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
span.clone(),
|
span.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(self.evaluate_lt_expression(resolved_left, resolved_right, span)?)
|
Ok(self.evaluate_lt_expression(cs, resolved_left, resolved_right, span)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conditionals
|
// Conditionals
|
||||||
|
@ -12,8 +12,10 @@ use crate::{
|
|||||||
},
|
},
|
||||||
errors::{FunctionError, StatementError},
|
errors::{FunctionError, StatementError},
|
||||||
GroupType,
|
GroupType,
|
||||||
|
Integer,
|
||||||
};
|
};
|
||||||
use leo_types::{Expression, Function, InputValue, Integer, Span, Type};
|
|
||||||
|
use leo_types::{Expression, Function, InputValue, Span, Type};
|
||||||
|
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
curves::{Field, PrimeField},
|
curves::{Field, PrimeField},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! Conversion of integer declarations to constraints in Leo.
|
//! Conversion of integer declarations to constraints in Leo.
|
||||||
|
use crate::{errors::IntegerError, ComparatorGadget, EvaluateLtGadget};
|
||||||
use crate::{errors::IntegerError, InputValue, IntegerType, Span};
|
use leo_types::{InputValue, IntegerType, Span};
|
||||||
|
|
||||||
use snarkos_errors::gadgets::SynthesisError;
|
use snarkos_errors::gadgets::SynthesisError;
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
@ -88,6 +88,16 @@ impl Integer {
|
|||||||
Ok(value as usize)
|
Ok(value as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_bits_le(&self) -> Vec<Boolean> {
|
||||||
|
match self {
|
||||||
|
Integer::U8(num) => num.bits.clone(),
|
||||||
|
Integer::U16(num) => num.bits.clone(),
|
||||||
|
Integer::U32(num) => num.bits.clone(),
|
||||||
|
Integer::U64(num) => num.bits.clone(),
|
||||||
|
Integer::U128(num) => num.bits.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_type(&self) -> IntegerType {
|
pub fn get_type(&self) -> IntegerType {
|
||||||
match self {
|
match self {
|
||||||
Integer::U8(_u8) => IntegerType::U8,
|
Integer::U8(_u8) => IntegerType::U8,
|
||||||
@ -435,6 +445,42 @@ impl<F: Field + PrimeField> EvaluateEqGadget<F> for Integer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<F: Field + PrimeField> EvaluateLtGadget<F> for Integer {
|
||||||
|
fn less_than<CS: ConstraintSystem<F>>(&self, mut cs: CS, other: &Self) -> Result<Boolean, SynthesisError> {
|
||||||
|
if self.to_bits_le().len() != other.to_bits_le().len() {
|
||||||
|
return Err(SynthesisError::Unsatisfiable);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i, (self_bit, other_bit)) in self
|
||||||
|
.to_bits_le()
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.zip(other.to_bits_le().iter().rev())
|
||||||
|
.enumerate()
|
||||||
|
{
|
||||||
|
// is_greater = a & !b
|
||||||
|
// only true when a > b
|
||||||
|
let is_greater = Boolean::and(cs.ns(|| format!("a and not b [{}]", i)), self_bit, &other_bit.not())?;
|
||||||
|
|
||||||
|
// is_less = !a & b
|
||||||
|
// only true when a < b
|
||||||
|
let is_less = Boolean::and(cs.ns(|| format!("not a and b [{}]", i)), &self_bit.not(), other_bit)?;
|
||||||
|
|
||||||
|
if is_greater.get_value().unwrap() {
|
||||||
|
return Ok(is_greater.not());
|
||||||
|
} else if is_less.get_value().unwrap() {
|
||||||
|
return Ok(is_less);
|
||||||
|
} else if i == self.to_bits_le().len() - 1 {
|
||||||
|
return Ok(is_less);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(SynthesisError::Unsatisfiable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F: Field + PrimeField> ComparatorGadget<F> for Integer {}
|
||||||
|
|
||||||
impl<F: Field + PrimeField> EqGadget<F> for Integer {}
|
impl<F: Field + PrimeField> EqGadget<F> for Integer {}
|
||||||
|
|
||||||
impl<F: Field + PrimeField> ConditionalEqGadget<F> for Integer {
|
impl<F: Field + PrimeField> ConditionalEqGadget<F> for Integer {
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
pub mod boolean;
|
pub mod boolean;
|
||||||
|
|
||||||
|
pub(crate) mod comparator;
|
||||||
|
pub(crate) use comparator::*;
|
||||||
|
|
||||||
pub mod function;
|
pub mod function;
|
||||||
pub use self::function::*;
|
pub use self::function::*;
|
||||||
|
|
||||||
@ -10,6 +13,9 @@ pub use self::expression::*;
|
|||||||
|
|
||||||
pub mod field;
|
pub mod field;
|
||||||
|
|
||||||
|
pub mod integer;
|
||||||
|
pub use integer::*;
|
||||||
|
|
||||||
pub mod generate_constraints;
|
pub mod generate_constraints;
|
||||||
pub use self::generate_constraints::*;
|
pub use self::generate_constraints::*;
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ use crate::{
|
|||||||
errors::{StatementError, ValueError},
|
errors::{StatementError, ValueError},
|
||||||
new_scope,
|
new_scope,
|
||||||
GroupType,
|
GroupType,
|
||||||
|
Integer,
|
||||||
};
|
};
|
||||||
use leo_types::{
|
use leo_types::{
|
||||||
Assignee,
|
Assignee,
|
||||||
@ -13,7 +14,6 @@ use leo_types::{
|
|||||||
Declare,
|
Declare,
|
||||||
Expression,
|
Expression,
|
||||||
Identifier,
|
Identifier,
|
||||||
Integer,
|
|
||||||
RangeOrExpression,
|
RangeOrExpression,
|
||||||
Span,
|
Span,
|
||||||
Statement,
|
Statement,
|
||||||
|
@ -10,8 +10,9 @@ use crate::{
|
|||||||
new_scope,
|
new_scope,
|
||||||
FieldType,
|
FieldType,
|
||||||
GroupType,
|
GroupType,
|
||||||
|
Integer,
|
||||||
};
|
};
|
||||||
use leo_types::{Circuit, Function, Identifier, Integer, Span, Type};
|
use leo_types::{Circuit, Function, Identifier, Span, Type};
|
||||||
|
|
||||||
use crate::errors::ExpressionError;
|
use crate::errors::ExpressionError;
|
||||||
use snarkos_errors::gadgets::SynthesisError;
|
use snarkos_errors::gadgets::SynthesisError;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::errors::{BooleanError, FieldError, FunctionError, GroupError, ValueError};
|
use crate::errors::{BooleanError, FieldError, FunctionError, GroupError, IntegerError, ValueError};
|
||||||
use leo_types::{Error as FormattedError, Identifier, IntegerError, Span};
|
use leo_types::{Error as FormattedError, Identifier, Span};
|
||||||
|
|
||||||
use snarkos_errors::gadgets::SynthesisError;
|
use snarkos_errors::gadgets::SynthesisError;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::errors::{BooleanError, ExpressionError, FieldError, GroupError, StatementError, ValueError};
|
use crate::errors::{BooleanError, ExpressionError, FieldError, GroupError, IntegerError, StatementError, ValueError};
|
||||||
use leo_types::{Error as FormattedError, IntegerError, Span};
|
use leo_types::{Error as FormattedError, Span};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{error::Error as FormattedError, Span};
|
use leo_types::{error::Error as FormattedError, Span};
|
||||||
|
|
||||||
use snarkos_errors::gadgets::SynthesisError;
|
use snarkos_errors::gadgets::SynthesisError;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
@ -12,6 +12,9 @@ pub use self::expression::*;
|
|||||||
pub mod import;
|
pub mod import;
|
||||||
pub use self::import::*;
|
pub use self::import::*;
|
||||||
|
|
||||||
|
pub mod integer;
|
||||||
|
pub use integer::*;
|
||||||
|
|
||||||
pub mod field;
|
pub mod field;
|
||||||
pub use self::field::*;
|
pub use self::field::*;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::errors::{BooleanError, ExpressionError, ValueError};
|
use crate::errors::{BooleanError, ExpressionError, IntegerError, ValueError};
|
||||||
use leo_types::{Error as FormattedError, IntegerError, Span, Type};
|
use leo_types::{Error as FormattedError, Span, Type};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::errors::{BooleanError, FieldError, GroupError};
|
use crate::errors::{BooleanError, FieldError, GroupError, IntegerError};
|
||||||
use leo_types::{Error as FormattedError, IntegerError, Span};
|
use leo_types::{Error as FormattedError, Span};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
use crate::errors::FieldError;
|
use crate::errors::FieldError;
|
||||||
use leo_types::Span;
|
use leo_types::Span;
|
||||||
|
|
||||||
|
use crate::{ComparatorGadget, EvaluateLtGadget};
|
||||||
use snarkos_errors::gadgets::SynthesisError;
|
use snarkos_errors::gadgets::SynthesisError;
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
curves::{Field, PrimeField},
|
curves::{Field, PrimeField},
|
||||||
@ -210,6 +211,31 @@ impl<F: Field + PrimeField> EvaluateEqGadget<F> for FieldType<F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<F: Field + PrimeField> EvaluateLtGadget<F> for FieldType<F> {
|
||||||
|
fn less_than<CS: ConstraintSystem<F>>(&self, mut cs: CS, other: &Self) -> Result<Boolean, SynthesisError> {
|
||||||
|
match (self, other) {
|
||||||
|
(FieldType::Constant(first), FieldType::Constant(second)) => Ok(Boolean::constant(first.lt(second))),
|
||||||
|
(FieldType::Allocated(allocated), FieldType::Constant(constant))
|
||||||
|
| (FieldType::Constant(constant), FieldType::Allocated(allocated)) => {
|
||||||
|
let bool_option = allocated.value.map(|f| f.lt(constant));
|
||||||
|
|
||||||
|
Boolean::alloc(&mut cs.ns(|| "less than"), || {
|
||||||
|
bool_option.ok_or(SynthesisError::AssignmentMissing)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
(FieldType::Allocated(first), FieldType::Allocated(second)) => {
|
||||||
|
let bool_option = first.value.and_then(|a| second.value.map(|b| a.lt(&b)));
|
||||||
|
|
||||||
|
Boolean::alloc(&mut cs.ns(|| "less than"), || {
|
||||||
|
bool_option.ok_or(SynthesisError::AssignmentMissing)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F: Field + PrimeField> ComparatorGadget<F> for FieldType<F> {}
|
||||||
|
|
||||||
impl<F: Field + PrimeField> EqGadget<F> for FieldType<F> {}
|
impl<F: Field + PrimeField> EqGadget<F> for FieldType<F> {}
|
||||||
|
|
||||||
impl<F: Field + PrimeField> ConditionalEqGadget<F> for FieldType<F> {
|
impl<F: Field + PrimeField> ConditionalEqGadget<F> for FieldType<F> {
|
||||||
|
@ -9,9 +9,10 @@ use crate::{
|
|||||||
use leo_compiler::{
|
use leo_compiler::{
|
||||||
errors::{CompilerError, FunctionError},
|
errors::{CompilerError, FunctionError},
|
||||||
ConstrainedValue,
|
ConstrainedValue,
|
||||||
|
Integer,
|
||||||
};
|
};
|
||||||
use leo_inputs::types::{IntegerType, U32Type};
|
use leo_inputs::types::{IntegerType, U32Type};
|
||||||
use leo_types::{InputValue, Integer};
|
use leo_types::InputValue;
|
||||||
|
|
||||||
use snarkos_models::gadgets::utilities::uint::UInt32;
|
use snarkos_models::gadgets::utilities::uint::UInt32;
|
||||||
|
|
||||||
|
@ -10,8 +10,9 @@ use leo_compiler::{
|
|||||||
errors::{CompilerError, ExpressionError, FunctionError, StatementError},
|
errors::{CompilerError, ExpressionError, FunctionError, StatementError},
|
||||||
ConstrainedCircuitMember,
|
ConstrainedCircuitMember,
|
||||||
ConstrainedValue,
|
ConstrainedValue,
|
||||||
|
Integer,
|
||||||
};
|
};
|
||||||
use leo_types::{Expression, Function, Identifier, Integer, Span, Statement, Type};
|
use leo_types::{Expression, Function, Identifier, Span, Statement, Type};
|
||||||
|
|
||||||
use snarkos_models::gadgets::utilities::uint::UInt32;
|
use snarkos_models::gadgets::utilities::uint::UInt32;
|
||||||
|
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
pub mod macros;
|
pub mod macros;
|
||||||
|
|
||||||
use crate::{get_error, EdwardsTestCompiler};
|
use crate::{get_error, EdwardsTestCompiler};
|
||||||
use leo_compiler::errors::{CompilerError, FunctionError};
|
use leo_compiler::errors::{CompilerError, FunctionError, IntegerError};
|
||||||
use leo_types::IntegerError;
|
|
||||||
|
|
||||||
pub trait IntegerTester {
|
pub trait IntegerTester {
|
||||||
/// Tests use of the integer in a function input
|
/// Tests use of the integer in a function input
|
||||||
|
@ -7,9 +7,9 @@ use crate::{
|
|||||||
EdwardsConstrainedValue,
|
EdwardsConstrainedValue,
|
||||||
EdwardsTestCompiler,
|
EdwardsTestCompiler,
|
||||||
};
|
};
|
||||||
use leo_compiler::ConstrainedValue;
|
use leo_compiler::{ConstrainedValue, Integer};
|
||||||
use leo_inputs::types::{IntegerType, U128Type};
|
use leo_inputs::types::{IntegerType, U128Type};
|
||||||
use leo_types::{InputValue, Integer};
|
use leo_types::InputValue;
|
||||||
|
|
||||||
use snarkos_curves::edwards_bls12::Fq;
|
use snarkos_curves::edwards_bls12::Fq;
|
||||||
use snarkos_models::gadgets::{
|
use snarkos_models::gadgets::{
|
||||||
|
@ -7,9 +7,9 @@ use crate::{
|
|||||||
EdwardsConstrainedValue,
|
EdwardsConstrainedValue,
|
||||||
EdwardsTestCompiler,
|
EdwardsTestCompiler,
|
||||||
};
|
};
|
||||||
use leo_compiler::ConstrainedValue;
|
use leo_compiler::{ConstrainedValue, Integer};
|
||||||
use leo_inputs::types::{IntegerType, U16Type};
|
use leo_inputs::types::{IntegerType, U16Type};
|
||||||
use leo_types::{InputValue, Integer};
|
use leo_types::InputValue;
|
||||||
|
|
||||||
use snarkos_curves::edwards_bls12::Fq;
|
use snarkos_curves::edwards_bls12::Fq;
|
||||||
use snarkos_models::gadgets::{
|
use snarkos_models::gadgets::{
|
||||||
|
@ -7,9 +7,9 @@ use crate::{
|
|||||||
EdwardsConstrainedValue,
|
EdwardsConstrainedValue,
|
||||||
EdwardsTestCompiler,
|
EdwardsTestCompiler,
|
||||||
};
|
};
|
||||||
use leo_compiler::ConstrainedValue;
|
use leo_compiler::{ConstrainedValue, Integer};
|
||||||
use leo_inputs::types::{IntegerType, U32Type};
|
use leo_inputs::types::{IntegerType, U32Type};
|
||||||
use leo_types::{InputValue, Integer};
|
use leo_types::InputValue;
|
||||||
|
|
||||||
use snarkos_curves::edwards_bls12::Fq;
|
use snarkos_curves::edwards_bls12::Fq;
|
||||||
use snarkos_models::gadgets::{
|
use snarkos_models::gadgets::{
|
||||||
|
@ -7,9 +7,9 @@ use crate::{
|
|||||||
EdwardsConstrainedValue,
|
EdwardsConstrainedValue,
|
||||||
EdwardsTestCompiler,
|
EdwardsTestCompiler,
|
||||||
};
|
};
|
||||||
use leo_compiler::ConstrainedValue;
|
use leo_compiler::{ConstrainedValue, Integer};
|
||||||
use leo_inputs::types::{IntegerType, U64Type};
|
use leo_inputs::types::{IntegerType, U64Type};
|
||||||
use leo_types::{InputValue, Integer};
|
use leo_types::InputValue;
|
||||||
|
|
||||||
use snarkos_curves::edwards_bls12::Fq;
|
use snarkos_curves::edwards_bls12::Fq;
|
||||||
use snarkos_models::gadgets::{
|
use snarkos_models::gadgets::{
|
||||||
|
@ -7,9 +7,9 @@ use crate::{
|
|||||||
EdwardsConstrainedValue,
|
EdwardsConstrainedValue,
|
||||||
EdwardsTestCompiler,
|
EdwardsTestCompiler,
|
||||||
};
|
};
|
||||||
use leo_compiler::ConstrainedValue;
|
use leo_compiler::{ConstrainedValue, Integer};
|
||||||
use leo_inputs::types::{IntegerType, U8Type};
|
use leo_inputs::types::{IntegerType, U8Type};
|
||||||
use leo_types::{InputValue, Integer};
|
use leo_types::InputValue;
|
||||||
|
|
||||||
use snarkos_curves::edwards_bls12::Fq;
|
use snarkos_curves::edwards_bls12::Fq;
|
||||||
use snarkos_models::gadgets::{
|
use snarkos_models::gadgets::{
|
||||||
|
@ -2,8 +2,8 @@ use crate::{array::input_value_u32_one, parse_program, EdwardsConstrainedValue,
|
|||||||
use leo_compiler::{
|
use leo_compiler::{
|
||||||
errors::{CompilerError, FunctionError, StatementError},
|
errors::{CompilerError, FunctionError, StatementError},
|
||||||
ConstrainedValue,
|
ConstrainedValue,
|
||||||
|
Integer,
|
||||||
};
|
};
|
||||||
use leo_types::Integer;
|
|
||||||
|
|
||||||
use snarkos_curves::edwards_bls12::Fq;
|
use snarkos_curves::edwards_bls12::Fq;
|
||||||
use snarkos_models::gadgets::{r1cs::TestConstraintSystem, utilities::uint::UInt32};
|
use snarkos_models::gadgets::{r1cs::TestConstraintSystem, utilities::uint::UInt32};
|
||||||
|
@ -13,4 +13,3 @@ snarkos-models = { git = "ssh://git@github.com/AleoHQ/snarkOS.git", rev = "c7a5
|
|||||||
|
|
||||||
pest = { version = "2.0" }
|
pest = { version = "2.0" }
|
||||||
serde = { version = "1.0" }
|
serde = { version = "1.0" }
|
||||||
thiserror = { version = "1.0" }
|
|
||||||
|
@ -1,5 +1,2 @@
|
|||||||
pub mod error;
|
pub mod error;
|
||||||
pub use error::*;
|
pub use error::*;
|
||||||
|
|
||||||
pub mod integer;
|
|
||||||
pub use integer::*;
|
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
#[macro_use]
|
|
||||||
extern crate thiserror;
|
|
||||||
|
|
||||||
pub mod circuits;
|
pub mod circuits;
|
||||||
pub use self::circuits::*;
|
pub use self::circuits::*;
|
||||||
|
|
||||||
@ -22,9 +19,6 @@ pub use self::imports::*;
|
|||||||
pub mod inputs;
|
pub mod inputs;
|
||||||
pub use self::inputs::*;
|
pub use self::inputs::*;
|
||||||
|
|
||||||
pub mod integer;
|
|
||||||
pub use self::integer::*;
|
|
||||||
|
|
||||||
pub mod program;
|
pub mod program;
|
||||||
pub use self::program::*;
|
pub use self::program::*;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user