www.pudn.com > endecipher.rar > Idea.cpp
// Idea.cpp: implementation of the CIdea class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Cipher.h"
#include "Idea.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CIdea::CIdea()
{
}
CIdea::~CIdea()
{
}
/* 两数相加,模65536 */
WORD CIdea::Addition(WORD x, WORD y)
{
return ( x + y ) ;
}
/* 两数相乘,模65537 */
WORD CIdea::Multi(WORD x, WORD y)
{
if ( ! x && ! y )
return 0 ;
else if ( ! x )
return ( WORD ) ( ( y * CARDINALITY ) % ( CARDINALITY + 1 ) ) ;
else if ( ! y )
return ( WORD ) ( ( x * CARDINALITY ) % ( CARDINALITY + 1 ) ) ;
else
return ( WORD ) ( ( ( DOWORD ) x * y ) % ( CARDINALITY + 1 ) ) ;
}
/* 利用辗转相除法,求一个数模65537的逆 */
WORD CIdea::Inverse(WORD x)
{
DOWORD dwQuotient ; // 商
DOWORD dwResidual ; // 余
DOWORD dwDividend = CARDINALITY + 1 ; // 被除数
DOWORD dwDivisor = ( DOWORD ) x ; // 除数
DOWORD dwResult ; // 结果
DOWORD dwValue1 = 1 , dwValue2 ; // 中间值
if ( x <=1 )
return x ;
dwResult = dwValue2 = dwDividend / dwDivisor ;
dwResidual = dwDividend % dwDivisor ;
dwDividend = dwDivisor ;
dwDivisor = dwResidual ;
dwQuotient = dwDividend / dwDivisor ;
dwResidual = dwDividend % dwDivisor ;
while ( dwResidual )
{
dwResult = dwQuotient * dwValue2 + dwValue1 ;
dwValue1 = dwValue2 ;
dwValue2 = dwResult ;
dwDividend = dwDivisor ;
dwDivisor = dwResidual ;
dwQuotient = dwDividend / dwDivisor ;
dwResidual = dwDividend % dwDivisor ;
}
if ( ( ( dwResult * x ) % ( CARDINALITY + 1 ) ) == CARDINALITY )
{
int nModular = - ( int ) dwResult ;
while ( ( nModular += ( CARDINALITY + 1 ) ) <= 0 ) ;
dwResult = nModular ;
}
return ( WORD ) dwResult ;
}
/* 循环左移25位,生成一组密钥子块 */
void CIdea::GenSubKey( )
{
WORD wSave , wTemp ;
WORD * pwShift = wKeySeed ;
short sPos ;
wSave = pwShift [ 0 ] ;
wTemp = pwShift [ 1 ] ;
for ( sPos = 1 ; sPos < ROUND - 1; sPos ++ )
{
pwShift [ sPos - 1 ] = ( pwShift [ sPos ] << 9 ) | ( pwShift [ sPos + 1 ] >> 7 ) ;
}
pwShift [ sPos - 1 ] = ( pwShift [ sPos ] << 9 ) | ( wSave >> 7 ) ;
pwShift [ sPos ] = ( wSave << 9 ) | ( wTemp >> 7 ) ;
}
/* 生成加密密钥*/
void CIdea::GenEncryptKey( )
{
short sTimes , sPos , sLength = ROUND ;
for ( sPos = 0 ; sPos < sLength ; sPos ++ )
{
pwEncryptKey [ sPos ] = wKeySeed [ sPos ] ;
}
for ( sTimes = 1 ; sTimes <= KEYSIZE ; sTimes ++ )
{
GenSubKey ( ) ;
if ( KEYSIZE == sTimes )
sLength = ROUND / 2 ;
else
sLength = ROUND ;
for ( sPos = 0 ; sPos < sLength ; sPos ++ )
{
pwEncryptKey [ sTimes * ROUND + sPos ] = wKeySeed [ sPos ] ;
}
}
}
/* 生成解密密钥 */
void CIdea::GenDecryptKey( )
{
short sTurn ;
GenEncryptKey ( ) ; // 生成加密密钥
/* 由加密密钥生成解密密钥 */
for ( sTurn = 0 ; sTurn < ROUND ; sTurn ++ )
{
/* 生成8轮迭代解密密钥 */
pwDecryptKey [ sTurn * KEYSIZE ] = Inverse ( pwEncryptKey [ ( ROUND - sTurn ) * KEYSIZE ] ) ;
if( sTurn )
{
pwDecryptKey [ sTurn * KEYSIZE + 1 ] = - pwEncryptKey [ ( ROUND - sTurn ) * KEYSIZE + 2 ] ;
pwDecryptKey [ sTurn * KEYSIZE + 2 ] = - pwEncryptKey [ ( ROUND - sTurn ) * KEYSIZE + 1 ] ;
}
else
{
pwDecryptKey [ sTurn * KEYSIZE + 1 ] = - pwEncryptKey [ ( ROUND - sTurn ) * KEYSIZE + 1 ] ;
pwDecryptKey [ sTurn * KEYSIZE + 2 ] = - pwEncryptKey [ ( ROUND - sTurn ) * KEYSIZE + 2 ] ;
}
pwDecryptKey [ sTurn * KEYSIZE + 3 ] = Inverse ( pwEncryptKey [ ( ROUND - sTurn ) * KEYSIZE + 3 ] ) ;
pwDecryptKey [ sTurn * KEYSIZE + 4 ] = pwEncryptKey [ ( ROUND - 1 - sTurn ) * KEYSIZE + 4 ] ;
pwDecryptKey [ sTurn * KEYSIZE + 5 ] = pwEncryptKey [ ( ROUND - 1 - sTurn ) * KEYSIZE + 5 ] ;
}
/* 生成输出密钥 */
pwDecryptKey [ sTurn * KEYSIZE ] = Inverse ( pwEncryptKey [ 0 ] );
pwDecryptKey [ sTurn * KEYSIZE + 1 ] = - pwEncryptKey [ 1 ] ;
pwDecryptKey [ sTurn * KEYSIZE + 2 ] = - pwEncryptKey [ 2 ] ;
pwDecryptKey [ sTurn * KEYSIZE + 3 ] = Inverse ( pwEncryptKey [ 3 ] );
}
/* 单轮迭代 */
void CIdea::Iteration( short sTurn , bool bCrypt )
{
short sPos ;
WORD wSubKey [ KEYSIZE ];
WORD wMidValue [ 10 ] ;
WORD * pwKey , * wInputText , * wOutputText;
if ( bCrypt )
{
wInputText = wPlain ;
pwKey = pwEncryptKey ;
wOutputText = wCipher ;
}
else
{
wInputText = wCipher ;
pwKey = pwDecryptKey ;
wOutputText = wPlain ;
}
if ( sTurn < ROUND )
{
for ( sPos = 0 ; sPos < KEYSIZE ; sPos ++ )
{
wSubKey [ sPos ] = pwKey [ sTurn * KEYSIZE + sPos ] ;
}
wMidValue [ 0 ] = Multi ( wInputText [ 0 ] ,wSubKey [ 0 ] ) ;
wMidValue [ 1 ] = Addition ( wInputText [ 1 ] , wSubKey [ 1 ] ) ;
wMidValue [ 2 ] = Addition ( wInputText [ 2 ] , wSubKey [ 2 ] ) ;
wMidValue [ 3 ] = Multi ( wInputText [ 3 ] ,wSubKey [ 3 ] ) ;
wMidValue [ 4 ] = wMidValue [ 0 ] ^ wMidValue [ 2 ] ;
wMidValue [ 5 ] = wMidValue [ 1 ] ^ wMidValue [ 3 ] ;
wMidValue [ 6 ] = Multi ( wMidValue [ 4 ] , wSubKey [ 4 ] ) ;
wMidValue [ 7 ] = Addition ( wMidValue [ 5 ] , wMidValue [ 6 ] ) ;
wMidValue [ 8 ] = Multi ( wMidValue [ 7 ] , wSubKey [ 5 ] ) ;
wMidValue [ 9 ] = Addition ( wMidValue [ 6 ] , wMidValue [ 8 ] ) ;
/* 单轮输出 */
wInputText [ 0 ] = wMidValue [ 0 ] ^ wMidValue [ 8 ] ;
wInputText [ 1 ] = wMidValue [ 2 ] ^ wMidValue [ 8 ] ;
wInputText [ 2 ] = wMidValue [ 1 ] ^ wMidValue [ 9 ] ;
wInputText [ 3 ] = wMidValue [ 3 ] ^ wMidValue [ 9 ] ;
}
else
{
/* 最后输出子块 */
for ( sPos = 0 ; sPos < ROUND / 2 ; sPos ++ )
{
wSubKey [ sPos ] = pwKey [ sTurn * KEYSIZE + sPos ] ;
}
wOutputText [ 0 ] = Multi ( wInputText [ 0 ] , wSubKey [ 0 ] ) ;
wOutputText [ 1 ] = Addition ( wInputText [ 2 ] , wSubKey [ 1 ] ) ;
wOutputText [ 2 ] = Addition ( wInputText [ 1 ] , wSubKey [ 2 ] ) ;
wOutputText [ 3 ] = Multi ( wInputText [ 3 ] , wSubKey [ 3 ] ) ;
}
}
/* 对一组明文块进行加密 */
void CIdea::Encipher( )
{
short sTurn ;
for ( sTurn = 0 ; sTurn <= ROUND ; sTurn ++ )
Iteration ( sTurn , true ) ;
}
/* 对一组密文块进行解密 */
void CIdea::Decipher( )
{
short sTurn ;
for ( sTurn = 0 ; sTurn <= ROUND ; sTurn ++ )
Iteration ( sTurn , false ) ; // 单轮迭代
}
void CIdea::SetNewKey( WORD * KeySeed)
{
for( int i = 0; i < ROUND; i ++ )
{
wKeySeed[ i ] = KeySeed[ i ];
}
GenDecryptKey( );
}