Crypto++ 8.0 Free C++ class library of cryptographic schemes

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