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_