📄 idea.c
字号:
//#include <windows.h> // the string MUST be commented if // // we compile Windows 95 or NT drivers/*#ifndef __WIN95__#include <windef.h>#else#include <basedef.h>#endif*/#include "bc_idea.h"/********************************************************************** * * IDEA ECB implementation * **********************************************************************/#define WORD16(x) ((x) & 0xffff)/* * Multiplication, modulo (2**16)+1 * Procedure calling MUL(x,y) must have t16 and t32 local variables */#define MUL(x,y) \ ( (x) = WORD16((x)-1), \ t16 = WORD16((y)-1), \ t32 = (DWORD)(x)*t16 + (x) + t16 + 1, \ (x) = (WORD)(WORD16(t32)), \ t16 = (WORD)(t32>>16), \ (x) = ((x)-t16) + ((x)<t16) \ )/* * Compute the multiplicative inverse of x, modulo 65537, using Euclid's * algorithm. */WORD mulInv(WORD x) { WORD q, y, t0, t1; /* 0 and 1 are self-inverse, in this case we return x */ if (x <= 1) return x; /* Now x >= 2, so 65537 / 2 < 65536 - 1 (i.e. result is 16-bit number) */ t1 = 0x10001L / x; y = 0x10001L % x; if (y == 1) return WORD16(1-t1); t0 = 1; do { q = x / y; x = x % y; t0 += q * t1; if (x == 1) return t0; q = y / x; y = y % x; t1 += q * t0; } while (y != 1); return WORD16(1-t1);}/********************************************************************** * * KeyExtend() calculats extended key from a given key * **********************************************************************/BOOLKeyExtend( PUCHAR KeySource, // 8-bit uchars PDWORD KeyDestination ) // 32-bit dwords{ int i,j,k,k1; UCHAR *key; IdeaExtKey *ideaExtKey; WORD *extEncKey, *extDecKey; if ((!KeySource) || (!KeyDestination)) return FALSE; key = KeySource; ideaExtKey = (IdeaExtKey *)KeyDestination; extEncKey = ideaExtKey->encryptKeys; extDecKey = ideaExtKey->decryptKeys; /* * Calculate extended ENCRYPTION keys: each extended key * is 16 bit long, the number of extended keys is IDEA_EXPANDED_KEY_SIZE */ /* Calculate first 8 extended keys */ for( i=0,j=0; j<8; i +=2, j++ ) extEncKey[j] = (key[i]<<8) | key[i+1]; /* Calculate the next extended keys */ for( i=1; j < IDEA_EXPANDED_KEY_SIZE; j++, i++ ) { k = k1 = ((j>>3)-1)<<3; k += i & 7; k1 += (i + 1) & 7; extEncKey[j] = (extEncKey[k] << 9) | (extEncKey[k1] >> 7); } /* * Calculate extended DECRYPTION keys */ extDecKey[0 ] = mulInv(extEncKey[48]); extDecKey[1 ] = -extEncKey[49]; extDecKey[2 ] = -extEncKey[50]; extDecKey[3 ] = mulInv(extEncKey[51]); extDecKey[4 ] = extEncKey[46]; extDecKey[5 ] = extEncKey[47]; extDecKey[6 ] = mulInv(extEncKey[42]); extDecKey[7 ] = -extEncKey[44]; extDecKey[8 ] = -extEncKey[43]; extDecKey[9 ] = mulInv(extEncKey[45]); extDecKey[10] = extEncKey[40]; extDecKey[11] = extEncKey[41]; extDecKey[12] = mulInv(extEncKey[36]); extDecKey[13] = -extEncKey[38]; extDecKey[14] = -extEncKey[37]; extDecKey[15] = mulInv(extEncKey[39]); extDecKey[16] = extEncKey[34]; extDecKey[17] = extEncKey[35]; extDecKey[18] = mulInv(extEncKey[30]); extDecKey[19] = -extEncKey[32]; extDecKey[20] = -extEncKey[31]; extDecKey[21] = mulInv(extEncKey[33]); extDecKey[22] = extEncKey[28]; extDecKey[23] = extEncKey[29]; extDecKey[24] = mulInv(extEncKey[24]); extDecKey[25] = -extEncKey[26]; extDecKey[26] = -extEncKey[25]; extDecKey[27] = mulInv(extEncKey[27]); extDecKey[28] = extEncKey[22]; extDecKey[29] = extEncKey[23]; extDecKey[30] = mulInv(extEncKey[18]); extDecKey[31] = -extEncKey[20]; extDecKey[32] = -extEncKey[19]; extDecKey[33] = mulInv(extEncKey[21]); extDecKey[34] = extEncKey[16]; extDecKey[35] = extEncKey[17]; extDecKey[36] = mulInv(extEncKey[12]); extDecKey[37] = -extEncKey[14]; extDecKey[38] = -extEncKey[13]; extDecKey[39] = mulInv(extEncKey[15]); extDecKey[40] = extEncKey[10]; extDecKey[41] = extEncKey[11]; extDecKey[42] = mulInv(extEncKey[6]); extDecKey[43] = -extEncKey[8]; extDecKey[44] = -extEncKey[7]; extDecKey[45] = mulInv(extEncKey[9]); extDecKey[46] = extEncKey[4]; extDecKey[47] = extEncKey[5]; extDecKey[48] = mulInv(extEncKey[0]); extDecKey[49] = -extEncKey[1]; extDecKey[50] = -extEncKey[2]; extDecKey[51] = mulInv(extEncKey[3]); return TRUE;}/**************************************************************** * * IdeaECB() does encrypting (encrypt==TRUE) or * decrypting (encrypt==FALSE) for a block of data the size of * 64-bit block. * ****************************************************************//* * Macroses to transform array of 2 bytes to 16-bit words * (and reverse) without depending on the Little-Endian or * Big-Endian processor's architecture */#define BYTEStoWORD(bytePtr) \ (((WORD)bytePtr[0] << 8) | ((WORD)bytePtr[1]));#define WORDtoBYTES(bytePtr, data16b) \ bytePtr[1] = (UCHAR)(( data16b) & 0xFF ); \ bytePtr[0] = (UCHAR)(((data16b) >> 8 ) & 0xFF ); BOOL IdeaECB( UCHAR *InBlock, UCHAR *OutBlock, IdeaExtKey *ExtKey, BOOL Encrypt){ WORD x1, x2, x3, x4, s2, s3, t16; DWORD t32; int i; WORD *key; UCHAR *bytePtr; if ((!InBlock) || (!OutBlock) || (!ExtKey)) { return FALSE; } if( Encrypt ) key = ExtKey->encryptKeys; else key = ExtKey->decryptKeys; bytePtr = &(InBlock[0]); x1 = BYTEStoWORD(bytePtr); bytePtr = &(InBlock[2]); x2 = BYTEStoWORD(bytePtr); bytePtr = &(InBlock[4]); x3 = BYTEStoWORD(bytePtr); bytePtr = &(InBlock[6]); x4 = BYTEStoWORD(bytePtr); for(i=0; i<IDEA_ROUNDS; i++) { MUL(x1,*key++); x2 += *key++; x3 += *key++; MUL(x4, *key++); s3 = x3; x3 ^= x1; MUL(x3, *key++); s2 = x2; x2 ^= x4; x2 += x3; MUL(x2, *key++); x3 += x2; x1 ^= x2; x4 ^= x3; x2 ^= s3; x3 ^= s2; } MUL(x1, *key++); x3 += *key++; x2 += *key++; MUL(x4, *key); bytePtr = &(OutBlock[0]); WORDtoBYTES(bytePtr, x1); bytePtr = &(OutBlock[2]); WORDtoBYTES(bytePtr, x3); bytePtr = &(OutBlock[4]); WORDtoBYTES(bytePtr, x2); bytePtr = &(OutBlock[6]); WORDtoBYTES(bytePtr, x4); return TRUE;}/* Macroses to transform array of 4 bytes to 32-bit dwords * (and reverse) without depending on the Little-Endian or * Big-Endian processor's architecture */#define BYTES_TO_DWORD(b,d) (d =((DWORD)(*((b)++))), \ d|=((DWORD)(*((b)++)))<< 8, \ d|=((DWORD)(*((b)++)))<<16, \ d|=((DWORD)(*((b)++)))<<24)#define DWORD_TO_4BYTES(d,b) (*((b)++)=(BYTE)(((d) )&0xff), \ *((b)++)=(BYTE)(((d)>> 8)&0xff), \ *((b)++)=(BYTE)(((d)>>16)&0xff), \ *((b)++)=(BYTE)(((d)>>24)&0xff))//************ IDEA CBC mode encryption **************VOIDEncrypt( DWORD *IVector, DWORD *KeyAddress, DWORD *SrcBuffer, DWORD *DstBuffer, DWORD Length ) // in bytes{ DWORD i; DWORD left, right; UCHAR buf[8], *bytePtr; left = IVector[0]; right = IVector[1]; for(i = 0; i < (Length >> 2); i = i+2) { // do EBC encryption of (Initial_Vector XOR Data) left = SrcBuffer[i] ^ left; right = SrcBuffer[i+1] ^ right; bytePtr = buf; DWORD_TO_4BYTES(left, bytePtr); bytePtr = &(buf[4]); DWORD_TO_4BYTES(right,bytePtr); IdeaECB( buf, buf, (IdeaExtKey *)KeyAddress, TRUE ); bytePtr = buf; BYTES_TO_DWORD(bytePtr,left); bytePtr = &(buf[4]); BYTES_TO_DWORD(bytePtr,right); DstBuffer[i] = left; DstBuffer[i+1] = right; }}//************ IDEA CBC mode decryption **************VOIDDecrypt( DWORD *IVector, DWORD *KeyAddress, DWORD *SrcBuffer, DWORD *DstBuffer, DWORD Length ) // in bytes{ DWORD i; DWORD left, right, ivectorL, ivectorR, oldSrcL, oldSrcR; UCHAR buf[8], *bytePtr; ivectorL = IVector[0]; ivectorR = IVector[1]; for(i = 0; i < (Length >> 2); i = i+2) { left = oldSrcL = SrcBuffer[i]; right = oldSrcR = SrcBuffer[i+1]; // Encrypted Data -> new IV, // then do EBC decryption of Encrypted Data, // then XOR decrypted data with old IV bytePtr = buf; DWORD_TO_4BYTES(left, bytePtr); bytePtr = &(buf[4]); DWORD_TO_4BYTES(right,bytePtr); IdeaECB( buf, buf, (IdeaExtKey *)KeyAddress, FALSE ); bytePtr = buf; BYTES_TO_DWORD(bytePtr,left); bytePtr = &(buf[4]); BYTES_TO_DWORD(bytePtr,right); DstBuffer[i] = left ^ ivectorL; DstBuffer[i+1] = right ^ ivectorR; ivectorL = oldSrcL; ivectorR = oldSrcR; }}char idea_c[]="$Id: idea.c,v 1.3 2002/10/29 07:11:46 crypt Rel-1.6-5 $";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -