Flush out operation list

This commit is contained in:
Daniel Lubarov 2022-11-30 21:00:48 -08:00
parent 97ac5c59d6
commit 526dc9bb77
9 changed files with 125 additions and 78 deletions

View File

@ -1,4 +1,8 @@
use ethereum_types::U256;
use std::ops::Mul;
use std::str::FromStr;
use ethereum_types::{U256, U512};
use num::BigUint;
mod add;
mod compare;
@ -21,6 +25,9 @@ pub(crate) enum BinaryOperator {
Gt,
Shl,
Shr,
AddFp254,
MulFp254,
SubFp254,
}
impl BinaryOperator {
@ -47,6 +54,9 @@ impl BinaryOperator {
}
BinaryOperator::Shl => input0 << input1,
BinaryOperator::Shr => input0 >> input1,
BinaryOperator::AddFp254 => addmod(input0, input1, bn_base_order()),
BinaryOperator::MulFp254 => mulmod(input0, input1, bn_base_order()),
BinaryOperator::SubFp254 => submod(input0, input1, bn_base_order()),
}
}
}
@ -60,8 +70,8 @@ pub(crate) enum TernaryOperator {
impl TernaryOperator {
pub(crate) fn result(&self, input0: U256, input1: U256, input2: U256) -> U256 {
match self {
TernaryOperator::AddMod => (input0 + input1) % input2,
TernaryOperator::MulMod => (input0 * input1) % input2,
TernaryOperator::AddMod => addmod(input0, input1, input2),
TernaryOperator::MulMod => mulmod(input0, input1, input2),
}
}
}
@ -117,3 +127,51 @@ impl Operation {
}
}
}
fn addmod(x: U256, y: U256, m: U256) -> U256 {
if m.is_zero() {
return m;
}
let x = to_biguint(x);
let y = to_biguint(y);
let m = to_biguint(m);
from_biguint((x + y) % m)
}
fn mulmod(x: U256, y: U256, m: U256) -> U256 {
if m.is_zero() {
return m;
}
let x = to_biguint(x);
let y = to_biguint(y);
let m = to_biguint(m);
from_biguint(x * y % m)
}
fn submod(x: U256, y: U256, m: U256) -> U256 {
if m.is_zero() {
return m;
}
let mut x = to_biguint(x);
let y = to_biguint(y);
let m = to_biguint(m);
while x < y {
x += &m;
}
from_biguint((x - y) % m)
}
fn to_biguint(x: U256) -> BigUint {
let mut bytes = [0u8; 32];
x.to_little_endian(&mut bytes);
BigUint::from_bytes_le(&bytes)
}
fn from_biguint(x: BigUint) -> U256 {
let bytes = x.to_bytes_le();
U256::from_little_endian(&bytes)
}
fn bn_base_order() -> U256 {
U256::from_str("0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47").unwrap()
}

View File

