Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eip 1153 #58

Closed
wants to merge 15 commits into from
Closed
4 changes: 2 additions & 2 deletions docs/arithmetization/cpulogic.tex
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,15 @@ \subsection{Privileged instructions}
\item[0x21.] \texttt{KECCAK\_GENERAL}. Pops 2 elements (a Memory address, followed by a length $\ell$) and pushes the hash of the memory portion starting at the
constructed address and of length $\ell$. It is similar to KECCAK256 (0x20) instruction, but can be applied to any memory section (i.e. even privileged ones).

\item[0x49.] \texttt{PROVER\_INPUT}. Pushes a single prover input onto the stack.

\item[0xC0-0xDF.] \texttt{MSTORE\_32BYTES}. Pops 2 elements from the stack (a Memory address, and then a value), and pushes
a new address' onto the stack. The value is being decomposed into bytes and written to memory, starting from the fetched address. The new address being pushed is computed as the
initial address + the length of the byte sequence being written to memory. Note that similarly to PUSH (0x60-0x7F) instructions, there are 32 MSTORE\_32BYTES instructions, each
corresponding to a target byte length (length 0 is ignored, for the same reasons as MLOAD\_32BYTES, see below). Writing to memory an integer fitting in $n$ bytes with a length $\ell < n$ will
result in the integer being truncated. On the other hand, specifying a length $\ell$ greater than the byte size of the value being written will result in padding with zeroes. This
process is heavily used when resetting memory sections (by calling MSTORE\_32BYTES\_32 with the value 0).

\item[0xEE.] \texttt{PROVER\_INPUT}. Pushes a single prover input onto the stack.

\item[0xF6.] \texttt{GET\_CONTEXT}. Pushes the current context onto the stack. The kernel always has context 0.

