Crypto++ 8.2
Free C&
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
16ANONYMOUS_NAMESPACE_BEGIN
17
18using CryptoPP::word32;
19using CryptoPP::word64;
20using CryptoPP::rotlConstant;
21using CryptoPP::rotrConstant;
22
23/// \brief Round transformation helper
24/// \tparam W word type
25/// \param v value
26template <class W>
27inline 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
38template <class W>
39inline 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
51template <class W, unsigned int R>
52inline 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
72template <class W, unsigned int R>
73inline 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
94inline 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
113inline 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
133inline 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
154inline 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
175inline 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
193ANONYMOUS_NAMESPACE_END
194
195///////////////////////////////////////////////////////////
196
197NAMESPACE_BEGIN(CryptoPP)
198
199#if (CRYPTOPP_ARM_NEON_AVAILABLE)
200extern 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
203extern 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)
208extern 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
211extern 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)
216extern 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
219extern 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)
224extern 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
227extern 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)
232extern 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
235extern 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)
240extern 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
243extern 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
247std::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
270void 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
307void 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
330void 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
355std::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
374void 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
410void 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
436void 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)
463size_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
484size_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)
507size_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
528size_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
550NAMESPACE_END
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
Access a block of memory.
Definition: misc.h:2455
Interface for retrieving values given their names.
Definition: cryptlib.h:294
Access a block of memory.
Definition: misc.h:2496
Library configuration file.
Functions for CPU features and intrinsics.
bool HasAltivec()
Determine if a PowerPC processor has Altivec available.
Definition: cpu.h:614
bool HasNEON()
Determine if an ARM processor has Advanced SIMD available.
Definition: cpu.h:387
bool HasSSSE3()
Determines SSSE3 availability.
Definition: cpu.h:131
bool HasPower8()
Determine if a PowerPC processor has Power8 available.
Definition: cpu.h:640
bool HasSSE41()
Determines SSE4.1 availability.
Definition: cpu.h:142
Utility functions for the Crypto++ library.
Crypto++ library namespace.
Precompiled header file.
Classes for the Simon block cipher.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:69