ethereum.prague.vm.precompiled_contracts.bls12_381

BLS12 381 Precompile ^^^^^^^^^^^^^^^^^^^^

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

Introduction

Precompile for BLS12-381 curve operations.

G1_K_DISCOUNT

37
G1_K_DISCOUNT = [
38
    1000,
39
    949,
40
    848,
41
    797,
42
    764,
43
    750,
44
    738,
45
    728,
46
    719,
47
    712,
48
    705,
49
    698,
50
    692,
51
    687,
52
    682,
53
    677,
54
    673,
55
    669,
56
    665,
57
    661,
58
    658,
59
    654,
60
    651,
61
    648,
62
    645,
63
    642,
64
    640,
65
    637,
66
    635,
67
    632,
68
    630,
69
    627,
70
    625,
71
    623,
72
    621,
73
    619,
74
    617,
75
    615,
76
    613,
77
    611,
78
    609,
79
    608,
80
    606,
81
    604,
82
    603,
83
    601,
84
    599,
85
    598,
86
    596,
87
    595,
88
    593,
89
    592,
90
    591,
91
    589,
92
    588,
93
    586,
94
    585,
95
    584,
96
    582,
97
    581,
98
    580,
99
    579,
100
    577,
101
    576,
102
    575,
103
    574,
104
    573,
105
    572,
106
    570,
107
    569,
108
    568,
109
    567,
110
    566,
111
    565,
112
    564,
113
    563,
114
    562,
115
    561,
116
    560,
117
    559,
118
    558,
119
    557,
120
    556,
121
    555,
122
    554,
123
    553,
124
    552,
125
    551,
126
    550,
127
    549,
128
    548,
129
    547,
130
    547,
131
    546,
132
    545,
133
    544,
134
    543,
135
    542,
136
    541,
137
    540,
138
    540,
139
    539,
140
    538,
141
    537,
142
    536,
143
    536,
144
    535,
145
    534,
146
    533,
147
    532,
148
    532,
149
    531,
150
    530,
151
    529,
152
    528,
153
    528,
154
    527,
155
    526,
156
    525,
157
    525,
158
    524,
159
    523,
160
    522,
161
    522,
162
    521,
163
    520,
164
    520,
165
    519,
166
]

G2_K_DISCOUNT

168
G2_K_DISCOUNT = [
169
    1000,
170
    1000,
171
    923,
172
    884,
173
    855,
174
    832,
175
    812,
176
    796,
177
    782,
178
    770,
179
    759,
180
    749,
181
    740,
182
    732,
183
    724,
184
    717,
185
    711,
186
    704,
187
    699,
188
    693,
189
    688,
190
    683,
191
    679,
192
    674,
193
    670,
194
    666,
195
    663,
196
    659,
197
    655,
198
    652,
199
    649,
200
    646,
201
    643,
202
    640,
203
    637,
204
    634,
205
    632,
206
    629,
207
    627,
208
    624,
209
    622,
210
    620,
211
    618,
212
    615,
213
    613,
214
    611,
215
    609,
216
    607,
217
    606,
218
    604,
219
    602,
220
    600,
221
    598,
222
    597,
223
    595,
224
    593,
225
    592,
226
    590,
227
    589,
228
    587,
229
    586,
230
    584,
231
    583,
232
    582,
233
    580,
234
    579,
235
    578,
236
    576,
237
    575,
238
    574,
239
    573,
240
    571,
241
    570,
242
    569,
243
    568,
244
    567,
245
    566,
246
    565,
247
    563,
248
    562,
249
    561,
250
    560,
251
    559,
252
    558,
253
    557,
254
    556,
255
    555,
256
    554,
257
    553,
258
    552,
259
    552,
260
    551,
261
    550,
262
    549,
263
    548,
264
    547,
265
    546,
266
    545,
267
    545,
268
    544,
269
    543,
270
    542,
271
    541,
272
    541,
273
    540,
274
    539,
275
    538,
276
    537,
277
    537,
278
    536,
279
    535,
280
    535,
281
    534,
282
    533,
283
    532,
284
    532,
285
    531,
286
    530,
287
    530,
288
    529,
289
    528,
290
    528,
291
    527,
292
    526,
293
    526,
294
    525,
295
    524,
296
    524,
297
]

G1_MAX_DISCOUNT

299
G1_MAX_DISCOUNT = 519

G2_MAX_DISCOUNT

300
G2_MAX_DISCOUNT = 524

MULTIPLIER

301
MULTIPLIER = Uint(1000)

bytes_to_g1

Decode 128 bytes to a G1 point. Does not perform sub-group check.

Parameters

