Clearmatics Libsnark  0.1
C++ library for zkSNARK proofs
cp_handler.tcc
Go to the documentation of this file.
1 /** @file
2  *****************************************************************************
3 
4  Implementation of interfaces for a compliance predicate handler.
5 
6  See cp_handler.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 CP_HANDLER_TCC_
15 #define CP_HANDLER_TCC_
16 
17 #include <algorithm>
18 
19 namespace libsnark
20 {
21 
22 template<typename FieldT>
23 r1cs_pcd_message_variable<FieldT>::r1cs_pcd_message_variable(
24  protoboard<FieldT> &pb, const std::string &annotation_prefix)
25  : gadget<FieldT>(pb, annotation_prefix)
26 {
27  type.allocate(pb, FMT(annotation_prefix, " type"));
28  all_vars.emplace_back(type);
29 
30  num_vars_at_construction = pb.num_variables();
31 }
32 
33 template<typename FieldT>
34 void r1cs_pcd_message_variable<FieldT>::update_all_vars()
35 {
36  /* NOTE: this assumes that r1cs_pcd_message_variable has been the
37  * only gadget allocating variables on the protoboard and needs to
38  * be updated, e.g., in multicore variable allocation scenario. */
39 
40  for (size_t var_idx = num_vars_at_construction + 1;
41  var_idx <= this->pb.num_variables();
42  ++var_idx) {
43  all_vars.emplace_back(pb_variable<FieldT>(var_idx));
44  }
45 }
46 
47 template<typename FieldT>
48 void r1cs_pcd_message_variable<FieldT>::generate_r1cs_witness(
49  const std::shared_ptr<r1cs_pcd_message<FieldT>> &message)
50 {
51  all_vars.fill_with_field_elements(
52  this->pb, message->as_r1cs_variable_assignment());
53 }
54 
55 template<typename FieldT>
56 r1cs_pcd_local_data_variable<FieldT>::r1cs_pcd_local_data_variable(
57  protoboard<FieldT> &pb, const std::string &annotation_prefix)
58  : gadget<FieldT>(pb, annotation_prefix)
59 {
60  num_vars_at_construction = pb.num_variables();
61 }
62 
63 template<typename FieldT>
64 void r1cs_pcd_local_data_variable<FieldT>::update_all_vars()
65 {
66  /* (the same NOTE as for r1cs_message_variable applies) */
67 
68  for (size_t var_idx = num_vars_at_construction + 1;
69  var_idx <= this->pb.num_variables();
70  ++var_idx) {
71  all_vars.emplace_back(pb_variable<FieldT>(var_idx));
72  }
73 }
74 
75 template<typename FieldT>
76 void r1cs_pcd_local_data_variable<FieldT>::generate_r1cs_witness(
77  const std::shared_ptr<r1cs_pcd_local_data<FieldT>> &local_data)
78 {
79  all_vars.fill_with_field_elements(
80  this->pb, local_data->as_r1cs_variable_assignment());
81 }
82 
83 template<typename FieldT, typename protoboardT>
84 compliance_predicate_handler<FieldT, protoboardT>::compliance_predicate_handler(
85  const protoboardT &pb,
86  const size_t name,
87  const size_t type,
88  const size_t max_arity,
89  const bool relies_on_same_type_inputs,
90  const std::set<size_t> accepted_input_types)
91  : pb(pb)
92  , name(name)
93  , type(type)
94  , max_arity(max_arity)
95  , relies_on_same_type_inputs(relies_on_same_type_inputs)
96  , accepted_input_types(accepted_input_types)
97 {
98  incoming_messages.resize(max_arity);
99 }
100 
101 template<typename FieldT, typename protoboardT>
102 void compliance_predicate_handler<FieldT, protoboardT>::generate_r1cs_witness(
103  const std::vector<std::shared_ptr<r1cs_pcd_message<FieldT>>>
104  &incoming_message_values,
105  const std::shared_ptr<r1cs_pcd_local_data<FieldT>> &local_data_value)
106 {
107  pb.clear_values();
108  pb.val(outgoing_message->type) = FieldT(type);
109  pb.val(arity) = FieldT(incoming_message_values.size());
110 
111  for (size_t i = 0; i < incoming_message_values.size(); ++i) {
112  incoming_messages[i]->generate_r1cs_witness(incoming_message_values[i]);
113  }
114 
115  local_data->generate_r1cs_witness(local_data_value);
116 }
117 
118 template<typename FieldT, typename protoboardT>
119 r1cs_pcd_compliance_predicate<FieldT> compliance_predicate_handler<
120  FieldT,
121  protoboardT>::get_compliance_predicate() const
122 {
123  assert(incoming_messages.size() == max_arity);
124 
125  const size_t outgoing_message_payload_length =
126  outgoing_message->all_vars.size() - 1;
127 
128  std::vector<size_t> incoming_message_payload_lengths(max_arity);
129  std::transform(
130  incoming_messages.begin(),
131  incoming_messages.end(),
132  incoming_message_payload_lengths.begin(),
133  [](const std::shared_ptr<r1cs_pcd_message_variable<FieldT>> &msg) {
134  return msg->all_vars.size() - 1;
135  });
136 
137  const size_t local_data_length = local_data->all_vars.size();
138 
139  const size_t all_but_witness_length =
140  ((1 + outgoing_message_payload_length) + 1 +
141  (max_arity + std::accumulate(
142  incoming_message_payload_lengths.begin(),
143  incoming_message_payload_lengths.end(),
144  0)) +
145  local_data_length);
146  const size_t witness_length = pb.num_variables() - all_but_witness_length;
147 
148  r1cs_constraint_system<FieldT> constraint_system =
149  pb.get_constraint_system();
150  constraint_system.primary_input_size = 1 + outgoing_message_payload_length;
151  constraint_system.auxiliary_input_size =
152  pb.num_variables() - constraint_system.primary_input_size;
153 
154  return r1cs_pcd_compliance_predicate<FieldT>(
155  name,
156  type,
157  constraint_system,
158  outgoing_message_payload_length,
159  max_arity,
160  incoming_message_payload_lengths,
161  local_data_length,
162  witness_length,
163  relies_on_same_type_inputs,
164  accepted_input_types);
165 }
166 
167 template<typename FieldT, typename protoboardT>
168 r1cs_variable_assignment<FieldT> compliance_predicate_handler<
169  FieldT,
170  protoboardT>::get_full_variable_assignment() const
171 {
172  return pb.full_variable_assignment();
173 }
174 
175 template<typename FieldT, typename protoboardT>
176 std::shared_ptr<r1cs_pcd_message<FieldT>> compliance_predicate_handler<
177  FieldT,
178  protoboardT>::get_outgoing_message() const
179 {
180  return outgoing_message->get_message();
181 }
182 
183 template<typename FieldT, typename protoboardT>
184 size_t compliance_predicate_handler<FieldT, protoboardT>::get_arity() const
185 {
186  return pb.val(arity).as_ulong();
187 }
188 
189 template<typename FieldT, typename protoboardT>
190 std::shared_ptr<r1cs_pcd_message<FieldT>> compliance_predicate_handler<
191  FieldT,
192  protoboardT>::get_incoming_message(const size_t message_idx) const
193 {
194  assert(message_idx < max_arity);
195  return incoming_messages[message_idx]->get_message();
196 }
197 
198 template<typename FieldT, typename protoboardT>
199 std::shared_ptr<r1cs_pcd_local_data<FieldT>> compliance_predicate_handler<
200  FieldT,
201  protoboardT>::get_local_data() const
202 {
203  return local_data->get_local_data();
204 }
205 
206 template<typename FieldT, typename protoboardT>
207 r1cs_pcd_witness<FieldT> compliance_predicate_handler<FieldT, protoboardT>::
208  get_witness() const
209 {
210  const r1cs_variable_assignment<FieldT> va = pb.full_variable_assignment();
211  // outgoing_message + arity + incoming_messages + local_data
212  const size_t witness_pos =
213  (outgoing_message->all_vars.size() + 1 +
214  std::accumulate(
215  incoming_messages.begin(),
216  incoming_messages.end(),
217  0,
218  [](size_t acc,
219  const std::shared_ptr<r1cs_pcd_message_variable<FieldT>> &msg) {
220  return acc + msg->all_vars.size();
221  }) +
222  local_data->all_vars.size());
223 
224  return r1cs_variable_assignment<FieldT>(va.begin() + witness_pos, va.end());
225 }
226 
227 } // namespace libsnark
228 
229 #endif // CP_HANDLER_TCC_