blueprint.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2018-2021 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2020-2021 Nikita Kaskov <nbering@nil.foundation>
4 // Copyright (c) 2021 Noam Yemini <@NoamDev at GitHub>
5 //
6 // MIT License
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 // SOFTWARE.
25 //---------------------------------------------------------------------------//
26 
27 #ifndef CRYPTO3_ZK_BLUEPRINT_BLUEPRINT_HPP
28 #define CRYPTO3_ZK_BLUEPRINT_BLUEPRINT_HPP
29 
30 #include <algorithm>
31 #include <cassert>
32 #include <cstdio>
33 #include <string>
34 #include <vector>
35 
39 
40 namespace nil {
41  namespace crypto3 {
42  namespace zk {
43  namespace components {
44 
45  template<typename FieldType>
46  class blueprint {
47  snark::r1cs_variable_assignment<FieldType> values; /* values[0] will hold the value of the first
48  allocated variable of the blueprint, *NOT* constant 1 */
49  typename FieldType::value_type constant_term;
50 
51  typename snark::variable<FieldType>::index_type next_free_var;
52  lc_index_t next_free_lc;
53  std::vector<typename FieldType::value_type> lc_values;
55 
56  public:
57  typedef FieldType field_type;
58 
60  constant_term = FieldType::value_type::one();
61 
62  next_free_var = 1; /* to account for constant 1 term */
63  next_free_lc = 0;
64  }
65 
66  void clear_values() {
67  std::fill(values.begin(), values.end(), FieldType::value_type::zero());
68  }
69 
70  typename FieldType::value_type &val(const blueprint_variable<FieldType> &var) {
71  assert(var.index <= values.size());
72  return (var.index == 0 ? constant_term : values[var.index - 1]);
73  }
74 
75  typename FieldType::value_type val(const blueprint_variable<FieldType> &var) const {
76  assert(var.index <= values.size());
77  return (var.index == 0 ? constant_term : values[var.index - 1]);
78  }
79 
80  typename FieldType::value_type &lc_val(const blueprint_linear_combination<FieldType> &lc) {
81  if (lc.is_variable) {
82  return this->val(blueprint_variable<FieldType>(lc.index));
83  } else {
84  assert(lc.index < lc_values.size());
85  return lc_values[lc.index];
86  }
87  }
88 
89  typename FieldType::value_type lc_val(const blueprint_linear_combination<FieldType> &lc) const {
90  if (lc.is_variable) {
91  return this->val(blueprint_variable<FieldType>(lc.index));
92  } else {
93  assert(lc.index < lc_values.size());
94  return lc_values[lc.index];
95  }
96  }
97 
99  constraint_system.constraints.emplace_back(constr);
100  }
101 
102  bool is_satisfied() const {
103  return constraint_system.is_satisfied(primary_input(), auxiliary_input());
104  }
105 
106  std::size_t num_constraints() const {
107  return constraint_system.num_constraints();
108  }
109 
110  std::size_t num_inputs() const {
111  return constraint_system.num_inputs();
112  }
113 
114  std::size_t num_variables() const {
115  return next_free_var - 1;
116  }
117 
118  void set_input_sizes(const std::size_t primary_input_size) {
119  assert(primary_input_size <= num_variables());
120  constraint_system.primary_input_size = primary_input_size;
121  constraint_system.auxiliary_input_size = num_variables() - primary_input_size;
122  }
123 
125  return values;
126  }
127 
129  return snark::r1cs_primary_input<FieldType>(values.begin(), values.begin() + num_inputs());
130  }
131 
133  return snark::r1cs_auxiliary_input<FieldType>(values.begin() + num_inputs(), values.end());
134  }
135 
137  return constraint_system;
138  }
139 
140  friend class blueprint_variable<FieldType>;
141  friend class blueprint_linear_combination<FieldType>;
142 
143  private:
144  typename snark::variable<FieldType>::index_type allocate_var_index() {
145  ++constraint_system.auxiliary_input_size;
146  values.emplace_back(FieldType::value_type::zero());
147  return next_free_var++;
148  }
149 
150  lc_index_t allocate_lc_index() {
151  lc_values.emplace_back(FieldType::value_type::zero());
152  return next_free_lc++;
153  }
154  };
155  } // namespace components
156  } // namespace zk
157  } // namespace crypto3
158 } // namespace nil
159 #endif // CRYPTO3_ZK_BLUEPRINT_BLUEPRINT_HPP
Definition: blueprint_linear_combination.hpp:47
bool is_variable
Definition: blueprint_linear_combination.hpp:52
lc_index_t index
Definition: blueprint_linear_combination.hpp:53
Definition: blueprint_variable.hpp:46
Definition: blueprint.hpp:46
blueprint()
Definition: blueprint.hpp:59
void set_input_sizes(const std::size_t primary_input_size)
Definition: blueprint.hpp:118
snark::r1cs_primary_input< FieldType > primary_input() const
Definition: blueprint.hpp:128
FieldType::value_type & val(const blueprint_variable< FieldType > &var)
Definition: blueprint.hpp:70
void add_r1cs_constraint(const snark::r1cs_constraint< FieldType > &constr)
Definition: blueprint.hpp:98
snark::r1cs_constraint_system< FieldType > get_constraint_system() const
Definition: blueprint.hpp:136
std::size_t num_constraints() const
Definition: blueprint.hpp:106
snark::r1cs_variable_assignment< FieldType > full_variable_assignment() const
Definition: blueprint.hpp:124
FieldType field_type
Definition: blueprint.hpp:57
std::size_t num_inputs() const
Definition: blueprint.hpp:110
FieldType::value_type lc_val(const blueprint_linear_combination< FieldType > &lc) const
Definition: blueprint.hpp:89
std::size_t num_variables() const
Definition: blueprint.hpp:114
FieldType::value_type val(const blueprint_variable< FieldType > &var) const
Definition: blueprint.hpp:75
bool is_satisfied() const
Definition: blueprint.hpp:102
void clear_values()
Definition: blueprint.hpp:66
FieldType::value_type & lc_val(const blueprint_linear_combination< FieldType > &lc)
Definition: blueprint.hpp:80
snark::r1cs_auxiliary_input< FieldType > auxiliary_input() const
Definition: blueprint.hpp:132
constexpr matrix< T, N, M > fill(T value)
generates a matrix containing a single value
Definition: matrix/utility.hpp:102
std::size_t lc_index_t
Definition: blueprint_linear_combination.hpp:41
std::vector< typename FieldType::value_type > r1cs_auxiliary_input
Definition: r1cs.hpp:104
std::vector< typename FieldType::value_type > r1cs_primary_input
Definition: r1cs.hpp:101
std::vector< typename FieldType::value_type > r1cs_variable_assignment
Definition: r1cs.hpp:107
Definition: pair.hpp:31
bool is_satisfied(const r1cs_primary_input< FieldType > &primary_input, const r1cs_auxiliary_input< FieldType > &auxiliary_input) const
Definition: r1cs.hpp:162
std::vector< r1cs_constraint< FieldType > > constraints
Definition: r1cs.hpp:130
std::size_t num_constraints() const
Definition: r1cs.hpp:143
std::size_t primary_input_size
Definition: r1cs.hpp:127
std::size_t num_inputs() const
Definition: r1cs.hpp:135
std::size_t auxiliary_input_size
Definition: r1cs.hpp:128
index_type index
Definition: variable.hpp:69
std::size_t index_type
Definition: variable.hpp:68