mod high_level;
mod low_level;
pub use gbuiltin_bls381::{
Request, Response, ark_bls12_381, ark_ec, ark_ff, ark_scale, ark_serialize,
};
pub use high_level::*;
pub use low_level::Bls12_381OpsLowLevel;
use super::{BuiltinActorError, BuiltinContext};
use alloc::{vec, vec::Vec};
use gbuiltin_bls381::{
REQUEST_AGGREGATE_G1, REQUEST_FINAL_EXPONENTIATION, REQUEST_MAP_TO_G2AFFINE,
REQUEST_MULTI_MILLER_LOOP, REQUEST_MULTI_SCALAR_MULTIPLICATION_G1,
REQUEST_MULTI_SCALAR_MULTIPLICATION_G2, REQUEST_PROJECTIVE_MULTIPLICATION_G1,
REQUEST_PROJECTIVE_MULTIPLICATION_G2,
};
pub fn execute_bls12_381_builtins<Gas: BlsOpsGasCost, Ops: Bls12_381Ops>(
input: &[u8],
context: &mut BuiltinContext,
) -> Result<Response, BuiltinActorError> {
match input.first().copied() {
Some(REQUEST_MULTI_MILLER_LOOP) => {
high_level::multi_miller_loop::<Gas, Ops>(&input[1..], context)
}
Some(REQUEST_FINAL_EXPONENTIATION) => {
high_level::final_exponentiation::<Gas, Ops>(&input[1..], context)
}
Some(REQUEST_MULTI_SCALAR_MULTIPLICATION_G1) => high_level::msm::<Gas>(
&input[1..],
context,
Gas::bls12_381_msm_g1,
|bases, scalars| Ops::msm_g1(bases, scalars).map(Response::MultiScalarMultiplicationG1),
),
Some(REQUEST_MULTI_SCALAR_MULTIPLICATION_G2) => high_level::msm::<Gas>(
&input[1..],
context,
Gas::bls12_381_msm_g2,
|bases, scalars| Ops::msm_g2(bases, scalars).map(Response::MultiScalarMultiplicationG2),
),
Some(REQUEST_PROJECTIVE_MULTIPLICATION_G1) => high_level::projective_multiplication::<Gas>(
&input[1..],
context,
Gas::bls12_381_mul_projective_g1,
|base, scalar| {
Ops::projective_mul_g1(base, scalar).map(Response::ProjectiveMultiplicationG1)
},
),
Some(REQUEST_PROJECTIVE_MULTIPLICATION_G2) => high_level::projective_multiplication::<Gas>(
&input[1..],
context,
Gas::bls12_381_mul_projective_g2,
|base, scalar| {
Ops::projective_mul_g2(base, scalar).map(Response::ProjectiveMultiplicationG2)
},
),
Some(REQUEST_AGGREGATE_G1) => high_level::aggregate_g1::<Gas, Ops>(&input[1..], context),
Some(REQUEST_MAP_TO_G2AFFINE) => {
high_level::map_to_g2affine::<Gas, Ops>(&input[1..], context)
}
_ => Err(BuiltinActorError::DecodingError),
}
}
pub trait BlsOpsGasCost {
fn decode_bytes(len: u32) -> u64;
fn bls12_381_multi_miller_loop(count: u32) -> u64;
fn bls12_381_final_exponentiation() -> u64;
fn bls12_381_msm_g1(count: u32) -> u64;
fn bls12_381_msm_g2(count: u32) -> u64;
fn bls12_381_mul_projective_g1(count: u32) -> u64;
fn bls12_381_mul_projective_g2(count: u32) -> u64;
fn bls12_381_aggregate_g1(count: u32) -> u64;
fn bls12_381_map_to_g2affine(len: u32) -> u64;
}
pub trait Bls12_381Ops {
fn multi_miller_loop(g1: Vec<u8>, g2: Vec<u8>) -> Result<Vec<u8>, BuiltinActorError>;
fn final_exponentiation(f: Vec<u8>) -> Result<Vec<u8>, BuiltinActorError>;
fn msm_g1(bases: Vec<u8>, scalars: Vec<u8>) -> Result<Vec<u8>, BuiltinActorError>;
fn msm_g2(bases: Vec<u8>, scalars: Vec<u8>) -> Result<Vec<u8>, BuiltinActorError>;
fn projective_mul_g1(base: Vec<u8>, scalar: Vec<u8>) -> Result<Vec<u8>, BuiltinActorError>;
fn projective_mul_g2(base: Vec<u8>, scalar: Vec<u8>) -> Result<Vec<u8>, BuiltinActorError>;
fn aggregate_g1(points: Vec<u8>) -> Result<Vec<u8>, BuiltinActorError>;
fn map_to_g2affine(message: Vec<u8>) -> Result<Vec<u8>, BuiltinActorError>;
}