From c86cba537bfd93399d6a9c8ab36032a3a258afbd Mon Sep 17 00:00:00 2001 From: Iluvmagick Date: Tue, 21 Nov 2023 16:12:15 +0400 Subject: [PATCH] Added a proper private input extractor. --- .github/workflows/run_tests.yml | 1 + .../nil/blueprint/private_input_extractor.hpp | 90 +++++++++++++++++++ test/CMakeLists.txt | 1 + test/private_input_extractor.cpp | 74 +++++++++++++++ 4 files changed, 166 insertions(+) create mode 100644 include/nil/blueprint/private_input_extractor.hpp create mode 100644 test/private_input_extractor.cpp diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index a81b58081..613aa4a51 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -80,6 +80,7 @@ jobs: blueprint_verifiers_placeholder_gate_component_test, blueprint_proxy_test blueprint_mock_mocked_components_test + blueprint_private_input_extractor_test ] # Tests to execute include: # Abused to enable proof generation for some tests; add more as needed - target: blueprint_algebra_fields_plonk_non_native_logic_ops_test diff --git a/include/nil/blueprint/private_input_extractor.hpp b/include/nil/blueprint/private_input_extractor.hpp new file mode 100644 index 000000000..301466cc4 --- /dev/null +++ b/include/nil/blueprint/private_input_extractor.hpp @@ -0,0 +1,90 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2023 Dmitrii Tabalin +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_BLUEPRINT_PRIVATE_INPUT_EXTRACTOR_HPP +#define CRYPTO3_BLUEPRINT_PRIVATE_INPUT_EXTRACTOR_HPP + +#include +#include + +#include +#include +#include + +namespace nil { + namespace blueprint { + // So you want to figure out where a variable you pass into the component actually gets assigned to? + // Congratulations! You've come to the right place. You can do that in just 5 easy steps! + // Note that step 2 and 5 are IMPORTANT, and you SHOULD read them! + // Step 1: Instantiate your component. + // Step 2: Fill the input variables you want to assign to with distinct variables. + // IMPORTANT: the variables you want to assign to MUST be distinct from all others! + // They also MUST be outside of the component! + // ENSURE that they are not the same as the default variable (var(0, 0, false, witness)), + // (or fill all of the input values) + // E.g. you could make the variable to have very large witness column number. + // The variable CANNOT be with the legacy private input index: copy constraints + // would not generate for it and it would not be found. + // Step 3: Call input_assignment_variables with the component, the input and the row at which the component + // is going to be based. + // Step 4: The map you got in return maps the variables from instance_input to the variables from the + // component. + // Step 5: IMPORTANT! Be sure to check that the variable is in the map before assinging to it. + // In rare situations the variable might turn out to be unused. + // The map would not contain the variable in this case. + template + std::unordered_map< + crypto3::zk::snark::plonk_variable, + crypto3::zk::snark::plonk_variable> input_assignment_variables( + const ComponentType &component, + const crypto3::zk::snark::plonk_table_description &desc, + typename ComponentType::input_type instance_input, + const std::size_t start_row_index) { + + using constraint_system = crypto3::zk::snark::plonk_constraint_system; + using var = crypto3::zk::snark::plonk_variable; + + circuit bp; + assignment assignment(desc); + generate_copy_constraints(component, bp, assignment, instance_input, start_row_index); + auto input_vars = instance_input.all_vars(); + std::unordered_set input_vars_set(input_vars.begin(), input_vars.end()); + + std::unordered_map result; + for (const auto ©_constraint : bp.copy_constraints()) { + auto &var1 = copy_constraint.first, + &var2 = copy_constraint.second; + if (input_vars_set.find(var1) != input_vars_set.end()) { + result[var1] = var2; + } + if (input_vars_set.find(var2) != input_vars_set.end()) { + result[var2] = var1; + } + } + return result; + } + } // namespace blueprint +} // namespace nil + +#endif // CRYPTO3_BLUEPRINT_PRIVATE_INPUT_EXTRACTOR_HPP \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e24e14030..046af5b48 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -56,6 +56,7 @@ set(COMMON_TEST_FILES "gate_id" "utils/connectedness_check" "private_input" + "private_input_extractor" "proxy" "mock/mocked_components" ) diff --git a/test/private_input_extractor.cpp b/test/private_input_extractor.cpp new file mode 100644 index 000000000..3a5b16180 --- /dev/null +++ b/test/private_input_extractor.cpp @@ -0,0 +1,74 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2023 Dmitrii Tabalin +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#define BOOST_TEST_MODULE blueprint_private_input_extractor_test + +#include + +#include + +#include +#include + +#include +#include +#include + +#include + +#include "test_plonk_component.hpp" + +using namespace nil; + + +BOOST_AUTO_TEST_CASE(blueprint_plonk_private_input_test) { + using field_type = typename crypto3::algebra::curves::pallas::base_field_type; + constexpr std::size_t WitnessColumns = 3; + constexpr std::size_t PublicInputColumns = 1; + constexpr std::size_t ConstantColumns = 0; + constexpr std::size_t SelectorColumns = 1; + using ArithmetizationType = crypto3::zk::snark::plonk_constraint_system; + zk::snark::plonk_table_description desc( + WitnessColumns, PublicInputColumns, ConstantColumns, SelectorColumns); + + using var = crypto3::zk::snark::plonk_variable; + + using component_type = blueprint::components::addition>; + + typename component_type::input_type instance_input = { + var(0, 0, false, var::column_type::public_input), + var(0, 1, false, var::column_type::public_input) + }; + + component_type component_instance({0, 1, 2}, {}, {}); + + auto unopt = nil::blueprint::input_assignment_variables( + component_instance, desc, instance_input, 3); + BOOST_ASSERT(unopt.size() == 2); + BOOST_ASSERT(unopt.count(instance_input.x) == 1); + BOOST_ASSERT(unopt.count(instance_input.y) == 1); + BOOST_ASSERT(unopt[instance_input.x] == var(0, 3, false, var::column_type::witness)); + BOOST_ASSERT(unopt[instance_input.y] == var(1, 3, false, var::column_type::witness)); +}