use crate::utils;
use alloc::vec::Vec;
use ark_bls12_381_ext::CurveHooks;
use ark_ec::{pairing::Pairing, CurveConfig};
use sp_runtime_interface::runtime_interface;
pub mod g1 {
pub use ark_bls12_381_ext::g1::{BETA, G1_GENERATOR_X, G1_GENERATOR_Y};
pub type Config = ark_bls12_381_ext::g1::Config<super::HostHooks>;
pub type G1Affine = ark_bls12_381_ext::g1::G1Affine<super::HostHooks>;
pub type G1Projective = ark_bls12_381_ext::g1::G1Projective<super::HostHooks>;
}
pub mod g2 {
pub use ark_bls12_381_ext::g2::{
G2_GENERATOR_X, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1, G2_GENERATOR_Y, G2_GENERATOR_Y_C0,
G2_GENERATOR_Y_C1,
};
pub type Config = ark_bls12_381_ext::g2::Config<super::HostHooks>;
pub type G2Affine = ark_bls12_381_ext::g2::G2Affine<super::HostHooks>;
pub type G2Projective = ark_bls12_381_ext::g2::G2Projective<super::HostHooks>;
}
pub use self::{
g1::{Config as G1Config, G1Affine, G1Projective},
g2::{Config as G2Config, G2Affine, G2Projective},
};
#[derive(Copy, Clone)]
pub struct HostHooks;
pub type Config = ark_bls12_381_ext::Config<HostHooks>;
pub type Bls12_381 = ark_bls12_381_ext::Bls12_381<HostHooks>;
impl CurveHooks for HostHooks {
fn bls12_381_multi_miller_loop(
g1: impl Iterator<Item = <Bls12_381 as Pairing>::G1Prepared>,
g2: impl Iterator<Item = <Bls12_381 as Pairing>::G2Prepared>,
) -> Result<<Bls12_381 as Pairing>::TargetField, ()> {
let g1 = utils::encode(g1.collect::<Vec<_>>());
let g2 = utils::encode(g2.collect::<Vec<_>>());
let res = host_calls::bls12_381_multi_miller_loop(g1, g2).unwrap_or_default();
utils::decode(res)
}
fn bls12_381_final_exponentiation(
target: <Bls12_381 as Pairing>::TargetField,
) -> Result<<Bls12_381 as Pairing>::TargetField, ()> {
let target = utils::encode(target);
let res = host_calls::bls12_381_final_exponentiation(target).unwrap_or_default();
utils::decode(res)
}
fn bls12_381_msm_g1(
bases: &[G1Affine],
scalars: &[<G1Config as CurveConfig>::ScalarField],
) -> Result<G1Projective, ()> {
let bases = utils::encode(bases);
let scalars = utils::encode(scalars);
let res = host_calls::bls12_381_msm_g1(bases, scalars).unwrap_or_default();
utils::decode_proj_sw(res)
}
fn bls12_381_msm_g2(
bases: &[G2Affine],
scalars: &[<G2Config as CurveConfig>::ScalarField],
) -> Result<G2Projective, ()> {
let bases = utils::encode(bases);
let scalars = utils::encode(scalars);
let res = host_calls::bls12_381_msm_g2(bases, scalars).unwrap_or_default();
utils::decode_proj_sw(res)
}
fn bls12_381_mul_projective_g1(
base: &G1Projective,
scalar: &[u64],
) -> Result<G1Projective, ()> {
let base = utils::encode_proj_sw(base);
let scalar = utils::encode(scalar);
let res = host_calls::bls12_381_mul_projective_g1(base, scalar).unwrap_or_default();
utils::decode_proj_sw(res)
}
fn bls12_381_mul_projective_g2(
base: &G2Projective,
scalar: &[u64],
) -> Result<G2Projective, ()> {
let base = utils::encode_proj_sw(base);
let scalar = utils::encode(scalar);
let res = host_calls::bls12_381_mul_projective_g2(base, scalar).unwrap_or_default();
utils::decode_proj_sw(res)
}
}
#[runtime_interface]
pub trait HostCalls {
fn bls12_381_multi_miller_loop(a: Vec<u8>, b: Vec<u8>) -> Result<Vec<u8>, ()> {
utils::multi_miller_loop::<ark_bls12_381::Bls12_381>(a, b)
}
fn bls12_381_final_exponentiation(f: Vec<u8>) -> Result<Vec<u8>, ()> {
utils::final_exponentiation::<ark_bls12_381::Bls12_381>(f)
}
fn bls12_381_msm_g1(bases: Vec<u8>, scalars: Vec<u8>) -> Result<Vec<u8>, ()> {
utils::msm_sw::<ark_bls12_381::g1::Config>(bases, scalars)
}
fn bls12_381_msm_g2(bases: Vec<u8>, scalars: Vec<u8>) -> Result<Vec<u8>, ()> {
utils::msm_sw::<ark_bls12_381::g2::Config>(bases, scalars)
}
fn bls12_381_mul_projective_g1(base: Vec<u8>, scalar: Vec<u8>) -> Result<Vec<u8>, ()> {
utils::mul_projective_sw::<ark_bls12_381::g1::Config>(base, scalar)
}
fn bls12_381_mul_projective_g2(base: Vec<u8>, scalar: Vec<u8>) -> Result<Vec<u8>, ()> {
utils::mul_projective_sw::<ark_bls12_381::g2::Config>(base, scalar)
}
}