From 425448634b06e3003efc1d95bd9bedc1576401a6 Mon Sep 17 00:00:00 2001 From: nkaskov Date: Mon, 22 Nov 2021 16:58:28 +0300 Subject: [PATCH] PLONK blueprint updated. #16 --- .../algebra/curves/plonk/addition.hpp | 21 ++- .../nil/crypto3/zk/components/blueprint.hpp | 69 ++------ .../blueprint_linear_combination.hpp | 1 + .../blueprint_non_linear_combination.hpp | 167 ++++++++++++++++++ .../zk/components/blueprint_variable.hpp | 14 +- .../zk/components/hashes/plonk/sha256.hpp | 75 ++++++++ 6 files changed, 289 insertions(+), 58 deletions(-) create mode 100644 include/nil/crypto3/zk/components/blueprint_non_linear_combination.hpp create mode 100644 include/nil/crypto3/zk/components/hashes/plonk/sha256.hpp diff --git a/include/nil/crypto3/zk/components/algebra/curves/plonk/addition.hpp b/include/nil/crypto3/zk/components/algebra/curves/plonk/addition.hpp index 9f02583eb..ac51e378c 100644 --- a/include/nil/crypto3/zk/components/algebra/curves/plonk/addition.hpp +++ b/include/nil/crypto3/zk/components/algebra/curves/plonk/addition.hpp @@ -53,13 +53,20 @@ namespace nil { } void generate_r1cs_constraints() { - typename blueprint_type::variable_type x_1(W0, i); - typename blueprint_type::variable_type y_1(W1, i); - typename blueprint_type::variable_type x_2(W2, i); - typename blueprint_type::variable_type y_2(W3, i); - typename blueprint_type::variable_type x_3(W4, i); - typename blueprint_type::variable_type y_3(W5, i); - typename blueprint_type::variable_type r(W6, i); + typename blueprint_type::variable_type x_1(W0, + blueprint_type::variable_type::rotation_type::current); + typename blueprint_type::variable_type y_1(W1, + blueprint_type::variable_type::rotation_type::current); + typename blueprint_type::variable_type x_2(W2, + blueprint_type::variable_type::rotation_type::current); + typename blueprint_type::variable_type y_2(W3, + blueprint_type::variable_type::rotation_type::current); + typename blueprint_type::variable_type x_3(W4, + blueprint_type::variable_type::rotation_type::current); + typename blueprint_type::variable_type y_3(W5, + blueprint_type::variable_type::rotation_type::current); + typename blueprint_type::variable_type r(W6, + blueprint_type::variable_type::rotation_type::current); bp.add_gate(i, (x_2 - x_1)*(y_1 + y_3) - (y_1 - y_2)*(x_1 - x_3)); bp.add_gate(i, (x_1 + x_2 + x_3)*(x_1 - x_3)^2 - (y_1 + y_3)^2 ); diff --git a/include/nil/crypto3/zk/components/blueprint.hpp b/include/nil/crypto3/zk/components/blueprint.hpp index 71a7eb058..bac73aa27 100644 --- a/include/nil/crypto3/zk/components/blueprint.hpp +++ b/include/nil/crypto3/zk/components/blueprint.hpp @@ -157,78 +157,54 @@ namespace nil { } }; - template - class blueprint , TBlueprintField>{ - std::vector> values; - - typename TBlueprintField::value_type constant_term; - std::vector::index_type> next_free_vars; + template + class blueprint , TBlueprintField>{ + snark::plonk_variable_assignment assignments; - snark::plonk_constraint_system constraint_system; + snark::plonk_constraint_system constraint_system; public: - // typedef TBlueprintField field_type; blueprint(): next_free_vars(){ - constant_term = TBlueprintField::value_type::one(); - next_free_vars.push_back(1); /* to account for constant 1 term */ } - void clear_values() { - for (auto iter = values.begin(); iter != values.end(); iter++){ + void clear_assignments() { + for (auto iter = assignments.begin(); iter != assignments.end(); iter++){ std::fill(iter->begin(), iter->end(), TBlueprintField::value_type::zero()); } } - typename TBlueprintField::value_type &val(const blueprint_variable &var, std::size_t row_index) { - assert(row_index < values.size()); - assert(var.index <= values[row_index].size()); - return (var.index == 0 ? constant_term : values[row_index][var.index - 1]); + typename TBlueprintField::value_type &assignment(const blueprint_variable &var, std::size_t row_index) { + assert(row_index < assignments.size()); + assert(var.index <= assignments[row_index].size()); + return (assignments[row_index][var.index]); } - typename TBlueprintField::value_type val(const blueprint_variable &var, std::size_t row_index) const { - assert(row_index < values.size()); - assert(var.index <= values[row_index].size()); - return (var.index == 0 ? constant_term : values[row_index][var.index - 1]); + typename TBlueprintField::value_type assignment(const blueprint_variable &var, std::size_t row_index) const { + assert(row_index < assignments.size()); + assert(var.index <= assignments[row_index].size()); + return (assignments[row_index][var.index - 1]); - void add_constraint(const snark::plonk_constraint &constr) { + void add_gate(const snark::plonk_constraint &constr) { constraint_system.constraints.emplace_back(constr); } bool is_satisfied() const { - return constraint_system.is_satisfied(primary_input(), auxiliary_input()); + return constraint_system.is_satisfied(assignments); } std::size_t num_constraints() const { return constraint_system.num_constraints(); } - std::size_t num_inputs() const { - return constraint_system.num_inputs(); - } - - std::size_t num_variables(std::size_t row_index) const { - return next_free_vars[row_index] - 1; - } - - void set_input_sizes(const std::size_t primary_input_size) { - assert(primary_input_size <= num_variables()); - constraint_system.primary_input_size = primary_input_size; - constraint_system.auxiliary_input_size = num_variables() - primary_input_size; + constexpr std::size_t num_wires() { + return WiresAmount; } snark::plonk_variable_assignment full_variable_assignment() const { - return values; - } - - snark::plonk_primary_input primary_input() const { - return snark::plonk_primary_input(values.begin(), values.begin() + num_inputs()); - } - - snark::plonk_auxiliary_input auxiliary_input() const { - return snark::plonk_auxiliary_input(values.begin() + num_inputs(), values.end()); + return assignments; } snark::plonk_constraint_system get_constraint_system() const { @@ -236,13 +212,6 @@ namespace nil { } friend class blueprint_variable; - - private: - typename snark::variable::index_type allocate_var_index(std::size_t row_index) { - ++constraint_system.auxiliary_input_size; - values.emplace_back(TBlueprintField::value_type::zero()); - return next_free_vars[row_index]++; - } }; } // namespace components } // namespace zk diff --git a/include/nil/crypto3/zk/components/blueprint_linear_combination.hpp b/include/nil/crypto3/zk/components/blueprint_linear_combination.hpp index 327718acd..e3967d5ae 100644 --- a/include/nil/crypto3/zk/components/blueprint_linear_combination.hpp +++ b/include/nil/crypto3/zk/components/blueprint_linear_combination.hpp @@ -33,6 +33,7 @@ #include #include +#include namespace nil { namespace crypto3 { diff --git a/include/nil/crypto3/zk/components/blueprint_non_linear_combination.hpp b/include/nil/crypto3/zk/components/blueprint_non_linear_combination.hpp new file mode 100644 index 000000000..5cfe3a276 --- /dev/null +++ b/include/nil/crypto3/zk/components/blueprint_non_linear_combination.hpp @@ -0,0 +1,167 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2021 Mikhail Komarov +// Copyright (c) 2021 Nikita Kaskov +// +// 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_ZK_BLUEPRINT_NON_LINEAR_COMBINATION_HPP +#define CRYPTO3_ZK_BLUEPRINT_NON_LINEAR_COMBINATION_HPP + +#include + +#include +#include + +#include +#include + +namespace nil { + namespace crypto3 { + namespace zk { + namespace components { + + template + class blueprint; + + template + class blueprint_non_linear_combination; + + template + class blueprint_non_linear_combination, TBlueprintField> : + public snark::non_linear_combination { + typedef TBlueprintField field_type; + typedef typename field_type::value_type field_value_type; + + public: + + using index_type = std::size_t; + bool is_variable; + index_type index; + + blueprint_non_linear_combination() { + this->is_variable = false; + } + + blueprint_non_linear_combination(const blueprint_variable &var) { + this->is_variable = true; + this->index = var.index; + this->terms.emplace_back(snark::linear_term(var)); + } + + // template + // void evaluate(std::size_t row_index, blueprint &bp) const { + // if (this->is_variable) { + // return; // do nothing + // } + + // field_value_type sum = 0; + // for (auto term : this->terms) { + // sum += term.coeff * bp.val(blueprint_variable(term.index)); + // } + + // bp.lc_val(*this) = sum; + // } + + bool is_constant() const { + if (is_variable) { + return (index == 0); + } else { + for (auto term : this->terms) { + if (term.vars.size() != 0) { + return false; + } + } + + return true; + } + } + + field_value_type constant_term() const { + if (is_variable) { + return (index == 0 ? field_value_type::one() : field_value_type::zero()); + } else { + field_value_type result = field_value_type::zero(); + for (auto term : this->terms) { + if (term.index == 0) { + result += term.coeff; + } + } + return result; + } + } + }; + + template + class blueprint_non_linear_combination_vector + : private std::vector> { + + typedef TBlueprintField field_type; + typedef typename field_type::value_type field_value_type; + typedef std::vector> contents; + + public: + using typename contents::const_iterator; + using typename contents::const_reverse_iterator; + using typename contents::iterator; + using typename contents::reverse_iterator; + + using contents::begin; + using contents::emplace_back; + using contents::empty; + using contents::end; + using contents::insert; + using contents::rbegin; + using contents::rend; + using contents::reserve; + using contents::size; + using contents::operator[]; + using contents::resize; + + blueprint_non_linear_combination_vector() : contents() {}; + blueprint_non_linear_combination_vector(const blueprint_variable_vector &arr) { + for (auto &v : arr) + this->emplace_back(blueprint_non_linear_combination(v)); + }; + blueprint_non_linear_combination_vector(std::size_t count) : contents(count) {}; + blueprint_non_linear_combination_vector(std::size_t count, + const blueprint_non_linear_combination &value) : + contents(count, value) {}; + blueprint_non_linear_combination_vector(typename contents::const_iterator first, + typename contents::const_iterator last) : + contents(first, last) {}; + blueprint_non_linear_combination_vector(typename contents::const_reverse_iterator first, + typename contents::const_reverse_iterator last) : + contents(first, last) {}; + + template + void evaluate(blueprint &bp) const { + for (std::size_t i = 0; i < this->size(); ++i) { + (*this)[i].evaluate(bp); + } + } + }; + } // namespace components + } // namespace zk + } // namespace crypto3 +} // namespace nil + +#endif // CRYPTO3_ZK_BLUEPRINT_NON_LINEAR_COMBINATION_HPP diff --git a/include/nil/crypto3/zk/components/blueprint_variable.hpp b/include/nil/crypto3/zk/components/blueprint_variable.hpp index 39e93ef49..1951235f8 100644 --- a/include/nil/crypto3/zk/components/blueprint_variable.hpp +++ b/include/nil/crypto3/zk/components/blueprint_variable.hpp @@ -42,8 +42,12 @@ namespace nil { template class blueprint; + template + class blueprint_variable; + template - class blueprint_variable : public snark::variable { + class blueprint_variable, TBlueprintField> : + public snark::variable { public: blueprint_variable(const typename snark::variable::index_type index = 0) : snark::variable(index) {}; @@ -58,6 +62,14 @@ namespace nil { } }; + template + class blueprint_variable, TBlueprintField> : + public snark::variable { + public: + blueprint_variable(const wire_index_type wire_index, rotation_type rotation = rotation_type::current) : + snark::variable(index) {}; + }; + template class blueprint_variable_vector : private std::vector> { typedef typename TBlueprintField::value_type field_value_type; diff --git a/include/nil/crypto3/zk/components/hashes/plonk/sha256.hpp b/include/nil/crypto3/zk/components/hashes/plonk/sha256.hpp new file mode 100644 index 000000000..5f2aaa09b --- /dev/null +++ b/include/nil/crypto3/zk/components/hashes/plonk/sha256.hpp @@ -0,0 +1,75 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2021 Mikhail Komarov +// Copyright (c) 2021 Nikita Kaskov +// +// 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. +//---------------------------------------------------------------------------// +// @file Declaration of interfaces for auxiliary components for the SHA256 component. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_ZK_BLUEPRINT_PLONK_SHA256_HPP +#define CRYPTO3_ZK_BLUEPRINT_PLONK_SHA256_HPP + +#include +#include + +namespace nil { + namespace crypto3 { + namespace zk { + namespace components { + + template + class sha256_plonk_sigma_0 : public component { + typedef snark::plonk_constraint_system arithmetization_type; + public: + + range range_proof; + + sha256_plonk_sigma_0(blueprint &bp, + const std::array &w_indexes, + const ... &output) : + component(bp), range_proof(input, 2**32) { + + + + } + + void generate_r1cs_constraints(bool ensure_output_bitness = true) { // TODO: ignored for now + padding->generate_r1cs_constraints(); + for (auto f : blocks_components) { + f->generate_r1cs_constraints(); + } + } + + void generate_r1cs_witness() { + padding->generate_r1cs_witness(); + for (auto f : blocks_components) { + f->generate_r1cs_witness(); + } + } + }; + + } // namespace components + } // namespace zk + } // namespace crypto3 +} // namespace nil + +#endif // CRYPTO3_ZK_BLUEPRINT_PLONK_SHA256_HPP