revm_precompile/id.rs
1use std::borrow::Cow;
2use std::fmt;
3
4use crate::{Precompile, PrecompileSpecId};
5
6/// Precompile with address and function.
7/// Unique precompile identifier.
8#[derive(Clone, Debug, PartialEq, Eq, Hash)]
9pub enum PrecompileId {
10 /// Elliptic curve digital signature algorithm (ECDSA) public key recovery function.
11 EcRec,
12 /// SHA2-256 hash function.
13 Sha256,
14 /// RIPEMD-160 hash function.
15 Ripemd160,
16 /// Identity precompile.
17 Identity,
18 /// Arbitrary-precision exponentiation under modulo.
19 ModExp,
20 /// Point addition (ADD) on the elliptic curve 'alt_bn128'.
21 Bn254Add,
22 /// Scalar multiplication (MUL) on the elliptic curve 'alt_bn128'.
23 Bn254Mul,
24 /// Bilinear function on groups on the elliptic curve 'alt_bn128'.
25 Bn254Pairing,
26 /// Compression function F used in the BLAKE2 cryptographic hashing algorithm.
27 Blake2F,
28 /// Verify p(z) = y given commitment that corresponds to the polynomial p(x) and a KZG proof. Also verify that the provided commitment matches the provided versioned_hash.
29 KzgPointEvaluation,
30 /// Point addition in G1 (curve over base prime field).
31 Bls12G1Add,
32 /// Multi-scalar-multiplication (MSM) in G1 (curve over base prime field).
33 Bls12G1Msm,
34 /// Point addition in G2 (curve over quadratic extension of the base prime field).
35 Bls12G2Add,
36 /// Multi-scalar-multiplication (MSM) in G2 (curve over quadratic extension of the base prime field).
37 Bls12G2Msm,
38 /// Pairing operations between a set of pairs of (G1, G2) points.
39 Bls12Pairing,
40 /// Base field element mapping into the G1 point.
41 Bls12MapFpToGp1,
42 /// Extension field element mapping into the G2 point.
43 Bls12MapFp2ToGp2,
44 /// ECDSA signature verification over the secp256r1 elliptic curve (also known as P-256 or prime256v1).
45 P256Verify,
46 /// Custom precompile identifier.
47 Custom(Cow<'static, str>),
48}
49
50impl PrecompileId {
51 /// Create new custom precompile ID.
52 pub fn custom<I>(id: I) -> Self
53 where
54 I: Into<Cow<'static, str>>,
55 {
56 Self::Custom(id.into())
57 }
58
59 /// Returns the name of the precompile as defined in EIP-7910.
60 pub fn name(&self) -> &str {
61 match self {
62 Self::EcRec => "ECREC",
63 Self::Sha256 => "SHA256",
64 Self::Ripemd160 => "RIPEMD160",
65 Self::Identity => "ID",
66 Self::ModExp => "MODEXP",
67 Self::Bn254Add => "BN254_ADD",
68 Self::Bn254Mul => "BN254_MUL",
69 Self::Bn254Pairing => "BN254_PAIRING",
70 Self::Blake2F => "BLAKE2F",
71 Self::KzgPointEvaluation => "KZG_POINT_EVALUATION",
72 Self::Bls12G1Add => "BLS12_G1ADD",
73 Self::Bls12G1Msm => "BLS12_G1MSM",
74 Self::Bls12G2Add => "BLS12_G2ADD",
75 Self::Bls12G2Msm => "BLS12_G2MSM",
76 Self::Bls12Pairing => "BLS12_PAIRING_CHECK",
77 Self::Bls12MapFpToGp1 => "BLS12_MAP_FP_TO_G1",
78 Self::Bls12MapFp2ToGp2 => "BLS12_MAP_FP2_TO_G2",
79 Self::P256Verify => "P256VERIFY",
80 Self::Custom(a) => a.as_ref(),
81 }
82 }
83
84 /// Returns the precompile function for the given spec.
85 ///
86 /// If case of [`PrecompileId::Custom`] it will return [`None`].
87 ///
88 /// For case where precompile was still not introduced in the spec,
89 /// it will return [`Some`] with fork closest to activation.
90 pub fn precompile(&self, spec: PrecompileSpecId) -> Option<Precompile> {
91 use PrecompileSpecId::*;
92
93 let precompile = match self {
94 Self::EcRec => crate::secp256k1::ECRECOVER,
95 Self::Sha256 => crate::hash::SHA256,
96 Self::Ripemd160 => crate::hash::RIPEMD160,
97 Self::Identity => crate::identity::FUN,
98 Self::ModExp => {
99 // ModExp changes gas calculation based on spec
100 if spec < BERLIN {
101 crate::modexp::BYZANTIUM
102 } else if spec < OSAKA {
103 crate::modexp::BERLIN
104 } else {
105 crate::modexp::OSAKA
106 }
107 }
108 Self::Bn254Add => {
109 // BN254 add - gas cost changes in Istanbul
110 if spec < ISTANBUL {
111 crate::bn254::add::BYZANTIUM
112 } else {
113 crate::bn254::add::ISTANBUL
114 }
115 }
116 Self::Bn254Mul => {
117 // BN254 mul - gas cost changes in Istanbul
118 if spec < ISTANBUL {
119 crate::bn254::mul::BYZANTIUM
120 } else {
121 crate::bn254::mul::ISTANBUL
122 }
123 }
124 Self::Bn254Pairing => {
125 // BN254 pairing - gas cost changes in Istanbul
126 if spec < ISTANBUL {
127 crate::bn254::pair::BYZANTIUM
128 } else {
129 crate::bn254::pair::ISTANBUL
130 }
131 }
132 Self::Blake2F => crate::blake2::FUN,
133 Self::KzgPointEvaluation => crate::kzg_point_evaluation::POINT_EVALUATION,
134 Self::Bls12G1Add => crate::bls12_381::g1_add::PRECOMPILE,
135 Self::Bls12G1Msm => crate::bls12_381::g1_msm::PRECOMPILE,
136 Self::Bls12G2Add => crate::bls12_381::g2_add::PRECOMPILE,
137 Self::Bls12G2Msm => crate::bls12_381::g2_msm::PRECOMPILE,
138 Self::Bls12Pairing => crate::bls12_381::pairing::PRECOMPILE,
139 Self::Bls12MapFpToGp1 => crate::bls12_381::map_fp_to_g1::PRECOMPILE,
140 Self::Bls12MapFp2ToGp2 => crate::bls12_381::map_fp2_to_g2::PRECOMPILE,
141 Self::P256Verify => {
142 // P256 verify - gas cost changes in Osaka
143 if spec < OSAKA {
144 crate::secp256r1::P256VERIFY
145 } else {
146 crate::secp256r1::P256VERIFY_OSAKA
147 }
148 }
149 Self::Custom(_) => return None,
150 };
151
152 Some(precompile)
153 }
154}
155
156impl fmt::Display for PrecompileId {
157 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
158 f.write_str(self.name())
159 }
160}