sha256_aux.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 auxiliary components for the SHA256 component.
26 //---------------------------------------------------------------------------//
27 
28 #ifndef CRYPTO3_ZK_BLUEPRINT_SHA256_AUX_HPP
29 #define CRYPTO3_ZK_BLUEPRINT_SHA256_AUX_HPP
30 
33 
34 namespace nil {
35  namespace crypto3 {
36  namespace zk {
37  namespace components {
38 
39  template<typename FieldType>
40  class lastbits_component : public component<FieldType> {
41  public:
43  std::size_t X_bits;
46 
48  std::shared_ptr<packing_component<FieldType>> unpack_bits;
49  std::shared_ptr<packing_component<FieldType>> pack_result;
50 
53  std::size_t X_bits,
56  component<FieldType>(bp),
58 
60  for (std::size_t i = result_bits.size(); i < X_bits; ++i) {
61  blueprint_variable<FieldType> full_bits_overflow;
62  full_bits_overflow.allocate(bp);
63  full_bits.emplace_back(full_bits_overflow);
64  }
65 
68  }
69 
71  unpack_bits->generate_r1cs_constraints(true);
72  pack_result->generate_r1cs_constraints(false);
73  }
74 
76  unpack_bits->generate_r1cs_witness_from_packed();
77  pack_result->generate_r1cs_witness_from_bits();
78  }
79  };
80 
81  template<typename FieldType>
82  class XOR3_component : public component<FieldType> {
83  private:
85 
86  public:
92 
97  bool assume_C_is_zero,
99  component<FieldType>(bp),
101  if (!assume_C_is_zero) {
102  tmp.allocate(bp);
103  }
104  }
105 
107  /*
108  tmp = A + B - 2AB i.e. tmp = A xor B
109  out = tmp + C - 2tmp C i.e. out = tmp xor C
110  */
111  if (assume_C_is_zero) {
112  this->bp.add_r1cs_constraint(snark::r1cs_constraint<FieldType>(2 * A, B, A + B - out));
113  } else {
114  this->bp.add_r1cs_constraint(snark::r1cs_constraint<FieldType>(2 * A, B, A + B - tmp));
115  this->bp.add_r1cs_constraint(snark::r1cs_constraint<FieldType>(2 * tmp, C, tmp + C - out));
116  }
117  }
118 
120  if (assume_C_is_zero) {
121  this->bp.lc_val(out) =
122  this->bp.lc_val(A) + this->bp.lc_val(B) -
123  typename FieldType::value_type(0x02) * this->bp.lc_val(A) * this->bp.lc_val(B);
124  } else {
125  this->bp.val(tmp) =
126  this->bp.lc_val(A) + this->bp.lc_val(B) -
127  typename FieldType::value_type(0x02) * this->bp.lc_val(A) * this->bp.lc_val(B);
128  this->bp.lc_val(out) =
129  this->bp.val(tmp) + this->bp.lc_val(C) -
130  typename FieldType::value_type(0x02) * this->bp.val(tmp) * this->bp.lc_val(C);
131  }
132  }
133  };
134 
135 #define SHA256_COMPONENT_ROTR(A, i, k) A[((i) + (k)) % 32]
136 
137  /* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */
138  template<typename FieldType>
139  class small_sigma_component : public component<FieldType> {
140  private:
143 
144  public:
146  std::vector<std::shared_ptr<XOR3_component<FieldType>>> compute_bits;
147  std::shared_ptr<packing_component<FieldType>> pack_result;
148 
151  const blueprint_variable<FieldType> &result,
152  std::size_t rot1,
153  std::size_t rot2,
154  std::size_t shift) :
155  component<FieldType>(bp),
156  W(W), result(result) {
157 
158  result_bits.allocate(bp, 32);
159  compute_bits.resize(32);
160  for (std::size_t i = 0; i < 32; ++i) {
162  bp, SHA256_COMPONENT_ROTR(W, i, rot1), SHA256_COMPONENT_ROTR(W, i, rot2),
163  (i + shift < 32 ? W[i + shift] : blueprint_variable<FieldType>(0)), (i + shift >= 32),
164  result_bits[i]));
165  }
167  }
168 
170  for (std::size_t i = 0; i < 32; ++i) {
171  compute_bits[i]->generate_r1cs_constraints();
172  }
173 
174  pack_result->generate_r1cs_constraints(false);
175  }
176 
178  for (std::size_t i = 0; i < 32; ++i) {
179  compute_bits[i]->generate_r1cs_witness();
180  }
181 
182  pack_result->generate_r1cs_witness_from_bits();
183  }
184  };
185 
186  /* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */
187  template<typename FieldType>
188  class big_sigma_component : public component<FieldType> {
189  private:
192 
193  public:
195  std::vector<std::shared_ptr<XOR3_component<FieldType>>> compute_bits;
196  std::shared_ptr<packing_component<FieldType>> pack_result;
197 
200  const blueprint_variable<FieldType> &result,
201  std::size_t rot1,
202  std::size_t rot2,
203  std::size_t rot3) :
204  component<FieldType>(bp),
205  W(W), result(result) {
206 
207  result_bits.allocate(bp, 32);
208  compute_bits.resize(32);
209  for (std::size_t i = 0; i < 32; ++i) {
211  bp, SHA256_COMPONENT_ROTR(W, i, rot1), SHA256_COMPONENT_ROTR(W, i, rot2),
212  SHA256_COMPONENT_ROTR(W, i, rot3), false, result_bits[i]));
213  }
214 
216  }
217 
219  for (std::size_t i = 0; i < 32; ++i) {
220  compute_bits[i]->generate_r1cs_constraints();
221  }
222 
223  pack_result->generate_r1cs_constraints(false);
224  }
225 
227  for (std::size_t i = 0; i < 32; ++i) {
228  compute_bits[i]->generate_r1cs_witness();
229  }
230 
231  pack_result->generate_r1cs_witness_from_bits();
232  }
233  };
234 
235  /* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */
236  template<typename FieldType>
237  class choice_component : public component<FieldType> {
238  private:
240 
241  public:
246  std::shared_ptr<packing_component<FieldType>> pack_result;
247 
253  component<FieldType>(bp),
254  X(X), Y(Y), Z(Z), result(result) {
255 
256  result_bits.allocate(bp, 32);
257  pack_result.reset(new packing_component<FieldType>(bp, result_bits, result));
258  }
259 
261  for (std::size_t i = 0; i < 32; ++i) {
262  /*
263  result = x * y + (1-x) * z
264  result - z = x * (y - z)
265  */
266  this->bp.add_r1cs_constraint(
267  snark::r1cs_constraint<FieldType>(X[i], Y[i] - Z[i], result_bits[i] - Z[i]));
268  }
269  pack_result->generate_r1cs_constraints(false);
270  }
271 
273  for (std::size_t i = 0; i < 32; ++i) {
274  this->bp.val(result_bits[i]) =
275  this->bp.lc_val(X[i]) * this->bp.lc_val(Y[i]) +
276  (FieldType::value_type::one() - this->bp.lc_val(X[i])) * this->bp.lc_val(Z[i]);
277  }
278  pack_result->generate_r1cs_witness_from_bits();
279  }
280  };
281 
282  /* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */
283  template<typename FieldType>
284  class majority_component : public component<FieldType> {
285  private:
287  std::shared_ptr<packing_component<FieldType>> pack_result;
288 
289  public:
294 
300  component<FieldType>(bp),
301  X(X), Y(Y), Z(Z), result(result) {
302  result_bits.allocate(bp, 32);
303  pack_result.reset(new packing_component<FieldType>(bp, result_bits, result));
304  }
305 
307  for (std::size_t i = 0; i < 32; ++i) {
308  /*
309  2*result + aux = x + y + z
310  x, y, z, aux -- bits
311  aux = x + y + z - 2*result
312  */
313  generate_boolean_r1cs_constraint<FieldType>(this->bp, result_bits[i]);
314  this->bp.add_r1cs_constraint(
315  snark::r1cs_constraint<FieldType>(X[i] + Y[i] + Z[i] - 2 * result_bits[i],
316  1 - (X[i] + Y[i] + Z[i] - 2 * result_bits[i]), 0));
317  }
318  pack_result->generate_r1cs_constraints(false);
319  }
320 
322 
323  // temporary added until fixed-precision modular adaptor is ready:
324  typedef nil::crypto3::multiprecision::number<
325  nil::crypto3::multiprecision::backends::cpp_int_backend<>>
326  non_fixed_precision_integral_type;
327 
328  using integral_type = typename FieldType::integral_type;
329 
330  for (std::size_t i = 0; i < 32; ++i) {
331  const non_fixed_precision_integral_type v = non_fixed_precision_integral_type(
332  (this->bp.lc_val(X[i]) + this->bp.lc_val(Y[i]) + this->bp.lc_val(Z[i])).data);
333  this->bp.val(result_bits[i]) = typename FieldType::value_type(integral_type(v / 2));
334  }
335 
336  pack_result->generate_r1cs_witness_from_bits();
337  }
338  };
339 
340  } // namespace components
341  } // namespace zk
342  } // namespace crypto3
343 } // namespace nil
344 
345 #endif // CRYPTO3_ZK_BLUEPRINT_SHA256_AUX_HPP
blueprint_linear_combination< FieldType > B
Definition: sha256_aux.hpp:88
blueprint_linear_combination< FieldType > C
Definition: sha256_aux.hpp:89
XOR3_component(blueprint< FieldType > &bp, const blueprint_linear_combination< FieldType > &A, const blueprint_linear_combination< FieldType > &B, const blueprint_linear_combination< FieldType > &C, bool assume_C_is_zero, const blueprint_linear_combination< FieldType > &out)
Definition: sha256_aux.hpp:93
bool assume_C_is_zero
Definition: sha256_aux.hpp:90
void generate_r1cs_constraints()
Definition: sha256_aux.hpp:106
void generate_r1cs_witness()
Definition: sha256_aux.hpp:119
blueprint_linear_combination< FieldType > A
Definition: sha256_aux.hpp:87
blueprint_linear_combination< FieldType > out
Definition: sha256_aux.hpp:91
void generate_r1cs_constraints()
Definition: sha256_aux.hpp:218
std::vector< std::shared_ptr< XOR3_component< FieldType > > > compute_bits
Definition: sha256_aux.hpp:195
std::shared_ptr< packing_component< FieldType > > pack_result
Definition: sha256_aux.hpp:196
big_sigma_component(blueprint< FieldType > &bp, const blueprint_linear_combination_vector< FieldType > &W, const blueprint_variable< FieldType > &result, std::size_t rot1, std::size_t rot2, std::size_t rot3)
Definition: sha256_aux.hpp:198
blueprint_variable_vector< FieldType > result_bits
Definition: sha256_aux.hpp:194
void generate_r1cs_witness()
Definition: sha256_aux.hpp:226
Definition: blueprint_linear_combination.hpp:115
Definition: blueprint_linear_combination.hpp:47
Definition: blueprint_variable.hpp:57
void allocate(blueprint< field_type > &bp, const std::size_t n)
Definition: blueprint_variable.hpp:91
Definition: blueprint_variable.hpp:46
void allocate(blueprint< FieldType > &bp)
Definition: blueprint_variable.hpp:51
Definition: blueprint.hpp:46
blueprint_linear_combination_vector< FieldType > Y
Definition: sha256_aux.hpp:243
void generate_r1cs_constraints()
Definition: sha256_aux.hpp:260
std::shared_ptr< packing_component< FieldType > > pack_result
Definition: sha256_aux.hpp:246
choice_component(blueprint< FieldType > &bp, const blueprint_linear_combination_vector< FieldType > &X, const blueprint_linear_combination_vector< FieldType > &Y, const blueprint_linear_combination_vector< FieldType > &Z, const blueprint_variable< FieldType > &result)
Definition: sha256_aux.hpp:248
blueprint_variable< FieldType > result
Definition: sha256_aux.hpp:245
blueprint_linear_combination_vector< FieldType > X
Definition: sha256_aux.hpp:242
void generate_r1cs_witness()
Definition: sha256_aux.hpp:272
blueprint_linear_combination_vector< FieldType > Z
Definition: sha256_aux.hpp:244
Definition: component.hpp:37
blueprint< FieldType > & bp
Definition: component.hpp:39
std::size_t X_bits
Definition: sha256_aux.hpp:43
void generate_r1cs_witness()
Definition: sha256_aux.hpp:75
blueprint_variable< FieldType > result
Definition: sha256_aux.hpp:44
void generate_r1cs_constraints()
Definition: sha256_aux.hpp:70
blueprint_linear_combination_vector< FieldType > result_bits
Definition: sha256_aux.hpp:45
lastbits_component(blueprint< FieldType > &bp, const blueprint_variable< FieldType > &X, std::size_t X_bits, const blueprint_variable< FieldType > &result, const blueprint_linear_combination_vector< FieldType > &result_bits)
Definition: sha256_aux.hpp:51
std::shared_ptr< packing_component< FieldType > > unpack_bits
Definition: sha256_aux.hpp:48
blueprint_variable< FieldType > X
Definition: sha256_aux.hpp:42
blueprint_linear_combination_vector< FieldType > full_bits
Definition: sha256_aux.hpp:47
std::shared_ptr< packing_component< FieldType > > pack_result
Definition: sha256_aux.hpp:49
blueprint_variable< FieldType > result
Definition: sha256_aux.hpp:293
blueprint_linear_combination_vector< FieldType > X
Definition: sha256_aux.hpp:290
blueprint_linear_combination_vector< FieldType > Z
Definition: sha256_aux.hpp:292
majority_component(blueprint< FieldType > &bp, const blueprint_linear_combination_vector< FieldType > &X, const blueprint_linear_combination_vector< FieldType > &Y, const blueprint_linear_combination_vector< FieldType > &Z, const blueprint_variable< FieldType > &result)
Definition: sha256_aux.hpp:295
blueprint_linear_combination_vector< FieldType > Y
Definition: sha256_aux.hpp:291
void generate_r1cs_witness()
Definition: sha256_aux.hpp:321
void generate_r1cs_constraints()
Definition: sha256_aux.hpp:306
small_sigma_component(blueprint< FieldType > &bp, const blueprint_variable_vector< FieldType > &W, const blueprint_variable< FieldType > &result, std::size_t rot1, std::size_t rot2, std::size_t shift)
Definition: sha256_aux.hpp:149
void generate_r1cs_constraints()
Definition: sha256_aux.hpp:169
std::shared_ptr< packing_component< FieldType > > pack_result
Definition: sha256_aux.hpp:147
blueprint_variable_vector< FieldType > result_bits
Definition: sha256_aux.hpp:145
void generate_r1cs_witness()
Definition: sha256_aux.hpp:177
std::vector< std::shared_ptr< XOR3_component< FieldType > > > compute_bits
Definition: sha256_aux.hpp:146
Definition: pair.hpp:31
#define SHA256_COMPONENT_ROTR(A, i, k)
Definition: sha256_aux.hpp:135