use super::utils::{self, HostcallResult, FAIL_MSG};
use crate::runtime_interface::{
pass_by::{PassFatPointerAndRead, PassFatPointerAndWrite},
runtime_interface,
};
use alloc::vec::Vec;
use ark_ec::{AffineRepr, CurveConfig, CurveGroup};
use ark_ed_on_bls12_381_bandersnatch_ext::CurveHooks;
pub type BandersnatchConfig = ark_ed_on_bls12_381_bandersnatch_ext::BandersnatchConfig<HostHooks>;
pub type EdwardsConfig = ark_ed_on_bls12_381_bandersnatch_ext::EdwardsConfig<HostHooks>;
pub type EdwardsAffine = ark_ed_on_bls12_381_bandersnatch_ext::EdwardsAffine<HostHooks>;
pub type EdwardsProjective = ark_ed_on_bls12_381_bandersnatch_ext::EdwardsProjective<HostHooks>;
pub type SWConfig = ark_ed_on_bls12_381_bandersnatch_ext::SWConfig<HostHooks>;
pub type SWAffine = ark_ed_on_bls12_381_bandersnatch_ext::SWAffine<HostHooks>;
pub type SWProjective = ark_ed_on_bls12_381_bandersnatch_ext::SWProjective<HostHooks>;
pub type ScalarField = <BandersnatchConfig as CurveConfig>::ScalarField;
#[derive(Copy, Clone)]
pub struct HostHooks;
impl CurveHooks for HostHooks {
fn msm_te(bases: &[EdwardsAffine], scalars: &[ScalarField]) -> EdwardsProjective {
let mut out = utils::buffer_for::<EdwardsAffine>();
host_calls::ed_on_bls12_381_bandersnatch_msm(
&utils::encode(bases),
&utils::encode(scalars),
&mut out,
)
.and_then(|_| utils::decode::<EdwardsAffine>(&out))
.expect(FAIL_MSG)
.into_group()
}
fn mul_projective_te(base: &EdwardsProjective, scalar: &[u64]) -> EdwardsProjective {
let mut out = utils::buffer_for::<EdwardsAffine>();
host_calls::ed_on_bls12_381_bandersnatch_mul(
&utils::encode(base.into_affine()),
&utils::encode(scalar),
&mut out,
)
.and_then(|_| utils::decode::<EdwardsAffine>(&out))
.expect(FAIL_MSG)
.into_group()
}
fn msm_sw(bases: &[SWAffine], scalars: &[ScalarField]) -> SWProjective {
let mut out = utils::buffer_for::<SWAffine>();
host_calls::ed_on_bls12_381_bandersnatch_msm_sw(
&utils::encode(bases),
&utils::encode(scalars),
&mut out,
)
.and_then(|_| utils::decode::<SWAffine>(&out))
.expect(FAIL_MSG)
.into_group()
}
fn mul_projective_sw(base: &SWProjective, scalar: &[u64]) -> SWProjective {
let mut out = utils::buffer_for::<SWAffine>();
host_calls::ed_on_bls12_381_bandersnatch_mul_sw(
&utils::encode(base.into_affine()),
&utils::encode(scalar),
&mut out,
)
.and_then(|_| utils::decode::<SWAffine>(&out))
.expect(FAIL_MSG)
.into_group()
}
}
#[runtime_interface]
pub trait HostCalls {
fn ed_on_bls12_381_bandersnatch_msm(
bases: PassFatPointerAndRead<&[u8]>,
scalars: PassFatPointerAndRead<&[u8]>,
out: PassFatPointerAndWrite<&mut [u8]>,
) -> HostcallResult {
utils::msm_te::<ark_ed_on_bls12_381_bandersnatch::EdwardsConfig>(bases, scalars, out)
}
fn ed_on_bls12_381_bandersnatch_mul(
base: PassFatPointerAndRead<&[u8]>,
scalar: PassFatPointerAndRead<&[u8]>,
out: PassFatPointerAndWrite<&mut [u8]>,
) -> HostcallResult {
utils::mul_te::<ark_ed_on_bls12_381_bandersnatch::EdwardsConfig>(base, scalar, out)
}
fn ed_on_bls12_381_bandersnatch_msm_sw(
bases: PassFatPointerAndRead<&[u8]>,
scalars: PassFatPointerAndRead<&[u8]>,
out: PassFatPointerAndWrite<&mut [u8]>,
) -> HostcallResult {
utils::msm_sw::<ark_ed_on_bls12_381_bandersnatch::SWConfig>(bases, scalars, out)
}
fn ed_on_bls12_381_bandersnatch_mul_sw(
base: PassFatPointerAndRead<&[u8]>,
scalar: PassFatPointerAndRead<&[u8]>,
out: PassFatPointerAndWrite<&mut [u8]>,
) -> HostcallResult {
utils::mul_sw::<ark_ed_on_bls12_381_bandersnatch::SWConfig>(base, scalar, out)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::crypto_ec_utils::utils::testing::*;
#[test]
fn mul_works() {
mul_te_test::<EdwardsAffine, ark_ed_on_bls12_381_bandersnatch::EdwardsAffine>();
}
#[test]
fn msm_works() {
msm_te_test::<EdwardsAffine, ark_ed_on_bls12_381_bandersnatch::EdwardsAffine>();
}
#[test]
fn mul_works_sw() {
mul_test::<SWAffine, ark_ed_on_bls12_381_bandersnatch::SWAffine>();
}
#[test]
fn msm_works_sw() {
msm_test::<SWAffine, ark_ed_on_bls12_381_bandersnatch::SWAffine>();
}
}