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

# L1 Proof Verification

> STARK proofs can be verified on L1 (Ethereum), so that other contracts deployed on Ethereum can use FactRegistry contract to check whether given proof was verified.

<Note>
  Proof verification can only be performed together with
  [Proof Generation](/atlantic-api/steps/proof-generation).
</Note>

### How to use?

Follow instructions for [Proof Generation](/atlantic-api/steps/proof-generation), but select `PROOF_VERIFICATION_ON_L1` as `result`.

After a proof is verified, you can call
`isCairoFactValid(bytes32 fact_hash, bool is_mocked)` on the
[Satellite contract](/atlantic-api/contract-addresses#evm-chains).

You can also set `mockFactHash` to omit actual proof verification on-chain, reducing the cost for testing purposes.

### Calculating fact hash

On EVM chains, fact hash is calculated from `programHash` and `output` array in the following way:

```solidity theme={null}
// Output has to match the output of the program and can have any length
uint256[] memory outputs = new uint256[](2);
outputs[0] = 10;
outputs[1] = 55;

bytes32 outputHash = keccak256(abi.encodePacked(outputs));

// Program hash is constant for given program, regardless of input and output, so it can be hardcoded
bytes32 programHash = bytes32(uint256(0x407908712e70dd914b006062d8d70bd8aeae06bcfc973cbd4309e7f3a2e825b));

bytes32 fact = keccak256(abi.encode(ms.programHash, outputHash));
```
