revm_precompile/bls12_381/
map_fp2_to_g2.rsuse super::{
g2::check_canonical_fp2,
g2::encode_g2_point,
utils::{remove_padding, PADDED_FP2_LENGTH, PADDED_FP_LENGTH},
};
use crate::{u64_to_address, PrecompileWithAddress};
use crate::{Precompile, PrecompileError, PrecompileOutput, PrecompileResult};
use blst::{blst_map_to_g2, blst_p2, blst_p2_affine, blst_p2_to_affine};
use primitives::Bytes;
pub const PRECOMPILE: PrecompileWithAddress =
PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(map_fp2_to_g2));
pub const ADDRESS: u64 = 0x13;
const BASE_GAS_FEE: u64 = 75000;
pub(super) fn map_fp2_to_g2(input: &Bytes, gas_limit: u64) -> PrecompileResult {
if BASE_GAS_FEE > gas_limit {
return Err(PrecompileError::OutOfGas.into());
}
if input.len() != PADDED_FP2_LENGTH {
return Err(PrecompileError::Other(format!(
"MAP_FP2_TO_G2 input should be {PADDED_FP2_LENGTH} bytes, was {}",
input.len()
))
.into());
}
let input_p0_x = remove_padding(&input[..PADDED_FP_LENGTH])?;
let input_p0_y = remove_padding(&input[PADDED_FP_LENGTH..PADDED_FP2_LENGTH])?;
let fp2 = check_canonical_fp2(input_p0_x, input_p0_y)?;
let mut p = blst_p2::default();
unsafe { blst_map_to_g2(&mut p, &fp2, core::ptr::null()) };
let mut p_aff = blst_p2_affine::default();
unsafe { blst_p2_to_affine(&mut p_aff, &p) };
let out = encode_g2_point(&p_aff);
Ok(PrecompileOutput::new(BASE_GAS_FEE, out))
}