revm_precompile/bls12_381/
g2_add.rs1use super::g2::{encode_g2_point, extract_g2_input};
2use crate::bls12_381_const::{
3 G2_ADD_ADDRESS, G2_ADD_BASE_GAS_FEE, G2_ADD_INPUT_LENGTH, G2_INPUT_ITEM_LENGTH,
4};
5use crate::{u64_to_address, PrecompileWithAddress};
6use crate::{PrecompileError, PrecompileOutput, PrecompileResult};
7use blst::{
8 blst_p2, blst_p2_add_or_double_affine, blst_p2_affine, blst_p2_from_affine, blst_p2_to_affine,
9};
10use primitives::Bytes;
11
12pub const PRECOMPILE: PrecompileWithAddress =
14 PrecompileWithAddress(u64_to_address(G2_ADD_ADDRESS), g2_add);
15
16pub(super) fn g2_add(input: &Bytes, gas_limit: u64) -> PrecompileResult {
23 if G2_ADD_BASE_GAS_FEE > gas_limit {
24 return Err(PrecompileError::OutOfGas);
25 }
26
27 if input.len() != G2_ADD_INPUT_LENGTH {
28 return Err(PrecompileError::Other(format!(
29 "G2ADD input should be {G2_ADD_INPUT_LENGTH} bytes, was {}",
30 input.len()
31 )));
32 }
33
34 let a_aff = &extract_g2_input(&input[..G2_INPUT_ITEM_LENGTH], false)?;
38 let b_aff = &extract_g2_input(&input[G2_INPUT_ITEM_LENGTH..], false)?;
39
40 let mut b = blst_p2::default();
41 unsafe { blst_p2_from_affine(&mut b, b_aff) };
43
44 let mut p = blst_p2::default();
45 unsafe { blst_p2_add_or_double_affine(&mut p, &b, a_aff) };
47
48 let mut p_aff = blst_p2_affine::default();
49 unsafe { blst_p2_to_affine(&mut p_aff, &p) };
51
52 let out = encode_g2_point(&p_aff);
53 Ok(PrecompileOutput::new(G2_ADD_BASE_GAS_FEE, out))
54}