1use precompile::{
2 bn128, {PrecompileError, PrecompileResult, PrecompileWithAddress},
3};
4
5pub mod pair {
6 use super::*;
7
8 pub const GRANITE_MAX_INPUT_SIZE: usize = 112687;
9 pub const GRANITE: PrecompileWithAddress =
10 PrecompileWithAddress(bn128::pair::ADDRESS, |input, gas_limit| {
11 run_pair(input, gas_limit)
12 });
13
14 pub fn run_pair(input: &[u8], gas_limit: u64) -> PrecompileResult {
15 if input.len() > GRANITE_MAX_INPUT_SIZE {
16 return Err(PrecompileError::Bn128PairLength);
17 }
18 bn128::run_pair(
19 input,
20 bn128::pair::ISTANBUL_PAIR_PER_POINT,
21 bn128::pair::ISTANBUL_PAIR_BASE,
22 gas_limit,
23 )
24 }
25}
26
27#[cfg(test)]
28mod tests {
29 use super::*;
30 use revm::{precompile::PrecompileError, primitives::hex};
31 use std::vec;
32
33 #[test]
34 fn test_bn128_pair() {
35 let input = hex::decode(
36 "\
37 1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f59\
38 3034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41\
39 209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf7\
40 04bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a41678\
41 2bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d\
42 120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550\
43 111e129f1cf1097710d41c4ac70fcdfa5ba2023c6ff1cbeac322de49d1b6df7c\
44 2032c61a830e3c17286de9462bf242fca2883585b93870a73853face6a6bf411\
45 198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2\
46 1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed\
47 090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b\
48 12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa",
49 )
50 .unwrap();
51 let expected =
52 hex::decode("0000000000000000000000000000000000000000000000000000000000000001")
53 .unwrap();
54 let outcome = pair::run_pair(&input, 260_000).unwrap();
55 assert_eq!(outcome.bytes, expected);
56
57 let input = hex::decode(
59 "\
60 1111111111111111111111111111111111111111111111111111111111111111\
61 1111111111111111111111111111111111111111111111111111111111111111\
62 111111111111111111111111111111\
63 ",
64 )
65 .unwrap();
66
67 let res = pair::run_pair(&input, 260_000);
68 assert!(matches!(res, Err(PrecompileError::Bn128PairLength)));
69
70 let input = vec![1u8; 586 * bn128::PAIR_ELEMENT_LEN];
72 let res = pair::run_pair(&input, 260_000);
73 assert!(matches!(res, Err(PrecompileError::OutOfGas)));
74
75 let input = vec![1u8; 587 * bn128::PAIR_ELEMENT_LEN];
77 let res = pair::run_pair(&input, 260_000);
78 assert!(matches!(res, Err(PrecompileError::Bn128PairLength)));
79 }
80}