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