Skip to content

Commit

Permalink
Merge 'main' into merge-pc-push0
Browse files Browse the repository at this point in the history
  • Loading branch information
LindaGuiga committed Oct 18, 2023
2 parents d6f98e5 + 817e3e7 commit 0c4fd56
Showing 20 changed files with 230 additions and 62 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -178,8 +178,8 @@ Plonky2's default hash function is Poseidon, configured with 8 full rounds, 22 p

## Links

- [System Zero](https://github.com/mir-protocol/system-zero), a zkVM built on top of Starky (no longer maintained)
- [Waksman](https://github.com/mir-protocol/plonky2-waksman), Plonky2 gadgets for permutation checking using Waksman networks (no longer maintained)
- [Insertion](https://github.com/mir-protocol/plonky2-insertion), Plonky2 gadgets for insertion into a list (no longer maintained)
- [u32](https://github.com/mir-protocol/plonky2-u32), Plonky2 gadgets for u32 arithmetic (no longer actively maintained)
- [ECDSA](https://github.com/mir-protocol/plonky2-ecdsa), Plonky2 gadgets for the ECDSA algorithm (no longer actively maintained)
- [System Zero](https://github.com/0xPolygonZero/system-zero), a zkVM built on top of Starky (no longer maintained)
- [Waksman](https://github.com/0xPolygonZero/plonky2-waksman), Plonky2 gadgets for permutation checking using Waksman networks (no longer maintained)
- [Insertion](https://github.com/0xPolygonZero/plonky2-insertion), Plonky2 gadgets for insertion into a list (no longer maintained)
- [u32](https://github.com/0xPolygonZero/plonky2-u32), Plonky2 gadgets for u32 arithmetic (no longer actively maintained)
- [ECDSA](https://github.com/0xPolygonZero/plonky2-ecdsa), Plonky2 gadgets for the ECDSA algorithm (no longer actively maintained)
4 changes: 2 additions & 2 deletions evm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ description = "Implementation of STARKs for the Ethereum Virtual Machine"
version = "0.1.1"
authors = ["Daniel Lubarov <daniel@lubarov.com>", "William Borgeaud <williamborgeaud@gmail.com>"]
readme = "README.md"
repository = "https://github.com/mir-protocol/plonky2"
repository = "https://github.com/0xPolygonZero/plonky2"
keywords = ["EVM", "STARK", "Ethereum"]
categories = ["cryptography"]
edition = "2021"
@@ -13,7 +13,7 @@ edition = "2021"
anyhow = "1.0.40"
bytes = "1.4.0"
env_logger = "0.10.0"
eth_trie_utils = { git = "https://github.com/mir-protocol/eth_trie_utils.git", rev = "e9ec4ec2aa2ae976b7c699ef40c1ffc716d87ed5" }
eth_trie_utils = { git = "https://github.com/0xPolygonZero/eth_trie_utils.git", rev = "e9ec4ec2aa2ae976b7c699ef40c1ffc716d87ed5" }
ethereum-types = "0.14.0"
hex = { version = "0.4.3", optional = true }
hex-literal = "0.4.1"
3 changes: 1 addition & 2 deletions evm/src/cpu/columns/ops.rs
Original file line number Diff line number Diff line change
@@ -20,8 +20,7 @@ pub struct OpsColumnsView<T: Copy> {
pub jumps: T, // Combines JUMP and JUMPI flags.
pub jumpdest: T,
pub push: T,
pub dup: T,
pub swap: T,
pub dup_swap: T,
pub get_context: T,
pub set_context: T,
pub mstore_32bytes: T,
5 changes: 2 additions & 3 deletions evm/src/cpu/control_flow.rs
Original file line number Diff line number Diff line change
@@ -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; 17] = [
const NATIVE_INSTRUCTIONS: [usize; 16] = [
COL_MAP.op.binary_op,
COL_MAP.op.ternary_op,
COL_MAP.op.fp254_op,
@@ -23,8 +23,7 @@ const NATIVE_INSTRUCTIONS: [usize; 17] = [
COL_MAP.op.pc_push0,
COL_MAP.op.jumpdest,
// not PUSH (need to increment by more than 1)
COL_MAP.op.dup,
COL_MAP.op.swap,
COL_MAP.op.dup_swap,
COL_MAP.op.get_context,
COL_MAP.op.set_context,
// not EXIT_KERNEL (performs a jump)
7 changes: 3 additions & 4 deletions evm/src/cpu/decode.rs
Original file line number Diff line number Diff line change
@@ -23,7 +23,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); 15] = [
const OPCODES: [(u8, usize, bool, usize); 14] = [
// (start index of block, number of top bits to check (log2), kernel-only, flag column)
// ADD, MUL, SUB, DIV, MOD, LT, GT and BYTE flags are handled partly manually here, and partly through the Arithmetic table CTL.
// ADDMOD, MULMOD and SUBMOD flags are handled partly manually here, and partly through the Arithmetic table CTL.
@@ -37,9 +37,8 @@ const OPCODES: [(u8, usize, bool, usize); 15] = [
(0x50, 0, false, COL_MAP.op.pop),
(0x56, 1, false, COL_MAP.op.jumps), // 0x56-0x57
(0x5b, 0, false, COL_MAP.op.jumpdest),
(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
(0x60, 5, false, COL_MAP.op.push), // 0x60-0x7f
(0x80, 5, false, COL_MAP.op.dup_swap), // 0x80-0x9f
(0xee, 0, true, COL_MAP.op.mstore_32bytes),
(0xf6, 0, true, COL_MAP.op.get_context),
(0xf7, 0, true, COL_MAP.op.set_context),
15 changes: 10 additions & 5 deletions evm/src/cpu/dup_swap.rs
Original file line number Diff line number Diff line change
@@ -114,7 +114,8 @@ fn eval_packed_dup<P: PackedField>(
nv: &CpuColumnsView<P>,
yield_constr: &mut ConstraintConsumer<P>,
) {
let filter = lv.op.dup;
// DUP opcodes have 0 at the 5-th position, while SWAP opcodes have 1.
let filter = lv.op.dup_swap * (P::ONES - lv.opcode_bits[4]);

let write_channel = &lv.mem_channels[1];
let read_channel = &lv.mem_channels[2];
@@ -139,8 +140,10 @@ fn eval_ext_circuit_dup<F: RichField + Extendable<D>, const D: usize>(
yield_constr: &mut RecursiveConstraintConsumer<F, D>,
) {
let zero = builder.zero_extension();

let filter = lv.op.dup;
let one = builder.one_extension();
// DUP opcodes have 0 at the 5-th position, while SWAP opcodes have 1.
let mut filter = builder.sub_extension(one, lv.opcode_bits[4]);
filter = builder.mul_extension(lv.op.dup_swap, filter);

let write_channel = &lv.mem_channels[1];
let read_channel = &lv.mem_channels[2];
@@ -187,7 +190,8 @@ fn eval_packed_swap<P: PackedField>(
) {
let n_plus_one = n + P::ONES;

let filter = lv.op.swap;
// DUP opcodes have 0 at the 5-th position, while SWAP opcodes have 1.
let filter = lv.op.dup_swap * lv.opcode_bits[4];

let in1_channel = &lv.mem_channels[0];
let in2_channel = &lv.mem_channels[1];
@@ -215,7 +219,8 @@ fn eval_ext_circuit_swap<F: RichField + Extendable<D>, const D: usize>(
let one = builder.one_extension();
let n_plus_one = builder.add_extension(n, one);

let filter = lv.op.swap;
// DUP opcodes have 0 at the 5-th position, while SWAP opcodes have 1.
let filter = builder.mul_extension(lv.op.dup_swap, lv.opcode_bits[4]);

let in1_channel = &lv.mem_channels[0];
let in2_channel = &lv.mem_channels[1];
3 changes: 1 addition & 2 deletions evm/src/cpu/gas.rs
Original file line number Diff line number Diff line change
@@ -33,8 +33,7 @@ const SIMPLE_OPCODES: OpsColumnsView<Option<u32>> = OpsColumnsView {
pc_push0: G_BASE,
jumpdest: G_JUMPDEST,
push: G_VERYLOW,
dup: G_VERYLOW,
swap: G_VERYLOW,
dup_swap: G_VERYLOW,
get_context: KERNEL_ONLY_INSTR,
set_context: KERNEL_ONLY_INSTR,
mstore_32bytes: KERNEL_ONLY_INSTR,
3 changes: 1 addition & 2 deletions evm/src/cpu/stack.rs
Original file line number Diff line number Diff line change
@@ -103,8 +103,7 @@ pub(crate) const STACK_BEHAVIORS: OpsColumnsView<Option<StackBehavior>> = OpsCol
disable_other_channels: true,
}),
push: None, // TODO
dup: None,
swap: None,
dup_swap: None,
get_context: Some(StackBehavior {
num_pops: 0,
pushes: true,
17 changes: 15 additions & 2 deletions evm/src/cross_table_lookup.rs
Original file line number Diff line number Diff line change
@@ -838,20 +838,21 @@ pub(crate) mod testutils {
type MultiSet<F> = HashMap<Vec<F>, Vec<(Table, usize)>>;

/// Check that the provided traces and cross-table lookups are consistent.
#[allow(unused)] // TODO: used later?
pub(crate) fn check_ctls<F: Field>(
trace_poly_values: &[Vec<PolynomialValues<F>>],
cross_table_lookups: &[CrossTableLookup<F>],
extra_memory_looking_values: &[Vec<F>],
) {
for (i, ctl) in cross_table_lookups.iter().enumerate() {
check_ctl(trace_poly_values, ctl, i);
check_ctl(trace_poly_values, ctl, i, extra_memory_looking_values);
}
}

fn check_ctl<F: Field>(
trace_poly_values: &[Vec<PolynomialValues<F>>],
ctl: &CrossTableLookup<F>,
ctl_index: usize,
extra_memory_looking_values: &[Vec<F>],
) {
let CrossTableLookup {
looking_tables,
@@ -868,6 +869,18 @@ pub(crate) mod testutils {
}
process_table(trace_poly_values, looked_table, &mut looked_multiset);

// Extra looking values for memory
if ctl_index == Table::Memory as usize {
for row in extra_memory_looking_values.iter() {
// The table and the row index don't matter here, as we just want to enforce
// that the special extra values do appear when looking against the Memory table.
looking_multiset
.entry(row.to_vec())
.or_default()
.push((Table::Cpu, 0));
}
}

let empty = &vec![];
// Check that every row in the looking tables appears in the looked table the same number of times.
for (row, looking_locations) in &looking_multiset {
15 changes: 6 additions & 9 deletions evm/src/fixed_recursive_verifier.rs
Original file line number Diff line number Diff line change
@@ -819,12 +819,11 @@ where
// Connect intermediary values for gas_used and bloom filters to the block's final values. We only plug on the right, so there is no need to check the left-handside block.
Self::connect_final_block_values_to_intermediary(builder, rhs);

let zero = builder.zero();
let has_not_parent_block = builder.sub(one, has_parent_block.target);

// Check that the genesis block number is 0.
let gen_block_constr = builder.mul(has_not_parent_block, rhs.block_metadata.block_number);
builder.connect(gen_block_constr, zero);
builder.assert_zero(gen_block_constr);

// Check that the genesis block has the predetermined state trie root in `ExtraBlockData`.
Self::connect_genesis_block(builder, rhs, has_not_parent_block);
@@ -837,7 +836,6 @@ where
) where
F: RichField + Extendable<D>,
{
let zero = builder.zero();
for (&limb0, limb1) in x
.trie_roots_before
.state_root
@@ -846,7 +844,7 @@ where
{
let mut constr = builder.sub(limb0, limb1);
constr = builder.mul(has_not_parent_block, constr);
builder.connect(constr, zero);
builder.assert_zero(constr);
}
}

@@ -879,16 +877,15 @@ where
where
F: RichField + Extendable<D>,
{
let zero = builder.constant(F::ZERO);
// The initial number of transactions is 0.
builder.connect(x.extra_block_data.txn_number_before, zero);
builder.assert_zero(x.extra_block_data.txn_number_before);
// The initial gas used is 0.
builder.connect(x.extra_block_data.gas_used_before[0], zero);
builder.connect(x.extra_block_data.gas_used_before[1], zero);
builder.assert_zero(x.extra_block_data.gas_used_before[0]);
builder.assert_zero(x.extra_block_data.gas_used_before[1]);

// The initial bloom filter is all zeroes.
for t in x.extra_block_data.block_bloom_before {
builder.connect(t, zero);
builder.assert_zero(t);
}

// The transactions and receipts tries are empty at the beginning of the block.
27 changes: 21 additions & 6 deletions evm/src/prover.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::any::type_name;

use anyhow::{ensure, Result};
use itertools::Itertools;
use once_cell::sync::Lazy;
@@ -35,6 +33,10 @@ use crate::lookup::{lookup_helper_columns, Lookup, LookupCheckVars};
use crate::proof::{AllProof, PublicValues, StarkOpeningSet, StarkProof, StarkProofWithMetadata};
use crate::stark::Stark;
use crate::vanishing_poly::eval_vanishing_poly;
#[cfg(test)]
use crate::{
cross_table_lookup::testutils::check_ctls, verifier::testutils::get_memory_extra_looking_values,
};

/// Generate traces, then create all STARK proofs.
pub fn prove<F, C, const D: usize>(
@@ -142,7 +144,7 @@ where
prove_with_commitments(
all_stark,
config,
trace_poly_values,
&trace_poly_values,
trace_commitments,
ctl_data_per_table,
&mut challenger,
@@ -151,6 +153,15 @@ where
)?
);

#[cfg(test)]
{
check_ctls(
&trace_poly_values,
&all_stark.cross_table_lookups,
&get_memory_extra_looking_values(&public_values),
);
}

Ok(AllProof {
stark_proofs,
ctl_challenges,
@@ -161,7 +172,7 @@ where
fn prove_with_commitments<F, C, const D: usize>(
all_stark: &AllStark<F, D>,
config: &StarkConfig,
trace_poly_values: [Vec<PolynomialValues<F>>; NUM_TABLES],
trace_poly_values: &[Vec<PolynomialValues<F>>; NUM_TABLES],
trace_commitments: Vec<PolynomialBatch<F, C, D>>,
ctl_data_per_table: [CtlData<F>; NUM_TABLES],
challenger: &mut Challenger<F, C::Hasher>,
@@ -365,7 +376,9 @@ where
challenger.observe_cap(&auxiliary_polys_cap);

let alphas = challenger.get_n_challenges(config.num_challenges);
if cfg!(test) {

#[cfg(test)]
{
check_constraints(
stark,
trace_commitment,
@@ -378,6 +391,7 @@ where
num_lookup_columns,
);
}

let quotient_polys = timed!(
timing,
"compute quotient polys",
@@ -606,6 +620,7 @@ where
.collect()
}

#[cfg(test)]
/// Check that all constraints evaluate to zero on `H`.
/// Can also be used to check the degree of the constraints by evaluating on a larger subgroup.
fn check_constraints<'a, F, C, S, const D: usize>(
@@ -705,7 +720,7 @@ fn check_constraints<'a, F, C, S, const D: usize>(
assert!(
v.iter().all(|x| x.is_zero()),
"Constraint failed in {}",
type_name::<S>()
std::any::type_name::<S>()
);
}
}
19 changes: 9 additions & 10 deletions evm/src/recursive_verifier.rs
Original file line number Diff line number Diff line change
@@ -619,14 +619,11 @@ fn add_data_write<F: RichField + Extendable<D>, const D: usize>(
debug_assert!(val.len() <= VALUE_LIMBS);
let len = core::cmp::min(val.len(), VALUE_LIMBS);

let zero = builder.zero();
let one = builder.one();

let row = builder.add_virtual_targets(13);
// is_read
builder.connect(row[0], zero);
// context
builder.connect(row[1], zero);
// is_read = false
builder.assert_zero(row[0]);
// context = 0
builder.assert_zero(row[1]);
// segment
builder.connect(row[2], segment);
// virtual
@@ -635,14 +632,16 @@ fn add_data_write<F: RichField + Extendable<D>, const D: usize>(

// values
for j in 0..len {
// connect the actual value limbs
builder.connect(row[4 + j], val[j]);
}
for j in len..VALUE_LIMBS {
builder.connect(row[4 + j], zero);
// assert that the remaining limbs are 0
builder.assert_zero(row[4 + j]);
}

// timestamp
builder.connect(row[12], one);
// timestamp = 1
builder.assert_one(row[12]);

let combined = challenge.combine_base_circuit(builder, &row);
builder.mul(running_product, combined)
Loading

0 comments on commit 0c4fd56

Please sign in to comment.