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;
}
}