ethereum.forks.prague.vm.precompiled_contracts.bls12_381.bls12_381_g1

Ethereum Virtual Machine (EVM) BLS12 381 CONTRACTS.

.. contents:: Table of Contents :backlinks: none :local:

Introduction

Implementation of pre-compiles in G1 (curve over base prime field).

LENGTH_PER_PAIR

38
LENGTH_PER_PAIR = 160

bls12_g1_add

The bls12_381 G1 point addition precompile.

Parameters

evm : The current EVM frame.

Raises

InvalidParameter If the input length is invalid.

def bls12_g1_add(evm: Evm) -> None:
42
    """
43
    The bls12_381 G1 point addition precompile.
44
45
    Parameters
46
    ----------
47
    evm :
48
        The current EVM frame.
49
50
    Raises
51
    ------
52
    InvalidParameter
53
        If the input length is invalid.
54
55
    """
56
    data = evm.message.data
57
    if len(data) != 256:
58
        raise InvalidParameter("Invalid Input Length")
59
60
    # GAS
61
    charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1ADD))
62
63
    # OPERATION
64
    p1 = bytes_to_g1(buffer_read(data, U256(0), U256(128)))
65
    p2 = bytes_to_g1(buffer_read(data, U256(128), U256(128)))
66
67
    result = bls12_add(p1, p2)
68
69
    evm.output = g1_to_bytes(result)

bls12_g1_msm

The bls12_381 G1 multi-scalar multiplication precompile. Note: This uses the naive approach to multi-scalar multiplication which is not suitably optimized for production clients. Clients are required to implement a more efficient algorithm such as the Pippenger algorithm.

Parameters

evm : The current EVM frame.

Raises

InvalidParameter If the input length is invalid.

def bls12_g1_msm(evm: Evm) -> None:
73
    """
74
    The bls12_381 G1 multi-scalar multiplication precompile.
75
    Note: This uses the naive approach to multi-scalar multiplication
76
    which is not suitably optimized for production clients. Clients are
77
    required to implement a more efficient algorithm such as the Pippenger
78
    algorithm.
79
80
    Parameters
81
    ----------
82
    evm :
83
        The current EVM frame.
84
85
    Raises
86
    ------
87
    InvalidParameter
88
        If the input length is invalid.
89
90
    """
91
    data = evm.message.data
92
    if len(data) == 0 or len(data) % LENGTH_PER_PAIR != 0:
93
        raise InvalidParameter("Invalid Input Length")
94
95
    # GAS
96
    k = len(data) // LENGTH_PER_PAIR
97
    if k <= 128:
98
        discount = Uint(G1_K_DISCOUNT[k - 1])
99
    else:
100
        discount = Uint(G1_MAX_DISCOUNT)
101
102
    gas_cost = Uint(k) * GasCosts.PRECOMPILE_BLS_G1MUL * discount // MULTIPLIER
103
    charge_gas(evm, gas_cost)
104
105
    # OPERATION
106
    for i in range(k):
107
        start_index = i * LENGTH_PER_PAIR
108
        end_index = start_index + LENGTH_PER_PAIR
109
110
        p, m = decode_g1_scalar_pair(data[start_index:end_index])
111
        product = bls12_multiply(p, m)
112
113
        if i == 0:
114
            result = product
115
        else:
116
            result = bls12_add(result, product)
117
118
    evm.output = g1_to_bytes(result)

bls12_map_fp_to_g1

Precompile to map field element to G1.

Parameters

evm : The current EVM frame.

Raises

InvalidParameter If the input length is invalid.

def bls12_map_fp_to_g1(evm: Evm) -> None:
122
    """
123
    Precompile to map field element to G1.
124
125
    Parameters
126
    ----------
127
    evm :
128
        The current EVM frame.
129
130
    Raises
131
    ------
132
    InvalidParameter
133
        If the input length is invalid.
134
135
    """
136
    data = evm.message.data
137
    if len(data) != 64:
138
        raise InvalidParameter("Invalid Input Length")
139
140
    # GAS
141
    charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G1MAP))
142
143
    # OPERATION
144
    fp = int.from_bytes(data, "big")
145
    if fp >= FQ.field_modulus:
146
        raise InvalidParameter("coordinate >= field modulus")
147
148
    g1_optimized_3d = clear_cofactor_G1(map_to_curve_G1(FQ(fp)))
149
    evm.output = g1_to_bytes(g1_optimized_3d)