From be4cbc08e0a33430589c34b4c988fda3242f4d7a Mon Sep 17 00:00:00 2001 From: Filip Krawczyk Date: Tue, 19 Nov 2024 18:25:53 +0100 Subject: [PATCH] Update README --- README.md | 125 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 110 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index ae8c9751..edf4e183 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ - [Prerequisites](#prerequisites) - [Using Verifier contracts on Starknet](#using-verifier-contracts-on-starknet) +- [Calls from Starknet contracts](#calls-from-starknet-contracts) - [Running locally](#running-locally) - [Creating a Proof](#creating-a-proof) - [Deployment](#deployment) @@ -21,10 +22,6 @@ To use the verifier with contracts deployed on Starknet, you need to have [Rust] For running locally and development, you will need [scarb](https://docs.swmansion.com/scarb/) (we recommend using [asdf](https://asdf-vm.com/) version manager). -### Getting example proofs - -Because of large size of proofs, we don't store example proofs directly in this repository, but rather in [Large File Storage](https://git-lfs.com/), so you need to have it installed and then run `git lfs pull` to get all example proofs. - ## Using Verifier contracts on Starknet Integrity verifier is deployed on Starknet and can be used for verifying proofs onchain. The intended way of using the verifier is through FactRegistry contract, which besides running the verification process, also stores data for all verified proofs. (For more information see [FactRegistry and Proxy contract](#factregistry-and-proxy-contract)) @@ -44,7 +41,7 @@ After that, you can use `verify-on-starknet.sh` script to send the transaction t For example, run: ```bash -./verify-on-starknet.sh 0x16409cfef9b6c3e6002133b61c59d09484594b37b8e4daef7dcba5495a0ef1a examples/calldata recursive keccak_248_lsb stone5 strict +./verify-on-starknet.sh 0x4ce7851f00b6c3289674841fd7a1b96b6fd41ed1edc248faccd672c26371b8c examples/calldata recursive keccak_248_lsb stone5 strict ``` This bash script internally calls `verify_proof_full_and_register_fact` function on FactRegistry contract. @@ -53,6 +50,86 @@ This bash script internally calls `verify_proof_full_and_register_fact` function To generate split calldata, please refer to [Calldata Generator README](https://github.com/HerodotusDev/integrity-calldata-generator/blob/main/README.md). This repository also provides script for automatic transaction sending (proof verification is split into multiple transactions, for more information see [Split Verifier Architecture](#split-verifier-architecture)). +## Calls from Starknet contracts + +Since integrity is deployed on Starknet, other contracts can call FactRegistry to check whether certain proof has been verified. Integrity can be used as a dependency of your cairo1 project by including it in project's `Scarb.toml`: + +```toml +[dependencies] +integrity = { git = "https://github.com/HerodotusDev/integrity" } +``` + +The package provides many utility functions for interacting with the verifier. For contract calls, you can use `Integrity` struct which provides following methods: + +- `new() -> Integrity` - creates new interface for interacting with official FactRegistry (contract address is set automatically). +- `new_proxy() -> Integrity` - creates new interface using official Proxy contract (contract address is set automatically). +- `from_address(address: ContractAddress) -> Integrity` - create new interface using custom FactRegistry deployment. +- `is_fact_hash_valid_with_security(self: Integrity, fact_hash: felt252, security_bits: u32) -> bool` - checks if given `fact_hash` has been verified with at least `security_bits` number of security bits. +- `is_verification_hash_valid(self: Integrity, verification_hash: felt252) -> bool` - checks if given `verification_hash` has been verified. +- `with_config(self: Integrity, verifier_config: VerifierConfiguration, security_bits: u32) -> IntegrityWithConfig` - returns new interface with custom verifier configuration. +- `with_hashed_config(self: Integrity, verifier_config_hash: felt252, security_bits: u32) -> IntegrityWithConfig` - returns new interface with custom verifier configuration given its hash. + +On `IntegrityWithConfig` interface you can call: + +- `is_fact_hash_valid(self: IntegrityWithConfig, fact_hash: felt252) -> bool` - checks if given `fact_hash` has been verified with selected config. + +There are also few utility function for calculating hashes: + +- `get_verifier_config_hash(verifier_config: VerifierConfiguration) -> felt252` - calculates hash for given verifier configuration, which is used necessary for calculating verification hash. +- `get_verification_hash(fact_hash: felt252, verifier_config_hash: felt252, security_bits: u32) -> felt252` - calculates verification hash for given `fact_hash`, `verifier_config_hash` and `security_bits`. +- `calculate_fact_hash(program_hash: felt256, output: Span) -> felt252` - calculates fact hash for given `program_hash` and `output` array. +- `calculate_bootloaded_fact_hash(bootloader_program_hash: felt252, child_program_hash: felt252, child_output: Span) -> felt252` - calculates fact hash for program that was bootloaded with standard bootloader. + +Available constants are: + +- `INTEGRITY_ADDRESS` - address of official FactRegistry contract deployed on Starknet Sepolia +- `PROXY_ADDRESS` - address of official Proxy contract deployed on Starknet Sepolia +- `SHARP_BOOTLOADER_PROGRAM_HASH` - program hash of the bootloader used by SHARP prover +- `STONE_BOOTLOADER_PROGRAM_HASH` - program hash of [TODO LINK] + +Example: + +``` +use integrity::{Integrity, IntegrityWithConfig, calculate_bootloaded_fact_hash, SHARP_BOOTLOADER_PROGRAM_HASH, VerifierConfiguration}; + +fn is_fibonacci_verified(fib_index: felt252, fib_value: felt252) -> bool { + let SECURITY_BITS = 70; + let fibonacci_program_hash = 0x59874649ccc5a0a15ee77538f1eb760acb88cab027a2d48f4246bf17b7b7694; + let fact_hash = calculate_bootloaded_fact_hash( + SHARP_BOOTLOADER_PROGRAM_HASH, fibonacci_program_hash, [fib_index, fib_value].span() + ); + + let integrity = Integrity::new(); + integrity.is_fact_hash_valid_with_security(fact_hash, SECURITY_BITS) +} + +fn is_multi_fibonacci_verified(fib: Span<(felt252, felt252)>) -> bool { + let config = VerifierConfiguration { + layout: 'recursive_with_poseidon', + hasher: 'keccak_160_lsb', + stone_version: 'stone6', + memory_verification: 'relaxed', + }; + let SECURITY_BITS = 96; + let fibonacci_program_hash = 0x59874649ccc5a0a15ee77538f1eb760acb88cab027a2d48f4246bf17b7b7694; + + let integrity = Integrity::new().with_config(config, SECURITY_BITS); + + let mut ret = true; + for f in fib { + let (fib_index, fib_value) = *f; + let fact_hash = calculate_bootloaded_fact_hash( + SHARP_BOOTLOADER_PROGRAM_HASH, fibonacci_program_hash, [fib_index, fib_value].span() + ); + + if !integrity.is_fact_hash_valid(fact_hash) { + ret = false; + } + }; + ret +} +``` + ## Running locally To run the verifier locally, first you need to build cairo project using: @@ -84,21 +161,41 @@ By default, the verifier is configured for monolith version, recursive layout an scarb build --no-default-features --features small,blake2s,monolith ``` -`layout`: [`dex`, `recursive`, `recursive_with_poseidon`, `small`, `starknet`, `starknet_with_keccak`]
-hash functions: [`keccak`, `blake2s`]
-verifier types: [`monolith`, `split`] +- `layout` + - `dex` + - `recursive` + - `recursive_with_poseidon` + - `small` + - `starknet` + - `starknet_with_keccak` +- hash functions: + - `keccak` + - `blake2s` +- verifier types + - `monolith` + - `split` There are also additional settings that can be configured at runtime: -`memory_verification`: [`strict`, `relaxed`, `cairo1`]
-`stone_version`: [`stone5`, `stone6`]
-hasher bit length: [`160_lsb`, `248_lsb`] +- `memory_verification` + - `strict` + - `relaxed` + - `cairo1` +- `stone_version` + - `stone5` + - `stone6` +- hasher bit length + - `160_lsb` + - `248_lsb` Hash function and hasher bit length are combined into one setting: -`hasher`: [`keccak_160_lsb`, `blake2s_160`, `blake2s_248_lsb`] +- `hasher` + - `keccak_160_lsb` + - `blake2s_160` + - `blake2s_248_lsb` -For `stone5` available `hasher`s are `keccak_160_lsb` and `blake2s_160`, for `stone6` - `keccak_160_lsb` and `blake2s_248_lsb`. +For `stone5` available hashers are `keccak_160_lsb` and `blake2s_160`, for `stone6` - `keccak_160_lsb` and `blake2s_248_lsb`. ### Running tests @@ -176,5 +273,3 @@ After proof is verified, `FactRegistered` event is emitted which contains `fact_ - `get_all_verifications_for_fact_hash(fact_hash)` - returns list of all verification hashes, security bits and settings for given `fact_hash`. This method is useful for checking if given program has been verified by someone with secure enough proof. FactRegistry contract is trustless which means that the owner of the contract can't override or change any existing behavior, they can only add new verifiers. Proxy contract on the other hand is upgradable, so every function can be changed or removed. It has the advantage of having all future updates of the verifier logic without having to replace the address of FactRegistry contract. - -TODO: how to read FactRegistered event