mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-09-11 05:45:30 +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)) => {
|
||||
// Self::field_eq(fe_1, fe_2)
|
||||
// }
|
||||
// (ConstrainedValue::Group(ge_1), ConstrainedValue::Group(ge_2)) => {
|
||||
// Ok(Self::evaluate_group_eq(ge_1, ge_2))
|
||||
// }
|
||||
(ConstrainedValue::Group(ge_1), ConstrainedValue::Group(ge_2)) => {
|
||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(ge_1.eq(&ge_2))))
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
||||
self.evaluate_eq_expression(val_1, val_2)
|
||||
|
@ -422,6 +422,9 @@ impl<
|
||||
(ConstrainedValue::FieldElement(fe_1), ConstrainedValue::FieldElement(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)) => {
|
||||
for (left, right) in arr_1.into_iter().zip(arr_2.into_iter()) {
|
||||
self.enforce_assert_eq_statement(cs, left, right)?;
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::errors::{BooleanError, ExpressionError, FieldElementError, IntegerError, ValueError};
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum StatementError {
|
||||
@ -62,6 +63,9 @@ pub enum StatementError {
|
||||
|
||||
#[error("Expected assignment of return values for expression {}", _0)]
|
||||
Unassigned(String),
|
||||
|
||||
#[error("{}", _0)]
|
||||
SynthesisError(#[from] SynthesisError),
|
||||
}
|
||||
|
||||
impl From<ExpressionError> for StatementError {
|
||||
|
@ -3,10 +3,13 @@ use crate::GroupType;
|
||||
|
||||
use snarkos_curves::edwards_bls12::{EdwardsAffine, EdwardsParameters, Fq};
|
||||
use snarkos_curves::templates::twisted_edwards_extended::GroupAffine;
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_gadgets::curves::edwards_bls12::EdwardsBlsGadget;
|
||||
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::utilities::boolean::Boolean;
|
||||
use snarkos_models::gadgets::utilities::eq::{ConditionalEqGadget, EqGadget};
|
||||
use std::ops::Sub;
|
||||
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 snarkos_models::curves::Field;
|
||||
use snarkos_models::gadgets::r1cs::ConstraintSystem;
|
||||
use snarkos_models::gadgets::utilities::eq::{ConditionalEqGadget, EqGadget};
|
||||
use std::fmt::Debug;
|
||||
|
||||
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 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/";
|
||||
|
||||
fn output_true(program: EdwardsTestCompiler) {
|
||||
pub fn output_true(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
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);
|
||||
assert_eq!(
|
||||
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::ConstrainedValue;
|
||||
|
||||
use snarkos_curves::edwards_bls12::EdwardsAffine;
|
||||
use snarkos_models::curves::Group;
|
||||
|
||||
use crate::boolean::{output_false, output_true};
|
||||
use leo_compiler::errors::{CompilerError, FunctionError, StatementError};
|
||||
use std::str::FromStr;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/group/";
|
||||
@ -27,6 +29,15 @@ fn output_zero(program: EdwardsTestCompiler) {
|
||||
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]
|
||||
fn test_zero() {
|
||||
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();
|
||||
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