evmprecompiles

package
v0.15.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 13, 2026 License: Apache-2.0 Imports: 24 Imported by: 7

Documentation

Overview

Package evmprecompiles implements the Ethereum VM precompile contracts.

This package collects all the precompile functions into a single location for easier integration. The main functionality is implemented elsewhere. This package right now implements:

  1. ECRECOVER ✅ -- function ECRecover
  2. SHA256 ❌ -- in progress
  3. RIPEMD160 ❌ -- postponed
  4. ID ❌ -- trivial to implement without function
  5. EXPMOD ✅ -- function Expmod
  6. BN_ADD ✅ -- function ECAdd
  7. BN_MUL ✅ -- function ECMul
  8. SNARKV ✅ -- function ECPair
  9. BLAKE2F ❌ -- postponed
  10. POINT_EVALUATION ✅ -- functions KzgPointEvaluation, KzgPointEvaluationFailure
  11. BLS12_G1MSM ✅ -- function ECAddG1BLS
  12. BLS12_G1MSM ✅ -- function ECG1ScalarMulSumBLS
  13. BLS12_G2ADD ✅ -- function ECAddG2BLS
  14. BLS12_G2MSM ✅ -- function ECG2ScalarMulSumBLS
  15. BLS12_PAIRING_CHECK ✅ -- function ECPairBLS
  16. BLS12_MAP_FP_TO_G1 ✅ -- function ECMapToG1BLS
  17. BLS12_MAP_FP2_TO_G2 ✅ -- function ECMapToG2BLS

This package uses local representation for the arguments. It is up to the user to instantiate corresponding types from their application-specific data.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ECAdd

ECAdd implements ALT_BN128_ADD precompile contract at address 0x06.

func ECAddG1BLS added in v0.13.0

func ECAddG1BLS(api frontend.API, P, Q, expected *sw_emulated.AffinePoint[emulated.BLS12381Fp])

ECAddG1BLS implements BLS12_G1ADD precompile contract at address 0x0b.

func ECAddG2BLS added in v0.13.0

func ECAddG2BLS(api frontend.API, P, Q, expected *sw_bls12381.G2Affine)

ECAddG2BLS implements BLS12_G2ADD precompile contract at address 0x0d.

func ECG1ScalarMulSumBLS added in v0.14.0

func ECG1ScalarMulSumBLS(api frontend.API, prev, P *sw_bls12381.G1Affine, s *emulated.Element[sw_bls12381.ScalarField], expected *sw_bls12381.G1Affine) error

ECG1ScalarMulSumBLS computes the scalar multiplication of a point P by a scalar s, adds it to a previous point prev, and checks that the result is equal to expected. It is used to implement the BLS12_G1MSM precompile contract at address 0x0c.

func ECG2ScalarMulSumBLS added in v0.14.0

func ECG2ScalarMulSumBLS(api frontend.API, prev, Q *sw_bls12381.G2Affine, s *emulated.Element[sw_bls12381.ScalarField], expected *sw_bls12381.G2Affine) error

ECG2ScalarMulSumBLS computes the scalar multiplication of a point P by a scalar s in G2, adds it to a previous point prev, and checks that the result is equal to expected. It is used to implement the [BLS12_G2MSM] precompile contract at address 0x0e.

func ECMapToG1BLS added in v0.13.0

ECMapToG1BLS implements [BLS12_MAP_FP_TO_G1] precompile contract at address 0x10.

func ECMapToG2BLS added in v0.13.0

func ECMapToG2BLS(api frontend.API, u *fields_bls12381.E2, expected *sw_bls12381.G2Affine) error

ECMapToG2BLS implements [BLS12_MAP_FP2_TO_G2] precompile contract at address 0x11.

func ECMul

ECMul implements ALT_BN128_MUL precompile contract at address 0x07.

func ECPair

func ECPair(api frontend.API, P []*sw_bn254.G1Affine, Q []*sw_bn254.G2Affine)

ECPair implements ALT_BN128_PAIRING_CHECK precompile contract at address 0x08.

