|
1 | 1 | const std = @import("std"); |
2 | 2 | const primitives = @import("primitives"); |
3 | 3 |
|
| 4 | +// Import precompile modules (needed for PrecompileId.precompile method) |
| 5 | +pub const identity = @import("identity.zig"); |
| 6 | +pub const hash = @import("hash.zig"); |
| 7 | +pub const secp256k1 = @import("secp256k1.zig"); |
| 8 | +pub const secp256r1 = @import("secp256r1.zig"); |
| 9 | +pub const modexp = @import("modexp.zig"); |
| 10 | +pub const bn254 = @import("bn254.zig"); |
| 11 | +pub const blake2 = @import("blake2.zig"); |
| 12 | +pub const kzg_point_evaluation = @import("kzg_point_evaluation.zig"); |
| 13 | +pub const bls12_381 = @import("bls12_381.zig"); |
| 14 | + |
4 | 15 | /// Precompile error type |
5 | 16 | pub const PrecompileError = error{ |
6 | 17 | OutOfGas, |
@@ -71,7 +82,7 @@ pub const PrecompileOutput = struct { |
71 | 82 | pub const PrecompileFn = *const fn (input: []const u8, gas_limit: u64) PrecompileResult; |
72 | 83 |
|
73 | 84 | /// Precompile identifier |
74 | | -pub const PrecompileId = enum { |
| 85 | +pub const PrecompileId = union(enum) { |
75 | 86 | /// Elliptic curve digital signature algorithm (ECDSA) public key recovery function. |
76 | 87 | EcRec, |
77 | 88 | /// SHA2-256 hash function. |
@@ -108,6 +119,88 @@ pub const PrecompileId = enum { |
108 | 119 | Bls12MapFp2ToGp2, |
109 | 120 | /// ECDSA signature verification over the secp256r1 elliptic curve. |
110 | 121 | P256Verify, |
| 122 | + /// Custom precompile identifier. |
| 123 | + Custom: []const u8, |
| 124 | + |
| 125 | + /// Create new custom precompile ID. |
| 126 | + pub fn custom(id: []const u8) PrecompileId { |
| 127 | + return PrecompileId{ .Custom = id }; |
| 128 | + } |
| 129 | + |
| 130 | + /// Returns the name of the precompile as defined in EIP-7910. |
| 131 | + pub fn name(self: PrecompileId) []const u8 { |
| 132 | + return switch (self) { |
| 133 | + .EcRec => "ECREC", |
| 134 | + .Sha256 => "SHA256", |
| 135 | + .Ripemd160 => "RIPEMD160", |
| 136 | + .Identity => "ID", |
| 137 | + .ModExp => "MODEXP", |
| 138 | + .Bn254Add => "BN254_ADD", |
| 139 | + .Bn254Mul => "BN254_MUL", |
| 140 | + .Bn254Pairing => "BN254_PAIRING", |
| 141 | + .Blake2F => "BLAKE2F", |
| 142 | + .KzgPointEvaluation => "KZG_POINT_EVALUATION", |
| 143 | + .Bls12G1Add => "BLS12_G1ADD", |
| 144 | + .Bls12G1Msm => "BLS12_G1MSM", |
| 145 | + .Bls12G2Add => "BLS12_G2ADD", |
| 146 | + .Bls12G2Msm => "BLS12_G2MSM", |
| 147 | + .Bls12Pairing => "BLS12_PAIRING_CHECK", |
| 148 | + .Bls12MapFpToGp1 => "BLS12_MAP_FP_TO_G1", |
| 149 | + .Bls12MapFp2ToGp2 => "BLS12_MAP_FP2_TO_G2", |
| 150 | + .P256Verify => "P256VERIFY", |
| 151 | + .Custom => |id| id, |
| 152 | + }; |
| 153 | + } |
| 154 | + |
| 155 | + /// Returns the precompile function for the given spec. |
| 156 | + /// |
| 157 | + /// If case of Custom it will return null. |
| 158 | + /// |
| 159 | + /// For case where precompile was still not introduced in the spec, |
| 160 | + /// it will return the fork closest to activation. |
| 161 | + pub fn precompile(self: PrecompileId, spec: PrecompileSpecId) ?Precompile { |
| 162 | + return switch (self) { |
| 163 | + .EcRec => secp256k1.ECRECOVER, |
| 164 | + .Sha256 => hash.SHA256, |
| 165 | + .Ripemd160 => hash.RIPEMD160, |
| 166 | + .Identity => identity.FUN, |
| 167 | + .ModExp => blk: { |
| 168 | + // ModExp changes gas calculation based on spec |
| 169 | + const mod_exp_precompile: Precompile = if (@intFromEnum(spec) < @intFromEnum(PrecompileSpecId.Berlin)) modexp.BYZANTIUM else if (@intFromEnum(spec) < @intFromEnum(PrecompileSpecId.Osaka)) modexp.BERLIN else modexp.OSAKA; |
| 170 | + break :blk mod_exp_precompile; |
| 171 | + }, |
| 172 | + .Bn254Add => blk: { |
| 173 | + // BN254 add - gas cost changes in Istanbul |
| 174 | + const bn254_add_precompile: Precompile = if (@intFromEnum(spec) < @intFromEnum(PrecompileSpecId.Istanbul)) bn254.add.BYZANTIUM else bn254.add.ISTANBUL; |
| 175 | + break :blk bn254_add_precompile; |
| 176 | + }, |
| 177 | + .Bn254Mul => blk: { |
| 178 | + // BN254 mul - gas cost changes in Istanbul |
| 179 | + const bn254_mul_precompile: Precompile = if (@intFromEnum(spec) < @intFromEnum(PrecompileSpecId.Istanbul)) bn254.mul.BYZANTIUM else bn254.mul.ISTANBUL; |
| 180 | + break :blk bn254_mul_precompile; |
| 181 | + }, |
| 182 | + .Bn254Pairing => blk: { |
| 183 | + // BN254 pairing - gas cost changes in Istanbul |
| 184 | + const bn254_pair_precompile: Precompile = if (@intFromEnum(spec) < @intFromEnum(PrecompileSpecId.Istanbul)) bn254.pair.BYZANTIUM else bn254.pair.ISTANBUL; |
| 185 | + break :blk bn254_pair_precompile; |
| 186 | + }, |
| 187 | + .Blake2F => blake2.FUN, |
| 188 | + .KzgPointEvaluation => kzg_point_evaluation.POINT_EVALUATION, |
| 189 | + .Bls12G1Add => bls12_381.g1_add.PRECOMPILE, |
| 190 | + .Bls12G1Msm => bls12_381.g1_msm.PRECOMPILE, |
| 191 | + .Bls12G2Add => bls12_381.g2_add.PRECOMPILE, |
| 192 | + .Bls12G2Msm => bls12_381.g2_msm.PRECOMPILE, |
| 193 | + .Bls12Pairing => bls12_381.pairing.PRECOMPILE, |
| 194 | + .Bls12MapFpToGp1 => bls12_381.map_fp_to_g1.PRECOMPILE, |
| 195 | + .Bls12MapFp2ToGp2 => bls12_381.map_fp2_to_g2.PRECOMPILE, |
| 196 | + .P256Verify => blk: { |
| 197 | + // P256 verify - gas cost changes in Osaka |
| 198 | + const p256_precompile: Precompile = if (@intFromEnum(spec) < @intFromEnum(PrecompileSpecId.Osaka)) secp256r1.P256VERIFY else secp256r1.P256VERIFY_OSAKA; |
| 199 | + break :blk p256_precompile; |
| 200 | + }, |
| 201 | + .Custom => return null, |
| 202 | + }; |
| 203 | + } |
111 | 204 | }; |
112 | 205 |
|
113 | 206 | /// Precompile specification ID |
@@ -309,16 +402,6 @@ pub const Precompiles = struct { |
309 | 402 | } |
310 | 403 | }; |
311 | 404 |
|
312 | | -// Import precompile modules |
313 | | -pub const identity = @import("identity.zig"); |
314 | | -pub const hash = @import("hash.zig"); |
315 | | -pub const secp256k1 = @import("secp256k1.zig"); |
316 | | -pub const secp256r1 = @import("secp256r1.zig"); |
317 | | -pub const modexp = @import("modexp.zig"); |
318 | | -pub const bn254 = @import("bn254.zig"); |
319 | | -pub const blake2 = @import("blake2.zig"); |
320 | | -pub const kzg_point_evaluation = @import("kzg_point_evaluation.zig"); |
321 | | -pub const bls12_381 = @import("bls12_381.zig"); |
322 | 405 |
|
323 | 406 | // Import test module |
324 | 407 | pub const tests = @import("tests.zig"); |
|
0 commit comments