From a4b29d26519fb3b6d38e57405f351d6f88449353 Mon Sep 17 00:00:00 2001 From: collin Date: Sat, 15 Aug 2020 17:21:18 -0700 Subject: [PATCH] impl new group notation for inputs compiler --- compiler/src/value/group/group_type.rs | 2 +- compiler/src/value/group/input.rs | 4 +- .../src/value/group/targets/edwards_bls12.rs | 122 +++++++----------- compiler/tests/group/input/invalid.in | 3 + compiler/tests/group/input/one_one.in | 3 - compiler/tests/group/input/one_zero.in | 3 - compiler/tests/group/input/valid.in | 3 + compiler/tests/group/mod.rs | 99 ++++++++------ compiler/tests/group/x_and_y.leo | 3 + 9 files changed, 118 insertions(+), 124 deletions(-) create mode 100644 compiler/tests/group/input/invalid.in delete mode 100644 compiler/tests/group/input/one_one.in delete mode 100644 compiler/tests/group/input/one_zero.in create mode 100644 compiler/tests/group/input/valid.in create mode 100644 compiler/tests/group/x_and_y.leo diff --git a/compiler/src/value/group/group_type.rs b/compiler/src/value/group/group_type.rs index ed863625c7..fc7534e2ed 100644 --- a/compiler/src/value/group/group_type.rs +++ b/compiler/src/value/group/group_type.rs @@ -27,7 +27,7 @@ pub trait GroupType: + EvaluateEqGadget + EqGadget + ConditionalEqGadget - + AllocGadget + + AllocGadget + CondSelectGadget + ToBitsGadget + ToBytesGadget diff --git a/compiler/src/value/group/input.rs b/compiler/src/value/group/input.rs index 4f0e44017f..a5df8f4112 100644 --- a/compiler/src/value/group/input.rs +++ b/compiler/src/value/group/input.rs @@ -1,7 +1,7 @@ //! Methods to enforce constraints on input group values in a Leo program. use crate::{errors::GroupError, ConstrainedValue, GroupType}; -use leo_typed::{InputValue, Span}; +use leo_typed::{GroupValue, InputValue, Span}; use snarkos_errors::gadgets::SynthesisError; use snarkos_models::{ @@ -12,7 +12,7 @@ use snarkos_models::{ pub(crate) fn allocate_group, CS: ConstraintSystem>( cs: &mut CS, name: String, - option: Option, + option: Option, span: Span, ) -> Result { let group_name = format!("{}: group", name); diff --git a/compiler/src/value/group/targets/edwards_bls12.rs b/compiler/src/value/group/targets/edwards_bls12.rs index 308d56d276..a53be4e1f7 100644 --- a/compiler/src/value/group/targets/edwards_bls12.rs +++ b/compiler/src/value/group/targets/edwards_bls12.rs @@ -37,42 +37,7 @@ pub enum EdwardsGroupType { impl GroupType for EdwardsGroupType { fn constant(group: GroupValue) -> Result { - let span = group.span; - let x = group.x; - let y = group.y; - - let value = match (x, y) { - // (x, y) - (GroupCoordinate::Number(x_string, x_span), GroupCoordinate::Number(y_string, y_span)) => { - Self::edwards_affine_from_pair(x_string, y_string, x_span, y_span, span)? - } - // (x, +) - (GroupCoordinate::Number(x_string, x_span), GroupCoordinate::SignHigh) => { - Self::edwards_affine_from_x_str(x_string, x_span, Some(true), span)? - } - // (x, -) - (GroupCoordinate::Number(x_string, x_span), GroupCoordinate::SignLow) => { - Self::edwards_affine_from_x_str(x_string, x_span, Some(false), span)? - } - // (x, _) - (GroupCoordinate::Number(x_string, x_span), GroupCoordinate::Inferred) => { - Self::edwards_affine_from_x_str(x_string, x_span, None, span)? - } - // (+, y) - (GroupCoordinate::SignHigh, GroupCoordinate::Number(y_string, y_span)) => { - Self::edwards_affine_from_y_str(y_string, y_span, Some(true), span)? - } - // (-, y) - (GroupCoordinate::SignLow, GroupCoordinate::Number(y_string, y_span)) => { - Self::edwards_affine_from_y_str(y_string, y_span, Some(false), span)? - } - // (_, y) - (GroupCoordinate::Inferred, GroupCoordinate::Number(y_string, y_span)) => { - Self::edwards_affine_from_y_str(y_string, y_span, None, span)? - } - // Invalid - (x, y) => return Err(GroupError::invalid_group(format!("({}, {})", x, y), span)), - }; + let value = Self::edwards_affine_from_value(group)?; Ok(EdwardsGroupType::Constant(value)) } @@ -153,6 +118,45 @@ impl GroupType for EdwardsGroupType { } impl EdwardsGroupType { + pub fn edwards_affine_from_value(group: GroupValue) -> Result { + let span = group.span; + let x = group.x; + let y = group.y; + + match (x, y) { + // (x, y) + (GroupCoordinate::Number(x_string, x_span), GroupCoordinate::Number(y_string, y_span)) => { + Self::edwards_affine_from_pair(x_string, y_string, x_span, y_span, span) + } + // (x, +) + (GroupCoordinate::Number(x_string, x_span), GroupCoordinate::SignHigh) => { + Self::edwards_affine_from_x_str(x_string, x_span, Some(true), span) + } + // (x, -) + (GroupCoordinate::Number(x_string, x_span), GroupCoordinate::SignLow) => { + Self::edwards_affine_from_x_str(x_string, x_span, Some(false), span) + } + // (x, _) + (GroupCoordinate::Number(x_string, x_span), GroupCoordinate::Inferred) => { + Self::edwards_affine_from_x_str(x_string, x_span, None, span) + } + // (+, y) + (GroupCoordinate::SignHigh, GroupCoordinate::Number(y_string, y_span)) => { + Self::edwards_affine_from_y_str(y_string, y_span, Some(true), span) + } + // (-, y) + (GroupCoordinate::SignLow, GroupCoordinate::Number(y_string, y_span)) => { + Self::edwards_affine_from_y_str(y_string, y_span, Some(false), span) + } + // (_, y) + (GroupCoordinate::Inferred, GroupCoordinate::Number(y_string, y_span)) => { + Self::edwards_affine_from_y_str(y_string, y_span, None, span) + } + // Invalid + (x, y) => Err(GroupError::invalid_group(format!("({}, {})", x, y), span)), + } + } + pub fn edwards_affine_from_x_str( x_string: String, x_span: Span, @@ -230,44 +234,18 @@ impl EdwardsGroupType { } } - pub fn edwards_affine_from_str(string: String) -> Result { - // (x, y) - match Fq::from_str(&string).ok() { - Some(x) => { - // Attempt to recover with a sign_low bit. - if let Some(element) = EdwardsAffine::from_x_coordinate(x.clone(), false) { - return Ok(element); - } - - // Attempt to recover with a sign_high bit. - if let Some(element) = EdwardsAffine::from_x_coordinate(x, true) { - return Ok(element); - } - - // Otherwise return error. - Err(SynthesisError::AssignmentMissing) - } - None => EdwardsAffine::from_str(&string).map_err(|_| SynthesisError::AssignmentMissing), - } - } - - pub fn alloc_x_helper Result, T: Borrow>( + pub fn alloc_helper Result, T: Borrow>( value_gen: Fn, ) -> Result { - let affine_string = match value_gen() { + let group_value = match value_gen() { Ok(value) => { - let string_value = value.borrow().clone(); - Ok(string_value) + let group_value = value.borrow().clone(); + Ok(group_value) } _ => Err(SynthesisError::AssignmentMissing), }?; - // 1group = generator - if affine_string.eq("1") { - Ok(edwards_affine_one()) - } else { - Self::edwards_affine_from_str(affine_string) - } + Self::edwards_affine_from_value(group_value).map_err(|_| SynthesisError::AssignmentMissing) } pub fn allocated>(&self, mut cs: CS) -> Result { @@ -295,24 +273,24 @@ impl EdwardsGroupType { } } -impl AllocGadget for EdwardsGroupType { - fn alloc Result, T: Borrow, CS: ConstraintSystem>( +impl AllocGadget for EdwardsGroupType { + fn alloc Result, T: Borrow, CS: ConstraintSystem>( cs: CS, value_gen: Fn, ) -> Result { let value = , Fq>>::alloc(cs, || { - Self::alloc_x_helper(value_gen) + Self::alloc_helper(value_gen) })?; Ok(EdwardsGroupType::Allocated(value)) } - fn alloc_input Result, T: Borrow, CS: ConstraintSystem>( + fn alloc_input Result, T: Borrow, CS: ConstraintSystem>( cs: CS, value_gen: Fn, ) -> Result { let value = , Fq>>::alloc_input(cs, || { - Self::alloc_x_helper(value_gen) + Self::alloc_helper(value_gen) })?; Ok(EdwardsGroupType::Allocated(value)) diff --git a/compiler/tests/group/input/invalid.in b/compiler/tests/group/input/invalid.in new file mode 100644 index 0000000000..d55c096738 --- /dev/null +++ b/compiler/tests/group/input/invalid.in @@ -0,0 +1,3 @@ +[main] +a: group = (1, 0)group; +b: group = (+, +)group; diff --git a/compiler/tests/group/input/one_one.in b/compiler/tests/group/input/one_one.in deleted file mode 100644 index 27d529509f..0000000000 --- a/compiler/tests/group/input/one_one.in +++ /dev/null @@ -1,3 +0,0 @@ -[main] -a: group = 1; -b: group = 1; diff --git a/compiler/tests/group/input/one_zero.in b/compiler/tests/group/input/one_zero.in deleted file mode 100644 index 98bcfb999d..0000000000 --- a/compiler/tests/group/input/one_zero.in +++ /dev/null @@ -1,3 +0,0 @@ -[main] -a: group = 1; -b: group = 0; diff --git a/compiler/tests/group/input/valid.in b/compiler/tests/group/input/valid.in new file mode 100644 index 0000000000..651a28bea6 --- /dev/null +++ b/compiler/tests/group/input/valid.in @@ -0,0 +1,3 @@ +[main] +a: group = (0, -)group; +b: group = (0, _)group; diff --git a/compiler/tests/group/mod.rs b/compiler/tests/group/mod.rs index 70b986c701..eebdd96bb2 100644 --- a/compiler/tests/group/mod.rs +++ b/compiler/tests/group/mod.rs @@ -7,18 +7,31 @@ use crate::{ parse_program, parse_program_with_input, }; -use leo_typed::InputValue; +use leo_typed::{GroupCoordinate, GroupValue, InputValue, Span}; use snarkos_curves::edwards_bls12::EdwardsAffine; use rand::{Rng, SeedableRng}; use rand_xorshift::XorShiftRng; -pub fn group_to_decimal_string(g: EdwardsAffine) -> String { +pub fn group_element_to_input_value(g: EdwardsAffine) -> GroupValue { let x = field_to_decimal_string(g.x); let y = field_to_decimal_string(g.y); - format!("({}, {})", x, y) + format!("({}, {})", x, y); + + let fake_span = Span { + text: "".to_string(), + line: 0, + start: 0, + end: 0, + }; + + GroupValue { + x: GroupCoordinate::Number(x, fake_span.clone()), + y: GroupCoordinate::Number(y, fake_span.clone()), + span: fake_span, + } } #[test] @@ -117,8 +130,8 @@ fn test_point_input() { #[test] fn test_input() { let program_bytes = include_bytes!("input.leo"); - let input_bytes_pass = include_bytes!("input/one_one.in"); - let input_bytes_fail = include_bytes!("input/one_zero.in"); + let input_bytes_pass = include_bytes!("input/valid.in"); + let input_bytes_fail = include_bytes!("input/invalid.in"); let program = parse_program_with_input(program_bytes, input_bytes_pass).unwrap(); @@ -126,7 +139,7 @@ fn test_input() { let program = parse_program_with_input(program_bytes, input_bytes_fail).unwrap(); - expect_synthesis_error(program); + expect_compiler_error(program); } #[test] @@ -139,15 +152,15 @@ fn test_negate() { let a: EdwardsAffine = rng.gen(); let b = a.neg(); - let a_string = group_to_decimal_string(a); - let b_string = group_to_decimal_string(b); + let a_element = group_element_to_input_value(a); + let b_element = group_element_to_input_value(b); let bytes = include_bytes!("negate.leo"); let mut program = parse_program(bytes).unwrap(); let main_input = generate_main_input(vec![ - ("a", Some(InputValue::Group(a_string))), - ("b", Some(InputValue::Group(b_string))), + ("a", Some(InputValue::Group(a_element))), + ("b", Some(InputValue::Group(b_element))), ]); program.set_main_input(main_input); @@ -166,17 +179,17 @@ fn test_add() { let b: EdwardsAffine = rng.gen(); let c = a.add(&b); - let a_string = group_to_decimal_string(a); - let b_string = group_to_decimal_string(b); - let c_string = group_to_decimal_string(c); + let a_element = group_element_to_input_value(a); + let b_element = group_element_to_input_value(b); + let c_element = group_element_to_input_value(c); let bytes = include_bytes!("add.leo"); let mut program = parse_program(bytes).unwrap(); let main_input = generate_main_input(vec![ - ("a", Some(InputValue::Group(a_string))), - ("b", Some(InputValue::Group(b_string))), - ("c", Some(InputValue::Group(c_string))), + ("a", Some(InputValue::Group(a_element))), + ("b", Some(InputValue::Group(b_element))), + ("c", Some(InputValue::Group(c_element))), ]); program.set_main_input(main_input); @@ -195,17 +208,17 @@ fn test_sub() { let b: EdwardsAffine = rng.gen(); let c = a.sub(&b); - let a_string = group_to_decimal_string(a); - let b_string = group_to_decimal_string(b); - let c_string = group_to_decimal_string(c); + let a_element = group_element_to_input_value(a); + let b_element = group_element_to_input_value(b); + let c_element = group_element_to_input_value(c); let bytes = include_bytes!("sub.leo"); let mut program = parse_program(bytes).unwrap(); let main_input = generate_main_input(vec![ - ("a", Some(InputValue::Group(a_string))), - ("b", Some(InputValue::Group(b_string))), - ("c", Some(InputValue::Group(c_string))), + ("a", Some(InputValue::Group(a_element))), + ("b", Some(InputValue::Group(b_element))), + ("c", Some(InputValue::Group(c_element))), ]); program.set_main_input(main_input); @@ -220,14 +233,14 @@ fn test_assert_eq_pass() { for _ in 0..10 { let a: EdwardsAffine = rng.gen(); - let a_string = group_to_decimal_string(a); + let a_element = group_element_to_input_value(a); let bytes = include_bytes!("assert_eq.leo"); let mut program = parse_program(bytes).unwrap(); let main_input = generate_main_input(vec![ - ("a", Some(InputValue::Group(a_string.clone()))), - ("b", Some(InputValue::Group(a_string))), + ("a", Some(InputValue::Group(a_element.clone()))), + ("b", Some(InputValue::Group(a_element))), ]); program.set_main_input(main_input); @@ -248,15 +261,15 @@ fn test_assert_eq_fail() { continue; } - let a_string = group_to_decimal_string(a); - let b_string = group_to_decimal_string(b); + let a_element = group_element_to_input_value(a); + let b_element = group_element_to_input_value(b); let bytes = include_bytes!("assert_eq.leo"); let mut program = parse_program(bytes).unwrap(); let main_input = generate_main_input(vec![ - ("a", Some(InputValue::Group(a_string))), - ("b", Some(InputValue::Group(b_string))), + ("a", Some(InputValue::Group(a_element))), + ("b", Some(InputValue::Group(b_element))), ]); program.set_main_input(main_input); @@ -274,8 +287,8 @@ fn test_eq() { let a: EdwardsAffine = rng.gen(); let b: EdwardsAffine = rng.gen(); - let a_string = group_to_decimal_string(a); - let b_string = group_to_decimal_string(b); + let a_element = group_element_to_input_value(a); + let b_element = group_element_to_input_value(b); // test equal @@ -283,8 +296,8 @@ fn test_eq() { let mut program = parse_program(bytes).unwrap(); let main_input = generate_main_input(vec![ - ("a", Some(InputValue::Group(a_string.clone()))), - ("b", Some(InputValue::Group(a_string.clone()))), + ("a", Some(InputValue::Group(a_element.clone()))), + ("b", Some(InputValue::Group(a_element.clone()))), ("c", Some(InputValue::Boolean(true))), ]); @@ -299,8 +312,8 @@ fn test_eq() { let mut program = parse_program(bytes).unwrap(); let main_input = generate_main_input(vec![ - ("a", Some(InputValue::Group(a_string))), - ("b", Some(InputValue::Group(b_string))), + ("a", Some(InputValue::Group(a_element))), + ("b", Some(InputValue::Group(b_element))), ("c", Some(InputValue::Boolean(c))), ]); @@ -317,8 +330,8 @@ fn test_ternary() { let a: EdwardsAffine = rng.gen(); let b: EdwardsAffine = rng.gen(); - let a_string = group_to_decimal_string(a); - let b_string = group_to_decimal_string(b); + let a_element = group_element_to_input_value(a); + let b_element = group_element_to_input_value(b); let bytes = include_bytes!("ternary.leo"); let mut program = parse_program(bytes).unwrap(); @@ -326,9 +339,9 @@ fn test_ternary() { // true -> field a let main_input = generate_main_input(vec![ ("s", Some(InputValue::Boolean(true))), - ("a", Some(InputValue::Group(a_string.clone()))), - ("b", Some(InputValue::Group(b_string.clone()))), - ("c", Some(InputValue::Group(a_string.clone()))), + ("a", Some(InputValue::Group(a_element.clone()))), + ("b", Some(InputValue::Group(b_element.clone()))), + ("c", Some(InputValue::Group(a_element.clone()))), ]); program.set_main_input(main_input); @@ -340,9 +353,9 @@ fn test_ternary() { // false -> field b let main_input = generate_main_input(vec![ ("s", Some(InputValue::Boolean(false))), - ("a", Some(InputValue::Group(a_string))), - ("b", Some(InputValue::Group(b_string.clone()))), - ("c", Some(InputValue::Group(b_string))), + ("a", Some(InputValue::Group(a_element))), + ("b", Some(InputValue::Group(b_element.clone()))), + ("c", Some(InputValue::Group(b_element))), ]); program.set_main_input(main_input); diff --git a/compiler/tests/group/x_and_y.leo b/compiler/tests/group/x_and_y.leo new file mode 100644 index 0000000000..1b64702db1 --- /dev/null +++ b/compiler/tests/group/x_and_y.leo @@ -0,0 +1,3 @@ +function main(element: group) { + let b = element; +} \ No newline at end of file