1use std::borrow::Cow;
2use std::fmt;
3
4use primitives::{address, Address};
5
6use crate::{Precompile, PrecompileSpecId};
7
8#[derive(Clone, Debug, PartialEq, Eq, Hash)]
11pub enum PrecompileId {
12 EcRec,
14 Sha256,
16 Ripemd160,
18 Identity,
20 ModExp,
22 Bn254Add,
24 Bn254Mul,
26 Bn254Pairing,
28 Blake2F,
30 KzgPointEvaluation,
32 Bls12G1Add,
34 Bls12G1Msm,
36 Bls12G2Add,
38 Bls12G2Msm,
40 Bls12Pairing,
42 Bls12MapFpToGp1,
44 Bls12MapFp2ToGp2,
46 P256Verify,
48 Custom(Cow<'static, str>),
50}
51
52impl PrecompileId {
53 pub fn custom<I>(id: I) -> Self
55 where
56 I: Into<Cow<'static, str>>,
57 {
58 Self::Custom(id.into())
59 }
60
61 pub fn mainnet_address(&self) -> Option<Address> {
63 let address = match self {
64 Self::EcRec => address!("0x0000000000000000000000000000000000000001"),
65 Self::Sha256 => address!("0x0000000000000000000000000000000000000002"),
66 Self::Ripemd160 => address!("0x0000000000000000000000000000000000000003"),
67 Self::Identity => address!("0x0000000000000000000000000000000000000004"),
68 Self::ModExp => address!("0x0000000000000000000000000000000000000005"),
69 Self::Bn254Add => address!("0x0000000000000000000000000000000000000006"),
70 Self::Bn254Mul => address!("0x0000000000000000000000000000000000000007"),
71 Self::Bn254Pairing => address!("0x0000000000000000000000000000000000000008"),
72 Self::Blake2F => address!("0x0000000000000000000000000000000000000009"),
73 Self::KzgPointEvaluation => address!("0x000000000000000000000000000000000000000A"),
74 Self::Bls12G1Add => address!("0x000000000000000000000000000000000000000B"),
75 Self::Bls12G1Msm => address!("0x000000000000000000000000000000000000000C"),
76 Self::Bls12G2Add => address!("0x000000000000000000000000000000000000000D"),
77 Self::Bls12G2Msm => address!("0x000000000000000000000000000000000000000E"),
78 Self::Bls12Pairing => address!("0x000000000000000000000000000000000000000F"),
79 Self::Bls12MapFpToGp1 => address!("0x0000000000000000000000000000000000000010"),
80 Self::Bls12MapFp2ToGp2 => address!("0x0000000000000000000000000000000000000011"),
81 Self::P256Verify => address!("0x0000000000000000000000000000000000000012"),
82 Self::Custom(_) => return None,
83 };
84 Some(address)
85 }
86
87 pub fn name(&self) -> &str {
89 match self {
90 Self::EcRec => "ECREC",
91 Self::Sha256 => "SHA256",
92 Self::Ripemd160 => "RIPEMD160",
93 Self::Identity => "ID",
94 Self::ModExp => "MODEXP",
95 Self::Bn254Add => "BN254_ADD",
96 Self::Bn254Mul => "BN254_MUL",
97 Self::Bn254Pairing => "BN254_PAIRING",
98 Self::Blake2F => "BLAKE2F",
99 Self::KzgPointEvaluation => "KZG_POINT_EVALUATION",
100 Self::Bls12G1Add => "BLS12_G1ADD",
101 Self::Bls12G1Msm => "BLS12_G1MSM",
102 Self::Bls12G2Add => "BLS12_G2ADD",
103 Self::Bls12G2Msm => "BLS12_G2MSM",
104 Self::Bls12Pairing => "BLS12_PAIRING_CHECK",
105 Self::Bls12MapFpToGp1 => "BLS12_MAP_FP_TO_G1",
106 Self::Bls12MapFp2ToGp2 => "BLS12_MAP_FP2_TO_G2",
107 Self::P256Verify => "P256VERIFY",
108 Self::Custom(a) => a.as_ref(),
109 }
110 }
111
112 pub fn precompile(&self, spec: PrecompileSpecId) -> Option<Precompile> {
119 use PrecompileSpecId::*;
120
121 let precompile = match self {
122 Self::EcRec => crate::secp256k1::ECRECOVER,
123 Self::Sha256 => crate::hash::SHA256,
124 Self::Ripemd160 => crate::hash::RIPEMD160,
125 Self::Identity => crate::identity::FUN,
126 Self::ModExp => {
127 if spec < BERLIN {
129 crate::modexp::BYZANTIUM
130 } else if spec < OSAKA {
131 crate::modexp::BERLIN
132 } else {
133 crate::modexp::OSAKA
134 }
135 }
136 Self::Bn254Add => {
137 if spec < ISTANBUL {
139 crate::bn254::add::BYZANTIUM
140 } else {
141 crate::bn254::add::ISTANBUL
142 }
143 }
144 Self::Bn254Mul => {
145 if spec < ISTANBUL {
147 crate::bn254::mul::BYZANTIUM
148 } else {
149 crate::bn254::mul::ISTANBUL
150 }
151 }
152 Self::Bn254Pairing => {
153 if spec < ISTANBUL {
155 crate::bn254::pair::BYZANTIUM
156 } else {
157 crate::bn254::pair::ISTANBUL
158 }
159 }
160 Self::Blake2F => crate::blake2::FUN,
161 Self::KzgPointEvaluation => crate::kzg_point_evaluation::POINT_EVALUATION,
162 Self::Bls12G1Add => crate::bls12_381::g1_add::PRECOMPILE,
163 Self::Bls12G1Msm => crate::bls12_381::g1_msm::PRECOMPILE,
164 Self::Bls12G2Add => crate::bls12_381::g2_add::PRECOMPILE,
165 Self::Bls12G2Msm => crate::bls12_381::g2_msm::PRECOMPILE,
166 Self::Bls12Pairing => crate::bls12_381::pairing::PRECOMPILE,
167 Self::Bls12MapFpToGp1 => crate::bls12_381::map_fp_to_g1::PRECOMPILE,
168 Self::Bls12MapFp2ToGp2 => crate::bls12_381::map_fp2_to_g2::PRECOMPILE,
169 Self::P256Verify => {
170 if spec < OSAKA {
172 crate::secp256r1::P256VERIFY
173 } else {
174 crate::secp256r1::P256VERIFY_OSAKA
175 }
176 }
177 Self::Custom(_) => return None,
178 };
179
180 Some(precompile)
181 }
182}
183
184impl fmt::Display for PrecompileId {
185 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
186 f.write_str(self.name())
187 }
188}