revm_precompile/bls12_381/
g2_add.rs1use super::utils::{pad_g2_point, remove_g2_padding};
3use crate::{
4 bls12_381_const::{G2_ADD_ADDRESS, G2_ADD_BASE_GAS_FEE, G2_ADD_INPUT_LENGTH, PADDED_G2_LENGTH},
5 crypto, eth_precompile_fn, EthPrecompileOutput, EthPrecompileResult, Precompile,
6 PrecompileHalt, PrecompileId,
7};
8
9eth_precompile_fn!(g2_add_precompile, g2_add);
10
11pub const PRECOMPILE: Precompile =
13 Precompile::new(PrecompileId::Bls12G2Add, G2_ADD_ADDRESS, g2_add_precompile);
14
15pub fn g2_add(input: &[u8], gas_limit: u64) -> EthPrecompileResult {
22 if G2_ADD_BASE_GAS_FEE > gas_limit {
23 return Err(PrecompileHalt::OutOfGas);
24 }
25
26 if input.len() != G2_ADD_INPUT_LENGTH {
27 return Err(PrecompileHalt::Bls12381G2AddInputLength);
28 }
29
30 let [a_x_0, a_x_1, a_y_0, a_y_1] = remove_g2_padding(&input[..PADDED_G2_LENGTH])?;
32 let [b_x_0, b_x_1, b_y_0, b_y_1] = remove_g2_padding(&input[PADDED_G2_LENGTH..])?;
33
34 let a = (*a_x_0, *a_x_1, *a_y_0, *a_y_1);
35 let b = (*b_x_0, *b_x_1, *b_y_0, *b_y_1);
36
37 let unpadded_result = crypto().bls12_381_g2_add(a, b)?;
38
39 let padded_result = pad_g2_point(&unpadded_result);
41
42 Ok(EthPrecompileOutput::new(
43 G2_ADD_BASE_GAS_FEE,
44 padded_result.into(),
45 ))
46}