mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-25 19:22:01 +03:00
impl new group notation compiler
This commit is contained in:
parent
60bf079e33
commit
3fe25da23f
@ -52,4 +52,34 @@ impl GroupError {
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn x_invalid(x: String, span: Span) -> Self {
|
||||
let message = format!("invalid x coordinate `{}`", x);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn y_invalid(y: String, span: Span) -> Self {
|
||||
let message = format!("invalid y coordinate `{}`", y);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn not_on_curve(element: String, span: Span) -> Self {
|
||||
let message = format!("group element `{}` is not on the supported curve", element);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn x_recover(span: Span) -> Self {
|
||||
let message = format!("could not recover group element from x coordinate");
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn y_recover(span: Span) -> Self {
|
||||
let message = format!("could not recover group element from x coordinate");
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
}
|
||||
|
@ -45,4 +45,10 @@ impl ValueError {
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn implicit_group(span: Span) -> Self {
|
||||
let message = format!("group coordinates should be in (x, y)group format");
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Expression::Address(address, span) => Ok(ConstrainedValue::Address(Address::new(address, span)?)),
|
||||
Expression::Boolean(boolean, span) => Ok(ConstrainedValue::Boolean(new_bool_constant(boolean, span)?)),
|
||||
Expression::Field(field, span) => Ok(ConstrainedValue::Field(FieldType::constant(field, span)?)),
|
||||
Expression::Group(group_affine, span) => Ok(ConstrainedValue::Group(G::constant(group_affine, span)?)),
|
||||
Expression::Group(group_affine) => Ok(ConstrainedValue::Group(G::constant(group_affine)?)),
|
||||
Expression::Implicit(value, span) => Ok(enforce_number_implicit(expected_type, value, span)?),
|
||||
Expression::Integer(type_, integer, span) => {
|
||||
Ok(ConstrainedValue::Integer(Integer::new_constant(&type_, integer, span)?))
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! A data type that represents members in the group formed by the set of affine points on a curve.
|
||||
|
||||
use crate::errors::GroupError;
|
||||
use leo_typed::Span;
|
||||
use leo_typed::{GroupValue, Span};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, One},
|
||||
@ -32,7 +32,7 @@ pub trait GroupType<F: Field>:
|
||||
+ ToBitsGadget<F>
|
||||
+ ToBytesGadget<F>
|
||||
{
|
||||
fn constant(string: String, span: Span) -> Result<Self, GroupError>;
|
||||
fn constant(value: GroupValue) -> Result<Self, GroupError>;
|
||||
|
||||
fn to_allocated<CS: ConstraintSystem<F>>(&self, cs: CS, span: Span) -> Result<Self, GroupError>;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{errors::GroupError, GroupType};
|
||||
use leo_typed::Span;
|
||||
use leo_typed::{GroupCoordinate, GroupValue, Span};
|
||||
|
||||
use snarkos_curves::{
|
||||
edwards_bls12::{EdwardsAffine, EdwardsParameters, Fq},
|
||||
@ -36,14 +36,43 @@ pub enum EdwardsGroupType {
|
||||
}
|
||||
|
||||
impl GroupType<Fq> for EdwardsGroupType {
|
||||
fn constant(string: String, span: Span) -> Result<Self, GroupError> {
|
||||
// 1group = generator
|
||||
if string.eq("1") {
|
||||
return Ok(Self::one());
|
||||
}
|
||||
fn constant(group: GroupValue) -> Result<Self, GroupError> {
|
||||
let span = group.span;
|
||||
let x = group.x;
|
||||
let y = group.y;
|
||||
|
||||
let value =
|
||||
Self::edwards_affine_from_str(string.clone()).map_err(|_| GroupError::invalid_group(string, span))?;
|
||||
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)),
|
||||
};
|
||||
|
||||
Ok(EdwardsGroupType::Constant(value))
|
||||
}
|
||||
@ -124,8 +153,85 @@ impl GroupType<Fq> for EdwardsGroupType {
|
||||
}
|
||||
|
||||
impl EdwardsGroupType {
|
||||
pub fn edwards_affine_from_x_str(
|
||||
x_string: String,
|
||||
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))?;
|
||||
match greatest {
|
||||
// Sign provided
|
||||
Some(greatest) => EdwardsAffine::from_x_coordinate(x, greatest).ok_or(GroupError::x_recover(element_span)),
|
||||
// Sign inferred
|
||||
None => {
|
||||
// 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(GroupError::x_recover(element_span))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn edwards_affine_from_y_str(
|
||||
y_string: String,
|
||||
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))?;
|
||||
|
||||
unimplemented!("recover from_y_coordinate not implemented for Edwards Affine")
|
||||
// match greatest {
|
||||
// // Sign provided
|
||||
// Some(greatest) => EdwardsAffine::from_y_coordinate(y, greatest).ok_or(GroupError::y_recover(element_span)),
|
||||
// // Sign inferred
|
||||
// None => {
|
||||
// // Attempt to recover with a sign_low bit.
|
||||
// if let Some(element) = EdwardsAffine::from_y_coordinate(y.clone(), false) {
|
||||
// return Ok(element);
|
||||
// }
|
||||
//
|
||||
// // Attempt to recover with a sign_high bit.
|
||||
// if let Some(element) = EdwardsAffine::from_y_coordinate(y, true) {
|
||||
// return Ok(element);
|
||||
// }
|
||||
//
|
||||
// // Otherwise return error.
|
||||
// Err(GroupError::y_recover(element_span))
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
pub fn edwards_affine_from_pair(
|
||||
x_string: String,
|
||||
y_string: String,
|
||||
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))?;
|
||||
let y = Fq::from_str(&y_string).map_err(|_| GroupError::y_invalid(y_string, y_span))?;
|
||||
|
||||
let element = EdwardsAffine::new(x, y);
|
||||
|
||||
if element.is_on_curve() {
|
||||
Ok(element)
|
||||
} else {
|
||||
Err(GroupError::not_on_curve(format!("{}", element), element_span))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn edwards_affine_from_str(string: String) -> Result<EdwardsAffine, SynthesisError> {
|
||||
// x or (x, y)
|
||||
// (x, y)
|
||||
match Fq::from_str(&string).ok() {
|
||||
Some(x) => {
|
||||
// Attempt to recover with a sign_low bit.
|
||||
|
@ -69,7 +69,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
||||
Type::Address => Ok(ConstrainedValue::Address(Address::new(value, span)?)),
|
||||
Type::Boolean => Ok(ConstrainedValue::Boolean(new_bool_constant(value, span)?)),
|
||||
Type::Field => Ok(ConstrainedValue::Field(FieldType::constant(value, span)?)),
|
||||
Type::Group => Ok(ConstrainedValue::Group(G::constant(value, span)?)),
|
||||
Type::Group => Err(ValueError::implicit_group(span)),
|
||||
Type::IntegerType(integer_type) => Ok(ConstrainedValue::Integer(Integer::new_constant(
|
||||
integer_type,
|
||||
value,
|
||||
|
@ -13,9 +13,9 @@ use std::fmt;
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum GroupCoordinate {
|
||||
Number(String, Span),
|
||||
SignHigh(Span),
|
||||
SignLow(Span),
|
||||
Inferred(Span),
|
||||
SignHigh,
|
||||
SignLow,
|
||||
Inferred,
|
||||
}
|
||||
|
||||
impl<'ast> From<AstGroupCoordinate<'ast>> for GroupCoordinate {
|
||||
@ -33,9 +33,9 @@ impl fmt::Display for GroupCoordinate {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
GroupCoordinate::Number(number, _) => write!(f, "{}", number),
|
||||
GroupCoordinate::SignHigh(_) => write!(f, "+"),
|
||||
GroupCoordinate::SignLow(_) => write!(f, "-"),
|
||||
GroupCoordinate::Inferred(_) => write!(f, "_"),
|
||||
GroupCoordinate::SignHigh => write!(f, "+"),
|
||||
GroupCoordinate::SignLow => write!(f, "-"),
|
||||
GroupCoordinate::Inferred => write!(f, "_"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -50,19 +50,19 @@ impl<'ast> From<AstNumberValue<'ast>> for GroupCoordinate {
|
||||
}
|
||||
|
||||
impl<'ast> From<AstSignHigh<'ast>> for GroupCoordinate {
|
||||
fn from(sign: AstSignHigh<'ast>) -> Self {
|
||||
GroupCoordinate::SignHigh(Span::from(sign.span))
|
||||
fn from(_sign: AstSignHigh<'ast>) -> Self {
|
||||
GroupCoordinate::SignHigh
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<AstSignLow<'ast>> for GroupCoordinate {
|
||||
fn from(sign: AstSignLow<'ast>) -> Self {
|
||||
GroupCoordinate::SignLow(Span::from(sign.span))
|
||||
fn from(_sign: AstSignLow<'ast>) -> Self {
|
||||
GroupCoordinate::SignLow
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<AstInferred<'ast>> for GroupCoordinate {
|
||||
fn from(sign: AstInferred<'ast>) -> Self {
|
||||
GroupCoordinate::Inferred(Span::from(sign.span))
|
||||
fn from(_sign: AstInferred<'ast>) -> Self {
|
||||
GroupCoordinate::Inferred
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user