16ANONYMOUS_NAMESPACE_BEGIN
18using CryptoPP::word32;
19using CryptoPP::word64;
20using CryptoPP::rotlConstant;
21using CryptoPP::rotrConstant;
29 return (rotlConstant<1>(v) & rotlConstant<8>(v)) ^ rotlConstant<2>(v);
39inline void R2(W& x, W& y,
const W k,
const W l)
51template <
class W,
unsigned int R>
52inline void SIMON_Encrypt(W c[2],
const W p[2],
const W k[R])
56 for (
int i = 0; i < static_cast<int>(R-1); i += 2)
57 R2(c[0], c[1], k[i], k[i + 1]);
61 c[1] ^= f(c[0]); c[1] ^= k[R-1];
62 W t = c[0]; c[0] = c[1]; c[1] = t;
72template <
class W,
unsigned int R>
73inline void SIMON_Decrypt(W p[2],
const W c[2],
const W k[R])
76 unsigned int rounds = R;
80 const W t = p[1]; p[1] = p[0]; p[0] = t;
81 p[1] ^= k[R - 1]; p[1] ^= f(p[0]);
85 for (
int i =
static_cast<int>(rounds - 2); i >= 0; i -= 2)
86 R2(p[1], p[0], k[i + 1], k[i]);
94inline void SIMON64_ExpandKey_3W(
word32 key[42],
const word32 k[3])
96 const word32 c = 0xfffffffc;
97 word64 z = W64LIT(0x7369f885192c0ef5);
99 key[0] = k[2]; key[1] = k[1]; key[2] = k[0];
100 for (
size_t i = 3; i<42; ++i)
102 key[i] =
static_cast<word32>(c ^ (z & 1) ^ key[i - 3] ^
103 rotrConstant<3>(key[i - 1]) ^ rotrConstant<4>(key[i - 1]));
113inline void SIMON64_ExpandKey_4W(
word32 key[44],
const word32 k[4])
115 const word32 c = 0xfffffffc;
116 word64 z = W64LIT(0xfc2ce51207a635db);
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)
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]));
133inline void SIMON128_ExpandKey_2W(word64 key[68],
const word64 k[2])
135 const word64 c = W64LIT(0xfffffffffffffffc);
136 word64 z = W64LIT(0x7369f885192c0ef5);
138 key[0] = k[1]; key[1] = k[0];
139 for (
size_t i=2; i<66; ++i)
141 key[i] = c ^ (z & 1) ^ key[i - 2] ^ rotrConstant<3>(key[i - 1]) ^ rotrConstant<4>(key[i - 1]);
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]);
154inline void SIMON128_ExpandKey_3W(word64 key[69],
const word64 k[3])
156 const word64 c = W64LIT(0xfffffffffffffffc);
157 word64 z = W64LIT(0xfc2ce51207a635db);
159 key[0]=k[2]; key[1]=k[1]; key[2]=k[0];
160 for (
size_t i=3; i<67; ++i)
162 key[i] = c ^ (z & 1) ^ key[i - 3] ^ rotrConstant<3>(key[i - 1]) ^ rotrConstant<4>(key[i - 1]);
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]);
175inline void SIMON128_ExpandKey_4W(word64 key[72],
const word64 k[4])
177 const word64 c = W64LIT(0xfffffffffffffffc);
178 word64 z = W64LIT(0xfdc94c3a046d678b);
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)
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]);
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]);
193ANONYMOUS_NAMESPACE_END
197NAMESPACE_BEGIN(CryptoPP)
199#if (CRYPTOPP_ARM_NEON_AVAILABLE)
200extern size_t SIMON128_Enc_AdvancedProcessBlocks_NEON(
const word64* subKeys,
size_t rounds,
201 const byte *inBlocks,
const byte *xorBlocks,
byte *outBlocks,
size_t length,
word32 flags);
203extern size_t SIMON128_Dec_AdvancedProcessBlocks_NEON(
const word64* subKeys,
size_t rounds,
204 const byte *inBlocks,
const byte *xorBlocks,
byte *outBlocks,
size_t length,
word32 flags);
207#if (CRYPTOPP_SSSE3_AVAILABLE)
208extern size_t SIMON128_Enc_AdvancedProcessBlocks_SSSE3(
const word64* subKeys,
size_t rounds,
209 const byte *inBlocks,
const byte *xorBlocks,
byte *outBlocks,
size_t length,
word32 flags);
211extern size_t SIMON128_Dec_AdvancedProcessBlocks_SSSE3(
const word64* subKeys,
size_t rounds,
212 const byte *inBlocks,
const byte *xorBlocks,
byte *outBlocks,
size_t length,
word32 flags);
215#if (CRYPTOPP_ALTIVEC_AVAILABLE)
216extern size_t SIMON128_Enc_AdvancedProcessBlocks_ALTIVEC(
const word64* subKeys,
size_t rounds,
217 const byte *inBlocks,
const byte *xorBlocks,
byte *outBlocks,
size_t length,
word32 flags);
219extern size_t SIMON128_Dec_AdvancedProcessBlocks_ALTIVEC(
const word64* subKeys,
size_t rounds,
220 const byte *inBlocks,
const byte *xorBlocks,
byte *outBlocks,
size_t length,
word32 flags);
223std::string SIMON64::Base::AlgorithmProvider()
const
230 return GetAlignmentOf<word32>();
233void SIMON64::Base::UncheckedSetKey(
const byte *userKey,
unsigned int keyLength,
const NameValuePairs ¶ms)
235 CRYPTOPP_ASSERT(keyLength == 12 || keyLength == 16);
236 CRYPTOPP_UNUSED(params);
240 m_kwords = keyLength/
sizeof(
word32);
245 KeyBlock kblk(userKey);
250 m_rkeys.New((m_rounds = 42));
251 kblk(m_wspace[2])(m_wspace[1])(m_wspace[0]);
252 SIMON64_ExpandKey_3W(m_rkeys, m_wspace);
255 m_rkeys.New((m_rounds = 44));
256 kblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]);
257 SIMON64_ExpandKey_4W(m_rkeys, m_wspace);
264void SIMON64::Enc::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock,
byte *outBlock)
const
268 InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]);
273 SIMON_Encrypt<word32, 42>(m_wspace+2, m_wspace+0, m_rkeys);
276 SIMON_Encrypt<word32, 44>(m_wspace+2, m_wspace+0, m_rkeys);
284 OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]);
287void SIMON64::Dec::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock,
byte *outBlock)
const
291 InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]);
296 SIMON_Decrypt<word32, 42>(m_wspace+2, m_wspace+0, m_rkeys);
299 SIMON_Decrypt<word32, 44>(m_wspace+2, m_wspace+0, m_rkeys);
307 OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]);
312std::string SIMON128::Base::AlgorithmProvider()
const
314#if (CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS)
315# if (CRYPTOPP_SSSE3_AVAILABLE)
319# if (CRYPTOPP_ARM_NEON_AVAILABLE)
323# if (CRYPTOPP_ALTIVEC_AVAILABLE)
333#if (CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS)
334# if (CRYPTOPP_SSSE3_AVAILABLE)
338# if (CRYPTOPP_ARM_NEON_AVAILABLE)
342# if (CRYPTOPP_ALTIVEC_AVAILABLE)
347 return GetAlignmentOf<word64>();
350void SIMON128::Base::UncheckedSetKey(
const byte *userKey,
unsigned int keyLength,
const NameValuePairs ¶ms)
352 CRYPTOPP_ASSERT(keyLength == 16 || keyLength == 24 || keyLength == 32);
353 CRYPTOPP_UNUSED(params);
357 m_kwords = keyLength/
sizeof(word64);
362 KeyBlock kblk(userKey);
367 m_rkeys.New((m_rounds = 68));
368 kblk(m_wspace[1])(m_wspace[0]);
369 SIMON128_ExpandKey_2W(m_rkeys, m_wspace);
372 m_rkeys.New((m_rounds = 69));
373 kblk(m_wspace[2])(m_wspace[1])(m_wspace[0]);
374 SIMON128_ExpandKey_3W(m_rkeys, m_wspace);
377 m_rkeys.New((m_rounds = 72));
378 kblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]);
379 SIMON128_ExpandKey_4W(m_rkeys, m_wspace);
385#if CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS
388#if CRYPTOPP_ALTIVEC_AVAILABLE
389 if (IsForwardTransformation() && HasAltivec())
391 AlignedSecBlock presplat(m_rkeys.size()*2);
392 for (
size_t i=0, j=0; i<m_rkeys.size(); i++, j+=2)
393 presplat[j+0] = presplat[j+1] = m_rkeys[i];
394 m_rkeys.swap(presplat);
396#elif CRYPTOPP_SSSE3_AVAILABLE
397 if (IsForwardTransformation() && HasSSSE3())
399 AlignedSecBlock presplat(m_rkeys.size()*2);
400 for (
size_t i=0, j=0; i<m_rkeys.size(); i++, j+=2)
401 presplat[j+0] = presplat[j+1] = m_rkeys[i];
402 m_rkeys.swap(presplat);
409void SIMON128::Enc::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock,
byte *outBlock)
const
413 InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]);
418 SIMON_Encrypt<word64, 68>(m_wspace+2, m_wspace+0, m_rkeys);
421 SIMON_Encrypt<word64, 69>(m_wspace+2, m_wspace+0, m_rkeys);
424 SIMON_Encrypt<word64, 72>(m_wspace+2, m_wspace+0, m_rkeys);
432 OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]);
435void SIMON128::Dec::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock,
byte *outBlock)
const
439 InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]);
444 SIMON_Decrypt<word64, 68>(m_wspace+2, m_wspace+0, m_rkeys);
447 SIMON_Decrypt<word64, 69>(m_wspace+2, m_wspace+0, m_rkeys);
450 SIMON_Decrypt<word64, 72>(m_wspace+2, m_wspace+0, m_rkeys);
458 OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]);
461#if (CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS)
462size_t SIMON128::Enc::AdvancedProcessBlocks(
const byte *inBlocks,
const byte *xorBlocks,
463 byte *outBlocks,
size_t length,
word32 flags)
const
465#if (CRYPTOPP_SSSE3_AVAILABLE)
467 return SIMON128_Enc_AdvancedProcessBlocks_SSSE3(m_rkeys, (
size_t)m_rounds,
468 inBlocks, xorBlocks, outBlocks, length, flags);
470#if (CRYPTOPP_ARM_NEON_AVAILABLE)
472 return SIMON128_Enc_AdvancedProcessBlocks_NEON(m_rkeys, (
size_t)m_rounds,
473 inBlocks, xorBlocks, outBlocks, length, flags);
475#if (CRYPTOPP_ALTIVEC_AVAILABLE)
477 return SIMON128_Enc_AdvancedProcessBlocks_ALTIVEC(m_rkeys, (
size_t)m_rounds,
478 inBlocks, xorBlocks, outBlocks, length, flags);
483size_t SIMON128::Dec::AdvancedProcessBlocks(
const byte *inBlocks,
const byte *xorBlocks,
484 byte *outBlocks,
size_t length,
word32 flags)
const
486#if (CRYPTOPP_SSSE3_AVAILABLE)
488 return SIMON128_Dec_AdvancedProcessBlocks_SSSE3(m_rkeys, (
size_t)m_rounds,
489 inBlocks, xorBlocks, outBlocks, length, flags);
491#if (CRYPTOPP_ARM_NEON_AVAILABLE)
493 return SIMON128_Dec_AdvancedProcessBlocks_NEON(m_rkeys, (
size_t)m_rounds,
494 inBlocks, xorBlocks, outBlocks, length, flags);
496#if (CRYPTOPP_ALTIVEC_AVAILABLE)
498 return SIMON128_Dec_AdvancedProcessBlocks_ALTIVEC(m_rkeys, (
size_t)m_rounds,
499 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 Simon block cipher.