SHARP
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.

Example

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*}():
    alloc_locals

    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.
    serialize_word(prime_1)
    serialize_word(prime_2)
    serialize_word(expected)

    return ()
end

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)
        external
        view
        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;
    }
}

Addresses

Fact Registry Contract - Goerli Alpha

0xAB43bA48c9edF4C2C4bB01237348D1D7B28ef168