21 NAMESPACE_BEGIN(CryptoPP)
76 static inline
void IPERM(word32 &left, word32 &right)
80 right = rotlFixed(right, 4U);
81 work = (left ^ right) & 0xf0f0f0f0;
83 right = rotrFixed(right^work, 20U);
84 work = (left ^ right) & 0xffff0000;
86 right = rotrFixed(right^work, 18U);
87 work = (left ^ right) & 0x33333333;
89 right = rotrFixed(right^work, 6U);
90 work = (left ^ right) & 0x00ff00ff;
92 right = rotlFixed(right^work, 9U);
93 work = (left ^ right) & 0xaaaaaaaa;
94 left = rotlFixed(left^work, 1U);
98 static inline void FPERM(word32 &left, word32 &right)
102 right = rotrFixed(right, 1U);
103 work = (left ^ right) & 0xaaaaaaaa;
105 left = rotrFixed(left^work, 9U);
106 work = (left ^ right) & 0x00ff00ff;
108 left = rotlFixed(left^work, 6U);
109 work = (left ^ right) & 0x33333333;
111 left = rotlFixed(left^work, 18U);
112 work = (left ^ right) & 0xffff0000;
114 left = rotlFixed(left^work, 20U);
115 work = (left ^ right) & 0xf0f0f0f0;
117 left = rotrFixed(left^work, 4U);
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)
277 byte *
const pc1m=buffer;
278 byte *
const pcr=pc1m+56;
279 byte *
const ks=pcr+56;
283 for (j=0; j<56; j++) {
290 for (i=0; i<16; i++) {
293 pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
295 for (j=0; j<48; j++){
300 ks[j/6] |= bytebit[l] >> 2;
304 k[2*i] = ((word32)ks[0] << 24)
305 | ((word32)ks[2] << 16)
306 | ((word32)ks[4] << 8)
308 k[2*i+1] = ((word32)ks[1] << 24)
309 | ((word32)ks[3] << 16)
310 | ((word32)ks[5] << 8)
315 for (i=0; i<16; i+=2)
317 std::swap(k[i], k[32-2-i]);
318 std::swap(k[i+1], k[32-1-i]);
322 void RawDES::RawProcessBlock(word32 &l_, word32 &r_)
const
324 word32 l = l_, r = r_;
325 const word32 *kptr=k;
327 for (
unsigned i=0; i<8; i++)
329 word32 work = rotrFixed(r, 4U) ^ kptr[4*i+0];
330 l ^= Spbox[6][(work) & 0x3f]
331 ^ Spbox[4][(work >> 8) & 0x3f]
332 ^ Spbox[2][(work >> 16) & 0x3f]
333 ^ Spbox[0][(work >> 24) & 0x3f];
334 work = r ^ kptr[4*i+1];
335 l ^= Spbox[7][(work) & 0x3f]
336 ^ Spbox[5][(work >> 8) & 0x3f]
337 ^ Spbox[3][(work >> 16) & 0x3f]
338 ^ Spbox[1][(work >> 24) & 0x3f];
340 work = rotrFixed(l, 4U) ^ kptr[4*i+2];
341 r ^= Spbox[6][(work) & 0x3f]
342 ^ Spbox[4][(work >> 8) & 0x3f]
343 ^ Spbox[2][(work >> 16) & 0x3f]
344 ^ Spbox[0][(work >> 24) & 0x3f];
345 work = l ^ kptr[4*i+3];
346 r ^= Spbox[7][(work) & 0x3f]
347 ^ Spbox[5][(work >> 8) & 0x3f]
348 ^ Spbox[3][(work >> 16) & 0x3f]
349 ^ Spbox[1][(work >> 24) & 0x3f];
355 void DES_EDE2::Base::UncheckedSetKey(
const byte *userKey,
unsigned int length,
const NameValuePairs &)
357 AssertValidKeyLength(length);
359 m_des1.RawSetKey(GetCipherDirection(), userKey);
360 m_des2.RawSetKey(ReverseCipherDir(GetCipherDirection()), userKey+8);
363 void DES_EDE2::Base::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock, byte *outBlock)
const
366 Block::Get(inBlock)(l)(r);
368 m_des1.RawProcessBlock(l, r);
369 m_des2.RawProcessBlock(r, l);
370 m_des1.RawProcessBlock(l, r);
375 void DES_EDE3::Base::UncheckedSetKey(
const byte *userKey,
unsigned int length,
const NameValuePairs &)
377 AssertValidKeyLength(length);
379 m_des1.RawSetKey(GetCipherDirection(), userKey + (IsForwardTransformation() ? 0 : 16));
380 m_des2.RawSetKey(ReverseCipherDir(GetCipherDirection()), userKey + 8);
381 m_des3.RawSetKey(GetCipherDirection(), userKey + (IsForwardTransformation() ? 16 : 0));
384 void DES_EDE3::Base::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock, byte *outBlock)
const
387 Block::Get(inBlock)(l)(r);
389 m_des1.RawProcessBlock(l, r);
390 m_des2.RawProcessBlock(r, l);
391 m_des3.RawProcessBlock(l, r);
396 #endif // #ifndef CRYPTOPP_IMPORTS
398 static inline bool CheckParity(byte b)
400 unsigned int a = b ^ (b >> 4);
401 return ((a ^ (a>>1) ^ (a>>2) ^ (a>>3)) & 1) == 1;
406 for (
unsigned int i=0; i<8; i++)
407 if (!CheckParity(key[i]))
414 for (
unsigned int i=0; i<8; i++)
415 if (!CheckParity(key[i]))
420 void DES::Base::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock, byte *outBlock)
const
423 Block::Get(inBlock)(l)(r);
425 RawProcessBlock(l, r);
430 void DES_XEX3::Base::UncheckedSetKey(
const byte *key,
unsigned int length,
const NameValuePairs &)
432 AssertValidKeyLength(length);
437 memcpy(m_x1, key + (IsForwardTransformation() ? 0 : 16), BLOCKSIZE);
438 m_des->RawSetKey(GetCipherDirection(), key + 8);
439 memcpy(m_x3, key + (IsForwardTransformation() ? 16 : 0), BLOCKSIZE);
442 void DES_XEX3::Base::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock, byte *outBlock)
const
444 xorbuf(outBlock, inBlock, m_x1, BLOCKSIZE);
445 m_des->ProcessAndXorBlock(outBlock, xorBlock, outBlock);
446 xorbuf(outBlock, m_x3, BLOCKSIZE);