76 static inline
void IPERM(word32 &left, word32 &right)
81 work = (left ^ right) & 0xf0f0f0f0;
84 work = (left ^ right) & 0xffff0000;
87 work = (left ^ right) & 0x33333333;
90 work = (left ^ right) & 0x00ff00ff;
93 work = (left ^ right) & 0xaaaaaaaa;
98 static inline void FPERM(word32 &left, word32 &right)
103 work = (left ^ right) & 0xaaaaaaaa;
106 work = (left ^ right) & 0x00ff00ff;
109 work = (left ^ right) & 0x33333333;
112 work = (left ^ right) & 0xffff0000;
115 work = (left ^ right) & 0xf0f0f0f0;
120 void DES::Base::UncheckedSetKey(
const byte *userKey,
unsigned int length,
const NameValuePairs &)
122 AssertValidKeyLength(length);
124 RawSetKey(GetCipherDirection(), userKey);
127 #ifndef CRYPTOPP_IMPORTS 140 58, 50, 42, 34, 26, 18, 10, 2,
141 60, 52, 44, 36, 28, 20, 12, 4,
142 62, 54, 46, 38, 30, 22, 14, 6,
143 64, 56, 48, 40, 32, 24, 16, 8,
144 57, 49, 41, 33, 25, 17, 9, 1,
145 59, 51, 43, 35, 27, 19, 11, 3,
146 61, 53, 45, 37, 29, 21, 13, 5,
147 63, 55, 47, 39, 31, 23, 15, 7
152 40, 8, 48, 16, 56, 24, 64, 32,
153 39, 7, 47, 15, 55, 23, 63, 31,
154 38, 6, 46, 14, 54, 22, 62, 30,
155 37, 5, 45, 13, 53, 21, 61, 29,
156 36, 4, 44, 12, 52, 20, 60, 28,
157 35, 3, 43, 11, 51, 19, 59, 27,
158 34, 2, 42, 10, 50, 18, 58, 26,
159 33, 1, 41, 9, 49, 17, 57, 25
165 8, 9, 10, 11, 12, 13,
166 12, 13, 14, 15, 16, 17,
167 16, 17, 18, 19, 20, 21,
168 20, 21, 22, 23, 24, 25,
169 24, 25, 26, 27, 28, 29,
170 28, 29, 30, 31, 32, 1
173 static byte sbox[8][64] = {
175 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
176 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
177 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
178 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
181 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
182 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
183 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
184 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
187 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
188 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
189 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
190 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
193 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
194 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
195 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
196 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
199 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
200 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
201 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
202 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
205 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
206 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
207 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
208 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
211 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
212 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
213 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
214 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
217 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
218 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
219 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
220 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
224 static byte p32i[] = {
237 static const byte pc1[] = {
238 57, 49, 41, 33, 25, 17, 9,
239 1, 58, 50, 42, 34, 26, 18,
240 10, 2, 59, 51, 43, 35, 27,
241 19, 11, 3, 60, 52, 44, 36,
243 63, 55, 47, 39, 31, 23, 15,
244 7, 62, 54, 46, 38, 30, 22,
245 14, 6, 61, 53, 45, 37, 29,
246 21, 13, 5, 28, 20, 12, 4
250 static const byte totrot[] = {
251 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
255 static const byte pc2[] = {
256 14, 17, 11, 24, 1, 5,
257 3, 28, 15, 6, 21, 10,
258 23, 19, 12, 4, 26, 8,
259 16, 7, 27, 20, 13, 2,
260 41, 52, 31, 37, 47, 55,
261 30, 40, 51, 45, 33, 48,
262 44, 49, 39, 56, 34, 53,
263 46, 42, 50, 36, 29, 32
269 static const int bytebit[] = {
270 0200,0100,040,020,010,04,02,01
274 void RawDES::RawSetKey(
CipherDir dir,
const byte *key)
276 #if (_MSC_VER >= 1600) || (__cplusplus >= 201103L) 281 byte *
const pc1m=buffer;
282 byte *
const pcr=pc1m+56;
283 byte *
const ks=pcr+56;
287 for (j=0; j<56; j++) {
294 for (i=0; i<16; i++) {
297 pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
299 for (j=0; j<48; j++){
304 ks[j/6] |= bytebit[l] >> 2;
308 k[2*i] = ((word32)ks[0] << 24)
309 | ((word32)ks[2] << 16)
310 | ((word32)ks[4] << 8)
312 k[2*i+1] = ((word32)ks[1] << 24)
313 | ((word32)ks[3] << 16)
314 | ((word32)ks[5] << 8)
319 for (i=0; i<16; i+=2)
321 std::swap(k[i], k[32-2-i]);
322 std::swap(k[i+1], k[32-1-i]);
326 void RawDES::RawProcessBlock(word32 &l_, word32 &r_)
const 328 word32 l = l_, r = r_;
329 const word32 *kptr=k;
331 for (
unsigned i=0; i<8; i++)
333 word32 work =
rotrFixed(r, 4U) ^ kptr[4*i+0];
334 l ^= Spbox[6][(work) & 0x3f]
335 ^ Spbox[4][(work >> 8) & 0x3f]
336 ^ Spbox[2][(work >> 16) & 0x3f]
337 ^ Spbox[0][(work >> 24) & 0x3f];
338 work = r ^ kptr[4*i+1];
339 l ^= Spbox[7][(work) & 0x3f]
340 ^ Spbox[5][(work >> 8) & 0x3f]
341 ^ Spbox[3][(work >> 16) & 0x3f]
342 ^ Spbox[1][(work >> 24) & 0x3f];
345 r ^= Spbox[6][(work) & 0x3f]
346 ^ Spbox[4][(work >> 8) & 0x3f]
347 ^ Spbox[2][(work >> 16) & 0x3f]
348 ^ Spbox[0][(work >> 24) & 0x3f];
349 work = l ^ kptr[4*i+3];
350 r ^= Spbox[7][(work) & 0x3f]
351 ^ Spbox[5][(work >> 8) & 0x3f]
352 ^ Spbox[3][(work >> 16) & 0x3f]
353 ^ Spbox[1][(work >> 24) & 0x3f];
359 void DES_EDE2::Base::UncheckedSetKey(
const byte *userKey,
unsigned int length,
const NameValuePairs &)
361 AssertValidKeyLength(length);
363 m_des1.RawSetKey(GetCipherDirection(), userKey);
367 void DES_EDE2::Base::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock, byte *outBlock)
const 370 Block::Get(inBlock)(l)(r);
372 m_des1.RawProcessBlock(l, r);
373 m_des2.RawProcessBlock(r, l);
374 m_des1.RawProcessBlock(l, r);
379 void DES_EDE3::Base::UncheckedSetKey(
const byte *userKey,
unsigned int length,
const NameValuePairs &)
381 AssertValidKeyLength(length);
383 m_des1.RawSetKey(GetCipherDirection(), userKey + (IsForwardTransformation() ? 0 : 16));
385 m_des3.RawSetKey(GetCipherDirection(), userKey + (IsForwardTransformation() ? 16 : 0));
388 void DES_EDE3::Base::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock, byte *outBlock)
const 391 Block::Get(inBlock)(l)(r);
393 m_des1.RawProcessBlock(l, r);
394 m_des2.RawProcessBlock(r, l);
395 m_des3.RawProcessBlock(l, r);
400 #endif // #ifndef CRYPTOPP_IMPORTS 402 static inline bool CheckParity(byte b)
404 unsigned int a = b ^ (b >> 4);
405 return ((a ^ (a>>1) ^ (a>>2) ^ (a>>3)) & 1) == 1;
410 for (
unsigned int i=0; i<8; i++)
411 if (!CheckParity(key[i]))
418 for (
unsigned int i=0; i<8; i++)
419 if (!CheckParity(key[i]))
424 void DES::Base::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock, byte *outBlock)
const 427 Block::Get(inBlock)(l)(r);
429 RawProcessBlock(l, r);
434 void DES_XEX3::Base::UncheckedSetKey(
const byte *key,
unsigned int length,
const NameValuePairs &)
436 AssertValidKeyLength(length);
441 memcpy(m_x1, key + (IsForwardTransformation() ? 0 : 16), BLOCKSIZE);
442 m_des->RawSetKey(GetCipherDirection(), key + 8);
443 memcpy(m_x3, key + (IsForwardTransformation() ? 16 : 0), BLOCKSIZE);
446 void DES_XEX3::Base::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock, byte *outBlock)
const 448 xorbuf(outBlock, inBlock, m_x1, BLOCKSIZE);
449 m_des->ProcessAndXorBlock(outBlock, xorBlock, outBlock);
450 xorbuf(outBlock, m_x3, BLOCKSIZE);
Utility functions for the Crypto++ library.
static void CorrectKeyParityBits(byte *key)
correct DES key parity bits
T rotlFixed(T x, unsigned int y)
Performs a left rotate.
Converts a typename to an enumerated value.
CipherDir
Specifies a direction for a cipher to operate.
SecByteBlock is a SecBlock<byte> typedef.
Provides class member functions to key a block cipher.
static bool CheckKeyParityBits(const byte *key)
check DES key parity bits
CipherDir ReverseCipherDir(CipherDir dir)
Inverts the cipher's direction.
Classes for DES, 2-key Triple-DES, 3-key Triple-DES and DESX.
void xorbuf(byte *buf, const byte *mask, size_t count)
Performs an XOR of a buffer with a mask.
Crypto++ library namespace.
T rotrFixed(T x, unsigned int y)
Performs a right rotate.
Interface for retrieving values given their names.