diff --git a/tests/core/pyspec/eth2spec/test/fulu/kzg/__init__.py b/tests/core/pyspec/eth2spec/test/fulu/kzg/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/core/pyspec/eth2spec/test/fulu/kzg/test_compute_cells.py b/tests/core/pyspec/eth2spec/test/fulu/kzg/test_compute_cells.py new file mode 100644 index 0000000000..0e50225454 --- /dev/null +++ b/tests/core/pyspec/eth2spec/test/fulu/kzg/test_compute_cells.py @@ -0,0 +1,75 @@ +from eth_utils import encode_hex + +from eth2spec.test.context import only_generator, single_phase, spec_test, with_phases +from eth2spec.test.helpers.constants import FULU +from eth2spec.test.utils.kzg_tests import ( + encode_hex_list, + INVALID_BLOBS, + VALID_BLOBS, +) +from tests.infra.manifest import manifest +from tests.infra.template_test import template_test + + +@template_test +def _compute_cells_case_valid(blob_index): + blob = VALID_BLOBS[blob_index] + + @manifest(preset_name="general", suite_name="kzg-mainnet") + @only_generator("too slow") + @with_phases([FULU]) + @spec_test + @single_phase + def the_test(spec): + cells = spec.compute_cells(blob) + + yield ( + "data", + "data", + { + "input": { + "blob": encode_hex(blob), + }, + "output": encode_hex_list(cells), + }, + ) + + return (the_test, f"test_compute_cells_case_valid_{blob_index}") + + +for blob_index in range(len(VALID_BLOBS)): + _compute_cells_case_valid(blob_index) + + +@template_test +def _compute_cells_invalid_blob(blob_index): + blob = INVALID_BLOBS[blob_index] + + @manifest(preset_name="general", suite_name="kzg-mainnet") + @only_generator("too slow") + @with_phases([FULU]) + @spec_test + @single_phase + def the_test(spec): + try: + spec.compute_cells(blob) + assert False, "Expected exception not thrown" + except Exception: + pass + + yield ( + "data", + "data", + { + "input": { + "blob": encode_hex(blob), + }, + "output": None, + }, + ) + + return (the_test, f"test_compute_cells_invalid_blob_{blob_index}") + + +for blob_index in range(len(INVALID_BLOBS)): + _compute_cells_invalid_blob(blob_index) diff --git a/tests/core/pyspec/eth2spec/test/fulu/kzg/test_compute_cells_and_kzg_proofs.py b/tests/core/pyspec/eth2spec/test/fulu/kzg/test_compute_cells_and_kzg_proofs.py new file mode 100644 index 0000000000..7f5407a003 --- /dev/null +++ b/tests/core/pyspec/eth2spec/test/fulu/kzg/test_compute_cells_and_kzg_proofs.py @@ -0,0 +1,75 @@ +from eth_utils import encode_hex + +from eth2spec.test.context import only_generator, single_phase, spec_test, with_phases +from eth2spec.test.helpers.constants import FULU +from eth2spec.test.utils.kzg_tests import ( + encode_hex_list, + INVALID_BLOBS, + VALID_BLOBS, +) +from tests.infra.manifest import manifest +from tests.infra.template_test import template_test + + +@template_test +def _compute_cells_and_kzg_proofs_case_valid(blob_index): + blob = VALID_BLOBS[blob_index] + + @manifest(preset_name="general", suite_name="kzg-mainnet") + @only_generator("too slow") + @with_phases([FULU]) + @spec_test + @single_phase + def the_test(spec): + cells, proofs = spec.compute_cells_and_kzg_proofs(blob) + + yield ( + "data", + "data", + { + "input": { + "blob": encode_hex(blob), + }, + "output": (encode_hex_list(cells), encode_hex_list(proofs)), + }, + ) + + return (the_test, f"test_compute_cells_and_kzg_proofs_case_valid_{blob_index}") + + +for blob_index in range(len(VALID_BLOBS)): + _compute_cells_and_kzg_proofs_case_valid(blob_index) + + +@template_test +def _compute_cells_and_kzg_proofs_case_invalid_blob(blob_index): + blob = INVALID_BLOBS[blob_index] + + @manifest(preset_name="general", suite_name="kzg-mainnet") + @only_generator("too slow") + @with_phases([FULU]) + @spec_test + @single_phase + def the_test(spec): + try: + spec.compute_cells_and_kzg_proofs(blob) + assert False, "Expected exception not thrown" + except Exception: + pass + + yield ( + "data", + "data", + { + "input": { + "blob": encode_hex(blob), + }, + "output": None, + }, + ) + + return (the_test, f"test_compute_cells_and_kzg_proofs_case_invalid_blob_{blob_index}") + + +for blob_index in range(len(INVALID_BLOBS)): + _compute_cells_and_kzg_proofs_case_invalid_blob(blob_index) diff --git a/tests/core/pyspec/eth2spec/test/fulu/kzg/test_compute_verify_cell_kzg_proof_batch_challenge.py b/tests/core/pyspec/eth2spec/test/fulu/kzg/test_compute_verify_cell_kzg_proof_batch_challenge.py new file mode 100644 index 0000000000..1cb6cd5fb6 --- /dev/null +++ b/tests/core/pyspec/eth2spec/test/fulu/kzg/test_compute_verify_cell_kzg_proof_batch_challenge.py @@ -0,0 +1,334 @@ +from eth_utils import encode_hex + +from eth2spec.test.context import only_generator, single_phase, spec_test, with_phases +from eth2spec.test.helpers.constants import FULU +from eth2spec.test.utils.kzg_tests import ( + encode_hex_list, + VALID_BLOBS, +) +from tests.infra.manifest import manifest + + +def _run_compute_verify_cell_kzg_proof_batch_challenge_test( + spec, commitments, commitment_indices, cell_indices, cosets_evals, proofs, valid: bool = True +): + if valid: + challenge = spec.compute_verify_cell_kzg_proof_batch_challenge( + commitments, commitment_indices, cell_indices, cosets_evals, proofs + ) + else: + try: + challenge = spec.compute_verify_cell_kzg_proof_batch_challenge( + commitments, commitment_indices, cell_indices, cosets_evals, proofs + ) + assert False, "should raise exception" + except Exception: + pass + + yield ( + "data", + "data", + { + "input": { + "commitments": encode_hex_list(commitments), + "commitment_indices": commitment_indices, + "cell_indices": cell_indices, + "cosets_evals": [ + [encode_hex(spec.bls_field_to_bytes(eval)) for eval in coset_evals] + for coset_evals in cosets_evals + ], + "proofs": encode_hex_list(proofs), + }, + "output": encode_hex(spec.bls_field_to_bytes(challenge)) if valid else None, + }, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_compute_verify_cell_kzg_proof_batch_challenge_case_empty(spec): + yield from _run_compute_verify_cell_kzg_proof_batch_challenge_test( + spec, + [], + [], + [], + [], + [], + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_compute_verify_cell_kzg_proof_batch_challenge_case_single_cell(spec): + blob = VALID_BLOBS[0] + cells, proofs = spec.compute_cells_and_kzg_proofs(blob) + commitment = spec.blob_to_kzg_commitment(blob) + + commitments = [commitment] + commitment_indices = [0] + cell_indices = [0] + cosets_evals = [spec.cell_to_coset_evals(cells[0])] + proofs_selected = [proofs[0]] + + yield from _run_compute_verify_cell_kzg_proof_batch_challenge_test( + spec, + commitments, + commitment_indices, + cell_indices, + cosets_evals, + proofs_selected, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_compute_verify_cell_kzg_proof_batch_challenge_case_multiple_cells_single_blob(spec): + blob = VALID_BLOBS[1] + cells, proofs = spec.compute_cells_and_kzg_proofs(blob) + commitment = spec.blob_to_kzg_commitment(blob) + + num_cells = 4 + commitments = [commitment] + commitment_indices = [0] * num_cells + cell_indices = list(range(num_cells)) + cosets_evals = [spec.cell_to_coset_evals(cells[i]) for i in range(num_cells)] + proofs_selected = [proofs[i] for i in range(num_cells)] + + yield from _run_compute_verify_cell_kzg_proof_batch_challenge_test( + spec, + commitments, + commitment_indices, + cell_indices, + cosets_evals, + proofs_selected, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_compute_verify_cell_kzg_proof_batch_challenge_case_multiple_cells_multiple_blobs(spec): + blob0 = VALID_BLOBS[2] + blob1 = VALID_BLOBS[3] + cells0, proofs0 = spec.compute_cells_and_kzg_proofs(blob0) + cells1, proofs1 = spec.compute_cells_and_kzg_proofs(blob1) + commitment0 = spec.blob_to_kzg_commitment(blob0) + commitment1 = spec.blob_to_kzg_commitment(blob1) + + commitments = [commitment0, commitment1] + commitment_indices = [0, 1, 0, 1] + cell_indices = [0, 1, 2, 3] + cosets_evals = [ + spec.cell_to_coset_evals(cells0[0]), + spec.cell_to_coset_evals(cells1[1]), + spec.cell_to_coset_evals(cells0[2]), + spec.cell_to_coset_evals(cells1[3]), + ] + proofs_selected = [proofs0[0], proofs1[1], proofs0[2], proofs1[3]] + + yield from _run_compute_verify_cell_kzg_proof_batch_challenge_test( + spec, + commitments, + commitment_indices, + cell_indices, + cosets_evals, + proofs_selected, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_compute_verify_cell_kzg_proof_batch_challenge_case_duplicate_cells(spec): + blob = VALID_BLOBS[4] + cells, proofs = spec.compute_cells_and_kzg_proofs(blob) + commitment = spec.blob_to_kzg_commitment(blob) + + num_duplicates = 3 + commitments = [commitment] + commitment_indices = [0] * num_duplicates + cell_indices = [5] * num_duplicates # Same cell index repeated + cosets_evals = [spec.cell_to_coset_evals(cells[5])] * num_duplicates + proofs_selected = [proofs[5]] * num_duplicates + + yield from _run_compute_verify_cell_kzg_proof_batch_challenge_test( + spec, + commitments, + commitment_indices, + cell_indices, + cosets_evals, + proofs_selected, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_compute_verify_cell_kzg_proof_batch_challenge_case_many_cells(spec): + blob = VALID_BLOBS[5] + cells, proofs = spec.compute_cells_and_kzg_proofs(blob) + commitment = spec.blob_to_kzg_commitment(blob) + + # Use half of all cells + num_cells = spec.CELLS_PER_EXT_BLOB // 2 + commitments = [commitment] + commitment_indices = [0] * num_cells + cell_indices = list(range(num_cells)) + cosets_evals = [spec.cell_to_coset_evals(cells[i]) for i in range(num_cells)] + proofs_selected = [proofs[i] for i in range(num_cells)] + + yield from _run_compute_verify_cell_kzg_proof_batch_challenge_test( + spec, + commitments, + commitment_indices, + cell_indices, + cosets_evals, + proofs_selected, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_compute_verify_cell_kzg_proof_batch_challenge_case_non_sequential_indices(spec): + blob = VALID_BLOBS[6] + cells, proofs = spec.compute_cells_and_kzg_proofs(blob) + commitment = spec.blob_to_kzg_commitment(blob) + + # Use non-sequential indices + indices = [10, 5, 20, 15, 0, 30] + commitments = [commitment] + commitment_indices = [0] * len(indices) + cell_indices = indices + cosets_evals = [spec.cell_to_coset_evals(cells[i]) for i in indices] + proofs_selected = [proofs[i] for i in indices] + + yield from _run_compute_verify_cell_kzg_proof_batch_challenge_test( + spec, + commitments, + commitment_indices, + cell_indices, + cosets_evals, + proofs_selected, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_compute_verify_cell_kzg_proof_batch_challenge_case_mixed_commitment_indices(spec): + blob0 = VALID_BLOBS[0] + blob1 = VALID_BLOBS[1] + blob2 = VALID_BLOBS[2] + cells0, proofs0 = spec.compute_cells_and_kzg_proofs(blob0) + cells1, proofs1 = spec.compute_cells_and_kzg_proofs(blob1) + cells2, proofs2 = spec.compute_cells_and_kzg_proofs(blob2) + commitment0 = spec.blob_to_kzg_commitment(blob0) + commitment1 = spec.blob_to_kzg_commitment(blob1) + commitment2 = spec.blob_to_kzg_commitment(blob2) + + # Mix up the order of commitment indices + commitments = [commitment0, commitment1, commitment2] + commitment_indices = [2, 0, 1, 0, 2, 1] + cell_indices = [0, 1, 2, 3, 4, 5] + cosets_evals = [ + spec.cell_to_coset_evals(cells2[0]), + spec.cell_to_coset_evals(cells0[1]), + spec.cell_to_coset_evals(cells1[2]), + spec.cell_to_coset_evals(cells0[3]), + spec.cell_to_coset_evals(cells2[4]), + spec.cell_to_coset_evals(cells1[5]), + ] + proofs_selected = [ + proofs2[0], + proofs0[1], + proofs1[2], + proofs0[3], + proofs2[4], + proofs1[5], + ] + + yield from _run_compute_verify_cell_kzg_proof_batch_challenge_test( + spec, + commitments, + commitment_indices, + cell_indices, + cosets_evals, + proofs_selected, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_compute_verify_cell_kzg_proof_batch_challenge_case_max_cell_indices(spec): + blob = VALID_BLOBS[3] + cells, proofs = spec.compute_cells_and_kzg_proofs(blob) + commitment = spec.blob_to_kzg_commitment(blob) + + # Use the highest valid cell indices + max_index = spec.CELLS_PER_EXT_BLOB - 1 + indices = [max_index, max_index - 1, max_index - 2] + commitments = [commitment] + commitment_indices = [0] * len(indices) + cell_indices = indices + cosets_evals = [spec.cell_to_coset_evals(cells[i]) for i in indices] + proofs_selected = [proofs[i] for i in indices] + + yield from _run_compute_verify_cell_kzg_proof_batch_challenge_test( + spec, + commitments, + commitment_indices, + cell_indices, + cosets_evals, + proofs_selected, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_compute_verify_cell_kzg_proof_batch_challenge_case_all_cells(spec): + blob = VALID_BLOBS[4] + cells, proofs = spec.compute_cells_and_kzg_proofs(blob) + commitment = spec.blob_to_kzg_commitment(blob) + + # Use all cells + num_cells = spec.CELLS_PER_EXT_BLOB + commitments = [commitment] + commitment_indices = [0] * num_cells + cell_indices = list(range(num_cells)) + cosets_evals = [spec.cell_to_coset_evals(cells[i]) for i in range(num_cells)] + proofs_selected = proofs + + yield from _run_compute_verify_cell_kzg_proof_batch_challenge_test( + spec, + commitments, + commitment_indices, + cell_indices, + cosets_evals, + proofs_selected, + ) diff --git a/tests/core/pyspec/eth2spec/test/fulu/kzg/test_recover_cells_and_kzg_proofs.py b/tests/core/pyspec/eth2spec/test/fulu/kzg/test_recover_cells_and_kzg_proofs.py new file mode 100644 index 0000000000..07681e5808 --- /dev/null +++ b/tests/core/pyspec/eth2spec/test/fulu/kzg/test_recover_cells_and_kzg_proofs.py @@ -0,0 +1,354 @@ +import random + +from eth2spec.test.context import only_generator, single_phase, spec_test, with_phases +from eth2spec.test.helpers.constants import FULU +from eth2spec.test.utils.kzg_tests import ( + CELL_RANDOM_VALID1, + encode_hex_list, + INVALID_INDIVIDUAL_CELL_BYTES, + VALID_BLOBS, +) +from tests.infra.manifest import manifest +from tests.infra.template_test import template_test + + +def _run_recover_cells_and_kzg_proofs_test( + spec, + cell_indices, + cells, + expected_recovered_cells=None, + expected_recovered_proofs=None, + valid: bool = True, +): + if valid: + recovered_cells, recovered_proofs = spec.recover_cells_and_kzg_proofs(cell_indices, cells) + if expected_recovered_cells is not None: + assert recovered_cells == expected_recovered_cells + if expected_recovered_proofs is not None: + assert recovered_proofs == expected_recovered_proofs + else: + try: + recovered_cells, recovered_proofs = spec.recover_cells_and_kzg_proofs( + cell_indices, cells + ) + assert False, "should raise exception" + except Exception: + recovered_cells, recovered_proofs = None, None + + yield ( + "data", + "data", + { + "input": { + "cell_indices": cell_indices, + "cells": encode_hex_list(cells), + }, + "output": ( + (encode_hex_list(recovered_cells), encode_hex_list(recovered_proofs)) + if recovered_cells is not None + else None + ), + }, + ) + + +############################################################################### +# Valid cases +############################################################################### + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_recover_cells_and_kzg_proofs_case_valid_no_missing(spec): + cells, _ = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[0]) + cell_indices = list(range(spec.CELLS_PER_EXT_BLOB)) + + yield from _run_recover_cells_and_kzg_proofs_test( + spec, + cell_indices, + cells, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_recover_cells_and_kzg_proofs_case_valid_half_missing_every_other_cell(spec): + cells, _ = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[1]) + cell_indices = list(range(0, spec.CELLS_PER_EXT_BLOB, 2)) + partial_cells = [cells[cell_index] for cell_index in cell_indices] + + yield from _run_recover_cells_and_kzg_proofs_test( + spec, + cell_indices, + partial_cells, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_recover_cells_and_kzg_proofs_case_valid_half_missing_first_half(spec): + cells, _ = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[2]) + cell_indices = list(range(0, spec.CELLS_PER_EXT_BLOB // 2)) + partial_cells = [cells[cell_index] for cell_index in cell_indices] + + yield from _run_recover_cells_and_kzg_proofs_test( + spec, + cell_indices, + partial_cells, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_recover_cells_and_kzg_proofs_case_valid_half_missing_second_half(spec): + cells, _ = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[3]) + cell_indices = list(range(spec.CELLS_PER_EXT_BLOB // 2, spec.CELLS_PER_EXT_BLOB)) + partial_cells = [cells[cell_index] for cell_index in cell_indices] + + yield from _run_recover_cells_and_kzg_proofs_test( + spec, + cell_indices, + partial_cells, + ) + + +############################################################################### +# Invalid cases +############################################################################### + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_recover_cells_and_kzg_proofs_case_invalid_all_cells_are_missing(spec): + yield from _run_recover_cells_and_kzg_proofs_test( + spec, + [], + [], + valid=False, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_recover_cells_and_kzg_proofs_case_invalid_more_than_half_missing(spec): + cells, _ = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[4]) + cell_indices = list(range(spec.CELLS_PER_EXT_BLOB // 2 - 1)) + partial_cells = [cells[cell_index] for cell_index in cell_indices] + + yield from _run_recover_cells_and_kzg_proofs_test( + spec, + cell_indices, + partial_cells, + valid=False, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_recover_cells_and_kzg_proofs_case_invalid_more_cells_than_cells_per_ext_blob(spec): + cells, _ = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[5]) + cell_indices = list(range(spec.CELLS_PER_EXT_BLOB)) + [0] + partial_cells = [cells[cell_index] for cell_index in cell_indices] + + yield from _run_recover_cells_and_kzg_proofs_test( + spec, + cell_indices, + partial_cells, + valid=False, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_recover_cells_and_kzg_proofs_case_invalid_cell_index(spec): + cells, _ = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[6]) + cell_indices = list(range(spec.CELLS_PER_EXT_BLOB // 2)) + partial_cells = [cells[cell_index] for cell_index in cell_indices] + # Replace first cell_index with an invalid value + cell_indices[0] = int(spec.CELLS_PER_EXT_BLOB) + + yield from _run_recover_cells_and_kzg_proofs_test( + spec, + cell_indices, + partial_cells, + valid=False, + ) + + +@template_test +def _recover_cells_and_kzg_proofs_case_invalid_cell(index): + cell = INVALID_INDIVIDUAL_CELL_BYTES[index] + + @manifest(preset_name="general", suite_name="kzg-mainnet") + @only_generator("too slow") + @with_phases([FULU]) + @spec_test + @single_phase + def the_test(spec): + cells, _ = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[6]) + cell_indices = list(range(spec.CELLS_PER_EXT_BLOB // 2)) + partial_cells = [cells[cell_index] for cell_index in cell_indices] + # Replace first cell with an invalid value + partial_cells[0] = cell + + yield from _run_recover_cells_and_kzg_proofs_test( + spec, + cell_indices, + partial_cells, + valid=False, + ) + + return (the_test, f"test_recover_cells_and_kzg_proofs_case_invalid_cell_{index}") + + +for index in range(len(INVALID_INDIVIDUAL_CELL_BYTES)): + _recover_cells_and_kzg_proofs_case_invalid_cell(index) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_recover_cells_and_kzg_proofs_case_invalid_more_cell_indices_than_cells(spec): + cells, _ = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[0]) + cell_indices = list(range(0, spec.CELLS_PER_EXT_BLOB, 2)) + partial_cells = [cells[cell_index] for cell_index in cell_indices] + # Add another cell_index + cell_indices.append(int(spec.CELLS_PER_EXT_BLOB - 1)) + + yield from _run_recover_cells_and_kzg_proofs_test( + spec, + cell_indices, + partial_cells, + valid=False, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_recover_cells_and_kzg_proofs_case_invalid_more_cells_than_cell_indices(spec): + cells, _ = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[1]) + cell_indices = list(range(0, spec.CELLS_PER_EXT_BLOB, 2)) + partial_cells = [cells[cell_index] for cell_index in cell_indices] + # Add another cell + partial_cells.append(CELL_RANDOM_VALID1) + + yield from _run_recover_cells_and_kzg_proofs_test( + spec, + cell_indices, + partial_cells, + valid=False, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_recover_cells_and_kzg_proofs_case_invalid_duplicate_cell_index(spec): + cells, _ = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[2]) + # There will be 65 cells, where 64 are unique and 1 is a duplicate. + # Depending on the implementation, 63 & 1 might not fail for the right + # reason. For example, if the implementation assigns cells in an array + # via index, this would result in 63 cells and the test would fail due + # to insufficient cell count, not because of a duplicate cell. + cell_indices = list(range(spec.CELLS_PER_EXT_BLOB // 2 + 1)) + partial_cells = [cells[cell_index] for cell_index in cell_indices] + # Replace first cell_index with the second cell_index + cell_indices[0] = cell_indices[1] + + yield from _run_recover_cells_and_kzg_proofs_test( + spec, + cell_indices, + partial_cells, + valid=False, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_recover_cells_and_kzg_proofs_case_invalid_shuffled_no_missing(spec): + cells, _ = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[4]) + cell_indices = list(range(spec.CELLS_PER_EXT_BLOB)) + random.seed(42) # Use fixed seed for reproducibility + random.shuffle(cell_indices) + all_cells = [cells[cell_index] for cell_index in cell_indices] + + yield from _run_recover_cells_and_kzg_proofs_test( + spec, + cell_indices, + all_cells, + valid=False, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_recover_cells_and_kzg_proofs_case_invalid_shuffled_one_missing(spec): + cells, _ = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[5]) + cell_indices = list(range(spec.CELLS_PER_EXT_BLOB - 1)) + random.seed(42) # Use fixed seed for reproducibility + random.shuffle(cell_indices) + partial_cells = [cells[cell_index] for cell_index in cell_indices] + + yield from _run_recover_cells_and_kzg_proofs_test( + spec, + cell_indices, + partial_cells, + valid=False, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_recover_cells_and_kzg_proofs_case_invalid_shuffled_half_missing(spec): + cells, _ = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[5]) + cell_indices = list(range(spec.CELLS_PER_EXT_BLOB // 2)) + random.seed(42) # Use fixed seed for reproducibility + random.shuffle(cell_indices) + partial_cells = [cells[cell_index] for cell_index in cell_indices] + + yield from _run_recover_cells_and_kzg_proofs_test( + spec, + cell_indices, + partial_cells, + valid=False, + ) diff --git a/tests/core/pyspec/eth2spec/test/fulu/kzg/test_verify_cell_kzg_proof_batch.py b/tests/core/pyspec/eth2spec/test/fulu/kzg/test_verify_cell_kzg_proof_batch.py new file mode 100644 index 0000000000..44c1adc493 --- /dev/null +++ b/tests/core/pyspec/eth2spec/test/fulu/kzg/test_verify_cell_kzg_proof_batch.py @@ -0,0 +1,546 @@ +from eth2spec.test.context import only_generator, single_phase, spec_test, with_phases +from eth2spec.test.helpers.constants import FULU +from eth2spec.test.utils.kzg_tests import ( + bls_add_one, + CELL_RANDOM_VALID2, + encode_hex_list, + INVALID_G1_POINTS, + INVALID_INDIVIDUAL_CELL_BYTES, + VALID_BLOBS, +) +from tests.infra.manifest import manifest +from tests.infra.template_test import template_test + + +def _run_verify_cell_kzg_proof_batch_test( + spec, commitments, cell_indices, cells, proofs, expected_result=None, valid: bool = True +): + if valid: + result = spec.verify_cell_kzg_proof_batch(commitments, cell_indices, cells, proofs) + if expected_result is not None: + assert result == expected_result + else: + try: + result = spec.verify_cell_kzg_proof_batch(commitments, cell_indices, cells, proofs) + assert False, "should raise exception" + except Exception: + result = None + + yield ( + "data", + "data", + { + "input": { + "commitments": encode_hex_list(commitments), + "cell_indices": cell_indices, + "cells": encode_hex_list(cells), + "proofs": encode_hex_list(proofs), + }, + "output": result, + }, + ) + + +############################################################################### +# Valid cases +############################################################################### + + +@template_test +def _verify_cell_kzg_proof_batch_case_valid(blob_index): + blob = VALID_BLOBS[blob_index] + + @manifest(preset_name="general", suite_name="kzg-mainnet") + @only_generator("too slow") + @with_phases([FULU]) + @spec_test + @single_phase + def the_test(spec): + cells, proofs = spec.compute_cells_and_kzg_proofs(blob) + commitments = [spec.blob_to_kzg_commitment(blob) for _ in cells] + cell_indices = list(range(spec.CELLS_PER_EXT_BLOB)) + + yield from _run_verify_cell_kzg_proof_batch_test( + spec, + commitments, + cell_indices, + cells, + proofs, + expected_result=True, + ) + + return (the_test, f"test_verify_cell_kzg_proof_batch_case_valid_{blob_index}") + + +for blob_index in range(len(VALID_BLOBS)): + _verify_cell_kzg_proof_batch_case_valid(blob_index) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_verify_cell_kzg_proof_batch_case_valid_zero_cells(spec): + yield from _run_verify_cell_kzg_proof_batch_test( + spec, + [], + [], + [], + [], + expected_result=True, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_verify_cell_kzg_proof_batch_case_valid_multiple_blobs(spec): + cells0, proofs0 = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[0]) + cells1, proofs1 = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[1]) + commitments = [ + spec.blob_to_kzg_commitment(VALID_BLOBS[0]), + spec.blob_to_kzg_commitment(VALID_BLOBS[1]), + ] + cell_indices = [0, 0] + cells = [cells0[0], cells1[0]] + proofs = [proofs0[0], proofs1[0]] + + yield from _run_verify_cell_kzg_proof_batch_test( + spec, + commitments, + cell_indices, + cells, + proofs, + expected_result=True, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_verify_cell_kzg_proof_batch_case_valid_same_cell_multiple_times(spec): + num_duplicates = 3 + commitments = [spec.blob_to_kzg_commitment(VALID_BLOBS[3])] * num_duplicates + cell_indices = [0] * num_duplicates + cells = [spec.compute_cells_and_kzg_proofs(VALID_BLOBS[3])[0][0]] * num_duplicates + proofs = [spec.compute_cells_and_kzg_proofs(VALID_BLOBS[3])[1][0]] * num_duplicates + + yield from _run_verify_cell_kzg_proof_batch_test( + spec, + commitments, + cell_indices, + cells, + proofs, + expected_result=True, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_verify_cell_kzg_proof_batch_case_valid_not_sorted(spec): + cell_indices = [3, 2, 0, 1] + + commitments = [] + commitments.append(spec.blob_to_kzg_commitment(VALID_BLOBS[3])) + commitments.append(spec.blob_to_kzg_commitment(VALID_BLOBS[4])) + commitments.append(spec.blob_to_kzg_commitment(VALID_BLOBS[3])) + commitments.append(spec.blob_to_kzg_commitment(VALID_BLOBS[5])) + + cells = [] + cells.append(spec.compute_cells_and_kzg_proofs(VALID_BLOBS[3])[0][3]) + cells.append(spec.compute_cells_and_kzg_proofs(VALID_BLOBS[4])[0][2]) + cells.append(spec.compute_cells_and_kzg_proofs(VALID_BLOBS[3])[0][0]) + cells.append(spec.compute_cells_and_kzg_proofs(VALID_BLOBS[5])[0][1]) + + proofs = [] + proofs.append(spec.compute_cells_and_kzg_proofs(VALID_BLOBS[3])[1][3]) + proofs.append(spec.compute_cells_and_kzg_proofs(VALID_BLOBS[4])[1][2]) + proofs.append(spec.compute_cells_and_kzg_proofs(VALID_BLOBS[3])[1][0]) + proofs.append(spec.compute_cells_and_kzg_proofs(VALID_BLOBS[5])[1][1]) + + yield from _run_verify_cell_kzg_proof_batch_test( + spec, + commitments, + cell_indices, + cells, + proofs, + expected_result=True, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_verify_cell_kzg_proof_batch_case_valid_regression1(spec): + """ + Regression from fusaka-devnet-5. + + In c-kzg-4844, given 8 or more blobs where one of the commitments was the point-at-infinity, + the verification result would be incorrect. The 8 blob threshold is because c-kzg-4844 uses a + naive MSM implementation for small inputs, which is why existing reference tests did not find + the problem. The actual bug was in blst though; it was fixed here: + https://github.com/supranational/blst/commit/f48500c1fdbefa7c0bf9800bccd65d28236799c1 + + Test inputs came from Teku here: + https://github.com/Consensys/teku/pull/9893 + """ + # fmt: off + commitments = [] + commitments.append(bytes.fromhex("b854f381e18109d9ab6df98769a21e7242184b9751b38d1abc132e5a5434418a4b0ad9e06ad29f9c71fa6aab93e9423b")) + commitments.append(bytes.fromhex("c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) + commitments.append(bytes.fromhex("8ace3bd3b1fea7377d20e065de07f99556721ed54855065f436edf17996973f7d04a6f5654d58205b4a8412c94ca821d")) + commitments.append(bytes.fromhex("ae6c661e5901116d00f1e8555734bdd8aa2d63ea26a92c3a333765b53b4436b1ded3f0e9c6dd2f990f715e817b3af756")) + commitments.append(bytes.fromhex("b09ace4559d243c732862c8a40e06afc4bb98a21011db1c6ee16df15c28d1c3d421b9991aa602db2fcf2410a37e6f7de")) + commitments.append(bytes.fromhex("8f9c4dbac70b5f818791a71edfaeef6b185c6d614377d7217acaa6df70a97067539f5ce4528e0e61b3bd64831b24b0fd")) + commitments.append(bytes.fromhex("8ae5c52c21b7d831bef232e428f16eaa28ae72b19e53902cb650417aa4c5311fc1b99b0ef9a3f2bb5232f63696d92382")) + commitments.append(bytes.fromhex("afa9021c53f2be07edc4aae82bf4d1f6777e2581c7b327ab1b75e9701d7d7cf45e9354cd2d5bd430da89f1ca89de3755")) + commitments.append(bytes.fromhex("b7b5f17d1d9ddca22815f327a8038cc6f1279ddae863e908d2a527d5a2707bd2aa496641635dcc4f8b265c7e7a6b53ff")) + commitments.append(bytes.fromhex("8dd8b69e18f913807af5c178902f23659945437527c2c75fc8ae7ffefbdf91b0a3f9a5ac78b48df09bb2e613695582f3")) + + # This case comes from a DataColumnSidecar(index=41) + cell_indices = [41] * len(commitments) + + cells = [] + cells.append(bytes.fromhex("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) + cells.append(bytes.fromhex("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) + cells.append(bytes.fromhex("0039aa9df5db058cb79e462c4d3036d677b714eb1a72685192cd6375406ff0b200b839ba04279f66026ddbf15d5730e5f1aae1609a463f2651e519057875928a003a0871c3e9b87f3998ad1b85c473b4e5e560239ac56f28b7c252b4cac0599f0006f4fcf37c88588f9f27d50e3224e83dec70620b50832c662124c03ecf4d3b00c1e76a55d7eab8339303d422c206efc3e3101aab80a8e2142f94793aee510100a1b53ef0424c8c5ca5240c697df3990a2f0c55cb22aa7b6dba1f9b496861b400b0ce842fef679bc7850b5d172f731196adf0c894fb59ed11b1d152ad99c4aa00d2e60701bad62c6793d95270a8165b160c3cbbeaa03749253187eb88c4ef46006283cbe0b11910d94eb564922a3810c2ef6b041f1e9b5c7304b28065f43622009cd823dabc556d40a2af78bc9c874ef9fca66010d7a8e040da3cf6818575e7002d28d8ff8045e8b3d20155b7667ccf89a06fb29de0d3e1bdce888ed5d02e4e001aa7c0c5ea29c035990bf4bb740daac678474e9cf97b77fcd8e96857aeb34d00bf4e665292e6670071f2881517d32a12f26ecbad17bed3e6d7181d458810e4007945c0d9815a93a56c1cdb0af536b256bc7e54f7232020227c4dafbbb79d190096d30d693e5f2f4f6ef73b5dc16e434381c18cdc9a6caaa87dc8d34f0005a3001cc8f38600471dac3ab880a8a7e96941894c4aea7bb2fd01eb8266fc16dc5b00208571813e8a4b7841bbd5088fc78bb6bbaad60d6e29d5a396c382ffdaf17800a8d6c79351ee9b8f31388dc73bfb9724cc0c34dfdf97e288518563afe41472001c021ed5ef37064d616ca50cf879696e12a5f58591a2edfbad34d661c6361b0078aa7a3171cb4b8d252b3cbf1b5a8a368350534aa27479248d7e3002e2ad050053bdee7dfb77724b39d4e398d6dfd32f9a7ad578d6158eb88f6bc012defcd200e5698160bc0f99e9f8541b51c70d62486d11779dbc2d4ad08484ec586c9d57005466452d630b92409a8c013f01ab4a2f422099e31d8e2d1950fc5c1b8d8c1a0000cf5e63bfe4ec59e689459444630d279f8aa33ec1240f50a68ed70ee3b878004149c19ab30937b0b482053c82e45e6616d0e7190e4969b6e47030d67f7de80035c0939010a985a77a5b193a02ab54fba2f80b3e2da30be4140aa1f154f4cf00c0d54139fb78f1827e302d84b8bf1b6cccd1abb98ea3382e1806d502c16a270043b8c2753f2a771f1ec7ed0a5857c1a21f040cadfecd602d63034cdee232a300079ddb764829d7095ec74749aeb48294612d3ae1045face2b1107edd126f8a0056c98e313d6e08d361a12003425bd36b030aa600ad29911f4037567a0e17f800809164e8146c5bc514fd4250e907662e68831a80f333c8344c01811fcbcc490096b91272abc7a00cd993aea27ac35cbdf27c7aeaf54a420930717e5bdd7252002a9ecbd82c18f7beb52139d6b668c1d79b4416c39de3144b0d26d10ff821b700f966aa99d45a7faff14134c2beac285dc1b6c4eead7957d97bea86d7fac89a0008f24da3d86c1bed5b38a418bf2f86aeec71b7ae61d320dd6cb128ed5de0e900f3f7b9f837f82471ce145712db3440b5b6990b4411be524c3c2d70edfd10d80052a408dadf34698c25da7469764ad24b2f66f6cadd29baf748cd78d576bd5a006bbf1a939b04ea37afd1b4a23401d6ab9c205a8c05c59d1a874351ad68d56f00bbd3a36d39853d9626882c4b90bf84f2f4288dcd5c102e43480488d71a2fb90096ec604e75a6fc27c0d6891dad3473da91f455198a3d4e33f14bf02506061400581dbaf6c37294de950424b8f47967e46b67fe387d2a86fff05f73cfe70e26002271e84b1c26daae542edbe9dd127d0503959d321dd6ef4bbe1ba44955242f005ad159ef4f4e4f65b238e4656081ed1410555e45d276b05b1cf70475fa8fbc0034e76537cae9249857b6bf92cea63e77906e0987ff090a609d4bbd4668f4d100a2e12496899742614b7e60b13efa0a4f4bb0e47e7c26b4c32ee92bd9c663eb00783dd1ec6e19f57665d5bc7a9dbde785350cd181d1b3802baf1d10082de15100e9ea7cd0d5f44de5de417771adf49c1f04bb7e2a5592640f6552ffae5bc21500ca6fd090a113d52295d420534eed4f61851bd9eac7c5ee108b5a8f3d7e967c006088980342c0854c9744b7448702ec8843e80491b1296cbf815caea3970cff00eded33c7b35f305604df3301b318f26448165a03b4dbcd9bd68548b31a48c30036fedea6980d39ba1d542815d1f5e77471f83ff7455c380a9e13bff500054000d669f39aeed2a72a20e1f9f5560745a7e49586ed9f33171ac07c8eef42110600000da0556f6c1003241b449687565e2c281fef93da9d9c714a6d8650defceb00a6dd378b4b1e0cafdd172a19b42fc2347da9d9596c3c99b1a87339bac94adc005fa5493314a84e82e9179f4d8b7ac5983830dba3151f3cc7c500831dafdf56001d413be5d4b83ccc944c4dd30478c32e28b1ed8b5cf1e97aefe348bd0f2824008f7741828d72baa66df519253714d11592f95e97347594b16061249e99d2f500e406378e6bafad704151725fd626f92640de511f0f9ac6a406a648fe783737006baf972d715bb1bdfb76897c1f01984c48fba8da23402c465387d0f7dd1b17005f3a0874cb607ee8bcdaab86c869abdcdf799b755cf259a7e0331a2b137b420085c8cd1715adb4e58c3d138de9feb9e486973f7cd307d73f8e8e831dca4620005bdb87804a275eaf8a6e2cafc97739ccfd0dfcebc273cf7450a744056281260072bab2f9fca8d34f676f245e9ab5152e8614b2e8879b6284dead0de63a96f4005cfc6ec166352bfe28579b7a52ad0e359f3809df67cd397d63abd9d006ee83")) + cells.append(bytes.fromhex("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) + cells.append(bytes.fromhex("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) + cells.append(bytes.fromhex("00048d34a9ee8df14099f4167b043b37cacbaa622c09b5338525199fe24c9c1300f3464d9fb58c0d84543171b3f9c4ae529146087de5629bfe8546c6c64c7a0a0017853b8e392be8c4abab1e4aef33cfce2abe4ae975c9a62f79f49080fc58bf00d2fdc9ef8f3108d9e3106c0e5aea7cdd8c1326876a50c8f877b6395be05dc60006664b9f62d4f2fe69c7c1377ece721a0e3fa0e29efbd3720539ea2779403a00b30a3403d0581469916b822df59041fe9b32622d3ef1cedd6139ca5b47d7cb004e174178e2287cbfe543e1d77e019ea465fe7d74705880c432552297a1350b004e2070d9caa59a0b78acf06052f0ec2666d540abb1e7756c55edb28db23b9000ed95539f72b4091254cb9125171cc658e2faa6a3d26341f7bdfefdd442d859001676825de61cbbedf50aa19cb95a857866df6c5f26cec3fd1832313e241a4d00fbf50d071d8145bb62f2d18cf63563a758c0b1a6c51dfa0224624ea1f134060088c6344d2574289623dc1e11a6ff3570f594c851c370804f1e213c5bd604c90090d48eda8da181f070d64f13853eb16f6f3a877fce465e7ba3e184295cb85200f3fe8c3264847d7152eacc07417f445bcbc6a9c2fe6bea43b6553a97ac4f0500e73d4828da0bd94ff59cd5b44a79365f26c21b964dea9dc8d902f34c866f2c0065eb7db5c878a53cd42d5b9bce3fd10b8cfd6811bf3ba99af29469d238646400d0e89e344c7ad56642e26a6a4c77c837cd48ccb7d43e475dfcf43d0eb4347900d83fa10da2de93ff94c8a479c9a50214bee03960a726d1273c0f5214f951ad000cc602b3e9065717b30dd0892848e1870a67d476f7e0136092a73c879e74ff00274d00e08da2a04a38435662fb7fa385a5587f521493183d96f797fd28a7390038ac1e8140f32571e7e4c743a5551808a2a694a7bc8284647acec77d4a14500054df291488fbddb60e146532efc040188561e631d872b6bed85a1a51c5c57a00320c45c9cc4317d79d3fc6f75a634a03fbdb09ca17ea33aa84de886029bff10051f2c8b79736fb7915dcb08176228bd76def747204faad6e3212878023421e001085b8a4f66a77d5c5e28ec6807d1962e5a02f803322fa972e35e4cef7ebc600728916bc88686fbbe4fe86fa614bc58150e2898e561433eeed5e0490ee4d93000db0d179d9332508811e3e17ca5b45bda8bd489a5964aedf0007bb96c5e67a004c063ff194e0bc7e20c41bf4b794fdf0e4511b262f167c327227023681d03f004003a22a215edc54ceec153b32fba83ed8847fa032dc00e65106b55a6256bf00c5ace98731bab0b6bb1a2750895c0742448811624f66a41d45ddb987a75c3d00dc9cf280e47c371cc613603998a7981ee85eab27112ae5d2d6d4521af16e9c00c1141087b20a349fdd98289ff511920017d8f6311a0c7b780a586589caa6bc0015f34e10f2269b5577581e82970cfa47134af55683ebfaff28f757d48d3cc400798cb57c5143290b2a306868fd10e20add34cea80f9113d4454d956cbde379008449c5e74f377e3e7a122536766ecdba350908f2823e4fc2f376eb2b3d21f500ea7659cd184a1928f2c514006b90c73c3943a38a4de3e02e021672c23fec9100feb096041ddeaa0b4ba7329c361dc4e0acce06807fccc3ef9363ef711d26d6002bf2c8e76ebdbe65f1fac60e0fd3a3c5e87186c04ba6096fdce8ce794ec28a002606c57beae3475c4fc1bee6a727a0c7970fb557e2cf6cfd4b5f719ee6da540056da840668ac1ed5c01c6b3174849837ae6ae8968adc2bdd8770b003b85ced00d6889245babf1f6af375e3892d81cc0c84b62bc7e327146a9379073532818e001e667e2da08179da670d098085c50329a29d73c0a2a0fce6a003f5146651ef00cde464289ca2fe14cb8ac5bca13aaaf74beb16aaecdcc830a230954639762a0027ecf12a74f05886273fda9a8fb215c4b469233eac96be952ff91bdefa3f1f006909cc12c440a50716b07120003dff7f74b768552a558b2c1b0f14848e93e2006beca40379fc6e014f97e8ab4f6d745bffc8634e8c6ed3eb5b9c658b350f630076264aed87640033d1567add40f3f06109eba63452ac023d0990fc9264061b00131e48216a1d7dbd8a42536d15b0af1e96c19775a7b946f77851c436b06e230010fd4e721c4102aad4dafe9bb7a8b87e0d1a45d696b097ca436408fd657aa70009274ca7b1346071705b5188e6e2e4682e6bd6fb868a95f3511040b9edab3500cdb49ec502dd44152724a5cb3f8139f03dcfd4f388277c1f70536dec8c28db006d317a2a74a8233d328f46002d59bce329943bb4cb47e22e47435783fcb9f6006d83b0649b7916dda4843fadae0eb84bf8e95bd155074a7b3f22a29b0aec60007bb59ad89ac32bca5531abff32474445fa67392512f836bc7e66b51de0fd80005e5ac27656f8df57dcca232ddc985b3835e1281a9fd0f6ab6a2752437f575200fc6187d02b06fd2bd4d9dc0b6348cd17489897353f91c08e5305490b9a4a7d0006b2cd6530a94d6a6433cd4643d502af18adca92dd4c6e2f775ab519cef2a300aefddd251f2264bbff829a02ab354332353d0ff6738c3ac71a0fd9800cc2b400710e47bd8827671c3ab02a5a6a75d4188900beb0983406797aa8b91a5e299500ac49f72bbaa09a2071f63242070c7eb6557aa2b4399cda87e7a53f101d7ee4000c71b1c23f456102cd9230b15319833b7e39a129c93e79d27ce5530d86411b007b9199a66061ee0855ad6c4b54aab5faa7f853a79a78af033334c06ebeb2d3002e77f3d8157a65f040f2b19ff8dbb7682265e957c5c0b4d4b9163464e01268003cdd694dcd0f204358f6582a3810f9252223ebf0770d6e8d89bc29c15c53de")) + cells.append(bytes.fromhex("00c49b376cd0a2ed62fdb0542fa62cb2ee87e75fa4649ec2a95a91f4b1e2d8d800570a90f4939f60c123ee945d7fa06ce9ffd6facb622ea1158c008be4513bcc00f3fae389614f0dc1f8c000a2ad41df7f3a69835d867c0f084a53cf4618edd40066ed15ceee79a96f686883051c700793a2daf646a36d6783b4ce2ee9fc6de700296e88931434490a0161e4d21b9417d62053a1eb83dabf01e4935c2fb8c871008723eff8757313fbda4e7c18d02f4500abf5745879487e4f85e5c61beeb0460009ff30e0c4aadef826ea2c48ffd22e1939aabc1a27c4ad5df25f6be54a94840054758c3fc538120f380010e1af64820c9e3d480b8c1f6f92f222e5683ec92d00d2767b236d13e6585ad6446c6d35b3a3ac73c0209f53c0c766b4beaf7e4108007b9e3dba3886f76c3c0262b85733ffd179664ab2ec9fb1c1b6b573dbc3409b00ecf7a6bb6bf65d1c801d6af6609aa87705d7e07a58cc19b7e0feb3d062024300a1ba721d0299ffbc2ae1a417e6d1bdf8082f7e563dc20e015b593884724d8a009fe0950ab49c953dbe739e89a9f209920683dfc431d8c650f87276134bbc0e001b2f8cd802d886ac216c1a54c14272f9d489f7ba468671aab02c2bf4e7b40400254f7f84a2a3693ab3ea43a7e55d6ba6ea00bfd57c7dd0813623a4470d9bbe00007a4e4b1b93c025663eb80913b7de7754a74b9a00ec290c4eaf51eb3a45ab00d5090e747645bdc4714cb0f8b906fed5b62a949b8b61f0887e2ee51659268c0030672fda8f33b457d865ae59479209d8f76a2e35771b5a63f44b8a61e4262a0020e5aac80fa90f10efdf49b757a43c7c5d5054c89bb7893e8f4ddf498c813d00904ecb5b63e71f861aa42be2266a22678826267322a76f8431408d9cad527c0009731cad0d9f634466c16b6ffccab534bded9ffcdbcc1e34204575e4e9cd770064734b53d93bae235deb2de8811ba848228035e905d1148ae55fa3154b89910054b256f6e659fd1250282b000e75528e3d26b453ac26b3f2990dbbcc4bef2e002cee176a402059bd4f64039050a6fdca5ea2f46df19ec81c09497bafaf3be300b656cc6ee54c0ecd15584badda53384d49e25bf5efba093f497a1dab0193ec005ddcc9ae5e3853f1e9f30961d5e5299113f13a2c9789f7c6ae086891c2593700956ec15dc8a45e8a4c4a4d5102494c9775c56fb0df1115268e07a5900a28c300159c950b70a1290c5b5c1835c047fcebe083cf1fd2376724a4cb119adb45240029dd3a3e1e1d8f38671a4407382078b13a01bec834db752e3bc15424cfa73600dfa26055d745971a3b143a9a736ffaafd9e3a12b8f7f5f63848dcaf2b27cf800f8ec9ec18fc0ad48d94867cbf1b9ccb7d04b049261dbcf89ff461597d361d900306f852ce37c6a8b6a8dd53f71d15fe4f285916187214bdac278d9e28cb76b001fe567da874b8371cc9cbfa7e3ded684414057a68280ce87188e6fe45c50b8002434b4dda7b6e33aed83ef7106638773490168caa0275199fd560b4f6c658b003273ecce6bb6c897f270f1b3aca8930459cacac541b0806a87fe024a33eea2008673f8fdeda9fb7e96cc0215cbec8c99abd29558972238241aeae4af94062e00663f2630f7d07737e27dc78ffbddf3b9f217739dec0f86bd9bdaaf2018fd160022124f1c3852c7e6a300a0ab7f4cfccd9d55c4cf4347a25bf2ddf13c6ec01e00b6daf38bc8ef4eb4e6789917391b0e74799518b843906e2f616e9681d2c633002a7ddcbf96760777c9afa100e9a4e0b7dc03e9c7bd22f95cf267fb86d8e50000e77616de7447a74ef69fea377dadd55d22affb2ce5275440ba090a6b6aa54a00d5037cbd99ee1f5eaa2069c5279fbddd7ce030a0aed1fceb3ced1a7276ea290046570594465ed946432d752d4ddd670af0cc2660fd1a5845ef2c48a7a9432700e6e4fc416c58b51618d7637f09a7b7ddbd5820fcafa5132a21b0650bb5e8f4009bf1dddda661797c6398e9748ae02e20895b931f97e448ef56b74141119f0a005335a127a7896e9b5ac09fa02350dba92249a145fe8b16d5463b828899ba64009fe9e2e97c7a885009efd1e6ca313254b9dd34191c1f6a1ff5025eb3a11a6900b1a75837f14207afaae9d7163580e52ca3b18437f1cf9de159552a88db3732004215283b1665daefb129b918284cc6d2f89bc5f41e76fe770c800a708c648c006c99ec5d9808a1bbc7b9c8806ca114e27a880022c1b52777c295f162f89a4d00af1e7ca0d2748d38ebd02eafcb4e9124ca35e02a49a4f821cdd653ffb6d283007f8c92d0c64df01d5b9b09a44dc67667a14bde6287c522123a108720011e6b00ffb7b9187081068b1f255d8dda7a5058a8d98e6ff0c7ff47df7f33f76e8e4f00b0d3bd4053eb2695de9ca68c69ea235befd7e805e6097d82005a6ece6ed0660030e523ee030d474b08c3f2b9b5d238d06dc0256a3c772ba25f8c45f6904f98002355b8d0afe4c970bf6c2ee79ea525dfc08b3a8e5bfacb9a05aa410edafb8a000ef5f23c17fbb6cb35a1aadd833684ada62b9468ed85f244923d6efb07f84e00e07a658143379fb3cd74bb67f00fa57da2ae7c02c289f22f60df63cc4c1d3c004df7269d5c39ff56bfd721b36c4bf0dcbb25f28d51e9acddc1be128abd0b39006ed245cdb1f172f271c379445cc7f2be32bb7353c5dbb9a916ad94108ea274008ece432918ea37879594a942b18ebe3920d9a9b9cc1fb16bc866cedfc333bd00d4c1ff1c9da7215fa351f60fd5fc6375abb8c32a287362a51bd49e1d976b4900a3af57a2c9bd26ace18f5959b750c174311bd174317a3cb0a981615ad7885f00c64d04034c04a267b2d3bdaa12fb9c291ce4a1e747c37ac66c5e38dc456293")) + cells.append(bytes.fromhex("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) + cells.append(bytes.fromhex("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) + cells.append(bytes.fromhex("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) + + proofs = [] + proofs.append(bytes.fromhex("87f5479eb540c88b0e6d790d901de990ebded06410774891e21f1b0e27f9b6a68b547e1a2d5c779298d22844d9f979b3")) + proofs.append(bytes.fromhex("c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) + proofs.append(bytes.fromhex("9769f9395f56dc41314a65dd0cfc05bedbcc1616c96dad73b252bdaeb5f4a9b1ffe01ca710978dc56ee6f775eb44d211")) + proofs.append(bytes.fromhex("9200f1f4730536c43fb2e87f8d920d473dd177f935d0d8dc5cbc069ca7158a1897d0e124f7777a34ffd00c0d63eb4ee6")) + proofs.append(bytes.fromhex("a701b8ad14b15f1225093832b1c2f28306a7924641d32f82da760428146d66ed127548c0a3d446d81a20f5382229294d")) + proofs.append(bytes.fromhex("b33e2d16efc03b838e81d759c2bed0ecf9ec81d9aa70743c8dd86b2a3f240d60bca14dc7528bc960d478abef8e8e80ac")) + proofs.append(bytes.fromhex("85916811fa3299b4fd8ad3567b5796444693c8e72c3451d09788935199b4d5aebd7036b9aa4c539a3fa15ecaaf3dbabf")) + proofs.append(bytes.fromhex("b36f5457ef6700a1802a33f70b5c1e4d8edb79130533255ab39d379a34580528e3a82895a788c5a6731117e32c37a266")) + proofs.append(bytes.fromhex("b363a0b7f79f5d5f976f42f89d6b8d49a93163c42a236039116cadadbd260fc4f9832218d55480ca6ca3efc9da9f25d0")) + proofs.append(bytes.fromhex("98c9663a80a003f7e97e5bb13f3b37af7a5f08a76cfe170b099e62bddc2cf9dd0d46755a34e6eb99bd58cc11dcec6618")) + # fmt: on + + yield from _run_verify_cell_kzg_proof_batch_test( + spec, + commitments, + cell_indices, + cells, + proofs, + expected_result=True, + ) + + +############################################################################### +# Invalid cases +############################################################################### + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_verify_cell_kzg_proof_batch_case_incorrect_commitment(spec): + cells, proofs = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[5]) + cells, proofs = cells[:1], proofs[:1] + # Use the wrong commitment + commitments = [bls_add_one(spec.blob_to_kzg_commitment(VALID_BLOBS[5]))] + cell_indices = list(range(len(cells))) + + yield from _run_verify_cell_kzg_proof_batch_test( + spec, + commitments, + cell_indices, + cells, + proofs, + expected_result=False, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_verify_cell_kzg_proof_batch_case_incorrect_cell(spec): + cells, proofs = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[6]) + cells, proofs = cells[:1], proofs[:1] + commitments = [spec.blob_to_kzg_commitment(VALID_BLOBS[6])] + cell_indices = list(range(len(cells))) + # Change last cell so it's wrong + cells[-1] = CELL_RANDOM_VALID2 + + yield from _run_verify_cell_kzg_proof_batch_test( + spec, + commitments, + cell_indices, + cells, + proofs, + expected_result=False, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_verify_cell_kzg_proof_batch_case_incorrect_proof(spec): + cells, proofs = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[0]) + cells, proofs = cells[:1], proofs[:1] + commitments = [spec.blob_to_kzg_commitment(VALID_BLOBS[0])] + cell_indices = list(range(len(cells))) + # Change last proof so it's wrong + proofs[-1] = bls_add_one(proofs[-1]) + + yield from _run_verify_cell_kzg_proof_batch_test( + spec, + commitments, + cell_indices, + cells, + proofs, + expected_result=False, + ) + + +@template_test +def _verify_cell_kzg_proof_batch_case_invalid_commitment(index): + commitment = INVALID_G1_POINTS[index] + + @manifest(preset_name="general", suite_name="kzg-mainnet") + @only_generator("too slow") + @with_phases([FULU]) + @spec_test + @single_phase + def the_test(spec): + cells, proofs = spec.compute_cells_and_kzg_proofs( + VALID_BLOBS[index % len(INVALID_G1_POINTS)] + ) + cells, proofs = cells[:1], proofs[:1] + # Set commitments to the invalid commitment + commitments = [commitment] + cell_indices = list(range(len(cells))) + + yield from _run_verify_cell_kzg_proof_batch_test( + spec, + commitments, + cell_indices, + cells, + proofs, + valid=False, + ) + + return (the_test, f"test_verify_cell_kzg_proof_batch_case_invalid_commitment_{index}") + + +for index in range(len(INVALID_G1_POINTS)): + _verify_cell_kzg_proof_batch_case_invalid_commitment(index) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_verify_cell_kzg_proof_batch_case_invalid_cell_index(spec): + cells, proofs = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[1]) + cells, proofs = cells[:1], proofs[:1] + commitments = [spec.blob_to_kzg_commitment(VALID_BLOBS[1])] + cell_indices = list(range(len(cells))) + # Set first cell index to an invalid value + cell_indices[0] = int(spec.CELLS_PER_EXT_BLOB) + + yield from _run_verify_cell_kzg_proof_batch_test( + spec, + commitments, + cell_indices, + cells, + proofs, + valid=False, + ) + + +@template_test +def _verify_cell_kzg_proof_batch_case_invalid_cell(index): + cell = INVALID_INDIVIDUAL_CELL_BYTES[index] + + @manifest(preset_name="general", suite_name="kzg-mainnet") + @only_generator("too slow") + @with_phases([FULU]) + @spec_test + @single_phase + def the_test(spec): + cells, proofs = spec.compute_cells_and_kzg_proofs( + VALID_BLOBS[index % len(INVALID_INDIVIDUAL_CELL_BYTES)] + ) + cells, proofs = cells[:1], proofs[:1] + commitments = [ + spec.blob_to_kzg_commitment(VALID_BLOBS[index % len(INVALID_INDIVIDUAL_CELL_BYTES)]) + ] + cell_indices = list(range(len(cells))) + # Set first cell to the invalid cell + cells[0] = cell + + yield from _run_verify_cell_kzg_proof_batch_test( + spec, + commitments, + cell_indices, + cells, + proofs, + valid=False, + ) + + return (the_test, f"test_verify_cell_kzg_proof_batch_case_invalid_cell_{index}") + + +for index in range(len(INVALID_INDIVIDUAL_CELL_BYTES)): + _verify_cell_kzg_proof_batch_case_invalid_cell(index) + + +@template_test +def _verify_cell_kzg_proof_batch_case_invalid_proof(index): + proof = INVALID_G1_POINTS[index] + + @manifest(preset_name="general", suite_name="kzg-mainnet") + @only_generator("too slow") + @with_phases([FULU]) + @spec_test + @single_phase + def the_test(spec): + cells, proofs = spec.compute_cells_and_kzg_proofs( + VALID_BLOBS[index % len(INVALID_G1_POINTS)] + ) + cells, proofs = cells[:1], proofs[:1] + commitments = [spec.blob_to_kzg_commitment(VALID_BLOBS[index % len(INVALID_G1_POINTS)])] + cell_indices = list(range(len(cells))) + # Set first proof to the invalid proof + proofs[0] = proof + + yield from _run_verify_cell_kzg_proof_batch_test( + spec, + commitments, + cell_indices, + cells, + proofs, + valid=False, + ) + + return (the_test, f"test_verify_cell_kzg_proof_batch_case_invalid_proof_{index}") + + +for index in range(len(INVALID_G1_POINTS)): + _verify_cell_kzg_proof_batch_case_invalid_proof(index) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_verify_cell_kzg_proof_batch_case_invalid_missing_commitment(spec): + cells, proofs = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[0]) + cells, proofs = cells[:2], proofs[:2] + # Do not include the second commitment + commitments = [spec.blob_to_kzg_commitment(VALID_BLOBS[0])] + cell_indices = list(range(len(cells))) + + yield from _run_verify_cell_kzg_proof_batch_test( + spec, + commitments, + cell_indices, + cells, + proofs, + valid=False, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_verify_cell_kzg_proof_batch_case_invalid_missing_cell_index(spec): + cells, proofs = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[2]) + cells, proofs = cells[:2], proofs[:2] + commitments = [ + spec.blob_to_kzg_commitment(VALID_BLOBS[2]), + spec.blob_to_kzg_commitment(VALID_BLOBS[2]), + ] + # Leave off one of the cell indices + cell_indices = list(range(len(cells) - 1)) + + yield from _run_verify_cell_kzg_proof_batch_test( + spec, + commitments, + cell_indices, + cells, + proofs, + valid=False, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_verify_cell_kzg_proof_batch_case_invalid_missing_cell(spec): + cells, proofs = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[3]) + cells, proofs = cells[:2], proofs[:2] + commitments = [ + spec.blob_to_kzg_commitment(VALID_BLOBS[3]), + spec.blob_to_kzg_commitment(VALID_BLOBS[3]), + ] + cell_indices = list(range(len(cells))) + # Remove the last cell + cells = cells[:-1] + + yield from _run_verify_cell_kzg_proof_batch_test( + spec, + commitments, + cell_indices, + cells, + proofs, + valid=False, + ) + + +@manifest(preset_name="general", suite_name="kzg-mainnet") +@only_generator("too slow") +@with_phases([FULU]) +@spec_test +@single_phase +def test_verify_cell_kzg_proof_batch_case_invalid_missing_proof(spec): + cells, proofs = spec.compute_cells_and_kzg_proofs(VALID_BLOBS[4]) + cells, proofs = cells[:2], proofs[:2] + commitments = [ + spec.blob_to_kzg_commitment(VALID_BLOBS[4]), + spec.blob_to_kzg_commitment(VALID_BLOBS[4]), + ] + cell_indices = list(range(len(cells))) + # Remove the last proof + proofs = proofs[:-1] + + yield from _run_verify_cell_kzg_proof_batch_test( + spec, + commitments, + cell_indices, + cells, + proofs, + valid=False, + ) diff --git a/tests/generators/runners/kzg_4844.py b/tests/generators/runners/kzg.py similarity index 100% rename from tests/generators/runners/kzg_4844.py rename to tests/generators/runners/kzg.py diff --git a/tests/generators/runners/kzg_7594.py b/tests/generators/runners/kzg_7594.py deleted file mode 100644 index ae7d34c1d6..0000000000 --- a/tests/generators/runners/kzg_7594.py +++ /dev/null @@ -1,1038 +0,0 @@ -""" -KZG test vectors generator for EIP-7594 -""" - -import random -from collections.abc import Iterable -from functools import cache - -from eth_utils import encode_hex - -from eth2spec.fulu import spec -from eth2spec.gen_helpers.gen_base.gen_typing import TestCase -from eth2spec.test.helpers.constants import FULU -from eth2spec.test.utils.kzg_tests import ( - bls_add_one, - CELL_RANDOM_VALID1, - CELL_RANDOM_VALID2, - encode_hex_list, - INVALID_BLOBS, - INVALID_G1_POINTS, - INVALID_INDIVIDUAL_CELL_BYTES, - VALID_BLOBS, -) - -############################################################################### -# Test helpers -############################################################################### - - -@cache -def cached_blob_to_kzg_commitment(blob): - return spec.blob_to_kzg_commitment(blob) - - -@cache -def cached_compute_cells_and_kzg_proofs(blob): - return spec.compute_cells_and_kzg_proofs(blob) - - -############################################################################### -# Test cases for compute_cells -############################################################################### - - -def case_compute_cells(): - def get_test_runner(blob): - def _runner(): - try: - cells = None - cells = spec.compute_cells(blob) - except Exception: - pass - return [ - ( - "data", - "data", - { - "input": {"blob": encode_hex(blob)}, - "output": encode_hex_list(cells) if cells is not None else None, - }, - ) - ] - - return _runner - - # Valid cases - for index, blob in enumerate(VALID_BLOBS): - yield f"compute_cells_case_valid_{index}", get_test_runner(blob) - - # Edge case: Invalid blobs - for index, blob in enumerate(INVALID_BLOBS): - yield f"compute_cells_invalid_blob_{index}", get_test_runner(blob) - - -############################################################################### -# Test cases for compute_cells_and_kzg_proofs -############################################################################### - - -def case_compute_cells_and_kzg_proofs(): - def get_test_runner(blob): - def _runner(): - try: - cells, proofs = None, None - cells, proofs = cached_compute_cells_and_kzg_proofs(blob) - except Exception: - pass - return [ - ( - "data", - "data", - { - "input": {"blob": encode_hex(blob)}, - "output": ( - (encode_hex_list(cells), encode_hex_list(proofs)) - if cells is not None - else None - ), - }, - ) - ] - - return _runner - - # Valid cases - for index, blob in enumerate(VALID_BLOBS): - yield f"compute_cells_and_kzg_proofs_case_valid_{index}", get_test_runner(blob) - - # Edge case: Invalid blobs - for index, blob in enumerate(INVALID_BLOBS): - yield f"compute_cells_and_kzg_proofs_case_invalid_blob_{index}", get_test_runner(blob) - - -############################################################################### -# Test cases for verify_cell_kzg_proof_batch -############################################################################### - - -def case_verify_cell_kzg_proof_batch(): - def get_test_runner(input_getter): - def _runner(): - commitments, cell_indices, cells, proofs = input_getter() - try: - ok = None - ok = spec.verify_cell_kzg_proof_batch(commitments, cell_indices, cells, proofs) - except Exception: - pass - return [ - ( - "data", - "data", - { - "input": { - "commitments": encode_hex_list(commitments), - "cell_indices": cell_indices, - "cells": encode_hex_list(cells), - "proofs": encode_hex_list(proofs), - }, - "output": ok if ok is not None else None, - }, - ) - ] - - return _runner - - # Valid cases - for index, blob in enumerate(VALID_BLOBS): - - def get_inputs(blob=blob): - cells, proofs = cached_compute_cells_and_kzg_proofs(blob) - commitments = [cached_blob_to_kzg_commitment(blob) for _ in cells] - cell_indices = list(range(spec.CELLS_PER_EXT_BLOB)) - return commitments, cell_indices, cells, proofs - - yield f"verify_cell_kzg_proof_batch_case_valid_{index}", get_test_runner(get_inputs) - - # Valid: zero cells - if True: - - def get_inputs(): - return [], [], [], [] - - yield "verify_cell_kzg_proof_batch_case_valid_zero_cells", get_test_runner(get_inputs) - - # Valid: Verify cells from multiple blobs - if True: - - def get_inputs(): - cells0, proofs0 = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[0]) - cells1, proofs1 = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[1]) - commitments = [ - cached_blob_to_kzg_commitment(VALID_BLOBS[0]), - cached_blob_to_kzg_commitment(VALID_BLOBS[1]), - ] - cell_indices = [0, 0] - cells = [cells0[0], cells1[0]] - proofs = [proofs0[0], proofs1[0]] - return commitments, cell_indices, cells, proofs - - yield "verify_cell_kzg_proof_batch_case_valid_multiple_blobs", get_test_runner(get_inputs) - - # Valid: Same cell multiple times - if True: - - def get_inputs(): - num_duplicates = 3 - commitments = [cached_blob_to_kzg_commitment(VALID_BLOBS[3])] * num_duplicates - cell_indices = [0] * num_duplicates - cells = [cached_compute_cells_and_kzg_proofs(VALID_BLOBS[3])[0][0]] * num_duplicates - proofs = [cached_compute_cells_and_kzg_proofs(VALID_BLOBS[3])[1][0]] * num_duplicates - return commitments, cell_indices, cells, proofs - - yield ( - "verify_cell_kzg_proof_batch_case_valid_same_cell_multiple_times", - get_test_runner(get_inputs), - ) - - # Valid: Not sorted - if True: - - def get_inputs(): - cell_indices = [3, 2, 0, 1] - - commitments = [] - commitments.append(cached_blob_to_kzg_commitment(VALID_BLOBS[3])) - commitments.append(cached_blob_to_kzg_commitment(VALID_BLOBS[4])) - commitments.append(cached_blob_to_kzg_commitment(VALID_BLOBS[3])) - commitments.append(cached_blob_to_kzg_commitment(VALID_BLOBS[5])) - - cells = [] - cells.append(cached_compute_cells_and_kzg_proofs(VALID_BLOBS[3])[0][3]) - cells.append(cached_compute_cells_and_kzg_proofs(VALID_BLOBS[4])[0][2]) - cells.append(cached_compute_cells_and_kzg_proofs(VALID_BLOBS[3])[0][0]) - cells.append(cached_compute_cells_and_kzg_proofs(VALID_BLOBS[5])[0][1]) - - proofs = [] - proofs.append(cached_compute_cells_and_kzg_proofs(VALID_BLOBS[3])[1][3]) - proofs.append(cached_compute_cells_and_kzg_proofs(VALID_BLOBS[4])[1][2]) - proofs.append(cached_compute_cells_and_kzg_proofs(VALID_BLOBS[3])[1][0]) - proofs.append(cached_compute_cells_and_kzg_proofs(VALID_BLOBS[5])[1][1]) - - return commitments, cell_indices, cells, proofs - - yield ( - "verify_cell_kzg_proof_batch_case_valid_not_sorted", - get_test_runner(get_inputs), - ) - - # Valid: Regression from fusaka-devnet-5. - # - # In c-kzg-4844, given 8 or more blobs where one of the commitments was the point-at-infinity, - # the verification result would be incorrect. The 8 blob threshold is because c-kzg-4844 uses a - # naive MSM implementation for small inputs, which is why existing reference tests did not find - # the problem. The actual bug was in blst though; it was fixed here: - # https://github.com/supranational/blst/commit/f48500c1fdbefa7c0bf9800bccd65d28236799c1 - # - # Test inputs came from Teku here: - # https://github.com/Consensys/teku/pull/9893 - if True: - - def get_inputs(): - # fmt: off - commitments = [] - commitments.append(bytes.fromhex("b854f381e18109d9ab6df98769a21e7242184b9751b38d1abc132e5a5434418a4b0ad9e06ad29f9c71fa6aab93e9423b")) - commitments.append(bytes.fromhex("c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) - commitments.append(bytes.fromhex("8ace3bd3b1fea7377d20e065de07f99556721ed54855065f436edf17996973f7d04a6f5654d58205b4a8412c94ca821d")) - commitments.append(bytes.fromhex("ae6c661e5901116d00f1e8555734bdd8aa2d63ea26a92c3a333765b53b4436b1ded3f0e9c6dd2f990f715e817b3af756")) - commitments.append(bytes.fromhex("b09ace4559d243c732862c8a40e06afc4bb98a21011db1c6ee16df15c28d1c3d421b9991aa602db2fcf2410a37e6f7de")) - commitments.append(bytes.fromhex("8f9c4dbac70b5f818791a71edfaeef6b185c6d614377d7217acaa6df70a97067539f5ce4528e0e61b3bd64831b24b0fd")) - commitments.append(bytes.fromhex("8ae5c52c21b7d831bef232e428f16eaa28ae72b19e53902cb650417aa4c5311fc1b99b0ef9a3f2bb5232f63696d92382")) - commitments.append(bytes.fromhex("afa9021c53f2be07edc4aae82bf4d1f6777e2581c7b327ab1b75e9701d7d7cf45e9354cd2d5bd430da89f1ca89de3755")) - commitments.append(bytes.fromhex("b7b5f17d1d9ddca22815f327a8038cc6f1279ddae863e908d2a527d5a2707bd2aa496641635dcc4f8b265c7e7a6b53ff")) - commitments.append(bytes.fromhex("8dd8b69e18f913807af5c178902f23659945437527c2c75fc8ae7ffefbdf91b0a3f9a5ac78b48df09bb2e613695582f3")) - - # This case comes from a DataColumnSidecar(index=41) - cell_indices = [41] * len(commitments) - - cells = [] - cells.append(bytes.fromhex("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) - cells.append(bytes.fromhex("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) - cells.append(bytes.fromhex("0039aa9df5db058cb79e462c4d3036d677b714eb1a72685192cd6375406ff0b200b839ba04279f66026ddbf15d5730e5f1aae1609a463f2651e519057875928a003a0871c3e9b87f3998ad1b85c473b4e5e560239ac56f28b7c252b4cac0599f0006f4fcf37c88588f9f27d50e3224e83dec70620b50832c662124c03ecf4d3b00c1e76a55d7eab8339303d422c206efc3e3101aab80a8e2142f94793aee510100a1b53ef0424c8c5ca5240c697df3990a2f0c55cb22aa7b6dba1f9b496861b400b0ce842fef679bc7850b5d172f731196adf0c894fb59ed11b1d152ad99c4aa00d2e60701bad62c6793d95270a8165b160c3cbbeaa03749253187eb88c4ef46006283cbe0b11910d94eb564922a3810c2ef6b041f1e9b5c7304b28065f43622009cd823dabc556d40a2af78bc9c874ef9fca66010d7a8e040da3cf6818575e7002d28d8ff8045e8b3d20155b7667ccf89a06fb29de0d3e1bdce888ed5d02e4e001aa7c0c5ea29c035990bf4bb740daac678474e9cf97b77fcd8e96857aeb34d00bf4e665292e6670071f2881517d32a12f26ecbad17bed3e6d7181d458810e4007945c0d9815a93a56c1cdb0af536b256bc7e54f7232020227c4dafbbb79d190096d30d693e5f2f4f6ef73b5dc16e434381c18cdc9a6caaa87dc8d34f0005a3001cc8f38600471dac3ab880a8a7e96941894c4aea7bb2fd01eb8266fc16dc5b00208571813e8a4b7841bbd5088fc78bb6bbaad60d6e29d5a396c382ffdaf17800a8d6c79351ee9b8f31388dc73bfb9724cc0c34dfdf97e288518563afe41472001c021ed5ef37064d616ca50cf879696e12a5f58591a2edfbad34d661c6361b0078aa7a3171cb4b8d252b3cbf1b5a8a368350534aa27479248d7e3002e2ad050053bdee7dfb77724b39d4e398d6dfd32f9a7ad578d6158eb88f6bc012defcd200e5698160bc0f99e9f8541b51c70d62486d11779dbc2d4ad08484ec586c9d57005466452d630b92409a8c013f01ab4a2f422099e31d8e2d1950fc5c1b8d8c1a0000cf5e63bfe4ec59e689459444630d279f8aa33ec1240f50a68ed70ee3b878004149c19ab30937b0b482053c82e45e6616d0e7190e4969b6e47030d67f7de80035c0939010a985a77a5b193a02ab54fba2f80b3e2da30be4140aa1f154f4cf00c0d54139fb78f1827e302d84b8bf1b6cccd1abb98ea3382e1806d502c16a270043b8c2753f2a771f1ec7ed0a5857c1a21f040cadfecd602d63034cdee232a300079ddb764829d7095ec74749aeb48294612d3ae1045face2b1107edd126f8a0056c98e313d6e08d361a12003425bd36b030aa600ad29911f4037567a0e17f800809164e8146c5bc514fd4250e907662e68831a80f333c8344c01811fcbcc490096b91272abc7a00cd993aea27ac35cbdf27c7aeaf54a420930717e5bdd7252002a9ecbd82c18f7beb52139d6b668c1d79b4416c39de3144b0d26d10ff821b700f966aa99d45a7faff14134c2beac285dc1b6c4eead7957d97bea86d7fac89a0008f24da3d86c1bed5b38a418bf2f86aeec71b7ae61d320dd6cb128ed5de0e900f3f7b9f837f82471ce145712db3440b5b6990b4411be524c3c2d70edfd10d80052a408dadf34698c25da7469764ad24b2f66f6cadd29baf748cd78d576bd5a006bbf1a939b04ea37afd1b4a23401d6ab9c205a8c05c59d1a874351ad68d56f00bbd3a36d39853d9626882c4b90bf84f2f4288dcd5c102e43480488d71a2fb90096ec604e75a6fc27c0d6891dad3473da91f455198a3d4e33f14bf02506061400581dbaf6c37294de950424b8f47967e46b67fe387d2a86fff05f73cfe70e26002271e84b1c26daae542edbe9dd127d0503959d321dd6ef4bbe1ba44955242f005ad159ef4f4e4f65b238e4656081ed1410555e45d276b05b1cf70475fa8fbc0034e76537cae9249857b6bf92cea63e77906e0987ff090a609d4bbd4668f4d100a2e12496899742614b7e60b13efa0a4f4bb0e47e7c26b4c32ee92bd9c663eb00783dd1ec6e19f57665d5bc7a9dbde785350cd181d1b3802baf1d10082de15100e9ea7cd0d5f44de5de417771adf49c1f04bb7e2a5592640f6552ffae5bc21500ca6fd090a113d52295d420534eed4f61851bd9eac7c5ee108b5a8f3d7e967c006088980342c0854c9744b7448702ec8843e80491b1296cbf815caea3970cff00eded33c7b35f305604df3301b318f26448165a03b4dbcd9bd68548b31a48c30036fedea6980d39ba1d542815d1f5e77471f83ff7455c380a9e13bff500054000d669f39aeed2a72a20e1f9f5560745a7e49586ed9f33171ac07c8eef42110600000da0556f6c1003241b449687565e2c281fef93da9d9c714a6d8650defceb00a6dd378b4b1e0cafdd172a19b42fc2347da9d9596c3c99b1a87339bac94adc005fa5493314a84e82e9179f4d8b7ac5983830dba3151f3cc7c500831dafdf56001d413be5d4b83ccc944c4dd30478c32e28b1ed8b5cf1e97aefe348bd0f2824008f7741828d72baa66df519253714d11592f95e97347594b16061249e99d2f500e406378e6bafad704151725fd626f92640de511f0f9ac6a406a648fe783737006baf972d715bb1bdfb76897c1f01984c48fba8da23402c465387d0f7dd1b17005f3a0874cb607ee8bcdaab86c869abdcdf799b755cf259a7e0331a2b137b420085c8cd1715adb4e58c3d138de9feb9e486973f7cd307d73f8e8e831dca4620005bdb87804a275eaf8a6e2cafc97739ccfd0dfcebc273cf7450a744056281260072bab2f9fca8d34f676f245e9ab5152e8614b2e8879b6284dead0de63a96f4005cfc6ec166352bfe28579b7a52ad0e359f3809df67cd397d63abd9d006ee83")) - cells.append(bytes.fromhex("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) - cells.append(bytes.fromhex("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) - cells.append(bytes.fromhex("00048d34a9ee8df14099f4167b043b37cacbaa622c09b5338525199fe24c9c1300f3464d9fb58c0d84543171b3f9c4ae529146087de5629bfe8546c6c64c7a0a0017853b8e392be8c4abab1e4aef33cfce2abe4ae975c9a62f79f49080fc58bf00d2fdc9ef8f3108d9e3106c0e5aea7cdd8c1326876a50c8f877b6395be05dc60006664b9f62d4f2fe69c7c1377ece721a0e3fa0e29efbd3720539ea2779403a00b30a3403d0581469916b822df59041fe9b32622d3ef1cedd6139ca5b47d7cb004e174178e2287cbfe543e1d77e019ea465fe7d74705880c432552297a1350b004e2070d9caa59a0b78acf06052f0ec2666d540abb1e7756c55edb28db23b9000ed95539f72b4091254cb9125171cc658e2faa6a3d26341f7bdfefdd442d859001676825de61cbbedf50aa19cb95a857866df6c5f26cec3fd1832313e241a4d00fbf50d071d8145bb62f2d18cf63563a758c0b1a6c51dfa0224624ea1f134060088c6344d2574289623dc1e11a6ff3570f594c851c370804f1e213c5bd604c90090d48eda8da181f070d64f13853eb16f6f3a877fce465e7ba3e184295cb85200f3fe8c3264847d7152eacc07417f445bcbc6a9c2fe6bea43b6553a97ac4f0500e73d4828da0bd94ff59cd5b44a79365f26c21b964dea9dc8d902f34c866f2c0065eb7db5c878a53cd42d5b9bce3fd10b8cfd6811bf3ba99af29469d238646400d0e89e344c7ad56642e26a6a4c77c837cd48ccb7d43e475dfcf43d0eb4347900d83fa10da2de93ff94c8a479c9a50214bee03960a726d1273c0f5214f951ad000cc602b3e9065717b30dd0892848e1870a67d476f7e0136092a73c879e74ff00274d00e08da2a04a38435662fb7fa385a5587f521493183d96f797fd28a7390038ac1e8140f32571e7e4c743a5551808a2a694a7bc8284647acec77d4a14500054df291488fbddb60e146532efc040188561e631d872b6bed85a1a51c5c57a00320c45c9cc4317d79d3fc6f75a634a03fbdb09ca17ea33aa84de886029bff10051f2c8b79736fb7915dcb08176228bd76def747204faad6e3212878023421e001085b8a4f66a77d5c5e28ec6807d1962e5a02f803322fa972e35e4cef7ebc600728916bc88686fbbe4fe86fa614bc58150e2898e561433eeed5e0490ee4d93000db0d179d9332508811e3e17ca5b45bda8bd489a5964aedf0007bb96c5e67a004c063ff194e0bc7e20c41bf4b794fdf0e4511b262f167c327227023681d03f004003a22a215edc54ceec153b32fba83ed8847fa032dc00e65106b55a6256bf00c5ace98731bab0b6bb1a2750895c0742448811624f66a41d45ddb987a75c3d00dc9cf280e47c371cc613603998a7981ee85eab27112ae5d2d6d4521af16e9c00c1141087b20a349fdd98289ff511920017d8f6311a0c7b780a586589caa6bc0015f34e10f2269b5577581e82970cfa47134af55683ebfaff28f757d48d3cc400798cb57c5143290b2a306868fd10e20add34cea80f9113d4454d956cbde379008449c5e74f377e3e7a122536766ecdba350908f2823e4fc2f376eb2b3d21f500ea7659cd184a1928f2c514006b90c73c3943a38a4de3e02e021672c23fec9100feb096041ddeaa0b4ba7329c361dc4e0acce06807fccc3ef9363ef711d26d6002bf2c8e76ebdbe65f1fac60e0fd3a3c5e87186c04ba6096fdce8ce794ec28a002606c57beae3475c4fc1bee6a727a0c7970fb557e2cf6cfd4b5f719ee6da540056da840668ac1ed5c01c6b3174849837ae6ae8968adc2bdd8770b003b85ced00d6889245babf1f6af375e3892d81cc0c84b62bc7e327146a9379073532818e001e667e2da08179da670d098085c50329a29d73c0a2a0fce6a003f5146651ef00cde464289ca2fe14cb8ac5bca13aaaf74beb16aaecdcc830a230954639762a0027ecf12a74f05886273fda9a8fb215c4b469233eac96be952ff91bdefa3f1f006909cc12c440a50716b07120003dff7f74b768552a558b2c1b0f14848e93e2006beca40379fc6e014f97e8ab4f6d745bffc8634e8c6ed3eb5b9c658b350f630076264aed87640033d1567add40f3f06109eba63452ac023d0990fc9264061b00131e48216a1d7dbd8a42536d15b0af1e96c19775a7b946f77851c436b06e230010fd4e721c4102aad4dafe9bb7a8b87e0d1a45d696b097ca436408fd657aa70009274ca7b1346071705b5188e6e2e4682e6bd6fb868a95f3511040b9edab3500cdb49ec502dd44152724a5cb3f8139f03dcfd4f388277c1f70536dec8c28db006d317a2a74a8233d328f46002d59bce329943bb4cb47e22e47435783fcb9f6006d83b0649b7916dda4843fadae0eb84bf8e95bd155074a7b3f22a29b0aec60007bb59ad89ac32bca5531abff32474445fa67392512f836bc7e66b51de0fd80005e5ac27656f8df57dcca232ddc985b3835e1281a9fd0f6ab6a2752437f575200fc6187d02b06fd2bd4d9dc0b6348cd17489897353f91c08e5305490b9a4a7d0006b2cd6530a94d6a6433cd4643d502af18adca92dd4c6e2f775ab519cef2a300aefddd251f2264bbff829a02ab354332353d0ff6738c3ac71a0fd9800cc2b400710e47bd8827671c3ab02a5a6a75d4188900beb0983406797aa8b91a5e299500ac49f72bbaa09a2071f63242070c7eb6557aa2b4399cda87e7a53f101d7ee4000c71b1c23f456102cd9230b15319833b7e39a129c93e79d27ce5530d86411b007b9199a66061ee0855ad6c4b54aab5faa7f853a79a78af033334c06ebeb2d3002e77f3d8157a65f040f2b19ff8dbb7682265e957c5c0b4d4b9163464e01268003cdd694dcd0f204358f6582a3810f9252223ebf0770d6e8d89bc29c15c53de")) - cells.append(bytes.fromhex("00c49b376cd0a2ed62fdb0542fa62cb2ee87e75fa4649ec2a95a91f4b1e2d8d800570a90f4939f60c123ee945d7fa06ce9ffd6facb622ea1158c008be4513bcc00f3fae389614f0dc1f8c000a2ad41df7f3a69835d867c0f084a53cf4618edd40066ed15ceee79a96f686883051c700793a2daf646a36d6783b4ce2ee9fc6de700296e88931434490a0161e4d21b9417d62053a1eb83dabf01e4935c2fb8c871008723eff8757313fbda4e7c18d02f4500abf5745879487e4f85e5c61beeb0460009ff30e0c4aadef826ea2c48ffd22e1939aabc1a27c4ad5df25f6be54a94840054758c3fc538120f380010e1af64820c9e3d480b8c1f6f92f222e5683ec92d00d2767b236d13e6585ad6446c6d35b3a3ac73c0209f53c0c766b4beaf7e4108007b9e3dba3886f76c3c0262b85733ffd179664ab2ec9fb1c1b6b573dbc3409b00ecf7a6bb6bf65d1c801d6af6609aa87705d7e07a58cc19b7e0feb3d062024300a1ba721d0299ffbc2ae1a417e6d1bdf8082f7e563dc20e015b593884724d8a009fe0950ab49c953dbe739e89a9f209920683dfc431d8c650f87276134bbc0e001b2f8cd802d886ac216c1a54c14272f9d489f7ba468671aab02c2bf4e7b40400254f7f84a2a3693ab3ea43a7e55d6ba6ea00bfd57c7dd0813623a4470d9bbe00007a4e4b1b93c025663eb80913b7de7754a74b9a00ec290c4eaf51eb3a45ab00d5090e747645bdc4714cb0f8b906fed5b62a949b8b61f0887e2ee51659268c0030672fda8f33b457d865ae59479209d8f76a2e35771b5a63f44b8a61e4262a0020e5aac80fa90f10efdf49b757a43c7c5d5054c89bb7893e8f4ddf498c813d00904ecb5b63e71f861aa42be2266a22678826267322a76f8431408d9cad527c0009731cad0d9f634466c16b6ffccab534bded9ffcdbcc1e34204575e4e9cd770064734b53d93bae235deb2de8811ba848228035e905d1148ae55fa3154b89910054b256f6e659fd1250282b000e75528e3d26b453ac26b3f2990dbbcc4bef2e002cee176a402059bd4f64039050a6fdca5ea2f46df19ec81c09497bafaf3be300b656cc6ee54c0ecd15584badda53384d49e25bf5efba093f497a1dab0193ec005ddcc9ae5e3853f1e9f30961d5e5299113f13a2c9789f7c6ae086891c2593700956ec15dc8a45e8a4c4a4d5102494c9775c56fb0df1115268e07a5900a28c300159c950b70a1290c5b5c1835c047fcebe083cf1fd2376724a4cb119adb45240029dd3a3e1e1d8f38671a4407382078b13a01bec834db752e3bc15424cfa73600dfa26055d745971a3b143a9a736ffaafd9e3a12b8f7f5f63848dcaf2b27cf800f8ec9ec18fc0ad48d94867cbf1b9ccb7d04b049261dbcf89ff461597d361d900306f852ce37c6a8b6a8dd53f71d15fe4f285916187214bdac278d9e28cb76b001fe567da874b8371cc9cbfa7e3ded684414057a68280ce87188e6fe45c50b8002434b4dda7b6e33aed83ef7106638773490168caa0275199fd560b4f6c658b003273ecce6bb6c897f270f1b3aca8930459cacac541b0806a87fe024a33eea2008673f8fdeda9fb7e96cc0215cbec8c99abd29558972238241aeae4af94062e00663f2630f7d07737e27dc78ffbddf3b9f217739dec0f86bd9bdaaf2018fd160022124f1c3852c7e6a300a0ab7f4cfccd9d55c4cf4347a25bf2ddf13c6ec01e00b6daf38bc8ef4eb4e6789917391b0e74799518b843906e2f616e9681d2c633002a7ddcbf96760777c9afa100e9a4e0b7dc03e9c7bd22f95cf267fb86d8e50000e77616de7447a74ef69fea377dadd55d22affb2ce5275440ba090a6b6aa54a00d5037cbd99ee1f5eaa2069c5279fbddd7ce030a0aed1fceb3ced1a7276ea290046570594465ed946432d752d4ddd670af0cc2660fd1a5845ef2c48a7a9432700e6e4fc416c58b51618d7637f09a7b7ddbd5820fcafa5132a21b0650bb5e8f4009bf1dddda661797c6398e9748ae02e20895b931f97e448ef56b74141119f0a005335a127a7896e9b5ac09fa02350dba92249a145fe8b16d5463b828899ba64009fe9e2e97c7a885009efd1e6ca313254b9dd34191c1f6a1ff5025eb3a11a6900b1a75837f14207afaae9d7163580e52ca3b18437f1cf9de159552a88db3732004215283b1665daefb129b918284cc6d2f89bc5f41e76fe770c800a708c648c006c99ec5d9808a1bbc7b9c8806ca114e27a880022c1b52777c295f162f89a4d00af1e7ca0d2748d38ebd02eafcb4e9124ca35e02a49a4f821cdd653ffb6d283007f8c92d0c64df01d5b9b09a44dc67667a14bde6287c522123a108720011e6b00ffb7b9187081068b1f255d8dda7a5058a8d98e6ff0c7ff47df7f33f76e8e4f00b0d3bd4053eb2695de9ca68c69ea235befd7e805e6097d82005a6ece6ed0660030e523ee030d474b08c3f2b9b5d238d06dc0256a3c772ba25f8c45f6904f98002355b8d0afe4c970bf6c2ee79ea525dfc08b3a8e5bfacb9a05aa410edafb8a000ef5f23c17fbb6cb35a1aadd833684ada62b9468ed85f244923d6efb07f84e00e07a658143379fb3cd74bb67f00fa57da2ae7c02c289f22f60df63cc4c1d3c004df7269d5c39ff56bfd721b36c4bf0dcbb25f28d51e9acddc1be128abd0b39006ed245cdb1f172f271c379445cc7f2be32bb7353c5dbb9a916ad94108ea274008ece432918ea37879594a942b18ebe3920d9a9b9cc1fb16bc866cedfc333bd00d4c1ff1c9da7215fa351f60fd5fc6375abb8c32a287362a51bd49e1d976b4900a3af57a2c9bd26ace18f5959b750c174311bd174317a3cb0a981615ad7885f00c64d04034c04a267b2d3bdaa12fb9c291ce4a1e747c37ac66c5e38dc456293")) - cells.append(bytes.fromhex("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) - cells.append(bytes.fromhex("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) - cells.append(bytes.fromhex("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) - - proofs = [] - proofs.append(bytes.fromhex("87f5479eb540c88b0e6d790d901de990ebded06410774891e21f1b0e27f9b6a68b547e1a2d5c779298d22844d9f979b3")) - proofs.append(bytes.fromhex("c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) - proofs.append(bytes.fromhex("9769f9395f56dc41314a65dd0cfc05bedbcc1616c96dad73b252bdaeb5f4a9b1ffe01ca710978dc56ee6f775eb44d211")) - proofs.append(bytes.fromhex("9200f1f4730536c43fb2e87f8d920d473dd177f935d0d8dc5cbc069ca7158a1897d0e124f7777a34ffd00c0d63eb4ee6")) - proofs.append(bytes.fromhex("a701b8ad14b15f1225093832b1c2f28306a7924641d32f82da760428146d66ed127548c0a3d446d81a20f5382229294d")) - proofs.append(bytes.fromhex("b33e2d16efc03b838e81d759c2bed0ecf9ec81d9aa70743c8dd86b2a3f240d60bca14dc7528bc960d478abef8e8e80ac")) - proofs.append(bytes.fromhex("85916811fa3299b4fd8ad3567b5796444693c8e72c3451d09788935199b4d5aebd7036b9aa4c539a3fa15ecaaf3dbabf")) - proofs.append(bytes.fromhex("b36f5457ef6700a1802a33f70b5c1e4d8edb79130533255ab39d379a34580528e3a82895a788c5a6731117e32c37a266")) - proofs.append(bytes.fromhex("b363a0b7f79f5d5f976f42f89d6b8d49a93163c42a236039116cadadbd260fc4f9832218d55480ca6ca3efc9da9f25d0")) - proofs.append(bytes.fromhex("98c9663a80a003f7e97e5bb13f3b37af7a5f08a76cfe170b099e62bddc2cf9dd0d46755a34e6eb99bd58cc11dcec6618")) - # fmt: on - - return commitments, cell_indices, cells, proofs - - yield ( - "verify_cell_kzg_proof_batch_case_valid_regression1", - get_test_runner(get_inputs), - ) - - # Incorrect commitment - if True: - - def get_inputs(): - cells, proofs = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[5]) - cells, proofs = cells[:1], proofs[:1] - # Use the wrong commitment - commitments = [bls_add_one(cached_blob_to_kzg_commitment(VALID_BLOBS[5]))] - cell_indices = list(range(len(cells))) - return commitments, cell_indices, cells, proofs - - yield "verify_cell_kzg_proof_batch_case_incorrect_commitment", get_test_runner(get_inputs) - - # Incorrect cell - if True: - - def get_inputs(): - cells, proofs = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[6]) - cells, proofs = cells[:1], proofs[:1] - commitments = [cached_blob_to_kzg_commitment(VALID_BLOBS[6])] - cell_indices = list(range(len(cells))) - # Change last cell so it's wrong - cells[-1] = CELL_RANDOM_VALID2 - return commitments, cell_indices, cells, proofs - - yield "verify_cell_kzg_proof_batch_case_incorrect_cell", get_test_runner(get_inputs) - - # Incorrect proof - if True: - - def get_inputs(): - cells, proofs = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[0]) - cells, proofs = cells[:1], proofs[:1] - commitments = [cached_blob_to_kzg_commitment(VALID_BLOBS[0])] - cell_indices = list(range(len(cells))) - # Change last proof so it's wrong - proofs[-1] = bls_add_one(proofs[-1]) - return commitments, cell_indices, cells, proofs - - yield "verify_cell_kzg_proof_batch_case_incorrect_proof", get_test_runner(get_inputs) - - # Edge case: Invalid commitment - for index, commitment in enumerate(INVALID_G1_POINTS): - - def get_inputs(index=index, commitment=commitment): - cells, proofs = cached_compute_cells_and_kzg_proofs( - VALID_BLOBS[index % len(INVALID_G1_POINTS)] - ) - cells, proofs = cells[:1], proofs[:1] - # Set commitments to the invalid commitment - commitments = [commitment] - cell_indices = list(range(len(cells))) - return commitments, cell_indices, cells, proofs - - yield ( - f"verify_cell_kzg_proof_batch_case_invalid_commitment_{index}", - get_test_runner(get_inputs), - ) - - # Edge case: Invalid cell_index - if True: - - def get_inputs(): - cells, proofs = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[1]) - cells, proofs = cells[:1], proofs[:1] - commitments = [cached_blob_to_kzg_commitment(VALID_BLOBS[1])] - cell_indices = list(range(len(cells))) - # Set first cell index to an invalid value - cell_indices[0] = int(spec.CELLS_PER_EXT_BLOB) - return commitments, cell_indices, cells, proofs - - yield "verify_cell_kzg_proof_batch_case_invalid_cell_index", get_test_runner(get_inputs) - - # Edge case: Invalid cell - for index, cell in enumerate(INVALID_INDIVIDUAL_CELL_BYTES): - - def get_inputs(index=index, cell=cell): - cells, proofs = cached_compute_cells_and_kzg_proofs( - VALID_BLOBS[index % len(INVALID_INDIVIDUAL_CELL_BYTES)] - ) - cells, proofs = cells[:1], proofs[:1] - commitments = [ - cached_blob_to_kzg_commitment( - VALID_BLOBS[index % len(INVALID_INDIVIDUAL_CELL_BYTES)] - ) - ] - cell_indices = list(range(len(cells))) - # Set first cell to the invalid cell - cells[0] = cell - return commitments, cell_indices, cells, proofs - - yield f"verify_cell_kzg_proof_batch_case_invalid_cell_{index}", get_test_runner(get_inputs) - - # Edge case: Invalid proof - for index, proof in enumerate(INVALID_G1_POINTS): - - def get_inputs(index=index, proof=proof): - cells, proofs = cached_compute_cells_and_kzg_proofs( - VALID_BLOBS[index % len(INVALID_G1_POINTS)] - ) - cells, proofs = cells[:1], proofs[:1] - commitments = [ - cached_blob_to_kzg_commitment(VALID_BLOBS[index % len(INVALID_G1_POINTS)]) - ] - cell_indices = list(range(len(cells))) - # Set first proof to the invalid proof - proofs[0] = proof - return commitments, cell_indices, cells, proofs - - yield f"verify_cell_kzg_proof_batch_case_invalid_proof_{index}", get_test_runner(get_inputs) - - # Edge case: Missing a commitment - if True: - - def get_inputs(): - cells, proofs = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[0]) - cells, proofs = cells[:2], proofs[:2] - # Do not include the second commitment - commitments = [cached_blob_to_kzg_commitment(VALID_BLOBS[0])] - cell_indices = list(range(len(cells))) - return commitments, cell_indices, cells, proofs - - yield ( - "verify_cell_kzg_proof_batch_case_invalid_missing_commitment", - get_test_runner(get_inputs), - ) - - # Edge case: Missing a cell index - if True: - - def get_inputs(): - cells, proofs = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[2]) - cells, proofs = cells[:2], proofs[:2] - commitments = [ - cached_blob_to_kzg_commitment(VALID_BLOBS[2]), - cached_blob_to_kzg_commitment(VALID_BLOBS[2]), - ] - # Leave off one of the cell indices - cell_indices = list(range(len(cells) - 1)) - return commitments, cell_indices, cells, proofs - - yield ( - "verify_cell_kzg_proof_batch_case_invalid_missing_cell_index", - get_test_runner(get_inputs), - ) - - # Edge case: Missing a cell - if True: - - def get_inputs(): - cells, proofs = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[3]) - cells, proofs = cells[:2], proofs[:2] - commitments = [ - cached_blob_to_kzg_commitment(VALID_BLOBS[3]), - cached_blob_to_kzg_commitment(VALID_BLOBS[3]), - ] - cell_indices = list(range(len(cells))) - # Remove the last proof - cells = cells[:-1] - return commitments, cell_indices, cells, proofs - - yield "verify_cell_kzg_proof_batch_case_invalid_missing_cell", get_test_runner(get_inputs) - - # Edge case: Missing a proof - if True: - - def get_inputs(): - cells, proofs = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[4]) - cells, proofs = cells[:2], proofs[:2] - commitments = [ - cached_blob_to_kzg_commitment(VALID_BLOBS[4]), - cached_blob_to_kzg_commitment(VALID_BLOBS[4]), - ] - cell_indices = list(range(len(cells))) - # Remove the last proof - proofs = proofs[:-1] - return commitments, cell_indices, cells, proofs - - yield "verify_cell_kzg_proof_batch_case_invalid_missing_proof", get_test_runner(get_inputs) - - -############################################################################### -# Test cases for recover_cells_and_kzg_proofs -############################################################################### - - -def case_recover_cells_and_kzg_proofs(): - def get_test_runner(input_getter): - def _runner(): - cell_indices, cells = input_getter() - try: - recovered_cells, recovered_proofs = None, None - recovered_cells, recovered_proofs = spec.recover_cells_and_kzg_proofs( - cell_indices, cells - ) - except Exception: - pass - return [ - ( - "data", - "data", - { - "input": { - "cell_indices": cell_indices, - "cells": encode_hex_list(cells), - }, - "output": ( - (encode_hex_list(recovered_cells), encode_hex_list(recovered_proofs)) - if recovered_cells is not None - else None - ), - }, - ) - ] - - return _runner - - # Valid: No missing cells - if True: - - def get_inputs(): - cells, _ = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[0]) - cell_indices = list(range(spec.CELLS_PER_EXT_BLOB)) - return cell_indices, cells - - yield "recover_cells_and_kzg_proofs_case_valid_no_missing", get_test_runner(get_inputs) - - # Valid: Half missing cells (every other cell) - if True: - - def get_inputs(): - cells, _ = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[1]) - cell_indices = list(range(0, spec.CELLS_PER_EXT_BLOB, 2)) - partial_cells = [cells[cell_index] for cell_index in cell_indices] - return cell_indices, partial_cells - - yield ( - "recover_cells_and_kzg_proofs_case_valid_half_missing_every_other_cell", - get_test_runner(get_inputs), - ) - - # Valid: Half missing cells (first half) - if True: - - def get_inputs(): - cells, _ = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[2]) - cell_indices = list(range(0, spec.CELLS_PER_EXT_BLOB // 2)) - partial_cells = [cells[cell_index] for cell_index in cell_indices] - return cell_indices, partial_cells - - yield ( - "recover_cells_and_kzg_proofs_case_valid_half_missing_first_half", - get_test_runner(get_inputs), - ) - - # Valid: Half missing cells (second half) - if True: - - def get_inputs(): - cells, _ = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[3]) - cell_indices = list(range(spec.CELLS_PER_EXT_BLOB // 2, spec.CELLS_PER_EXT_BLOB)) - partial_cells = [cells[cell_index] for cell_index in cell_indices] - return cell_indices, partial_cells - - yield ( - "recover_cells_and_kzg_proofs_case_valid_half_missing_second_half", - get_test_runner(get_inputs), - ) - - # Edge case: All cells are missing - if True: - - def get_inputs(): - return [], [] - - yield ( - "recover_cells_and_kzg_proofs_case_invalid_all_cells_are_missing", - get_test_runner(get_inputs), - ) - - # Edge case: More than half missing - if True: - - def get_inputs(): - cells, _ = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[4]) - cell_indices = list(range(spec.CELLS_PER_EXT_BLOB // 2 - 1)) - partial_cells = [cells[cell_index] for cell_index in cell_indices] - return cell_indices, partial_cells - - yield ( - "recover_cells_and_kzg_proofs_case_invalid_more_than_half_missing", - get_test_runner(get_inputs), - ) - - # Edge case: More cells provided than CELLS_PER_EXT_BLOB - if True: - - def get_inputs(): - cells, _ = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[5]) - cell_indices = list(range(spec.CELLS_PER_EXT_BLOB)) + [0] - partial_cells = [cells[cell_index] for cell_index in cell_indices] - return cell_indices, partial_cells - - yield ( - "recover_cells_and_kzg_proofs_case_invalid_more_cells_than_cells_per_ext_blob", - get_test_runner(get_inputs), - ) - - # Edge case: Invalid cell_index - if True: - - def get_inputs(): - cells, _ = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[6]) - cell_indices = list(range(spec.CELLS_PER_EXT_BLOB // 2)) - partial_cells = [cells[cell_index] for cell_index in cell_indices] - # Replace first cell_index with an invalid value - cell_indices[0] = int(spec.CELLS_PER_EXT_BLOB) - return cell_indices, partial_cells - - yield "recover_cells_and_kzg_proofs_case_invalid_cell_index", get_test_runner(get_inputs) - - # Edge case: Invalid cell - for index, cell in enumerate(INVALID_INDIVIDUAL_CELL_BYTES): - - def get_inputs(cell=cell): - cells, _ = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[6]) - cell_indices = list(range(spec.CELLS_PER_EXT_BLOB // 2)) - partial_cells = [cells[cell_index] for cell_index in cell_indices] - # Replace first cell with an invalid value - partial_cells[0] = cell - return cell_indices, partial_cells - - yield f"recover_cells_and_kzg_proofs_case_invalid_cell_{index}", get_test_runner(get_inputs) - - # Edge case: More cell_indices than cells - if True: - - def get_inputs(): - cells, _ = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[0]) - cell_indices = list(range(0, spec.CELLS_PER_EXT_BLOB, 2)) - partial_cells = [cells[cell_index] for cell_index in cell_indices] - # Add another cell_index - cell_indices.append(int(spec.CELLS_PER_EXT_BLOB - 1)) - return cell_indices, partial_cells - - yield ( - "recover_cells_and_kzg_proofs_case_invalid_more_cell_indices_than_cells", - get_test_runner(get_inputs), - ) - - # Edge case: More cells than cell_indices - if True: - - def get_inputs(): - cells, _ = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[1]) - cell_indices = list(range(0, spec.CELLS_PER_EXT_BLOB, 2)) - partial_cells = [cells[cell_index] for cell_index in cell_indices] - # Add another cell - partial_cells.append(CELL_RANDOM_VALID1) - return cell_indices, partial_cells - - yield ( - "recover_cells_and_kzg_proofs_case_invalid_more_cells_than_cell_indices", - get_test_runner(get_inputs), - ) - - # Edge case: Duplicate cell_index - if True: - - def get_inputs(): - cells, _ = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[2]) - # There will be 65 cells, where 64 are unique and 1 is a duplicate. - # Depending on the implementation, 63 & 1 might not fail for the right - # reason. For example, if the implementation assigns cells in an array - # via index, this would result in 63 cells and the test would fail due - # to insufficient cell count, not because of a duplicate cell. - cell_indices = list(range(spec.CELLS_PER_EXT_BLOB // 2 + 1)) - partial_cells = [cells[cell_index] for cell_index in cell_indices] - # Replace first cell_index with the second cell_index - cell_indices[0] = cell_indices[1] - return cell_indices, partial_cells - - yield ( - "recover_cells_and_kzg_proofs_case_invalid_duplicate_cell_index", - get_test_runner(get_inputs), - ) - - # Edge case: Shuffled indices, no missing - if True: - - def get_inputs(): - cells, _ = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[4]) - cell_indices = list(range(spec.CELLS_PER_EXT_BLOB)) - random.seed(42) # Use fixed seed for reproducibility - random.shuffle(cell_indices) - all_cells = [cells[cell_index] for cell_index in cell_indices] - return cell_indices, all_cells - - yield ( - "recover_cells_and_kzg_proofs_case_invalid_shuffled_no_missing", - get_test_runner(get_inputs), - ) - - # Edge case: Shuffled indices, one missing - if True: - - def get_inputs(): - cells, _ = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[5]) - cell_indices = list(range(spec.CELLS_PER_EXT_BLOB - 1)) - random.seed(42) # Use fixed seed for reproducibility - random.shuffle(cell_indices) - partial_cells = [cells[cell_index] for cell_index in cell_indices] - return cell_indices, partial_cells - - yield ( - "recover_cells_and_kzg_proofs_case_invalid_shuffled_one_missing", - get_test_runner(get_inputs), - ) - - # Edge case: Shuffled indices, half missing - if True: - - def get_inputs(): - cells, _ = cached_compute_cells_and_kzg_proofs(VALID_BLOBS[5]) - cell_indices = list(range(spec.CELLS_PER_EXT_BLOB // 2)) - random.seed(42) # Use fixed seed for reproducibility - random.shuffle(cell_indices) - partial_cells = [cells[cell_index] for cell_index in cell_indices] - return cell_indices, partial_cells - - yield ( - "recover_cells_and_kzg_proofs_case_invalid_shuffled_half_missing", - get_test_runner(get_inputs), - ) - - -############################################################################### -# Test cases for compute_verify_cell_kzg_proof_batch_challenge -############################################################################### - - -def case_compute_verify_cell_kzg_proof_batch_challenge(): - def get_test_runner(input_getter): - def _runner(): - commitments, commitment_indices, cell_indices, cosets_evals, proofs = input_getter() - try: - challenge = None - challenge = spec.compute_verify_cell_kzg_proof_batch_challenge( - commitments, commitment_indices, cell_indices, cosets_evals, proofs - ) - except Exception: - pass - return [ - ( - "data", - "data", - { - "input": { - "commitments": encode_hex_list(commitments), - "commitment_indices": commitment_indices, - "cell_indices": cell_indices, - "cosets_evals": [ - [encode_hex(spec.bls_field_to_bytes(eval)) for eval in coset_evals] - for coset_evals in cosets_evals - ], - "proofs": encode_hex_list(proofs), - }, - "output": encode_hex(spec.bls_field_to_bytes(challenge)) - if challenge is not None - else None, - }, - ) - ] - - return _runner - - # Valid: Empty inputs - if True: - - def get_inputs(): - return [], [], [], [], [] - - yield ( - "compute_verify_cell_kzg_proof_batch_challenge_case_empty", - get_test_runner(get_inputs), - ) - - # Valid: Single cell - if True: - - def get_inputs(): - blob = VALID_BLOBS[0] - cells, proofs = cached_compute_cells_and_kzg_proofs(blob) - commitment = cached_blob_to_kzg_commitment(blob) - - commitments = [commitment] - commitment_indices = [0] - cell_indices = [0] - cosets_evals = [spec.cell_to_coset_evals(cells[0])] - proofs_selected = [proofs[0]] - - return commitments, commitment_indices, cell_indices, cosets_evals, proofs_selected - - yield ( - "compute_verify_cell_kzg_proof_batch_challenge_case_single_cell", - get_test_runner(get_inputs), - ) - - # Valid: Multiple cells from single blob - if True: - - def get_inputs(): - blob = VALID_BLOBS[1] - cells, proofs = cached_compute_cells_and_kzg_proofs(blob) - commitment = cached_blob_to_kzg_commitment(blob) - - num_cells = 4 - commitments = [commitment] - commitment_indices = [0] * num_cells - cell_indices = list(range(num_cells)) - cosets_evals = [spec.cell_to_coset_evals(cells[i]) for i in range(num_cells)] - proofs_selected = [proofs[i] for i in range(num_cells)] - - return commitments, commitment_indices, cell_indices, cosets_evals, proofs_selected - - yield ( - "compute_verify_cell_kzg_proof_batch_challenge_case_multiple_cells_single_blob", - get_test_runner(get_inputs), - ) - - # Valid: Multiple cells from multiple blobs - if True: - - def get_inputs(): - blob0 = VALID_BLOBS[2] - blob1 = VALID_BLOBS[3] - cells0, proofs0 = cached_compute_cells_and_kzg_proofs(blob0) - cells1, proofs1 = cached_compute_cells_and_kzg_proofs(blob1) - commitment0 = cached_blob_to_kzg_commitment(blob0) - commitment1 = cached_blob_to_kzg_commitment(blob1) - - commitments = [commitment0, commitment1] - commitment_indices = [0, 1, 0, 1] - cell_indices = [0, 1, 2, 3] - cosets_evals = [ - spec.cell_to_coset_evals(cells0[0]), - spec.cell_to_coset_evals(cells1[1]), - spec.cell_to_coset_evals(cells0[2]), - spec.cell_to_coset_evals(cells1[3]), - ] - proofs_selected = [proofs0[0], proofs1[1], proofs0[2], proofs1[3]] - - return commitments, commitment_indices, cell_indices, cosets_evals, proofs_selected - - yield ( - "compute_verify_cell_kzg_proof_batch_challenge_case_multiple_cells_multiple_blobs", - get_test_runner(get_inputs), - ) - - # Valid: Same cell multiple times (duplicate cells) - if True: - - def get_inputs(): - blob = VALID_BLOBS[4] - cells, proofs = cached_compute_cells_and_kzg_proofs(blob) - commitment = cached_blob_to_kzg_commitment(blob) - - num_duplicates = 3 - commitments = [commitment] - commitment_indices = [0] * num_duplicates - cell_indices = [5] * num_duplicates # Same cell index repeated - cosets_evals = [spec.cell_to_coset_evals(cells[5])] * num_duplicates - proofs_selected = [proofs[5]] * num_duplicates - - return commitments, commitment_indices, cell_indices, cosets_evals, proofs_selected - - yield ( - "compute_verify_cell_kzg_proof_batch_challenge_case_duplicate_cells", - get_test_runner(get_inputs), - ) - - # Valid: Many cells (stress test with many cells) - if True: - - def get_inputs(): - blob = VALID_BLOBS[5] - cells, proofs = cached_compute_cells_and_kzg_proofs(blob) - commitment = cached_blob_to_kzg_commitment(blob) - - # Use half of all cells - num_cells = spec.CELLS_PER_EXT_BLOB // 2 - commitments = [commitment] - commitment_indices = [0] * num_cells - cell_indices = list(range(num_cells)) - cosets_evals = [spec.cell_to_coset_evals(cells[i]) for i in range(num_cells)] - proofs_selected = [proofs[i] for i in range(num_cells)] - - return commitments, commitment_indices, cell_indices, cosets_evals, proofs_selected - - yield ( - "compute_verify_cell_kzg_proof_batch_challenge_case_many_cells", - get_test_runner(get_inputs), - ) - - # Valid: Non-sequential cell indices - if True: - - def get_inputs(): - blob = VALID_BLOBS[6] - cells, proofs = cached_compute_cells_and_kzg_proofs(blob) - commitment = cached_blob_to_kzg_commitment(blob) - - # Use non-sequential indices - indices = [10, 5, 20, 15, 0, 30] - commitments = [commitment] - commitment_indices = [0] * len(indices) - cell_indices = indices - cosets_evals = [spec.cell_to_coset_evals(cells[i]) for i in indices] - proofs_selected = [proofs[i] for i in indices] - - return commitments, commitment_indices, cell_indices, cosets_evals, proofs_selected - - yield ( - "compute_verify_cell_kzg_proof_batch_challenge_case_non_sequential_indices", - get_test_runner(get_inputs), - ) - - # Valid: Mixed commitment indices order - if True: - - def get_inputs(): - blob0 = VALID_BLOBS[0] - blob1 = VALID_BLOBS[1] - blob2 = VALID_BLOBS[2] - cells0, proofs0 = cached_compute_cells_and_kzg_proofs(blob0) - cells1, proofs1 = cached_compute_cells_and_kzg_proofs(blob1) - cells2, proofs2 = cached_compute_cells_and_kzg_proofs(blob2) - commitment0 = cached_blob_to_kzg_commitment(blob0) - commitment1 = cached_blob_to_kzg_commitment(blob1) - commitment2 = cached_blob_to_kzg_commitment(blob2) - - # Mix up the order of commitment indices - commitments = [commitment0, commitment1, commitment2] - commitment_indices = [2, 0, 1, 0, 2, 1] - cell_indices = [0, 1, 2, 3, 4, 5] - cosets_evals = [ - spec.cell_to_coset_evals(cells2[0]), - spec.cell_to_coset_evals(cells0[1]), - spec.cell_to_coset_evals(cells1[2]), - spec.cell_to_coset_evals(cells0[3]), - spec.cell_to_coset_evals(cells2[4]), - spec.cell_to_coset_evals(cells1[5]), - ] - proofs_selected = [ - proofs2[0], - proofs0[1], - proofs1[2], - proofs0[3], - proofs2[4], - proofs1[5], - ] - - return commitments, commitment_indices, cell_indices, cosets_evals, proofs_selected - - yield ( - "compute_verify_cell_kzg_proof_batch_challenge_case_mixed_commitment_indices", - get_test_runner(get_inputs), - ) - - # Valid: Maximum cell index values - if True: - - def get_inputs(): - blob = VALID_BLOBS[3] - cells, proofs = cached_compute_cells_and_kzg_proofs(blob) - commitment = cached_blob_to_kzg_commitment(blob) - - # Use the highest valid cell indices - max_index = spec.CELLS_PER_EXT_BLOB - 1 - indices = [max_index, max_index - 1, max_index - 2] - commitments = [commitment] - commitment_indices = [0] * len(indices) - cell_indices = indices - cosets_evals = [spec.cell_to_coset_evals(cells[i]) for i in indices] - proofs_selected = [proofs[i] for i in indices] - - return commitments, commitment_indices, cell_indices, cosets_evals, proofs_selected - - yield ( - "compute_verify_cell_kzg_proof_batch_challenge_case_max_cell_indices", - get_test_runner(get_inputs), - ) - - # Valid: All cells from a blob - if True: - - def get_inputs(): - blob = VALID_BLOBS[4] - cells, proofs = cached_compute_cells_and_kzg_proofs(blob) - commitment = cached_blob_to_kzg_commitment(blob) - - # Use all cells - num_cells = spec.CELLS_PER_EXT_BLOB - commitments = [commitment] - commitment_indices = [0] * num_cells - cell_indices = list(range(num_cells)) - cosets_evals = [spec.cell_to_coset_evals(cells[i]) for i in range(num_cells)] - proofs_selected = proofs - - return commitments, commitment_indices, cell_indices, cosets_evals, proofs_selected - - yield ( - "compute_verify_cell_kzg_proof_batch_challenge_case_all_cells", - get_test_runner(get_inputs), - ) - - -############################################################################### -# Main logic -############################################################################### - - -def get_test_cases() -> Iterable[TestCase]: - test_case_fns = [ - ("compute_cells", case_compute_cells), - ("compute_cells_and_kzg_proofs", case_compute_cells_and_kzg_proofs), - ("verify_cell_kzg_proof_batch", case_verify_cell_kzg_proof_batch), - ("recover_cells_and_kzg_proofs", case_recover_cells_and_kzg_proofs), - ( - "compute_verify_cell_kzg_proof_batch_challenge", - case_compute_verify_cell_kzg_proof_batch_challenge, - ), - ] - - test_cases = [] - for handler_name, test_case_fn in test_case_fns: - for case_name, case_fn in test_case_fn(): - test_cases.append( - TestCase( - fork_name=FULU, - preset_name="general", - runner_name="kzg", - handler_name=handler_name, - suite_name="kzg-mainnet", - case_name=case_name, - case_fn=case_fn, - ) - ) - return test_cases