1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
// simeck.cpp - written and placed in the public domain by Gangqiang Yang and Jeffrey Walton.
// Based on "The Simeck Family of Lightweight Block Ciphers" by Gangqiang Yang,
// Bo Zhu, Valentin Suder, Mark D. Aagaard, and Guang Gong
#include "pch.h"
#include "config.h"
#include "simeck.h"
#include "misc.h"
#include "cpu.h"
ANONYMOUS_NAMESPACE_BEGIN
using CryptoPP::rotlConstant;
using CryptoPP::rotrConstant;
/// \brief SIMECK encryption round
/// \tparam T word type
/// \param key the key for the round or iteration
/// \param left the first value
/// \param right the second value
/// \details SIMECK_Encryption serves as the key schedule, encryption and
/// decryption functions.
template <class T>
inline void SIMECK_Encryption(const T key, T& left, T& right)
{
const T temp = left;
left = (left & rotlConstant<5>(left)) ^ rotlConstant<1>(left) ^ right ^ key;
right = temp;
}
ANONYMOUS_NAMESPACE_END
NAMESPACE_BEGIN(CryptoPP)
#if CRYPTOPP_SIMECK_ADVANCED_PROCESS_BLOCKS
# if (CRYPTOPP_SSSE3_AVAILABLE)
extern size_t SIMECK64_Enc_AdvancedProcessBlocks_SSSE3(const word32* subKeys, size_t rounds,
const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
extern size_t SIMECK64_Dec_AdvancedProcessBlocks_SSSE3(const word32* subKeys, size_t rounds,
const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
# endif // CRYPTOPP_SSSE3_AVAILABLE
#endif // CRYPTOPP_SIMECK_ADVANCED_PROCESS_BLOCKS
std::string SIMECK32::Base::AlgorithmProvider() const
{
return "C++";
}
void SIMECK32::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms)
{
CRYPTOPP_UNUSED(params);
CRYPTOPP_UNUSED(keyLength);
GetBlock<word16, BigEndian> kblock(userKey);
kblock(m_t[3])(m_t[2])(m_t[1])(m_t[0]);
word16 constant = 0xFFFC;
word32 sequence = 0x9A42BB1F;
for (unsigned int i = 0; i < ROUNDS; ++i)
{
m_rk[i] = m_t[0];
constant &= 0xFFFC;
constant |= sequence & 1;
sequence >>= 1;
SIMECK_Encryption(static_cast<word16>(constant), m_t[1], m_t[0]);
// rotate the LFSR of m_t
m_t[4] = m_t[1];
m_t[1] = m_t[2];
m_t[2] = m_t[3];
m_t[3] = m_t[4];
}
}
void SIMECK32::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
// Do not cast the buffer. It will SIGBUS on some ARM and SPARC.
GetBlock<word16, BigEndian> iblock(inBlock);
iblock(m_t[1])(m_t[0]);
for (int idx = 0; idx < ROUNDS; ++idx)
SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]);
PutBlock<word16, BigEndian> oblock(xorBlock, outBlock);
oblock(m_t[1])(m_t[0]);
}
void SIMECK32::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
// Do not cast the buffer. It will SIGBUS on some ARM and SPARC.
GetBlock<word16, BigEndian> iblock(inBlock);
iblock(m_t[0])(m_t[1]);
for (int idx = ROUNDS - 1; idx >= 0; --idx)
SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]);
PutBlock<word16, BigEndian> oblock(xorBlock, outBlock);
oblock(m_t[0])(m_t[1]);
}
std::string SIMECK64::Base::AlgorithmProvider() const
{
#if (CRYPTOPP_SSSE3_AVAILABLE)
if (HasSSSE3())
return "SSSE3";
#endif
return "C++";
}
void SIMECK64::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms)
{
CRYPTOPP_UNUSED(params);
CRYPTOPP_UNUSED(keyLength);
GetBlock<word32, BigEndian> kblock(userKey);
kblock(m_t[3])(m_t[2])(m_t[1])(m_t[0]);
word64 constant = W64LIT(0xFFFFFFFC);
word64 sequence = W64LIT(0x938BCA3083F);
for (unsigned int i = 0; i < ROUNDS; ++i)
{
m_rk[i] = m_t[0];
constant &= W64LIT(0xFFFFFFFC);
constant |= sequence & 1;
sequence >>= 1;
SIMECK_Encryption(static_cast<word32>(constant), m_t[1], m_t[0]);
// rotate the LFSR of m_t
m_t[4] = m_t[1];
m_t[1] = m_t[2];
m_t[2] = m_t[3];
m_t[3] = m_t[4];
}
}
void SIMECK64::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
// Do not cast the buffer. It will SIGBUS on some ARM and SPARC.
GetBlock<word32, BigEndian> iblock(inBlock);
iblock(m_t[1])(m_t[0]);
for (int idx = 0; idx < ROUNDS; ++idx)
SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]);
PutBlock<word32, BigEndian> oblock(xorBlock, outBlock);
oblock(m_t[1])(m_t[0]);
}
void SIMECK64::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
// Do not cast the buffer. It will SIGBUS on some ARM and SPARC.
GetBlock<word32, BigEndian> iblock(inBlock);
iblock(m_t[0])(m_t[1]);
for (int idx = ROUNDS - 1; idx >= 0; --idx)
SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0]);
PutBlock<word32, BigEndian> oblock(xorBlock, outBlock);
oblock(m_t[0])(m_t[1]);
}
#if CRYPTOPP_SIMECK_ADVANCED_PROCESS_BLOCKS
size_t SIMECK64::Enc::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks,
byte *outBlocks, size_t length, word32 flags) const
{
# if (CRYPTOPP_SSSE3_AVAILABLE)
if (HasSSSE3()) {
return SIMECK64_Enc_AdvancedProcessBlocks_SSSE3(m_rk, ROUNDS,
inBlocks, xorBlocks, outBlocks, length, flags);
}
# endif // CRYPTOPP_SSSE3_AVAILABLE
return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags);
}
size_t SIMECK64::Dec::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks,
byte *outBlocks, size_t length, word32 flags) const
{
# if (CRYPTOPP_SSSE3_AVAILABLE)
if (HasSSSE3()) {
return SIMECK64_Dec_AdvancedProcessBlocks_SSSE3(m_rk, ROUNDS,
inBlocks, xorBlocks, outBlocks, length, flags);
}
# endif // CRYPTOPP_SSSE3_AVAILABLE
return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags);
}
#endif // CRYPTOPP_SIMECK_ADVANCED_PROCESS_BLOCKS
NAMESPACE_END
|