aurora_engine_precompiles/bls12_381/
g2_add.rs

1use crate::prelude::{Borrowed, Vec};
2use crate::{EvmPrecompileResult, Precompile, PrecompileOutput};
3use aurora_engine_sdk::bls12_381;
4use aurora_engine_types::types::{make_address, Address, EthGas};
5use aurora_evm::{Context, ExitError};
6
7/// Base gas fee for BLS12-381 `g2_add` operation.
8const BASE_GAS_FEE: u64 = 600;
9
10/// Input length of `g2_add` operation.
11const INPUT_LENGTH: usize = 512;
12
13/// BLS12-381 G2 Add
14pub struct BlsG2Add;
15
16impl BlsG2Add {
17    pub const ADDRESS: Address = make_address(0, 0xD);
18
19    fn execute(input: &[u8]) -> Result<Vec<u8>, ExitError> {
20        bls12_381::g2_add(input).map_err(|e| ExitError::Other(Borrowed(e.as_ref())))
21    }
22}
23
24impl Precompile for BlsG2Add {
25    fn required_gas(_input: &[u8]) -> Result<EthGas, ExitError>
26    where
27        Self: Sized,
28    {
29        Ok(EthGas::new(BASE_GAS_FEE))
30    }
31
32    /// G2 addition call expects `512` bytes as an input that is interpreted as byte
33    /// concatenation of two G2 points (`256` bytes each).
34    ///
35    /// Output is an encoding of addition operation result - single G2 point (`256`
36    /// bytes).
37    /// See also <https://eips.ethereum.org/EIPS/eip-2537#abi-for-g2-addition>
38    fn run(
39        &self,
40        input: &[u8],
41        target_gas: Option<EthGas>,
42        _context: &Context,
43        _is_static: bool,
44    ) -> EvmPrecompileResult {
45        let cost = Self::required_gas(input)?;
46        if let Some(target_gas) = target_gas {
47            if cost > target_gas {
48                return Err(ExitError::OutOfGas);
49            }
50        }
51
52        if input.len() != INPUT_LENGTH {
53            return Err(ExitError::Other(Borrowed("ERR_BLS_G2ADD_INPUT_LEN")));
54        }
55
56        let output = Self::execute(input)?;
57        Ok(PrecompileOutput::without_logs(cost, output))
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use super::*;
64    use aurora_engine_types::H160;
65
66    #[test]
67    fn bls12_381_g2_add() {
68        let precompile = BlsG2Add;
69        let ctx = Context {
70            address: H160::zero(),
71            caller: H160::zero(),
72            apparent_value: 0.into(),
73        };
74        let input = hex::decode("\
75               00000000000000000000000000000000161c595d151a765c7dee03c9210414cdffab84b9078b4b98f9df09be5ec299b8f6322c692214f00ede97958f235c352b\
76			   00000000000000000000000000000000106883e0937cb869e579b513bde8f61020fcf26be38f8b98eae3885cedec2e028970415fc653cf10e64727b7f6232e06\
77			   000000000000000000000000000000000f351a82b733af31af453904874b7ca6252957a1ab51ec7f7b6fff85bbf3331f870a7e72a81594a9930859237e7a154d\
78			   0000000000000000000000000000000012fcf20d1750901f2cfed64fd362f010ee64fafe9ddab406cc352b65829b929881a50514d53247d1cca7d6995d0bc9b2\
79			   00000000000000000000000000000000148b7dfc21521d79ff817c7a0305f1048851e283be13c07d5c04d28b571d48172838399ba539529e8d037ffd1f729558\
80			   0000000000000000000000000000000003015abea326c15098f5205a8b2d3cd74d72dac59d60671ca6ef8c9c714ea61ffdacd46d1024b5b4f7e6b3b569fabaf2\
81			   0000000000000000000000000000000011f0c512fe7dc2dd8abdc1d22c2ecd2e7d1b84f8950ab90fc93bf54badf7bb9a9bad8c355d52a5efb110dca891e4cc3d\
82			   0000000000000000000000000000000019774010814d1d94caf3ecda3ef4f5c5986e966eaf187c32a8a5a4a59452af0849690cf71338193f2d8435819160bcfb")
83            .expect("hex decoding failed");
84
85        let res = precompile
86            .run(&input, None, &ctx, false)
87            .expect("precompile run should not fail");
88        let expected = hex::decode("\
89               000000000000000000000000000000000383ab7a17cc57e239e874af3f1aaabba0e64625b848676712f05f56132dbbd1cadfabeb3fe1f461daba3f1720057ddd\
90			   00000000000000000000000000000000096967e9b3747f1b8e344535eaa0c51e70bc77412bfaa2a7ce76f11f570c9febb8f4227316866a416a50436d098e6f9a\
91			   000000000000000000000000000000001079452b7519a7b090d668d54c266335b1cdd1080ed867dd17a2476b11c2617da829bf740e51cb7dfd60d73ed02c0c67\
92			   00000000000000000000000000000000015fc3a972e05cbd9014882cfe6f2f16d0291c403bf28b05056ac625e4f71dfb1295c85d73145ef554614e6eb2d5bf02")
93            .expect("hex decoding failed");
94
95        assert_eq!(res.output, expected);
96    }
97}