Annotation of truecrypt/crypto/idea.c, revision 1.1.1.1

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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.