免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3340 | 回复: 2
打印 上一主题 下一主题

[函数] DES函数 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-11-18 10:10 |只看该作者 |倒序浏览
1、哪里可以下到C代码的DES函数库
2、以下是我找到的一段代码
  1. #define NULL    0

  2. #ifdef  LITTLE_ENDIAN
  3. unsigned long byteswap();
  4. #endif

  5. /* Tables defined in the Data Encryption Standard documents */

  6. /* initial permutation IP */
  7. static char ip[] = {
  8.         58, 50, 42, 34, 26, 18, 10,  2,
  9.         60, 52, 44, 36, 28, 20, 12,  4,
  10.         62, 54, 46, 38, 30, 22, 14,  6,
  11.         64, 56, 48, 40, 32, 24, 16,  8,
  12.         57, 49, 41, 33, 25, 17,  9,  1,
  13.         59, 51, 43, 35, 27, 19, 11,  3,
  14.         61, 53, 45, 37, 29, 21, 13,  5,
  15.         63, 55, 47, 39, 31, 23, 15,  7
  16. };

  17. /* final permutation IP^-1 */
  18. static char fp[] = {
  19.         40,  8, 48, 16, 56, 24, 64, 32,
  20.         39,  7, 47, 15, 55, 23, 63, 31,
  21.         38,  6, 46, 14, 54, 22, 62, 30,
  22.         37,  5, 45, 13, 53, 21, 61, 29,
  23.         36,  4, 44, 12, 52, 20, 60, 28,
  24.         35,  3, 43, 11, 51, 19, 59, 27,
  25.         34,  2, 42, 10, 50, 18, 58, 26,
  26.         33,  1, 41,  9, 49, 17, 57, 25
  27. };

  28. /* expansion operation matrix
  29. * This is for reference only; it is unused in the code
  30. * as the f() function performs it implicitly for speed
  31. */
  32. #ifdef notdef
  33. static char ei[] = {
  34.         32,  1,  2,  3,  4,  5,
  35.          4,  5,  6,  7,  8,  9,
  36.          8,  9, 10, 11, 12, 13,
  37.         12, 13, 14, 15, 16, 17,
  38.         16, 17, 18, 19, 20, 21,
  39.         20, 21, 22, 23, 24, 25,
  40.         24, 25, 26, 27, 28, 29,
  41.         28, 29, 30, 31, 32,  1
  42. };
  43. #endif

  44. /* permuted choice table (key) */
  45. static char pc1[] = {
  46.         57, 49, 41, 33, 25, 17,  9,
  47.          1, 58, 50, 42, 34, 26, 18,
  48.         10,  2, 59, 51, 43, 35, 27,
  49.         19, 11,  3, 60, 52, 44, 36,

  50.         63, 55, 47, 39, 31, 23, 15,
  51.          7, 62, 54, 46, 38, 30, 22,
  52.         14,  6, 61, 53, 45, 37, 29,
  53.         21, 13,  5, 28, 20, 12,  4
  54. };

  55. /* number left rotations of pc1 */
  56. static char totrot[] = {
  57.         1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
  58. };

  59. /* permuted choice key (table) */
  60. static char pc2[] = {
  61.         14, 17, 11, 24,  1,  5,
  62.          3, 28, 15,  6, 21, 10,
  63.         23, 19, 12,  4, 26,  8,
  64.         16,  7, 27, 20, 13,  2,
  65.         41, 52, 31, 37, 47, 55,
  66.         30, 40, 51, 45, 33, 48,
  67.         44, 49, 39, 56, 34, 53,
  68.         46, 42, 50, 36, 29, 32
  69. };
  70. /* The (in)famous S-boxes */
  71. static char si[8][64] = {
  72.         /* S1 */
  73.         14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
  74.          0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
  75.          4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
  76.         15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,

  77.         /* S2 */
  78.         15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
  79.          3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
  80.          0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
  81.         13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,

  82.         /* S3 */
  83.         10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
  84.         13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
  85.         13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
  86.          1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,

  87.         /* S4 */
  88.          7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
  89.         13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
  90.         10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
  91.          3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,

  92.         /* S5 */
  93.          2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
  94.         14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
  95.          4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
  96.         11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,

  97.         /* S6 */
  98.         12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
  99.         10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
  100.          9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
  101.          4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,

  102.         /* S7 */
  103.          4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
  104.         13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
  105.          1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
  106.          6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,

  107.         /* S8 */
  108.         13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
  109.          1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
  110.          7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
  111.          2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11
  112. };

  113. /* 32-bit permutation function P used on the output of the S-boxes */
  114. static char p32i[] = {  
  115.         16,  7, 20, 21,
  116.         29, 12, 28, 17,
  117.          1, 15, 23, 26,
  118.          5, 18, 31, 10,
  119.          2,  8, 24, 14,
  120.         32, 27,  3,  9,
  121.         19, 13, 30,  6,
  122.         22, 11,  4, 25
  123. };
  124. /* End of DES-defined tables */

  125. /* Lookup tables initialized once only at startup by desinit() */
  126. static long (*sp)[64];          /* Combined S and P boxes */

  127. static char (*iperm)[16][8];    /* Initial and final permutations */
  128. static char (*fperm)[16][8];

  129. /* 8 6-bit subkeys for each of 16 rounds, initialized by setkey() */
  130. static unsigned char (*kn)[8];

  131. /* bit 0 is left-most in byte */
  132. static int bytebit[] = {
  133.         0200,0100,040,020,010,04,02,01
  134. };

  135. static int nibblebit[] = {
  136.          010,04,02,01
  137. };
  138. static int desmode;

  139. /* Allocate space and initialize DES lookup arrays
  140. * mode == 0: standard Data Encryption Algorithm
  141. * mode == 1: DEA without initial and final permutations for speed
  142. * mode == 2: DEA without permutations and with 128-byte key (completely
  143. *            independent subkeys for each round)
  144. */
  145. desinit(mode)
  146. int mode;
  147. {
  148.         char *malloc();

  149.         if(sp != NULL){
  150.                 /* Already initialized */
  151.                 return 0;
  152.         }
  153.         desmode = mode;
  154.         
  155.         if((sp = (long (*)[64])malloc(sizeof(long) * 8 * 64)) == NULL){
  156.                 return -1;
  157.         }
  158.         spinit();
  159.         kn = (unsigned char (*)[8])malloc(sizeof(char) * 8 * 16);
  160.         if(kn == NULL){
  161.                 free((char *)sp);
  162.                 return -1;
  163.         }
  164.         if(mode == 1 || mode == 2)      /* No permutations */
  165.                 return 0;

  166.         iperm = (char (*)[16][8])malloc(sizeof(char) * 16 * 16 * 8);
  167.         if(iperm == NULL){
  168.                 free((char *)sp);
  169.                 free((char *)kn);
  170.                 return -1;
  171.         }
  172.         perminit(iperm,ip);

  173.         fperm = (char (*)[16][8])malloc(sizeof(char) * 16 * 16 * 8);
  174.         if(fperm == NULL){
  175.                 free((char *)sp);
  176.                 free((char *)kn);
  177.                 free((char *)iperm);
  178.                 return -1;
  179.         }
  180.         perminit(fperm,fp);
  181.         
  182.         return 0;
  183. }
  184. /* Free up storage used by DES */
  185. desdone()
  186. {
  187.         if(sp == NULL)
  188.                 return; /* Already done */

  189.         free((char *)sp);
  190.         free((char *)kn);
  191.         if(iperm != NULL)
  192.                 free((char *)iperm);
  193.         if(fperm != NULL)
  194.                 free((char *)fperm);

  195.         sp = NULL;
  196.         iperm = NULL;
  197.         fperm = NULL;
  198.         kn = NULL;
  199. }
  200. /* Set key (initialize key schedule array) */
  201. setkey(key)
  202. char *key;                      /* 64 bits (will use only 56) */
  203. {
  204.         char pc1m[56];          /* place to modify pc1 into */
  205.         char pcr[56];           /* place to rotate pc1 into */
  206.         register int i,j,l;
  207.         int m;

  208.         /* In mode 2, the 128 bytes of subkey are set directly from the
  209.          * user's key, allowing him to use completely independent
  210.          * subkeys for each round. Note that the user MUST specify a
  211.          * full 128 bytes.
  212.          *
  213.          * I would like to think that this technique gives the NSA a real
  214.          * headache, but I'm not THAT naive.
  215.          */
  216.         if(desmode == 2){
  217.                 for(i=0;i<16;i++)
  218.                         for(j=0;j<8;j++)
  219.                                 kn[i][j] = *key++;
  220.                 return;
  221.         }
  222.         /* Clear key schedule */
  223.         for (i=0; i<16; i++)
  224.                 for (j=0; j<8; j++)
  225.                         kn[i][j]=0;

  226.         for (j=0; j<56; j++) {          /* convert pc1 to bits of key */
  227.                 l=pc1[j]-1;             /* integer bit location  */
  228.                 m = l & 07;             /* find bit              */
  229.                 pc1m[j]=(key[l>;>;3] &    /* find which key byte l is in */
  230.                         bytebit[m])     /* and which bit of that byte */
  231.                         ? 1 : 0;        /* and store 1-bit result */
  232.         }
  233.         for (i=0; i<16; i++) {          /* key chunk for each iteration */
  234.                 for (j=0; j<56; j++)    /* rotate pc1 the right amount */
  235.                         pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
  236.                         /* rotate left and right halves independently */
  237.                 for (j=0; j<48; j++){   /* select bits individually */
  238.                         /* check bit that goes to kn[j] */
  239.                         if (pcr[pc2[j]-1]){
  240.                                 /* mask it in if it's there */
  241.                                 l= j % 6;
  242.                                 kn[i][j/6] |= bytebit[l] >;>; 2;
  243.                         }
  244.                 }
  245.         }
  246. }
  247. /* In-place encryption of 64-bit block */
  248. endes(block)
  249. char *block;
  250. {
  251.         register int i;
  252.         unsigned long work[2];          /* Working data storage */
  253.         long tmp;

  254.         permute(block,iperm,(char *)work);      /* Initial Permutation */
  255. #ifdef LITTLE_ENDIAN
  256.         work[0] = byteswap(work[0]);
  257.         work[1] = byteswap(work[1]);
  258. #endif

  259.         /* Do the 16 rounds */
  260.         for (i=0; i<16; i++)
  261.                 round(i,work);

  262.         /* Left/right half swap */
  263.         tmp = work[0];
  264.         work[0] = work[1];      
  265.         work[1] = tmp;

  266. #ifdef LITTLE_ENDIAN
  267.         work[0] = byteswap(work[0]);
  268.         work[1] = byteswap(work[1]);
  269. #endif
  270.         permute((char *)work,fperm,block);      /* Inverse initial permutation */
  271. }
  272. /* In-place decryption of 64-bit block */
  273. dedes(block)
  274. char *block;
  275. {
  276.         register int i;
  277.         unsigned long work[2];  /* Working data storage */
  278.         long tmp;

  279.         permute(block,iperm,(char *)work);      /* Initial permutation */

  280. #ifdef LITTLE_ENDIAN
  281.         work[0] = byteswap(work[0]);
  282.         work[1] = byteswap(work[1]);
  283. #endif

  284.         /* Left/right half swap */
  285.         tmp = work[0];
  286.         work[0] = work[1];      
  287.         work[1] = tmp;

  288.         /* Do the 16 rounds in reverse order */
  289.         for (i=15; i >;= 0; i--)
  290.                 round(i,work);

  291. #ifdef LITTLE_ENDIAN
  292.         work[0] = byteswap(work[0]);
  293.         work[1] = byteswap(work[1]);
  294. #endif

  295.         permute((char *)work,fperm,block);      /* Inverse initial permutation */
  296. }

  297. /* Permute inblock with perm */
  298. static
  299. permute(inblock,perm,outblock)
  300. char *inblock, *outblock;               /* result into outblock,64 bits */
  301. char perm[16][16][8];                   /* 2K bytes defining perm. */
  302. {
  303.         register int i,j;
  304.         register char *ib, *ob;         /* ptr to input or output block */
  305.         register char *p, *q;

  306.         if(perm == NULL){
  307.                 /* No permutation, just copy */
  308.                 for(i=8; i!=0; i--)
  309.                         *outblock++ = *inblock++;
  310.                 return;
  311.         }
  312.         /* Clear output block    */
  313.         for (i=8, ob = outblock; i != 0; i--)
  314.                 *ob++ = 0;

  315.         ib = inblock;
  316.         for (j = 0; j < 16; j += 2, ib++) { /* for each input nibble */
  317.                 ob = outblock;
  318.                 p = perm[j][(*ib >;>; 4) & 017];
  319.                 q = perm[j + 1][*ib & 017];
  320.                 for (i = 8; i != 0; i--){   /* and each output byte */
  321.                         *ob++ |= *p++ | *q++;   /* OR the masks together*/
  322.                 }
  323.         }
  324. }

  325. /* Do one DES cipher round */
  326. static
  327. round(num,block)
  328. int num;                                /* i.e. the num-th one   */
  329. unsigned long *block;
  330. {
  331.         long f();

  332.         /* The rounds are numbered from 0 to 15. On even rounds
  333.          * the right half is fed to f() and the result exclusive-ORs
  334.          * the left half; on odd rounds the reverse is done.
  335.          */
  336.         if(num & 1){
  337.                 block[1] ^= f(block[0],kn[num]);
  338.         } else {
  339.                 block[0] ^= f(block[1],kn[num]);
  340.         }
  341. }
  342. /* The nonlinear function f(r,k), the heart of DES */
  343. static
  344. long
  345. f(r,subkey)
  346. unsigned long r;                /* 32 bits */
  347. unsigned char subkey[8];        /* 48-bit key for this round */
  348. {
  349.         register unsigned long rval,rt;
  350. #ifdef  TRACE
  351.         unsigned char *cp;
  352.         int i;

  353.         printf("f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ",
  354.                 r,
  355.                 subkey[0], subkey[1], subkey[2],
  356.                 subkey[3], subkey[4], subkey[5],
  357.                 subkey[6], subkey[7]);
  358. #endif
  359.         /* Run E(R) ^ K through the combined S & P boxes
  360.          * This code takes advantage of a convenient regularity in
  361.          * E, namely that each group of 6 bits in E(R) feeding
  362.          * a single S-box is a contiguous segment of R.
  363.          */
  364.         rt = (r >;>; 1) | ((r & 1) ? 0x80000000 : 0);
  365.         rval = 0;
  366.         rval |= sp[0][((rt >;>; 26) ^ *subkey++) & 0x3f];
  367.         rval |= sp[1][((rt >;>; 22) ^ *subkey++) & 0x3f];
  368.         rval |= sp[2][((rt >;>; 18) ^ *subkey++) & 0x3f];
  369.         rval |= sp[3][((rt >;>; 14) ^ *subkey++) & 0x3f];
  370.         rval |= sp[4][((rt >;>; 10) ^ *subkey++) & 0x3f];
  371.         rval |= sp[5][((rt >;>; 6) ^ *subkey++) & 0x3f];
  372.         rval |= sp[6][((rt >;>; 2) ^ *subkey++) & 0x3f];
  373.         rt = (r << 1) | ((r & 0x80000000) ? 1 : 0);
  374.         rval |= sp[7][(rt ^ *subkey) & 0x3f];
  375. #ifdef  TRACE
  376.         printf(" %08lx\n",rval);
  377. #endif
  378.         return rval;
  379. }
  380. /* initialize a perm array */
  381. static
  382. perminit(perm,p)
  383. char perm[16][16][8];                   /* 64-bit, either init or final */
  384. char p[64];
  385. {
  386.         register int l, j, k;
  387.         int i,m;

  388.         /* Clear the permutation array */
  389.         for (i=0; i<16; i++)
  390.                 for (j=0; j<16; j++)
  391.                         for (k=0; k<8; k++)
  392.                                 perm[i][j][k]=0;

  393.         for (i=0; i<16; i++)            /* each input nibble position */
  394.                 for (j = 0; j < 16; j++)/* each possible input nibble */
  395.                 for (k = 0; k < 64; k++)/* each output bit position */
  396.                 {   l = p[k] - 1;       /* where does this bit come from*/
  397.                         if ((l >;>; 2) != i)  /* does it come from input posn?*/
  398.                         continue;       /* if not, bit k is 0    */
  399.                         if (!(j & nibblebit[l & 3]))
  400.                         continue;       /* any such bit in input? */
  401.                         m = k & 07;     /* which bit is this in the byte*/
  402.                         perm[i][j][k>;>;3] |= bytebit[m];
  403.                 }
  404. }

  405. /* Initialize the lookup table for the combined S and P boxes */
  406. static int
  407. spinit()
  408. {
  409.         char pbox[32];
  410.         int p,i,s,j,rowcol;
  411.         long val;

  412.         /* Compute pbox, the inverse of p32i.
  413.          * This is easier to work with
  414.          */
  415.         for(p=0;p<32;p++){
  416.                 for(i=0;i<32;i++){
  417.                         if(p32i[i]-1 == p){
  418.                                 pbox[p] = i;
  419.                                 break;
  420.                         }
  421.                 }
  422.         }
  423.         for(s = 0; s < 8; s++){                 /* For each S-box */
  424.                 for(i=0; i<64; i++){            /* For each possible input */
  425.                         val = 0;
  426.                         /* The row number is formed from the first and last
  427.                          * bits; the column number is from the middle 4
  428.                          */
  429.                         rowcol = (i & 32) | ((i & 1) ? 16 : 0) | ((i >;>; 1) & 0xf);
  430.                         for(j=0;j<4;j++){       /* For each output bit */
  431.                                 if(si[s][rowcol] & (8 >;>; j)){
  432.                                  val |= 1L << (31 - pbox[4*s + j]);
  433.                                 }
  434.                         }
  435.                         sp[s][i] = val;

  436. #ifdef  DEBUG
  437.                         printf("sp[%d][%2d] = %08lx\n",s,i,sp[s][i]);
  438. #endif
  439.                 }
  440.         }
  441. }
  442. #ifdef  LITTLE_ENDIAN
  443. /* Byte swap a long */
  444. static
  445. unsigned long
  446. byteswap(x)
  447. unsigned long x;
  448. {
  449.         register char *cp,tmp;

  450.         cp = (char *)&
  451.         tmp = cp[3];
  452.         cp[3] = cp[0];
  453.         cp[0] = tmp;

  454.         tmp = cp[2];
  455.         cp[2] = cp[1];
  456.         cp[1] = tmp;

  457.         return x;
  458. }
  459. #endif
复制代码

读起来比较头痛,看了后不知道它提到的3种MODE分别怎么理解?DES一般来说有4种加密模式:ECB CBC CFB OFB,那这里的0-2三种模式和4种加密模式有什么区别呢,哪位大虾帮忙解释下,最好能大概注解下程序,那就感谢不尽了:)

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2003-11-18 16:15 |只看该作者

DES函数

没研究过。

crypt使用des加密的。

openssl也用到了des。

这两个所属的软件包应该包含des算法的源代码。

论坛徽章:
0
3 [报告]
发表于 2003-11-26 09:06 |只看该作者

DES函数

粗略地看了一下,desmode=2应该是指双重DES,除了ECB、CBC之类的分类外,还有单重DES、双重DES、三重DES的区分
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP