idea.c
来自「在PGP中用到的IDEA专利算法源码」· C语言 代码 · 共 632 行 · 第 1/2 页
C
632 行
else for(i=0; i<6; i++) printf(" %6u", Z[j*6+i]); } /* Compute decryption subkeys from encryption subkeys... */ de_key_idea(Z,DK); printf("\nDecryption key subblocks: "); for(j=0; j<ROUNDS+1; j++) { printf("\nround %d: ", j+1); if (j==ROUNDS) for(i=0; i<4; i++) printf(" %6u", DK[j*6+i]); else for(i=0; i<6; i++) printf(" %6u", DK[j*6+i]); } /* Make a sample plaintext pattern for testing... */ for (k=0; k<4; k++) XX[k] = k; printf("\n Encrypting %d KBytes (%ld blocks)...", KBYTES, KBYTES*64l); fflush(stdout); start = clock(); cipher_idea(XX,YY,Z); /* encrypt plaintext XX, making YY */ for (l = 1; l < 64*KBYTES; l++) cipher_idea(YY,YY,Z); /* repeated encryption */ cipher_idea(YY,TT,DK); /* decrypt ciphertext YY, making TT */ for (l = 1; l < 64*KBYTES; l++) cipher_idea(TT,TT,DK); /* repeated decryption */ end = clock() - start; l = end * 1000. / CLOCKS_PER_SEC + 1; i = l/1000; j = l%1000; l = KBYTES * 1024. * CLOCKS_PER_SEC / end; printf("%d.%03d seconds = %ld bytes per second\n", i, j, l); printf("\nX %6u %6u %6u %6u \n", XX[0], XX[1], XX[2], XX[3]); printf("Y %6u %6u %6u %6u \n", YY[0], YY[1], YY[2], YY[3]); printf("T %6u %6u %6u %6u \n", TT[0], TT[1], TT[2], TT[3]); /* Now decrypted TT should be same as original XX */ for (k=0; k<4; k++) if (TT[k] != XX[k]) { printf("\n\07Error! Noninvertable encryption.\n"); exit(-1); /* error exit */ } printf("\nNormal exit.\n"); exit(0); /* normal exit */ } /* main */#endif /* TEST *//*************************************************************************//* * xorbuf - change buffer via xor with random mask block * Used for Cipher Feedback (CFB) or Cipher Block Chaining * (CBC) modes of encryption. * Can be applied for any block encryption algorithm, * with any block size, such as the DES or the IDEA cipher. */static void xorbuf(register byteptr buf, register byteptr mask, register int count)/* count must be > 0 */{ if (count) do *buf++ ^= *mask++; while (--count);} /* xorbuf *//* * cfbshift - shift bytes into IV for CFB input * Used only for Cipher Feedback (CFB) mode of encryption. * Can be applied for any block encryption algorithm with any * block size, such as the DES or the IDEA cipher. */static void cfbshift(register byteptr iv, register byteptr buf, register int count, int blocksize)/* iv is the initialization vector. * buf is the buffer pointer. * count is the number of bytes to shift in...must be > 0. * blocksize is 8 bytes for DES or IDEA ciphers. */{ int retained; if (count) { retained = blocksize-count; /* number bytes in iv to retain */ /* left-shift retained bytes of IV over by count bytes to make room */ while (retained--) { *iv = *(iv+count); iv++; } /* now copy count bytes from buf to shifted tail of IV */ do *iv++ = *buf++; while (--count); }} /* cfbshift *//* Key schedules for IDEA encryption and decryption */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 */static void initkey_idea(byte key[16], boolean decryp){ word16 userkey[8]; /* IDEA key is 16 bytes long */ int i; /* Assume each pair of bytes comprising a word is ordered MSB-first. */ for (i=0; i<8; i++) { userkey[i] = (key[0]<<8) + key[1]; key++; key++; } en_key_idea(userkey,Z); if (decryp) { de_key_idea(Z,Z); /* compute inverse key schedule DK */ } for (i=0; i<8; i++) /* Erase dangerous traces */ userkey[i] = 0;} /* initkey_idea *//* Run a 64-bit block thru IDEA in ECB (Electronic Code Book) mode, using the currently selected key schedule.*/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 */ word16 x; /* Invert the byte order for each 16-bit word for internal use. */ x = inbuf[0]; outbuf[0] = x >> 8 | x << 8; x = inbuf[1]; outbuf[1] = x >> 8 | x << 8; x = inbuf[2]; outbuf[2] = x >> 8 | x << 8; x = inbuf[3]; outbuf[3] = x >> 8 | x << 8; cipher_idea(outbuf, outbuf, Z); x = outbuf[0]; outbuf[0] = x >> 8 | x << 8; x = outbuf[1]; outbuf[1] = x >> 8 | x << 8; x = outbuf[2]; outbuf[2] = x >> 8 | x << 8; x = outbuf[3]; outbuf[3] = x >> 8 | x << 8;#else /* HIGHFIRST */ /* Byte order for internal and external representations is the same. */ cipher_idea(inbuf, outbuf, Z);#endif /* HIGHFIRST */} /* idea_ecb *//* * initcfb - Initializes the IDEA key schedule tables via key, * and initializes the Cipher Feedback mode IV. * References context variables cfb_dc_idea and iv_idea. */void initcfb_idea(word16 iv0[4], byte key[16], boolean decryp)/* iv0 is copied to global iv_idea, buffer will be destroyed by ideacfb. key is pointer to key buffer. decryp is TRUE if decrypting, FALSE if encrypting.*/{ iv_idea = iv0; cfb_dc_idea = decryp; initkey_idea(key,FALSE);} /* initcfb_idea *//* * ideacfb - encipher a buffer with IDEA enciphering algorithm, * using Cipher Feedback (CFB) mode. * * Assumes initcfb_idea has already been called. * References context variables cfb_dc_idea and iv_idea. */void ideacfb(byteptr buf, int count)/* buf is input, output buffer, may be more than 1 block. * count is byte count of buffer. May be > IDEABLOCKSIZE. */{ int chunksize; /* smaller of count, IDEABLOCKSIZE */ word16 temp[IDEABLOCKSIZE/2]; while ((chunksize = min(count,IDEABLOCKSIZE)) > 0) { idea_ecb(iv_idea,temp); /* encrypt iv_idea, making temp. */ if (cfb_dc_idea) /* buf is ciphertext */ /* shift in ciphertext to IV... */ cfbshift((byte *)iv_idea,buf,chunksize,IDEABLOCKSIZE); /* convert buf via xor */ xorbuf(buf,(byte *)temp,chunksize); /* buf now has enciphered output */ if (!cfb_dc_idea) /* buf was plaintext, is now ciphertext */ /* shift in ciphertext to IV... */ cfbshift((byte *)iv_idea,buf,chunksize,IDEABLOCKSIZE); count -= chunksize; buf += chunksize; }} /* ideacfb *//* close_idea function erases all the key schedule information when we are all done with a set of operations for a particular IDEA key context. This is to prevent any sensitive data from being left around in memory.*/void close_idea(void) /* erase current key schedule tables */{ short i; for (i = 0; i < KEYLEN; i++) Z[i] = 0;} /* close_idea() *//********************************************************************//* * These buffers are used by init_idearand, idearand, and close_idearand. */static word16 dtbuf_idea[4] = {0}; /* buffer for enciphered timestamp */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. * Used for generating cryptographically strong random numbers. * Much of the design comes from Appendix C of ANSI X9.17. * key is pointer to IDEA key buffer. * seed is pointer to random number seed buffer. * tstamp is a 32-bit timestamp */void init_idearand(byte key[16], byte seed[8], word32 tstamp){ int i; en_key_idea((word16 *)key, randkey_idea); for (i=0; i<4; i++) /* capture timestamp material */ { dtbuf_idea[i] = tstamp; /* get bottom word */ tstamp = tstamp >> 16; /* drop bottom word */ /* tstamp has only 4 bytes-- last 4 bytes will always be 0 */ } /* Start with enciphered timestamp: */ cipher_idea(dtbuf_idea, dtbuf_idea, randkey_idea); /* initialize seed material */ for (i=0; i<8; i++) ((byte *)randseed_idea)[i] = seed[i]; randbuf_idea_counter = 0; /* # of random bytes left in randbuf_idea */} /* init_idearand *//* * idearand - IDEA pseudo-random number generator * Used for generating cryptographically strong random numbers. * Much of the design comes from Appendix C of ANSI X9.17. */byte idearand(void){ int i; if (randbuf_idea_counter==0) /* if random buffer is spent...*/ { /* Combine enciphered timestamp with seed material: */ for (i=0; i<4; i++) randseed_idea[i] ^= dtbuf_idea[i]; 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]; cipher_idea(randseed_idea,randseed_idea,randkey_idea); /* fill new seed */ randbuf_idea_counter = 8; /* reset counter for full buffer */ } /* Take a byte from randbuf_idea: */ return(((byte *)randbuf_idea)[--randbuf_idea_counter]);} /* idearand */void close_idearand(void){ /* Erase random IDEA buffers and wipe out IDEA key info */ int i; for (i=0; i<4; i++) { randbuf_idea[i] = 0; randseed_idea[i] = 0; dtbuf_idea[i] = 0; } for (i = 0; i<KEYLEN; i++) randkey_idea[i] = 0;} /* close_idearand *//* end of idea.c */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?