Skip to content

Commit

Permalink
Public methods must accept raw bytes
Browse files Browse the repository at this point in the history
  • Loading branch information
asn-d6 committed Jan 15, 2024
1 parent b4d418d commit 789e24e
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 20 deletions.
48 changes: 36 additions & 12 deletions specs/_features/eip7594/polynomial-commitments-sampling.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ Cells are the smallest unit of blob data that can come with their own KZG proofs

## Helper functions

### BLS12-381 helpers

#### `bytes_to_cell`

```python
def bytes_to_cell(cell_bytes: Vector[Bytes32, FIELD_ELEMENTS_PER_CELL]) -> Cell:
"""
Convert untrusted bytes into a Cell.
"""
return [bytes_to_bls_field(element) for element in cell_bytes]
```

### Linear combinations

#### `g2_lincomb`
Expand Down Expand Up @@ -397,28 +409,32 @@ def compute_cells(blob: Blob) -> Vector[Cell, CELLS_PER_BLOB]:
#### `verify_cell_proof`

```python
def verify_cell_proof(commitment: KZGCommitment,
def verify_cell_proof(commitment_bytes: Bytes48,
cell_id: int,
cell: Cell,
proof: KZGProof) -> bool:
cell_bytes: Vector[Bytes32, FIELD_ELEMENTS_PER_CELL],
proof: Bytes48) -> bool:
"""
Check a cell proof
Public method.
"""
coset = coset_for_cell(cell_id)

return verify_kzg_proof_multi_impl(commitment, coset, cell, proof)
return verify_kzg_proof_multi_impl(
bytes_to_kzg_commitment(commitment_bytes),
coset,
bytes_to_cell(cell_bytes),
bytes_to_kzg_proof(proof))
```

#### `verify_cell_proof_batch`

```python
def verify_cell_proof_batch(row_commitments: Sequence[KZGCommitment],
def verify_cell_proof_batch(row_commitments_bytes: Sequence[Bytes48],
row_ids: Sequence[int],
column_ids: Sequence[int],
cells: Sequence[Cell],
proofs: Sequence[KZGProof]) -> bool:
cells_bytes: Sequence[Vector[Bytes32, FIELD_ELEMENTS_PER_CELL]],
proofs_bytes: Sequence[Bytes48]) -> bool:
"""
Check multiple cell proofs. This function implements the naive algorithm of checking every cell
individually; an efficient algorithm can be found here:
Expand All @@ -430,10 +446,14 @@ def verify_cell_proof_batch(row_commitments: Sequence[KZGCommitment],
Public method.
"""

# Get commitments via row IDs
commitments = [row_commitments[row_id] for row_id in row_ids]

commitments_bytes = [row_commitments_bytes[row_id] for row_id in row_ids]

# Get objects from bytes
commitments = [bytes_to_kzg_commitment(commitment_bytes) for commitment_bytes in commitments_bytes]
cells = [bytes_to_cell(cell_bytes) for cell_bytes in cells_bytes]
proofs = [bytes_to_kzg_proof(proof_bytes) for proof_bytes in proofs_bytes]

return all(
verify_kzg_proof_multi_impl(commitment, coset_for_cell(column_id), cell, proof)
for commitment, column_id, cell, proof in zip(commitments, column_ids, cells, proofs)
Expand All @@ -445,7 +465,8 @@ def verify_cell_proof_batch(row_commitments: Sequence[KZGCommitment],
### `recover_polynomial`

```python
def recover_polynomial(cell_ids: Sequence[CellID], cells: Sequence[Cell]) -> Polynomial:
def recover_polynomial(cell_ids: Sequence[CellID],
cells_bytes: Sequence[Vector[Bytes32, FIELD_ELEMENTS_PER_CELL]]) -> Polynomial:
"""
Recovers a polynomial from 2 * FIELD_ELEMENTS_PER_CELL evaluations, half of which can be missing.
Expand All @@ -455,7 +476,10 @@ def recover_polynomial(cell_ids: Sequence[CellID], cells: Sequence[Cell]) -> Pol
Public method.
"""
assert len(cell_ids) == len(cells)
assert len(cell_ids) == len(cells_bytes)

cells = [bytes_to_cell(cell_bytes) for cell_bytes in cells_bytes]

assert len(cells) >= CELLS_PER_BLOB // 2
missing_cell_ids = [cell_id for cell_id in range(CELLS_PER_BLOB) if cell_id not in cell_ids]
roots_of_unity_reduced = compute_roots_of_unity(CELLS_PER_BLOB)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
from eth2spec.utils.bls import BLS_MODULUS


def field_element_bytes(x):
return int.to_bytes(x % BLS_MODULUS, 32, "big")


@with_eip7594_and_later
@spec_test
@single_phase
Expand All @@ -34,10 +38,13 @@ def test_verify_cell_proof(spec):
blob = get_sample_blob(spec)
commitment = spec.blob_to_kzg_commitment(blob)
cells, proofs = spec.compute_cells_and_proofs(blob)

cells_bytes = [[field_element_bytes(element) for element in cell] for cell in cells]

cell_id = 0
assert spec.verify_cell_proof(commitment, cell_id, cells[cell_id], proofs[cell_id])
assert spec.verify_cell_proof(commitment, cell_id, cells_bytes[cell_id], proofs[cell_id])
cell_id = 1
assert spec.verify_cell_proof(commitment, cell_id, cells[cell_id], proofs[cell_id])
assert spec.verify_cell_proof(commitment, cell_id, cells_bytes[cell_id], proofs[cell_id])


@with_eip7594_and_later
Expand All @@ -48,12 +55,14 @@ def test_verify_cell_proof_batch(spec):
commitment = spec.blob_to_kzg_commitment(blob)
cells, proofs = spec.compute_cells_and_proofs(blob)

cells_bytes = [[field_element_bytes(element) for element in cell] for cell in cells]

assert spec.verify_cell_proof_batch(
row_commitments=[commitment],
row_commitments_bytes=[commitment],
row_ids=[0],
column_ids=[0, 1],
cells=cells[0:1],
proofs=proofs,
cells_bytes=cells_bytes[0:1],
proofs_bytes=proofs,
)


Expand All @@ -73,21 +82,21 @@ def test_recover_polynomial(spec):

# Extend data with Reed-Solomon and split the extended data in cells
cells = spec.compute_cells(blob)
cells_bytes = [[field_element_bytes(element) for element in cell] for cell in cells]

# Compute the cells we will be recovering from
cell_ids = []
known_cells = []
# First figure out just the indices of the cells
for i in range(N_SAMPLES):
j = rng.randint(0, spec.CELLS_PER_BLOB)
while j in cell_ids:
j = rng.randint(0, spec.CELLS_PER_BLOB)
cell_ids.append(j)
# Now the cells themselves
known_cells = [cells[cell_id] for cell_id in cell_ids]
known_cells_bytes = [cells_bytes[cell_id] for cell_id in cell_ids]

# Recover the data
recovered_data = spec.recover_polynomial(cell_ids, known_cells)
recovered_data = spec.recover_polynomial(cell_ids, known_cells_bytes)

# Check that the original data match the non-extended portion of the recovered data
assert original_polynomial == recovered_data[:len(recovered_data) // 2]
Expand Down

0 comments on commit 789e24e

Please sign in to comment.