sha256_construction.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 components for the SHA256 message schedule and round function.
26 //---------------------------------------------------------------------------//
27 
28 #ifndef CRYPTO3_ZK_BLUEPRINT_SHA256_COMPONENTS_HPP
29 #define CRYPTO3_ZK_BLUEPRINT_SHA256_COMPONENTS_HPP
30 
32 
36 
38 
39 namespace nil {
40  namespace crypto3 {
41  namespace zk {
42  namespace components {
43 
44  template<typename FieldType>
45  class sha256_message_schedule_component : public component<FieldType> {
46  public:
47  std::vector<blueprint_variable_vector<FieldType>> W_bits;
48  std::vector<std::shared_ptr<packing_component<FieldType>>> pack_W;
49 
50  std::vector<blueprint_variable<FieldType>> sigma0;
51  std::vector<blueprint_variable<FieldType>> sigma1;
52  std::vector<std::shared_ptr<small_sigma_component<FieldType>>> compute_sigma0;
53  std::vector<std::shared_ptr<small_sigma_component<FieldType>>> compute_sigma1;
54  std::vector<blueprint_variable<FieldType>> unreduced_W;
55  std::vector<std::shared_ptr<lastbits_component<FieldType>>> mod_reduce_W;
56 
57  public:
63  component<FieldType>(bp),
64  M(M), packed_W(packed_W) {
65 
66  W_bits.resize(64);
67 
68  pack_W.resize(16);
69  for (std::size_t i = 0; i < 16; ++i) {
71  M.rbegin() + (15 - i) * hashes::sha2<256>::word_bits,
72  M.rbegin() + (16 - i) * hashes::sha2<256>::word_bits);
73 
74  pack_W[i].reset(new packing_component<FieldType>(bp, W_bits[i], packed_W[i]));
75  }
76 
77  /* NB: some of those will be un-allocated */
78  sigma0.resize(64);
79  sigma1.resize(64);
80  compute_sigma0.resize(64);
81  compute_sigma1.resize(64);
82  unreduced_W.resize(64);
83  mod_reduce_W.resize(64);
84 
85  for (std::size_t i = 16; i < block::detail::shacal2_policy<256>::rounds; ++i) {
86  /* allocate result variables for sigma0/sigma1 invocations */
87  sigma0[i].allocate(bp);
88  sigma1[i].allocate(bp);
89 
90  /* compute sigma0/sigma1 */
91  compute_sigma0[i].reset(
92  new small_sigma_component<FieldType>(bp, W_bits[i - 15], sigma0[i], 7, 18, 3));
93  compute_sigma1[i].reset(
94  new small_sigma_component<FieldType>(bp, W_bits[i - 2], sigma1[i], 17, 19, 10));
95 
96  /* unreduced_W = sigma0(W_{i-15}) + sigma1(W_{i-2}) + W_{i-7} + W_{i-16} before modulo
97  * 2^32
98  */
99  unreduced_W[i].allocate(bp);
100 
101  /* allocate the bit representation of packed_W[i] */
102  W_bits[i].allocate(bp, hashes::sha2<256>::word_bits);
103 
104  /* and finally reduce this into packed and bit representations */
107  }
108  }
109 
111  for (std::size_t i = 0; i < 16; ++i) {
112  pack_W[i]->generate_r1cs_constraints(
113  false); // do not enforce bitness here; caller be aware.
114  }
115 
116  for (std::size_t i = 16; i < block::detail::shacal2_policy<256>::rounds; ++i) {
117  compute_sigma0[i]->generate_r1cs_constraints();
118  compute_sigma1[i]->generate_r1cs_constraints();
119 
120  this->bp.add_r1cs_constraint(snark::r1cs_constraint<FieldType>(
121  1, sigma0[i] + sigma1[i] + packed_W[i - 16] + packed_W[i - 7], unreduced_W[i]));
122 
123  mod_reduce_W[i]->generate_r1cs_constraints();
124  }
125  }
126 
128  for (std::size_t i = 0; i < 16; ++i) {
129  pack_W[i]->generate_r1cs_witness_from_bits();
130  }
131 
132  for (std::size_t i = 16; i < block::detail::shacal2_policy<256>::rounds; ++i) {
133  compute_sigma0[i]->generate_r1cs_witness();
134  compute_sigma1[i]->generate_r1cs_witness();
135 
136  this->bp.val(unreduced_W[i]) = this->bp.val(sigma0[i]) + this->bp.val(sigma1[i]) +
137  this->bp.val(packed_W[i - 16]) +
138  this->bp.val(packed_W[i - 7]);
139 
140  mod_reduce_W[i]->generate_r1cs_witness();
141  }
142  }
143  };
144 
145  template<typename FieldType>
146  class sha256_round_function_component : public component<FieldType> {
147  public:
150  std::shared_ptr<big_sigma_component<FieldType>> compute_sigma0;
151  std::shared_ptr<big_sigma_component<FieldType>> compute_sigma1;
154  std::shared_ptr<choice_component<FieldType>> compute_choice;
155  std::shared_ptr<majority_component<FieldType>> compute_majority;
157  std::shared_ptr<packing_component<FieldType>> pack_d;
159  std::shared_ptr<packing_component<FieldType>> pack_h;
162  std::shared_ptr<lastbits_component<FieldType>> mod_reduce_new_a;
163  std::shared_ptr<lastbits_component<FieldType>> mod_reduce_new_e;
166 
167  public:
177  long K;
180 
191  const long &K,
194  component<FieldType>(bp),
195  a(a), b(b), c(c), d(d), e(e), f(f), g(g), h(h), W(W), K(K), new_a(new_a), new_e(new_e) {
196 
197  /* compute sigma0 and sigma1 */
198  sigma0.allocate(bp);
199  sigma1.allocate(bp);
200  compute_sigma0.reset(new big_sigma_component<FieldType>(bp, a, sigma0, 2, 13, 22));
201  compute_sigma1.reset(new big_sigma_component<FieldType>(bp, e, sigma1, 6, 11, 25));
202 
203  /* compute choice */
204  choice.allocate(bp);
206 
207  /* compute majority */
208  majority.allocate(bp);
210 
211  /* pack d */
212  packed_d.allocate(bp);
214 
215  /* pack h */
216  packed_h.allocate(bp);
218 
219  /* compute the actual results for the round */
220  unreduced_new_a.allocate(bp);
221  unreduced_new_e.allocate(bp);
222 
223  packed_new_a.allocate(bp);
224  packed_new_e.allocate(bp);
225 
230  }
231 
233  compute_sigma0->generate_r1cs_constraints();
234  compute_sigma1->generate_r1cs_constraints();
235 
236  compute_choice->generate_r1cs_constraints();
237  compute_majority->generate_r1cs_constraints();
238 
239  pack_d->generate_r1cs_constraints(false);
240  pack_h->generate_r1cs_constraints(false);
241 
242  this->bp.add_r1cs_constraint(snark::r1cs_constraint<FieldType>(
244 
245  this->bp.add_r1cs_constraint(snark::r1cs_constraint<FieldType>(
246  1, packed_d + packed_h + sigma1 + choice + K + W, unreduced_new_e));
247 
248  mod_reduce_new_a->generate_r1cs_constraints();
249  mod_reduce_new_e->generate_r1cs_constraints();
250  }
251 
253  compute_sigma0->generate_r1cs_witness();
254  compute_sigma1->generate_r1cs_witness();
255 
256  compute_choice->generate_r1cs_witness();
257  compute_majority->generate_r1cs_witness();
258  pack_d->generate_r1cs_witness_from_bits();
259  pack_h->generate_r1cs_witness_from_bits();
260 
261  this->bp.val(unreduced_new_a) = this->bp.val(packed_h) + this->bp.val(sigma1) +
262  this->bp.val(choice) + typename FieldType::value_type(K) +
263  this->bp.val(W) + this->bp.val(sigma0) + this->bp.val(majority);
264  this->bp.val(unreduced_new_e) = this->bp.val(packed_d) + this->bp.val(packed_h) +
265  this->bp.val(sigma1) + this->bp.val(choice) +
266  typename FieldType::value_type(K) + this->bp.val(W);
267 
268  mod_reduce_new_a->generate_r1cs_witness();
269  mod_reduce_new_e->generate_r1cs_witness();
270  }
271  };
272 
273  template<typename FieldType>
275  using namespace hashes::detail;
276 
277  typename sha2_policy<256>::state_type iv = sha2_policy<256>::iv_generator()();
278 
280  result.reserve(hashes::sha2<256>::digest_bits);
281 
282  for (std::size_t i = 0; i < hashes::sha2<256>::digest_bits; ++i) {
283  int iv_val =
285 
287  iv_element.assign(bp, iv_val * blueprint_variable<FieldType>(0));
288  iv_element.evaluate(bp);
289 
290  result.emplace_back(iv_element);
291  }
292 
293  return result;
294  }
295 
296  } // namespace components
297  } // namespace zk
298  } // namespace crypto3
299 } // namespace nil
300 
301 #endif // CRYPTO3_ZK_BLUEPRINT_SHA256_COMPONENTS_HPP
SHA2.
Definition: sha2.hpp:46
Definition: blueprint_linear_combination.hpp:115
Definition: blueprint_linear_combination.hpp:47
void assign(blueprint< field_type > &bp, const snark::linear_combination< field_type > &lc)
Definition: blueprint_linear_combination.hpp:65
void evaluate(blueprint< field_type > &bp) const
Definition: blueprint_linear_combination.hpp:71
Definition: blueprint_variable.hpp:57
Definition: blueprint_variable.hpp:46
Definition: blueprint.hpp:46
Definition: component.hpp:37
blueprint< FieldType > & bp
Definition: component.hpp:39
blueprint_variable_vector< FieldType > M
Definition: sha256_construction.hpp:58
std::vector< blueprint_variable< FieldType > > sigma0
Definition: sha256_construction.hpp:50
std::vector< std::shared_ptr< packing_component< FieldType > > > pack_W
Definition: sha256_construction.hpp:48
std::vector< std::shared_ptr< lastbits_component< FieldType > > > mod_reduce_W
Definition: sha256_construction.hpp:55
void generate_r1cs_constraints()
Definition: sha256_construction.hpp:110
std::vector< std::shared_ptr< small_sigma_component< FieldType > > > compute_sigma1
Definition: sha256_construction.hpp:53
std::vector< std::shared_ptr< small_sigma_component< FieldType > > > compute_sigma0
Definition: sha256_construction.hpp:52
std::vector< blueprint_variable< FieldType > > unreduced_W
Definition: sha256_construction.hpp:54
void generate_r1cs_witness()
Definition: sha256_construction.hpp:127
std::vector< blueprint_variable< FieldType > > sigma1
Definition: sha256_construction.hpp:51
sha256_message_schedule_component(blueprint< FieldType > &bp, const blueprint_variable_vector< FieldType > &M, const blueprint_variable_vector< FieldType > &packed_W)
Definition: sha256_construction.hpp:60
std::vector< blueprint_variable_vector< FieldType > > W_bits
Definition: sha256_construction.hpp:47
blueprint_variable_vector< FieldType > packed_W
Definition: sha256_construction.hpp:59
void generate_r1cs_constraints()
Definition: sha256_construction.hpp:232
blueprint_linear_combination_vector< FieldType > d
Definition: sha256_construction.hpp:171
blueprint_variable< FieldType > W
Definition: sha256_construction.hpp:176
std::shared_ptr< packing_component< FieldType > > pack_d
Definition: sha256_construction.hpp:157
sha256_round_function_component(blueprint< FieldType > &bp, const blueprint_linear_combination_vector< FieldType > &a, const blueprint_linear_combination_vector< FieldType > &b, const blueprint_linear_combination_vector< FieldType > &c, const blueprint_linear_combination_vector< FieldType > &d, const blueprint_linear_combination_vector< FieldType > &e, const blueprint_linear_combination_vector< FieldType > &f, const blueprint_linear_combination_vector< FieldType > &g, const blueprint_linear_combination_vector< FieldType > &h, const blueprint_variable< FieldType > &W, const long &K, const blueprint_linear_combination_vector< FieldType > &new_a, const blueprint_linear_combination_vector< FieldType > &new_e)
Definition: sha256_construction.hpp:181
long K
Definition: sha256_construction.hpp:177
blueprint_variable< FieldType > packed_h
Definition: sha256_construction.hpp:158
blueprint_linear_combination_vector< FieldType > b
Definition: sha256_construction.hpp:169
blueprint_linear_combination_vector< FieldType > h
Definition: sha256_construction.hpp:175
blueprint_variable< FieldType > majority
Definition: sha256_construction.hpp:153
blueprint_linear_combination_vector< FieldType > new_e
Definition: sha256_construction.hpp:179
blueprint_variable< FieldType > packed_d
Definition: sha256_construction.hpp:156
std::shared_ptr< majority_component< FieldType > > compute_majority
Definition: sha256_construction.hpp:155
std::shared_ptr< choice_component< FieldType > > compute_choice
Definition: sha256_construction.hpp:154
blueprint_linear_combination_vector< FieldType > new_a
Definition: sha256_construction.hpp:178
blueprint_variable< FieldType > sigma1
Definition: sha256_construction.hpp:149
blueprint_variable< FieldType > packed_new_a
Definition: sha256_construction.hpp:164
blueprint_linear_combination_vector< FieldType > e
Definition: sha256_construction.hpp:172
blueprint_linear_combination_vector< FieldType > g
Definition: sha256_construction.hpp:174
void generate_r1cs_witness()
Definition: sha256_construction.hpp:252
std::shared_ptr< big_sigma_component< FieldType > > compute_sigma0
Definition: sha256_construction.hpp:150
blueprint_linear_combination_vector< FieldType > f
Definition: sha256_construction.hpp:173
blueprint_variable< FieldType > packed_new_e
Definition: sha256_construction.hpp:165
std::shared_ptr< big_sigma_component< FieldType > > compute_sigma1
Definition: sha256_construction.hpp:151
blueprint_variable< FieldType > sigma0
Definition: sha256_construction.hpp:148
blueprint_linear_combination_vector< FieldType > c
Definition: sha256_construction.hpp:170
blueprint_linear_combination_vector< FieldType > a
Definition: sha256_construction.hpp:168
std::shared_ptr< lastbits_component< FieldType > > mod_reduce_new_e
Definition: sha256_construction.hpp:163
blueprint_variable< FieldType > unreduced_new_e
Definition: sha256_construction.hpp:161
blueprint_variable< FieldType > choice
Definition: sha256_construction.hpp:152
blueprint_variable< FieldType > unreduced_new_a
Definition: sha256_construction.hpp:160
std::shared_ptr< packing_component< FieldType > > pack_h
Definition: sha256_construction.hpp:159
std::shared_ptr< lastbits_component< FieldType > > mod_reduce_new_a
Definition: sha256_construction.hpp:162
blueprint_linear_combination_vector< FieldType > SHA256_default_IV(blueprint< FieldType > &bp)
Definition: sha256_construction.hpp:274
Definition: pair.hpp:31