"Fossies" - the Fresh Open Source Software Archive

Member "libmcrypt-2.5.8/modules/algorithms/3-way.c" (19 Jan 2003, 7447 Bytes) of package /linux/privat/old/libmcrypt-2.5.8.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "3-way.c" see the Fossies "Dox" file reference documentation.

    1 /********************************************************************\
    2 *                                                                    *
    3 * C specification of the threeway block cipher                       *
    4 *                                                                    *
    5 * found in ftp://ftp.funet.fi/pub/crypt/                             *
    6 \********************************************************************/
    7 
    8 /* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos 
    9  * All modifications are placed under the license of libmcrypt.
   10  */
   11 
   12 /* $Id: 3-way.c,v 1.12 2003/01/19 17:48:27 nmav Exp $ */
   13 
   14 #include <libdefs.h>
   15 
   16 #include <mcrypt_modules.h>
   17 #include "3-way.h"
   18 
   19 #define   STRT_E   0x0b0b   /* round constant of first encryption round */
   20 #define   STRT_D   0xb1b1   /* round constant of first decryption round */
   21 #define     NMBR       11   /* number of rounds is 11                   */
   22 
   23 #define _mcrypt_set_key threeway_LTX__mcrypt_set_key
   24 #define _mcrypt_encrypt threeway_LTX__mcrypt_encrypt
   25 #define _mcrypt_decrypt threeway_LTX__mcrypt_decrypt
   26 #define _mcrypt_get_size threeway_LTX__mcrypt_get_size
   27 #define _mcrypt_get_block_size threeway_LTX__mcrypt_get_block_size
   28 #define _is_block_algorithm threeway_LTX__is_block_algorithm
   29 #define _mcrypt_get_key_size threeway_LTX__mcrypt_get_key_size
   30 #define _mcrypt_get_supported_key_sizes threeway_LTX__mcrypt_get_supported_key_sizes
   31 #define _mcrypt_get_algorithms_name threeway_LTX__mcrypt_get_algorithms_name
   32 #define _mcrypt_self_test threeway_LTX__mcrypt_self_test
   33 #define _mcrypt_algorithm_version threeway_LTX__mcrypt_algorithm_version
   34 
   35 WIN32DLL_DEFINE
   36     int _mcrypt_set_key(word32 * k, word32 * input_key, int len)
   37 {
   38     k[0] = 0;
   39     k[2] = 0;
   40     k[1] = 0;
   41     memmove(k, input_key, len);
   42     return 0;
   43 }
   44 
   45 
   46 void mu(word32 * a)
   47 {               /* inverts the order of the bits of a */
   48     int i;
   49     word32 b[3];
   50 
   51     b[0] = b[1] = b[2] = 0;
   52     for (i = 0; i < 32; i++) {
   53         b[0] <<= 1;
   54         b[1] <<= 1;
   55         b[2] <<= 1;
   56         if (a[0] & 1)
   57             b[2] |= 1;
   58         if (a[1] & 1)
   59             b[1] |= 1;
   60         if (a[2] & 1)
   61             b[0] |= 1;
   62         a[0] >>= 1;
   63         a[1] >>= 1;
   64         a[2] >>= 1;
   65     }
   66 
   67     a[0] = b[0];
   68     a[1] = b[1];
   69     a[2] = b[2];
   70 }
   71 
   72 void gamma(word32 * a)
   73 {               /* the nonlinear step */
   74     word32 b[3];
   75 
   76     b[0] = a[0] ^ (a[1] | (~a[2]));
   77     b[1] = a[1] ^ (a[2] | (~a[0]));
   78     b[2] = a[2] ^ (a[0] | (~a[1]));
   79 
   80     a[0] = b[0];
   81     a[1] = b[1];
   82     a[2] = b[2];
   83 }
   84 
   85 
   86 void theta(word32 * a)
   87 {               /* the linear step */
   88     word32 b[3];
   89 
   90     b[0] =
   91         a[0] ^ (a[0] >> 16) ^ (a[1] << 16) ^ (a[1] >> 16) ^ (a[2] <<
   92                                  16) ^
   93         (a[1] >> 24) ^ (a[2] << 8) ^ (a[2] >> 8) ^ (a[0] << 24) ^ (a[2]
   94                                        >>
   95                                        16)
   96         ^ (a[0] << 16) ^ (a[2] >> 24) ^ (a[0] << 8);
   97     b[1] =
   98         a[1] ^ (a[1] >> 16) ^ (a[2] << 16) ^ (a[2] >> 16) ^ (a[0] <<
   99                                  16) ^
  100         (a[2] >> 24) ^ (a[0] << 8) ^ (a[0] >> 8) ^ (a[1] << 24) ^ (a[0]
  101                                        >>
  102                                        16)
  103         ^ (a[1] << 16) ^ (a[0] >> 24) ^ (a[1] << 8);
  104     b[2] =
  105         a[2] ^ (a[2] >> 16) ^ (a[0] << 16) ^ (a[0] >> 16) ^ (a[1] <<
  106                                  16) ^
  107         (a[0] >> 24) ^ (a[1] << 8) ^ (a[1] >> 8) ^ (a[2] << 24) ^ (a[1]
  108                                        >>
  109                                        16)
  110         ^ (a[2] << 16) ^ (a[1] >> 24) ^ (a[2] << 8);
  111 
  112     a[0] = b[0];
  113     a[1] = b[1];
  114     a[2] = b[2];
  115 }
  116 
  117 void pi_1(word32 * a)
  118 {
  119     a[0] = (a[0] >> 10) ^ (a[0] << 22);
  120     a[2] = (a[2] << 1) ^ (a[2] >> 31);
  121 }
  122 
  123 void pi_2(word32 * a)
  124 {
  125     a[0] = (a[0] << 1) ^ (a[0] >> 31);
  126     a[2] = (a[2] >> 10) ^ (a[2] << 22);
  127 }
  128 
  129 void rho(word32 * a)
  130 {               /* the round function       */
  131     theta(a);
  132     pi_1(a);
  133     gamma(a);
  134     pi_2(a);
  135 }
  136 
  137 void rndcon_gen(word32 strt, word32 * rtab)
  138 {               /* generates the round constants */
  139     int i;
  140 
  141     for (i = 0; i <= NMBR; i++) {
  142         rtab[i] = strt;
  143         strt <<= 1;
  144         if (strt & 0x10000)
  145             strt ^= 0x11011;
  146     }
  147 }
  148 
  149 WIN32DLL_DEFINE void _mcrypt_encrypt(word32 * tk, word32 * ta)
  150 {
  151     int i;
  152     word32 rcon[NMBR + 1];
  153     word32 a[3], k[3];
  154 
  155 /* Added to make it compatible with bigendian machines
  156  * --nikos
  157  */
  158 
  159 #ifndef WORDS_BIGENDIAN
  160     a[0] = byteswap32(ta[0]);
  161     a[1] = byteswap32(ta[1]);
  162     a[2] = byteswap32(ta[2]);
  163     k[0] = byteswap32(tk[0]);
  164     k[1] = byteswap32(tk[1]);
  165     k[2] = byteswap32(tk[2]);
  166 #else
  167     a[0] = ta[0];
  168     a[1] = ta[1];
  169     a[2] = ta[2];
  170     k[0] = (tk[0]);
  171     k[1] = (tk[1]);
  172     k[2] = (tk[2]);
  173 #endif
  174 
  175     rndcon_gen(STRT_E, rcon);
  176     for (i = 0; i < NMBR; i++) {
  177         a[0] ^= k[0] ^ (rcon[i] << 16);
  178         a[1] ^= k[1];
  179         a[2] ^= k[2] ^ rcon[i];
  180         rho(a);
  181     }
  182     a[0] ^= k[0] ^ (rcon[NMBR] << 16);
  183     a[1] ^= k[1];
  184     a[2] ^= k[2] ^ rcon[NMBR];
  185     theta(a);
  186 
  187 #ifndef WORDS_BIGENDIAN
  188     ta[0] = byteswap32(a[0]);
  189     ta[1] = byteswap32(a[1]);
  190     ta[2] = byteswap32(a[2]);
  191 #else
  192     ta[0] = a[0];
  193     ta[1] = a[1];
  194     ta[2] = a[2];
  195 #endif
  196 
  197 }
  198 
  199 
  200 WIN32DLL_DEFINE void _mcrypt_decrypt(word32 * k, word32 * ta)
  201 {
  202     int i;
  203     word32 ki[3];       /* the `inverse' key             */
  204     word32 rcon[NMBR + 1];  /* the `inverse' round constants */
  205     word32 a[3];
  206 
  207 #ifndef WORDS_BIGENDIAN
  208     a[0] = byteswap32(ta[0]);
  209     a[1] = byteswap32(ta[1]);
  210     a[2] = byteswap32(ta[2]);
  211     ki[0] = byteswap32(k[0]);
  212     ki[1] = byteswap32(k[1]);
  213     ki[2] = byteswap32(k[2]);
  214 #else
  215     a[0] = ta[0];
  216     a[1] = ta[1];
  217     a[2] = ta[2];
  218     ki[0] = k[0];
  219     ki[1] = k[1];
  220     ki[2] = k[2];
  221 #endif
  222 
  223     theta(ki);
  224     mu(ki);
  225 
  226     rndcon_gen(STRT_D, rcon);
  227 
  228     mu(a);
  229     for (i = 0; i < NMBR; i++) {
  230         a[0] ^= ki[0] ^ (rcon[i] << 16);
  231         a[1] ^= ki[1];
  232         a[2] ^= ki[2] ^ rcon[i];
  233         rho(a);
  234     }
  235     a[0] ^= ki[0] ^ (rcon[NMBR] << 16);
  236     a[1] ^= ki[1];
  237     a[2] ^= ki[2] ^ rcon[NMBR];
  238     theta(a);
  239     mu(a);
  240 
  241 #ifndef WORDS_BIGENDIAN
  242     ta[0] = byteswap32(a[0]);
  243     ta[1] = byteswap32(a[1]);
  244     ta[2] = byteswap32(a[2]);
  245 
  246 #else
  247     ta[0] = a[0];
  248     ta[1] = a[1];
  249     ta[2] = a[2];
  250 #endif
  251 
  252 }
  253 
  254 WIN32DLL_DEFINE int _mcrypt_get_size()
  255 {
  256     return 3 * sizeof(word32);
  257 }
  258 WIN32DLL_DEFINE int _mcrypt_get_block_size()
  259 {
  260     return 12;
  261 }
  262 WIN32DLL_DEFINE int _is_block_algorithm()
  263 {
  264     return 1;
  265 }
  266 WIN32DLL_DEFINE int _mcrypt_get_key_size()
  267 {
  268     return 12;
  269 }
  270 
  271 static const int key_sizes[] = { 12 };
  272 WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
  273 {
  274     *len = sizeof(key_sizes)/sizeof(int);
  275     return key_sizes;
  276 
  277 }
  278 WIN32DLL_DEFINE const char *_mcrypt_get_algorithms_name()
  279 {
  280 return "3-WAY";
  281 }
  282 
  283 #define CIPHER "46823287358d68f6e034ca62"
  284 
  285 WIN32DLL_DEFINE int _mcrypt_self_test()
  286 {
  287     char *keyword;
  288     unsigned char plaintext[16];
  289     unsigned char ciphertext[16];
  290     int blocksize = _mcrypt_get_block_size(), j;
  291     void *key;
  292     unsigned char cipher_tmp[200];
  293 
  294     keyword = calloc(1, _mcrypt_get_key_size());
  295     if (keyword == NULL)
  296         return -1;
  297 
  298     for (j = 0; j < _mcrypt_get_key_size(); j++) {
  299         keyword[j] = ((j * 2 + 10) % 256);
  300     }
  301 
  302     for (j = 0; j < blocksize; j++) {
  303         plaintext[j] = j % 256;
  304     }
  305     key = malloc(_mcrypt_get_size());
  306     if (key == NULL)
  307         return -1;
  308 
  309     memcpy(ciphertext, plaintext, blocksize);
  310 
  311     _mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
  312     free(keyword);
  313 
  314     _mcrypt_encrypt(key, (void *) ciphertext);
  315 
  316     for (j = 0; j < blocksize; j++) {
  317         sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
  318             ciphertext[j]);
  319     }
  320 
  321     if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
  322         printf("failed compatibility\n");
  323         printf("Expected: %s\nGot: %s\n", CIPHER,
  324                (char *) cipher_tmp);
  325         free(key);
  326         return -1;
  327     }
  328     _mcrypt_decrypt(key, (void *) ciphertext);
  329     free(key);
  330 
  331     if (strcmp(ciphertext, plaintext) != 0) {
  332         printf("failed internally\n");
  333         return -1;
  334     }
  335 
  336     return 0;
  337 }
  338 
  339 WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
  340 {
  341     return 20010801;
  342 }
  343 
  344 #ifdef WIN32
  345 # ifdef USE_LTDL
  346 WIN32DLL_DEFINE int main (void)
  347 {
  348        /* empty main function to avoid linker error (see cygwin FAQ) */
  349 }
  350 # endif
  351 #endif