home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / alde_c / misc / util / cipher2 / desgut.cv2 next >
Encoding:
Text File  |  1985-03-04  |  13.0 KB  |  316 lines

  1. /* des: duplicate the NBS Data Encryption Standard in software.
  2.  *
  3.  * Jim Gillogly, May 1977
  4.  * Modified 8/84 by Jim Gillogly and Lauren Weinstein to compile with
  5.  *      post-1977 C compilers and systems
  6.  * 8409.30 Static & void declarations added.  Interface & testing removed.
  7.  * 8501.28 Rewritten to handle 48-bit blocks during computation.
  8.  * 8502.15 Basic unit of operation changed to 24-bit longs.
  9.  * 8502.19 Type-conversion bugs killed; table pre-computes minimized.
  10.  * 8502.25 Array-size mismatch in p48init() squelched.  KSX64 added.
  11.  *      Richard Outerbridge
  12.  *
  13.  * The copyright in this program remains the proprietary property of
  14.  * the authors.  Permission is hereby given for non-commercial use
  15.  * provided the copyright lines are retained.
  16.  *
  17.  *      Copyright (c) 1977, 1984 by Jim Gillogly
  18.  *      Copyright (c) 1984 by Lauren Weinstein
  19.  *      Copyright (c) 1984, 1985 by Richard Outerbridge
  20.  *
  21.  */
  22.  
  23. #define DE      1
  24. typedef char     BYTE;   /* BYTE = (vax) ? int : char    */
  25.  
  26. void desinit(), p48init(), permute();
  27.  
  28. static char s12[4096], s34[4096], s56[4096], s78[4096];
  29. static long p48a[256][2], p48b[256][2], p48c[256][2], p48d[256][2];
  30. static long kn[32];
  31.  
  32. static int pmv[8] = { 64, 16,  4,  1, 128, 32,  8,  2   };
  33. static int pvs[8] = {  1,  2,  4,  8,  16, 32, 64, 128  };
  34.  
  35. void des(inblock,outblock)
  36. BYTE *inblock, *outblock;
  37.         {
  38.         register long *fmp, suba, subb, val, *h0L, *h1R, *keys;
  39.         BYTE scratch[8], *small;
  40.         long swap[4];
  41.         int i;
  42.  
  43.         permute(inblock, pmv, pvs, scratch);
  44.         h0L = swap, h1R = &swap[4], small = scratch;
  45.         while(h0L < h1R) {
  46.                 val = ((*small++)&0377L)<<24, val |= ((*small++)&0377L)<<16;
  47.                 val |= ((*small++)&0377L)<<8, val |= (*small++)&0377L;
  48.                 *h0L++ = ((val&0x1L)<<23) | ((val>>9)&0x7C0000L) |
  49.                         ((val&0x1F800000L)>>11) | 
  50.                         ((val&0x1F80000L)>>13) |
  51.                         ((val&0x1F8000L)>>15);
  52.                 *h0L++ = ((val&0x1F800L)<<7) |
  53.                         ((val&0x1F80L)<<5) |
  54.                         ((val&0x1F8L)<<3) |
  55.                         ((val&0x1FL)<<1) | ((val>>31)&0x1L);
  56.                 }
  57.         keys = kn, h0L = swap, h1R = &swap[2];
  58.         for(i=0; i<16; i++) {
  59.                 val = *keys++ ^ *h1R++;
  60.                 fmp = &p48a[ s12[(val>>12)]&0377 ][0];
  61.                 suba = *fmp++, subb = *fmp;
  62.                 fmp = &p48b[ s34[(val&07777L)]&0377 ][0];
  63.                 suba |= *fmp++, subb |= *fmp;
  64.                 val = *keys++ ^ *h1R++;
  65.                 fmp = &p48c[ s56[(val>>12)]&0377 ][0];
  66.                 suba |= *fmp++, subb |= *fmp;
  67.                 fmp = &p48d[ s78[(val&07777L)]&0377 ][0];
  68.                 suba |= *fmp++, subb |= *fmp;
  69.                 *h0L++ ^= suba, *h0L++ ^= subb;
  70.                 if(i&1) h0L = swap;
  71.                 else h1R = swap;
  72.                 }
  73.         val = *h0L, *h0L++ = *h1R, *h1R++ = val;
  74.         val = *h0L, *h0L = *h1R, *h1R = val;
  75.         h0L = swap, h1R = &swap[4], small = scratch;
  76.         while(h0L < h1R) {
  77.                 *small++ = ((*h0L&036000000L)>>15) | ((*h0L&0360000L)>>13);
  78.                 *small++ = ((*h0L&03600L)>>3) | ((*h0L&036L)>>1);
  79.                 h0L++;
  80.                 }
  81.         permute(scratch, pvs, pmv, outblock);
  82.         return;
  83.         }
  84.  
  85. static char s1[64] = {                  /* S[1]<<4              */
  86.        224, 64,208, 16, 32,240,176,128, 48,160, 96,192, 80,144,  0,112,
  87.          0,240,112, 64,224, 32,208, 16,160, 96,192,176,144, 80, 48,128,
  88.         64, 16,224,128,208, 96, 32,176,240,192,144,112, 48,160, 80,  0,
  89.        240,192,128, 32, 64,144, 16,112, 80,176, 48,224,160,  0, 96,208  };
  90. static char s3[64] = {                  /* S[3]<<4              */
  91.        160,  0,144,224, 96, 48,240, 80, 16,208,192,112,176, 64, 32,128,
  92.        208,112,  0,144, 48, 64, 96,160, 32,128, 80,224,192,176,240, 16,
  93.        208, 96, 64,144,128,240, 48,  0,176, 16, 32,192, 80,160,224,112,
  94.         16,160,208,  0, 96,144,128,112, 64,240,224, 48,176, 80, 32,192  };
  95. static char s5[64] = {                  /* S[5]<<4              */
  96.         32,192, 64, 16,112,160,176, 96,128, 80, 48,240,208,  0,224,144,
  97.        224,176, 32,192, 64,112,208, 16, 80,  0,240,160, 48,144,128, 96,
  98.         64, 32, 16,176,160,208,112,128,240,144,192, 80, 96, 48,  0,224,
  99.        176,128,192,112, 16,224, 32,208, 96,240,  0,144,160, 64, 80, 48  };
  100. static char s7[64] = {                  /* S[7]<<4              */
  101.         64,176, 32,224,240,  0,128,208, 48,192,144,112, 80,160, 96, 16,
  102.        208,  0,176,112, 64,144, 16,160,224, 48, 80,192, 32,240,128, 96,
  103.         16, 64,176,208,192, 48,112,224,160,240, 96,128,  0, 80,144, 32,
  104.         96,176,208,128, 16, 64,160,112,144, 80,  0,240,224, 32, 48,192  };
  105.  
  106. static char s2[64] = {                  /* S[2]                 */
  107.         15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
  108.          3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
  109.          0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
  110.         13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9  };
  111. static char s4[64] = {                  /* S[4]                 */
  112.          7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
  113.         13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
  114.         10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
  115.          3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14  };
  116. static char s6[64] = {                  /* S[6]                 */
  117.         12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
  118.         10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
  119.          9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
  120.          4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13  };
  121. static char s8[64] = {                  /* S[8]                 */
  122.         13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
  123.          1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
  124.          7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
  125.          2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11  };
  126.  
  127. static char p48i[] = {
  128.         24, 15,  6, 19, 20, 28, 20, 28, 11, 27, 16,  0,
  129.         16,  0, 14, 22, 25,  4, 25,  4, 17, 30,  9,  1,
  130.          9,  1,  7, 23, 13, 31, 13, 31, 26,  2,  8, 18,
  131.          8, 18, 12, 29,  5, 21,  5, 21, 10,  3, 24, 15  };
  132.  
  133. static int bytebit[]                /* bit 0 is left-most in byte   */
  134.         = {     0200,0100,040,020,010,04,02,01 };
  135.  
  136. static long bigbyte[] = {
  137.         0x800000L, 0x400000L, 0x200000L, 0x100000L,
  138.         0x80000L,  0x40000L,  0x20000L,  0x10000L,
  139.         0x8000L,   0x4000L,   0x2000L,   0x1000L,
  140.         0x800L,    0x400L,    0x200L,    0x100L,
  141.         0x80L,     0x40L,     0x20L,     0x10L,
  142.         0x8L,      0x4L,      0x2L,      0x1L       };
  143.  
  144. static int Ignited = 0;
  145.  
  146. void desinit() {
  147.         register int j, left, right;
  148.  
  149.         if(Ignited) return;
  150.         for(j=0; j<4096; j++) {
  151.                 left = ((j>>6)&040) | ((j>>2)&020) | ((j>>7)&017);
  152.                 right = (j&040) | ((j<<4)&020) | ((j>>1)&017);
  153.                 s12[j] = s1[left] | s2[right];
  154.                 s34[j] = s3[left] | s4[right];
  155.                 s56[j] = s5[left] | s6[right];
  156.                 s78[j] = s7[left] | s8[right];
  157.                 }
  158.         p48init();
  159.         Ignited = 1;
  160.         return;
  161.         }
  162.  
  163. #ifdef KSX64
  164. /* Implement an experimental, non-standard, simple-minded 64-bit key.   */
  165.  
  166. void kinit(key, edf)
  167. BYTE *key;
  168. int edf;
  169.         {
  170.         register int i;
  171.         register long *tofill;
  172.         long master[16];
  173.  
  174.         if(!Ignited) desinit(); 
  175.         for(i=0; i<16; i++) {
  176.                 master[i++] = (*key>>4)&017L;
  177.                 master[i] = (*key++)&017L;
  178.                 }
  179.         for(i=0; i<16; i++) {
  180.                 if(edf == DE) tofill = &kn[(15-i)<<1];
  181.                 else tofill = &kn[i<<1];
  182.                 *tofill = (master[(i + 1)&017]<<20);
  183.                 *tofill |= (master[(i + 8)&017]<<16);
  184.                 *tofill |= (master[(i + 5)&017]<<12);
  185.                 *tofill |= (master[(i + 10)&017]<<8);
  186.                 *tofill |= (master[(i + 3)&017]<<4);
  187.                 *tofill++ |= master[(i + 14)&017];
  188.                 *tofill = (master[(i + 6)&017]<<20);
  189.                 *tofill |= (master[(i + 11)&017]<<16);
  190.                 *tofill |= (master[(i + 2)&017]<<12);
  191.                 *tofill |= (master[(i + 13)&017]<<8);
  192.                 *tofill |= (master[i]<<4);
  193.                 *tofill |= master[(i + 9)&017];
  194.                 }
  195.         return;
  196.         }
  197.  
  198. #else
  199. /* Use the key schedule specified in the Standard (ANSI X3.92-1981).    */
  200.  
  201. static char pc1[] = {                   /* permuted choice table (key)  */
  202.         56, 48, 40, 32, 24, 16,  8,
  203.          0, 57, 49, 41, 33, 25, 17,
  204.          9,  1, 58, 50, 42, 34, 26,
  205.         18, 10,  2, 59, 51, 43, 35,
  206.         62, 54, 46, 38, 30, 22, 14,
  207.          6, 61, 53, 45, 37, 29, 21,
  208.         13,  5, 60, 52, 44, 36, 28,
  209.         20, 12,  4, 27, 19, 11,  3      };
  210.  
  211. static char totrot[]                    /* number left rotations of pc1 */
  212. = {     1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28      };
  213.  
  214. static char pc2[] = {                   /* permuted choice key (table)  */
  215.         13, 16, 10, 23,  0,  4,
  216.          2, 27, 14,  5, 20,  9,
  217.         22, 18, 11,  3, 25,  7,
  218.         15,  6, 26, 19, 12,  1,
  219.         40, 51, 30, 36, 46, 54,
  220.         29, 39, 50, 44, 32, 47,
  221.         43, 48, 38, 55, 33, 52,
  222.         45, 41, 49, 35, 28, 31  };
  223.  
  224. void kinit(key, edf)                    /* initialize key schedule array*/
  225. BYTE *key;                              /* 64 bits; we'll only use 56   */
  226. int edf;
  227. {
  228.         register int i, j, l, m, n;
  229.         char pc1m[56], pcr[56];
  230.  
  231.         if(!Ignited) desinit();
  232.         for (j=0; j<56; j++) {          /* convert pc1 to bits of key   */
  233.                 l = pc1[j];             /* integer bit location         */
  234.                 m = l & 07;             /* find bit                     */
  235.                 pc1m[j] = (key[l>>3] &  bytebit[m]) ? 1 : 0;
  236.                 }
  237.         for (i=0; i<16; i++) {          /* key chunk for each iteration */
  238.                 if(edf == DE) m = (15 - i)<<1;
  239.                 else m = i<<1;
  240.                 n = m + 1;
  241.                 kn[m] = kn[n] = 0L;
  242.                 for (j=0; j<56; j++)    /* rotate pc1 the right amount  */
  243.                 pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
  244.                         /* rotate left and right halves independently   */
  245.                 for(j=0; j<24; j++) {
  246.                         if(pcr[pc2[j]]) kn[m] |= bigbyte[j];
  247.                         if(pcr[pc2[j+24]]) kn[n] |= bigbyte[j];
  248.                         }
  249.                 }
  250.         return;
  251.         }
  252.  
  253. #endif
  254.  
  255. static void p48init() {                 /* initialize 32-bit permutation*/
  256.         register int l, j, k, i;
  257.         register long (*pfill)[2];
  258.  
  259.         for (i=0; i<4; i++) {           /* each input byte position     */
  260.                 switch(i) {
  261.                         case 0: pfill = p48a;
  262.                                 break;
  263.                         case 1: pfill = p48b;
  264.                                 break;
  265.                         case 2: pfill = p48c;
  266.                                 break;
  267.                         case 3: pfill = p48d;
  268.                                 break;
  269.                         default: break;
  270.                         }
  271.                 for (j=0; j<256; j++) {
  272.                         for(k=0; k<2; k++) pfill[j][k] = 0L;
  273.                         for(k=0; k<24; k++) {
  274.                                 l = p48i[k];
  275.                                 if((l>>3) != i) continue;
  276.                                 if( !(j&bytebit[l&07]) ) continue;
  277.                                 pfill[j][0] |= bigbyte[k];
  278.                                 }
  279.                         for(k=24; k<48; k++) {
  280.                                 l = p48i[k];
  281.                                 if((l>>3) != i) continue;
  282.                                 if( !(j&bytebit[l&07]) ) continue;
  283.                                 pfill[j][1] |= bigbyte[k-24];
  284.                                 }
  285.                         }
  286.                 }
  287.         return;
  288.         }
  289.  
  290. static void permute(inblock, test, vals, outblock)
  291. register BYTE *inblock;
  292. int *test;
  293. register int *vals;
  294. BYTE *outblock;
  295.         {
  296.         register BYTE *cp;
  297.         register int *dp;
  298.         register BYTE *eop, *eip;
  299.  
  300.         eop = &outblock[8]; eip = &inblock[8];
  301.         for(cp = outblock; cp < eop;) *cp++ = 0;
  302.         while(inblock < eip) {
  303.                 cp = outblock;
  304.                 dp = test;
  305.                 while(cp < eop) {
  306.                         if(*inblock&*dp++) *cp |= *vals;
  307.                         cp++;
  308.                         }
  309.                 inblock++;
  310.                 vals++;
  311.                 }
  312.         return;
  313.         }
  314.  
  315. /**************** End of DES algorithm PROP rel V2.4 8502.25 **************/
  316.