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

EIP4844: Update cryptography API and Fiat-Shamir logic #3038

Merged
merged 35 commits into from
Nov 3, 2022
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
429e597
4844: Start moving cryptography functions to polynomial-commitments
asn-d6 Oct 14, 2022
22a4dcd
4844: hash_to_bls_field() doesn't use SSZ and does domain separation
asn-d6 Oct 14, 2022
b5959a1
4844: Refactor aggregation and move to polynomial-commitments
asn-d6 Oct 14, 2022
642f138
4844: Fix ToC
asn-d6 Oct 14, 2022
ff528a2
Merge branch 'dev' into pr3038
hwwhww Oct 15, 2022
91476fe
Fix linter error
hwwhww Oct 15, 2022
090dc7e
Blobs as flat ByteVector
dankrad Oct 20, 2022
30d19a3
Move is_data_available from validator to beacon_chain
dankrad Oct 21, 2022
0eb82cf
Set domain separators to empty string
dankrad Oct 21, 2022
7631c18
Add placeholder domain separators for two protocols; add old transcri…
dankrad Oct 21, 2022
fe7af4b
Remove duplicate hash in
dankrad Oct 22, 2022
46b6b24
Fix typo
dankrad Oct 22, 2022
889deff
Fix doctoc
dankrad Oct 22, 2022
83ca385
Fix typo
dankrad Oct 22, 2022
cbc170b
Fix tests
dankrad Oct 22, 2022
89d4ae0
Fix doctoc
dankrad Oct 22, 2022
b9dfdaf
Happy linter
dankrad Oct 22, 2022
033567b
Use Polynomial type consistently, vector_lincomb to poly_lincomb
dankrad Oct 22, 2022
e81d54c
Small fixes
dankrad Oct 22, 2022
463948e
Fix get_sample_blob
dankrad Oct 22, 2022
a33a423
Make `blob_to_field_elements` return `Polynomial` and fix tests
hwwhww Oct 23, 2022
31ad8a5
Rearrange presets
hwwhww Oct 24, 2022
0174521
Proofread
hwwhww Oct 24, 2022
dfcf33c
By kev: Removes domain separators as constants, Removes second call t…
dankrad Oct 27, 2022
d98c103
Add name for Fiat-Shamir protocol
dankrad Oct 30, 2022
80d4d09
Improve comments in polynomial-commitments.md
asn-d6 Nov 1, 2022
c8b8b53
Fix description of BLS_MODULUS
asn-d6 Nov 1, 2022
5354a96
blob_to_field_elements() -> blob_to_polynomial()
asn-d6 Nov 1, 2022
0e2e477
Use modular multiplication in compute_aggregated_poly_and_commitment
asn-d6 Nov 1, 2022
db619e2
Satisfy executable spec tests
asn-d6 Nov 1, 2022
cb46b11
Improve code that deals with the evaluation challenge
asn-d6 Nov 2, 2022
af48987
Minor spec improvements (after review by hww)
asn-d6 Nov 2, 2022
1c9a8db
Remove extra space
dankrad Nov 3, 2022
186a2eb
Move `BYTES_PER_FIELD_ELEMENT` from presets to constants
hwwhww Nov 3, 2022
c130995
Clarify BYTES_PER_FIELD_ELEMENT comment a bit more
asn-d6 Nov 3, 2022
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
2 changes: 2 additions & 0 deletions presets/mainnet/eip4844.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@
# ---------------------------------------------------------------
# `uint64(4096)`
FIELD_ELEMENTS_PER_BLOB: 4096
# `uint64(32)`
BYTES_PER_FIELD_ELEMENT: 32
# `uint64(2**4)` (= 16)
MAX_BLOBS_PER_BLOCK: 16
2 changes: 2 additions & 0 deletions presets/minimal/eip4844.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@
# ---------------------------------------------------------------
# [customized]
FIELD_ELEMENTS_PER_BLOB: 4
# `uint64(32)`
BYTES_PER_FIELD_ELEMENT: 32
# `uint64(2**4)` (= 16)
MAX_BLOBS_PER_BLOCK: 16
8 changes: 4 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ def get_spec(file_name: Path, preset: Dict[str, str], config: Dict[str, str]) ->

if not _is_constant_id(name):
# Check for short type declarations
if value.startswith(("uint", "Bytes", "ByteList", "Union", "Vector", "List")):
if value.startswith(("uint", "Bytes", "ByteList", "Union", "Vector", "List", "ByteVector")):
custom_types[name] = value
continue

Expand Down Expand Up @@ -590,7 +590,6 @@ def imports(cls, preset_name: str):
return super().imports(preset_name) + f'''
from eth2spec.utils import kzg
from eth2spec.bellatrix import {preset_name} as bellatrix
from eth2spec.utils.ssz.ssz_impl import serialize as ssz_serialize
'''


Expand Down Expand Up @@ -618,12 +617,13 @@ def sundry_functions(cls) -> str:


def retrieve_blobs_sidecar(slot: Slot, beacon_block_root: Root) -> BlobsSidecar:
pass'''
return "TEST"'''
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return type is wrong. how about:

