@@ -477,34 +477,40 @@ def verify_cell_proof_batch(row_commitments_bytes: Sequence[Bytes48],
477477### ` construct_vanishing_polynomial `
478478
479479``` python
480- def construct_vanishing_polynomial (cell_ids : Sequence[CellID],
481- cells : Sequence[Cell]) -> Tuple[
482- Sequence[BLSFieldElement],
483- Sequence[BLSFieldElement]]:
484- missing_cell_ids = [cell_id for cell_id in range (CELLS_PER_BLOB ) if cell_id not in cell_ids]
480+ def construct_vanishing_polynomial (missing_cell_ids : Sequence[CellID]) -> Tuple[
481+ Sequence[BLSFieldElement],
482+ Sequence[BLSFieldElement]]:
483+ """
484+ Given the cells that are missing from the data, compute the polynomial that vanishes at every point that
485+ corresponds to a missing field element
486+ """
487+ # Get the small domain
485488 roots_of_unity_reduced = compute_roots_of_unity(CELLS_PER_BLOB )
489+
490+ # Compute polynomial that vanishes at all the missing cells (over the small domain)
486491 short_zero_poly = vanishing_polynomialcoeff([
487- roots_of_unity_reduced[reverse_bits(cell_id , CELLS_PER_BLOB )]
488- for cell_id in missing_cell_ids
492+ roots_of_unity_reduced[reverse_bits(missing_cell_id , CELLS_PER_BLOB )]
493+ for missing_cell_id in missing_cell_ids
489494 ])
490495
491- zero_poly_coeff = []
492- for i in short_zero_poly:
493- zero_poly_coeff.append(i)
494- zero_poly_coeff.extend([0 ] * (FIELD_ELEMENTS_PER_CELL - 1 ))
495- zero_poly_coeff = zero_poly_coeff + [0 ] * (2 * FIELD_ELEMENTS_PER_BLOB - len (zero_poly_coeff))
496+ # Extend vanishing polynomial to full domain using the closed form of the vanishing polynomial over a coset
497+ zero_poly_coeff = [0 ] * (FIELD_ELEMENTS_PER_BLOB * 2 )
498+ for (i, coeff) in enumerate (short_zero_poly):
499+ zero_poly_coeff[i * FIELD_ELEMENTS_PER_CELL ] = coeff
496500
501+ # Compute evaluations of the extended vanishing polynomial
497502 zero_poly_eval = fft_field(zero_poly_coeff,
498503 compute_roots_of_unity(2 * FIELD_ELEMENTS_PER_BLOB ))
499504 zero_poly_eval_brp = bit_reversal_permutation(zero_poly_eval)
500- for cell_id in missing_cell_ids:
501- start = cell_id * FIELD_ELEMENTS_PER_CELL
502- end = (cell_id + 1 ) * FIELD_ELEMENTS_PER_CELL
503- assert zero_poly_eval_brp[start:end] == [0 ] * FIELD_ELEMENTS_PER_CELL
504- for cell_id in cell_ids:
505+
506+ # Sanity check
507+ for cell_id in range (CELLS_PER_BLOB ):
505508 start = cell_id * FIELD_ELEMENTS_PER_CELL
506509 end = (cell_id + 1 ) * FIELD_ELEMENTS_PER_CELL
507- assert all (a != 0 for a in zero_poly_eval_brp[start:end])
510+ if cell_id in missing_cell_ids:
511+ assert zero_poly_eval_brp[start:end] == [0 ] * FIELD_ELEMENTS_PER_CELL
512+ else : # cell_id in cell_ids
513+ assert all (a != 0 for a in zero_poly_eval_brp[start:end])
508514
509515 return zero_poly_coeff, zero_poly_eval, zero_poly_eval_brp
510516```
@@ -593,12 +599,15 @@ def recover_polynomial(cell_ids: Sequence[CellID],
593599 """
594600 assert len (cell_ids) == len (cells_bytes)
595601
602+ # Get the extended domain
603+ roots_of_unity_extended = compute_roots_of_unity(2 * FIELD_ELEMENTS_PER_BLOB )
604+
605+ # Convert from bytes to cells
596606 cells = [bytes_to_cell(cell_bytes) for cell_bytes in cells_bytes]
597607 assert len (cells) >= CELLS_PER_BLOB // 2
598608
599- roots_of_unity_extended = compute_roots_of_unity(2 * FIELD_ELEMENTS_PER_BLOB )
600-
601- zero_poly_coeff, zero_poly_eval, zero_poly_eval_brp = construct_vanishing_polynomial(cell_ids, cells)
609+ missing_cell_ids = [cell_id for cell_id in range (CELLS_PER_BLOB ) if cell_id not in cell_ids]
610+ zero_poly_coeff, zero_poly_eval, zero_poly_eval_brp = construct_vanishing_polynomial(missing_cell_ids)
602611
603612 eval_shifted_extended_evaluation, eval_shifted_zero_poly, shift_inv = \
604613 recover_shifted_data(cell_ids, cells, zero_poly_eval, zero_poly_coeff, roots_of_unity_extended)
0 commit comments