From db6c3fd8112e41a38f4449146985bb95966471b3 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Thu, 19 May 2022 12:49:01 -0700 Subject: [PATCH 01/31] keccak stark --- evm/src/keccak/keccak_stark.rs | 428 ++++++++++++++++++++++++++++++++- evm/src/keccak/mod.rs | 3 + field/src/packed_field.rs | 4 + 3 files changed, 423 insertions(+), 12 deletions(-) diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index 0a8a49f6..dfaca5cd 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -1,48 +1,452 @@ use std::marker::PhantomData; +use itertools::Itertools; +use log::info; use plonky2::field::extension_field::{Extendable, FieldExtension}; use plonky2::field::packed_field::PackedField; +use plonky2::field::polynomial::PolynomialValues; use plonky2::hash::hash_types::RichField; +use plonky2::plonk::plonk_common::reduce_with_powers_ext_circuit; +use plonky2::timed; +use plonky2::util::timing::TimingTree; use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; -use crate::permutation::PermutationPair; +use crate::keccak::logic::{ + andn, andn_gen, andn_gen_circuit, xor, xor3_gen, xor3_gen_circuit, xor_gen, xor_gen_circuit, +}; +use crate::keccak::registers::{ + rc_value, rc_value_bit, reg_a, reg_a_prime, reg_a_prime_prime, reg_a_prime_prime_0_0_bit, + reg_a_prime_prime_prime, reg_b, reg_c, reg_c_partial, reg_step, NUM_REGISTERS, +}; +use crate::keccak::round_flags::{eval_round_flags, eval_round_flags_recursively}; use crate::stark::Stark; +use crate::util::trace_rows_to_poly_values; use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars}; +/// Number of rounds in a Keccak permutation. +pub(crate) const NUM_ROUNDS: usize = 24; + +/// Number of 64-bit limbs in a preimage of the Keccak permutation. +pub(crate) const INPUT_LIMBS: usize = 25; + +pub(crate) const NUM_PUBLIC_INPUTS: usize = 4; + #[derive(Copy, Clone)] pub struct KeccakStark { pub(crate) f: PhantomData, } +impl, const D: usize> KeccakStark { + /// Generate the rows of the trace. Note that this does not generate the permuted columns used + /// in our lookup arguments, as those are computed after transposing to column-wise form. + fn generate_trace_rows(&self, inputs: Vec<[u64; INPUT_LIMBS]>) -> Vec<[F; NUM_REGISTERS]> { + let num_rows = (inputs.len() * NUM_ROUNDS).next_power_of_two(); + info!("{} rows", num_rows); + let mut rows = Vec::with_capacity(num_rows); + for input in inputs { + rows.extend(self.generate_trace_rows_for_perm(input)); + } + + for i in rows.len()..num_rows { + let mut row = [F::ZERO; NUM_REGISTERS]; + self.generate_trace_rows_for_round(&mut row, i % NUM_ROUNDS); + rows.push(row); + } + + rows + } + + fn generate_trace_rows_for_perm( + &self, + input: [u64; INPUT_LIMBS], + ) -> [[F; NUM_REGISTERS]; NUM_ROUNDS] { + let mut rows = [[F::ZERO; NUM_REGISTERS]; NUM_ROUNDS]; + + for x in 0..5 { + for y in 0..5 { + let input_xy = input[x * 5 + y]; + for z in 0..64 { + rows[0][reg_a(x, y, z)] = F::from_canonical_u64((input_xy >> z) & 1); + } + } + } + + self.generate_trace_rows_for_round(&mut rows[0], 0); + for round in 1..24 { + // TODO: Populate input from prev. row output. + self.generate_trace_rows_for_round(&mut rows[round], round); + } + + rows + } + + fn generate_trace_rows_for_round(&self, row: &mut [F; NUM_REGISTERS], round: usize) { + row[round] = F::ONE; + + // Populate C partial and C. + for x in 0..5 { + for z in 0..64 { + let a = [0, 1, 2, 3, 4].map(|i| row[reg_a(x, i, z)]); + let c_partial = xor([a[0], a[1], a[2]]); + let c = xor([c_partial, a[3], a[4]]); + row[reg_c_partial(x, z)] = c_partial; + row[reg_c(x, z)] = c; + } + } + + // Populate A'. + // A'[x, y] = xor(A[x, y], D[x]) + // = xor(A[x, y], C[x - 1], ROT(C[x + 1], 1)) + for x in 0..5 { + for y in 0..5 { + for z in 0..64 { + row[reg_a_prime(x, y, z)] = xor([ + row[reg_a(x, y, z)], + row[reg_c((x + 4) % 5, z)], + row[reg_c((x + 1) % 5, (z + 1) % 64)], + ]); + } + } + } + + // Populate A''. + // A''[x, y] = xor(B[x, y], andn(B[x + 1, y], B[x + 2, y])). + for x in 0..5 { + for y in 0..5 { + let get_bit = |z| { + xor([ + row[reg_b(x, y, z)], + andn(row[reg_b((x + 1) % 5, y, z)], row[reg_b((x + 2) % 5, y, z)]), + ]) + }; + + let lo = (0..32) + .rev() + .fold(F::ZERO, |acc, z| acc.double() + get_bit(z)); + let hi = (32..64) + .rev() + .fold(F::ZERO, |acc, z| acc.double() + get_bit(z)); + + let reg_lo = reg_a_prime_prime(x, y); + let reg_hi = reg_lo + 1; + row[reg_lo] = lo; + row[reg_hi] = hi; + } + } + + // A''[0, 0] is additionally xor'd with RC. + let reg_lo = reg_a_prime_prime(0, 0); + let reg_hi = reg_lo + 1; + let rc_lo = rc_value(round) % (1 << 32); + let rc_hi = rc_value(round) >> 32; + row[reg_lo] = F::from_canonical_u64(row[reg_lo].to_canonical_u64() ^ rc_lo); + row[reg_hi] = F::from_canonical_u64(row[reg_hi].to_canonical_u64() ^ rc_hi); + } + + pub fn generate_trace(&self, inputs: Vec<[u64; INPUT_LIMBS]>) -> Vec> { + let mut timing = TimingTree::new("generate trace", log::Level::Debug); + + // Generate the witness, except for permuted columns in the lookup argument. + let trace_rows = timed!( + &mut timing, + "generate trace rows", + self.generate_trace_rows(inputs) + ); + + let trace_polys = timed!( + &mut timing, + "convert to PolynomialValues", + trace_rows_to_poly_values(trace_rows) + ); + + timing.print(); + trace_polys + } +} + impl, const D: usize> Stark for KeccakStark { - const COLUMNS: usize = 7; - const PUBLIC_INPUTS: usize = 0; + const COLUMNS: usize = NUM_REGISTERS; + const PUBLIC_INPUTS: usize = NUM_PUBLIC_INPUTS; fn eval_packed_generic( &self, - _vars: StarkEvaluationVars, - _yield_constr: &mut ConstraintConsumer

, + vars: StarkEvaluationVars, + yield_constr: &mut ConstraintConsumer

