Clearmatics Libsnark  0.1
C++ library for zkSNARK proofs
tbcs.cpp
Go to the documentation of this file.
1 
17 #include <algorithm>
18 #include <libff/common/utils.hpp>
20 
21 namespace libsnark
22 {
23 
25 {
31  const bool X = (left_wire == 0 ? true : input[left_wire - 1]);
32  const bool Y = (right_wire == 0 ? true : input[right_wire - 1]);
33 
34  // 3 - ... inverts position
35  const size_t pos = 3 - ((X ? 2 : 0) + (Y ? 1 : 0));
36 
37  return (((int)type) & (1u << pos));
38 }
39 
41  const tbcs_wire_t wire,
42  const std::map<size_t, std::string> &variable_annotations)
43 {
48  if (wire == 0) {
49  printf(" 1");
50  } else {
51  auto it = variable_annotations.find(wire);
52  printf(
53  " x_%zu (%s)",
54  wire,
55  (it == variable_annotations.end() ? "no annotation"
56  : it->second.c_str()));
57  }
58 }
59 
61  const std::map<size_t, std::string> &variable_annotations) const
62 {
63  switch (this->type) {
65  printf("CONSTANT_0");
66  break;
67  case TBCS_GATE_AND:
68  printf("AND");
69  break;
71  printf("X_AND_NOT_Y");
72  break;
73  case TBCS_GATE_X:
74  printf("X");
75  break;
77  printf("NOT_X_AND_Y");
78  break;
79  case TBCS_GATE_Y:
80  printf("Y");
81  break;
82  case TBCS_GATE_XOR:
83  printf("XOR");
84  break;
85  case TBCS_GATE_OR:
86  printf("OR");
87  break;
88  case TBCS_GATE_NOR:
89  printf("NOR");
90  break;
92  printf("EQUIVALENCE");
93  break;
94  case TBCS_GATE_NOT_Y:
95  printf("NOT_Y");
96  break;
98  printf("IF_Y_THEN_X");
99  break;
100  case TBCS_GATE_NOT_X:
101  printf("NOT_X");
102  break;
104  printf("IF_X_THEN_Y");
105  break;
106  case TBCS_GATE_NAND:
107  printf("NAND");
108  break;
110  printf("CONSTANT_1");
111  break;
112  default:
113  printf("Invalid type");
114  }
115 
116  printf("\n(\n");
117  print_tbcs_wire(left_wire, variable_annotations);
118  printf(",\n");
119  print_tbcs_wire(right_wire, variable_annotations);
120  printf("\n) ->\n");
121  print_tbcs_wire(output, variable_annotations);
122  printf(" (%s)\n", is_circuit_output ? "circuit output" : "internal wire");
123 }
124 
125 bool tbcs_gate::operator==(const tbcs_gate &other) const
126 {
127  return (
128  this->left_wire == other.left_wire &&
129  this->right_wire == other.right_wire && this->type == other.type &&
130  this->output == other.output &&
131  this->is_circuit_output == other.is_circuit_output);
132 }
133 
134 std::ostream &operator<<(std::ostream &out, const tbcs_gate &g)
135 {
136  out << g.left_wire << "\n";
137  out << g.right_wire << "\n";
138  out << (int)g.type << "\n";
139  out << g.output << "\n";
140  libff::output_bool(out, g.is_circuit_output);
141 
142  return out;
143 }
144 
145 std::istream &operator>>(std::istream &in, tbcs_gate &g)
146 {
147  in >> g.left_wire;
148  libff::consume_newline(in);
149  in >> g.right_wire;
150  libff::consume_newline(in);
151  int tmp;
152  in >> tmp;
153  g.type = (tbcs_gate_type)tmp;
154  libff::consume_newline(in);
155  in >> g.output;
156  libff::input_bool(in, g.is_circuit_output);
157 
158  return in;
159 }
160 
161 std::vector<size_t> tbcs_circuit::wire_depths() const
162 {
163  std::vector<size_t> depths(num_inputs(), 1);
164 
165  for (auto &g : gates) {
166  depths.emplace_back(
167  std::max(depths[g.left_wire], depths[g.right_wire]) + 1);
168  }
169 
170  return depths;
171 }
172 
174 {
176 }
177 
178 size_t tbcs_circuit::num_gates() const { return gates.size(); }
179 
180 size_t tbcs_circuit::num_wires() const { return num_inputs() + num_gates(); }
181 
182 size_t tbcs_circuit::depth() const
183 {
184  std::vector<size_t> all_depths = this->wire_depths();
185  return *(std::max_element(all_depths.begin(), all_depths.end()));
186 }
187 
189 {
190  for (size_t i = 0; i < num_gates(); ++i) {
195  if (gates[i].output != num_inputs() + i + 1) {
196  return false;
197  }
198 
202  if (gates[i].left_wire >= gates[i].output ||
203  gates[i].right_wire >= gates[i].output) {
204  return false;
205  }
206  }
207 
208  return true;
209 }
210 
212  const tbcs_primary_input &primary_input,
213  const tbcs_auxiliary_input &auxiliary_input) const
214 {
215  assert(primary_input.size() == primary_input_size);
216  assert(auxiliary_input.size() == auxiliary_input_size);
217 
219  result.insert(result.end(), primary_input.begin(), primary_input.end());
220  result.insert(result.end(), auxiliary_input.begin(), auxiliary_input.end());
221 
222  assert(result.size() == num_inputs());
223 
224  for (auto &g : gates) {
225  const bool gate_output = g.evaluate(result);
226  result.push_back(gate_output);
227  }
228 
229  return result;
230 }
231 
233  const tbcs_primary_input &primary_input,
234  const tbcs_auxiliary_input &auxiliary_input) const
235 {
236  const tbcs_variable_assignment all_wires =
237  get_all_wires(primary_input, auxiliary_input);
238  tbcs_variable_assignment all_outputs;
239 
240  for (auto &g : gates) {
241  if (g.is_circuit_output) {
242  all_outputs.push_back(all_wires[g.output - 1]);
243  }
244  }
245 
246  return all_outputs;
247 }
248 
250  const tbcs_primary_input &primary_input,
251  const tbcs_auxiliary_input &auxiliary_input) const
252 {
253  const tbcs_variable_assignment all_outputs =
254  get_all_outputs(primary_input, auxiliary_input);
255  for (size_t i = 0; i < all_outputs.size(); ++i) {
256  if (all_outputs[i]) {
257  return false;
258  }
259  }
260 
261  return true;
262 }
263 
265 {
266  assert(g.output == num_wires() + 1);
267  gates.emplace_back(g);
268 }
269 
270 void tbcs_circuit::add_gate(const tbcs_gate &g, const std::string &annotation)
271 {
272  assert(g.output == num_wires() + 1);
273  gates.emplace_back(g);
274 #ifdef DEBUG
275  gate_annotations[g.output] = annotation;
276 #else
277  libff::UNUSED(annotation);
278 #endif
279 }
280 
281 bool tbcs_circuit::operator==(const tbcs_circuit &other) const
282 {
283  return (
284  this->primary_input_size == other.primary_input_size &&
285  this->auxiliary_input_size == other.auxiliary_input_size &&
286  this->gates == other.gates);
287 }
288 
289 std::ostream &operator<<(std::ostream &out, const tbcs_circuit &circuit)
290 {
291  out << circuit.primary_input_size << "\n";
292  out << circuit.auxiliary_input_size << "\n";
293  libff::operator<<(out, circuit.gates);
294  out << OUTPUT_NEWLINE;
295 
296  return out;
297 }
298 
299 std::istream &operator>>(std::istream &in, tbcs_circuit &circuit)
300 {
301  in >> circuit.primary_input_size;
302  libff::consume_newline(in);
303  in >> circuit.auxiliary_input_size;
304  libff::consume_newline(in);
305  libff::operator>>(in, circuit.gates);
306  libff::consume_OUTPUT_NEWLINE(in);
307 
308  return in;
309 }
310 
312 {
313  libff::print_indent();
314  printf("General information about the circuit:\n");
315  this->print_info();
316  libff::print_indent();
317  printf("All gates:\n");
318  for (size_t i = 0; i < gates.size(); ++i) {
319  std::string annotation = "no annotation";
320 #ifdef DEBUG
321  auto it = gate_annotations.find(i);
322  if (it != gate_annotations.end()) {
323  annotation = it->second;
324  }
325 #endif
326  printf("Gate %zu (%s):\n", i, annotation.c_str());
327 #ifdef DEBUG
328  gates[i].print(variable_annotations);
329 #else
330  gates[i].print();
331 #endif
332  }
333 }
334 
336 {
337  libff::print_indent();
338  printf("* Number of inputs: %zu\n", this->num_inputs());
339  libff::print_indent();
340  printf("* Number of gates: %zu\n", this->num_gates());
341  libff::print_indent();
342  printf("* Number of wires: %zu\n", this->num_wires());
343  libff::print_indent();
344  printf("* Depth: %zu\n", this->depth());
345 }
346 
347 } // namespace libsnark
libsnark::tbcs_circuit::operator==
bool operator==(const tbcs_circuit &other) const
Definition: tbcs.cpp:281
libsnark::tbcs_circuit::gates
std::vector< tbcs_gate > gates
Definition: tbcs.hpp:138
libsnark::tbcs_circuit::depth
size_t depth() const
Definition: tbcs.cpp:182
libsnark::tbcs_gate::print
void print(const std::map< size_t, std::string > &variable_annotations=std::map< size_t, std::string >()) const
Definition: tbcs.cpp:60
libsnark::TBCS_GATE_X
@ TBCS_GATE_X
Definition: tbcs.hpp:59
libsnark::tbcs_circuit
Definition: tbcs.hpp:133
libsnark::tbcs_gate::output
tbcs_wire_t output
Definition: tbcs.hpp:95
libsnark::tbcs_circuit::get_all_outputs
tbcs_variable_assignment get_all_outputs(const tbcs_primary_input &primary_input, const tbcs_auxiliary_input &auxiliary_input) const
Definition: tbcs.cpp:232
libsnark::TBCS_GATE_NOT_X
@ TBCS_GATE_NOT_X
Definition: tbcs.hpp:68
libsnark::tbcs_gate::left_wire
tbcs_wire_t left_wire
Definition: tbcs.hpp:90
libsnark::tbcs_primary_input
tbcs_variable_assignment tbcs_primary_input
Definition: tbcs.hpp:114
libsnark
Definition: accumulation_vector.hpp:18
libsnark::tbcs_circuit::num_gates
size_t num_gates() const
Definition: tbcs.cpp:178
libsnark::operator<<
std::ostream & operator<<(std::ostream &out, const accumulation_vector< T > &v)
libsnark::tbcs_circuit::wire_depths
std::vector< size_t > wire_depths() const
Definition: tbcs.cpp:161
libsnark::tbcs_gate::right_wire
tbcs_wire_t right_wire
Definition: tbcs.hpp:91
libsnark::TBCS_GATE_IF_X_THEN_Y
@ TBCS_GATE_IF_X_THEN_Y
Definition: tbcs.hpp:69
libsnark::TBCS_GATE_NOT_X_AND_Y
@ TBCS_GATE_NOT_X_AND_Y
Definition: tbcs.hpp:60
libsnark::TBCS_GATE_X_AND_NOT_Y
@ TBCS_GATE_X_AND_NOT_Y
Definition: tbcs.hpp:58
libsnark::tbcs_circuit::primary_input_size
size_t primary_input_size
Definition: tbcs.hpp:136
libsnark::print_tbcs_wire
void print_tbcs_wire(const tbcs_wire_t wire, const std::map< size_t, std::string > &variable_annotations)
Definition: tbcs.cpp:40
libsnark::tbcs_circuit::is_valid
bool is_valid() const
Definition: tbcs.cpp:188
libsnark::tbcs_gate::evaluate
bool evaluate(const tbcs_variable_assignment &input) const
Definition: tbcs.cpp:24
libsnark::tbcs_circuit::add_gate
void add_gate(const tbcs_gate &g)
Definition: tbcs.cpp:264
libsnark::tbcs_circuit::num_wires
size_t num_wires() const
Definition: tbcs.cpp:180
libsnark::tbcs_gate
Definition: tbcs.hpp:87
libsnark::operator<<
std::ostream & operator<<(std::ostream &out, const tbcs_circuit &circuit)
Definition: tbcs.cpp:289
libsnark::TBCS_GATE_Y
@ TBCS_GATE_Y
Definition: tbcs.hpp:61
libsnark::tbcs_circuit::is_satisfied
bool is_satisfied(const tbcs_primary_input &primary_input, const tbcs_auxiliary_input &auxiliary_input) const
Definition: tbcs.cpp:249
libsnark::tbcs_circuit::print_info
void print_info() const
Definition: tbcs.cpp:335
libsnark::tbcs_auxiliary_input
tbcs_variable_assignment tbcs_auxiliary_input
Definition: tbcs.hpp:119
tbcs.hpp
libsnark::TBCS_GATE_NOT_Y
@ TBCS_GATE_NOT_Y
Definition: tbcs.hpp:66
libsnark::tbcs_gate_type
tbcs_gate_type
Definition: tbcs.hpp:55
libsnark::tbcs_circuit::get_all_wires
tbcs_variable_assignment get_all_wires(const tbcs_primary_input &primary_input, const tbcs_auxiliary_input &auxiliary_input) const
Definition: tbcs.cpp:211
libsnark::TBCS_GATE_NOR
@ TBCS_GATE_NOR
Definition: tbcs.hpp:64
libsnark::TBCS_GATE_XOR
@ TBCS_GATE_XOR
Definition: tbcs.hpp:62
libsnark::tbcs_circuit::num_inputs
size_t num_inputs() const
Definition: tbcs.cpp:173
libsnark::TBCS_GATE_AND
@ TBCS_GATE_AND
Definition: tbcs.hpp:57
libsnark::TBCS_GATE_IF_Y_THEN_X
@ TBCS_GATE_IF_Y_THEN_X
Definition: tbcs.hpp:67
libsnark::TBCS_GATE_OR
@ TBCS_GATE_OR
Definition: tbcs.hpp:63
libsnark::operator>>
std::istream & operator>>(std::istream &in, accumulation_vector< T > &v)
libsnark::tbcs_circuit::print
void print() const
Definition: tbcs.cpp:311
libsnark::TBCS_GATE_EQUIVALENCE
@ TBCS_GATE_EQUIVALENCE
Definition: tbcs.hpp:65
libsnark::tbcs_gate::operator==
bool operator==(const tbcs_gate &other) const
Definition: tbcs.cpp:125
libsnark::tbcs_gate::type
tbcs_gate_type type
Definition: tbcs.hpp:93
libsnark::tbcs_circuit::auxiliary_input_size
size_t auxiliary_input_size
Definition: tbcs.hpp:137
libsnark::TBCS_GATE_CONSTANT_0
@ TBCS_GATE_CONSTANT_0
Definition: tbcs.hpp:56
libsnark::tbcs_wire_t
size_t tbcs_wire_t
Definition: tbcs.hpp:35
libsnark::tbcs_variable_assignment
std::vector< bool > tbcs_variable_assignment
Definition: tbcs.hpp:31
libsnark::tbcs_gate::is_circuit_output
bool is_circuit_output
Definition: tbcs.hpp:97
libsnark::TBCS_GATE_NAND
@ TBCS_GATE_NAND
Definition: tbcs.hpp:70
libsnark::TBCS_GATE_CONSTANT_1
@ TBCS_GATE_CONSTANT_1
Definition: tbcs.hpp:71
libsnark::operator>>
std::istream & operator>>(std::istream &in, tbcs_circuit &circuit)
Definition: tbcs.cpp:299