From 8b89ba3b938767ed648e48244c596b50edbbddf4 Mon Sep 17 00:00:00 2001 From: microproofs Date: Tue, 7 Nov 2023 14:14:33 -0500 Subject: [PATCH] feat: implement bls primitives in code gen --- crates/aiken-lang/src/ast.rs | 21 ++++++++++++++++--- crates/aiken-lang/src/expr.rs | 4 ++-- crates/aiken-lang/src/format.rs | 12 +++++++++-- crates/aiken-lang/src/gen_uplc.rs | 9 ++++++-- crates/aiken-lang/src/gen_uplc/air.rs | 5 ++++- crates/aiken-lang/src/gen_uplc/builder.rs | 7 ++++++- crates/aiken-lang/src/gen_uplc/tree.rs | 12 ++++++++++- .../src/parser/definition/constant.rs | 2 +- .../aiken-lang/src/parser/expr/bytearray.rs | 2 +- crates/aiken-lang/src/tipo/expr.rs | 4 ++-- crates/uplc/src/builder.rs | 8 +++++++ 11 files changed, 70 insertions(+), 16 deletions(-) diff --git a/crates/aiken-lang/src/ast.rs b/crates/aiken-lang/src/ast.rs index fa4226c0..9f2959a0 100644 --- a/crates/aiken-lang/src/ast.rs +++ b/crates/aiken-lang/src/ast.rs @@ -1,5 +1,5 @@ use crate::{ - builtins::{self, bool}, + builtins::{self, bool, g1_element, g2_element}, expr::{TypedExpr, UntypedExpr}, parser::token::{Base, Token}, tipo::{PatternConstructor, Type, TypeInfo}, @@ -496,7 +496,7 @@ pub enum Constant { CurvePoint { location: Span, - point: Curve, + point: Box, preferred_format: ByteArrayFormatPreference, }, } @@ -507,7 +507,7 @@ impl Constant { Constant::Int { .. } => builtins::int(), Constant::String { .. } => builtins::string(), Constant::ByteArray { .. } => builtins::byte_array(), - Constant::CurvePoint { point, .. } => match point { + Constant::CurvePoint { point, .. } => match point.as_ref() { Curve::Bls12_381(Bls12_381Point::G1(_)) => builtins::g1_element(), Curve::Bls12_381(Bls12_381Point::G2(_)) => builtins::g2_element(), }, @@ -1067,6 +1067,12 @@ impl Curve { }, } } + + pub fn tipo(&self) -> Rc { + match self { + Curve::Bls12_381(point) => point.tipo(), + } + } } #[derive(Debug, Clone, PartialEq, Eq, Copy)] @@ -1075,6 +1081,15 @@ pub enum Bls12_381Point { G2(blst::blst_p2), } +impl Bls12_381Point { + pub fn tipo(&self) -> Rc { + match self { + Bls12_381Point::G1(_) => g1_element(), + Bls12_381Point::G2(_) => g2_element(), + } + } +} + impl Default for Bls12_381Point { fn default() -> Self { Bls12_381Point::G1(Default::default()) diff --git a/crates/aiken-lang/src/expr.rs b/crates/aiken-lang/src/expr.rs index 476659a1..bb94da7f 100644 --- a/crates/aiken-lang/src/expr.rs +++ b/crates/aiken-lang/src/expr.rs @@ -37,7 +37,7 @@ pub enum TypedExpr { CurvePoint { location: Span, tipo: Rc, - point: Curve, + point: Box, }, Sequence { @@ -485,7 +485,7 @@ pub enum UntypedExpr { CurvePoint { location: Span, - point: Curve, + point: Box, preferred_format: ByteArrayFormatPreference, }, diff --git a/crates/aiken-lang/src/format.rs b/crates/aiken-lang/src/format.rs index 1e667443..4537c25d 100644 --- a/crates/aiken-lang/src/format.rs +++ b/crates/aiken-lang/src/format.rs @@ -357,7 +357,11 @@ impl<'comments> Formatter<'comments> { point, preferred_format, .. - } => self.bytearray(&point.compress(), Some(point.into()), preferred_format), + } => self.bytearray( + &point.compress(), + Some(point.as_ref().into()), + preferred_format, + ), Constant::Int { value, base, .. } => self.int(value, base), Constant::String { value, .. } => self.string(value), } @@ -792,7 +796,11 @@ impl<'comments> Formatter<'comments> { point, preferred_format, .. - } => self.bytearray(&point.compress(), Some(point.into()), preferred_format), + } => self.bytearray( + &point.compress(), + Some(point.as_ref().into()), + preferred_format, + ), UntypedExpr::If { branches, diff --git a/crates/aiken-lang/src/gen_uplc.rs b/crates/aiken-lang/src/gen_uplc.rs index 2f28951b..787c1a2d 100644 --- a/crates/aiken-lang/src/gen_uplc.rs +++ b/crates/aiken-lang/src/gen_uplc.rs @@ -19,8 +19,8 @@ use uplc::{ use crate::{ ast::{ - AssignmentKind, BinOp, Pattern, Span, TypedArg, TypedClause, TypedDataType, TypedFunction, - TypedPattern, TypedValidator, UnOp, + AssignmentKind, BinOp, Bls12_381Point, Curve, Pattern, Span, TypedArg, TypedClause, + TypedDataType, TypedFunction, TypedPattern, TypedValidator, UnOp, }, builtins::{bool, data, int, list, string, void}, expr::TypedExpr, @@ -725,6 +725,7 @@ impl<'a> CodeGenerator<'a> { } TypedExpr::UnOp { value, op, .. } => AirTree::unop(*op, self.build(value)), + TypedExpr::CurvePoint { point, .. } => AirTree::curve(*point.as_ref()), } } @@ -3550,6 +3551,10 @@ impl<'a> CodeGenerator<'a> { Air::Bool { value } => { arg_stack.push(Term::bool(value)); } + Air::CurvePoint { point, .. } => match point { + Curve::Bls12_381(Bls12_381Point::G1(g1)) => arg_stack.push(Term::bls12_381_g1(g1)), + Curve::Bls12_381(Bls12_381Point::G2(g2)) => arg_stack.push(Term::bls12_381_g2(g2)), + }, Air::Var { name, constructor, diff --git a/crates/aiken-lang/src/gen_uplc/air.rs b/crates/aiken-lang/src/gen_uplc/air.rs index 224c6ac0..4543f939 100644 --- a/crates/aiken-lang/src/gen_uplc/air.rs +++ b/crates/aiken-lang/src/gen_uplc/air.rs @@ -3,7 +3,7 @@ use std::rc::Rc; use uplc::builtins::DefaultFunction; use crate::{ - ast::{BinOp, UnOp}, + ast::{BinOp, Curve, UnOp}, tipo::{Type, ValueConstructor}, }; @@ -19,6 +19,9 @@ pub enum Air { ByteArray { bytes: Vec, }, + CurvePoint { + point: Curve, + }, Bool { value: bool, }, diff --git a/crates/aiken-lang/src/gen_uplc/builder.rs b/crates/aiken-lang/src/gen_uplc/builder.rs index 14731960..d5732214 100644 --- a/crates/aiken-lang/src/gen_uplc/builder.rs +++ b/crates/aiken-lang/src/gen_uplc/builder.rs @@ -506,6 +506,7 @@ pub fn constants_ir(literal: &Constant) -> AirTree { Constant::Int { value, .. } => AirTree::int(value), Constant::String { value, .. } => AirTree::string(value), Constant::ByteArray { bytes, .. } => AirTree::byte_array(bytes.clone()), + Constant::CurvePoint { point, .. } => AirTree::curve(*point.as_ref()), } } @@ -1217,6 +1218,8 @@ pub fn convert_data_to_type(term: Term, field_type: &Rc) -> Term>) -> Vec UplcConstant::Data(PlutusData::BoundedBytes( b.deref().clone().compress().into(), )), - UplcConstant::Bls12_381MlResult(_) => unreachable!(), + UplcConstant::Bls12_381MlResult(_) => unreachable!("Bls12_381MlResult not supported"), }; new_constants.push(constant); } @@ -1365,6 +1368,8 @@ pub fn convert_type_to_data(term: Term, field_type: &Rc) -> Term, }, + CurvePoint { + point: Curve, + }, Bool { value: bool, }, @@ -341,6 +344,9 @@ impl AirTree { pub fn byte_array(bytes: Vec) -> AirTree { AirTree::Expression(AirExpression::ByteArray { bytes }) } + pub fn curve(point: Curve) -> AirTree { + AirTree::Expression(AirExpression::CurvePoint { point }) + } pub fn bool(value: bool) -> AirTree { AirTree::Expression(AirExpression::Bool { value }) } @@ -1058,6 +1064,9 @@ impl AirTree { AirExpression::ByteArray { bytes } => air_vec.push(Air::ByteArray { bytes: bytes.clone(), }), + AirExpression::CurvePoint { point } => { + air_vec.push(Air::CurvePoint { point: *point }) + } AirExpression::Bool { value } => air_vec.push(Air::Bool { value: *value }), AirExpression::List { tipo, tail, items } => { air_vec.push(Air::List { @@ -1286,6 +1295,7 @@ impl AirTree { AirExpression::String { .. } => string(), AirExpression::ByteArray { .. } => byte_array(), AirExpression::Bool { .. } => bool(), + AirExpression::CurvePoint { point } => point.tipo(), AirExpression::List { tipo, .. } | AirExpression::Tuple { tipo, .. } | AirExpression::Call { tipo, .. } diff --git a/crates/aiken-lang/src/parser/definition/constant.rs b/crates/aiken-lang/src/parser/definition/constant.rs index 01cddaec..f7c28acb 100644 --- a/crates/aiken-lang/src/parser/definition/constant.rs +++ b/crates/aiken-lang/src/parser/definition/constant.rs @@ -66,7 +66,7 @@ pub fn value() -> impl Parser { ast::Constant::CurvePoint { location, - point: ast::Curve::Bls12_381(point), + point: ast::Curve::Bls12_381(point).into(), preferred_format, } } diff --git a/crates/aiken-lang/src/parser/expr/bytearray.rs b/crates/aiken-lang/src/parser/expr/bytearray.rs index 4aefefae..a750f441 100644 --- a/crates/aiken-lang/src/parser/expr/bytearray.rs +++ b/crates/aiken-lang/src/parser/expr/bytearray.rs @@ -27,7 +27,7 @@ pub fn parser() -> impl Parser { UntypedExpr::CurvePoint { location, - point: ast::Curve::Bls12_381(point), + point: ast::Curve::Bls12_381(point).into(), preferred_format, } } diff --git a/crates/aiken-lang/src/tipo/expr.rs b/crates/aiken-lang/src/tipo/expr.rs index 46c9c9a9..bef14653 100644 --- a/crates/aiken-lang/src/tipo/expr.rs +++ b/crates/aiken-lang/src/tipo/expr.rs @@ -323,7 +323,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { UntypedExpr::CurvePoint { location, point, .. - } => self.infer_curve_point(point, location), + } => self.infer_curve_point(*point, location), UntypedExpr::RecordUpdate { location, @@ -377,7 +377,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { Ok(TypedExpr::CurvePoint { location, - point: curve, + point: curve.into(), tipo, }) } diff --git a/crates/uplc/src/builder.rs b/crates/uplc/src/builder.rs index d0703b0c..8f62905f 100644 --- a/crates/uplc/src/builder.rs +++ b/crates/uplc/src/builder.rs @@ -38,6 +38,14 @@ impl Term { Term::Constant(Constant::ByteString(b).into()) } + pub fn bls12_381_g1(b: blst::blst_p1) -> Self { + Term::Constant(Constant::Bls12_381G1Element(b.into()).into()) + } + + pub fn bls12_381_g2(b: blst::blst_p2) -> Self { + Term::Constant(Constant::Bls12_381G2Element(b.into()).into()) + } + pub fn bool(b: bool) -> Self { Term::Constant(Constant::Bool(b).into()) }