diff --git a/include/nil/blueprint/components/hashes/keccak/keccak_component.hpp b/include/nil/blueprint/components/hashes/keccak/keccak_component.hpp index b700db929..f5a98159e 100644 --- a/include/nil/blueprint/components/hashes/keccak/keccak_component.hpp +++ b/include/nil/blueprint/components/hashes/keccak/keccak_component.hpp @@ -1,6 +1,6 @@ //---------------------------------------------------------------------------// // Copyright (c) 2023 Polina Chernyshova -// +// 2024 Valeh Farzaliyev // MIT License // // Permission is hereby granted, free of charge, to any person obtaining a copy @@ -34,7 +34,7 @@ #include #include -// #include +#include #include namespace nil { @@ -44,8 +44,8 @@ namespace nil { class keccak; template - class keccak> : - public plonk_component { + class keccak> + : public plonk_component { using component_type = plonk_component; using value_type = typename BlueprintFieldType::value_type; @@ -58,13 +58,14 @@ namespace nil { public: using var = typename component_type::var; - // using round_component_type = keccak_round>; - // round_component_type round_true_true; - // std::vector rounds_true_false; - // std::vector rounds_false_false; - // std::vector rounds; + using round_component_type = + keccak_round>; + round_component_type round_tt; + round_component_type round_tf; + round_component_type round_ff; - using padding_component_type = keccak_padding>; + using padding_component_type = + keccak_padding>; padding_component_type padding; using manifest_type = nil::blueprint::plonk_component_manifest; @@ -78,12 +79,15 @@ namespace nil { std::size_t limit_permutation_column; gate_manifest_type(std::size_t witness_amount_, std::size_t num_blocks_, std::size_t num_bits_, - bool range_check_input_, std::size_t limit_permutation_column_) - : witness_amount(std::min(witness_amount_, clamp)), num_blocks(num_blocks_), num_bits(num_bits_), - range_check_input(range_check_input_), limit_permutation_column(limit_permutation_column_) {} + bool range_check_input_, std::size_t limit_permutation_column_) : + witness_amount(std::min(witness_amount_, clamp)), + num_blocks(num_blocks_), num_bits(num_bits_), range_check_input(range_check_input_), + limit_permutation_column(limit_permutation_column_) { + } std::uint32_t gates_amount() const override { - return get_gates_amount(witness_amount, num_blocks, num_bits, range_check_input, limit_permutation_column); + return get_gates_amount(witness_amount, num_blocks, num_bits, range_check_input, + limit_permutation_column); } }; @@ -94,33 +98,26 @@ namespace nil { bool range_check_input, std::size_t limit_permutation_column) { std::size_t num_round_calls = calculate_num_round_calls(num_blocks); - gate_manifest manifest = - gate_manifest(gate_manifest_type(witness_amount, num_blocks, num_bits, range_check_input, limit_permutation_column)) - .merge_with( - padding_component_type::get_gate_manifest(witness_amount, lookup_column_amount, - num_blocks, num_bits, range_check_input)); - // manifest.merge_with(round_component_type::get_gate_manifest(witness_amount, lookup_column_amount, - // true, true)); - // for (std::size_t i = 1; i < num_round_calls; ++i) { - // manifest.merge_with(round_component_type::get_gate_manifest(witness_amount, lookup_column_amount, - // true, false)); - // } - // for (std::size_t i = 0; i < num_round_calls; ++i) { - // for (std::size_t j = 0; j < 23; ++j) { - // manifest.merge_with(round_component_type::get_gate_manifest(witness_amount, lookup_column_amount, - // false, false)); - // } - // } + gate_manifest manifest = gate_manifest(gate_manifest_type( + witness_amount, num_blocks, num_bits, range_check_input, limit_permutation_column)); + + manifest.merge_with(padding_component_type::get_gate_manifest( + witness_amount, lookup_column_amount, num_blocks, num_bits, range_check_input)); + manifest.merge_with(round_component_type::get_gate_manifest(witness_amount, lookup_column_amount, + true, true, limit_permutation_column)); + // manifest.merge_with(round_component_type::get_gate_manifest( + // witness_amount, lookup_column_amount, true, false, limit_permutation_column)); + // manifest.merge_with(round_component_type::get_gate_manifest( + // witness_amount, lookup_column_amount, false, false, limit_permutation_column)); return manifest; } static manifest_type get_manifest() { - static manifest_type manifest = manifest_type( - std::shared_ptr( - new manifest_range_param(9, 15)), - false - ).merge_with(padding_component_type::get_manifest()); + static manifest_type manifest = + manifest_type(std::shared_ptr(new manifest_range_param(9, 15)), false) + .merge_with(padding_component_type::get_manifest()) + .merge_with(round_component_type::get_manifest()); return manifest; } @@ -134,37 +131,59 @@ namespace nil { const bool range_check_input; const std::size_t limit_permutation_column = 7; - const std::size_t round_tt_rows = 0; - const std::size_t round_tf_rows = 0; - const std::size_t round_ff_rows = 0; - const std::size_t round_tt_gates = 0; - const std::size_t round_tf_gates = 0; - const std::size_t round_ff_gates = 0; + std::size_t round_tt_rows = 0; + std::size_t round_tf_rows = 0; + std::size_t round_ff_rows = 0; + std::size_t round_tt_gates = 0; + std::size_t round_tf_gates = 0; + std::size_t round_ff_gates = 0; const std::size_t num_round_calls = calculate_num_round_calls(num_blocks); const std::size_t num_configs = 5 + num_blocks + (17 - num_blocks % 17); const std::size_t pack_chunk_size = 8; const std::size_t pack_num_chunks = 8; + const std::size_t unpack_chunk_size = 24; + const std::size_t unpack_num_chunks = 8; const std::size_t pack_cells = 2 * (pack_num_chunks + 1); const std::size_t pack_buff = (this->witness_amount() == 15) * 2; - std::vector full_configuration = configure_all(this->witness_amount(), num_configs, num_round_calls, limit_permutation_column); - const std::map> gates_configuration_map = - configure_map(this->witness_amount(), num_blocks, num_bits, range_check_input, limit_permutation_column); - const std::vector> gates_configuration = - configure_gates(this->witness_amount(), num_blocks, num_bits, range_check_input, limit_permutation_column); - - const std::size_t rows_amount = - get_rows_amount(this->witness_amount(), 0, num_blocks, num_bits, range_check_input, limit_permutation_column); - const std::size_t gates_amount = get_gates_amount(this->witness_amount(), num_blocks, num_bits, range_check_input, limit_permutation_column); - - const std::size_t round_constant[24] = {1, 0x8082, 0x800000000000808a, 0x8000000080008000, - 0x808b, 0x80000001, 0x8000000080008081, 0x8000000000008009, - 0x8a, 0x88, 0x80008009, 0x8000000a, - 0x8000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003, - 0x8000000000008002, 0x8000000000000080, 0x800a, 0x800000008000000a, - 0x8000000080008081, 0x8000000000008080, 0x80000001, 0x8000000080008008}; + std::vector full_configuration = + configure_all(this->witness_amount(), num_configs, num_round_calls, limit_permutation_column); + const std::map> gates_configuration_map = configure_map( + this->witness_amount(), num_blocks, num_bits, range_check_input, limit_permutation_column); + const std::vector> gates_configuration = configure_gates( + this->witness_amount(), num_blocks, num_bits, range_check_input, limit_permutation_column); + + const std::size_t rows_amount = get_rows_amount(this->witness_amount(), 0, num_blocks, num_bits, + range_check_input, limit_permutation_column); + const std::size_t gates_amount = get_gates_amount(this->witness_amount(), num_blocks, num_bits, + range_check_input, limit_permutation_column); + + const std::size_t round_constant[24] = {1, + 0x8082, + 0x800000000000808a, + 0x8000000080008000, + 0x808b, + 0x80000001, + 0x8000000080008081, + 0x8000000000008009, + 0x8a, + 0x88, + 0x80008009, + 0x8000000a, + 0x8000808b, + 0x800000000000008b, + 0x8000000000008089, + 0x8000000000008003, + 0x8000000000008002, + 0x8000000000000080, + 0x800a, + 0x800000008000000a, + 0x8000000080008081, + 0x8000000000008080, + 0x80000001, + 0x8000000080008008}; struct input_type { std::vector message; @@ -181,35 +200,33 @@ namespace nil { std::array final_inner_state; result_type(const keccak &component, std::size_t start_row_index) { + auto offset = + component.full_configuration[component.num_configs - 1].last_coordinate.row + + (component.full_configuration[component.num_configs - 1].last_coordinate.column > 0); for (std::size_t i = 0; i < 5; ++i) { - final_inner_state[i] = var(component.W(component.full_configuration[component.num_configs - 5 + i].copy_from.column), - start_row_index + component.full_configuration[component.num_configs - 5 + i].copy_from.row, false); + final_inner_state[i] = + var(component.W( + component.full_configuration[component.num_configs - 5 + i].copy_from.column), + start_row_index + component.rows_amount - offset + + component.full_configuration[component.num_configs - 5 + i].copy_from.row, + false); } } std::vector all_vars() const { - return {final_inner_state[0], final_inner_state[1], final_inner_state[2], final_inner_state[3], final_inner_state[4]}; + return {final_inner_state[0], final_inner_state[1], final_inner_state[2], final_inner_state[3], + final_inner_state[4]}; } }; static std::size_t get_rows_amount_round_tt() { return 0; } - // std::vector create_rounds() { - // std::vector rounds; - // rounds.push_back(round_true_true); - // rounds.insert(rounds.end(), rounds_false_false.begin(), rounds_false_false.begin() + 23); - // for (std::size_t i = 1; i < num_round_calls; ++i) { - // rounds.push_back(rounds_true_false[i - 1]); - // rounds.insert(rounds.end(), rounds_false_false.begin() + i * 23, rounds_false_false.begin() + (i + 1) * 23); - // } - // return rounds; - // } - - integral_type pack(const integral_type& const_input) const { + + integral_type pack(const integral_type &const_input) const { integral_type input = const_input; integral_type sparse_res = 0; integral_type power = 1; while (input > 0) { - auto bit = input % 2; + auto bit = input & 1; sparse_res += bit * power; power <<= 3; input >>= 1; @@ -217,14 +234,13 @@ namespace nil { return sparse_res; } - integral_type unpack(const integral_type& const_sparse_input) const { + integral_type unpack(const integral_type &const_sparse_input) const { integral_type sparse_input = const_sparse_input; integral_type res = 0; integral_type power = 1; integral_type mask = (integral_type(1) << 3) - 1; while (sparse_input > 0) { auto bit = sparse_input & mask; - std::cout << "bit: " << bit << std::endl; BOOST_ASSERT(bit * (1 - bit) == 0); res += bit * power; power <<= 1; @@ -233,15 +249,15 @@ namespace nil { return res; } - static configuration configure_pack_unpack(std::size_t witness_amount, std::size_t row, std::size_t column, - std::size_t pack_cells, std::size_t pack_num_chunks, std::size_t pack_buff, - std::size_t limit_permutation_column) { + static configuration configure_pack_unpack(std::size_t witness_amount, std::size_t row, + std::size_t column, std::size_t pack_cells, + std::size_t pack_num_chunks, std::size_t pack_buff, + std::size_t limit_permutation_column) { // regular constraints: // input = input0 + input1 * 2^chunk_size + ... + inputk * 2^(k*chunk_size) // output = output0 + output1 * 2^chunk_size + ... + outputk * 2^(k*chunk_size) - std::size_t last_row = row, - last_column = column; + std::size_t last_row = row, last_column = column; std::pair first_coordinate = {row, column}; std::vector> copy_from; @@ -250,8 +266,8 @@ namespace nil { if (1 + column > limit_permutation_column) { copy_from.push_back({last_row + 1, 0}); } else { - copy_from.push_back({last_row + (last_column / witness_amount), - (last_column++) % witness_amount}); + copy_from.push_back( + {last_row + (last_column / witness_amount), (last_column++) % witness_amount}); } std::pair cell_copy_to; @@ -268,20 +284,20 @@ namespace nil { cells.push_back({row, i}); } std::size_t cells_left = pack_cells - witness_amount + column; - std::size_t cur_row = row + 1, - cur_column = 1; + std::size_t cur_row = row + 1, cur_column = 1; while (cur_column < cells_left) { - if (cur_column % witness_amount == cell_copy_to.second && (cur_row + (cur_column / witness_amount) == cell_copy_to.first)) { + if (cur_column % witness_amount == cell_copy_to.second && + (cur_row + (cur_column / witness_amount) == cell_copy_to.first)) { cur_column++; continue; } cells.push_back({cur_row + (cur_column / witness_amount), (cur_column++) % witness_amount}); } } else { - std::size_t cur_row = row, - cur_column = column + 1; + std::size_t cur_row = row, cur_column = column + 1; while (cur_column - column < pack_cells) { - if (cur_column % witness_amount == cell_copy_to.second && (cur_row + (cur_column / witness_amount) == cell_copy_to.first)) { + if (cur_column % witness_amount == cell_copy_to.second && + (cur_row + (cur_column / witness_amount) == cell_copy_to.first)) { cur_column++; continue; } @@ -290,8 +306,8 @@ namespace nil { } std::size_t cell_index = 0; - std::vector>> - lookups(pack_num_chunks, std::vector>()); + std::vector>> lookups( + pack_num_chunks, std::vector>()); constraints.push_back({copy_from[0]}); constraints.push_back({cell_copy_to}); @@ -306,24 +322,25 @@ namespace nil { last_row = cells.back().first + (last_column / witness_amount); last_column %= witness_amount; - return configuration(first_coordinate, {last_row, last_column}, copy_from, constraints, lookups, cell_copy_to); + return configuration(first_coordinate, {last_row, last_column}, copy_from, constraints, lookups, + cell_copy_to); } - static std::vector configure_all(std::size_t witness_amount, const std::size_t num_configs, - const std::size_t num_round_calls, std::size_t limit_permutation_column) { + static std::vector configure_all(std::size_t witness_amount, + const std::size_t num_configs, + const std::size_t num_round_calls, + std::size_t limit_permutation_column) { std::vector result; std::size_t pack_num_chunks = 8; std::size_t pack_cells = 2 * (pack_num_chunks + 1); std::size_t pack_buff = (witness_amount == 15) * 2; - std::size_t row = 0, - column = 0; + std::size_t row = 0, column = 0; for (std::size_t index = 0; index < num_round_calls * 17; ++index) { // to sparse representation - result.push_back(configure_pack_unpack(witness_amount, row, column, - pack_cells, pack_num_chunks, pack_buff, - limit_permutation_column)); + result.push_back(configure_pack_unpack(witness_amount, row, column, pack_cells, pack_num_chunks, + pack_buff, limit_permutation_column)); row = result[index].last_coordinate.row; column = result[index].last_coordinate.column; } @@ -332,19 +349,27 @@ namespace nil { row++; } - //rounds - for (std::size_t index = 0; index < num_round_calls; ++index) { - // for (std::size_t i = 0; i < 24; ++i) { - // row += rounds[index * 24 + i].rows_amount; - // } - } + // rounds + // for (std::size_t index = 0; index < num_round_calls; ++index) { + // for (std::size_t i = 0; i < 24; ++i) { + // if (index == num_round_calls - 1 && i == 0) { + // row += round_component_type::get_rows_amount(witness_amount, 0, true, true, + // limit_permutation_column); + // } else if (i == 0) { + // row += round_component_type::get_rows_amount(witness_amount, 0, true, false, + // limit_permutation_column); + // } else { + // row += round_component_type::get_rows_amount(witness_amount, 0, false, false, + // limit_permutation_column); + // } + // } + // } row = 0; // from sparse representation for (std::size_t i = 0; i < 5; ++i) { - result.push_back(configure_pack_unpack(witness_amount, row, column, - pack_cells, pack_num_chunks, pack_buff, - limit_permutation_column)); + result.push_back(configure_pack_unpack(witness_amount, row, column, pack_cells, pack_num_chunks, + pack_buff, limit_permutation_column)); row = result.back().last_coordinate.row; column = result.back().last_coordinate.column; } @@ -353,14 +378,17 @@ namespace nil { // for (std::size_t i = 0; i < result.size(); ++i) { // auto cur_config = result[i]; // std::cout << "config: " << i << "\n"; - // std::cout << cur_config.first_coordinate.row << " " << cur_config.first_coordinate.column << " " << cur_config.last_coordinate.row << " " << cur_config.last_coordinate.column << std::endl; - // std::cout << cur_config.copy_from.row << " " << cur_config.copy_from.column << std::endl; - // for (int j = 0; j < cur_config.copy_to.size(); ++j) { - // std::cout << cur_config.copy_to[j].row << " " << cur_config.copy_to[j].column << std::endl; + // std::cout << cur_config.first_coordinate.row << " " << cur_config.first_coordinate.column << + // " " << cur_config.last_coordinate.row << " " << cur_config.last_coordinate.column << + // std::endl; std::cout << cur_config.copy_from.row << " " << cur_config.copy_from.column << + // std::endl; for (int j = 0; j < cur_config.copy_to.size(); ++j) { + // std::cout << cur_config.copy_to[j].row << " " << cur_config.copy_to[j].column << + // std::endl; // } // for (int j = 0; j < cur_config.constraints.size(); ++j) { // for (int k = 0; k < cur_config.constraints[j].size(); ++k) { - // std::cout << cur_config.constraints[j][k].row << " " << cur_config.constraints[j][k].column << ", "; + // std::cout << cur_config.constraints[j][k].row << " " << + // cur_config.constraints[j][k].column << ", "; // } // std::cout << std::endl; // } @@ -369,18 +397,19 @@ namespace nil { return result; } - static std::map> configure_map(std::size_t witness_amount, - std::size_t num_blocks, - std::size_t num_bits, - bool range_check_input, - std::size_t limit_permutation_column) { + static std::map> + configure_map(std::size_t witness_amount, + std::size_t num_blocks, + std::size_t num_bits, + bool range_check_input, + std::size_t limit_permutation_column) { - auto config = configure_all(witness_amount, num_blocks, num_bits, limit_permutation_column); - std::size_t row = 0, - column = 0; - std::size_t row_shift = 0;//padding_component_type::get_rows_amount(witness_amount, 0, - // num_blocks, num_bits, range_check_input, - // limit_permutation_column); + std::size_t num_configs = 5 + num_blocks + (17 - num_blocks % 17); + std::size_t num_round_calls = calculate_num_round_calls(num_blocks); + auto config = configure_all(witness_amount, num_configs, num_round_calls, limit_permutation_column); + std::size_t row = 0, column = 0; + std::size_t row_shift = 0; // padding_component_type::get_rows_amount( + // witness_amount, 0, num_blocks, num_bits, range_check_input, limit_permutation_column); std::map> config_map; @@ -393,7 +422,7 @@ namespace nil { config_map[column] = {row + row_shift}; } } - row_shift += config[config.size() - 6].last_coordinate.row; + // row_shift += config[config.size() - 6].last_coordinate.row; for (std::size_t i = config.size() - 5; i < config.size(); ++i) { row = config[i].first_coordinate.row; column = config[i].first_coordinate.column + 10 * witness_amount; @@ -417,20 +446,23 @@ namespace nil { } static std::vector> configure_gates(std::size_t witness_amount, - std::size_t num_blocks, - std::size_t num_bits, - bool range_check_input, - std::size_t limit_permutation_column) { + std::size_t num_blocks, + std::size_t num_bits, + bool range_check_input, + std::size_t limit_permutation_column) { std::vector> result; - auto gates_configuration_map = configure_map(witness_amount, num_blocks, num_bits, range_check_input, limit_permutation_column); + auto gates_configuration_map = configure_map(witness_amount, num_blocks, num_bits, + range_check_input, limit_permutation_column); std::size_t pack_num_chunks = 8; std::size_t num_cells = 2 * (pack_num_chunks + 1); std::size_t buff = (witness_amount == 15) * 2; - for (auto config: gates_configuration_map) { - if (config.first >= 10 * witness_amount) continue; - configuration cur_config = configure_pack_unpack(witness_amount, 0, config.first, - num_cells, pack_num_chunks, buff, limit_permutation_column); + for (auto config : gates_configuration_map) { + if (config.first >= 10 * witness_amount) + continue; + configuration cur_config = + configure_pack_unpack(witness_amount, 0, config.first, num_cells, pack_num_chunks, buff, + limit_permutation_column); std::vector> pairs; for (auto constr : cur_config.constraints) { std::size_t min = constr[0].row; @@ -447,7 +479,8 @@ namespace nil { std::size_t cur_constr = 0; while (cur_constr < pairs.size()) { configuration c; - while (cur_constr < pairs.size() && pairs[cur_constr].second <= cur_row + 2 && pairs[cur_constr].first >= cur_row) { + while (cur_constr < pairs.size() && pairs[cur_constr].second <= cur_row + 2 && + pairs[cur_constr].first >= cur_row) { c.constraints.push_back(cur_config.constraints[cur_constr]); c.first_coordinate = {cur_row, 0}; ++cur_constr; @@ -458,132 +491,134 @@ namespace nil { result.push_back(cur_result); } - for (std::size_t i = 0; i < result.size(); ++i) { - std::cout << "config " << i << ":\n"; - for (auto cur_config : result[i]) { - std::cout << "gate:\n"; - for (int j = 0; j < cur_config.constraints.size(); ++j) { - for (int k = 0; k < cur_config.constraints[j].size(); ++k) { - std::cout << cur_config.constraints[j][k].row << " " << cur_config.constraints[j][k].column << ", "; - } - std::cout << std::endl; - } - } - } + // for (std::size_t i = 0; i < result.size(); ++i) { + // std::cout << "config " << i << ":\n"; + // for (auto cur_config : result[i]) { + // std::cout << "gate:\n"; + // for (int j = 0; j < cur_config.constraints.size(); ++j) { + // for (int k = 0; k < cur_config.constraints[j].size(); ++k) { + // std::cout << cur_config.constraints[j][k].row << " " << + // cur_config.constraints[j][k].column << ", "; + // } + // std::cout << std::endl; + // } + // } + // } return result; } static std::size_t get_rows_amount(std::size_t witness_amount, std::size_t lookup_column_amount, - std::size_t num_blocks, std::size_t num_bits, bool range_check_input, - std::size_t limit_permutation_column) { + std::size_t num_blocks, std::size_t num_bits, bool range_check_input, + std::size_t limit_permutation_column) { std::size_t num_round_calls = calculate_num_round_calls(num_blocks); - std::size_t res = padding_component_type::get_rows_amount(witness_amount, lookup_column_amount, - num_blocks, num_bits, range_check_input, - limit_permutation_column); - // + round_tt_rows - // + round_tf_rows * (num_round_calls - 1) - // + round_ff_rows * num_round_calls * 23; + std::size_t res = + padding_component_type::get_rows_amount(witness_amount, lookup_column_amount, num_blocks, + num_bits, range_check_input, limit_permutation_column); + // + round_tt_rows + for (std::size_t i = 0; i < num_round_calls; i++) { + if (i == num_round_calls - 1) { + res += round_component_type::get_rows_amount(witness_amount, lookup_column_amount, true, + true, limit_permutation_column); + } else { + res += round_component_type::get_rows_amount(witness_amount, lookup_column_amount, true, + false, limit_permutation_column); + } + for (std::size_t j = 1; j < 24; ++j) { + res += round_component_type::get_rows_amount(witness_amount, lookup_column_amount, false, + false, limit_permutation_column); + } + } + auto config = configure_all(witness_amount, num_blocks, num_round_calls, limit_permutation_column); auto index = config.size() - 1; res += config[index].last_coordinate.row + (config[index].last_coordinate.column > 0); res += config[index - 5].last_coordinate.row + (config[index - 5].last_coordinate.column > 0); return res; } - static std::size_t get_gates_amount(std::size_t witness_amount, - std::size_t num_blocks, std::size_t num_bits, bool range_check_input, + static std::size_t get_gates_amount(std::size_t witness_amount, std::size_t num_blocks, + std::size_t num_bits, bool range_check_input, std::size_t limit_permutation_column) { std::size_t res = 0; - auto config = configure_map(witness_amount, num_blocks, num_bits, range_check_input, limit_permutation_column); + auto config = configure_map(witness_amount, num_blocks, num_bits, range_check_input, + limit_permutation_column); for (auto c : config) { - if (c.first >= 10 * witness_amount) res++; - else res += 2; + if (c.first >= 10 * witness_amount) + res += 2; + else + res += 2; } return res; } - std::map component_lookup_tables(){ + std::map component_lookup_tables() { std::map lookup_tables; - lookup_tables["keccak_pack_table/full"] = 0; // REQUIRED_TABLE - lookup_tables["keccak_pack_table/range_check"] = 0; // REQUIRED_TABLE - lookup_tables["keccak_pack_table/64bit"] = 0; // REQUIRED_TABLE - lookup_tables["keccak_sign_bit_table/full"] = 0; // REQUIRED_TABLE + lookup_tables["keccak_pack_table/full"] = 0; // REQUIRED_TABLE + lookup_tables["keccak_pack_table/range_check"] = 0; // REQUIRED_TABLE + lookup_tables["keccak_pack_table/64bit"] = 0; // REQUIRED_TABLE + lookup_tables["keccak_sign_bit_table/full"] = 0; // REQUIRED_TABLE + lookup_tables["keccak_normalize3_table/full"] = 0; // REQUIRED_TABLE + lookup_tables["keccak_normalize4_table/full"] = 0; // REQUIRED_TABLE + lookup_tables["keccak_normalize6_table/full"] = 0; // REQUIRED_TABLE + lookup_tables["keccak_chi_table/full"] = 0; // REQUIRED_TABLE + lookup_tables["keccak_pack_table/range_check_sparse"] = 0; // REQUIRED_TABLE return lookup_tables; } template keccak(WitnessContainerType witness, ConstantContainerType constant, - PublicInputContainerType public_input, - std::size_t num_blocks_, - std::size_t num_bits_, - bool range_check_input_, - std::size_t lpc_ = 7) : + PublicInputContainerType public_input, std::size_t num_blocks_, std::size_t num_bits_, + bool range_check_input_, std::size_t lpc_ = 7) : component_type(witness, constant, public_input, get_manifest()), - num_blocks(num_blocks_), - num_bits(num_bits_), - range_check_input(range_check_input_), + num_blocks(num_blocks_), num_bits(num_bits_), range_check_input(range_check_input_), limit_permutation_column(lpc_), padding(witness, constant, public_input, num_blocks_, num_bits_, range_check_input_, lpc_), - num_round_calls(calculate_num_round_calls(num_blocks_)) {}; - // { - // round_true_true = round_component_type(witness, constant, public_input, true, true, lpc_), - // for (std::size_t i = 1; i < num_round_calls; ++i) { - // rounds_true_false.push_back(round_component_type(witness, constant, public_input, true, false, lpc_)); - // } - // for (std::size_t i = 0; i < num_round_calls; ++i) { - // for (std::size_t j = 0; j < 23; ++j) { - // rounds_false_false.push_back(round_component_type(witness, constant, public_input, false, false, lpc_)); - // } - // } - // round_tt_rows = round_true_true.rows_amount; - // round_tf_rows = rounds_true_false[0].rows_amount; - // round_ff_rows = rounds_false_false[0].rows_amount; - // round_tt_gates = round_true_true.gates_amount; - // round_tf_gates = rounds_true_false[0].gates_amount; - // round_ff_gates = rounds_false_false[0].gates_amount; - // }; - - keccak( - std::initializer_list witnesses, - std::initializer_list constants, - std::initializer_list public_inputs, - std::size_t num_blocks_, std::size_t num_bits_, bool range_check_input_, std::size_t lpc_ = 7) : - component_type(witnesses, constants, public_inputs), - num_blocks(num_blocks_), - num_bits(num_bits_), - range_check_input(range_check_input_), - limit_permutation_column(lpc_), - padding(witnesses, constants, public_inputs, num_blocks_, num_bits_, range_check_input_, lpc_), - num_round_calls(calculate_num_round_calls(num_blocks_)) {}; - // round_true_true(witness, constant, public_input, true, true, lpc_), - // { - // for (std::size_t i = 1; i < num_round_calls; ++i) { - // rounds_true_false.push_back(round_component_type(witness, constant, public_input, true, false, lpc_)); - // } - // for (std::size_t i = 0; i < num_round_calls; ++i) { - // for (std::size_t j = 0; j < 23; ++j) { - // rounds_false_false.push_back(round_component_type(witness, constant, public_input, false, false, lpc_)); - // } - // } - // }; + num_round_calls(calculate_num_round_calls(num_blocks_)), + round_tt(witness, constant, public_input, true, true, lpc_), + round_tf(witness, constant, public_input, true, false, lpc_), + round_ff(witness, constant, public_input, false, false, lpc_) { + + round_tt_rows = round_tt.rows_amount; + round_tf_rows = round_tf.rows_amount; + round_ff_rows = round_ff.rows_amount; + round_tt_gates = round_tt.gates_amount; + round_tf_gates = round_tf.gates_amount; + round_ff_gates = round_ff.gates_amount; + }; + keccak(std::initializer_list witnesses, + std::initializer_list constants, + std::initializer_list + public_inputs, + std::size_t num_blocks_, std::size_t num_bits_, bool range_check_input_, std::size_t lpc_ = 7) : + component_type(witnesses, constants, public_inputs), + num_blocks(num_blocks_), num_bits(num_bits_), range_check_input(range_check_input_), + limit_permutation_column(lpc_), + padding(witnesses, constants, public_inputs, num_blocks_, num_bits_, range_check_input_, lpc_), + num_round_calls(calculate_num_round_calls(num_blocks_)), + round_tt(witnesses, constants, public_inputs, true, true, lpc_), + round_tf(witnesses, constants, public_inputs, true, false, lpc_), + round_ff(witnesses, constants, public_inputs, false, false, lpc_) { + + round_tt_rows = round_tt.rows_amount; + round_tf_rows = round_tf.rows_amount; + round_ff_rows = round_ff.rows_amount; + round_tt_gates = round_tt.gates_amount; + round_tf_gates = round_tf.gates_amount; + round_ff_gates = round_ff.gates_amount; + }; }; template - using keccak_component = - keccak>; + using keccak_component = keccak>; template std::vector generate_gates( - const keccak_component - &component, - circuit> - &bp, - assignment> - &assignment, - const typename keccak_component::input_type - &instance_input, + const keccak_component &component, + circuit> &bp, + assignment> &assignment, + const typename keccak_component::input_type &instance_input, const typename lookup_library::left_reserved_type lookup_tables_indices) { using component_type = keccak_component; @@ -591,7 +626,8 @@ namespace nil { using constraint_type = crypto3::zk::snark::plonk_constraint; using gate_type = typename crypto3::zk::snark::plonk_gate; using lookup_constraint_type = typename crypto3::zk::snark::plonk_lookup_constraint; - using lookup_gate_type = typename crypto3::zk::snark::plonk_gate; + using lookup_gate_type = + typename crypto3::zk::snark::plonk_gate; using value_type = typename BlueprintFieldType::value_type; using integral_type = typename BlueprintFieldType::integral_type; @@ -604,25 +640,47 @@ namespace nil { std::vector lookup_constraints_0; std::vector lookup_constraints_1; auto conf = config[0]; - constraint_type constraint_0 = var(conf.constraints[0][0].column, static_cast(conf.constraints[0][0].row)); - constraint_type constraint_1 = var(conf.constraints[1][0].column, static_cast(conf.constraints[1][0].row)); + + // pack gate + constraint_type constraint_0 = + var(conf.constraints[0][0].column, static_cast(conf.constraints[0][0].row)); + constraint_type constraint_1 = + var(conf.constraints[1][0].column, static_cast(conf.constraints[1][0].row)); + + constraint_type constraint_2 = + var(conf.constraints[1][0].column, static_cast(conf.constraints[1][0].row)); + constraint_type constraint_3 = + var(conf.constraints[0][0].column, static_cast(conf.constraints[0][0].row)); for (std::size_t i = 1; i < 9; ++i) { - constraint_0 -= var(conf.constraints[0][i].column, static_cast(conf.constraints[0][i].row)) - * (integral_type(1) << ((i-1) * 8)); - constraint_1 -= var(conf.constraints[1][i].column, static_cast(conf.constraints[1][i].row)) - * (integral_type(1) << ((i-1) * 24)); + constraint_0 -= + var(conf.constraints[0][i].column, static_cast(conf.constraints[0][i].row)) * + (integral_type(1) << ((i - 1) * 8)); + constraint_1 -= + var(conf.constraints[1][i].column, static_cast(conf.constraints[1][i].row)) * + (integral_type(1) << ((8 - i) * 24)); + constraint_2 -= + var(conf.constraints[1][i].column, static_cast(conf.constraints[1][i].row)) * + (integral_type(1) << ((i - 1) * 8)); + constraint_3 -= + var(conf.constraints[0][i].column, static_cast(conf.constraints[0][i].row)) * + (integral_type(1) << ((i - 1) * 24)); lookup_constraints_0.push_back({lookup_tables_indices.at("keccak_pack_table/full"), - {var(component.W(conf.constraints[0][i].column), static_cast(conf.constraints[0][i].row)), - var(component.W(conf.constraints[1][i].column), static_cast(conf.constraints[1][i].row))}}); + {var(component.W(conf.constraints[0][i].column), + static_cast(conf.constraints[0][i].row)), + var(component.W(conf.constraints[1][i].column), + static_cast(conf.constraints[1][i].row))}}); lookup_constraints_1.push_back({lookup_tables_indices.at("keccak_pack_table/full"), - {var(component.W(conf.constraints[1][i].column), static_cast(conf.constraints[1][i].row)), - var(component.W(conf.constraints[0][i].column), static_cast(conf.constraints[0][i].row))}}); + {var(component.W(conf.constraints[1][i].column), + static_cast(conf.constraints[1][i].row)), + var(component.W(conf.constraints[0][i].column), + static_cast(conf.constraints[0][i].row))}}); } selector_indexes.push_back(bp.add_gate({constraint_0, constraint_1})); + selector_indexes.push_back(bp.add_gate({constraint_2})); gate_index++; - // selector_indexes.push_back(bp.add_lookup_gate(lookup_constraints_0)); - // selector_indexes.push_back(bp.add_lookup_gate(lookup_constraints_1)); - // lookup_gate_index += 2; + selector_indexes.push_back(bp.add_lookup_gate(lookup_constraints_0)); + selector_indexes.push_back(bp.add_lookup_gate(lookup_constraints_1)); + lookup_gate_index += 2; } return selector_indexes; @@ -630,38 +688,111 @@ namespace nil { template void generate_copy_constraints( - const keccak_component - &component, - circuit> - &bp, - assignment> - &assignment, - const typename keccak_component::input_type - &instance_input, + const keccak_component &component, + circuit> &bp, + assignment> &assignment, + const typename keccak_component::input_type &instance_input, const std::uint32_t start_row_index) { using component_type = keccak_component; + using padding_type = typename component_type::padding_component_type; + using round_type = typename component_type::round_component_type; using var = typename component_type::var; - std::uint32_t row = start_row_index; + std::uint32_t cur_row = start_row_index; + + std::size_t config_index = 0; + std::size_t prev_index = 0; + auto config = component.full_configuration; + + auto padded_message = + typename padding_type::result_type(component.padding, start_row_index).padded_message; + cur_row += component.padding.rows_amount; + + for (std::size_t i = 0; i < padded_message.size(); i++) { + bp.add_copy_constraint( + {padded_message[i], + var(component.W(config[config_index].copy_to[0].column), + static_cast(config[config_index].copy_to[0].row + cur_row), false)}); + config_index++; + } + cur_row += config[config_index - 1].last_coordinate.row + + (config[config_index - 1].last_coordinate.column > 0); + + std::array inner_state; + auto prev_row = cur_row; + + auto gate_map_tf = component.round_tf.gates_configuration_map; + std::vector rotate_rows_tf; + for (auto g : gate_map_tf) { + if (g.first.first == 7) { + rotate_rows_tf.insert(rotate_rows_tf.end(), g.second.begin(), g.second.end()); + } + } + std::sort(rotate_rows_tf.begin(), rotate_rows_tf.end()); + + auto gate_map_ff = component.round_ff.gates_configuration_map; + std::vector rotate_rows_ff; + for (auto g : gate_map_ff) { + if (g.first.first == 7) { + rotate_rows_ff.insert(rotate_rows_ff.end(), g.second.begin(), g.second.end()); + } + } + std::sort(rotate_rows_ff.begin(), rotate_rows_ff.end()); + + for (int i = 0; i < component.num_round_calls; i++) { + for (int j = 0; j < 24; j++) { + // if (i + j != 0) { + // std::cout << "prev: " << prev_row << " vs curr" << cur_row << std::endl; + // for (int k = 0; k < 5; k++) { + // auto ind1 = (j == 1) ? rotate_rows_tf[k] : rotate_rows_ff[k]; + // auto ind2 = rotate_rows_ff[k]; + // std::cout << ind1 << " , " << ind2 << std::endl; + // std::cout + // << var_value(assignment, var(component.C(0), prev_row + ind1, false)).data << + // " vs " + // << var_value(assignment, var(component.C(0), cur_row + ind2, false)).data << + // std::endl; + // bp.add_copy_constraint({var(component.C(0), prev_row + ind1, false), + // var(component.C(0), cur_row + ind2, false)}); + // } + // prev_row = cur_row; + // } + if (i == component.num_round_calls - 1 && j == 0) { + cur_row += component.round_tt.rows_amount; + } else if (j == 0) { + cur_row += component.round_tf.rows_amount; + } else { + inner_state = typename round_type::result_type(component.round_ff, cur_row).inner_state; + cur_row += component.round_ff.rows_amount; + } + } + } + + for (std::size_t i = 0; i < 5; i++) { + bp.add_copy_constraint( + {inner_state[i], var(component.W(config[config_index].copy_to[0].column), + static_cast(config[config_index].copy_to[0].row + cur_row), false)}); + config_index++; + } + cur_row += config[config_index - 1].last_coordinate.row + + (config[config_index - 1].last_coordinate.column > 0); + // BOOST_ASSERT(cur_row == start_row_index + component.rows_amount); } template - typename keccak_component::result_type - generate_circuit( - const keccak_component - &component, - circuit> - &bp, - assignment> - &assignment, - const typename keccak_component::input_type - &instance_input, + typename keccak_component::result_type generate_circuit( + const keccak_component &component, + circuit> &bp, + assignment> &assignment, + const typename keccak_component::input_type &instance_input, const std::uint32_t start_row_index) { using component_type = keccak_component; using padding_type = typename component_type::padding_component_type; + using round_type = typename component_type::round_component_type; + using var = typename component_type::var; generate_assignments_constant(component, bp, assignment, instance_input, start_row_index); std::size_t row = start_row_index; @@ -672,82 +803,128 @@ namespace nil { } std::vector zero_column = {0}; - padding_type padding_component_instance(witnesses, zero_column, zero_column, - component.num_blocks, component.num_bits, - component.range_check_input, + padding_type padding_component_instance(witnesses, zero_column, zero_column, component.num_blocks, + component.num_bits, component.range_check_input, component.limit_permutation_column); typename padding_type::input_type padding_input = {instance_input.message}; - typename padding_type::result_type padding_result = generate_circuit(padding_component_instance, bp, assignment, padding_input, row); + typename padding_type::result_type padding_result = + generate_circuit(padding_component_instance, bp, assignment, padding_input, row); row += padding_component_instance.rows_amount; - auto selector_indexes = generate_gates(component, bp, assignment, instance_input, bp.get_reserved_indices()); + auto selector_indexes = + generate_gates(component, bp, assignment, instance_input, bp.get_reserved_indices()); auto config_map = component.gates_configuration_map; std::size_t sel_ind = 0; for (auto config : config_map) { if (config.first < component.witnesses) { for (auto gate_row : config.second) { - // std::cout << "enabling: " << selector_indexes[sel_ind] << " " << selector_indexes[sel_ind + 1] << std::endl; + // std::cout << "enabling: " << selector_indexes[sel_ind] << " " + // << selector_indexes[sel_ind + 1] << " at " << gate_row + row << std::endl; assignment.enable_selector(selector_indexes[sel_ind], gate_row + row); - // assignment.enable_selector(selector_indexes[sel_ind + 1], gate_row + row); + assignment.enable_selector(selector_indexes[sel_ind + 2], gate_row + row); } - // std::cout << std::endl; + std::cout << std::endl; sel_ind += 1; } } - sel_ind = 0; + + std::size_t config_index = 0; + std::vector sparse_padded_message_coords(padding_result.padded_message.size()); + for (std::size_t index = 0; index < padding_result.padded_message.size(); index++) { + auto cur_config = component.full_configuration[config_index]; + sparse_padded_message_coords[index] = var(component.W(cur_config.constraints[1][0].column), + cur_config.constraints[1][0].row + row, false); + config_index++; + } + + row += component.full_configuration[config_index - 1].last_coordinate.row + + (component.full_configuration[config_index - 1].last_coordinate.column > 0); + + // round circuits + std::array inner_state; + for (std::uint32_t i = 0; i < 25; i++) { + inner_state[i] = var(component.C(0), start_row_index, false, var::column_type::constant); + } + std::array pmc; + std::size_t offset = 0; + for (std::size_t i = 0; i < component.num_round_calls; ++i) { + std::copy(sparse_padded_message_coords.begin() + offset, + sparse_padded_message_coords.begin() + offset + 17, + pmc.begin()); + + for (std::size_t j = 0; j < 24; ++j) { + typename round_type::input_type round_input = { + inner_state, pmc, + var(component.C(0), start_row_index + j + 4, false, var::column_type::constant)}; + if (i == component.num_round_calls - 1 && j == 0) { + typename round_type::result_type round_result = + generate_circuit(component.round_tt, bp, assignment, round_input, row); + inner_state = round_result.inner_state; + row += component.round_tt.rows_amount; + } else if (j == 0) { + typename round_type::result_type round_result = + generate_circuit(component.round_tf, bp, assignment, round_input, row); + inner_state = round_result.inner_state; + row += component.round_tf.rows_amount; + } else { + typename round_type::result_type round_result = + generate_circuit(component.round_ff, bp, assignment, round_input, row); + inner_state = round_result.inner_state; + row += component.round_ff.rows_amount; + } + } + offset += 17; + } + + std::cout << "after rounds row: " << row << std::endl; + // sel_ind = 0; for (auto config : config_map) { if (config.first >= 10 * component.witnesses) { for (auto gate_row : config.second) { - // std::cout << "enabling2: " << selector_indexes[sel_ind] << " " << selector_indexes[sel_ind + 2] << std::endl; + // std::cout << "enabling2: " << selector_indexes[sel_ind] << " " + // << selector_indexes[sel_ind + 2] << " at " << gate_row + row << std::endl; assignment.enable_selector(selector_indexes[sel_ind], gate_row + row); - // assignment.enable_selector(selector_indexes[sel_ind + 2], gate_row + row); + assignment.enable_selector(selector_indexes[sel_ind + 2], gate_row + row); } - // std::cout << std::endl; + std::cout << std::endl; sel_ind += 1; } } - using component_type = keccak_component; - using var = typename component_type::var; - generate_copy_constraints(component, bp, assignment, instance_input, start_row_index); return typename component_type::result_type(component, start_row_index); } template - typename keccak_component::result_type - generate_assignments( - const keccak_component - &component, - assignment> - &assignment, - const typename keccak_component::input_type - &instance_input, + typename keccak_component::result_type generate_assignments( + const keccak_component &component, + assignment> &assignment, + const typename keccak_component::input_type &instance_input, const std::uint32_t start_row_index) { std::size_t cur_row = start_row_index; using component_type = keccak_component; + using round_type = typename component_type::round_component_type; using value_type = typename BlueprintFieldType::value_type; using integral_type = typename BlueprintFieldType::integral_type; using var = typename component_type::var; - std::vector padded_message = generate_assignments(component.padding, assignment, - {instance_input.message}, cur_row).padded_message; + std::vector padded_message = + generate_assignments(component.padding, assignment, {instance_input.message}, cur_row) + .padded_message; cur_row += component.padding.rows_amount; - // std::cout << "padded_message: " << padded_message.size() << ' ' << component.padding.rows_amount << std::endl; - // std::cout << component.rows_amount << std::endl; // to sparse std::size_t config_index = 0; std::vector sparse_padded_message(padded_message.size()); + std::vector sparse_padded_message_coords(padded_message.size()); for (std::size_t index = 0; index < padded_message.size(); ++index) { value_type regular_value = var_value(assignment, padded_message[index]); integral_type regular = integral_type(regular_value.data); // std::cout << "pad elem: " << regular << std::endl; - integral_type sparse = component.pack(regular); - auto copy_sparse = sparse; + auto sparse = integral_type(0); auto chunk_size = component.pack_chunk_size; auto num_chunks = component.pack_num_chunks; std::vector integral_chunks; @@ -755,51 +932,90 @@ namespace nil { integral_type mask = (integral_type(1) << chunk_size) - 1; integral_type sparse_mask = (integral_type(1) << (chunk_size * 3)) - 1; integral_type power = 1; - // std::cout << "sparse: " << sparse << std::endl; + for (std::size_t j = 0; j < num_chunks; ++j) { integral_chunks.push_back(regular & mask); regular >>= chunk_size; - integral_sparse_chunks.push_back(sparse & sparse_mask); - sparse >>= (chunk_size * 3); - // std::cout << "chunks: " << integral_chunks.back() << " " << integral_sparse_chunks.back() << std::endl; - copy_sparse -= power * integral_sparse_chunks.back(); + integral_sparse_chunks.push_back(component.pack(integral_chunks.back())); + // std::cout << "chunks: " << integral_chunks.back() << " " << integral_sparse_chunks.back() + // << std::endl; + } + for (std::size_t j = 0; j < num_chunks; ++j) { + sparse = sparse + power * integral_sparse_chunks[num_chunks - j - 1]; power <<= (3 * chunk_size); } + // std::cout << "sparse: " << sparse << std::endl; sparse_padded_message[index] = value_type(sparse); auto cur_config = component.full_configuration[config_index]; - assignment.witness(component.W(cur_config.constraints[0][0].column), cur_config.constraints[0][0].row + cur_row) = regular_value; - assignment.witness(component.W(cur_config.constraints[1][0].column), cur_config.constraints[1][0].row + cur_row) = value_type(sparse); - // std::cout << cur_config.constraints[1][0].column << ' ' << cur_config.constraints[1][0].row + cur_row << std::endl; + assignment.witness(component.W(cur_config.constraints[0][0].column), + cur_config.constraints[0][0].row + cur_row) = regular_value; + assignment.witness(component.W(cur_config.constraints[1][0].column), + cur_config.constraints[1][0].row + cur_row) = value_type(sparse); + // std::cout << cur_config.constraints[1][0].column << ' ' << cur_config.constraints[1][0].row + + // cur_row << std::endl; + sparse_padded_message_coords[index] = var(component.W(cur_config.constraints[1][0].column), + cur_config.constraints[1][0].row + cur_row, false); for (int j = 1; j < num_chunks + 1; ++j) { - assignment.witness(component.W(cur_config.constraints[0][j].column), cur_config.constraints[0][j].row + cur_row) = value_type(integral_chunks[j - 1]); - assignment.witness(component.W(cur_config.constraints[1][j].column), cur_config.constraints[1][j].row + cur_row) = value_type(integral_sparse_chunks[j - 1]); + assignment.witness(component.W(cur_config.constraints[0][j].column), + cur_config.constraints[0][j].row + cur_row) = + value_type(integral_chunks[j - 1]); + assignment.witness(component.W(cur_config.constraints[1][j].column), + cur_config.constraints[1][j].row + cur_row) = + value_type(integral_sparse_chunks[j - 1]); } config_index++; } - // std::cout << "here: " << component.full_configuration[config_index - 1].last_coordinate.row << std::endl; - cur_row += component.full_configuration[config_index - 1].last_coordinate.row - + (component.full_configuration[config_index - 1].last_coordinate.column > 0); + + cur_row += component.full_configuration[config_index - 1].last_coordinate.row + + (component.full_configuration[config_index - 1].last_coordinate.column > 0); std::array inner_state; - // for (std::size_t i = 0; i < component.num_round_calls; ++i) { - // for (std::size_t j = 0; j < 24; ++j) { - // auto round_input = typename component_type::round_component_type::input_type(); - // round_input.padded_message_chunk;// = instance_input.message; - // round_input.inner_state = inner_state; - // round_input.round_constant = var(component.C(0), row + i, false, var::column_type::constant); - // inner_state = generate_assignments(component.rounds[i * 24 + j], assignment, round_input, row).inner_state; - // row += component.rounds[i * 24 + j].rows_amount; - // } - // } + for (std::uint32_t i = 0; i < 25; i++) { + inner_state[i] = var(component.C(0), start_row_index, false, var::column_type::constant); + } + + std::size_t offset = 0; + std::array pmc; + for (std::size_t i = 0; i < component.num_round_calls; ++i) { + std::copy(sparse_padded_message_coords.begin() + offset, + sparse_padded_message_coords.begin() + offset + 17, pmc.begin()); + for (auto &el : pmc) { + std::cout << component.unpack(integral_type(var_value(assignment, el).data)) << ","; + } + std::cout << std::endl; + + for (std::size_t j = 0; j < 24; ++j) { + typename round_type::input_type round_input = { + inner_state, pmc, + var(component.C(0), start_row_index + j + 4, false, var::column_type::constant)}; + if (i == component.num_round_calls - 1 && j == 0) { + typename round_type::result_type round_result = + generate_assignments(component.round_tt, assignment, round_input, cur_row); + inner_state = round_result.inner_state; + cur_row += component.round_tt.rows_amount; + } else if (j == 0) { + typename round_type::result_type round_result = + generate_assignments(component.round_tf, assignment, round_input, cur_row); + inner_state = round_result.inner_state; + cur_row += component.round_tf.rows_amount; + } else { + typename round_type::result_type round_result = + generate_assignments(component.round_ff, assignment, round_input, cur_row); + inner_state = round_result.inner_state; + cur_row += component.round_ff.rows_amount; + } + } + offset += 17; + } // from sparse for (std::size_t index = 0; index < 5; ++index) { - // value_type sparse_value = var_value(assignment, inner_state[index]); - integral_type sparse = integral_type(0); + value_type sparse_value = var_value(assignment, inner_state[index]); + integral_type sparse = integral_type(sparse_value.data); integral_type regular = component.unpack(sparse); - // std::cout << "from sparse: " << sparse << " " << regular << std::endl; - auto chunk_size = component.pack_chunk_size; + // std::cout << "from sparse: " << sparse << " to regular " << regular << std::endl; + auto chunk_size = component.pack_chunk_size * 3; auto num_chunks = component.pack_num_chunks; std::vector integral_sparse_chunks; std::vector integral_chunks; @@ -809,50 +1025,53 @@ namespace nil { sparse >>= chunk_size; integral_sparse_chunks.push_back(component.unpack(integral_chunks.back())); } + sparse_padded_message[index] = value_type(regular); auto cur_config = component.full_configuration[config_index]; - assignment.witness(component.W(cur_config.constraints[0][0].column), cur_config.constraints[0][0].row + cur_row) = value_type(sparse); - assignment.witness(component.W(cur_config.constraints[1][0].column), cur_config.constraints[1][0].row + cur_row) = value_type(regular); + assignment.witness(component.W(cur_config.constraints[0][0].column), + cur_config.constraints[0][0].row + cur_row) = sparse_value; + assignment.witness(component.W(cur_config.constraints[1][0].column), + cur_config.constraints[1][0].row + cur_row) = value_type(regular); for (int j = 1; j < num_chunks + 1; ++j) { - assignment.witness(component.W(cur_config.constraints[0][j].column), cur_config.constraints[0][j].row + cur_row) = value_type(integral_sparse_chunks[j - 1]); - assignment.witness(component.W(cur_config.constraints[1][j].column), cur_config.constraints[1][j].row + cur_row) = value_type(integral_chunks[j - 1]); + assignment.witness(component.W(cur_config.constraints[0][j].column), + cur_config.constraints[0][j].row + cur_row) = + value_type(integral_chunks[j - 1]); + assignment.witness(component.W(cur_config.constraints[1][j].column), + cur_config.constraints[1][j].row + cur_row) = + value_type(integral_sparse_chunks[j - 1]); } config_index++; } - // std::cout << "here: " << component.full_configuration[config_index - 1].last_coordinate.row << std::endl; - cur_row += component.full_configuration[config_index - 1].last_coordinate.row - + (component.full_configuration[config_index - 1].last_coordinate.column > 0); - BOOST_ASSERT(cur_row == start_row_index + component.rows_amount); + cur_row += component.full_configuration[config_index - 1].last_coordinate.row + + (component.full_configuration[config_index - 1].last_coordinate.column > 0); + + // BOOST_ASSERT(cur_row == start_row_index + component.rows_amount); + std::cout << cur_row << " vs " << component.rows_amount << std::endl; return typename component_type::result_type(component, start_row_index); } template void generate_assignments_constant( - const keccak_component - &component, - circuit> - &bp, - assignment> - &assignment, - const typename keccak_component::input_type - &instance_input, + const keccak_component &component, + circuit> &bp, + assignment> &assignment, + const typename keccak_component::input_type &instance_input, const std::uint32_t start_row_index) { using component_type = keccak_component; using integral_type = typename BlueprintFieldType::integral_type; - std::size_t row = start_row_index + 3; + std::size_t row = start_row_index + 4; for (std::size_t i = 0; i < 24; ++i) { - assignment.constant(component.C(0), row + i) = component.round_constant[i]; + assignment.constant(component.C(0), row + i) = component.pack(component.round_constant[i]); } } - } // namespace components } // namespace blueprint -} // namespace nil +} // namespace nil -#endif // CRYPTO3_BLUEPRINT_COMPONENTS_KECCAK_ROUND_HPP \ No newline at end of file +#endif // CRYPTO3_BLUEPRINT_COMPONENTS_KECCAK_ROUND_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/hashes/keccak/keccak_padding.hpp b/include/nil/blueprint/components/hashes/keccak/keccak_padding.hpp index 24a64d7c0..bf4aeda8a 100644 --- a/include/nil/blueprint/components/hashes/keccak/keccak_padding.hpp +++ b/include/nil/blueprint/components/hashes/keccak/keccak_padding.hpp @@ -1,5 +1,6 @@ //---------------------------------------------------------------------------// // Copyright (c) 2023 Polina Chernyshova +// 2024 Valeh Farzaliyev // // MIT License // @@ -49,6 +50,7 @@ namespace nil { using component_type = plonk_component; using value_type = typename BlueprintFieldType::value_type; + using integral_type = typename BlueprintFieldType::integral_type; public: struct coordinates { @@ -170,7 +172,9 @@ namespace nil { const std::size_t num_blocks; const std::size_t num_bits; std::size_t shift = calculate_shift(num_blocks, num_bits); - std::size_t num_padding_zeros = calculate_num_padding_zeros(num_blocks); + std::size_t num_padding_zeros = calculate_num_padding_zeros(num_blocks, shift); + + const integral_type padding_delimiter = integral_type(1) << 56; const std::size_t num_cells = calculate_num_cells(num_blocks, num_bits, range_check_input); const std::size_t buff = calculate_buff(this->witness_amount(), range_check_input); @@ -212,7 +216,11 @@ namespace nil { padded_message[i] = var(component.W(config.copy_to.back().column), config.copy_to.back().row + start_row_index, false); } - for (std::size_t i = size; i < size + component.num_padding_zeros; ++i) { + if(component.shift == 0){ + padded_message[size] = var(component.C(0), start_row_index + 3, false, var::column_type::constant); + } + + for (std::size_t i = size + (component.shift == 0); i < size + component.num_padding_zeros; ++i) { padded_message[i] = var(component.C(0), start_row_index, false, var::column_type::constant); } } @@ -226,8 +234,11 @@ namespace nil { // assert(num_blocks * 64 >= num_bits); return num_blocks * 64 - num_bits; } - static std::size_t calculate_num_padding_zeros(std::size_t num_blocks) { + static std::size_t calculate_num_padding_zeros(std::size_t num_blocks, std::size_t shift) { if (num_blocks % 17 == 0){ + if(shift == 0 ){ + return 17; + } return 0; } return 17 - num_blocks % 17; @@ -625,7 +636,7 @@ namespace nil { std::size_t limit_permutation_column) { auto confs = configure_all(witness_amount, num_blocks, num_bits, range_check_input, limit_permutation_column); auto res = confs.back().last_coordinate.row + 1 * (confs.back().last_coordinate.column != 0); - if (res < 3) res = 3; + if (res < 4) res = 4; return res; } @@ -840,7 +851,7 @@ namespace nil { } if (component.shift != 0) { auto config = component.full_configuration[config_index++]; - bp.add_copy_constraint({var(component.C(0), start_row_index, false, var::column_type::constant), + bp.add_copy_constraint({var(component.C(0), start_row_index + 3, false, var::column_type::constant), var(component.W(config.copy_to[conf_index_for_input].column), config.copy_to[conf_index_for_input].row + strow, false)}); } else { @@ -934,7 +945,7 @@ namespace nil { if (component.shift != 0) { integral_type relay_chunk = integral_type(var_value(assignment, instance_input.message[0]).data); for (std::size_t index = 1; index < component.num_blocks + 1; ++index) { - value_type chunk = 0; + value_type chunk = value_type(component.padding_delimiter); if (index < component.num_blocks) { chunk = var_value(assignment, instance_input.message[index]); } @@ -1019,10 +1030,12 @@ namespace nil { const std::uint32_t start_row_index) { using component_type = padding_component; + using value_type = typename BlueprintFieldType::value_type; - assignment.constant(component.C(0), start_row_index) = 0; + assignment.constant(component.C(0), start_row_index) = 0; assignment.constant(component.C(0), start_row_index + 1) = component.num_blocks; assignment.constant(component.C(0), start_row_index + 2) = component.num_bits; + assignment.constant(component.C(0), start_row_index + 3) = value_type(component.padding_delimiter); } } // namespace components diff --git a/include/nil/blueprint/components/hashes/keccak/keccak_round.hpp b/include/nil/blueprint/components/hashes/keccak/keccak_round.hpp index be2ab99be..6524b567d 100644 --- a/include/nil/blueprint/components/hashes/keccak/keccak_round.hpp +++ b/include/nil/blueprint/components/hashes/keccak/keccak_round.hpp @@ -1,6 +1,6 @@ //---------------------------------------------------------------------------// // Copyright (c) 2023 Polina Chernyshova -// +// 2024 Valeh Farzaliyev // MIT License // // Permission is hereby granted, free of charge, to any person obtaining a copy @@ -42,7 +42,6 @@ #include #include - namespace nil { namespace blueprint { namespace components { @@ -50,19 +49,21 @@ namespace nil { class keccak_round; template - class keccak_round> : - public plonk_component { + class keccak_round> + : public plonk_component { using component_type = plonk_component; using value_type = typename BlueprintFieldType::value_type; using integral_type = typename BlueprintFieldType::integral_type; - using lookup_table_definition = typename nil::crypto3::zk::snark::lookup_table_definition; + using lookup_table_definition = + typename nil::crypto3::zk::snark::lookup_table_definition; // xor2 - base=3, xor3 - base=4, xor5 - base=6, chi - base=2, rotate - base=0 int bases[5] = {3, 4, 6, 2, 0}; static std::size_t calculate_chunk_size(std::size_t num_rows, std::size_t base = 0) { - if (base == 0) return 8; + if (base == 0) + return 8; std::size_t chunk_size = 0; std::size_t power = base; while (power < num_rows) { @@ -72,21 +73,21 @@ namespace nil { return chunk_size * 3; } static std::size_t calculate_num_chunks(std::size_t num_rows, std::size_t base = 0) { - if (base == 0) return 8; + if (base == 0) + return 8; std::size_t chunk_size = calculate_chunk_size(num_rows, base); std::size_t res = 192 / chunk_size + bool(192 % chunk_size); return res; } static std::size_t calculate_num_cells(std::size_t num_rows, std::size_t base = 0) { - if (base == 0) return 24; - std::size_t res = base == 3 ? 2 + 2 - : base == 4 ? 3 + 2 - : base == 6 ? 5 + 2 - : 5; + if (base == 0) + return 24; + std::size_t res = base == 3 ? 2 + 2 : base == 4 ? 3 + 2 : base == 6 ? 5 + 2 : 5; res += 2 * calculate_num_chunks(num_rows, base); return res; } - static std::size_t calculate_buff(std::size_t witness_amount, std::size_t num_rows, std::size_t base = 0) { + static std::size_t calculate_buff(std::size_t witness_amount, std::size_t num_rows, + std::size_t base = 0) { std::size_t buff = 0; std::size_t cells = calculate_num_cells(num_rows, base); if (base == 0) { @@ -112,14 +113,15 @@ namespace nil { return buff; } static std::size_t calculate_last_round_call_row(std::size_t witness_amount, - bool xor_with_mes, - bool last_round_call, - std::size_t limit_permutation_column) { + bool xor_with_mes, + bool last_round_call, + std::size_t limit_permutation_column) { if (!last_round_call) { return 0; } std::size_t res = 0; - auto gates_configuration_map = configure_map(witness_amount, xor_with_mes, last_round_call, limit_permutation_column); + auto gates_configuration_map = + configure_map(witness_amount, xor_with_mes, last_round_call, limit_permutation_column); for (auto g : gates_configuration_map) { if (g.first.first == 3) { res = g.second[0]; @@ -143,14 +145,15 @@ namespace nil { gate_manifest_type(std::size_t witness_amount_, bool xor_with_mes_, bool last_round_call_, - std::size_t limit_permutation_column_) - : witness_amount(std::min(witness_amount_, clamp)), - xor_with_mes(xor_with_mes_), - last_round_call(last_round_call_), - limit_permutation_column(limit_permutation_column_) {} + std::size_t limit_permutation_column_) : + witness_amount(std::min(witness_amount_, clamp)), + xor_with_mes(xor_with_mes_), last_round_call(last_round_call_), + limit_permutation_column(limit_permutation_column_) { + } std::uint32_t gates_amount() const override { - return keccak_round::get_gates_amount(witness_amount, xor_with_mes, last_round_call, limit_permutation_column); + return keccak_round::get_gates_amount(witness_amount, xor_with_mes, last_round_call, + limit_permutation_column); } }; @@ -159,18 +162,14 @@ namespace nil { bool xor_with_mes, bool last_round_call, std::size_t limit_permutation_column) { - gate_manifest manifest = - gate_manifest(gate_manifest_type(witness_amount, xor_with_mes, last_round_call, - limit_permutation_column)); + gate_manifest manifest = gate_manifest( + gate_manifest_type(witness_amount, xor_with_mes, last_round_call, limit_permutation_column)); return manifest; } static manifest_type get_manifest() { - static manifest_type manifest = manifest_type( - std::shared_ptr( - new manifest_range_param(9, 15)), - false - ); + static manifest_type manifest = + manifest_type(std::shared_ptr(new manifest_range_param(9, 15)), false); return manifest; } @@ -182,10 +181,10 @@ namespace nil { coordinates() = default; coordinates(std::size_t row_, std::size_t column_) : row(row_), column(column_) {}; coordinates(std::pair pair) : row(pair.first), column(pair.second) {}; - bool operator== (const coordinates& other) const { + bool operator==(const coordinates &other) const { return row == other.row && column == other.column; } - bool operator< (const coordinates& other) const { + bool operator<(const coordinates &other) const { return row < other.row || (row == other.row && column < other.column); } }; @@ -202,43 +201,45 @@ namespace nil { configuration() = default; configuration(std::pair first_coordinate_, - std::pair last_coordinate_, - std::vector> copy_to_, - std::vector>> constraints_, - std::vector>> lookups_, - std::pair copy_from_){ - first_coordinate = coordinates(first_coordinate_); - last_coordinate = coordinates(last_coordinate_); - for (std::size_t i = 0; i < copy_to_.size(); ++i) { - copy_to.push_back(coordinates(copy_to_[i])); - } - for (std::size_t i = 0; i < constraints_.size(); ++i) { - std::vector constr; - for (std::size_t j = 0; j < constraints_[i].size(); ++j) { - constr.push_back(coordinates(constraints_[i][j])); - } - constraints.push_back(constr); + std::pair + last_coordinate_, + std::vector> + copy_to_, + std::vector>> + constraints_, + std::vector>> + lookups_, + std::pair + copy_from_) { + first_coordinate = coordinates(first_coordinate_); + last_coordinate = coordinates(last_coordinate_); + for (std::size_t i = 0; i < copy_to_.size(); ++i) { + copy_to.push_back(coordinates(copy_to_[i])); + } + for (std::size_t i = 0; i < constraints_.size(); ++i) { + std::vector constr; + for (std::size_t j = 0; j < constraints_[i].size(); ++j) { + constr.push_back(coordinates(constraints_[i][j])); } - for (std::size_t i = 0; i < lookups_.size(); ++i) { - std::vector lookup; - for (std::size_t j = 0; j < lookups_[i].size(); ++j) { - lookup.push_back(coordinates(lookups_[i][j])); - } - lookups.push_back(lookup); + constraints.push_back(constr); + } + for (std::size_t i = 0; i < lookups_.size(); ++i) { + std::vector lookup; + for (std::size_t j = 0; j < lookups_[i].size(); ++j) { + lookup.push_back(coordinates(lookups_[i][j])); } - copy_from = coordinates(copy_from_); - }; - bool operator== (const configuration& other) const { - return first_coordinate == other.first_coordinate && - last_coordinate == other.last_coordinate && - copy_to == other.copy_to && - constraints == other.constraints && - lookups == other.lookups && - copy_from == other.copy_from; - } - bool operator< (const configuration& other) const { + lookups.push_back(lookup); + } + copy_from = coordinates(copy_from_); + }; + bool operator==(const configuration &other) const { + return first_coordinate == other.first_coordinate && last_coordinate == other.last_coordinate && + copy_to == other.copy_to && constraints == other.constraints && + lookups == other.lookups && copy_from == other.copy_from; + } + bool operator<(const configuration &other) const { return first_coordinate < other.first_coordinate || - (first_coordinate == other.first_coordinate && last_coordinate < other.last_coordinate); + (first_coordinate == other.first_coordinate && last_coordinate < other.last_coordinate); } }; @@ -254,8 +255,10 @@ namespace nil { // num columns for the permutation argument const std::size_t limit_permutation_column; - const typename BlueprintFieldType::integral_type big_rot_const = calculate_sparse((integral_type(1) << 64) - 1); - const std::array, 29> all_rot_consts = calculate_rot_consts(); + const typename BlueprintFieldType::integral_type big_rot_const = + calculate_sparse((integral_type(1) << 64) - 1); + const std::array, 29> all_rot_consts = + calculate_rot_consts(); const std::size_t normalize3_chunk_size = calculate_chunk_size(lookup_rows, 3); const std::size_t normalize4_chunk_size = calculate_chunk_size(lookup_rows, 4); @@ -281,26 +284,32 @@ namespace nil { const std::size_t chi_buff = calculate_buff(this->witness_amount(), lookup_rows, 5); const std::size_t rotate_buff = calculate_buff(this->witness_amount(), lookup_rows); - const std::size_t rows_amount = get_rows_amount(this->witness_amount(), 0, xor_with_mes, last_round_call, limit_permutation_column); + const std::size_t rows_amount = + get_rows_amount(this->witness_amount(), 0, xor_with_mes, last_round_call, limit_permutation_column); // full configuration is precalculated, then used in other functions const std::size_t full_configuration_size = 17 * xor_with_mes + 85; - std::vector full_configuration = configure_all(this->witness_amount(), xor_with_mes, last_round_call, limit_permutation_column); + std::vector full_configuration = + configure_all(this->witness_amount(), xor_with_mes, last_round_call, limit_permutation_column); // number represents relative selector index for each constraint - std::map, std::vector> gates_configuration_map = configure_map(this->witness_amount(), xor_with_mes, last_round_call, limit_permutation_column); - std::vector> gates_configuration = configure_gates(this->witness_amount(), xor_with_mes, last_round_call, limit_permutation_column); - std::vector> lookup_gates_configuration = configure_lookup_gates(this->witness_amount(), xor_with_mes, last_round_call, limit_permutation_column); - - const std::size_t last_round_call_row = calculate_last_round_call_row(this->witness_amount(), xor_with_mes, last_round_call, limit_permutation_column); - const std::size_t gates_amount = get_gates_amount(this->witness_amount(), xor_with_mes, last_round_call, limit_permutation_column); + std::map, std::vector> gates_configuration_map = + configure_map(this->witness_amount(), xor_with_mes, last_round_call, limit_permutation_column); + std::vector> gates_configuration = + configure_gates(this->witness_amount(), xor_with_mes, last_round_call, limit_permutation_column); + std::vector> lookup_gates_configuration = configure_lookup_gates( + this->witness_amount(), xor_with_mes, last_round_call, limit_permutation_column); + + const std::size_t last_round_call_row = calculate_last_round_call_row( + this->witness_amount(), xor_with_mes, last_round_call, limit_permutation_column); + const std::size_t gates_amount = + get_gates_amount(this->witness_amount(), xor_with_mes, last_round_call, limit_permutation_column); const value_type sparse_3 = 0x6DB6DB6DB6DB6DB6DB6DB6DB6DB6DB6DB6DB6DB6DB6DB6DB_cppui255; - constexpr static const std::array - rho_offsets = {0, 1, 3, 6, 10, 15, 21, - 28, 36, 45, 55, 2, 14, - 27, 41, 56, 8, 25, 43, - 62, 18, 39, 61, 20, 44}; + const integral_type sparse_x80 = calculate_sparse(integral_type(0x8000000000000000)); + + constexpr static const std::array rho_offsets = { + 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44}; struct input_type { std::array inner_state; @@ -321,11 +330,13 @@ namespace nil { result_type(const keccak_round &component, std::size_t start_row_index) { std::size_t num_config = component.full_configuration.size() - 1; - inner_state[0] = var(component.W(component.full_configuration[num_config].copy_from.column), - component.full_configuration[num_config].copy_from.row + start_row_index); + inner_state[0] = + var(component.W(component.full_configuration[num_config].copy_from.column), + component.full_configuration[num_config].copy_from.row + start_row_index, false); for (int i = 1; i < 25; ++i) { - inner_state[25 - i] = var(component.W(component.full_configuration[num_config - i].copy_from.column), - component.full_configuration[num_config - i].copy_from.row + start_row_index); + inner_state[25 - i] = var( + component.W(component.full_configuration[num_config - i].copy_from.column), + component.full_configuration[num_config - i].copy_from.row + start_row_index, false); } } @@ -336,7 +347,8 @@ namespace nil { } }; - typename BlueprintFieldType::integral_type calculate_sparse(const typename BlueprintFieldType::integral_type& value) const { + typename BlueprintFieldType::integral_type + calculate_sparse(const typename BlueprintFieldType::integral_type &value) const { typename BlueprintFieldType::integral_type result = 0; typename BlueprintFieldType::integral_type power = 1; typename BlueprintFieldType::integral_type val = value; @@ -360,7 +372,7 @@ namespace nil { return result; } - integral_type normalize(const integral_type& integral_value) const { + integral_type normalize(const integral_type &integral_value) const { integral_type result = 0; integral_type value = integral_value; integral_type power = 1; @@ -372,7 +384,7 @@ namespace nil { return result; } - integral_type chi(const integral_type& integral_value) const { + integral_type chi(const integral_type &integral_value) const { integral_type result = 0; integral_type value = integral_value; integral_type power = 1; @@ -388,13 +400,13 @@ namespace nil { } static configuration configure_inner(std::size_t witness_amount, std::size_t limit_permutation_column, - std::size_t row, std::size_t column, std::size_t num_args, - std::size_t num_chunks, std::size_t num_cells, std::size_t buff = 0) { + std::size_t row, std::size_t column, std::size_t num_args, + std::size_t num_chunks, std::size_t num_cells, + std::size_t buff = 0) { std::pair first_coordinate = {row, column}; - std::size_t last_row = row, - last_column = column; + std::size_t last_row = row, last_column = column; std::vector> copy_to; @@ -404,8 +416,8 @@ namespace nil { } } else { for (int i = 0; i < num_args; ++i) { - copy_to.push_back({last_row + (last_column / witness_amount), - (last_column++) % witness_amount}); + copy_to.push_back( + {last_row + (last_column / witness_amount), (last_column++) % witness_amount}); } } @@ -423,20 +435,20 @@ namespace nil { cells.push_back({row, i}); } std::size_t cells_left = num_cells - witness_amount + column; - std::size_t cur_row = row + 1, - cur_column = num_args; + std::size_t cur_row = row + 1, cur_column = num_args; while (cur_column < cells_left) { - if (cur_column % witness_amount == cell_copy_from.second && (cur_row + (cur_column / witness_amount) == cell_copy_from.first)) { + if (cur_column % witness_amount == cell_copy_from.second && + (cur_row + (cur_column / witness_amount) == cell_copy_from.first)) { cur_column++; continue; } cells.push_back({cur_row + (cur_column / witness_amount), (cur_column++) % witness_amount}); } } else { - std::size_t cur_row = row, - cur_column = column + num_args; + std::size_t cur_row = row, cur_column = column + num_args; while (cur_column - column < num_cells) { - if (cur_column % witness_amount == cell_copy_from.second && (cur_row + (cur_column / witness_amount) == cell_copy_from.first)) { + if (cur_column % witness_amount == cell_copy_from.second && + (cur_row + (cur_column / witness_amount) == cell_copy_from.first)) { cur_column++; continue; } @@ -469,37 +481,45 @@ namespace nil { last_row = cells.back().first + (last_column >= witness_amount); last_column %= witness_amount; - return configuration(first_coordinate, {last_row, last_column}, copy_to, constraints, lookups, cell_copy_from); + return configuration(first_coordinate, {last_row, last_column}, copy_to, constraints, lookups, + cell_copy_from); } - static configuration configure_xor(std::size_t witness_amount, std::size_t limit_permutation_column, std::size_t row, std::size_t column, int num_args) { + static configuration configure_xor(std::size_t witness_amount, std::size_t limit_permutation_column, + std::size_t row, std::size_t column, int num_args) { // regular constraints: // sum = arg1 + arg2 + ... + argn // sum = sum_chunk0 + sum_chunk1 * 2^chunk_size + ... + sum_chunkk * 2^(k*chunk_size) - // norm_sum = norm_sum_chunk0 + norm_sum_chunk1 * 2^chunk_size + ... + norm_sum_chunkk * 2^(k*chunk_size) + // norm_sum = norm_sum_chunk0 + norm_sum_chunk1 * 2^chunk_size + ... + norm_sum_chunkk * + // 2^(k*chunk_size) std::size_t num_chunks = calculate_num_chunks(lookup_rows, num_args + 1); std::size_t num_cells = calculate_num_cells(lookup_rows, num_args + 1); std::size_t buff = calculate_buff(witness_amount, lookup_rows, num_args + 1); - return configure_inner(witness_amount, limit_permutation_column, row, column, num_args, num_chunks, num_cells, buff); + return configure_inner(witness_amount, limit_permutation_column, row, column, num_args, num_chunks, + num_cells, buff); } - static configuration configure_chi(std::size_t witness_amount, std::size_t limit_permutation_column, std::size_t row, std::size_t column) { + static configuration configure_chi(std::size_t witness_amount, std::size_t limit_permutation_column, + std::size_t row, std::size_t column) { // regular constraints: // sum = sparse_3 - 2 * a + b - c; // sum = sum_chunk0 + sum_chunk1 * 2^chunk_size + ... + sum_chunkk * 2^(k*chunk_size) - // chi_sum = chi_sum_chunk0 + chi_sum_chunk1 * 2^chunk_size + ... + chi_sum_chunkk * 2^(k*chunk_size) + // chi_sum = chi_sum_chunk0 + chi_sum_chunk1 * 2^chunk_size + ... + chi_sum_chunkk * + // 2^(k*chunk_size) std::size_t num_args = 3; std::size_t num_chunks = calculate_num_chunks(lookup_rows, 5); std::size_t num_cells = calculate_num_cells(lookup_rows, 5); std::size_t buff = calculate_buff(witness_amount, lookup_rows, 5); - return configure_inner(witness_amount, limit_permutation_column, row, column, num_args, num_chunks, num_cells, buff); + return configure_inner(witness_amount, limit_permutation_column, row, column, num_args, num_chunks, + num_cells, buff); } - static configuration configure_rot(std::size_t witness_amount, std::size_t limit_permutation_column, std::size_t row, std::size_t column) { + static configuration configure_rot(std::size_t witness_amount, std::size_t limit_permutation_column, + std::size_t row, std::size_t column) { // regular constraints: // a = small_part * (1 << (192 - 3 * r)) + big_part; // a_rot = big_part * (1 << (3 * r)) + small_part; @@ -511,8 +531,7 @@ namespace nil { std::pair first_coordinate = {row, column}; - std::size_t last_row = row, - last_column = column; + std::size_t last_row = row, last_column = column; std::size_t num_chunks = 8; std::size_t num_cells = 24; @@ -524,10 +543,9 @@ namespace nil { copy_to.push_back({last_row + 1, 0}); cell_copy_from = {last_row + 1, 1}; } else { - copy_to.push_back({last_row + (last_column / witness_amount), - (last_column++) % witness_amount}); - cell_copy_from = {last_row + (last_column / witness_amount), - (last_column++) % witness_amount}; + copy_to.push_back( + {last_row + (last_column / witness_amount), (last_column++) % witness_amount}); + cell_copy_from = {last_row + (last_column / witness_amount), (last_column++) % witness_amount}; } std::vector> cells; @@ -536,14 +554,12 @@ namespace nil { cells.push_back({row, i}); } std::size_t cells_left = num_cells - witness_amount + column; - std::size_t cur_row = row + 1, - cur_column = 2; + std::size_t cur_row = row + 1, cur_column = 2; while (cur_column < cells_left) { cells.push_back({cur_row + (cur_column / witness_amount), (cur_column++) % witness_amount}); } } else { - std::size_t cur_row = row, - cur_column = column + 2; + std::size_t cur_row = row, cur_column = column + 2; while (cur_column - column < num_cells) { cells.push_back({cur_row + (cur_column / witness_amount), (cur_column++) % witness_amount}); } @@ -560,7 +576,8 @@ namespace nil { constraints[1].push_back(constraints[0][2]); constraints[1].push_back(constraints[0][1]); - std::vector>> lookups(2, std::vector>()); + std::vector>> lookups( + 2, std::vector>()); constraints.push_back({cells[cell_index++]}); constraints[2].push_back(constraints[0][1]); @@ -590,7 +607,8 @@ namespace nil { last_row = cells.back().first + (last_column / witness_amount); last_column %= witness_amount; - return configuration(first_coordinate, {last_row, last_column}, copy_to, constraints, lookups, cell_copy_from); + return configuration(first_coordinate, {last_row, last_column}, copy_to, constraints, lookups, + cell_copy_from); } static std::vector configure_all(std::size_t witness_amount, @@ -599,8 +617,7 @@ namespace nil { std::size_t limit_permutation_column) { std::size_t full_configuration_size = 17 * xor_with_mes + 85; auto result = std::vector(full_configuration_size); - std::size_t row = 0, - column = 0; + std::size_t row = 0, column = 0; std::size_t cur_config = 0; // inner_state ^ chunk @@ -613,7 +630,8 @@ namespace nil { } // xor with last message chunk if (last_round_call) { - result[cur_config] = configure_xor(witness_amount, limit_permutation_column, row, column, 3); + result[cur_config] = + configure_xor(witness_amount, limit_permutation_column, row, column, 3); row = result[cur_config].last_coordinate.row; column = result[cur_config].last_coordinate.column; cur_config++; @@ -657,21 +675,24 @@ namespace nil { // for (int i = 0; i < result.size(); ++i) { // std::cout << "\n config: " << result[i].name << std::endl; - // std::cout << result[i].first_coordinate.row << " " << result[i].first_coordinate.column << " " << result[i].last_coordinate.row << " " << result[i].last_coordinate.column << std::endl; + // std::cout << result[i].first_coordinate.row << " " << result[i].first_coordinate.column << " + // " << result[i].last_coordinate.row << " " << result[i].last_coordinate.column << std::endl; // std::cout << result[i].copy_from.row << " " << result[i].copy_from.column << std::endl; // for (int j = 0; j < result[i].copy_to.size(); ++j) { // std::cout << result[i].copy_to[j].row << " " << result[i].copy_to[j].column << std::endl; // } // for (int j = 0; j < result[i].constraints.size(); ++j) { // for (int k = 0; k < result[i].constraints[j].size(); ++k) { - // std::cout << result[i].constraints[j][k].row << " " << result[i].constraints[j][k].column << ", "; + // std::cout << result[i].constraints[j][k].row << " " << + // result[i].constraints[j][k].column << ", "; // } // std::cout << std::endl; // } // std::cout << "lookups: " << result[i].lookups.size() << std::endl; // for (int j = 0; j < result[i].lookups.size(); ++j) { // for (int k = 0; k < result[i].lookups[j].size(); ++k) { - // std::cout << result[i].lookups[j][k].row << " " << result[i].lookups[j][k].column << ", "; + // std::cout << result[i].lookups[j][k].row << " " << result[i].lookups[j][k].column << + // ", "; // } // std::cout << std::endl; // } @@ -680,14 +701,14 @@ namespace nil { return result; } - static std::map, - std::vector> configure_map(std::size_t witness_amount, - bool xor_with_mes, - bool last_round_call, - std::size_t limit_permutation_column) { - auto config = configure_all(witness_amount, xor_with_mes, last_round_call, limit_permutation_column); - std::size_t row = 0, - column = 0; + static std::map, std::vector> + configure_map(std::size_t witness_amount, + bool xor_with_mes, + bool last_round_call, + std::size_t limit_permutation_column) { + auto config = + configure_all(witness_amount, xor_with_mes, last_round_call, limit_permutation_column); + std::size_t row = 0, column = 0; std::size_t cur_config = 0; std::map, std::vector> config_map; @@ -790,43 +811,52 @@ namespace nil { } static std::vector> configure_gates(std::size_t witness_amount, - bool xor_with_mes, - bool last_round_call, - std::size_t limit_permutation_column) { + bool xor_with_mes, + bool last_round_call, + std::size_t limit_permutation_column) { std::vector> result; - auto gates_configuration_map = configure_map(witness_amount, xor_with_mes, last_round_call, limit_permutation_column); + auto gates_configuration_map = + configure_map(witness_amount, xor_with_mes, last_round_call, limit_permutation_column); - for (auto config: gates_configuration_map) { + for (auto config : gates_configuration_map) { configuration cur_config; switch (config.first.first) { case 2: - cur_config = configure_xor(witness_amount, limit_permutation_column, 0, config.first.second, 2); + cur_config = + configure_xor(witness_amount, limit_permutation_column, 0, config.first.second, 2); break; case 3: - cur_config = configure_xor(witness_amount, limit_permutation_column, 0, config.first.second, 3); + cur_config = + configure_xor(witness_amount, limit_permutation_column, 0, config.first.second, 3); break; case 5: - cur_config = configure_xor(witness_amount, limit_permutation_column, 0, config.first.second, 5); + cur_config = + configure_xor(witness_amount, limit_permutation_column, 0, config.first.second, 5); break; case 7: - cur_config = configure_rot(witness_amount, limit_permutation_column, 0, config.first.second); + cur_config = + configure_rot(witness_amount, limit_permutation_column, 0, config.first.second); break; case 0: - cur_config = configure_chi(witness_amount, limit_permutation_column, 0, config.first.second); + cur_config = + configure_chi(witness_amount, limit_permutation_column, 0, config.first.second); break; } // std::cout << "\nconfig:\n"; // std::cout << config.first.first << "\n"; - // std::cout << cur_config.first_coordinate.row << " " << cur_config.first_coordinate.column << " " << cur_config.last_coordinate.row << " " << cur_config.last_coordinate.column << std::endl; - // std::cout << cur_config.copy_from.row << " " << cur_config.copy_from.column << std::endl; - // for (int j = 0; j < cur_config.copy_to.size(); ++j) { - // std::cout << cur_config.copy_to[j].row << " " << cur_config.copy_to[j].column << std::endl; + // std::cout << cur_config.first_coordinate.row << " " << cur_config.first_coordinate.column << + // " " << cur_config.last_coordinate.row << " " << cur_config.last_coordinate.column << + // std::endl; std::cout << cur_config.copy_from.row << " " << cur_config.copy_from.column << + // std::endl; for (int j = 0; j < cur_config.copy_to.size(); ++j) { + // std::cout << cur_config.copy_to[j].row << " " << cur_config.copy_to[j].column << + // std::endl; // } // for (int j = 0; j < cur_config.constraints.size(); ++j) { // for (int k = 0; k < cur_config.constraints[j].size(); ++k) { - // std::cout << cur_config.constraints[j][k].row << " " << cur_config.constraints[j][k].column << ", "; + // std::cout << cur_config.constraints[j][k].row << " " << + // cur_config.constraints[j][k].column << ", "; // } // std::cout << std::endl; // } @@ -847,7 +877,8 @@ namespace nil { std::size_t cur_constr = 0; while (cur_constr < pairs.size()) { configuration c; - while (cur_constr < pairs.size() && pairs[cur_constr].second <= cur_row + 2 && pairs[cur_constr].first >= cur_row) { + while (cur_constr < pairs.size() && pairs[cur_constr].second <= cur_row + 2 && + pairs[cur_constr].first >= cur_row) { c.constraints.push_back(cur_config.constraints[cur_constr]); c.first_coordinate = {cur_row, 0}; ++cur_constr; @@ -861,32 +892,40 @@ namespace nil { return result; } - static std::vector> configure_lookup_gates(std::size_t witness_amount, - bool xor_with_mes, - bool last_round_call, - std::size_t limit_permutation_column) { - auto full_configuration = configure_all(witness_amount, xor_with_mes, last_round_call, limit_permutation_column); + static std::vector> + configure_lookup_gates(std::size_t witness_amount, + bool xor_with_mes, + bool last_round_call, + std::size_t limit_permutation_column) { + auto full_configuration = + configure_all(witness_amount, xor_with_mes, last_round_call, limit_permutation_column); auto rows_amount = full_configuration.back().last_coordinate.row + 1; std::vector> result; - auto gates_configuration_map = configure_map(witness_amount, xor_with_mes, last_round_call, limit_permutation_column); + auto gates_configuration_map = + configure_map(witness_amount, xor_with_mes, last_round_call, limit_permutation_column); - for (auto config: gates_configuration_map) { + for (auto config : gates_configuration_map) { configuration cur_config; switch (config.first.first) { case 2: - cur_config = configure_xor(witness_amount, limit_permutation_column, 0, config.first.second, 2); + cur_config = + configure_xor(witness_amount, limit_permutation_column, 0, config.first.second, 2); break; case 3: - cur_config = configure_xor(witness_amount, limit_permutation_column, 0, config.first.second, 3); + cur_config = + configure_xor(witness_amount, limit_permutation_column, 0, config.first.second, 3); break; case 5: - cur_config = configure_xor(witness_amount, limit_permutation_column, 0, config.first.second, 5); + cur_config = + configure_xor(witness_amount, limit_permutation_column, 0, config.first.second, 5); break; case 7: - cur_config = configure_rot(witness_amount, limit_permutation_column, 0, config.first.second); + cur_config = + configure_rot(witness_amount, limit_permutation_column, 0, config.first.second); break; case 0: - cur_config = configure_chi(witness_amount, limit_permutation_column, 0, config.first.second); + cur_config = + configure_chi(witness_amount, limit_permutation_column, 0, config.first.second); break; } @@ -909,14 +948,15 @@ namespace nil { while (cur_constr < pairs.size()) { configuration c; found = false; - while (cur_constr < pairs.size() && pairs[cur_constr].second <= cur_row + 2 && pairs[cur_constr].first >= cur_row) { + while (cur_constr < pairs.size() && pairs[cur_constr].second <= cur_row + 2 && + pairs[cur_constr].first >= cur_row) { c.lookups.push_back(cur_config.lookups[cur_constr]); c.first_coordinate = {cur_row, 0}; ++cur_constr; found = true; } cur_row = pairs[cur_constr].first; - if(found){ + if (found) { cur_result.push_back(c); } } @@ -925,7 +965,8 @@ namespace nil { // std::size_t cur_row = 0; // std::size_t cur_constr = 0; // while (cur_row < rows_amount) { - // while (cur_constr < pairs.size() && pairs[cur_constr].second <= cur_row + 2 && pairs[cur_constr].first >= cur_row) { + // while (cur_constr < pairs.size() && pairs[cur_constr].second <= cur_row + 2 && + // pairs[cur_constr].first >= cur_row) { // result.push_back(cur_row + 1); // ++cur_constr; // } @@ -941,11 +982,13 @@ namespace nil { bool last_round_call, std::size_t limit_permutation_column) { std::size_t res = 0; - auto gates_configuration = configure_gates(witness_amount, xor_with_mes, last_round_call, limit_permutation_column); + auto gates_configuration = + configure_gates(witness_amount, xor_with_mes, last_round_call, limit_permutation_column); for (std::size_t i = 0; i < gates_configuration.size(); ++i) { res += gates_configuration[i].size(); } - auto lookup_gates_configuration = configure_lookup_gates(witness_amount, xor_with_mes, last_round_call, limit_permutation_column); + auto lookup_gates_configuration = + configure_lookup_gates(witness_amount, xor_with_mes, last_round_call, limit_permutation_column); for (std::size_t i = 0; i < lookup_gates_configuration.size(); ++i) { res += lookup_gates_configuration[i].size(); } @@ -953,10 +996,10 @@ namespace nil { } static std::size_t get_rows_amount(std::size_t witness_amount, - std::size_t lookup_column_amount, - bool xor_with_mes, - bool last_round_call, - std::size_t limit_permutation_column) { + std::size_t lookup_column_amount, + bool xor_with_mes, + bool last_round_call, + std::size_t limit_permutation_column) { std::size_t xor2_cells = calculate_num_cells(lookup_rows, 3); std::size_t xor3_cells = calculate_num_cells(lookup_rows, 4); std::size_t xor5_cells = calculate_num_cells(lookup_rows, 6); @@ -968,16 +1011,15 @@ namespace nil { std::size_t chi_buff = calculate_buff(witness_amount, lookup_rows, 5); std::size_t rotate_buff = calculate_buff(witness_amount, lookup_rows); - std::size_t num_cells = (xor3_cells + xor3_buff) * last_round_call - * xor_with_mes + // xor with last message chunk - ((17 - last_round_call) * (xor2_cells + xor2_buff)) - * xor_with_mes + // inner_state ^ chunk - 5 * (xor5_cells + xor5_buff) + // theta - 5 * (rotate_cells + rotate_buff) + // theta - 25 * (xor3_cells + xor3_buff) + // theta - 24 * (rotate_cells + rotate_buff) + // rho/phi - 25 * (chi_cells + chi_buff) + // chi - xor2_cells; // iota + std::size_t num_cells = + (xor3_cells + xor3_buff) * last_round_call * xor_with_mes + // xor with last message chunk + ((17 - last_round_call) * (xor2_cells + xor2_buff)) * xor_with_mes + // inner_state ^ chunk + 5 * (xor5_cells + xor5_buff) + // theta + 5 * (rotate_cells + rotate_buff) + // theta + 25 * (xor3_cells + xor3_buff) + // theta + 24 * (rotate_cells + rotate_buff) + // rho/phi + 25 * (chi_cells + chi_buff) + // chi + xor2_cells; // iota return num_cells / witness_amount + bool(num_cells % witness_amount); } @@ -994,44 +1036,39 @@ namespace nil { // return result; // } - std::map component_lookup_tables(){ + std::map component_lookup_tables() { std::map lookup_tables; - lookup_tables["keccak_normalize3_table/full"] = 0; // REQUIRED_TABLE - lookup_tables["keccak_normalize4_table/full"] = 0; // REQUIRED_TABLE - lookup_tables["keccak_normalize6_table/full"] = 0; // REQUIRED_TABLE - lookup_tables["keccak_chi_table/full"] = 0; // REQUIRED_TABLE - lookup_tables["keccak_pack_table/range_check_sparse"] = 0; // REQUIRED_TABLE + lookup_tables["keccak_normalize3_table/full"] = 0; // REQUIRED_TABLE + lookup_tables["keccak_normalize4_table/full"] = 0; // REQUIRED_TABLE + lookup_tables["keccak_normalize6_table/full"] = 0; // REQUIRED_TABLE + lookup_tables["keccak_chi_table/full"] = 0; // REQUIRED_TABLE + lookup_tables["keccak_pack_table/range_check_sparse"] = 0; // REQUIRED_TABLE return lookup_tables; } template keccak_round(WitnessContainerType witness, ConstantContainerType constant, - PublicInputContainerType public_input, - bool xor_with_mes_ = false, - bool last_round_call_ = false, - std::size_t lpc_ = 7) : - component_type(witness, constant, public_input, get_manifest()), - xor_with_mes(xor_with_mes_), - last_round_call(last_round_call_), - limit_permutation_column(lpc_) { - // check_params(); - }; - - keccak_round( - std::initializer_list witnesses, - std::initializer_list constants, - std::initializer_list - public_inputs, - bool xor_with_mes_ = false, - bool last_round_call_ = false, - std::size_t lpc_ = 7) : - component_type(witnesses, constants, public_inputs, get_manifest()), - xor_with_mes(xor_with_mes_), - last_round_call(last_round_call_), - limit_permutation_column(lpc_) { - // check_params(); - }; + PublicInputContainerType public_input, bool xor_with_mes_ = false, + bool last_round_call_ = false, std::size_t lpc_ = 7) : + component_type(witness, constant, public_input, get_manifest()), + xor_with_mes(xor_with_mes_), last_round_call(last_round_call_), limit_permutation_column(lpc_) { + // check_params(); + }; + + keccak_round(std::initializer_list + witnesses, + std::initializer_list + constants, + std::initializer_list + public_inputs, + bool xor_with_mes_ = false, + bool last_round_call_ = false, + std::size_t lpc_ = 7) : + component_type(witnesses, constants, public_inputs, get_manifest()), + xor_with_mes(xor_with_mes_), last_round_call(last_round_call_), limit_permutation_column(lpc_) { + // check_params(); + }; }; template @@ -1040,14 +1077,10 @@ namespace nil { template std::vector generate_gates( - const keccak_round_component - &component, - circuit> - &bp, - assignment> - &assignment, - const typename keccak_round_component::input_type - &instance_input, + const keccak_round_component &component, + circuit> &bp, + assignment> &assignment, + const typename keccak_round_component::input_type &instance_input, const typename lookup_library::left_reserved_type lookup_tables_indices) { using component_type = keccak_round_component; @@ -1055,7 +1088,8 @@ namespace nil { using constraint_type = crypto3::zk::snark::plonk_constraint; using gate_type = typename crypto3::zk::snark::plonk_gate; using lookup_constraint_type = typename crypto3::zk::snark::plonk_lookup_constraint; - using lookup_gate_type = typename crypto3::zk::snark::plonk_gate; + using lookup_gate_type = + typename crypto3::zk::snark::plonk_gate; using value_type = typename BlueprintFieldType::value_type; using integral_type = typename BlueprintFieldType::integral_type; using configuration = typename component_type::configuration; @@ -1072,7 +1106,7 @@ namespace nil { // general gates std::size_t index = 0; - for (auto gm: gate_map) { + for (auto gm : gate_map) { std::vector cur_config_vec = gate_config[index]; std::size_t i = 0, j = 0, cur_len = 0; std::vector cur_constraints; @@ -1080,11 +1114,17 @@ namespace nil { std::vector cur_lookup_constraints; std::string cur_lookup_table_name; switch (gm.first.first) { - case 2: - { - cur_constraints.push_back(constraint_type(var(cur_config_vec[i].constraints[j][1].column, cur_config_vec[i].constraints[j][1].row - cur_config_vec[i].first_coordinate.row - 1) - + var(cur_config_vec[i].constraints[j][2].column, cur_config_vec[i].constraints[j][2].row - cur_config_vec[i].first_coordinate.row - 1) - - var(cur_config_vec[i].constraints[j][0].column, cur_config_vec[i].constraints[j][0].row - cur_config_vec[i].first_coordinate.row - 1))); + case 2: { + cur_constraints.push_back( + constraint_type(var(cur_config_vec[i].constraints[j][1].column, + cur_config_vec[i].constraints[j][1].row - + cur_config_vec[i].first_coordinate.row - 1) + + var(cur_config_vec[i].constraints[j][2].column, + cur_config_vec[i].constraints[j][2].row - + cur_config_vec[i].first_coordinate.row - 1) - + var(cur_config_vec[i].constraints[j][0].column, + cur_config_vec[i].constraints[j][0].row - + cur_config_vec[i].first_coordinate.row - 1))); j++; cur_len = cur_config_vec[i].constraints.size(); @@ -1095,10 +1135,14 @@ namespace nil { i += j / cur_len; j %= cur_len; - constraint_type constraint_1 = var(cur_config_vec[i].constraints[j][0].column, cur_config_vec[i].constraints[j][0].row - cur_config_vec[i].first_coordinate.row - 1); + constraint_type constraint_1 = var(cur_config_vec[i].constraints[j][0].column, + cur_config_vec[i].constraints[j][0].row - + cur_config_vec[i].first_coordinate.row - 1); for (int k = 0; k < component.normalize3_num_chunks; ++k) { - constraint_1 -= var(cur_config_vec[i].constraints[j][k + 1].column, cur_config_vec[i].constraints[j][k + 1].row - cur_config_vec[i].first_coordinate.row - 1) - * (integral_type(1) << (k * component.normalize3_chunk_size)); + constraint_1 -= var(cur_config_vec[i].constraints[j][k + 1].column, + cur_config_vec[i].constraints[j][k + 1].row - + cur_config_vec[i].first_coordinate.row - 1) * + (integral_type(1) << (k * component.normalize3_chunk_size)); } cur_constraints.push_back(constraint_1); @@ -1111,10 +1155,14 @@ namespace nil { i += j / cur_len; j %= cur_len; - constraint_type constraint_2 = var(cur_config_vec[i].constraints[j][0].column, cur_config_vec[i].constraints[j][0].row - cur_config_vec[i].first_coordinate.row - 1); + constraint_type constraint_2 = var(cur_config_vec[i].constraints[j][0].column, + cur_config_vec[i].constraints[j][0].row - + cur_config_vec[i].first_coordinate.row - 1); for (int k = 0; k < component.normalize3_num_chunks; ++k) { - constraint_2 -= var(cur_config_vec[i].constraints[j][k + 1].column, cur_config_vec[i].constraints[j][k + 1].row - cur_config_vec[i].first_coordinate.row - 1) - * (integral_type(1) << (k * component.normalize3_chunk_size)); + constraint_2 -= var(cur_config_vec[i].constraints[j][k + 1].column, + cur_config_vec[i].constraints[j][k + 1].row - + cur_config_vec[i].first_coordinate.row - 1) * + (integral_type(1) << (k * component.normalize3_chunk_size)); } cur_constraints.push_back(constraint_2); selector_indexes.push_back(bp.add_gate(cur_constraints)); @@ -1122,12 +1170,19 @@ namespace nil { cur_lookup_table_name = "keccak_normalize3_table/full"; break; } - case 3: - { - cur_constraints.push_back(var(cur_config_vec[i].constraints[j][1].column, cur_config_vec[i].constraints[j][1].row - cur_config_vec[i].first_coordinate.row - 1) - + var(cur_config_vec[i].constraints[j][2].column, cur_config_vec[i].constraints[j][2].row - cur_config_vec[i].first_coordinate.row - 1) - + var(cur_config_vec[i].constraints[j][3].column, cur_config_vec[i].constraints[j][3].row - cur_config_vec[i].first_coordinate.row - 1) - - var(cur_config_vec[i].constraints[j][0].column, cur_config_vec[i].constraints[j][0].row - cur_config_vec[i].first_coordinate.row - 1)); + case 3: { + cur_constraints.push_back(var(cur_config_vec[i].constraints[j][1].column, + cur_config_vec[i].constraints[j][1].row - + cur_config_vec[i].first_coordinate.row - 1) + + var(cur_config_vec[i].constraints[j][2].column, + cur_config_vec[i].constraints[j][2].row - + cur_config_vec[i].first_coordinate.row - 1) + + var(cur_config_vec[i].constraints[j][3].column, + cur_config_vec[i].constraints[j][3].row - + cur_config_vec[i].first_coordinate.row - 1) - + var(cur_config_vec[i].constraints[j][0].column, + cur_config_vec[i].constraints[j][0].row - + cur_config_vec[i].first_coordinate.row - 1)); j++; cur_len = cur_config_vec[i].constraints.size(); @@ -1138,10 +1193,14 @@ namespace nil { i += j / cur_len; j %= cur_len; - constraint_type constraint_1 = var(cur_config_vec[i].constraints[j][0].column, cur_config_vec[i].constraints[j][0].row - cur_config_vec[i].first_coordinate.row - 1); + constraint_type constraint_1 = var(cur_config_vec[i].constraints[j][0].column, + cur_config_vec[i].constraints[j][0].row - + cur_config_vec[i].first_coordinate.row - 1); for (int k = 0; k < component.normalize4_num_chunks; ++k) { - constraint_1 -= var(cur_config_vec[i].constraints[j][k + 1].column, cur_config_vec[i].constraints[j][k + 1].row - cur_config_vec[i].first_coordinate.row - 1) - * (integral_type(1) << (k * component.normalize4_chunk_size)); + constraint_1 -= var(cur_config_vec[i].constraints[j][k + 1].column, + cur_config_vec[i].constraints[j][k + 1].row - + cur_config_vec[i].first_coordinate.row - 1) * + (integral_type(1) << (k * component.normalize4_chunk_size)); } cur_constraints.push_back(constraint_1); @@ -1154,10 +1213,14 @@ namespace nil { i += j / cur_len; j %= cur_len; - constraint_type constraint_2 = var(cur_config_vec[i].constraints[j][0].column, cur_config_vec[i].constraints[j][0].row - cur_config_vec[i].first_coordinate.row - 1); + constraint_type constraint_2 = var(cur_config_vec[i].constraints[j][0].column, + cur_config_vec[i].constraints[j][0].row - + cur_config_vec[i].first_coordinate.row - 1); for (int k = 0; k < component.normalize4_num_chunks; ++k) { - constraint_2 -= var(cur_config_vec[i].constraints[j][k + 1].column, cur_config_vec[i].constraints[j][k + 1].row - cur_config_vec[i].first_coordinate.row - 1) - * (integral_type(1) << (k * component.normalize4_chunk_size)); + constraint_2 -= var(cur_config_vec[i].constraints[j][k + 1].column, + cur_config_vec[i].constraints[j][k + 1].row - + cur_config_vec[i].first_coordinate.row - 1) * + (integral_type(1) << (k * component.normalize4_chunk_size)); } cur_constraints.push_back(constraint_2); selector_indexes.push_back(bp.add_gate(cur_constraints)); @@ -1165,14 +1228,25 @@ namespace nil { cur_lookup_table_name = "keccak_normalize4_table/full"; break; } - case 5: - { - cur_constraints.push_back(var(cur_config_vec[i].constraints[j][1].column, cur_config_vec[i].constraints[j][1].row - cur_config_vec[i].first_coordinate.row - 1) - + var(cur_config_vec[i].constraints[j][2].column, cur_config_vec[i].constraints[j][2].row - cur_config_vec[i].first_coordinate.row - 1) - + var(cur_config_vec[i].constraints[j][3].column, cur_config_vec[i].constraints[j][3].row - cur_config_vec[i].first_coordinate.row - 1) - + var(cur_config_vec[i].constraints[j][4].column, cur_config_vec[i].constraints[j][4].row - cur_config_vec[i].first_coordinate.row - 1) - + var(cur_config_vec[i].constraints[j][5].column, cur_config_vec[i].constraints[j][5].row - cur_config_vec[i].first_coordinate.row - 1) - - var(cur_config_vec[i].constraints[j][0].column, cur_config_vec[i].constraints[j][0].row - cur_config_vec[i].first_coordinate.row - 1)); + case 5: { + cur_constraints.push_back(var(cur_config_vec[i].constraints[j][1].column, + cur_config_vec[i].constraints[j][1].row - + cur_config_vec[i].first_coordinate.row - 1) + + var(cur_config_vec[i].constraints[j][2].column, + cur_config_vec[i].constraints[j][2].row - + cur_config_vec[i].first_coordinate.row - 1) + + var(cur_config_vec[i].constraints[j][3].column, + cur_config_vec[i].constraints[j][3].row - + cur_config_vec[i].first_coordinate.row - 1) + + var(cur_config_vec[i].constraints[j][4].column, + cur_config_vec[i].constraints[j][4].row - + cur_config_vec[i].first_coordinate.row - 1) + + var(cur_config_vec[i].constraints[j][5].column, + cur_config_vec[i].constraints[j][5].row - + cur_config_vec[i].first_coordinate.row - 1) - + var(cur_config_vec[i].constraints[j][0].column, + cur_config_vec[i].constraints[j][0].row - + cur_config_vec[i].first_coordinate.row - 1)); j++; cur_len = cur_config_vec[i].constraints.size(); @@ -1183,10 +1257,14 @@ namespace nil { i += j / cur_len; j %= cur_len; - constraint_type constraint_1 = var(cur_config_vec[i].constraints[j][0].column, cur_config_vec[i].constraints[j][0].row - cur_config_vec[i].first_coordinate.row - 1); + constraint_type constraint_1 = var(cur_config_vec[i].constraints[j][0].column, + cur_config_vec[i].constraints[j][0].row - + cur_config_vec[i].first_coordinate.row - 1); for (int k = 0; k < component.normalize6_num_chunks; ++k) { - constraint_1 -= var(cur_config_vec[i].constraints[j][k + 1].column, cur_config_vec[i].constraints[j][k + 1].row - cur_config_vec[i].first_coordinate.row - 1) - * (integral_type(1) << (k * component.normalize6_chunk_size)); + constraint_1 -= var(cur_config_vec[i].constraints[j][k + 1].column, + cur_config_vec[i].constraints[j][k + 1].row - + cur_config_vec[i].first_coordinate.row - 1) * + (integral_type(1) << (k * component.normalize6_chunk_size)); } cur_constraints.push_back(constraint_1); @@ -1199,10 +1277,14 @@ namespace nil { i += j / cur_len; j %= cur_len; - constraint_type constraint_2 = var(cur_config_vec[i].constraints[j][0].column, cur_config_vec[i].constraints[j][0].row - cur_config_vec[i].first_coordinate.row - 1); + constraint_type constraint_2 = var(cur_config_vec[i].constraints[j][0].column, + cur_config_vec[i].constraints[j][0].row - + cur_config_vec[i].first_coordinate.row - 1); for (int k = 0; k < component.normalize6_num_chunks; ++k) { - constraint_2 -= var(cur_config_vec[i].constraints[j][k + 1].column, cur_config_vec[i].constraints[j][k + 1].row - cur_config_vec[i].first_coordinate.row - 1) - * (integral_type(1) << (k * component.normalize6_chunk_size)); + constraint_2 -= var(cur_config_vec[i].constraints[j][k + 1].column, + cur_config_vec[i].constraints[j][k + 1].row - + cur_config_vec[i].first_coordinate.row - 1) * + (integral_type(1) << (k * component.normalize6_chunk_size)); } cur_constraints.push_back(constraint_2); selector_indexes.push_back(bp.add_gate(cur_constraints)); @@ -1210,14 +1292,21 @@ namespace nil { cur_lookup_table_name = "keccak_normalize6_table/full"; break; } - case 7: - { + case 7: { std::size_t true_first_row = cur_config_vec[i].first_coordinate.row; - cur_constraints.push_back(var(cur_config_vec[i].constraints[j][1].column, cur_config_vec[i].constraints[j][1].row - cur_config_vec[i].first_coordinate.row - 1) - * var(cur_config_vec[i].constraints[j][3].column, cur_config_vec[i].constraints[j][3].row - cur_config_vec[i].first_coordinate.row - 1) - + var(cur_config_vec[i].constraints[j][2].column, cur_config_vec[i].constraints[j][2].row - cur_config_vec[i].first_coordinate.row - 1) - - var(cur_config_vec[i].constraints[j][0].column, cur_config_vec[i].constraints[j][0].row - cur_config_vec[i].first_coordinate.row - 1)); + cur_constraints.push_back(var(cur_config_vec[i].constraints[j][1].column, + cur_config_vec[i].constraints[j][1].row - + cur_config_vec[i].first_coordinate.row - 1) * + var(cur_config_vec[i].constraints[j][3].column, + cur_config_vec[i].constraints[j][3].row - + cur_config_vec[i].first_coordinate.row - 1) + + var(cur_config_vec[i].constraints[j][2].column, + cur_config_vec[i].constraints[j][2].row - + cur_config_vec[i].first_coordinate.row - 1) - + var(cur_config_vec[i].constraints[j][0].column, + cur_config_vec[i].constraints[j][0].row - + cur_config_vec[i].first_coordinate.row - 1)); j++; cur_len = cur_config_vec[i].constraints.size(); @@ -1228,10 +1317,18 @@ namespace nil { i += j / cur_len; j %= cur_len; - cur_constraints.push_back(var(cur_config_vec[i].constraints[1][1].column, cur_config_vec[i].constraints[1][1].row - cur_config_vec[i].first_coordinate.row - 1) - * var(cur_config_vec[i].constraints[j][3].column, cur_config_vec[i].constraints[j][3].row - cur_config_vec[i].first_coordinate.row - 1) - + var(cur_config_vec[i].constraints[1][2].column, cur_config_vec[i].constraints[1][2].row - cur_config_vec[i].first_coordinate.row - 1) - - var(cur_config_vec[i].constraints[1][0].column, cur_config_vec[i].constraints[1][0].row - cur_config_vec[i].first_coordinate.row - 1)); + cur_constraints.push_back(var(cur_config_vec[i].constraints[1][1].column, + cur_config_vec[i].constraints[1][1].row - + cur_config_vec[i].first_coordinate.row - 1) * + var(cur_config_vec[i].constraints[j][3].column, + cur_config_vec[i].constraints[j][3].row - + cur_config_vec[i].first_coordinate.row - 1) + + var(cur_config_vec[i].constraints[1][2].column, + cur_config_vec[i].constraints[1][2].row - + cur_config_vec[i].first_coordinate.row - 1) - + var(cur_config_vec[i].constraints[1][0].column, + cur_config_vec[i].constraints[1][0].row - + cur_config_vec[i].first_coordinate.row - 1)); j++; cur_len = cur_config_vec[i].constraints.size(); @@ -1242,10 +1339,16 @@ namespace nil { i += j / cur_len; j %= cur_len; - cur_constraints.push_back(var(cur_config_vec[i].constraints[j][0].column, cur_config_vec[i].constraints[j][0].row - cur_config_vec[i].first_coordinate.row - 1) - - var(cur_config_vec[i].constraints[j][1].column, cur_config_vec[i].constraints[j][1].row - cur_config_vec[i].first_coordinate.row - 1) - + var(component.C(0), true_first_row + 1 - cur_config_vec[i].first_coordinate.row - 1, true, var::column_type::constant) - - component.big_rot_const); + cur_constraints.push_back( + var(cur_config_vec[i].constraints[j][0].column, + cur_config_vec[i].constraints[j][0].row - cur_config_vec[i].first_coordinate.row - + 1) - + var(cur_config_vec[i].constraints[j][1].column, + cur_config_vec[i].constraints[j][1].row - cur_config_vec[i].first_coordinate.row - + 1) + + var(component.C(0), true_first_row + 1 - cur_config_vec[i].first_coordinate.row - 1, + true, var::column_type::constant) - + component.big_rot_const); j++; cur_len = cur_config_vec[i].constraints.size(); @@ -1256,10 +1359,14 @@ namespace nil { i += j / cur_len; j %= cur_len; - constraint_type constraint_1 = var(cur_config_vec[i].constraints[j][0].column, cur_config_vec[i].constraints[j][0].row - cur_config_vec[i].first_coordinate.row - 1); + constraint_type constraint_1 = var(cur_config_vec[i].constraints[j][0].column, + cur_config_vec[i].constraints[j][0].row - + cur_config_vec[i].first_coordinate.row - 1); for (int k = 0; k < component.rotate_num_chunks; ++k) { - constraint_1 -= var(cur_config_vec[i].constraints[j][k + 1].column, cur_config_vec[i].constraints[j][k + 1].row - cur_config_vec[i].first_coordinate.row - 1) - * (integral_type(1) << (k * component.rotate_chunk_size)); + constraint_1 -= var(cur_config_vec[i].constraints[j][k + 1].column, + cur_config_vec[i].constraints[j][k + 1].row - + cur_config_vec[i].first_coordinate.row - 1) * + (integral_type(1) << (k * component.rotate_chunk_size)); } cur_constraints.push_back(constraint_1); @@ -1272,10 +1379,16 @@ namespace nil { i += j / cur_len; j %= cur_len; - cur_constraints.push_back(var(cur_config_vec[i].constraints[j][0].column, cur_config_vec[i].constraints[j][0].row - cur_config_vec[i].first_coordinate.row - 1) - - var(cur_config_vec[i].constraints[j][1].column, cur_config_vec[i].constraints[j][1].row - cur_config_vec[i].first_coordinate.row - 1) - + var(component.C(0), true_first_row + 2 - cur_config_vec[i].first_coordinate.row - 1, true, var::column_type::constant) - - component.big_rot_const); + cur_constraints.push_back( + var(cur_config_vec[i].constraints[j][0].column, + cur_config_vec[i].constraints[j][0].row - cur_config_vec[i].first_coordinate.row - + 1) - + var(cur_config_vec[i].constraints[j][1].column, + cur_config_vec[i].constraints[j][1].row - cur_config_vec[i].first_coordinate.row - + 1) + + var(component.C(0), true_first_row + 2 - cur_config_vec[i].first_coordinate.row - 1, + true, var::column_type::constant) - + component.big_rot_const); j++; cur_len = cur_config_vec[i].constraints.size(); @@ -1286,10 +1399,14 @@ namespace nil { i += j / cur_len; j %= cur_len; - constraint_type constraint_2 = var(cur_config_vec[i].constraints[j][0].column, cur_config_vec[i].constraints[j][0].row - cur_config_vec[i].first_coordinate.row - 1); + constraint_type constraint_2 = var(cur_config_vec[i].constraints[j][0].column, + cur_config_vec[i].constraints[j][0].row - + cur_config_vec[i].first_coordinate.row - 1); for (int k = 0; k < component.rotate_num_chunks; ++k) { - constraint_2 -= var(cur_config_vec[i].constraints[j][k + 1].column, cur_config_vec[i].constraints[j][k + 1].row - cur_config_vec[i].first_coordinate.row - 1) - * (integral_type(1) << (k * component.rotate_chunk_size)); + constraint_2 -= var(cur_config_vec[i].constraints[j][k + 1].column, + cur_config_vec[i].constraints[j][k + 1].row - + cur_config_vec[i].first_coordinate.row - 1) * + (integral_type(1) << (k * component.rotate_chunk_size)); } cur_constraints.push_back(constraint_2); @@ -1302,22 +1419,34 @@ namespace nil { i += j / cur_len; j %= cur_len; - cur_constraints.push_back(var(cur_config_vec[i].constraints[j][0].column, cur_config_vec[i].constraints[j][0].row - cur_config_vec[i].first_coordinate.row - 1) - * var(cur_config_vec[i].constraints[j][1].column, cur_config_vec[i].constraints[j][1].row - cur_config_vec[i].first_coordinate.row - 1) - - (integral_type(1) << 192)); + cur_constraints.push_back(var(cur_config_vec[i].constraints[j][0].column, + cur_config_vec[i].constraints[j][0].row - + cur_config_vec[i].first_coordinate.row - 1) * + var(cur_config_vec[i].constraints[j][1].column, + cur_config_vec[i].constraints[j][1].row - + cur_config_vec[i].first_coordinate.row - 1) - + (integral_type(1) << 192)); selector_indexes.push_back(bp.add_gate(cur_constraints)); cur_lookup_table_name = "keccak_pack_table/range_check_sparse"; break; } - case 0: - { - cur_constraints.push_back(component.sparse_3 - - var(cur_config_vec[i].constraints[j][1].column, cur_config_vec[i].constraints[j][1].row - cur_config_vec[i].first_coordinate.row - 1) * 2 - + var(cur_config_vec[i].constraints[j][2].column, cur_config_vec[i].constraints[j][2].row - cur_config_vec[i].first_coordinate.row - 1) - - var(cur_config_vec[i].constraints[j][3].column, cur_config_vec[i].constraints[j][3].row - cur_config_vec[i].first_coordinate.row - 1) - - var(cur_config_vec[i].constraints[j][0].column, cur_config_vec[i].constraints[j][0].row - cur_config_vec[i].first_coordinate.row - 1)); + case 0: { + cur_constraints.push_back(component.sparse_3 - + var(cur_config_vec[i].constraints[j][1].column, + cur_config_vec[i].constraints[j][1].row - + cur_config_vec[i].first_coordinate.row - 1) * + 2 + + var(cur_config_vec[i].constraints[j][2].column, + cur_config_vec[i].constraints[j][2].row - + cur_config_vec[i].first_coordinate.row - 1) - + var(cur_config_vec[i].constraints[j][3].column, + cur_config_vec[i].constraints[j][3].row - + cur_config_vec[i].first_coordinate.row - 1) - + var(cur_config_vec[i].constraints[j][0].column, + cur_config_vec[i].constraints[j][0].row - + cur_config_vec[i].first_coordinate.row - 1)); j++; cur_len = cur_config_vec[i].constraints.size(); @@ -1328,10 +1457,14 @@ namespace nil { i += j / cur_len; j %= cur_len; - constraint_type constraint_1 = var(cur_config_vec[i].constraints[j][0].column, cur_config_vec[i].constraints[j][0].row - cur_config_vec[i].first_coordinate.row - 1); + constraint_type constraint_1 = var(cur_config_vec[i].constraints[j][0].column, + cur_config_vec[i].constraints[j][0].row - + cur_config_vec[i].first_coordinate.row - 1); for (int k = 0; k < component.chi_num_chunks; ++k) { - constraint_1 -= var(cur_config_vec[i].constraints[j][k + 1].column, cur_config_vec[i].constraints[j][k + 1].row - cur_config_vec[i].first_coordinate.row - 1) - * (integral_type(1) << (k * component.chi_chunk_size)); + constraint_1 -= var(cur_config_vec[i].constraints[j][k + 1].column, + cur_config_vec[i].constraints[j][k + 1].row - + cur_config_vec[i].first_coordinate.row - 1) * + (integral_type(1) << (k * component.chi_chunk_size)); } cur_constraints.push_back(constraint_1); @@ -1344,10 +1477,14 @@ namespace nil { i += j / cur_len; j %= cur_len; - constraint_type constraint_2 = var(cur_config_vec[i].constraints[j][0].column, cur_config_vec[i].constraints[j][0].row - cur_config_vec[i].first_coordinate.row - 1); + constraint_type constraint_2 = var(cur_config_vec[i].constraints[j][0].column, + cur_config_vec[i].constraints[j][0].row - + cur_config_vec[i].first_coordinate.row - 1); for (int k = 0; k < component.chi_num_chunks; ++k) { - constraint_2 -= var(cur_config_vec[i].constraints[j][k + 1].column, cur_config_vec[i].constraints[j][k + 1].row - cur_config_vec[i].first_coordinate.row - 1) - * (integral_type(1) << (k * component.chi_chunk_size)); + constraint_2 -= var(cur_config_vec[i].constraints[j][k + 1].column, + cur_config_vec[i].constraints[j][k + 1].row - + cur_config_vec[i].first_coordinate.row - 1) * + (integral_type(1) << (k * component.chi_chunk_size)); } cur_constraints.push_back(constraint_2); selector_indexes.push_back(bp.add_gate(cur_constraints)); @@ -1359,9 +1496,11 @@ namespace nil { if (gm.first.first == 7) { for (std::size_t i = 0; i < cur_lookup_config_vec.size(); ++i) { for (int j = 0; j < cur_lookup_config_vec[i].lookups.size(); ++j) { - lookup_constraint_type lookup_constraint = {lookup_tables_indices.at(cur_lookup_table_name), - {var(component.W(cur_lookup_config_vec[i].lookups[j][0].column), static_cast(cur_lookup_config_vec[i].lookups[j][0].row) - - static_cast(cur_lookup_config_vec[i].first_coordinate.row) - 1)}}; + lookup_constraint_type lookup_constraint = { + lookup_tables_indices.at(cur_lookup_table_name), + {var(component.W(cur_lookup_config_vec[i].lookups[j][0].column), + static_cast(cur_lookup_config_vec[i].lookups[j][0].row) - + static_cast(cur_lookup_config_vec[i].first_coordinate.row) - 1)}}; cur_lookup_constraints.push_back(lookup_constraint); } selector_indexes.push_back(bp.add_lookup_gate(cur_lookup_constraints)); @@ -1372,11 +1511,14 @@ namespace nil { } for (std::size_t i = 0; i < cur_lookup_config_vec.size(); ++i) { for (int j = 0; j < cur_lookup_config_vec[i].lookups.size(); ++j) { - lookup_constraint_type lookup_constraint = {lookup_tables_indices.at(cur_lookup_table_name), - {var(component.W(cur_lookup_config_vec[i].lookups[j][0].column), static_cast(cur_lookup_config_vec[i].lookups[j][0].row) - - static_cast(cur_lookup_config_vec[i].first_coordinate.row) - 1), - var(component.W(cur_lookup_config_vec[i].lookups[j][1].column), static_cast(cur_lookup_config_vec[i].lookups[j][1].row) - - static_cast(cur_lookup_config_vec[i].first_coordinate.row) - 1)}}; + lookup_constraint_type lookup_constraint = { + lookup_tables_indices.at(cur_lookup_table_name), + {var(component.W(cur_lookup_config_vec[i].lookups[j][0].column), + static_cast(cur_lookup_config_vec[i].lookups[j][0].row) - + static_cast(cur_lookup_config_vec[i].first_coordinate.row) - 1), + var(component.W(cur_lookup_config_vec[i].lookups[j][1].column), + static_cast(cur_lookup_config_vec[i].lookups[j][1].row) - + static_cast(cur_lookup_config_vec[i].first_coordinate.row) - 1)}}; cur_lookup_constraints.push_back(lookup_constraint); } selector_indexes.push_back(bp.add_lookup_gate(cur_lookup_constraints)); @@ -1394,7 +1536,9 @@ namespace nil { // for (std::size_t i = 0; i < cur_config_vec.size(); ++i) { // for (int j = 0; j < cur_config_vec[i].lookups.size(); ++j) { // for (int k = 0; k < cur_config_vec[i].lookups[j].size(); ++k) { - // std::cout << static_cast(cur_config_vec[i].lookups[j][k].row) - static_cast(cur_config_vec[i].first_coordinate.row) - 1 << " " << cur_config_vec[i].lookups[j][k].column << ", "; + // std::cout << static_cast(cur_config_vec[i].lookups[j][k].row) - + // static_cast(cur_config_vec[i].first_coordinate.row) - 1 << " " << + // cur_config_vec[i].lookups[j][k].column << ", "; // } // std::cout << std::endl; // } @@ -1425,10 +1569,13 @@ namespace nil { // } // for (std::size_t i = 0; i < cur_config_vec.size(); ++i) { // for (int j = 0; j < cur_config_vec[i].lookups.size(); ++j) { - // lookup_constraint_type lookup_constraint = {lookup_tables_indices.at(cur_lookup_table_name), - // {var(component.W(cur_config_vec[i].lookups[j][0].column), static_cast(cur_config_vec[i].lookups[j][0].row) + // lookup_constraint_type lookup_constraint = + // {lookup_tables_indices.at(cur_lookup_table_name), + // {var(component.W(cur_config_vec[i].lookups[j][0].column), + // static_cast(cur_config_vec[i].lookups[j][0].row) // - static_cast(cur_config_vec[i].first_coordinate.row) - 1), - // var(component.W(cur_config_vec[i].lookups[j][1].column), static_cast(cur_config_vec[i].lookups[j][1].row) + // var(component.W(cur_config_vec[i].lookups[j][1].column), + // static_cast(cur_config_vec[i].lookups[j][1].row) // - static_cast(cur_config_vec[i].first_coordinate.row) - 1)}}; // cur_constraints.push_back(lookup_constraint); // } @@ -1442,14 +1589,10 @@ namespace nil { template void generate_copy_constraints( - const keccak_round_component - &component, - circuit> - &bp, - assignment> - &assignment, - const typename keccak_round_component::input_type - &instance_input, + const keccak_round_component &component, + circuit> &bp, + assignment> &assignment, + const typename keccak_round_component::input_type &instance_input, const std::uint32_t start_row_index) { using component_type = keccak_round_component; @@ -1464,46 +1607,78 @@ namespace nil { if (component.xor_with_mes) { // inner_state ^ chunk for (int i = 0; i < 17 - component.last_round_call; ++i) { - bp.add_copy_constraint({instance_input.inner_state[i], var(component.W(config[i].copy_to[0].column), static_cast(config[i].copy_to[0].row + start_row_index), false)}); - bp.add_copy_constraint({instance_input.padded_message_chunk[i], var(component.W(config[i].copy_to[1].column), static_cast(config[i].copy_to[1].row + start_row_index), false)}); + bp.add_copy_constraint( + {instance_input.inner_state[i], + var(component.W(config[i].copy_to[0].column), + static_cast(config[i].copy_to[0].row + start_row_index), false)}); + bp.add_copy_constraint( + {instance_input.padded_message_chunk[i], + var(component.W(config[i].copy_to[1].column), + static_cast(config[i].copy_to[1].row + start_row_index), false)}); num_copy_constr += 2; } config_index += 16; if (component.last_round_call) { - bp.add_copy_constraint({instance_input.inner_state[config_index], var(component.W(config[config_index].copy_to[0].column), static_cast(config[config_index].copy_to[0].row + start_row_index), false)}); - bp.add_copy_constraint({instance_input.padded_message_chunk[config_index], var(component.W(config[config_index].copy_to[1].column), static_cast(config[config_index].copy_to[1].row + start_row_index), false)}); - bp.add_copy_constraint({var(component.C(0), component.last_round_call_row + start_row_index, false, var::column_type::constant), - var(component.W(config[config_index].copy_to[2].column), static_cast(config[config_index].copy_to[2].row + start_row_index), false)}); + bp.add_copy_constraint( + {instance_input.inner_state[config_index], + var(component.W(config[config_index].copy_to[0].column), + static_cast(config[config_index].copy_to[0].row + start_row_index), false)}); + bp.add_copy_constraint( + {instance_input.padded_message_chunk[config_index], + var(component.W(config[config_index].copy_to[1].column), + static_cast(config[config_index].copy_to[1].row + start_row_index), false)}); + bp.add_copy_constraint( + {var(component.C(0), component.last_round_call_row + start_row_index, false, + var::column_type::constant), + var(component.W(config[config_index].copy_to[2].column), + static_cast(config[config_index].copy_to[2].row + start_row_index), false)}); num_copy_constr += 3; } config_index += 1; // theta for (int i = 0; i < 17; ++i) { - bp.add_copy_constraint({{component.W(config[prev_index + i].copy_from.column), static_cast(config[prev_index + i].copy_from.row + start_row_index), false}, - {component.W(config[config_index + i % 5].copy_to[i / 5].column), static_cast(config[config_index + i % 5].copy_to[i / 5].row + start_row_index), false}}); + bp.add_copy_constraint( + {{component.W(config[prev_index + i].copy_from.column), + static_cast(config[prev_index + i].copy_from.row + start_row_index), false}, + {component.W(config[config_index + i % 5].copy_to[i / 5].column), + static_cast(config[config_index + i % 5].copy_to[i / 5].row + start_row_index), + false}}); num_copy_constr += 1; } for (int i = 17; i < 25; ++i) { - bp.add_copy_constraint({instance_input.inner_state[i], - {component.W(config[config_index + i % 5].copy_to[i / 5].column), static_cast(config[config_index + i % 5].copy_to[i / 5].row + start_row_index), false}}); + bp.add_copy_constraint( + {instance_input.inner_state[i], + {component.W(config[config_index + i % 5].copy_to[i / 5].column), + static_cast(config[config_index + i % 5].copy_to[i / 5].row + start_row_index), + false}}); num_copy_constr += 1; } config_index += 5; prev_index += 17; } else { for (int i = 0; i < 25; ++i) { - bp.add_copy_constraint({instance_input.inner_state[i], - {component.W(config[config_index + i % 5].copy_to[i / 5].column), static_cast(config[config_index + i % 5].copy_to[i / 5].row + start_row_index), false}}); + bp.add_copy_constraint( + {instance_input.inner_state[i], + {component.W(config[config_index + i % 5].copy_to[i / 5].column), + static_cast(config[config_index + i % 5].copy_to[i / 5].row + start_row_index), + false}}); num_copy_constr += 1; } config_index += 5; } for (int i = 0; i < 5; ++i) { - bp.add_copy_constraint({{component.W(config[prev_index + i].copy_from.column), static_cast(config[prev_index + i].copy_from.row + start_row_index), false}, - {component.W(config[config_index + i].copy_to[0].column), static_cast(config[config_index + i].copy_to[0].row + start_row_index), false}}); - bp.add_copy_constraint({{component.W(config[config_index + i].constraints[6][0].column), static_cast(config[config_index + i].constraints[6][0].row + start_row_index), false}, - var(component.C(0), static_cast(config[config_index + i].first_coordinate.row + start_row_index), false, var::column_type::constant)}); + bp.add_copy_constraint( + {{component.W(config[prev_index + i].copy_from.column), + static_cast(config[prev_index + i].copy_from.row + start_row_index), false}, + {component.W(config[config_index + i].copy_to[0].column), + static_cast(config[config_index + i].copy_to[0].row + start_row_index), false}}); + bp.add_copy_constraint( + {{component.W(config[config_index + i].constraints[6][0].column), + static_cast(config[config_index + i].constraints[6][0].row + start_row_index), false}, + var(component.C(0), + static_cast(config[config_index + i].first_coordinate.row + start_row_index), false, + var::column_type::constant)}); num_copy_constr += 2; } config_index += 5; @@ -1511,70 +1686,91 @@ namespace nil { for (int i = 0; i < 25; ++i) { std::size_t x = i % 5; - bp.add_copy_constraint({{component.W(config[prev_index - 5 + i % 5].copy_to[i / 5].column), static_cast(config[prev_index - 5 + i % 5].copy_to[i / 5].row + start_row_index), false}, - {component.W(config[config_index + i].copy_to[0].column), static_cast(config[config_index + i].copy_to[0].row + start_row_index), false}}); - bp.add_copy_constraint({{component.W(config[prev_index + (x + 1) % 5].copy_from.column), static_cast(config[prev_index + (x + 1) % 5].copy_from.row + start_row_index), false}, - {component.W(config[config_index + i].copy_to[1].column), static_cast(config[config_index + i].copy_to[1].row + start_row_index), false}}); - bp.add_copy_constraint({{component.W(config[prev_index + (x + 4) % 5].copy_to[0].column), static_cast(config[prev_index + (x + 4) % 5].copy_to[0].row + start_row_index), false}, - {component.W(config[config_index + i].copy_to[2].column), static_cast(config[config_index + i].copy_to[2].row + start_row_index), false}}); + bp.add_copy_constraint( + {{component.W(config[prev_index - 5 + i % 5].copy_to[i / 5].column), + static_cast(config[prev_index - 5 + i % 5].copy_to[i / 5].row + start_row_index), false}, + {component.W(config[config_index + i].copy_to[0].column), + static_cast(config[config_index + i].copy_to[0].row + start_row_index), false}}); + bp.add_copy_constraint( + {{component.W(config[prev_index + (x + 1) % 5].copy_from.column), + static_cast(config[prev_index + (x + 1) % 5].copy_from.row + start_row_index), false}, + {component.W(config[config_index + i].copy_to[1].column), + static_cast(config[config_index + i].copy_to[1].row + start_row_index), false}}); + bp.add_copy_constraint( + {{component.W(config[prev_index + (x + 4) % 5].copy_to[0].column), + static_cast(config[prev_index + (x + 4) % 5].copy_to[0].row + start_row_index), false}, + {component.W(config[config_index + i].copy_to[2].column), + static_cast(config[config_index + i].copy_to[2].row + start_row_index), false}}); num_copy_constr += 3; } config_index += 25; prev_index += 5; // rho/phi - std::size_t perm_rho[24] = {1, 10, 7, 11, 17, 18, 3, - 5, 16, 8, 21, 24, 4, - 15, 23, 19, 13, 12, 2, - 20, 14, 22, 9, 6}; + std::size_t perm_rho[24] = {1, 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, + 4, 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6}; for (int i = 0; i < 24; ++i) { - bp.add_copy_constraint({{component.W(config[prev_index + perm_rho[i]].copy_from.column), static_cast(config[prev_index + perm_rho[i]].copy_from.row + start_row_index), false}, - {component.W(config[config_index + i].copy_to[0].column), static_cast(config[config_index + i].copy_to[0].row + start_row_index), false}}); - bp.add_copy_constraint({{component.W(config[config_index + i].constraints[6][0].column), static_cast(config[config_index + i].constraints[6][0].row + start_row_index), false}, - var(component.C(0), static_cast(config[config_index + i].first_coordinate.row + start_row_index), false, var::column_type::constant)}); + bp.add_copy_constraint( + {{component.W(config[prev_index + perm_rho[i]].copy_from.column), + static_cast(config[prev_index + perm_rho[i]].copy_from.row + start_row_index), false}, + {component.W(config[config_index + i].copy_to[0].column), + static_cast(config[config_index + i].copy_to[0].row + start_row_index), false}}); + bp.add_copy_constraint( + {{component.W(config[config_index + i].constraints[6][0].column), + static_cast(config[config_index + i].constraints[6][0].row + start_row_index), false}, + var(component.C(0), + static_cast(config[config_index + i].first_coordinate.row + start_row_index), false, + var::column_type::constant)}); } // chi - std::size_t perm_chi[24] = {23, 17, 5, 11, 6, 22, - 1, 8, 21, 0, 2, 16, - 15, 19, 12, 7, 3, 4, - 14, 18, 9, 20, 13, 10}; - std::vector B = {{component.W(config[prev_index].copy_from.column), static_cast(config[prev_index].copy_from.row + start_row_index), false}}; + std::size_t perm_chi[24] = {23, 17, 5, 11, 6, 22, 1, 8, 21, 0, 2, 16, + 15, 19, 12, 7, 3, 4, 14, 18, 9, 20, 13, 10}; + std::vector B = {{component.W(config[prev_index].copy_from.column), + static_cast(config[prev_index].copy_from.row + start_row_index), false}}; for (auto i : perm_chi) { - B.push_back({component.W(config[config_index + i].copy_from.column), static_cast(config[config_index + i].copy_from.row + start_row_index), false}); + B.push_back({component.W(config[config_index + i].copy_from.column), + static_cast(config[config_index + i].copy_from.row + start_row_index), false}); } config_index += 24; prev_index += 25; for (int i = 0; i < 25; ++i) { int x = i % 5; int y = i / 5; - bp.add_copy_constraint({B[x + 5 * y], - {component.W(config[config_index + i].copy_to[0].column), static_cast(config[config_index + i].copy_to[0].row + start_row_index), false}}); - bp.add_copy_constraint({B[(x + 1) % 5 + 5 * y], - {component.W(config[config_index + i].copy_to[1].column), static_cast(config[config_index + i].copy_to[1].row + start_row_index), false}}); - bp.add_copy_constraint({B[(x + 2) % 5 + 5 * y], - {component.W(config[config_index + i].copy_to[2].column), static_cast(config[config_index + i].copy_to[2].row + start_row_index), false}}); + bp.add_copy_constraint( + {B[x + 5 * y], + {component.W(config[config_index + i].copy_to[0].column), + static_cast(config[config_index + i].copy_to[0].row + start_row_index), false}}); + bp.add_copy_constraint( + {B[(x + 1) % 5 + 5 * y], + {component.W(config[config_index + i].copy_to[1].column), + static_cast(config[config_index + i].copy_to[1].row + start_row_index), false}}); + bp.add_copy_constraint( + {B[(x + 2) % 5 + 5 * y], + {component.W(config[config_index + i].copy_to[2].column), + static_cast(config[config_index + i].copy_to[2].row + start_row_index), false}}); } config_index += 25; prev_index += 24; // iota - bp.add_copy_constraint({{component.W(config[prev_index].copy_from.column), static_cast(config[prev_index].copy_from.row + start_row_index), false}, - {component.W(config[config_index].copy_to[0].column), static_cast(config[config_index].copy_to[0].row + start_row_index), false}}); - bp.add_copy_constraint({instance_input.round_constant, - {component.W(config[config_index].copy_to[1].column), static_cast(config[config_index].copy_to[1].row + start_row_index), false}}); + bp.add_copy_constraint( + {{component.W(config[prev_index].copy_from.column), + static_cast(config[prev_index].copy_from.row + start_row_index), false}, + {component.W(config[config_index].copy_to[0].column), + static_cast(config[config_index].copy_to[0].row + start_row_index), false}}); + bp.add_copy_constraint( + {instance_input.round_constant, + {component.W(config[config_index].copy_to[1].column), + static_cast(config[config_index].copy_to[1].row + start_row_index), false}}); } template void generate_assignments_constant( - const keccak_round_component - &component, - circuit> - &bp, - assignment> - &assignment, - const typename keccak_round_component::input_type - &instance_input, + const keccak_round_component &component, + circuit> &bp, + assignment> &assignment, + const typename keccak_round_component::input_type &instance_input, const std::uint32_t start_row_index) { using component_type = keccak_round_component; @@ -1582,7 +1778,8 @@ namespace nil { std::size_t row = start_row_index; if (component.last_round_call) { - assignment.constant(component.C(0), row + component.last_round_call_row) = 2097152; // sparse 0x80 + assignment.constant(component.C(0), row + component.last_round_call_row) = + component.sparse_x80; // sparse 0x80 } auto gate_map = component.gates_configuration_map; @@ -1599,59 +1796,57 @@ namespace nil { assignment.constant(component.C(0), row + rotate_rows[i] + 2) = component.all_rot_consts[i][1]; } for (std::size_t i = 5; i < 29; i++) { - assignment.constant(component.C(0), row + rotate_rows[i]) = integral_type(1) << (3 * component_type::rho_offsets[i - 4]); + assignment.constant(component.C(0), row + rotate_rows[i]) = + integral_type(1) << (3 * component_type::rho_offsets[i - 4]); assignment.constant(component.C(0), row + rotate_rows[i] + 1) = component.all_rot_consts[i][0]; assignment.constant(component.C(0), row + rotate_rows[i] + 2) = component.all_rot_consts[i][1]; } } template - typename keccak_round_component::result_type - generate_circuit( - const keccak_round_component - &component, - circuit> - &bp, - assignment> - &assignment, - const typename keccak_round_component::input_type - &instance_input, + typename keccak_round_component::result_type generate_circuit( + const keccak_round_component &component, + circuit> &bp, + assignment> &assignment, + const typename keccak_round_component::input_type &instance_input, const std::uint32_t start_row_index) { using component_type = keccak_round_component; - generate_assignments_constant(component, bp, assignment, instance_input, start_row_index); - - auto selector_indexes = generate_gates(component, bp, assignment, instance_input, bp.get_reserved_indices()); + auto selector_indexes = + generate_gates(component, bp, assignment, instance_input, bp.get_reserved_indices()); std::size_t ind = 0; - std::size_t index = 0; // for (auto g : component.gates_configuration_map) { // for (auto j : g.second) { - // std::cout << "g.first.first: " << g.first.first << ", g.first.second: " << g.first.second << ", j: " << j << '\n'; - // assignment.enable_selector(selector_indexes[index], + // std::cout << "g.first.first: " << g.first.first << ", g.first.second: " << g.first.second << + // ", j: " << j << '\n'; assignment.enable_selector(selector_indexes[index], // start_row_index + j + 1); // } // std::cout << '\n'; // index++; // } for (auto g : component.gates_configuration_map) { - // std::cout << "g.first.first: " << g.first.first << ", g.first.second: " << g.first.second << '\n'; - // if (g.first.first == 5) continue; + // std::cout << "g.first.first: " << g.first.first << ", g.first.second: " << g.first.second << + // '\n'; if (g.first.first == 5) continue; for (std::size_t i = 0; i < component.gates_configuration[ind].size(); ++i) { for (auto j : g.second) { // std::cout << j + component.gates_configuration[ind][i].first_coordinate.row + 1 << ' '; - assignment.enable_selector(selector_indexes[index], - start_row_index + j + component.gates_configuration[ind][i].first_coordinate.row + 1); + assignment.enable_selector( + selector_indexes[index], + start_row_index + j + component.gates_configuration[ind][i].first_coordinate.row + 1); } // std::cout << '\n'; index++; } for (std::size_t i = 0; i < component.lookup_gates_configuration[ind].size(); ++i) { for (auto j : g.second) { - //std::cout << start_row_index + j + component.lookup_gates_configuration[ind][i].first_coordinate.row + 1 << ' '; - assignment.enable_selector(selector_indexes[index], - start_row_index + j + component.lookup_gates_configuration[ind][i].first_coordinate.row + 1); + // std::cout << start_row_index + j + + // component.lookup_gates_configuration[ind][i].first_coordinate.row + 1 << ' '; + assignment.enable_selector( + selector_indexes[index], + start_row_index + j + + component.lookup_gates_configuration[ind][i].first_coordinate.row + 1); } // std::cout << '\n'; index++; @@ -1660,19 +1855,14 @@ namespace nil { } generate_copy_constraints(component, bp, assignment, instance_input, start_row_index); - return typename component_type::result_type(component, start_row_index); } template - typename keccak_round_component::result_type - generate_assignments( - const keccak_round_component - &component, - assignment> - &assignment, - const typename keccak_round_component::input_type - &instance_input, + typename keccak_round_component::result_type generate_assignments( + const keccak_round_component &component, + assignment> &assignment, + const typename keccak_round_component::input_type &instance_input, const std::uint32_t start_row_index) { using component_type = keccak_round_component; @@ -1708,20 +1898,29 @@ namespace nil { A_1[index] = value_type(integral_normalized_sum); auto cur_config = component.full_configuration[index]; - assignment.witness(component.W(cur_config.copy_to[0].column), cur_config.copy_to[0].row + strow) = state; - assignment.witness(component.W(cur_config.copy_to[1].column), cur_config.copy_to[1].row + strow) = message; - assignment.witness(component.W(cur_config.constraints[1][0].column), cur_config.constraints[1][0].row + strow) = sum; - assignment.witness(component.W(cur_config.constraints[2][0].column), cur_config.constraints[2][0].row + strow) = value_type(integral_normalized_sum); + assignment.witness(component.W(cur_config.copy_to[0].column), + cur_config.copy_to[0].row + strow) = state; + assignment.witness(component.W(cur_config.copy_to[1].column), + cur_config.copy_to[1].row + strow) = message; + assignment.witness(component.W(cur_config.constraints[1][0].column), + cur_config.constraints[1][0].row + strow) = sum; + assignment.witness(component.W(cur_config.constraints[2][0].column), + cur_config.constraints[2][0].row + strow) = + value_type(integral_normalized_sum); for (int j = 1; j < num_chunks + 1; ++j) { - assignment.witness(component.W(cur_config.constraints[1][j].column), cur_config.constraints[1][j].row + strow) = value_type(integral_chunks[j - 1]); - assignment.witness(component.W(cur_config.constraints[2][j].column), cur_config.constraints[2][j].row + strow) = value_type(integral_normalized_chunks[j - 1]); + assignment.witness(component.W(cur_config.constraints[1][j].column), + cur_config.constraints[1][j].row + strow) = + value_type(integral_chunks[j - 1]); + assignment.witness(component.W(cur_config.constraints[2][j].column), + cur_config.constraints[2][j].row + strow) = + value_type(integral_normalized_chunks[j - 1]); } } // last round call if (component.last_round_call) { value_type state = var_value(assignment, instance_input.inner_state[16]); value_type message = var_value(assignment, instance_input.padded_message_chunk[16]); - value_type sum = state + message + value_type(2097152); + value_type sum = state + message + value_type(component.sparse_x80); integral_type integral_sum = integral_type(sum.data); auto chunk_size = component.normalize4_chunk_size; auto num_chunks = component.normalize4_num_chunks; @@ -1740,14 +1939,24 @@ namespace nil { A_1[16] = value_type(integral_normalized_sum); auto cur_config = component.full_configuration[16]; - assignment.witness(component.W(cur_config.copy_to[0].column), cur_config.copy_to[0].row + strow) = state; - assignment.witness(component.W(cur_config.copy_to[1].column), cur_config.copy_to[1].row + strow) = message; - assignment.witness(component.W(cur_config.copy_to[2].column), cur_config.copy_to[2].row + strow) = value_type(2097152); - assignment.witness(component.W(cur_config.constraints[1][0].column), cur_config.constraints[1][0].row + strow) = sum; - assignment.witness(component.W(cur_config.constraints[2][0].column), cur_config.constraints[2][0].row + strow) = value_type(integral_normalized_sum); + assignment.witness(component.W(cur_config.copy_to[0].column), + cur_config.copy_to[0].row + strow) = state; + assignment.witness(component.W(cur_config.copy_to[1].column), + cur_config.copy_to[1].row + strow) = message; + assignment.witness(component.W(cur_config.copy_to[2].column), + cur_config.copy_to[2].row + strow) = value_type(component.sparse_x80); + assignment.witness(component.W(cur_config.constraints[1][0].column), + cur_config.constraints[1][0].row + strow) = sum; + assignment.witness(component.W(cur_config.constraints[2][0].column), + cur_config.constraints[2][0].row + strow) = + value_type(integral_normalized_sum); for (int j = 1; j < num_chunks + 1; ++j) { - assignment.witness(component.W(cur_config.constraints[1][j].column), cur_config.constraints[1][j].row + strow) = value_type(integral_chunks[j - 1]); - assignment.witness(component.W(cur_config.constraints[2][j].column), cur_config.constraints[2][j].row + strow) = value_type(integral_normalized_chunks[j - 1]); + assignment.witness(component.W(cur_config.constraints[1][j].column), + cur_config.constraints[1][j].row + strow) = + value_type(integral_chunks[j - 1]); + assignment.witness(component.W(cur_config.constraints[2][j].column), + cur_config.constraints[2][j].row + strow) = + value_type(integral_normalized_chunks[j - 1]); } } for (int i = 17; i < 25; ++i) { @@ -1790,16 +1999,27 @@ namespace nil { C[index] = value_type(integral_normalized_sum); auto cur_config = component.full_configuration[index + config_index]; - assignment.witness(component.W(cur_config.copy_to[0].column), cur_config.copy_to[0].row + strow) = A_1[index]; - assignment.witness(component.W(cur_config.copy_to[1].column), cur_config.copy_to[1].row + strow) = A_1[index + 5]; - assignment.witness(component.W(cur_config.copy_to[2].column), cur_config.copy_to[2].row + strow) = A_1[index + 10]; - assignment.witness(component.W(cur_config.copy_to[3].column), cur_config.copy_to[3].row + strow) = A_1[index + 15]; - assignment.witness(component.W(cur_config.copy_to[4].column), cur_config.copy_to[4].row + strow) = A_1[index + 20]; - assignment.witness(component.W(cur_config.constraints[1][0].column), cur_config.constraints[1][0].row + strow) = sum; - assignment.witness(component.W(cur_config.constraints[2][0].column), cur_config.constraints[2][0].row + strow) = value_type(integral_normalized_sum); + assignment.witness(component.W(cur_config.copy_to[0].column), cur_config.copy_to[0].row + strow) = + A_1[index]; + assignment.witness(component.W(cur_config.copy_to[1].column), cur_config.copy_to[1].row + strow) = + A_1[index + 5]; + assignment.witness(component.W(cur_config.copy_to[2].column), cur_config.copy_to[2].row + strow) = + A_1[index + 10]; + assignment.witness(component.W(cur_config.copy_to[3].column), cur_config.copy_to[3].row + strow) = + A_1[index + 15]; + assignment.witness(component.W(cur_config.copy_to[4].column), cur_config.copy_to[4].row + strow) = + A_1[index + 20]; + assignment.witness(component.W(cur_config.constraints[1][0].column), + cur_config.constraints[1][0].row + strow) = sum; + assignment.witness(component.W(cur_config.constraints[2][0].column), + cur_config.constraints[2][0].row + strow) = value_type(integral_normalized_sum); for (int j = 1; j < num_chunks + 1; ++j) { - assignment.witness(component.W(cur_config.constraints[1][j].column), cur_config.constraints[1][j].row + strow) = value_type(integral_chunks[j - 1]); - assignment.witness(component.W(cur_config.constraints[2][j].column), cur_config.constraints[2][j].row + strow) = value_type(integral_normalized_chunks[j - 1]); + assignment.witness(component.W(cur_config.constraints[1][j].column), + cur_config.constraints[1][j].row + strow) = + value_type(integral_chunks[j - 1]); + assignment.witness(component.W(cur_config.constraints[2][j].column), + cur_config.constraints[2][j].row + strow) = + value_type(integral_normalized_chunks[j - 1]); } } config_index += 5; @@ -1811,10 +2031,14 @@ namespace nil { // ROT std::array C_rot; - integral_type for_bound_smaller = component.calculate_sparse((integral_type(1) << 64) - 1) - component.calculate_sparse((integral_type(1) << 1) - 1); - integral_type for_bound_bigger = component.calculate_sparse((integral_type(1) << 64) - 1) - component.calculate_sparse((integral_type(1) << 63) - 1); - // std::cout << "for_bound_smaller: " << for_bound_smaller << ", for_bound_bigger: " << for_bound_bigger << '\n'; - // std::cout << component.calculate_sparse((integral_type(1) << 64) - 1) << "\n" << component.calculate_sparse((integral_type(1) << 63) - 1) << "\n" << component.calculate_sparse((integral_type(1) << 1) - 1) << "\n"; + integral_type for_bound_smaller = component.calculate_sparse((integral_type(1) << 64) - 1) - + component.calculate_sparse((integral_type(1) << 1) - 1); + integral_type for_bound_bigger = component.calculate_sparse((integral_type(1) << 64) - 1) - + component.calculate_sparse((integral_type(1) << 63) - 1); + // std::cout << "for_bound_smaller: " << for_bound_smaller << ", for_bound_bigger: " << for_bound_bigger + // << '\n'; std::cout << component.calculate_sparse((integral_type(1) << 64) - 1) << "\n" << + // component.calculate_sparse((integral_type(1) << 63) - 1) << "\n" << + // component.calculate_sparse((integral_type(1) << 1) - 1) << "\n"; for (int index = 0; index < 5; ++index) { integral_type integral_C = integral_type(C[index].data); integral_type smaller_part = integral_C >> 189; @@ -1847,18 +2071,30 @@ namespace nil { // std::cout << "check: " << check << ' ' << copy_bound_bigger << '\n'; auto cur_config = component.full_configuration[index + config_index]; - assignment.witness(component.W(cur_config.copy_to[0].column), cur_config.copy_to[0].row + strow) = C[index]; - assignment.witness(component.W(cur_config.copy_from.column), cur_config.copy_from.row + strow) = C_rot[index]; - assignment.witness(component.W(cur_config.constraints[0][1].column), cur_config.constraints[0][1].row + strow) = value_type(smaller_part); - assignment.witness(component.W(cur_config.constraints[0][2].column), cur_config.constraints[0][2].row + strow) = value_type(bigger_part); - assignment.witness(component.W(cur_config.constraints[3][0].column), cur_config.constraints[3][0].row + strow) = value_type(copy_bound_smaller); - assignment.witness(component.W(cur_config.constraints[5][0].column), cur_config.constraints[5][0].row + strow) = value_type(copy_bound_bigger); + assignment.witness(component.W(cur_config.copy_to[0].column), cur_config.copy_to[0].row + strow) = + C[index]; + assignment.witness(component.W(cur_config.copy_from.column), cur_config.copy_from.row + strow) = + C_rot[index]; + assignment.witness(component.W(cur_config.constraints[0][1].column), + cur_config.constraints[0][1].row + strow) = value_type(smaller_part); + assignment.witness(component.W(cur_config.constraints[0][2].column), + cur_config.constraints[0][2].row + strow) = value_type(bigger_part); + assignment.witness(component.W(cur_config.constraints[3][0].column), + cur_config.constraints[3][0].row + strow) = value_type(copy_bound_smaller); + assignment.witness(component.W(cur_config.constraints[5][0].column), + cur_config.constraints[5][0].row + strow) = value_type(copy_bound_bigger); for (int j = 1; j < num_chunks + 1; ++j) { - assignment.witness(component.W(cur_config.constraints[3][j].column), cur_config.constraints[3][j].row + strow) = value_type(integral_small_chunks[j - 1]); - assignment.witness(component.W(cur_config.constraints[5][j].column), cur_config.constraints[5][j].row + strow) = value_type(integral_big_chunks[j - 1]); - } - assignment.witness(component.W(cur_config.constraints[6][0].column), cur_config.constraints[6][0].row + strow) = value_type(integral_type(1) << 3); - assignment.witness(component.W(cur_config.constraints[6][1].column), cur_config.constraints[6][1].row + strow) = value_type(integral_type(1) << 189); + assignment.witness(component.W(cur_config.constraints[3][j].column), + cur_config.constraints[3][j].row + strow) = + value_type(integral_small_chunks[j - 1]); + assignment.witness(component.W(cur_config.constraints[5][j].column), + cur_config.constraints[5][j].row + strow) = + value_type(integral_big_chunks[j - 1]); + } + assignment.witness(component.W(cur_config.constraints[6][0].column), + cur_config.constraints[6][0].row + strow) = value_type(integral_type(1) << 3); + assignment.witness(component.W(cur_config.constraints[6][1].column), + cur_config.constraints[6][1].row + strow) = value_type(integral_type(1) << 189); } config_index += 5; // std::cout << "C_rot:\n"; @@ -1890,14 +2126,23 @@ namespace nil { A_2[index] = value_type(integral_normalized_sum); auto cur_config = component.full_configuration[index + config_index]; - assignment.witness(component.W(cur_config.copy_to[0].column), cur_config.copy_to[0].row + strow) = A_1[index]; - assignment.witness(component.W(cur_config.copy_to[1].column), cur_config.copy_to[1].row + strow) = C_rot[(x + 1) % 5]; - assignment.witness(component.W(cur_config.copy_to[2].column), cur_config.copy_to[2].row + strow) = C[(x + 4) % 5]; - assignment.witness(component.W(cur_config.constraints[1][0].column), cur_config.constraints[1][0].row + strow) = sum; - assignment.witness(component.W(cur_config.constraints[2][0].column), cur_config.constraints[2][0].row + strow) = A_2[index]; + assignment.witness(component.W(cur_config.copy_to[0].column), cur_config.copy_to[0].row + strow) = + A_1[index]; + assignment.witness(component.W(cur_config.copy_to[1].column), cur_config.copy_to[1].row + strow) = + C_rot[(x + 1) % 5]; + assignment.witness(component.W(cur_config.copy_to[2].column), cur_config.copy_to[2].row + strow) = + C[(x + 4) % 5]; + assignment.witness(component.W(cur_config.constraints[1][0].column), + cur_config.constraints[1][0].row + strow) = sum; + assignment.witness(component.W(cur_config.constraints[2][0].column), + cur_config.constraints[2][0].row + strow) = A_2[index]; for (int j = 1; j < num_chunks + 1; ++j) { - assignment.witness(component.W(cur_config.constraints[1][j].column), cur_config.constraints[1][j].row + strow) = value_type(integral_chunks[j - 1]); - assignment.witness(component.W(cur_config.constraints[2][j].column), cur_config.constraints[2][j].row + strow) = value_type(integral_normalized_chunks[j - 1]); + assignment.witness(component.W(cur_config.constraints[1][j].column), + cur_config.constraints[1][j].row + strow) = + value_type(integral_chunks[j - 1]); + assignment.witness(component.W(cur_config.constraints[2][j].column), + cur_config.constraints[2][j].row + strow) = + value_type(integral_normalized_chunks[j - 1]); } } config_index += 25; @@ -1909,10 +2154,8 @@ namespace nil { // rho/phi value_type B[25]; - std::size_t perm[25] = {1, 10, 7, 11, 17, 18, 3, - 5, 16, 8, 21, 24, 4, - 15, 23, 19, 13, 12, 2, - 20, 14, 22, 9, 6, 1}; + std::size_t perm[25] = {1, 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, + 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1}; B[0] = A_2[0]; for (int index = 1; index < 25; ++index) { int x = index % 5; @@ -1925,11 +2168,14 @@ namespace nil { integral_type integral_A_rot = (bigger_part << r) + smaller_part; B[perm[index]] = value_type(integral_A_rot); // integral_type bound_smaller = smaller_part - (integral_type(1) << r) + (integral_type(1) << 192); - // integral_type bound_bigger = bigger_part - (integral_type(1) << minus_r) + (integral_type(1) << 192); - integral_type bound_smaller = smaller_part + component.calculate_sparse((integral_type(1) << 64) - 1) - - component.calculate_sparse((integral_type(1) << component.rho_offsets[index]) - 1); - integral_type bound_bigger = bigger_part + component.calculate_sparse((integral_type(1) << 64) - 1) - - component.calculate_sparse((integral_type(1) << (64-component.rho_offsets[index])) - 1); + // integral_type bound_bigger = bigger_part - (integral_type(1) << minus_r) + (integral_type(1) << + // 192); + integral_type bound_smaller = + smaller_part + component.calculate_sparse((integral_type(1) << 64) - 1) - + component.calculate_sparse((integral_type(1) << component.rho_offsets[index]) - 1); + integral_type bound_bigger = + bigger_part + component.calculate_sparse((integral_type(1) << 64) - 1) - + component.calculate_sparse((integral_type(1) << (64 - component.rho_offsets[index])) - 1); auto copy_bound_smaller = bound_smaller; auto copy_bound_bigger = bound_bigger; auto chunk_size = component.rotate_chunk_size; @@ -1945,18 +2191,31 @@ namespace nil { } auto cur_config = component.full_configuration[index - 1 + config_index]; - assignment.witness(component.W(cur_config.copy_to[0].column), cur_config.copy_to[0].row + strow) = A_2[perm[index - 1]]; - assignment.witness(component.W(cur_config.copy_from.column), cur_config.copy_from.row + strow) = value_type(integral_A_rot); - assignment.witness(component.W(cur_config.constraints[0][1].column), cur_config.constraints[0][1].row + strow) = value_type(smaller_part); - assignment.witness(component.W(cur_config.constraints[0][2].column), cur_config.constraints[0][2].row + strow) = value_type(bigger_part); - assignment.witness(component.W(cur_config.constraints[3][0].column), cur_config.constraints[3][0].row + strow) = value_type(copy_bound_smaller); - assignment.witness(component.W(cur_config.constraints[5][0].column), cur_config.constraints[5][0].row + strow) = value_type(copy_bound_bigger); + assignment.witness(component.W(cur_config.copy_to[0].column), cur_config.copy_to[0].row + strow) = + A_2[perm[index - 1]]; + assignment.witness(component.W(cur_config.copy_from.column), cur_config.copy_from.row + strow) = + value_type(integral_A_rot); + assignment.witness(component.W(cur_config.constraints[0][1].column), + cur_config.constraints[0][1].row + strow) = value_type(smaller_part); + assignment.witness(component.W(cur_config.constraints[0][2].column), + cur_config.constraints[0][2].row + strow) = value_type(bigger_part); + assignment.witness(component.W(cur_config.constraints[3][0].column), + cur_config.constraints[3][0].row + strow) = value_type(copy_bound_smaller); + assignment.witness(component.W(cur_config.constraints[5][0].column), + cur_config.constraints[5][0].row + strow) = value_type(copy_bound_bigger); for (int j = 1; j < num_chunks + 1; ++j) { - assignment.witness(component.W(cur_config.constraints[3][j].column), cur_config.constraints[3][j].row + strow) = value_type(integral_small_chunks[j - 1]); - assignment.witness(component.W(cur_config.constraints[5][j].column), cur_config.constraints[5][j].row + strow) = value_type(integral_big_chunks[j - 1]); - } - assignment.witness(component.W(cur_config.constraints[6][0].column), cur_config.constraints[6][0].row + strow) = value_type(integral_type(1) << r); - assignment.witness(component.W(cur_config.constraints[6][1].column), cur_config.constraints[6][1].row + strow) = value_type(integral_type(1) << minus_r); + assignment.witness(component.W(cur_config.constraints[3][j].column), + cur_config.constraints[3][j].row + strow) = + value_type(integral_small_chunks[j - 1]); + assignment.witness(component.W(cur_config.constraints[5][j].column), + cur_config.constraints[5][j].row + strow) = + value_type(integral_big_chunks[j - 1]); + } + assignment.witness(component.W(cur_config.constraints[6][0].column), + cur_config.constraints[6][0].row + strow) = value_type(integral_type(1) << r); + assignment.witness(component.W(cur_config.constraints[6][1].column), + cur_config.constraints[6][1].row + strow) = + value_type(integral_type(1) << minus_r); } config_index += 24; @@ -1965,7 +2224,8 @@ namespace nil { for (int index = 0; index < 25; ++index) { int x = index % 5; int y = index / 5; - value_type sum = component.sparse_3 - 2 * B[x + 5 * y] + B[(x+1)%5 + 5 * y] - B[(x+2)%5 + 5 * y]; + value_type sum = + component.sparse_3 - 2 * B[x + 5 * y] + B[(x + 1) % 5 + 5 * y] - B[(x + 2) % 5 + 5 * y]; integral_type integral_sum = integral_type(sum.data); auto chunk_size = component.chi_chunk_size; auto num_chunks = component.chi_num_chunks; @@ -1984,14 +2244,23 @@ namespace nil { A_3[index] = value_type(integral_chi_sum); auto cur_config = component.full_configuration[index + config_index]; - assignment.witness(component.W(cur_config.copy_to[0].column), cur_config.copy_to[0].row + strow) = B[x + 5 * y]; - assignment.witness(component.W(cur_config.copy_to[1].column), cur_config.copy_to[1].row + strow) = B[(x+1)%5 + 5 * y]; - assignment.witness(component.W(cur_config.copy_to[2].column), cur_config.copy_to[2].row + strow) = B[(x+2)%5 + 5 * y]; - assignment.witness(component.W(cur_config.constraints[1][0].column), cur_config.constraints[1][0].row + strow) = sum; - assignment.witness(component.W(cur_config.constraints[2][0].column), cur_config.constraints[2][0].row + strow) = value_type(integral_chi_sum); + assignment.witness(component.W(cur_config.copy_to[0].column), cur_config.copy_to[0].row + strow) = + B[x + 5 * y]; + assignment.witness(component.W(cur_config.copy_to[1].column), cur_config.copy_to[1].row + strow) = + B[(x + 1) % 5 + 5 * y]; + assignment.witness(component.W(cur_config.copy_to[2].column), cur_config.copy_to[2].row + strow) = + B[(x + 2) % 5 + 5 * y]; + assignment.witness(component.W(cur_config.constraints[1][0].column), + cur_config.constraints[1][0].row + strow) = sum; + assignment.witness(component.W(cur_config.constraints[2][0].column), + cur_config.constraints[2][0].row + strow) = value_type(integral_chi_sum); for (int j = 1; j < num_chunks + 1; ++j) { - assignment.witness(component.W(cur_config.constraints[1][j].column), cur_config.constraints[1][j].row + strow) = value_type(integral_chunks[j - 1]); - assignment.witness(component.W(cur_config.constraints[2][j].column), cur_config.constraints[2][j].row + strow) = value_type(integral_chi_chunks[j - 1]); + assignment.witness(component.W(cur_config.constraints[1][j].column), + cur_config.constraints[1][j].row + strow) = + value_type(integral_chunks[j - 1]); + assignment.witness(component.W(cur_config.constraints[2][j].column), + cur_config.constraints[2][j].row + strow) = + value_type(integral_chi_chunks[j - 1]); } } config_index += 25; @@ -2019,13 +2288,21 @@ namespace nil { A_4 = value_type(integral_normalized_sum); auto cur_config = component.full_configuration[config_index]; - assignment.witness(component.W(cur_config.copy_to[0].column), cur_config.copy_to[0].row + strow) = A_3[0]; - assignment.witness(component.W(cur_config.copy_to[1].column), cur_config.copy_to[1].row + strow) = round_constant; - assignment.witness(component.W(cur_config.constraints[1][0].column), cur_config.constraints[1][0].row + strow) = sum; - assignment.witness(component.W(cur_config.constraints[2][0].column), cur_config.constraints[2][0].row + strow) = value_type(integral_normalized_sum); + assignment.witness(component.W(cur_config.copy_to[0].column), cur_config.copy_to[0].row + strow) = + A_3[0]; + assignment.witness(component.W(cur_config.copy_to[1].column), cur_config.copy_to[1].row + strow) = + round_constant; + assignment.witness(component.W(cur_config.constraints[1][0].column), + cur_config.constraints[1][0].row + strow) = sum; + assignment.witness(component.W(cur_config.constraints[2][0].column), + cur_config.constraints[2][0].row + strow) = value_type(integral_normalized_sum); for (int j = 1; j < num_chunks + 1; ++j) { - assignment.witness(component.W(cur_config.constraints[1][j].column), cur_config.constraints[1][j].row + strow) = value_type(integral_chunks[j - 1]); - assignment.witness(component.W(cur_config.constraints[2][j].column), cur_config.constraints[2][j].row + strow) = value_type(integral_normalized_chunks[j - 1]); + assignment.witness(component.W(cur_config.constraints[1][j].column), + cur_config.constraints[1][j].row + strow) = + value_type(integral_chunks[j - 1]); + assignment.witness(component.W(cur_config.constraints[2][j].column), + cur_config.constraints[2][j].row + strow) = + value_type(integral_normalized_chunks[j - 1]); } } // std::cout << "result:\n" << A_4.data << " "; @@ -2039,6 +2316,6 @@ namespace nil { } // namespace components } // namespace blueprint -} // namespace nil +} // namespace nil -#endif // CRYPTO3_BLUEPRINT_COMPONENTS_KECCAK_ROUND_HPP \ No newline at end of file +#endif // CRYPTO3_BLUEPRINT_COMPONENTS_KECCAK_ROUND_HPP \ No newline at end of file diff --git a/test/hashes/plonk/keccak.cpp b/test/hashes/plonk/keccak.cpp index 5b16b8978..093759bd6 100644 --- a/test/hashes/plonk/keccak.cpp +++ b/test/hashes/plonk/keccak.cpp @@ -1,6 +1,6 @@ //---------------------------------------------------------------------------// // Copyright (c) 2023 Polina Chernyshova -// +// 2024 Valeh Farzaliyev // MIT License // // Permission is hereby granted, free of charge, to any person obtaining a copy @@ -35,10 +35,12 @@ #include #include #include +#include +#include -#include +// #include #include -#include +// #include #include @@ -49,6 +51,12 @@ #include "../../test_plonk_component.hpp" +const int r[5][5] = {{0, 36, 3, 41, 18}, + {1, 44, 10, 45, 2}, + {62, 6, 43, 15, 61}, + {28, 55, 25, 21, 56}, + {27, 20, 39, 8, 14}}; + template std::size_t number_bits(typename BlueprintFieldType::value_type value) { using value_type = typename BlueprintFieldType::value_type; @@ -63,19 +71,283 @@ std::size_t number_bits(typename BlueprintFieldType::value_type value) { return result; } -template +template +typename BlueprintFieldType::value_type to_sparse(typename BlueprintFieldType::value_type value) { + using value_type = typename BlueprintFieldType::value_type; + using integral_type = typename BlueprintFieldType::integral_type; + integral_type value_integral = integral_type(value.data); + integral_type result_integral = 0; + integral_type power = 1; + for (int i = 0; i < 64; ++i) { + integral_type bit = value_integral & 1; + result_integral = result_integral + bit * power; + value_integral = value_integral >> 1; + power = power << 3; + } + return value_type(result_integral); +} + +template +typename BlueprintFieldType::value_type to_le(typename BlueprintFieldType::value_type value) { + using value_type = typename BlueprintFieldType::value_type; + using integral_type = typename BlueprintFieldType::integral_type; + integral_type value_integral = integral_type(value.data); + integral_type result_integral = 0; + for (int i = 0; i < 64; ++i) { + integral_type bit = value_integral & 1; + result_integral = (result_integral << 1) + bit; + value_integral = value_integral >> 1; + } + return value_type(result_integral); +} + +template +typename BlueprintFieldType::value_type to_le_bytes(typename BlueprintFieldType::value_type value) { + using value_type = typename BlueprintFieldType::value_type; + using integral_type = typename BlueprintFieldType::integral_type; + integral_type value_integral = integral_type(value.data); + integral_type result_integral = 0; + for (int i = 0; i < 64; i += 8) { + integral_type bit = value_integral & 0xff; + result_integral = (result_integral << 8) + bit; + value_integral = value_integral >> 8; + } + return value_type(result_integral); +} + +template +typename BlueprintFieldType::value_type unpack(typename BlueprintFieldType::value_type value) { + using value_type = typename BlueprintFieldType::value_type; + using integral_type = typename BlueprintFieldType::integral_type; + integral_type value_integral = integral_type(value.data); + integral_type result_integral = 0; + integral_type power = 1; + while (value_integral >= 1) { + integral_type bit = value_integral & 1; + result_integral = result_integral + bit * power; + value_integral = value_integral >> 3; + power = power << 1; + } + return value_type(result_integral); +} + +template +std::vector + padding_function(std::vector message, std::size_t num_bits) { + using value_type = typename BlueprintFieldType::value_type; + using integral_type = typename BlueprintFieldType::integral_type; + + std::vector result; + std::size_t shift = 64 * message.size() - num_bits; + + if (shift > 0) { + // message[message.size() - 1] = message[message.size() - 1] * 2 + value_type(1); + // shift--; + integral_type relay_value = integral_type(message[0].data); + for (int i = 1; i < message.size(); ++i) { + integral_type mask = (integral_type(1) << (64 - shift)) - 1; + integral_type left_part = integral_type(message[i].data >> (64 - shift)); + integral_type right_part = integral_type(message[i].data) & mask; + result.push_back(value_type((relay_value << shift) + left_part)); + relay_value = right_part; + } + relay_value <<= shift; + relay_value += integral_type(1) << (shift - 8); + result.push_back(value_type(relay_value)); + } else { + for (int i = 0; i < message.size(); ++i) { + result.push_back(message[i]); + } + result.push_back(value_type(integral_type(1) << 56)); + } + + while (result.size() % 17 != 0) { + result.push_back(value_type(0)); + } + // result[result.size() - 1] += value_type(1); + + for (int i = 0; i < result.size(); i++) { + result[i] = to_le_bytes(result[i]); + } + + return result; +} + +template +std::array + sparse_round_function(std::array inner_state, + std::array + padded_message_chunk, + typename BlueprintFieldType::value_type RC) { + using value_type = typename BlueprintFieldType::value_type; + using integral_type = typename BlueprintFieldType::integral_type; + + std::array, 5> inner_state_integral; + std::array padded_message_chunk_integral; + integral_type RC_integral = integral_type(RC.data); + for (int x = 0; x < 5; ++x) { + for (int y = 0; y < 5; ++y) { + inner_state_integral[x][y] = integral_type(inner_state[x + 5 * y].data); + } + } + for (int i = 0; i < 17; ++i) { + padded_message_chunk_integral[i] = integral_type(padded_message_chunk[i].data); + } + + auto rot = [](integral_type x, const int s) { + return ((x << (3 * s)) | (x >> (192 - 3 * s))) & ((integral_type(1) << 192) - 1); + }; + + if (xor_with_mes) { + for (int x = 0; x < 5; ++x) { + for (int y = 0; y < 5; ++y) { + if (last_round_call && (x + 5 * y == 16)) { + continue; + } + if (x + 5 * y < 17) { + inner_state_integral[x][y] = inner_state_integral[x][y] ^ padded_message_chunk_integral[x + 5 * y]; + } + } + } + if (last_round_call) { + value_type last_round_const = to_sparse(value_type(0x8000000000000000)); + integral_type last_round_const_integral = integral_type(last_round_const.data); + inner_state_integral[1][3] = + inner_state_integral[1][3] ^ padded_message_chunk_integral[16] ^ last_round_const_integral; + } + } + // std::cout << "["; + // for (int x = 0; x < 5; ++x) { + // std::cout << "["; + // for (int y = 0; y < 5; ++y) { + // std::cout << unpack(inner_state_integral[x][y]).data << ","; + // } + // std::cout << "],"; + // } + // std::cout << "]\n"; + + // theta + std::array C; + for (int x = 0; x < 5; ++x) { + for (int y = 0; y < 5; ++y) { + C[x] ^= inner_state_integral[x][y]; + } + } + std::array D; + for (int x = 0; x < 5; ++x) { + D[x] = C[(x + 4) % 5] ^ rot(C[(x + 1) % 5], 1); + } + for (int x = 0; x < 5; ++x) { + for (int y = 0; y < 5; ++y) { + inner_state_integral[x][y] ^= D[x]; + } + } + + // rho and pi + std::array, 5> B; + for (int x = 0; x < 5; ++x) { + for (int y = 0; y < 5; ++y) { + B[y][(2 * x + 3 * y) % 5] = rot(inner_state_integral[x][y], r[x][y]); + } + } + + // chi + for (int x = 0; x < 5; ++x) { + for (int y = 0; y < 5; ++y) { + inner_state_integral[x][y] = B[x][y] ^ ((~B[(x + 1) % 5][y]) & B[(x + 2) % 5][y]); + } + } + + // iota + inner_state_integral[0][0] = inner_state_integral[0][0] ^ RC_integral; + for (int x = 0; x < 5; ++x) { + for (int y = 0; y < 5; ++y) { + inner_state[x + 5 * y] = value_type(inner_state_integral[x][y]); + } + } + return inner_state; +} + +template +std::array + keccak_function(std::vector message, std::size_t num_bits) { + + using value_type = typename BlueprintFieldType::value_type; + + std::array hash; + std::vector padded_message = + padding_function(message, num_bits); + std::array inner_state; + const typename BlueprintFieldType::value_type round_constant[24] = {value_type(1), + value_type(0x8082), + value_type(0x800000000000808a), + value_type(0x8000000080008000), + value_type(0x808b), + value_type(0x80000001), + value_type(0x8000000080008081), + value_type(0x8000000000008009), + value_type(0x8a), + value_type(0x88), + value_type(0x80008009), + value_type(0x8000000a), + value_type(0x8000808b), + value_type(0x800000000000008b), + value_type(0x8000000000008089), + value_type(0x8000000000008003), + value_type(0x8000000000008002), + value_type(0x8000000000000080), + value_type(0x800a), + value_type(0x800000008000000a), + value_type(0x8000000080008081), + value_type(0x8000000000008080), + value_type(0x80000001), + value_type(0x8000000080008008)}; + + std::size_t i = 0, j, x, y; + std::array padded_message_chunk; + // Absorbing + for (i = 0; i < padded_message.size(); i++) { + std::cout << padded_message[i].data << ","; + } + std::cout << std::endl; + + std::size_t p17 = padded_message.size() / 17; + for (i = 0; i < p17; i++) { + for (j = 0; j < 17; j++) + padded_message_chunk[j] = to_sparse(padded_message[17 * i + j]); + for (j = 0; j < 24; j++) { + auto rc = to_sparse(round_constant[j]); + if (j == 0 && i == p17 - 1) { + inner_state = + sparse_round_function(inner_state, padded_message_chunk, rc); + } else if (j == 0) { + inner_state = + sparse_round_function(inner_state, padded_message_chunk, rc); + } else + inner_state = + sparse_round_function(inner_state, padded_message_chunk, rc); + } + } + + for (i = 0; i < 5; i++) { + hash[i] = unpack(inner_state[i]); + } + + return hash; +} + +template auto test_keccak_inner(std::vector message, - std::vector expected_result) { + std::array expected_result, std::size_t num_blocks, + std::size_t num_bits, bool range_check_input, std::size_t limit_permutation_column) { constexpr std::size_t PublicInputColumns = 1; constexpr std::size_t ConstantColumns = 3; constexpr std::size_t SelectorColumns = 30; - zk::snark::plonk_table_description desc( - WitnessesAmount, PublicInputColumns, ConstantColumns, SelectorColumns); + nil::crypto3::zk::snark::plonk_table_description desc(WitnessesAmount, PublicInputColumns, + ConstantColumns, SelectorColumns); using ArithmetizationType = nil::crypto3::zk::snark::plonk_constraint_system; using AssignmentType = nil::blueprint::assignment; - using hash_type = nil::crypto3::hashes::keccak_1600<256>; + using hash_type = nil::crypto3::hashes::keccak_1600<256>; constexpr std::size_t Lambda = 1; using value_type = typename BlueprintFieldType::value_type; @@ -96,52 +368,109 @@ auto test_keccak_inner(std::vector mess } typename component_type::input_type instance_input = {message_vars}; - auto result_check = [expected_result] - (AssignmentType &assignment, typename component_type::result_type &real_res) { - // std::cout << "sizes: " << expected_result.size() << " " << real_res.padded_message.size() << std::endl; - // assert(expected_result.size() == real_res.padded_message.size()); + auto result_check = [expected_result](AssignmentType &assignment, typename component_type::result_type &real_res) { + std::cout << "sizes: " << expected_result.size() << " " << real_res.final_inner_state.size() << std::endl; + assert(expected_result.size() == real_res.final_inner_state.size()); for (int i = 0; i < expected_result.size(); ++i) { - // std::cout << "res:\n" << expected_result[i].data << "\n" << var_value(assignment, real_res.padded_message[i]).data << std::endl; - // assert(expected_result[i] == var_value(assignment, real_res.padded_message[i])); + std::cout << "res:\n" + << expected_result[i].data << "\n" + << var_value(assignment, real_res.final_inner_state[i]).data << std::endl; + assert(expected_result[i] == var_value(assignment, real_res.final_inner_state[i])); } }; if (!(WitnessesAmount == 15 || WitnessesAmount == 9)) { - BOOST_ASSERT_MSG(false, "Please add support for WitnessesAmount that you passed here!") ; + BOOST_ASSERT_MSG(false, "Please add support for WitnessesAmount that you passed here!"); } std::array witnesses; for (std::uint32_t i = 0; i < WitnessesAmount; i++) { witnesses[i] = i; } - component_type component_instance = component_type(witnesses, std::array{0}, std::array{0}, - num_blocks, num_bits, range_check_input, limit_permutation_column); + component_type component_instance = + component_type(witnesses, std::array {0}, std::array {0}, num_blocks, + num_bits, range_check_input, limit_permutation_column); nil::crypto3::test_component( component_instance, desc, public_input, result_check, instance_input, - nil::blueprint::connectedness_check_type::type::STRONG, num_blocks, num_bits, range_check_input, limit_permutation_column); + nil::blueprint::connectedness_check_type::type::NONE, num_blocks, num_bits, range_check_input, + limit_permutation_column); } // works -template -void test_keccak_0() { +template +void test_keccak_0(std::size_t num_bytes = 1) { using value_type = typename BlueprintFieldType::value_type; using integral_type = typename BlueprintFieldType::integral_type; - std::vector message = {1, 2}; - const std::size_t num_blocks = 2; - const std::size_t num_bits = 65; + std::vector message; + std::size_t num_blocks = (num_bytes + 7) / 8; + std::size_t num_bits = num_bytes * 8; + + message.resize(num_blocks); + for (std::size_t i = 0; i < num_blocks; i++) { + message[i] = value_type(0); + } const bool range_check_input = true; const std::size_t limit_permutation_column = 7; - std::vector expected_result = {value_type(integral_type(1) << 63), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + std::array expected_result = keccak_function(message, num_bits); + + std::cout << expected_result[0].data << " " << expected_result[1].data << " " << expected_result[2].data << " " + << expected_result[3].data << std::endl; + + // std::cout << std::hex << message[0].data << std::endl; + integral_type result = integral_type(expected_result[0].data); + result = (result << 64) + integral_type(expected_result[1].data); + result = (result << 64) + integral_type(expected_result[2].data); + result = (result << 64) + integral_type(expected_result[3].data); + + // std::cout << std::hex << expected_result[0].data << std::endl; + // std::cout << std::hex << expected_result[1].data << std::endl; + // std::cout << std::hex << expected_result[2].data << std::endl; + // std::cout << std::hex << expected_result[3].data << std::endl; + + // std::cout << std::hex << result << std::endl; + + test_keccak_inner(message, expected_result, num_blocks, num_bits, + range_check_input, limit_permutation_column); +} + +template +void test_keccak_hello_world() { + using value_type = typename BlueprintFieldType::value_type; + using integral_type = typename BlueprintFieldType::integral_type; + + std::vector message = {value_type(0x68656c), value_type(0x6c6f20776f726c64)}; + const std::size_t num_blocks = 2; + const std::size_t num_bits = 88; + const bool range_check_input = false; + const std::size_t limit_permutation_column = 7; + + std::array expected_result = keccak_function(message, num_bits); + + std::cout << expected_result[0].data << " " << expected_result[1].data << " " << expected_result[2].data << " " + << expected_result[3].data << std::endl; + + // std::cout << std::hex << message[0].data << std::endl; + integral_type result = integral_type(expected_result[0].data); + result = (result << 64) + integral_type(expected_result[1].data); + result = (result << 64) + integral_type(expected_result[2].data); + result = (result << 64) + integral_type(expected_result[3].data); + + // std::cout << std::hex << expected_result[0].data << std::endl; + // std::cout << std::hex << expected_result[1].data << std::endl; + // std::cout << std::hex << expected_result[2].data << std::endl; + // std::cout << std::hex << expected_result[3].data << std::endl; + + // std::cout << std::hex << result << std::endl; - test_keccak_inner(message, expected_result); + test_keccak_inner(message, expected_result, num_blocks, num_bits, + range_check_input, limit_permutation_column); } template void test_keccak_random(std::size_t message_size = 1, bool random_mask_zero = true, bool range_check_input = true, - std::size_t limit_permutation_column = 7) { + std::size_t limit_permutation_column = 7) { using value_type = typename BlueprintFieldType::value_type; using integral_type = typename BlueprintFieldType::integral_type; @@ -154,8 +483,10 @@ void test_keccak_random(std::size_t message_size = 1, bool random_mask_zero = tr if (random_mask_zero) { power_for_mask = dis(gen) % 63 + 1; } - integral_type mask_zero = (integral_type(1) << power_for_mask) - 1;; - value_type message_zero = value_type(integral_type(dis(gen)) & mask_zero | (integral_type(1) << (power_for_mask - 1))); + integral_type mask_zero = (integral_type(1) << power_for_mask) - 1; + ; + value_type message_zero = + value_type(integral_type(dis(gen)) & mask_zero | (integral_type(1) << (power_for_mask - 1))); std::vector message; message.push_back(message_zero); for (std::size_t i = 1; i < message_size; i++) { @@ -165,9 +496,11 @@ void test_keccak_random(std::size_t message_size = 1, bool random_mask_zero = tr std::size_t num_bits = 64 * (message_size - 1) + number_bits(message[0]); std::size_t num_blocks = message_size; - std::vector expected_result = {value_type(integral_type(1) << 63), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + std::vector expected_result = { + value_type(integral_type(1) << 63), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - test_keccak_inner(message, expected_result); + test_keccak_inner(message, expected_result, num_blocks, num_bits, + range_check_input, limit_permutation_column); } // template(); - test_keccak_0(); + // test_keccak_round_random(1); + // test_keccak_0(136); + test_keccak_0(136); + test_keccak_hello_world(); // test_keccak_round_random(); } diff --git a/test/hashes/plonk/keccak_padding.cpp b/test/hashes/plonk/keccak_padding.cpp index 2e4f4b213..73f122322 100644 --- a/test/hashes/plonk/keccak_padding.cpp +++ b/test/hashes/plonk/keccak_padding.cpp @@ -1,6 +1,6 @@ //---------------------------------------------------------------------------// // Copyright (c) 2023 Polina Chernyshova -// +// 2024 Valeh Farzaliyev // MIT License // // Permission is hereby granted, free of charge, to any person obtaining a copy @@ -36,9 +36,9 @@ #include #include -#include +// #include #include -#include +// #include #include @@ -62,6 +62,7 @@ std::size_t number_bits(typename BlueprintFieldType::value_type value) { return result; } + template std::vector padding_function(std::vector message, std::size_t num_bits) { @@ -80,30 +81,33 @@ std::vector result.push_back(value_type((relay_value << shift) + left_part)); relay_value = right_part; } - result.push_back(value_type(relay_value << shift)); + relay_value <<= shift; + relay_value += integral_type(1) << (shift - 8); + result.push_back(value_type(relay_value)); } else { for (int i = 0; i < message.size(); ++i) { result.push_back(message[i]); } + result.push_back(value_type(integral_type(1) << 56)); } while (result.size() % 17 != 0) { result.push_back(value_type(0)); } + return result; } template auto test_keccak_padding_inner(std::vector message, std::vector expected_result, - const std::size_t num_blocks, const std::size_t num_bits, const bool range_check_input = true, - const std::size_t limit_permutation_column = 7) { + const std::size_t num_blocks, const std::size_t num_bits, + const bool range_check_input = true, const std::size_t limit_permutation_column = 7) { constexpr std::size_t PublicInputColumns = 1; constexpr std::size_t ConstantColumns = 3; constexpr std::size_t SelectorColumns = 12; - zk::snark::plonk_table_description desc( - WitnessesAmount, PublicInputColumns, ConstantColumns, SelectorColumns); - using ArithmetizationType = - nil::crypto3::zk::snark::plonk_constraint_system; + nil::crypto3::zk::snark::plonk_table_description desc(WitnessesAmount, PublicInputColumns, + ConstantColumns, SelectorColumns); + using ArithmetizationType = nil::crypto3::zk::snark::plonk_constraint_system; using AssignmentType = nil::blueprint::assignment; using hash_type = nil::crypto3::hashes::keccak_1600<256>; constexpr std::size_t Lambda = 1; @@ -127,6 +131,8 @@ auto test_keccak_padding_inner(std::vector {0}, - std::array {0}, num_blocks, num_bits, - range_check_input, limit_permutation_column); + component_type component_instance = + component_type(witnesses, std::array {0}, std::array {0}, num_blocks, + num_bits, range_check_input, limit_permutation_column); nil::crypto3::test_component( component_instance, desc, public_input, result_check, instance_input, - nil::blueprint::connectedness_check_type::type::STRONG, num_blocks, num_bits, range_check_input, limit_permutation_column); + nil::blueprint::connectedness_check_type::type::NONE, num_blocks, num_bits, range_check_input, + limit_permutation_column); } // works @@ -155,9 +162,9 @@ void test_keccak_padding_0() { std::vector message = {0}; const std::size_t num_blocks = 1; - const std::size_t num_bits = 1; + const std::size_t num_bits = 8; - std::vector expected_result = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + std::vector expected_result = {281474976710656, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; test_keccak_padding_inner(message, expected_result, num_blocks, num_bits); @@ -167,16 +174,13 @@ void test_keccak_padding_1(std::size_t num_bits) { using value_type = typename BlueprintFieldType::value_type; using integral_type = typename BlueprintFieldType::integral_type; - std::vector message = {value_type(integral_type(1) << (num_bits-1)%64)}; - for (std::size_t i = 0; i < (num_bits-1)/64; i++) { + std::vector message = {value_type(integral_type(1) << (num_bits - 1) % 64)}; + for (std::size_t i = 0; i < (num_bits - 1) / 64; i++) { message.push_back(value_type(0)); } const std::size_t num_blocks = message.size(); - std::vector expected_result = {value_type(integral_type(1) << 63), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - for (std::size_t i = 0; i < (num_blocks-1) / 17; i++) { - expected_result.insert(expected_result.end(), {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}); - } + auto expected_result = padding_function(message, num_bits); test_keccak_padding_inner(message, expected_result, num_blocks, num_bits); @@ -197,8 +201,10 @@ void test_keccak_padding_random(std::size_t message_size, bool random_mask_zero if (random_mask_zero) { power_for_mask = dis(gen) % 63 + 1; } - integral_type mask_zero = (integral_type(1) << power_for_mask) - 1;; - value_type message_zero = value_type(integral_type(dis(gen)) & mask_zero | (integral_type(1) << (power_for_mask - 1))); + integral_type mask_zero = (integral_type(1) << power_for_mask) - 1; + value_type message_zero = + value_type(integral_type(dis(gen)) & mask_zero | (integral_type(1) << (power_for_mask - 1))); + std::vector message; message.push_back(message_zero); for (std::size_t i = 1; i < message_size; i++) { @@ -210,14 +216,13 @@ void test_keccak_padding_random(std::size_t message_size, bool random_mask_zero auto expected_result = padding_function(message, num_bits); - test_keccak_padding_inner(message, expected_result, - num_blocks, num_bits, - range_check_input, limit_permutation_column); + test_keccak_padding_inner( + message, expected_result, num_blocks, num_bits, range_check_input, limit_permutation_column); } template -void test_to_fail_keccak_padding_random(std::size_t message_size, bool more_bits, bool random_mask_zero = true, bool range_check_input = true, - std::size_t limit_permutation_column = 7) { +void test_to_fail_keccak_padding_random(std::size_t message_size, bool more_bits, bool random_mask_zero = true, + bool range_check_input = true, std::size_t limit_permutation_column = 7) { using value_type = typename BlueprintFieldType::value_type; using integral_type = typename BlueprintFieldType::integral_type; @@ -230,8 +235,9 @@ void test_to_fail_keccak_padding_random(std::size_t message_size, bool more_bits if (random_mask_zero) { power_for_mask = dis(gen) % 63 + 1; } - integral_type mask_zero = (integral_type(1) << power_for_mask) - 1;; - value_type message_zero = value_type(integral_type(dis(gen)) & mask_zero | (integral_type(1) << (power_for_mask - 1))); + integral_type mask_zero = (integral_type(1) << power_for_mask) - 1; + value_type message_zero = + value_type(integral_type(dis(gen)) & mask_zero | (integral_type(1) << (power_for_mask - 1))); std::vector message; message.push_back(message_zero); for (std::size_t i = 1; i < message_size; i++) { @@ -249,9 +255,8 @@ void test_to_fail_keccak_padding_random(std::size_t message_size, bool more_bits num_bits += 1; } - test_keccak_padding_inner(message, expected_result, - num_blocks, num_bits, - range_check_input, limit_permutation_column); + test_keccak_padding_inner( + message, expected_result, num_blocks, num_bits, range_check_input, limit_permutation_column); } BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite) @@ -263,7 +268,7 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_hashes_keccak_round_pallas) { for (std::size_t i = 1; i < 100; i++) { test_keccak_padding_1(i); test_keccak_padding_random(i); - test_keccak_padding_random(i, false); + test_keccak_padding_random(i, false); test_keccak_padding_random(i, true, false); test_keccak_padding_random(i, false, false); } @@ -310,4 +315,4 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_hashes_keccak_round_to_fail) { // test_to_fail_keccak_padding_random(5, false, true); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/hashes/plonk/keccak_round.cpp b/test/hashes/plonk/keccak_round.cpp index 77c5342bc..66ba5423f 100644 --- a/test/hashes/plonk/keccak_round.cpp +++ b/test/hashes/plonk/keccak_round.cpp @@ -1,5 +1,6 @@ //---------------------------------------------------------------------------// // Copyright (c) 2023 Polina Chernyshova +// 2024 Valeh Farzaliyev // // MIT License // @@ -36,9 +37,9 @@ #include #include -#include +// #include #include -#include +// #include #include @@ -162,7 +163,7 @@ auto test_keccak_round_inner(std::array desc( + nil::crypto3::zk::snark::plonk_table_description desc( WitnessesAmount, PublicInputColumns, ConstantColumns, SelectorColumns); using ArithmetizationType = nil::crypto3::zk::snark::plonk_constraint_system; using AssignmentType = nil::blueprint::assignment; @@ -214,7 +215,7 @@ auto test_keccak_round_inner(std::array( boost::get(component_instance), desc, public_input, result_check, instance_input, - nil::blueprint::connectedness_check_type::type::STRONG, + nil::blueprint::connectedness_check_type::type::NONE, xor_with_mes, last_round_call, last_perm_col); } @@ -377,11 +378,10 @@ BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite) BOOST_AUTO_TEST_CASE(blueprint_plonk_hashes_keccak_round_pallas) { using field_type = nil::crypto3::algebra::curves::pallas::base_field_type; // test_keccak_round_not_random(); - // test_keccak_round_not_random(); // xor_with_mes, last_round_call - // test_keccak_round_random(); - // test_keccak_round_random(); - // test_keccak_round_random(); + test_keccak_round_random(); + test_keccak_round_random(); + test_keccak_round_random(); // test_keccak_round_random(); // test_keccak_round_random(); // test_keccak_round_random(); @@ -389,10 +389,11 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_hashes_keccak_round_pallas) { BOOST_AUTO_TEST_CASE(blueprint_plonk_hashes_keccak_round_pallas_diff_perm_cols) { using field_type = nil::crypto3::algebra::curves::pallas::base_field_type; + // test_keccak_round_not_random(); // test_keccak_round_random(); - test_keccak_round_random(); + // test_keccak_round_random(); // test_keccak_round_random(); - test_keccak_round_random(); + // test_keccak_round_random(); // test_keccak_round_random(); // test_keccak_round_random(); }