Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate new CosetEvals type #3701

Merged
merged 17 commits into from
Apr 22, 2024
Merged
9 changes: 4 additions & 5 deletions specs/_features/eip7594/das-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ We define the following Python custom types for type hinting and readability:

| Name | SSZ equivalent | Description |
| - | - | - |
| `DataColumn` | `List[Cell, MAX_BLOB_COMMITMENTS_PER_BLOCK]` | The data of each column in EIP-7594 |
| `ExtendedMatrix` | `List[Cell, MAX_BLOBS_PER_BLOCK * NUMBER_OF_COLUMNS]` | The full data of one-dimensional erasure coding extended blobs (in row major format) |
| `DataColumn` | `List[CellBytes, MAX_BLOB_COMMITMENTS_PER_BLOCK]` | The data of each column in EIP-7594 |
| `ExtendedMatrix` | `List[CellBytes, MAX_BLOBS_PER_BLOCK * NUMBER_OF_COLUMNS]` | The full data of one-dimensional erasure coding extended blobs (in row major format) |

## Configuration

Expand Down Expand Up @@ -131,7 +131,7 @@ def compute_extended_matrix(blobs: Sequence[Blob]) -> ExtendedMatrix:
#### `recover_matrix`

```python
def recover_matrix(cells_dict: Dict[Tuple[BlobIndex, CellID], Cell], blob_count: uint64) -> ExtendedMatrix:
def recover_matrix(cells_dict: Dict[Tuple[BlobIndex, CellID], CellBytes], blob_count: uint64) -> ExtendedMatrix:
"""
Return the recovered ``ExtendedMatrix``.

Expand All @@ -141,8 +141,7 @@ def recover_matrix(cells_dict: Dict[Tuple[BlobIndex, CellID], Cell], blob_count:
extended_matrix = []
for blob_index in range(blob_count):
cell_ids = [cell_id for b_index, cell_id in cells_dict.keys() if b_index == blob_index]
cells = [cells_dict[(blob_index, cell_id)] for cell_id in cell_ids]
cells_bytes = [[bls_field_to_bytes(element) for element in cell] for cell in cells]
cells_bytes = [cells_dict[(blob_index, cell_id)] for cell_id in cell_ids]

full_polynomial = recover_polynomial(cell_ids, cells_bytes)
cells_from_full_polynomial = [
Expand Down
40 changes: 30 additions & 10 deletions specs/_features/eip7594/polynomial-commitments-sampling.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ Public functions MUST accept raw bytes as input and perform the required cryptog
| - | - | - |
| `PolynomialCoeff` | `List[BLSFieldElement, FIELD_ELEMENTS_PER_EXT_BLOB]` | A polynomial in coefficient form |
| `Cell` | `Vector[BLSFieldElement, FIELD_ELEMENTS_PER_CELL]` | The unit of blob data that can come with their own KZG proofs |
| `CellBytes` | `ByteVector[BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_CELL]` | The flattened bytes representation of a cell |
| `CellID` | `uint64` | Cell identifier |
| `RowIndex` | `uint64` | Row identifier |
| `ColumnIndex` | `uint64` | Column identifier |
Expand Down Expand Up @@ -94,11 +95,26 @@ Cells are the smallest unit of blob data that can come with their own KZG proofs
#### `bytes_to_cell`

```python
def bytes_to_cell(cell_bytes: Vector[Bytes32, FIELD_ELEMENTS_PER_CELL]) -> Cell:
def bytes_to_cell(cell_bytes: CellBytes) -> Cell:
"""
Convert untrusted bytes into a Cell.
"""
return [bytes_to_bls_field(element) for element in cell_bytes]
cell = Cell()
jtraglia marked this conversation as resolved.
Show resolved Hide resolved
for i in range(FIELD_ELEMENTS_PER_CELL):
value = bytes_to_bls_field(cell_bytes[i * BYTES_PER_FIELD_ELEMENT: (i + 1) * BYTES_PER_FIELD_ELEMENT])
cell[i] = value
return cell
jtraglia marked this conversation as resolved.
Show resolved Hide resolved
```

```python
def cell_to_bytes(cell: Cell) -> CellBytes:
"""
Convert a Cell into bytes.
"""
cell_bytes = b""
jtraglia marked this conversation as resolved.
Show resolved Hide resolved
for i in range(FIELD_ELEMENTS_PER_CELL):
cell_bytes += bls_field_to_bytes(cell[i])
return cell_bytes
jtraglia marked this conversation as resolved.
Show resolved Hide resolved
```

### Linear combinations
Expand Down Expand Up @@ -374,7 +390,7 @@ def coset_for_cell(cell_id: CellID) -> Cell:

```python
def compute_cells_and_proofs(blob: Blob) -> Tuple[
Vector[Cell, CELLS_PER_BLOB],
Vector[CellBytes, CELLS_PER_BLOB],
Vector[KZGProof, CELLS_PER_BLOB]]:
"""
Compute all the cell proofs for one blob. This is an inefficient O(n^2) algorithm,
Expand All @@ -392,7 +408,7 @@ def compute_cells_and_proofs(blob: Blob) -> Tuple[
for i in range(CELLS_PER_BLOB):
coset = coset_for_cell(i)
proof, ys = compute_kzg_proof_multi_impl(polynomial_coeff, coset)
cells.append(ys)
cells.append(cell_to_bytes(ys))
proofs.append(proof)

return cells, proofs
Expand All @@ -401,7 +417,7 @@ def compute_cells_and_proofs(blob: Blob) -> Tuple[
#### `compute_cells`

```python
def compute_cells(blob: Blob) -> Vector[Cell, CELLS_PER_BLOB]:
def compute_cells(blob: Blob) -> Vector[CellBytes, CELLS_PER_BLOB]:
"""
Compute the cell data for a blob (without computing the proofs).

