EEVM.Precompiles.Bls12381 (eevm v0.1.0)

Copy Markdown View Source

BLS12-381 precompiles — addresses 0x0B through 0x11 (EIP-2537).

This module owns gas accounting, the EIP-2537 encoding, and input validation for the Prague-gated BLS12-381 precompiles. The curve arithmetic is EEVM.Precompiles.Bls12381.Curve, in pure Elixir.

Encoding and validation

An Fp element is 64 bytes: 16 zero bytes, then a 48-byte big-endian value below p. An Fp2 element c0 + c1·u is c0 then c1. A G1 point is x then y (128 bytes), a G2 point x then y in Fp2 (256 bytes), and the point at infinity is all zeros. A scalar is 32 big-endian bytes.

Every input point must be on its curve (ADD included); MSM and pairing inputs must also be in the order-r subgroup. Any violation is an error, which burns all gas supplied to the call.

Summary

Functions

BLS12_G1ADD (0x0B): adds two G1 points. Costs 375 gas.

BLS12_G1MSM (0x0C): returns Σ kᵢ·Pᵢ over (G1 point, scalar) pairs. Costs 12,000 gas per pair times the EIP-2537 discount for the pair count.

BLS12_G2ADD (0x0D): adds two G2 points. Costs 600 gas.

BLS12_G2MSM (0x0E): returns Σ kᵢ·Qᵢ over (G2 point, scalar) pairs. Costs 22,500 gas per pair times the EIP-2537 discount for the pair count.

BLS12_MAP_FP2_TO_G2 (0x11): maps an Fp2 element to G2. Costs 23,800 gas.

BLS12_MAP_FP_TO_G1 (0x10): maps an Fp element to G1. Costs 5,500 gas.

BLS12_PAIRING_CHECK (0x0F): returns 1 as a 32-byte word if the product of the pairings of the given (G1, G2) pairs is 1, else 0. Costs 37,700 + 32,600 per pair.

Functions

execute_g1_add(input, gas_limit)

@spec execute_g1_add(binary(), non_neg_integer()) ::
  {:ok, binary(), non_neg_integer()} | {:error, atom()}

BLS12_G1ADD (0x0B): adds two G1 points. Costs 375 gas.

execute_g1_msm(input, gas_limit)

@spec execute_g1_msm(binary(), non_neg_integer()) ::
  {:ok, binary(), non_neg_integer()} | {:error, atom()}

BLS12_G1MSM (0x0C): returns Σ kᵢ·Pᵢ over (G1 point, scalar) pairs. Costs 12,000 gas per pair times the EIP-2537 discount for the pair count.

execute_g2_add(input, gas_limit)

@spec execute_g2_add(binary(), non_neg_integer()) ::
  {:ok, binary(), non_neg_integer()} | {:error, atom()}

BLS12_G2ADD (0x0D): adds two G2 points. Costs 600 gas.

execute_g2_msm(input, gas_limit)

@spec execute_g2_msm(binary(), non_neg_integer()) ::
  {:ok, binary(), non_neg_integer()} | {:error, atom()}

BLS12_G2MSM (0x0E): returns Σ kᵢ·Qᵢ over (G2 point, scalar) pairs. Costs 22,500 gas per pair times the EIP-2537 discount for the pair count.

execute_map_fp2_to_g2(input, gas_limit)

@spec execute_map_fp2_to_g2(binary(), non_neg_integer()) ::
  {:ok, binary(), non_neg_integer()} | {:error, atom()}

BLS12_MAP_FP2_TO_G2 (0x11): maps an Fp2 element to G2. Costs 23,800 gas.

execute_map_fp_to_g1(input, gas_limit)

@spec execute_map_fp_to_g1(binary(), non_neg_integer()) ::
  {:ok, binary(), non_neg_integer()} | {:error, atom()}

BLS12_MAP_FP_TO_G1 (0x10): maps an Fp element to G1. Costs 5,500 gas.

execute_pairing(input, gas_limit)

@spec execute_pairing(binary(), non_neg_integer()) ::
  {:ok, binary(), non_neg_integer()} | {:error, atom()}

BLS12_PAIRING_CHECK (0x0F): returns 1 as a 32-byte word if the product of the pairings of the given (G1, G2) pairs is 1, else 0. Costs 37,700 + 32,600 per pair.