plonky2/evm/src/get_challenges.rs

364 lines
12 KiB
Rust
Raw Normal View History

2023-08-18 18:59:58 -04:00
use ethereum_types::{BigEndianHash, H256, U256};
use plonky2::field::extension::Extendable;
2022-05-20 11:21:13 +02:00
use plonky2::fri::proof::{FriProof, FriProofTarget};
2022-05-18 09:22:58 +02:00
use plonky2::hash::hash_types::RichField;
2022-05-04 20:57:07 +02:00
use plonky2::iop::challenger::{Challenger, RecursiveChallenger};
use plonky2::plonk::circuit_builder::CircuitBuilder;
use plonky2::plonk::config::{AlgebraicHasher, GenericConfig};
2022-09-22 11:01:27 +02:00
use crate::all_stark::{AllStark, NUM_TABLES};
2022-05-04 20:57:07 +02:00
use crate::config::StarkConfig;
2023-02-13 15:58:26 +01:00
use crate::cross_table_lookup::get_grand_product_challenge_set;
2022-05-04 20:57:07 +02:00
use crate::proof::*;
use crate::util::{h256_limbs, u256_limbs, u256_to_u32, u256_to_u64};
2023-09-12 19:23:16 -04:00
use crate::witness::errors::ProgramError;
2023-08-18 18:59:58 -04:00
fn observe_root<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>(
challenger: &mut Challenger<F, C::Hasher>,
root: H256,
) {
for limb in root.into_uint().0.into_iter() {
challenger.observe_element(F::from_canonical_u32(limb as u32));
challenger.observe_element(F::from_canonical_u32((limb >> 32) as u32));
}
}
fn observe_trie_roots<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>(
challenger: &mut Challenger<F, C::Hasher>,
trie_roots: &TrieRoots,
) {
observe_root::<F, C, D>(challenger, trie_roots.state_root);
observe_root::<F, C, D>(challenger, trie_roots.transactions_root);
observe_root::<F, C, D>(challenger, trie_roots.receipts_root);
}
fn observe_trie_roots_target<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
const D: usize,
>(
challenger: &mut RecursiveChallenger<F, C::Hasher, D>,
trie_roots: &TrieRootsTarget,
) where
C::Hasher: AlgebraicHasher<F>,
{
challenger.observe_elements(&trie_roots.state_root);
challenger.observe_elements(&trie_roots.transactions_root);
challenger.observe_elements(&trie_roots.receipts_root);
}
fn observe_block_metadata<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
const D: usize,
>(
challenger: &mut Challenger<F, C::Hasher>,
block_metadata: &BlockMetadata,
2023-09-12 19:23:16 -04:00
) -> Result<(), ProgramError> {
2023-08-18 18:59:58 -04:00
challenger.observe_elements(
&u256_limbs::<F>(U256::from_big_endian(&block_metadata.block_beneficiary.0))[..5],
);
challenger.observe_element(u256_to_u32(block_metadata.block_timestamp)?);
challenger.observe_element(u256_to_u32(block_metadata.block_number)?);
challenger.observe_element(u256_to_u32(block_metadata.block_difficulty)?);
challenger.observe_elements(&h256_limbs::<F>(block_metadata.block_random));
challenger.observe_element(u256_to_u32(block_metadata.block_gaslimit)?);
challenger.observe_element(u256_to_u32(block_metadata.block_chain_id)?);
let basefee = u256_to_u64(block_metadata.block_base_fee)?;
2023-09-12 19:23:16 -04:00
challenger.observe_element(basefee.0);
challenger.observe_element(basefee.1);
challenger.observe_element(u256_to_u32(block_metadata.block_gas_used)?);
for i in 0..8 {
challenger.observe_elements(&u256_limbs(block_metadata.block_bloom[i]));
}
2023-09-12 19:23:16 -04:00
Ok(())
2023-08-18 18:59:58 -04:00
}
fn observe_block_metadata_target<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
const D: usize,
>(
challenger: &mut RecursiveChallenger<F, C::Hasher, D>,
block_metadata: &BlockMetadataTarget,
) where
C::Hasher: AlgebraicHasher<F>,
{
challenger.observe_elements(&block_metadata.block_beneficiary);
challenger.observe_element(block_metadata.block_timestamp);
challenger.observe_element(block_metadata.block_number);
challenger.observe_element(block_metadata.block_difficulty);
challenger.observe_elements(&block_metadata.block_random);
2023-08-18 18:59:58 -04:00
challenger.observe_element(block_metadata.block_gaslimit);
challenger.observe_element(block_metadata.block_chain_id);
2023-08-19 10:23:24 -04:00
challenger.observe_elements(&block_metadata.block_base_fee);
challenger.observe_element(block_metadata.block_gas_used);
challenger.observe_elements(&block_metadata.block_bloom);
}
fn observe_extra_block_data<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
const D: usize,
>(
challenger: &mut Challenger<F, C::Hasher>,
extra_data: &ExtraBlockData,
2023-09-12 19:23:16 -04:00
) -> Result<(), ProgramError> {
2023-09-11 15:47:33 +01:00
challenger.observe_elements(&h256_limbs(extra_data.genesis_state_root));
challenger.observe_element(u256_to_u32(extra_data.txn_number_before)?);
challenger.observe_element(u256_to_u32(extra_data.txn_number_after)?);
challenger.observe_element(u256_to_u32(extra_data.gas_used_before)?);
challenger.observe_element(u256_to_u32(extra_data.gas_used_after)?);
for i in 0..8 {
challenger.observe_elements(&u256_limbs(extra_data.block_bloom_before[i]));
}
for i in 0..8 {
challenger.observe_elements(&u256_limbs(extra_data.block_bloom_after[i]));
}
2023-09-12 19:23:16 -04:00
Ok(())
}
fn observe_extra_block_data_target<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
const D: usize,
>(
challenger: &mut RecursiveChallenger<F, C::Hasher, D>,
extra_data: &ExtraBlockDataTarget,
) where
C::Hasher: AlgebraicHasher<F>,
{
2023-09-11 15:47:33 +01:00
challenger.observe_elements(&extra_data.genesis_state_root);
challenger.observe_element(extra_data.txn_number_before);
challenger.observe_element(extra_data.txn_number_after);
challenger.observe_element(extra_data.gas_used_before);
challenger.observe_element(extra_data.gas_used_after);
challenger.observe_elements(&extra_data.block_bloom_before);
challenger.observe_elements(&extra_data.block_bloom_after);
2023-08-18 18:59:58 -04:00
}
2023-08-21 23:32:53 +01:00
fn observe_block_hashes<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
const D: usize,
>(
challenger: &mut Challenger<F, C::Hasher>,
block_hashes: &BlockHashes,
) {
for i in 0..256 {
challenger.observe_elements(&h256_limbs::<F>(block_hashes.prev_hashes[i]));
2023-08-21 23:32:53 +01:00
}
challenger.observe_elements(&h256_limbs::<F>(block_hashes.cur_hash));
2023-08-21 23:32:53 +01:00
}
fn observe_block_hashes_target<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
const D: usize,
>(
challenger: &mut RecursiveChallenger<F, C::Hasher, D>,
block_hashes: &BlockHashesTarget,
) where
C::Hasher: AlgebraicHasher<F>,
{
challenger.observe_elements(&block_hashes.prev_hashes);
challenger.observe_elements(&block_hashes.cur_hash);
}
2023-08-18 18:59:58 -04:00
pub(crate) fn observe_public_values<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
const D: usize,
>(
challenger: &mut Challenger<F, C::Hasher>,
public_values: &PublicValues,
2023-09-12 19:23:16 -04:00
) -> Result<(), ProgramError> {
2023-08-18 18:59:58 -04:00
observe_trie_roots::<F, C, D>(challenger, &public_values.trie_roots_before);
observe_trie_roots::<F, C, D>(challenger, &public_values.trie_roots_after);
2023-09-12 19:23:16 -04:00
observe_block_metadata::<F, C, D>(challenger, &public_values.block_metadata)?;
2023-08-21 23:32:53 +01:00
observe_block_hashes::<F, C, D>(challenger, &public_values.block_hashes);
2023-09-12 19:23:16 -04:00
observe_extra_block_data::<F, C, D>(challenger, &public_values.extra_block_data)
2023-08-18 18:59:58 -04:00
}
pub(crate) fn observe_public_values_target<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
const D: usize,
>(
challenger: &mut RecursiveChallenger<F, C::Hasher, D>,
public_values: &PublicValuesTarget,
) where
C::Hasher: AlgebraicHasher<F>,
{
observe_trie_roots_target::<F, C, D>(challenger, &public_values.trie_roots_before);
observe_trie_roots_target::<F, C, D>(challenger, &public_values.trie_roots_after);
observe_block_metadata_target::<F, C, D>(challenger, &public_values.block_metadata);
2023-08-21 23:32:53 +01:00
observe_block_hashes_target::<F, C, D>(challenger, &public_values.block_hashes);
observe_extra_block_data_target::<F, C, D>(challenger, &public_values.extra_block_data);
2023-08-18 18:59:58 -04:00
}
2022-05-04 20:57:07 +02:00
impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize> AllProof<F, C, D> {
2022-05-11 14:35:33 +02:00
/// Computes all Fiat-Shamir challenges used in the STARK proof.
pub(crate) fn get_challenges(
&self,
config: &StarkConfig,
2023-09-12 19:23:16 -04:00
) -> Result<AllProofChallenges<F, D>, ProgramError> {
let mut challenger = Challenger::<F, C::Hasher>::new();
2022-05-11 14:35:33 +02:00
2022-05-19 09:41:15 +02:00
for proof in &self.stark_proofs {
challenger.observe_cap(&proof.proof.trace_cap);
2022-05-11 14:35:33 +02:00
}
2023-09-12 19:23:16 -04:00
observe_public_values::<F, C, D>(&mut challenger, &self.public_values)?;
2022-08-25 12:24:22 -07:00
let ctl_challenges =
get_grand_product_challenge_set(&mut challenger, config.num_challenges);
2022-05-11 14:35:33 +02:00
2023-09-12 19:23:16 -04:00
Ok(AllProofChallenges {
2023-01-30 08:51:33 -08:00
stark_challenges: core::array::from_fn(|i| {
2022-10-03 10:53:33 +02:00
challenger.compact();
2023-02-13 15:58:26 +01:00
self.stark_proofs[i]
.proof
.get_challenges(&mut challenger, config)
2022-08-26 10:12:45 +02:00
}),
2022-05-11 14:35:33 +02:00
ctl_challenges,
2023-09-12 19:23:16 -04:00
})
2022-05-11 14:35:33 +02:00
}
2022-10-06 16:40:03 +02:00
#[allow(unused)] // TODO: should be used soon
2022-09-22 11:01:27 +02:00
pub(crate) fn get_challenger_states(
&self,
all_stark: &AllStark<F, D>,
config: &StarkConfig,
) -> AllChallengerState<F, C::Hasher, D> {
let mut challenger = Challenger::<F, C::Hasher>::new();
2022-09-22 11:01:27 +02:00
for proof in &self.stark_proofs {
challenger.observe_cap(&proof.proof.trace_cap);
2022-09-22 11:01:27 +02:00
}
2023-08-18 18:59:58 -04:00
observe_public_values::<F, C, D>(&mut challenger, &self.public_values);
2022-09-22 11:01:27 +02:00
let ctl_challenges =
get_grand_product_challenge_set(&mut challenger, config.num_challenges);
2023-02-13 15:58:26 +01:00
let lookups = all_stark.num_lookups_helper_columns(config);
2022-09-22 11:01:27 +02:00
2022-10-03 10:53:33 +02:00
let mut challenger_states = vec![challenger.compact()];
2022-09-22 11:01:27 +02:00
for i in 0..NUM_TABLES {
2023-02-13 15:58:26 +01:00
self.stark_proofs[i]
.proof
.get_challenges(&mut challenger, config);
2022-10-03 10:53:33 +02:00
challenger_states.push(challenger.compact());
2022-09-22 11:01:27 +02:00
}
AllChallengerState {
states: challenger_states.try_into().unwrap(),
ctl_challenges,
}
}
2022-05-11 14:35:33 +02:00
}
impl<F, C, const D: usize> StarkProof<F, C, D>
2022-05-04 20:57:07 +02:00
where
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
2022-05-04 20:57:07 +02:00
{
/// Computes all Fiat-Shamir challenges used in the STARK proof.
2022-05-19 09:41:15 +02:00
pub(crate) fn get_challenges(
2022-05-04 20:57:07 +02:00
&self,
challenger: &mut Challenger<F, C::Hasher>,
2022-05-04 20:57:07 +02:00
config: &StarkConfig,
) -> StarkProofChallenges<F, D> {
2022-08-25 12:24:22 -07:00
let degree_bits = self.recover_degree_bits(config);
2022-05-11 14:35:33 +02:00
2022-05-04 20:57:07 +02:00
let StarkProof {
2023-02-13 15:58:26 +01:00
auxiliary_polys_cap,
2022-05-04 20:57:07 +02:00
quotient_polys_cap,
openings,
opening_proof:
FriProof {
commit_phase_merkle_caps,
final_poly,
pow_witness,
..
},
2022-05-12 22:35:13 +02:00
..
2022-08-25 12:24:22 -07:00
} = &self;
2022-05-04 20:57:07 +02:00
2022-05-18 09:22:58 +02:00
let num_challenges = config.num_challenges;
2022-05-04 20:57:07 +02:00
2023-02-13 15:58:26 +01:00
challenger.observe_cap(auxiliary_polys_cap);
2022-05-04 20:57:07 +02:00
2022-05-18 09:22:58 +02:00
let stark_alphas = challenger.get_n_challenges(num_challenges);
2022-05-04 20:57:07 +02:00
2022-05-18 09:22:58 +02:00
challenger.observe_cap(quotient_polys_cap);
let stark_zeta = challenger.get_extension_challenge::<D>();
2022-05-04 20:57:07 +02:00
2022-05-18 09:22:58 +02:00
challenger.observe_openings(&openings.to_fri_openings());
2022-05-04 20:57:07 +02:00
2022-05-18 09:22:58 +02:00
StarkProofChallenges {
stark_alphas,
stark_zeta,
fri_challenges: challenger.fri_challenges::<C, D>(
2022-05-18 09:22:58 +02:00
commit_phase_merkle_caps,
final_poly,
*pow_witness,
degree_bits,
&config.fri_config,
),
}
2022-05-04 20:57:07 +02:00
}
}
2022-08-25 12:24:22 -07:00
impl<const D: usize> StarkProofTarget<D> {
pub(crate) fn get_challenges<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>>(
2022-05-04 20:57:07 +02:00
&self,
builder: &mut CircuitBuilder<F, D>,
challenger: &mut RecursiveChallenger<F, C::Hasher, D>,
2022-05-04 20:57:07 +02:00
config: &StarkConfig,
) -> StarkProofChallengesTarget<D>
where
C::Hasher: AlgebraicHasher<F>,
2022-05-04 20:57:07 +02:00
{
2022-05-20 11:21:13 +02:00
let StarkProofTarget {
2023-02-13 15:58:26 +01:00
auxiliary_polys_cap: auxiliary_polys,
2022-05-20 11:21:13 +02:00
quotient_polys_cap,
openings,
opening_proof:
FriProofTarget {
commit_phase_merkle_caps,
final_poly,
pow_witness,
..
},
..
2022-08-25 12:24:22 -07:00
} = &self;
2022-05-20 11:21:13 +02:00
2022-05-18 09:22:58 +02:00
let num_challenges = config.num_challenges;
2022-05-20 11:21:13 +02:00
2023-02-13 15:58:26 +01:00
challenger.observe_cap(auxiliary_polys);
2022-05-20 11:21:13 +02:00
2022-05-18 09:22:58 +02:00
let stark_alphas = challenger.get_n_challenges(builder, num_challenges);
2022-05-20 11:21:13 +02:00
challenger.observe_cap(quotient_polys_cap);
2022-05-18 09:22:58 +02:00
let stark_zeta = challenger.get_extension_challenge(builder);
2022-05-20 11:21:13 +02:00
challenger.observe_openings(&openings.to_fri_openings(builder.zero()));
2022-05-18 09:22:58 +02:00
StarkProofChallengesTarget {
stark_alphas,
stark_zeta,
2023-02-25 08:55:55 -08:00
fri_challenges: challenger.fri_challenges(
2022-05-18 09:22:58 +02:00
builder,
2022-05-20 11:21:13 +02:00
commit_phase_merkle_caps,
final_poly,
*pow_witness,
2022-05-18 09:22:58 +02:00
&config.fri_config,
),
}
2022-05-04 20:57:07 +02:00
}
}