Skip to content

Commit

Permalink
Replace recover_data with recover_polynomialcoeff (#3820)
Browse files Browse the repository at this point in the history
* chore: remove recover_data

* make it look closer to final code

* Improve comments

* Fix lint issue

* Fix tests & clean things up a bit

* Replace a couple uses of "monomial" with "coefficient"

* Revert "Replace a couple uses of "monomial" with "coefficient""

This reverts commit c9a1a75.

* Only replace "monomial" with "coefficient"

---------

Co-authored-by: Justin Traglia <[email protected]>
Co-authored-by: Justin Traglia <[email protected]>
  • Loading branch information
3 people authored Jul 17, 2024
1 parent bb8f3ca commit 2331291
Showing 1 changed file with 41 additions and 56 deletions.
97 changes: 41 additions & 56 deletions specs/_features/eip7594/polynomial-commitments-sampling.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@
- [`coset_for_cell`](#coset_for_cell)
- [Cells](#cells-1)
- [Cell computation](#cell-computation)
- [`compute_cells_and_kzg_proofs_polynomialcoeff`](#compute_cells_and_kzg_proofs_polynomialcoeff)
- [`compute_cells_and_kzg_proofs`](#compute_cells_and_kzg_proofs)
- [Cell verification](#cell-verification)
- [`verify_cell_kzg_proof_batch`](#verify_cell_kzg_proof_batch)
- [Reconstruction](#reconstruction)
- [`construct_vanishing_polynomial`](#construct_vanishing_polynomial)
- [`recover_data`](#recover_data)
- [`recover_polynomialcoeff`](#recover_polynomialcoeff)
- [`recover_cells_and_kzg_proofs`](#recover_cells_and_kzg_proofs)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
Expand Down Expand Up @@ -555,6 +556,24 @@ def coset_for_cell(cell_index: CellIndex) -> Coset:

### Cell computation

#### `compute_cells_and_kzg_proofs_polynomialcoeff`

```python
def compute_cells_and_kzg_proofs_polynomialcoeff(polynomial_coeff: PolynomialCoeff) -> Tuple[
Vector[Cell, CELLS_PER_EXT_BLOB],
Vector[KZGProof, CELLS_PER_EXT_BLOB]]:
"""
Helper function which computes cells/proofs for a polynomial in coefficient form.
"""
cells, proofs = [], []
for i in range(CELLS_PER_EXT_BLOB):
coset = coset_for_cell(CellIndex(i))
proof, ys = compute_kzg_proof_multi_impl(polynomial_coeff, coset)
cells.append(coset_evals_to_cell(ys))
proofs.append(proof)
return cells, proofs
```

#### `compute_cells_and_kzg_proofs`

```python
Expand All @@ -572,17 +591,7 @@ def compute_cells_and_kzg_proofs(blob: Blob) -> Tuple[

polynomial = blob_to_polynomial(blob)
polynomial_coeff = polynomial_eval_to_coeff(polynomial)

cells = []
proofs = []

for i in range(CELLS_PER_EXT_BLOB):
coset = coset_for_cell(CellIndex(i))
proof, ys = compute_kzg_proof_multi_impl(polynomial_coeff, coset)
cells.append(coset_evals_to_cell(ys))
proofs.append(proof)

return cells, proofs
return compute_cells_and_kzg_proofs_polynomialcoeff(polynomial_coeff)
```

### Cell verification
Expand Down Expand Up @@ -668,29 +677,27 @@ def construct_vanishing_polynomial(missing_cell_indices: Sequence[CellIndex]) ->
return zero_poly_coeff
```

### `recover_data`
### `recover_polynomialcoeff`

```python
def recover_data(cell_indices: Sequence[CellIndex],
cells: Sequence[Cell],
) -> Sequence[BLSFieldElement]:
def recover_polynomialcoeff(cell_indices: Sequence[CellIndex],
cells: Sequence[Cell]) -> Sequence[BLSFieldElement]:
"""
Recover the missing evaluations for the extended blob, given at least half of the evaluations.
Recover the polynomial in coefficient form that when evaluated at the roots of unity will give the extended blob.
"""

# Get the extended domain. This will be referred to as the FFT domain.
# Get the extended domain. This will be referred to as the FFT domain
roots_of_unity_extended = compute_roots_of_unity(FIELD_ELEMENTS_PER_EXT_BLOB)

# Flatten the cells into evaluations.
# If a cell is missing, then its evaluation is zero.
# Flatten the cells into evaluations
# If a cell is missing, then its evaluation is zero
extended_evaluation_rbo = [0] * FIELD_ELEMENTS_PER_EXT_BLOB
for cell_index, cell in zip(cell_indices, cells):
start = cell_index * FIELD_ELEMENTS_PER_CELL
end = (cell_index + 1) * FIELD_ELEMENTS_PER_CELL
extended_evaluation_rbo[start:end] = cell
extended_evaluation = bit_reversal_permutation(extended_evaluation_rbo)

# Compute Z(x) in monomial form
# Compute Z(x) in coefficient form
# Z(x) is the polynomial which vanishes on all of the evaluations which are missing
missing_cell_indices = [CellIndex(cell_index) for cell_index in range(CELLS_PER_EXT_BLOB)
if cell_index not in cell_indices]
Expand All @@ -703,7 +710,7 @@ def recover_data(cell_indices: Sequence[CellIndex],
extended_evaluation_times_zero = [BLSFieldElement(int(a) * int(b) % BLS_MODULUS)
for a, b in zip(zero_poly_eval, extended_evaluation)]

# Convert (E*Z)(x) to monomial form
# Convert (E*Z)(x) to coefficient form
extended_evaluation_times_zero_coeffs = fft_field(extended_evaluation_times_zero, roots_of_unity_extended, inv=True)

# Convert (E*Z)(x) to evaluation form over a coset of the FFT domain
Expand All @@ -713,18 +720,12 @@ def recover_data(cell_indices: Sequence[CellIndex],
zero_poly_over_coset = coset_fft_field(zero_poly_coeff, roots_of_unity_extended)

# Compute Q_3(x) = (E*Z)(x) / Z(x) in evaluation form over a coset of the FFT domain
reconstructed_poly_over_coset = [
div(a, b)
for a, b in zip(extended_evaluations_over_coset, zero_poly_over_coset)
]
reconstructed_poly_over_coset = [div(a, b) for a, b in zip(extended_evaluations_over_coset, zero_poly_over_coset)]

# Convert Q_3(x) to monomial form
# Convert Q_3(x) to coefficient form
reconstructed_poly_coeff = coset_fft_field(reconstructed_poly_over_coset, roots_of_unity_extended, inv=True)

# Convert Q_3(x) to evaluation form over the FFT domain and bit reverse the result
reconstructed_data = bit_reversal_permutation(fft_field(reconstructed_poly_coeff, roots_of_unity_extended))

return reconstructed_data
return reconstructed_poly_coeff[:FIELD_ELEMENTS_PER_BLOB]
```

### `recover_cells_and_kzg_proofs`
Expand All @@ -735,7 +736,7 @@ def recover_cells_and_kzg_proofs(cell_indices: Sequence[CellIndex],
Vector[Cell, CELLS_PER_EXT_BLOB],
Vector[KZGProof, CELLS_PER_EXT_BLOB]]:
"""
Given at least 50% of cells/proofs for a blob, recover all the cells/proofs.
Given at least 50% of cells for a blob, recover all the cells/proofs.
This algorithm uses FFTs to recover cells faster than using Lagrange
implementation, as can be seen here:
https://ethresear.ch/t/reed-solomon-erasure-code-recovery-in-n-log-2-n-time-with-ffts/3039
Expand All @@ -745,6 +746,7 @@ def recover_cells_and_kzg_proofs(cell_indices: Sequence[CellIndex],
Public method.
"""
# Check we have the same number of cells and indices
assert len(cell_indices) == len(cells)
# Check we have enough cells to be able to perform the reconstruction
assert CELLS_PER_EXT_BLOB / 2 <= len(cell_indices) <= CELLS_PER_EXT_BLOB
Expand All @@ -757,29 +759,12 @@ def recover_cells_and_kzg_proofs(cell_indices: Sequence[CellIndex],
for cell in cells:
assert len(cell) == BYTES_PER_CELL

# Convert cells to coset evals
# Convert cells to coset evaluations
cosets_evals = [cell_to_coset_evals(cell) for cell in cells]

reconstructed_data = recover_data(cell_indices, cosets_evals)

for cell_index, coset_evals in zip(cell_indices, cosets_evals):
start = cell_index * FIELD_ELEMENTS_PER_CELL
end = (cell_index + 1) * FIELD_ELEMENTS_PER_CELL
assert reconstructed_data[start:end] == coset_evals

recovered_cells = [
coset_evals_to_cell(reconstructed_data[i * FIELD_ELEMENTS_PER_CELL:(i + 1) * FIELD_ELEMENTS_PER_CELL])
for i in range(CELLS_PER_EXT_BLOB)]

polynomial_eval = reconstructed_data[:FIELD_ELEMENTS_PER_BLOB]
polynomial_coeff = polynomial_eval_to_coeff(polynomial_eval)
recovered_proofs = [None] * CELLS_PER_EXT_BLOB

for i in range(CELLS_PER_EXT_BLOB):
coset = coset_for_cell(CellIndex(i))
proof, ys = compute_kzg_proof_multi_impl(polynomial_coeff, coset)
assert coset_evals_to_cell(ys) == recovered_cells[i]
recovered_proofs[i] = proof

return recovered_cells, recovered_proofs
# Given the coset evaluations, recover the polynomial in coefficient form
polynomial_coeff = recover_polynomialcoeff(cell_indices, cosets_evals)

# Recompute all cells/proofs
return compute_cells_and_kzg_proofs_polynomialcoeff(polynomial_coeff)
```

0 comments on commit 2331291

Please sign in to comment.