--- pgp/src/idea.c 2018/04/24 16:38:49 1.1.1.2 +++ pgp/src/idea.c 2018/04/24 16:39:32 1.1.1.3 @@ -7,7 +7,9 @@ * Zero-based indexing added, names changed from IPES to IDEA. * CFB functions added. Random number routines added. * - * Optimized for speed 21 Oct 92 by Colin Plumb + * Optimized for speed 21 Oct 92 by Colin Plumb. + * Very minor speedup on 23 Feb 93 by Colin Plumb. + * idearand() given a separate expanded key on 25 Feb 93, Colin Plumb. * * There are two adjustments that can be made to this code to * speed it up. Defaults may be used for PCs. Only the -DIDEA32 @@ -81,7 +83,7 @@ typedef word16 uint16; #define CONST #endif -static void en_key_idea(word16 userkey[8], IDEAkey Z); +static void en_key_idea(word16 *userkey, word16 *Z); static void de_key_idea(IDEAkey Z, IDEAkey DK); static void cipher_idea(word16 in[4], word16 out[4], CONST IDEAkey Z); @@ -126,8 +128,8 @@ CONST static uint16 inv(uint16 x) if (x <= 1) return x; /* 0 and 1 are self-inverse */ - t1 = 0x10001 / x; /* Since x >= 2, this fits into 16 bits */ - y = 0x10001 % x; + t1 = 0x10001L / x; /* Since x >= 2, this fits into 16 bits */ + y = 0x10001L % x; if (y == 1) return low16(1-t1); t0 = 1; @@ -239,9 +241,11 @@ static void de_key_idea(IDEAkey Z, IDEAk /* Note that in and out can be the same buffer */ static void cipher_idea(word16 in[4], word16 out[4], register CONST IDEAkey Z) { - register uint16 x1, x2, x3, x4, t1, t2; + register uint16 x1, x2, x3, x4, s2, s3; +#ifndef SMALL_CACHE register uint16 t16; register word32 t32; +#endif int r = ROUNDS; @@ -254,18 +258,20 @@ static void cipher_idea(word16 in[4], wo x3 += *Z++; MUL(x4, *Z++); - t2 = x1^x3; - MUL(t2, *Z++); - t1 = t2 + (x2^x4); - MUL(t1, *Z++); - t2 = t1+t2; - - x1 ^= t1; - x4 ^= t2; - - t2 ^= x2; - x2 = x3^t1; - x3 = t2; + s3 = x3; + x3 ^= x1; + MUL(x3, *Z++); + s2 = x2; + x2 ^= x4; + x2 += x3; + MUL(x2, *Z++); + x3 += x2; + + x1 ^= x2; + x4 ^= x3; + + x2 ^= s3; + x3 ^= s2; } while (--r); MUL(x1, *Z++); *out++ = x1; @@ -423,13 +429,13 @@ static void cfbshift(register byteptr iv /* Key schedules for IDEA encryption and decryption */ -static IDEAkey Z, DK; +static IDEAkey Z; static word16 *iv_idea; /* pointer to IV for CFB or CBC */ static boolean cfb_dc_idea; /* TRUE iff CFB decrypting */ /* initkey_idea initializes IDEA for ECB mode operations */ -void initkey_idea(byte key[16], boolean decryp) +static void initkey_idea(byte key[16], boolean decryp) { word16 userkey[8]; /* IDEA key is 16 bytes long */ int i; @@ -452,7 +458,7 @@ void initkey_idea(byte key[16], boolean /* Run a 64-bit block thru IDEA in ECB (Electronic Code Book) mode, using the currently selected key schedule. */ -void idea_ecb(word16 *inbuf, word16 *outbuf) +static void idea_ecb(word16 *inbuf, word16 *outbuf) { /* Assume each pair of bytes comprising a word is ordered MSB-first. */ #ifndef HIGHFIRST /* If this is a least-significant-byte-first CPU */ @@ -550,6 +556,7 @@ static word16 dtbuf_idea[4] = {0}; /* bu static word16 randseed_idea[4] = {0}; /* seed for IDEA random # generator */ static word16 randbuf_idea[4] = {0}; /* buffer for IDEA random # generator */ static byte randbuf_idea_counter = 0; /* # of random bytes left in randbuf_idea */ +static IDEAkey randkey_idea; /* Expanded key for IDEA random # generator */ /* * init_idearand - initialize idearand, IDEA random number generator. @@ -562,7 +569,8 @@ static byte randbuf_idea_counter = 0; /* void init_idearand(byte key[16], byte seed[8], word32 tstamp) { int i; - initkey_idea(key, FALSE); /* initialize IDEA */ + + en_key_idea((word16 *)key, randkey_idea); for (i=0; i<4; i++) /* capture timestamp material */ { dtbuf_idea[i] = tstamp; /* get bottom word */ @@ -570,7 +578,7 @@ void init_idearand(byte key[16], byte se /* tstamp has only 4 bytes-- last 4 bytes will always be 0 */ } /* Start with enciphered timestamp: */ - idea_ecb(dtbuf_idea,dtbuf_idea); + cipher_idea(dtbuf_idea, dtbuf_idea, randkey_idea); /* initialize seed material */ for (i=0; i<8; i++) @@ -593,12 +601,12 @@ byte idearand(void) { /* Combine enciphered timestamp with seed material: */ for (i=0; i<4; i++) randseed_idea[i] ^= dtbuf_idea[i]; - idea_ecb(randseed_idea,randbuf_idea); /* fill new block */ + cipher_idea(randseed_idea,randbuf_idea,randkey_idea); /* fill new block */ /* Compute new seed vector: */ for (i=0; i<4; i++) randseed_idea[i] = randbuf_idea[i] ^ dtbuf_idea[i]; - idea_ecb(randseed_idea,randseed_idea); /* fill new seed */ + cipher_idea(randseed_idea,randseed_idea,randkey_idea); /* fill new seed */ randbuf_idea_counter = 8; /* reset counter for full buffer */ } @@ -615,7 +623,8 @@ void close_idearand(void) randseed_idea[i] = 0; dtbuf_idea[i] = 0; } - close_idea(); /* erase current key schedule tables */ + for (i = 0; i