Skip to content

Commit ae3ef6f

Browse files
authored
Merge pull request #3579 from asn-d6/peerdas_public_method_bytes
peerDAS: Public methods must accept raw bytes
2 parents f1dff5f + 2000a4f commit ae3ef6f

File tree

3 files changed

+71
-30
lines changed

3 files changed

+71
-30
lines changed

specs/_features/eip7594/polynomial-commitments-sampling.md

+50-19
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
- [Preset](#preset)
1313
- [Cells](#cells)
1414
- [Helper functions](#helper-functions)
15+
- [BLS12-381 helpers](#bls12-381-helpers)
16+
- [`bytes_to_cell`](#bytes_to_cell)
1517
- [Linear combinations](#linear-combinations)
1618
- [`g2_lincomb`](#g2_lincomb)
1719
- [FFTs](#ffts)
@@ -81,6 +83,18 @@ Cells are the smallest unit of blob data that can come with their own KZG proofs
8183

8284
## Helper functions
8385

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+
8498
### Linear combinations
8599

86100
#### `g2_lincomb`
@@ -244,7 +258,7 @@ def interpolate_polynomialcoeff(xs: Sequence[BLSFieldElement], ys: Sequence[BLSF
244258
summand, [(- int(weight_adjustment) * int(xs[j])) % BLS_MODULUS, weight_adjustment]
245259
)
246260
r = add_polynomialcoeff(r, summand)
247-
261+
248262
return r
249263
```
250264

@@ -332,7 +346,7 @@ def verify_kzg_proof_multi_impl(commitment: KZGCommitment,
332346
#### `coset_for_cell`
333347

334348
```python
335-
def coset_for_cell(cell_id: int) -> Cell:
349+
def coset_for_cell(cell_id: CellID) -> Cell:
336350
"""
337351
Get the coset for a given ``cell_id``
338352
"""
@@ -387,7 +401,7 @@ def compute_cells(blob: Blob) -> Vector[Cell, CELLS_PER_BLOB]:
387401
polynomial = blob_to_polynomial(blob)
388402
polynomial_coeff = polynomial_eval_to_coeff(polynomial)
389403

390-
extended_data = fft_field(polynomial_coeff + [0] * FIELD_ELEMENTS_PER_BLOB,
404+
extended_data = fft_field(polynomial_coeff + [0] * FIELD_ELEMENTS_PER_BLOB,
391405
compute_roots_of_unity(2 * FIELD_ELEMENTS_PER_BLOB))
392406
extended_data_rbo = bit_reversal_permutation(extended_data)
393407
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]:
399413
#### `verify_cell_proof`
400414

401415
```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:
406420
"""
407421
Check a cell proof
408422
409423
Public method.
410424
"""
411425
coset = coset_for_cell(cell_id)
412426

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))
414432
```
415433

416434
#### `verify_cell_proof_batch`
417435

418436
```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:
424442
"""
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
426447
individually; an efficient algorithm can be found here:
427448
https://ethresear.ch/t/a-universal-verification-equation-for-data-availability-sampling/13240
428449
@@ -432,10 +453,16 @@ def verify_cell_proof_batch(row_commitments: Sequence[KZGCommitment],
432453
433454
Public method.
434455
"""
456+
assert len(cells_bytes) == len(proofs_bytes) == len(row_ids) == len(column_ids)
435457

436458
# 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+
439466
return all(
440467
verify_kzg_proof_multi_impl(commitment, coset_for_cell(column_id), cell, proof)
441468
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],
447474
### `recover_polynomial`
448475

449476
```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:
451479
"""
452480
Recovers a polynomial from 2 * FIELD_ELEMENTS_PER_CELL evaluations, half of which can be missing.
453481
@@ -457,7 +485,10 @@ def recover_polynomial(cell_ids: Sequence[CellID], cells: Sequence[Cell]) -> Pol
457485
458486
Public method.
459487
"""
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+
461492
assert len(cells) >= CELLS_PER_BLOB // 2
462493
missing_cell_ids = [cell_id for cell_id in range(CELLS_PER_BLOB) if cell_id not in cell_ids]
463494
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
506537

507538
eval_shifted_extended_evaluation = fft_field(shifted_extended_evaluation, roots_of_unity_extended)
508539
eval_shifted_zero_poly = fft_field(shifted_zero_poly, roots_of_unity_extended)
509-
540+
510541
eval_shifted_reconstructed_poly = [
511542
div(a, b)
512543
for a, b in zip(eval_shifted_extended_evaluation, eval_shifted_zero_poly)

specs/deneb/polynomial-commitments.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ def verify_blob_kzg_proof_batch(blobs: Sequence[Blob],
578578
"""
579579

580580
assert len(blobs) == len(commitments_bytes) == len(proofs_bytes)
581-
581+
582582
commitments, evaluation_challenges, ys, proofs = [], [], [], []
583583
for blob, commitment_bytes, proof_bytes in zip(blobs, commitments_bytes, proofs_bytes):
584584
assert len(blob) == BYTES_PER_BLOB

tests/core/pyspec/eth2spec/test/eip7594/unittests/polynomial_commitments/test_polynomial_commitments.py

+20-10
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
from eth2spec.utils.bls import BLS_MODULUS
1111

1212

13+
def field_element_bytes(x):
14+
return int.to_bytes(x % BLS_MODULUS, 32, "big")
15+
16+
1317
@with_eip7594_and_later
1418
@spec_test
1519
@single_phase
@@ -34,10 +38,13 @@ def test_verify_cell_proof(spec):
3438
blob = get_sample_blob(spec)
3539
commitment = spec.blob_to_kzg_commitment(blob)
3640
cells, proofs = spec.compute_cells_and_proofs(blob)
41+
42+
cells_bytes = [[field_element_bytes(element) for element in cell] for cell in cells]
43+
3744
cell_id = 0
38-
assert spec.verify_cell_proof(commitment, cell_id, cells[cell_id], proofs[cell_id])
45+
assert spec.verify_cell_proof(commitment, cell_id, cells_bytes[cell_id], proofs[cell_id])
3946
cell_id = 1
40-
assert spec.verify_cell_proof(commitment, cell_id, cells[cell_id], proofs[cell_id])
47+
assert spec.verify_cell_proof(commitment, cell_id, cells_bytes[cell_id], proofs[cell_id])
4148

4249

4350
@with_eip7594_and_later
@@ -47,13 +54,16 @@ def test_verify_cell_proof_batch(spec):
4754
blob = get_sample_blob(spec)
4855
commitment = spec.blob_to_kzg_commitment(blob)
4956
cells, proofs = spec.compute_cells_and_proofs(blob)
57+
cells_bytes = [[field_element_bytes(element) for element in cell] for cell in cells]
58+
59+
assert len(cells) == len(proofs)
5060

5161
assert spec.verify_cell_proof_batch(
52-
row_commitments=[commitment],
53-
row_ids=[0],
54-
column_ids=[0, 1],
55-
cells=cells[0:1],
56-
proofs=proofs,
62+
row_commitments_bytes=[commitment],
63+
row_ids=[0, 0],
64+
column_ids=[0, 4],
65+
cells_bytes=[cells_bytes[0], cells_bytes[4]],
66+
proofs_bytes=[proofs[0], proofs[4]],
5767
)
5868

5969

@@ -73,21 +83,21 @@ def test_recover_polynomial(spec):
7383

7484
# Extend data with Reed-Solomon and split the extended data in cells
7585
cells = spec.compute_cells(blob)
86+
cells_bytes = [[field_element_bytes(element) for element in cell] for cell in cells]
7687

7788
# Compute the cells we will be recovering from
7889
cell_ids = []
79-
known_cells = []
8090
# First figure out just the indices of the cells
8191
for i in range(N_SAMPLES):
8292
j = rng.randint(0, spec.CELLS_PER_BLOB)
8393
while j in cell_ids:
8494
j = rng.randint(0, spec.CELLS_PER_BLOB)
8595
cell_ids.append(j)
8696
# Now the cells themselves
87-
known_cells = [cells[cell_id] for cell_id in cell_ids]
97+
known_cells_bytes = [cells_bytes[cell_id] for cell_id in cell_ids]
8898

8999
# Recover the data
90-
recovered_data = spec.recover_polynomial(cell_ids, known_cells)
100+
recovered_data = spec.recover_polynomial(cell_ids, known_cells_bytes)
91101

92102
# Check that the original data match the non-extended portion of the recovered data
93103
assert original_polynomial == recovered_data[:len(recovered_data) // 2]

0 commit comments

Comments
 (0)