@ -41,12 +41,6 @@ pub struct OpsColumnsView<T: Copy> {
pub pc: T,
pub gas: T,
pub jumpdest: T,
// TODO: combine GET_STATE_ROOT and SET_STATE_ROOT into one flag
pub get_state_root: T,
pub set_state_root: T,
// TODO: combine GET_RECEIPT_ROOT and SET_RECEIPT_ROOT into one flag
pub get_receipt_root: T,
pub set_receipt_root: T,
pub push: T,
pub dup: T,
pub swap: T,

View File

@ -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; 37] = [
const NATIVE_INSTRUCTIONS: [usize; 33] = [
COL_MAP.op.add,
COL_MAP.op.mul,
COL_MAP.op.sub,
@ -37,10 +37,6 @@ const NATIVE_INSTRUCTIONS: [usize; 37] = [
COL_MAP.op.pc,
COL_MAP.op.gas,
COL_MAP.op.jumpdest,
COL_MAP.op.get_state_root,
COL_MAP.op.set_state_root,
COL_MAP.op.get_receipt_root,
COL_MAP.op.set_receipt_root,
// not PUSH (need to increment by more than 1)
COL_MAP.op.dup,
COL_MAP.op.swap,

View File

@ -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); 42] = [
const OPCODES: [(u8, usize, bool, usize); 38] = [
// (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),
@ -53,10 +53,6 @@ const OPCODES: [(u8, usize, bool, usize); 42] = [
(0x58, 0, false, COL_MAP.op.pc),
(0x5a, 0, false, COL_MAP.op.gas),
(0x5b, 0, false, COL_MAP.op.jumpdest),
(0x5c, 0, true, COL_MAP.op.get_state_root),
(0x5d, 0, true, COL_MAP.op.set_state_root),
(0x5e, 0, true, COL_MAP.op.get_receipt_root),
(0x5f, 0, true, COL_MAP.op.set_receipt_root),
(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

View File

@ -318,10 +318,6 @@ impl<'a> Interpreter<'a> {
0x59 => self.run_msize(), // "MSIZE",
0x5a => todo!(), // "GAS",
0x5b => self.run_jumpdest(), // "JUMPDEST",
0x5c => todo!(), // "GET_STATE_ROOT",
0x5d => todo!(), // "SET_STATE_ROOT",
0x5e => todo!(), // "GET_RECEIPT_ROOT",
0x5f => todo!(), // "SET_RECEIPT_ROOT",
x if (0x60..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"
@ -830,10 +826,6 @@ fn get_mnemonic(opcode: u8) -> &'static str {
0x59 => "MSIZE",
0x5a => "GAS",
0x5b => "JUMPDEST",
0x5c => "GET_STATE_ROOT",
0x5d => "SET_STATE_ROOT",
0x5e => "GET_RECEIPT_ROOT",
0x5f => "SET_RECEIPT_ROOT",
0x60 => "PUSH1",
0x61 => "PUSH2",
0x62 => "PUSH3",

View File

@ -76,10 +76,6 @@ pub(crate) fn get_opcode(mnemonic: &str) -> u8 {
"MSIZE" => 0x59,
"GAS" => 0x5a,
"JUMPDEST" => 0x5b,
"GET_STATE_ROOT" => 0x5c,
"SET_STATE_ROOT" => 0x5d,
"GET_RECEIPT_ROOT" => 0x5e,
"SET_RECEIPT_ROOT" => 0x5f,
"DUP1" => 0x80,
"DUP2" => 0x81,
"DUP3" => 0x82,

View File

@ -61,19 +61,15 @@ const STACK_BEHAVIORS: OpsColumnsView<Option<StackBehavior>> = OpsColumnsView {
byte: BASIC_BINARY_OP,
shl: BASIC_BINARY_OP,
shr: BASIC_BINARY_OP,
keccak_general: None, // TODO
prover_input: None, // TODO
pop: None, // TODO
jump: None, // TODO
jumpi: None, // TODO
pc: None, // TODO
gas: None, // TODO
jumpdest: None, // TODO
get_state_root: None, // TODO
set_state_root: None, // TODO
get_receipt_root: None, // TODO
set_receipt_root: None, // TODO
push: None, // TODO
keccak_general: None, // TODO
prover_input: None, // TODO
pop: None, // TODO
jump: None, // TODO
jumpi: None, // TODO
pc: None, // TODO
gas: None, // TODO
jumpdest: None, // TODO
push: None, // TODO
dup: None,
swap: None,
get_context: None, // TODO

View File

@ -24,13 +24,26 @@ pub(crate) enum Operation {
Swap(u8),
Iszero,
Not,
Byte,
Syscall(u8),
Eq,
ExitKernel,
BinaryLogic(logic::Op),
BinaryArithmetic(arithmetic::BinaryOperator),
TernaryArithmetic(arithmetic::TernaryOperator),
NotImplemented,
KeccakGeneral,
ProverInput,
Pop,
Jump,
Jumpi,
Pc,
Gas,
Jumpdest,
GetContext,
SetContext,
ConsumeGas,
ExitKernel,
MloadGeneral,
MstoreGeneral,
}
pub(crate) fn generate_binary_logic_op<F: Field>(

View File

@ -40,22 +40,32 @@ fn read_code_memory<F: Field>(
fn decode(registers_state: RegistersState, opcode: u8) -> Result<Operation, ProgramError> {
match (opcode, registers_state.is_kernel) {
(0x00, _) => Ok(Operation::Syscall(opcode)),
(0x01, _) => Ok(Operation::NotImplemented),
(0x02, _) => Ok(Operation::NotImplemented),
(0x03, _) => Ok(Operation::NotImplemented),
(0x04, _) => Ok(Operation::NotImplemented),
(0x01, _) => Ok(Operation::BinaryArithmetic(arithmetic::BinaryOperator::Add)),
(0x02, _) => Ok(Operation::BinaryArithmetic(arithmetic::BinaryOperator::Mul)),
(0x03, _) => Ok(Operation::BinaryArithmetic(arithmetic::BinaryOperator::Sub)),
(0x04, _) => Ok(Operation::BinaryArithmetic(arithmetic::BinaryOperator::Div)),
(0x05, _) => Ok(Operation::Syscall(opcode)),
(0x06, _) => Ok(Operation::NotImplemented),
(0x06, _) => Ok(Operation::BinaryArithmetic(arithmetic::BinaryOperator::Mod)),
(0x07, _) => Ok(Operation::Syscall(opcode)),
(0x08, _) => Ok(Operation::NotImplemented),
(0x09, _) => Ok(Operation::NotImplemented),
(0x08, _) => Ok(Operation::TernaryArithmetic(
arithmetic::TernaryOperator::AddMod,
)),
(0x09, _) => Ok(Operation::TernaryArithmetic(
arithmetic::TernaryOperator::MulMod,
)),
(0x0a, _) => Ok(Operation::Syscall(opcode)),
(0x0b, _) => Ok(Operation::Syscall(opcode)),
(0x0c, true) => Ok(Operation::NotImplemented),
(0x0d, true) => Ok(Operation::NotImplemented),
(0x0e, true) => Ok(Operation::NotImplemented),
(0x10, _) => Ok(Operation::NotImplemented),
(0x11, _) => Ok(Operation::NotImplemented),
(0x0c, true) => Ok(Operation::BinaryArithmetic(
arithmetic::BinaryOperator::AddFp254,
)),
(0x0d, true) => Ok(Operation::BinaryArithmetic(
arithmetic::BinaryOperator::MulFp254,
)),
(0x0e, true) => Ok(Operation::BinaryArithmetic(
arithmetic::BinaryOperator::SubFp254,
)),
(0x10, _) => Ok(Operation::BinaryArithmetic(arithmetic::BinaryOperator::Lt)),
(0x11, _) => Ok(Operation::BinaryArithmetic(arithmetic::BinaryOperator::Gt)),
(0x12, _) => Ok(Operation::Syscall(opcode)),
(0x13, _) => Ok(Operation::Syscall(opcode)),
(0x14, _) => Ok(Operation::Eq),
@ -64,12 +74,12 @@ fn decode(registers_state: RegistersState, opcode: u8) -> Result<Operation, Prog
(0x17, _) => Ok(Operation::BinaryLogic(logic::Op::Or)),
(0x18, _) => Ok(Operation::BinaryLogic(logic::Op::Xor)),
(0x19, _) => Ok(Operation::Not),
(0x1a, _) => Ok(Operation::NotImplemented),
(0x1b, _) => Ok(Operation::NotImplemented),
(0x1c, _) => Ok(Operation::NotImplemented),
(0x1a, _) => Ok(Operation::Byte),
(0x1b, _) => Ok(Operation::BinaryArithmetic(arithmetic::BinaryOperator::Shl)),
(0x1c, _) => Ok(Operation::BinaryArithmetic(arithmetic::BinaryOperator::Shr)),
(0x1d, _) => Ok(Operation::Syscall(opcode)),
(0x20, _) => Ok(Operation::Syscall(opcode)),
(0x21, _) => Ok(Operation::NotImplemented),
(0x21, true) => Ok(Operation::KeccakGeneral),
(0x30, _) => Ok(Operation::Syscall(opcode)),
(0x31, _) => Ok(Operation::Syscall(opcode)),
(0x32, _) => Ok(Operation::Syscall(opcode)),
@ -95,23 +105,19 @@ fn decode(registers_state: RegistersState, opcode: u8) -> Result<Operation, Prog
(0x46, _) => Ok(Operation::Syscall(opcode)),
(0x47, _) => Ok(Operation::Syscall(opcode)),
(0x48, _) => Ok(Operation::Syscall(opcode)),
(0x49, _) => Ok(Operation::NotImplemented),
(0x50, _) => Ok(Operation::NotImplemented),
(0x49, _) => Ok(Operation::ProverInput),
(0x50, _) => Ok(Operation::Pop),
(0x51, _) => Ok(Operation::Syscall(opcode)),
(0x52, _) => Ok(Operation::Syscall(opcode)),
(0x53, _) => Ok(Operation::Syscall(opcode)),
(0x54, _) => Ok(Operation::Syscall(opcode)),
(0x55, _) => Ok(Operation::Syscall(opcode)),
(0x56, _) => Ok(Operation::NotImplemented),
(0x57, _) => Ok(Operation::NotImplemented),
(0x58, _) => Ok(Operation::NotImplemented),
(0x56, _) => Ok(Operation::Jump),
(0x57, _) => Ok(Operation::Jumpi),
(0x58, _) => Ok(Operation::Pc),
(0x59, _) => Ok(Operation::Syscall(opcode)),
(0x5a, _) => Ok(Operation::NotImplemented),
(0x5b, _) => Ok(Operation::NotImplemented),
(0x5c, true) => Ok(Operation::NotImplemented),
(0x5d, true) => Ok(Operation::NotImplemented),
(0x5e, true) => Ok(Operation::NotImplemented),
(0x5f, true) => Ok(Operation::NotImplemented),
(0x5a, _) => Ok(Operation::Gas),
(0x5b, _) => Ok(Operation::Jumpdest),
(0x60..=0x7f, _) => Ok(Operation::Push(opcode & 0x1f)),
(0x80..=0x8f, _) => Ok(Operation::Dup(opcode & 0xf)),
(0x90..=0x9f, _) => Ok(Operation::Swap(opcode & 0xf)),
@ -126,13 +132,13 @@ fn decode(registers_state: RegistersState, opcode: u8) -> Result<Operation, Prog
(0xf3, _) => Ok(Operation::Syscall(opcode)),
(0xf4, _) => Ok(Operation::Syscall(opcode)),
(0xf5, _) => Ok(Operation::Syscall(opcode)),
(0xf6, true) => Ok(Operation::NotImplemented),
(0xf7, true) => Ok(Operation::NotImplemented),
(0xf8, true) => Ok(Operation::NotImplemented),
(0xf6, true) => Ok(Operation::GetContext),
(0xf7, true) => Ok(Operation::SetContext),
(0xf8, true) => Ok(Operation::ConsumeGas),
(0xf9, true) => Ok(Operation::ExitKernel),
(0xfa, _) => Ok(Operation::Syscall(opcode)),
(0xfb, true) => Ok(Operation::NotImplemented),
(0xfc, true) => Ok(Operation::NotImplemented),
(0xfb, true) => Ok(Operation::MloadGeneral),
(0xfc, true) => Ok(Operation::MstoreGeneral),
(0xfd, _) => Ok(Operation::Syscall(opcode)),
(0xff, _) => Ok(Operation::Syscall(opcode)),
_ => Err(ProgramError::InvalidOpcode),