Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into feat/incr_opcode
Browse files Browse the repository at this point in the history
  • Loading branch information
Nashtare committed Oct 20, 2024
2 parents 7c765fd + f8c5f9c commit b786905
Show file tree
Hide file tree
Showing 9 changed files with 324 additions and 241 deletions.
21 changes: 18 additions & 3 deletions evm_arithmetization/src/all_stark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,24 @@ pub const NUM_TABLES: usize = if cfg!(feature = "cdk_erigon") {
Table::MemAfter as usize + 1
};

/// Indices of Keccak Tables
pub const KECCAK_TABLES_INDICES: [usize; 2] =
[Table::Keccak as usize, Table::KeccakSponge as usize];
/// Indices of optional Tables
#[cfg(not(feature = "cdk_erigon"))]
pub const OPTIONAL_TABLE_INDICES: [usize; 5] = [
Table::BytePacking as usize,
Table::Keccak as usize,
Table::KeccakSponge as usize,
Table::Logic as usize,
Table::MemAfter as usize,
];
#[cfg(feature = "cdk_erigon")]
pub const OPTIONAL_TABLE_INDICES: [usize; 6] = [
Table::BytePacking as usize,
Table::Keccak as usize,
Table::KeccakSponge as usize,
Table::Logic as usize,
Table::MemAfter as usize,
Table::Poseidon as usize,
];

impl Table {
/// Returns all STARK table indices.
Expand Down
148 changes: 87 additions & 61 deletions evm_arithmetization/src/fixed_recursive_verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ use starky::proof::StarkProofWithMetadata;
use starky::stark::Stark;

use crate::all_stark::{
all_cross_table_lookups, AllStark, Table, KECCAK_TABLES_INDICES, MEMORY_CTL_IDX, NUM_CTLS,
NUM_TABLES,
all_cross_table_lookups, AllStark, Table, MEMORY_CTL_IDX, NUM_CTLS, NUM_TABLES,
OPTIONAL_TABLE_INDICES,
};
use crate::cpu::kernel::aggregator::KERNEL;
use crate::generation::segments::{GenerationSegmentData, SegmentDataIterator};
Expand Down Expand Up @@ -156,8 +156,8 @@ where
/// for EVM root proofs; the circuit has them just to match the
/// structure of aggregation proofs.
cyclic_vk: VerifierCircuitTarget,
/// We can skip verifying Keccak tables when they are not in use.
use_keccak_tables: BoolTarget,
/// We can skip verifying tables when they are not in use.
table_in_use: [BoolTarget; NUM_TABLES],
}

impl<F, C, const D: usize> RootCircuitData<F, C, D>
Expand All @@ -180,7 +180,9 @@ where
}
self.public_values.to_buffer(buffer)?;
buffer.write_target_verifier_circuit(&self.cyclic_vk)?;
buffer.write_target_bool(self.use_keccak_tables)?;
for table_in_use in self.table_in_use {
buffer.write_target_bool(table_in_use)?;
}
Ok(())
}

Expand All @@ -200,15 +202,18 @@ where
}
let public_values = PublicValuesTarget::from_buffer(buffer)?;
let cyclic_vk = buffer.read_target_verifier_circuit()?;
let use_keccak_tables = buffer.read_target_bool()?;
let mut table_in_use = Vec::with_capacity(NUM_TABLES);
for _ in 0..NUM_TABLES {
table_in_use.push(buffer.read_target_bool()?);
}

Ok(Self {
circuit,
proof_with_pis: proof_with_pis.try_into().unwrap(),
index_verifier_data: index_verifier_data.try_into().unwrap(),
public_values,
cyclic_vk,
use_keccak_tables,
table_in_use: table_in_use.try_into().unwrap(),
})
}
}
Expand Down Expand Up @@ -832,26 +837,24 @@ where
let block_wrapper = Self::create_block_wrapper_circuit(&block);
let two_to_one_block = Self::create_two_to_one_block_circuit(&block_wrapper);

