Crypto++  8.2
Free C++ class library of cryptographic schemes
simon.cpp
1 // simon.h - written and placed in the public domain by Jeffrey Walton
2 
3 #include "pch.h"
4 #include "config.h"
5 
6 #include "simon.h"
7 #include "misc.h"
8 #include "cpu.h"
9 
10 // Uncomment for benchmarking C++ against SSE or NEON.
11 // Do so in both simon.cpp and simon-simd.cpp.
12 // #undef CRYPTOPP_SSSE3_AVAILABLE
13 // #undef CRYPTOPP_SSE41_AVAILABLE
14 // #undef CRYPTOPP_ARM_NEON_AVAILABLE
15 
16 ANONYMOUS_NAMESPACE_BEGIN
17 
18 using CryptoPP::word32;
19 using CryptoPP::word64;
22 
23 /// \brief Round transformation helper
24 /// \tparam W word type
25 /// \param v value
26 template <class W>
27 inline W f(const W v)
28 {
29  return (rotlConstant<1>(v) & rotlConstant<8>(v)) ^ rotlConstant<2>(v);
30 }
31 
32 /// \brief Round transformation
33 /// \tparam W word type
34 /// \param x value
35 /// \param y value
36 /// \param k value
37 /// \param l value
38 template <class W>
39 inline void R2(W& x, W& y, const W k, const W l)
40 {
41  y ^= f(x); y ^= k;
42  x ^= f(y); x ^= l;
43 }
44 
45 /// \brief Forward transformation
46 /// \tparam W word type
47 /// \tparam R number of rounds
48 /// \param c output array
49 /// \param p input array
50 /// \param k subkey array
51 template <class W, unsigned int R>
52 inline void SIMON_Encrypt(W c[2], const W p[2], const W k[R])
53 {
54  c[0]=p[0]; c[1]=p[1];
55 
56  for (int i = 0; i < static_cast<int>(R-1); i += 2)
57  R2(c[0], c[1], k[i], k[i + 1]);
58 
59  if (R & 1)
60  {
61  c[1] ^= f(c[0]); c[1] ^= k[R-1];
62  W t = c[0]; c[0] = c[1]; c[1] = t;
63  }
64 }
65 
66 /// \brief Reverse transformation
67 /// \tparam W word type
68 /// \tparam R number of rounds
69 /// \param p output array
70 /// \param c input array
71 /// \param k subkey array
72 template <class W, unsigned int R>
73 inline void SIMON_Decrypt(W p[2], const W c[2], const W k[R])
74 {
75  p[0]=c[0]; p[1]=c[1];
76  unsigned int rounds = R;
77 
78  if (R & 1)
79  {
80  const W t = p[1]; p[1] = p[0]; p[0] = t;
81  p[1] ^= k[R - 1]; p[1] ^= f(p[0]);
82  rounds--;
83  }
84 
85  for (int i = static_cast<int>(rounds - 2); i >= 0; i -= 2)
86  R2(p[1], p[0], k[i + 1], k[i]);
87 }
88 
89 /// \brief Subkey generation function
90 /// \details Used for SIMON-64 with 96-bit key and 42 rounds. A template was
91 /// not worthwhile because all instantiations would need specialization.
92 /// \param key empty subkey array
93 /// \param k user key array
94 inline void SIMON64_ExpandKey_3W(word32 key[42], const word32 k[3])
95 {
96  const word32 c = 0xfffffffc;
97  word64 z = W64LIT(0x7369f885192c0ef5);
98 
99  key[0] = k[2]; key[1] = k[1]; key[2] = k[0];
100  for (size_t i = 3; i<42; ++i)
101  {
102  key[i] = static_cast<word32>(c ^ (z & 1) ^ key[i - 3] ^
103  rotrConstant<3>(key[i - 1]) ^ rotrConstant<4>(key[i - 1]));
104  z >>= 1;
105  }
106 }
107 
108 /// \brief Subkey generation function
109 /// \details Used for SIMON-64 with 128-bit key and 44 rounds. A template was
110 /// not worthwhile because all instantiations would need specialization.
111 /// \param key empty subkey array
112 /// \param k user key array
113 inline void SIMON64_ExpandKey_4W(word32 key[44], const word32 k[4])
114 {
115  const word32 c = 0xfffffffc;
116  word64 z = W64LIT(0xfc2ce51207a635db);
117 
118  key[0] = k[3]; key[1] = k[2]; key[2] = k[1]; key[3] = k[0];
119  for (size_t i = 4; i<44; ++i)
120  {
121  key[i] = static_cast<word32>(c ^ (z & 1) ^ key[i - 4] ^
122  rotrConstant<3>(key[i - 1]) ^ key[i - 3] ^ rotrConstant<4>(key[i - 1]) ^
123  rotrConstant<1>(key[i - 3]));
124  z >>= 1;
125  }
126 }
127 
128 /// \brief Subkey generation function
129 /// \details Used for SIMON-128 with 128-bit key and 68 rounds. A template was
130 /// not worthwhile because all instantiations would need specialization.
131 /// \param key empty subkey array
132 /// \param k user key array
133 inline void SIMON128_ExpandKey_2W(word64 key[68], const word64 k[2])
134 {
135  const word64 c = W64LIT(0xfffffffffffffffc);
136  word64 z = W64LIT(0x7369f885192c0ef5);
137 
138  key[0] = k[1]; key[1] = k[0];
139  for (size_t i=2; i<66; ++i)
140  {
141  key[i] = c ^ (z & 1) ^ key[i - 2] ^ rotrConstant<3>(key[i - 1]) ^ rotrConstant<4>(key[i - 1]);
142  z>>=1;
143  }
144 
145  key[66] = c ^ 1 ^ key[64] ^ rotrConstant<3>(key[65]) ^ rotrConstant<4>(key[65]);
146  key[67] = c^key[65] ^ rotrConstant<3>(key[66]) ^ rotrConstant<4>(key[66]);
147 }
148 
149 /// \brief Subkey generation function
150 /// \details Used for SIMON-128 with 192-bit key and 69 rounds. A template was
151 /// not worthwhile because all instantiations would need specialization.
152 /// \param key empty subkey array
153 /// \param k user key array
154 inline void SIMON128_ExpandKey_3W(word64 key[69], const word64 k[3])
155 {
156  const word64 c = W64LIT(0xfffffffffffffffc);
157  word64 z = W64LIT(0xfc2ce51207a635db);
158 
159  key[0]=k[2]; key[1]=k[1]; key[2]=k[0];
160  for (size_t i=3; i<67; ++i)
161  {
162  key[i] = c ^ (z & 1) ^ key[i - 3] ^ rotrConstant<3>(key[i - 1]) ^ rotrConstant<4>(key[i - 1]);
163  z>>=1;
164  }
165 
166  key[67] = c^key[64] ^ rotrConstant<3>(key[66]) ^ rotrConstant<4>(key[66]);
167  key[68] = c ^ 1 ^ key[65] ^ rotrConstant<3>(key[67]) ^ rotrConstant<4>(key[67]);
168 }
169 
170 /// \brief Subkey generation function
171 /// \details Used for SIMON-128 with 256-bit key and 72 rounds. A template was
172 /// not worthwhile because all instantiations would need specialization.
173 /// \param key empty subkey array
174 /// \param k user key array
175 inline void SIMON128_ExpandKey_4W(word64 key[72], const word64 k[4])
176 {
177  const word64 c = W64LIT(0xfffffffffffffffc);
178  word64 z = W64LIT(0xfdc94c3a046d678b);
179 
180  key[0]=k[3]; key[1]=k[2]; key[2]=k[1]; key[3]=k[0];
181  for (size_t i=4; i<68; ++i)
182  {
183  key[i] = c ^ (z & 1) ^ key[i - 4] ^ rotrConstant<3>(key[i - 1]) ^ key[i - 3] ^ rotrConstant<4>(key[i - 1]) ^ rotrConstant<1>(key[i - 3]);
184  z>>=1;
185  }
186 
187  key[68] = c^key[64] ^ rotrConstant<3>(key[67]) ^ key[65] ^ rotrConstant<4>(key[67]) ^ rotrConstant<1>(key[65]);
188  key[69] = c ^ 1 ^ key[65] ^ rotrConstant<3>(key[68]) ^ key[66] ^ rotrConstant<4>(key[68]) ^ rotrConstant<1>(key[66]);
189  key[70] = c^key[66] ^ rotrConstant<3>(key[69]) ^ key[67] ^ rotrConstant<4>(key[69]) ^ rotrConstant<1>(key[67]);
190  key[71] = c^key[67] ^ rotrConstant<3>(key[70]) ^ key[68] ^ rotrConstant<4>(key[70]) ^ rotrConstant<1>(key[68]);
191 }
192 
193 ANONYMOUS_NAMESPACE_END
194 
195 ///////////////////////////////////////////////////////////
196 
197 NAMESPACE_BEGIN(CryptoPP)
198 
199 #if (CRYPTOPP_ARM_NEON_AVAILABLE)
200 extern size_t SIMON64_Enc_AdvancedProcessBlocks_NEON(const word32* subKeys, size_t rounds,
201  const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
202 
203 extern size_t SIMON64_Dec_AdvancedProcessBlocks_NEON(const word32* subKeys, size_t rounds,
204  const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
205 #endif
206 
207 #if (CRYPTOPP_ARM_NEON_AVAILABLE)
208 extern size_t SIMON128_Enc_AdvancedProcessBlocks_NEON(const word64* subKeys, size_t rounds,
209  const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
210 
211 extern size_t SIMON128_Dec_AdvancedProcessBlocks_NEON(const word64* subKeys, size_t rounds,
212  const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
213 #endif
214 
215 #if defined(CRYPTOPP_SSE41_AVAILABLE)
216 extern size_t SIMON64_Enc_AdvancedProcessBlocks_SSE41(const word32* subKeys, size_t rounds,
217  const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
218 
219 extern size_t SIMON64_Dec_AdvancedProcessBlocks_SSE41(const word32* subKeys, size_t rounds,
220  const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
221 #endif
222 
223 #if defined(CRYPTOPP_SSSE3_AVAILABLE)
224 extern size_t SIMON128_Enc_AdvancedProcessBlocks_SSSE3(const word64* subKeys, size_t rounds,
225  const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
226 
227 extern size_t SIMON128_Dec_AdvancedProcessBlocks_SSSE3(const word64* subKeys, size_t rounds,
228  const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
229 #endif
230 
231 #if (CRYPTOPP_ALTIVEC_AVAILABLE)
232 extern size_t SIMON64_Enc_AdvancedProcessBlocks_ALTIVEC(const word32* subKeys, size_t rounds,
233  const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
234 
235 extern size_t SIMON64_Dec_AdvancedProcessBlocks_ALTIVEC(const word32* subKeys, size_t rounds,
236  const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
237 #endif
238 
239 #if (CRYPTOPP_POWER8_AVAILABLE)
240 extern size_t SIMON128_Enc_AdvancedProcessBlocks_POWER8(const word64* subKeys, size_t rounds,
241  const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
242 
243 extern size_t SIMON128_Dec_AdvancedProcessBlocks_POWER8(const word64* subKeys, size_t rounds,
244  const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
245 #endif
246 
247 std::string SIMON64::Base::AlgorithmProvider() const
248 {
249 #if (CRYPTOPP_SIMON64_ADVANCED_PROCESS_BLOCKS)
250 # if (CRYPTOPP_SSE41_AVAILABLE)
251  if (HasSSE41())
252  return "SSE4.1";
253 # endif
254 # if (CRYPTOPP_ARM_NEON_AVAILABLE)
255  if (HasNEON())
256  return "NEON";
257 # endif
258 # if (CRYPTOPP_POWER8_AVAILABLE)
259  if (HasPower8())
260  return "Power8";
261 # endif
262 # if (CRYPTOPP_ALTIVEC_AVAILABLE)
263  if (HasAltivec())
264  return "Altivec";
265 # endif
266 #endif
267  return "C++";
268 }
269 
270 void SIMON64::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params)
271 {
272  CRYPTOPP_ASSERT(keyLength == 12 || keyLength == 16);
273  CRYPTOPP_UNUSED(params);
274 
275  // Building the key schedule table requires {3,4} words workspace.
276  // Encrypting and decrypting requires 4 words workspace.
277  m_kwords = keyLength/sizeof(word32);
278  m_wspace.New(4U);
279 
280  // Do the endian gyrations from the paper and align pointers
281  typedef GetBlock<word32, LittleEndian> KeyBlock;
282  KeyBlock kblk(userKey);
283 
284  switch (m_kwords)
285  {
286  case 3:
287  m_rkeys.New((m_rounds = 42));
288  kblk(m_wspace[2])(m_wspace[1])(m_wspace[0]);
289  SIMON64_ExpandKey_3W(m_rkeys, m_wspace);
290  break;
291  case 4:
292  m_rkeys.New((m_rounds = 44));
293  kblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]);
294  SIMON64_ExpandKey_4W(m_rkeys, m_wspace);
295  break;
296  default:
297  CRYPTOPP_ASSERT(0);;
298  }
299 
300  // Altivec loads the current subkey as a 16-byte vector
301  // The extra elements ensure memory backs the last subkey.
302 #if CRYPTOPP_ALTIVEC_AVAILABLE
303  m_rkeys.Grow(m_rkeys.size()+4);
304 #endif
305 }
306 
307 void SIMON64::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
308 {
309  // Do the endian gyrations from the paper and align pointers
310  typedef GetBlock<word32, LittleEndian> InBlock;
311  InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]);
312 
313  switch (m_rounds)
314  {
315  case 42:
316  SIMON_Encrypt<word32, 42>(m_wspace+2, m_wspace+0, m_rkeys);
317  break;
318  case 44:
319  SIMON_Encrypt<word32, 44>(m_wspace+2, m_wspace+0, m_rkeys);
320  break;
321  default:
322  CRYPTOPP_ASSERT(0);;
323  }
324 
325  // Do the endian gyrations from the paper and align pointers
326  typedef PutBlock<word32, LittleEndian> OutBlock;
327  OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]);
328 }
329 
330 void SIMON64::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
331 {
332  // Do the endian gyrations from the paper and align pointers
333  typedef GetBlock<word32, LittleEndian> InBlock;
334  InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]);
335 
336  switch (m_rounds)
337  {
338  case 42:
339  SIMON_Decrypt<word32, 42>(m_wspace+2, m_wspace+0, m_rkeys);
340  break;
341  case 44:
342  SIMON_Decrypt<word32, 44>(m_wspace+2, m_wspace+0, m_rkeys);
343  break;
344  default:
345  CRYPTOPP_ASSERT(0);;
346  }
347 
348  // Do the endian gyrations from the paper and align pointers
349  typedef PutBlock<word32, LittleEndian> OutBlock;
350  OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]);
351 }
352 
353 ///////////////////////////////////////////////////////////
354 
355 std::string SIMON128::Base::AlgorithmProvider() const
356 {
357 #if (CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS)
358 # if (CRYPTOPP_SSSE3_AVAILABLE)
359  if (HasSSSE3())
360  return "SSSE3";
361 # endif
362 # if (CRYPTOPP_ARM_NEON_AVAILABLE)
363  if (HasNEON())
364  return "NEON";
365 # endif
366 # if (CRYPTOPP_POWER8_AVAILABLE)
367  if (HasPower8())
368  return "Power8";
369 # endif
370 #endif
371  return "C++";
372 }
373 
374 void SIMON128::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params)
375 {
376  CRYPTOPP_ASSERT(keyLength == 16 || keyLength == 24 || keyLength == 32);
377  CRYPTOPP_UNUSED(params);
378 
379  // Building the key schedule table requires {2,3,4} words workspace.
380  // Encrypting and decrypting requires 4 words workspace.
381  m_kwords = keyLength/sizeof(word64);
382  m_wspace.New(4U);
383 
384  // Do the endian gyrations from the paper and align pointers
385  typedef GetBlock<word64, LittleEndian> KeyBlock;
386  KeyBlock kblk(userKey);
387 
388  switch (m_kwords)
389  {
390  case 2:
391  m_rkeys.New((m_rounds = 68));
392  kblk(m_wspace[1])(m_wspace[0]);
393  SIMON128_ExpandKey_2W(m_rkeys, m_wspace);
394  break;
395  case 3:
396  m_rkeys.New((m_rounds = 69));
397  kblk(m_wspace[2])(m_wspace[1])(m_wspace[0]);
398  SIMON128_ExpandKey_3W(m_rkeys, m_wspace);
399  break;
400  case 4:
401  m_rkeys.New((m_rounds = 72));
402  kblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]);
403  SIMON128_ExpandKey_4W(m_rkeys, m_wspace);
404  break;
405  default:
406  CRYPTOPP_ASSERT(0);;
407  }
408 }
409 
410 void SIMON128::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
411 {
412  // Do the endian gyrations from the paper and align pointers
413  typedef GetBlock<word64, LittleEndian> InBlock;
414  InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]);
415 
416  switch (m_rounds)
417  {
418  case 68:
419  SIMON_Encrypt<word64, 68>(m_wspace+2, m_wspace+0, m_rkeys);
420  break;
421  case 69:
422  SIMON_Encrypt<word64, 69>(m_wspace+2, m_wspace+0, m_rkeys);
423  break;
424  case 72:
425  SIMON_Encrypt<word64, 72>(m_wspace+2, m_wspace+0, m_rkeys);
426  break;
427  default:
428  CRYPTOPP_ASSERT(0);;
429  }
430 
431  // Do the endian gyrations from the paper and align pointers
432  typedef PutBlock<word64, LittleEndian> OutBlock;
433  OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]);
434 }
435 
436 void SIMON128::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
437 {
438  // Do the endian gyrations from the paper and align pointers
439  typedef GetBlock<word64, LittleEndian> InBlock;
440  InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]);
441 
442  switch (m_rounds)
443  {
444  case 68:
445  SIMON_Decrypt<word64, 68>(m_wspace+2, m_wspace+0, m_rkeys);
446  break;
447  case 69:
448  SIMON_Decrypt<word64, 69>(m_wspace+2, m_wspace+0, m_rkeys);
449  break;
450  case 72:
451  SIMON_Decrypt<word64, 72>(m_wspace+2, m_wspace+0, m_rkeys);
452  break;
453  default:
454  CRYPTOPP_ASSERT(0);;
455  }
456 
457  // Do the endian gyrations from the paper and align pointers
458  typedef PutBlock<word64, LittleEndian> OutBlock;
459  OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]);
460 }
461 
462 #if defined(CRYPTOPP_SIMON64_ADVANCED_PROCESS_BLOCKS)
463 size_t SIMON64::Enc::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks,
464  byte *outBlocks, size_t length, word32 flags) const
465 {
466 #if defined(CRYPTOPP_SSE41_AVAILABLE)
467  if (HasSSE41())
468  return SIMON64_Enc_AdvancedProcessBlocks_SSE41(m_rkeys, (size_t)m_rounds,
469  inBlocks, xorBlocks, outBlocks, length, flags);
470 #endif
471 #if (CRYPTOPP_ARM_NEON_AVAILABLE)
472  if (HasNEON())
473  return SIMON64_Enc_AdvancedProcessBlocks_NEON(m_rkeys, (size_t)m_rounds,
474  inBlocks, xorBlocks, outBlocks, length, flags);
475 #endif
476 #if (CRYPTOPP_ALTIVEC_AVAILABLE)
477  if (HasAltivec())
478  return SIMON64_Enc_AdvancedProcessBlocks_ALTIVEC(m_rkeys, (size_t)m_rounds,
479  inBlocks, xorBlocks, outBlocks, length, flags);
480 #endif
481  return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags);
482 }
483 
484 size_t SIMON64::Dec::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks,
485  byte *outBlocks, size_t length, word32 flags) const
486 {
487 #if defined(CRYPTOPP_SSE41_AVAILABLE)
488  if (HasSSE41())
489  return SIMON64_Dec_AdvancedProcessBlocks_SSE41(m_rkeys, (size_t)m_rounds,
490  inBlocks, xorBlocks, outBlocks, length, flags);
491 #endif
492 #if (CRYPTOPP_ARM_NEON_AVAILABLE)
493  if (HasNEON())
494  return SIMON64_Dec_AdvancedProcessBlocks_NEON(m_rkeys, (size_t)m_rounds,
495  inBlocks, xorBlocks, outBlocks, length, flags);
496 #endif
497 #if (CRYPTOPP_ALTIVEC_AVAILABLE)
498  if (HasAltivec())
499  return SIMON64_Dec_AdvancedProcessBlocks_ALTIVEC(m_rkeys, (size_t)m_rounds,
500  inBlocks, xorBlocks, outBlocks, length, flags);
501 #endif
502  return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags);
503 }
504 #endif // CRYPTOPP_SIMON64_ADVANCED_PROCESS_BLOCKS
505 
506 #if defined(CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS)
507 size_t SIMON128::Enc::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks,
508  byte *outBlocks, size_t length, word32 flags) const
509 {
510 #if defined(CRYPTOPP_SSSE3_AVAILABLE)
511  if (HasSSSE3())
512  return SIMON128_Enc_AdvancedProcessBlocks_SSSE3(m_rkeys, (size_t)m_rounds,
513  inBlocks, xorBlocks, outBlocks, length, flags);
514 #endif
515 #if (CRYPTOPP_ARM_NEON_AVAILABLE)
516  if (HasNEON())
517  return SIMON128_Enc_AdvancedProcessBlocks_NEON(m_rkeys, (size_t)m_rounds,
518  inBlocks, xorBlocks, outBlocks, length, flags);
519 #endif
520 #if (CRYPTOPP_POWER8_AVAILABLE)
521  if (HasPower8())
522  return SIMON128_Enc_AdvancedProcessBlocks_POWER8(m_rkeys, (size_t)m_rounds,
523  inBlocks, xorBlocks, outBlocks, length, flags);
524 #endif
525  return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags);
526 }
527 
528 size_t SIMON128::Dec::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks,
529  byte *outBlocks, size_t length, word32 flags) const
530 {
531 #if defined(CRYPTOPP_SSSE3_AVAILABLE)
532  if (HasSSSE3())
533  return SIMON128_Dec_AdvancedProcessBlocks_SSSE3(m_rkeys, (size_t)m_rounds,
534  inBlocks, xorBlocks, outBlocks, length, flags);
535 #endif
536 #if (CRYPTOPP_ARM_NEON_AVAILABLE)
537  if (HasNEON())
538  return SIMON128_Dec_AdvancedProcessBlocks_NEON(m_rkeys, (size_t)m_rounds,
539  inBlocks, xorBlocks, outBlocks, length, flags);
540 #endif
541 #if (CRYPTOPP_POWER8_AVAILABLE)
542  if (HasPower8())
543  return SIMON128_Dec_AdvancedProcessBlocks_POWER8(m_rkeys, (size_t)m_rounds,
544  inBlocks, xorBlocks, outBlocks, length, flags);
545 #endif
546  return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags);
547 }
548 #endif // CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS
549 
550 NAMESPACE_END
bool HasAltivec()
Determine if a PowerPC processor has Altivec available.
Definition: cpu.h:614
Utility functions for the Crypto++ library.
bool HasSSSE3()
Determines SSSE3 availability.
Definition: cpu.h:131
Library configuration file.
T rotlConstant(T x)
Performs a left rotate.
Definition: misc.h:1499
bool HasPower8()
Determine if a PowerPC processor has Power8 available.
Definition: cpu.h:640
virtual size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const
Encrypt and xor multiple blocks using additional flags.
Definition: cryptlib.cpp:141
Precompiled header file.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:69
Functions for CPU features and intrinsics.
T rotrConstant(T x)
Performs a right rotate.
Definition: misc.h:1525
Access a block of memory.
Definition: misc.h:2454
Classes for the Simon block cipher.
bool HasSSE41()
Determines SSE4.1 availability.
Definition: cpu.h:142
Access a block of memory.
Definition: misc.h:2495
Crypto++ library namespace.
bool HasNEON()
Determine if an ARM processor has Advanced SIMD available.
Definition: cpu.h:387
Interface for retrieving values given their names.
Definition: cryptlib.h:293