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<var>::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<FieldType, stage>::lookup_table;
             public:
                 using typename generic_component<FieldType,stage>::TYPE;
+                using integral_type = boost::multiprecision::number<boost::multiprecision::backends::cpp_int_modular_backend<257>>;
 
                 zkevm_add_sub_bbf(context_type &context_object, const opcode_input_type<FieldType, stage> &current_state, bool is_add):
                     generic_component<FieldType,stage>(context_object, false)
                 {
+                    integral_type two_128 = integral_type(1) << 128;
+
                     std::vector<TYPE> A(16);
                     std::vector<TYPE> B(16);
-                    std::vector<TYPE> C(16);
+                    std::vector<TYPE> 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<TYPE>(A);
+                        auto B_128 = chunks16_to_chunks128<TYPE>(B);
+                        auto S_128 = chunks16_to_chunks128<TYPE>(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<TYPE>(A);
                     auto B_128 = chunks16_to_chunks128<TYPE>(B);
+                    auto S_128 = chunks16_to_chunks128<TYPE>(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<TYPE> 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 <e.tatuzova@nil.foundation>
+//
+// 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 <boost/assert.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <nil/crypto3/algebra/curves/pallas.hpp>
+#include <nil/crypto3/algebra/fields/arithmetic_params/pallas.hpp>
+#include <nil/crypto3/algebra/curves/vesta.hpp>
+#include <nil/crypto3/algebra/fields/arithmetic_params/vesta.hpp>
+#include <nil/crypto3/algebra/random_element.hpp>
+
+#include <nil/crypto3/hash/algorithm/hash.hpp>
+#include <nil/crypto3/hash/sha2.hpp>
+#include <nil/crypto3/hash/keccak.hpp>
+
+#include <nil/blueprint/zkevm_bbf/types/hashed_buffers.hpp>
+#include <nil/blueprint/zkevm_bbf/types/rw_operation.hpp>
+#include <nil/blueprint/zkevm_bbf/types/copy_event.hpp>
+#include <nil/blueprint/zkevm_bbf/types/zkevm_state.hpp>
+#include <nil/blueprint/zkevm_bbf/input_generators/opcode_tester.hpp>
+#include <nil/blueprint/zkevm_bbf/input_generators/opcode_tester_input_generator.hpp>
+
+#include <nil/blueprint/blueprint/plonk/circuit.hpp>
+#include <nil/blueprint/blueprint/plonk/assignment.hpp>
+#include <nil/blueprint/bbf/l1_wrapper.hpp>
+#include <nil/blueprint/zkevm_bbf/zkevm.hpp>
+#include <nil/blueprint/zkevm_bbf/rw.hpp>
+#include <nil/blueprint/zkevm_bbf/copy.hpp>
+#include <nil/blueprint/zkevm_bbf/bytecode.hpp>
+#include <nil/blueprint/zkevm_bbf/keccak.hpp>
+
+#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<field_type>(opcode_tester, max_sizes);
+}
+BOOST_AUTO_TEST_SUITE_END()