Expand All @@ -413,8 +429,12 @@ def compute_cells(blob: Blob) -> Vector[Cell, CELLS_PER_BLOB]:
extended_data = fft_field(polynomial_coeff + [0] * FIELD_ELEMENTS_PER_BLOB,
compute_roots_of_unity(FIELD_ELEMENTS_PER_EXT_BLOB))
extended_data_rbo = bit_reversal_permutation(extended_data)
return [extended_data_rbo[i * FIELD_ELEMENTS_PER_CELL:(i + 1) * FIELD_ELEMENTS_PER_CELL]
for i in range(CELLS_PER_BLOB)]
cells = []
for cell_id in range(CELLS_PER_BLOB):
start = cell_id * FIELD_ELEMENTS_PER_CELL
end = (cell_id + 1) * FIELD_ELEMENTS_PER_CELL
cells.append(cell_to_bytes(extended_data_rbo[start:end]))
return cells
```

### Cell verification
Expand All @@ -424,7 +444,7 @@ def compute_cells(blob: Blob) -> Vector[Cell, CELLS_PER_BLOB]:
```python
def verify_cell_proof(commitment_bytes: Bytes48,
cell_id: CellID,
cell_bytes: Vector[Bytes32, FIELD_ELEMENTS_PER_CELL],
cell_bytes: CellBytes,
proof_bytes: Bytes48) -> bool:
"""
Check a cell proof
Expand All @@ -446,7 +466,7 @@ def verify_cell_proof(commitment_bytes: Bytes48,
def verify_cell_proof_batch(row_commitments_bytes: Sequence[Bytes48],
row_indices: Sequence[RowIndex],
column_indices: Sequence[ColumnIndex],
cells_bytes: Sequence[Vector[Bytes32, FIELD_ELEMENTS_PER_CELL]],
cells_bytes: Sequence[CellBytes],
proofs_bytes: Sequence[Bytes48]) -> bool:
"""
Verify a set of cells, given their corresponding proofs and their coordinates (row_id, column_id) in the blob
Expand Down Expand Up @@ -592,7 +612,7 @@ def recover_original_data(eval_shifted_extended_evaluation: Sequence[BLSFieldEle

```python
def recover_polynomial(cell_ids: Sequence[CellID],
cells_bytes: Sequence[Vector[Bytes32, FIELD_ELEMENTS_PER_CELL]]) -> Polynomial:
cells_bytes: Sequence[CellBytes]) -> Polynomial:
"""
Recover original polynomial from FIELD_ELEMENTS_PER_EXT_BLOB evaluations, half of which can be missing. This
algorithm uses FFTs to recover cells faster than using Lagrange implementation, as can be seen here:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def test_verify_cell_proof(spec):
commitment = spec.blob_to_kzg_commitment(blob)
cells, proofs = spec.compute_cells_and_proofs(blob)

cells_bytes = [[spec.bls_field_to_bytes(element) for element in cell] for cell in cells]
cells_bytes = [spec.cell_to_bytes(cell) for cell in cells]

cell_id = 0
assert spec.verify_cell_proof(commitment, cell_id, cells_bytes[cell_id], proofs[cell_id])
Expand All @@ -51,7 +51,7 @@ def test_verify_cell_proof_batch(spec):
blob = get_sample_blob(spec)
commitment = spec.blob_to_kzg_commitment(blob)
cells, proofs = spec.compute_cells_and_proofs(blob)
cells_bytes = [[spec.bls_field_to_bytes(element) for element in cell] for cell in cells]
cells_bytes = [spec.cell_to_bytes(cell) for cell in cells]

assert len(cells) == len(proofs)

Expand Down Expand Up @@ -80,7 +80,7 @@ def test_recover_polynomial(spec):

# Extend data with Reed-Solomon and split the extended data in cells
cells = spec.compute_cells(blob)
cells_bytes = [[spec.bls_field_to_bytes(element) for element in cell] for cell in cells]
cells_bytes = [spec.cell_to_bytes(cell) for cell in cells]

# Compute the cells we will be recovering from
cell_ids = []
Expand Down
Loading