revm_precompile/bls12_381/
map_fp2_to_g2.rs

1use super::{g2::check_canonical_fp2, g2::encode_g2_point, utils::remove_padding};
2use crate::bls12_381_const::{
3    MAP_FP2_TO_G2_ADDRESS, MAP_FP2_TO_G2_BASE_GAS_FEE, PADDED_FP2_LENGTH, PADDED_FP_LENGTH,
4};
5use crate::{u64_to_address, PrecompileWithAddress};
6use crate::{PrecompileError, PrecompileOutput, PrecompileResult};
7use blst::{blst_map_to_g2, blst_p2, blst_p2_affine, blst_p2_to_affine};
8use primitives::Bytes;
9
10/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_MAP_FP2_TO_G2 precompile.
11pub const PRECOMPILE: PrecompileWithAddress =
12    PrecompileWithAddress(u64_to_address(MAP_FP2_TO_G2_ADDRESS), map_fp2_to_g2);
13
14/// Field-to-curve call expects 128 bytes as an input that is interpreted as
15/// an element of Fp2. Output of this call is 256 bytes and is an encoded G2
16/// point.
17/// See also: <https://eips.ethereum.org/EIPS/eip-2537#abi-for-mapping-fp2-element-to-g2-point>
18pub(super) fn map_fp2_to_g2(input: &Bytes, gas_limit: u64) -> PrecompileResult {
19    if MAP_FP2_TO_G2_BASE_GAS_FEE > gas_limit {
20        return Err(PrecompileError::OutOfGas);
21    }
22
23    if input.len() != PADDED_FP2_LENGTH {
24        return Err(PrecompileError::Other(format!(
25            "MAP_FP2_TO_G2 input should be {PADDED_FP2_LENGTH} bytes, was {}",
26            input.len()
27        )));
28    }
29
30    let input_p0_x = remove_padding(&input[..PADDED_FP_LENGTH])?;
31    let input_p0_y = remove_padding(&input[PADDED_FP_LENGTH..PADDED_FP2_LENGTH])?;
32    let fp2 = check_canonical_fp2(input_p0_x, input_p0_y)?;
33
34    let mut p = blst_p2::default();
35    // SAFETY: `p` and `fp2` are blst values.
36    // Third argument is unused if null.
37    unsafe { blst_map_to_g2(&mut p, &fp2, core::ptr::null()) };
38
39    let mut p_aff = blst_p2_affine::default();
40    // SAFETY: `p_aff` and `p` are blst values.
41    unsafe { blst_p2_to_affine(&mut p_aff, &p) };
42
43    let out = encode_g2_point(&p_aff);
44    Ok(PrecompileOutput::new(MAP_FP2_TO_G2_BASE_GAS_FEE, out))
45}