From 09729f9a6e3d8799977382b11b74f54fcc7c0995 Mon Sep 17 00:00:00 2001 From: "e.tatuzova" Date: Mon, 18 Nov 2024 19:00:53 +0400 Subject: [PATCH] ADD and SUB implemented #95 --- .../include/nil/blueprint/bbf/generic.hpp | 2 +- .../opcode_tester_input_generator.hpp | 277 ++++++++++++------ .../blueprint/zkevm_bbf/opcodes/add_sub.hpp | 67 ++++- crypto3/libs/blueprint/test/CMakeLists.txt | 1 + .../test/zkevm_bbf/opcodes/add_sub.cpp | 99 +++++++ 5 files changed, 348 insertions(+), 98 deletions(-) create mode 100644 crypto3/libs/blueprint/test/zkevm_bbf/opcodes/add_sub.cpp diff --git a/crypto3/libs/blueprint/include/nil/blueprint/bbf/generic.hpp b/crypto3/libs/blueprint/include/nil/blueprint/bbf/generic.hpp index 3188c7d972..1fc92691ce 100644 --- a/crypto3/libs/blueprint/include/nil/blueprint/bbf/generic.hpp +++ b/crypto3/libs/blueprint/include/nil/blueprint/bbf/generic.hpp @@ -325,7 +325,7 @@ namespace nil { void allocate(TYPE &C, size_t col, size_t row, column_type t) { if (is_allocated(col, row, t)) { - BOOST_LOG_TRIVIAL(warning) << "RE-allocation of " << t << " cell at col = " << col << ", row = " << row << ".\n"; + // BOOST_LOG_TRIVIAL(warning) << "RE-allocation of " << t << " cell at col = " << col << ", row = " << row << ".\n"; } if (t == column_type::constant) { auto [has_vars, min_row, max_row] = expression_row_range_visitor::row_range(C); 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 6a3d8aee81..e56f7ba6d7 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 @@ -92,8 +92,159 @@ namespace nil { if(opcode == zkevm_opcode::STOP){ break; + } else if (opcode == zkevm_opcode::ADD){ + // 0x01 + 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)); + zkevm_word_type result = (a + b); + _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, true, result)); + stack.push_back(result); + pc++; + gas -= 3; + } else if (opcode == zkevm_opcode::SUB){ + // 0x03 + 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)); + zkevm_word_type result = (a - b); + _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, true, result)); + stack.push_back(result); + pc++; + gas -= 3; + } else if(opcode == zkevm_opcode::ADDMOD) { + // 0x08 + 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)); + zkevm_word_type modulus = stack.back(); + stack.pop_back(); + _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, false, modulus)); + // This is how the result is calculated inside the circuit + // It is suppose to avoid overflow of the type zkevm_word_type + integral_type s_integral = integral_type(a) + integral_type(b); + integral_type r_integral = modulus != 0u ? s_integral / integral_type(modulus) : 0u; + zkevm_word_type q = zkevm_word_type(s_integral - r_integral * integral_type(modulus)); + zkevm_word_type result = modulus != 0u ? q : 0; + //zkevm_word_type result = integral_type(modulus) == 0? 0 :(a + b) % modulus; + _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, true, result)); + stack.push_back(result); + pc++; + gas -= 8; + } else if(opcode == zkevm_opcode::MULMOD) { + // 0x09 + 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)); + zkevm_word_type modulus = stack.back(); + stack.pop_back(); + _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, false, modulus)); + a = modulus != 0u ? a : 0; + extended_integral_type s_integral = extended_integral_type(integral_type(a)) * extended_integral_type(integral_type(b)); + zkevm_word_type sp = zkevm_word_type(s_integral % extended_integral_type(zkevm_modulus)); + zkevm_word_type spp = zkevm_word_type(s_integral / extended_integral_type(zkevm_modulus)); + extended_integral_type r_integral = modulus != 0u ? s_integral / extended_integral_type(integral_type(modulus)): 0u; + zkevm_word_type rp = zkevm_word_type(r_integral % extended_integral_type(zkevm_modulus)); + zkevm_word_type rpp = zkevm_word_type(r_integral / extended_integral_type(zkevm_modulus)); + zkevm_word_type result = modulus != 0u ? zkevm_word_type(s_integral % extended_integral_type(integral_type(modulus))): 0u; + //zkevm_word_type result = integral_type(modulus) == 0? 0 : (a * b) % modulus; + _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, true, result)); + stack.push_back(result); + pc++; + gas -= 8; + } else if (opcode == zkevm_opcode::LT){ + // 0x10 + 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)); + zkevm_word_type result = a < b; + _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, true, result)); + stack.push_back(result); + pc++; + gas -= 3; + } else if (opcode == zkevm_opcode::GT){ + // 0x11 + 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)); + zkevm_word_type result = a > b; + _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, true, result)); + stack.push_back(result); + pc++; + gas -= 3; + } else if (opcode == zkevm_opcode::SLT){ + // 0x12 + 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)); + zkevm_word_type result; + if( is_negative(a) && !is_negative(b) ){ + result = 1; + } else if( is_negative(a) && is_negative(b) ){ + result = a > b; + } else if( !is_negative(a) && !is_negative(b) ){ + result = a < b; + } + _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, true, result)); + stack.push_back(result); + pc++; + gas -= 3; + } else if (opcode == zkevm_opcode::SGT){ + // 0x13 + 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)); + zkevm_word_type result; + if( !is_negative(a) && is_negative(b) ){ + result = 1; + } else if( is_negative(a) && is_negative(b) ){ + result = a < b; + } else if( !is_negative(a) && !is_negative(b) ){ + result = a > b; + } + _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, true, result)); + stack.push_back(result); + pc++; + gas -= 3; + } else if (opcode == zkevm_opcode::EQ){ + // 0x14 + 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)); + zkevm_word_type result = (a == b); + _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, true, result)); + stack.push_back(result); + pc++; + gas -= 3; } else if (opcode == zkevm_opcode::ISZERO){ - // 0x5f + // 0x15 zkevm_word_type a = stack.back(); _rw_operations.push_back(stack_rw_operation(call_id, stack.size()-1, rw_counter++, false, a)); stack.pop_back(); @@ -102,6 +253,45 @@ namespace nil { _rw_operations.push_back(stack_rw_operation(call_id, stack.size()-1, rw_counter++, true, result)); gas -= 3; pc++; + } else if(opcode == zkevm_opcode::AND) { + // 0x16 + 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)); + zkevm_word_type result = a & b; + _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, true, result)); + stack.push_back(result); + pc++; + gas -= 3; + } else if(opcode == zkevm_opcode::OR) { + // 0x17 + 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)); + zkevm_word_type result = a | b; + _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, true, result)); + stack.push_back(result); + pc++; + gas -= 3; + } else if(opcode == zkevm_opcode::XOR) { + // 0x18 + 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)); + zkevm_word_type result = a ^ b; + _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, true, result)); + stack.push_back(result); + pc++; + gas -= 3; } else if (opcode == zkevm_opcode::PUSH0){ // 0x5f _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, true, additional_input)); @@ -300,91 +490,6 @@ namespace nil { stack.push_back(additional_input); gas -= 3; pc += 33; - } else if(opcode == zkevm_opcode::ADDMOD) { - // 0x08 - 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)); - zkevm_word_type modulus = stack.back(); - stack.pop_back(); - _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, false, modulus)); - // This is how the result is calculated inside the circuit - // It is suppose to avoid overflow of the type zkevm_word_type - integral_type s_integral = integral_type(a) + integral_type(b); - integral_type r_integral = modulus != 0u ? s_integral / integral_type(modulus) : 0u; - zkevm_word_type q = zkevm_word_type(s_integral - r_integral * integral_type(modulus)); - zkevm_word_type result = modulus != 0u ? q : 0; - //zkevm_word_type result = integral_type(modulus) == 0? 0 :(a + b) % modulus; - _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, true, result)); - stack.push_back(result); - pc++; - gas -= 8; - } else if(opcode == zkevm_opcode::MULMOD) { - // 0x09 - 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)); - zkevm_word_type modulus = stack.back(); - stack.pop_back(); - _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, false, modulus)); - a = modulus != 0u ? a : 0; - extended_integral_type s_integral = extended_integral_type(integral_type(a)) * extended_integral_type(integral_type(b)); - zkevm_word_type sp = zkevm_word_type(s_integral % extended_integral_type(zkevm_modulus)); - zkevm_word_type spp = zkevm_word_type(s_integral / extended_integral_type(zkevm_modulus)); - extended_integral_type r_integral = modulus != 0u ? s_integral / extended_integral_type(integral_type(modulus)): 0u; - zkevm_word_type rp = zkevm_word_type(r_integral % extended_integral_type(zkevm_modulus)); - zkevm_word_type rpp = zkevm_word_type(r_integral / extended_integral_type(zkevm_modulus)); - zkevm_word_type result = modulus != 0u ? zkevm_word_type(s_integral % extended_integral_type(integral_type(modulus))): 0u; - //zkevm_word_type result = integral_type(modulus) == 0? 0 : (a * b) % modulus; - _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, true, result)); - stack.push_back(result); - pc++; - gas -= 8; - } else if(opcode == zkevm_opcode::AND) { - // 0x16 - 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)); - zkevm_word_type result = a & b; - _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, true, result)); - stack.push_back(result); - pc++; - gas -= 3; - } else if(opcode == zkevm_opcode::OR) { - // 0x17 - 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)); - zkevm_word_type result = a | b; - _rw_operations.push_back(stack_rw_operation(call_id, stack.size(), rw_counter++, true, result)); - stack.push_back(result); - pc++; - gas -= 3; - } else if(opcode == zkevm_opcode::XOR) { - // 0x18 - 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)); - zkevm_word_type result = a ^ b; - _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/add_sub.hpp b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/add_sub.hpp index 27ad43f900..f05308e898 100644 --- a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/add_sub.hpp +++ b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/add_sub.hpp @@ -47,35 +47,65 @@ namespace nil { using generic_component::lookup_table; public: using typename generic_component::TYPE; + using integral_type = boost::multiprecision::number>; zkevm_add_sub_bbf(context_type &context_object, const opcode_input_type ¤t_state, bool is_add): generic_component(context_object, false) { + integral_type two_128 = integral_type(1) << 128; + std::vector A(16); std::vector B(16); - std::vector C(16); + std::vector S(16); // S = A+B + TYPE carry0; + TYPE carry1; if constexpr( stage == GenerationStage::ASSIGNMENT ){ auto a = w_to_16(current_state.stack_top()); auto b = w_to_16(current_state.stack_top(1)); + auto s = + is_add ? + w_to_16(current_state.stack_top() + current_state.stack_top(1)): + w_to_16(current_state.stack_top() - current_state.stack_top(1)); + for( std::size_t i = 0; i < 16; i++){ - A[i] = a[i]; + A[i] = is_add? a[i]: s[i]; B[i] = b[i]; + S[i] = is_add? s[i] : a[i]; } + auto A_128 = chunks16_to_chunks128(A); + auto B_128 = chunks16_to_chunks128(B); + auto S_128 = chunks16_to_chunks128(S); + carry0 = (A_128.second + B_128.second >= two_128); + carry1 = (A_128.first + B_128.first + carry0 >= two_128); + std::cout << std::hex; + std::cout << "\tA = " << A_128.first << " " << A_128.second << std::endl; + std::cout << "\tB = " << B_128.first << " " << B_128.second << std::endl; + std::cout << "\tS = " << S_128.first << " " << S_128.second << std::endl; + std::cout << "\tcarry0 = " << carry0 << std::endl; + std::cout << "\tcarry1 = " << carry1 << std::endl; + std::cout << std::dec; } for( std::size_t i = 0; i < 16; i++){ allocate(A[i], i, 0); allocate(B[i], i + 16, 0); - allocate(C[i], i, 1); + allocate(S[i], i, 1); } + allocate(carry0, 32, 0); + allocate(carry1, 33, 0); auto A_128 = chunks16_to_chunks128(A); auto B_128 = chunks16_to_chunks128(B); + auto S_128 = chunks16_to_chunks128(S); + constrain(carry0 * (carry0 - 1)); + constrain(carry1 * (carry1 - 1)); + constrain(A_128.second + B_128.second - carry0 * two_128 - S_128.second); + constrain(A_128.first + B_128.first + carry0 - carry1 * two_128 - S_128.first); if constexpr( stage == GenerationStage::CONSTRAINTS ){ - constrain(current_state.pc_next() - current_state.pc(2) - 1); // PC transition - constrain(current_state.gas(2) - current_state.gas_next() - 3); // GAS transition - constrain(current_state.stack_size(2) - current_state.stack_size_next() - 1); // stack_size transition - constrain(current_state.memory_size(2) - current_state.memory_size_next()); // memory_size transition - constrain(current_state.rw_counter_next() - current_state.rw_counter(2) - 3); // rw_counter transition + constrain(current_state.pc_next() - current_state.pc(1) - 1); // PC transition + constrain(current_state.gas(1) - current_state.gas_next() - 3); // GAS transition + constrain(current_state.stack_size(1) - current_state.stack_size_next() - 1); // stack_size transition + constrain(current_state.memory_size(1) - current_state.memory_size_next()); // memory_size transition + constrain(current_state.rw_counter_next() - current_state.rw_counter(1) - 3); // rw_counter transition std::vector tmp; tmp = { TYPE(rw_op_to_num(rw_operation_type::stack)), @@ -86,8 +116,8 @@ namespace nil { TYPE(0),// field current_state.rw_counter(1), TYPE(0),// is_write - A_128.first, - A_128.second + is_add? A_128.first: S_128.first, + is_add? A_128.second: S_128.second }; lookup(tmp, "zkevm_rw"); tmp = { @@ -103,6 +133,21 @@ namespace nil { B_128.second }; 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 + is_add? S_128.first: A_128.first, + is_add? S_128.second: A_128.second + }; + lookup(tmp, "zkevm_rw"); + } else { + std::cout << "\tAssignment implemented" << std::endl; } } }; @@ -125,7 +170,7 @@ namespace nil { zkevm_add_sub_operation(bool _is_add):is_add(_is_add){ } std::size_t rows_amount() override { - return 3; + return 2; } protected: bool is_add; diff --git a/crypto3/libs/blueprint/test/CMakeLists.txt b/crypto3/libs/blueprint/test/CMakeLists.txt index da8e7b13c3..7896ce94c5 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/mod_ops" "zkevm_bbf/opcodes/bitwise" "zkevm_bbf/opcodes/cmp" + "zkevm_bbf/opcodes/add_sub" ) diff --git a/crypto3/libs/blueprint/test/zkevm_bbf/opcodes/add_sub.cpp b/crypto3/libs/blueprint/test/zkevm_bbf/opcodes/add_sub.cpp new file mode 100644 index 0000000000..b233140b24 --- /dev/null +++ b/crypto3/libs/blueprint/test/zkevm_bbf/opcodes/add_sub.cpp @@ -0,0 +1,99 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2024 Elena Tatuzova +// +// 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 blueprint_plonk_opcodes_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::crypto3; +using namespace nil::blueprint::bbf; + +// Remember that in production sizes should be preset. +// Here they are different for different tests just for fast and easy testing +BOOST_AUTO_TEST_SUITE(zkevm_opcode_test_suite) + +BOOST_AUTO_TEST_CASE(add_sub) { + using field_type = typename algebra::curves::pallas::base_field_type; + zkevm_opcode_tester opcode_tester; + + l1_size_restrictions max_sizes; + + opcode_tester.push_opcode(zkevm_opcode::PUSH32, zwordc(0x1234567890_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::ADD); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, zwordc(0x1234567890_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::SUB); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, zwordc(0xFb70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, zwordc(0xFb70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::ADD); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, zwordc(0x1234567890_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::SUB); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, zwordc(0x1234567890_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::ADD); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, zwordc(0x1234567890_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::PUSH32, zwordc(0x1b70726fb8d3a24da9ff9647225a18412b8f010425938504d73ebc8801e2e016_cppui_modular257)); + opcode_tester.push_opcode(zkevm_opcode::SUB); + 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()