76 static inline void IPERM(word32 &left, word32 &right)
80 right = rotlConstant<4>(right);
81 work = (left ^ right) & 0xf0f0f0f0;
83 right = rotrConstant<20>(right^work);
84 work = (left ^ right) & 0xffff0000;
86 right = rotrConstant<18>(right^work);
87 work = (left ^ right) & 0x33333333;
89 right = rotrConstant<6>(right^work);
90 work = (left ^ right) & 0x00ff00ff;
92 right = rotlConstant<9>(right^work);
93 work = (left ^ right) & 0xaaaaaaaa;
94 left = rotlConstant<1>(left^work);
98 static inline void FPERM(word32 &left, word32 &right)
102 right = rotrConstant<1>(right);
103 work = (left ^ right) & 0xaaaaaaaa;
105 left = rotrConstant<9>(left^work);
106 work = (left ^ right) & 0x00ff00ff;
108 left = rotlConstant<6>(left^work);
109 work = (left ^ right) & 0x33333333;
111 left = rotlConstant<18>(left^work);
112 work = (left ^ right) & 0xffff0000;
114 left = rotlConstant<20>(left^work);
115 work = (left ^ right) & 0xf0f0f0f0;
117 left = rotrConstant<4>(left^work);
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
225 const byte p32i[] = {
241 57, 49, 41, 33, 25, 17, 9,
242 1, 58, 50, 42, 34, 26, 18,
243 10, 2, 59, 51, 43, 35, 27,
244 19, 11, 3, 60, 52, 44, 36,
246 63, 55, 47, 39, 31, 23, 15,
247 7, 62, 54, 46, 38, 30, 22,
248 14, 6, 61, 53, 45, 37, 29,
249 21, 13, 5, 28, 20, 12, 4
255 const byte totrot[] = {
256 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
263 14, 17, 11, 24, 1, 5,
264 3, 28, 15, 6, 21, 10,
265 23, 19, 12, 4, 26, 8,
266 16, 7, 27, 20, 13, 2,
267 41, 52, 31, 37, 47, 55,
268 30, 40, 51, 45, 33, 48,
269 44, 49, 39, 56, 34, 53,
270 46, 42, 50, 36, 29, 32
278 const int bytebit[] = {
279 0200,0100,040,020,010,04,02,01
284 void RawDES::RawSetKey(
CipherDir dir,
const byte *key)
286 #if (_MSC_VER >= 1600) || (__cplusplus >= 201103L) 291 byte *
const pc1m=buffer;
292 byte *
const pcr=pc1m+56;
293 byte *
const ks=pcr+56;
297 for (j=0; j<56; j++) {
304 for (i=0; i<16; i++) {
307 pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
309 for (j=0; j<48; j++){
314 ks[j/6] |= bytebit[l] >> 2;
318 k[2*i] = ((word32)ks[0] << 24)
319 | ((word32)ks[2] << 16)
320 | ((word32)ks[4] << 8)
322 k[2*i+1] = ((word32)ks[1] << 24)
323 | ((word32)ks[3] << 16)
324 | ((word32)ks[5] << 8)
329 for (i=0; i<16; i+=2)
331 std::swap(k[i], k[32-2-i]);
332 std::swap(k[i+1], k[32-1-i]);
336 void RawDES::RawProcessBlock(word32 &l_, word32 &r_)
const 338 word32 l = l_, r = r_;
339 const word32 *kptr=k;
341 for (
unsigned i=0; i<8; i++)
343 word32 work = rotrConstant<4>(r) ^ kptr[4 * i + 0];
344 l ^= Spbox[6][(work) & 0x3f]
345 ^ Spbox[4][(work >> 8) & 0x3f]
346 ^ Spbox[2][(work >> 16) & 0x3f]
347 ^ Spbox[0][(work >> 24) & 0x3f];
348 work = r ^ kptr[4*i+1];
349 l ^= Spbox[7][(work) & 0x3f]
350 ^ Spbox[5][(work >> 8) & 0x3f]
351 ^ Spbox[3][(work >> 16) & 0x3f]
352 ^ Spbox[1][(work >> 24) & 0x3f];
354 work = rotrConstant<4>(l) ^ kptr[4 * i + 2];
355 r ^= Spbox[6][(work) & 0x3f]
356 ^ Spbox[4][(work >> 8) & 0x3f]
357 ^ Spbox[2][(work >> 16) & 0x3f]
358 ^ Spbox[0][(work >> 24) & 0x3f];
359 work = l ^ kptr[4*i+3];
360 r ^= Spbox[7][(work) & 0x3f]
361 ^ Spbox[5][(work >> 8) & 0x3f]
362 ^ Spbox[3][(work >> 16) & 0x3f]
363 ^ Spbox[1][(work >> 24) & 0x3f];
369 void DES_EDE2::Base::UncheckedSetKey(
const byte *userKey,
unsigned int length,
const NameValuePairs &)
371 AssertValidKeyLength(length);
373 m_des1.RawSetKey(GetCipherDirection(), userKey);
377 void DES_EDE2::Base::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock,
byte *outBlock)
const 380 Block::Get(inBlock)(l)(r);
382 m_des1.RawProcessBlock(l, r);
383 m_des2.RawProcessBlock(r, l);
384 m_des1.RawProcessBlock(l, r);
389 void DES_EDE3::Base::UncheckedSetKey(
const byte *userKey,
unsigned int length,
const NameValuePairs &)
391 AssertValidKeyLength(length);
393 m_des1.RawSetKey(GetCipherDirection(), userKey + (IsForwardTransformation() ? 0 : 16));
395 m_des3.RawSetKey(GetCipherDirection(), userKey + (IsForwardTransformation() ? 16 : 0));
398 void DES_EDE3::Base::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock,
byte *outBlock)
const 401 Block::Get(inBlock)(l)(r);
403 m_des1.RawProcessBlock(l, r);
404 m_des2.RawProcessBlock(r, l);
405 m_des3.RawProcessBlock(l, r);
410 #endif // #ifndef CRYPTOPP_IMPORTS 412 static inline bool CheckParity(
byte b)
414 unsigned int a = b ^ (b >> 4);
415 return ((a ^ (a>>1) ^ (a>>2) ^ (a>>3)) & 1) == 1;
420 for (
unsigned int i=0; i<8; i++)
421 if (!CheckParity(key[i]))
428 for (
unsigned int i=0; i<8; i++)
429 if (!CheckParity(key[i]))
434 void DES::Base::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock,
byte *outBlock)
const 437 Block::Get(inBlock)(l)(r);
439 RawProcessBlock(l, r);
444 void DES_XEX3::Base::UncheckedSetKey(
const byte *key,
unsigned int length,
const NameValuePairs &)
446 AssertValidKeyLength(length);
451 memcpy(m_x1, key + (IsForwardTransformation() ? 0 : 16), BLOCKSIZE);
452 m_des->RawSetKey(GetCipherDirection(), key + 8);
453 memcpy(m_x3, key + (IsForwardTransformation() ? 16 : 0), BLOCKSIZE);
456 void DES_XEX3::Base::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock,
byte *outBlock)
const 458 xorbuf(outBlock, inBlock, m_x1, BLOCKSIZE);
459 m_des->ProcessAndXorBlock(outBlock, xorBlock, outBlock);
460 xorbuf(outBlock, m_x3, BLOCKSIZE);
the cipher is performing decryption
Utility functions for the Crypto++ library.
static void CorrectKeyParityBits(byte *key)
correct DES key parity bits
CipherDir
Specifies a direction for a cipher to operate.
Access a block of memory.
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.
Access a block of memory.
Crypto++ library namespace.
Interface for retrieving values given their names.