revm_precompile/bls12_381/
map_fp_to_g1.rs1use super::utils::{pad_g1_point, remove_fp_padding};
3use crate::bls12_381_const::{MAP_FP_TO_G1_ADDRESS, MAP_FP_TO_G1_BASE_GAS_FEE, PADDED_FP_LENGTH};
4use crate::{
5 crypto, Precompile, PrecompileError, PrecompileId, PrecompileOutput, PrecompileResult,
6};
7
8pub const PRECOMPILE: Precompile = Precompile::new(
10 PrecompileId::Bls12MapFpToGp1,
11 MAP_FP_TO_G1_ADDRESS,
12 map_fp_to_g1,
13);
14
15pub fn map_fp_to_g1(input: &[u8], gas_limit: u64) -> PrecompileResult {
19 if MAP_FP_TO_G1_BASE_GAS_FEE > gas_limit {
20 return Err(PrecompileError::OutOfGas);
21 }
22
23 if input.len() != PADDED_FP_LENGTH {
24 return Err(PrecompileError::Bls12381MapFpToG1InputLength);
25 }
26
27 let input_p0 = remove_fp_padding(input)?;
28
29 let unpadded_result = crypto().bls12_381_fp_to_g1(input_p0)?;
30
31 let padded_result = pad_g1_point(&unpadded_result);
33
34 Ok(PrecompileOutput::new(
35 MAP_FP_TO_G1_BASE_GAS_FEE,
36 padded_result.into(),
37 ))
38}
39
40#[cfg(test)]
41mod test {
42 use super::*;
43 use primitives::{hex, Bytes};
44
45 #[test]
46 fn sanity_test() {
47 let input = Bytes::from(hex!("000000000000000000000000000000006900000000000000636f6e7472616374595a603f343061cd305a03f40239f5ffff31818185c136bc2595f2aa18e08f17"));
48 let fail = map_fp_to_g1(&input, MAP_FP_TO_G1_BASE_GAS_FEE);
49 assert_eq!(fail, Err(PrecompileError::NonCanonicalFp));
50 }
51}