Annotation of truecrypt/crypto/idea.c, revision 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.