Remove proof parameter from `recover_cells_and_kzg_proofs` (#3819)

This commit is contained in:
kevaundray 2024-06-27 20:17:14 +01:00 committed by GitHub
parent 0a49572799
commit a3a6c916b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 35 additions and 103 deletions

View File

@ -179,9 +179,8 @@ def recover_matrix(partial_matrix: Sequence[MatrixEntry],
for blob_index in range(blob_count):
cell_indices = [e.column_index for e in partial_matrix if e.row_index == blob_index]
cells = [e.cell for e in partial_matrix if e.row_index == blob_index]
proofs = [e.kzg_proof for e in partial_matrix if e.row_index == blob_index]
recovered_cells, recovered_proofs = recover_cells_and_kzg_proofs(cell_indices, cells, proofs)
recovered_cells, recovered_proofs = recover_cells_and_kzg_proofs(cell_indices, cells)
for cell_index, (cell, proof) in enumerate(zip(recovered_cells, recovered_proofs)):
extended_matrix.append(MatrixEntry(
cell=cell,

View File

@ -645,8 +645,7 @@ def recover_data(cell_indices: Sequence[CellIndex],
```python
def recover_cells_and_kzg_proofs(cell_indices: Sequence[CellIndex],
cells: Sequence[Cell],
proofs_bytes: Sequence[Bytes48]) -> Tuple[
cells: Sequence[Cell]) -> Tuple[
Vector[Cell, CELLS_PER_EXT_BLOB],
Vector[KZGProof, CELLS_PER_EXT_BLOB]]:
"""
@ -660,7 +659,7 @@ def recover_cells_and_kzg_proofs(cell_indices: Sequence[CellIndex],
Public method.
"""
assert len(cell_indices) == len(cells) == len(proofs_bytes)
assert len(cell_indices) == len(cells)
# Check we have enough cells to be able to perform the reconstruction
assert CELLS_PER_EXT_BLOB / 2 <= len(cell_indices) <= CELLS_PER_EXT_BLOB
# Check for duplicates
@ -671,9 +670,6 @@ def recover_cells_and_kzg_proofs(cell_indices: Sequence[CellIndex],
# Check that each cell is the correct length
for cell in cells:
assert len(cell) == BYTES_PER_CELL
# Check that each proof is the correct length
for proof_bytes in proofs_bytes:
assert len(proof_bytes) == BYTES_PER_PROOF
# Convert cells to coset evals
cosets_evals = [cell_to_coset_evals(cell) for cell in cells]
@ -692,14 +688,12 @@ def recover_cells_and_kzg_proofs(cell_indices: Sequence[CellIndex],
polynomial_eval = reconstructed_data[:FIELD_ELEMENTS_PER_BLOB]
polynomial_coeff = polynomial_eval_to_coeff(polynomial_eval)
recovered_proofs = [None] * CELLS_PER_EXT_BLOB
for i, cell_index in enumerate(cell_indices):
recovered_proofs[cell_index] = bytes_to_kzg_proof(proofs_bytes[i])
for i in range(CELLS_PER_EXT_BLOB):
if recovered_proofs[i] is None:
coset = coset_for_cell(CellIndex(i))
proof, ys = compute_kzg_proof_multi_impl(polynomial_coeff, coset)
assert coset_evals_to_cell(ys) == recovered_cells[i]
recovered_proofs[i] = proof
coset = coset_for_cell(CellIndex(i))
proof, ys = compute_kzg_proof_multi_impl(polynomial_coeff, coset)
assert coset_evals_to_cell(ys) == recovered_cells[i]
recovered_proofs[i] = proof
return recovered_cells, recovered_proofs
```

View File

@ -164,12 +164,11 @@ def test_recover_cells_and_kzg_proofs(spec):
while j in cell_indices:
j = rng.randint(0, spec.CELLS_PER_EXT_BLOB - 1)
cell_indices.append(j)
# Now the cells/proofs themselves
# Now the cells themselves
known_cells = [cells[cell_index] for cell_index in cell_indices]
known_proofs = [proofs[cell_index] for cell_index in cell_indices]
# Recover the missing cells and proofs
recovered_cells, recovered_proofs = spec.recover_cells_and_kzg_proofs(cell_indices, known_cells, known_proofs)
recovered_cells, recovered_proofs = spec.recover_cells_and_kzg_proofs(cell_indices, known_cells)
recovered_data = [x for xs in recovered_cells for x in xs]
# Check that the original data match the non-extended portion of the recovered data

View File

@ -21,4 +21,4 @@ All byte(s) fields are encoded as strings, hexadecimal encoding, prefixed with `
## Condition
The `recover_cells_and_kzg_proofs` handler should recover missing cells and proofs, and the result should match the expected `output`. If any cell is invalid (e.g. incorrect length or one of the 32-byte blocks does not represent a BLS field element), any proof is invalid (e.g. not on the curve or not in the G1 subgroup of the BLS curve), or any `cell_index` is invalid (e.g. greater than the number of cells for an extended blob), it should error, i.e. the output should be `null`.
The `recover_cells_and_kzg_proofs` handler should recover missing cells and proofs, and the result should match the expected `output`. If any cell is invalid (e.g. incorrect length or one of the 32-byte blocks does not represent a BLS field element), or any `cell_index` is invalid (e.g. greater than the number of cells for an extended blob), it should error, i.e. the output should be `null`.

View File

@ -13,7 +13,6 @@ from eth2spec.test.helpers.typing import SpecForkName
from eth2spec.test.utils.kzg_tests import (
CELL_RANDOM_VALID1,
CELL_RANDOM_VALID2,
G1,
INVALID_BLOBS,
INVALID_G1_POINTS,
INVALID_INDIVIDUAL_CELL_BYTES,
@ -593,15 +592,14 @@ def case_recover_cells_and_kzg_proofs():
# Valid: No missing cells
cells, proofs = VALID_CELLS_AND_PROOFS[0]
cell_indices = list(range(spec.CELLS_PER_EXT_BLOB))
recovered_cells, recovered_proofs = spec.recover_cells_and_kzg_proofs(cell_indices, cells, proofs)
recovered_cells, recovered_proofs = spec.recover_cells_and_kzg_proofs(cell_indices, cells)
assert recovered_cells == cells
assert recovered_proofs == proofs
identifier = make_id(cell_indices, cells, proofs)
identifier = make_id(cell_indices, cells)
yield f'recover_cells_and_kzg_proofs_case_valid_no_missing_{identifier}', {
'input': {
'cell_indices': cell_indices,
'cells': encode_hex_list(cells),
'proofs': encode_hex_list(proofs),
},
'output': (encode_hex_list(recovered_cells), encode_hex_list(recovered_proofs))
}
@ -610,16 +608,14 @@ def case_recover_cells_and_kzg_proofs():
cells, proofs = VALID_CELLS_AND_PROOFS[1]
cell_indices = list(range(0, spec.CELLS_PER_EXT_BLOB, 2))
partial_cells = [cells[cell_index] for cell_index in cell_indices]
partial_proofs = [proofs[cell_index] for cell_index in cell_indices]
recovered_cells, recovered_proofs = spec.recover_cells_and_kzg_proofs(cell_indices, partial_cells, partial_proofs)
recovered_cells, recovered_proofs = spec.recover_cells_and_kzg_proofs(cell_indices, partial_cells)
assert recovered_cells == cells
assert recovered_proofs == proofs
identifier = make_id(cell_indices, partial_cells, partial_proofs)
identifier = make_id(cell_indices, partial_cells)
yield f'recover_cells_and_kzg_proofs_case_valid_half_missing_every_other_cell_{identifier}', {
'input': {
'cell_indices': cell_indices,
'cells': encode_hex_list(partial_cells),
'proofs': encode_hex_list(partial_proofs),
},
'output': (encode_hex_list(recovered_cells), encode_hex_list(recovered_proofs))
}
@ -628,8 +624,7 @@ def case_recover_cells_and_kzg_proofs():
cells, proofs = VALID_CELLS_AND_PROOFS[2]
cell_indices = list(range(0, spec.CELLS_PER_EXT_BLOB // 2))
partial_cells = [cells[cell_index] for cell_index in cell_indices]
partial_proofs = [proofs[cell_index] for cell_index in cell_indices]
recovered_cells, recovered_proofs = spec.recover_cells_and_kzg_proofs(cell_indices, partial_cells, partial_proofs)
recovered_cells, recovered_proofs = spec.recover_cells_and_kzg_proofs(cell_indices, partial_cells)
assert recovered_cells == cells
assert recovered_proofs == proofs
identifier = make_id(cell_indices, partial_cells)
@ -637,7 +632,6 @@ def case_recover_cells_and_kzg_proofs():
'input': {
'cell_indices': cell_indices,
'cells': encode_hex_list(partial_cells),
'proofs': encode_hex_list(partial_proofs),
},
'output': (encode_hex_list(recovered_cells), encode_hex_list(recovered_proofs))
}
@ -646,8 +640,7 @@ def case_recover_cells_and_kzg_proofs():
cells, proofs = VALID_CELLS_AND_PROOFS[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]
partial_proofs = [proofs[cell_index] for cell_index in cell_indices]
recovered_cells, recovered_proofs = spec.recover_cells_and_kzg_proofs(cell_indices, partial_cells, partial_proofs)
recovered_cells, recovered_proofs = spec.recover_cells_and_kzg_proofs(cell_indices, partial_cells)
assert recovered_cells == cells
assert recovered_proofs == proofs
identifier = make_id(cell_indices, partial_cells)
@ -655,7 +648,6 @@ def case_recover_cells_and_kzg_proofs():
'input': {
'cell_indices': cell_indices,
'cells': encode_hex_list(partial_cells),
'proofs': encode_hex_list(partial_proofs),
},
'output': (encode_hex_list(recovered_cells), encode_hex_list(recovered_proofs))
}
@ -668,95 +660,67 @@ def case_recover_cells_and_kzg_proofs():
'input': {
'cell_indices': cell_indices,
'cells': encode_hex_list(partial_cells),
'proofs': encode_hex_list(partial_proofs),
},
'output': None
}
# Edge case: More than half missing
cells, proofs = VALID_CELLS_AND_PROOFS[4]
cells, _ = VALID_CELLS_AND_PROOFS[4]
cell_indices = list(range(spec.CELLS_PER_EXT_BLOB // 2 - 1))
partial_cells = [cells[cell_index] for cell_index in cell_indices]
partial_proofs = [proofs[cell_index] for cell_index in cell_indices]
expect_exception(spec.recover_cells_and_kzg_proofs, cell_indices, partial_cells, partial_proofs)
identifier = make_id(cell_indices, partial_cells, partial_proofs)
expect_exception(spec.recover_cells_and_kzg_proofs, cell_indices, partial_cells)
identifier = make_id(cell_indices, partial_cells)
yield f'recover_cells_and_kzg_proofs_case_invalid_more_than_half_missing_{identifier}', {
'input': {
'cell_indices': cell_indices,
'cells': encode_hex_list(partial_cells),
'proofs': encode_hex_list(partial_proofs),
},
'output': None
}
# Edge case: More cells provided than CELLS_PER_EXT_BLOB
cells, proofs = VALID_CELLS_AND_PROOFS[5]
cells, _ = VALID_CELLS_AND_PROOFS[5]
cell_indices = list(range(spec.CELLS_PER_EXT_BLOB)) + [0]
partial_cells = [cells[cell_index] for cell_index in cell_indices]
partial_proofs = [proofs[cell_index] for cell_index in cell_indices]
expect_exception(spec.recover_cells_and_kzg_proofs, cell_indices, partial_cells, partial_proofs)
identifier = make_id(cell_indices, partial_cells, partial_proofs)
expect_exception(spec.recover_cells_and_kzg_proofs, cell_indices, partial_cells)
identifier = make_id(cell_indices, partial_cells)
yield f'recover_cells_and_kzg_proofs_case_invalid_more_cells_than_cells_per_ext_blob_{identifier}', {
'input': {
'cell_indices': cell_indices,
'cells': encode_hex_list(partial_cells),
'proofs': encode_hex_list(partial_proofs),
},
'output': None
}
# Edge case: Invalid cell_index
cells, proofs = VALID_CELLS_AND_PROOFS[6]
cells, _ = VALID_CELLS_AND_PROOFS[6]
cell_indices = list(range(spec.CELLS_PER_EXT_BLOB // 2))
partial_cells = [cells[cell_index] for cell_index in cell_indices]
partial_proofs = [proofs[cell_index] for cell_index in cell_indices]
# Replace first cell_index with an invalid value
cell_indices[0] = spec.CELLS_PER_EXT_BLOB
expect_exception(spec.recover_cells_and_kzg_proofs, cell_indices, partial_cells, partial_proofs)
identifier = make_id(cell_indices, partial_cells, partial_proofs)
expect_exception(spec.recover_cells_and_kzg_proofs, cell_indices, partial_cells)
identifier = make_id(cell_indices, partial_cells)
yield f'recover_cells_and_kzg_proofs_case_invalid_cell_index_{identifier}', {
'input': {
'cell_indices': cell_indices,
'cells': encode_hex_list(partial_cells),
'proofs': encode_hex_list(partial_proofs),
},
'output': None
}
# Edge case: Invalid cell
for cell in INVALID_INDIVIDUAL_CELL_BYTES:
cells, proofs = VALID_CELLS_AND_PROOFS[6]
cells, _ = VALID_CELLS_AND_PROOFS[6]
cell_indices = list(range(spec.CELLS_PER_EXT_BLOB // 2))
partial_cells = [cells[cell_index] for cell_index in cell_indices]
partial_proofs = [proofs[cell_index] for cell_index in cell_indices]
# Replace first cell with an invalid value
partial_cells[0] = cell
expect_exception(spec.recover_cells_and_kzg_proofs, cell_indices, partial_cells, partial_proofs)
identifier = make_id(cell_indices, partial_cells, partial_proofs)
expect_exception(spec.recover_cells_and_kzg_proofs, cell_indices, partial_cells)
identifier = make_id(cell_indices, partial_cells)
yield f'recover_cells_and_kzg_proofs_case_invalid_cell_{identifier}', {
'input': {
'cell_indices': cell_indices,
'cells': encode_hex_list(partial_cells),
'proofs': encode_hex_list(partial_proofs),
},
'output': None
}
# Edge case: Invalid proof
for proof in INVALID_G1_POINTS:
cells, proofs = VALID_CELLS_AND_PROOFS[0]
cell_indices = list(range(spec.CELLS_PER_EXT_BLOB // 2))
partial_cells = [cells[cell_index] for cell_index in cell_indices]
partial_proofs = [proofs[cell_index] for cell_index in cell_indices]
# Replace first proof with an invalid value
partial_proofs[0] = proof
expect_exception(spec.recover_cells_and_kzg_proofs, cell_indices, partial_cells, partial_proofs)
identifier = make_id(cell_indices, partial_cells, partial_proofs)
yield f'recover_cells_and_kzg_proofs_case_invalid_proof_{identifier}', {
'input': {
'cell_indices': cell_indices,
'cells': encode_hex_list(partial_cells),
'proofs': encode_hex_list(partial_proofs),
},
'output': None
}
@ -765,16 +729,14 @@ def case_recover_cells_and_kzg_proofs():
cells, proofs = VALID_CELLS_AND_PROOFS[0]
cell_indices = list(range(0, spec.CELLS_PER_EXT_BLOB, 2))
partial_cells = [cells[cell_index] for cell_index in cell_indices]
partial_proofs = [proofs[cell_index] for cell_index in cell_indices]
# Add another cell_index
cell_indices.append(spec.CELLS_PER_EXT_BLOB - 1)
expect_exception(spec.recover_cells_and_kzg_proofs, cell_indices, partial_cells, partial_proofs)
identifier = make_id(cell_indices, partial_cells, partial_proofs)
expect_exception(spec.recover_cells_and_kzg_proofs, cell_indices, partial_cells)
identifier = make_id(cell_indices, partial_cells)
yield f'recover_cells_and_kzg_proofs_case_invalid_more_cell_indices_than_cells_{identifier}', {
'input': {
'cell_indices': cell_indices,
'cells': encode_hex_list(partial_cells),
'proofs': encode_hex_list(partial_proofs),
},
'output': None
}
@ -783,34 +745,14 @@ def case_recover_cells_and_kzg_proofs():
cells, proofs = VALID_CELLS_AND_PROOFS[1]
cell_indices = list(range(0, spec.CELLS_PER_EXT_BLOB, 2))
partial_cells = [cells[cell_index] for cell_index in cell_indices]
partial_proofs = [proofs[cell_index] for cell_index in cell_indices]
# Add another cell
partial_cells.append(CELL_RANDOM_VALID1)
expect_exception(spec.recover_cells_and_kzg_proofs, cell_indices, partial_cells, partial_proofs)
identifier = make_id(cell_indices, partial_cells, partial_proofs)
expect_exception(spec.recover_cells_and_kzg_proofs, cell_indices, partial_cells)
identifier = make_id(cell_indices, partial_cells)
yield f'recover_cells_and_kzg_proofs_case_invalid_more_cells_than_cell_indices_{identifier}', {
'input': {
'cell_indices': cell_indices,
'cells': encode_hex_list(partial_cells),
'proofs': encode_hex_list(partial_proofs),
},
'output': None
}
# Edge case: More proofs than cell_indices
cells, proofs = VALID_CELLS_AND_PROOFS[1]
cell_indices = list(range(0, spec.CELLS_PER_EXT_BLOB, 2))
partial_cells = [cells[cell_index] for cell_index in cell_indices]
partial_proofs = [proofs[cell_index] for cell_index in cell_indices]
# Add another proof
partial_proofs.append(G1)
expect_exception(spec.recover_cells_and_kzg_proofs, cell_indices, partial_cells, partial_proofs)
identifier = make_id(cell_indices, partial_cells, partial_proofs)
yield f'recover_cells_and_kzg_proofs_case_invalid_more_proofs_than_cell_indices_{identifier}', {
'input': {
'cell_indices': cell_indices,
'cells': encode_hex_list(partial_cells),
'proofs': encode_hex_list(partial_proofs),
},
'output': None
}
@ -824,16 +766,14 @@ def case_recover_cells_and_kzg_proofs():
# 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]
partial_proofs = [proofs[cell_index] for cell_index in cell_indices]
# Replace first cell_index with the second cell_index
cell_indices[0] = cell_indices[1]
expect_exception(spec.recover_cells_and_kzg_proofs, cell_indices, partial_cells, partial_proofs)
identifier = make_id(cell_indices, partial_cells, partial_proofs)
expect_exception(spec.recover_cells_and_kzg_proofs, cell_indices, partial_cells)
identifier = make_id(cell_indices, partial_cells)
yield f'recover_cells_and_kzg_proofs_case_invalid_duplicate_cell_index_{identifier}', {
'input': {
'cell_indices': cell_indices,
'cells': encode_hex_list(partial_cells),
'proofs': encode_hex_list(partial_proofs),
},
'output': None
}