revm_precompile/bls12_381/
g1_add.rs1use super::g1::{encode_g1_point, extract_g1_input};
2use crate::bls12_381_const::{
3 G1_ADD_ADDRESS, G1_ADD_BASE_GAS_FEE, G1_ADD_INPUT_LENGTH, G1_INPUT_ITEM_LENGTH,
4};
5use crate::{u64_to_address, PrecompileWithAddress};
6use crate::{PrecompileError, PrecompileOutput, PrecompileResult};
7use blst::{
8 blst_p1, blst_p1_add_or_double_affine, blst_p1_affine, blst_p1_from_affine, blst_p1_to_affine,
9};
10use primitives::Bytes;
11
12pub const PRECOMPILE: PrecompileWithAddress =
14 PrecompileWithAddress(u64_to_address(G1_ADD_ADDRESS), g1_add);
15
16pub(super) fn g1_add(input: &Bytes, gas_limit: u64) -> PrecompileResult {
22 if G1_ADD_BASE_GAS_FEE > gas_limit {
23 return Err(PrecompileError::OutOfGas);
24 }
25
26 if input.len() != G1_ADD_INPUT_LENGTH {
27 return Err(PrecompileError::Other(format!(
28 "G1ADD input should be {G1_ADD_INPUT_LENGTH} bytes, was {}",
29 input.len()
30 )));
31 }
32
33 let a_aff = &extract_g1_input(&input[..G1_INPUT_ITEM_LENGTH], false)?;
37 let b_aff = &extract_g1_input(&input[G1_INPUT_ITEM_LENGTH..], false)?;
38
39 let mut b = blst_p1::default();
40 unsafe { blst_p1_from_affine(&mut b, b_aff) };
42
43 let mut p = blst_p1::default();
44 unsafe { blst_p1_add_or_double_affine(&mut p, &b, a_aff) };
46
47 let mut p_aff = blst_p1_affine::default();
48 unsafe { blst_p1_to_affine(&mut p_aff, &p) };
50
51 let out = encode_g1_point(&p_aff);
52 Ok(PrecompileOutput::new(G1_ADD_BASE_GAS_FEE, out))
53}