aurora_engine_precompiles/bls12_381/
g2_add.rs

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