tbcs.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 //
5 // MIT License
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files (the "Software"), to deal
9 // in the Software without restriction, including without limitation the rights
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 // copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included in all
15 // copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 // SOFTWARE.
24 //---------------------------------------------------------------------------//
25 // @file Declaration of interfaces for:
26 // - a TBCS gate,
27 // - a TBCS variable assignment, and
28 // - a TBCS circuit.
29 //
30 // Above, TBCS stands for "Two-input Boolean Circuit Satisfiability".
31 //---------------------------------------------------------------------------//
32 
33 #ifndef CRYPTO3_ZK_TBCS_HPP
34 #define CRYPTO3_ZK_TBCS_HPP
35 
37 
38 namespace nil {
39  namespace crypto3 {
40  namespace zk {
41  namespace snark {
42 
43  /*********************** BACS variable assignment ****************************/
44 
48  typedef std::vector<bool> tbcs_variable_assignment;
49 
50  /**************************** TBCS gate **************************************/
51 
52  typedef std::size_t tbcs_wire_t;
53 
88  };
89 
90  static const int num_tbcs_gate_types = 16;
91 
103  struct tbcs_gate {
104 
107 
109 
111 
113 
114  bool evaluate(const tbcs_variable_assignment &input) const {
120  const bool X = (left_wire == 0 ? true : input[left_wire - 1]);
121  const bool Y = (right_wire == 0 ? true : input[right_wire - 1]);
122 
123  const std::size_t pos = 3 - ((X ? 2 : 0) + (Y ? 1 : 0)); /* 3 - ... inverts position */
124 
125  return (((int)type) & (1u << pos));
126  }
127 
128  bool operator==(const tbcs_gate &other) const {
129  return (this->left_wire == other.left_wire && this->right_wire == other.right_wire &&
130  this->type == other.type && this->output == other.output &&
131  this->is_circuit_output == other.is_circuit_output);
132  }
133  };
134 
135  /****************************** TBCS inputs **********************************/
136 
141 
146 
147  /************************** TBCS circuit *************************************/
148 
159  struct tbcs_circuit {
160 
161  std::size_t primary_input_size;
162  std::size_t auxiliary_input_size;
163  std::vector<tbcs_gate> gates;
164 
166  }
167 
168  std::size_t num_inputs() const {
170  }
171 
172  std::size_t num_gates() const {
173  return gates.size();
174  }
175 
176  std::size_t num_wires() const {
177  return num_inputs() + num_gates();
178  }
179 
180  std::vector<std::size_t> wire_depths() const {
181  std::vector<std::size_t> depths(num_inputs(), 1);
182 
183  for (auto &g : gates) {
184  depths.emplace_back(std::max(depths[g.left_wire], depths[g.right_wire]) + 1);
185  }
186 
187  return depths;
188  }
189 
190  std::size_t depth() const {
191  std::vector<std::size_t> all_depths = this->wire_depths();
192  return *(std::max_element(all_depths.begin(), all_depths.end()));
193  }
194 
195  bool is_valid() const {
196  for (std::size_t i = 0; i < num_gates(); ++i) {
201  if (gates[i].output != num_inputs() + i + 1) {
202  return false;
203  }
204 
208  if (gates[i].left_wire >= gates[i].output || gates[i].right_wire >= gates[i].output) {
209  return false;
210  }
211  }
212 
213  return true;
214  }
215 
216  bool is_satisfied(const tbcs_primary_input &primary_input,
217  const tbcs_auxiliary_input &auxiliary_input) const {
218  const tbcs_variable_assignment all_outputs = get_all_outputs(primary_input, auxiliary_input);
219  for (size_t i = 0; i < all_outputs.size(); ++i) {
220  if (all_outputs[i]) {
221  return false;
222  }
223  }
224 
225  return true;
226  }
227 
229  const tbcs_auxiliary_input &auxiliary_input) const {
230  assert(primary_input.size() == primary_input_size);
231  assert(auxiliary_input.size() == auxiliary_input_size);
232 
234  result.insert(result.end(), primary_input.begin(), primary_input.end());
235  result.insert(result.end(), auxiliary_input.begin(), auxiliary_input.end());
236 
237  assert(result.size() == num_inputs());
238 
239  for (auto &g : gates) {
240  const bool gate_output = g.evaluate(result);
241  result.push_back(gate_output);
242  }
243 
244  return result;
245  }
246 
248  const tbcs_auxiliary_input &auxiliary_input) const {
249  const tbcs_variable_assignment all_wires = get_all_wires(primary_input, auxiliary_input);
250  tbcs_variable_assignment all_outputs;
251 
252  for (auto &g : gates) {
253  if (g.is_circuit_output) {
254  all_outputs.push_back(all_wires[g.output - 1]);
255  }
256  }
257 
258  return all_outputs;
259  }
260 
261  void add_gate(const tbcs_gate &g) {
262  assert(g.output == num_wires() + 1);
263  gates.emplace_back(g);
264  }
265 
266  bool operator==(const tbcs_circuit &other) const {
267  return (this->primary_input_size == other.primary_input_size &&
268  this->auxiliary_input_size == other.auxiliary_input_size && this->gates == other.gates);
269  }
270  };
271 
272  } // namespace snark
273  } // namespace zk
274  } // namespace crypto3
275 } // namespace nil
276 
277 #endif // CRYPTO3_TBCS_HPP
constexpr T max(const vector< T, N > &v)
computes the maximum valued element
Definition: algebra/include/nil/crypto3/algebra/vector/math.hpp:146
tbcs_gate_type
Definition: tbcs.hpp:71
@ TBCS_GATE_NOT_X
Definition: tbcs.hpp:84
@ TBCS_GATE_EQUIVALENCE
Definition: tbcs.hpp:81
@ TBCS_GATE_IF_X_THEN_Y
Definition: tbcs.hpp:85
@ TBCS_GATE_CONSTANT_0
Definition: tbcs.hpp:72
@ TBCS_GATE_NOT_Y
Definition: tbcs.hpp:82
@ TBCS_GATE_OR
Definition: tbcs.hpp:79
@ TBCS_GATE_Y
Definition: tbcs.hpp:77
@ TBCS_GATE_XOR
Definition: tbcs.hpp:78
@ TBCS_GATE_NOT_X_AND_Y
Definition: tbcs.hpp:76
@ TBCS_GATE_AND
Definition: tbcs.hpp:73
@ TBCS_GATE_X_AND_NOT_Y
Definition: tbcs.hpp:74
@ TBCS_GATE_X
Definition: tbcs.hpp:75
@ TBCS_GATE_NOR
Definition: tbcs.hpp:80
@ TBCS_GATE_NAND
Definition: tbcs.hpp:86
@ TBCS_GATE_IF_Y_THEN_X
Definition: tbcs.hpp:83
@ TBCS_GATE_CONSTANT_1
Definition: tbcs.hpp:87
tbcs_variable_assignment tbcs_primary_input
Definition: tbcs.hpp:140
tbcs_variable_assignment tbcs_auxiliary_input
Definition: tbcs.hpp:145
std::size_t tbcs_wire_t
Definition: tbcs.hpp:52
std::vector< bool > tbcs_variable_assignment
Definition: tbcs.hpp:48
Definition: pair.hpp:31
std::size_t num_wires() const
Definition: tbcs.hpp:176
void add_gate(const tbcs_gate &g)
Definition: tbcs.hpp:261
bool is_satisfied(const tbcs_primary_input &primary_input, const tbcs_auxiliary_input &auxiliary_input) const
Definition: tbcs.hpp:216
bool is_valid() const
Definition: tbcs.hpp:195
std::size_t depth() const
Definition: tbcs.hpp:190
bool operator==(const tbcs_circuit &other) const
Definition: tbcs.hpp:266
tbcs_circuit()
Definition: tbcs.hpp:165
std::size_t num_inputs() const
Definition: tbcs.hpp:168
std::vector< std::size_t > wire_depths() const
Definition: tbcs.hpp:180
std::vector< tbcs_gate > gates
Definition: tbcs.hpp:163
tbcs_variable_assignment get_all_wires(const tbcs_primary_input &primary_input, const tbcs_auxiliary_input &auxiliary_input) const
Definition: tbcs.hpp:228
std::size_t primary_input_size
Definition: tbcs.hpp:161
std::size_t num_gates() const
Definition: tbcs.hpp:172
std::size_t auxiliary_input_size
Definition: tbcs.hpp:162
tbcs_variable_assignment get_all_outputs(const tbcs_primary_input &primary_input, const tbcs_auxiliary_input &auxiliary_input) const
Definition: tbcs.hpp:247
Definition: tbcs.hpp:103
bool is_circuit_output
Definition: tbcs.hpp:112
tbcs_wire_t right_wire
Definition: tbcs.hpp:106
bool operator==(const tbcs_gate &other) const
Definition: tbcs.hpp:128
tbcs_wire_t left_wire
Definition: tbcs.hpp:105
bool evaluate(const tbcs_variable_assignment &input) const
Definition: tbcs.hpp:114
tbcs_gate_type type
Definition: tbcs.hpp:108
tbcs_wire_t output
Definition: tbcs.hpp:110