use crate::utils;
use alloc::vec::Vec;
use ark_bw6_761_ext::CurveHooks;
use ark_ec::{pairing::Pairing, CurveConfig};
use pezsp_runtime_interface::{
pass_by::{AllocateAndReturnByCodec, PassFatPointerAndRead},
runtime_interface,
};
pub mod g1 {
pub use ark_bw6_761_ext::g1::{G1_GENERATOR_X, G1_GENERATOR_Y};
pub type Config = ark_bw6_761_ext::g1::Config<super::HostHooks>;
pub type G1Affine = ark_bw6_761_ext::g1::G1Affine<super::HostHooks>;
pub type G1Projective = ark_bw6_761_ext::g1::G1Projective<super::HostHooks>;
}
pub mod g2 {
pub use ark_bw6_761_ext::g2::{G2_GENERATOR_X, G2_GENERATOR_Y};
pub type Config = ark_bw6_761_ext::g2::Config<super::HostHooks>;
pub type G2Affine = ark_bw6_761_ext::g2::G2Affine<super::HostHooks>;
pub type G2Projective = ark_bw6_761_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_bw6_761_ext::Config<HostHooks>;
pub type BW6_761 = ark_bw6_761_ext::BW6_761<HostHooks>;
impl CurveHooks for HostHooks {
fn multi_miller_loop(
g1: impl Iterator<Item = <BW6_761 as Pairing>::G1Prepared>,
g2: impl Iterator<Item = <BW6_761 as Pairing>::G2Prepared>,
) -> <BW6_761 as Pairing>::TargetField {
host_calls::bw6_761_multi_miller_loop(utils::encode_iter(g1), utils::encode_iter(g2))
.and_then(|res| utils::decode(res))
.unwrap_or_default()
}
fn final_exponentiation(
target: <BW6_761 as Pairing>::TargetField,
) -> <BW6_761 as Pairing>::TargetField {
host_calls::bw6_761_final_exponentiation(utils::encode(target))
.and_then(|res| utils::decode(res))
.unwrap_or_default()
}
fn msm_g1(
bases: &[G1Affine],
scalars: &[<G1Config as CurveConfig>::ScalarField],
) -> G1Projective {
host_calls::bw6_761_msm_g1(utils::encode(bases), utils::encode(scalars))
.and_then(|res| utils::decode_proj_sw(res))
.unwrap_or_default()
}
fn msm_g2(
bases: &[G2Affine],
scalars: &[<G2Config as CurveConfig>::ScalarField],
) -> G2Projective {
host_calls::bw6_761_msm_g2(utils::encode(bases), utils::encode(scalars))
.and_then(|res| utils::decode_proj_sw(res))
.unwrap_or_default()
}
fn mul_projective_g1(base: &G1Projective, scalar: &[u64]) -> G1Projective {
host_calls::bw6_761_mul_projective_g1(utils::encode_proj_sw(base), utils::encode(scalar))
.and_then(|res| utils::decode_proj_sw(res))
.unwrap_or_default()
}
fn mul_projective_g2(base: &G2Projective, scalar: &[u64]) -> G2Projective {
host_calls::bw6_761_mul_projective_g2(utils::encode_proj_sw(base), utils::encode(scalar))
.and_then(|res| utils::decode_proj_sw(res))
.unwrap_or_default()
}
}
#[runtime_interface]
pub trait HostCalls {
fn bw6_761_multi_miller_loop(
a: PassFatPointerAndRead<Vec<u8>>,
b: PassFatPointerAndRead<Vec<u8>>,
) -> AllocateAndReturnByCodec<Result<Vec<u8>, ()>> {
utils::multi_miller_loop::<ark_bw6_761::BW6_761>(a, b)
}
fn bw6_761_final_exponentiation(
f: PassFatPointerAndRead<Vec<u8>>,
) -> AllocateAndReturnByCodec<Result<Vec<u8>, ()>> {
utils::final_exponentiation::<ark_bw6_761::BW6_761>(f)
}
fn bw6_761_msm_g1(
bases: PassFatPointerAndRead<Vec<u8>>,
scalars: PassFatPointerAndRead<Vec<u8>>,
) -> AllocateAndReturnByCodec<Result<Vec<u8>, ()>> {
utils::msm_sw::<ark_bw6_761::g1::Config>(bases, scalars)
}
fn bw6_761_msm_g2(
bases: PassFatPointerAndRead<Vec<u8>>,
scalars: PassFatPointerAndRead<Vec<u8>>,
) -> AllocateAndReturnByCodec<Result<Vec<u8>, ()>> {
utils::msm_sw::<ark_bw6_761::g2::Config>(bases, scalars)
}
fn bw6_761_mul_projective_g1(
base: PassFatPointerAndRead<Vec<u8>>,
scalar: PassFatPointerAndRead<Vec<u8>>,
) -> AllocateAndReturnByCodec<Result<Vec<u8>, ()>> {
utils::mul_projective_sw::<ark_bw6_761::g1::Config>(base, scalar)
}
fn bw6_761_mul_projective_g2(
base: PassFatPointerAndRead<Vec<u8>>,
scalar: PassFatPointerAndRead<Vec<u8>>,
) -> AllocateAndReturnByCodec<Result<Vec<u8>, ()>> {
utils::mul_projective_sw::<ark_bw6_761::g2::Config>(base, scalar)
}
}