home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Spezial / SPEZIAL2_97.zip / SPEZIAL2_97.iso / ANWEND / ONLINE / ELM23-2 / ELM23-2.ZIP / src / encode.c < prev    next >
C/C++ Source or Header  |  1990-04-28  |  5KB  |  216 lines

  1.  
  2. static char rcsid[] = "@(#)$Id: encode.c,v 4.1 90/04/28 22:42:57 syd Exp $";
  3.  
  4. /*******************************************************************************
  5.  *  The Elm Mail System  -  $Revision: 4.1 $   $State: Exp $
  6.  *
  7.  *             Copyright (c) 1986, 1987 Dave Taylor
  8.  *             Copyright (c) 1988, 1989, 1990 USENET Community Trust
  9.  *******************************************************************************
  10.  * Bug reports, patches, comments, suggestions should be sent to:
  11.  *
  12.  *    Syd Weinstein, Elm Coordinator
  13.  *    elm@DSI.COM            dsinc!elm
  14.  *
  15.  *******************************************************************************
  16.  * $Log:    encode.c,v $
  17.  * Revision 4.1  90/04/28  22:42:57  syd
  18.  * checkin of Elm 2.3 as of Release PL0
  19.  *
  20.  *
  21.  ******************************************************************************/
  22.  
  23. /** This is a heavily mangled version of the 'cypher' program written by
  24.     person or persons unknown.
  25.  
  26. **/
  27.  
  28. #include "headers.h"
  29.  
  30. #define RS    94
  31. #define RN    4
  32. #define RMASK    0x7fff    /* use only 15 bits */
  33.  
  34. static char r[RS][RN];        /* rotors */
  35. static char ir[RS][RN];        /* inverse rotors */
  36. static char h[RS];        /* half rotor */
  37. static char s[RS];        /* shuffle vector */
  38. static int  p[RN];        /* rotor indices */
  39.  
  40. static char the_key[SLEN];    /* unencrypted key */
  41. static char *encrypted_key;    /* encrypted key   */
  42.  
  43. char *strncpy(), *strcpy();
  44. unsigned long sleep();
  45.  
  46. #define DECRYPT_PROMPT        "Enter decryption key: "
  47. #define FIRST_ENC_PROMPT    "Enter encryption key: "
  48. #define SECOND_ENC_PROMPT    "Please enter it again: "
  49. #define PROMPT_LINE        LINES-1
  50.  
  51. getkey(send)
  52. int send;
  53. {
  54.     /** this routine prompts for and returns an encode/decode
  55.         key for use in the rest of the program. **/
  56.  
  57.     char buffer[2][NLEN];
  58.  
  59.     while (1) {
  60.       PutLine0(PROMPT_LINE, 0, (send ? FIRST_ENC_PROMPT : DECRYPT_PROMPT));
  61.       CleartoEOLN();
  62.       optionally_enter(buffer[0], PROMPT_LINE,
  63.         strlen(send ? FIRST_ENC_PROMPT : DECRYPT_PROMPT), FALSE, TRUE);
  64.       if (send) {
  65.         PutLine0(PROMPT_LINE, 0, SECOND_ENC_PROMPT);
  66.         CleartoEOLN();
  67.         optionally_enter(buffer[1], PROMPT_LINE, strlen(SECOND_ENC_PROMPT),
  68.           FALSE, TRUE);
  69.         if(strcmp(buffer[0], buffer[1]) != 0) {
  70.           error("Your keys were not the same!");
  71.           sleep(1);
  72.           clear_error();
  73.           continue;
  74.         }
  75.       }
  76.       break;
  77.     }
  78.         strcpy(the_key, buffer[0]);    /* save unencrypted key */
  79.     makekey(buffer[0]);
  80.  
  81.     setup();        /** initialize the rotors etc. **/
  82.  
  83.     ClearLine(PROMPT_LINE);
  84.     clear_error();
  85. }
  86.  
  87. get_key_no_prompt()
  88. {
  89.     /** This performs the same action as get_key, but assumes that
  90.         the current value of 'the_key' is acceptable.  This is used
  91.         when a message is encrypted twice... **/
  92.  
  93.     char buffer[SLEN];
  94.  
  95.     strcpy(buffer, the_key);
  96.  
  97.     makekey( buffer );
  98.  
  99.     setup();
  100. }
  101.  
  102. encode(line)
  103. char *line;
  104. {
  105.     /** encrypt or decrypt the specified line.  Uses the previously
  106.         entered key... **/
  107.  
  108.     register int i, j, ph = 0;
  109.  
  110.     for (; *line; line++) {
  111.       i = (int) *line;
  112.  
  113.       if ( (i >= ' ') && (i < '~') ) {
  114.         i -= ' ';
  115.  
  116.         for ( j = 0; j < RN; j++ )        /* rotor forwards */
  117.           i = r[(i+p[j])%RS][j];
  118.  
  119.         i = ((h[(i+ph)%RS])-ph+RS)%RS;    /* half rotor */
  120.  
  121.         for ( j--  ; j >= 0; j-- )        /* rotor backwards */
  122.           i = (ir[i][j]+RS-p[j])%RS;
  123.  
  124.         j = 0;                /* rotate rotors */
  125.         p[0]++;
  126.         while ( p[j] == RS ) {
  127.           p[j] = 0;
  128.           j++;
  129.           if ( j == RN ) break;
  130.           p[j]++;
  131.             }
  132.  
  133.         if ( ++ph == RS )
  134.           ph = 0;
  135.  
  136.         i += ' ';
  137.       }
  138.  
  139.       *line = (char) i;    /* replace with altered one */
  140.     }
  141. }
  142.  
  143.  
  144. makekey( rkey)
  145. char *rkey;
  146. {
  147.     /** encrypt the key using the system routine 'crypt' **/
  148.  
  149.     char key[9], salt[2], *crypt();
  150.  
  151.     strncpy( key, rkey, 8);
  152.     key[8] = '\0';
  153.     salt[0] = key[0];
  154.     salt[1] = key[1];
  155. #ifdef CRYPT
  156.     encrypted_key = crypt( key, salt);
  157. #else
  158.     encrypted_key = key;
  159. #endif
  160. }
  161.  
  162. /*
  163.  * shuffle rotors.
  164.  * shuffle each of the rotors indiscriminately.  shuffle the half-rotor
  165.  * using a special obvious and not very tricky algorithm which is not as
  166.  * sophisticated as the one in crypt(1) and Oh God, I'm so depressed.
  167.  * After all this is done build the inverses of the rotors.
  168.  */
  169.  
  170. setup()
  171. {
  172.     register long i, j, k, temp;
  173.     long seed;
  174.  
  175.     for ( j = 0; j < RN; j++ ) {
  176.         p[j] = 0;
  177.         for ( i = 0; i < RS; i++ )
  178.             r[i][j] = i;
  179.     }
  180.  
  181.     seed = 123;
  182.     for ( i = 0; i < 13; i++)        /* now personalize the seed */
  183.       seed = (seed*encrypted_key[i] + i) & RMASK;
  184.  
  185.     for ( i = 0; i < RS; i++ )        /* initialize shuffle vector */
  186.       h[i] = s[i] = i;
  187.  
  188.     for ( i = 0; i < RS; i++) {        /* shuffle the vector */
  189.       seed = (5 * seed + encrypted_key[i%13]) & RMASK;;
  190.       k = ((seed % 65521) & RMASK) % RS;
  191.       temp = s[k];
  192.       s[k] = s[i];
  193.       s[i] = temp;
  194.     }
  195.  
  196.     for ( i = 0; i < RS; i += 2 ) {    /* scramble the half-rotor */
  197.       temp = h[s[i]];            /* swap rotor elements ONCE */
  198.       h[s[i]] = h[s[i+1]];
  199.       h[s[i+1]] = temp;
  200.     }
  201.  
  202.     for ( j = 0; j < RN; j++) {            /* select a rotor */
  203.  
  204.       for ( i = 0; i < RS; i++) {        /* shuffle the vector */
  205.         seed = (5 * seed + encrypted_key[i%13]) & RMASK;;
  206.         k = ((seed % 65521) & RMASK) % RS;
  207.         temp = r[i][j];
  208.         r[i][j] = r[k][j];
  209.         r[k][j] = temp;
  210.       }
  211.  
  212.       for ( i = 0; i < RS; i++)         /* create inverse rotors */
  213.         ir[r[i][j]][j] = i;
  214.        }
  215. }
  216.