Skip to content
This repository has been archived by the owner on Feb 21, 2024. It is now read-only.

Commit

Permalink
Remove new_stack_top_channel from StackBehavior (0xPolygonZero#1296)
Browse files Browse the repository at this point in the history
  • Loading branch information
LindaGuiga authored Oct 26, 2023
1 parent 3aeec83 commit 666a155
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 115 deletions.
8 changes: 8 additions & 0 deletions evm/src/cpu/bootstrap_kernel.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! The initial phase of execution, where the kernel code is hashed while being written to memory.
//! The hash is then checked against a precomputed kernel hash.
use ethereum_types::U256;
use itertools::Itertools;
use plonky2::field::extension::Extendable;
use plonky2::field::packed::PackedField;
Expand Down Expand Up @@ -52,6 +53,13 @@ pub(crate) fn generate_bootstrap_kernel<F: Field>(state: &mut GenerationState<F>
MemoryAddress::new(0, Segment::Code, 0),
KERNEL.code.clone(),
);
state.registers.stack_top = KERNEL
.code_hash
.iter()
.enumerate()
.fold(0.into(), |acc, (i, &elt)| {
acc + (U256::from(elt) << (224 - 32 * i))
});
state.traces.push_cpu(final_cpu_row);
log::info!("Bootstrapping took {} cycles", state.traces.clock());
}
Expand Down
11 changes: 3 additions & 8 deletions evm/src/cpu/cpu_stark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use super::halt;
use crate::all_stark::Table;
use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer};
use crate::cpu::columns::{COL_MAP, NUM_CPU_COLUMNS};
use crate::cpu::membus::NUM_GP_CHANNELS;
use crate::cpu::{
bootstrap_kernel, contextops, control_flow, decode, dup_swap, gas, jumps, membus, memio,
modfp254, pc, push0, shift, simple_logic, stack, stack_bounds, syscalls_exceptions,
Expand All @@ -41,7 +40,7 @@ pub fn ctl_data_keccak_sponge<F: Field>() -> Vec<Column<F>> {
let timestamp = Column::linear_combination([(COL_MAP.clock, num_channels)]);

let mut cols = vec![context, segment, virt, len, timestamp];
cols.extend(COL_MAP.mem_channels[4].value.map(Column::single));
cols.extend(Column::singles_next_row(COL_MAP.mem_channels[0].value));
cols
}

Expand All @@ -54,9 +53,7 @@ pub fn ctl_filter_keccak_sponge<F: Field>() -> Column<F> {
fn ctl_data_binops<F: Field>() -> Vec<Column<F>> {
let mut res = Column::singles(COL_MAP.mem_channels[0].value).collect_vec();
res.extend(Column::singles(COL_MAP.mem_channels[1].value));
res.extend(Column::singles(
COL_MAP.mem_channels[NUM_GP_CHANNELS - 1].value,
));
res.extend(Column::singles_next_row(COL_MAP.mem_channels[0].value));
res
}

Expand All @@ -68,9 +65,7 @@ fn ctl_data_ternops<F: Field>() -> Vec<Column<F>> {
let mut res = Column::singles(COL_MAP.mem_channels[0].value).collect_vec();
res.extend(Column::singles(COL_MAP.mem_channels[1].value));
res.extend(Column::singles(COL_MAP.mem_channels[2].value));
res.extend(Column::singles(
COL_MAP.mem_channels[NUM_GP_CHANNELS - 1].value,
));
res.extend(Column::singles_next_row(COL_MAP.mem_channels[0].value));
res
}

Expand Down
11 changes: 2 additions & 9 deletions evm/src/cpu/simple_logic/eq_iszero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,6 @@ pub fn generate_pinv_diff<F: Field>(val0: U256, val1: U256, lv: &mut CpuColumnsV
let num_unequal_limbs = izip!(val0_limbs, val1_limbs)
.map(|(limb0, limb1)| (limb0 != limb1) as usize)
.sum();
let equal = num_unequal_limbs == 0;

let output = &mut lv.mem_channels[2].value;
output[0] = F::from_bool(equal);
for limb in &mut output[1..] {
*limb = F::ZERO;
}

// Form `diff_pinv`.
// Let `diff = val0 - val1`. Consider `x[i] = diff[i]^-1` if `diff[i] != 0` and 0 otherwise.
Expand All @@ -57,7 +50,7 @@ pub fn eval_packed<P: PackedField>(
let logic = lv.general.logic();
let input0 = lv.mem_channels[0].value;
let input1 = lv.mem_channels[1].value;
let output = lv.mem_channels[2].value;
let output = nv.mem_channels[0].value;

// EQ (0x14) and ISZERO (0x15) are differentiated by their first opcode bit.
let eq_filter = lv.op.eq_iszero * (P::ONES - lv.opcode_bits[0]);
Expand Down Expand Up @@ -117,7 +110,7 @@ pub fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(
let logic = lv.general.logic();
let input0 = lv.mem_channels[0].value;
let input1 = lv.mem_channels[1].value;
let output = lv.mem_channels[2].value;
let output = nv.mem_channels[0].value;

// EQ (0x14) and ISZERO (0x15) are differentiated by their first opcode bit.
let eq_filter = builder.mul_extension(lv.op.eq_iszero, lv.opcode_bits[0]);
Expand Down
4 changes: 2 additions & 2 deletions evm/src/cpu/simple_logic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub fn eval_packed<P: PackedField>(
nv: &CpuColumnsView<P>,
yield_constr: &mut ConstraintConsumer<P>,
) {
not::eval_packed(lv, yield_constr);
not::eval_packed(lv, nv, yield_constr);
eq_iszero::eval_packed(lv, nv, yield_constr);
}

Expand All @@ -24,6 +24,6 @@ pub fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(
nv: &CpuColumnsView<ExtensionTarget<D>>,
yield_constr: &mut RecursiveConstraintConsumer<F, D>,
) {
not::eval_ext_circuit(builder, lv, yield_constr);
not::eval_ext_circuit(builder, lv, nv, yield_constr);
eq_iszero::eval_ext_circuit(builder, lv, nv, yield_constr);
}
7 changes: 4 additions & 3 deletions evm/src/cpu/simple_logic/not.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ use plonky2::iop::ext_target::ExtensionTarget;

use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer};
use crate::cpu::columns::CpuColumnsView;
use crate::cpu::membus::NUM_GP_CHANNELS;

const LIMB_SIZE: usize = 32;
const ALL_1_LIMB: u64 = (1 << LIMB_SIZE) - 1;

pub fn eval_packed<P: PackedField>(
lv: &CpuColumnsView<P>,
nv: &CpuColumnsView<P>,
yield_constr: &mut ConstraintConsumer<P>,
) {
// This is simple: just do output = 0xffffffff - input.
let input = lv.mem_channels[0].value;
let output = lv.mem_channels[NUM_GP_CHANNELS - 1].value;
let output = nv.mem_channels[0].value;
let filter = lv.op.not;
for (input_limb, output_limb) in input.into_iter().zip(output) {
yield_constr.constraint(
Expand All @@ -29,10 +29,11 @@ pub fn eval_packed<P: PackedField>(
pub fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(
builder: &mut plonky2::plonk::circuit_builder::CircuitBuilder<F, D>,
lv: &CpuColumnsView<ExtensionTarget<D>>,
nv: &CpuColumnsView<ExtensionTarget<D>>,
yield_constr: &mut RecursiveConstraintConsumer<F, D>,
) {
let input = lv.mem_channels[0].value;
let output = lv.mem_channels[NUM_GP_CHANNELS - 1].value;
let output = nv.mem_channels[0].value;
let filter = lv.op.not;
for (input_limb, output_limb) in input.into_iter().zip(output) {
let constr = builder.add_extension(output_limb, input_limb);
Expand Down
47 changes: 0 additions & 47 deletions evm/src/cpu/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,39 +17,33 @@ use crate::memory::segments::Segment;
pub(crate) struct StackBehavior {
pub(crate) num_pops: usize,
pub(crate) pushes: bool,
new_top_stack_channel: Option<usize>,
disable_other_channels: bool,
}

const BASIC_BINARY_OP: Option<StackBehavior> = Some(StackBehavior {
num_pops: 2,
pushes: true,
new_top_stack_channel: Some(NUM_GP_CHANNELS - 1),
disable_other_channels: true,
});
const BASIC_TERNARY_OP: Option<StackBehavior> = Some(StackBehavior {
num_pops: 3,
pushes: true,
new_top_stack_channel: Some(NUM_GP_CHANNELS - 1),
disable_other_channels: true,
});
pub(crate) const JUMP_OP: Option<StackBehavior> = Some(StackBehavior {
num_pops: 1,
pushes: false,
new_top_stack_channel: None,
disable_other_channels: false,
});
pub(crate) const JUMPI_OP: Option<StackBehavior> = Some(StackBehavior {
num_pops: 2,
pushes: false,
new_top_stack_channel: None,
disable_other_channels: false,
});

pub(crate) const MLOAD_GENERAL_OP: Option<StackBehavior> = Some(StackBehavior {
num_pops: 3,
pushes: true,
new_top_stack_channel: None,
disable_other_channels: false,
});

Expand All @@ -67,99 +61,84 @@ pub(crate) const STACK_BEHAVIORS: OpsColumnsView<Option<StackBehavior>> = OpsCol
not: Some(StackBehavior {
num_pops: 1,
pushes: true,
new_top_stack_channel: Some(NUM_GP_CHANNELS - 1),
disable_other_channels: true,
}),
shift: Some(StackBehavior {
num_pops: 2,
pushes: true,
new_top_stack_channel: Some(NUM_GP_CHANNELS - 1),
disable_other_channels: false,
}),
keccak_general: Some(StackBehavior {
num_pops: 4,
pushes: true,
new_top_stack_channel: Some(NUM_GP_CHANNELS - 1),
disable_other_channels: true,
}),
prover_input: None, // TODO
pop: Some(StackBehavior {
num_pops: 1,
pushes: false,
new_top_stack_channel: None,
disable_other_channels: true,
}),
jumps: None, // Depends on whether it's a JUMP or a JUMPI.
pc: Some(StackBehavior {
num_pops: 0,
pushes: true,
new_top_stack_channel: None,
disable_other_channels: true,
}),
jumpdest: Some(StackBehavior {
num_pops: 0,
pushes: false,
new_top_stack_channel: None,
disable_other_channels: true,
}),
push0: Some(StackBehavior {
num_pops: 0,
pushes: true,
new_top_stack_channel: None,
disable_other_channels: true,
}),
push: None, // TODO
dup_swap: None,
get_context: Some(StackBehavior {
num_pops: 0,
pushes: true,
new_top_stack_channel: None,
disable_other_channels: true,
}),
set_context: None, // SET_CONTEXT is special since it involves the old and the new stack.
mload_32bytes: Some(StackBehavior {
num_pops: 4,
pushes: true,
new_top_stack_channel: Some(4),
disable_other_channels: false,
}),
mstore_32bytes: Some(StackBehavior {
num_pops: 5,
pushes: false,
new_top_stack_channel: None,
disable_other_channels: false,
}),
exit_kernel: Some(StackBehavior {
num_pops: 1,
pushes: false,
new_top_stack_channel: None,
disable_other_channels: true,
}),
m_op_general: None,
syscall: Some(StackBehavior {
num_pops: 0,
pushes: true,
new_top_stack_channel: None,
disable_other_channels: false,
}),
exception: Some(StackBehavior {
num_pops: 0,
pushes: true,
new_top_stack_channel: None,
disable_other_channels: false,
}),
};

pub(crate) const EQ_STACK_BEHAVIOR: Option<StackBehavior> = Some(StackBehavior {
num_pops: 2,
pushes: true,
new_top_stack_channel: Some(2),
disable_other_channels: true,
});
pub(crate) const IS_ZERO_STACK_BEHAVIOR: Option<StackBehavior> = Some(StackBehavior {
num_pops: 1,
pushes: true,
new_top_stack_channel: Some(2),
disable_other_channels: true,
});

Expand Down Expand Up @@ -256,18 +235,6 @@ pub(crate) fn eval_packed_one<P: PackedField>(
}
}

// Maybe constrain next stack_top.
// These are transition constraints: they don't apply to the last row.
if let Some(next_top_ch) = stack_behavior.new_top_stack_channel {
for (limb_ch, limb_top) in lv.mem_channels[next_top_ch]
.value
.iter()
.zip(nv.mem_channels[0].value.iter())
{
yield_constr.constraint_transition(filter * (*limb_ch - *limb_top));
}
}

// Unused channels
if stack_behavior.disable_other_channels {
// The first channel contains (or not) the top od the stack and is constrained elsewhere.
Expand Down Expand Up @@ -478,20 +445,6 @@ pub(crate) fn eval_ext_circuit_one<F: RichField + Extendable<D>, const D: usize>
}
}

// Maybe constrain next stack_top.
// These are transition constraints: they don't apply to the last row.
if let Some(next_top_ch) = stack_behavior.new_top_stack_channel {
for (limb_ch, limb_top) in lv.mem_channels[next_top_ch]
.value
.iter()
.zip(nv.mem_channels[0].value.iter())
{
let diff = builder.sub_extension(*limb_ch, *limb_top);
let constr = builder.mul_extension(filter, diff);
yield_constr.constraint_transition(builder, constr);
}
}

// Unused channels
if stack_behavior.disable_other_channels {
// The first channel contains (or not) the top od the stack and is constrained elsewhere.
Expand Down
Loading

0 comments on commit 666a155

Please sign in to comment.