diff --git a/specs/fulu/polynomial-commitments-sampling.md b/specs/fulu/polynomial-commitments-sampling.md index 4ef9f40cdd..f8cab9a7aa 100644 --- a/specs/fulu/polynomial-commitments-sampling.md +++ b/specs/fulu/polynomial-commitments-sampling.md @@ -39,6 +39,7 @@ - [`coset_for_cell`](#coset_for_cell) - [Cells](#cells-1) - [Cell computation](#cell-computation) + - [`compute_cells`](#compute_cells) - [`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) @@ -520,6 +521,28 @@ def coset_for_cell(cell_index: CellIndex) -> Coset: ### Cell computation +#### `compute_cells` + +```python +def compute_cells(blob: Blob) -> Vector[Cell, CELLS_PER_EXT_BLOB]: + """ + Given a blob, extend it and return all the cells of the extended blob. + + Public method. + """ + assert len(blob) == BYTES_PER_BLOB + + polynomial = blob_to_polynomial(blob) + polynomial_coeff = polynomial_eval_to_coeff(polynomial) + + cells = [] + for i in range(CELLS_PER_EXT_BLOB): + coset = coset_for_cell(CellIndex(i)) + ys = CosetEvals([evaluate_polynomialcoeff(polynomial_coeff, z) for z in coset]) + cells.append(coset_evals_to_cell(CosetEvals(ys))) + return cells +``` + #### `compute_cells_and_kzg_proofs_polynomialcoeff` ```python diff --git a/tests/formats/kzg_7594/compute_cells.md b/tests/formats/kzg_7594/compute_cells.md new file mode 100644 index 0000000000..aec118c20b --- /dev/null +++ b/tests/formats/kzg_7594/compute_cells.md @@ -0,0 +1,22 @@ +# Test format: Compute cells + +Compute the cells for a given `blob`. + +## Test case format + +The test data is declared in a `data.yaml` file: + +```yaml +input: + blob: Blob -- the data blob +output: List[Cell] -- the cells +``` + +- `Blob` is a 131072-byte hexadecimal string, prefixed with `0x`. +- `Cell` is a 2048-byte hexadecimal string, prefixed with `0x`. + +All byte(s) fields are encoded as strings, hexadecimal encoding, prefixed with `0x`. + +## Condition + +The `compute_cells` handler should compute the cells (chunks of an extended blob) for `blob`, and the result should match the expected `output`. If the blob is invalid (e.g. incorrect length or one of the 32-byte blocks does not represent a BLS field element) it should error, i.e. the output should be `null`. diff --git a/tests/generators/kzg_7594/main.py b/tests/generators/kzg_7594/main.py index 0c7222fd21..4d4973ea26 100644 --- a/tests/generators/kzg_7594/main.py +++ b/tests/generators/kzg_7594/main.py @@ -27,6 +27,34 @@ from eth2spec.utils import bls +############################################################################### +# Test cases for compute_cells +############################################################################### + +def case_compute_cells(): + # Valid cases + for blob in VALID_BLOBS: + cells = spec.compute_cells(blob) + identifier = make_id(blob) + yield f'compute_cells_case_valid_{identifier}', { + 'input': { + 'blob': encode_hex(blob), + }, + 'output': encode_hex_list(cells) + } + + # Edge case: Invalid blobs + for blob in INVALID_BLOBS: + expect_exception(spec.compute_cells, blob) + identifier = make_id(blob) + yield f'compute_cells_invalid_blob_{identifier}', { + 'input': { + 'blob': encode_hex(blob) + }, + 'output': None + } + + ############################################################################### # Test cases for compute_cells_and_kzg_proofs ############################################################################### @@ -565,6 +593,7 @@ def cases_fn() -> Iterable[gen_typing.TestCase]: if __name__ == "__main__": bls.use_arkworks() gen_runner.run_generator("kzg_7594", [ + create_provider(FULU, 'compute_cells', case_compute_cells), create_provider(FULU, 'compute_cells_and_kzg_proofs', case_compute_cells_and_kzg_proofs), create_provider(FULU, 'verify_cell_kzg_proof_batch', case_verify_cell_kzg_proof_batch), create_provider(FULU, 'recover_cells_and_kzg_proofs', case_recover_cells_and_kzg_proofs),