revm_precompile/
id.rs

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