Clearmatics Libsnark  0.1
C++ library for zkSNARK proofs
uscs_examples.tcc
Go to the documentation of this file.
1 /** @file
2  *****************************************************************************
3 
4  Implementation of functions to sample USCS examples with prescribed parameters
5  (according to some distribution).
6 
7  See uscs_examples.hpp .
8 
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  *****************************************************************************/
14 
15 #ifndef USCS_EXAMPLES_TCC_
16 #define USCS_EXAMPLES_TCC_
17 
18 #include <cassert>
19 #include <libff/common/utils.hpp>
20 
21 namespace libsnark
22 {
23 
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)
27 {
28  libff::enter_block("Call to generate_uscs_example_with_field_input");
29 
30  assert(num_inputs >= 1);
31  assert(num_constraints >= num_inputs);
32 
33  uscs_constraint_system<FieldT> cs;
34  cs.primary_input_size = num_inputs;
35  cs.auxiliary_input_size = num_constraints - num_inputs;
36 
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()));
40  }
41 
42  for (size_t i = 0; i < num_constraints; ++i) {
43  size_t x, y, z;
44 
45  do {
46  x = std::rand() % num_constraints;
47  y = std::rand() % num_constraints;
48  z = std::rand() % num_constraints;
49  } while (x == z || y == z);
50 
51  const FieldT x_coeff = FieldT(std::rand());
52  const FieldT y_coeff = FieldT(std::rand());
53  const FieldT val =
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();
58 
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);
63 
64  cs.add_constraint(constr);
65  }
66 
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());
74 
75  /* sanity checks */
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));
81 
82  libff::leave_block("Call to generate_uscs_example_with_field_input");
83 
84  return uscs_example<FieldT>(
85  std::move(cs), std::move(primary_input), std::move(auxiliary_input));
86 }
87 
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)
91 {
92  libff::enter_block("Call to generate_uscs_example_with_binary_input");
93 
94  assert(num_inputs >= 1);
95 
96  uscs_constraint_system<FieldT> cs;
97  cs.primary_input_size = num_inputs;
98  cs.auxiliary_input_size = num_constraints;
99 
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));
103  }
104 
105  size_t lastvar = num_inputs - 1;
106  for (size_t i = 0; i < num_constraints; ++i) {
107  ++lastvar;
108 
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);
112 
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);
117  constr.add_term(
118  0, -FieldT::one()); // shift constant term (which is 0) by 1
119 
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]);
125  }
126 
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());
134 
135  /* sanity checks */
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));
141 
142  libff::leave_block("Call to generate_uscs_example_with_binary_input");
143 
144  return uscs_example<FieldT>(
145  std::move(cs), std::move(primary_input), std::move(auxiliary_input));
146 }
147 
148 } // namespace libsnark
149 #endif // USCS_EXAMPLES_TCC