12
12
- [ Preset] ( #preset )
13
13
- [ Cells] ( #cells )
14
14
- [ Helper functions] ( #helper-functions )
15
+ - [ BLS12-381 helpers] ( #bls12-381-helpers )
16
+ - [ ` bytes_to_cell ` ] ( #bytes_to_cell )
15
17
- [ Linear combinations] ( #linear-combinations )
16
18
- [ ` g2_lincomb ` ] ( #g2_lincomb )
17
19
- [ FFTs] ( #ffts )
@@ -81,6 +83,18 @@ Cells are the smallest unit of blob data that can come with their own KZG proofs
81
83
82
84
## Helper functions
83
85
86
+ ### BLS12-381 helpers
87
+
88
+ #### ` bytes_to_cell `
89
+
90
+ ``` python
91
+ def bytes_to_cell (cell_bytes : Vector[Bytes32, FIELD_ELEMENTS_PER_CELL ]) -> Cell:
92
+ """
93
+ Convert untrusted bytes into a Cell.
94
+ """
95
+ return [bytes_to_bls_field(element) for element in cell_bytes]
96
+ ```
97
+
84
98
### Linear combinations
85
99
86
100
#### ` g2_lincomb `
@@ -244,7 +258,7 @@ def interpolate_polynomialcoeff(xs: Sequence[BLSFieldElement], ys: Sequence[BLSF
244
258
summand, [(- int (weight_adjustment) * int (xs[j])) % BLS_MODULUS , weight_adjustment]
245
259
)
246
260
r = add_polynomialcoeff(r, summand)
247
-
261
+
248
262
return r
249
263
```
250
264
@@ -332,7 +346,7 @@ def verify_kzg_proof_multi_impl(commitment: KZGCommitment,
332
346
#### ` coset_for_cell `
333
347
334
348
``` python
335
- def coset_for_cell (cell_id : int ) -> Cell:
349
+ def coset_for_cell (cell_id : CellID ) -> Cell:
336
350
"""
337
351
Get the coset for a given ``cell_id``
338
352
"""
@@ -387,7 +401,7 @@ def compute_cells(blob: Blob) -> Vector[Cell, CELLS_PER_BLOB]:
387
401
polynomial = blob_to_polynomial(blob)
388
402
polynomial_coeff = polynomial_eval_to_coeff(polynomial)
389
403
390
- extended_data = fft_field(polynomial_coeff + [0 ] * FIELD_ELEMENTS_PER_BLOB ,
404
+ extended_data = fft_field(polynomial_coeff + [0 ] * FIELD_ELEMENTS_PER_BLOB ,
391
405
compute_roots_of_unity(2 * FIELD_ELEMENTS_PER_BLOB ))
392
406
extended_data_rbo = bit_reversal_permutation(extended_data)
393
407
return [extended_data_rbo[i * FIELD_ELEMENTS_PER_CELL :(i + 1 ) * FIELD_ELEMENTS_PER_CELL ]
@@ -399,30 +413,37 @@ def compute_cells(blob: Blob) -> Vector[Cell, CELLS_PER_BLOB]:
399
413
#### ` verify_cell_proof `
400
414
401
415
``` python
402
- def verify_cell_proof (commitment : KZGCommitment ,
403
- cell_id : int ,
404
- cell : Cell ,
405
- proof : KZGProof ) -> bool :
416
+ def verify_cell_proof (commitment_bytes : Bytes48 ,
417
+ cell_id : CellID ,
418
+ cell_bytes : Vector[Bytes32, FIELD_ELEMENTS_PER_CELL ] ,
419
+ proof_bytes : Bytes48 ) -> bool :
406
420
"""
407
421
Check a cell proof
408
422
409
423
Public method.
410
424
"""
411
425
coset = coset_for_cell(cell_id)
412
426
413
- return verify_kzg_proof_multi_impl(commitment, coset, cell, proof)
427
+ return verify_kzg_proof_multi_impl(
428
+ bytes_to_kzg_commitment(commitment_bytes),
429
+ coset,
430
+ bytes_to_cell(cell_bytes),
431
+ bytes_to_kzg_proof(proof_bytes))
414
432
```
415
433
416
434
#### ` verify_cell_proof_batch `
417
435
418
436
``` python
419
- def verify_cell_proof_batch (row_commitments : Sequence[KZGCommitment ],
420
- row_ids : Sequence[int ],
421
- column_ids : Sequence[int ],
422
- cells : Sequence[Cell ],
423
- proofs : Sequence[KZGProof ]) -> bool :
437
+ def verify_cell_proof_batch (row_commitments_bytes : Sequence[Bytes48 ],
438
+ row_ids : Sequence[uint64 ],
439
+ column_ids : Sequence[uint64 ],
440
+ cells_bytes : Sequence[Vector[Bytes32, FIELD_ELEMENTS_PER_CELL ] ],
441
+ proofs_bytes : Sequence[Bytes48 ]) -> bool :
424
442
"""
425
- Check multiple cell proofs. This function implements the naive algorithm of checking every cell
443
+ Verify a set of cells, given their corresponding proofs and their coordinates (row_id, column_id) in the blob
444
+ matrix. The list of all commitments is also provided in row_commitments_bytes.
445
+
446
+ This function implements the naive algorithm of checking every cell
426
447
individually; an efficient algorithm can be found here:
427
448
https://ethresear.ch/t/a-universal-verification-equation-for-data-availability-sampling/13240
428
449
@@ -432,10 +453,16 @@ def verify_cell_proof_batch(row_commitments: Sequence[KZGCommitment],
432
453
433
454
Public method.
434
455
"""
456
+ assert len (cells_bytes) == len (proofs_bytes) == len (row_ids) == len (column_ids)
435
457
436
458
# Get commitments via row IDs
437
- commitments = [row_commitments[row_id] for row_id in row_ids]
438
-
459
+ commitments_bytes = [row_commitments_bytes[row_id] for row_id in row_ids]
460
+
461
+ # Get objects from bytes
462
+ commitments = [bytes_to_kzg_commitment(commitment_bytes) for commitment_bytes in commitments_bytes]
463
+ cells = [bytes_to_cell(cell_bytes) for cell_bytes in cells_bytes]
464
+ proofs = [bytes_to_kzg_proof(proof_bytes) for proof_bytes in proofs_bytes]
465
+
439
466
return all (
440
467
verify_kzg_proof_multi_impl(commitment, coset_for_cell(column_id), cell, proof)
441
468
for commitment, column_id, cell, proof in zip (commitments, column_ids, cells, proofs)
@@ -447,7 +474,8 @@ def verify_cell_proof_batch(row_commitments: Sequence[KZGCommitment],
447
474
### ` recover_polynomial `
448
475
449
476
``` python
450
- def recover_polynomial (cell_ids : Sequence[CellID], cells : Sequence[Cell]) -> Polynomial:
477
+ def recover_polynomial (cell_ids : Sequence[CellID],
478
+ cells_bytes : Sequence[Vector[Bytes32, FIELD_ELEMENTS_PER_CELL ]]) -> Polynomial:
451
479
"""
452
480
Recovers a polynomial from 2 * FIELD_ELEMENTS_PER_CELL evaluations, half of which can be missing.
453
481
@@ -457,7 +485,10 @@ def recover_polynomial(cell_ids: Sequence[CellID], cells: Sequence[Cell]) -> Pol
457
485
458
486
Public method.
459
487
"""
460
- assert len (cell_ids) == len (cells)
488
+ assert len (cell_ids) == len (cells_bytes)
489
+
490
+ cells = [bytes_to_cell(cell_bytes) for cell_bytes in cells_bytes]
491
+
461
492
assert len (cells) >= CELLS_PER_BLOB // 2
462
493
missing_cell_ids = [cell_id for cell_id in range (CELLS_PER_BLOB ) if cell_id not in cell_ids]
463
494
roots_of_unity_reduced = compute_roots_of_unity(CELLS_PER_BLOB )
@@ -506,7 +537,7 @@ def recover_polynomial(cell_ids: Sequence[CellID], cells: Sequence[Cell]) -> Pol
506
537
507
538
eval_shifted_extended_evaluation = fft_field(shifted_extended_evaluation, roots_of_unity_extended)
508
539
eval_shifted_zero_poly = fft_field(shifted_zero_poly, roots_of_unity_extended)
509
-
540
+
510
541
eval_shifted_reconstructed_poly = [
511
542
div(a, b)
512
543
for a, b in zip (eval_shifted_extended_evaluation, eval_shifted_zero_poly)
0 commit comments