// TODO(sdeng): enable more optional Tables
let table_dummy_proofs = core::array::from_fn(|i| {
if KECCAK_TABLES_INDICES.contains(&i) {
if OPTIONAL_TABLE_INDICES.contains(&i) {
let init_degree = degree_bits_ranges[i].start;
let common_circuit_data = by_table[i]
let chain = by_table[i]
.by_stark_size
.get(&init_degree)
.expect("Unable to get the shrinking circuits")
.expect("Unable to get the shrinking circuits");
let common_circuit_data = chain
.shrinking_wrappers
.last()
.expect("Unable to get the last shrinking circuit")
.circuit
.common
.clone();
let dummy_circuit: CircuitData<F, C, D> = dummy_circuit(&common_circuit_data);
.map(|wrapper| &wrapper.circuit.common)
.unwrap_or(&chain.initial_wrapper.circuit.common);
let dummy_circuit: CircuitData<F, C, D> = dummy_circuit(common_circuit_data);
let dummy_pis = HashMap::new();
let proof = dummy_proof(&dummy_circuit, dummy_pis)
.expect("Unable to generate dummy proofs");
Some(ShrunkProofData {
common_circuit_data,
common_circuit_data: common_circuit_data.clone(),
proof,
})
} else {
Expand Down Expand Up @@ -900,8 +903,10 @@ where

let mut builder = CircuitBuilder::new(CircuitConfig::standard_recursion_config());

let use_keccak_tables = builder.add_virtual_bool_target_safe();
let skip_keccak_tables = builder.not(use_keccak_tables);
let table_in_use: [BoolTarget; NUM_TABLES] =
core::array::from_fn(|_| builder.add_virtual_bool_target_safe());
let table_not_in_use: [BoolTarget; NUM_TABLES] =
core::array::from_fn(|i| builder.not(table_in_use[i]));
let public_values = add_virtual_public_values_public_input(&mut builder);

let recursive_proofs =
Expand All @@ -921,11 +926,17 @@ where
}
}

for (i, table) in table_in_use.iter().enumerate() {
if !OPTIONAL_TABLE_INDICES.contains(&i) {
builder.assert_one(table.target);
}
}

// Ensures that the trace cap is set to 0 when skipping Keccak tables.
for i in KECCAK_TABLES_INDICES {
for i in OPTIONAL_TABLE_INDICES {
for h in &pis[i].trace_cap {
for t in h {
let trace_cap_check = builder.mul(skip_keccak_tables.target, *t);
let trace_cap_check = builder.mul(table_not_in_use[i].target, *t);
builder.assert_zero(trace_cap_check);
}
}
Expand All @@ -941,16 +952,16 @@ where
// Check that the correct CTL challenges are used in every proof.
for (i, pi) in pis.iter().enumerate() {
for j in 0..stark_config.num_challenges {
if KECCAK_TABLES_INDICES.contains(&i) {
// Ensures that the correct CTL challenges are used in Keccak tables when
// `enable_keccak_tables` is true.
if OPTIONAL_TABLE_INDICES.contains(&i) {
// Ensures that the correct CTL challenges are used when an optional table
// is in use.
builder.conditional_assert_eq(
use_keccak_tables.target,
table_in_use[i].target,
ctl_challenges.challenges[j].beta,
pi.ctl_challenges.challenges[j].beta,
);
builder.conditional_assert_eq(
use_keccak_tables.target,
table_in_use[i].target,
ctl_challenges.challenges[j].gamma,
pi.ctl_challenges.challenges[j].gamma,
);
Expand Down Expand Up @@ -978,18 +989,18 @@ where
let current_state_before = pis[i].challenger_state_before.as_ref();
let current_state_after = pis[i].challenger_state_after.as_ref();
for j in 0..state_len {
if KECCAK_TABLES_INDICES.contains(&i) {
if OPTIONAL_TABLE_INDICES.contains(&i) {
// Ensure the challenger state:
// 1) prev == current_before when using Keccak
// 1) prev == current_before when using this table
builder.conditional_assert_eq(
use_keccak_tables.target,
table_in_use[i].target,
prev_state[j],
current_state_before[j],
);
// 2) Update prev <- current_after when using Keccak
// 3) Keep prev <- prev when skipping Keccak
// 2) Update prev <- current_after when using this table
// 3) Keep prev <- prev when skipping this table
prev_state[j] =
builder.select(use_keccak_tables, current_state_after[j], prev_state[j]);
builder.select(table_in_use[i], current_state_after[j], prev_state[j]);
} else {
builder.connect(prev_state[j], current_state_before[j]);
prev_state[j] = current_state_after[j];
Expand Down Expand Up @@ -1017,11 +1028,10 @@ where
.collect_vec(),
);

// Ensure that when Keccak tables are skipped, the Keccak tables' ctl_zs_first
// are all zeros.
for &i in KECCAK_TABLES_INDICES.iter() {
// Ensure that when a table is skipped, the table's ctl_zs_first are all zeros.
for &i in OPTIONAL_TABLE_INDICES.iter() {
for &t in pis[i].ctl_zs_first.iter() {
let ctl_check = builder.mul(skip_keccak_tables.target, t);
let ctl_check = builder.mul(table_not_in_use[i].target, t);
builder.assert_zero(ctl_check);
}
}
Expand Down Expand Up @@ -1055,10 +1065,10 @@ where
let inner_verifier_data =
builder.random_access_verifier_data(index_verifier_data[i], possible_vks);

if KECCAK_TABLES_INDICES.contains(&i) {
if OPTIONAL_TABLE_INDICES.contains(&i) {
builder
.conditionally_verify_proof_or_dummy::<C>(
use_keccak_tables,
table_in_use[i],
&recursive_proofs[i],
&inner_verifier_data,
inner_common_data[i],
Expand Down Expand Up @@ -1101,7 +1111,7 @@ where
index_verifier_data,
public_values,
cyclic_vk,
use_keccak_tables,
table_in_use,
}
}

Expand Down Expand Up @@ -2014,16 +2024,7 @@ where

for table in 0..NUM_TABLES {
let table_circuits = &self.by_table[table];
if KECCAK_TABLES_INDICES.contains(&table) && !all_proof.use_keccak_tables {
let dummy_proof_data = self.table_dummy_proofs[table]
.as_ref()
.ok_or_else(|| anyhow::format_err!("No dummy_proof_data"))?;
root_inputs.set_target(self.root.index_verifier_data[table], F::ZERO)?;
root_inputs.set_proof_with_pis_target(
&self.root.proof_with_pis[table],
&dummy_proof_data.proof,
)?;
} else {
if all_proof.table_in_use[table] {
let stark_proof = &all_proof.multi_proof.stark_proofs[table]
.as_ref()
.ok_or_else(|| anyhow::format_err!("Unable to get stark proof"))?;
Expand All @@ -2050,6 +2051,16 @@ where
)?;
root_inputs
.set_proof_with_pis_target(&self.root.proof_with_pis[table], &shrunk_proof)?;
} else {
assert!(OPTIONAL_TABLE_INDICES.contains(&table));
let dummy_proof_data = self.table_dummy_proofs[table]
.as_ref()
.ok_or_else(|| anyhow::format_err!("No dummy_proof_data"))?;
root_inputs.set_target(self.root.index_verifier_data[table], F::ZERO)?;
root_inputs.set_proof_with_pis_target(
&self.root.proof_with_pis[table],
&dummy_proof_data.proof,
)?;
}

check_abort_signal(abort_signal.clone())?;
Expand All @@ -2069,7 +2080,11 @@ where
anyhow::Error::msg("Invalid conversion when setting public values targets.")
})?;

root_inputs.set_bool_target(self.root.use_keccak_tables, all_proof.use_keccak_tables)?;
self.root
.table_in_use
.iter()
.zip(all_proof.table_in_use.iter())
.try_for_each(|(target, value)| root_inputs.set_bool_target(*target, *value))?;

let root_proof = self.root.circuit.prove(root_inputs)?;

Expand Down Expand Up @@ -2142,16 +2157,7 @@ where
let mut root_inputs = PartialWitness::new();

for table in 0..NUM_TABLES {
if KECCAK_TABLES_INDICES.contains(&table) && !all_proof.use_keccak_tables {
let dummy_proof = self.table_dummy_proofs[table]
.as_ref()
.ok_or_else(|| anyhow::format_err!("Unable to get dummpy proof"))?;
root_inputs.set_target(self.root.index_verifier_data[table], F::ZERO)?;
root_inputs.set_proof_with_pis_target(
&self.root.proof_with_pis[table],
&dummy_proof.proof,
)?;
} else {
if all_proof.table_in_use[table] {
let (table_circuit, index_verifier_data) = &table_circuits[table]
.as_ref()
.ok_or_else(|| anyhow::format_err!("Unable to get circuits"))?;
Expand All @@ -2166,6 +2172,16 @@ where
table_circuit.shrink(stark_proof, &all_proof.multi_proof.ctl_challenges)?;
root_inputs
.set_proof_with_pis_target(&self.root.proof_with_pis[table], &shrunk_proof)?;
} else {
assert!(OPTIONAL_TABLE_INDICES.contains(&table));
let dummy_proof = self.table_dummy_proofs[table]
.as_ref()
.ok_or_else(|| anyhow::format_err!("Unable to get dummpy proof"))?;
root_inputs.set_target(self.root.index_verifier_data[table], F::ZERO)?;
root_inputs.set_proof_with_pis_target(
&self.root.proof_with_pis[table],
&dummy_proof.proof,
)?;
}

check_abort_signal(abort_signal.clone())?;
Expand All @@ -2185,7 +2201,11 @@ where
anyhow::Error::msg("Invalid conversion when setting public values targets.")
})?;

root_inputs.set_bool_target(self.root.use_keccak_tables, all_proof.use_keccak_tables)?;
self.root
.table_in_use
.iter()
.zip(all_proof.table_in_use.iter())
.try_for_each(|(target, value)| root_inputs.set_bool_target(*target, *value))?;

let root_proof = self.root.circuit.prove(root_inputs)?;

Expand Down Expand Up @@ -3047,6 +3067,12 @@ where
});
}

log::debug!(
"Table: {:?}, degree: {}, shrinking_wrappers_len: {}",
table,
degree_bits,
shrinking_wrappers.len()
);
Self {
initial_wrapper,
shrinking_wrappers,
Expand Down
Loading

0 comments on commit b786905

Please sign in to comment.