To have a fixed-circuit regardless of the number of inputs, we need 2 fixed circuits:

  • MillerLoopAndMul: A Miller loop of fixed size 1 followed by a multiplication in 𝔽p¹².
  • MillerLoopAndFinalExpCheck: A Miller loop of fixed size 1 followed by a multiplication in 𝔽p¹², and a check that the result lies in the same equivalence class as the reduced pairing purported to be 1. This check replaces the final exponentiation step in-circuit and follows Section 4 of On Proving Pairings paper by A. Novakovic and L. Eagen.

N.B.: This is a sub-optimal routine but defines a fixed circuit regardless of the number of inputs. We can extend this routine to handle a 2-by-2 logic but we prefer a minimal number of circuits (2).

See the methods ECPairMillerLoopAndMul and ECPairMillerLoopAndFinalExpCheck for the fixed circuits. See the method ECPairIsOnG2 for the check that Qᵢ are on G2.

func ECPairBLS added in v0.13.0

func ECPairBLS(api frontend.API, P []*sw_bls12381.G1Affine, Q []*sw_bls12381.G2Affine)

ECPairBLS implements BLS12_PAIRING_CHECK precompile contract at address 0x0f.

To have a fixed-circuit regardless of the number of inputs, we need 2 fixed circuits:

  • MillerLoopAndMul: A Miller loop of fixed size 1 followed by a multiplication in 𝔽p¹².
  • MillerLoopAndFinalExpCheck: A Miller loop of fixed size 1 followed by a multiplication in 𝔽p¹², and a check that the result lies in the same equivalence class as the reduced pairing purported to be 1. This check replaces the final exponentiation step in-circuit and follows Section 4 of On Proving Pairings paper by A. Novakovic and L. Eagen.

N.B.: This is a sub-optimal routine but defines a fixed circuit regardless of the number of inputs. We can extend this routine to handle a 2-by-2 logic but we prefer a minimal number of circuits (2).

See the methods ECPairMillerLoopAndMul and ECPairMillerLoopAndFinalExpCheck for the fixed circuits. See the methods ECPairBLSIsOnG1 and ECPairBLSIsOnG2 for the check that Pᵢ and Qᵢ are on G1 and resp. G2.

func ECPairBLSIsOnG1 added in v0.13.0

func ECPairBLSIsOnG1(api frontend.API, Q *sw_bls12381.G1Affine, expectedIsOnG1 frontend.Variable) error

ECPairBLSIsOnG1 implements the fixed circuit for checking G1 membership and non-membership.

func ECPairBLSIsOnG2 added in v0.13.0

func ECPairBLSIsOnG2(api frontend.API, Q *sw_bls12381.G2Affine, expectedIsOnG2 frontend.Variable) error

ECPairBLSIsOnG2 implements the fixed circuit for checking G2 membership and non-membership.

func ECPairBLSMillerLoopAndFinalExpCheck added in v0.13.0

func ECPairBLSMillerLoopAndFinalExpCheck(api frontend.API, accumulator *sw_bls12381.GTEl, P *sw_bls12381.G1Affine, Q *sw_bls12381.G2Affine, expectedIsSuccess frontend.Variable) error

ECPairMillerLoopAndFinalExpCheck implements the fixed circuit for a Miller loop of fixed size 1 followed by a multiplication with an accumulator in 𝔽p¹², and a check that the result corresponds to the expected result.

func ECPairBLSMillerLoopAndMul added in v0.13.0

func ECPairBLSMillerLoopAndMul(api frontend.API, accumulator *sw_bls12381.GTEl, P *sw_bls12381.G1Affine, Q *sw_bls12381.G2Affine, expected *sw_bls12381.GTEl) error

ECPairMillerLoopAndMul implements the fixed circuit for a Miller loop of fixed size 1 followed by a multiplication with an accumulator in 𝔽p¹². It asserts that the result corresponds to the expected result.

func ECPairIsOnG2 added in v0.11.0

func ECPairIsOnG2(api frontend.API, Q *sw_bn254.G2Affine, expectedIsOnG2 frontend.Variable) error

ECPairIsOnG2 implements the fixed circuit for checking G2 membership and non-membership.

func ECPairMillerLoopAndFinalExpCheck added in v0.11.0

