impl group partialeq, eq, enforce_eq, cond_enforce_eq

This commit is contained in:
collin 2020-06-01 12:15:49 -07:00
parent d1e448d630
commit d1297fc60c
11 changed files with 159 additions and 8 deletions

View File

@ -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)

View File

@ -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)?;

View File

@ -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 {

View File

@ -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
}
}

View File

@ -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>;

View File

@ -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))])

View 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);
}

View 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);
}

View 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
}

View 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
}

View File

@ -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);
}