revm_precompile/
id.rs

1use std::borrow::Cow;
2use std::fmt;
3
4use primitives::{address, Address};
5
6use crate::{Precompile, PrecompileSpecId};
7
8/// Precompile with address and function.
9/// Unique precompile identifier.
10#[derive(Clone, Debug, PartialEq, Eq, Hash)]
11pub enum PrecompileId {
12    /// Elliptic curve digital signature algorithm (ECDSA) public key recovery function.
13    EcRec,
14    /// SHA2-256 hash function.
15    Sha256,
16    /// RIPEMD-160 hash function.
17    Ripemd160,
18    /// Identity precompile.
19    Identity,
20    /// Arbitrary-precision exponentiation under modulo.
21    ModExp,
22    /// Point addition (ADD) on the elliptic curve 'alt_bn128'.
23    Bn254Add,
24    /// Scalar multiplication (MUL) on the elliptic curve 'alt_bn128'.
25    Bn254Mul,
26    /// Bilinear function on groups on the elliptic curve 'alt_bn128'.
27    Bn254Pairing,
28    /// Compression function F used in the BLAKE2 cryptographic hashing algorithm.
29    Blake2F,
30    /// 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.
31    KzgPointEvaluation,
32    /// Point addition in G1 (curve over base prime field).
33    Bls12G1Add,
34    /// Multi-scalar-multiplication (MSM) in G1 (curve over base prime field).
35    Bls12G1Msm,
36    /// Point addition in G2 (curve over quadratic extension of the base prime field).
37    Bls12G2Add,
38    /// Multi-scalar-multiplication (MSM) in G2 (curve over quadratic extension of the base prime field).
39    Bls12G2Msm,
40    /// Pairing operations between a set of pairs of (G1, G2) points.
41    Bls12Pairing,
42    /// Base field element mapping into the G1 point.
43    Bls12MapFpToGp1,
44    /// Extension field element mapping into the G2 point.
45    Bls12MapFp2ToGp2,
46    /// ECDSA signature verification over the secp256r1 elliptic curve (also known as P-256 or prime256v1).
47    P256Verify,
48    /// Custom precompile identifier.
49    Custom(Cow<'static, str>),
50}
51
52impl PrecompileId {
53    /// Create new custom precompile ID.
54    pub fn custom<I>(id: I) -> Self
55    where
56        I: Into<Cow<'static, str>>,
57    {
58        Self::Custom(id.into())
59    }
60
61    /// Returns the mainnet address for the precompile.
62    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    /// Returns the name of the precompile as defined in EIP-7910.
88    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    /// Returns the precompile function for the given spec.
113    ///
114    /// If case of [`PrecompileId::Custom`] it will return [`None`].
115    ///
116    /// For case where precompile was still not introduced in the spec,
117    /// it will return [`Some`] with fork closest to activation.
118    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                // ModExp changes gas calculation based on spec
128                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                // BN254 add - gas cost changes in Istanbul
138                if spec < ISTANBUL {
139                    crate::bn254::add::BYZANTIUM
140                } else {
141                    crate::bn254::add::ISTANBUL
142                }
143            }
144            Self::Bn254Mul => {
145                // BN254 mul - gas cost changes in Istanbul
146                if spec < ISTANBUL {
147                    crate::bn254::mul::BYZANTIUM
148                } else {
149                    crate::bn254::mul::ISTANBUL
150                }
151            }
152            Self::Bn254Pairing => {
153                // BN254 pairing - gas cost changes in Istanbul
154                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                // P256 verify - gas cost changes in Osaka
171                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}