Clearmatics Libsnark  0.1
C++ library for zkSNARK proofs
uscs.tcc
Go to the documentation of this file.
1 /** @file
2  *****************************************************************************
3 
4  Implementation of interfaces for:
5  - a USCS constraint,
6  - a USCS variable assignment, and
7  - a USCS constraint system.
8 
9  See uscs.hpp .
10 
11  *****************************************************************************
12  * @author This file is part of libsnark, developed by SCIPR Lab
13  * and contributors (see AUTHORS).
14  * @copyright MIT license (see LICENSE file)
15  *****************************************************************************/
16 
17 #ifndef USCS_TCC_
18 #define USCS_TCC_
19 
20 #include <algorithm>
21 #include <cassert>
22 #include <libff/algebra/fields/bigint.hpp>
23 #include <libff/common/profiling.hpp>
24 #include <libff/common/utils.hpp>
25 #include <set>
26 
27 namespace libsnark
28 {
29 
30 template<typename FieldT>
31 size_t uscs_constraint_system<FieldT>::num_inputs() const
32 {
33  return primary_input_size;
34 }
35 
36 template<typename FieldT>
37 size_t uscs_constraint_system<FieldT>::num_variables() const
38 {
39  return primary_input_size + auxiliary_input_size;
40 }
41 
42 template<typename FieldT>
43 size_t uscs_constraint_system<FieldT>::num_constraints() const
44 {
45  return constraints.size();
46 }
47 
48 template<typename FieldT> bool uscs_constraint_system<FieldT>::is_valid() const
49 {
50  if (this->num_inputs() > this->num_variables())
51  return false;
52 
53  for (size_t c = 0; c < constraints.size(); ++c) {
54  if (!valid_vector(constraints[c], this->num_variables())) {
55  return false;
56  }
57  }
58 
59  return true;
60 }
61 
62 template<typename FieldT>
63 void dump_uscs_constraint(
64  const uscs_constraint<FieldT> &constraint,
65  const uscs_variable_assignment<FieldT> &full_variable_assignment,
66  const std::map<size_t, std::string> &variable_annotations)
67 {
68  printf("terms:\n");
69  constraint.print_with_assignment(
70  full_variable_assignment, variable_annotations);
71 }
72 
73 template<typename FieldT>
74 bool uscs_constraint_system<FieldT>::is_satisfied(
75  const uscs_primary_input<FieldT> &primary_input,
76  const uscs_auxiliary_input<FieldT> &auxiliary_input) const
77 {
78  assert(primary_input.size() == num_inputs());
79  assert(primary_input.size() + auxiliary_input.size() == num_variables());
80 
81  uscs_variable_assignment<FieldT> full_variable_assignment = primary_input;
82  full_variable_assignment.insert(
83  full_variable_assignment.end(),
84  auxiliary_input.begin(),
85  auxiliary_input.end());
86 
87  for (size_t c = 0; c < constraints.size(); ++c) {
88  FieldT res = constraints[c].evaluate(full_variable_assignment);
89  if (!(res.squared() == FieldT::one())) {
90 #ifdef DEBUG
91  auto it = constraint_annotations.find(c);
92  printf(
93  "constraint %zu (%s) unsatisfied\n",
94  c,
95  (it == constraint_annotations.end() ? "no annotation"
96  : it->second.c_str()));
97  printf("<a,(1,x)> = ");
98  res.print();
99  printf("constraint was:\n");
100  dump_uscs_constraint(
101  constraints[c], full_variable_assignment, variable_annotations);
102 #endif // DEBUG
103  return false;
104  }
105  }
106 
107  return true;
108 }
109 
110 template<typename FieldT>
111 void uscs_constraint_system<FieldT>::add_constraint(
112  const uscs_constraint<FieldT> &c)
113 {
114  constraints.emplace_back(c);
115 }
116 
117 template<typename FieldT>
118 void uscs_constraint_system<FieldT>::add_constraint(
119  const uscs_constraint<FieldT> &c, const std::string &annotation)
120 {
121 #ifdef DEBUG
122  constraint_annotations[constraints.size()] = annotation;
123 #else
124  libff::UNUSED(annotation);
125 #endif
126  constraints.emplace_back(c);
127 }
128 
129 template<typename FieldT>
130 bool uscs_constraint_system<FieldT>::operator==(
131  const uscs_constraint_system<FieldT> &other) const
132 {
133  return (
134  this->constraints == other.constraints &&
135  this->primary_input_size == other.primary_input_size &&
136  this->auxiliary_input_size == other.auxiliary_input_size);
137 }
138 
139 template<typename FieldT>
140 std::ostream &operator<<(
141  std::ostream &out, const uscs_constraint_system<FieldT> &cs)
142 {
143  out << cs.primary_input_size << "\n";
144  out << cs.auxiliary_input_size << "\n";
145 
146  out << cs.num_constraints() << "\n";
147  for (const uscs_constraint<FieldT> &c : cs.constraints) {
148  out << c;
149  }
150 
151  return out;
152 }
153 
154 template<typename FieldT>
155 std::istream &operator>>(std::istream &in, uscs_constraint_system<FieldT> &cs)
156 {
157  in >> cs.primary_input_size;
158  in >> cs.auxiliary_input_size;
159 
160  cs.constraints.clear();
161 
162  size_t s;
163  in >> s;
164 
165  char b;
166  in.read(&b, 1);
167 
168  cs.constraints.reserve(s);
169 
170  for (size_t i = 0; i < s; ++i) {
171  uscs_constraint<FieldT> c;
172  in >> c;
173  cs.constraints.emplace_back(c);
174  }
175 
176  return in;
177 }
178 
179 template<typename FieldT>
180 void uscs_constraint_system<FieldT>::report_linear_constraint_statistics() const
181 {
182 #ifdef DEBUG
183  for (size_t i = 0; i < constraints.size(); ++i) {
184  auto &constr = constraints[i];
185  bool a_is_const = true;
186  for (auto &t : constr.terms) {
187  a_is_const = a_is_const && (t.index == 0);
188  }
189 
190  if (a_is_const) {
191  auto it = constraint_annotations.find(i);
192  printf(
193  "%s\n",
194  (it == constraint_annotations.end()
195  ? FMT("", "constraint_%zu", i)
196  : it->second)
197  .c_str());
198  }
199  }
200 #endif
201 }
202 
203 } // namespace libsnark
204 
205 #endif // USCS_TCC_