1use std::borrow::Cow;
2
3use primitives::{address, Address};
4
5use crate::{Precompile, PrecompileSpecId};
6
7#[derive(Clone, Debug, PartialEq, Eq, Hash)]
10pub enum PrecompileId {
11 EcRec,
13 Sha256,
15 Ripemd160,
17 Identity,
19 ModExp,
21 Bn254Add,
23 Bn254Mul,
25 Bn254Pairing,
27 Blake2F,
29 KzgPointEvaluation,
31 Bls12G1Add,
33 Bls12G1Msm,
35 Bls12G2Add,
37 Bls12G2Msm,
39 Bls12Pairing,
41 Bls12MapFpToGp1,
43 Bls12MapFp2ToGp2,
45 P256Verify,
47 Custom(Cow<'static, str>),
49}
50
51impl PrecompileId {
52 pub fn custom<I>(id: I) -> Self
54 where
55 I: Into<Cow<'static, str>>,
56 {
57 Self::Custom(id.into())
58 }
59
60 pub fn mainnet_address(&self) -> Option<Address> {
62 let address = match self {
63 Self::EcRec => address!("0x0000000000000000000000000000000000000001"),
64 Self::Sha256 => address!("0x0000000000000000000000000000000000000002"),
65 Self::Ripemd160 => address!("0x0000000000000000000000000000000000000003"),
66 Self::Identity => address!("0x0000000000000000000000000000000000000004"),
67 Self::ModExp => address!("0x0000000000000000000000000000000000000005"),
68 Self::Bn254Add => address!("0x0000000000000000000000000000000000000006"),
69 Self::Bn254Mul => address!("0x0000000000000000000000000000000000000007"),
70 Self::Bn254Pairing => address!("0x0000000000000000000000000000000000000008"),
71 Self::Blake2F => address!("0x0000000000000000000000000000000000000009"),
72 Self::KzgPointEvaluation => address!("0x000000000000000000000000000000000000000A"),
73 Self::Bls12G1Add => address!("0x000000000000000000000000000000000000000B"),
74 Self::Bls12G1Msm => address!("0x000000000000000000000000000000000000000C"),
75 Self::Bls12G2Add => address!("0x000000000000000000000000000000000000000D"),
76 Self::Bls12G2Msm => address!("0x000000000000000000000000000000000000000E"),
77 Self::Bls12Pairing => address!("0x000000000000000000000000000000000000000F"),
78 Self::Bls12MapFpToGp1 => address!("0x0000000000000000000000000000000000000010"),
79 Self::Bls12MapFp2ToGp2 => address!("0x0000000000000000000000000000000000000011"),
80 Self::P256Verify => address!("0x0000000000000000000000000000000000000012"),
81 Self::Custom(_) => return None,
82 };
83 Some(address)
84 }
85
86 pub fn name(&self) -> &str {
88 match self {
89 Self::EcRec => "ECREC",
90 Self::Sha256 => "SHA256",
91 Self::Ripemd160 => "RIPEMD160",
92 Self::Identity => "ID",
93 Self::ModExp => "MODEXP",
94 Self::Bn254Add => "BN254_ADD",
95 Self::Bn254Mul => "BN254_MUL",
96 Self::Bn254Pairing => "BN254_PAIRING",
97 Self::Blake2F => "BLAKE2F",
98 Self::KzgPointEvaluation => "KZG_POINT_EVALUATION",
99 Self::Bls12G1Add => "BLS12_G1ADD",
100 Self::Bls12G1Msm => "BLS12_G1MSM",
101 Self::Bls12G2Add => "BLS12_G2ADD",
102 Self::Bls12G2Msm => "BLS12_G2MSM",
103 Self::Bls12Pairing => "BLS12_PAIRING_CHECK",
104 Self::Bls12MapFpToGp1 => "BLS12_MAP_FP_TO_G1",
105 Self::Bls12MapFp2ToGp2 => "BLS12_MAP_FP2_TO_G2",
106 Self::P256Verify => "P256VERIFY",
107 Self::Custom(a) => a.as_ref(),
108 }
109 }
110
111 pub fn precompile(&self, spec: PrecompileSpecId) -> Option<Precompile> {
118 use PrecompileSpecId::*;
119
120 let precompile = match self {
121 Self::EcRec => crate::secp256k1::ECRECOVER,
122 Self::Sha256 => crate::hash::SHA256,
123 Self::Ripemd160 => crate::hash::RIPEMD160,
124 Self::Identity => crate::identity::FUN,
125 Self::ModExp => {
126 if spec < BERLIN {
128 crate::modexp::BYZANTIUM
129 } else if spec < OSAKA {
130 crate::modexp::BERLIN
131 } else {
132 crate::modexp::OSAKA
133 }
134 }
135 Self::Bn254Add => {
136 if spec < ISTANBUL {
138 crate::bn254::add::BYZANTIUM
139 } else {
140 crate::bn254::add::ISTANBUL
141 }
142 }
143 Self::Bn254Mul => {
144 if spec < ISTANBUL {
146 crate::bn254::mul::BYZANTIUM
147 } else {
148 crate::bn254::mul::ISTANBUL
149 }
150 }
151 Self::Bn254Pairing => {
152 if spec < ISTANBUL {
154 crate::bn254::pair::BYZANTIUM
155 } else {
156 crate::bn254::pair::ISTANBUL
157 }
158 }
159 Self::Blake2F => crate::blake2::FUN,
160 Self::KzgPointEvaluation => crate::kzg_point_evaluation::POINT_EVALUATION,
161 Self::Bls12G1Add => crate::bls12_381::g1_add::PRECOMPILE,
162 Self::Bls12G1Msm => crate::bls12_381::g1_msm::PRECOMPILE,
163 Self::Bls12G2Add => crate::bls12_381::g2_add::PRECOMPILE,
164 Self::Bls12G2Msm => crate::bls12_381::g2_msm::PRECOMPILE,
165 Self::Bls12Pairing => crate::bls12_381::pairing::PRECOMPILE,
166 Self::Bls12MapFpToGp1 => crate::bls12_381::map_fp_to_g1::PRECOMPILE,
167 Self::Bls12MapFp2ToGp2 => crate::bls12_381::map_fp2_to_g2::PRECOMPILE,
168 Self::P256Verify => {
169 if spec < OSAKA {
171 crate::secp256r1::P256VERIFY
172 } else {
173 crate::secp256r1::P256VERIFY_OSAKA
174 }
175 }
176 Self::Custom(_) => return None,
177 };
178
179 Some(precompile)
180 }
181}