diff --git a/specs/_features/eip7594/polynomial-commitments-sampling.md b/specs/_features/eip7594/polynomial-commitments-sampling.md index 05ddc55e0a..b2d86241d7 100644 --- a/specs/_features/eip7594/polynomial-commitments-sampling.md +++ b/specs/_features/eip7594/polynomial-commitments-sampling.md @@ -576,6 +576,20 @@ def construct_vanishing_polynomial(missing_cell_ids: Sequence[CellID]) -> Sequen Given the cells IDs that are missing from the data, compute the polynomial that vanishes at every point that corresponds to a missing field element. """ + + # If all of the cells are missing, then the vanishing polynomial + # can be computed as Z(x) = x^n - 1, where `n` is FIELD_ELEMENTS_PER_EXT_BLOB + # + # Note: this makes the function complete on all inputs, however this code path should not + # be hit since this method is used for data recovery and if all of the + # cells are missing, then we can return early. + if len(missing_cell_ids) == CELLS_PER_EXT_BLOB: + z_x = [BLSFieldElement(0)] * (FIELD_ELEMENTS_PER_EXT_BLOB + 1) + z_x[0] = BLS_MODULUS - 1 + z_x[-1] = 1 + + return z_x + # Get the small domain roots_of_unity_reduced = compute_roots_of_unity(CELLS_PER_EXT_BLOB) @@ -618,11 +632,10 @@ def recover_data(cell_ids: Sequence[CellID], # Compute Z(x) in monomial form # Z(x) is the polynomial which vanishes on all of the evaluations which are missing missing_cell_ids = [CellID(cell_id) for cell_id in range(CELLS_PER_EXT_BLOB) if cell_id not in cell_ids] - zero_poly_coeff = construct_vanishing_polynomial(missing_cell_ids) + zero_poly_coeff = construct_vanishing_polynomial(missing_cell_ids) # Convert Z(x) to evaluation form over the FFT domain zero_poly_eval = fft_field(zero_poly_coeff, roots_of_unity_extended) - # Compute (E*Z)(x) = E(x) * Z(x) in evaluation form over the FFT domain extended_evaluation_times_zero = [BLSFieldElement(int(a) * int(b) % BLS_MODULUS) for a, b in zip(zero_poly_eval, extended_evaluation)] diff --git a/tests/core/pyspec/eth2spec/test/eip7594/unittests/polynomial_commitments/test_polynomial_commitments.py b/tests/core/pyspec/eth2spec/test/eip7594/unittests/polynomial_commitments/test_polynomial_commitments.py index d9b31c0312..2932af5e5b 100644 --- a/tests/core/pyspec/eth2spec/test/eip7594/unittests/polynomial_commitments/test_polynomial_commitments.py +++ b/tests/core/pyspec/eth2spec/test/eip7594/unittests/polynomial_commitments/test_polynomial_commitments.py @@ -69,6 +69,20 @@ def test_construct_vanishing_polynomial(spec): assert all(a != 0 for a in zero_poly_eval_brp[start:end]) +@with_eip7594_and_later +@spec_test +@single_phase +def test_construct_vanishing_polynomial_all_missing_zeros(spec): + + all_cell_ids = range(spec.CELLS_PER_EXT_BLOB) + + zero_poly_coeff = spec.construct_vanishing_polynomial(all_cell_ids) + roots_of_unity = spec.compute_roots_of_unity(spec.FIELD_ELEMENTS_PER_EXT_BLOB) + zero_poly_eval = spec.fft_field(zero_poly_coeff, roots_of_unity) + + assert all(a == 0 for a in zero_poly_eval) + + @with_eip7594_and_later @spec_test @single_phase