\item[0xF7.] \texttt{SET\_CONTEXT}. Pops the top element of the stack and updates the current context to this value. It is usually used when calling another contract or precompile,
Expand Down
8 changes: 2 additions & 6 deletions evm_arithmetization/src/cpu/control_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ pub(crate) fn eval_packed_generic<P: PackedField>(
.constraint_transition(is_native_instruction * (lv.is_kernel_mode - nv.is_kernel_mode));

// Apply the same checks as before, for PROVER_INPUT.
let is_prover_input: P = lv.op.push_prover_input * (lv.opcode_bits[5] - P::ONES);
let is_prover_input: P = lv.op.push_prover_input * lv.opcode_bits[7];
yield_constr.constraint_transition(
is_prover_input * (lv.program_counter - nv.program_counter + P::ONES),
);
Expand Down Expand Up @@ -129,11 +129,7 @@ pub(crate) fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(
yield_constr.constraint_transition(builder, kernel_constr);

// Same constraints as before, for PROVER_INPUT.
let is_prover_input = builder.mul_sub_extension(
lv.op.push_prover_input,
lv.opcode_bits[5],
lv.op.push_prover_input,
);
let is_prover_input = builder.mul_extension(lv.op.push_prover_input, lv.opcode_bits[7]);
let pc_constr = builder.mul_add_extension(is_prover_input, pc_diff, is_prover_input);
yield_constr.constraint_transition(builder, pc_constr);
let kernel_constr = builder.mul_extension(is_prover_input, kernel_diff);
Expand Down
13 changes: 7 additions & 6 deletions evm_arithmetization/src/cpu/cpu_stark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,7 @@ pub(crate) fn ctl_arithmetic_base_rows<F: Field>() -> TableWithColumns<F> {
// (also `ops` is used as the operation filter). The list of
// operations includes binary operations which will simply ignore
// the third input.
let col_bit = Column::linear_combination_with_constant(
vec![(COL_MAP.opcode_bits[5], F::NEG_ONE)],
F::ONE,
);
let col_bit = Column::single(COL_MAP.opcode_bits[7]);
TableWithColumns::new(
*Table::Cpu,
columns,
Expand Down Expand Up @@ -263,9 +260,13 @@ pub(crate) fn ctl_data_byte_packing_push<F: Field>() -> Vec<Column<F>> {

/// CTL filter for the `PUSH` operation.
pub(crate) fn ctl_filter_byte_packing_push<F: Field>() -> Filter<F> {
let bit_col = Column::single(COL_MAP.opcode_bits[5]);
let col_bit = Column::linear_combination_with_constant(
vec![(COL_MAP.opcode_bits[7], F::NEG_ONE)],
F::ONE,
);

Filter::new(
vec![(Column::single(COL_MAP.op.push_prover_input), bit_col)],
vec![(Column::single(COL_MAP.op.push_prover_input), col_bit)],
vec![],
)
}
Expand Down
15 changes: 5 additions & 10 deletions evm_arithmetization/src/cpu/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,11 @@ pub(crate) fn eval_packed_generic<P: PackedField>(

// Manually check PUSH and PROVER_INPUT.
// PROVER_INPUT is a kernel-only instruction, but not PUSH.
let push_prover_input_constr = (opcode - P::Scalar::from_canonical_usize(0x49_usize))
let push_prover_input_constr = (opcode - P::Scalar::from_canonical_usize(0xee_usize))
* (opcode_high_three - P::Scalar::from_canonical_usize(0x60_usize))
* lv.op.push_prover_input;
yield_constr.constraint(push_prover_input_constr);
let prover_input_constr =
lv.op.push_prover_input * (lv.opcode_bits[5] - P::ONES) * (P::ONES - kernel_mode);
let prover_input_constr = lv.op.push_prover_input * lv.opcode_bits[7] * (P::ONES - kernel_mode);
yield_constr.constraint(prover_input_constr);
}

Expand Down Expand Up @@ -389,20 +388,16 @@ pub(crate) fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(
// Manually check PUSH and PROVER_INPUT.
// PROVER_INPUT is a kernel-only instruction, but not PUSH.
let prover_input_opcode =
builder.constant_extension(F::Extension::from_canonical_usize(0x49usize));
let push_opcodes = builder.constant_extension(F::Extension::from_canonical_usize(0x60usize));
builder.constant_extension(F::Extension::from_canonical_usize(0xee_usize));
let push_opcodes = builder.constant_extension(F::Extension::from_canonical_usize(0x60_usize));

let push_constr = builder.sub_extension(opcode_high_three, push_opcodes);
let prover_input_constr = builder.sub_extension(opcode, prover_input_opcode);

let push_prover_input_constr =
builder.mul_many_extension([lv.op.push_prover_input, prover_input_constr, push_constr]);
yield_constr.constraint(builder, push_prover_input_constr);
let prover_input_filter = builder.mul_sub_extension(
lv.op.push_prover_input,
lv.opcode_bits[5],
lv.op.push_prover_input,
);
let prover_input_filter = builder.mul_extension(lv.op.push_prover_input, lv.opcode_bits[7]);
let constr = builder.mul_extension(prover_input_filter, is_not_kernel_mode);
yield_constr.constraint(builder, constr);
}
16 changes: 8 additions & 8 deletions evm_arithmetization/src/cpu/gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,11 @@ fn eval_packed_accumulate<P: PackedField>(
);

// For PROVER_INPUT and PUSH operations.
// PUSH operations are differentiated from PROVER_INPUT by their 6th bit set to
// PUSH operations are differentiated from PROVER_INPUT by their 8th bit set to
// 1.
let push_prover_input_gas_cost = lv.opcode_bits[5]
let push_prover_input_gas_cost = (P::ONES - lv.opcode_bits[7])
* P::Scalar::from_canonical_u32(G_VERYLOW.unwrap())
+ (P::ONES - lv.opcode_bits[5]) * P::Scalar::from_canonical_u32(KERNEL_ONLY_INSTR.unwrap());
+ lv.opcode_bits[7] * P::Scalar::from_canonical_u32(KERNEL_ONLY_INSTR.unwrap());
yield_constr
.constraint_transition(lv.op.push_prover_input * (gas_diff - push_prover_input_gas_cost));
}
Expand Down Expand Up @@ -282,13 +282,13 @@ fn eval_ext_circuit_accumulate<F: RichField + Extendable<D>, const D: usize>(
yield_constr.constraint_transition(builder, constr);

// For PROVER_INPUT and PUSH operations.
// PUSH operations are differentiated from PROVER_INPUT by their 6th bit set to
// PUSH operations are differentiated from PROVER_INPUT by their 8th bit set to
// 1.
let push_prover_input_gas_cost = builder.arithmetic_extension(
F::from_canonical_u32(G_VERYLOW.unwrap())
- F::from_canonical_u32(KERNEL_ONLY_INSTR.unwrap()),
F::from_canonical_u32(KERNEL_ONLY_INSTR.unwrap()),
lv.opcode_bits[5],
F::from_canonical_u32(KERNEL_ONLY_INSTR.unwrap())
- F::from_canonical_u32(G_VERYLOW.unwrap()),
F::from_canonical_u32(G_VERYLOW.unwrap()),
lv.opcode_bits[7],
one,
one,
);
Expand Down
Loading
Loading