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] =
static_cast<word32
>(c ^ (z & 1) ^ key[i - 3] ^
103 rotrConstant<3>(key[i - 1]) ^ rotrConstant<4>(key[i - 1]));
113 inline 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]));
133 inline 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]);
154 inline 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]);
175 inline 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]);
193 ANONYMOUS_NAMESPACE_END
199 #if (CRYPTOPP_ARM_NEON_AVAILABLE)
200 extern 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);
203 extern 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)
208 extern 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);
211 extern 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)
216 extern 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);
219 extern 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);
223 std::string SIMON64::Base::AlgorithmProvider()
const
230 return GetAlignmentOf<word32>();
233 void SIMON64::Base::UncheckedSetKey(
const byte *userKey,
unsigned int keyLength,
const NameValuePairs ¶ms)
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);
264 void 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]);
287 void 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]);
312 std::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>();
350 void 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);
406 #endif // CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS
409 void 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]);
435 void 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)
462 size_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);
483 size_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);
503 #endif // CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS