home *** CD-ROM | disk | FTP | other *** search
/ PCMania 10 / Pcmania_Ep2_10_CD-01.iso / ARTICULOS / tecnologia / DLOCK2.ZIP / DIAMOND2.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-21  |  15.4 KB  |  425 lines

  1. /* diamond2.c - Encryption designed to exceed DES in security.
  2.    This file and the Diamond2 and Diamond2 Lite Block Ciphers
  3.    described herein are hereby dedicated to the Public Domain by the
  4.    author and inventor, Michael Paul Johnson.  Feel free to use these
  5.    for any purpose that is legally and morally right.  The names
  6.    "Diamond2 Block Cipher" and "Diamond2 Lite Block Cipher" should only
  7.    be used to describe the algorithms described in this file, to avoid
  8.    confusion.
  9.  
  10.    Disclaimers:  the following comes with no warranty, expressed or
  11.    implied.  You, the user, must determine the suitability of this
  12.    information to your own uses.  You must also find out what legal
  13.    requirements exist with respect to this data and programs using
  14.    it, and comply with whatever valid requirements exist.
  15. */
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #ifdef UNIX
  19. #include <memory.h>
  20. #else
  21. #include <mem.h>
  22. #endif
  23. #include "def.h"
  24. #include "diamond2.h"
  25. #include "crc.h"
  26.  
  27. static byte *key = NULL;
  28. static uint keysize;
  29. static uint keyindex;
  30. static uint roundsize;          /* Number of bytes in one round of substitution boxes. */
  31. static int blocksize;           /* Number of bytes in a block. */
  32. static unsigned long accum;
  33. static uint numrounds;
  34. static byte *s = NULL;             /* Substitution boxes. */
  35. static byte *si = NULL;            /* Inverse substitution boxes. */
  36.  
  37. static uint keyrand(uint max_value, byte *sbox)    /* Returns uniformly distributed pseudorandom */
  38.     {                           /* value based on key[], sized keysize */
  39.     uint prandvalue, i;        /* Change from Diamond to Diamond 2: use of */
  40.     unsigned long mask;        /* sbox (previous 256-byte permutation array)*/
  41.     
  42.     if (!max_value) return 0;
  43.     mask = 0L;              /* Create a mask to get the minimum */
  44.     for (i=max_value; i > 0; i = i >> 1)    /* number of bits to cover the */
  45.         mask = (mask << 1) | 1L;        /* range 0 to max_value. */
  46.     i=0;
  47.     do
  48.         {
  49.     if (sbox)
  50.         accum = crc32(accum, sbox[key[keyindex++]]);
  51.     else
  52.         accum = crc32(accum, key[keyindex++]);
  53.         if (keyindex >= keysize)
  54.             {
  55.             keyindex = 0;   /* Recycle thru the key */
  56.             accum = crc32(accum, (keysize & 0xFF));
  57.             accum = crc32(accum, ((keysize >> 8) & 0xFF));
  58.             }
  59.         prandvalue = (uint) (accum & mask);
  60.         if ((++i>97) && (prandvalue > max_value))   /* Don't loop forever. */
  61.             prandvalue -= max_value;                /* Introduce negligible bias. */
  62.         }
  63.     while (prandvalue > max_value); /* Discard out of range values. */
  64.     return prandvalue;
  65.     }
  66.  
  67. static void makeonebox(uint i, uint j, byte *sbox)
  68.     {    /* Change from Diamond to Diamond 2: use of sbox. */
  69.         /* sbox is either NULL or a pointer to the previously filled array. */
  70.     int n;
  71.     uint pos, m, p;
  72.     boolean filled[256];
  73.  
  74.     for (m = 0; m < 256; m++)   /* The filled array is used to make sure that */
  75.         filled[m] = false;      /* each byte of the array is filled only once. */
  76.     for (n = 255; n >= 0 ; n--) /* n counts the number of bytes left to fill */
  77.         {
  78.         pos = keyrand(n, sbox); /* pos is the position among the UNFILLED */
  79.                                 /* components of the s array that the */
  80.                                 /* number n should be placed.  */
  81.         p=0;
  82.         while (filled[p]) p++;
  83.         for (m=0; m<pos; m++)
  84.             {
  85.             p++;
  86.             while (filled[p]) p++;
  87.             }
  88.         *(s + (roundsize*i) + (256*j) + p) = n;
  89.         filled[p] = true;
  90.         }
  91.     }
  92.  
  93. void set_diamond2_key(byte *external_key, uint key_size, uint rounds,
  94.     boolean invert, int block_size)
  95. /* This procedure generates internal keys by filling the substitution box array
  96.   s based on the external key given as input.  It DOES take a bit of time. */
  97.   {
  98.     uint i, j, k;
  99.     byte *sbox;
  100.  
  101.     if (s) diamond2_done();
  102.     numrounds = rounds;
  103.     if (block_size == 8)
  104.         {
  105.         blocksize = 8;
  106.         roundsize = 2048U;
  107.         if (numrounds < 3)
  108.             {
  109.             puts("Numrounds out of range in set_diamond2_key()");
  110.             exit(10);
  111.             }
  112.         }
  113.     else if (block_size == 16)
  114.         {
  115.         blocksize = 16;
  116.         roundsize = 4096U;
  117.         if (numrounds < 5)
  118.             {
  119.             puts("Numrounds out of range in set_diamond2_key()");
  120.             exit(10);
  121.             }
  122.         }
  123.     else
  124.         {
  125.         puts("Unsupported block size in set_diamond2_key()");
  126.         exit(11);
  127.         }
  128.  
  129.     if ((numrounds * blocksize) > 255)
  130.         {
  131.         puts("Numrounds out of range in set_diamond2_key()");
  132.         exit(10);
  133.         }
  134.     if (BuildCRCTable())
  135.         {
  136.         puts("Not enough memory.");
  137.         exit(5);
  138.         }
  139.     s=(byte *) malloc(numrounds * roundsize);
  140.     if (!s)
  141.         {
  142.         puts("Out of memory.");
  143.         exit(5);
  144.         }
  145.     key = external_key;
  146.     keysize = key_size;
  147.     keyindex = 0;
  148.     accum = 0xFFFFFFFFL;
  149.  
  150.     sbox = NULL;
  151.     for (i = 0; i < numrounds; i++)
  152.         {
  153.         for (j = 0; j < blocksize; j++)
  154.             {
  155.             makeonebox(i, j, sbox);
  156.             sbox = s + ((roundsize * i) + (256 * j));
  157.             }
  158.         }
  159.     if (invert)
  160.         {   /* Fill the inverse substitution box array si.  It is not
  161.                necessary to do this unless the decryption mode is used.  */
  162.         si=(byte *) malloc(numrounds * roundsize);
  163.         if (!si)
  164.             {
  165.             puts("Out of memory.");
  166.             exit(5);
  167.             }
  168.         for (i = 0; i < numrounds; i++)
  169.             {
  170.             for (j = 0; j < blocksize; j++)
  171.                 {
  172.                 for (k = 0; k < 256; k++)
  173.                     {
  174.                     *(si + (roundsize * i) + (256 * j) + *(s + (roundsize * i) + (256 * j) + k)) = k;
  175.                     }
  176.                 }
  177.             }
  178.         }
  179.     }
  180.  
  181. static void permute(byte *x, byte *y)   /* x and y must be different.
  182.   This procedure is designed to make each bit of the output dependent on as
  183.   many bytes of the input as possible, especially after repeated application.
  184.   Each output byte takes its least significant bit from the corresponding
  185.   input byte.  The next higher bit comes from the corresponding bit of the
  186.   next higher input byte.  This is done until all bits of the output byte
  187.   are filled.
  188. */
  189.     {
  190.     y[0] = (x[0] & 1) | (x[1] & 2) | (x[2] & 4) |
  191.             (x[3] & 8) | (x[4] & 16) | (x[5] & 32) |
  192.             (x[6] & 64) | (x[7] & 128);
  193.     y[1] = (x[1] & 1) | (x[2] & 2) | (x[3] & 4) |
  194.             (x[4] & 8) | (x[5] & 16) | (x[6] & 32) |
  195.             (x[7] & 64) | (x[8] & 128);
  196.     y[2] = (x[2] & 1) | (x[3] & 2) | (x[4] & 4) |
  197.             (x[5] & 8) | (x[6] & 16) | (x[7] & 32) |
  198.             (x[8] & 64) | (x[9] & 128);
  199.     y[3] = (x[3] & 1) | (x[4] & 2) | (x[5] & 4) |
  200.             (x[6] & 8) | (x[7] & 16) | (x[8] & 32) |
  201.             (x[9] & 64) | (x[10] & 128);
  202.     y[4] = (x[4] & 1) | (x[5] & 2) | (x[6] & 4) |
  203.             (x[7] & 8) | (x[8] & 16) | (x[9] & 32) |
  204.             (x[10] & 64) | (x[11] & 128);
  205.     y[5] = (x[5] & 1) | (x[6] & 2) | (x[7] & 4) |
  206.             (x[8] & 8) | (x[9] & 16) | (x[10] & 32) |
  207.             (x[11] & 64) | (x[12] & 128);
  208.     y[6] = (x[6] & 1) | (x[7] & 2) | (x[8] & 4) |
  209.             (x[9] & 8) | (x[10] & 16) | (x[11] & 32) |
  210.             (x[12] & 64) | (x[13] & 128);
  211.     y[7] = (x[7] & 1) | (x[8] & 2) | (x[9] & 4) |
  212.             (x[10] & 8) | (x[11] & 16) | (x[12] & 32) |
  213.             (x[13] & 64) | (x[14] & 128);
  214.     y[8] = (x[8] & 1) | (x[9] & 2) | (x[10] & 4) |
  215.             (x[11] & 8) | (x[12] & 16) | (x[13] & 32) |
  216.             (x[14] & 64) | (x[15] & 128);
  217.     y[9] = (x[9] & 1) | (x[10] & 2) | (x[11] & 4) |
  218.             (x[12] & 8) | (x[13] & 16) | (x[14] & 32) |
  219.             (x[15] & 64) | (x[0] & 128);
  220.     y[10] = (x[10] & 1) | (x[11] & 2) | (x[12] & 4) |
  221.             (x[13] & 8) | (x[14] & 16) | (x[15] & 32) |
  222.             (x[0] & 64) | (x[1] & 128);
  223.     y[11] = (x[11] & 1) | (x[12] & 2) | (x[13] & 4) |
  224.             (x[14] & 8) | (x[15] & 16) | (x[0] & 32) |
  225.             (x[1] & 64) | (x[2] & 128);
  226.     y[12] = (x[12] & 1) | (x[13] & 2) | (x[14] & 4) |
  227.             (x[15] & 8) | (x[0] & 16) | (x[1] & 32) |
  228.             (x[2] & 64) | (x[3] & 128);
  229.     y[13] = (x[13] & 1) | (x[14] & 2) | (x[15] & 4) |
  230.             (x[0] & 8) | (x[1] & 16) | (x[2] & 32) |
  231.             (x[3] & 64) | (x[4] & 128);
  232.     y[14] = (x[14] & 1) | (x[15] & 2) | (x[0] & 4) |
  233.             (x[1] & 8) | (x[2] & 16) | (x[3] & 32) |
  234.             (x[4] & 64) | (x[5] & 128);
  235.     y[15] = (x[15] & 1) | (x[0] & 2) | (x[1] & 4) |
  236.             (x[2] & 8) | (x[3] & 16) | (x[4] & 32) |
  237.             (x[5] & 64) | (x[6] & 128);
  238.     }
  239.  
  240. static void ipermute(byte *x, byte *y) /* x!=y */
  241. /* This is the inverse of the procedure permute. */
  242.     {
  243.     y[0] = (x[0] & 1) | (x[15] & 2) | (x[14] & 4) |
  244.             (x[13] & 8) | (x[12] & 16) | (x[11] & 32) |
  245.             (x[10] & 64) | (x[9] & 128);
  246.     y[1] = (x[1] & 1) | (x[0] & 2) | (x[15] & 4) |
  247.             (x[14] & 8) | (x[13] & 16) | (x[12] & 32) |
  248.             (x[11] & 64) | (x[10] & 128);
  249.     y[2] = (x[2] & 1) | (x[1] & 2) | (x[0] & 4) |
  250.             (x[15] & 8) | (x[14] & 16) | (x[13] & 32) |
  251.             (x[12] & 64) | (x[11] & 128);
  252.     y[3] = (x[3] & 1) | (x[2] & 2) | (x[1] & 4) |
  253.             (x[0] & 8) | (x[15] & 16) | (x[14] & 32) |
  254.             (x[13] & 64) | (x[12] & 128);
  255.     y[4] = (x[4] & 1) | (x[3] & 2) | (x[2] & 4) |
  256.             (x[1] & 8) | (x[0] & 16) | (x[15] & 32) |
  257.             (x[14] & 64) | (x[13] & 128);
  258.     y[5] = (x[5] & 1) | (x[4] & 2) | (x[3] & 4) |
  259.             (x[2] & 8) | (x[1] & 16) | (x[0] & 32) |
  260.             (x[15] & 64) | (x[14] & 128);
  261.     y[6] = (x[6] & 1) | (x[5] & 2) | (x[4] & 4) |
  262.             (x[3] & 8) | (x[2] & 16) | (x[1] & 32) |
  263.             (x[0] & 64) | (x[15] & 128);
  264.     y[7] = (x[7] & 1) | (x[6] & 2) | (x[5] & 4) |
  265.             (x[4] & 8) | (x[3] & 16) | (x[2] & 32) |
  266.             (x[1] & 64) | (x[0] & 128);
  267.     y[8] = (x[8] & 1) | (x[7] & 2) | (x[6] & 4) |
  268.             (x[5] & 8) | (x[4] & 16) | (x[3] & 32) |
  269.             (x[2] & 64) | (x[1] & 128);
  270.     y[9] = (x[9] & 1) | (x[8] & 2) | (x[7] & 4) |
  271.             (x[6] & 8) | (x[5] & 16) | (x[4] & 32) |
  272.             (x[3] & 64) | (x[2] & 128);
  273.     y[10] = (x[10] & 1) | (x[9] & 2) | (x[8] & 4) |
  274.             (x[7] & 8) | (x[6] & 16) | (x[5] & 32) |
  275.             (x[4] & 64) | (x[3] & 128);
  276.     y[11] = (x[11] & 1) | (x[10] & 2) | (x[9] & 4) |
  277.             (x[8] & 8) | (x[7] & 16) | (x[6] & 32) |
  278.             (x[5] & 64) | (x[4] & 128);
  279.     y[12] = (x[12] & 1) | (x[11] & 2) | (x[10] & 4) |
  280.             (x[9] & 8) | (x[8] & 16) | (x[7] & 32) |
  281.             (x[6] & 64) | (x[5] & 128);
  282.     y[13] = (x[13] & 1) | (x[12] & 2) | (x[11] & 4) |
  283.             (x[10] & 8) | (x[9] & 16) | (x[8] & 32) |
  284.             (x[7] & 64) | (x[6] & 128);
  285.     y[14] = (x[14] & 1) | (x[13] & 2) | (x[12] & 4) |
  286.             (x[11] & 8) | (x[10] & 16) | (x[9] & 32) |
  287.             (x[8] & 64) | (x[7] & 128);
  288.     y[15] = (x[15] & 1) | (x[14] & 2) | (x[13] & 4) |
  289.             (x[12] & 8) | (x[11] & 16) | (x[10] & 32) |
  290.             (x[9] & 64) | (x[8] & 128);
  291.     }
  292.  
  293. static void CALLTYPE permute_lite2(byte *a, byte *b)
  294.   {
  295. /* This procedure is designed to make each bit of the output dependent on as
  296.   many bytes of the input as possible, especially after repeated application.
  297. */
  298.     b[0] = (a[0] & 1) + (a[1] & 2) + (a[2] & 4) + (a[3] & 8) + (a[4] & 0x10) +
  299.         (a[5] & 0x20) + (a[6] & 0x40) + (a[7] & 0x80);
  300.     b[1] = (a[1] & 1) + (a[2] & 2) + (a[3] & 4) + (a[4] & 8) + (a[5] & 0x10) +
  301.         (a[6] & 0x20) + (a[7] & 0x40) + (a[0] & 0x80);
  302.     b[2] = (a[2] & 1) + (a[3] & 2) + (a[4] & 4) + (a[5] & 8) + (a[6] & 0x10) +
  303.         (a[7] & 0x20) + (a[0] & 0x40) + (a[1] & 0x80);
  304.     b[3] = (a[3] & 1) + (a[4] & 2) + (a[5] & 4) + (a[6] & 8) + (a[7] & 0x10) +
  305.         (a[0] & 0x20) + (a[1] & 0x40) + (a[2] & 0x80);
  306.     b[4] = (a[4] & 1) + (a[5] & 2) + (a[6] & 4) + (a[7] & 8) + (a[0] & 0x10) +
  307.         (a[1] & 0x20) + (a[2] & 0x40) + (a[3] & 0x80);
  308.     b[5] = (a[5] & 1) + (a[6] & 2) + (a[7] & 4) + (a[0] & 8) + (a[1] & 0x10) +
  309.         (a[2] & 0x20) + (a[3] & 0x40) + (a[4] & 0x80);
  310.     b[6] = (a[6] & 1) + (a[7] & 2) + (a[0] & 4) + (a[1] & 8) + (a[2] & 0x10) +
  311.         (a[3] & 0x20) + (a[4] & 0x40) + (a[5] & 0x80);
  312.     b[7] = (a[7] & 1) + (a[0] & 2) + (a[1] & 4) + (a[2] & 8) + (a[3] & 0x10) +
  313.         (a[4] & 0x20) + (a[5] & 0x40) + (a[6] & 0x80);
  314.   }
  315.  
  316. static void CALLTYPE ipermute_lite2(byte *b, byte *a)
  317.   {
  318. /* This is the inverse of the procedure permute. */
  319.     a[0] = (b[0] & 1) + (b[7] & 2) + (b[6] & 4) + (b[5] & 8) + (b[4] & 0x10) +
  320.         (b[3] & 0x20) + (b[2] & 0x40) + (b[1] & 0x80);
  321.     a[1] = (b[1] & 1) + (b[0] & 2) + (b[7] & 4) + (b[6] & 8) + (b[5] & 0x10) +
  322.         (b[4] & 0x20) + (b[3] & 0x40) + (b[2] & 0x80);
  323.     a[2] = (b[2] & 1) + (b[1] & 2) + (b[0] & 4) + (b[7] & 8) + (b[6] & 0x10) +
  324.         (b[5] & 0x20) + (b[4] & 0x40) + (b[3] & 0x80);
  325.     a[3] = (b[3] & 1) + (b[2] & 2) + (b[1] & 4) + (b[0] & 8) + (b[7] & 0x10) +
  326.         (b[6] & 0x20) + (b[5] & 0x40) + (b[4] & 0x80);
  327.     a[4] = (b[4] & 1) + (b[3] & 2) + (b[2] & 4) + (b[1] & 8) + (b[0] & 0x10) +
  328.         (b[7] & 0x20) + (b[6] & 0x40) + (b[5] & 0x80);
  329.     a[5] = (b[5] & 1) + (b[4] & 2) + (b[3] & 4) + (b[2] & 8) + (b[1] & 0x10) +
  330.         (b[0] & 0x20) + (b[7] & 0x40) + (b[6] & 0x80);
  331.     a[6] = (b[6] & 1) + (b[5] & 2) + (b[4] & 4) + (b[3] & 8) + (b[2] & 0x10) +
  332.         (b[1] & 0x20) + (b[0] & 0x40) + (b[7] & 0x80);
  333.     a[7] = (b[7] & 1) + (b[6] & 2) + (b[5] & 4) + (b[4] & 8) + (b[3] & 0x10) +
  334.         (b[2] & 0x20) + (b[1] & 0x40) + (b[0] & 0x80);
  335.   }
  336.  
  337. static void substitute(uint round, byte *x, byte *y)
  338.     {
  339.     uint i;
  340.  
  341.     for (i = 0; i < blocksize; i++)
  342.         y[i] = *(s + (roundsize*round) + (256*i) + x[i]);
  343.     }
  344.  
  345. static void isubst(uint round, byte *x, byte *y)
  346.     {
  347.     uint i;
  348.  
  349.     for (i = 0; i < blocksize; i++)
  350.         y[i] = *(si + (roundsize*round) + (256*i) + x[i]);
  351.     }
  352.  
  353. void diamond2_encrypt_block(byte *x, byte *y)
  354. /* Encrypt a block of 16 bytes. */
  355.     {
  356.     uint round;
  357.     byte z[16];
  358.  
  359.     substitute(0, x, y);
  360.     for (round=1; round < numrounds; round++)
  361.         {
  362.         permute(y, z);
  363.         substitute(round, z, y);
  364.         }
  365.     }
  366.  
  367. void diamond2_decrypt_block(byte *x, byte *y)
  368. /* Decrypt a block of 16 bytes. */
  369.     {
  370.     int round;
  371.     byte z[16];
  372.     
  373.     isubst(numrounds-1, x, y);
  374.     for (round=numrounds-2; round >= 0; round--)
  375.         {
  376.         ipermute(y, z);
  377.         isubst(round, z, y);
  378.         }
  379.     }
  380.  
  381. void lite2_encrypt_block(byte *x, byte *y)
  382. /* Encrypt a block of 16 bytes. */
  383.     {
  384.     uint round;
  385.     byte z[16];
  386.  
  387.     substitute(0, x, y);
  388.     for (round=1; round < numrounds; round++)
  389.         {
  390.         permute_lite2(y, z);
  391.         substitute(round, z, y);
  392.         }
  393.     }
  394.  
  395. void lite2_decrypt_block(byte *x, byte *y)
  396. /* Decrypt a block of 8 bytes. */
  397.     {
  398.     int round;
  399.     byte z[8];
  400.     
  401.     isubst(numrounds-1, x, y);
  402.     for (round=numrounds-2; round >= 0; round--)
  403.         {
  404.         ipermute_lite2(y, z);
  405.         isubst(round, z, y);
  406.         }
  407.     }
  408.  
  409. void diamond2_done(void)
  410.     {
  411.     if (s)
  412.         {
  413.         memset(s, 0, numrounds * roundsize);
  414.         free((char *)s);
  415.         s=NULL;
  416.         }
  417.     if (si)
  418.         {
  419.         memset(si, 0, numrounds * roundsize);
  420.         free((char *)si);
  421.         si=NULL;
  422.         }
  423.     }
  424.  
  425.