From ec3391f9c4e14055e811697dae957e6c85631639 Mon Sep 17 00:00:00 2001 From: Jacqueline Nabaglo Date: Thu, 13 Oct 2022 14:02:19 -0700 Subject: [PATCH] Add Fp254 ops to the CPU table (#779) * Add Fp254 ops to the CPU table * Add forgotten file --- evm/src/cpu/columns/ops.rs | 3 ++ evm/src/cpu/control_flow.rs | 5 ++- evm/src/cpu/cpu_stark.rs | 4 ++- evm/src/cpu/decode.rs | 5 ++- evm/src/cpu/kernel/interpreter.rs | 3 ++ evm/src/cpu/kernel/opcodes.rs | 3 ++ evm/src/cpu/mod.rs | 1 + evm/src/cpu/modfp254.rs | 53 +++++++++++++++++++++++++++++++ evm/src/cpu/stack.rs | 3 ++ 9 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 evm/src/cpu/modfp254.rs diff --git a/evm/src/cpu/columns/ops.rs b/evm/src/cpu/columns/ops.rs index e0cb2952..04d4d0f2 100644 --- a/evm/src/cpu/columns/ops.rs +++ b/evm/src/cpu/columns/ops.rs @@ -19,6 +19,9 @@ pub struct OpsColumnsView { pub mulmod: T, pub exp: T, pub signextend: T, + pub addfp254: T, + pub mulfp254: T, + pub subfp254: T, pub lt: T, pub gt: T, pub slt: T, diff --git a/evm/src/cpu/control_flow.rs b/evm/src/cpu/control_flow.rs index 3856726c..c7b7c6bb 100644 --- a/evm/src/cpu/control_flow.rs +++ b/evm/src/cpu/control_flow.rs @@ -9,7 +9,7 @@ use crate::cpu::columns::{CpuColumnsView, COL_MAP}; use crate::cpu::kernel::aggregator::KERNEL; // TODO: This list is incomplete. -const NATIVE_INSTRUCTIONS: [usize; 25] = [ +const NATIVE_INSTRUCTIONS: [usize; 28] = [ COL_MAP.op.add, COL_MAP.op.mul, COL_MAP.op.sub, @@ -20,6 +20,9 @@ const NATIVE_INSTRUCTIONS: [usize; 25] = [ COL_MAP.op.addmod, COL_MAP.op.mulmod, COL_MAP.op.signextend, + COL_MAP.op.addfp254, + COL_MAP.op.mulfp254, + COL_MAP.op.subfp254, COL_MAP.op.lt, COL_MAP.op.gt, COL_MAP.op.slt, diff --git a/evm/src/cpu/cpu_stark.rs b/evm/src/cpu/cpu_stark.rs index b11ff9f5..7b34cc4f 100644 --- a/evm/src/cpu/cpu_stark.rs +++ b/evm/src/cpu/cpu_stark.rs @@ -11,7 +11,7 @@ use plonky2::hash::hash_types::RichField; use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; use crate::cpu::columns::{CpuColumnsView, COL_MAP, NUM_CPU_COLUMNS}; use crate::cpu::{ - bootstrap_kernel, control_flow, decode, dup_swap, jumps, membus, simple_logic, stack, + bootstrap_kernel, control_flow, decode, dup_swap, jumps, membus, modfp254, simple_logic, stack, stack_bounds, syscalls, }; use crate::cross_table_lookup::Column; @@ -150,6 +150,7 @@ impl, const D: usize> Stark for CpuStark, const D: usize> Stark for CpuStark Interpreter<'a> { 0x09 => self.run_mulmod(), // "MULMOD", 0x0a => self.run_exp(), // "EXP", 0x0b => todo!(), // "SIGNEXTEND", + 0x0c => todo!(), // "ADDFP254", + 0x0d => todo!(), // "MULFP254", + 0x0e => todo!(), // "SUBFP254", 0x10 => self.run_lt(), // "LT", 0x11 => self.run_gt(), // "GT", 0x12 => todo!(), // "SLT", diff --git a/evm/src/cpu/kernel/opcodes.rs b/evm/src/cpu/kernel/opcodes.rs index c5133050..20601267 100644 --- a/evm/src/cpu/kernel/opcodes.rs +++ b/evm/src/cpu/kernel/opcodes.rs @@ -20,6 +20,9 @@ pub(crate) fn get_opcode(mnemonic: &str) -> u8 { "MULMOD" => 0x09, "EXP" => 0x0a, "SIGNEXTEND" => 0x0b, + "ADDFP254" => 0x0c, + "MULFP254" => 0x0d, + "SUBFP254" => 0x0e, "LT" => 0x10, "GT" => 0x11, "SLT" => 0x12, diff --git a/evm/src/cpu/mod.rs b/evm/src/cpu/mod.rs index bde06585..fda5db80 100644 --- a/evm/src/cpu/mod.rs +++ b/evm/src/cpu/mod.rs @@ -7,6 +7,7 @@ mod dup_swap; mod jumps; pub mod kernel; pub(crate) mod membus; +mod modfp254; mod simple_logic; mod stack; mod stack_bounds; diff --git a/evm/src/cpu/modfp254.rs b/evm/src/cpu/modfp254.rs new file mode 100644 index 00000000..defbf862 --- /dev/null +++ b/evm/src/cpu/modfp254.rs @@ -0,0 +1,53 @@ +use itertools::izip; +use plonky2::field::extension::Extendable; +use plonky2::field::packed::PackedField; +use plonky2::field::types::Field; +use plonky2::hash::hash_types::RichField; +use plonky2::iop::ext_target::ExtensionTarget; + +use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; +use crate::cpu::columns::CpuColumnsView; + +// Python: +// >>> P = 21888242871839275222246405745257275088696311157297823662689037894645226208583 +// >>> "[" + ", ".join(hex((P >> n) % 2**32) for n in range(0, 256, 32)) + "]" +const P_LIMBS: [u32; 8] = [ + 0xd87cfd47, 0x3c208c16, 0x6871ca8d, 0x97816a91, 0x8181585d, 0xb85045b6, 0xe131a029, 0x30644e72, +]; + +pub fn eval_packed( + lv: &CpuColumnsView

, + yield_constr: &mut ConstraintConsumer

, +) { + let filter = lv.is_cpu_cycle * (lv.op.addfp254 + lv.op.mulfp254 + lv.op.subfp254); + + // We want to use all the same logic as the usual mod operations, but without needing to read + // the modulus from the stack. We simply constrain `mem_channels[2]` to be our prime (that's + // where the modulus goes in the generalized operations). + let channel_val = lv.mem_channels[2].value; + for (channel_limb, p_limb) in izip!(channel_val, P_LIMBS) { + let p_limb = P::Scalar::from_canonical_u32(p_limb); + yield_constr.constraint(filter * (channel_limb - p_limb)); + } +} + +pub fn eval_ext_circuit, const D: usize>( + builder: &mut plonky2::plonk::circuit_builder::CircuitBuilder, + lv: &CpuColumnsView>, + yield_constr: &mut RecursiveConstraintConsumer, +) { + let filter = { + let flag_sum = builder.add_many_extension([lv.op.addfp254, lv.op.mulfp254, lv.op.subfp254]); + builder.mul_extension(lv.is_cpu_cycle, flag_sum) + }; + + // We want to use all the same logic as the usual mod operations, but without needing to read + // the modulus from the stack. We simply constrain `mem_channels[2]` to be our prime (that's + // where the modulus goes in the generalized operations). + let channel_val = lv.mem_channels[2].value; + for (channel_limb, p_limb) in izip!(channel_val, P_LIMBS) { + let p_limb = F::from_canonical_u32(p_limb); + let constr = builder.arithmetic_extension(F::ONE, -p_limb, filter, channel_limb, filter); + yield_constr.constraint(builder, constr); + } +} diff --git a/evm/src/cpu/stack.rs b/evm/src/cpu/stack.rs index 9bc08091..c72688ed 100644 --- a/evm/src/cpu/stack.rs +++ b/evm/src/cpu/stack.rs @@ -52,6 +52,9 @@ const STACK_BEHAVIORS: OpsColumnsView> = OpsColumnsView { mulmod: BASIC_TERNARY_OP, exp: None, // TODO signextend: BASIC_BINARY_OP, + addfp254: BASIC_BINARY_OP, + mulfp254: BASIC_BINARY_OP, + subfp254: BASIC_BINARY_OP, lt: BASIC_BINARY_OP, gt: BASIC_BINARY_OP, slt: BASIC_BINARY_OP,