16 ANONYMOUS_NAMESPACE_BEGIN
18 using CryptoPP::word32;
19 using CryptoPP::word64;
29 return (rotlConstant<1>(v) & rotlConstant<8>(v)) ^ rotlConstant<2>(v);
39 inline void R2(W& x, W& y,
const W k,
const W l)
51 template <
class W,
unsigned int R>
52 inline 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;
72 template <
class W,
unsigned int R>
73 inline 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]);
94 inline 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] = c ^ (z & 1) ^ key[i - 3] ^ rotrConstant<3>(key[i - 1]) ^ rotrConstant<4>(key[i - 1]);
112 inline void SIMON64_ExpandKey_4W(word32 key[44],
const word32 k[4])
114 const word32 c = 0xfffffffc;
115 word64 z = W64LIT(0xfc2ce51207a635db);
117 key[0] = k[3]; key[1] = k[2]; key[2] = k[1]; key[3] = k[0];
118 for (
size_t i = 4; i<44; ++i)
120 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]);
130 inline void SIMON128_ExpandKey_2W(word64 key[68],
const word64 k[2])
132 const word64 c = W64LIT(0xfffffffffffffffc);
133 word64 z = W64LIT(0x7369f885192c0ef5);
135 key[0] = k[1]; key[1] = k[0];
136 for (
size_t i=2; i<66; ++i)
138 key[i] = c ^ (z & 1) ^ key[i - 2] ^ rotrConstant<3>(key[i - 1]) ^ rotrConstant<4>(key[i - 1]);
142 key[66] = c ^ 1 ^ key[64] ^ rotrConstant<3>(key[65]) ^ rotrConstant<4>(key[65]);
143 key[67] = c^key[65] ^ rotrConstant<3>(key[66]) ^ rotrConstant<4>(key[66]);
151 inline void SIMON128_ExpandKey_3W(word64 key[69],
const word64 k[3])
153 const word64 c = W64LIT(0xfffffffffffffffc);
154 word64 z = W64LIT(0xfc2ce51207a635db);
156 key[0]=k[2]; key[1]=k[1]; key[2]=k[0];
157 for (
size_t i=3; i<67; ++i)
159 key[i] = c ^ (z & 1) ^ key[i - 3] ^ rotrConstant<3>(key[i - 1]) ^ rotrConstant<4>(key[i - 1]);
163 key[67] = c^key[64] ^ rotrConstant<3>(key[66]) ^ rotrConstant<4>(key[66]);
164 key[68] = c ^ 1 ^ key[65] ^ rotrConstant<3>(key[67]) ^ rotrConstant<4>(key[67]);
172 inline void SIMON128_ExpandKey_4W(word64 key[72],
const word64 k[4])
174 const word64 c = W64LIT(0xfffffffffffffffc);
175 word64 z = W64LIT(0xfdc94c3a046d678b);
177 key[0]=k[3]; key[1]=k[2]; key[2]=k[1]; key[3]=k[0];
178 for (
size_t i=4; i<68; ++i)
180 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 key[68] = c^key[64] ^ rotrConstant<3>(key[67]) ^ key[65] ^ rotrConstant<4>(key[67]) ^ rotrConstant<1>(key[65]);
185 key[69] = c ^ 1 ^ key[65] ^ rotrConstant<3>(key[68]) ^ key[66] ^ rotrConstant<4>(key[68]) ^ rotrConstant<1>(key[66]);
186 key[70] = c^key[66] ^ rotrConstant<3>(key[69]) ^ key[67] ^ rotrConstant<4>(key[69]) ^ rotrConstant<1>(key[67]);
187 key[71] = c^key[67] ^ rotrConstant<3>(key[70]) ^ key[68] ^ rotrConstant<4>(key[70]) ^ rotrConstant<1>(key[68]);
190 ANONYMOUS_NAMESPACE_END
196 #if (CRYPTOPP_ARM_NEON_AVAILABLE) 197 extern size_t SIMON64_Enc_AdvancedProcessBlocks_NEON(
const word32* subKeys,
size_t rounds,
198 const byte *inBlocks,
const byte *xorBlocks, byte *outBlocks,
size_t length, word32 flags);
200 extern size_t SIMON64_Dec_AdvancedProcessBlocks_NEON(
const word32* subKeys,
size_t rounds,
201 const byte *inBlocks,
const byte *xorBlocks, byte *outBlocks,
size_t length, word32 flags);
204 #if (CRYPTOPP_ARM_NEON_AVAILABLE) 205 extern size_t SIMON128_Enc_AdvancedProcessBlocks_NEON(
const word64* subKeys,
size_t rounds,
206 const byte *inBlocks,
const byte *xorBlocks, byte *outBlocks,
size_t length, word32 flags);
208 extern size_t SIMON128_Dec_AdvancedProcessBlocks_NEON(
const word64* subKeys,
size_t rounds,
209 const byte *inBlocks,
const byte *xorBlocks, byte *outBlocks,
size_t length, word32 flags);
212 #if defined(CRYPTOPP_SSE41_AVAILABLE) 213 extern size_t SIMON64_Enc_AdvancedProcessBlocks_SSE41(
const word32* subKeys,
size_t rounds,
214 const byte *inBlocks,
const byte *xorBlocks, byte *outBlocks,
size_t length, word32 flags);
216 extern size_t SIMON64_Dec_AdvancedProcessBlocks_SSE41(
const word32* subKeys,
size_t rounds,
217 const byte *inBlocks,
const byte *xorBlocks, byte *outBlocks,
size_t length, word32 flags);
220 #if defined(CRYPTOPP_SSSE3_AVAILABLE) 221 extern size_t SIMON128_Enc_AdvancedProcessBlocks_SSSE3(
const word64* subKeys,
size_t rounds,
222 const byte *inBlocks,
const byte *xorBlocks, byte *outBlocks,
size_t length, word32 flags);
224 extern size_t SIMON128_Dec_AdvancedProcessBlocks_SSSE3(
const word64* subKeys,
size_t rounds,
225 const byte *inBlocks,
const byte *xorBlocks, byte *outBlocks,
size_t length, word32 flags);
228 void SIMON64::Base::UncheckedSetKey(
const byte *userKey,
unsigned int keyLength,
const NameValuePairs ¶ms)
231 CRYPTOPP_UNUSED(params);
235 m_kwords = keyLength/
sizeof(word32);
240 KeyBlock kblk(userKey);
245 m_rkeys.
New((m_rounds = 42));
246 kblk(m_wspace[2])(m_wspace[1])(m_wspace[0]);
247 SIMON64_ExpandKey_3W(m_rkeys, m_wspace);
250 m_rkeys.
New((m_rounds = 44));
251 kblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]);
252 SIMON64_ExpandKey_4W(m_rkeys, m_wspace);
259 void SIMON64::Enc::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock, byte *outBlock)
const 263 InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]);
268 SIMON_Encrypt<word32, 42>(m_wspace+2, m_wspace+0, m_rkeys);
271 SIMON_Encrypt<word32, 44>(m_wspace+2, m_wspace+0, m_rkeys);
279 OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]);
282 void SIMON64::Dec::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock, byte *outBlock)
const 286 InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]);
291 SIMON_Decrypt<word32, 42>(m_wspace+2, m_wspace+0, m_rkeys);
294 SIMON_Decrypt<word32, 44>(m_wspace+2, m_wspace+0, m_rkeys);
302 OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]);
307 void SIMON128::Base::UncheckedSetKey(
const byte *userKey,
unsigned int keyLength,
const NameValuePairs ¶ms)
309 CRYPTOPP_ASSERT(keyLength == 16 || keyLength == 24 || keyLength == 32);
310 CRYPTOPP_UNUSED(params);
314 m_kwords = keyLength/
sizeof(word64);
319 KeyBlock kblk(userKey);
324 m_rkeys.
New((m_rounds = 68));
325 kblk(m_wspace[1])(m_wspace[0]);
326 SIMON128_ExpandKey_2W(m_rkeys, m_wspace);
329 m_rkeys.
New((m_rounds = 69));
330 kblk(m_wspace[2])(m_wspace[1])(m_wspace[0]);
331 SIMON128_ExpandKey_3W(m_rkeys, m_wspace);
334 m_rkeys.
New((m_rounds = 72));
335 kblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]);
336 SIMON128_ExpandKey_4W(m_rkeys, m_wspace);
343 void SIMON128::Enc::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock, byte *outBlock)
const 347 InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]);
352 SIMON_Encrypt<word64, 68>(m_wspace+2, m_wspace+0, m_rkeys);
355 SIMON_Encrypt<word64, 69>(m_wspace+2, m_wspace+0, m_rkeys);
358 SIMON_Encrypt<word64, 72>(m_wspace+2, m_wspace+0, m_rkeys);
366 OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]);
369 void SIMON128::Dec::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock, byte *outBlock)
const 373 InBlock iblk(inBlock); iblk(m_wspace[1])(m_wspace[0]);
378 SIMON_Decrypt<word64, 68>(m_wspace+2, m_wspace+0, m_rkeys);
381 SIMON_Decrypt<word64, 69>(m_wspace+2, m_wspace+0, m_rkeys);
384 SIMON_Decrypt<word64, 72>(m_wspace+2, m_wspace+0, m_rkeys);
392 OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2]);
395 #if defined(CRYPTOPP_SIMON64_ADVANCED_PROCESS_BLOCKS) 396 size_t SIMON64::Enc::AdvancedProcessBlocks(
const byte *inBlocks,
const byte *xorBlocks,
397 byte *outBlocks,
size_t length, word32 flags)
const 399 #if defined(CRYPTOPP_SSE41_AVAILABLE) 401 return SIMON64_Enc_AdvancedProcessBlocks_SSE41(m_rkeys, (
size_t)m_rounds,
402 inBlocks, xorBlocks, outBlocks, length, flags);
404 #if (CRYPTOPP_ARM_NEON_AVAILABLE) 406 return SIMON64_Enc_AdvancedProcessBlocks_NEON(m_rkeys, (
size_t)m_rounds,
407 inBlocks, xorBlocks, outBlocks, length, flags);
412 size_t SIMON64::Dec::AdvancedProcessBlocks(
const byte *inBlocks,
const byte *xorBlocks,
413 byte *outBlocks,
size_t length, word32 flags)
const 415 #if defined(CRYPTOPP_SSE41_AVAILABLE) 417 return SIMON64_Dec_AdvancedProcessBlocks_SSE41(m_rkeys, (
size_t)m_rounds,
418 inBlocks, xorBlocks, outBlocks, length, flags);
420 #if (CRYPTOPP_ARM_NEON_AVAILABLE) 422 return SIMON64_Dec_AdvancedProcessBlocks_NEON(m_rkeys, (
size_t)m_rounds,
423 inBlocks, xorBlocks, outBlocks, length, flags);
427 #endif // CRYPTOPP_SIMON64_ADVANCED_PROCESS_BLOCKS 429 #if defined(CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS) 430 size_t SIMON128::Enc::AdvancedProcessBlocks(
const byte *inBlocks,
const byte *xorBlocks,
431 byte *outBlocks,
size_t length, word32 flags)
const 433 #if defined(CRYPTOPP_SSSE3_AVAILABLE) 435 return SIMON128_Enc_AdvancedProcessBlocks_SSSE3(m_rkeys, (
size_t)m_rounds,
436 inBlocks, xorBlocks, outBlocks, length, flags);
438 #if (CRYPTOPP_ARM_NEON_AVAILABLE) 440 return SIMON128_Enc_AdvancedProcessBlocks_NEON(m_rkeys, (
size_t)m_rounds,
441 inBlocks, xorBlocks, outBlocks, length, flags);
446 size_t SIMON128::Dec::AdvancedProcessBlocks(
const byte *inBlocks,
const byte *xorBlocks,
447 byte *outBlocks,
size_t length, word32 flags)
const 449 #if defined(CRYPTOPP_SSSE3_AVAILABLE) 451 return SIMON128_Dec_AdvancedProcessBlocks_SSSE3(m_rkeys, (
size_t)m_rounds,
452 inBlocks, xorBlocks, outBlocks, length, flags);
454 #if (CRYPTOPP_ARM_NEON_AVAILABLE) 456 return SIMON128_Dec_AdvancedProcessBlocks_NEON(m_rkeys, (
size_t)m_rounds,
457 inBlocks, xorBlocks, outBlocks, length, flags);
461 #endif // CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS Utility functions for the Crypto++ library.
bool HasSSSE3()
Determines SSSE3 availability.
Library configuration file.
void New(size_type newSize)
Change size without preserving contents.
T rotlConstant(T x)
Performs a left rotate.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Functions for CPU features and intrinsics.
T rotrConstant(T x)
Performs a right rotate.
Access a block of memory.
Classes for the Simon block cipher.
bool HasSSE41()
Determines SSE4.1 availability.
Access a block of memory.
Crypto++ library namespace.
bool HasNEON()
Determine if an ARM processor has Advanced SIMD available.
Interface for retrieving values given their names.