rijndael_power8_impl.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_RIJNDAEL_POWER8_IMPL_HPP
26 #define CRYPTO3_RIJNDAEL_POWER8_IMPL_HPP
27 
28 #include <nil/crypto3/block/detail/rijndael_impl.hpp>
29 
30 #include <cstddef>
31 #include <altivec.h>
32 
33 namespace nil {
34  namespace crypto3 {
35  namespace block {
36  namespace detail {
37 
38 #undef vector
39 #undef bool
40 
41  __vector unsigned long long LoadKey(const uint32_t *src) {
42  __vector unsigned int vec = vec_vsx_ld(0, src);
43 
45  const __vector unsigned char mask = {12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3};
46  const __vector unsigned char zero = {0};
47  return (__vector unsigned long long)vec_perm((__vector unsigned char)vec, zero, mask);
48  } else {
49  return (__vector unsigned long long)vec;
50  }
51  }
52 
53  __vector unsigned char Reverse8x16(const __vector unsigned char src) {
55  const __vector unsigned char mask = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
56  const __vector unsigned char zero = {0};
57  return vec_perm(src, zero, mask);
58  } else {
59  return src;
60  }
61  }
62 
63  __vector unsigned long long LoadBlock(const uint8_t *src) {
64  return (__vector unsigned long long)Reverse8x16(vec_vsx_ld(0, src));
65  }
66 
67  void StoreBlock(const __vector unsigned long long src, uint8_t *dest) {
68  vec_vsx_st(Reverse8x16((__vector unsigned char)src), 0, dest);
69  }
70 
71  template<std::size_t KeyBitsImpl, std::size_t BlockBitsImpl, typename PolicyType>
73  BOOST_STATIC_ASSERT(BlockBitsImpl == 128);
74 
75  public:
76  static inline void schedule_key(const key_type &key,
77  key_schedule_type encryption_key,
78  key_schedule_type &decryption_key) {
79  rijndael_impl<KeyBitsImpl, 128>::schedule_key(key, encryption_key, decryption_key);
80 
81  for (typename basic_type::key_schedule_type::value_type &c : encryption_key) {
82  c = reverse_bytes(c);
83  }
84  for (typename basic_type::key_schedule_type::value_type &c : decryption_key) {
85  c = reverse_bytes(c);
86  }
87  }
88  };
89 
90  template<std::size_t KeyBitsImpl, std::size_t BlockBitsImpl, typename PolicyType>
91  class rijndael_power8_impl : public basic_rijndael_power8_impl<KeyBitsImpl, BlockBitsImpl, PolicyType> {
92  BOOST_STATIC_ASSERT(BlockBitsImpl == 128);
93  };
94 
95  template<typename PolicyType>
96  class rijndael_power8_impl<128, 128, PolicyType>
97  : public basic_rijndael_power8_impl<128, 128, PolicyType> {
98  protected:
99  typedef PolicyType policy_type;
100  typedef typename policy_type::block_type block_type;
101  typedef typename policy_type::key_type key_type;
102  typedef typename policy_type::key_schedule_type key_schedule_type;
103 
104  BOOST_STATIC_ASSERT(PolicyType::key_bits == 128);
105  BOOST_STATIC_ASSERT(PolicyType::block_bits == 128);
106 
107  public:
108  static block_type encrypt_block(const block_type &plaintext,
109  const key_schedule_type &encryption_key) {
110  block_type out = {0};
111 
112  const __vector unsigned long long K0 = LoadKey(&encryption_key[0]);
113  const __vector unsigned long long K1 = LoadKey(&encryption_key[4]);
114  const __vector unsigned long long K2 = LoadKey(&encryption_key[8]);
115  const __vector unsigned long long K3 = LoadKey(&encryption_key[12]);
116  const __vector unsigned long long K4 = LoadKey(&encryption_key[16]);
117  const __vector unsigned long long K5 = LoadKey(&encryption_key[20]);
118  const __vector unsigned long long K6 = LoadKey(&encryption_key[24]);
119  const __vector unsigned long long K7 = LoadKey(&encryption_key[28]);
120  const __vector unsigned long long K8 = LoadKey(&encryption_key[32]);
121  const __vector unsigned long long K9 = LoadKey(&encryption_key[36]);
122  const __vector unsigned long long K10 = LoadBlock(m_ME.data());
123 
124  __vector unsigned long long B = LoadBlock(plaintext.data());
125 
126  B = vec_xor(B, K0);
127  B = __builtin_crypto_vcipher(B, K1);
128  B = __builtin_crypto_vcipher(B, K2);
129  B = __builtin_crypto_vcipher(B, K3);
130  B = __builtin_crypto_vcipher(B, K4);
131  B = __builtin_crypto_vcipher(B, K5);
132  B = __builtin_crypto_vcipher(B, K6);
133  B = __builtin_crypto_vcipher(B, K7);
134  B = __builtin_crypto_vcipher(B, K8);
135  B = __builtin_crypto_vcipher(B, K9);
136  B = __builtin_crypto_vcipherlast(B, K10);
137 
138  StoreBlock(B, out.data());
139 
140  return out;
141  }
142 
143  static block_type decrypt_block(const block_type &plaintext,
144  const key_schedule_type &encryption_key) {
145  block_type out = {0};
146 
147  const __vector unsigned long long K0 = LoadBlock(&m_ME.data());
148  const __vector unsigned long long K1 = LoadKey(&encryption_key[36]);
149  const __vector unsigned long long K2 = LoadKey(&encryption_key[32]);
150  const __vector unsigned long long K3 = LoadKey(&encryption_key[28]);
151  const __vector unsigned long long K4 = LoadKey(&encryption_key[24]);
152  const __vector unsigned long long K5 = LoadKey(&encryption_key[20]);
153  const __vector unsigned long long K6 = LoadKey(&encryption_key[16]);
154  const __vector unsigned long long K7 = LoadKey(&encryption_key[12]);
155  const __vector unsigned long long K8 = LoadKey(&encryption_key[8]);
156  const __vector unsigned long long K9 = LoadKey(&encryption_key[4]);
157  const __vector unsigned long long K10 = LoadKey(&encryption_key[0]);
158 
159  __vector unsigned long long B = LoadBlock(plaintext.data());
160 
161  B = vec_xor(B, K0);
162  B = __builtin_crypto_vncipher(B, K1);
163  B = __builtin_crypto_vncipher(B, K2);
164  B = __builtin_crypto_vncipher(B, K3);
165  B = __builtin_crypto_vncipher(B, K4);
166  B = __builtin_crypto_vncipher(B, K5);
167  B = __builtin_crypto_vncipher(B, K6);
168  B = __builtin_crypto_vncipher(B, K7);
169  B = __builtin_crypto_vncipher(B, K8);
170  B = __builtin_crypto_vncipher(B, K9);
171  B = __builtin_crypto_vncipherlast(B, K10);
172 
173  StoreBlock(B, out.data());
174 
175  return out;
176  }
177  };
178 
179  template<typename PolicyType>
180  class rijndael_power8_impl<192, 128, PolicyType>
181  : public basic_rijndael_power8_impl<192, 128, PolicyType> {
182  protected:
183  typedef PolicyType policy_type;
184  typedef typename policy_type::block_type block_type;
185  typedef typename policy_type::key_type key_type;
186  typedef typename policy_type::key_schedule_type key_schedule_type;
187 
188  BOOST_STATIC_ASSERT(PolicyType::key_bits == 192);
189  BOOST_STATIC_ASSERT(PolicyType::block_bits == 128);
190 
191  public:
192  static block_type encrypt_block(const block_type &plaintext,
193  const key_schedule_type &encryption_key) {
194  block_type out = {0};
195 
196  const __vector unsigned long long K0 = LoadKey(&encryption_key[0]);
197  const __vector unsigned long long K1 = LoadKey(&encryption_key[4]);
198  const __vector unsigned long long K2 = LoadKey(&encryption_key[8]);
199  const __vector unsigned long long K3 = LoadKey(&encryption_key[12]);
200  const __vector unsigned long long K4 = LoadKey(&encryption_key[16]);
201  const __vector unsigned long long K5 = LoadKey(&encryption_key[20]);
202  const __vector unsigned long long K6 = LoadKey(&encryption_key[24]);
203  const __vector unsigned long long K7 = LoadKey(&encryption_key[28]);
204  const __vector unsigned long long K8 = LoadKey(&encryption_key[32]);
205  const __vector unsigned long long K9 = LoadKey(&encryption_key[36]);
206  const __vector unsigned long long K10 = LoadKey(&encryption_key[40]);
207  const __vector unsigned long long K11 = LoadKey(&encryption_key[44]);
208  const __vector unsigned long long K12 = LoadBlock(m_ME.data());
209 
210  __vector unsigned long long B = LoadBlock(plaintext.data());
211 
212  B = vec_xor(B, K0);
213  B = __builtin_crypto_vcipher(B, K1);
214  B = __builtin_crypto_vcipher(B, K2);
215  B = __builtin_crypto_vcipher(B, K3);
216  B = __builtin_crypto_vcipher(B, K4);
217  B = __builtin_crypto_vcipher(B, K5);
218  B = __builtin_crypto_vcipher(B, K6);
219  B = __builtin_crypto_vcipher(B, K7);
220  B = __builtin_crypto_vcipher(B, K8);
221  B = __builtin_crypto_vcipher(B, K9);
222  B = __builtin_crypto_vcipher(B, K10);
223  B = __builtin_crypto_vcipher(B, K11);
224  B = __builtin_crypto_vcipherlast(B, K12);
225 
226  StoreBlock(B, out.data());
227 
228  return out;
229  }
230 
231  static block_type decrypt_block(const block_type &plaintext,
232  const key_schedule_type &encryption_key) {
233  block_type out = {0};
234 
235  const __vector unsigned long long K0 = LoadBlock(m_ME.data());
236  const __vector unsigned long long K1 = LoadKey(&encryption_key[44]);
237  const __vector unsigned long long K2 = LoadKey(&encryption_key[40]);
238  const __vector unsigned long long K3 = LoadKey(&encryption_key[36]);
239  const __vector unsigned long long K4 = LoadKey(&encryption_key[32]);
240  const __vector unsigned long long K5 = LoadKey(&encryption_key[28]);
241  const __vector unsigned long long K6 = LoadKey(&encryption_key[24]);
242  const __vector unsigned long long K7 = LoadKey(&encryption_key[20]);
243  const __vector unsigned long long K8 = LoadKey(&encryption_key[16]);
244  const __vector unsigned long long K9 = LoadKey(&encryption_key[12]);
245  const __vector unsigned long long K10 = LoadKey(&encryption_key[8]);
246  const __vector unsigned long long K11 = LoadKey(&encryption_key[4]);
247  const __vector unsigned long long K12 = LoadKey(&encryption_key[0]);
248 
249  __vector unsigned long long B = LoadBlock(plaintext.data());
250 
251  B = vec_xor(B, K0);
252  B = __builtin_crypto_vncipher(B, K1);
253  B = __builtin_crypto_vncipher(B, K2);
254  B = __builtin_crypto_vncipher(B, K3);
255  B = __builtin_crypto_vncipher(B, K4);
256  B = __builtin_crypto_vncipher(B, K5);
257  B = __builtin_crypto_vncipher(B, K6);
258  B = __builtin_crypto_vncipher(B, K7);
259  B = __builtin_crypto_vncipher(B, K8);
260  B = __builtin_crypto_vncipher(B, K9);
261  B = __builtin_crypto_vncipher(B, K10);
262  B = __builtin_crypto_vncipher(B, K11);
263  B = __builtin_crypto_vncipherlast(B, K12);
264 
265  StoreBlock(B, out.data());
266  }
267  };
268 
269  template<typename PolicyType>
270  class rijndael_power8_impl<256, 128, PolicyType>
271  : public basic_rijndael_power8_impl<256, 128, PolicyType> {
272  protected:
273  typedef PolicyType policy_type;
274  typedef typename policy_type::block_type block_type;
275  typedef typename policy_type::key_type key_type;
276  typedef typename policy_type::key_schedule_type key_schedule_type;
277 
278  BOOST_STATIC_ASSERT(PolicyType::key_bits == 256);
279  BOOST_STATIC_ASSERT(PolicyType::block_bits == 128);
280 
281  public:
282  static block_type encrypt_block(const block_type &plaintext,
283  const key_schedule_type &encryption_key) {
284  block_type out = {0};
285 
286  const __vector unsigned long long K0 = LoadKey(&encryption_key[0]);
287  const __vector unsigned long long K1 = LoadKey(&encryption_key[4]);
288  const __vector unsigned long long K2 = LoadKey(&encryption_key[8]);
289  const __vector unsigned long long K3 = LoadKey(&encryption_key[12]);
290  const __vector unsigned long long K4 = LoadKey(&encryption_key[16]);
291  const __vector unsigned long long K5 = LoadKey(&encryption_key[20]);
292  const __vector unsigned long long K6 = LoadKey(&encryption_key[24]);
293  const __vector unsigned long long K7 = LoadKey(&encryption_key[28]);
294  const __vector unsigned long long K8 = LoadKey(&encryption_key[32]);
295  const __vector unsigned long long K9 = LoadKey(&encryption_key[36]);
296  const __vector unsigned long long K10 = LoadKey(&encryption_key[40]);
297  const __vector unsigned long long K11 = LoadKey(&encryption_key[44]);
298  const __vector unsigned long long K12 = LoadKey(&encryption_key[48]);
299  const __vector unsigned long long K13 = LoadKey(&encryption_key[52]);
300  const __vector unsigned long long K14 = LoadBlock(m_ME.data());
301 
302  __vector unsigned long long B = LoadBlock(plaintext.data());
303 
304  B = vec_xor(B, K0);
305  B = __builtin_crypto_vcipher(B, K1);
306  B = __builtin_crypto_vcipher(B, K2);
307  B = __builtin_crypto_vcipher(B, K3);
308  B = __builtin_crypto_vcipher(B, K4);
309  B = __builtin_crypto_vcipher(B, K5);
310  B = __builtin_crypto_vcipher(B, K6);
311  B = __builtin_crypto_vcipher(B, K7);
312  B = __builtin_crypto_vcipher(B, K8);
313  B = __builtin_crypto_vcipher(B, K9);
314  B = __builtin_crypto_vcipher(B, K10);
315  B = __builtin_crypto_vcipher(B, K11);
316  B = __builtin_crypto_vcipher(B, K12);
317  B = __builtin_crypto_vcipher(B, K13);
318  B = __builtin_crypto_vcipherlast(B, K14);
319 
320  StoreBlock(B, out.data());
321 
322  return out;
323  }
324 
325  static block_type decrypt_block(const block_type &plaintext,
326  const key_schedule_type &encryption_key) {
327 
328  block_type out = {0};
329 
330  const __vector unsigned long long K0 = LoadBlock(m_ME.data());
331  const __vector unsigned long long K1 = LoadKey(&encryption_key[52]);
332  const __vector unsigned long long K2 = LoadKey(&encryption_key[48]);
333  const __vector unsigned long long K3 = LoadKey(&encryption_key[44]);
334  const __vector unsigned long long K4 = LoadKey(&encryption_key[40]);
335  const __vector unsigned long long K5 = LoadKey(&encryption_key[36]);
336  const __vector unsigned long long K6 = LoadKey(&encryption_key[32]);
337  const __vector unsigned long long K7 = LoadKey(&encryption_key[28]);
338  const __vector unsigned long long K8 = LoadKey(&encryption_key[24]);
339  const __vector unsigned long long K9 = LoadKey(&encryption_key[20]);
340  const __vector unsigned long long K10 = LoadKey(&encryption_key[16]);
341  const __vector unsigned long long K11 = LoadKey(&encryption_key[12]);
342  const __vector unsigned long long K12 = LoadKey(&encryption_key[8]);
343  const __vector unsigned long long K13 = LoadKey(&encryption_key[4]);
344  const __vector unsigned long long K14 = LoadKey(&encryption_key[0]);
345 
346  __vector unsigned long long B = LoadBlock(plaintext.data());
347 
348  B = vec_xor(B, K0);
349  B = __builtin_crypto_vncipher(B, K1);
350  B = __builtin_crypto_vncipher(B, K2);
351  B = __builtin_crypto_vncipher(B, K3);
352  B = __builtin_crypto_vncipher(B, K4);
353  B = __builtin_crypto_vncipher(B, K5);
354  B = __builtin_crypto_vncipher(B, K6);
355  B = __builtin_crypto_vncipher(B, K7);
356  B = __builtin_crypto_vncipher(B, K8);
357  B = __builtin_crypto_vncipher(B, K9);
358  B = __builtin_crypto_vncipher(B, K10);
359  B = __builtin_crypto_vncipher(B, K11);
360  B = __builtin_crypto_vncipher(B, K12);
361  B = __builtin_crypto_vncipher(B, K13);
362  B = __builtin_crypto_vncipherlast(B, K14);
363 
364  StoreBlock(B, out.data());
365 
366  return out;
367  }
368  };
369  } // namespace detail
370  } // namespace block
371  } // namespace crypto3
372 } // namespace nil
373 
374 #endif // CRYPTO3_RIJNDAEL_POWER8_IMPL_HPP
Definition: rijndael_power8_impl.hpp:72
static void schedule_key(const key_type &key, key_schedule_type encryption_key, key_schedule_type &decryption_key)
Definition: rijndael_power8_impl.hpp:76
static block_type encrypt_block(const block_type &plaintext, const key_schedule_type &encryption_key)
Definition: rijndael_power8_impl.hpp:108
policy_type::key_schedule_type key_schedule_type
Definition: rijndael_power8_impl.hpp:102
PolicyType policy_type
Definition: rijndael_power8_impl.hpp:99
static block_type decrypt_block(const block_type &plaintext, const key_schedule_type &encryption_key)
Definition: rijndael_power8_impl.hpp:143
policy_type::block_type block_type
Definition: rijndael_power8_impl.hpp:100
policy_type::key_type key_type
Definition: rijndael_power8_impl.hpp:101
policy_type::key_schedule_type key_schedule_type
Definition: rijndael_power8_impl.hpp:186
static block_type encrypt_block(const block_type &plaintext, const key_schedule_type &encryption_key)
Definition: rijndael_power8_impl.hpp:192
policy_type::block_type block_type
Definition: rijndael_power8_impl.hpp:184
policy_type::key_type key_type
Definition: rijndael_power8_impl.hpp:185
static block_type decrypt_block(const block_type &plaintext, const key_schedule_type &encryption_key)
Definition: rijndael_power8_impl.hpp:231
PolicyType policy_type
Definition: rijndael_power8_impl.hpp:183
static block_type encrypt_block(const block_type &plaintext, const key_schedule_type &encryption_key)
Definition: rijndael_power8_impl.hpp:282
policy_type::key_type key_type
Definition: rijndael_power8_impl.hpp:275
static block_type decrypt_block(const block_type &plaintext, const key_schedule_type &encryption_key)
Definition: rijndael_power8_impl.hpp:325
policy_type::key_schedule_type key_schedule_type
Definition: rijndael_power8_impl.hpp:276
policy_type::block_type block_type
Definition: rijndael_power8_impl.hpp:274
PolicyType policy_type
Definition: rijndael_power8_impl.hpp:273
Definition: rijndael_power8_impl.hpp:91
static bool is_little_endian()
Definition: cpuid.hpp:141
boost::mpl::apply< AccumulatorSet, tag::block< Mode > >::type::result_type block(const AccumulatorSet &acc)
Definition: accumulators/block.hpp:259
void StoreBlock(const __vector unsigned long long src, uint8_t *dest)
Definition: rijndael_power8_impl.hpp:67
__vector unsigned long long LoadBlock(const uint8_t *src)
Definition: rijndael_power8_impl.hpp:63
__vector unsigned long long LoadKey(const uint32_t *src)
Definition: rijndael_power8_impl.hpp:41
__vector unsigned char Reverse8x16(const __vector unsigned char src)
Definition: rijndael_power8_impl.hpp:53
Definition: pair.hpp:31