data : The bytes data to decode.

Returns

point : Point3D[FQ] The G1 point.

Raises

InvalidParameter Either a field element is invalid or the point is not on the curve.

def bytes_to_g1(data: Bytes) -> Point3D[FQ]:
307
    """
308
    Decode 128 bytes to a G1 point. Does not perform sub-group check.
309
310
    Parameters
311
    ----------
312
    data :
313
        The bytes data to decode.
314
315
    Returns
316
    -------
317
    point : Point3D[FQ]
318
        The G1 point.
319
320
    Raises
321
    ------
322
    InvalidParameter
323
        Either a field element is invalid or the point is not on the curve.
324
    """
325
    if len(data) != 128:
326
        raise InvalidParameter("Input should be 128 bytes long")
327
328
    x = bytes_to_fq(data[:64])
329
    y = bytes_to_fq(data[64:])
330
331
    if x >= FQ.field_modulus:
332
        raise InvalidParameter("x >= field modulus")
333
    if y >= FQ.field_modulus:
334
        raise InvalidParameter("y >= field modulus")
335
336
    z = 1
337
    if x == 0 and y == 0:
338
        z = 0
339
    point = FQ(x), FQ(y), FQ(z)
340
341
    if not is_on_curve(point, b):
342
        raise InvalidParameter("Point is not on curve")
343
344
    return point

g1_to_bytes

Encode a G1 point to 128 bytes.

Parameters

g1_point : The G1 point to encode.

Returns

data : Bytes The encoded data.

def g1_to_bytes(g1_point: Point3D[FQ]) -> Bytes:
350
    """
351
    Encode a G1 point to 128 bytes.
352
353
    Parameters
354
    ----------
355
    g1_point :
356
        The G1 point to encode.
357
358
    Returns
359
    -------
360
    data : Bytes
361
        The encoded data.
362
    """
363
    g1_normalized = normalize(g1_point)
364
    x, y = g1_normalized
365
    return b"".join([int(x).to_bytes(64, "big"), int(y).to_bytes(64, "big")])

decode_g1_scalar_pair

Decode 160 bytes to a G1 point and a scalar.

Parameters

data : The bytes data to decode.

Returns

point : Tuple[Point3D[FQ], int] The G1 point and the scalar.

Raises

InvalidParameter If the sub-group check failed.

def decode_g1_scalar_pair(data: Bytes) -> Tuple[Point3D[FQ], int]:
371
    """
372
    Decode 160 bytes to a G1 point and a scalar.
373
374
    Parameters
375
    ----------
376
    data :
377
        The bytes data to decode.
378
379
    Returns
380
    -------
381
    point : Tuple[Point3D[FQ], int]
382
        The G1 point and the scalar.
383
384
    Raises
385
    ------
386
    InvalidParameter
387
        If the sub-group check failed.
388
    """
389
    if len(data) != 160:
390
        InvalidParameter("Input should be 160 bytes long")
391
392
    point = bytes_to_g1(data[:128])
393
    if not is_inf(bls12_multiply(point, curve_order)):
394
        raise InvalidParameter("Sub-group check failed.")
395
396
    m = int.from_bytes(buffer_read(data, U256(128), U256(32)), "big")
397
398
    return point, m

bytes_to_fq

Decode 64 bytes to a FQ element.

Parameters

data : The bytes data to decode.

Returns

fq : FQ The FQ element.

Raises

InvalidParameter If the field element is invalid.

def bytes_to_fq(data: Bytes) -> FQ:
402
    """
403
    Decode 64 bytes to a FQ element.
404
405
    Parameters
406
    ----------
407
    data :
408
        The bytes data to decode.
409
410
    Returns
411
    -------
412
    fq : FQ
413
        The FQ element.
414
415
    Raises
416
    ------
417
    InvalidParameter
418
        If the field element is invalid.
419
    """
420
    if len(data) != 64:
421
        raise InvalidParameter("FQ should be 64 bytes long")
422
423
    c = int.from_bytes(data[:64], "big")
424
425
    if c >= FQ.field_modulus:
426
        raise InvalidParameter("Invalid field element")
427
428
    return FQ(c)

bytes_to_fq2

Decode 128 bytes to an FQ2 element.

Parameters

data : The bytes data to decode.

Returns

fq2 : FQ2 The FQ2 element.

Raises

InvalidParameter If the field element is invalid.

def bytes_to_fq2(data: Bytes) -> FQ2:
432
    """
433
    Decode 128 bytes to an FQ2 element.
434
435
    Parameters
436
    ----------
437
    data :
438
        The bytes data to decode.
439
440
    Returns
441
    -------
442
    fq2 : FQ2
443
        The FQ2 element.
444
445
    Raises
446
    ------
447
    InvalidParameter
448
        If the field element is invalid.
449
    """
