mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-18 07:11:53 +03:00
Merge #670
670: feature_626/negative-group-contstraints r=collinc97 a=gluax Resolves #626. Allows a negative group outside of a pair as well as negative numbers inside a pair group. Waiting to see if the later was necessary in the feature discussion, but I assume it would be. Co-authored-by: gluax <jonathan.t.pavlik@gmail.com>
This commit is contained in:
commit
6715f91690
@ -133,6 +133,23 @@ impl GroupType<Fq> for EdwardsGroupType {
|
||||
}
|
||||
}
|
||||
|
||||
fn number_string_typing(number: &str, span: &Span) -> Result<(String, bool), GroupError> {
|
||||
let first_char = number.chars().next().unwrap();
|
||||
|
||||
// Check if first symbol is a negative.
|
||||
// If so strip it, parse rest of string and then negate it.
|
||||
if first_char == '-' {
|
||||
let uint = number
|
||||
.chars()
|
||||
.next()
|
||||
.map(|c| &number[c.len_utf8()..])
|
||||
.ok_or_else(|| GroupError::invalid_group(number.to_string(), span.to_owned()))?;
|
||||
Ok((uint.to_string(), true))
|
||||
} else {
|
||||
Ok((number.to_string(), false))
|
||||
}
|
||||
}
|
||||
|
||||
impl EdwardsGroupType {
|
||||
pub fn edwards_affine_from_value(value: &GroupValue, span: &Span) -> Result<EdwardsAffine, GroupError> {
|
||||
match value {
|
||||
@ -142,12 +159,19 @@ impl EdwardsGroupType {
|
||||
}
|
||||
|
||||
pub fn edwards_affine_from_single(number: &str, span: &Span) -> Result<EdwardsAffine, GroupError> {
|
||||
if number.eq("0") {
|
||||
let number_info = number_string_typing(number, &span.clone())?;
|
||||
|
||||
if number_info.0.eq("0") {
|
||||
Ok(EdwardsAffine::zero())
|
||||
} else {
|
||||
let one = edwards_affine_one();
|
||||
let number_value =
|
||||
Fp256::from_str(&number).map_err(|_| GroupError::n_group(number.to_string(), span.clone()))?;
|
||||
let number_value = match number_info {
|
||||
(number, neg) if neg => {
|
||||
-Fp256::from_str(&number).map_err(|_| GroupError::n_group(number, span.clone()))?
|
||||
}
|
||||
(number, _) => Fp256::from_str(&number).map_err(|_| GroupError::n_group(number, span.clone()))?,
|
||||
};
|
||||
|
||||
let result: EdwardsAffine = one.mul(&number_value);
|
||||
|
||||
Ok(result)
|
||||
@ -164,32 +188,42 @@ impl EdwardsGroupType {
|
||||
|
||||
match (x, y) {
|
||||
// (x, y)
|
||||
(GroupCoordinate::Number(x_string), GroupCoordinate::Number(y_string)) => {
|
||||
Self::edwards_affine_from_pair(x_string, y_string, span, span, span)
|
||||
}
|
||||
(GroupCoordinate::Number(x_string), GroupCoordinate::Number(y_string)) => Self::edwards_affine_from_pair(
|
||||
number_string_typing(&x_string, &span.clone())?,
|
||||
number_string_typing(&y_string, &span.clone())?,
|
||||
span,
|
||||
span,
|
||||
span,
|
||||
),
|
||||
// (x, +)
|
||||
(GroupCoordinate::Number(x_string), GroupCoordinate::SignHigh) => {
|
||||
Self::edwards_affine_from_x_str(x_string, span, Some(true), span)
|
||||
Self::edwards_affine_from_x_str(number_string_typing(&x_string, &span.clone())?, span, Some(true), span)
|
||||
}
|
||||
// (x, -)
|
||||
(GroupCoordinate::Number(x_string), GroupCoordinate::SignLow) => {
|
||||
Self::edwards_affine_from_x_str(x_string, span, Some(false), span)
|
||||
}
|
||||
(GroupCoordinate::Number(x_string), GroupCoordinate::SignLow) => Self::edwards_affine_from_x_str(
|
||||
number_string_typing(&x_string, &span.clone())?,
|
||||
span,
|
||||
Some(false),
|
||||
span,
|
||||
),
|
||||
// (x, _)
|
||||
(GroupCoordinate::Number(x_string), GroupCoordinate::Inferred) => {
|
||||
Self::edwards_affine_from_x_str(x_string, span, None, span)
|
||||
Self::edwards_affine_from_x_str(number_string_typing(&x_string, &span.clone())?, span, None, span)
|
||||
}
|
||||
// (+, y)
|
||||
(GroupCoordinate::SignHigh, GroupCoordinate::Number(y_string)) => {
|
||||
Self::edwards_affine_from_y_str(y_string, span, Some(true), span)
|
||||
Self::edwards_affine_from_y_str(number_string_typing(&y_string, &span.clone())?, span, Some(true), span)
|
||||
}
|
||||
// (-, y)
|
||||
(GroupCoordinate::SignLow, GroupCoordinate::Number(y_string)) => {
|
||||
Self::edwards_affine_from_y_str(y_string, span, Some(false), span)
|
||||
}
|
||||
(GroupCoordinate::SignLow, GroupCoordinate::Number(y_string)) => Self::edwards_affine_from_y_str(
|
||||
number_string_typing(&y_string, &span.clone())?,
|
||||
span,
|
||||
Some(false),
|
||||
span,
|
||||
),
|
||||
// (_, y)
|
||||
(GroupCoordinate::Inferred, GroupCoordinate::Number(y_string)) => {
|
||||
Self::edwards_affine_from_y_str(y_string, span, None, span)
|
||||
Self::edwards_affine_from_y_str(number_string_typing(&y_string, &span.clone())?, span, None, span)
|
||||
}
|
||||
// Invalid
|
||||
(x, y) => Err(GroupError::invalid_group(format!("({}, {})", x, y), span.clone())),
|
||||
@ -197,12 +231,16 @@ impl EdwardsGroupType {
|
||||
}
|
||||
|
||||
pub fn edwards_affine_from_x_str(
|
||||
x_string: String,
|
||||
x_info: (String, bool),
|
||||
x_span: &Span,
|
||||
greatest: Option<bool>,
|
||||
element_span: &Span,
|
||||
) -> Result<EdwardsAffine, GroupError> {
|
||||
let x = Fq::from_str(&x_string).map_err(|_| GroupError::x_invalid(x_string, x_span.clone()))?;
|
||||
let x = match x_info {
|
||||
(x_str, neg) if neg => -Fq::from_str(&x_str).map_err(|_| GroupError::x_invalid(x_str, x_span.clone()))?,
|
||||
(x_str, _) => Fq::from_str(&x_str).map_err(|_| GroupError::x_invalid(x_str, x_span.clone()))?,
|
||||
};
|
||||
|
||||
match greatest {
|
||||
// Sign provided
|
||||
Some(greatest) => {
|
||||
@ -227,12 +265,15 @@ impl EdwardsGroupType {
|
||||
}
|
||||
|
||||
pub fn edwards_affine_from_y_str(
|
||||
y_string: String,
|
||||
y_info: (String, bool),
|
||||
y_span: &Span,
|
||||
greatest: Option<bool>,
|
||||
element_span: &Span,
|
||||
) -> Result<EdwardsAffine, GroupError> {
|
||||
let y = Fq::from_str(&y_string).map_err(|_| GroupError::y_invalid(y_string, y_span.clone()))?;
|
||||
let y = match y_info {
|
||||
(y_str, neg) if neg => -Fq::from_str(&y_str).map_err(|_| GroupError::y_invalid(y_str, y_span.clone()))?,
|
||||
(y_str, _) => Fq::from_str(&y_str).map_err(|_| GroupError::y_invalid(y_str, y_span.clone()))?,
|
||||
};
|
||||
|
||||
match greatest {
|
||||
// Sign provided
|
||||
@ -258,14 +299,25 @@ impl EdwardsGroupType {
|
||||
}
|
||||
|
||||
pub fn edwards_affine_from_pair(
|
||||
x_string: String,
|
||||
y_string: String,
|
||||
x_info: (String, bool),
|
||||
y_info: (String, bool),
|
||||
x_span: &Span,
|
||||
y_span: &Span,
|
||||
element_span: &Span,
|
||||
) -> Result<EdwardsAffine, GroupError> {
|
||||
let x = Fq::from_str(&x_string).map_err(|_| GroupError::x_invalid(x_string, x_span.clone()))?;
|
||||
let y = Fq::from_str(&y_string).map_err(|_| GroupError::y_invalid(y_string, y_span.clone()))?;
|
||||
let x = match x_info {
|
||||
(x_str, neg) if neg => {
|
||||
-Fq::from_str(&x_str).map_err(|_| GroupError::x_invalid(x_str.to_string(), x_span.clone()))?
|
||||
}
|
||||
(x_str, _) => Fq::from_str(&x_str).map_err(|_| GroupError::x_invalid(x_str.to_string(), x_span.clone()))?,
|
||||
};
|
||||
|
||||
let y = match y_info {
|
||||
(y_str, neg) if neg => {
|
||||
-Fq::from_str(&y_str).map_err(|_| GroupError::y_invalid(y_str.to_string(), y_span.clone()))?
|
||||
}
|
||||
(y_str, _) => Fq::from_str(&y_str).map_err(|_| GroupError::y_invalid(y_str.to_string(), y_span.clone()))?,
|
||||
};
|
||||
|
||||
let element = EdwardsAffine::new(x, y);
|
||||
|
||||
|
@ -388,3 +388,12 @@ fn test_ternary() {
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_positive_and_negative() {
|
||||
let program_string = include_str!("positive_and_negative.leo");
|
||||
|
||||
let program = parse_program(program_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
10
compiler/tests/group/positive_and_negative.leo
Normal file
10
compiler/tests/group/positive_and_negative.leo
Normal file
@ -0,0 +1,10 @@
|
||||
function main() {
|
||||
let pos_element = 1group;
|
||||
let neg_element = -1group;
|
||||
|
||||
let pair_x_pos = (1, _)group;
|
||||
let pair_x_neg = (-1, _)group;
|
||||
|
||||
let pair_y_pos = (_, 1)group;
|
||||
let pair_y_neg = (_, -1)group;
|
||||
}
|
Loading…
Reference in New Issue
Block a user