shacal2.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2018-2020 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2020 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 
26 #ifndef CRYPTO3_BLOCK_SHACAL2_HPP
27 #define CRYPTO3_BLOCK_SHACAL2_HPP
28 
30 
33 
34 #include <boost/static_assert.hpp>
35 
36 #ifdef CRYPTO3_BLOCK_SHOW_PROGRESS
37 #include <cstdio>
38 #endif
39 
40 namespace nil {
41  namespace crypto3 {
42  namespace block {
43 
65  template<std::size_t BlockBits>
66  class shacal2 {
67 
69 
70  public:
71  constexpr static const std::size_t version = BlockBits;
72 
73  constexpr static const std::size_t word_bits = policy_type::word_bits;
74  typedef typename policy_type::word_type word_type;
75 
76  constexpr static const std::size_t key_bits = policy_type::key_bits;
77  constexpr static const std::size_t key_words = policy_type::key_words;
78  typedef typename policy_type::key_type key_type;
79 
80  constexpr static const std::size_t block_bits = policy_type::block_bits;
81  constexpr static const std::size_t block_words = policy_type::block_words;
82  typedef typename policy_type::block_type block_type;
83 
84  static const std::size_t rounds = policy_type::rounds;
85  typedef typename policy_type::key_schedule_type key_schedule_type;
86 
87  template<class Mode, typename StateAccumulator, std::size_t ValueBits>
89  struct params_type {
90 
91  constexpr static const std::size_t value_bits = ValueBits;
92  constexpr static const std::size_t length_bits = policy_type::word_bits * 2;
93  };
94 
96  };
97 
99 
100  shacal2(const key_type &key) : schedule(build_schedule(key)) {
101  }
102 
104  }
105 
106  block_type encrypt(block_type const &plaintext) const {
107  return encrypt_block(plaintext);
108  }
109 
110  inline block_type decrypt(const block_type &ciphertext) const {
111  return decrypt_block(ciphertext);
112  }
113 
114  protected:
116 
118  // Copy key into beginning of round_constants_words
120  for (unsigned t = 0; t < key_words; ++t) {
121  schedule[t] = key[t];
122  }
124  return schedule;
125  }
126 
128  for (unsigned t = key_words; t < rounds; ++t) {
129  schedule[t] = policy_type::sigma_1(schedule[t - 2]) + schedule[t - 7] +
130  policy_type::sigma_0(schedule[t - 15]) + schedule[t - 16];
131  }
132  }
133 
134  block_type encrypt_block(const block_type &plaintext) const {
135  return encrypt_block(schedule, plaintext);
136  }
137 
138  inline static block_type encrypt_block(const key_schedule_type &schedule, block_type const &plaintext) {
139 
140  // Initialize working variables with block
141  word_type a = plaintext[0], b = plaintext[1], c = plaintext[2], d = plaintext[3], e = plaintext[4],
142  f = plaintext[5], g = plaintext[6], h = plaintext[7];
143 
144  // Encipher block
145 #ifdef CRYPTO3_BLOCK_NO_OPTIMIZATION
146 
147  for (unsigned t = 0; t < rounds; ++t) {
148  word_type T1 = h + policy_type::Sigma_1(e) + policy_type::Ch(e, f, g) +
149  policy_type::constants[t] + round_constants_words[t];
150  word_type T2 = policy_type::Sigma_0(a) + policy_type::Maj(a, b, c);
151 
152  h = g;
153  g = f;
154  f = e;
155  e = d + T1;
156  d = c;
157  c = b;
158  b = a;
159  a = T1 + T2;
160  }
161 
162 #else // CRYPTO3_BLOCK_NO_OPTIMIZATION
163 
164  BOOST_STATIC_ASSERT(rounds % block_words == 0);
165  for (unsigned t = 0; t < rounds;) {
166  for (int n = block_words; n--; ++t) {
167  word_type T1 = h + policy_type::Sigma_1(e) + policy_type::Ch(e, f, g) +
168  policy_type::constants[t] + schedule[t];
169  word_type T2 = policy_type::Sigma_0(a) + policy_type::Maj(a, b, c);
170 
171  h = g;
172  g = f;
173  f = e;
174  e = d + T1;
175  d = c;
176  c = b;
177  b = a;
178  a = T1 + T2;
179  }
180  }
181 
182 #endif
183 
184  return {{a, b, c, d, e, f, g, h}};
185  }
186 
187  block_type decrypt_block(const block_type &ciphertext) const {
188  return decrypt_block(schedule, ciphertext);
189  }
190 
192  const block_type &ciphertext) {
193  // Initialize working variables with block
194  word_type a = ciphertext[0], b = ciphertext[1], c = ciphertext[2], d = ciphertext[3],
195  e = ciphertext[4], f = ciphertext[5], g = ciphertext[6], h = ciphertext[7];
196 
197  // Decipher block
198  for (unsigned t = rounds; t--;) {
199  word_type T2 = policy_type::Sigma_0(b) + policy_type::Maj(b, c, d);
200  word_type T1 = a - T2;
201 
202  a = b;
203  b = c;
204  c = d;
205  d = e - T1;
206  e = f;
207  f = g;
208  g = h;
209  h = T1 - policy_type::Sigma_1(e) - policy_type::Ch(e, f, g) - policy_type::constants[t] -
210  schedule[t];
211  }
212  return {{a, b, c, d, e, f, g, h}};
213  }
214  };
215  } // namespace block
216  } // namespace crypto3
217 } // namespace nil
218 
219 #endif // CRYPTO3_BLOCK_CIPHERS_SHACAL2_HPP
Shacal2. Merkle-Damgård construction foundation for SHA2 hashes. Accepts up to a 512-bit key....
Definition: shacal2.hpp:66
shacal2(key_schedule_type s)
Definition: shacal2.hpp:103
constexpr static const std::size_t key_words
Definition: shacal2.hpp:77
policy_type::key_type key_type
Definition: shacal2.hpp:78
block_type encrypt(block_type const &plaintext) const
Definition: shacal2.hpp:106
block_type decrypt(const block_type &ciphertext) const
Definition: shacal2.hpp:110
policy_type::word_type word_type
Definition: shacal2.hpp:74
static block_type decrypt_block(const key_schedule_type &schedule, const block_type &ciphertext)
Definition: shacal2.hpp:191
constexpr static const std::size_t block_bits
Definition: shacal2.hpp:80
constexpr static const std::size_t key_bits
Definition: shacal2.hpp:76
constexpr static const std::size_t word_bits
Definition: shacal2.hpp:73
static void prepare_schedule(key_schedule_type &schedule)
Definition: shacal2.hpp:127
static key_schedule_type build_schedule(const key_type &key)
Definition: shacal2.hpp:117
block_type decrypt_block(const block_type &ciphertext) const
Definition: shacal2.hpp:187
stream_endian::little_octet_big_bit endian_type
Definition: shacal2.hpp:98
policy_type::key_schedule_type key_schedule_type
Definition: shacal2.hpp:85
shacal2(const key_type &key)
Definition: shacal2.hpp:100
constexpr static const std::size_t version
Definition: shacal2.hpp:71
static block_type encrypt_block(const key_schedule_type &schedule, block_type const &plaintext)
Definition: shacal2.hpp:138
policy_type::block_type block_type
Definition: shacal2.hpp:82
constexpr static const std::size_t block_words
Definition: shacal2.hpp:81
const key_schedule_type schedule
Definition: shacal2.hpp:115
static const std::size_t rounds
Definition: shacal2.hpp:84
block_type encrypt_block(const block_type &plaintext) const
Definition: shacal2.hpp:134
boost::mpl::apply< AccumulatorSet, tag::block< Mode > >::type::result_type block(const AccumulatorSet &acc)
Definition: accumulators/block.hpp:259
Definition: pair.hpp:31
Definition: block/include/nil/crypto3/block/detail/block_stream_processor.hpp:50
Definition: shacal2_policy.hpp:55
constexpr static const std::size_t value_bits
Definition: shacal2.hpp:91
constexpr static const std::size_t length_bits
Definition: shacal2.hpp:92
block_stream_processor< Mode, StateAccumulator, params_type > type
Definition: shacal2.hpp:95
Definition: algebra/include/nil/crypto3/detail/stream_endian.hpp:45