450
    if len(data) != 128:
451
        raise InvalidParameter("FQ2 input should be 128 bytes long")
452
    c_0 = int.from_bytes(data[:64], "big")
453
    c_1 = int.from_bytes(data[64:], "big")
454
455
    if c_0 >= FQ.field_modulus:
456
        raise InvalidParameter("Invalid field element")
457
    if c_1 >= FQ.field_modulus:
458
        raise InvalidParameter("Invalid field element")
459
460
    return FQ2((c_0, c_1))

bytes_to_g2

Decode 256 bytes to a G2 point. Does not perform sub-group check.

Parameters

data : The bytes data to decode.

Returns

point : Point3D[FQ2] The G2 point.

Raises

InvalidParameter Either a field element is invalid or the point is not on the curve.

def bytes_to_g2(data: Bytes) -> Point3D[FQ2]:
466
    """
467
    Decode 256 bytes to a G2 point. Does not perform sub-group check.
468
469
    Parameters
470
    ----------
471
    data :
472
        The bytes data to decode.
473
474
    Returns
475
    -------
476
    point : Point3D[FQ2]
477
        The G2 point.
478
479
    Raises
480
    ------
481
    InvalidParameter
482
        Either a field element is invalid or the point is not on the curve.
483
    """
484
    if len(data) != 256:
485
        raise InvalidParameter("G2 should be 256 bytes long")
486
487
    x = bytes_to_fq2(data[:128])
488
    y = bytes_to_fq2(data[128:])
489
490
    z = (1, 0)
491
    if x == FQ2((0, 0)) and y == FQ2((0, 0)):
492
        z = (0, 0)
493
494
    point = x, y, FQ2(z)
495
496
    # Check if the point is on the curve
497
    if not is_on_curve(point, b2):
498
        raise InvalidParameter("Point is not on curve")
499
500
    return point

FQ2_to_bytes

Encode a FQ2 point to 128 bytes.

Parameters

fq2 : The FQ2 point to encode.

Returns

data : Bytes The encoded data.

def FQ2_to_bytes(fq2: FQ2) -> Bytes:
504
    """
505
    Encode a FQ2 point to 128 bytes.
506
507
    Parameters
508
    ----------
509
    fq2 :
510
        The FQ2 point to encode.
511
512
    Returns
513
    -------
514
    data : Bytes
515
        The encoded data.
516
    """
517
    coord0, coord1 = fq2.coeffs
518
    return b"".join(
519
        [
520
            int(coord0).to_bytes(64, "big"),
521
            int(coord1).to_bytes(64, "big"),
522
        ]
523
    )

g2_to_bytes

Encode a G2 point to 256 bytes.

Parameters

g2_point : The G2 point to encode.

Returns

data : Bytes The encoded data.

def g2_to_bytes(g2_point: Point3D[FQ2]) -> Bytes:
529
    """
530
    Encode a G2 point to 256 bytes.
531
532
    Parameters
533
    ----------
534
    g2_point :
535
        The G2 point to encode.
536
537
    Returns
538
    -------
539
    data : Bytes
540
        The encoded data.
541
    """
542
    x_coords, y_coords = normalize(g2_point)
543
    return b"".join([FQ2_to_bytes(x_coords), FQ2_to_bytes(y_coords)])

decode_g2_scalar_pair

Decode 288 bytes to a G2 point and a scalar.

Parameters

data : The bytes data to decode.

Returns

point : Tuple[Point3D[FQ2], int] The G2 point and the scalar.

Raises

InvalidParameter If the sub-group check failed.

def decode_g2_scalar_pair(data: Bytes) -> Tuple[Point3D[FQ2], int]:
549
    """
550
    Decode 288 bytes to a G2 point and a scalar.
551
552
    Parameters
553
    ----------
554
    data :
555
        The bytes data to decode.
556
557
    Returns
558
    -------
559
    point : Tuple[Point3D[FQ2], int]
560
        The G2 point and the scalar.
561
562
    Raises
563
    ------
564
    InvalidParameter
565
        If the sub-group check failed.
566
    """
567
    if len(data) != 288:
568
        InvalidParameter("Input should be 288 bytes long")
569
570
    point = bytes_to_g2(data[:256])
571
572
    if not is_inf(bls12_multiply(point, curve_order)):
573
        raise InvalidParameter("Point failed sub-group check.")
574
575
    n = int.from_bytes(data[256 : 256 + 32], "big")
576
577
    return point, n