Skip to content
Merged
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
2 changes: 1 addition & 1 deletion pysetup/spec_builders/eip8321.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class EIP8321SpecBuilder(BaseSpecBuilder):
@classmethod
def imports(cls, preset_name: str):
return f"""
from eth_consensus_specs.utils.hash_function import blake3
from blake3 import blake3 as blake3_hash

from eth_consensus_specs.heze import {preset_name} as heze
"""
2 changes: 1 addition & 1 deletion pysetup/spec_builders/phase0.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def imports(cls, preset_name: str) -> str:
dataclass,
field,
)
from hashlib import sha256 as sha256_hash
from typing import (
Any, Callable, Dict, DefaultDict, Set, Sequence, Tuple, Optional, TypeAlias, TypeVar, NamedTuple, Final
)
Expand All @@ -35,7 +36,6 @@ def imports(cls, preset_name: str) -> str:
Bytes1, Bytes4, Bytes20, Bytes32, Bytes48, Bytes96, BitList)
from eth_consensus_specs.utils.ssz.ssz_typing import BitVector # noqa: F401
from eth_consensus_specs.utils import bls
from eth_consensus_specs.utils.hash_function import hash
"""

@classmethod
Expand Down
15 changes: 8 additions & 7 deletions specs/_features/eip8321/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,12 +261,13 @@ class BeaconState(ProgressiveContainer(active_fields=[1] * 48)):

#### New `blake3`

`def blake3(data: bytes) -> Bytes32` is the BLAKE3 hash function in its default
unkeyed hash mode, with no derive-key context, restricted to its default 32-byte
output.

All hashing introduced by this upgrade uses `blake3`; the `hash` helper
continues to serve the legacy reveal path.
```python
def blake3(data: bytes) -> Bytes32:
"""
Return the BLAKE3 hash of ``data``.
"""
return Bytes32(blake3_hash(data).digest())
```

### Validator registry

Expand Down Expand Up @@ -409,7 +410,7 @@ def process_randao(state: BeaconState, body: BeaconBlockBody) -> None:
state.randao_commitments[proposer_index] = body.hash_chain_reveal
else:
verify_bls_randao_reveal(state, body, proposer_index)
mix = xor(get_randao_mix(state, epoch), hash(body.randao_reveal))
mix = xor(get_randao_mix(state, epoch), sha256(body.randao_reveal))
state.randao_mixes[epoch % EPOCHS_PER_HISTORICAL_VECTOR] = mix
```

Expand Down
2 changes: 1 addition & 1 deletion specs/altair/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ def get_next_sync_committee_indices(state: BeaconState) -> Sequence[ValidatorInd
Uint64(i % active_validator_count), active_validator_count, seed
)
candidate_index = active_validator_indices[shuffled_index]
random_byte = hash(seed + uint_to_bytes(Uint64(i // 32)))[i % 32]
random_byte = sha256(seed + uint_to_bytes(Uint64(i // 32)))[i % 32]
effective_balance = state.validators[candidate_index].effective_balance
if effective_balance * MAX_RANDOM_BYTE >= MAX_EFFECTIVE_BALANCE * random_byte:
sync_committee_indices.append(candidate_index)
Expand Down
2 changes: 1 addition & 1 deletion specs/altair/validator.md
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ def is_sync_committee_aggregator(signature: BLSSignature) -> bool:
// SYNC_COMMITTEE_SUBNET_COUNT
// TARGET_AGGREGATORS_PER_SYNC_SUBCOMMITTEE,
)
return bytes_to_uint64(hash(signature)[0:8]) % modulo == 0
return bytes_to_uint64(sha256(signature)[0:8]) % modulo == 0
```

*Note*: The set of aggregators generally changes every slot; however, the
Expand Down
2 changes: 1 addition & 1 deletion specs/capella/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ def process_bls_to_execution_change(
validator = state.validators[address_change.validator_index]

assert validator.withdrawal_credentials[:1] == BLS_WITHDRAWAL_PREFIX
assert validator.withdrawal_credentials[1:] == hash(address_change.from_bls_pubkey)[1:]
assert validator.withdrawal_credentials[1:] == sha256(address_change.from_bls_pubkey)[1:]

# Fork-agnostic domain since address changes are valid across forks
domain = compute_domain(
Expand Down
9 changes: 3 additions & 6 deletions specs/capella/p2p-interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,19 +237,16 @@ def validate_bls_to_execution_change_gossip(
raise GossipReject("validator does not have BLS withdrawal credentials")

# [REJECT] The bls_to_execution_change is for the validator's withdrawal pubkey
if validator.withdrawal_credentials[1:] != hash(bls_to_execution_change.from_bls_pubkey)[1:]:
pubkey = bls_to_execution_change.from_bls_pubkey
if validator.withdrawal_credentials[1:] != sha256(pubkey)[1:]:
raise GossipReject("pubkey does not match validator withdrawal credentials")

# [REJECT] The signature is valid
domain = compute_domain(
DOMAIN_BLS_TO_EXECUTION_CHANGE, genesis_validators_root=state.genesis_validators_root
)
signing_root = compute_signing_root(bls_to_execution_change, domain)
if not bls.Verify(
bls_to_execution_change.from_bls_pubkey,
signing_root,
signed_bls_to_execution_change.signature,
):
if not bls.Verify(pubkey, signing_root, signed_bls_to_execution_change.signature):
raise GossipReject("invalid BLS to execution change signature")

# Mark this bls_to_execution_change as seen
Expand Down
2 changes: 1 addition & 1 deletion specs/deneb/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ class BeaconState(Container):

```python
def kzg_commitment_to_versioned_hash(kzg_commitment: KZGCommitment) -> VersionedHash:
return VERSIONED_HASH_VERSION_KZG + hash(kzg_commitment)[1:]
return VERSIONED_HASH_VERSION_KZG + sha256(kzg_commitment)[1:]
```

### Beacon state accessors
Expand Down
4 changes: 2 additions & 2 deletions specs/electra/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ def compute_proposer_index(
while True:
candidate_index = indices[compute_shuffled_index(i % total, total, seed)]
# [Modified in Electra]
random_bytes = hash(seed + uint_to_bytes(i // 16))
random_bytes = sha256(seed + uint_to_bytes(i // 16))
offset = i % 16 * 2
random_value = bytes_to_uint64(random_bytes[offset : offset + 2])
effective_balance = state.validators[candidate_index].effective_balance
Expand Down Expand Up @@ -815,7 +815,7 @@ def get_next_sync_committee_indices(state: BeaconState) -> Sequence[ValidatorInd
)
candidate_index = active_validator_indices[shuffled_index]
# [Modified in Electra]
random_bytes = hash(seed + uint_to_bytes(i // 16))
random_bytes = sha256(seed + uint_to_bytes(i // 16))
offset = i % 16 * 2
random_value = bytes_to_uint64(random_bytes[offset : offset + 2])
effective_balance = state.validators[candidate_index].effective_balance
Expand Down
4 changes: 2 additions & 2 deletions specs/fulu/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ def compute_fork_digest(
bytes(
xor(
base_digest,
hash(
sha256(
uint_to_bytes(Uint64(blob_parameters.epoch))
+ uint_to_bytes(Uint64(blob_parameters.max_blobs_per_block))
),
Expand All @@ -345,7 +345,7 @@ def compute_proposer_indices(
Return the proposer indices for the given ``epoch``.
"""
start_slot = compute_start_slot_at_epoch(epoch)
seeds = [hash(seed + uint_to_bytes(Slot(start_slot + i))) for i in range(SLOTS_PER_EPOCH)]
seeds = [sha256(seed + uint_to_bytes(Slot(start_slot + i))) for i in range(SLOTS_PER_EPOCH)]
return ProposerIndices(compute_proposer_index(state, indices, seed) for seed in seeds)
```

Expand Down
2 changes: 1 addition & 1 deletion specs/fulu/das-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ def get_custody_groups(node_id: NodeID, custody_group_count: Uint64) -> Sequence
custody_groups: list[CustodyIndex] = []
while len(custody_groups) < custody_group_count:
custody_group = CustodyIndex(
bytes_to_uint64(hash(uint_to_bytes(current_id))[0:8]) % NUMBER_OF_CUSTODY_GROUPS
bytes_to_uint64(sha256(uint_to_bytes(current_id))[0:8]) % NUMBER_OF_CUSTODY_GROUPS
)
if custody_group not in custody_groups:
custody_groups.append(custody_group)
Expand Down
6 changes: 3 additions & 3 deletions specs/gloas/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -1174,7 +1174,7 @@ def compute_balance_weighted_selection(
while len(selected) < size:
offset = i % 16 * 2
if offset == 0:
random_bytes = hash(seed + uint_to_bytes(i // 16))
random_bytes = sha256(seed + uint_to_bytes(i // 16))
next_index = i % total
if shuffle_indices:
next_index = compute_shuffled_index(next_index, total, seed)
Expand All @@ -1201,7 +1201,7 @@ def compute_proposer_indices(
Return the proposer indices for the given ``epoch``.
"""
start_slot = compute_start_slot_at_epoch(epoch)
seeds = [hash(seed + uint_to_bytes(Slot(start_slot + i))) for i in range(SLOTS_PER_EPOCH)]
seeds = [sha256(seed + uint_to_bytes(Slot(start_slot + i))) for i in range(SLOTS_PER_EPOCH)]
# [Modified in Gloas:EIP7732]
return ProposerIndices(
compute_balance_weighted_selection(state, indices, seed, size=1, shuffle_indices=True)[0]
Expand All @@ -1217,7 +1217,7 @@ def compute_ptc(state: BeaconState, slot: Slot) -> PayloadTimelinessCommittee:
Get the payload timeliness committee, with possible duplicates, for the given ``slot``.
"""
epoch = compute_epoch_at_slot(slot)
seed = hash(get_seed(state, epoch, DOMAIN_PTC_ATTESTER) + uint_to_bytes(slot))
seed = sha256(get_seed(state, epoch, DOMAIN_PTC_ATTESTER) + uint_to_bytes(slot))
indices: list[ValidatorIndex] = []
# Concatenate all committees for this slot in order
committees_per_slot = get_committee_count_per_slot(state, epoch)
Expand Down
28 changes: 17 additions & 11 deletions specs/phase0/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
- [`uint_to_bytes`](#uint_to_bytes)
- [`bytes_to_uint64`](#bytes_to_uint64)
- [Crypto](#crypto)
- [`hash`](#hash)
- [`sha256`](#sha256)
- [`hash_tree_root`](#hash_tree_root)
- [BLS signatures](#bls-signatures)
- [Predicates](#predicates)
Expand Down Expand Up @@ -985,9 +985,15 @@ def bytes_to_uint64(data: bytes) -> Uint64:

### Crypto

#### `hash`
#### `sha256`

`def hash(data: bytes) -> Bytes32` is SHA256.
```python
def sha256(data: bytes) -> Bytes32:
"""
Return the SHA256 hash of ``data``.
"""
return Bytes32(sha256_hash(data).digest())
```

#### `hash_tree_root`

Expand Down Expand Up @@ -1111,9 +1117,9 @@ def compute_merkle_branch_root(
value = leaf
for i in range(depth):
if index // (2**i) % 2:
value = hash(branch[i] + value)
value = sha256(branch[i] + value)
else:
value = hash(value + branch[i])
value = sha256(value + branch[i])
return Root(value)
```

