|
|
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.