Advertisement
mrburns

3-Way

Mar 26th, 2011
38
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.64 KB | None | 0 0
  1. /********************************************************************\
  2. *                                                                    *
  3. * C specification of the threeway block cipher                       *
  4. *                                                                    *
  5. \********************************************************************/
  6. /*file i/o main function by Pate Williams 1996*/
  7.  
  8. // Source: http://www.schneier.com/sccd/3-WAY.ZIP
  9.  
  10. #include <ctype.h>
  11. #include <stdio.h>
  12. //#include <process.h>
  13. #include <unistd.h>
  14. #include <sys/stat.h>
  15. #include <sys/types.h>
  16. #include <string.h>
  17. #include <time.h>
  18.  
  19. #define   STRT_E   0x0b0b /* round constant of first encryption round */
  20. #define   STRT_D   0xb1b1 /* round constant of first decryption round */
  21. #define     NMBR       11 /* number of rounds is 11                   */
  22.  
  23. #define   BLK_SIZE     12 /*number of bytes per block*/
  24.  
  25. typedef   unsigned long int  word32 ;
  26.                  /* the program only works correctly if long = 32bits */
  27.  
  28. void mu(word32 *a)       /* inverts the order of the bits of a */
  29. {
  30. int i ;
  31. word32 b[3] ;
  32.  
  33. b[0] = b[1] = b[2] = 0 ;
  34. for( i=0 ; i<32 ; i++ )
  35.    {
  36.    b[0] <<= 1 ; b[1] <<= 1 ; b[2] <<= 1 ;
  37.    if(a[0]&1) b[2] |= 1 ;
  38.    if(a[1]&1) b[1] |= 1 ;
  39.    if(a[2]&1) b[0] |= 1 ;
  40.    a[0] >>= 1 ; a[1] >>= 1 ; a[2] >>= 1 ;
  41.    }
  42.  
  43. a[0] = b[0] ;      a[1] = b[1] ;      a[2] = b[2] ;
  44. }
  45.  
  46. void gamma(word32 *a)   /* the nonlinear step */
  47. {
  48. word32 b[3] ;
  49.  
  50. b[0] = a[0] ^ (a[1]|(~a[2])) ;
  51. b[1] = a[1] ^ (a[2]|(~a[0])) ;
  52. b[2] = a[2] ^ (a[0]|(~a[1])) ;
  53.  
  54. a[0] = b[0] ;      a[1] = b[1] ;      a[2] = b[2] ;
  55. }
  56.  
  57. void theta(word32 *a)    /* the linear step */
  58. {
  59. word32 b[3];
  60.  
  61. b[0] = a[0] ^  (a[0]>>16) ^ (a[1]<<16) ^     (a[1]>>16) ^ (a[2]<<16) ^
  62.                (a[1]>>24) ^ (a[2]<<8)  ^     (a[2]>>8)  ^ (a[0]<<24) ^
  63.                (a[2]>>16) ^ (a[0]<<16) ^     (a[2]>>24) ^ (a[0]<<8)  ;
  64. b[1] = a[1] ^  (a[1]>>16) ^ (a[2]<<16) ^     (a[2]>>16) ^ (a[0]<<16) ^
  65.                (a[2]>>24) ^ (a[0]<<8)  ^     (a[0]>>8)  ^ (a[1]<<24) ^
  66.                (a[0]>>16) ^ (a[1]<<16) ^     (a[0]>>24) ^ (a[1]<<8)  ;
  67. b[2] = a[2] ^  (a[2]>>16) ^ (a[0]<<16) ^     (a[0]>>16) ^ (a[1]<<16) ^
  68.                (a[0]>>24) ^ (a[1]<<8)  ^     (a[1]>>8)  ^ (a[2]<<24) ^
  69.                (a[1]>>16) ^ (a[2]<<16) ^     (a[1]>>24) ^ (a[2]<<8)  ;
  70.  
  71. a[0] = b[0] ;      a[1] = b[1] ;      a[2] = b[2] ;
  72. }
  73.  
  74. void pi_1(word32 *a)
  75. {
  76. a[0] = (a[0]>>10) ^ (a[0]<<22);
  77. a[2] = (a[2]<<1)  ^ (a[2]>>31);
  78. }
  79.  
  80. void pi_2(word32 *a)
  81. {
  82. a[0] = (a[0]<<1)  ^ (a[0]>>31);
  83. a[2] = (a[2]>>10) ^ (a[2]<<22);
  84. }
  85.  
  86. void rho(word32 *a)    /* the round function       */
  87. {
  88. theta(a) ;
  89. pi_1(a) ;
  90. gamma(a) ;
  91. pi_2(a) ;
  92. }
  93.  
  94. void rndcon_gen(word32 strt,word32 *rtab)
  95. {                           /* generates the round constants */
  96. int i ;
  97.  
  98. for(i=0 ; i<=NMBR ; i++ )
  99.    {
  100.    rtab[i] = strt ;
  101.    strt <<= 1 ;
  102.    if( strt&0x10000 ) strt ^= 0x11011 ;
  103.    }
  104. }
  105.  
  106. void encrypt(word32 *a, word32 *k)
  107. {
  108. char i ;
  109. word32 rcon[NMBR+1] ;
  110.  
  111. rndcon_gen(STRT_E,rcon) ;
  112. for( i=0 ; i<NMBR ; i++ )
  113.    {
  114.    a[0] ^= k[0] ^ (rcon[i]<<16) ;
  115.    a[1] ^= k[1] ;
  116.    a[2] ^= k[2] ^ rcon[i] ;
  117.    rho(a) ;
  118.    }
  119. a[0] ^= k[0] ^ (rcon[NMBR]<<16) ;
  120. a[1] ^= k[1] ;
  121. a[2] ^= k[2] ^ rcon[NMBR] ;
  122. theta(a) ;
  123. }
  124.  
  125. void decrypt(word32 *a, word32 *k)
  126. {
  127. char i ;
  128. word32 ki[3] ;          /* the `inverse' key             */
  129. word32 rcon[NMBR+1] ;   /* the `inverse' round constants */
  130.  
  131. ki[0] = k[0] ; ki[1] = k[1] ; ki[2] = k[2] ;
  132. theta(ki) ;
  133. mu(ki) ;
  134.  
  135. rndcon_gen(STRT_D,rcon) ;
  136.  
  137. mu(a) ;
  138. for( i=0 ; i<NMBR ; i++ )
  139.    {
  140.    a[0] ^= ki[0] ^ (rcon[i]<<16) ;
  141.    a[1] ^= ki[1] ;
  142.    a[2] ^= ki[2] ^ rcon[i] ;
  143.    rho(a) ;
  144.    }
  145. a[0] ^= ki[0] ^ (rcon[NMBR]<<16) ;
  146. a[1] ^= ki[1] ;
  147. a[2] ^= ki[2] ^ rcon[NMBR] ;
  148. theta(a) ;
  149. mu(a) ;
  150. }
  151.  
  152. int main(int argc, char *argv[])
  153. {
  154.   char key[128], *kp = key;
  155.   double time;
  156.   int c, command, k, left, len;
  157.   long i, length, number;
  158.   FILE *inp, *out;
  159.   clock_t time0 = clock();
  160.   word32 buffer[12], word_key[3];
  161.  
  162.   if (argc != 5)
  163.   {
  164.     printf("usage: %s inp_file out_file x key\n\n", argv[0]);
  165.     printf("where x is d for decrypt or x is e for encrypt,\n");
  166.     printf("and the key is twelve characters\n");
  167.     return 1;
  168.   }
  169.   inp = fopen(argv[1], "rb");
  170.   if (!inp)
  171.   {
  172.     printf("*error*\ncould not open input file %s\n", argv[1]);
  173.     return 1;
  174.   }
  175.   out = fopen(argv[2], "wb");
  176.   if (!out)
  177.   {
  178.     printf("*error*\ncould not open input file %s\n", argv[2]);
  179.     return 1;
  180.   }
  181.   command = tolower(argv[3][0]);
  182.   if (command != 'd' && command != 'e')
  183.   {
  184.     printf("*error*\nillegal function indicator %c\n", argv[3][0]);
  185.     return 1;
  186.   }
  187.   strcpy(key, argv[4]);
  188.   len = strlen(key);
  189.   if (len < 12)
  190.     for (k = len; k < 12; k++) key[k] = ' ';
  191.   key[12] = '\0';
  192.   memcpy(word_key, key, 12);
  193.   fseek(inp, 0, SEEK_END);
  194.   length = ftell(inp);
  195.   fseek(inp, 0, SEEK_SET);
  196.   number = length / BLK_SIZE;
  197.   left = (int) (length % BLK_SIZE);
  198.   if (command == 'd')
  199.     for (i = 0; i < number; i++)
  200.     {
  201.       fread(buffer, BLK_SIZE, 1, inp);
  202.       decrypt(buffer, word_key);
  203.       fwrite(buffer, BLK_SIZE, 1, out);
  204.     }
  205.   else
  206.     for (i = 0; i < number; i++)
  207.     {
  208.       fread(buffer, BLK_SIZE, 1, inp);
  209.       encrypt(buffer, word_key);
  210.       fwrite(buffer, BLK_SIZE, 1, out);
  211.     }
  212.   for (k = 0; k < left; k++)
  213.   {
  214.     c = fgetc(inp);
  215.     c ^= *kp++;
  216.     fputc(c, out);
  217.   }
  218.   time = (clock() - time0) / (double) CLOCKS_PER_SEC;
  219.   printf("total time required  = %f seconds\n", time);
  220.   if (time != 0.0)
  221.     printf("kilobytes per second = %f\n", length / (time * 1024.0));
  222.   else
  223.     printf("total bytes processed = %ld\n", length);
  224. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement