mirror of
https://github.com/AleoHQ/leo.git
synced 2024-11-29 22:36:05 +03:00
impl group partialeq, eq, enforce_eq, cond_enforce_eq
This commit is contained in:
parent
d1e448d630
commit
d1297fc60c
@ -224,9 +224,9 @@ impl<
|
|||||||
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
|
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
|
||||||
// Self::field_eq(fe_1, fe_2)
|
// Self::field_eq(fe_1, fe_2)
|
||||||
// }
|
// }
|
||||||
// (ConstrainedValue::Group(ge_1), ConstrainedValue::Group(ge_2)) => {
|
(ConstrainedValue::Group(ge_1), ConstrainedValue::Group(ge_2)) => {
|
||||||
// Ok(Self::evaluate_group_eq(ge_1, ge_2))
|
Ok(ConstrainedValue::Boolean(Boolean::Constant(ge_1.eq(&ge_2))))
|
||||||
// }
|
}
|
||||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||||
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
||||||
self.evaluate_eq_expression(val_1, val_2)
|
self.evaluate_eq_expression(val_1, val_2)
|
||||||
|
@ -422,6 +422,9 @@ impl<
|
|||||||
(ConstrainedValue::FieldElement(fe_1), ConstrainedValue::FieldElement(fe_2)) => {
|
(ConstrainedValue::FieldElement(fe_1), ConstrainedValue::FieldElement(fe_2)) => {
|
||||||
self.enforce_field_eq(cs, fe_1, fe_2)
|
self.enforce_field_eq(cs, fe_1, fe_2)
|
||||||
}
|
}
|
||||||
|
(ConstrainedValue::Group(ge_1), ConstrainedValue::Group(ge_2)) => {
|
||||||
|
ge_1.enforce_equal(cs, &ge_2)?
|
||||||
|
}
|
||||||
(ConstrainedValue::Array(arr_1), ConstrainedValue::Array(arr_2)) => {
|
(ConstrainedValue::Array(arr_1), ConstrainedValue::Array(arr_2)) => {
|
||||||
for (left, right) in arr_1.into_iter().zip(arr_2.into_iter()) {
|
for (left, right) in arr_1.into_iter().zip(arr_2.into_iter()) {
|
||||||
self.enforce_assert_eq_statement(cs, left, right)?;
|
self.enforce_assert_eq_statement(cs, left, right)?;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::errors::{BooleanError, ExpressionError, FieldElementError, IntegerError, ValueError};
|
use crate::errors::{BooleanError, ExpressionError, FieldElementError, IntegerError, ValueError};
|
||||||
|
use snarkos_errors::gadgets::SynthesisError;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum StatementError {
|
pub enum StatementError {
|
||||||
@ -62,6 +63,9 @@ pub enum StatementError {
|
|||||||
|
|
||||||
#[error("Expected assignment of return values for expression {}", _0)]
|
#[error("Expected assignment of return values for expression {}", _0)]
|
||||||
Unassigned(String),
|
Unassigned(String),
|
||||||
|
|
||||||
|
#[error("{}", _0)]
|
||||||
|
SynthesisError(#[from] SynthesisError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ExpressionError> for StatementError {
|
impl From<ExpressionError> for StatementError {
|
||||||
|
@ -3,10 +3,13 @@ use crate::GroupType;
|
|||||||
|
|
||||||
use snarkos_curves::edwards_bls12::{EdwardsAffine, EdwardsParameters, Fq};
|
use snarkos_curves::edwards_bls12::{EdwardsAffine, EdwardsParameters, Fq};
|
||||||
use snarkos_curves::templates::twisted_edwards_extended::GroupAffine;
|
use snarkos_curves::templates::twisted_edwards_extended::GroupAffine;
|
||||||
|
use snarkos_errors::gadgets::SynthesisError;
|
||||||
use snarkos_gadgets::curves::edwards_bls12::EdwardsBlsGadget;
|
use snarkos_gadgets::curves::edwards_bls12::EdwardsBlsGadget;
|
||||||
use snarkos_models::curves::{AffineCurve, ModelParameters};
|
use snarkos_models::curves::{AffineCurve, ModelParameters};
|
||||||
use snarkos_models::gadgets::curves::GroupGadget;
|
use snarkos_models::gadgets::curves::{FpGadget, GroupGadget};
|
||||||
use snarkos_models::gadgets::r1cs::ConstraintSystem;
|
use snarkos_models::gadgets::r1cs::ConstraintSystem;
|
||||||
|
use snarkos_models::gadgets::utilities::boolean::Boolean;
|
||||||
|
use snarkos_models::gadgets::utilities::eq::{ConditionalEqGadget, EqGadget};
|
||||||
use std::ops::Sub;
|
use std::ops::Sub;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
@ -84,3 +87,82 @@ impl GroupType<<EdwardsParameters as ModelParameters>::BaseField, Fq> for Edward
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq for EdwardsGroupType {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
match (self, other) {
|
||||||
|
(EdwardsGroupType::Constant(self_value), EdwardsGroupType::Constant(other_value)) => {
|
||||||
|
self_value == other_value
|
||||||
|
}
|
||||||
|
|
||||||
|
(EdwardsGroupType::Allocated(self_value), EdwardsGroupType::Allocated(other_value)) => {
|
||||||
|
self_value.eq(other_value)
|
||||||
|
}
|
||||||
|
|
||||||
|
(
|
||||||
|
EdwardsGroupType::Constant(constant_value),
|
||||||
|
EdwardsGroupType::Allocated(allocated_value),
|
||||||
|
)
|
||||||
|
| (
|
||||||
|
EdwardsGroupType::Allocated(allocated_value),
|
||||||
|
EdwardsGroupType::Constant(constant_value),
|
||||||
|
) => <EdwardsBlsGadget as GroupGadget<GroupAffine<EdwardsParameters>, Fq>>::get_value(
|
||||||
|
allocated_value,
|
||||||
|
)
|
||||||
|
.map(|allocated_value| allocated_value == *constant_value)
|
||||||
|
.unwrap_or(false),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for EdwardsGroupType {}
|
||||||
|
|
||||||
|
impl EqGadget<Fq> for EdwardsGroupType {}
|
||||||
|
|
||||||
|
impl ConditionalEqGadget<Fq> for EdwardsGroupType {
|
||||||
|
#[inline]
|
||||||
|
fn conditional_enforce_equal<CS: ConstraintSystem<Fq>>(
|
||||||
|
&self,
|
||||||
|
mut cs: CS,
|
||||||
|
other: &Self,
|
||||||
|
condition: &Boolean,
|
||||||
|
) -> Result<(), SynthesisError> {
|
||||||
|
match (self, other) {
|
||||||
|
// c - c
|
||||||
|
(EdwardsGroupType::Constant(self_value), EdwardsGroupType::Constant(other_value)) => {
|
||||||
|
if self_value == other_value {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
Err(SynthesisError::AssignmentMissing)
|
||||||
|
}
|
||||||
|
// a - a
|
||||||
|
(EdwardsGroupType::Allocated(self_value), EdwardsGroupType::Allocated(other_value)) => {
|
||||||
|
return <EdwardsBlsGadget>::conditional_enforce_equal(
|
||||||
|
self_value,
|
||||||
|
cs,
|
||||||
|
other_value,
|
||||||
|
condition,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// c - a = a - c
|
||||||
|
(
|
||||||
|
EdwardsGroupType::Constant(constant_value),
|
||||||
|
EdwardsGroupType::Allocated(allocated_value),
|
||||||
|
)
|
||||||
|
| (
|
||||||
|
EdwardsGroupType::Allocated(allocated_value),
|
||||||
|
EdwardsGroupType::Constant(constant_value),
|
||||||
|
) => {
|
||||||
|
let x = FpGadget::from(&mut cs, &constant_value.x);
|
||||||
|
let y = FpGadget::from(&mut cs, &constant_value.y);
|
||||||
|
let constant_gadget = EdwardsBlsGadget::new(x, y);
|
||||||
|
|
||||||
|
constant_gadget.conditional_enforce_equal(cs, allocated_value, condition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cost() -> usize {
|
||||||
|
2 * <EdwardsBlsGadget as ConditionalEqGadget<Fq>>::cost() //upper bound
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
use crate::errors::GroupError;
|
use crate::errors::GroupError;
|
||||||
use snarkos_models::curves::Field;
|
use snarkos_models::curves::Field;
|
||||||
use snarkos_models::gadgets::r1cs::ConstraintSystem;
|
use snarkos_models::gadgets::r1cs::ConstraintSystem;
|
||||||
|
use snarkos_models::gadgets::utilities::eq::{ConditionalEqGadget, EqGadget};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
pub mod edwards_bls12;
|
pub mod edwards_bls12;
|
||||||
|
|
||||||
pub trait GroupType<NativeF: Field, F: Field>: Sized + Clone + Debug {
|
pub trait GroupType<NativeF: Field, F: Field>:
|
||||||
|
Sized + Clone + Debug + EqGadget<F> + ConditionalEqGadget<F>
|
||||||
|
{
|
||||||
fn constant(string: String) -> Result<Self, GroupError>;
|
fn constant(string: String) -> Result<Self, GroupError>;
|
||||||
|
|
||||||
fn add<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, GroupError>;
|
fn add<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, GroupError>;
|
||||||
|
@ -9,7 +9,7 @@ use snarkos_models::gadgets::utilities::boolean::Boolean;
|
|||||||
|
|
||||||
const DIRECTORY_NAME: &str = "tests/boolean/";
|
const DIRECTORY_NAME: &str = "tests/boolean/";
|
||||||
|
|
||||||
fn output_true(program: EdwardsTestCompiler) {
|
pub fn output_true(program: EdwardsTestCompiler) {
|
||||||
let output = get_output(program);
|
let output = get_output(program);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Boolean(Boolean::Constant(true))])
|
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Boolean(Boolean::Constant(true))])
|
||||||
@ -18,7 +18,7 @@ fn output_true(program: EdwardsTestCompiler) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn output_false(program: EdwardsTestCompiler) {
|
pub fn output_false(program: EdwardsTestCompiler) {
|
||||||
let output = get_output(program);
|
let output = get_output(program);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Boolean(Boolean::Constant(false))])
|
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Boolean(Boolean::Constant(false))])
|
||||||
|
6
compiler/tests/group/assert_eq_false.leo
Normal file
6
compiler/tests/group/assert_eq_false.leo
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
function main() {
|
||||||
|
let point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||||
|
let point_2 = (1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)group;
|
||||||
|
|
||||||
|
assert_eq!(point_1, point_2);
|
||||||
|
}
|
6
compiler/tests/group/assert_eq_true.leo
Normal file
6
compiler/tests/group/assert_eq_true.leo
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
function main() {
|
||||||
|
let point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||||
|
let point_2 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||||
|
|
||||||
|
assert_eq!(point_1, point_2);
|
||||||
|
}
|
6
compiler/tests/group/eq_false.leo
Normal file
6
compiler/tests/group/eq_false.leo
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
function main() -> bool {
|
||||||
|
let point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||||
|
let point_2 = (1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)group;
|
||||||
|
|
||||||
|
return point_1 == point_2
|
||||||
|
}
|
6
compiler/tests/group/eq_true.leo
Normal file
6
compiler/tests/group/eq_true.leo
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
function main() -> bool {
|
||||||
|
let point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||||
|
let point_2 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||||
|
|
||||||
|
return point_1 == point_2
|
||||||
|
}
|
@ -1,10 +1,12 @@
|
|||||||
use crate::{compile_program, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
|
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
|
||||||
use leo_compiler::group::edwards_bls12::EdwardsGroupType;
|
use leo_compiler::group::edwards_bls12::EdwardsGroupType;
|
||||||
use leo_compiler::ConstrainedValue;
|
use leo_compiler::ConstrainedValue;
|
||||||
|
|
||||||
use snarkos_curves::edwards_bls12::EdwardsAffine;
|
use snarkos_curves::edwards_bls12::EdwardsAffine;
|
||||||
use snarkos_models::curves::Group;
|
use snarkos_models::curves::Group;
|
||||||
|
|
||||||
|
use crate::boolean::{output_false, output_true};
|
||||||
|
use leo_compiler::errors::{CompilerError, FunctionError, StatementError};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
const DIRECTORY_NAME: &str = "tests/group/";
|
const DIRECTORY_NAME: &str = "tests/group/";
|
||||||
@ -27,6 +29,15 @@ fn output_zero(program: EdwardsTestCompiler) {
|
|||||||
output_expected(program, EdwardsAffine::zero())
|
output_expected(program, EdwardsAffine::zero())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fail_enforce(program: EdwardsTestCompiler) {
|
||||||
|
match get_error(program) {
|
||||||
|
CompilerError::FunctionError(FunctionError::StatementError(
|
||||||
|
StatementError::SynthesisError(_),
|
||||||
|
)) => {}
|
||||||
|
error => panic!("Expected evaluate error, got {}", error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_zero() {
|
fn test_zero() {
|
||||||
let program = compile_program(DIRECTORY_NAME, "zero.leo").unwrap();
|
let program = compile_program(DIRECTORY_NAME, "zero.leo").unwrap();
|
||||||
@ -65,3 +76,27 @@ fn test_sub() {
|
|||||||
let program = compile_program(DIRECTORY_NAME, "sub.leo").unwrap();
|
let program = compile_program(DIRECTORY_NAME, "sub.leo").unwrap();
|
||||||
output_expected(program, sum);
|
output_expected(program, sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_eq_true() {
|
||||||
|
let program = compile_program(DIRECTORY_NAME, "eq_true.leo").unwrap();
|
||||||
|
output_true(program)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_eq_false() {
|
||||||
|
let program = compile_program(DIRECTORY_NAME, "eq_false.leo").unwrap();
|
||||||
|
output_false(program)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_assert_eq_true() {
|
||||||
|
let program = compile_program(DIRECTORY_NAME, "assert_eq_true.leo").unwrap();
|
||||||
|
let _res = get_output(program);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_assert_eq_false() {
|
||||||
|
let program = compile_program(DIRECTORY_NAME, "assert_eq_false.leo").unwrap();
|
||||||
|
fail_enforce(program);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user