Expand Down Expand Up @@ -1145,14 +1151,14 @@ def compute_shuffled_permutation(index_count: Uint64, seed: Bytes32) -> Sequence
indices = [Uint64(i) for i in range(index_count)]
for current_round in range(SHUFFLE_ROUND_COUNT):
round_bytes = current_round.to_bytes(1, "little")
pivot = int.from_bytes(hash(seed + round_bytes)[0:8], "little") % index_count
pivot = int.from_bytes(sha256(seed + round_bytes)[0:8], "little") % index_count
source_by_bucket: Dict[Uint64, Bytes32] = {}
for i in range(index_count):
flip = (pivot + index_count - indices[i]) % index_count
position = max(indices[i], flip)
position_bucket = position // 256
if position_bucket not in source_by_bucket:
source_by_bucket[position_bucket] = hash(
source_by_bucket[position_bucket] = sha256(
seed + round_bytes + position_bucket.to_bytes(4, "little")
)
source = source_by_bucket[position_bucket]
Expand Down Expand Up @@ -1188,7 +1194,7 @@ def compute_proposer_index(
total = Uint64(len(indices))
while True:
candidate_index = indices[compute_shuffled_index(i % total, total, seed)]
random_byte = hash(seed + uint_to_bytes(Uint64(i // 32)))[i % 32]
random_byte = sha256(seed + uint_to_bytes(Uint64(i // 32)))[i % 32]
effective_balance = state.validators[candidate_index].effective_balance
if effective_balance * MAX_RANDOM_BYTE >= MAX_EFFECTIVE_BALANCE * random_byte:
return candidate_index
Expand Down Expand Up @@ -1391,7 +1397,7 @@ def get_seed(state: BeaconState, epoch: Epoch, domain_type: DomainType) -> Bytes
mix = get_randao_mix(
state, Epoch(epoch + EPOCHS_PER_HISTORICAL_VECTOR - MIN_SEED_LOOKAHEAD - 1)
) # Avoid underflow
return hash(domain_type + uint_to_bytes(epoch) + mix)
return sha256(domain_type + uint_to_bytes(epoch) + mix)
```

#### `get_committee_count_per_slot`
Expand Down Expand Up @@ -1439,7 +1445,7 @@ def get_beacon_proposer_index(state: BeaconState) -> ValidatorIndex:
Return the beacon proposer index at the current slot.
"""
epoch = get_current_epoch(state)
seed = hash(get_seed(state, epoch, DOMAIN_BEACON_PROPOSER) + uint_to_bytes(state.slot))
seed = sha256(get_seed(state, epoch, DOMAIN_BEACON_PROPOSER) + uint_to_bytes(state.slot))
indices = get_active_validator_indices(state, epoch)
return compute_proposer_index(state, indices, seed)
```
Expand Down Expand Up @@ -2236,7 +2242,7 @@ def process_randao(state: BeaconState, body: BeaconBlockBody) -> None:
signing_root = compute_signing_root(epoch, get_domain(state, DOMAIN_RANDAO))
assert bls.Verify(proposer.pubkey, signing_root, body.randao_reveal)
# Mix in RANDAO reveal
mix = xor(get_randao_mix(state, epoch), hash(body.randao_reveal))
mix = xor(get_randao_mix(state, epoch), sha256(body.randao_reveal))
state.randao_mixes[epoch % EPOCHS_PER_HISTORICAL_VECTOR] = mix
```

Expand Down
2 changes: 1 addition & 1 deletion specs/phase0/p2p-interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -1792,7 +1792,7 @@ def compute_subscribed_subnet(node_id: NodeID, epoch: Epoch, index: int) -> Subn
prefix_bits = int(compute_attestation_subnet_prefix_bits())
node_id_prefix = node_id >> int(NODE_ID_BITS - prefix_bits)
node_offset = Uint64(node_id % Uint256(EPOCHS_PER_SUBNET_SUBSCRIPTION))
permutation_seed = hash(
permutation_seed = sha256(
uint_to_bytes(Uint64((epoch + node_offset) // EPOCHS_PER_SUBNET_SUBSCRIPTION))
)
permutated_prefix = compute_shuffled_index(
Expand Down
4 changes: 2 additions & 2 deletions specs/phase0/validator.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ Withdrawal credentials with the BLS withdrawal prefix allow a BLS key pair
`withdrawal_credentials` field must be such that:

- `withdrawal_credentials[:1] == BLS_WITHDRAWAL_PREFIX`
- `withdrawal_credentials[1:] == hash(bls_withdrawal_pubkey)[1:]`
- `withdrawal_credentials[1:] == sha256(bls_withdrawal_pubkey)[1:]`

*Note*: The `bls_withdrawal_privkey` is not required for validating and can be
kept in cold storage.
Expand Down Expand Up @@ -735,7 +735,7 @@ def is_aggregator(
) -> bool:
committee = get_beacon_committee(state, slot, index)
modulo = max(1, len(committee) // TARGET_AGGREGATORS_PER_COMMITTEE)
return bytes_to_uint64(hash(slot_signature)[0:8]) % modulo == 0
return bytes_to_uint64(sha256(slot_signature)[0:8]) % modulo == 0
```

#### Construct aggregate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ def test_is_sync_committee_aggregator(spec, state):
sample_count = int(spec.SYNC_COMMITTEE_SIZE // spec.SYNC_COMMITTEE_SUBNET_COUNT) * 100
is_aggregator_count = 0
for i in range(sample_count):
signature = spec.hash(i.to_bytes(32, byteorder="little"))
signature = spec.sha256(i.to_bytes(32, byteorder="little"))
if spec.is_sync_committee_aggregator(signature):
is_aggregator_count += 1

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def test_from_syncing_to_invalid(spec, state):
block.body.execution_payload.parent_hash = (
block_hashes[f"chain_a_{i - 1}"] if i != 0 else block_hashes["block_0"]
)
block.body.execution_payload.extra_data = spec.hash(bytes(f"chain_a_{i}", "UTF-8"))
block.body.execution_payload.extra_data = spec.sha256(bytes(f"chain_a_{i}", "UTF-8"))
block.body.execution_payload.block_hash = compute_el_block_hash(
spec, block.body.execution_payload, state
)
Expand All @@ -90,7 +90,7 @@ def test_from_syncing_to_invalid(spec, state):
block.body.execution_payload.parent_hash = (
block_hashes[f"chain_b_{i - 1}"] if i != 0 else block_hashes["block_0"]
)
block.body.execution_payload.extra_data = spec.hash(bytes(f"chain_b_{i}", "UTF-8"))
block.body.execution_payload.extra_data = spec.sha256(bytes(f"chain_b_{i}", "UTF-8"))
block.body.execution_payload.block_hash = compute_el_block_hash(
spec, block.body.execution_payload, state
)
Expand All @@ -110,7 +110,7 @@ def test_from_syncing_to_invalid(spec, state):
block.body.execution_payload.parent_hash = signed_blocks_b[
-1
].message.body.execution_payload.block_hash
block.body.execution_payload.extra_data = spec.hash(bytes(f"chain_b_{i}", "UTF-8"))
block.body.execution_payload.extra_data = spec.sha256(bytes(f"chain_b_{i}", "UTF-8"))
block.body.execution_payload.block_hash = compute_el_block_hash(
spec, block.body.execution_payload, state
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ def test_valid_signature_from_staking_deposit_cli(spec, state):
"4b363db94e286120d76eb905340fdd4e54bfe9f06bf33ff6cf5ad27f511bfe95"
)
validator = state.validators[validator_index]
validator.withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(from_bls_pubkey)[1:]
validator.withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.sha256(from_bls_pubkey)[1:]

address_change = spec.BLSToExecutionChange(
validator_index=validator_index,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def test_blob_sidecar_inclusion_proof_incorrect_wrong_body(spec, state):

for blob_sidecar in blob_sidecars:
block = blob_sidecar.signed_block_header.message
block.body_root = spec.hash(block.body_root) # mutate body root to break proof
block.body_root = spec.sha256(block.body_root) # mutate body root to break proof
assert not spec.verify_blob_sidecar_inclusion_proof(blob_sidecar)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def test_unregistered_proposer_uses_bls_reveal(spec, state):
yield from run_process_randao(spec, state, block)

assert spec.get_randao_mix(state, epoch) == spec.xor(
pre_mix, spec.hash(block.body.randao_reveal)
pre_mix, spec.sha256(block.body.randao_reveal)
)
# An unregistered validator stays unregistered
assert state.randao_commitments[proposer_index] == spec.Bytes32()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ def test_apply_pending_deposit_incorrect_sig_top_up(spec, state):
def test_apply_pending_deposit_incorrect_withdrawal_credentials_top_up(spec, state):
validator_index = 0
amount = spec.MIN_ACTIVATION_BALANCE // 4
withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(b"junk")[1:]
withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.sha256(b"junk")[1:]
pending_deposit = prepare_pending_deposit(
spec, validator_index, amount, signed=True, withdrawal_credentials=withdrawal_credentials
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def prepare_state_and_block(
# use min activation balance
spec.MIN_ACTIVATION_BALANCE,
# insecurely use pubkey as withdrawal key
spec.BLS_WITHDRAWAL_PREFIX + spec.hash(pubkeys[keypair_index])[1:],
spec.BLS_WITHDRAWAL_PREFIX + spec.sha256(pubkeys[keypair_index])[1:],
signed=True,
)
deposit_data_list.append(deposit_data)
Expand Down
Loading