From 49ae8152f88a690b8808059ea85ac7463a698ff5 Mon Sep 17 00:00:00 2001 From: rvcas Date: Mon, 6 Nov 2023 09:25:17 -0500 Subject: [PATCH] feat(bls): add new aiken level builtins --- crates/aiken-lang/src/builtins.rs | 217 +++++++++++++++++++----------- crates/uplc/src/builtins.rs | 14 +- 2 files changed, 144 insertions(+), 87 deletions(-) diff --git a/crates/aiken-lang/src/builtins.rs b/crates/aiken-lang/src/builtins.rs index 6391d411..369d25e5 100644 --- a/crates/aiken-lang/src/builtins.rs +++ b/crates/aiken-lang/src/builtins.rs @@ -426,19 +426,16 @@ pub fn plutus(id_gen: &IdGenerator) -> TypeInfo { }; for builtin in DefaultFunction::iter() { - if let Some(value) = from_default_function(builtin, id_gen) { - plutus.values.insert(builtin.aiken_name(), value); - } + let value = from_default_function(builtin, id_gen); + + plutus.values.insert(builtin.aiken_name(), value); } plutus } -pub fn from_default_function( - builtin: DefaultFunction, - id_gen: &IdGenerator, -) -> Option { - let info = match builtin { +pub fn from_default_function(builtin: DefaultFunction, id_gen: &IdGenerator) -> ValueConstructor { + let (tipo, arity) = match builtin { DefaultFunction::AddInteger | DefaultFunction::SubtractInteger | DefaultFunction::MultiplyInteger @@ -448,7 +445,7 @@ pub fn from_default_function( | DefaultFunction::ModInteger => { let tipo = function(vec![int(), int()], int()); - Some((tipo, 2)) + (tipo, 2) } DefaultFunction::EqualsInteger @@ -456,39 +453,39 @@ pub fn from_default_function( | DefaultFunction::LessThanEqualsInteger => { let tipo = function(vec![int(), int()], bool()); - Some((tipo, 2)) + (tipo, 2) } DefaultFunction::AppendByteString => { let tipo = function(vec![byte_array(), byte_array()], byte_array()); - Some((tipo, 2)) + (tipo, 2) } DefaultFunction::ConsByteString => { let tipo = function(vec![int(), byte_array()], byte_array()); - Some((tipo, 2)) + (tipo, 2) } DefaultFunction::SliceByteString => { let tipo = function(vec![int(), int(), byte_array()], byte_array()); - Some((tipo, 3)) + (tipo, 3) } DefaultFunction::LengthOfByteString => { let tipo = function(vec![byte_array()], int()); - Some((tipo, 1)) + (tipo, 1) } DefaultFunction::IndexByteString => { let tipo = function(vec![byte_array(), int()], int()); - Some((tipo, 2)) + (tipo, 2) } DefaultFunction::EqualsByteString | DefaultFunction::LessThanByteString | DefaultFunction::LessThanEqualsByteString => { let tipo = function(vec![byte_array(), byte_array()], bool()); - Some((tipo, 2)) + (tipo, 2) } DefaultFunction::Sha2_256 | DefaultFunction::Sha3_256 @@ -497,133 +494,133 @@ pub fn from_default_function( | DefaultFunction::Keccak_256 => { let tipo = function(vec![byte_array()], byte_array()); - Some((tipo, 1)) + (tipo, 1) } DefaultFunction::VerifyEd25519Signature => { let tipo = function(vec![byte_array(), byte_array(), byte_array()], bool()); - Some((tipo, 3)) + (tipo, 3) } DefaultFunction::VerifyEcdsaSecp256k1Signature => { let tipo = function(vec![byte_array(), byte_array(), byte_array()], bool()); - Some((tipo, 3)) + (tipo, 3) } DefaultFunction::VerifySchnorrSecp256k1Signature => { let tipo = function(vec![byte_array(), byte_array(), byte_array()], bool()); - Some((tipo, 3)) + (tipo, 3) } DefaultFunction::AppendString => { let tipo = function(vec![string(), string()], string()); - Some((tipo, 2)) + (tipo, 2) } DefaultFunction::EqualsString => { let tipo = function(vec![string(), string()], bool()); - Some((tipo, 2)) + (tipo, 2) } DefaultFunction::EncodeUtf8 => { let tipo = function(vec![string()], byte_array()); - Some((tipo, 1)) + (tipo, 1) } DefaultFunction::DecodeUtf8 => { let tipo = function(vec![byte_array()], string()); - Some((tipo, 1)) + (tipo, 1) } DefaultFunction::IfThenElse => { let ret = generic_var(id_gen.next()); let tipo = function(vec![bool(), ret.clone(), ret.clone()], ret); - Some((tipo, 3)) + (tipo, 3) } DefaultFunction::HeadList => { let ret = generic_var(id_gen.next()); let tipo = function(vec![list(ret.clone())], ret); - Some((tipo, 1)) + (tipo, 1) } DefaultFunction::TailList => { let ret = list(generic_var(id_gen.next())); let tipo = function(vec![ret.clone()], ret); - Some((tipo, 1)) + (tipo, 1) } DefaultFunction::NullList => { let ret = list(generic_var(id_gen.next())); let tipo = function(vec![ret], bool()); - Some((tipo, 1)) + (tipo, 1) } DefaultFunction::ConstrData => { let tipo = function(vec![int(), list(data())], data()); - Some((tipo, 2)) + (tipo, 2) } DefaultFunction::MapData => { let tipo = function(vec![list(tuple(vec![data(), data()]))], data()); - Some((tipo, 1)) + (tipo, 1) } DefaultFunction::ListData => { let tipo = function(vec![list(data())], data()); - Some((tipo, 1)) + (tipo, 1) } DefaultFunction::IData => { let tipo = function(vec![int()], data()); - Some((tipo, 1)) + (tipo, 1) } DefaultFunction::BData => { let tipo = function(vec![byte_array()], data()); - Some((tipo, 1)) + (tipo, 1) } DefaultFunction::UnConstrData => { let tipo = function(vec![data()], tuple(vec![int(), list(data())])); - Some((tipo, 1)) + (tipo, 1) } DefaultFunction::UnMapData => { let tipo = function(vec![data()], list(tuple(vec![data(), data()]))); - Some((tipo, 1)) + (tipo, 1) } DefaultFunction::UnListData => { let tipo = function(vec![data()], list(data())); - Some((tipo, 1)) + (tipo, 1) } DefaultFunction::UnIData => { let tipo = function(vec![data()], int()); - Some((tipo, 1)) + (tipo, 1) } DefaultFunction::UnBData => { let tipo = function(vec![data()], byte_array()); - Some((tipo, 1)) + (tipo, 1) } DefaultFunction::EqualsData => { let tipo = function(vec![data(), data()], bool()); - Some((tipo, 2)) + (tipo, 2) } DefaultFunction::SerialiseData => { let tipo = function(vec![data()], byte_array()); - Some((tipo, 1)) + (tipo, 1) } DefaultFunction::ChooseData => { let a = generic_var(id_gen.next()); @@ -638,86 +635,146 @@ pub fn from_default_function( ], a, ); - Some((tipo, 6)) + (tipo, 6) } DefaultFunction::MkPairData => { let tipo = function(vec![data(), data()], tuple(vec![data(), data()])); - Some((tipo, 2)) + (tipo, 2) } DefaultFunction::MkNilData => { let tipo = function(vec![], list(data())); - Some((tipo, 0)) + (tipo, 0) } DefaultFunction::MkNilPairData => { let tipo = function(vec![], list(tuple(vec![data(), data()]))); - Some((tipo, 0)) + (tipo, 0) } DefaultFunction::ChooseUnit => { let a = generic_var(id_gen.next()); let tipo = function(vec![data(), a.clone()], a); - Some((tipo, 2)) + (tipo, 2) } DefaultFunction::Trace => { let a = generic_var(id_gen.next()); let tipo = function(vec![string(), a.clone()], a); - Some((tipo, 2)) + (tipo, 2) } DefaultFunction::FstPair => { let a = generic_var(id_gen.next()); let b = generic_var(id_gen.next()); let tipo = function(vec![tuple(vec![a.clone(), b])], a); - Some((tipo, 1)) + (tipo, 1) } DefaultFunction::SndPair => { let a = generic_var(id_gen.next()); let b = generic_var(id_gen.next()); let tipo = function(vec![tuple(vec![a, b.clone()])], b); - Some((tipo, 1)) + (tipo, 1) } DefaultFunction::ChooseList => { let a = generic_var(id_gen.next()); let b = generic_var(id_gen.next()); let tipo = function(vec![list(a), b.clone(), b.clone()], b); - Some((tipo, 3)) + (tipo, 3) } DefaultFunction::MkCons => { let a = generic_var(id_gen.next()); let tipo = function(vec![a.clone(), list(a.clone())], list(a)); - Some((tipo, 2)) + (tipo, 2) } - DefaultFunction::Bls12_381_G1_Add => todo!(), - DefaultFunction::Bls12_381_G1_Neg => todo!(), - DefaultFunction::Bls12_381_G1_Scalarmul => todo!(), - DefaultFunction::Bls12_381_G1_Equal => todo!(), - DefaultFunction::Bls12_381_G1_Compress => todo!(), - DefaultFunction::Bls12_381_G1_Uncompress => todo!(), - DefaultFunction::Bls12_381_G1_Hashtogroup => todo!(), - DefaultFunction::Bls12_381_G2_Add => todo!(), - DefaultFunction::Bls12_381_G2_Neg => todo!(), - DefaultFunction::Bls12_381_G2_Scalarmul => todo!(), - DefaultFunction::Bls12_381_G2_Equal => todo!(), - DefaultFunction::Bls12_381_G2_Compress => todo!(), - DefaultFunction::Bls12_381_G2_Uncompress => todo!(), - DefaultFunction::Bls12_381_G2_Hashtogroup => todo!(), - DefaultFunction::Bls12_381_MillerLoop => todo!(), - DefaultFunction::Bls12_381_MulMlResult => todo!(), - DefaultFunction::Bls12_381_FinalVerify => todo!(), + DefaultFunction::Bls12_381_G1_Add | DefaultFunction::Bls12_381_G1_Equal => { + let tipo = function(vec![g1_element(), g1_element()], g1_element()); + + (tipo, 2) + } + DefaultFunction::Bls12_381_G1_Neg => { + let tipo = function(vec![g1_element()], g1_element()); + + (tipo, 1) + } + DefaultFunction::Bls12_381_G1_Scalarmul => { + let tipo = function(vec![int(), g1_element()], g1_element()); + + (tipo, 2) + } + DefaultFunction::Bls12_381_G1_Compress => { + let tipo = function(vec![g1_element()], byte_array()); + + (tipo, 1) + } + DefaultFunction::Bls12_381_G1_Uncompress => { + let tipo = function(vec![byte_array()], g1_element()); + + (tipo, 1) + } + DefaultFunction::Bls12_381_G1_Hashtogroup => { + let tipo = function(vec![byte_array(), byte_array()], g1_element()); + + (tipo, 2) + } + + DefaultFunction::Bls12_381_G2_Add | DefaultFunction::Bls12_381_G2_Equal => { + let tipo = function(vec![g2_element(), g2_element()], g2_element()); + + (tipo, 2) + } + DefaultFunction::Bls12_381_G2_Neg => { + let tipo = function(vec![g2_element()], g2_element()); + + (tipo, 1) + } + DefaultFunction::Bls12_381_G2_Scalarmul => { + let tipo = function(vec![int(), g2_element()], g2_element()); + + (tipo, 2) + } + DefaultFunction::Bls12_381_G2_Compress => { + let tipo = function(vec![g2_element()], byte_array()); + + (tipo, 1) + } + DefaultFunction::Bls12_381_G2_Uncompress => { + let tipo = function(vec![byte_array()], g2_element()); + + (tipo, 1) + } + DefaultFunction::Bls12_381_G2_Hashtogroup => { + let tipo = function(vec![byte_array(), byte_array()], g2_element()); + + (tipo, 2) + } + DefaultFunction::Bls12_381_MillerLoop => { + let tipo = function(vec![g1_element(), g2_element()], miller_loop_result()); + + (tipo, 2) + } + DefaultFunction::Bls12_381_MulMlResult => { + let tipo = function( + vec![miller_loop_result(), miller_loop_result()], + miller_loop_result(), + ); + + (tipo, 2) + } + DefaultFunction::Bls12_381_FinalVerify => { + let tipo = function(vec![miller_loop_result(), miller_loop_result()], bool()); + + (tipo, 2) + } }; - info.map(|(tipo, arity)| { - ValueConstructor::public( - tipo, - ValueConstructorVariant::ModuleFn { - name: builtin.aiken_name(), - field_map: None, - module: "".to_string(), - arity, - location: Span::empty(), - builtin: Some(builtin), - }, - ) - }) + ValueConstructor::public( + tipo, + ValueConstructorVariant::ModuleFn { + name: builtin.aiken_name(), + field_map: None, + module: "".to_string(), + arity, + location: Span::empty(), + builtin: Some(builtin), + }, + ) } pub fn prelude_functions(id_gen: &IdGenerator) -> IndexMap { diff --git a/crates/uplc/src/builtins.rs b/crates/uplc/src/builtins.rs index 336af60f..a8dce188 100644 --- a/crates/uplc/src/builtins.rs +++ b/crates/uplc/src/builtins.rs @@ -502,21 +502,21 @@ impl DefaultFunction { MkNilPairData => "mk_nil_pair_data", Bls12_381_G1_Add => "bls12_381_g1_add", Bls12_381_G1_Neg => "bls12_381_g1_neg", - Bls12_381_G1_Scalarmul => "bls12_381_g1_scalarmul", + Bls12_381_G1_Scalarmul => "bls12_381_g1_scalar_mul", Bls12_381_G1_Equal => "bls12_381_g1_equal", Bls12_381_G1_Compress => "bls12_381_g1_compress", Bls12_381_G1_Uncompress => "bls12_381_g1_uncompress", - Bls12_381_G1_Hashtogroup => "bls12_381_g1_hashtogroup", + Bls12_381_G1_Hashtogroup => "bls12_381_g1_hash_to_group", Bls12_381_G2_Add => "bls12_381_g2_add", Bls12_381_G2_Neg => "bls12_381_g2_neg", - Bls12_381_G2_Scalarmul => "bls12_381_g2_scalarmul", + Bls12_381_G2_Scalarmul => "bls12_381_g2_scalar_mul", Bls12_381_G2_Equal => "bls12_381_g2_equal", Bls12_381_G2_Compress => "bls12_381_g2_compress", Bls12_381_G2_Uncompress => "bls12_381_g2_uncompress", - Bls12_381_G2_Hashtogroup => "bls12_381_g2_hashtogroup", - Bls12_381_MillerLoop => "bls12_381_millerloop", - Bls12_381_MulMlResult => "bls12_381_mulmlresult", - Bls12_381_FinalVerify => "bls12_381_finalverify", + Bls12_381_G2_Hashtogroup => "bls12_381_g2_hash_to_group", + Bls12_381_MillerLoop => "bls12_381_miller_loop", + Bls12_381_MulMlResult => "bls12_381_mul_miller_loop_result", + Bls12_381_FinalVerify => "bls12_381_final_verify", } .to_string() }