Clearmatics Libsnark  0.1
C++ library for zkSNARK proofs
compliance_predicate.tcc
Go to the documentation of this file.
1 /** @file
2  *****************************************************************************
3 
4  Implementation of interfaces for a compliance predicate for R1CS PCD.
5 
6  See compliance_predicate.hpp .
7 
8  *****************************************************************************
9  * @author This file is part of libsnark, developed by SCIPR Lab
10  * and contributors (see AUTHORS).
11  * @copyright MIT license (see LICENSE file)
12  *****************************************************************************/
13 
14 #ifndef COMPLIANCE_PREDICATE_TCC_
15 #define COMPLIANCE_PREDICATE_TCC_
16 
17 #include <libff/common/utils.hpp>
18 
19 namespace libsnark
20 {
21 
22 template<typename FieldT> class r1cs_pcd_compliance_predicate_primary_input;
23 
24 template<typename FieldT> class r1cs_pcd_compliance_predicate_auxiliary_input;
25 
26 template<typename FieldT>
27 r1cs_variable_assignment<FieldT> r1cs_pcd_message<
28  FieldT>::as_r1cs_variable_assignment() const
29 {
30  r1cs_variable_assignment<FieldT> result =
31  this->payload_as_r1cs_variable_assignment();
32  result.insert(result.begin(), FieldT(this->type));
33  return result;
34 }
35 
36 template<typename FieldT>
37 r1cs_pcd_message<FieldT>::r1cs_pcd_message(const size_t type) : type(type)
38 {
39 }
40 
41 template<typename FieldT> void r1cs_pcd_message<FieldT>::print() const
42 {
43  printf("PCD message (default print routines):\n");
44  printf(" Type: %zu\n", this->type);
45 
46  printf(" Payload\n");
47  const r1cs_variable_assignment<FieldT> payload =
48  this->payload_as_r1cs_variable_assignment();
49  for (auto &elt : payload) {
50  elt.print();
51  }
52 }
53 
54 template<typename FieldT>
55 r1cs_pcd_compliance_predicate<FieldT>::r1cs_pcd_compliance_predicate(
56  const size_t name,
57  const size_t type,
58  const r1cs_constraint_system<FieldT> &constraint_system,
59  const size_t outgoing_message_payload_length,
60  const size_t max_arity,
61  const std::vector<size_t> &incoming_message_payload_lengths,
62  const size_t local_data_length,
63  const size_t witness_length,
64  const bool relies_on_same_type_inputs,
65  const std::set<size_t> accepted_input_types)
66  : name(name)
67  , type(type)
68  , constraint_system(constraint_system)
69  , outgoing_message_payload_length(outgoing_message_payload_length)
70  , max_arity(max_arity)
71  , incoming_message_payload_lengths(incoming_message_payload_lengths)
72  , local_data_length(local_data_length)
73  , witness_length(witness_length)
74  , relies_on_same_type_inputs(relies_on_same_type_inputs)
75  , accepted_input_types(accepted_input_types)
76 {
77  assert(max_arity == incoming_message_payload_lengths.size());
78 }
79 
80 template<typename FieldT>
81 bool r1cs_pcd_compliance_predicate<FieldT>::is_well_formed() const
82 {
83  const bool type_not_zero = (type != 0);
84  const bool incoming_message_payload_lengths_well_specified =
85  (incoming_message_payload_lengths.size() == max_arity);
86 
87  size_t all_message_payload_lengths = outgoing_message_payload_length;
88  for (size_t i = 0; i < incoming_message_payload_lengths.size(); ++i) {
89  all_message_payload_lengths += incoming_message_payload_lengths[i];
90  }
91  const size_t type_vec_length = max_arity + 1;
92  const size_t arity_length = 1;
93 
94  const bool correct_num_inputs =
95  ((outgoing_message_payload_length + 1) ==
96  constraint_system.num_inputs());
97  const bool correct_num_variables =
98  ((all_message_payload_lengths + local_data_length + type_vec_length +
99  arity_length + witness_length) == constraint_system.num_variables());
100 
101 #ifdef DEBUG
102  printf(
103  "outgoing_message_payload_length: %zu\n",
104  outgoing_message_payload_length);
105  printf("incoming_message_payload_lengths:");
106  for (auto l : incoming_message_payload_lengths) {
107  printf(" %zu", l);
108  }
109  printf("\n");
110  printf("type_not_zero: %d\n", type_not_zero);
111  printf(
112  "incoming_message_payload_lengths_well_specified: %d\n",
113  incoming_message_payload_lengths_well_specified);
114  printf(
115  "correct_num_inputs: %d (outgoing_message_payload_length = %zu, "
116  "constraint_system.num_inputs() = %zu)\n",
117  correct_num_inputs,
118  outgoing_message_payload_length,
119  constraint_system.num_inputs());
120  printf(
121  "correct_num_variables: %d (all_message_payload_lengths = %zu, "
122  "local_data_length = %zu, type_vec_length = %zu, arity_length = %zu, "
123  "witness_length = %zu, constraint_system.num_variables() = %zu)\n",
124  correct_num_variables,
125  all_message_payload_lengths,
126  local_data_length,
127  type_vec_length,
128  arity_length,
129  witness_length,
130  constraint_system.num_variables());
131 #endif
132 
133  return (
134  type_not_zero && incoming_message_payload_lengths_well_specified &&
135  correct_num_inputs && correct_num_variables);
136 }
137 
138 template<typename FieldT>
139 bool r1cs_pcd_compliance_predicate<FieldT>::has_equal_input_and_output_lengths()
140  const
141 {
142  for (size_t i = 0; i < incoming_message_payload_lengths.size(); ++i) {
143  if (incoming_message_payload_lengths[i] !=
144  outgoing_message_payload_length) {
145  return false;
146  }
147  }
148 
149  return true;
150 }
151 
152 template<typename FieldT>
153 bool r1cs_pcd_compliance_predicate<FieldT>::has_equal_input_lengths() const
154 {
155  for (size_t i = 1; i < incoming_message_payload_lengths.size(); ++i) {
156  if (incoming_message_payload_lengths[i] !=
157  incoming_message_payload_lengths[0]) {
158  return false;
159  }
160  }
161 
162  return true;
163 }
164 
165 template<typename FieldT>
166 bool r1cs_pcd_compliance_predicate<FieldT>::operator==(
167  const r1cs_pcd_compliance_predicate<FieldT> &other) const
168 {
169  return (
170  this->name == other.name && this->type == other.type &&
171  this->constraint_system == other.constraint_system &&
172  this->outgoing_message_payload_length ==
173  other.outgoing_message_payload_length &&
174  this->max_arity == other.max_arity &&
175  this->incoming_message_payload_lengths ==
176  other.incoming_message_payload_lengths &&
177  this->local_data_length == other.local_data_length &&
178  this->witness_length == other.witness_length &&
179  this->relies_on_same_type_inputs == other.relies_on_same_type_inputs &&
180  this->accepted_input_types == other.accepted_input_types);
181 }
182 
183 template<typename FieldT>
184 std::ostream &operator<<(
185  std::ostream &out, const r1cs_pcd_compliance_predicate<FieldT> &cp)
186 {
187  out << cp.name << "\n";
188  out << cp.type << "\n";
189  out << cp.max_arity << "\n";
190  assert(cp.max_arity == cp.incoming_message_payload_lengths.size());
191  for (size_t i = 0; i < cp.max_arity; ++i) {
192  out << cp.incoming_message_payload_lengths[i] << "\n";
193  }
194  out << cp.outgoing_message_payload_length << "\n";
195  out << cp.local_data_length << "\n";
196  out << cp.witness_length << "\n";
197  libff::output_bool(out, cp.relies_on_same_type_inputs);
198  libff::operator<<(out, cp.accepted_input_types);
199  out << "\n" << cp.constraint_system << "\n";
200 
201  return out;
202 }
203 
204 template<typename FieldT>
205 std::istream &operator>>(
206  std::istream &in, r1cs_pcd_compliance_predicate<FieldT> &cp)
207 {
208  in >> cp.name;
209  libff::consume_newline(in);
210  in >> cp.type;
211  libff::consume_newline(in);
212  in >> cp.max_arity;
213  libff::consume_newline(in);
214  cp.incoming_message_payload_lengths.resize(cp.max_arity);
215  for (size_t i = 0; i < cp.max_arity; ++i) {
216  in >> cp.incoming_message_payload_lengths[i];
217  libff::consume_newline(in);
218  }
219  in >> cp.outgoing_message_payload_length;
220  libff::consume_newline(in);
221  in >> cp.local_data_length;
222  libff::consume_newline(in);
223  in >> cp.witness_length;
224  libff::consume_newline(in);
225  libff::input_bool(in, cp.relies_on_same_type_inputs);
226  libff::operator>>(in, cp.accepted_input_types);
227  libff::consume_newline(in);
228  in >> cp.constraint_system;
229  libff::consume_newline(in);
230 
231  return in;
232 }
233 
234 template<typename FieldT>
235 bool r1cs_pcd_compliance_predicate<FieldT>::is_satisfied(
236  const std::shared_ptr<r1cs_pcd_message<FieldT>> &outgoing_message,
237  const std::vector<std::shared_ptr<r1cs_pcd_message<FieldT>>>
238  &incoming_messages,
239  const std::shared_ptr<r1cs_pcd_local_data<FieldT>> &local_data,
240  const r1cs_pcd_witness<FieldT> &witness) const
241 {
242  assert(
243  outgoing_message.payload_as_r1cs_variable_assignment().size() ==
244  outgoing_message_payload_length);
245  assert(incoming_messages.size() <= max_arity);
246  for (size_t i = 0; i < incoming_messages.size(); ++i) {
247  assert(
248  incoming_messages[i].payload_as_r1cs_variable_assignment().size() ==
249  incoming_message_payload_lengths[i]);
250  }
251  assert(
252  local_data.as_r1cs_variable_assignment().size() == local_data_length);
253 
254  r1cs_pcd_compliance_predicate_primary_input<FieldT> cp_primary_input(
255  outgoing_message);
256  r1cs_pcd_compliance_predicate_auxiliary_input<FieldT> cp_auxiliary_input(
257  incoming_messages, local_data, witness);
258 
259  return constraint_system.is_satisfied(
260  cp_primary_input.as_r1cs_primary_input(),
261  cp_auxiliary_input.as_r1cs_auxiliary_input(
262  incoming_message_payload_lengths));
263 }
264 
265 } // namespace libsnark
266 
267 #endif // COMPLIANCE_PREDICATE_TCC_