Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removes SSZ and updates the crypto API #3030

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 120 additions & 22 deletions specs/eip4844/polynomial-commitments.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,35 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Introduction](#introduction)
- [Custom types](#custom-types)
- [Constants](#constants)
- [Preset](#preset)
- [Trusted setup](#trusted-setup)
- [Helper functions](#helper-functions)
- [Bit-reversal permutation](#bit-reversal-permutation)
- [`is_power_of_two`](#is_power_of_two)
- [`reverse_bits`](#reverse_bits)
- [`bit_reversal_permutation`](#bit_reversal_permutation)
- [BLS12-381 helpers](#bls12-381-helpers)
- [`bytes_to_bls_field`](#bytes_to_bls_field)
- [`bls_modular_inverse`](#bls_modular_inverse)
- [`div`](#div)
- [`g1_lincomb`](#g1_lincomb)
- [`vector_lincomb`](#vector_lincomb)
- [KZG](#kzg)
- [`blob_to_kzg_commitment`](#blob_to_kzg_commitment)
- [`verify_kzg_proof`](#verify_kzg_proof)
- [`compute_kzg_proof`](#compute_kzg_proof)
- [Polynomials](#polynomials)
- [`evaluate_polynomial_in_evaluation_form`](#evaluate_polynomial_in_evaluation_form)
- [EIP-4844 -- Polynomial Commitments](#eip-4844----polynomial-commitments)
- [Table of contents](#table-of-contents)
- [Introduction](#introduction)
- [Custom types](#custom-types)
- [Constants](#constants)
- [Preset](#preset)
- [Trusted setup](#trusted-setup)
- [Helper functions](#helper-functions)
- [Bit-reversal permutation](#bit-reversal-permutation)
- [`is_power_of_two`](#is_power_of_two)
- [`reverse_bits`](#reverse_bits)
- [`bit_reversal_permutation`](#bit_reversal_permutation)
- [BLS12-381 helpers](#bls12-381-helpers)
- [`bytes_to_bls_field`](#bytes_to_bls_field)
- [`hash_to_bls_field`](#hash_to_bls_field)
- [`bls_modular_inverse`](#bls_modular_inverse)
- [`div`](#div)
- [`g1_lincomb`](#g1_lincomb)
- [`vector_lincomb`](#vector_lincomb)
- [`compute_powers`](#compute_powers)
- [KZG](#kzg)
- [`blob_to_kzg_commitment`](#blob_to_kzg_commitment)
- [`verify_kzg_proof`](#verify_kzg_proof)
- [`compute_kzg_proof`](#compute_kzg_proof)
- [Polynomials](#polynomials)
- [`evaluate_polynomial_in_evaluation_form`](#evaluate_polynomial_in_evaluation_form)
- [`compute_aggregated_poly_and_commitment`](#compute_aggregated_poly_and_commitment)
- [`compute_aggregrate_kzg_proof`](#compute_aggregrate_kzg_proof)
- [`verify_aggregrate_kzg_proof`](#verify_aggregrate_kzg_proof)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- /TOC -->
Expand Down Expand Up @@ -122,6 +129,30 @@ def bytes_to_bls_field(b: Bytes32) -> BLSFieldElement:
return int.from_bytes(b, "little") % BLS_MODULUS
```

### `hash_to_bls_field`

```python
def hash_to_bls_field(polys: List[Polynomial], comms: List[KZGCommitment]) -> BLSFieldElement:
"""
Compute 32-byte hash of serialised polynomials and commitments concatenated
This hash is then converted to a BLS field.
The output is not uniform over the BLS field.
"""

bytes = []

# Append each polynomial
for poly in polys:
for serialised_evaluation in poly:
bytes.extend(serialised_evaluation)

# Append serialised g1 points
for serialised_comm in comms:
bytes.extend(serialised_comm)

return bytes_to_bls_field(hash(bytes))
```

#### `bls_modular_inverse`

```python
Expand Down Expand Up @@ -171,6 +202,21 @@ def vector_lincomb(vectors: Sequence[Sequence[BLSFieldElement]],
return [BLSFieldElement(x) for x in result]
```

### `compute_powers`

```python
def compute_powers(x: BLSFieldElement, n: uint64) -> Sequence[BLSFieldElement]:
"""
Return ``x`` to power of [0, n-1].
"""
current_power = 1
powers = []
for _ in range(n):
powers.append(BLSFieldElement(current_power))
current_power = current_power * int(x) % BLS_MODULUS
return powers
```

### KZG

KZG core functions. These are also defined in EIP-4844 execution specs.
Expand Down Expand Up @@ -226,6 +272,7 @@ def compute_kzg_proof(polynomial: Sequence[BLSFieldElement], z: BLSFieldElement)
return KZGProof(g1_lincomb(bit_reversal_permutation(KZG_SETUP_LAGRANGE), quotient_polynomial))
```


### Polynomials

#### `evaluate_polynomial_in_evaluation_form`
Expand Down Expand Up @@ -254,3 +301,54 @@ def evaluate_polynomial_in_evaluation_form(polynomial: Sequence[BLSFieldElement]
return result
```

### `compute_aggregated_poly_and_commitment`

```python
def compute_aggregated_poly_and_commitment(
blobs: Sequence[Sequence[BLSFieldElement]],
kzg_commitments: Sequence[KZGCommitment]) -> Tuple[Polynomial, KZGCommitment]:
"""
Return the aggregated polynomial and aggregated KZG commitment.
"""
# Generate random linear combination challenges
r = hash_to_bls_field(blobs, kzg_commitments)
r_powers = compute_powers(r, len(kzg_commitments))

# Create aggregated polynomial in evaluation form
aggregated_poly = Polynomial(vector_lincomb(blobs, r_powers))

# Compute commitment to aggregated polynomial
aggregated_poly_commitment = KZGCommitment(g1_lincomb(kzg_commitments, r_powers))

return aggregated_poly, aggregated_poly_commitment
```

### `compute_aggregrate_kzg_proof`

```python
def compute_aggregrate_kzg_proof(blobs: Sequence[BLSFieldElement]) -> KZGProof:
commitments = [blob_to_kzg_commitment(blob) for blob in blobs]
aggregated_poly, aggregated_poly_commitment = compute_aggregated_poly_and_commitment(blobs, commitments)
x = hash_to_bls_field([aggregated_poly],[aggregated_poly_commitment])
return compute_kzg_proof(aggregated_poly, x)
```

### `verify_aggregrate_kzg_proof`

```python
def verify_aggregrate_kzg_proof(blobs: Sequence[BLSFieldElement],expected_kzg_commitments: Sequence[KZGCommitment], kzg_aggregated_proof : KZGCommitment):

aggregated_poly, aggregated_poly_commitment = compute_aggregated_poly_and_commitment(
blobs,
expected_kzg_commitments,
)

# Generate challenge `x` and evaluate the aggregated polynomial at `x`
x = hash_to_bls_field([aggregated_poly], [aggregated_poly_commitment])
# Evaluate aggregated polynomial at `x` (evaluation function checks for div-by-zero)
y = evaluate_polynomial_in_evaluation_form(aggregated_poly, x)

# Verify aggregated proof
assert verify_kzg_proof(aggregated_poly_commitment, x, y, kzg_aggregated_proof)
```

121 changes: 20 additions & 101 deletions specs/eip4844/validator.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,21 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Introduction](#introduction)
- [Prerequisites](#prerequisites)
- [Custom types](#custom-types)
- [Containers](#containers)
- [`BlobsAndCommitments`](#blobsandcommitments)
- [`PolynomialAndCommitment`](#polynomialandcommitment)
- [Helpers](#helpers)
- [`is_data_available`](#is_data_available)
- [`hash_to_bls_field`](#hash_to_bls_field)
- [`compute_powers`](#compute_powers)
- [`compute_aggregated_poly_and_commitment`](#compute_aggregated_poly_and_commitment)
- [`validate_blobs_sidecar`](#validate_blobs_sidecar)
- [`compute_proof_from_blobs`](#compute_proof_from_blobs)
- [`get_blobs_and_kzg_commitments`](#get_blobs_and_kzg_commitments)
- [Beacon chain responsibilities](#beacon-chain-responsibilities)
- [Block proposal](#block-proposal)
- [Constructing the `BeaconBlockBody`](#constructing-the-beaconblockbody)
- [Blob KZG commitments](#blob-kzg-commitments)
- [Beacon Block publishing time](#beacon-block-publishing-time)
- [EIP-4844 -- Honest Validator](#eip-4844----honest-validator)
- [Table of contents](#table-of-contents)
- [Introduction](#introduction)
- [Prerequisites](#prerequisites)
- [Custom types](#custom-types)
- [Helpers](#helpers)
- [`is_data_available`](#is_data_available)
- [`validate_blobs_sidecar`](#validate_blobs_sidecar)
- [`compute_proof_from_blobs`](#compute_proof_from_blobs)
- [`get_blobs_and_kzg_commitments`](#get_blobs_and_kzg_commitments)
- [Beacon chain responsibilities](#beacon-chain-responsibilities)
- [Block proposal](#block-proposal)
- [Constructing the `BeaconBlockBody`](#constructing-the-beaconblockbody)
- [Blob KZG commitments](#blob-kzg-commitments)
- [Beacon Block publishing time](#beacon-block-publishing-time)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- /TOC -->
Expand All @@ -49,23 +45,6 @@ Please see related Beacon Chain doc before continuing and use them as a referenc
| - | - | - |
| `Polynomial` | `List[BLSFieldElement, FIELD_ELEMENTS_PER_BLOB]` | a polynomial in evaluation form |

## Containers

### `BlobsAndCommitments`

```python
class BlobsAndCommitments(Container):
blobs: List[Blob, MAX_BLOBS_PER_BLOCK]
kzg_commitments: List[KZGCommitment, MAX_BLOBS_PER_BLOCK]
```

### `PolynomialAndCommitment`

```python
class PolynomialAndCommitment(Container):
polynomial: Polynomial
kzg_commitment: KZGCommitment
```


## Helpers
Expand All @@ -88,52 +67,8 @@ def is_data_available(slot: Slot, beacon_block_root: Root, blob_kzg_commitments:
return True
```

### `hash_to_bls_field`

```python
def hash_to_bls_field(x: Container) -> BLSFieldElement:
"""
Compute 32-byte hash of serialized container and convert it to BLS field.
The output is not uniform over the BLS field.
"""
return bytes_to_bls_field(hash(ssz_serialize(x)))
```

### `compute_powers`
```python
def compute_powers(x: BLSFieldElement, n: uint64) -> Sequence[BLSFieldElement]:
"""
Return ``x`` to power of [0, n-1].
"""
current_power = 1
powers = []
for _ in range(n):
powers.append(BLSFieldElement(current_power))
current_power = current_power * int(x) % BLS_MODULUS
return powers
```

### `compute_aggregated_poly_and_commitment`

```python
def compute_aggregated_poly_and_commitment(
blobs: Sequence[Sequence[BLSFieldElement]],
kzg_commitments: Sequence[KZGCommitment]) -> Tuple[Polynomial, KZGCommitment]:
"""
Return the aggregated polynomial and aggregated KZG commitment.
"""
# Generate random linear combination challenges
r = hash_to_bls_field(BlobsAndCommitments(blobs=blobs, kzg_commitments=kzg_commitments))
r_powers = compute_powers(r, len(kzg_commitments))

# Create aggregated polynomial in evaluation form
aggregated_poly = Polynomial(vector_lincomb(blobs, r_powers))

# Compute commitment to aggregated polynomial
aggregated_poly_commitment = KZGCommitment(g1_lincomb(kzg_commitments, r_powers))

return aggregated_poly, aggregated_poly_commitment
```

### `validate_blobs_sidecar`

Expand All @@ -148,35 +83,19 @@ def validate_blobs_sidecar(slot: Slot,
kzg_aggregated_proof = blobs_sidecar.kzg_aggregated_proof
assert len(expected_kzg_commitments) == len(blobs)

aggregated_poly, aggregated_poly_commitment = compute_aggregated_poly_and_commitment(
blobs,
expected_kzg_commitments,
)

# Generate challenge `x` and evaluate the aggregated polynomial at `x`
x = hash_to_bls_field(
PolynomialAndCommitment(polynomial=aggregated_poly, kzg_commitment=aggregated_poly_commitment)
)
# Evaluate aggregated polynomial at `x` (evaluation function checks for div-by-zero)
y = evaluate_polynomial_in_evaluation_form(aggregated_poly, x)

# Verify aggregated proof
assert verify_kzg_proof(aggregated_poly_commitment, x, y, kzg_aggregated_proof)
verify_aggregrate_kzg_proof(blobs, expected_kzg_commitments, kzg_aggregated_proof)
```

### `compute_proof_from_blobs`

```python
def compute_proof_from_blobs(blobs: Sequence[BLSFieldElement]) -> KZGProof:
commitments = [blob_to_kzg_commitment(blob) for blob in blobs]
aggregated_poly, aggregated_poly_commitment = compute_aggregated_poly_and_commitment(blobs, commitments)
x = hash_to_bls_field(PolynomialAndCommitment(
polynomial=aggregated_poly,
kzg_commitment=aggregated_poly_commitment,
))
return compute_kzg_proof(aggregated_poly, x)
return compute_aggregrate_kzg_proof(blobs)
```




### `get_blobs_and_kzg_commitments`

The interface to retrieve blobs and corresponding kzg commitments.
Expand Down