> ## Documentation Index
> Fetch the complete documentation index at: https://gora.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Randomness and VRF

> Verifiable randomness from your off-chain app or smart contract using the Gora consensus VRF.

# Randomness and VRF

Gora produces randomness as a side effect of how committees are selected. Every consensus round already involves each validator publishing a verifiable random output. Your app or your on-chain contract can request that randomness, bound to a specific request, and verify it later.

## What VRF means here

A verifiable random function (VRF) is a sealed envelope:

* The validator computes the envelope with their private key.
* The envelope looks random to everyone else.
* Anyone with the validator's public key can verify the envelope is genuine.
* The envelope is decided before the round starts — no one can pick a different number after seeing how it played out.

The Gora VRF uses ed25519 signatures plus SHA-256. Output is 32 bytes; proof is 64 bytes. Both are deterministic given `(participation_key, input)`.

## Two ways to access VRF

| Surface           | Use it when                                                       | How                                                                                   |
| ----------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| Off-chain app     | You need randomness inside your app logic (e.g. a raffle winner). | Read `request.vrf` provided by the runtime.                                           |
| On-chain contract | A smart contract needs unpredictable randomness it can verify.    | Call Gora through the chain's gateway program; verify the VRF proof in your contract. |

Both use the same VRF — they just consume it from different sides.

## From an off-chain app

Every Gora app invocation arrives with a `vrf` field on the request. It is derived from the proposer's VRF output for that round, domain-separated by `request_id` so the same app on different requests sees different randomness.

```ts theme={null}
// src/index.ts
export async function run(req: GoraRequest): Promise<GoraResult> {
  const entrants: string[] = req.input.participants;
  const vrf = req.vrf;                       // { output_hex, proof_hex }

  // Map the 32-byte VRF output to an index, deterministically.
  const indexBigInt = BigInt("0x" + vrf.output_hex.slice(0, 16));
  const winnerIndex = Number(indexBigInt % BigInt(entrants.length));

  return {
    type: "raffle_result",
    schema_version: 1,
    app_id: req.app_id,
    decision: "winner_selected",
    payload: {
      winner: entrants[winnerIndex],
      vrf_output_hex: vrf.output_hex,        // for receipts / on-chain verification
    },
  };
}
```

Because the VRF is part of the round's published context, every committee member computes the same `winnerIndex` from the same `vrf.output_hex`. The result is reproducible at verification time.

## From a smart contract

A smart contract requests randomness by calling the Gora gateway on its chain. The gateway routes the request to Gora, the committee runs the request, and the gateway delivers a callback to the contract with `{ result, vrf_output, vrf_proof, signatures }`.

```solidity theme={null}
// Solidity sketch — Base
interface IGoraGateway {
    function requestRandomness(bytes calldata seed) external returns (bytes32 requestId);
}

interface IGoraConsumer {
    function fulfillRandomness(
        bytes32 requestId,
        bytes32 vrfOutput,
        bytes calldata vrfProof,
        bytes[] calldata signatures
    ) external;
}
```

When the callback lands, your contract:

1. Verifies the committee signatures against the registered validator set.
2. (Optional) Verifies the VRF proof against the committee proposer's pubkey using a Solana-style precompile or an EVM ed25519 verifier.
3. Uses `vrfOutput` as randomness.

The same pattern applies on Solana (instruction-based callback) and Algorand (atomic-group fulfillment). The exact gateway interfaces ship with the chain contracts in `contracts/`.

## What makes this safe

| Property         | Why it holds                                                                                                           |
| ---------------- | ---------------------------------------------------------------------------------------------------------------------- |
| Unpredictability | The VRF input includes `request_id` and the round's `sequence`; the participation key never leaves the validator.      |
| Verifiability    | Anyone with the proposer's public key can check the proof.                                                             |
| Tamper-evidence  | The output is committed to before votes are signed; changing it later invalidates the entire round attestation.        |
| Bias resistance  | The proposer is chosen by stake-weighted VRF score over the *collected* submissions, not by a single validator's whim. |

## When *not* to use Gora VRF

* You need millions of independent draws per second on-chain. Gora is request-scoped, not a high-throughput randomness firehose.
* You only need a hash of the recent block. The chain's own block hash is cheaper and sufficient for low-stakes randomness.

For everything between "trust me, it's random" and "I need a national lottery RNG," Gora VRF is the intended fit.

## Related

* [Validators and consensus](./validators-and-consensus) — where the VRF comes from in the first place.
* [External calls](./external-calls) — how to combine VRF with deterministic external data.
* [Raffle example](../examples/raffle-app) — a working end-to-end app that consumes VRF.