def retrieve_blobs_sidecar(slot: Slot, beacon_block_root: Root) -> Optional[BlobsSidecar]:
    return None  # Testing'''

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in af48987

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, slightly annoying because None could also mean that the sidecar is not available (I know in python we would do this by raising an exception but not all languages would have that available).


@classmethod
def hardcoded_custom_type_dep_constants(cls, spec_object) -> str:
constants = {
'FIELD_ELEMENTS_PER_BLOB': spec_object.preset_vars['FIELD_ELEMENTS_PER_BLOB'].value,
'BYTES_PER_FIELD_ELEMENT': spec_object.preset_vars['BYTES_PER_FIELD_ELEMENT'].value,
'MAX_BLOBS_PER_BLOCK': spec_object.preset_vars['MAX_BLOBS_PER_BLOCK'].value,
}
return {**super().hardcoded_custom_type_dep_constants(spec_object), **constants}
Expand Down Expand Up @@ -772,7 +772,7 @@ def combine_dicts(old_dict: Dict[str, T], new_dict: Dict[str, T]) -> Dict[str, T
'uint8', 'uint16', 'uint32', 'uint64', 'uint128', 'uint256',
'bytes', 'byte', 'ByteList', 'ByteVector',
'Dict', 'dict', 'field', 'ceillog2', 'floorlog2', 'Set',
'Optional', 'Sequence',
'Optional', 'Sequence',
]


Expand Down
45 changes: 42 additions & 3 deletions specs/eip4844/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
- [`ExecutionPayloadHeader`](#executionpayloadheader)
- [Helper functions](#helper-functions)
- [Misc](#misc)
- [`validate_blobs_sidecar`](#validate_blobs_sidecar)
- [`is_data_available`](#is_data_available)
- [`kzg_commitment_to_versioned_hash`](#kzg_commitment_to_versioned_hash)
- [`tx_peek_blob_versioned_hashes`](#tx_peek_blob_versioned_hashes)
- [`verify_kzg_commitments_against_transactions`](#verify_kzg_commitments_against_transactions)
Expand All @@ -44,9 +46,7 @@ This upgrade adds blobs to the beacon chain as part of EIP-4844.

| Name | SSZ equivalent | Description |
| - | - | - |
| `Blob` | `Vector[BLSFieldElement, FIELD_ELEMENTS_PER_BLOB]` | |
| `VersionedHash` | `Bytes32` | |
| `KZGCommitment` | `Bytes48` | Same as BLS standard "is valid pubkey" check but also allows `0x00..00` for point-at-infinity |

## Constants

Expand All @@ -55,7 +55,6 @@ This upgrade adds blobs to the beacon chain as part of EIP-4844.
| Name | Value |
| - | - |
| `BLOB_TX_TYPE` | `uint8(0x05)` |
| `FIELD_ELEMENTS_PER_BLOB` | `uint64(4096)` |
| `VERSIONED_HASH_VERSION_KZG` | `Bytes1(0x01)` |

### Domain types
Expand Down Expand Up @@ -150,6 +149,43 @@ class ExecutionPayloadHeader(Container):

### Misc

#### `validate_blobs_sidecar`

```python
def validate_blobs_sidecar(slot: Slot,
beacon_block_root: Root,
expected_kzg_commitments: Sequence[KZGCommitment],
blobs_sidecar: BlobsSidecar) -> None:
assert slot == blobs_sidecar.beacon_block_slot
assert beacon_block_root == blobs_sidecar.beacon_block_root
blobs = blobs_sidecar.blobs
kzg_aggregated_proof = blobs_sidecar.kzg_aggregated_proof
assert len(expected_kzg_commitments) == len(blobs)

assert verify_aggregate_kzg_proof(blobs, expected_kzg_commitments, kzg_aggregated_proof)
```

#### `is_data_available`

The implementation of `is_data_available` is meant to change with later sharding upgrades.
Initially, it requires every verifying actor to retrieve the matching `BlobsSidecar`,
and validate the sidecar with `validate_blobs_sidecar`.

Without the sidecar the block may be processed further optimistically,
but MUST NOT be considered valid until a valid `BlobsSidecar` has been downloaded.

```python
def is_data_available(slot: Slot, beacon_block_root: Root, blob_kzg_commitments: Sequence[KZGCommitment]) -> bool:
# `retrieve_blobs_sidecar` is implementation dependent, raises an exception if not available.
sidecar = retrieve_blobs_sidecar(slot, beacon_block_root)
if sidecar == "TEST":
return True # For testing; remove once we have a way to inject `BlobsSidecar` into tests
validate_blobs_sidecar(slot, beacon_block_root, blob_kzg_commitments, sidecar)

return True
```


#### `kzg_commitment_to_versioned_hash`

```python
Expand Down Expand Up @@ -204,6 +240,9 @@ def process_block(state: BeaconState, block: BeaconBlock) -> None:
process_operations(state, block.body)
process_sync_aggregate(state, block.body.sync_aggregate)
process_blob_kzg_commitments(state, block.body) # [New in EIP-4844]

# New in EIP-4844, note: Can sync optimistically without this condition, see note on `is_data_available`
assert is_data_available(block.slot, hash_tree_root(block), block.body.blob_kzg_commitments)
```

#### Execution payload
Expand Down
Loading