mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-03 14:23:07 +00:00
Combine get_context and set_context into one flag
This commit is contained in:
parent
f6f9fa3197
commit
c3cb227896
@ -40,9 +40,7 @@ pub struct OpsColumnsView<T: Copy> {
|
||||
pub push: T,
|
||||
pub dup: T,
|
||||
pub swap: T,
|
||||
// TODO: combine GET_CONTEXT and SET_CONTEXT into one flag
|
||||
pub get_context: T,
|
||||
pub set_context: T,
|
||||
pub context_op: T,
|
||||
pub exit_kernel: T,
|
||||
// TODO: combine MLOAD_GENERAL and MSTORE_GENERAL into one flag
|
||||
pub mload_general: T,
|
||||
|
||||
@ -15,12 +15,31 @@ fn eval_packed_get<P: PackedField>(
|
||||
lv: &CpuColumnsView<P>,
|
||||
yield_constr: &mut ConstraintConsumer<P>,
|
||||
) {
|
||||
let filter = lv.op.get_context;
|
||||
// If the opcode is GET_CONTEXT, then lv.opcode_bits[0] = 0
|
||||
let filter = lv.op.context_op * (P::ONES - lv.opcode_bits[0]);
|
||||
let push_channel = lv.mem_channels[NUM_GP_CHANNELS - 1];
|
||||
yield_constr.constraint(filter * (push_channel.value[0] - lv.context));
|
||||
for &limb in &push_channel.value[1..] {
|
||||
yield_constr.constraint(filter * limb);
|
||||
}
|
||||
|
||||
// Stack constraints
|
||||
let channel = lv.mem_channels[NUM_GP_CHANNELS - 1];
|
||||
yield_constr.constraint(filter * (channel.used - P::ONES));
|
||||
yield_constr.constraint(filter * channel.is_read);
|
||||
|
||||
yield_constr.constraint(filter * (channel.addr_context - lv.context));
|
||||
yield_constr.constraint(
|
||||
filter * (channel.addr_segment - P::Scalar::from_canonical_u64(Segment::Stack as u64)),
|
||||
);
|
||||
let addr_virtual = lv.stack_len;
|
||||
yield_constr.constraint(filter * (channel.addr_virtual - addr_virtual));
|
||||
|
||||
// Unused channels
|
||||
for i in 0..NUM_GP_CHANNELS - 1 {
|
||||
let channel = lv.mem_channels[i];
|
||||
yield_constr.constraint(filter * channel.used);
|
||||
}
|
||||
}
|
||||
|
||||
fn eval_ext_circuit_get<F: RichField + Extendable<D>, const D: usize>(
|
||||
@ -28,7 +47,11 @@ fn eval_ext_circuit_get<F: RichField + Extendable<D>, const D: usize>(
|
||||
lv: &CpuColumnsView<ExtensionTarget<D>>,
|
||||
yield_constr: &mut RecursiveConstraintConsumer<F, D>,
|
||||
) {
|
||||
let filter = lv.op.get_context;
|
||||
let mut filter = lv.op.context_op;
|
||||
let one = builder.one_extension();
|
||||
let minus = builder.sub_extension(one, lv.opcode_bits[0]);
|
||||
filter = builder.mul_extension(filter, minus);
|
||||
|
||||
let push_channel = lv.mem_channels[NUM_GP_CHANNELS - 1];
|
||||
{
|
||||
let diff = builder.sub_extension(push_channel.value[0], lv.context);
|
||||
@ -39,6 +62,45 @@ fn eval_ext_circuit_get<F: RichField + Extendable<D>, const D: usize>(
|
||||
let constr = builder.mul_extension(filter, limb);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
|
||||
// Stack constraints
|
||||
let channel = lv.mem_channels[NUM_GP_CHANNELS - 1];
|
||||
|
||||
{
|
||||
let constr = builder.mul_sub_extension(filter, channel.used, filter);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
{
|
||||
let constr = builder.mul_extension(filter, channel.is_read);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
|
||||
{
|
||||
let diff = builder.sub_extension(channel.addr_context, lv.context);
|
||||
let constr = builder.mul_extension(filter, diff);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
{
|
||||
let constr = builder.arithmetic_extension(
|
||||
F::ONE,
|
||||
-F::from_canonical_u64(Segment::Stack as u64),
|
||||
filter,
|
||||
channel.addr_segment,
|
||||
filter,
|
||||
);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
{
|
||||
let diff = builder.sub_extension(channel.addr_virtual, lv.stack_len);
|
||||
let constr = builder.arithmetic_extension(F::ONE, F::ZERO, filter, diff, filter);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
|
||||
for i in 0..NUM_GP_CHANNELS - 1 {
|
||||
let channel = lv.mem_channels[i];
|
||||
let constr = builder.mul_extension(filter, channel.used);
|
||||
yield_constr.constraint(builder, constr);
|
||||
}
|
||||
}
|
||||
|
||||
fn eval_packed_set<P: PackedField>(
|
||||
@ -46,7 +108,7 @@ fn eval_packed_set<P: PackedField>(
|
||||
nv: &CpuColumnsView<P>,
|
||||
yield_constr: &mut ConstraintConsumer<P>,
|
||||
) {
|
||||
let filter = lv.op.set_context;
|
||||
let filter = lv.op.context_op * lv.opcode_bits[0];
|
||||
let pop_channel = lv.mem_channels[0];
|
||||
let write_old_sp_channel = lv.mem_channels[1];
|
||||
let read_new_sp_channel = lv.mem_channels[2];
|
||||
@ -94,7 +156,8 @@ fn eval_ext_circuit_set<F: RichField + Extendable<D>, const D: usize>(
|
||||
nv: &CpuColumnsView<ExtensionTarget<D>>,
|
||||
yield_constr: &mut RecursiveConstraintConsumer<F, D>,
|
||||
) {
|
||||
let filter = lv.op.set_context;
|
||||
let mut filter = lv.op.context_op;
|
||||
filter = builder.mul_extension(filter, lv.opcode_bits[0]);
|
||||
let pop_channel = lv.mem_channels[0];
|
||||
let write_old_sp_channel = lv.mem_channels[1];
|
||||
let read_new_sp_channel = lv.mem_channels[2];
|
||||
|
||||
@ -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; 29] = [
|
||||
const NATIVE_INSTRUCTIONS: [usize; 28] = [
|
||||
COL_MAP.op.add,
|
||||
COL_MAP.op.mul,
|
||||
COL_MAP.op.sub,
|
||||
@ -37,8 +37,7 @@ const NATIVE_INSTRUCTIONS: [usize; 29] = [
|
||||
// not PUSH (need to increment by more than 1)
|
||||
COL_MAP.op.dup,
|
||||
COL_MAP.op.swap,
|
||||
COL_MAP.op.get_context,
|
||||
COL_MAP.op.set_context,
|
||||
COL_MAP.op.context_op,
|
||||
// not EXIT_KERNEL (performs a jump)
|
||||
COL_MAP.op.mload_general,
|
||||
COL_MAP.op.mstore_general,
|
||||
|
||||
@ -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); 32] = [
|
||||
const OPCODES: [(u8, usize, bool, usize); 31] = [
|
||||
// (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),
|
||||
@ -49,11 +49,10 @@ const OPCODES: [(u8, usize, bool, usize); 32] = [
|
||||
(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
|
||||
(0xf6, 0, true, COL_MAP.op.get_context),
|
||||
(0xf7, 0, true, COL_MAP.op.set_context),
|
||||
(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
|
||||
(0xf6, 1, true, COL_MAP.op.context_op), // 0xf6-0xf7
|
||||
(0xf9, 0, true, COL_MAP.op.exit_kernel),
|
||||
(0xfb, 0, true, COL_MAP.op.mload_general),
|
||||
(0xfc, 0, true, COL_MAP.op.mstore_general),
|
||||
|
||||
@ -48,8 +48,7 @@ const SIMPLE_OPCODES: OpsColumnsView<Option<u32>> = OpsColumnsView {
|
||||
push: G_VERYLOW,
|
||||
dup: G_VERYLOW,
|
||||
swap: G_VERYLOW,
|
||||
get_context: KERNEL_ONLY_INSTR,
|
||||
set_context: KERNEL_ONLY_INSTR,
|
||||
context_op: KERNEL_ONLY_INSTR,
|
||||
exit_kernel: None,
|
||||
mload_general: KERNEL_ONLY_INSTR,
|
||||
mstore_general: KERNEL_ONLY_INSTR,
|
||||
|
||||
@ -107,12 +107,7 @@ const STACK_BEHAVIORS: OpsColumnsView<Option<StackBehavior>> = OpsColumnsView {
|
||||
push: None, // TODO
|
||||
dup: None,
|
||||
swap: None,
|
||||
get_context: Some(StackBehavior {
|
||||
num_pops: 0,
|
||||
pushes: true,
|
||||
disable_other_channels: true,
|
||||
}),
|
||||
set_context: None, // SET_CONTEXT is special since it involves the old and the new stack.
|
||||
context_op: None, // SET_CONTEXT is special since it involves the old and the new stack.
|
||||
exit_kernel: Some(StackBehavior {
|
||||
num_pops: 1,
|
||||
pushes: false,
|
||||
|
||||
@ -42,8 +42,7 @@ pub(crate) fn gas_to_charge(op: Operation) -> u64 {
|
||||
Push(1..) => G_VERYLOW,
|
||||
Dup(_) => G_VERYLOW,
|
||||
Swap(_) => G_VERYLOW,
|
||||
GetContext => KERNEL_ONLY_INSTR,
|
||||
SetContext => KERNEL_ONLY_INSTR,
|
||||
ContextOp(_) => KERNEL_ONLY_INSTR,
|
||||
ExitKernel => KERNEL_ONLY_INSTR,
|
||||
MloadGeneral => KERNEL_ONLY_INSTR,
|
||||
MstoreGeneral => KERNEL_ONLY_INSTR,
|
||||
|
||||
@ -45,8 +45,7 @@ pub(crate) enum Operation {
|
||||
Push(u8),
|
||||
Dup(u8),
|
||||
Swap(u8),
|
||||
GetContext,
|
||||
SetContext,
|
||||
ContextOp(bool),
|
||||
ExitKernel,
|
||||
MloadGeneral,
|
||||
MstoreGeneral,
|
||||
@ -293,6 +292,19 @@ pub(crate) fn generate_jumpdest<F: Field>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn generate_context_op<F: Field>(
|
||||
is_set: bool,
|
||||
state: &mut GenerationState<F>,
|
||||
row: CpuColumnsView<F>,
|
||||
) -> Result<(), ProgramError> {
|
||||
// SET_CONTEXT uses mem_channels[0..=2]
|
||||
if is_set {
|
||||
generate_set_context(state, row)
|
||||
} else {
|
||||
generate_get_context(state, row)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn generate_get_context<F: Field>(
|
||||
state: &mut GenerationState<F>,
|
||||
mut row: CpuColumnsView<F>,
|
||||
|
||||
@ -134,8 +134,8 @@ fn decode(registers: RegistersState, opcode: u8) -> Result<Operation, ProgramErr
|
||||
(0xf3, _) => Ok(Operation::Syscall(opcode, 2, false)), // RETURN
|
||||
(0xf4, _) => Ok(Operation::Syscall(opcode, 6, false)), // DELEGATECALL
|
||||
(0xf5, _) => Ok(Operation::Syscall(opcode, 4, false)), // CREATE2
|
||||
(0xf6, true) => Ok(Operation::GetContext),
|
||||
(0xf7, true) => Ok(Operation::SetContext),
|
||||
(0xf6, true) => Ok(Operation::ContextOp(false)), // GET_CONTEXT
|
||||
(0xf7, true) => Ok(Operation::ContextOp(true)), // SET_CONTEXT
|
||||
(0xf9, true) => Ok(Operation::ExitKernel),
|
||||
(0xfa, _) => Ok(Operation::Syscall(opcode, 6, false)), // STATICCALL
|
||||
(0xfb, true) => Ok(Operation::MloadGeneral),
|
||||
@ -182,8 +182,7 @@ fn fill_op_flag<F: Field>(op: Operation, row: &mut CpuColumnsView<F>) {
|
||||
Operation::Jump | Operation::Jumpi => &mut flags.jumps,
|
||||
Operation::Pc => &mut flags.pc,
|
||||
Operation::Jumpdest => &mut flags.jumpdest,
|
||||
Operation::GetContext => &mut flags.get_context,
|
||||
Operation::SetContext => &mut flags.set_context,
|
||||
Operation::ContextOp(_) => &mut flags.context_op,
|
||||
Operation::ExitKernel => &mut flags.exit_kernel,
|
||||
Operation::MloadGeneral => &mut flags.mload_general,
|
||||
Operation::MstoreGeneral => &mut flags.mstore_general,
|
||||
@ -219,8 +218,7 @@ fn perform_op<F: Field>(
|
||||
Operation::Jumpi => generate_jumpi(state, row)?,
|
||||
Operation::Pc => generate_pc(state, row)?,
|
||||
Operation::Jumpdest => generate_jumpdest(state, row)?,
|
||||
Operation::GetContext => generate_get_context(state, row)?,
|
||||
Operation::SetContext => generate_set_context(state, row)?,
|
||||
Operation::ContextOp(is_set) => generate_context_op(is_set, state, row)?,
|
||||
Operation::ExitKernel => generate_exit_kernel(state, row)?,
|
||||
Operation::MloadGeneral => generate_mload_general(state, row)?,
|
||||
Operation::MstoreGeneral => generate_mstore_general(state, row)?,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user