diff --git a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/copy.hpp b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/copy.hpp index 6dbda1272a..dc1d947067 100644 --- a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/copy.hpp +++ b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/copy.hpp @@ -40,6 +40,8 @@ namespace nil { using generic_component::lookup_table; public: using typename generic_component::TYPE; + using integral_type = boost::multiprecision::number>; + struct input_type{ TYPE rlc_challenge; typename std::conditional::type bytecodes; @@ -128,7 +130,6 @@ namespace nil { std::vector rlc(max_copy); std::vector rlc_challenge(max_copy); std::vector is_last(max_copy); - std::vector length_inv(max_copy); if constexpr (stage == GenerationStage::ASSIGNMENT) { std::size_t current_row = 0; @@ -148,8 +149,6 @@ namespace nil { rlc[current_row + 1] = rlc[current_row] + bytes[current_row]; type_selector[current_row][copy_op_to_num(cp.source_type) - 1] = 1; type_selector[current_row + 1][copy_op_to_num(cp.destination_type) - 1] = 1; - length_inv[current_row] = (length[current_row] - 1) == 0? 0: (length[current_row] - 1).inversed(); - length_inv[current_row+1] = length_inv[current_row]; current_row += 2; } @@ -165,8 +164,7 @@ namespace nil { allocate(bytes[i],6, i); allocate(rlc[i],7, i); allocate(rlc_challenge[i],8, i); - allocate(length_inv[i],9, i); - allocate(is_last[i],10, i); + allocate(is_last[i], 9, i); TYPE memory_selector = type_selector[i][copy_op_to_num(copy_operand_type::memory) - 1]; TYPE keccak_selector = type_selector[i][copy_op_to_num(copy_operand_type::keccak) - 1]; @@ -210,8 +208,6 @@ namespace nil { } every.push_back(context_object.relativize(type_selector_sum * (type_selector_sum - 1), -1)); every.push_back(context_object.relativize(cp_type_constraint - cp_type[1], -1)); - every.push_back(context_object.relativize(type_selector_sum * (length[1] - 1) * ((length[1] - 1) * length_inv[1] - 1), -1)); - every.push_back(context_object.relativize(type_selector_sum * length_inv[1] * ((length[1] - 1) * length_inv[1] - 1), -1)); every.push_back(context_object.relativize((type_selector_sum - 1)* is_last[1], -1)); every.push_back(context_object.relativize((type_selector_sum - 1)* is_first[1], -1)); diff --git a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/keccak.hpp b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/keccak.hpp index 1b86483e82..7d9324eda6 100644 --- a/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/keccak.hpp +++ b/crypto3/libs/blueprint/include/nil/blueprint/zkevm_bbf/opcodes/keccak.hpp @@ -9,7 +9,6 @@ // 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. // @@ -46,16 +45,101 @@ namespace nil { using generic_component::lookup_table; public: using typename generic_component::TYPE; + using integral_type = boost::multiprecision::number>; zkevm_keccak_bbf(context_type &context_object, const opcode_input_type ¤t_state): generic_component(context_object, false) { + TYPE offset; + TYPE length; + TYPE hash_hi; + TYPE hash_lo; + if constexpr( stage == GenerationStage::ASSIGNMENT ){ + offset = w_lo(current_state.stack_top()); + length = w_lo(current_state.stack_top(1)); + std::size_t start_offset = std::size_t(integral_type(current_state.stack_top())); + std::size_t l = std::size_t(integral_type(current_state.stack_top(1))); + std::vector buffer; + for( std::size_t i = 0; i < l; i++ ){ + buffer.push_back(std::uint8_t(integral_type(current_state.memory(start_offset + i)))); + } + auto hash_value = zkevm_keccak_hash(buffer); + hash_hi = w_hi(hash_value); + hash_lo = w_lo(hash_value); + } + allocate(offset, 32, 0); + allocate(length, 33, 0); + allocate(hash_hi, 34, 0); + allocate(hash_lo, 35, 0); if constexpr( stage == GenerationStage::CONSTRAINTS ){ - // constrain(current_state.pc_next() - current_state.pc(0) - 1); // PC transition + constrain(current_state.pc_next() - current_state.pc(0) - 1); // PC transition // constrain(current_state.gas(0) - current_state.gas_next() - 2); // GAS transition - // constrain(current_state.stack_size_next() - current_state.stack_size(0) - 1); // stack_size transition + constrain(current_state.stack_size_next() - current_state.stack_size(0) + 1); // stack_size transition // constrain(current_state.memory_size(0) - current_state.memory_size_next()); // memory_size transition - // constrain(current_state.rw_counter_next() - current_state.rw_counter(0) - 1); // rw_counter transition + constrain(current_state.rw_counter_next() - current_state.rw_counter(0) - 3 - length); // rw_counter transition + + std::vector tmp; + tmp = { + TYPE(rw_op_to_num(rw_operation_type::stack)), + current_state.call_id(0), + current_state.stack_size(0) - 1, + TYPE(0),// storage_key_hi + TYPE(0),// storage_key_lo + TYPE(0),// field + current_state.rw_counter(0), + TYPE(0),// is_write + TYPE(0),// hi bytes are 0 + offset // addr is smaller than maximum contract size + }; + lookup(tmp, "zkevm_rw"); + tmp = { + TYPE(rw_op_to_num(rw_operation_type::stack)), + current_state.call_id(0), + current_state.stack_size(0) - 2, + TYPE(0),// storage_key_hi + TYPE(0),// storage_key_lo + TYPE(0),// field + current_state.rw_counter(0) +1, + TYPE(0),// is_write + TYPE(0),// hi bytes are 0 + length // addr is smaller than maximum contract size + }; + lookup(tmp, "zkevm_rw"); + tmp = { + TYPE(1), // is_first + TYPE(0), // source_id_hi + current_state.call_id(0), // source_id_lo + TYPE(copy_op_to_num(copy_operand_type::memory)), // cp_type + offset, + length, + TYPE(0), // is_write + current_state.rw_counter(0) + 2 // addr is smaller than maximum contract size + }; + lookup(tmp, "zkevm_copy"); + tmp = { + TYPE(1), // is_first + hash_hi, // source_id_hi + hash_lo, // source_id_lo + TYPE(copy_op_to_num(copy_operand_type::keccak)), // cp_type + 0, + length, + TYPE(1), // is_write + current_state.rw_counter(0) + 2 + length // addr is smaller than maximum contract size + }; + lookup(tmp, "zkevm_copy"); + tmp = { + TYPE(rw_op_to_num(rw_operation_type::stack)), + current_state.call_id(0), + current_state.stack_size(0) - 2, + TYPE(0),// storage_key_hi + TYPE(0),// storage_key_lo + TYPE(0),// field + current_state.rw_counter(0) + 2 + length, + TYPE(1),// is_write + hash_hi, + hash_lo + }; + lookup(tmp, "zkevm_rw"); } else { std::cout << "\tASSIGNMENT implemented" << std::endl; } @@ -66,7 +150,7 @@ namespace nil { class zkevm_keccak_operation : public opcode_abstract { public: virtual std::size_t rows_amount() override { - return 2; + return 1; } virtual void fill_context( typename generic_component::context_type &context,