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( ); 
}