diff --git a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/input_generators/opcode_tester_input_generator.hpp b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/input_generators/opcode_tester_input_generator.hpp index 6a3d8aee8..246e0db5d 100644 --- a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/input_generators/opcode_tester_input_generator.hpp +++ b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/input_generators/opcode_tester_input_generator.hpp @@ -385,6 +385,20 @@ namespace nil { stack.push_back(result); pc++; gas -= 3; + }else if(opcode == zkevm_opcode::SHL) { + //0x1d + zkevm_word_type a = stack.back(); + stack.pop_back(); + _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, false, a)); + zkevm_word_type b = stack.back(); + stack.pop_back(); + _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, false, b)); + int shift = (integral_type(b) < 256) ? int(integral_type(b)) : 256; + zkevm_word_type result = zkevm_word_type(integral_type(a) << shift); + _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, true, result)); + stack.push_back(result); + pc++; + gas -= 3; } else { std::cout << "Opcode tester machine doesn't contain " << opcode << " implementation" << std::endl; BOOST_ASSERT(false); diff --git a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/addmod.hpp b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/addmod.hpp index 9b334fc32..bdbf29b5c 100644 --- a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/addmod.hpp +++ b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/addmod.hpp @@ -128,9 +128,8 @@ namespace nil { public: zkevm_addmod_bbf(context_type &context_object, - const opcode_input_type ¤t_state, - bool make_links = true) - : generic_component(context_object), res(chunk_amount) { + const opcode_input_type ¤t_state) + : generic_component(context_object,false), res(chunk_amount) { using integral_type = boost::multiprecision::number< boost::multiprecision::backends::cpp_int_modular_backend<257>>; diff --git a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/mulmod.hpp b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/mulmod.hpp index 08a11dae5..2564f3ead 100644 --- a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/mulmod.hpp +++ b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/mulmod.hpp @@ -45,7 +45,6 @@ namespace nil { using generic_component::lookup_table; using value_type = typename FieldType::value_type; - using var = crypto3::zk::snark::plonk_variable; constexpr static const std::size_t chunk_amount = 16; constexpr static const std::size_t carry_amount = 16 / 3 + 1; @@ -138,9 +137,8 @@ namespace nil { public: zkevm_mulmod_bbf(context_type &context_object, - const opcode_input_type ¤t_state, - bool make_links = true) - : generic_component(context_object), res(chunk_amount) { + const opcode_input_type ¤t_state) + : generic_component(context_object,false), res(chunk_amount) { using integral_type = boost::multiprecision::number< boost::multiprecision::backends::cpp_int_modular_backend<257>>; using extended_integral_type = boost::multiprecision::number< diff --git a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/shl.hpp b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/shl.hpp index 53edde4c4..4a1e79a6d 100644 --- a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/shl.hpp +++ b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/shl.hpp @@ -1,5 +1,6 @@ //---------------------------------------------------------------------------// // Copyright (c) 2024 Alexey Yashunsky +// Copyright (c) 2024 Antoine Cyr // // MIT License // @@ -24,33 +25,331 @@ #pragma once -#include #include - +#include #include #include +#include namespace nil { namespace blueprint { - namespace bbf{ + namespace bbf { template class opcode_abstract; + template + class zkevm_shl_bbf : public generic_component { + using generic_component::allocate; + using generic_component::copy_constrain; + using generic_component::constrain; + using generic_component::lookup; + using generic_component::lookup_table; + + using value_type = typename FieldType::value_type; + + constexpr static const std::size_t chunk_amount = 16; + constexpr static const value_type two_16 = 65536; + constexpr static const value_type two_32 = 4294967296; + constexpr static const value_type two_48 = 281474976710656; + constexpr static const value_type two_64 = 0x10000000000000000_cppui_modular254; + constexpr static const value_type two_128 = + 0x100000000000000000000000000000000_cppui_modular254; + constexpr static const value_type two_192 = + 0x1000000000000000000000000000000000000000000000000_cppui_modular254; + + public: + using typename generic_component::TYPE; + using typename generic_component::context_type; + + template + T chunk_sum_64(const std::vector &chunks, const unsigned char chunk_idx) const { + BOOST_ASSERT(chunk_idx < 4); + return chunks[4 * chunk_idx] + chunks[4 * chunk_idx + 1] * two_16 + + chunks[4 * chunk_idx + 2] * two_32 + chunks[4 * chunk_idx + 3] * two_48; + } + + template + T first_carryless_consrtruct(const std::vector &a_64_chunks, + const std::vector &b_64_chunks, + const std::vector &r_64_chunks) const { + return a_64_chunks[0] * b_64_chunks[0] + + two_64 * + (a_64_chunks[0] * b_64_chunks[1] + a_64_chunks[1] * b_64_chunks[0]) - + r_64_chunks[0] - two_64 * r_64_chunks[1]; + } + + template + T second_carryless_construct(const std::vector &a_64_chunks, + const std::vector &b_64_chunks, + const std::vector &r_64_chunks) { + return (a_64_chunks[0] * b_64_chunks[2] + a_64_chunks[1] * b_64_chunks[1] + + a_64_chunks[2] * b_64_chunks[0] - r_64_chunks[2]) + + two_64 * + (a_64_chunks[0] * b_64_chunks[3] + a_64_chunks[1] * b_64_chunks[2] + + a_64_chunks[2] * b_64_chunks[1] + a_64_chunks[3] * b_64_chunks[0] - + r_64_chunks[3]); + } + + std::vector res; + + public: + zkevm_shl_bbf(context_type &context_object, + const opcode_input_type ¤t_state) + : generic_component(context_object, false), + res(chunk_amount) { + using integral_type = boost::multiprecision::number< + boost::multiprecision::backends::cpp_int_modular_backend<257>>; + + TYPE first_carryless; + TYPE second_carryless; + + TYPE b0p; + TYPE b0pp; + TYPE b0ppp; + TYPE b0p_range_check; + TYPE b0pp_range_check; + TYPE b0ppp_range_check; + TYPE I1; + TYPE I2; + TYPE z; + TYPE tp; + TYPE two_powers; + TYPE sum_b; + + std::vector a_64_chunks(4); + std::vector b_64_chunks(4); + std::vector r_64_chunks(4); + + std::vector c_1_chunks(4); + std::vector c_3_chunks(4); + TYPE c_1; + TYPE c_2; + TYPE c_3; + TYPE c_4; + + TYPE c_1_64; + TYPE c_3_64; + + std::vector input_b_chunks(chunk_amount); + std::vector a_chunks(chunk_amount); + std::vector b_chunks(chunk_amount); + std::vector r_chunks(chunk_amount); + + if constexpr (stage == GenerationStage::ASSIGNMENT) { + zkevm_word_type a = current_state.stack_top(); + zkevm_word_type input_b = current_state.stack_top(1); + + int shift = + (integral_type(input_b) < 256) ? int(integral_type(input_b)) : 256; + + zkevm_word_type result = zkevm_word_type(integral_type(a) << shift); + + zkevm_word_type b = zkevm_word_type(integral_type(1) << shift); + + input_b_chunks = zkevm_word_to_field_element(input_b); + a_chunks = zkevm_word_to_field_element(a); + b_chunks = zkevm_word_to_field_element(b); + r_chunks = zkevm_word_to_field_element(result); + + b0p = integral_type(input_b) % 16; + b0pp = (integral_type(input_b) / 16) % 16; + b0ppp = (integral_type(input_b) % 65536) / 256; + I1 = b0ppp.is_zero() ? 0 : b0ppp.inversed(); + + sum_b = 0; + for (std::size_t i = 1; i < chunk_amount; i++) { + sum_b += input_b_chunks[i]; + } + I2 = sum_b.is_zero() ? 0 : sum_b.inversed(); + z = (1 - b0ppp * I1) * + (1 - sum_b * I2); // z is zero if input_b >= 256, otherwise it is 1 + two_powers = + (static_cast(1) << int(integral_type(input_b) % 16)); + tp = z * two_powers; + + // note that we don't assign 64-chunks for a/b, as we can build them from + // 16-chunks with constraints under the same logic we only assign the 16 - + // bit + + // chunks for carries + for (std::size_t i = 0; i < 4; i++) { + a_64_chunks.push_back(chunk_sum_64(a_chunks, i)); + b_64_chunks.push_back(chunk_sum_64(b_chunks, i)); + r_64_chunks.push_back(chunk_sum_64(r_chunks, i)); + } + // caluclate first row carries + first_carryless = + first_carryless_consrtruct(a_64_chunks, b_64_chunks, r_64_chunks); + auto first_row_carries = + first_carryless_consrtruct(a_64_chunks, b_64_chunks, r_64_chunks) + .data >> + 128; + c_1 = static_cast(first_row_carries & (two_64 - 1).data); + c_2 = static_cast(first_row_carries >> 64); + c_1_chunks = chunk_64_to_16(c_1); + // no need for c_2 chunks as there is only a single chunk + second_carryless = + second_carryless_construct(a_64_chunks, b_64_chunks, r_64_chunks); + auto second_row_carries = + (second_carryless_construct(a_64_chunks, b_64_chunks, r_64_chunks) + + c_1 + c_2 * two_64) + .data >> + 128; + c_3 = static_cast(second_row_carries & (two_64 - 1).data); + c_4 = static_cast(second_row_carries >> 64); + c_3_chunks = chunk_64_to_16(c_3); + + c_1_64 = chunk_sum_64(c_1_chunks, 0); + c_3_64 = chunk_sum_64(c_3_chunks, 0); + + // lookup constrain b0p < 16, b0pp < 16, b0ppp < 256 + b0p_range_check = 4096 * b0p; + b0pp_range_check = 4096 * b0pp; + b0ppp_range_check = 256 * b0ppp; + } + + allocate(b0p_range_check, 0, 2); + allocate(b0pp_range_check, 1, 2); + allocate(b0ppp_range_check, 2, 2); + + for (std::size_t i = 0; i < chunk_amount; i++) { + allocate(a_chunks[i], i, 0); + allocate(b_chunks[i], i + chunk_amount, 0); + allocate(input_b_chunks[i], i, 1); + allocate(r_chunks[i], i + chunk_amount, 1); + res[i] = r_chunks[i]; + } + + allocate(tp, 32, 0); + allocate(z, 33, 0); + allocate(I1, 34, 0); + allocate(I2, 35, 0); + allocate(two_powers, 36, 0); + + constrain(tp - z * two_powers); + + allocate(b0p, 32, 1); + allocate(b0pp, 33, 1); + allocate(b0ppp, 34, 1); + allocate(sum_b, 35, 1); + + constrain(input_b_chunks[0] - b0p - 16 * b0pp - 256 * b0ppp); + constrain(b0ppp * (1 - b0ppp * I1)); + + constrain(sum_b * (1 - sum_b * I2)); + constrain((z - (1 - b0ppp * I1) * (1 - sum_b * I2))); + + allocate(first_carryless, 32, 2); + allocate(second_carryless, 33, 2); + allocate(c_1_64, 34, 2); + allocate(c_2, 35, 2); + allocate(c_3_64, 36, 2); + allocate(c_4, 37, 2); + + constrain(first_carryless - c_1_64 * two_128 - c_2 * two_192); + constrain(second_carryless + c_1_64 + c_2 * two_64 - c_3_64 * two_128 - + c_4 * two_192); + // add constraints for c_2/c_4: c_2 is 0/1, c_4 is 0/1/2/3 + constrain(c_2 * (c_2 - 1)); + constrain(c_4 * (c_4 - 1) * (c_4 - 2) * (c_4 - 3)); + + auto A_128 = chunks16_to_chunks128_reversed(a_chunks); + auto B_128 = chunks16_to_chunks128_reversed(input_b_chunks); + auto Res_128 = chunks16_to_chunks128_reversed(res); + + TYPE A0, A1, B0, B1, Res0, Res1; + if constexpr (stage == GenerationStage::ASSIGNMENT) { + A0 = A_128.first; + A1 = A_128.second; + B0 = B_128.first; + B1 = B_128.second; + Res0 = Res_128.first; + Res1 = Res_128.second; + } + allocate(A0, 37, 0); + allocate(A1, 37, 1); + allocate(B0, 38, 0); + allocate(B1, 38, 1); + allocate(Res0, 39, 0); + allocate(Res1, 39, 1); + + constrain(A0 - A_128.first); + constrain(A1 - A_128.second); + constrain(B0 - B_128.first); + constrain(B1 - B_128.second); + constrain(Res0 - Res_128.first); + constrain(Res1 - Res_128.second); + + if constexpr (stage == GenerationStage::CONSTRAINTS) { + constrain(current_state.pc_next() - current_state.pc(3) - + 1); // PC transition + constrain(current_state.gas(3) - current_state.gas_next() - + 3); // GAS transition + constrain(current_state.stack_size(3) - current_state.stack_size_next() - + 1); // stack_size transition + constrain(current_state.memory_size(3) - + current_state.memory_size_next()); // memory_size transition + constrain(current_state.rw_counter_next() - current_state.rw_counter(3) - + 3); // rw_counter transition + std::vector tmp; + tmp = {TYPE(rw_op_to_num(rw_operation_type::stack)), + current_state.call_id(1), + current_state.stack_size(1) - 1, + TYPE(0), // storage_key_hi + TYPE(0), // storage_key_lo + TYPE(0), // field + current_state.rw_counter(1), + TYPE(0), // is_write + A0, + A1}; + lookup(tmp, "zkevm_rw"); + tmp = {TYPE(rw_op_to_num(rw_operation_type::stack)), + current_state.call_id(1), + current_state.stack_size(1) - 2, + TYPE(0), // storage_key_hi + TYPE(0), // storage_key_lo + TYPE(0), // field + current_state.rw_counter(1) + 1, + TYPE(0), // is_write + B0, + B1}; + lookup(tmp, "zkevm_rw"); + tmp = {TYPE(rw_op_to_num(rw_operation_type::stack)), + current_state.call_id(1), + current_state.stack_size(1) - 2, + TYPE(0), // storage_key_hi + TYPE(0), // storage_key_lo + TYPE(0), // field + current_state.rw_counter(1) + 2, + TYPE(1), // is_write + Res0, + Res1}; + lookup(tmp, "zkevm_rw"); + } + } + }; + template class zkevm_shl_operation : public opcode_abstract { - public: + public: virtual void fill_context( - typename generic_component::context_type &context, - const opcode_input_type ¤t_state - ) {} + typename generic_component::context_type + &context, + const opcode_input_type + ¤t_state) { + zkevm_shl_bbf bbf_obj(context, + current_state); + } virtual void fill_context( - typename generic_component::context_type &context, - const opcode_input_type ¤t_state - ) {} - virtual std::size_t rows_amount() override { - return 4; + typename generic_component::context_type &context, + const opcode_input_type + ¤t_state) { + zkevm_shl_bbf bbf_obj(context, + current_state); } + virtual std::size_t rows_amount() override { return 4; } }; - } // namespace bbf - } // namespace blueprint -} // namespace nil + } // namespace bbf + } // namespace blueprint +} // namespace nil diff --git a/crypto3/libs/blueprint/test/CMakeLists.txt b/crypto3/libs/blueprint/test/CMakeLists.txt index 3847371a4..fa66fa5f4 100644 --- a/crypto3/libs/blueprint/test/CMakeLists.txt +++ b/crypto3/libs/blueprint/test/CMakeLists.txt @@ -232,6 +232,7 @@ set(ZKEVM_BBF_TESTS_FILES "zkevm_bbf/opcodes/iszero" "zkevm_bbf/opcodes/mod_ops" "zkevm_bbf/opcodes/bitwise" + "zkevm_bbf/opcodes/byte_ops" ) diff --git a/crypto3/libs/blueprint/test/zkevm_bbf/opcodes/byte_ops.cpp b/crypto3/libs/blueprint/test/zkevm_bbf/opcodes/byte_ops.cpp new file mode 100644 index 000000000..b509bfd3a --- /dev/null +++ b/crypto3/libs/blueprint/test/zkevm_bbf/opcodes/byte_ops.cpp @@ -0,0 +1,264 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2024 Alexey Yashunsky +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#define BOOST_TEST_MODULE zkevm_bbf_byte_ops_test + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../test_l1_wrapper.hpp" + +using namespace nil::blueprint; +using namespace nil::crypto3::algebra; + +BOOST_AUTO_TEST_SUITE(zkevm_byte_ops_test_suite) + +BOOST_AUTO_TEST_CASE(zkevm_byte_ops_test) { + using field_type = typename algebra::curves::pallas::base_field_type; + zkevm_opcode_tester opcode_tester; + + l1_size_restrictions max_sizes; + + // incorrect test logic, but we have no memory operations so + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0xFb70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::BYTE); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0xFb70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::SIGNEXTEND); + opcode_tester.push_opcode( + zkevm_opcode::PUSH32, + zwordc( + 0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + opcode_tester.push_opcode( + zkevm_opcode::PUSH32, + zwordc( + 0xFb70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::SHL); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0xFb70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::SHR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0xFb70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::SAR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x8b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,0); + // opcode_tester.push_opcode(zkevm_opcode::BYTE); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x8b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,0); + // opcode_tester.push_opcode(zkevm_opcode::SIGNEXTEND); + opcode_tester.push_opcode( + zkevm_opcode::PUSH32, + zwordc( + 0x8b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, 0); + opcode_tester.push_opcode(zkevm_opcode::SHL); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x8b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,0); + // opcode_tester.push_opcode(zkevm_opcode::SHR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x8b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,0); + // opcode_tester.push_opcode(zkevm_opcode::SAR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x8b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,10); + // opcode_tester.push_opcode(zkevm_opcode::BYTE); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x8b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,10); + // opcode_tester.push_opcode(zkevm_opcode::SIGNEXTEND); + opcode_tester.push_opcode( + zkevm_opcode::PUSH32, + zwordc( + 0x8b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, 10); + opcode_tester.push_opcode(zkevm_opcode::SHL); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x8b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,10); + // opcode_tester.push_opcode(zkevm_opcode::SHR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x8b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,10); + // opcode_tester.push_opcode(zkevm_opcode::SAR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x8b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,257); + // opcode_tester.push_opcode(zkevm_opcode::BYTE); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x8b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,257); + // opcode_tester.push_opcode(zkevm_opcode::SIGNEXTEND); + opcode_tester.push_opcode( + zkevm_opcode::PUSH32, + zwordc( + 0x8b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, 257); + opcode_tester.push_opcode(zkevm_opcode::SHL); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x8b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,257); + // opcode_tester.push_opcode(zkevm_opcode::SHR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x8b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,257); + // opcode_tester.push_opcode(zkevm_opcode::SAR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x8b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,65538); + // opcode_tester.push_opcode(zkevm_opcode::BYTE); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x8b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,65538); + // opcode_tester.push_opcode(zkevm_opcode::SIGNEXTEND); + opcode_tester.push_opcode( + zkevm_opcode::PUSH32, + zwordc( + 0x8b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, 65538); + opcode_tester.push_opcode(zkevm_opcode::SHL); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x8b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,65538); + // opcode_tester.push_opcode(zkevm_opcode::SHR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x8b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,65538); + // opcode_tester.push_opcode(zkevm_opcode::SAR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,10); + // opcode_tester.push_opcode(zkevm_opcode::BYTE); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,10); + // opcode_tester.push_opcode(zkevm_opcode::SIGNEXTEND); + opcode_tester.push_opcode( + zkevm_opcode::PUSH32, + zwordc( + 0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, 10); + opcode_tester.push_opcode(zkevm_opcode::SHL); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,10); + // opcode_tester.push_opcode(zkevm_opcode::SHR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,10); + // opcode_tester.push_opcode(zkevm_opcode::SAR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,30); + // opcode_tester.push_opcode(zkevm_opcode::BYTE); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,30); + // opcode_tester.push_opcode(zkevm_opcode::SIGNEXTEND); + opcode_tester.push_opcode( + zkevm_opcode::PUSH32, + zwordc( + 0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, 30); + opcode_tester.push_opcode(zkevm_opcode::SHL); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,30); + // opcode_tester.push_opcode(zkevm_opcode::SHR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,30); + // opcode_tester.push_opcode(zkevm_opcode::SAR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,50); + // opcode_tester.push_opcode(zkevm_opcode::BYTE); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,50); + // opcode_tester.push_opcode(zkevm_opcode::SIGNEXTEND); + opcode_tester.push_opcode( + zkevm_opcode::PUSH32, + zwordc( + 0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, 50); + opcode_tester.push_opcode(zkevm_opcode::SHL); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,50); + // opcode_tester.push_opcode(zkevm_opcode::SHR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,50); + // opcode_tester.push_opcode(zkevm_opcode::SAR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1234567890_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,1); + // opcode_tester.push_opcode(zkevm_opcode::BYTE); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1234567890_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,1); + // opcode_tester.push_opcode(zkevm_opcode::SIGNEXTEND); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, zwordc(0x1234567890_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, 1); + opcode_tester.push_opcode(zkevm_opcode::SHL); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1234567890_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,1); + // opcode_tester.push_opcode(zkevm_opcode::SHR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1234567890_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,1); + // opcode_tester.push_opcode(zkevm_opcode::SAR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1234567890_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,31); + // opcode_tester.push_opcode(zkevm_opcode::BYTE); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1234567890_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,31); + // opcode_tester.push_opcode(zkevm_opcode::SIGNEXTEND); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, zwordc(0x1234567890_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, 31); + opcode_tester.push_opcode(zkevm_opcode::SHL); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1234567890_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,31); + // opcode_tester.push_opcode(zkevm_opcode::SHR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1234567890_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,31); + // opcode_tester.push_opcode(zkevm_opcode::SAR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x33_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::SAR); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x33_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::PUSH32,zwordc(0x1_cppui_modular257)); + // opcode_tester.push_opcode(zkevm_opcode::SHR); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, zwordc(0x33_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, zwordc(0x1_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::SHL); + + opcode_tester.push_opcode(zkevm_opcode::STOP); + + max_sizes.max_keccak_blocks = 10; + max_sizes.max_bytecode = 3000; + max_sizes.max_mpt = 0; + max_sizes.max_rw = 500; + max_sizes.max_copy = 500; + max_sizes.max_zkevm_rows = 300; + complex_opcode_test(opcode_tester, max_sizes); +} + +BOOST_AUTO_TEST_SUITE_END()