2 *****************************************************************************
4 Implementation of interfaces for a compliance predicate handler.
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 *****************************************************************************/
14 #ifndef CP_HANDLER_TCC_
15 #define CP_HANDLER_TCC_
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)
27 type.allocate(pb, FMT(annotation_prefix, " type"));
28 all_vars.emplace_back(type);
30 num_vars_at_construction = pb.num_variables();
33 template<typename FieldT>
34 void r1cs_pcd_message_variable<FieldT>::update_all_vars()
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. */
40 for (size_t var_idx = num_vars_at_construction + 1;
41 var_idx <= this->pb.num_variables();
43 all_vars.emplace_back(pb_variable<FieldT>(var_idx));
47 template<typename FieldT>
48 void r1cs_pcd_message_variable<FieldT>::generate_r1cs_witness(
49 const std::shared_ptr<r1cs_pcd_message<FieldT>> &message)
51 all_vars.fill_with_field_elements(
52 this->pb, message->as_r1cs_variable_assignment());
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)
60 num_vars_at_construction = pb.num_variables();
63 template<typename FieldT>
64 void r1cs_pcd_local_data_variable<FieldT>::update_all_vars()
66 /* (the same NOTE as for r1cs_message_variable applies) */
68 for (size_t var_idx = num_vars_at_construction + 1;
69 var_idx <= this->pb.num_variables();
71 all_vars.emplace_back(pb_variable<FieldT>(var_idx));
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)
79 all_vars.fill_with_field_elements(
80 this->pb, local_data->as_r1cs_variable_assignment());
83 template<typename FieldT, typename protoboardT>
84 compliance_predicate_handler<FieldT, protoboardT>::compliance_predicate_handler(
85 const protoboardT &pb,
88 const size_t max_arity,
89 const bool relies_on_same_type_inputs,
90 const std::set<size_t> accepted_input_types)
94 , max_arity(max_arity)
95 , relies_on_same_type_inputs(relies_on_same_type_inputs)
96 , accepted_input_types(accepted_input_types)
98 incoming_messages.resize(max_arity);
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)
108 pb.val(outgoing_message->type) = FieldT(type);
109 pb.val(arity) = FieldT(incoming_message_values.size());
111 for (size_t i = 0; i < incoming_message_values.size(); ++i) {
112 incoming_messages[i]->generate_r1cs_witness(incoming_message_values[i]);
115 local_data->generate_r1cs_witness(local_data_value);
118 template<typename FieldT, typename protoboardT>
119 r1cs_pcd_compliance_predicate<FieldT> compliance_predicate_handler<
121 protoboardT>::get_compliance_predicate() const
123 assert(incoming_messages.size() == max_arity);
125 const size_t outgoing_message_payload_length =
126 outgoing_message->all_vars.size() - 1;
128 std::vector<size_t> incoming_message_payload_lengths(max_arity);
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;
137 const size_t local_data_length = local_data->all_vars.size();
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(),
146 const size_t witness_length = pb.num_variables() - all_but_witness_length;
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;
154 return r1cs_pcd_compliance_predicate<FieldT>(
158 outgoing_message_payload_length,
160 incoming_message_payload_lengths,
163 relies_on_same_type_inputs,
164 accepted_input_types);
167 template<typename FieldT, typename protoboardT>
168 r1cs_variable_assignment<FieldT> compliance_predicate_handler<
170 protoboardT>::get_full_variable_assignment() const
172 return pb.full_variable_assignment();
175 template<typename FieldT, typename protoboardT>
176 std::shared_ptr<r1cs_pcd_message<FieldT>> compliance_predicate_handler<
178 protoboardT>::get_outgoing_message() const
180 return outgoing_message->get_message();
183 template<typename FieldT, typename protoboardT>
184 size_t compliance_predicate_handler<FieldT, protoboardT>::get_arity() const
186 return pb.val(arity).as_ulong();
189 template<typename FieldT, typename protoboardT>
190 std::shared_ptr<r1cs_pcd_message<FieldT>> compliance_predicate_handler<
192 protoboardT>::get_incoming_message(const size_t message_idx) const
194 assert(message_idx < max_arity);
195 return incoming_messages[message_idx]->get_message();
198 template<typename FieldT, typename protoboardT>
199 std::shared_ptr<r1cs_pcd_local_data<FieldT>> compliance_predicate_handler<
201 protoboardT>::get_local_data() const
203 return local_data->get_local_data();
206 template<typename FieldT, typename protoboardT>
207 r1cs_pcd_witness<FieldT> compliance_predicate_handler<FieldT, protoboardT>::
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 +
215 incoming_messages.begin(),
216 incoming_messages.end(),
219 const std::shared_ptr<r1cs_pcd_message_variable<FieldT>> &msg) {
220 return acc + msg->all_vars.size();
222 local_data->all_vars.size());
224 return r1cs_variable_assignment<FieldT>(va.begin() + witness_pos, va.end());
227 } // namespace libsnark
229 #endif // CP_HANDLER_TCC_