revm_precompile/bls12_381/
map_fp2_to_g2.rs1use super::{
2 crypto_backend::{encode_g2_point, map_fp2_to_g2 as blst_map_fp2_to_g2, read_fp2},
3 utils::remove_fp_padding,
4};
5use crate::bls12_381_const::{
6 MAP_FP2_TO_G2_ADDRESS, MAP_FP2_TO_G2_BASE_GAS_FEE, PADDED_FP2_LENGTH, PADDED_FP_LENGTH,
7};
8use crate::PrecompileWithAddress;
9use crate::{PrecompileError, PrecompileOutput, PrecompileResult};
10use primitives::Bytes;
11
12pub const PRECOMPILE: PrecompileWithAddress =
14 PrecompileWithAddress(MAP_FP2_TO_G2_ADDRESS, map_fp2_to_g2);
15
16pub(super) fn map_fp2_to_g2(input: &Bytes, gas_limit: u64) -> PrecompileResult {
21 if MAP_FP2_TO_G2_BASE_GAS_FEE > gas_limit {
22 return Err(PrecompileError::OutOfGas);
23 }
24
25 if input.len() != PADDED_FP2_LENGTH {
26 return Err(PrecompileError::Other(format!(
27 "MAP_FP2_TO_G2 input should be {PADDED_FP2_LENGTH} bytes, was {}",
28 input.len()
29 )));
30 }
31
32 let input_p0_x = remove_fp_padding(&input[..PADDED_FP_LENGTH])?;
33 let input_p0_y = remove_fp_padding(&input[PADDED_FP_LENGTH..PADDED_FP2_LENGTH])?;
34 let fp2 = read_fp2(input_p0_x, input_p0_y)?;
35 let p_aff = blst_map_fp2_to_g2(&fp2);
36
37 let out = encode_g2_point(&p_aff);
38 Ok(PrecompileOutput::new(
39 MAP_FP2_TO_G2_BASE_GAS_FEE,
40 out.into(),
41 ))
42}