@@ -520,22 +520,28 @@ def recover_shifted_data(cell_ids: Sequence[CellID],
520520 Sequence[BLSFieldElement],
521521 Sequence[BLSFieldElement],
522522 BLSFieldElement]:
523+ """
524+ Given Z(x), return polynomial Q_1(x)=(E*Z)(k*x) and Q_2(x)=Z(k*x) and k^{-1}
525+ """
526+ shift_factor = BLSFieldElement(PRIMITIVE_ROOT_OF_UNITY )
527+ shift_inv = div(BLSFieldElement(1 ), shift_factor)
528+
523529 extended_evaluation_rbo = [0 ] * (FIELD_ELEMENTS_PER_BLOB * 2 )
524530 for cell_id, cell in zip (cell_ids, cells):
525531 start = cell_id * FIELD_ELEMENTS_PER_CELL
526532 end = (cell_id + 1 ) * FIELD_ELEMENTS_PER_CELL
527533 extended_evaluation_rbo[start:end] = cell
528534 extended_evaluation = bit_reversal_permutation(extended_evaluation_rbo)
529535
536+ # Compute (E*Z)(x)
530537 extended_evaluation_times_zero = [BLSFieldElement(int (a) * int (b) % BLS_MODULUS )
531538 for a, b in zip (zero_poly_eval, extended_evaluation)]
532539
533540 extended_evaluations_fft = fft_field(extended_evaluation_times_zero, roots_of_unity_extended, inv = True )
534541
535- shift_factor = BLSFieldElement(PRIMITIVE_ROOT_OF_UNITY )
536- shift_inv = div(BLSFieldElement(1 ), shift_factor)
537-
542+ # Compute (E*Z)(k*x)
538543 shifted_extended_evaluation = shift_polynomialcoeff(extended_evaluations_fft, shift_factor)
544+ # Compute Z(k*x)
539545 shifted_zero_poly = shift_polynomialcoeff(zero_poly_coeff, shift_factor)
540546
541547 eval_shifted_extended_evaluation = fft_field(shifted_extended_evaluation, roots_of_unity_extended)
@@ -551,13 +557,18 @@ def recover_original_data(eval_shifted_extended_evaluation: Sequence[BLSFieldEle
551557 eval_shifted_zero_poly : Sequence[BLSFieldElement],
552558 shift_inv : BLSFieldElement,
553559 roots_of_unity_extended : Sequence[BLSFieldElement]) -> Sequence[BLSFieldElement]:
560+ """
561+ Given Q_1, Q_2 and k^{-1}, compute P(x)
562+ """
563+ # Compute Q_3 = Q_1(x)/Q_2(x) = P(k*x)
554564 eval_shifted_reconstructed_poly = [
555565 div(a, b)
556566 for a, b in zip (eval_shifted_extended_evaluation, eval_shifted_zero_poly)
557567 ]
558568
559569 shifted_reconstructed_poly = fft_field(eval_shifted_reconstructed_poly, roots_of_unity_extended, inv = True )
560570
571+ # Unshift P(k*x) by k^{-1} to get P(x)
561572 reconstructed_poly = shift_polynomialcoeff(shifted_reconstructed_poly, shift_inv)
562573
563574 reconstructed_data = bit_reversal_permutation(fft_field(reconstructed_poly, roots_of_unity_extended))
@@ -571,10 +582,11 @@ def recover_original_data(eval_shifted_extended_evaluation: Sequence[BLSFieldEle
571582def recover_polynomial (cell_ids : Sequence[CellID],
572583 cells_bytes : Sequence[Vector[Bytes32, FIELD_ELEMENTS_PER_CELL ]]) -> Polynomial:
573584 """
574- Recovers a polynomial from 2 * FIELD_ELEMENTS_PER_CELL evaluations, half of which can be missing.
585+ Recover original polynomial from 2 * FIELD_ELEMENTS_PER_CELL evaluations, half of which can be missing. This
586+ algorithm uses FFTs to recover cells faster than using Lagrange implementation, as can be seen here:
587+ https://ethresear.ch/t/reed-solomon-erasure-code-recovery-in-n-log-2-n-time-with-ffts/3039
575588
576- This algorithm uses FFTs to recover cells faster than using Lagrange implementation. However,
577- a faster version thanks to Qi Zhou can be found here:
589+ A faster version thanks to Qi Zhou can be found here:
578590 https://github.com/ethereum/research/blob/51b530a53bd4147d123ab3e390a9d08605c2cdb8/polynomial_reconstruction/polynomial_reconstruction_danksharding.py
579591
580592 Public method.
0 commit comments