home *** CD-ROM | disk | FTP | other *** search
- #include "stdafx.h"
- /// DES
-
- // Die erste Permutation vertauscht die Bits des zu verschlⁿsselnden Textes. Laut der
- // folgenden Tabelle mu▀ das Bit 0 an die Position 58, Bit 1 an die Position 50, Bit 3 an
- // Position 42 etc.
-
- static int iIniPerm[64]={ 57,49,41,33,25,17, 9, 1,59,51,43,35,27,19,11, 3,
- 61,53,45,37,29,21,13, 5,63,55,47,39,31,23,15, 7,
- 56,48,40,32,24,16, 8, 0,58,50,42,34,26,18,10, 2,
- 60,52,44,36,28,20,12, 4,62,54,46,38,30,22,14, 6 };
-
- DWORD dwIniPermMask[64][2];
-
- // Anzahl der Bits, die die 28-Bit HΣlften des 56-Bit Key je Runde nach links zu rotieren sind
- static int iRoundRotate[16] = { 1,1,2,2,2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
-
- // Die folgende Tabelle wird ben÷tigt, um aus dem 64-Bit Schlⁿssel einen 56-Bit Schlⁿssel
- // zu erzeugen. Jedes achte Bit wird ignoriert und au▀erdem werden die Bits vertuascht.
- // Die Tabelle ist wie folgt zu lesen:
- // Das 57-Bit im 64-Bit Key, kommt an Position 0 im 56-Bit Key. Bit 46(64-Bit Key) kommt an Position 1 (56-Bit Key)
-
- // KeyPermutation
- static int iKeyPerm[56] = { 56,48,40,32,24,16, 8, 0,57,49,41,33,25,17,
- 9, 1,58,50,42,34,26,18,10, 2,59,51,43,35,
- 62,54,46,38,30,22,14, 6,61,53,45,37,29,21,
- 13, 5,60,52,44,36,28,20,12, 4,27,19,11,3 };
- static DWORD dwKeyPermMask[56][2];
-
-
- // Welche der 56-Bits gehen in den 48-Bit Schlⁿssel ein?
- // Compression Permutation
- static int iComPerm[48] = { 13,16,10,23, 0, 4, 2,27,14, 5,20, 9,
- 22,18,11, 3,25, 7,15, 6,26,19,12, 1,
- 40,51,30,36,46,54,29,39,50,44,32,47,
- 43,48,38,55,33,52,45,41,49,35,28,31 };
- static DWORD dwComPermMask[48][2];
-
-
- static int iExpPerm[48] = { 31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8,
- 7, 8, 9,10,11,12,11,12,13,14,15,16,
- 15,16,17,18,19,20,19,20,21,22,23,24,
- 23,24,25,26,27,28,27,28,29,30,31, 0 };
- static DWORD dwExpPermMask[48];
-
- static char SBoxes[8][4][16] = { // S-Box 1
- { { 14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7 },
- { 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8 },
- { 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0 },
- { 15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13 } },
- // S-Box 2
- { { 15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10 },
- { 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5 },
- { 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15 },
- { 13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9 } },
- // S-Box 3
- { { 10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8 },
- { 13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1 },
- { 13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7 },
- { 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12 } },
- // S-Box 4
- { { 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15 },
- { 13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9 },
- { 10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4 },
- { 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2, 14} },
- // S-Box 5
- { { 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9},
- { 14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6},
- { 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14},
- { 11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3} },
- // S-Box 6
- { { 12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11},
- { 10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8},
- { 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6},
- { 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13} },
- //S-Box 7
- { { 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1},
- { 13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6},
- { 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2},
- { 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12} },
- // S-Box 8
- { { 13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7},
- { 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2},
- { 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8},
- { 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11 } } };
-
- static int iPBoxPerm[32] = { 15, 6,19,20,28,11,27,16, 0,14,22,25, 4,17,30, 9,
- 1, 7,23,13,31,26, 2, 8,18,12,29, 5,21,10, 3,24};
- static DWORD dwPBoxPermMask[32];
-
- void DES::BuildPermutationMasks()
- {
- int i;
-
- for( i = 0; i < 64; i++ )
- {
- // Aus den Bitposition werden Bitmasken erzeugt, damit sich die Bits
- // einfacher vertauschen lassen. In InitialPermutation() wirden dazu
- // die zu vertauschenden Original-Bits durchlaufen, um einen neuen
- // 64-Bit Wert "zusammenzubasteln". Neben der InitialPermutation wird
- // auf die FinalPermutation erzeugt.
-
- if( iIniPerm[i] >= 32 )
- {
- dwIniPermMask[i][0]= (1<<(iIniPerm[i]-32));
- dwIniPermMask[i][1]= 0;
- }
- else
- {
- dwIniPermMask[i][0]= 0;
- dwIniPermMask[i][1]= (1<<iIniPerm[i]);
- }
- }
-
- for( i = 0; i < 56; i++ )
- {
- if( iKeyPerm[i] >= 32 )
- {
- dwKeyPermMask[i][0]= (1<<(iKeyPerm[i]-32));
- dwKeyPermMask[i][1]= 0;
- }
- else
- {
- dwKeyPermMask[i][0]= 0;
- dwKeyPermMask[i][1]= (1<<iKeyPerm[i]);
- }
- }
-
- for( i = 0; i < 48; i++ )
- {
- if( iComPerm[i] >= 32 )
- {
- dwComPermMask[i][0]= (1<<(iComPerm[i]-32));
- dwComPermMask[i][1]= 0;
- }
- else
- {
- dwComPermMask[i][0]= 0;
- dwComPermMask[i][1]= (1<<iComPerm[i]);
- }
- }
-
- for( i = 0; i < 48; i++ )
- dwExpPermMask[i] = (1<<iExpPerm[i]);
-
- for( i = 0; i < 32; i++ )
- dwPBoxPermMask[i] = (1<<iPBoxPerm[i]);
- }
-
- DES::~DES()
- {
- memset( &RoundKeys, 0, sizeof( ROUNDKEYS ) );
- }
-
- DES::DES()
- {
- BuildPermutationMasks();
- }
-
- void DES::InitialPermutation( DWORD *PlainText, DWORD *dwPermutation )
- {
- DWORD dwResult[2];
- DWORD dwWorkingCopy[2];
- int i;
-
- // Arbeitskopie des zu verschlⁿsselnden Textes anlegen
- dwWorkingCopy[0]=PlainText[0];
- dwWorkingCopy[1]=PlainText[1];
-
- // Ergebnis l÷schen
- dwResult[0]=0;
- dwResult[1]=0;
-
- for( i = 63; i >= 32; i-- )
- {
- if( ( ( dwWorkingCopy[0] & dwIniPermMask[i][0] ) ==
- dwIniPermMask[i][0] ) &&
- ( ( dwWorkingCopy[1] & dwIniPermMask[i][1] ) ==
- dwIniPermMask[i][1] ) )
- dwResult[0] |= (1<<(i-32));
- }
-
- for( i = 31; i >= 0; i-- )
- {
- if( ( ( dwWorkingCopy[0] & dwIniPermMask[i][0] ) ==
- dwIniPermMask[i][0] ) &&
- ( ( dwWorkingCopy[1] & dwIniPermMask[i][1] ) ==
- dwIniPermMask[i][1] ) )
- dwResult[1] |= (1<<i);
- }
-
- dwPermutation[0] = dwResult[0];
- dwPermutation[1] = dwResult[1];
- }
-
- void DES::FinalPermutation( DWORD *CryptText, DWORD *dwPermutation )
- {
- DWORD dwResult[2];
- DWORD dwWorkingCopy[2];
- int i;
-
- // Arbeitskopie des zu verschlⁿsselnden Textes anlegen
- dwWorkingCopy[0]=CryptText[0];
- dwWorkingCopy[1]=CryptText[1];
-
- // Ergebnis l÷schen
- dwResult[0]=0;
- dwResult[1]=0;
-
-
- for( i = 63; i >= 32; i-- )
- {
- if( dwWorkingCopy[0] & ( 1 << (i-32) ) )
- {
- dwResult[0] |= dwIniPermMask[i][0];
- dwResult[1] |= dwIniPermMask[i][1];
- }
- }
-
- for( i = 31; i >= 0; i-- )
- {
- if( dwWorkingCopy[1] & ( 1 << i ) )
- {
- dwResult[0] |= dwIniPermMask[i][0];
- dwResult[1] |= dwIniPermMask[i][1];
- }
- }
-
- dwPermutation[0] = dwResult[0];
- dwPermutation[1] = dwResult[1];
- }
-
-
- void DES::KeyPermutation( DWORD *Key64, DWORD *Key56 )
- {
- int i;
-
- // 56-Bit Schlⁿssel l÷schen
- Key56[0]=0;
- Key56[1]=0;
-
-
- for( i = 55; i >= 32; i-- )
- {
- if( ( ( Key64[0] & dwKeyPermMask[i][0] ) ==
- dwKeyPermMask[i][0] ) &&
- ( ( Key64[1] & dwKeyPermMask[i][1] ) ==
- dwKeyPermMask[i][1] ) )
- Key56[0] |= (1<<(i-32));
- }
-
- for( i = 31; i >= 0; i-- )
- {
- if( ( ( Key64[0] & dwKeyPermMask[i][0] ) ==
- dwKeyPermMask[i][0] ) &&
- ( ( Key64[1] & dwKeyPermMask[i][1] ) ==
- dwKeyPermMask[i][1] ) )
- Key56[1] |= (1<<i);
- }
- }
-
- void DES::Compress( DWORD *Key56, DWORD *Key48 )
- {
- int i;
-
- // 56-Bit Schlⁿssel l÷schen
- Key48[0]=0;
- Key48[1]=0;
-
-
- for( i = 47; i >= 32; i-- )
- {
- if( ( ( Key56[0] & dwComPermMask[i][0] ) ==
- dwComPermMask[i][0] ) &&
- ( ( Key56[1] & dwComPermMask[i][1] ) ==
- dwComPermMask[i][1] ) )
- Key48[0] |= (1<<(i-32));
- }
-
- for( i = 31; i >= 0; i-- )
- {
- if( ( ( Key56[0] & dwComPermMask[i][0] ) ==
- dwComPermMask[i][0] ) &&
- ( ( Key56[1] & dwComPermMask[i][1] ) ==
- dwComPermMask[i][1] ) )
- Key48[1] |= (1 << i);
- }
- }
-
- void DES::CreateRoundKeys( ROUNDKEYS *keys, DWORD *dw56Key, BOOL bDecrypt )
- {
- DWORD dw28Left; // Die linke und rechte 28-Bit HΣlfte des 56-Bit Schlⁿssels
- DWORD dw28Right;
- DWORD dw28LeftOverhang,
- dw28RightOverhang;
- DWORD dwUseKey56[2];
- int i;
-
- // Die oberen 28 Bitt:
- dw28Left = (dw56Key[0] << 4 ) | ( dw56Key[1] & 0xF0000000 ) >> 28;
- // die unteren 28 Bit:
- dw28Right= dw56Key[1] & 0x0FFFFFFF;
-
- for( i = 0; i < 16; i++ )
- {
- if( iRoundRotate[i] == 1 ) // IN Jeder Runde wird der halbe Schlⁿssel nur 1 oder 2 Bit rotiert
- {
- dw28LeftOverhang = (dw28Left & 0x01 ) << 27;
- dw28RightOverhang = (dw28Right & 0x1 ) << 27;
- }
- else
- {
- dw28LeftOverhang = (dw28Left & 0x3 ) << 26;
- dw28RightOverhang = (dw28Right & 0x3 ) << 26;
- }
-
- dw28Left >>= iRoundRotate[i];
- dw28Left |= dw28LeftOverhang;
-
- dw28Right >>= iRoundRotate[i];
- dw28Right |= dw28RightOverhang;
-
- dwUseKey56[0] = dw28Left>>4;
- dwUseKey56[1] = (dw28Left<<28) | dw28Right;
-
- Compress( dwUseKey56, &keys->dwKeys48[bDecrypt?(15-i):i][0] );
- }
- }
-
- void DES::Expand( DWORD dw32Bit, DWORD *dw48Bit )
- {
- int i;
-
- dw48Bit[0]=0;
- dw48Bit[1]=0;
-
- for( i = 47; i >= 32; i-- )
- {
- if( ( dw32Bit & dwExpPermMask[i] ) == dwExpPermMask[i] )
- dw48Bit[0] |= (1<<(i-32));
- }
-
- for( i = 31; i >= 0; i-- )
- {
- if( ( dw32Bit & dwExpPermMask[i] ) == dwExpPermMask[i] )
- dw48Bit[1] |= (1 << i);
- }
- }
-
- void DES::SBox( DWORD *dw48Bit, DWORD *dw32Bit )
- {
- int s[8];
- int i, row,col;
- // Isoliere die 8 6-Bit Gruppen
- for( i = 0; i < 8; i++ )
- {
- s[i] = dw48Bit[1] & 0x0000003F;
- dw48Bit[1] >>= 6;
- dw48Bit[1] |= (dw48Bit[0] & 0x0000003F) << 26;
- dw48Bit[0] >>= 6;
- }
-
- *dw32Bit = 0;
- for( i = 7; i >= 0; i-- )
- {
-
- row = ( s[i] & 0x20 ) >> 4;
- row |= ( s[i] & 0x1 );
-
- col = ( s[i] & 0x1E ) >> 1;
-
- *dw32Bit <<= 4; // Platz fⁿr 4 But schaffen
- *dw32Bit |= SBoxes[i][row][col]; // Sbox hinzu
- }
- }
-
- void DES::PBox( DWORD *dw32Bit )
- {
- DWORD dwCopy;
- int i;
-
- dwCopy = *dw32Bit;
-
- *dw32Bit = 0;
- for( i=0; i < 32; i++ )
- if( dwCopy & dwPBoxPermMask[i] )
- *dw32Bit |= (1 << i);
- }
-
- void DES::BuildEncryptionKey( DWORD *dw64Key )
- {
- DWORD dw56Key[2];
-
- KeyPermutation( dw64Key, dw56Key );
- CreateRoundKeys( &RoundKeys, dw56Key, FALSE ); // Achtung! Auch dwKey56 Σndert sich!
- dw56Key[0]=0; // Nie was ⁿbriglassen
- dw56Key[1]=0;
- }
-
- void DES::BuildDecryptionKey( DWORD *dw64Key )
- {
- DWORD dw56Key[2];
-
- KeyPermutation( dw64Key, dw56Key );
- CreateRoundKeys( &RoundKeys, dw56Key, TRUE ); // Achtung! Auch dwKey56 Σndert sich!
- dw56Key[0]=0; // Nie was ⁿbriglassen
- dw56Key[1]=0;
- }
-
- void DES::Codec( DWORD *dw64BitIn, DWORD *dw64BitOut )
- {
- int i;
- DWORD dwWorkingCopy[2];
- DWORD left, right;
- DWORD dw48Bit[2];
- DWORD dwSaveRight;
-
- InitialPermutation( dw64BitIn, dwWorkingCopy );
-
- left = dwWorkingCopy[0];
- right = dwWorkingCopy[1];
-
- for( i = 0; i < 16; i++ )
- {
- dwSaveRight = right;
-
- Expand( right, dw48Bit );
- dw48Bit[0] ^= RoundKeys.dwKeys48[i][0];
- dw48Bit[1] ^= RoundKeys.dwKeys48[i][1];
-
- SBox( dw48Bit, &right );
- PBox( &right );
- right ^= left;
- left = dwSaveRight;
- }
-
- dwWorkingCopy[0] = right;
- dwWorkingCopy[1] = left;
- FinalPermutation( dwWorkingCopy, dw64BitOut );
- }
-