#include "precomp.h"
const SYMCRYPT_BLOCKCIPHER SymCrypt3DesBlockCipher_default = {
SymCrypt3DesExpandKey,
SymCrypt3DesEncrypt,
SymCrypt3DesDecrypt,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
8,
sizeof( SYMCRYPT_3DES_EXPANDED_KEY ),
};
const SYMCRYPT_BLOCKCIPHER SymCryptDesBlockCipher_default = {
SymCryptDesExpandKey,
SymCryptDesEncrypt,
SymCryptDesDecrypt,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
8,
sizeof( SYMCRYPT_DES_EXPANDED_KEY ),
};
const PCSYMCRYPT_BLOCKCIPHER SymCrypt3DesBlockCipher = &SymCrypt3DesBlockCipher_default;
const PCSYMCRYPT_BLOCKCIPHER SymCryptDesBlockCipher = &SymCryptDesBlockCipher_default;
extern SYMCRYPT_ALIGN_AT(256) const UINT32 SymCryptDesSpbox[8][64];
extern SYMCRYPT_ALIGN_AT(256) const UINT32 SymCryptDesKeySelect[8][64];
#define SWAP_BITS_WITHIN_UINT32( _value, _shift, _mask ) \
{ \
UINT32 _tmp; \
_tmp = ((_value) ^ ((_value) >> (_shift))) & (_mask ); \
_value = (_value) ^ _tmp ^ (_tmp << (_shift)); \
}
#define SWAP_BITS_BETWEEN_UINT32( _v1, _v2, _shift, _mask ) \
{ \
UINT32 _tmp; \
_tmp = ((_v1) ^ ((_v2) >> (_shift))) & (_mask); \
_v1 ^= _tmp; \
_v2 ^= (_tmp << (_shift )); \
}
static const BYTE SymCryptDesDoubleShift[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
SYMCRYPT_ERROR
SYMCRYPT_CALL
SymCryptDesExpandKey(
_Out_ PSYMCRYPT_DES_EXPANDED_KEY pExpandedKey,
_In_reads_( cbKey ) PCBYTE pbKey,
SIZE_T cbKey )
{
if( cbKey != 8 )
{
return SYMCRYPT_WRONG_KEY_SIZE;
}
return SymCrypt3DesExpandKey( &pExpandedKey->threeDes, pbKey, cbKey );
}
VOID
SYMCRYPT_CALL
SymCryptDesEncrypt(
_In_ PCSYMCRYPT_DES_EXPANDED_KEY pExpandedKey,
_In_reads_( SYMCRYPT_DES_BLOCK_SIZE ) PCBYTE pbSrc,
_Out_writes_( SYMCRYPT_DES_BLOCK_SIZE ) PBYTE pbDst )
{
SymCrypt3DesEncrypt( &pExpandedKey->threeDes, pbSrc, pbDst );
}
VOID
SYMCRYPT_CALL
SymCryptDesDecrypt(
_In_ PCSYMCRYPT_DES_EXPANDED_KEY pExpandedKey,
_In_reads_( SYMCRYPT_DES_BLOCK_SIZE ) PCBYTE pbSrc,
_Out_writes_( SYMCRYPT_DES_BLOCK_SIZE ) PBYTE pbDst )
{
SymCrypt3DesDecrypt( &pExpandedKey->threeDes, pbSrc, pbDst );
}
VOID
SYMCRYPT_CALL
SymCrypt3DesCbcEncrypt(
_In_ PCSYMCRYPT_3DES_EXPANDED_KEY pExpandedKey,
_Inout_updates_( SYMCRYPT_3DES_BLOCK_SIZE ) PBYTE pbChainingValue,
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData )
{
SYMCRYPT_ASSERT( SymCrypt3DesBlockCipher->blockSize == SYMCRYPT_3DES_BLOCK_SIZE );
SymCryptCbcEncrypt( SymCrypt3DesBlockCipher, pExpandedKey, pbChainingValue, pbSrc, pbDst, cbData );
}
VOID
SYMCRYPT_CALL
SymCrypt3DesCbcDecrypt(
_In_ PCSYMCRYPT_3DES_EXPANDED_KEY pExpandedKey,
_Inout_updates_( SYMCRYPT_3DES_BLOCK_SIZE ) PBYTE pbChainingValue,
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData )
{
SYMCRYPT_ASSERT( SymCrypt3DesBlockCipher->blockSize == SYMCRYPT_3DES_BLOCK_SIZE );
SymCryptCbcDecrypt( SymCrypt3DesBlockCipher, pExpandedKey, pbChainingValue, pbSrc, pbDst, cbData );
}
VOID
SYMCRYPT_CALL
SymCryptDesExpandSingleKey(
_Out_writes_bytes_(128) UINT32 expandedKeyTable[16][2],
_In_reads_(8) PCBYTE pKey )
{
UINT32 Cr, Dr;
UINT32 r;
UINT32 K1, K2;
UINT32 tmp;
Cr = SYMCRYPT_LOAD_LSBFIRST32( pKey );
Dr = SYMCRYPT_LOAD_LSBFIRST32( pKey + 4 );
SWAP_BITS_BETWEEN_UINT32( Cr, Dr, 4, 0x0f0f0f0f );
SWAP_BITS_WITHIN_UINT32( Dr, 18, 0x00003333 );
SWAP_BITS_WITHIN_UINT32( Cr, 18, 0x00003333 );
SWAP_BITS_BETWEEN_UINT32( Cr, Dr, 1, 0x55555555 );
SWAP_BITS_BETWEEN_UINT32( Dr, Cr, 8, 0x00ff00ff );
SWAP_BITS_BETWEEN_UINT32( Cr, Dr, 1, 0x55555555 );
SWAP_BITS_WITHIN_UINT32( Dr, 16, 0xff );
Dr = (Dr & 0x00ffffff) | ((Cr & 0xf0000000 ) >> 4 );
Cr = (Cr & 0x0fffffff);
for( r = 0; r < 16; r++)
{
if( SymCryptDesDoubleShift[ r ] ) {
Cr = ((Cr >> 2) | (Cr << 26));
Dr = ((Dr >> 2) | (Dr << 26));
} else {
Cr = ((Cr >> 1) | (Cr << 27));
Dr = ((Dr >> 1) | (Dr << 27));
}
Cr &= 0x0fffffff;
Dr &= 0x0fffffff;
K1 = SymCryptDesKeySelect[0][ (Cr )&0x3f ] |
SymCryptDesKeySelect[1][((Cr >> 6)&0x03) | ((Cr >> 7)&0x3c)] |
SymCryptDesKeySelect[2][((Cr >> 13)&0x0f) | ((Cr >> 14)&0x30)] |
SymCryptDesKeySelect[3][((Cr >> 20)&0x01) | ((Cr >> 21)&0x06) | ((Cr >> 22)&0x38)];
K2 = SymCryptDesKeySelect[4][ (Dr )&0x3f ] |
SymCryptDesKeySelect[5][((Dr >> 7)&0x03) | ((Dr >> 8)&0x3c)] |
SymCryptDesKeySelect[6][ (Dr >> 15)&0x3f ] |
SymCryptDesKeySelect[7][((Dr >> 21)&0x0f) | ((Dr >> 22)&0x30)];
tmp = ((K2 << 16) | (K1 & 0x0000ffff)) ;
expandedKeyTable[r][0] = ROL32(tmp, 2);
tmp = ((K1 >> 16) | (K2 & 0xffff0000));
expandedKeyTable[r][1] = ROL32(tmp, 6);
}
}
SYMCRYPT_NOINLINE
SYMCRYPT_ERROR
SYMCRYPT_CALL
SymCrypt3DesExpandKey(
_Out_ PSYMCRYPT_3DES_EXPANDED_KEY pExpandedKey,
_In_reads_(cbKey) PCBYTE pbKey,
SIZE_T cbKey )
{
SIZE_T keyIndex = 0;
int i;
if( cbKey != 8 && cbKey != 16 && cbKey != 24 )
{
return SYMCRYPT_WRONG_KEY_SIZE;
}
for( i=0; i<3; i++ )
{
SYMCRYPT_ASSERT( keyIndex <= cbKey - 8 );
SymCryptDesExpandSingleKey( pExpandedKey->roundKey[i], pbKey + keyIndex );
keyIndex = (keyIndex + 8) % cbKey;
}
SYMCRYPT_SET_MAGIC( pExpandedKey );
return SYMCRYPT_NO_ERROR;
}
#define F(L, R, keyptr) { \
Ta = keyptr[0] ^ R; \
Tb = keyptr[1] ^ R; \
Tb = ROR32(Tb, 4); \
L ^= *(UINT32 *)((PBYTE)SymCryptDesSpbox[0] + ( Ta & 0xfc)); \
L ^= *(UINT32 *)((PBYTE)SymCryptDesSpbox[1] + ( Tb & 0xfc)); \
L ^= *(UINT32 *)((PBYTE)SymCryptDesSpbox[2] + ((Ta>> 8)& 0xfc)); \
L ^= *(UINT32 *)((PBYTE)SymCryptDesSpbox[3] + ((Tb>> 8)& 0xfc)); \
L ^= *(UINT32 *)((PBYTE)SymCryptDesSpbox[4] + ((Ta>>16)& 0xfc)); \
L ^= *(UINT32 *)((PBYTE)SymCryptDesSpbox[5] + ((Tb>>16)& 0xfc)); \
L ^= *(UINT32 *)((PBYTE)SymCryptDesSpbox[6] + ((Ta>>24)& 0xfc)); \
L ^= *(UINT32 *)((PBYTE)SymCryptDesSpbox[7] + ((Tb>>24)& 0xfc)); }
SYMCRYPT_NOINLINE
VOID
SYMCRYPT_CALL
SymCrypt3DesEncrypt(
_In_ PCSYMCRYPT_3DES_EXPANDED_KEY pExpandedKey,
_In_reads_( SYMCRYPT_3DES_BLOCK_SIZE ) PCBYTE pbSrc,
_Out_writes_( SYMCRYPT_3DES_BLOCK_SIZE ) PBYTE pbDst )
{
UINT32 L, R, Ta, Tb;
int r;
SYMCRYPT_CHECK_MAGIC( pExpandedKey );
R = SYMCRYPT_LOAD_LSBFIRST32( pbSrc );
L = SYMCRYPT_LOAD_LSBFIRST32( pbSrc + 4 );
R = ROL32(R, 4);
Ta = (L ^ R) & 0xf0f0f0f0;
L ^= Ta;
R ^= Ta;
L = ROL32(L, 20);
Ta = (L ^ R) & 0xfff0000f;
R ^= Ta;
L ^= Ta;
L = ROL32(L,14);
Ta = (L ^ R) & 0x33333333;
R ^= Ta;
L ^= Ta;
R = ROL32(R, 22);
Ta = (L ^ R) & 0x03fc03fc;
R ^= Ta;
L ^= Ta;
R = ROL32(R, 9);
Ta = (L ^ R) & 0xaaaaaaaa;
R ^= Ta;
L ^= Ta;
L = ROL32(L, 1);
for( r=0; r<16; r += 2 )
{
F( L, R, pExpandedKey->roundKey[0][r ] );
F( R, L, pExpandedKey->roundKey[0][r+1] );
}
for( r=14; r>=0; r -= 2 )
{
F( R, L, pExpandedKey->roundKey[1][r+1] );
F( L, R, pExpandedKey->roundKey[1][r ] );
}
for( r=0; r<16; r += 2 )
{
F( L, R, pExpandedKey->roundKey[2][r ] );
F( R, L, pExpandedKey->roundKey[2][r+1] );
}
R = ROR32(R, 1);
Ta = (L ^ R) & 0xaaaaaaaa;
R ^= Ta;
L ^= Ta;
L = ROR32(L, 9);
Ta = (L ^ R) & 0x03fc03fc;
R ^= Ta;
L ^= Ta;
L = ROR32(L, 22);
Ta = (L ^ R) & 0x33333333;
R ^= Ta;
L ^= Ta;
R = ROR32(R, 14);
Ta = (L ^ R) & 0xfff0000f;
R ^= Ta;
L ^= Ta;
R = ROR32(R, 20);
Ta = (L ^ R) & 0xf0f0f0f0;
R ^= Ta;
L ^= Ta;
L = ROR32(L, 4);
SYMCRYPT_STORE_LSBFIRST32( pbDst, L );
SYMCRYPT_STORE_LSBFIRST32( pbDst + 4, R );
}
SYMCRYPT_NOINLINE
VOID
SYMCRYPT_CALL
SymCrypt3DesDecrypt(
_In_ PCSYMCRYPT_3DES_EXPANDED_KEY pExpandedKey,
_In_reads_( SYMCRYPT_3DES_BLOCK_SIZE ) PCBYTE pbSrc,
_Out_writes_( SYMCRYPT_3DES_BLOCK_SIZE ) PBYTE pbDst )
{
UINT32 L, R, Ta, Tb;
int r;
SYMCRYPT_CHECK_MAGIC( pExpandedKey );
R = SYMCRYPT_LOAD_LSBFIRST32( pbSrc );
L = SYMCRYPT_LOAD_LSBFIRST32( pbSrc + 4 );
R = ROL32(R, 4);
Ta = (L ^ R) & 0xf0f0f0f0;
L ^= Ta;
R ^= Ta;
L = ROL32(L, 20);
Ta = (L ^ R) & 0xfff0000f;
L ^= Ta;
R ^= Ta;
L = ROL32(L, 14);
Ta = (L ^ R) & 0x33333333;
L ^= Ta;
R ^= Ta;
R = ROL32(R, 22);
Ta = (L ^ R) & 0x03fc03fc;
L ^= Ta;
R ^= Ta;
R = ROL32(R, 9);
Ta = (L ^ R) & 0xaaaaaaaa;
L ^= Ta;
R ^= Ta;
L = ROL32(L, 1);
for( r=14; r>=0; r -= 2 )
{
F( L, R, pExpandedKey->roundKey[2][r+1] );
F( R, L, pExpandedKey->roundKey[2][r ] );
}
for( r=0; r<16; r += 2 )
{
F( R, L, pExpandedKey->roundKey[1][r ] );
F( L, R, pExpandedKey->roundKey[1][r+1] );
}
for( r=14; r>=0; r -= 2 )
{
F( L, R, pExpandedKey->roundKey[0][r+1] );
F( R, L, pExpandedKey->roundKey[0][r ] );
}
R = ROR32(R, 1);
Ta = (L ^ R) & 0xaaaaaaaa;
L ^= Ta;
R ^= Ta;
L = ROR32(L, 9);
Ta = (L ^ R) & 0x03fc03fc;
L ^= Ta;
R ^= Ta;
L = ROR32(L, 22);
Ta = (L ^ R) & 0x33333333;
L ^= Ta;
R ^= Ta;
R = ROR32(R, 14);
Ta = (L ^ R) & 0xfff0000f;
L ^= Ta;
R ^= Ta;
R = ROR32(R, 20);
Ta = (L ^ R) & 0xf0f0f0f0;
L ^= Ta;
R ^= Ta;
L = ROR32(L, 4);
SYMCRYPT_STORE_LSBFIRST32( pbDst, L );
SYMCRYPT_STORE_LSBFIRST32( pbDst + 4, R );
}
VOID
SYMCRYPT_CALL
SymCryptDesSetOddParity(
_Inout_updates_( cbData ) PBYTE pbData,
_In_ SIZE_T cbData )
{
SIZE_T i;
BYTE b, t;
for( i=0; i<cbData; i++ )
{
b = *pbData;
t = b ^ (b>>4);
t ^= t>>2;
t ^= t>>1;
*pbData++ = b ^ (t&1) ^ 1;
}
}
static const BYTE SP800_67Key[24] = {
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23,
};
static const BYTE des3KnownPlaintext[8] = {
0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74,
};
static const BYTE des3KnownCiphertext[8] = {
0x31, 0x4F, 0x83, 0x27, 0xFA, 0x7A, 0x09, 0xA8,
};
static const BYTE desKnownCiphertext[8] = {
0x3F, 0xA4, 0x0E, 0x8A, 0x98, 0x4D, 0x48, 0x15,
};
VOID
SYMCRYPT_CALL
SymCryptDesSelftest(void)
{
BYTE buf[SYMCRYPT_DES_BLOCK_SIZE];
SYMCRYPT_DES_EXPANDED_KEY key;
if( SymCryptDesExpandKey( &key, SP800_67Key, 8 ) != SYMCRYPT_NO_ERROR )
{
SymCryptFatal( 'desa' );
}
SymCryptDesEncrypt( &key, des3KnownPlaintext, buf );
SymCryptInjectError( buf, SYMCRYPT_DES_BLOCK_SIZE );
if( memcmp( buf, desKnownCiphertext, SYMCRYPT_DES_BLOCK_SIZE ) != 0 )
{
SymCryptFatal( 'desb' );
}
SymCryptDesDecrypt( &key, desKnownCiphertext, buf );
SymCryptInjectError( buf, SYMCRYPT_DES_BLOCK_SIZE );
if( memcmp( buf, des3KnownPlaintext, SYMCRYPT_DES_BLOCK_SIZE ) != 0 )
{
SymCryptFatal( 'desc' );
}
}
VOID
SYMCRYPT_CALL
SymCrypt3DesSelftest(void)
{
BYTE buf[SYMCRYPT_3DES_BLOCK_SIZE];
SYMCRYPT_3DES_EXPANDED_KEY key;
if( SymCrypt3DesExpandKey( &key, SP800_67Key, 24 ) != SYMCRYPT_NO_ERROR )
{
SymCryptFatal( 'des3' );
}
SymCrypt3DesEncrypt( &key, des3KnownPlaintext, buf );
SymCryptInjectError( buf, SYMCRYPT_3DES_BLOCK_SIZE );
if( memcmp( buf, des3KnownCiphertext, SYMCRYPT_3DES_BLOCK_SIZE ) != 0 )
{
SymCryptFatal( 'des4' );
}
SymCrypt3DesDecrypt( &key, des3KnownCiphertext, buf );
SymCryptInjectError( buf, SYMCRYPT_3DES_BLOCK_SIZE );
if( memcmp( buf, des3KnownPlaintext, SYMCRYPT_3DES_BLOCK_SIZE ) != 0 )
{
SymCryptFatal( 'des5' );
}
}
#if 0
static unsigned BYTE ip[] = {
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
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
};
static unsigned BYTE fp[] = {
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25
};
static unsigned BYTE ei[] = {
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1
};
static unsigned BYTE sbox[8][64] = {
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,
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,
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,
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,
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,
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,
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,
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 unsigned BYTE p32i[] = {
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25
};
static unsigned BYTE pc1[] = {
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4
};
static unsigned BYTE totrot[] = {
1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
};
static unsigned BYTE pc2[] = {
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
};
#endif