---
eip: 7998
title: Turn `randao_reveal` into a VRF
description: Transforms Ethereum’s `randao_reveal` into a per-slot BLS-based VRF by signing the previous epoch’s mix and current slot.
author: Alberto La Rocca (@71104), Aryaethn (@aryaethn)
discussions-to: https://ethereum-magicians.org/t/eip-7998-turn-randao-reveal-into-a-vrf/24999
status: Draft
type: Standards Track
category: Core
created: 2025-08-03
---

## Abstract

This EIP proposes a modification to the data signed by a block proposer for the `randao_reveal`. The current `randao_reveal` is a BLS signature over the current epoch number, which is predictable. This proposal incorporates the RANDAO mix of the previous epoch and the current slot number into the signed data. This change transforms the `randao_reveal` into a Verifiable Random Function (VRF), making it unpredictable across epochs even for the revealer itself. This enhancement strengthens Ethereum's native randomness source and enables protocols such as Single Secret Leader Election (SSLE).

## Motivation

This change creates a secure, per-slot VRF output from the proposer, with several benefits:

1. it **paves the way for secret proposer election**, which would in turn reduce MEV and completely eliminate the well-known RANDAO bias attack vector;
2. it supports other proposals like [EIP-7956](./eip-7956.md) that rely on a source of verifiable randomness.

Using a BLS signature as a VRF is sound under the Computational Diffie-Hellman (CDH) assumption, rather than Decisional Diffie-Hellman. The BLS verification process inherently proves the correctness of the VRF output without requiring a separate proof.

## Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119) and [RFC 8174](https://www.rfc-editor.org/rfc/rfc8174).

The gist of the change is in `process_randao`, which now uses the RANDAO mix of the previous epoch and the current slot number to seed the `randao_reveal` signature. We are introducing a new SSZ-serializable container called `RandaoRevealSeed` containing that information.

### New SSZ Container

A new SSZ `Container` is introduced to serve as the message for the `randao_reveal` signature post-fork.

```python
class RandaoRevealSeed(Container):
    previous_mix: Bytes32  # last RANDAO mix of the previous epoch
    slot: Slot             # current slot number
```

### Modified `process_randao`

The block processing function `process_randao` in the beacon state transition is modified.

Let `FORK_EPOCH` be the epoch of the network upgrade.

The logic for verifying `body.randao_reveal` within `process_randao` is updated as follows:

```python
def process_randao(state: BeaconState, body: BeaconBlockBody) -> None:
    epoch = get_current_epoch(state)
    # Verify RANDAO reveal
    proposer = state.validators[get_beacon_proposer_index(state)]
    if epoch < FORK_EPOCH:
        signing_root = compute_signing_root(epoch, get_domain(state, DOMAIN_RANDAO))
    else:
        previous_epoch = get_previous_epoch(state)
        previous_mix = get_randao_mix(state, previous_epoch)
        seed = RandaoRevealSeed(previous_mix, state.slot)
        signing_root = compute_signing_root(seed, 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))
    state.randao_mixes[epoch % EPOCHS_PER_HISTORICAL_VECTOR] = mix
```

## Rationale

### Choice of VRF Input

The `randao_reveal` is effectively transformed into `VRF(sk, message)` where the `message` is the SSZ serialization of the `RandaoRevealSeed` container.

- `previous_mix`: Including the RANDAO mix from the previous epoch (`previous_mix`) is the core of this proposal. Since the previous epoch's final mix is not known until the end of that epoch, a proposer cannot compute their `randao_reveal` of future epochs, beforehand.
- `slot`: Including the current `slot` number ensures that the `randao_reveal` is unique for each slot and unpredictable to other validators. Without it, a validator chosen to propose multiple times in an epoch would produce the same reveal, which is undesirable for protocols that require unique randomness per instance, such as SSLE.

### Alternatives Considered

We considered adding the _latest_ RANDAO mix rather than that from the previous epoch so that we could obtain per-slot unpredictability, but that would cause fork ambiguity in the future if `randao_reveal` is used to implement SSLE.

## Backwards Compatibility

This EIP introduces a backwards-incompatible change to the consensus rules and MUST be activated as part of a scheduled network upgrade (i.e., a hard fork).

Blocks produced after the `FORK_EPOCH` that do not use the new `RandaoRevealSeed` structure for the `randao_reveal` signature SHALL be considered invalid. Pre-fork blocks remain valid under the old rules.

## Security Considerations

### VRF Security

The security of the BLS signature scheme as a VRF relies on the Computational Diffie-Hellman (CDH) assumption in the target group. This is a standard cryptographic assumption. The output of the signature (a uniformly distributed G2 point in compressed format) can be treated as a pseudorandom number.

### Grinding

The value of `randao_reveal` is deterministic and cannot be manipulated. It will be verified with the public BLS key of the validator, so it must be calculated using the corresponding private key. There are no grindable elements.

### Slot-by-slot Unpredictability

Including the slot number is superfluous at the moment because it does not make the VRF slot-by-slot unpredictable to the revealer, only to other validators. But it will become critical in the future if and when we decide to implement secret proposer election and/or EIP-7956.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