func ECPairMillerLoopAndFinalExpCheck(api frontend.API, accumulator *sw_bn254.GTEl, P *sw_bn254.G1Affine, Q *sw_bn254.G2Affine, expectedIsSuccess frontend.Variable) error

ECPairMillerLoopAndFinalExpCheck implements the fixed circuit for a Miller loop of fixed size 1 followed by a multiplication with an accumulator in 𝔽p¹², and a check that the result corresponds to the expected result.

func ECPairMillerLoopAndMul added in v0.11.0

func ECPairMillerLoopAndMul(api frontend.API, accumulator *sw_bn254.GTEl, P *sw_bn254.G1Affine, Q *sw_bn254.G2Affine, expected *sw_bn254.GTEl) error

ECPairMillerLoopAndMul implements the fixed circuit for a Miller loop of fixed size 1 followed by a multiplication with an accumulator in 𝔽p¹². It asserts that the result corresponds to the expected result.

func ECRecover

ECRecover implements ECRECOVER precompile contract at address 0x01.

The method allows checking both the transaction signatures and ECRecover precompile calls. The difference between TX signature verification and ECRecover precompile call is that there is additional check for s <= (Fr-1)/2 in the former case. To enforce this check, the strictRange variable should be set to 1.

The isFailure variable is set to 1 when the inputs are expected to be invalid in the context of ECRecover. The failure cases are:

  1. The public key is zero.
  2. The value r^3 + 7 is not a quadratic residue.

func Expmod added in v0.10.0

func Expmod[P emulated.FieldParams](api frontend.API, base, exp, modulus *emulated.Element[P]) *emulated.Element[P]

Expmod implements MODEXP precompile contract at address 0x05.

Internally, uses 4k elements for representing the base, exponent and modulus, upper bounding the sizes of the inputs. The runtime is constant regardless of the actual length of the inputs.

func GetHints

func GetHints() []solver.Hint

GetHints returns all the hints used in this package.

func KzgPointEvaluation added in v0.14.0

func KzgPointEvaluation(
	api frontend.API,
	versionedHash [2]frontend.Variable,
	evaluationPoint *emulated.Element[sw_bls12381.ScalarField],
	claimedValue *emulated.Element[sw_bls12381.ScalarField],
	commitmentCompressed [3]frontend.Variable,
	proofCompressed [3]frontend.Variable,
	expectedBlobSize [2]frontend.Variable,
	expectedBlsModulus [2]frontend.Variable,
) error

KzgPointEvaluation implements the KZG_POINT_EVALUATION precompile at address 0xa using 128-bit limbs.

The data is encoded as follows:

[ versioned_hash | point |  claim  | commitment |   proof   ]
 <---- 32b -----> <-32b-> <- 32b -> <-- 48b  --> <-- 48b -->

Values point and claim are the evaluation point and the claimed value, they are represented as 32-byte scalar field elements. We use [2]frontend.Variable as the arithmetization provides them as 16-byte words.

Values commitment and proof are the KZG commitment and proof respectively. They are given as compressed points, for which we use 3 native elements to represent. The method performs decompression and all necessary checks. The encoding is given by Appendix C of PAIRING_FRIENDLY_CURVES.

func KzgPointEvaluation16 added in v0.15.0

func KzgPointEvaluation16(
	api frontend.API,
	versionedHash [16]frontend.Variable,
	evaluationPoint *emulated.Element[sw_bls12381.ScalarField],
	claimedValue *emulated.Element[sw_bls12381.ScalarField],
	commitmentCompressed [24]frontend.Variable,
	proofCompressed [24]frontend.Variable,
	expectedBlobSize [16]frontend.Variable,
	expectedBlsModulus [16]frontend.Variable,
) error

KzgPointEvaluation16 implements the KZG_POINT_EVALUATION precompile at address 0xa using 16-bit limbs.

The data is encoded as follows:

[ versioned_hash | point |  claim  | commitment |   proof   ]
 <---- 32b -----> <-32b-> <- 32b -> <-- 48b  --> <-- 48b -->

Values point and claim are the evaluation point and the claimed value, they are represented as 32-byte scalar field elements. We use [16]frontend.Variable as the arithmetization provides them as 2-byte words.

