revm_precompile/bls12_381/
g2_add.rs1use super::crypto_backend::{encode_g2_point, p2_add_affine, read_g2_no_subgroup_check};
2use super::utils::remove_g2_padding;
3use crate::bls12_381_const::{
4 G2_ADD_ADDRESS, G2_ADD_BASE_GAS_FEE, G2_ADD_INPUT_LENGTH, PADDED_G2_LENGTH,
5};
6use crate::{PrecompileError, PrecompileOutput, PrecompileResult, PrecompileWithAddress};
7use primitives::Bytes;
8
9pub const PRECOMPILE: PrecompileWithAddress = PrecompileWithAddress(G2_ADD_ADDRESS, g2_add);
11
12pub(super) fn g2_add(input: &Bytes, gas_limit: u64) -> PrecompileResult {
19 if G2_ADD_BASE_GAS_FEE > gas_limit {
20 return Err(PrecompileError::OutOfGas);
21 }
22
23 if input.len() != G2_ADD_INPUT_LENGTH {
24 return Err(PrecompileError::Other(format!(
25 "G2ADD input should be {G2_ADD_INPUT_LENGTH} bytes, was {}",
26 input.len()
27 )));
28 }
29
30 let [a_x_0, a_x_1, a_y_0, a_y_1] = remove_g2_padding(&input[..PADDED_G2_LENGTH])?;
31 let [b_x_0, b_x_1, b_y_0, b_y_1] = remove_g2_padding(&input[PADDED_G2_LENGTH..])?;
32
33 let a_aff = &read_g2_no_subgroup_check(a_x_0, a_x_1, a_y_0, a_y_1)?;
38 let b_aff = &read_g2_no_subgroup_check(b_x_0, b_x_1, b_y_0, b_y_1)?;
39
40 let p_aff = p2_add_affine(a_aff, b_aff);
42
43 let out = encode_g2_point(&p_aff);
44 Ok(PrecompileOutput::new(G2_ADD_BASE_GAS_FEE, out.into()))
45}