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);
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);
120void 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
173static 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
284void RawDES::RawSetKey(
CipherDir dir,
const byte *key)
286#if (_MSC_VER >= 1600) || (__cplusplus >= 201103L)
289# define REGISTER register
293 byte *
const pc1m=buffer;
294 byte *
const pcr=pc1m+56;
295 byte *
const ks=pcr+56;
299 for (j=0; j<56; j++) {
306 for (i=0; i<16; i++) {
309 pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
311 for (j=0; j<48; j++){
316 ks[j/6] |= bytebit[l] >> 2;
320 k[2*i] = ((
word32)ks[0] << 24)
324 k[2*i+1] = ((
word32)ks[1] << 24)
331 for (i=0; i<16; i+=2)
338void RawDES::RawProcessBlock(
word32 &l_,
word32 &r_)
const
343 for (
unsigned i=0; i<8; i++)
345 word32 work = rotrConstant<4>(r) ^ kptr[4 * i + 0];
346 l ^= Spbox[6][(work) & 0x3f]
347 ^ Spbox[4][(work >> 8) & 0x3f]
348 ^ Spbox[2][(work >> 16) & 0x3f]
349 ^ Spbox[0][(work >> 24) & 0x3f];
350 work = r ^ kptr[4*i+1];
351 l ^= Spbox[7][(work) & 0x3f]
352 ^ Spbox[5][(work >> 8) & 0x3f]
353 ^ Spbox[3][(work >> 16) & 0x3f]
354 ^ Spbox[1][(work >> 24) & 0x3f];
356 work = rotrConstant<4>(l) ^ kptr[4 * i + 2];
357 r ^= Spbox[6][(work) & 0x3f]
358 ^ Spbox[4][(work >> 8) & 0x3f]
359 ^ Spbox[2][(work >> 16) & 0x3f]
360 ^ Spbox[0][(work >> 24) & 0x3f];
361 work = l ^ kptr[4*i+3];
362 r ^= Spbox[7][(work) & 0x3f]
363 ^ Spbox[5][(work >> 8) & 0x3f]
364 ^ Spbox[3][(work >> 16) & 0x3f]
365 ^ Spbox[1][(work >> 24) & 0x3f];
371void DES_EDE2::Base::UncheckedSetKey(
const byte *userKey,
unsigned int length,
const NameValuePairs &)
373 AssertValidKeyLength(length);
375 m_des1.RawSetKey(GetCipherDirection(), userKey);
379void DES_EDE2::Base::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock,
byte *outBlock)
const
382 Block::Get(inBlock)(l)(r);
384 m_des1.RawProcessBlock(l, r);
385 m_des2.RawProcessBlock(r, l);
386 m_des1.RawProcessBlock(l, r);
391void DES_EDE3::Base::UncheckedSetKey(
const byte *userKey,
unsigned int length,
const NameValuePairs &)
393 AssertValidKeyLength(length);
395 m_des1.RawSetKey(GetCipherDirection(), userKey + (IsForwardTransformation() ? 0 : 16));
397 m_des3.RawSetKey(GetCipherDirection(), userKey + (IsForwardTransformation() ? 16 : 0));
400void DES_EDE3::Base::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock,
byte *outBlock)
const
403 Block::Get(inBlock)(l)(r);
405 m_des1.RawProcessBlock(l, r);
406 m_des2.RawProcessBlock(r, l);
407 m_des3.RawProcessBlock(l, r);
414static inline bool CheckParity(
byte b)
416 unsigned int a = b ^ (b >> 4);
417 return ((a ^ (a>>1) ^ (a>>2) ^ (a>>3)) & 1) == 1;
422 for (
unsigned int i=0; i<8; i++)
423 if (!CheckParity(key[i]))
430 for (
unsigned int i=0; i<8; i++)
431 if (!CheckParity(key[i]))
436void DES::Base::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock,
byte *outBlock)
const
439 Block::Get(inBlock)(l)(r);
441 RawProcessBlock(l, r);
446void DES_XEX3::Base::UncheckedSetKey(
const byte *key,
unsigned int length,
const NameValuePairs &)
448 AssertValidKeyLength(length);
453 memcpy(m_x1, key + (IsForwardTransformation() ? 0 : 16), BLOCKSIZE);
454 m_des->RawSetKey(GetCipherDirection(), key + 8);
455 memcpy(m_x3, key + (IsForwardTransformation() ? 16 : 0), BLOCKSIZE);
458void DES_XEX3::Base::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock,
byte *outBlock)
const
460 xorbuf(outBlock, inBlock, m_x1, BLOCKSIZE);
461 m_des->ProcessAndXorBlock(outBlock, xorBlock, outBlock);
462 xorbuf(outBlock, m_x3, BLOCKSIZE);
Provides class member functions to key a block cipher.
static bool CheckKeyParityBits(const byte *key)
check DES key parity bits
static void CorrectKeyParityBits(byte *key)
correct DES key parity bits
Interface for retrieving values given their names.
Access a block of memory.
unsigned int word32
32-bit unsigned datatype
CipherDir
Specifies a direction for a cipher to operate.
@ DECRYPTION
the cipher is performing decryption
Classes for DES, 2-key Triple-DES, 3-key Triple-DES and DESX.
Utility functions for the Crypto++ library.
CRYPTOPP_DLL void xorbuf(byte *buf, const byte *mask, size_t count)
Performs an XOR of a buffer with a mask.
Crypto++ library namespace.
void swap(::SecBlock< T, A > &a, ::SecBlock< T, A > &b)
Swap two SecBlocks.
CipherDir ReverseCipherDir(CipherDir dir)
Inverts the cipher's direction.
Access a block of memory.