home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / alt / security / 5217 < prev    next >
Encoding:
Text File  |  1992-12-23  |  11.1 KB  |  403 lines

  1. Newsgroups: alt.security
  2. Path: sparky!uunet!psinntp!jpradley!jpr
  3. From: jpr@jpradley.jpr.com (Jean-Pierre Radley)
  4. Subject: Re: encryption program?
  5. Date: Wed, 23 Dec 1992 04:45:09 GMT
  6. Message-ID: <1992Dec23.044509.23809@jpradley.jpr.com>
  7. References: <1992Dec16.104806.23577@nuscc.nus.sg>
  8. Organization: Unix in NYC
  9. Lines: 392
  10.  
  11. In article <1992Dec16.104806.23577@nuscc.nus.sg> elekokws@nuscc.nus.sg (Netweaver) writes:
  12. >I have some data file ( binary and text ) that I would like to
  13. >encrypt, using something better than the Unix's crypt().
  14. >can anyone tell me where I can ftp one?
  15. >
  16.  
  17.  
  18.  
  19. :
  20. # hill.c : an encryption program superior to Xenix 'crypt'
  21. # Author: John Cowan.  Copyright (c) 1987 by John Cowan.  Permission
  22. # for unrestricted noncommercial republication granted provided this
  23. # copyright notice is retained on all republished copies.  Permission
  24. # to post this file on Compuserve specifically granted by John Cowan.
  25. #
  26. # The Unix/Xenix 'crypt' program is not, as many erroneously believe,
  27. # an implementation of the National Bureau of Standard's "Data Encryption
  28. # Standard" (DES) for data encryption.  It is, instead, an implementation
  29. # of an unrelated algorithm, much simpler, much faster-running, and much
  30. # more vulnerable to determined code-breaking, mostly because it preserves
  31. # the structure of the original (plaintext) data and is therefore open to
  32. # statistically-based pattern-recognition methods of code-breaking.
  33. # This program provides an encryption/decryption scheme that's
  34. # stronger than Unix/Xenix 'crypt', but is still weaker than the
  35. # DES standard.  No utility is supplied with any current
  36. # microcomputer version of Unix or Xenix that truly implements the
  37. # DES standard, although such utilities can be constructed (more
  38. # or less) with the function libraries that usually come with Unix
  39. # (Xenix with the "Development System(s)") and a bit of twiddling
  40. # around.  The Unix/Xenix password-encryption scheme does use the
  41. # DES standard (in a stronger way than does the DES standard
  42. # itself), but it's something else again.
  43. # This archive contains the files hill.doc, hill.c, table.i, and
  44. # kappa.c.  To extract these files, type "sh filename" where
  45. # 'filename' is the name you've saved this file under.
  46. echo splitting out files
  47. sed -n '/#START/,$p' <$0 | \
  48. sed -e '/file: hill\.doc/,/EOF: hill\.doc/w hill.doc' \
  49.     -e '/file: hill\.c/,/EOF: hill\.c/w hill.c' \
  50.     -e '/file: table\.i/,/EOF: table\.i/w table\.i' \
  51.     -e '/file: kappa\.c/,$w kappa.c' >/dev/null
  52. echo compiling hill
  53. cc -o hill hill.c
  54. echo compiling kappa
  55. cc -o kappa kappa.c
  56. echo Done.
  57. exit
  58. #START
  59. /* file: hill.doc */
  60. Hill encryption (decryption) program
  61.  
  62. Hill operates as a filter, reading plain (encrypted) text from the standard
  63. input and writing encrypted (plain) text to the standard output.  It is
  64. necessary to specify either -e for encryption or -d for decryption.  The
  65. key may be specified on the command line or, if omitted, will be prompted
  66. for.  The minimum keysize is 9 characters; the maximum is 256.  Longer keys
  67. make for greater security and slower operation.
  68.  
  69. The options -c, -C, -p, and -s are mutually exclusive, and specify pre-encoding
  70. (post-decoding) of the plaintext.  -c specifies dynamic Huffman encoding using
  71. 'compact' ('uncompact'); -C specifies Lempel-Ziv encoding using 'compress'
  72. ('uncompress'); -p specifies fixed Huffman encoding using 'pack' ('unpack');
  73. -s specifies CP/M compatible fixed Huffman encoding using 'sq' ('usq').
  74. The specified programs for each option must exist on the system for the option
  75. to be effective.  The options -c and -C actually improve cryptographic security,
  76. and should be used whenever time is not critical; the options -p and -s decrease
  77. security, and should be used only when space is critical.
  78.  
  79. Timing considerations:  On an 8MHz IBM PC-AT running Microport Unix, 'hill'
  80. operates at about 3K/sec for a 16-byte key.  Using a 100-byte key, speed is
  81. about half that.
  82.  
  83. Space considerations:  Encrypted files are about 1% longer than their plaintext
  84. equivalents.
  85.  
  86. Kappa:  Kappa is a utility program which prints the byte frequencies of the
  87. standard input.  The output is in the form of an array of 256 frequencies,
  88. read row-wise.  Each frequency is multiplied by 1000 on output.
  89. /* EOF: hill.doc */
  90. /* file: hill.c */
  91. # include <stdio.h>
  92. # include "table.i"
  93. FILE *popen();
  94.  
  95. # define Over(x) for (x = 0; x < order; x++)
  96. # define Times(a,b) ((long)(a) * (long)(b) % 257)
  97.  
  98. int mode;
  99. int reduction;
  100.  
  101. char key[256];
  102. int matkey[16][16];
  103. int invec[16];
  104. int outvec[16];
  105. int order;
  106.  
  107. FILE *input;
  108. FILE *output;
  109.  
  110. setup(argc, argv)
  111. int argc; char **argv;
  112.     {
  113.     extern int optind;
  114.     extern int opterr;
  115.     int eflag = 0;
  116.     int dflag = 0;
  117.     int cflag = 0;
  118.     int Cflag = 0;
  119.     int pflag = 0;
  120.     int sflag = 0;
  121.     int qflag = 0;
  122.     int c;
  123.     long tloc;
  124.  
  125.     time(&tloc);
  126.     srand((int) tloc);
  127.     opterr = 0;
  128.     mode = 0;
  129.     reduction = 0;
  130.     while ((c = getopt(argc, argv, "edcCps")) != EOF)
  131.     switch(c) {
  132.     case 'e': eflag++; break;
  133.     case 'd': dflag++; break;
  134.     case 'c': cflag++; break;
  135.     case 'C': Cflag++; break;
  136.     case 'p': pflag++; break;
  137.     case 's': sflag++; break;
  138.     case '?': qflag++; break;
  139.         }
  140.     if (qflag || (!eflag && !dflag) || (eflag && dflag) ||
  141.         (cflag + Cflag + pflag + sflag > 1)) {
  142.     fprintf(stderr,
  143. "usage: %s { -e | -d } [{ -c | -C | -p | -s }] [key]\n", argv[0]);
  144.     exit(1);
  145.     }
  146.     if (eflag) mode = 'e';
  147.     if (dflag) mode = 'd';
  148.     if (cflag) reduction = 'c';
  149.     if (Cflag) reduction = 'C';
  150.     if (pflag) reduction = 'p';
  151.     if (sflag) reduction = 's';
  152.     strcpy(key, argv[optind]);
  153.     argv[optind] = 0;
  154.     }
  155.  
  156. makemat()
  157.     {
  158.     int i, j, k;
  159.     int n = 0;
  160.     FILE *tty;
  161.  
  162.     if (strlen(key) == 0) {
  163.     tty = fopen("/dev/tty", "r+");
  164.     setbuf(tty, NULL);
  165.     fprintf(tty, "Key? ");
  166.     fgets(key, sizeof(key), tty);
  167.     key[strlen(key) - 1] = 0;
  168.     fclose(tty);
  169.     }
  170.     setorder();
  171.     Over(i) Over(j)
  172.     matkey[i][j] = key[n++];
  173.     for (i = 0; i < strlen(key); i++)
  174.     key[i] = 0;
  175.     square();
  176.     while ((k = invert()) != EOF)
  177.     matkey[k][k] = (matkey[k][k] + 1) % 257;
  178.     }
  179.  
  180. setorder()
  181.     {
  182.     int n = strlen(key);
  183.  
  184.     for (order = 0; order < 17; order++)
  185.     if (order*order > n) break;
  186.     order--;
  187.     if (order < 3) {
  188.     fprintf(stderr, "key size < 9\n");
  189.     exit(1);
  190.     }
  191.     }
  192.  
  193. square()
  194.     {
  195.     int result[16][16];
  196.     int i, j, k;
  197.  
  198.     Over(i) Over(j)
  199.     result[i][j] = 0;
  200.     Over(i) Over(j) Over(k)
  201.     result[i][j] += Times(matkey[i][k], matkey[k][j]);
  202.     Over(i) Over(j)
  203.     matkey[i][j] = result[i][j] % 257;
  204.     }
  205.  
  206. int invert()
  207.     {
  208.     int matrix[16][16];
  209.     int inverse[16][16];
  210.     int i, j, k;
  211.     int t;
  212.     int pivot;
  213.  
  214.     Over(i) Over(j) {
  215.     matrix[i][j] = matkey[i][j];
  216.     inverse[i][j] = 0;
  217.     }
  218.     Over(k)
  219.     inverse[k][k] = 1;
  220.  
  221.     Over(k) {
  222.     if (matrix[k][k] == 0) {
  223.         for (i = k + 1; i < order; i++)
  224.         if (matrix[i][k]) {
  225.             Over(j) {
  226.                 t = matrix[i][j];
  227.                 matrix[i][j] = matrix[k][j];
  228.                 matrix[k][j] = t;
  229.                 t = inverse[i][j];
  230.                 inverse[i][j] = inverse[k][j];
  231.                 inverse[k][j] = t;
  232.                 }
  233.             break;
  234.             }
  235.         if (i == order) return(k);
  236.         }
  237.  
  238.     pivot = inverses[matrix[k][k]];
  239.     Over(j) {
  240.         matrix[k][j] = Times(matrix[k][j], pivot);
  241.         inverse[k][j] = Times(inverse[k][j], pivot);
  242.         }
  243.     Over(i) if (i != k) {
  244.         pivot = matrix[i][k];
  245.         Over(j) {
  246.         matrix[i][j] -= Times(pivot, matrix[k][j]);
  247.         if (matrix[i][j] < 0) matrix[i][j] += 257;
  248.         inverse[i][j] -= Times(pivot, inverse[k][j]);
  249.         if (inverse[i][j] < 0) inverse[i][j] += 257;
  250.         }
  251.         }
  252.     }
  253.  
  254.     if (mode == 'd') Over(i) Over(j)
  255.     matkey[i][j] = inverse[i][j];
  256.     return(EOF);
  257.     }
  258.  
  259. streams()
  260.     {
  261.     input = stdin;
  262.     output = stdout;
  263.     if (mode == 'e') {
  264.     if (reduction == 'c')
  265.         input = popen("compact", "r");
  266.     else if (reduction == 'C')
  267.         input = popen("compress", "r");
  268.     else if (reduction == 'p')
  269.         input = popen("cat >/tmp/hl$$;\
  270. pack /tmp/hl$$ >/dev/null; cat </tmp/hl$$.z; rm /tmp/hl$$.z", "r");
  271.     else if (reduction == 's')
  272.         input = popen("cat >/tmp/hl$$;\
  273. sq /tmp/hl$$ >/dev/null; cat </tmp/hl$$.SQ;\
  274. rm /tmp/hl$$ /tmp/hl$$.SQ", "r");
  275.     }
  276.     else {
  277.     if (reduction == 'c')
  278.         output = popen("uncompact", "w");
  279.     else if (reduction == 'C')
  280.         output = popen("uncompress", "w");
  281.     else if (reduction == 'p')
  282.         output = popen("cat >/tmp/hl$$.z;\
  283. unpack /tmp/hl$$ >/dev/null; cat </tmp/hl$$; rm /tmp/hl$$", "w");
  284.     else if (reduction == 's')
  285.         output = popen("cat >/tmp/hl$$.SQ;\
  286. usq /tmp/hl$$.SQ >/dev/null; cat </tmp/hl$$;\
  287. rm /tmp/hl$$ /tmp/hl$$.SQ", "w");
  288.     }
  289.     }
  290.  
  291. int getvec()
  292.     {
  293.     int i;
  294.     int padf = 0;
  295.  
  296.     Over(i)
  297.     if ((invec[i] = getc(input)) == EOF) {
  298.         if (i == 0) return(0);
  299.         else if (padf) invec[i] = rand() % 257;
  300.         else { invec[i] = 256; padf++; }
  301.         }
  302.     else if (invec[i] == 255 && mode == 'd')
  303.         invec[i] += getc(input);
  304.     return(i);
  305.     }
  306.  
  307. putvec()
  308.     {
  309.     int j;
  310.  
  311.     Over(j)
  312.     switch(outvec[j]) {
  313.     case 256:
  314.         if (mode == 'd') return;
  315.         else putc(255, output) , putc(1, output);
  316.         break;
  317.     case 255:
  318.         putc(255, output);
  319.         if (mode == 'e') putc(0, output);
  320.         break;
  321.     default:
  322.         putc(outvec[j], output);
  323.         }
  324.     }
  325.  
  326. matmul()
  327.     {
  328.     int i, j, k;
  329.  
  330.     Over(i) {
  331.     outvec[i] = 0;
  332.     Over(j)
  333.         outvec[i] += Times(invec[j], matkey[i][j]);
  334.     outvec[i] %= 257;
  335.     }
  336.     }
  337.  
  338. main(argc, argv)
  339. int argc; char **argv;
  340.     {
  341.     setup(argc, argv);
  342.     streams();
  343.     makemat();
  344.     while(getvec()) {
  345.     matmul();
  346.     putvec();
  347.     }
  348.     if (mode == 'e' && reduction) pclose(input);
  349.     if (mode == 'd' && reduction) pclose(output);
  350.     }
  351. /* EOF: hill.c */
  352. /* file: table.i */
  353. int inverses[257] = { 0, 1, 129, 86, 193, 103, 43, 147, 225, 200, 180, 187, 
  354. 150, 178, 202, 120, 241, 121, 100, 230, 90, 49, 222, 190, 75, 72, 89, 238, 101, 
  355. 195, 60, 199, 249, 148, 189, 235, 50, 132, 115, 145, 45, 163, 153, 6, 111, 40, 
  356. 95, 175, 166, 21, 36, 126, 173, 97, 119, 243, 179, 248, 226, 61, 30, 59, 228, 
  357. 102, 253, 87, 74, 234, 223, 149, 246, 181, 25, 169, 66, 24, 186, 247, 201, 244, 
  358. 151, 165, 210, 96, 205, 127, 3, 65, 184, 26, 20, 209, 176, 152, 216, 46, 83, 
  359. 53, 139, 135, 18, 28, 63, 5, 215, 164, 177, 245, 188, 224, 250, 44, 218, 116, 
  360. 124, 38, 113, 134, 159, 54, 15, 17, 158, 140, 114, 220, 51, 85, 255, 2, 172, 
  361. 206, 37, 143, 117, 99, 240, 242, 203, 98, 123, 144, 219, 133, 141, 39, 213, 7, 
  362. 33, 69, 12, 80, 93, 42, 252, 194, 229, 239, 122, 118, 204, 174, 211, 41, 105, 
  363. 81, 48, 237, 231, 73, 192, 254, 130, 52, 161, 47, 92, 106, 13, 56, 10, 71, 233, 
  364. 191, 88, 232, 76, 11, 108, 34, 23, 183, 170, 4, 155, 29, 198, 227, 196, 31, 9, 
  365. 78, 14, 138, 160, 84, 131, 221, 236, 91, 82, 162, 217, 146, 251, 104, 94, 212, 
  366. 112, 142, 125, 207, 22, 68, 109, 8, 58, 197, 62, 156, 19, 168, 185, 182, 67, 
  367. 35, 208, 167, 27, 157, 136, 16, 137, 55, 79, 107, 70, 77, 57, 32, 110, 214, 
  368. 154, 64, 171, 128, 256};
  369. /* EOF: table.i */
  370. /* file: kappa.c */
  371. # include <stdio.h>
  372.  
  373. long table[256];
  374. long total;
  375.  
  376. main()
  377.     {
  378.     int ch;
  379.     int i;
  380.     int lcmpr();
  381.  
  382.     while ((ch = getchar()) != EOF) {
  383.     table[ch]++;
  384.     total++;
  385.     }
  386.     printf("Total: %ld\n\n", total);
  387.     for (i = 0; i < 256; i++) {
  388.     table[i] *= 1000;
  389.     table[i] /= total;
  390.     }
  391.     for (i = 0; i < 256; i++) {
  392.     printf("%3.3ld ", table[i]);
  393.     if ((i + 1) % 16 == 0) putchar('\n');
  394.     if ((i + 1) % 128 == 0) putchar('\n');
  395.     }
  396.     }
  397. -- 
  398. Jean-Pierre Radley   Unix in NYC   jpr@jpr.com   jpradley!jpr   CIS: 72160.1341
  399.