tbcs_to_uscs.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2018-2021 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2020-2021 Nikita Kaskov <nbering@nil.foundation>
4 //
5 // MIT License
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files (the "Software"), to deal
9 // in the Software without restriction, including without limitation the rights
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 // copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included in all
15 // copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 // SOFTWARE.
24 //---------------------------------------------------------------------------//
25 // @file Declaration of interfaces for a TBCS-to-USCS reduction, that is, constructing
26 // a USCS ("Unitary-Square Constraint System") from a TBCS ("Two-input Boolean Circuit Satisfiability").
27 //
28 // The reduction is straightforward: each non-output wire is mapped to a
29 // corresponding USCS constraint that enforces the wire to carry a boolean value;
30 // each 2-input boolean gate is mapped to a corresponding USCS constraint that
31 // enforces correct computation of the gate; each output wire is mapped to a
32 // corresponding USCS constraint that enforces that the output is zero.
33 //
34 // The mapping of a gate to a USCS constraint is due to \[GOS12].
35 //
36 // References:
37 //
38 // \[GOS12]:
39 // "New techniques for noninteractive zero-knowledge",
40 // Jens Groth, Rafail Ostrovsky, Amit Sahai
41 // JACM 2012,
42 // <http://www0.cs.ucl.ac.uk/staff/J.Groth/NIZKJournal.pdf>
43 //---------------------------------------------------------------------------//
44 
45 #ifndef CRYPTO3_ZK_TBCS_TO_USCS_BASIC_POLICY_HPP
46 #define CRYPTO3_ZK_TBCS_TO_USCS_BASIC_POLICY_HPP
47 
50 
51 namespace nil {
52  namespace crypto3 {
53  namespace zk {
54  namespace snark {
55  namespace reductions {
56  template<typename FieldType>
57  struct tbcs_to_uscs {
58  typedef FieldType field_type;
59 
64  assert(circuit.is_valid());
66 
67  result.primary_input_size = circuit.primary_input_size;
68  result.auxiliary_input_size = circuit.auxiliary_input_size + circuit.gates.size();
69 
70  for (auto &g : circuit.gates) {
71  const variable<FieldType> x(g.left_wire);
72  const variable<FieldType> y(g.right_wire);
73  const variable<FieldType> z(g.output);
74 
75  switch (g.type) {
77  /* Truth table (00, 01, 10, 11): (0, 0, 0, 0)
78  0 * x + 0 * y + 1 * z + 1 \in {-1, 1} */
79  result.add_constraint(0 * x + 0 * y + 1 * z + 1);
80  break;
81  case TBCS_GATE_AND:
82  /* Truth table (00, 01, 10, 11): (0, 0, 0, 1)
83  -2 * x + -2 * y + 4 * z + 1 \in {-1, 1} */
84  result.add_constraint(-2 * x + -2 * y + 4 * z + 1);
85  break;
87  /* Truth table (00, 01, 10, 11): (0, 0, 1, 0)
88  -2 * x + 2 * y + 4 * z + -1 \in {-1, 1} */
89  result.add_constraint(-2 * x + 2 * y + 4 * z + -1);
90  break;
91  case TBCS_GATE_X:
92  /* Truth table (00, 01, 10, 11): (0, 0, 1, 1)
93  -1 * x + 0 * y + 1 * z + 1 \in {-1, 1} */
94  result.add_constraint(-1 * x + 0 * y + 1 * z + 1);
95  break;
97  /* Truth table (00, 01, 10, 11): (0, 1, 0, 0)
98  2 * x + -2 * y + 4 * z + -1 \in {-1, 1} */
99  result.add_constraint(2 * x + -2 * y + 4 * z + -1);
100  break;
101  case TBCS_GATE_Y:
102  /* Truth table (00, 01, 10, 11): (0, 1, 0, 1)
103  0 * x + 1 * y + 1 * z + -1 \in {-1, 1} */
104  result.add_constraint(0 * x + 1 * y + 1 * z + -1);
105  break;
106  case TBCS_GATE_XOR:
107  /* Truth table (00, 01, 10, 11): (0, 1, 1, 0)
108  1 * x + 1 * y + 1 * z + -1 \in {-1, 1} */
109  result.add_constraint(1 * x + 1 * y + 1 * z + -1);
110  break;
111  case TBCS_GATE_OR:
112  /* Truth table (00, 01, 10, 11): (0, 1, 1, 1)
113  -2 * x + -2 * y + 4 * z + -1 \in {-1, 1} */
114  result.add_constraint(-2 * x + -2 * y + 4 * z + -1);
115  break;
116  case TBCS_GATE_NOR:
117  /* Truth table (00, 01, 10, 11): (1, 0, 0, 0)
118  2 * x + 2 * y + 4 * z + -3 \in {-1, 1} */
119  result.add_constraint(2 * x + 2 * y + 4 * z + -3);
120  break;
122  /* Truth table (00, 01, 10, 11): (1, 0, 0, 1)
123  1 * x + 1 * y + 1 * z + -2 \in {-1, 1} */
124  result.add_constraint(1 * x + 1 * y + 1 * z + -2);
125  break;
126  case TBCS_GATE_NOT_Y:
127  /* Truth table (00, 01, 10, 11): (1, 0, 1, 0)
128  0 * x + -1 * y + 1 * z + 0 \in {-1, 1} */
129  result.add_constraint(0 * x + -1 * y + 1 * z + 0);
130  break;
132  /* Truth table (00, 01, 10, 11): (1, 0, 1, 1)
133  -2 * x + 2 * y + 4 * z + -3 \in {-1, 1} */
134  result.add_constraint(-2 * x + 2 * y + 4 * z + -3);
135  break;
136  case TBCS_GATE_NOT_X:
137  /* Truth table (00, 01, 10, 11): (1, 1, 0, 0)
138  -1 * x + 0 * y + 1 * z + 0 \in {-1, 1} */
139  result.add_constraint(-1 * x + 0 * y + 1 * z + 0);
140  break;
142  /* Truth table (00, 01, 10, 11): (1, 1, 0, 1)
143  2 * x + -2 * y + 4 * z + -3 \in {-1, 1} */
144  result.add_constraint(2 * x + -2 * y + 4 * z + -3);
145  break;
146  case TBCS_GATE_NAND:
147  /* Truth table (00, 01, 10, 11): (1, 1, 1, 0)
148  2 * x + 2 * y + 4 * z + -5 \in {-1, 1} */
149  result.add_constraint(2 * x + 2 * y + 4 * z + -5);
150  break;
152  /* Truth table (00, 01, 10, 11): (1, 1, 1, 1)
153  0 * x + 0 * y + 1 * z + 0 \in {-1, 1} */
154  result.add_constraint(0 * x + 0 * y + 1 * z + 0);
155  break;
156  default:
157  assert(0);
158  }
159  }
160 
161  for (std::size_t i = 0;
162  i < circuit.primary_input_size + circuit.auxiliary_input_size + circuit.gates.size();
163  ++i) {
164  /* require that 2 * wire - 1 \in {-1,1}, that is wire \in {0,1} */
165  result.add_constraint(2 * variable<FieldType>(i) - 1);
166  }
167 
168  for (auto &g : circuit.gates) {
169  if (g.is_circuit_output) {
170  /* require that output + 1 \in {-1,1}, this together with output binary (above)
171  * enforces output = 0 */
172  result.add_constraint(variable<FieldType>(g.output) + 1);
173  }
174  }
175 
176  return result;
177  }
178 
183  witness_map(const tbcs_circuit &circuit,
184  const tbcs_primary_input &primary_input,
185  const tbcs_auxiliary_input &auxiliary_input) {
186 
187  const tbcs_variable_assignment all_wires =
188  circuit.get_all_wires(primary_input, auxiliary_input);
190  algebra::convert_bit_vector_to_field_element_vector<FieldType>(all_wires);
191  return result;
192  }
193  };
194  } // namespace reductions
195  } // namespace snark
196  } // namespace zk
197  } // namespace crypto3
198 } // namespace nil
199 
200 #endif // CRYPTO3_ZK_TBCS_TO_USCS_BASIC_POLICY_HPP
@ TBCS_GATE_NOT_X
Definition: tbcs.hpp:84
@ TBCS_GATE_EQUIVALENCE
Definition: tbcs.hpp:81
@ TBCS_GATE_IF_X_THEN_Y
Definition: tbcs.hpp:85
@ TBCS_GATE_CONSTANT_0
Definition: tbcs.hpp:72
@ TBCS_GATE_NOT_Y
Definition: tbcs.hpp:82
@ TBCS_GATE_OR
Definition: tbcs.hpp:79
@ TBCS_GATE_Y
Definition: tbcs.hpp:77
@ TBCS_GATE_XOR
Definition: tbcs.hpp:78
@ TBCS_GATE_NOT_X_AND_Y
Definition: tbcs.hpp:76
@ TBCS_GATE_AND
Definition: tbcs.hpp:73
@ TBCS_GATE_X_AND_NOT_Y
Definition: tbcs.hpp:74
@ TBCS_GATE_X
Definition: tbcs.hpp:75
@ TBCS_GATE_NOR
Definition: tbcs.hpp:80
@ TBCS_GATE_NAND
Definition: tbcs.hpp:86
@ TBCS_GATE_IF_Y_THEN_X
Definition: tbcs.hpp:83
@ TBCS_GATE_CONSTANT_1
Definition: tbcs.hpp:87
tbcs_variable_assignment tbcs_primary_input
Definition: tbcs.hpp:140
tbcs_variable_assignment tbcs_auxiliary_input
Definition: tbcs.hpp:145
std::vector< typename FieldType::value_type > uscs_variable_assignment
Definition: uscs.hpp:73
std::vector< bool > tbcs_variable_assignment
Definition: tbcs.hpp:48
Definition: pair.hpp:31
static uscs_constraint_system< FieldType > instance_map(const tbcs_circuit &circuit)
Definition: tbcs_to_uscs.hpp:63
FieldType field_type
Definition: tbcs_to_uscs.hpp:58
static uscs_variable_assignment< FieldType > witness_map(const tbcs_circuit &circuit, const tbcs_primary_input &primary_input, const tbcs_auxiliary_input &auxiliary_input)
Definition: tbcs_to_uscs.hpp:183
bool is_valid() const
Definition: tbcs.hpp:195
std::vector< tbcs_gate > gates
Definition: tbcs.hpp:163
tbcs_variable_assignment get_all_wires(const tbcs_primary_input &primary_input, const tbcs_auxiliary_input &auxiliary_input) const
Definition: tbcs.hpp:228
std::size_t primary_input_size
Definition: tbcs.hpp:161
std::size_t auxiliary_input_size
Definition: tbcs.hpp:162
void add_constraint(const uscs_constraint< FieldType > &constraint)
Definition: uscs.hpp:143
std::size_t auxiliary_input_size
Definition: uscs.hpp:93
std::size_t primary_input_size
Definition: uscs.hpp:92
Definition: variable.hpp:66