Values commitment and proof are the KZG commitment and proof respectively. They are given as compressed points, for which we use 24 native elements to represent. The method performs decompression and all necessary checks. The encoding is given by Appendix C of PAIRING_FRIENDLY_CURVES.

func KzgPointEvaluationFailure added in v0.15.0

func KzgPointEvaluationFailure(
	api frontend.API,
	versionedHash [2]frontend.Variable,
	evaluationPoint *emulated.Element[sw_bls12381.ScalarField],
	claimedValue *emulated.Element[sw_bls12381.ScalarField],
	commitmentCompressed [3]frontend.Variable,
	proofCompressed [3]frontend.Variable,
	expectedBlobSize [2]frontend.Variable,
	expectedBlsModulus [2]frontend.Variable,
) error

KzgPointEvaluationFailure checks a failing case of KZG point evaluation precompile using 128-bit limbs. It has the same interface as KzgPointEvaluation but it allows to pass in inputs which should fail according to the EIP-4844 specification. The method CAN NOT assert validity of valid inputs. The goal of the method is to allow proving that the precompile call failed in EVM.

For data encoding (particularly for compressed inputs), see KzgPointEvaluation method documentation.

The method checks that any of the following failure cases happen:

  • the versioned hash version is incorrect
  • the versioned hash does not match the commitment
  • the compressed commitment or proof have invalid compression mask (allowed masks are 0b100, 0b101 and 0b110)
  • x coordinate value in compressed commitment or proof does overflows
  • x coordinate value in compressed commitment or proof differs from mask (for infinity mask x != 0, for non-infinity mask x == 0)
  • the compressed commitment or proof do not represent curve points
  • the compressed commitment or proof do not represent points in the correct subgroup
  • pairing check fails for the inputs
  • expected blob size is incorrect (should be 4096)
  • expected BLS modulus is incorrect (should be BLS12-381 scalar field modulus)

The checks are non-exclusive, i.e. multiple of them can fail at the same time.

func KzgPointEvaluationFailure16 added in v0.15.0

func KzgPointEvaluationFailure16(
	api frontend.API,
	versionedHash [16]frontend.Variable,
	evaluationPoint *emulated.Element[sw_bls12381.ScalarField],
	claimedValue *emulated.Element[sw_bls12381.ScalarField],
	commitmentCompressed [24]frontend.Variable,
	proofCompressed [24]frontend.Variable,
	expectedBlobSize [16]frontend.Variable,
	expectedBlsModulus [16]frontend.Variable,
) error

KzgPointEvaluationFailure16 checks a failing case of KZG point evaluation precompile using 16-bit limbs. It has the same interface as KzgPointEvaluation16 but it allows to pass in inputs which should fail according to the EIP-4844 specification. The method CAN NOT assert validity of valid inputs. The goal of the method is to allow proving that the precompile call failed in EVM.

For data encoding (particularly for compressed inputs), see KzgPointEvaluation16 method documentation.

The method checks that any of the following failure cases happen:

  • the versioned hash version is incorrect
  • the versioned hash does not match the commitment
  • the compressed commitment or proof have invalid compression mask (allowed masks are 0b100, 0b101 and 0b110)
  • x coordinate value in compressed commitment or proof does overflows
  • x coordinate value in compressed commitment or proof differs from mask (for infinity mask x != 0, for non-infinity mask x == 0)
  • the compressed commitment or proof do not represent curve points
  • the compressed commitment or proof do not represent points in the correct subgroup
  • pairing check fails for the inputs
  • expected blob size is incorrect (should be 4096)
  • expected BLS modulus is incorrect (should be BLS12-381 scalar field modulus)

The checks are non-exclusive, i.e. multiple of them can fail at the same time.

func P256Verify added in v0.15.0

P256Verify implements P256Verify precompile contract at address 0x100.

This circuit performs ECDSA signature verification over the secp256r1 elliptic curve (also known as P-256 or prime256v1).

The method is specific to zkEVM context where some checks are already done by the arithmetization. Particularly this method assumes: * r and s are in the range [1, n-1] * 0 ≤ qx < p and 0 ≤ qy < p * (qx, qy) is a valid point on the curve P256 * (qx, qy) is not (0,0)

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL