mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-03 06:13:07 +00:00
commit
23bc390a83
@ -41,6 +41,7 @@ pub struct OpsColumnsView<T: Copy> {
|
||||
pub jumpi: T, // Note: This column must be 0 when is_cpu_cycle = 0.
|
||||
pub pc: T,
|
||||
pub jumpdest: T,
|
||||
pub push0: T,
|
||||
pub push: T,
|
||||
pub dup: T,
|
||||
pub swap: T,
|
||||
|
||||
@ -8,7 +8,7 @@ use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer
|
||||
use crate::cpu::columns::{CpuColumnsView, COL_MAP};
|
||||
use crate::cpu::kernel::aggregator::KERNEL;
|
||||
|
||||
const NATIVE_INSTRUCTIONS: [usize; 31] = [
|
||||
const NATIVE_INSTRUCTIONS: [usize; 32] = [
|
||||
COL_MAP.op.add,
|
||||
COL_MAP.op.mul,
|
||||
COL_MAP.op.sub,
|
||||
@ -36,6 +36,7 @@ const NATIVE_INSTRUCTIONS: [usize; 31] = [
|
||||
// not JUMPI (possible need to jump)
|
||||
COL_MAP.op.pc,
|
||||
COL_MAP.op.jumpdest,
|
||||
COL_MAP.op.push0,
|
||||
// not PUSH (need to increment by more than 1)
|
||||
COL_MAP.op.dup,
|
||||
COL_MAP.op.swap,
|
||||
|
||||
@ -14,7 +14,7 @@ use crate::cpu::columns::{CpuColumnsView, COL_MAP, NUM_CPU_COLUMNS};
|
||||
use crate::cpu::membus::NUM_GP_CHANNELS;
|
||||
use crate::cpu::{
|
||||
bootstrap_kernel, contextops, control_flow, decode, dup_swap, exceptions, gas, jumps, membus,
|
||||
memio, modfp254, pc, shift, simple_logic, stack, stack_bounds, syscalls,
|
||||
memio, modfp254, pc, push0, shift, simple_logic, stack, stack_bounds, syscalls,
|
||||
};
|
||||
use crate::cross_table_lookup::{Column, TableWithColumns};
|
||||
use crate::memory::segments::Segment;
|
||||
@ -197,6 +197,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Stark<F, D> for CpuStark<F, D
|
||||
memio::eval_packed(local_values, yield_constr);
|
||||
modfp254::eval_packed(local_values, yield_constr);
|
||||
pc::eval_packed(local_values, yield_constr);
|
||||
push0::eval_packed(local_values, yield_constr);
|
||||
shift::eval_packed(local_values, yield_constr);
|
||||
simple_logic::eval_packed(local_values, yield_constr);
|
||||
stack::eval_packed(local_values, yield_constr);
|
||||
@ -224,6 +225,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Stark<F, D> for CpuStark<F, D
|
||||
memio::eval_ext_circuit(builder, local_values, yield_constr);
|
||||
modfp254::eval_ext_circuit(builder, local_values, yield_constr);
|
||||
pc::eval_ext_circuit(builder, local_values, yield_constr);
|
||||
push0::eval_ext_circuit(builder, local_values, yield_constr);
|
||||
shift::eval_ext_circuit(builder, local_values, yield_constr);
|
||||
simple_logic::eval_ext_circuit(builder, local_values, yield_constr);
|
||||
stack::eval_ext_circuit(builder, local_values, yield_constr);
|
||||
|
||||
@ -22,7 +22,7 @@ use crate::cpu::columns::{CpuColumnsView, COL_MAP};
|
||||
/// behavior.
|
||||
/// Note: invalid opcodes are not represented here. _Any_ opcode is permitted to decode to
|
||||
/// `is_invalid`. The kernel then verifies that the opcode was _actually_ invalid.
|
||||
const OPCODES: [(u8, usize, bool, usize); 36] = [
|
||||
const OPCODES: [(u8, usize, bool, usize); 37] = [
|
||||
// (start index of block, number of top bits to check (log2), kernel-only, flag column)
|
||||
(0x01, 0, false, COL_MAP.op.add),
|
||||
(0x02, 0, false, COL_MAP.op.mul),
|
||||
@ -52,6 +52,7 @@ const OPCODES: [(u8, usize, bool, usize); 36] = [
|
||||
(0x57, 0, false, COL_MAP.op.jumpi),
|
||||
(0x58, 0, false, COL_MAP.op.pc),
|
||||
(0x5b, 0, false, COL_MAP.op.jumpdest),
|
||||
(0x5f, 0, false, COL_MAP.op.push0),
|
||||
(0x60, 5, false, COL_MAP.op.push), // 0x60-0x7f
|
||||
(0x80, 4, false, COL_MAP.op.dup), // 0x80-0x8f
|
||||
(0x90, 4, false, COL_MAP.op.swap), // 0x90-0x9f
|
||||
|
||||
@ -47,6 +47,7 @@ const SIMPLE_OPCODES: OpsColumnsView<Option<u32>> = OpsColumnsView {
|
||||
jumpi: G_HIGH,
|
||||
pc: G_BASE,
|
||||
jumpdest: G_JUMPDEST,
|
||||
push0: G_BASE,
|
||||
push: G_VERYLOW,
|
||||
dup: G_VERYLOW,
|
||||
swap: G_VERYLOW,
|
||||
|
||||
@ -227,11 +227,11 @@ min_stack_len_for_opcode:
|
||||
BYTES 0 // 0x59, MSIZE
|
||||
BYTES 0 // 0x5a, GAS
|
||||
BYTES 0 // 0x5b, JUMPDEST
|
||||
%rep 4 // 0x5c-0x5f, invalid
|
||||
%rep 3 // 0x5c-0x5e, invalid
|
||||
BYTES 0
|
||||
%endrep
|
||||
|
||||
%rep 32 // 0x60-0x7f, PUSH1-PUSH32
|
||||
%rep 33 // 0x5f-0x7f, PUSH0-PUSH32
|
||||
BYTES 0
|
||||
%endrep
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@ pub const STACK_LENGTH_INCREASING_OPCODES_USER: U256 = u256_from_set_index_range
|
||||
0x3d..=0x3d, // RETURNDATASIZE
|
||||
0x41..=0x48, // COINBASE, TIMESTAMP, NUMBER, DIFFICULTY, GASLIMIT, CHAINID, SELFBALANCE, BASEFEE
|
||||
0x58..=0x5a, // PC, MSIZE, GAS
|
||||
0x60..=0x8f, // PUSH*, DUP*
|
||||
0x5f..=0x8f, // PUSH*, DUP*
|
||||
]);
|
||||
|
||||
pub const INVALID_OPCODES_USER: U256 = u256_from_set_index_ranges([
|
||||
@ -45,7 +45,7 @@ pub const INVALID_OPCODES_USER: U256 = u256_from_set_index_ranges([
|
||||
0x1e..=0x1f,
|
||||
0x21..=0x2f,
|
||||
0x49..=0x4f,
|
||||
0x5c..=0x5f,
|
||||
0x5c..=0x5e,
|
||||
0xa5..=0xef,
|
||||
0xf6..=0xf9,
|
||||
0xfb..=0xfc,
|
||||
|
||||
@ -369,7 +369,7 @@ impl<'a> Interpreter<'a> {
|
||||
0x59 => self.run_msize(), // "MSIZE",
|
||||
0x5a => todo!(), // "GAS",
|
||||
0x5b => self.run_jumpdest(), // "JUMPDEST",
|
||||
x if (0x60..0x80).contains(&x) => self.run_push(x - 0x5f), // "PUSH"
|
||||
x if (0x5f..0x80).contains(&x) => self.run_push(x - 0x5f), // "PUSH"
|
||||
x if (0x80..0x90).contains(&x) => self.run_dup(x - 0x7f), // "DUP"
|
||||
x if (0x90..0xa0).contains(&x) => self.run_swap(x - 0x8f)?, // "SWAP"
|
||||
0xa0 => todo!(), // "LOG0",
|
||||
@ -1189,6 +1189,7 @@ fn get_mnemonic(opcode: u8) -> &'static str {
|
||||
0x59 => "MSIZE",
|
||||
0x5a => "GAS",
|
||||
0x5b => "JUMPDEST",
|
||||
0x5f => "PUSH0",
|
||||
0x60 => "PUSH1",
|
||||
0x61 => "PUSH2",
|
||||
0x62 => "PUSH3",
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
/// The opcode of the `PUSH[n]` instruction, given a byte count `n`.
|
||||
pub fn get_push_opcode(n: u8) -> u8 {
|
||||
assert!(n > 0);
|
||||
assert!(n <= 32);
|
||||
0x60 + n - 1
|
||||
0x5f + n
|
||||
}
|
||||
|
||||
/// The opcode of a standard instruction (not a `PUSH`).
|
||||
|
||||
@ -26,7 +26,7 @@ where
|
||||
}
|
||||
|
||||
pub(crate) fn u256_to_trimmed_be_bytes(u256: &U256) -> Vec<u8> {
|
||||
let num_bytes = ceil_div_usize(u256.bits(), 8).max(1);
|
||||
let num_bytes = ceil_div_usize(u256.bits(), 8);
|
||||
// `byte` is little-endian, so we manually reverse it.
|
||||
(0..num_bytes).rev().map(|i| u256.byte(i)).collect()
|
||||
}
|
||||
@ -60,7 +60,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn literal_to_be_bytes() {
|
||||
assert_eq!(u256_to_trimmed_be_bytes(&0.into()), vec![0x00]);
|
||||
assert_eq!(u256_to_trimmed_be_bytes(&0.into()), Vec::<u8>::new());
|
||||
|
||||
assert_eq!(u256_to_trimmed_be_bytes(&1.into()), vec![0x01]);
|
||||
|
||||
assert_eq!(u256_to_trimmed_be_bytes(&768.into()), vec![0x03, 0x00]);
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@ pub(crate) mod membus;
|
||||
mod memio;
|
||||
mod modfp254;
|
||||
mod pc;
|
||||
mod push0;
|
||||
mod shift;
|
||||
pub(crate) mod simple_logic;
|
||||
mod stack;
|
||||
|
||||
32
evm/src/cpu/push0.rs
Normal file
32
evm/src/cpu/push0.rs
Normal file
@ -0,0 +1,32 @@
|
||||
use plonky2::field::extension::Extendable;
|
||||
use plonky2::field::packed::PackedField;
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::iop::ext_target::ExtensionTarget;
|
||||
|
||||
use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer};
|
||||
use crate::cpu::columns::CpuColumnsView;
|
||||
use crate::cpu::membus::NUM_GP_CHANNELS;
|
||||
|
||||
pub fn eval_packed<P: PackedField>(
|
||||
lv: &CpuColumnsView<P>,
|
||||
yield_constr: &mut ConstraintConsumer<P>,
|
||||
) {
|
||||
let filter = lv.op.push0;
|
||||
let push_value = lv.mem_channels[NUM_GP_CHANNELS - 1].value;
|
||||
for limb in push_value {
|
||||
yield_constr.constraint(filter * limb);
|
||||
}
|
||||
}
|
||||
|
||||
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>>,
|
||||
yield_constr: &mut RecursiveConstraintConsumer<F, D>,
|
||||
) {
|
||||
let filter = lv.op.push0;
|
||||
let push_value = lv.mem_channels[NUM_GP_CHANNELS - 1].value;
|
||||
for limb in push_value {
|
||||
let constr = builder.mul_extension(filter, limb);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
}
|
||||
@ -97,6 +97,11 @@ const STACK_BEHAVIORS: OpsColumnsView<Option<StackBehavior>> = OpsColumnsView {
|
||||
pushes: false,
|
||||
disable_other_channels: true,
|
||||
}),
|
||||
push0: Some(StackBehavior {
|
||||
num_pops: 0,
|
||||
pushes: true,
|
||||
disable_other_channels: true,
|
||||
}),
|
||||
push: None, // TODO
|
||||
dup: None,
|
||||
swap: None,
|
||||
|
||||
@ -38,7 +38,8 @@ pub(crate) fn gas_to_charge(op: Operation) -> u64 {
|
||||
Jumpi => G_HIGH,
|
||||
Pc => G_BASE,
|
||||
Jumpdest => G_JUMPDEST,
|
||||
Push(_) => G_VERYLOW,
|
||||
Push(0) => G_BASE,
|
||||
Push(1..) => G_VERYLOW,
|
||||
Dup(_) => G_VERYLOW,
|
||||
Swap(_) => G_VERYLOW,
|
||||
GetContext => KERNEL_ONLY_INSTR,
|
||||
|
||||
@ -335,7 +335,7 @@ pub(crate) fn generate_push<F: Field>(
|
||||
mut row: CpuColumnsView<F>,
|
||||
) -> Result<(), ProgramError> {
|
||||
let code_context = state.registers.code_context();
|
||||
let num_bytes = n as usize + 1;
|
||||
let num_bytes = n as usize;
|
||||
let initial_offset = state.registers.program_counter + 1;
|
||||
|
||||
// First read val without going through `mem_read_with_log` type methods, so we can pass it
|
||||
|
||||
@ -113,7 +113,7 @@ fn decode(registers: RegistersState, opcode: u8) -> Result<Operation, ProgramErr
|
||||
(0x59, _) => Ok(Operation::Syscall(opcode, 0, true)), // MSIZE
|
||||
(0x5a, _) => Ok(Operation::Syscall(opcode, 0, true)), // GAS
|
||||
(0x5b, _) => Ok(Operation::Jumpdest),
|
||||
(0x60..=0x7f, _) => Ok(Operation::Push(opcode & 0x1f)),
|
||||
(0x5f..=0x7f, _) => Ok(Operation::Push(opcode - 0x5f)),
|
||||
(0x80..=0x8f, _) => Ok(Operation::Dup(opcode & 0xf)),
|
||||
(0x90..=0x9f, _) => Ok(Operation::Swap(opcode & 0xf)),
|
||||
(0xa0, _) => Ok(Operation::Syscall(opcode, 2, false)), // LOG0
|
||||
@ -152,7 +152,8 @@ fn decode(registers: RegistersState, opcode: u8) -> Result<Operation, ProgramErr
|
||||
fn fill_op_flag<F: Field>(op: Operation, row: &mut CpuColumnsView<F>) {
|
||||
let flags = &mut row.op;
|
||||
*match op {
|
||||
Operation::Push(_) => &mut flags.push,
|
||||
Operation::Push(0) => &mut flags.push0,
|
||||
Operation::Push(1..) => &mut flags.push,
|
||||
Operation::Dup(_) => &mut flags.dup,
|
||||
Operation::Swap(_) => &mut flags.swap,
|
||||
Operation::Iszero => &mut flags.iszero,
|
||||
@ -231,7 +232,7 @@ fn perform_op<F: Field>(
|
||||
|
||||
state.registers.program_counter += match op {
|
||||
Operation::Syscall(_, _, _) | Operation::ExitKernel => 0,
|
||||
Operation::Push(n) => n as usize + 2,
|
||||
Operation::Push(n) => n as usize + 1,
|
||||
Operation::Jump | Operation::Jumpi => 0,
|
||||
_ => 1,
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user