diff --git a/.github/workflows/proof_verification_tests.yml b/.github/workflows/proof_verification_tests.yml index 38280402f..c9eedfdc7 100644 --- a/.github/workflows/proof_verification_tests.yml +++ b/.github/workflows/proof_verification_tests.yml @@ -15,7 +15,8 @@ jobs: matrix: cairo_version: ["cairo0", "cairo1"] layout: ["recursive", "recursive_with_poseidon", "small", "dex", "starknet", "starknet_with_keccak"] - hasher: ["keccak"] + hasher: ["keccak_160_lsb"] + prover: ["stone5"] steps: - name: Checkout repository uses: actions/checkout@v3 @@ -27,7 +28,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 - name: Build project - run: scarb build --no-default-features --features monolith,${{ matrix.layout }},${{ matrix.hasher }} + run: scarb build --no-default-features --features monolith,${{ matrix.layout }},${{ matrix.hasher }},${{ matrix.prover }} - name: Run verification run: cargo run --release --bin runner -- -p target/dev/cairo_verifier.sierra.json -c ${{ matrix.cairo_version }} < examples/proofs/${{ matrix.layout }}/${{ matrix.cairo_version }}_example_proof.json diff --git a/Scarb.toml b/Scarb.toml index d6d726da0..461e1fe18 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -22,10 +22,15 @@ small = [] starknet = [] starknet_with_keccak = [] -keccak = [] -blake2s = [] +keccak_160_lsb = [] +keccak_248_lsb = [] +blake2s_160_lsb = [] +blake2s_248_lsb = [] + +stone5 = [] +stone6 = [] monolith = [] split = [] -default = ["recursive", "keccak", "monolith"] +default = ["recursive", "keccak_160_lsb", "stone5", "monolith"] diff --git a/examples/prover/cpu_air_params.json b/examples/prover/cpu_air_params.json index 415ed7693..c56155c56 100644 --- a/examples/prover/cpu_air_params.json +++ b/examples/prover/cpu_air_params.json @@ -1,9 +1,9 @@ { "field": "PrimeField0", "channel_hash": "poseidon3", - "commitment_hash": "keccak256_masked160_lsb", + "commitment_hash": "blake256_masked160_lsb", "n_verifier_friendly_commitment_layers": 9999, - "pow_hash": "keccak256", + "pow_hash": "blake256", "statement": { "page_hash": "pedersen" }, @@ -16,8 +16,8 @@ 3 ], "last_layer_degree_bound": 128, - "n_queries": 10, - "proof_of_work_bits": 30 + "n_queries": 18, + "proof_of_work_bits": 24 }, "log_n_cosets": 2 }, diff --git a/fact_registry/1-declare.sh b/fact_registry/1-declare.sh deleted file mode 100755 index e4f3b1be7..000000000 --- a/fact_registry/1-declare.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -sncast --profile testnet --wait declare --contract-name FactRegistry diff --git a/fact_registry/2-deploy.sh b/fact_registry/2-deploy.sh deleted file mode 100755 index e6dcf0636..000000000 --- a/fact_registry/2-deploy.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -# Check if the arguments are provided -if [ $# -ne 1 ]; then - echo "Usage: $0 " - exit 1 -fi - -# Assign argument to variable -class_hash=$1 - -# Pass the class hash to the sncast command -sncast --profile testnet --wait deploy --class-hash "$class_hash" diff --git a/fact_registry/3-is-valid.sh b/fact_registry/3-is-valid.sh deleted file mode 100755 index 3c7776fe5..000000000 --- a/fact_registry/3-is-valid.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -# Check if the arguments are provided -if [ $# -ne 2 ]; then - echo "Usage: $0 " - exit 1 -fi - -# Assign arguments to variables -contract_address=$1 -fact_hash=$2 - -# Pass the calldata to the sncast command -sncast --profile testnet \ - --wait \ - call \ - --contract-address "$contract_address" \ - --function "is_valid" \ - --calldata "$fact_hash" diff --git a/fact_registry/starknet/deploy.toml b/fact_registry/starknet/deploy.toml deleted file mode 100644 index 83cfa9e4b..000000000 --- a/fact_registry/starknet/deploy.toml +++ /dev/null @@ -1,6 +0,0 @@ -[[call]] -call_type = "deploy" -class_hash = "0x79b972400cbbbc9afe4056a377366773bc069e292e1b9657bec2e48b4353ad3" -inputs = ["REPLACE WITH YOUR ACCOUNT ADDRESS"] -unique = false -id = "fact_registry" \ No newline at end of file diff --git a/fact_registry/starknet/register_verifier.toml b/fact_registry/starknet/register_verifier.toml deleted file mode 100644 index 70582f280..000000000 --- a/fact_registry/starknet/register_verifier.toml +++ /dev/null @@ -1,18 +0,0 @@ -[[call]] -call_type = "deploy" -class_hash = "VERIFIER CLASS HASH" -inputs = [] -unique = false -id = "verifier" - -[[call]] -call_type = "invoke" -contract_address = "REPLACE WITH FACT REGISTRY ADDRESS" -function = "register_verifier" -inputs = [ - "SETTINGS.LAYOUT", - "SETTINGS.HASHER", - "SETTINGS.SECURITY_BITS", - "SETTINGS.VERSION", - "verifier" -] \ No newline at end of file diff --git a/multicall/verifiers/recursive/blake2s/deploy.toml b/multicall/verifiers/recursive/blake2s_160_lsb/deploy.toml similarity index 100% rename from multicall/verifiers/recursive/blake2s/deploy.toml rename to multicall/verifiers/recursive/blake2s_160_lsb/deploy.toml diff --git a/multicall/verifiers/recursive/blake2s/register.sh b/multicall/verifiers/recursive/blake2s_160_lsb/register.sh similarity index 69% rename from multicall/verifiers/recursive/blake2s/register.sh rename to multicall/verifiers/recursive/blake2s_160_lsb/register.sh index 9cd963746..7a96d5c52 100644 --- a/multicall/verifiers/recursive/blake2s/register.sh +++ b/multicall/verifiers/recursive/blake2s_160_lsb/register.sh @@ -9,4 +9,4 @@ sncast \ --fee-token eth \ --contract-address $FACT_REGISTRY \ --function "register_verifier" \ - --calldata "0x726563757273697665 0x626c616b653273 0x73746f6e6535 $VERIFIER" + --calldata "0x726563757273697665 0x626c616b6532735f3136305f6c7362 0x73746f6e6535 $VERIFIER" diff --git a/multicall/verifiers/recursive/keccak/deploy.toml b/multicall/verifiers/recursive/keccak_160_lsb/deploy.toml similarity index 100% rename from multicall/verifiers/recursive/keccak/deploy.toml rename to multicall/verifiers/recursive/keccak_160_lsb/deploy.toml diff --git a/multicall/verifiers/recursive/keccak/register.sh b/multicall/verifiers/recursive/keccak_160_lsb/register.sh similarity index 69% rename from multicall/verifiers/recursive/keccak/register.sh rename to multicall/verifiers/recursive/keccak_160_lsb/register.sh index 519175534..e99467200 100644 --- a/multicall/verifiers/recursive/keccak/register.sh +++ b/multicall/verifiers/recursive/keccak_160_lsb/register.sh @@ -9,4 +9,4 @@ sncast \ --fee-token eth \ --contract-address $FACT_REGISTRY \ --function "register_verifier" \ - --calldata "0x726563757273697665 0x6b656363616b 0x73746f6e6535 $VERIFIER" + --calldata "0x726563757273697665 0x6b656363616b5f3136305f6c7362 0x73746f6e6535 $VERIFIER" diff --git a/src/air/public_input.cairo b/src/air/public_input.cairo index 3fd14e9bf..864b6ab2d 100644 --- a/src/air/public_input.cairo +++ b/src/air/public_input.cairo @@ -60,7 +60,9 @@ trait PublicInputTrait { // Computes the hash of the public input, which is used as the initial seed for the Fiat-Shamir // heuristic. -fn get_public_input_hash(public_input: @PublicInput) -> felt252 { +fn get_public_input_hash( + public_input: @PublicInput, n_verifier_friendly_commitment_layers: felt252 +) -> felt252 { // Main page hash. let mut main_page_hash_state = PedersenTrait::new(0); let mut i: u32 = 0; @@ -76,10 +78,9 @@ fn get_public_input_hash(public_input: @PublicInput) -> felt252 { let main_page_hash = main_page_hash_state.finalize(); let mut hash_data = ArrayTrait::::new(); - hash_data.append(*public_input.log_n_steps); - hash_data.append(*public_input.range_check_min); - hash_data.append(*public_input.range_check_max); - hash_data.append(*public_input.layout); + + hash_data_init(ref hash_data, public_input, n_verifier_friendly_commitment_layers); + hash_data.extend(public_input.dynamic_params.span()); // Segments. @@ -118,6 +119,31 @@ fn get_public_input_hash(public_input: @PublicInput) -> felt252 { poseidon_hash_span(hash_data.span()) } +// Stone6 Prover version specific hash_data initialization +#[cfg(feature: 'stone6')] +fn hash_data_init( + ref hash_data: Array, + public_input: @PublicInput, + n_verifier_friendly_commitment_layers: felt252 +) { + hash_data.append(n_verifier_friendly_commitment_layers); + hash_data.append(*public_input.range_check_min); + hash_data.append(*public_input.range_check_max); + hash_data.append(*public_input.layout); +} + +// Stone5 Prover version specific hash_data initialization +#[cfg(feature: 'stone5')] +fn hash_data_init( + ref hash_data: Array, + public_input: @PublicInput, + _n_verifier_friendly_commitment_layers: felt252 +) { + hash_data.append(*public_input.range_check_min); + hash_data.append(*public_input.range_check_max); + hash_data.append(*public_input.layout); +} + // Returns the ratio between the product of all public memory cells and z^|public_memory|. // This is the value that needs to be at the memory__multi_column_perm__perm__public_memory_prod // member expression. @@ -181,8 +207,9 @@ fn verify_cairo1_public_input(public_input: @PublicInput) -> (felt252, felt252) (program_hash, output_hash) } + +#[cfg(feature: 'stone5')] #[cfg(feature: 'recursive')] -#[cfg(feature: 'keccak')] #[cfg(test)] mod tests { use super::get_public_input_hash; @@ -191,9 +218,10 @@ mod tests { #[available_gas(9999999999)] fn test_get_public_input_hash() { let public_input = get(); - let hash = get_public_input_hash(@public_input); + let hash = get_public_input_hash(@public_input, 0); assert( - hash == 0xaf91f2c71f4a594b1575d258ce82464475c82d8fb244142d0db450491c1b52, 'Hash invalid' + hash == 0x1c3097c2a1665c78d69edc47ff35a3f3c9c0678e3daaa74d2b68331a5757a37, + 'Hash invalid' ) } } diff --git a/src/common/blake2s.cairo b/src/common/blake2s.cairo index 063e40f09..4ebd51ff3 100644 --- a/src/common/blake2s.cairo +++ b/src/common/blake2s.cairo @@ -7,17 +7,6 @@ fn blake2s(data: Array) -> u256 { blake2s_final(state) } -// A 160 LSB truncated version of blake2s. -// hash: -// blake2s(x, y) & ~((1<<96) - 1). -fn truncated_blake2s(data: Array) -> felt252 { - // Truncate hash - convert value to felt, by taking the least significant 160 bits. - let hash = blake2s(data).flip_endianness() % 0x10000000000000000000000000000000000000000; - hash.try_into().unwrap() -} - -// internals: - #[inline(always)] fn rotr16(n: u32) -> u32 { let (high, low) = DivRem::div_rem(n, 65536); diff --git a/src/common/hasher.cairo b/src/common/hasher.cairo index 918112c28..7c2acb2df 100644 --- a/src/common/hasher.cairo +++ b/src/common/hasher.cairo @@ -1,9 +1,8 @@ use cairo_verifier::common::{ - blake2s::blake2s, blake2s::truncated_blake2s, blake2s_u8::blake2s as blake2s_u8, - flip_endianness::FlipEndiannessTrait + blake2s::blake2s, blake2s_u8::blake2s as blake2s_u8, flip_endianness::FlipEndiannessTrait }; -#[cfg(feature: 'blake2s')] +#[cfg(feature: 'blake2s_160_lsb')] fn hash_n_bytes(mut data: Array, n: u8, hash_len: bool) -> u256 { if hash_len { data.append(n); @@ -11,17 +10,63 @@ fn hash_n_bytes(mut data: Array, n: u8, hash_len: bool) -> u256 { blake2s_u8(data) } -#[cfg(feature: 'blake2s')] +#[cfg(feature: 'blake2s_160_lsb')] fn hash_truncated(data: Array) -> felt252 { - truncated_blake2s(data) + (blake2s(data).flip_endianness() + & 0x000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) + .try_into() + .unwrap() +} + +#[cfg(feature: 'blake2s_160_lsb')] +fn hash(data: Array) -> u256 { + blake2s(data) +} + +#[cfg(feature: 'blake2s_248_lsb')] +fn hash_n_bytes(mut data: Array, n: u8, hash_len: bool) -> u256 { + if hash_len { + data.append(n); + } + blake2s_u8(data) +} + +#[cfg(feature: 'blake2s_248_lsb')] +fn hash_truncated(data: Array) -> felt252 { + (blake2s(data).flip_endianness() + & 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) + .try_into() + .unwrap() } -#[cfg(feature: 'blake2s')] +#[cfg(feature: 'blake2s_248_lsb')] fn hash(data: Array) -> u256 { blake2s(data) } -#[cfg(feature: 'keccak')] +#[cfg(feature: 'keccak_160_lsb')] +fn hash_n_bytes(mut data: Array, n: u8, hash_len: bool) -> u256 { + if hash_len { + keccak::cairo_keccak(ref data, n.into(), 1) + } else { + keccak::cairo_keccak(ref data, 0, 0) + } +} + +#[cfg(feature: 'keccak_160_lsb')] +fn hash_truncated(mut data: Array) -> felt252 { + (keccak::cairo_keccak(ref data, 0, 0).flip_endianness() + & 0x0000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) + .try_into() + .unwrap() +} + +#[cfg(feature: 'keccak_160_lsb')] +fn hash(mut data: Array) -> u256 { + keccak::cairo_keccak(ref data, 0, 0) +} + +#[cfg(feature: 'keccak_248_lsb')] fn hash_n_bytes(mut data: Array, n: u8, hash_len: bool) -> u256 { if hash_len { keccak::cairo_keccak(ref data, n.into(), 1) @@ -30,15 +75,15 @@ fn hash_n_bytes(mut data: Array, n: u8, hash_len: bool) -> u256 { } } -#[cfg(feature: 'keccak')] +#[cfg(feature: 'keccak_248_lsb')] fn hash_truncated(mut data: Array) -> felt252 { - (keccak::cairo_keccak(ref data, 0, 0) - .flip_endianness() % 0x10000000000000000000000000000000000000000) + (keccak::cairo_keccak(ref data, 0, 0).flip_endianness() + & 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) .try_into() .unwrap() } -#[cfg(feature: 'keccak')] +#[cfg(feature: 'keccak_248_lsb')] fn hash(mut data: Array) -> u256 { keccak::cairo_keccak(ref data, 0, 0) } diff --git a/src/common/tests/test_blake2s.cairo b/src/common/tests/test_blake2s.cairo index 18f9cbac6..a4b4c3fa6 100644 --- a/src/common/tests/test_blake2s.cairo +++ b/src/common/tests/test_blake2s.cairo @@ -1,5 +1,5 @@ use cairo_verifier::common::{ - array_append::ArrayAppendTrait, blake2s::{blake2s, truncated_blake2s}, blake2s_u8::load32, + array_append::ArrayAppendTrait, blake2s::blake2s, hasher::hash_truncated, blake2s_u8::load32, }; fn get_arr_v1(n: u32) -> Array { @@ -84,14 +84,24 @@ fn test_blake2s_v2() { ); } +#[cfg(feature: 'blake2s_160_lsb')] #[test] #[available_gas(9999999999)] -fn test_truncated_blake2s() { +fn test_blake2s_160_lsb() { let mut data = ArrayTrait::::new(); - data.append_big_endian(1157029198022238202306346125123666191662554108005_u256); - data.append_big_endian(129252051435949032402481343903845417193011527432_u256); assert( - truncated_blake2s(data) == 642191007116032514313255519742888271333651019057, - 'invalid truncated_blake2s' + hash_truncated(data) == 0x00000000000000000000000042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9, + 'invalid value' + ); +} + +#[cfg(feature: 'blake2s_248_lsb')] +#[test] +#[available_gas(9999999999)] +fn test_blake2s_248_lsb() { + let mut data = ArrayTrait::::new(); + assert( + hash_truncated(data) == 0x00217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9, + 'invalid value' ); } diff --git a/src/stark.cairo b/src/stark.cairo index 8cb8a0f68..58531e28e 100644 --- a/src/stark.cairo +++ b/src/stark.cairo @@ -87,7 +87,10 @@ impl StarkProofImpl of StarkProofTrait { self.public_input.validate(@stark_domains); // Compute the initial hash seed for the Fiat-Shamir channel. - let digest = get_public_input_hash(self.public_input); + let digest = get_public_input_hash( + self.public_input, *self.config.n_verifier_friendly_commitment_layers + ); + // Construct the channel. let mut channel = ChannelImpl::new(digest);