Verifying Proofs

Verifying Proofs

The SHARP (Shared Prover) Service can be used to generate proofs that attest to the validity of Cairo program executions.

Cairo programs that are executed by the SHARP Service need to produce outputs.

Proofs are verified via a Smart Contract on Ethereum. The verification status can be checked via the CLI or programmatically via a Smart Contract deployed on Ethereum.


The following Cairo program checks if the numbers supplied via input parameters are the prime factors of the prime number 15.

# The program produces outputs which require the `output` builtin.
%builtins output

from starkware.cairo.common.serialize import serialize_word

func main{output_ptr : felt*}():

    local prime_1
    local prime_2
    let expected = 15

    # Read the Prime factors from the input and store them in local variables.
        ids.prime_1 = program_input["prime_1"]
        ids.prime_2 = program_input["prime_2"]

    # Compute the potential Prime number.
    let result = prime_1 * prime_2

    # Throw an error if the Prime factors are invalid.
    assert result = expected

    # Output Prime factors and Prime number.

    return ()

An input.json file for the program might look like the following:

  "prime_1": 3,
  "prime_2": 5

The program can be compiled and sent off to the SHARP Service via the following command:

cairo-sharp submit --source sharp.cairo --program_input input.json

Next up, a Smart Contract can be deployed on Ethereum that interacts with the Fact Registry Contract to check the validity of the program by calling the isValid function:

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
// Interface definition so that we can use the Fact Registry Contract.
interface IFactRegistry {
    function isValid(bytes32 fact) external view returns (bool);
contract SHARP {
    IFactRegistry factRegistry;
    constructor(IFactRegistry factRegistry_) {
        factRegistry = factRegistry_;
    function check(uint256 programHash, uint256[] memory outputs)
        returns (bool)
        // Compute the hash of the outputs.
        bytes32 outputHash = keccak256(abi.encodePacked(outputs));
        // Compute the fact which is the hash of the program hash combined
        //  with the output hash.
        bytes32 fact = keccak256(abi.encodePacked(programHash, outputHash));
        // Call the Fact Registry Contract to check if the fact is valid.
        bool isValid = factRegistry.isValid(fact);
        require(isValid, "Fact is invalid");
        return true;


Fact Registry Contract - Goerli Alpha