2  *****************************************************************************
 
    4  Implementation of functions to sample USCS examples with prescribed parameters
 
    5  (according to some distribution).
 
    7  See uscs_examples.hpp .
 
    9  *****************************************************************************
 
   10  * @author     This file is part of libsnark, developed by SCIPR Lab
 
   11  *             and contributors (see AUTHORS).
 
   12  * @copyright  MIT license (see LICENSE file)
 
   13  *****************************************************************************/
 
   15 #ifndef USCS_EXAMPLES_TCC_
 
   16 #define USCS_EXAMPLES_TCC_
 
   19 #include <libff/common/utils.hpp>
 
   24 template<typename FieldT>
 
   25 uscs_example<FieldT> generate_uscs_example_with_field_input(
 
   26     const size_t num_constraints, const size_t num_inputs)
 
   28     libff::enter_block("Call to generate_uscs_example_with_field_input");
 
   30     assert(num_inputs >= 1);
 
   31     assert(num_constraints >= num_inputs);
 
   33     uscs_constraint_system<FieldT> cs;
 
   34     cs.primary_input_size = num_inputs;
 
   35     cs.auxiliary_input_size = num_constraints - num_inputs;
 
   37     uscs_variable_assignment<FieldT> full_variable_assignment;
 
   38     for (size_t i = 0; i < num_constraints; ++i) {
 
   39         full_variable_assignment.emplace_back(FieldT(std::rand()));
 
   42     for (size_t i = 0; i < num_constraints; ++i) {
 
   46             x = std::rand() % num_constraints;
 
   47             y = std::rand() % num_constraints;
 
   48             z = std::rand() % num_constraints;
 
   49         } while (x == z || y == z);
 
   51         const FieldT x_coeff = FieldT(std::rand());
 
   52         const FieldT y_coeff = FieldT(std::rand());
 
   54             (std::rand() % 2 == 0 ? FieldT::one() : -FieldT::one());
 
   55         const FieldT z_coeff = (val - x_coeff * full_variable_assignment[x] -
 
   56                                 y_coeff * full_variable_assignment[y]) *
 
   57                                full_variable_assignment[z].inverse();
 
   59         uscs_constraint<FieldT> constr;
 
   60         constr.add_term(x + 1, x_coeff);
 
   61         constr.add_term(y + 1, y_coeff);
 
   62         constr.add_term(z + 1, z_coeff);
 
   64         cs.add_constraint(constr);
 
   67     /* split variable assignment */
 
   68     uscs_primary_input<FieldT> primary_input(
 
   69         full_variable_assignment.begin(),
 
   70         full_variable_assignment.begin() + num_inputs);
 
   71     uscs_primary_input<FieldT> auxiliary_input(
 
   72         full_variable_assignment.begin() + num_inputs,
 
   73         full_variable_assignment.end());
 
   76     assert(cs.num_variables() == full_variable_assignment.size());
 
   77     assert(cs.num_variables() >= num_inputs);
 
   78     assert(cs.num_inputs() == num_inputs);
 
   79     assert(cs.num_constraints() == num_constraints);
 
   80     assert(cs.is_satisfied(primary_input, auxiliary_input));
 
   82     libff::leave_block("Call to generate_uscs_example_with_field_input");
 
   84     return uscs_example<FieldT>(
 
   85         std::move(cs), std::move(primary_input), std::move(auxiliary_input));
 
   88 template<typename FieldT>
 
   89 uscs_example<FieldT> generate_uscs_example_with_binary_input(
 
   90     const size_t num_constraints, const size_t num_inputs)
 
   92     libff::enter_block("Call to generate_uscs_example_with_binary_input");
 
   94     assert(num_inputs >= 1);
 
   96     uscs_constraint_system<FieldT> cs;
 
   97     cs.primary_input_size = num_inputs;
 
   98     cs.auxiliary_input_size = num_constraints;
 
  100     uscs_variable_assignment<FieldT> full_variable_assignment;
 
  101     for (size_t i = 0; i < num_inputs; ++i) {
 
  102         full_variable_assignment.push_back(FieldT(std::rand() % 2));
 
  105     size_t lastvar = num_inputs - 1;
 
  106     for (size_t i = 0; i < num_constraints; ++i) {
 
  109         /* chose two random bits and XOR them together */
 
  110         const size_t u = (i == 0 ? std::rand() % num_inputs : std::rand() % i);
 
  111         const size_t v = (i == 0 ? std::rand() % num_inputs : std::rand() % i);
 
  113         uscs_constraint<FieldT> constr;
 
  114         constr.add_term(u + 1, 1);
 
  115         constr.add_term(v + 1, 1);
 
  116         constr.add_term(lastvar + 1, 1);
 
  118             0, -FieldT::one()); // shift constant term (which is 0) by 1
 
  120         cs.add_constraint(constr);
 
  121         full_variable_assignment.push_back(
 
  122             full_variable_assignment[u] + full_variable_assignment[v] -
 
  123             full_variable_assignment[u] * full_variable_assignment[v] -
 
  124             full_variable_assignment[u] * full_variable_assignment[v]);
 
  127     /* split variable assignment */
 
  128     uscs_primary_input<FieldT> primary_input(
 
  129         full_variable_assignment.begin(),
 
  130         full_variable_assignment.begin() + num_inputs);
 
  131     uscs_primary_input<FieldT> auxiliary_input(
 
  132         full_variable_assignment.begin() + num_inputs,
 
  133         full_variable_assignment.end());
 
  136     assert(cs.num_variables() == full_variable_assignment.size());
 
  137     assert(cs.num_variables() >= num_inputs);
 
  138     assert(cs.num_inputs() == num_inputs);
 
  139     assert(cs.num_constraints() == num_constraints);
 
  140     assert(cs.is_satisfied(primary_input, auxiliary_input));
 
  142     libff::leave_block("Call to generate_uscs_example_with_binary_input");
 
  144     return uscs_example<FieldT>(
 
  145         std::move(cs), std::move(primary_input), std::move(auxiliary_input));
 
  148 } // namespace libsnark
 
  149 #endif // USCS_EXAMPLES_TCC