ctr.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2019 Mikhail Komarov <nemo@nil.foundation>
3 //
4 // MIT License
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to deal
8 // in the Software without restriction, including without limitation the rights
9 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 // copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in all
14 // copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 // SOFTWARE.
23 //---------------------------------------------------------------------------//
24 
25 #ifndef CRYPTO3_BLOCK_MODE_CIPHER_BLOCK_CHAINING_HPP
26 #define CRYPTO3_BLOCK_MODE_CIPHER_BLOCK_CHAINING_HPP
27 
28 #include <boost/integer.hpp>
29 
33 
35 
36 //#include <nil/crypto3/codec/logic.hpp>
37 
38 namespace nil {
39  namespace crypto3 {
40  namespace block {
41  namespace modes {
42  namespace detail {
43  template<typename Cipher, typename Padding, template<typename> class Allocator = std::allocator>
44  struct ctr_policy {
45  typedef std::size_t size_type;
46 
47  typedef Cipher cipher_type;
48  typedef Padding padding_type;
49 
50  constexpr static const size_type block_bits = cipher_type::block_bits;
51  constexpr static const size_type block_words = cipher_type::block_words;
52  typedef typename cipher_type::block_type block_type;
53 
54  typedef std::vector<boost::uint_t<CHAR_BIT>, Allocator<boost::uint_t<CHAR_BIT>>> iv_type;
55  };
56 
57  template<typename Cipher, typename Padding, typename CiphertextStealingMode>
58  struct ctr_encryption_policy : public ctr_policy<Cipher, Padding> {};
59 
60  template<typename Cipher, typename Padding>
61  struct ctr_encryption_policy<Cipher, Padding, cts<0, Cipher, Padding>>
62  : public ctr_policy<Cipher, Padding> {
64 
67 
71 
73 
74  inline static block_type begin_message(const cipher_type &cipher, const block_type &plaintext,
75  const iv_type &iv = iv_type()) {
76  block_type block = {0};
77 
78  // codec::encode<codec::encoder::logic_xor>(plaintext, iv,
79  // block.begin());
80 
81  return cipher.encrypt(block);
82  }
83 
84  inline static block_type process_block(const cipher_type &cipher, const block_type &plaintext,
85  const block_type &previous = block_type()) {
86  block_type block = {0};
87 
88  // codec::encode<codec::encoder::logic_xor>(plaintext, previous,
89  // block.begin());
90 
91  return cipher.encrypt(block);
92  }
93 
94  inline static block_type end_message(const cipher_type &cipher, const block_type &plaintext,
95  const block_type &previous = block_type(),
96  const iv_type &iv = iv_type()) {
97  block_type result = {0};
98  std::array<uint8_t, block_bits / CHAR_BIT> byte_array = {0};
99 
100  pack(plaintext, byte_array);
101 
102  size_type rem = std::count(byte_array.begin(), byte_array.end(), block_type::value_type()) %
103  (block_bits / CHAR_BIT);
104  if (rem || padding_type::always_pad) {
105  block_type padbuffer = padding_type::pad(plaintext, rem), block;
106  // codec::encode<codec::encoder::logic_xor>(!iv.empty() ? iv
107  // : previous, padbuffer, block .begin());
108  result = cipher.encrypt(block);
109  }
110 
111  return result;
112  }
113  };
114 
115  template<typename Cipher, typename Padding>
116  struct ctr_encryption_policy<Cipher, Padding, cts<1, Cipher, Padding>>
117  : public ctr_policy<Cipher, Padding> {
119 
122 
126 
128 
129  inline static block_type begin_message(const cipher_type &cipher, const block_type &plaintext,
130  const iv_type &iv = iv_type()) {
131  block_type block = {0};
132 
133  // codec::encode<codec::encoder::logic_xor>(plaintext, iv,
134  // block.begin());
135 
136  return cipher.encrypt(block);
137  }
138 
139  inline static block_type process_block(const cipher_type &cipher, const block_type &plaintext,
140  const block_type &previous = block_type()) {
141  block_type block = {0};
142 
143  // codec::encode<codec::encoder::logic_xor>(plaintext, previous,
144  // block.begin());
145 
146  return cipher.encrypt(block);
147  }
148 
149  inline static block_type end_message(const cipher_type &cipher, const block_type &plaintext,
150  const block_type &previous = block_type(),
151  const iv_type &iv = iv_type()) {
152  block_type result = {0};
153  std::array<uint8_t, block_bits / CHAR_BIT> byte_array = {0};
154 
155  pack(plaintext, byte_array);
156 
157  size_type rem = std::count(byte_array.begin(), byte_array.end(), block_type::value_type()) %
158  (block_bits / CHAR_BIT);
159  if (rem || padding_type::always_pad) {
160  block_type padbuffer = padding_type::pad(plaintext, rem), block;
161  // codec::encode<codec::encoder::logic_xor>(!iv.empty() ? iv
162  // : previous, padbuffer, block .begin());
163  result = cipher.encrypt(block);
164  }
165 
166  return result;
167  }
168  };
169 
170  template<typename Cipher, typename Padding>
171  struct ctr_encryption_policy<Cipher, Padding, cts<2, Cipher, Padding>>
172  : public ctr_policy<Cipher, Padding> {
174 
177 
181 
183 
184  inline static block_type begin_message(const cipher_type &cipher, const block_type &plaintext,
185  const iv_type &iv = iv_type()) {
186  block_type block = {0};
187 
188  // codec::encode<codec::encoder::logic_xor>(plaintext, iv,
189  // block.begin());
190 
191  return cipher.encrypt(block);
192  }
193 
194  inline static block_type process_block(const cipher_type &cipher, const block_type &plaintext,
195  const block_type &previous = block_type()) {
196  block_type block = {0};
197 
198  // codec::encode<codec::encoder::logic_xor>(plaintext, previous,
199  // block.begin());
200 
201  return cipher.encrypt(block);
202  }
203 
204  inline static block_type end_message(const cipher_type &cipher, const block_type &plaintext,
205  const block_type &previous = block_type(),
206  const iv_type &iv = iv_type()) {
207  block_type result = {0};
208  std::array<uint8_t, block_bits / CHAR_BIT> byte_array = {0};
209 
210  pack(plaintext, byte_array);
211 
212  size_type rem = std::count(byte_array.begin(), byte_array.end(), block_type::value_type()) %
213  (block_bits / CHAR_BIT);
214  if (rem || padding_type::always_pad) {
215  block_type padbuffer = padding_type::pad(plaintext, rem), block;
216  // codec::encode<codec::encoder::logic_xor>(!iv.empty() ? iv
217  // : previous, padbuffer, block .begin());
218  result = cipher.encrypt(block);
219  }
220 
221  return result;
222  }
223  };
224 
225  template<typename Cipher, typename Padding>
226  struct ctr_encryption_policy<Cipher, Padding, cts<3, Cipher, Padding>>
227  : public ctr_policy<Cipher, Padding> {
229 
232 
236 
238 
239  inline static block_type begin_message(const cipher_type &cipher, const block_type &plaintext,
240  const iv_type &iv = iv_type()) {
241  block_type block = {0};
242 
243  // codec::encode<codec::encoder::logic_xor>(plaintext, iv,
244  // block.begin());
245 
246  return cipher.encrypt(block);
247  }
248 
249  inline static block_type process_block(const cipher_type &cipher, const block_type &plaintext,
250  const block_type &previous = block_type()) {
251  block_type block = {0};
252 
253  // codec::encode<codec::encoder::logic_xor>(plaintext, previous,
254  // block.begin());
255 
256  return cipher.encrypt(block);
257  }
258 
259  inline static block_type end_message(const cipher_type &cipher, const block_type &plaintext,
260  const block_type &previous = block_type(),
261  const iv_type &iv = iv_type()) {
262  block_type result = {0};
263  std::array<uint8_t, block_bits / CHAR_BIT> byte_array = {0};
264 
265  pack(plaintext, byte_array);
266 
267  size_type rem = std::count(byte_array.begin(), byte_array.end(), block_type::value_type()) %
268  (block_bits / CHAR_BIT);
269  if (rem || padding_type::always_pad) {
270  block_type padbuffer = padding_type::pad(plaintext, rem), block;
271  // codec::encode<codec::encoder::logic_xor>(!iv.empty() ? iv
272  // : previous, padbuffer, block .begin());
273  result = cipher.encrypt(block);
274  }
275 
276  return result;
277  }
278  };
279 
280  template<typename Cipher, typename Padding, typename CiphertextStealingMode>
281  struct ctr_decryption_policy : public ctr_policy<Cipher, Padding> {};
282 
283  template<typename Cipher, typename Padding>
284  struct ctr_decryption_policy<Cipher, Padding, cts<0, Cipher, Padding>>
285  : public ctr_policy<Cipher, Padding> {
287 
290 
291  constexpr static const std::size_t block_bits = ctr_policy<Cipher, Padding>::block_bits;
292  constexpr static const std::size_t block_words = ctr_policy<Cipher, Padding>::block_words;
294 
296 
297  inline static block_type begin_message(const cipher_type &cipher, const block_type &plaintext,
298  const iv_type &iv = iv_type()) {
299  block_type block = cipher.decrypt(plaintext);
300 
301  // codec::encode<codec::encoder::logic_xor>(block, iv);
302 
303  return block;
304  }
305 
306  inline static block_type process_block(const cipher_type &cipher, const block_type &plaintext,
307  const block_type &previous = block_type()) {
308  block_type result = cipher.decrypt(plaintext);
309 
310  // codec::encode<codec::encoder::logic_xor>(result, previous);
311 
312  return result;
313  }
314 
315  inline static block_type end_message(const cipher_type &cipher, const block_type &plaintext,
316  const iv_type &iv = iv_type()) {
317  block_type result = cipher.decrypt(plaintext);
318 
319  // codec::encode<codec::encoder::logic_xor>(result, iv);
320 
321  return result;
322  }
323  };
324 
325  template<typename Cipher, typename Padding>
326  struct ctr_decryption_policy<Cipher, Padding, cts<1, Cipher, Padding>>
327  : public ctr_policy<Cipher, Padding> {
329 
332 
333  constexpr static const std::size_t block_bits = ctr_policy<Cipher, Padding>::block_bits;
334  constexpr static const std::size_t block_words = ctr_policy<Cipher, Padding>::block_words;
336 
338 
339  inline static block_type begin_message(const cipher_type &cipher, const block_type &plaintext,
340  const iv_type &iv = iv_type()) {
341  block_type block = cipher.decrypt(plaintext);
342 
343  // codec::encode<codec::encoder::logic_xor>(block, iv);
344 
345  return block;
346  }
347 
348  inline static block_type process_block(const cipher_type &cipher, const block_type &plaintext,
349  const block_type &previous = block_type()) {
350  block_type result = cipher.decrypt(plaintext);
351 
352  // codec::encode<codec::encoder::logic_xor>(result, previous);
353 
354  return result;
355  }
356 
357  inline static block_type end_message(const cipher_type &cipher, const block_type &plaintext,
358  const iv_type &iv = iv_type()) {
359  block_type result = cipher.decrypt(plaintext);
360 
361  // codec::encode<codec::encoder::logic_xor>(result, iv);
362 
363  return result;
364  }
365  };
366 
367  template<typename Cipher, typename Padding>
368  struct ctr_decryption_policy<Cipher, Padding, cts<2, Cipher, Padding>>
369  : public ctr_policy<Cipher, Padding> {
371 
374 
375  constexpr static const std::size_t block_bits = ctr_policy<Cipher, Padding>::block_bits;
376  constexpr static const std::size_t block_words = ctr_policy<Cipher, Padding>::block_words;
378 
380 
381  inline static block_type begin_message(const cipher_type &cipher, const block_type &plaintext,
382  const iv_type &iv = iv_type()) {
383  block_type block = cipher.decrypt(plaintext);
384 
385  // codec::encode<codec::encoder::logic_xor>(block, iv);
386 
387  return block;
388  }
389 
390  inline static block_type process_block(const cipher_type &cipher, const block_type &plaintext,
391  const block_type &previous = block_type()) {
392  block_type result = cipher.decrypt(plaintext);
393 
394  // codec::encode<codec::encoder::logic_xor>(result, previous);
395 
396  return result;
397  }
398 
399  inline static block_type end_message(const cipher_type &cipher, const block_type &plaintext,
400  const iv_type &iv = iv_type()) {
401  block_type result = cipher.decrypt(plaintext);
402 
403  // codec::encode<codec::encoder::logic_xor>(result, iv);
404 
405  return result;
406  }
407  };
408 
409  template<typename Cipher, typename Padding>
410  struct ctr_decryption_policy<Cipher, Padding, cts<3, Cipher, Padding>>
411  : public ctr_policy<Cipher, Padding> {
413 
416 
417  constexpr static const std::size_t block_bits = ctr_policy<Cipher, Padding>::block_bits;
418  constexpr static const std::size_t block_words = ctr_policy<Cipher, Padding>::block_words;
420 
422 
423  inline static block_type begin_message(const cipher_type &cipher, const block_type &plaintext,
424  const iv_type &iv = iv_type()) {
425  block_type block = cipher.decrypt(plaintext);
426 
427  // codec::encode<codec::encoder::logic_xor>(block, iv);
428 
429  return block;
430  }
431 
432  inline static block_type process_block(const cipher_type &cipher, const block_type &plaintext,
433  const block_type &previous = block_type()) {
434  block_type result = cipher.decrypt(plaintext);
435 
436  // codec::encode<codec::encoder::logic_xor>(result, previous);
437 
438  return result;
439  }
440 
441  inline static block_type end_message(const cipher_type &cipher, const block_type &plaintext,
442  const iv_type &iv = iv_type()) {
443  block_type result = cipher.decrypt(plaintext);
444 
445  // codec::encode<codec::encoder::logic_xor>(result, iv);
446 
447  return result;
448  }
449  };
450 
451  template<typename Policy>
452  class counter {
453  typedef Policy policy_type;
454 
455  public:
456  typedef typename policy_type::cipher_type cipher_type;
457  typedef typename policy_type::padding_type padding_type;
458 
459  typedef typename policy_type::size_type size_type;
460 
461  typedef typename cipher_type::key_type key_type;
462  typedef typename policy_type::iv_type iv_type;
463 
464  constexpr static const size_type block_bits = policy_type::block_bits;
465  constexpr static const size_type block_words = policy_type::block_words;
466  typedef typename cipher_type::block_type block_type;
467 
469  }
470 
471  block_type begin_message(const block_type &plaintext, const iv_type &iv = iv_type()) {
472  previous = policy_type::begin_message(cipher, plaintext, iv);
473  return previous;
474  }
475 
476  block_type process_block(const block_type &plaintext) {
477  previous = policy_type::process_block(cipher, plaintext, previous);
478  return previous;
479  }
480 
481  block_type end_message(const block_type &plaintext, const iv_type &iv = iv_type()) {
482  return policy_type::end_message(cipher, plaintext, iv);
483  }
484 
485  inline static size_type required_output_size(size_type inputlen) {
486  return padding_type::required_output_size(inputlen);
487  }
488 
489  protected:
492  };
493  } // namespace detail
494 
502  template<typename Cipher, template<typename> class Padding,
503  template<typename, template<typename> class> class CiphertextStealingMode = cts0>
504  struct counter {
505  typedef Cipher cipher_type;
506  typedef Padding<Cipher> padding_type;
507  typedef CiphertextStealingMode<Cipher, Padding> ciphertext_stealing_type;
508 
513 
514  template<template<typename, typename> class Policy>
515  struct bind {
517  };
518  };
519 
529  template<typename Cipher, template<typename> class Padding,
530  template<typename, template<typename> class> class CiphertextStealingMode>
532  } // namespace modes
533  } // namespace block
534  } // namespace crypto3
535 } // namespace nil
536 
537 #endif
block_type process_block(const block_type &plaintext)
Definition: ctr.hpp:476
static size_type required_output_size(size_type inputlen)
Definition: ctr.hpp:485
cipher_type cipher
Definition: ctr.hpp:491
cipher_type::key_type key_type
Definition: ctr.hpp:461
block_type begin_message(const block_type &plaintext, const iv_type &iv=iv_type())
Definition: ctr.hpp:471
policy_type::padding_type padding_type
Definition: ctr.hpp:457
constexpr static const size_type block_bits
Definition: ctr.hpp:464
cipher_type::block_type block_type
Definition: ctr.hpp:466
constexpr static const size_type block_words
Definition: ctr.hpp:465
policy_type::cipher_type cipher_type
Definition: ctr.hpp:456
counter(const cipher_type &cipher)
Definition: ctr.hpp:468
block_type end_message(const block_type &plaintext, const iv_type &iv=iv_type())
Definition: ctr.hpp:481
block_type previous
Definition: ctr.hpp:490
policy_type::iv_type iv_type
Definition: ctr.hpp:462
policy_type::size_type size_type
Definition: ctr.hpp:459
void pack(InputIterator first, InputIterator last, std::random_access_iterator_tag, OutputIterator out)
Packs elements from the range [first, last) into elements starting from out. Works for input containe...
Definition: block/include/nil/crypto3/detail/pack.hpp:835
boost::mpl::apply< AccumulatorSet, tag::block< Mode > >::type::result_type block(const AccumulatorSet &acc)
Definition: accumulators/block.hpp:259
Definition: pair.hpp:31
Definition: cipher.hpp:38
detail::counter< Policy< cipher_type, padding_type > > type
Definition: ctr.hpp:516
Counter Mode (CTR).
Definition: ctr.hpp:504
detail::ctr_encryption_policy< cipher_type, padding_type, ciphertext_stealing_type > encryption_policy
Definition: ctr.hpp:510
detail::ctr_decryption_policy< cipher_type, padding_type, ciphertext_stealing_type > decryption_policy
Definition: ctr.hpp:512
Cipher cipher_type
Definition: ctr.hpp:505
CiphertextStealingMode< Cipher, Padding > ciphertext_stealing_type
Definition: ctr.hpp:507
Padding< Cipher > padding_type
Definition: ctr.hpp:506
static block_type process_block(const cipher_type &cipher, const block_type &plaintext, const block_type &previous=block_type())
Definition: ctr.hpp:306
static block_type begin_message(const cipher_type &cipher, const block_type &plaintext, const iv_type &iv=iv_type())
Definition: ctr.hpp:297
static block_type end_message(const cipher_type &cipher, const block_type &plaintext, const iv_type &iv=iv_type())
Definition: ctr.hpp:315
ctr_policy< Cipher, Padding >::padding_type padding_type
Definition: ctr.hpp:289
ctr_policy< Cipher, Padding >::padding_type padding_type
Definition: ctr.hpp:415
static block_type end_message(const cipher_type &cipher, const block_type &plaintext, const iv_type &iv=iv_type())
Definition: ctr.hpp:441
static block_type begin_message(const cipher_type &cipher, const block_type &plaintext, const iv_type &iv=iv_type())
Definition: ctr.hpp:423
static block_type process_block(const cipher_type &cipher, const block_type &plaintext, const block_type &previous=block_type())
Definition: ctr.hpp:432
ctr_policy< Cipher, Padding >::padding_type padding_type
Definition: ctr.hpp:373
static block_type begin_message(const cipher_type &cipher, const block_type &plaintext, const iv_type &iv=iv_type())
Definition: ctr.hpp:381
static block_type process_block(const cipher_type &cipher, const block_type &plaintext, const block_type &previous=block_type())
Definition: ctr.hpp:390
static block_type end_message(const cipher_type &cipher, const block_type &plaintext, const iv_type &iv=iv_type())
Definition: ctr.hpp:399
static block_type process_block(const cipher_type &cipher, const block_type &plaintext, const block_type &previous=block_type())
Definition: ctr.hpp:348
ctr_policy< Cipher, Padding >::padding_type padding_type
Definition: ctr.hpp:331
static block_type end_message(const cipher_type &cipher, const block_type &plaintext, const iv_type &iv=iv_type())
Definition: ctr.hpp:357
static block_type begin_message(const cipher_type &cipher, const block_type &plaintext, const iv_type &iv=iv_type())
Definition: ctr.hpp:339
static block_type process_block(const cipher_type &cipher, const block_type &plaintext, const block_type &previous=block_type())
Definition: ctr.hpp:194
static block_type begin_message(const cipher_type &cipher, const block_type &plaintext, const iv_type &iv=iv_type())
Definition: ctr.hpp:184
static block_type end_message(const cipher_type &cipher, const block_type &plaintext, const block_type &previous=block_type(), const iv_type &iv=iv_type())
Definition: ctr.hpp:204
ctr_policy< Cipher, Padding >::padding_type padding_type
Definition: ctr.hpp:176
static block_type end_message(const cipher_type &cipher, const block_type &plaintext, const block_type &previous=block_type(), const iv_type &iv=iv_type())
Definition: ctr.hpp:259
static block_type process_block(const cipher_type &cipher, const block_type &plaintext, const block_type &previous=block_type())
Definition: ctr.hpp:249
ctr_policy< Cipher, Padding >::padding_type padding_type
Definition: ctr.hpp:231
static block_type begin_message(const cipher_type &cipher, const block_type &plaintext, const iv_type &iv=iv_type())
Definition: ctr.hpp:239
ctr_policy< Cipher, Padding >::padding_type padding_type
Definition: ctr.hpp:66
static block_type process_block(const cipher_type &cipher, const block_type &plaintext, const block_type &previous=block_type())
Definition: ctr.hpp:84
static block_type end_message(const cipher_type &cipher, const block_type &plaintext, const block_type &previous=block_type(), const iv_type &iv=iv_type())
Definition: ctr.hpp:94
static block_type begin_message(const cipher_type &cipher, const block_type &plaintext, const iv_type &iv=iv_type())
Definition: ctr.hpp:74
static block_type process_block(const cipher_type &cipher, const block_type &plaintext, const block_type &previous=block_type())
Definition: ctr.hpp:139
static block_type begin_message(const cipher_type &cipher, const block_type &plaintext, const iv_type &iv=iv_type())
Definition: ctr.hpp:129
static block_type end_message(const cipher_type &cipher, const block_type &plaintext, const block_type &previous=block_type(), const iv_type &iv=iv_type())
Definition: ctr.hpp:149
ctr_policy< Cipher, Padding >::padding_type padding_type
Definition: ctr.hpp:121
std::vector< boost::uint_t< CHAR_BIT >, Allocator< boost::uint_t< CHAR_BIT > > > iv_type
Definition: ctr.hpp:54
constexpr static const size_type block_words
Definition: ctr.hpp:51
Padding padding_type
Definition: ctr.hpp:48
Cipher cipher_type
Definition: ctr.hpp:47
std::size_t size_type
Definition: ctr.hpp:45
constexpr static const size_type block_bits
Definition: ctr.hpp:50
cipher_type::block_type block_type
Definition: ctr.hpp:52