|
|
1.1 ! root 1: /* IDEA source code. This code came from a number of sources, the original ! 2: was written by Masayasu Kumagai <[email protected]>, but was ! 3: severely hacked for speed and portability on non-Intel machines using code ! 4: from the book "PGP - Source Code and Internals", Phil Zimmermann, MIT ! 5: Press 1995, ISBN 0-262-24039-4 (note that the equivalent code in Applied ! 6: Cryptography has bugs and won't work properly). Extra optimizations were ! 7: contributed by Paulo Barreto <[email protected]>, everything was put ! 8: together by Peter Gutmann <[email protected]> */ ! 9: ! 10: #include <string.h> ! 11: #include "idea.h" ! 12: ! 13: #pragma warning( disable : 4244 ) ! 14: ! 15: ! 16: /* Compute the multiplicative inverse of x mod 65537. Slightly optimised ! 17: version based on the "PGP - Source Code and Internals" code */ ! 18: ! 19: static word16 mulInv( word16 x ) ! 20: { ! 21: word16 t0, t1; ! 22: word16 q, y; ! 23: ! 24: if( x <= 1 ) ! 25: return x; /* 0 and 1 are self-inverse */ ! 26: t1 = ( word16 ) ( 0x10001L / x ); /* Since x >= 2, this fits into 16 bits */ ! 27: y = ( word16 ) ( 0x10001L % x ); ! 28: if( y == 1 ) ! 29: return( ( word16 ) ( 1 - t1 ) ); ! 30: t0 = 1; ! 31: do ! 32: { ! 33: q = x / y; ! 34: x = x % y; ! 35: t0 += q * t1; ! 36: if( x == 1 ) ! 37: return( t0 ); ! 38: q = y / x; ! 39: y = y % x; ! 40: t1 += q * t0; ! 41: } ! 42: while( y != 1 ); ! 43: ! 44: return( ( word16 ) ( 1 - t1 ) ); ! 45: } ! 46: ! 47: /* Expand the 128-bit user key into the encryption and decryption keys */ ! 48: ! 49: void _cdecl ideaExpandKey( unsigned char const *userkey, word16 *eKey, word16 *dKey ) ! 50: { ! 51: word16 *eKeyPtr = eKey; ! 52: int i, j, k, p, r; ! 53: ! 54: /* Create the expanded encryption key */ ! 55: for( j = 0; j < 8; j++ ) ! 56: { ! 57: eKey[ j ] = ( userkey[ 0 ] << 8 ) + userkey[ 1 ]; ! 58: userkey += 2; ! 59: } ! 60: for( i = 0; j < IDEA_KEYLEN; j++ ) ! 61: { ! 62: i++; ! 63: eKey[ i + 7 ] = ( eKey[ i & 7 ] << 9 ) | ( eKey[ i + 1 & 7 ] >> 7 ); ! 64: eKey += i & 8; ! 65: i &= 7; ! 66: } ! 67: eKey = eKeyPtr; ! 68: ! 69: /* Create the decryption key from the encryption key */ ! 70: p = IDEA_KEYLEN; ! 71: dKey[ p - 1 ] = mulInv( eKey[ 3 ] ); ! 72: dKey[ p - 2 ] = -( signed ) ( eKey[ 2 ] ); ! 73: dKey[ p - 3 ] = -( signed ) ( eKey[ 1 ] ); ! 74: dKey[ p - 4 ] = mulInv( eKey[ 0 ] ); ! 75: k = 4; ! 76: p -= 4; ! 77: for( r = IDEA_ROUNDS - 1; r > 0; r-- ) ! 78: { ! 79: dKey[ p - 1 ] = eKey[ k + 1 ]; ! 80: dKey[ p - 2 ] = eKey[ k ]; ! 81: dKey[ p - 3 ] = mulInv( eKey[ k + 5 ] ); ! 82: dKey[ p - 4 ] = -( signed ) ( eKey[ k + 3 ] ); ! 83: dKey[ p - 5 ] = -( signed ) ( eKey[ k + 4 ] ); ! 84: dKey[ p - 6 ] = mulInv( eKey[ k + 2 ] ); ! 85: k += 6; p -= 6; ! 86: } ! 87: dKey[ p - 1 ] = eKey[ k + 1 ]; ! 88: dKey[ p - 2 ] = eKey[ k ]; ! 89: dKey[ p - 3 ] = mulInv( eKey[ k + 5 ] ); ! 90: dKey[ p - 4 ] = -( signed ) ( eKey[ k + 4 ] ); ! 91: dKey[ p - 5 ] = -( signed ) ( eKey[ k + 3 ] ); ! 92: dKey[ p - 6 ] = mulInv( eKey[ k + 2 ] ); ! 93: } ! 94: ! 95: #ifndef __WIN32__ ! 96: ! 97: /* Compute x * y mod 65537, from "PGP - Source Code and Internals" */ ! 98: ! 99: #define mul( x, y ) \ ! 100: ( ( t16 = ( y ) ) ? \ ! 101: ( x ) ? \ ! 102: t32 = ( unsigned long ) x * t16, \ ! 103: x = ( word16 ) t32, \ ! 104: t16 = ( word16 ) ( t32 >> 16 ), \ ! 105: x = ( x - t16 ) + ( x < t16 ) \ ! 106: : ( x = 1 - t16 ) \ ! 107: : ( x = 1 - x ) ) ! 108: ! 109: #ifdef __TURBOC__ ! 110: #pragma warn -pia /* Turn off warnings for dodgy code in mul() macro */ ! 111: #endif /* __TURBOC__ */ ! 112: ! 113: /* The basic IDEA round */ ! 114: ! 115: #define ideaRound( count ) \ ! 116: mul( x1, key[ ( count * 6 ) ] ); \ ! 117: x2 += key[ ( count * 6 ) + 1 ]; \ ! 118: x3 += key[ ( count * 6 ) + 2 ]; \ ! 119: mul( x4, key[ ( count * 6 ) + 3 ] ); \ ! 120: \ ! 121: s3 = x3; \ ! 122: x3 ^= x1; \ ! 123: mul( x3, key[ ( count * 6 ) + 4 ] ); \ ! 124: s2 = x2; \ ! 125: x2 ^= x4; \ ! 126: x2 += x3; \ ! 127: mul( x2, key[ ( count * 6 ) + 5 ] ); \ ! 128: x3 += x2; \ ! 129: \ ! 130: x1 ^= x2; x4 ^= x3; \ ! 131: x2 ^= s3; x3 ^= s2; ! 132: ! 133: /* Encrypt/decrypt a block of data with IDEA */ ! 134: ! 135: #if 0 ! 136: void _cdecl ideaCrypt( unsigned char const *in, unsigned char *out, word16 const *key ) ! 137: { ! 138: register word16 x1, x2, x3, x4, s2, s3; ! 139: word16 *inPtr, *outPtr; ! 140: register word16 t16; /* Needed by mul() macro */ ! 141: register unsigned long t32; /* Needed by mul() macro */ ! 142: ! 143: inPtr = ( word16 * ) in; ! 144: x1 = *inPtr++; x2 = *inPtr++; ! 145: x3 = *inPtr++; x4 = *inPtr++; ! 146: #ifdef DATA_LITTLEENDIAN ! 147: x1 = ( x1 >> 8 ) | ( x1 << 8 ); ! 148: x2 = ( x2 >> 8 ) | ( x2 << 8 ); ! 149: x3 = ( x3 >> 8 ) | ( x3 << 8 ); ! 150: x4 = ( x4 >> 8 ) | ( x4 << 8 ); ! 151: #endif /* DATA_LITTLEENDIAN */ ! 152: ! 153: /* Perform 8 rounds of encryption */ ! 154: ideaRound( 0 ); ! 155: ideaRound( 1 ); ! 156: ideaRound( 2 ); ! 157: ideaRound( 3 ); ! 158: ideaRound( 4 ); ! 159: ideaRound( 5 ); ! 160: ideaRound( 6 ); ! 161: ideaRound( 7 ); ! 162: ! 163: /* final semiround: */ ! 164: mul( x1, key[ 48 ] ); ! 165: x3 += key[ 49 ]; ! 166: x2 += key[ 50 ]; ! 167: mul( x4, key[ 51 ] ); ! 168: ! 169: outPtr = ( word16 * ) out; ! 170: #ifdef DATA_LITTLEENDIAN ! 171: *outPtr++ = ( x1 >> 8 ) | ( x1 << 8 ); ! 172: *outPtr++ = ( x3 >> 8 ) | ( x3 << 8 ); ! 173: *outPtr++ = ( x2 >> 8 ) | ( x2 << 8 ); ! 174: *outPtr++ = ( x4 >> 8 ) | ( x4 << 8 ); ! 175: #else ! 176: *outPtr++ = x1; *outPtr++ = x3; ! 177: *outPtr++ = x2; *outPtr++ = x4; ! 178: #endif /* DATA_LITTLEENDIAN */ ! 179: } ! 180: #ifdef __TURBOC__ ! 181: #pragma warn +pia ! 182: #endif /* __TURBOC__ */ ! 183: ! 184: #endif /* !__WIN32__ */ ! 185: #endif ! 186: ! 187: ! 188: #if 0 ! 189: #include <stdio.h> ! 190: ! 191: void main( void ) ! 192: { ! 193: unsigned char key[] = { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, ! 194: 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 }; ! 195: unsigned char plain[] = { 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03 }; ! 196: unsigned char cipher[] = { 0x11, 0xFB, 0xED, 0x2B, 0x01, 0x98, 0x6D, 0xE5 }; ! 197: unsigned char temp[ 8 ] = { 0 }; ! 198: unsigned short eKey[ 52 ], dKey[ 52 ]; ! 199: ! 200: ideaExpandKey( key, eKey, dKey ); ! 201: ideaCrypt( plain, temp, eKey ); ! 202: if( memcmp( temp, cipher, 8 ) ) ! 203: puts( "Encrypt bang." ); ! 204: ideaCrypt( temp, temp, dKey ); ! 205: if( memcmp( temp, plain, 8 ) ) ! 206: puts( "Decrypt bang." ); ! 207: } ! 208: #endif /* 0 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.