, ) where FE: FieldExtension, P: PackedField, { + eval_round_flags(vars, yield_constr); + + // C_partial[x] = xor(A[x, 0], A[x, 1], A[x, 2]) + for x in 0..5 { + for z in 0..64 { + let c_partial = vars.local_values[reg_c_partial(x, z)]; + let a_0 = vars.local_values[reg_a(x, 0, z)]; + let a_1 = vars.local_values[reg_a(x, 1, z)]; + let a_2 = vars.local_values[reg_a(x, 2, z)]; + let xor_012 = xor3_gen(a_0, a_1, a_2); + yield_constr.constraint(c_partial - xor_012); + } + } + + // C[x] = xor(C_partial[x], A[x, 3], A[x, 4]) + for x in 0..5 { + for z in 0..64 { + let c = vars.local_values[reg_c(x, z)]; + let xor_012 = vars.local_values[reg_c_partial(x, z)]; + let a_3 = vars.local_values[reg_a(x, 3, z)]; + let a_4 = vars.local_values[reg_a(x, 4, z)]; + let xor_01234 = xor3_gen(xor_012, a_3, a_4); + yield_constr.constraint(c - xor_01234); + } + } + + // A'[x, y] = xor(A[x, y], D[x]) + // = xor(A[x, y], C[x - 1], ROT(C[x + 1], 1)) + for x in 0..5 { + for z in 0..64 { + let c_left = vars.local_values[reg_c((x + 4) % 5, z)]; + let c_right = vars.local_values[reg_c((x + 1) % 5, (z + 1) % 64)]; + let d = xor_gen(c_left, c_right); + + for y in 0..5 { + let a = vars.local_values[reg_a(x, y, z)]; + let a_prime = vars.local_values[reg_a_prime(x, y, z)]; + let xor = xor_gen(d, a); + yield_constr.constraint(a_prime - xor); + } + } + } + + // A''[x, y] = xor(B[x, y], andn(B[x + 1, y], B[x + 2, y])). + for x in 0..5 { + for y in 0..5 { + let get_bit = |z| { + xor_gen( + vars.local_values[reg_b(x, y, z)], + andn_gen( + vars.local_values[reg_b((x + 1) % 5, y, z)], + vars.local_values[reg_b((x + 2) % 5, y, z)], + ), + ) + }; + + let reg_lo = reg_a_prime_prime(x, y); + let reg_hi = reg_lo + 1; + let lo = vars.local_values[reg_lo]; + let hi = vars.local_values[reg_hi]; + let computed_lo = (0..32) + .rev() + .fold(P::ZEROS, |acc, z| acc.doubles() + get_bit(z)); + let computed_hi = (32..64) + .rev() + .fold(P::ZEROS, |acc, z| acc.doubles() + get_bit(z)); + + yield_constr.constraint(computed_lo - lo); + yield_constr.constraint(computed_hi - hi); + } + } + + // A'''[0, 0] = A''[0, 0] XOR RC + let a_prime_prime_0_0_bits = (0..64) + .map(|i| vars.local_values[reg_a_prime_prime_0_0_bit(i)]) + .collect_vec(); + let computed_a_prime_prime_0_0_lo = (0..32) + .rev() + .fold(P::ZEROS, |acc, z| acc.doubles() + a_prime_prime_0_0_bits[z]); + let computed_a_prime_prime_0_0_hi = (32..64) + .rev() + .fold(P::ZEROS, |acc, z| acc.doubles() + a_prime_prime_0_0_bits[z]); + let a_prime_prime_0_0_lo = vars.local_values[reg_a_prime_prime(0, 0)]; + let a_prime_prime_0_0_hi = vars.local_values[reg_a_prime_prime(0, 0) + 1]; + yield_constr.constraint(computed_a_prime_prime_0_0_lo - a_prime_prime_0_0_lo); + yield_constr.constraint(computed_a_prime_prime_0_0_hi - a_prime_prime_0_0_hi); + + let get_xored_bit = |i| { + let mut rc_bit_i = P::ZEROS; + for r in 0..NUM_ROUNDS { + let this_round = vars.local_values[reg_step(r)]; + let this_round_constant = + P::from(FE::from_canonical_u32(rc_value_bit(r, i) as u32)); + rc_bit_i += this_round * this_round_constant; + } + + xor_gen(a_prime_prime_0_0_bits[i], rc_bit_i) + }; + + let a_prime_prime_prime_0_0_lo = vars.local_values[reg_a_prime_prime_prime(0, 0)]; + let a_prime_prime_prime_0_0_hi = vars.local_values[reg_a_prime_prime_prime(0, 0) + 1]; + let computed_a_prime_prime_prime_0_0_lo = (0..32) + .rev() + .fold(P::ZEROS, |acc, z| acc.doubles() + get_xored_bit(z)); + let computed_a_prime_prime_prime_0_0_hi = (32..64) + .rev() + .fold(P::ZEROS, |acc, z| acc.doubles() + get_xored_bit(z)); + yield_constr.constraint(computed_a_prime_prime_prime_0_0_lo - a_prime_prime_prime_0_0_lo); + yield_constr.constraint(computed_a_prime_prime_prime_0_0_hi - a_prime_prime_prime_0_0_hi); + + // Enforce that this round's output equals the next round's input. + for x in 0..5 { + for y in 0..5 { + let output = vars.local_values[reg_a_prime_prime_prime(x, y)]; + let input_bits = (0..64) + .map(|z| vars.next_values[reg_a(x, y, z)]) + .collect_vec(); + let input_bits_combined = (0..64) + .rev() + .fold(P::ZEROS, |acc, z| acc.doubles() + input_bits[z]); + yield_constr.constraint(output - input_bits_combined); + } + } } fn eval_ext_circuit( &self, - _builder: &mut plonky2::plonk::circuit_builder::CircuitBuilder, - _vars: StarkEvaluationTargets, - _yield_constr: &mut RecursiveConstraintConsumer, + builder: &mut plonky2::plonk::circuit_builder::CircuitBuilder, + vars: StarkEvaluationTargets, + yield_constr: &mut RecursiveConstraintConsumer, ) { + let two = builder.two(); + + eval_round_flags_recursively(builder, vars, yield_constr); + + // C_partial[x] = xor(A[x, 0], A[x, 1], A[x, 2]) + for x in 0..5 { + for z in 0..64 { + let c_partial = vars.local_values[reg_c_partial(x, z)]; + let a_0 = vars.local_values[reg_a(x, 0, z)]; + let a_1 = vars.local_values[reg_a(x, 1, z)]; + let a_2 = vars.local_values[reg_a(x, 2, z)]; + + let xor_012 = xor3_gen_circuit(builder, a_0, a_1, a_2); + let diff = builder.sub_extension(c_partial, xor_012); + yield_constr.constraint(builder, diff); + } + } + + // C[x] = xor(C_partial[x], A[x, 3], A[x, 4]) + for x in 0..5 { + for z in 0..64 { + let c = vars.local_values[reg_c(x, z)]; + let xor_012 = vars.local_values[reg_c_partial(x, z)]; + let a_3 = vars.local_values[reg_a(x, 3, z)]; + let a_4 = vars.local_values[reg_a(x, 4, z)]; + + let xor_01234 = xor3_gen_circuit(builder, xor_012, a_3, a_4); + let diff = builder.sub_extension(c, xor_01234); + yield_constr.constraint(builder, diff); + } + } + + // A'[x, y] = xor(A[x, y], D[x]) + // = xor(A[x, y], C[x - 1], ROT(C[x + 1], 1)) + for x in 0..5 { + for z in 0..64 { + let c_left = vars.local_values[reg_c((x + 4) % 5, z)]; + let c_right = vars.local_values[reg_c((x + 1) % 5, (z + 1) % 64)]; + let d = xor_gen_circuit(builder, c_left, c_right); + + for y in 0..5 { + let a = vars.local_values[reg_a(x, y, z)]; + let a_prime = vars.local_values[reg_a_prime(x, y, z)]; + let xor = xor_gen_circuit(builder, d, a); + let diff = builder.sub_extension(a_prime, xor); + yield_constr.constraint(builder, diff); + } + } + } + + // A''[x, y] = xor(B[x, y], andn(B[x + 1, y], B[x + 2, y])). + for x in 0..5 { + for y in 0..5 { + let mut get_bit = |z| { + let andn = andn_gen_circuit( + builder, + vars.local_values[reg_b((x + 1) % 5, y, z)], + vars.local_values[reg_b((x + 2) % 5, y, z)], + ); + xor_gen_circuit(builder, vars.local_values[reg_b(x, y, z)], andn) + }; + + let reg_lo = reg_a_prime_prime(x, y); + let reg_hi = reg_lo + 1; + let lo = vars.local_values[reg_lo]; + let hi = vars.local_values[reg_hi]; + let bits_lo = (0..32).map(|z| get_bit(z)).collect_vec(); + let bits_hi = (32..64).map(|z| get_bit(z)).collect_vec(); + let computed_lo = reduce_with_powers_ext_circuit(builder, &bits_lo, two); + let computed_hi = reduce_with_powers_ext_circuit(builder, &bits_hi, two); + let diff = builder.sub_extension(computed_lo, lo); + yield_constr.constraint(builder, diff); + let diff = builder.sub_extension(computed_hi, hi); + yield_constr.constraint(builder, diff); + } + } + + // A'''[0, 0] = A''[0, 0] XOR RC + let a_prime_prime_0_0_bits = (0..64) + .map(|i| vars.local_values[reg_a_prime_prime_0_0_bit(i)]) + .collect_vec(); + let computed_a_prime_prime_0_0_lo = + reduce_with_powers_ext_circuit(builder, &a_prime_prime_0_0_bits[0..32], two); + let computed_a_prime_prime_0_0_hi = + reduce_with_powers_ext_circuit(builder, &a_prime_prime_0_0_bits[32..64], two); + let a_prime_prime_0_0_lo = vars.local_values[reg_a_prime_prime(0, 0)]; + let a_prime_prime_0_0_hi = vars.local_values[reg_a_prime_prime(0, 0) + 1]; + let diff = builder.sub_extension(computed_a_prime_prime_0_0_lo, a_prime_prime_0_0_lo); + yield_constr.constraint(builder, diff); + let diff = builder.sub_extension(computed_a_prime_prime_0_0_hi, a_prime_prime_0_0_hi); + yield_constr.constraint(builder, diff); + + let mut get_xored_bit = |i| { + let mut rc_bit_i = builder.zero_extension(); + for r in 0..NUM_ROUNDS { + let this_round = vars.local_values[reg_step(r)]; + let this_round_constant = builder + .constant_extension(F::from_canonical_u32(rc_value_bit(r, i) as u32).into()); + rc_bit_i = builder.mul_add_extension(this_round, this_round_constant, rc_bit_i); + } + + xor_gen_circuit(builder, a_prime_prime_0_0_bits[i], rc_bit_i) + }; + + let a_prime_prime_prime_0_0_lo = vars.local_values[reg_a_prime_prime_prime(0, 0)]; + let a_prime_prime_prime_0_0_hi = vars.local_values[reg_a_prime_prime_prime(0, 0) + 1]; + let bits_lo = (0..32).map(|z| get_xored_bit(z)).collect_vec(); + let bits_hi = (32..64).map(|z| get_xored_bit(z)).collect_vec(); + let computed_a_prime_prime_prime_0_0_lo = + reduce_with_powers_ext_circuit(builder, &bits_lo, two); + let computed_a_prime_prime_prime_0_0_hi = + reduce_with_powers_ext_circuit(builder, &bits_hi, two); + let diff = builder.sub_extension( + computed_a_prime_prime_prime_0_0_lo, + a_prime_prime_prime_0_0_lo, + ); + yield_constr.constraint(builder, diff); + let diff = builder.sub_extension( + computed_a_prime_prime_prime_0_0_hi, + a_prime_prime_prime_0_0_hi, + ); + yield_constr.constraint(builder, diff); + + // Enforce that this round's output equals the next round's input. + for x in 0..5 { + for y in 0..5 { + let output = vars.local_values[reg_a_prime_prime_prime(x, y)]; + let input_bits = (0..64) + .map(|z| vars.next_values[reg_a(x, y, z)]) + .collect_vec(); + let input_bits_combined = reduce_with_powers_ext_circuit(builder, &input_bits, two); + let diff = builder.sub_extension(output, input_bits_combined); + yield_constr.constraint(builder, diff); + } + } } fn constraint_degree(&self) -> usize { 3 } - - fn permutation_pairs(&self) -> Vec { - vec![PermutationPair::singletons(0, 6)] - } } #[cfg(test)] diff --git a/evm/src/keccak/mod.rs b/evm/src/keccak/mod.rs index 4c31c32b..41985c2a 100644 --- a/evm/src/keccak/mod.rs +++ b/evm/src/keccak/mod.rs @@ -1 +1,4 @@ pub mod keccak_stark; +pub mod logic; +pub mod registers; +pub mod round_flags; diff --git a/field/src/packed_field.rs b/field/src/packed_field.rs index 4b3336d9..bf5fed2d 100644 --- a/field/src/packed_field.rs +++ b/field/src/packed_field.rs @@ -95,6 +95,10 @@ where let n = buf.len() / Self::WIDTH; unsafe { std::slice::from_raw_parts_mut(buf_ptr, n) } } + + fn doubles(&self) -> Self { + *self * Self::Scalar::TWO + } } unsafe impl PackedField for F { From e6880e591b14c315db260541fd1ebd9b708522d5 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Thu, 26 May 2022 08:22:23 -0700 Subject: [PATCH 02/31] included everything --- evm/Cargo.toml | 1 + evm/src/keccak/logic.rs | 65 +++++++++ evm/src/keccak/registers.rs | 252 ++++++++++++++++++++++++++++++++++ evm/src/keccak/round_flags.rs | 40 ++++++ 4 files changed, 358 insertions(+) create mode 100644 evm/src/keccak/logic.rs create mode 100644 evm/src/keccak/registers.rs create mode 100644 evm/src/keccak/round_flags.rs diff --git a/evm/Cargo.toml b/evm/Cargo.toml index 2285a170..d65fb30c 100644 --- a/evm/Cargo.toml +++ b/evm/Cargo.toml @@ -13,3 +13,4 @@ itertools = "0.10.0" log = "0.4.14" rayon = "1.5.1" rand = "0.8.5" +rand_chacha = "0.3.1" diff --git a/evm/src/keccak/logic.rs b/evm/src/keccak/logic.rs new file mode 100644 index 00000000..7d248258 --- /dev/null +++ b/evm/src/keccak/logic.rs @@ -0,0 +1,65 @@ +use plonky2::field::extension_field::Extendable; +use plonky2::field::field_types::PrimeField64; +use plonky2::field::packed_field::PackedField; +use plonky2::hash::hash_types::RichField; +use plonky2::iop::ext_target::ExtensionTarget; +use plonky2::plonk::circuit_builder::CircuitBuilder; + +pub(crate) fn xor(xs: [F; N]) -> F { + xs.into_iter().fold(F::ZERO, |acc, x| { + debug_assert!(x.is_zero() || x.is_one()); + F::from_canonical_u64(acc.to_canonical_u64() ^ x.to_canonical_u64()) + }) +} + +/// Computes the arithmetic generalization of `xor(x, y)`, i.e. `x + y - 2 x y`. +pub(crate) fn xor_gen(x: P, y: P) -> P { + x + y - x * y.doubles() +} + +/// Computes the arithmetic generalization of `xor3(x, y, z)`. +pub(crate) fn xor3_gen(x: P, y: P, z: P) -> P { + xor_gen(x, xor_gen(y, z)) +} + +/// Computes the arithmetic generalization of `xor(x, y)`, i.e. `x + y - 2 x y`. +pub(crate) fn xor_gen_circuit, const D: usize>( + builder: &mut CircuitBuilder, + x: ExtensionTarget, + y: ExtensionTarget, +) -> ExtensionTarget { + let sum = builder.add_extension(x, y); + builder.arithmetic_extension(-F::TWO, F::ONE, x, y, sum) +} + +/// Computes the arithmetic generalization of `xor(x, y)`, i.e. `x + y - 2 x y`. +pub(crate) fn xor3_gen_circuit, const D: usize>( + builder: &mut CircuitBuilder, + x: ExtensionTarget, + y: ExtensionTarget, + z: ExtensionTarget, +) -> ExtensionTarget { + let x_xor_y = xor_gen_circuit(builder, x, y); + xor_gen_circuit(builder, x_xor_y, z) +} + +pub(crate) fn andn(x: F, y: F) -> F { + debug_assert!(x.is_zero() || x.is_one()); + debug_assert!(y.is_zero() || y.is_one()); + let x = x.to_canonical_u64(); + let y = y.to_canonical_u64(); + F::from_canonical_u64(!x & y) +} + +pub(crate) fn andn_gen(x: P, y: P) -> P { + (P::ONES - x) * y +} + +pub(crate) fn andn_gen_circuit, const D: usize>( + builder: &mut CircuitBuilder, + x: ExtensionTarget, + y: ExtensionTarget, +) -> ExtensionTarget { + // (1 - x) y = -xy + y + builder.arithmetic_extension(F::NEG_ONE, F::ONE, x, y, y) +} diff --git a/evm/src/keccak/registers.rs b/evm/src/keccak/registers.rs new file mode 100644 index 00000000..f3e847b1 --- /dev/null +++ b/evm/src/keccak/registers.rs @@ -0,0 +1,252 @@ +use crate::keccak::keccak_stark::NUM_ROUNDS; + +/// A register which is set to 1 if we are in the `i`th round, otherwise 0. +pub(crate) const fn reg_step(i: usize) -> usize { + debug_assert!(i < NUM_ROUNDS); + i +} + +const R: [[u8; 5]; 5] = [ + [0, 18, 41, 3, 36], + [1, 2, 45, 10, 44], + [62, 61, 15, 43, 6], + [28, 56, 21, 25, 55], + [27, 14, 8, 39, 20], +]; + +const RC: [u64; 24] = [ + 0x0000000000000001, + 0x0000000000008082, + 0x800000000000808A, + 0x8000000080008000, + 0x000000000000808B, + 0x0000000080000001, + 0x8000000080008081, + 0x8000000000008009, + 0x000000000000008A, + 0x0000000000000088, + 0x0000000080008009, + 0x000000008000000A, + 0x000000008000808B, + 0x800000000000008B, + 0x8000000000008089, + 0x8000000000008003, + 0x8000000000008002, + 0x8000000000000080, + 0x000000000000800A, + 0x800000008000000A, + 0x8000000080008081, + 0x8000000000008080, + 0x0000000080000001, + 0x8000000080008008, +]; + +const RC_BITS: [[u8; 64]; 24] = [ + [ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], +]; + +pub(crate) const fn rc_value_bit(round: usize, bit_index: usize) -> u8 { + RC_BITS[round][bit_index] +} + +pub(crate) const fn rc_value(round: usize) -> u64 { + RC[round] +} + +const START_A: usize = NUM_ROUNDS; +pub(crate) const fn reg_a(x: usize, y: usize, z: usize) -> usize { + debug_assert!(x < 5); + debug_assert!(y < 5); + debug_assert!(z < 64); + START_A + x * 64 * 5 + y * 64 + z +} + +// C_partial[x] = xor(A[x, 0], A[x, 1], A[x, 2]) +const START_C_PARTIAL: usize = START_A + 5 * 5 * 64; +pub(crate) const fn reg_c_partial(x: usize, z: usize) -> usize { + START_C_PARTIAL + x * 64 + z +} + +// C[x] = xor(C_partial[x], A[x, 3], A[x, 4]) +const START_C: usize = START_C_PARTIAL + 5 * 64; +pub(crate) const fn reg_c(x: usize, z: usize) -> usize { + START_C + x * 64 + z +} + +// D is inlined. +// const fn reg_d(x: usize, z: usize) {} + +// A'[x, y] = xor(A[x, y], D[x]) +// = xor(A[x, y], C[x - 1], ROT(C[x + 1], 1)) +const START_A_PRIME: usize = START_C + 5 * 64; +pub(crate) const fn reg_a_prime(x: usize, y: usize, z: usize) -> usize { + debug_assert!(x < 5); + debug_assert!(y < 5); + debug_assert!(z < 64); + START_A_PRIME + x * 64 * 5 + y * 64 + z +} + +pub(crate) const fn reg_b(x: usize, y: usize, z: usize) -> usize { + debug_assert!(x < 5); + debug_assert!(y < 5); + debug_assert!(z < 64); + // B is just a rotation of A', so these are aliases for A' registers. + // From the spec, + // B[y, (2x + 3y) % 5] = ROT(A'[x, y], r[x, y]) + // So, + // B[x, y] = f((x + 3y) % 5, x) + // where f(a, b) = ROT(A'[a, b], r[a, b]) + let a = (x + 3 * y) % 5; + let b = x; + let rot = R[a][b] as usize; + reg_a_prime(a, b, (z + rot) % 64) +} + +// A''[x, y] = xor(B[x, y], andn(B[x + 1, y], B[x + 2, y])). +// A''[0, 0] is additionally xor'd with RC. +const START_A_PRIME_PRIME: usize = START_A_PRIME + 5 * 5 * 64; +pub(crate) const fn reg_a_prime_prime(x: usize, y: usize) -> usize { + debug_assert!(x < 5); + debug_assert!(y < 5); + START_A_PRIME_PRIME + x * 2 * 5 + y * 2 +} + +const START_A_PRIME_PRIME_0_0_BITS: usize = START_A_PRIME_PRIME + 5 * 5 * 2; +pub(crate) const fn reg_a_prime_prime_0_0_bit(i: usize) -> usize { + debug_assert!(i < 64); + START_A_PRIME_PRIME_0_0_BITS + i +} + +const REG_A_PRIME_PRIME_PRIME_0_0_LO: usize = START_A_PRIME_PRIME_0_0_BITS + 64; +const REG_A_PRIME_PRIME_PRIME_0_0_HI: usize = REG_A_PRIME_PRIME_PRIME_0_0_LO + 1; + +pub(crate) const fn reg_a_prime_prime_prime(x: usize, y: usize) -> usize { + debug_assert!(x < 5); + debug_assert!(y < 5); + if x == 0 && y == 0 { + REG_A_PRIME_PRIME_PRIME_0_0_LO + } else { + reg_a_prime_prime(x, y) + } +} + +pub(crate) const NUM_REGISTERS: usize = REG_A_PRIME_PRIME_PRIME_0_0_HI + 1; diff --git a/evm/src/keccak/round_flags.rs b/evm/src/keccak/round_flags.rs new file mode 100644 index 00000000..63128ba1 --- /dev/null +++ b/evm/src/keccak/round_flags.rs @@ -0,0 +1,40 @@ +use plonky2::field::extension_field::Extendable; +use plonky2::field::field_types::Field; +use plonky2::field::packed_field::PackedField; +use plonky2::hash::hash_types::RichField; +use plonky2::plonk::circuit_builder::CircuitBuilder; + +use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; +use crate::keccak::keccak_stark::{NUM_PUBLIC_INPUTS, NUM_ROUNDS}; +use crate::keccak::registers::reg_step; +use crate::keccak::registers::NUM_REGISTERS; +use crate::vars::StarkEvaluationTargets; +use crate::vars::StarkEvaluationVars; + +pub(crate) fn eval_round_flags>( + vars: StarkEvaluationVars, + yield_constr: &mut ConstraintConsumer

, +) { + // Initially, the first step flag should be 1 while the others should be 0. + yield_constr.constraint_first_row(vars.local_values[reg_step(0)] - F::ONE); + for i in 1..NUM_ROUNDS { + yield_constr.constraint_first_row(vars.local_values[reg_step(i)]); + } + + // TODO: Transition. +} + +pub(crate) fn eval_round_flags_recursively, const D: usize>( + builder: &mut CircuitBuilder, + vars: StarkEvaluationTargets, + yield_constr: &mut RecursiveConstraintConsumer, +) { + let one = builder.one_extension(); + + // Initially, the first step flag should be 1 while the others should be 0. + let step_0_minus_1 = builder.sub_extension(vars.local_values[reg_step(0)], one); + yield_constr.constraint_first_row(builder, step_0_minus_1); + for i in 1..NUM_ROUNDS { + yield_constr.constraint_first_row(builder, vars.local_values[reg_step(i)]); + } +} From 2c285ca2cd16b9b7a291e6cb73c4b931719a405d Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 6 Jun 2022 10:31:42 -0700 Subject: [PATCH 03/31] fixes and debugging --- evm/src/all_stark.rs | 41 +++++++----- evm/src/keccak/keccak_stark.rs | 115 +++++++++++++++++++-------------- 2 files changed, 90 insertions(+), 66 deletions(-) diff --git a/evm/src/all_stark.rs b/evm/src/all_stark.rs index 4ef79314..a943e99c 100644 --- a/evm/src/all_stark.rs +++ b/evm/src/all_stark.rs @@ -49,6 +49,7 @@ impl Table { #[cfg(test)] mod tests { use anyhow::Result; + use itertools::Itertools; use plonky2::field::field_types::Field; use plonky2::field::polynomial::PolynomialValues; use plonky2::iop::witness::PartialWitness; @@ -62,7 +63,7 @@ mod tests { use crate::cpu; use crate::cpu::cpu_stark::CpuStark; use crate::cross_table_lookup::CrossTableLookup; - use crate::keccak::keccak_stark::KeccakStark; + use crate::keccak::keccak_stark::{KeccakStark, NUM_ROUNDS, INPUT_LIMBS}; use crate::proof::AllProof; use crate::prover::prove; use crate::recursive_verifier::{ @@ -80,29 +81,35 @@ mod tests { let cpu_stark = CpuStark:: { f: Default::default(), }; - let cpu_rows = 256; + let cpu_rows = 1 << 6; let keccak_stark = KeccakStark:: { f: Default::default(), }; - let keccak_rows = 256; - let keccak_looked_col = 3; + let keccak_rows = (NUM_ROUNDS + 1).next_power_of_two(); - let mut cpu_trace_rows = vec![]; - for i in 0..cpu_rows { - let mut cpu_trace_row = [F::ZERO; CpuStark::::COLUMNS]; - cpu_trace_row[cpu::columns::IS_CPU_CYCLE] = F::ONE; - cpu_trace_row[cpu::columns::OPCODE] = F::from_canonical_usize(i); - cpu_stark.generate(&mut cpu_trace_row); - cpu_trace_rows.push(cpu_trace_row); - } - let cpu_trace = trace_rows_to_poly_values(cpu_trace_rows); + let mut cpu_trace = vec![PolynomialValues::::zero(cpu_rows); 10]; + + let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); - let mut keccak_trace = - vec![PolynomialValues::zero(keccak_rows); KeccakStark::::COLUMNS]; - keccak_trace[keccak_looked_col] = cpu_trace[cpu::columns::OPCODE].clone(); + let num_inpts = 1; + let keccak_inputs = (0..num_inpts) + .map(|_| [0u64; INPUT_LIMBS].map(|_| rng.gen())) + .collect_vec(); + let keccak_trace = keccak_stark.generate_trace(keccak_inputs); + + let vs0: Vec<_> = keccak_trace[3].values[..].into(); + let vs1: Vec<_> = keccak_trace[5].values[..].into(); + + let start = thread_rng().gen_range(0..cpu_rows - keccak_rows); + + let default = vec![F::ONE; 2]; + + cpu_trace[2].values = vec![default[0]; cpu_rows]; + cpu_trace[2].values[start..start + keccak_rows].copy_from_slice(&vs0); + cpu_trace[4].values = vec![default[1]; cpu_rows]; + cpu_trace[4].values[start..start + keccak_rows].copy_from_slice(&vs1); - let default = vec![F::ZERO; 2]; let cross_table_lookups = vec![CrossTableLookup { looking_tables: vec![Table::Cpu], looking_columns: vec![vec![cpu::columns::OPCODE]], diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index dfaca5cd..3fbc7b94 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -29,7 +29,7 @@ pub(crate) const NUM_ROUNDS: usize = 24; /// Number of 64-bit limbs in a preimage of the Keccak permutation. pub(crate) const INPUT_LIMBS: usize = 25; -pub(crate) const NUM_PUBLIC_INPUTS: usize = 4; +pub(crate) const NUM_PUBLIC_INPUTS: usize = 0; #[derive(Copy, Clone)] pub struct KeccakStark { @@ -39,14 +39,15 @@ pub struct KeccakStark { impl, const D: usize> KeccakStark { /// Generate the rows of the trace. Note that this does not generate the permuted columns used /// in our lookup arguments, as those are computed after transposing to column-wise form. - fn generate_trace_rows(&self, inputs: Vec<[u64; INPUT_LIMBS]>) -> Vec<[F; NUM_REGISTERS]> { + pub(crate) fn generate_trace_rows(&self, inputs: Vec<[u64; INPUT_LIMBS]>) -> Vec<[F; NUM_REGISTERS]> { let num_rows = (inputs.len() * NUM_ROUNDS).next_power_of_two(); info!("{} rows", num_rows); let mut rows = Vec::with_capacity(num_rows); - for input in inputs { - rows.extend(self.generate_trace_rows_for_perm(input)); + for input in inputs.iter().take(1) { + rows.extend(self.generate_trace_rows_for_perm(input.clone())); } + // Pad rows to power of two. for i in rows.len()..num_rows { let mut row = [F::ZERO; NUM_REGISTERS]; self.generate_trace_rows_for_round(&mut row, i % NUM_ROUNDS); @@ -59,8 +60,8 @@ impl, const D: usize> KeccakStark { fn generate_trace_rows_for_perm( &self, input: [u64; INPUT_LIMBS], - ) -> [[F; NUM_REGISTERS]; NUM_ROUNDS] { - let mut rows = [[F::ZERO; NUM_REGISTERS]; NUM_ROUNDS]; + ) -> Vec<[F; NUM_REGISTERS]> { + let mut rows = vec![[F::ZERO; NUM_REGISTERS]; NUM_ROUNDS]; for x in 0..5 { for y in 0..5 { @@ -73,7 +74,24 @@ impl, const D: usize> KeccakStark { self.generate_trace_rows_for_round(&mut rows[0], 0); for round in 1..24 { - // TODO: Populate input from prev. row output. + for x in 0..5 { + for y in 0..5 { + let cur = rows[round - 1][reg_a_prime_prime_prime(x, y)]; + let cur_u64 = cur.to_canonical_u64(); + let bit_values: Vec = (0..64) + .scan(cur_u64, |acc, _| { + let tmp = *acc % 2; + *acc /= 2; + Some(tmp) + }) + .collect(); + + for z in 0..64 { + rows[round][reg_a(x, y, z)] = F::from_canonical_u64(bit_values[z]); + } + } + } + rows[round] = rows[round - 1].clone(); self.generate_trace_rows_for_round(&mut rows[round], round); } @@ -81,7 +99,7 @@ impl, const D: usize> KeccakStark { } fn generate_trace_rows_for_round(&self, row: &mut [F; NUM_REGISTERS], round: usize) { - row[round] = F::ONE; + row[reg_step(round)] = F::ONE; // Populate C partial and C. for x in 0..5 { @@ -113,24 +131,23 @@ impl, const D: usize> KeccakStark { // A''[x, y] = xor(B[x, y], andn(B[x + 1, y], B[x + 2, y])). for x in 0..5 { for y in 0..5 { - let get_bit = |z| { - xor([ - row[reg_b(x, y, z)], - andn(row[reg_b((x + 1) % 5, y, z)], row[reg_b((x + 2) % 5, y, z)]), - ]) - }; + // let get_bit = |z| { + + // // xor([ + // // row[reg_b(x, y, z)], + // // andn(row[reg_b((x + 1) % 5, y, z)], row[reg_b((x + 2) % 5, y, z)]), + // // ]) + // }; - let lo = (0..32) - .rev() - .fold(F::ZERO, |acc, z| acc.double() + get_bit(z)); - let hi = (32..64) - .rev() - .fold(F::ZERO, |acc, z| acc.double() + get_bit(z)); + let lo = F::ZERO;//row[reg_b(x, y, 0)]; + // let hi = (32..64) + // .rev() + // .fold(F::ZERO, |acc, z| acc.double() + get_bit(z)); let reg_lo = reg_a_prime_prime(x, y); let reg_hi = reg_lo + 1; row[reg_lo] = lo; - row[reg_hi] = hi; + // row[reg_hi] = hi; } } @@ -223,28 +240,28 @@ impl, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark Date: Wed, 1 Jun 2022 09:20:39 -0700 Subject: [PATCH 04/31] fmt --- evm/src/all_stark.rs | 8 ++++---- evm/src/keccak/keccak_stark.rs | 36 +++++++++++++++++----------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/evm/src/all_stark.rs b/evm/src/all_stark.rs index a943e99c..00344646 100644 --- a/evm/src/all_stark.rs +++ b/evm/src/all_stark.rs @@ -63,7 +63,7 @@ mod tests { use crate::cpu; use crate::cpu::cpu_stark::CpuStark; use crate::cross_table_lookup::CrossTableLookup; - use crate::keccak::keccak_stark::{KeccakStark, NUM_ROUNDS, INPUT_LIMBS}; + use crate::keccak::keccak_stark::{KeccakStark, INPUT_LIMBS, NUM_ROUNDS}; use crate::proof::AllProof; use crate::prover::prove; use crate::recursive_verifier::{ @@ -89,7 +89,7 @@ mod tests { let keccak_rows = (NUM_ROUNDS + 1).next_power_of_two(); let mut cpu_trace = vec![PolynomialValues::::zero(cpu_rows); 10]; - + let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); let num_inpts = 1; @@ -97,10 +97,10 @@ mod tests { .map(|_| [0u64; INPUT_LIMBS].map(|_| rng.gen())) .collect_vec(); let keccak_trace = keccak_stark.generate_trace(keccak_inputs); - + let vs0: Vec<_> = keccak_trace[3].values[..].into(); let vs1: Vec<_> = keccak_trace[5].values[..].into(); - + let start = thread_rng().gen_range(0..cpu_rows - keccak_rows); let default = vec![F::ONE; 2]; diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index 3fbc7b94..a6b0b162 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -39,7 +39,10 @@ pub struct KeccakStark { impl, const D: usize> KeccakStark { /// Generate the rows of the trace. Note that this does not generate the permuted columns used /// in our lookup arguments, as those are computed after transposing to column-wise form. - pub(crate) fn generate_trace_rows(&self, inputs: Vec<[u64; INPUT_LIMBS]>) -> Vec<[F; NUM_REGISTERS]> { + pub(crate) fn generate_trace_rows( + &self, + inputs: Vec<[u64; INPUT_LIMBS]>, + ) -> Vec<[F; NUM_REGISTERS]> { let num_rows = (inputs.len() * NUM_ROUNDS).next_power_of_two(); info!("{} rows", num_rows); let mut rows = Vec::with_capacity(num_rows); @@ -57,10 +60,7 @@ impl, const D: usize> KeccakStark { rows } - fn generate_trace_rows_for_perm( - &self, - input: [u64; INPUT_LIMBS], - ) -> Vec<[F; NUM_REGISTERS]> { + fn generate_trace_rows_for_perm(&self, input: [u64; INPUT_LIMBS]) -> Vec<[F; NUM_REGISTERS]> { let mut rows = vec![[F::ZERO; NUM_REGISTERS]; NUM_ROUNDS]; for x in 0..5 { @@ -132,17 +132,17 @@ impl, const D: usize> KeccakStark { for x in 0..5 { for y in 0..5 { // let get_bit = |z| { - + // // xor([ // // row[reg_b(x, y, z)], // // andn(row[reg_b((x + 1) % 5, y, z)], row[reg_b((x + 2) % 5, y, z)]), // // ]) // }; - let lo = F::ZERO;//row[reg_b(x, y, 0)]; - // let hi = (32..64) - // .rev() - // .fold(F::ZERO, |acc, z| acc.double() + get_bit(z)); + let lo = F::ZERO; //row[reg_b(x, y, 0)]; + // let hi = (32..64) + // .rev() + // .fold(F::ZERO, |acc, z| acc.double() + get_bit(z)); let reg_lo = reg_a_prime_prime(x, y); let reg_hi = reg_lo + 1; @@ -241,11 +241,11 @@ impl, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark Date: Fri, 27 May 2022 10:55:58 -0700 Subject: [PATCH 05/31] fix --- evm/src/keccak/keccak_stark.rs | 61 ++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index a6b0b162..638d6371 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -131,33 +131,36 @@ impl, const D: usize> KeccakStark { // A''[x, y] = xor(B[x, y], andn(B[x + 1, y], B[x + 2, y])). for x in 0..5 { for y in 0..5 { - // let get_bit = |z| { + let get_bit = |z| { + xor([ + row[reg_b(x, y, z)], + andn(row[reg_b((x + 1) % 5, y, z)], row[reg_b((x + 2) % 5, y, z)]), + ]) + }; - // // xor([ - // // row[reg_b(x, y, z)], - // // andn(row[reg_b((x + 1) % 5, y, z)], row[reg_b((x + 2) % 5, y, z)]), - // // ]) - // }; - - let lo = F::ZERO; //row[reg_b(x, y, 0)]; - // let hi = (32..64) - // .rev() - // .fold(F::ZERO, |acc, z| acc.double() + get_bit(z)); + let lo = (0..32) + .rev() + .fold(F::ZERO, |acc, z| acc.double() + get_bit(z)); + let hi = (32..64) + .rev() + .fold(F::ZERO, |acc, z| acc.double() + get_bit(z)); let reg_lo = reg_a_prime_prime(x, y); let reg_hi = reg_lo + 1; row[reg_lo] = lo; - // row[reg_hi] = hi; + row[reg_hi] = hi; } } // A''[0, 0] is additionally xor'd with RC. - let reg_lo = reg_a_prime_prime(0, 0); - let reg_hi = reg_lo + 1; + let in_reg_lo = reg_a_prime_prime(0, 0); + let in_reg_hi = in_reg_lo + 1; + let out_reg_lo = reg_a_prime_prime_prime(0, 0); + let out_reg_hi = out_reg_lo + 1; let rc_lo = rc_value(round) % (1 << 32); let rc_hi = rc_value(round) >> 32; - row[reg_lo] = F::from_canonical_u64(row[reg_lo].to_canonical_u64() ^ rc_lo); - row[reg_hi] = F::from_canonical_u64(row[reg_hi].to_canonical_u64() ^ rc_hi); + row[out_reg_lo] = F::from_canonical_u64(row[in_reg_lo].to_canonical_u64() ^ rc_lo); + row[out_reg_hi] = F::from_canonical_u64(row[in_reg_hi].to_canonical_u64() ^ rc_hi); } pub fn generate_trace(&self, inputs: Vec<[u64; INPUT_LIMBS]>) -> Vec> { @@ -240,28 +243,28 @@ impl, const D: usize> Stark for KeccakStark Date: Fri, 27 May 2022 14:55:59 -0700 Subject: [PATCH 06/31] fix --- evm/src/keccak/keccak_stark.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index 638d6371..511e2479 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -152,6 +152,21 @@ impl, const D: usize> KeccakStark { } } + // For the XOR, we split A''[0, 0] to bits. + let val_lo = row[reg_a_prime_prime(0, 0)].to_canonical_u64(); + let val_hi = row[reg_a_prime_prime(0, 0) + 1].to_canonical_u64(); + let val = val_lo + (1 << 32) * val_hi; + let bit_values: Vec = (0..64) + .scan(val, |acc, _| { + let tmp = *acc % 2; + *acc /= 2; + Some(tmp) + }) + .collect(); + for i in 0..64 { + row[reg_a_prime_prime_0_0_bit(i)] = F::from_canonical_u64(bit_values[i]); + } + // A''[0, 0] is additionally xor'd with RC. let in_reg_lo = reg_a_prime_prime(0, 0); let in_reg_hi = in_reg_lo + 1; @@ -280,8 +295,8 @@ impl, const D: usize> Stark for KeccakStark Date: Fri, 27 May 2022 15:20:47 -0700 Subject: [PATCH 07/31] fix --- evm/src/keccak/keccak_stark.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index 511e2479..6b90dbc1 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -91,7 +91,6 @@ impl, const D: usize> KeccakStark { } } } - rows[round] = rows[round - 1].clone(); self.generate_trace_rows_for_round(&mut rows[round], round); } @@ -318,8 +317,8 @@ impl, const D: usize> Stark for KeccakStark Date: Wed, 1 Jun 2022 09:19:23 -0700 Subject: [PATCH 08/31] fixes --- evm/src/keccak/keccak_stark.rs | 84 ++++++++++++++++++++-------------- evm/src/keccak/registers.rs | 7 ++- 2 files changed, 56 insertions(+), 35 deletions(-) diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index 6b90dbc1..54ce7f89 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -16,7 +16,7 @@ use crate::keccak::logic::{ }; use crate::keccak::registers::{ rc_value, rc_value_bit, reg_a, reg_a_prime, reg_a_prime_prime, reg_a_prime_prime_0_0_bit, - reg_a_prime_prime_prime, reg_b, reg_c, reg_c_partial, reg_step, NUM_REGISTERS, + reg_a_prime_prime_prime, reg_b, reg_c, reg_c_partial, reg_step, NUM_REGISTERS, reg_dummy, }; use crate::keccak::round_flags::{eval_round_flags, eval_round_flags_recursively}; use crate::stark::Stark; @@ -54,6 +54,7 @@ impl, const D: usize> KeccakStark { for i in rows.len()..num_rows { let mut row = [F::ZERO; NUM_REGISTERS]; self.generate_trace_rows_for_round(&mut row, i % NUM_ROUNDS); + row[reg_dummy()] = F::ONE; rows.push(row); } @@ -74,29 +75,34 @@ impl, const D: usize> KeccakStark { self.generate_trace_rows_for_round(&mut rows[0], 0); for round in 1..24 { - for x in 0..5 { - for y in 0..5 { - let cur = rows[round - 1][reg_a_prime_prime_prime(x, y)]; - let cur_u64 = cur.to_canonical_u64(); - let bit_values: Vec = (0..64) - .scan(cur_u64, |acc, _| { - let tmp = *acc % 2; - *acc /= 2; - Some(tmp) - }) - .collect(); - - for z in 0..64 { - rows[round][reg_a(x, y, z)] = F::from_canonical_u64(bit_values[z]); - } - } - } + self.copy_output_to_input(rows[round - 1], &mut rows[round]); self.generate_trace_rows_for_round(&mut rows[round], round); } rows } + fn copy_output_to_input(&self, prev_row: [F; NUM_REGISTERS], next_row: &mut [F; NUM_REGISTERS]) { + for x in 0..5 { + for y in 0..5 { + let cur_lo = prev_row[reg_a_prime_prime_prime(x, y)]; + let cur_hi = prev_row[reg_a_prime_prime_prime(x, y) + 1]; + let cur_u64 = cur_lo.to_canonical_u64() + (1 << 32) * cur_hi.to_canonical_u64(); + let bit_values: Vec = (0..64) + .scan(cur_u64, |acc, _| { + let tmp = *acc % 2; + *acc /= 2; + Some(tmp) + }) + .collect(); + + for z in 0..64 { + next_row[reg_a(x, y, z)] = F::from_canonical_u64(bit_values[z]); + } + } + } + } + fn generate_trace_rows_for_round(&self, row: &mut [F; NUM_REGISTERS], round: usize) { row[reg_step(round)] = F::ONE; @@ -323,14 +329,20 @@ impl, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark usize { i } +/// A register which is set to 1 if we are in the `i`th round, otherwise 0. +pub(crate) const fn reg_dummy() -> usize { + NUM_ROUNDS +} + const R: [[u8; 5]; 5] = [ [0, 18, 41, 3, 36], [1, 2, 45, 10, 44], @@ -172,7 +177,7 @@ pub(crate) const fn rc_value(round: usize) -> u64 { RC[round] } -const START_A: usize = NUM_ROUNDS; +const START_A: usize = NUM_ROUNDS + 1; pub(crate) const fn reg_a(x: usize, y: usize, z: usize) -> usize { debug_assert!(x < 5); debug_assert!(y < 5); From ac18c39044b5dd1a13e949b244cab21e70389100 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Wed, 1 Jun 2022 09:19:30 -0700 Subject: [PATCH 09/31] fmt --- evm/src/keccak/keccak_stark.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index 54ce7f89..56586e6e 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -16,7 +16,7 @@ use crate::keccak::logic::{ }; use crate::keccak::registers::{ rc_value, rc_value_bit, reg_a, reg_a_prime, reg_a_prime_prime, reg_a_prime_prime_0_0_bit, - reg_a_prime_prime_prime, reg_b, reg_c, reg_c_partial, reg_step, NUM_REGISTERS, reg_dummy, + reg_a_prime_prime_prime, reg_b, reg_c, reg_c_partial, reg_dummy, reg_step, NUM_REGISTERS, }; use crate::keccak::round_flags::{eval_round_flags, eval_round_flags_recursively}; use crate::stark::Stark; @@ -82,7 +82,11 @@ impl, const D: usize> KeccakStark { rows } - fn copy_output_to_input(&self, prev_row: [F; NUM_REGISTERS], next_row: &mut [F; NUM_REGISTERS]) { + fn copy_output_to_input( + &self, + prev_row: [F; NUM_REGISTERS], + next_row: &mut [F; NUM_REGISTERS], + ) { for x in 0..5 { for y in 0..5 { let cur_lo = prev_row[reg_a_prime_prime_prime(x, y)]; @@ -341,8 +345,12 @@ impl, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark Date: Wed, 1 Jun 2022 12:25:38 -0700 Subject: [PATCH 10/31] fix --- evm/src/keccak/keccak_stark.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index 56586e6e..ea2a61b4 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -497,9 +497,9 @@ impl, const D: usize> Stark for KeccakStark Date: Wed, 1 Jun 2022 14:05:35 -0700 Subject: [PATCH 11/31] fix yay --- evm/src/keccak/keccak_stark.rs | 30 +++++++++++++++++++++++++----- evm/src/keccak/registers.rs | 7 +------ 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index ea2a61b4..6e58f73c 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -16,7 +16,7 @@ use crate::keccak::logic::{ }; use crate::keccak::registers::{ rc_value, rc_value_bit, reg_a, reg_a_prime, reg_a_prime_prime, reg_a_prime_prime_0_0_bit, - reg_a_prime_prime_prime, reg_b, reg_c, reg_c_partial, reg_dummy, reg_step, NUM_REGISTERS, + reg_a_prime_prime_prime, reg_b, reg_c, reg_c_partial, reg_step, NUM_REGISTERS, }; use crate::keccak::round_flags::{eval_round_flags, eval_round_flags_recursively}; use crate::stark::Stark; @@ -53,8 +53,8 @@ impl, const D: usize> KeccakStark { // Pad rows to power of two. for i in rows.len()..num_rows { let mut row = [F::ZERO; NUM_REGISTERS]; + self.copy_output_to_input(rows[i - 1], &mut row); self.generate_trace_rows_for_round(&mut row, i % NUM_ROUNDS); - row[reg_dummy()] = F::ONE; rows.push(row); } @@ -344,12 +344,11 @@ impl, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark usize { diff --git a/evm/src/keccak/registers.rs b/evm/src/keccak/registers.rs index 2c328447..f3e847b1 100644 --- a/evm/src/keccak/registers.rs +++ b/evm/src/keccak/registers.rs @@ -6,11 +6,6 @@ pub(crate) const fn reg_step(i: usize) -> usize { i } -/// A register which is set to 1 if we are in the `i`th round, otherwise 0. -pub(crate) const fn reg_dummy() -> usize { - NUM_ROUNDS -} - const R: [[u8; 5]; 5] = [ [0, 18, 41, 3, 36], [1, 2, 45, 10, 44], @@ -177,7 +172,7 @@ pub(crate) const fn rc_value(round: usize) -> u64 { RC[round] } -const START_A: usize = NUM_ROUNDS + 1; +const START_A: usize = NUM_ROUNDS; pub(crate) const fn reg_a(x: usize, y: usize, z: usize) -> usize { debug_assert!(x < 5); debug_assert!(y < 5); From 9fbae06b61ebed3ceb3da32d5bc30ee101aa3664 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Wed, 1 Jun 2022 14:06:31 -0700 Subject: [PATCH 12/31] fmt --- evm/src/keccak/keccak_stark.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index 6e58f73c..147d393c 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -344,12 +344,8 @@ impl, const D: usize> Stark for KeccakStark Date: Fri, 3 Jun 2022 11:32:19 -0700 Subject: [PATCH 13/31] fixes, cleanup, and correctness test --- evm/Cargo.toml | 1 + evm/src/keccak/keccak_stark.rs | 71 +++++++++++++++++++++++----------- evm/src/keccak/registers.rs | 14 +++---- 3 files changed, 56 insertions(+), 30 deletions(-) diff --git a/evm/Cargo.toml b/evm/Cargo.toml index d65fb30c..e282583e 100644 --- a/evm/Cargo.toml +++ b/evm/Cargo.toml @@ -14,3 +14,4 @@ log = "0.4.14" rayon = "1.5.1" rand = "0.8.5" rand_chacha = "0.3.1" +keccak-rust = { git = "https://github.com/npwardberkeley/keccak-rust" } \ No newline at end of file diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index 147d393c..87787e31 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -130,7 +130,7 @@ impl, const D: usize> KeccakStark { row[reg_a_prime(x, y, z)] = xor([ row[reg_a(x, y, z)], row[reg_c((x + 4) % 5, z)], - row[reg_c((x + 1) % 5, (z + 1) % 64)], + row[reg_c((x + 1) % 5, (z + 64 - 1) % 64)], ]); } } @@ -358,12 +358,8 @@ impl, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark usize { @@ -528,9 +507,13 @@ impl, const D: usize> Stark for KeccakStark(stark) } + + #[test] + fn keccak_correctness_test() -> Result<()> { + let mut input: Vec = Vec::new(); + let mut rng = rand::thread_rng(); + for _ in 0..INPUT_LIMBS { + input.push(rng.gen()); + } + + const D: usize = 2; + type C = PoseidonGoldilocksConfig; + type F = >::F; + type S = KeccakStark; + + let stark = S { + f: Default::default(), + }; + + let rows = stark.generate_trace_rows(vec![input.clone().try_into().unwrap()]); + let last_row = rows[23]; + let mut output = Vec::new(); + let base = F::from_canonical_u64(1 << 32); + for x in 0..5 { + for y in 0..5 { + output.push(last_row[reg_a_prime_prime_prime(x, y)] + base * last_row[reg_a_prime_prime_prime(x, y) + 1]); + } + } + + let mut expected: [[u64; 5]; 5] = [input[0..5].try_into().unwrap(), + input[5..10].try_into().unwrap(), + input[10..15].try_into().unwrap(), + input[15..20].try_into().unwrap(), + input[20..25].try_into().unwrap()]; + + let keccak = KeccakF::new(StateBitsWidth::F1600); + keccak.permutations(&mut expected); + let expected_flattened: Vec<_> = expected.iter().flatten().map(|&x| F::from_canonical_u64(x)).collect(); + + assert_eq!(output, expected_flattened); + + Ok(()) + } } diff --git a/evm/src/keccak/registers.rs b/evm/src/keccak/registers.rs index f3e847b1..9a851eec 100644 --- a/evm/src/keccak/registers.rs +++ b/evm/src/keccak/registers.rs @@ -7,11 +7,11 @@ pub(crate) const fn reg_step(i: usize) -> usize { } const R: [[u8; 5]; 5] = [ - [0, 18, 41, 3, 36], - [1, 2, 45, 10, 44], - [62, 61, 15, 43, 6], - [28, 56, 21, 25, 55], - [27, 14, 8, 39, 20], + [0, 36, 3, 41, 18], + [1, 44, 10, 45, 2], + [62, 6, 43, 15, 61], + [28, 55, 25, 21, 56], + [27, 20, 39, 8, 14], ]; const RC: [u64; 24] = [ @@ -218,11 +218,10 @@ pub(crate) const fn reg_b(x: usize, y: usize, z: usize) -> usize { let a = (x + 3 * y) % 5; let b = x; let rot = R[a][b] as usize; - reg_a_prime(a, b, (z + rot) % 64) + reg_a_prime(a, b, (z + 64 - rot) % 64) } // A''[x, y] = xor(B[x, y], andn(B[x + 1, y], B[x + 2, y])). -// A''[0, 0] is additionally xor'd with RC. const START_A_PRIME_PRIME: usize = START_A_PRIME + 5 * 5 * 64; pub(crate) const fn reg_a_prime_prime(x: usize, y: usize) -> usize { debug_assert!(x < 5); @@ -239,6 +238,7 @@ pub(crate) const fn reg_a_prime_prime_0_0_bit(i: usize) -> usize { const REG_A_PRIME_PRIME_PRIME_0_0_LO: usize = START_A_PRIME_PRIME_0_0_BITS + 64; const REG_A_PRIME_PRIME_PRIME_0_0_HI: usize = REG_A_PRIME_PRIME_PRIME_0_0_LO + 1; +// A'''[0, 0] is additionally xor'd with RC. pub(crate) const fn reg_a_prime_prime_prime(x: usize, y: usize) -> usize { debug_assert!(x < 5); debug_assert!(y < 5); From dc082139c55bc2bbd86c7ef27d523ccc0008efe9 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Fri, 3 Jun 2022 11:32:27 -0700 Subject: [PATCH 14/31] fmt --- evm/src/keccak/keccak_stark.rs | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index 87787e31..37cce52a 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -508,8 +508,8 @@ impl, const D: usize> Stark for KeccakStark = expected.iter().flatten().map(|&x| F::from_canonical_u64(x)).collect(); + let expected_flattened: Vec<_> = expected + .iter() + .flatten() + .map(|&x| F::from_canonical_u64(x)) + .collect(); assert_eq!(output, expected_flattened); From 52afdae55162b5a11919d028592505c6b7588363 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 6 Jun 2022 08:36:13 -0700 Subject: [PATCH 15/31] cleanup --- evm/src/keccak/keccak_stark.rs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index 37cce52a..3d0641ac 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -512,12 +512,11 @@ mod tests { use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use rand::Rng; - use crate::keccak::keccak_stark::{KeccakStark, INPUT_LIMBS}; + use crate::keccak::keccak_stark::{KeccakStark, INPUT_LIMBS, NUM_ROUNDS}; use crate::keccak::registers::reg_a_prime_prime_prime; use crate::stark_testing::{test_stark_circuit_constraints, test_stark_low_degree}; #[test] - #[ignore] // TODO: remove this when constraints are no longer all 0. fn test_stark_degree() -> Result<()> { const D: usize = 2; type C = PoseidonGoldilocksConfig; @@ -545,11 +544,7 @@ mod tests { #[test] fn keccak_correctness_test() -> Result<()> { - let mut input: Vec = Vec::new(); - let mut rng = rand::thread_rng(); - for _ in 0..INPUT_LIMBS { - input.push(rng.gen()); - } + let input: [u64; INPUT_LIMBS] = rand::random(); const D: usize = 2; type C = PoseidonGoldilocksConfig; @@ -561,7 +556,7 @@ mod tests { }; let rows = stark.generate_trace_rows(vec![input.clone().try_into().unwrap()]); - let last_row = rows[23]; + let last_row = rows[NUM_ROUNDS - 1]; let mut output = Vec::new(); let base = F::from_canonical_u64(1 << 32); for x in 0..5 { @@ -573,7 +568,7 @@ mod tests { } } - let mut expected: [[u64; 5]; 5] = [ + let mut keccak_input: [[u64; 5]; 5] = [ input[0..5].try_into().unwrap(), input[5..10].try_into().unwrap(), input[10..15].try_into().unwrap(), @@ -582,14 +577,14 @@ mod tests { ]; let keccak = KeccakF::new(StateBitsWidth::F1600); - keccak.permutations(&mut expected); - let expected_flattened: Vec<_> = expected + keccak.permutations(&mut keccak_input); + let expected: Vec<_> = keccak_input .iter() .flatten() .map(|&x| F::from_canonical_u64(x)) .collect(); - assert_eq!(output, expected_flattened); + assert_eq!(output, expected); Ok(()) } From 78b2a5ebeff142044d5fbd3fe05459980dd54e61 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 6 Jun 2022 10:00:40 -0700 Subject: [PATCH 16/31] fixed constraints, in line with generator --- evm/src/keccak/keccak_stark.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index 3d0641ac..53fed3b8 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -251,7 +251,7 @@ impl, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark Date: Mon, 6 Jun 2022 12:50:56 -0700 Subject: [PATCH 17/31] trying to fix CTL --- evm/src/all_stark.rs | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/evm/src/all_stark.rs b/evm/src/all_stark.rs index 00344646..3119489b 100644 --- a/evm/src/all_stark.rs +++ b/evm/src/all_stark.rs @@ -51,12 +51,13 @@ mod tests { use anyhow::Result; use itertools::Itertools; use plonky2::field::field_types::Field; - use plonky2::field::polynomial::PolynomialValues; use plonky2::iop::witness::PartialWitness; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2::util::timing::TimingTree; + use rand::{SeedableRng, Rng}; + use rand_chacha::ChaCha8Rng; use crate::all_stark::{AllStark, Table}; use crate::config::StarkConfig; @@ -81,34 +82,37 @@ mod tests { let cpu_stark = CpuStark:: { f: Default::default(), }; - let cpu_rows = 1 << 6; + let cpu_rows = 256; let keccak_stark = KeccakStark:: { f: Default::default(), }; let keccak_rows = (NUM_ROUNDS + 1).next_power_of_two(); - - let mut cpu_trace = vec![PolynomialValues::::zero(cpu_rows); 10]; + let keccak_looked_col = 3; let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); - - let num_inpts = 1; - let keccak_inputs = (0..num_inpts) + let num_inputs = 1; + let keccak_inputs = (0..num_inputs) .map(|_| [0u64; INPUT_LIMBS].map(|_| rng.gen())) .collect_vec(); let keccak_trace = keccak_stark.generate_trace(keccak_inputs); - - let vs0: Vec<_> = keccak_trace[3].values[..].into(); - let vs1: Vec<_> = keccak_trace[5].values[..].into(); - - let start = thread_rng().gen_range(0..cpu_rows - keccak_rows); + let column_to_copy: Vec<_> = keccak_trace[keccak_looked_col].values[..].into(); let default = vec![F::ONE; 2]; - cpu_trace[2].values = vec![default[0]; cpu_rows]; - cpu_trace[2].values[start..start + keccak_rows].copy_from_slice(&vs0); - cpu_trace[4].values = vec![default[1]; cpu_rows]; - cpu_trace[4].values[start..start + keccak_rows].copy_from_slice(&vs1); + let mut cpu_trace_rows = vec![]; + for i in 0..cpu_rows { + let mut cpu_trace_row = [F::ZERO; CpuStark::::COLUMNS]; + cpu_trace_row[cpu::columns::IS_CPU_CYCLE] = F::ONE; + if i < keccak_rows { + cpu_trace_row[cpu::columns::OPCODE] = column_to_copy[i]; + } else { + cpu_trace_row[cpu::columns::OPCODE] = default[0]; + } + cpu_stark.generate(&mut cpu_trace_row); + cpu_trace_rows.push(cpu_trace_row); + } + let cpu_trace = trace_rows_to_poly_values(cpu_trace_rows); let cross_table_lookups = vec![CrossTableLookup { looking_tables: vec![Table::Cpu], From 08bda49b70552f5068b355a638b56967e5544e74 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 6 Jun 2022 12:51:09 -0700 Subject: [PATCH 18/31] fmt --- evm/src/all_stark.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm/src/all_stark.rs b/evm/src/all_stark.rs index 3119489b..0626d359 100644 --- a/evm/src/all_stark.rs +++ b/evm/src/all_stark.rs @@ -56,7 +56,7 @@ mod tests { use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2::util::timing::TimingTree; - use rand::{SeedableRng, Rng}; + use rand::{Rng, SeedableRng}; use rand_chacha::ChaCha8Rng; use crate::all_stark::{AllStark, Table}; From a4300fb6f707d4e9be6b0884081ccdeada4619f0 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 6 Jun 2022 14:12:58 -0700 Subject: [PATCH 19/31] fix --- evm/src/all_stark.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm/src/all_stark.rs b/evm/src/all_stark.rs index 0626d359..4cc95e20 100644 --- a/evm/src/all_stark.rs +++ b/evm/src/all_stark.rs @@ -98,7 +98,7 @@ mod tests { let keccak_trace = keccak_stark.generate_trace(keccak_inputs); let column_to_copy: Vec<_> = keccak_trace[keccak_looked_col].values[..].into(); - let default = vec![F::ONE; 2]; + let default = vec![F::ONE; 1]; let mut cpu_trace_rows = vec![]; for i in 0..cpu_rows { From c39e927d5270a3c616422100fd8ee3df30c276bf Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 6 Jun 2022 14:37:21 -0700 Subject: [PATCH 20/31] added check on length of --- evm/src/all_stark.rs | 12 ++++++------ evm/src/cross_table_lookup.rs | 11 ++++++----- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/evm/src/all_stark.rs b/evm/src/all_stark.rs index 4cc95e20..2361f798 100644 --- a/evm/src/all_stark.rs +++ b/evm/src/all_stark.rs @@ -114,13 +114,13 @@ mod tests { } let cpu_trace = trace_rows_to_poly_values(cpu_trace_rows); - let cross_table_lookups = vec![CrossTableLookup { - looking_tables: vec![Table::Cpu], - looking_columns: vec![vec![cpu::columns::OPCODE]], - looked_table: Table::Keccak, - looked_columns: vec![keccak_looked_col], + let cross_table_lookups = vec![CrossTableLookup::new( + vec![Table::Cpu], + vec![vec![cpu::columns::OPCODE]], + Table::Keccak, + vec![keccak_looked_col], default, - }]; + )]; let all_stark = AllStark { cpu_stark, diff --git a/evm/src/cross_table_lookup.rs b/evm/src/cross_table_lookup.rs index f4887b68..1f89f7b9 100644 --- a/evm/src/cross_table_lookup.rs +++ b/evm/src/cross_table_lookup.rs @@ -23,11 +23,11 @@ use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars}; #[derive(Clone)] pub struct CrossTableLookup { - pub looking_tables: Vec, - pub looking_columns: Vec>, - pub looked_table: Table, - pub looked_columns: Vec, - pub default: Vec, + looking_tables: Vec
, + looking_columns: Vec>, + looked_table: Table, + looked_columns: Vec, + default: Vec, } impl CrossTableLookup { @@ -42,6 +42,7 @@ impl CrossTableLookup { assert!(looking_columns .iter() .all(|cols| cols.len() == looked_columns.len())); + assert!(default.len() == looked_columns.len()); Self { looking_tables, looking_columns, From f0ed391865438080f7a651b344f61257bfba97e7 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 6 Jun 2022 14:41:54 -0700 Subject: [PATCH 21/31] clippy --- evm/src/keccak/keccak_stark.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index 53fed3b8..dc7468a7 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -47,7 +47,7 @@ impl, const D: usize> KeccakStark { info!("{} rows", num_rows); let mut rows = Vec::with_capacity(num_rows); for input in inputs.iter().take(1) { - rows.extend(self.generate_trace_rows_for_perm(input.clone())); + rows.extend(self.generate_trace_rows_for_perm(*input)); } // Pad rows to power of two. @@ -422,8 +422,8 @@ impl, const D: usize> Stark for KeccakStark, const D: usize> Stark for KeccakStark Date: Mon, 6 Jun 2022 16:23:05 -0700 Subject: [PATCH 22/31] constants crate --- evm/src/keccak/constants.rs | 157 ++++++++++++++++++++++++++++++++ evm/src/keccak/keccak_stark.rs | 3 +- evm/src/keccak/mod.rs | 1 + evm/src/keccak/registers.rs | 158 --------------------------------- 4 files changed, 160 insertions(+), 159 deletions(-) create mode 100644 evm/src/keccak/constants.rs diff --git a/evm/src/keccak/constants.rs b/evm/src/keccak/constants.rs new file mode 100644 index 00000000..72286237 --- /dev/null +++ b/evm/src/keccak/constants.rs @@ -0,0 +1,157 @@ +const RC: [u64; 24] = [ + 0x0000000000000001, + 0x0000000000008082, + 0x800000000000808A, + 0x8000000080008000, + 0x000000000000808B, + 0x0000000080000001, + 0x8000000080008081, + 0x8000000000008009, + 0x000000000000008A, + 0x0000000000000088, + 0x0000000080008009, + 0x000000008000000A, + 0x000000008000808B, + 0x800000000000008B, + 0x8000000000008089, + 0x8000000000008003, + 0x8000000000008002, + 0x8000000000000080, + 0x000000000000800A, + 0x800000008000000A, + 0x8000000080008081, + 0x8000000000008080, + 0x0000000080000001, + 0x8000000080008008, +]; + +const RC_BITS: [[u8; 64]; 24] = [ + [ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], + [ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ], + [ + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ], +]; + +pub(crate) const fn rc_value_bit(round: usize, bit_index: usize) -> u8 { + RC_BITS[round][bit_index] +} + +pub(crate) const fn rc_value(round: usize) -> u64 { + RC[round] +} diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index dc7468a7..10d4cbd0 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -11,11 +11,12 @@ use plonky2::timed; use plonky2::util::timing::TimingTree; use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; +use crate::keccak::constants::{rc_value, rc_value_bit}; use crate::keccak::logic::{ andn, andn_gen, andn_gen_circuit, xor, xor3_gen, xor3_gen_circuit, xor_gen, xor_gen_circuit, }; use crate::keccak::registers::{ - rc_value, rc_value_bit, reg_a, reg_a_prime, reg_a_prime_prime, reg_a_prime_prime_0_0_bit, + reg_a, reg_a_prime, reg_a_prime_prime, reg_a_prime_prime_0_0_bit, reg_a_prime_prime_prime, reg_b, reg_c, reg_c_partial, reg_step, NUM_REGISTERS, }; use crate::keccak::round_flags::{eval_round_flags, eval_round_flags_recursively}; diff --git a/evm/src/keccak/mod.rs b/evm/src/keccak/mod.rs index 41985c2a..2d104339 100644 --- a/evm/src/keccak/mod.rs +++ b/evm/src/keccak/mod.rs @@ -1,3 +1,4 @@ +pub mod constants; pub mod keccak_stark; pub mod logic; pub mod registers; diff --git a/evm/src/keccak/registers.rs b/evm/src/keccak/registers.rs index 9a851eec..3a891828 100644 --- a/evm/src/keccak/registers.rs +++ b/evm/src/keccak/registers.rs @@ -14,164 +14,6 @@ const R: [[u8; 5]; 5] = [ [27, 20, 39, 8, 14], ]; -const RC: [u64; 24] = [ - 0x0000000000000001, - 0x0000000000008082, - 0x800000000000808A, - 0x8000000080008000, - 0x000000000000808B, - 0x0000000080000001, - 0x8000000080008081, - 0x8000000000008009, - 0x000000000000008A, - 0x0000000000000088, - 0x0000000080008009, - 0x000000008000000A, - 0x000000008000808B, - 0x800000000000008B, - 0x8000000000008089, - 0x8000000000008003, - 0x8000000000008002, - 0x8000000000000080, - 0x000000000000800A, - 0x800000008000000A, - 0x8000000080008081, - 0x8000000000008080, - 0x0000000080000001, - 0x8000000080008008, -]; - -const RC_BITS: [[u8; 64]; 24] = [ - [ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, - ], - [ - 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, - ], - [ - 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ], - [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ], - [ - 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, - ], - [ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, - ], - [ - 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ], - [ - 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ], - [ - 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, - ], - [ - 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, - ], - [ - 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, - ], - [ - 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, - ], - [ - 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, - ], - [ - 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ], - [ - 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ], - [ - 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ], - [ - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ], - [ - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ], - [ - 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, - ], - [ - 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ], - [ - 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ], - [ - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ], - [ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, - ], - [ - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ], -]; - -pub(crate) const fn rc_value_bit(round: usize, bit_index: usize) -> u8 { - RC_BITS[round][bit_index] -} - -pub(crate) const fn rc_value(round: usize) -> u64 { - RC[round] -} - const START_A: usize = NUM_ROUNDS; pub(crate) const fn reg_a(x: usize, y: usize, z: usize) -> usize { debug_assert!(x < 5); From 9d118ca1ef493321eebf2053e7909ac6b432a00c Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 6 Jun 2022 17:25:53 -0700 Subject: [PATCH 23/31] fix --- evm/src/keccak/keccak_stark.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index 10d4cbd0..6c2674b4 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -47,7 +47,7 @@ impl, const D: usize> KeccakStark { let num_rows = (inputs.len() * NUM_ROUNDS).next_power_of_two(); info!("{} rows", num_rows); let mut rows = Vec::with_capacity(num_rows); - for input in inputs.iter().take(1) { + for input in inputs.iter() { rows.extend(self.generate_trace_rows_for_perm(*input)); } From cacc073e4ec95ada985fb836ac51e6e83428d529 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 6 Jun 2022 17:28:44 -0700 Subject: [PATCH 24/31] fix --- evm/src/keccak/keccak_stark.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index 6c2674b4..1631460f 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -74,10 +74,10 @@ impl, const D: usize> KeccakStark { } } - self.generate_trace_rows_for_round(&mut rows[0], 0); + self.generate_trace_row_for_round(&mut rows[0], 0); for round in 1..24 { self.copy_output_to_input(rows[round - 1], &mut rows[round]); - self.generate_trace_rows_for_round(&mut rows[round], round); + self.generate_trace_row_for_round(&mut rows[round], round); } rows @@ -108,7 +108,7 @@ impl, const D: usize> KeccakStark { } } - fn generate_trace_rows_for_round(&self, row: &mut [F; NUM_REGISTERS], round: usize) { + fn generate_trace_row_for_round(&self, row: &mut [F; NUM_REGISTERS], round: usize) { row[reg_step(round)] = F::ONE; // Populate C partial and C. From 3b9cb7a9cf8151783d2e513fb69f624a4d45c3fa Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 6 Jun 2022 17:28:52 -0700 Subject: [PATCH 25/31] fmt --- evm/src/keccak/keccak_stark.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index 1631460f..b4279671 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -16,8 +16,8 @@ use crate::keccak::logic::{ andn, andn_gen, andn_gen_circuit, xor, xor3_gen, xor3_gen_circuit, xor_gen, xor_gen_circuit, }; use crate::keccak::registers::{ - reg_a, reg_a_prime, reg_a_prime_prime, reg_a_prime_prime_0_0_bit, - reg_a_prime_prime_prime, reg_b, reg_c, reg_c_partial, reg_step, NUM_REGISTERS, + reg_a, reg_a_prime, reg_a_prime_prime, reg_a_prime_prime_0_0_bit, reg_a_prime_prime_prime, + reg_b, reg_c, reg_c_partial, reg_step, NUM_REGISTERS, }; use crate::keccak::round_flags::{eval_round_flags, eval_round_flags_recursively}; use crate::stark::Stark; From 8b37d5d25a2b5edbb54b3f9cbfc865d507167391 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 6 Jun 2022 17:29:23 -0700 Subject: [PATCH 26/31] fix --- evm/src/keccak/keccak_stark.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index b4279671..de3f8b0e 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -55,7 +55,7 @@ impl, const D: usize> KeccakStark { for i in rows.len()..num_rows { let mut row = [F::ZERO; NUM_REGISTERS]; self.copy_output_to_input(rows[i - 1], &mut row); - self.generate_trace_rows_for_round(&mut row, i % NUM_ROUNDS); + self.generate_trace_row_for_round(&mut row, i % NUM_ROUNDS); rows.push(row); } From 67167d8e03663c8f89951eba7985dadac341abb4 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 7 Jun 2022 08:51:57 -0700 Subject: [PATCH 27/31] use bit operations --- evm/src/all_stark.rs | 1 + evm/src/keccak/keccak_stark.rs | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/evm/src/all_stark.rs b/evm/src/all_stark.rs index 2361f798..c3c9653c 100644 --- a/evm/src/all_stark.rs +++ b/evm/src/all_stark.rs @@ -114,6 +114,7 @@ mod tests { } let cpu_trace = trace_rows_to_poly_values(cpu_trace_rows); + // TODO: temporary until cross-table-lookup filters are implemented let cross_table_lookups = vec![CrossTableLookup::new( vec![Table::Cpu], vec![vec![cpu::columns::OPCODE]], diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index de3f8b0e..66947ffb 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -92,11 +92,11 @@ impl, const D: usize> KeccakStark { for y in 0..5 { let cur_lo = prev_row[reg_a_prime_prime_prime(x, y)]; let cur_hi = prev_row[reg_a_prime_prime_prime(x, y) + 1]; - let cur_u64 = cur_lo.to_canonical_u64() + (1 << 32) * cur_hi.to_canonical_u64(); + let cur_u64 = cur_lo.to_canonical_u64() | (cur_hi.to_canonical_u64() << 32); let bit_values: Vec = (0..64) .scan(cur_u64, |acc, _| { - let tmp = *acc % 2; - *acc /= 2; + let tmp = *acc & 1; + *acc >>= 1; Some(tmp) }) .collect(); @@ -165,11 +165,11 @@ impl, const D: usize> KeccakStark { // For the XOR, we split A''[0, 0] to bits. let val_lo = row[reg_a_prime_prime(0, 0)].to_canonical_u64(); let val_hi = row[reg_a_prime_prime(0, 0) + 1].to_canonical_u64(); - let val = val_lo + (1 << 32) * val_hi; + let val = val_lo | (val_hi << 32); let bit_values: Vec = (0..64) .scan(val, |acc, _| { - let tmp = *acc % 2; - *acc /= 2; + let tmp = *acc & 1; + *acc >>= 1; Some(tmp) }) .collect(); @@ -182,7 +182,7 @@ impl, const D: usize> KeccakStark { let in_reg_hi = in_reg_lo + 1; let out_reg_lo = reg_a_prime_prime_prime(0, 0); let out_reg_hi = out_reg_lo + 1; - let rc_lo = rc_value(round) % (1 << 32); + let rc_lo = rc_value(round) & (1 << 32 - 1); let rc_hi = rc_value(round) >> 32; row[out_reg_lo] = F::from_canonical_u64(row[in_reg_lo].to_canonical_u64() ^ rc_lo); row[out_reg_hi] = F::from_canonical_u64(row[in_reg_hi].to_canonical_u64() ^ rc_hi); From 1ad8ec5f330637a425ace50504edc352d5b843fc Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 7 Jun 2022 09:41:32 -0700 Subject: [PATCH 28/31] fix --- evm/src/keccak/keccak_stark.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm/src/keccak/keccak_stark.rs b/evm/src/keccak/keccak_stark.rs index 66947ffb..cbc2408b 100644 --- a/evm/src/keccak/keccak_stark.rs +++ b/evm/src/keccak/keccak_stark.rs @@ -182,7 +182,7 @@ impl, const D: usize> KeccakStark { let in_reg_hi = in_reg_lo + 1; let out_reg_lo = reg_a_prime_prime_prime(0, 0); let out_reg_hi = out_reg_lo + 1; - let rc_lo = rc_value(round) & (1 << 32 - 1); + let rc_lo = rc_value(round) & ((1 << 32) - 1); let rc_hi = rc_value(round) >> 32; row[out_reg_lo] = F::from_canonical_u64(row[in_reg_lo].to_canonical_u64() ^ rc_lo); row[out_reg_hi] = F::from_canonical_u64(row[in_reg_hi].to_canonical_u64() ^ rc_hi); From 315d0882041218c24a78b69fa906339774d16148 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 7 Jun 2022 13:58:49 -0700 Subject: [PATCH 29/31] ignore silly clippy warning --- evm/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/evm/src/lib.rs b/evm/src/lib.rs index bd8ca5f3..e0f04e04 100644 --- a/evm/src/lib.rs +++ b/evm/src/lib.rs @@ -1,4 +1,5 @@ #![allow(incomplete_features)] +#![allow(clippy::needless_range_loop)] #![allow(clippy::too_many_arguments)] #![allow(clippy::type_complexity)] #![feature(generic_const_exprs)] From 9c6e65091605bcce9fe0f22eabfd603d2e8a5c0a Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 7 Jun 2022 14:15:28 -0700 Subject: [PATCH 30/31] moved allow to local --- evm/src/all_stark.rs | 1 + evm/src/lib.rs | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/evm/src/all_stark.rs b/evm/src/all_stark.rs index c3c9653c..4e8002a8 100644 --- a/evm/src/all_stark.rs +++ b/evm/src/all_stark.rs @@ -100,6 +100,7 @@ mod tests { let default = vec![F::ONE; 1]; + #[allow(clippy::needless_range_loop)] let mut cpu_trace_rows = vec![]; for i in 0..cpu_rows { let mut cpu_trace_row = [F::ZERO; CpuStark::::COLUMNS]; diff --git a/evm/src/lib.rs b/evm/src/lib.rs index e0f04e04..bd8ca5f3 100644 --- a/evm/src/lib.rs +++ b/evm/src/lib.rs @@ -1,5 +1,4 @@ #![allow(incomplete_features)] -#![allow(clippy::needless_range_loop)] #![allow(clippy::too_many_arguments)] #![allow(clippy::type_complexity)] #![feature(generic_const_exprs)] From 85d84a130fcb89c4d8925ada422241c7c997c33d Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 7 Jun 2022 14:20:51 -0700 Subject: [PATCH 31/31] moved back haha --- evm/src/all_stark.rs | 1 - evm/src/lib.rs | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/evm/src/all_stark.rs b/evm/src/all_stark.rs index 4e8002a8..c3c9653c 100644 --- a/evm/src/all_stark.rs +++ b/evm/src/all_stark.rs @@ -100,7 +100,6 @@ mod tests { let default = vec![F::ONE; 1]; - #[allow(clippy::needless_range_loop)] let mut cpu_trace_rows = vec![]; for i in 0..cpu_rows { let mut cpu_trace_row = [F::ZERO; CpuStark::::COLUMNS]; diff --git a/evm/src/lib.rs b/evm/src/lib.rs index bd8ca5f3..e0f04e04 100644 --- a/evm/src/lib.rs +++ b/evm/src/lib.rs @@ -1,4 +1,5 @@ #![allow(incomplete_features)] +#![allow(clippy::needless_range_loop)] #![allow(clippy::too_many_arguments)] #![allow(clippy::type_complexity)] #![feature(generic_const_exprs)]