Skip to content

Commit

Permalink
PLONK blueprint updated. #16
Browse files Browse the repository at this point in the history
  • Loading branch information
nkaskov committed Nov 22, 2021
1 parent 889ec71 commit 4254486
Show file tree
Hide file tree
Showing 6 changed files with 289 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand Down
69 changes: 19 additions & 50 deletions include/nil/crypto3/zk/components/blueprint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,92 +157,61 @@ namespace nil {
}
};

template<typename TBlueprintField>
class blueprint <snark::plonk_constraint_system<TBlueprintField>, TBlueprintField>{
std::vector<snark::plonk_variable_assignment<TBlueprintField>> values;

typename TBlueprintField::value_type constant_term;
std::vector<typename snark::variable<TBlueprintField>::index_type> next_free_vars;
template<typename TBlueprintField, std::size_t WiresAmount>
class blueprint <snark::plonk_constraint_system<TBlueprintField, WiresAmount>, TBlueprintField>{
snark::plonk_variable_assignment<TBlueprintField, WiresAmount> assignments;

snark::plonk_constraint_system<TBlueprintField> constraint_system;
snark::plonk_constraint_system<TBlueprintField, WiresAmount> 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<TBlueprintField> &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<TBlueprintField> &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<TBlueprintField> &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<TBlueprintField> &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<TBlueprintField> &constr) {
void add_gate(const snark::plonk_constraint<TBlueprintField> &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<TBlueprintField> full_variable_assignment() const {
return values;
}

snark::plonk_primary_input<TBlueprintField> primary_input() const {
return snark::plonk_primary_input<TBlueprintField>(values.begin(), values.begin() + num_inputs());
}

snark::plonk_auxiliary_input<TBlueprintField> auxiliary_input() const {
return snark::plonk_auxiliary_input<TBlueprintField>(values.begin() + num_inputs(), values.end());
return assignments;
}

snark::plonk_constraint_system<TBlueprintField> get_constraint_system() const {
return constraint_system;
}

friend class blueprint_variable<TBlueprintField>;

private:
typename snark::variable<TBlueprintField>::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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <nil/crypto3/multiprecision/number.hpp>

#include <nil/crypto3/zk/snark/relations/variable.hpp>
#include <nil/crypto3/zk/snark/relations/linear_combination.hpp>

namespace nil {
namespace crypto3 {
Expand Down
167 changes: 167 additions & 0 deletions include/nil/crypto3/zk/components/blueprint_non_linear_combination.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
//---------------------------------------------------------------------------//
// Copyright (c) 2021 Mikhail Komarov <nemo@nil.foundation>
// Copyright (c) 2021 Nikita Kaskov <nbering@nil.foundation>
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//---------------------------------------------------------------------------//

#ifndef CRYPTO3_ZK_BLUEPRINT_NON_LINEAR_COMBINATION_HPP
#define CRYPTO3_ZK_BLUEPRINT_NON_LINEAR_COMBINATION_HPP

#include <vector>

#include <nil/crypto3/multiprecision/integer.hpp>
#include <nil/crypto3/multiprecision/number.hpp>

#include <nil/crypto3/zk/snark/relations/variable.hpp>
#include <nil/crypto3/zk/snark/relations/non_linear_combination.hpp>

namespace nil {
namespace crypto3 {
namespace zk {
namespace components {

template<typename TArithmetization, typename TBlueprintField>
class blueprint;

template<typename TArithmetization, typename TBlueprintField>
class blueprint_non_linear_combination;

template<typename TBlueprintField>
class blueprint_non_linear_combination<snark::plonk_constraint_system<TBlueprintField>, TBlueprintField> :
public snark::non_linear_combination<TBlueprintField> {
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<field_type> &var) {
this->is_variable = true;
this->index = var.index;
this->terms.emplace_back(snark::linear_term<field_type>(var));
}

// template<typename TArithmetization>
// void evaluate(std::size_t row_index, blueprint<TArithmetization, field_type> &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<field_type>(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<typename TBlueprintField>
class blueprint_non_linear_combination_vector
: private std::vector<blueprint_non_linear_combination<TBlueprintField>> {

typedef TBlueprintField field_type;
typedef typename field_type::value_type field_value_type;
typedef std::vector<blueprint_non_linear_combination<field_type>> 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<field_type> &arr) {
for (auto &v : arr)
this->emplace_back(blueprint_non_linear_combination<field_type>(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<field_type> &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<typename TArithmetization>
void evaluate(blueprint<TArithmetization, field_type> &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
14 changes: 13 additions & 1 deletion include/nil/crypto3/zk/components/blueprint_variable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,12 @@ namespace nil {
template<typename TArithmetization, typename TBlueprintField>
class blueprint;

template<typename TArithmetization, typename TBlueprintField>
class blueprint_variable;

template<typename TBlueprintField>
class blueprint_variable : public snark::variable<TBlueprintField> {
class blueprint_variable<snark::r1cs_constraint_system<TBlueprintField>, TBlueprintField> :
public snark::variable<TBlueprintField, false> {
public:
blueprint_variable(const typename snark::variable<TBlueprintField>::index_type index = 0) :
snark::variable<TBlueprintField>(index) {};
Expand All @@ -58,6 +62,14 @@ namespace nil {
}
};

template<typename TBlueprintField>
class blueprint_variable<snark::plonk_constraint_system<TBlueprintField>, TBlueprintField> :
public snark::variable<TBlueprintField, true> {
public:
blueprint_variable(const wire_index_type wire_index, rotation_type rotation = rotation_type::current) :
snark::variable<TBlueprintField>(index) {};
};

template<typename TBlueprintField>
class blueprint_variable_vector : private std::vector<blueprint_variable<TBlueprintField>> {
typedef typename TBlueprintField::value_type field_value_type;
Expand Down
Loading

0 comments on commit 4254486

Please sign in to comment.