16ANONYMOUS_NAMESPACE_BEGIN
18using CryptoPP::word32;
19using CryptoPP::word64;
20using CryptoPP::rotlConstant;
21using CryptoPP::rotrConstant;
31inline void TF83(W& x, W& y,
const W k)
33 x = rotrConstant<8>(x);
35 y = rotlConstant<3>(y);
47inline void TR83(W& x, W& y,
const W k)
50 y = rotrConstant<3>(y);
52 x = rotlConstant<8>(x);
61template <
class W,
unsigned int R>
62inline void SPECK_Encrypt(W c[2],
const W p[2],
const W k[R])
67 for (
int i = 0; i < static_cast<int>(R); ++i)
68 TF83(c[0], c[1], k[i]);
77template <
class W,
unsigned int R>
78inline void SPECK_Decrypt(W p[2],
const W c[2],
const W k[R])
83 for (
int i =
static_cast<int>(R-1); i >= 0; --i)
84 TR83(p[0], p[1], k[i]);
93template <
class W,
unsigned int R>
94inline void SPECK_ExpandKey_2W(W key[R],
const W k[2])
96 CRYPTOPP_ASSERT(R==32);
97 W i=0, B=k[0], A=k[1];
101 key[i]=A; TF83(B, A, i);
113template <
class W,
unsigned int R>
114inline void SPECK_ExpandKey_3W(W key[R],
const W k[3])
116 CRYPTOPP_ASSERT(R==33 || R==26);
117 W i=0, C=k[0], B=k[1], A=k[2];
119 unsigned int blocks = R/2;
122 key[i+0]=A; TF83(B, A, i+0);
123 key[i+1]=A; TF83(C, A, i+1);
140template <
class W,
unsigned int R>
141inline void SPECK_ExpandKey_4W(W key[R],
const W k[4])
143 CRYPTOPP_ASSERT(R==34 || R==27);
144 W i=0, D=k[0], C=k[1], B=k[2], A=k[3];
146 unsigned int blocks = R/3;
149 key[i+0]=A; TF83(B, A, i+0);
150 key[i+1]=A; TF83(C, A, i+1);
151 key[i+2]=A; TF83(D, A, i+2);
162 key[R-2]=A; TF83(B, A, W(R-2));
167ANONYMOUS_NAMESPACE_END
171NAMESPACE_BEGIN(CryptoPP)
173#if (CRYPTOPP_ARM_NEON_AVAILABLE)
174extern size_t SPECK128_Enc_AdvancedProcessBlocks_NEON(
const word64* subKeys,
size_t rounds,
175 const byte *inBlocks,
const byte *xorBlocks,
byte *outBlocks,
size_t length,
word32 flags);
177extern size_t SPECK128_Dec_AdvancedProcessBlocks_NEON(
const word64* subKeys,
size_t rounds,
178 const byte *inBlocks,
const byte *xorBlocks,
byte *outBlocks,
size_t length,
word32 flags);
181#if (CRYPTOPP_SSE41_AVAILABLE)
182extern size_t SPECK64_Enc_AdvancedProcessBlocks_SSE41(
const word32* subKeys,
size_t rounds,
183 const byte *inBlocks,
const byte *xorBlocks,
byte *outBlocks,
size_t length,
word32 flags);
185extern size_t SPECK64_Dec_AdvancedProcessBlocks_SSE41(
const word32* subKeys,
size_t rounds,
186 const byte *inBlocks,
const byte *xorBlocks,
byte *outBlocks,
size_t length,
word32 flags);
189#if (CRYPTOPP_SSSE3_AVAILABLE)
190extern size_t SPECK128_Enc_AdvancedProcessBlocks_SSSE3(
const word64* subKeys,
size_t rounds,
191 const byte *inBlocks,
const byte *xorBlocks,
byte *outBlocks,
size_t length,
word32 flags);
193extern size_t SPECK128_Dec_AdvancedProcessBlocks_SSSE3(
const word64* subKeys,
size_t rounds,
194 const byte *inBlocks,
const byte *xorBlocks,
byte *outBlocks,
size_t length,
word32 flags);
197#if (CRYPTOPP_ALTIVEC_AVAILABLE)
198extern size_t SPECK128_Enc_AdvancedProcessBlocks_ALTIVEC(
const word64* subKeys,
size_t rounds,
199 const byte *inBlocks,
const byte *xorBlocks,
byte *outBlocks,
size_t length,
word32 flags);
201extern size_t SPECK128_Dec_AdvancedProcessBlocks_ALTIVEC(
const word64* subKeys,
size_t rounds,
202 const byte *inBlocks,
const byte *xorBlocks,
byte *outBlocks,
size_t length,
word32 flags);
205std::string SPECK64::Base::AlgorithmProvider()
const
212 return GetAlignmentOf<word32>();
215void SPECK64::Base::UncheckedSetKey(
const byte *userKey,
unsigned int keyLength,
const NameValuePairs ¶ms)
217 CRYPTOPP_ASSERT(keyLength == 12 || keyLength == 16);
218 CRYPTOPP_UNUSED(params);
222 m_kwords = keyLength/
sizeof(
word32);
227 KeyBlock kblk(userKey);
232 m_rkeys.New((m_rounds = 26));
233 kblk(m_wspace[2])(m_wspace[1])(m_wspace[0]);
234 SPECK_ExpandKey_3W<word32, 26>(m_rkeys, m_wspace);
237 m_rkeys.New((m_rounds = 27));
238 kblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]);
239 SPECK_ExpandKey_4W<word32, 27>(m_rkeys, m_wspace);
246void SPECK64::Enc::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock,
byte *outBlock)
const
250 InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]);
255 SPECK_Encrypt<word32, 26>(m_wspace+2, m_wspace+0, m_rkeys);
258 SPECK_Encrypt<word32, 27>(m_wspace+2, m_wspace+0, m_rkeys);
266 OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]);
269void SPECK64::Dec::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock,
byte *outBlock)
const
273 InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]);
278 SPECK_Decrypt<word32, 26>(m_wspace+2, m_wspace+0, m_rkeys);
281 SPECK_Decrypt<word32, 27>(m_wspace+2, m_wspace+0, m_rkeys);
289 OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]);
294std::string SPECK128::Base::AlgorithmProvider()
const
296#if (CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS)
297# if (CRYPTOPP_SSSE3_AVAILABLE)
301# if (CRYPTOPP_ARM_NEON_AVAILABLE)
305# if (CRYPTOPP_ALTIVEC_AVAILABLE)
315#if (CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS)
316# if (CRYPTOPP_SSSE3_AVAILABLE)
320# if (CRYPTOPP_ARM_NEON_AVAILABLE)
324# if (CRYPTOPP_ALTIVEC_AVAILABLE)
329 return GetAlignmentOf<word64>();
332void SPECK128::Base::UncheckedSetKey(
const byte *userKey,
unsigned int keyLength,
const NameValuePairs ¶ms)
334 CRYPTOPP_ASSERT(keyLength == 16 || keyLength == 24 || keyLength == 32);
335 CRYPTOPP_UNUSED(params);
339 m_kwords = keyLength/
sizeof(word64);
344 KeyBlock kblk(userKey);
349 m_rkeys.New((m_rounds = 32));
350 kblk(m_wspace[1])(m_wspace[0]);
351 SPECK_ExpandKey_2W<word64, 32>(m_rkeys, m_wspace);
354 m_rkeys.New((m_rounds = 33));
355 kblk(m_wspace[2])(m_wspace[1])(m_wspace[0]);
356 SPECK_ExpandKey_3W<word64, 33>(m_rkeys, m_wspace);
359 m_rkeys.New((m_rounds = 34));
360 kblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]);
361 SPECK_ExpandKey_4W<word64, 34>(m_rkeys, m_wspace);
367#if CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS
370#if CRYPTOPP_ALTIVEC_AVAILABLE
371 if (IsForwardTransformation() && HasAltivec())
373 AlignedSecBlock presplat(m_rkeys.size()*2);
374 for (
size_t i=0, j=0; i<m_rkeys.size(); i++, j+=2)
375 presplat[j+0] = presplat[j+1] = m_rkeys[i];
376 m_rkeys.swap(presplat);
378#elif CRYPTOPP_SSSE3_AVAILABLE
379 if (IsForwardTransformation() && HasSSSE3())
381 AlignedSecBlock presplat(m_rkeys.size()*2);
382 for (
size_t i=0, j=0; i<m_rkeys.size(); i++, j+=2)
383 presplat[j+0] = presplat[j+1] = m_rkeys[i];
384 m_rkeys.swap(presplat);
391void SPECK128::Enc::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock,
byte *outBlock)
const
395 InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]);
400 SPECK_Encrypt<word64, 32>(m_wspace+2, m_wspace+0, m_rkeys);
403 SPECK_Encrypt<word64, 33>(m_wspace+2, m_wspace+0, m_rkeys);
406 SPECK_Encrypt<word64, 34>(m_wspace+2, m_wspace+0, m_rkeys);
414 OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]);
417void SPECK128::Dec::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock,
byte *outBlock)
const
421 InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]);
426 SPECK_Decrypt<word64, 32>(m_wspace+2, m_wspace+0, m_rkeys);
429 SPECK_Decrypt<word64, 33>(m_wspace+2, m_wspace+0, m_rkeys);
432 SPECK_Decrypt<word64, 34>(m_wspace+2, m_wspace+0, m_rkeys);
440 OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]);
443#if (CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS)
444size_t SPECK128::Enc::AdvancedProcessBlocks(
const byte *inBlocks,
const byte *xorBlocks,
445 byte *outBlocks,
size_t length,
word32 flags)
const
447#if (CRYPTOPP_SSSE3_AVAILABLE)
449 return SPECK128_Enc_AdvancedProcessBlocks_SSSE3(m_rkeys, (
size_t)m_rounds,
450 inBlocks, xorBlocks, outBlocks, length, flags);
452#if (CRYPTOPP_ARM_NEON_AVAILABLE)
454 return SPECK128_Enc_AdvancedProcessBlocks_NEON(m_rkeys, (
size_t)m_rounds,
455 inBlocks, xorBlocks, outBlocks, length, flags);
457#if (CRYPTOPP_ALTIVEC_AVAILABLE)
459 return SPECK128_Enc_AdvancedProcessBlocks_ALTIVEC(m_rkeys, (
size_t)m_rounds,
460 inBlocks, xorBlocks, outBlocks, length, flags);
465size_t SPECK128::Dec::AdvancedProcessBlocks(
const byte *inBlocks,
const byte *xorBlocks,
466 byte *outBlocks,
size_t length,
word32 flags)
const
468#if (CRYPTOPP_SSSE3_AVAILABLE)
470 return SPECK128_Dec_AdvancedProcessBlocks_SSSE3(m_rkeys, (
size_t)m_rounds,
471 inBlocks, xorBlocks, outBlocks, length, flags);
473#if (CRYPTOPP_ARM_NEON_AVAILABLE)
475 return SPECK128_Dec_AdvancedProcessBlocks_NEON(m_rkeys, (
size_t)m_rounds,
476 inBlocks, xorBlocks, outBlocks, length, flags);
478#if (CRYPTOPP_ALTIVEC_AVAILABLE)
480 return SPECK128_Dec_AdvancedProcessBlocks_ALTIVEC(m_rkeys, (
size_t)m_rounds,
481 inBlocks, xorBlocks, outBlocks, length, flags);
Access a block of memory.
Interface for retrieving values given their names.
Access a block of memory.
unsigned int OptimalDataAlignment() const
Provides input and output data alignment for optimal performance.
unsigned int OptimalDataAlignment() const
Provides input and output data alignment for optimal performance.
Library configuration file.
unsigned int word32
32-bit unsigned datatype
Functions for CPU features and intrinsics.
Utility functions for the Crypto++ library.
Classes for the Speck block cipher.