basic_shacal.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2018-2020 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_BASIC_SHACAL_HPP
26 #define CRYPTO3_BLOCK_BASIC_SHACAL_HPP
27 
30 
31 #include <boost/static_assert.hpp>
32 
33 #ifdef CRYPTO3_BLOCK_SHOW_PROGRESS
34 #include <cstdio>
35 #endif
36 
37 namespace nil {
38  namespace crypto3 {
39  namespace block {
59  class basic_shacal {
60  protected:
62 
63  public:
64  constexpr static const std::size_t word_bits = policy_type::word_bits;
66 
67  constexpr static const std::size_t key_bits = policy_type::key_bits;
68  constexpr static const std::size_t key_words = policy_type::key_words;
70 
71  constexpr static const std::size_t block_bits = policy_type::block_bits;
72  constexpr static const std::size_t block_words = policy_type::block_words;
74 
75  constexpr static const std::size_t rounds = policy_type::rounds;
77 
78  protected:
79  basic_shacal(const schedule_type &s) : schedule(s) {
80  }
81 
82  virtual ~basic_shacal() {
83  schedule.fill(0);
84  }
85 
86  public:
87  inline block_type encrypt(const block_type &plaintext) const {
88  return encrypt_block(schedule, plaintext);
89  }
90 
91  inline block_type decrypt(const block_type &ciphertext) const {
92  return decrypt_block(schedule, ciphertext);
93  }
94 
95  private:
96  schedule_type schedule;
97 
98  inline static block_type encrypt_block(const schedule_type &schedule, const block_type &plaintext) {
99 
100 #ifdef CRYPTO3_BLOCK_SHOW_PROGRESS
101  for (unsigned t = 0; t < block_words; ++t) {
102  std::printf(word_bits == 32 ? "H[%d] = %.8x\n" : "H[%d] = %.16lx\n", t, plaintext[t]);
103  }
104 #endif
105 
106  // Initialize working variables with block
107  word_type a = plaintext[0], b = plaintext[1], c = plaintext[2], d = plaintext[3], e = plaintext[4];
108 
109  // Encipher block
110 #ifdef CRYPTO3_BLOCK_NO_OPTIMIZATION
111 
112  for (unsigned t = 0; t < rounds; ++t) {
113  word_type T = policy_type::rotl<5>(a) + policy_type::f(t, b, c, d) + e +
114  policy_type::constants[t] + round_constants_words[t];
115 
116  e = d;
117  d = c;
118  c = policy_type::rotl<30>(b);
119  b = a;
120  a = T;
121 
122 #ifdef CRYPTO3_BLOCK_SHOW_PROGRESS
123  printf(word_bits == 32 ? "t = %2d: %.8x %.8x %.8x %.8x %.8x\n" :
124  "t = %2d: %.16lx %.16lx %.16lx %.16lx %.16lx\n",
125  t, a, b, c, d, e);
126 #endif
127  }
128 
129 #else // CRYPTO3_BLOCK_NO_OPTIMIZATION
130 
131 #ifdef CRYPTO3_BLOCK_SHOW_PROGRESS
132 #define CRYPTO3_BLOCK_SHACAL1_TRANSFORM_PROGRESS \
133  printf(word_bits == 32 ? "t = %2d: %.8x %.8x %.8x %.8x %.8x\n" : "t = %2d: %.16lx %.16lx %.16lx %.16lx %.16lx\n", \
134  t, a, b, c, d, e);
135 #else
136 #define CRYPTO3_BLOCK_SHACAL1_TRANSFORM_PROGRESS
137 #endif
138 
139 #define CRYPTO3_BLOCK_SHACAL1_TRANSFORM \
140  word_type T = policy_type::rotl<5>(a) + policy_type::f(t, b, c, d) + e + policy_type::constants[t] + schedule[t]; \
141  e = d; \
142  d = c; \
143  c = policy_type::rotl<30>(b); \
144  b = a; \
145  a = T; \
146  CRYPTO3_BLOCK_SHACAL1_TRANSFORM_PROGRESS
147 
148  BOOST_STATIC_ASSERT(rounds == 80);
149  BOOST_STATIC_ASSERT(rounds % block_words == 0);
150  for (unsigned t = 0; t < 20;) {
151  for (int n = block_words; n--; ++t) {
153  }
154  }
155  for (unsigned t = 20; t < 40;) {
156  for (int n = block_words; n--; ++t) {
158  }
159  }
160  for (unsigned t = 40; t < 60;) {
161  for (int n = block_words; n--; ++t) {
163  }
164  }
165  for (unsigned t = 60; t < 80;) {
166  for (int n = block_words; n--; ++t) {
168  }
169  }
170 
171 #endif
172 
173  return {{a, b, c, d, e}};
174  }
175 
176  inline static block_type decrypt_block(const schedule_type &schedule, const block_type &ciphertext) {
177 
178 #ifdef CRYPTO3_BLOCK_SHOW_PROGRESS
179  for (unsigned t = 0; t < block_words; ++t) {
180  std::printf(word_bits == 32 ? "H[%d] = %.8x\n" : "H[%d] = %.16lx\n", t, ciphertext[t]);
181  }
182 #endif
183 
184  // Initialize working variables with block
185  word_type a = ciphertext[0], b = ciphertext[1], c = ciphertext[2], d = ciphertext[3],
186  e = ciphertext[4];
187 
188  // Decipher block
189  for (unsigned t = rounds; t--;) {
190  word_type T = a;
191 
192  a = b;
193  b = policy_type::rotr<30>(c);
194  c = d;
195  d = e;
196  e = T - policy_type::rotl<5>(a) - policy_type::f(t, b, c, d) - policy_type::constants[t] -
197  schedule[t];
198 
199 #ifdef CRYPTO3_BLOCK_SHOW_PROGRESS
200  std::printf(word_bits == 32 ? "t = %2d: %.8x %.8x %.8x %.8x %.8x\n" :
201  "t = %2d: %.16lx %.16lx %.16lx %.16lx %.16lx\n",
202  t, a, b, c, d, e);
203 #endif
204  }
205 
206  return {{a, b, c, d, e}};
207  }
208  };
209  } // namespace block
210  } // namespace crypto3
211 } // namespace nil
212 
213 #endif // CRYPTO3_BLOCK_CIPHERS_BASIC_SHACAL_HPP
#define CRYPTO3_BLOCK_SHACAL1_TRANSFORM
Definition: basic_shacal.hpp:59
block_type encrypt(const block_type &plaintext) const
Definition: basic_shacal.hpp:87
constexpr static const std::size_t word_bits
Definition: basic_shacal.hpp:64
policy_type::block_type block_type
Definition: basic_shacal.hpp:73
constexpr static const std::size_t key_bits
Definition: basic_shacal.hpp:67
constexpr static const std::size_t block_words
Definition: basic_shacal.hpp:72
policy_type::word_type word_type
Definition: basic_shacal.hpp:65
virtual ~basic_shacal()
Definition: basic_shacal.hpp:82
constexpr static const std::size_t key_words
Definition: basic_shacal.hpp:68
block_type decrypt(const block_type &ciphertext) const
Definition: basic_shacal.hpp:91
policy_type::schedule_type schedule_type
Definition: basic_shacal.hpp:76
basic_shacal(const schedule_type &s)
Definition: basic_shacal.hpp:79
constexpr static const std::size_t block_bits
Definition: basic_shacal.hpp:71
policy_type::key_type key_type
Definition: basic_shacal.hpp:69
detail::shacal_policy policy_type
Definition: basic_shacal.hpp:61
constexpr static const std::size_t rounds
Definition: basic_shacal.hpp:75
boost::mpl::apply< AccumulatorSet, tag::block< Mode > >::type::result_type block(const AccumulatorSet &acc)
Definition: accumulators/block.hpp:259
Definition: pair.hpp:31
static word_type f(unsigned t, word_type x, word_type y, word_type z)
Definition: shacal_functions.hpp:61
Definition: shacal_policy.hpp:37
std::array< word_type, block_words > block_type
Definition: shacal_policy.hpp:41
std::array< word_type, key_words > key_type
Definition: shacal_policy.hpp:45
std::array< word_type, rounds > schedule_type
Definition: shacal_policy.hpp:48
constexpr static const std::size_t block_words
Definition: shacal_policy.hpp:39
constexpr static const std::size_t block_bits
Definition: shacal_policy.hpp:40
constexpr static const std::size_t key_words
Definition: shacal_policy.hpp:43
static const std::size_t rounds
Definition: shacal_policy.hpp:47
constexpr static const std::size_t key_bits
Definition: shacal_policy.hpp:44
constexpr static constants_type const constants
Definition: shacal_policy.hpp:51
constexpr static const std::size_t word_bits
Definition: block/include/nil/crypto3/detail/basic_functions.hpp:41
boost::uint_t< word_bits >::exact word_type
Definition: block/include/nil/crypto3/detail/basic_functions.hpp:42