"Fossies" - the Fresh Open Source Software Archive

Member "libmcrypt-2.5.8/modules/algorithms/serpent.c" (15 Jan 2003, 22366 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 "serpent.c" see the Fossies "Dox" file reference documentation.

    1 /* This is an independent implementation of the encryption algorithm:
    2  *
    3  * Serpent by Ross Anderson, Eli Biham and Lars Knudsen 
    4  *
    5  * which is a candidate algorithm in the Advanced Encryption Standard
    6  * programme of the US National Institute of Standards and Technology
    7  *
    8  * Copyright in this implementation is held by Dr B R Gladman but I
    9  * hereby give permission for its free direct or derivative use subject
   10  * to acknowledgment of its origin and compliance with any conditions
   11  * that the originators of the algorithm place on its exploitation.
   12  *
   13  * Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999
   14  */
   15 
   16 /* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos 
   17  * All modifications are placed under the license of libmcrypt.
   18  */
   19 
   20 /*
   21 Algorithm serpent (serpent.c)
   22 
   23 128 bit key:
   24 Key Setup:    2366 cycles
   25 Encrypt:       954 cycles =    26.8 mbits/sec
   26 Decrypt:       907 cycles =    28.2 mbits/sec
   27 Mean:          931 cycles =    27.5 mbits/sec
   28 
   29 192 bit key:
   30 Key Setup:    2382 cycles
   31 Encrypt:       967 cycles =    26.5 mbits/sec
   32 Decrypt:       915 cycles =    28.0 mbits/sec
   33 Mean:          941 cycles =    27.2 mbits/sec
   34 
   35 256 bit key:
   36 Key Setup:    2360 cycles
   37 Encrypt:       967 cycles =    26.5 mbits/sec
   38 Decrypt:       915 cycles =    28.0 mbits/sec
   39 Mean:          941 cycles =    27.2 mbits/sec
   40 */
   41 
   42 #include <libdefs.h>
   43 
   44 #include <mcrypt_modules.h>
   45 #include "serpent.h"
   46 
   47 #define _mcrypt_set_key serpent_LTX__mcrypt_set_key
   48 #define _mcrypt_encrypt serpent_LTX__mcrypt_encrypt
   49 #define _mcrypt_decrypt serpent_LTX__mcrypt_decrypt
   50 #define _mcrypt_get_size serpent_LTX__mcrypt_get_size
   51 #define _mcrypt_get_block_size serpent_LTX__mcrypt_get_block_size
   52 #define _is_block_algorithm serpent_LTX__is_block_algorithm
   53 #define _mcrypt_get_key_size serpent_LTX__mcrypt_get_key_size
   54 #define _mcrypt_get_supported_key_sizes serpent_LTX__mcrypt_get_supported_key_sizes
   55 #define _mcrypt_get_algorithms_name serpent_LTX__mcrypt_get_algorithms_name
   56 #define _mcrypt_self_test serpent_LTX__mcrypt_self_test
   57 #define _mcrypt_algorithm_version serpent_LTX__mcrypt_algorithm_version
   58 
   59 /* Partially optimised Serpent S Box boolean functions derived  */
   60 /* using a recursive descent analyser but without a full search */
   61 /* of all subtrees. This set of S boxes is the result of work   */
   62 /* by Sam Simpson and Brian Gladman using the spare time on a   */
   63 /* cluster of high capacity servers to search for S boxes with  */
   64 /* this customised search engine.                               */
   65 /*                                                              */
   66 /* Copyright:   Dr B. R Gladman (gladman@seven77.demon.co.uk)   */
   67 /*              and Sam Simpson (s.simpson@mia.co.uk)           */
   68 /*              17th December 1998                              */
   69 /*                                                              */
   70 /* We hereby give permission for information in this file to be */
   71 /* used freely subject only to acknowledgement of its origin    */
   72 
   73 /* 15 terms */
   74 
   75 #define sb0(a,b,c,d,e,f,g,h)    \
   76     t1 = a ^ d;     \
   77     t2 = a & d;     \
   78     t3 = c ^ t1;    \
   79     t6 = b & t1;    \
   80     t4 = b ^ t3;    \
   81     t10 = ~t3;      \
   82     h = t2 ^ t4;    \
   83     t7 = a ^ t6;    \
   84     t14 = ~t7;      \
   85     t8 = c | t7;    \
   86     t11 = t3 ^ t7;  \
   87     g = t4 ^ t8;    \
   88     t12 = h & t11;  \
   89     f = t10 ^ t12;  \
   90     e = t12 ^ t14
   91 
   92 /* 15 terms */
   93 
   94 #define ib0(a,b,c,d,e,f,g,h)    \
   95     t1 = ~a;        \
   96     t2 = a ^ b;     \
   97     t3 = t1 | t2;   \
   98     t4 = d ^ t3;    \
   99     t7 = d & t2;    \
  100     t5 = c ^ t4;    \
  101     t8 = t1 ^ t7;   \
  102     g = t2 ^ t5;    \
  103     t11 = a & t4;   \
  104     t9 = g & t8;    \
  105     t14 = t5 ^ t8;  \
  106     f = t4 ^ t9;    \
  107     t12 = t5 | f;   \
  108     h = t11 ^ t12;  \
  109     e = h ^ t14
  110 
  111 /* 14 terms!  */
  112 
  113 #define sb1(a,b,c,d,e,f,g,h)    \
  114     t1 = ~a;        \
  115     t2 = b ^ t1;    \
  116     t3 = a | t2;    \
  117     t4 = d | t2;    \
  118     t5 = c ^ t3;    \
  119     g = d ^ t5;     \
  120     t7 = b ^ t4;    \
  121     t8 = t2 ^ g;    \
  122     t9 = t5 & t7;   \
  123     h = t8 ^ t9;    \
  124     t11 = t5 ^ t7;  \
  125     f = h ^ t11;    \
  126     t13 = t8 & t11; \
  127     e = t5 ^ t13
  128 
  129 /* 17 terms */
  130 
  131 #define ib1(a,b,c,d,e,f,g,h)    \
  132     t1 = a ^ d;     \
  133     t2 = a & b;     \
  134     t3 = b ^ c;     \
  135     t4 = a ^ t3;    \
  136     t5 = b | d;     \
  137     t7 = c | t1;    \
  138     h = t4 ^ t5;    \
  139     t8 = b ^ t7;    \
  140     t11 = ~t2;      \
  141     t9 = t4 & t8;   \
  142     f = t1 ^ t9;    \
  143     t13 = t9 ^ t11; \
  144     t12 = h & f;    \
  145     g = t12 ^ t13;  \
  146     t15 = a & d;    \
  147     t16 = c ^ t13;  \
  148     e = t15 ^ t16
  149 
  150 /* 16 terms */
  151 
  152 #define sb2(a,b,c,d,e,f,g,h)    \
  153     t1 = ~a;        \
  154     t2 = b ^ d;     \
  155     t3 = c & t1;    \
  156     t13 = d | t1;   \
  157     e = t2 ^ t3;    \
  158     t5 = c ^ t1;    \
  159     t6 = c ^ e;     \
  160     t7 = b & t6;    \
  161     t10 = e | t5;   \
  162     h = t5 ^ t7;    \
  163     t9 = d | t7;    \
  164     t11 = t9 & t10; \
  165     t14 = t2 ^ h;   \
  166     g = a ^ t11;    \
  167     t15 = g ^ t13;  \
  168     f = t14 ^ t15
  169 
  170 /* 16 terms */
  171 
  172 #define ib2(a,b,c,d,e,f,g,h)    \
  173     t1 = b ^ d;     \
  174     t2 = ~t1;       \
  175     t3 = a ^ c;     \
  176     t4 = c ^ t1;    \
  177     t7 = a | t2;    \
  178     t5 = b & t4;    \
  179     t8 = d ^ t7;    \
  180     t11 = ~t4;      \
  181     e = t3 ^ t5;    \
  182     t9 = t3 | t8;   \
  183     t14 = d & t11;  \
  184     h = t1 ^ t9;    \
  185     t12 = e | h;    \
  186     f = t11 ^ t12;  \
  187     t15 = t3 ^ t12; \
  188     g = t14 ^ t15
  189 
  190 /* 17 terms */
  191 
  192 #define sb3(a,b,c,d,e,f,g,h)    \
  193     t1 = a ^ c;     \
  194     t2 = d ^ t1;    \
  195     t3 = a & t2;    \
  196     t4 = d ^ t3;    \
  197     t5 = b & t4;    \
  198     g = t2 ^ t5;    \
  199     t7 = a | g;     \
  200     t8 = b | d;     \
  201     t11 = a | d;    \
  202     t9 = t4 & t7;   \
  203     f = t8 ^ t9;    \
  204     t12 = b ^ t11;  \
  205     t13 = g ^ t9;   \
  206     t15 = t3 ^ t8;  \
  207     h = t12 ^ t13;  \
  208     t16 = c & t15;  \
  209     e = t12 ^ t16
  210 
  211 /* 16 term solution that performs less well than 17 term one
  212    in my environment (PPro/PII)                                  
  213 
  214 #define sb3(a,b,c,d,e,f,g,h)    \
  215     t1 = a ^ b;     \
  216     t2 = a & c;     \
  217     t3 = a | d;     \
  218     t4 = c ^ d;     \
  219     t5 = t1 & t3;   \
  220     t6 = t2 | t5;   \
  221     g = t4 ^ t6;    \
  222     t8 = b ^ t3;    \
  223     t9 = t6 ^ t8;   \
  224     t10 = t4 & t9;  \
  225     e = t1 ^ t10;   \
  226     t12 = g & e;    \
  227     f = t9 ^ t12;   \
  228     t14 = b | d;    \
  229     t15 = t4 ^ t12; \
  230     h = t14 ^ t15
  231 */
  232 
  233 /* 17 terms */
  234 
  235 #define ib3(a,b,c,d,e,f,g,h)    \
  236     t1 = b ^ c;     \
  237     t2 = b | c;     \
  238     t3 = a ^ c;     \
  239     t7 = a ^ d;     \
  240     t4 = t2 ^ t3;   \
  241     t5 = d | t4;    \
  242     t9 = t2 ^ t7;   \
  243     e = t1 ^ t5;    \
  244     t8 = t1 | t5;   \
  245     t11 = a & t4;   \
  246     g = t8 ^ t9;    \
  247     t12 = e | t9;   \
  248     f = t11 ^ t12;  \
  249     t14 = a & g;    \
  250     t15 = t2 ^ t14; \
  251     t16 = e & t15;  \
  252     h = t4 ^ t16
  253 
  254 /* 15 terms */
  255 
  256 #define sb4(a,b,c,d,e,f,g,h)    \
  257     t1 = a ^ d;     \
  258     t2 = d & t1;    \
  259     t3 = c ^ t2;    \
  260     t4 = b | t3;    \
  261     h = t1 ^ t4;    \
  262     t6 = ~b;        \
  263     t7 = t1 | t6;   \
  264     e = t3 ^ t7;    \
  265     t9 = a & e;     \
  266     t10 = t1 ^ t6;  \
  267     t11 = t4 & t10; \
  268     g = t9 ^ t11;   \
  269     t13 = a ^ t3;   \
  270     t14 = t10 & g;  \
  271     f = t13 ^ t14
  272 
  273 /* 17 terms */
  274 
  275 #define ib4(a,b,c,d,e,f,g,h)    \
  276     t1 = c ^ d;     \
  277     t2 = c | d;     \
  278     t3 = b ^ t2;    \
  279     t4 = a & t3;    \
  280     f = t1 ^ t4;    \
  281     t6 = a ^ d;     \
  282     t7 = b | d;     \
  283     t8 = t6 & t7;   \
  284     h = t3 ^ t8;    \
  285     t10 = ~a;       \
  286     t11 = c ^ h;    \
  287     t12 = t10 | t11;\
  288     e = t3 ^ t12;   \
  289     t14 = c | t4;   \
  290     t15 = t7 ^ t14; \
  291     t16 = h | t10;  \
  292     g = t15 ^ t16
  293 
  294 /* 16 terms */
  295 
  296 #define sb5(a,b,c,d,e,f,g,h)    \
  297     t1 = ~a;        \
  298     t2 = a ^ b;     \
  299     t3 = a ^ d;     \
  300     t4 = c ^ t1;    \
  301     t5 = t2 | t3;   \
  302     e = t4 ^ t5;    \
  303     t7 = d & e;     \
  304     t8 = t2 ^ e;    \
  305     t10 = t1 | e;   \
  306     f = t7 ^ t8;    \
  307     t11 = t2 | t7;  \
  308     t12 = t3 ^ t10; \
  309     t14 = b ^ t7;   \
  310     g = t11 ^ t12;  \
  311     t15 = f & t12;  \
  312     h = t14 ^ t15
  313 
  314 /* 16 terms */
  315 
  316 #define ib5(a,b,c,d,e,f,g,h)    \
  317     t1 = ~c;        \
  318     t2 = b & t1;    \
  319     t3 = d ^ t2;    \
  320     t4 = a & t3;    \
  321     t5 = b ^ t1;    \
  322     h = t4 ^ t5;    \
  323     t7 = b | h;     \
  324     t8 = a & t7;    \
  325     f = t3 ^ t8;    \
  326     t10 = a | d;    \
  327     t11 = t1 ^ t7;  \
  328     e = t10 ^ t11;  \
  329     t13 = a ^ c;    \
  330     t14 = b & t10;  \
  331     t15 = t4 | t13; \
  332     g = t14 ^ t15
  333 
  334 /* 15 terms */
  335 
  336 #define sb6(a,b,c,d,e,f,g,h)    \
  337     t1 = ~a;        \
  338     t2 = a ^ d;     \
  339     t3 = b ^ t2;    \
  340     t4 = t1 | t2;   \
  341     t5 = c ^ t4;    \
  342     f = b ^ t5;     \
  343     t13 = ~t5;      \
  344     t7 = t2 | f;    \
  345     t8 = d ^ t7;    \
  346     t9 = t5 & t8;   \
  347     g = t3 ^ t9;    \
  348     t11 = t5 ^ t8;  \
  349     e = g ^ t11;    \
  350     t14 = t3 & t11; \
  351     h = t13 ^ t14
  352 
  353 /* 15 terms */
  354 
  355 #define ib6(a,b,c,d,e,f,g,h)    \
  356     t1 = ~a;        \
  357     t2 = a ^ b;     \
  358     t3 = c ^ t2;    \
  359     t4 = c | t1;    \
  360     t5 = d ^ t4;    \
  361     t13 = d & t1;   \
  362     f = t3 ^ t5;    \
  363     t7 = t3 & t5;   \
  364     t8 = t2 ^ t7;   \
  365     t9 = b | t8;    \
  366     h = t5 ^ t9;    \
  367     t11 = b | h;    \
  368     e = t8 ^ t11;   \
  369     t14 = t3 ^ t11; \
  370     g = t13 ^ t14
  371 
  372 /* 17 terms */
  373 
  374 #define sb7(a,b,c,d,e,f,g,h)    \
  375     t1 = ~c;        \
  376     t2 = b ^ c;     \
  377     t3 = b | t1;    \
  378     t4 = d ^ t3;    \
  379     t5 = a & t4;    \
  380     t7 = a ^ d;     \
  381     h = t2 ^ t5;    \
  382     t8 = b ^ t5;    \
  383     t9 = t2 | t8;   \
  384     t11 = d & t3;   \
  385     f = t7 ^ t9;    \
  386     t12 = t5 ^ f;   \
  387     t15 = t1 | t4;  \
  388     t13 = h & t12;  \
  389     g = t11 ^ t13;  \
  390     t16 = t12 ^ g;  \
  391     e = t15 ^ t16
  392 
  393 /* 17 terms */
  394 
  395 #define ib7(a,b,c,d,e,f,g,h)    \
  396     t1 = a & b;     \
  397     t2 = a | b;     \
  398     t3 = c | t1;    \
  399     t4 = d & t2;    \
  400     h = t3 ^ t4;    \
  401     t6 = ~d;        \
  402     t7 = b ^ t4;    \
  403     t8 = h ^ t6;    \
  404     t11 = c ^ t7;   \
  405     t9 = t7 | t8;   \
  406     f = a ^ t9;     \
  407     t12 = d | f;    \
  408     e = t11 ^ t12;  \
  409     t14 = a & h;    \
  410     t15 = t3 ^ f;   \
  411     t16 = e ^ t14;  \
  412     g = t15 ^ t16
  413 
  414 #define k_xor(r,a,b,c,d)    \
  415     a ^= spkey->l_key[4 * r +  8]; \
  416     b ^= spkey->l_key[4 * r +  9]; \
  417     c ^= spkey->l_key[4 * r + 10]; \
  418     d ^= spkey->l_key[4 * r + 11]
  419 
  420 #define k_set(r,a,b,c,d)    \
  421     a = spkey->l_key[4 * r +  8];  \
  422     b = spkey->l_key[4 * r +  9];  \
  423     c = spkey->l_key[4 * r + 10];  \
  424     d = spkey->l_key[4 * r + 11]
  425 
  426 #define k_get(r,a,b,c,d)    \
  427     spkey->l_key[4 * r +  8] = a;  \
  428     spkey->l_key[4 * r +  9] = b;  \
  429     spkey->l_key[4 * r + 10] = c;  \
  430     spkey->l_key[4 * r + 11] = d
  431 
  432 /* the linear transformation and its inverse    */
  433 
  434 #define rot(a,b,c,d)    \
  435     a = rotl32(a, 13);    \
  436     c = rotl32(c, 3);     \
  437     d ^= c ^ (a << 3);  \
  438     b ^= a ^ c;         \
  439     d = rotl32(d, 7);     \
  440     b = rotl32(b, 1);     \
  441     a ^= b ^ d;         \
  442     c ^= d ^ (b << 7);  \
  443     a = rotl32(a, 5);     \
  444     c = rotl32(c, 22)
  445 
  446 #define irot(a,b,c,d)   \
  447     c = rotr32(c, 22);    \
  448     a = rotr32(a, 5);     \
  449     c ^= d ^ (b << 7);  \
  450     a ^= b ^ d;         \
  451     d = rotr32(d, 7);     \
  452     b = rotr32(b, 1);     \
  453     d ^= c ^ (a << 3);  \
  454     b ^= a ^ c;         \
  455     c = rotr32(c, 3);     \
  456     a = rotr32(a, 13)
  457 
  458 /* initialise the key schedule from the user supplied key   */
  459 
  460 WIN32DLL_DEFINE
  461     int _mcrypt_set_key(SERPENT_KEY * spkey, const word32 * in_key,
  462             word32 key_len)
  463 {
  464     word32 i, lk, a, b, c, d, e, f, g, h;
  465     word32 t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14,
  466         t15, t16;
  467 
  468     key_len *= 8;
  469     if (key_len > 256)
  470 
  471         return -1;
  472 
  473     i = 0;
  474     lk = (key_len + 31) / 32;
  475 
  476     while (i < lk) {
  477 #ifdef WORDS_BIGENDIAN
  478         spkey->l_key[i] = byteswap32(in_key[i]);
  479 #else
  480         spkey->l_key[i] = (in_key[i]);
  481 #endif
  482         i++;
  483     }
  484 
  485     if (key_len < 256) {
  486         while (i < 8)
  487 
  488             spkey->l_key[i++] = 0;
  489 
  490         i = key_len / 32;
  491         lk = 1 << key_len % 32;
  492         spkey->l_key[i] = (spkey->l_key[i] & (lk - 1)) | lk;
  493     }
  494 
  495     for (i = 0; i < 132; ++i) {
  496         lk = spkey->l_key[i] ^ spkey->l_key[i +
  497                             3] ^ spkey->l_key[i +
  498                                       5] ^
  499             spkey->l_key[i + 7] ^ 0x9e3779b9 ^ i;
  500 
  501         spkey->l_key[i + 8] = (lk << 11) | (lk >> 21);
  502     }
  503 
  504     k_set(0, a, b, c, d);
  505     sb3(a, b, c, d, e, f, g, h);
  506     k_get(0, e, f, g, h);
  507     k_set(1, a, b, c, d);
  508     sb2(a, b, c, d, e, f, g, h);
  509     k_get(1, e, f, g, h);
  510     k_set(2, a, b, c, d);
  511     sb1(a, b, c, d, e, f, g, h);
  512     k_get(2, e, f, g, h);
  513     k_set(3, a, b, c, d);
  514     sb0(a, b, c, d, e, f, g, h);
  515     k_get(3, e, f, g, h);
  516     k_set(4, a, b, c, d);
  517     sb7(a, b, c, d, e, f, g, h);
  518     k_get(4, e, f, g, h);
  519     k_set(5, a, b, c, d);
  520     sb6(a, b, c, d, e, f, g, h);
  521     k_get(5, e, f, g, h);
  522     k_set(6, a, b, c, d);
  523     sb5(a, b, c, d, e, f, g, h);
  524     k_get(6, e, f, g, h);
  525     k_set(7, a, b, c, d);
  526     sb4(a, b, c, d, e, f, g, h);
  527     k_get(7, e, f, g, h);
  528     k_set(8, a, b, c, d);
  529     sb3(a, b, c, d, e, f, g, h);
  530     k_get(8, e, f, g, h);
  531     k_set(9, a, b, c, d);
  532     sb2(a, b, c, d, e, f, g, h);
  533     k_get(9, e, f, g, h);
  534     k_set(10, a, b, c, d);
  535     sb1(a, b, c, d, e, f, g, h);
  536     k_get(10, e, f, g, h);
  537     k_set(11, a, b, c, d);
  538     sb0(a, b, c, d, e, f, g, h);
  539     k_get(11, e, f, g, h);
  540     k_set(12, a, b, c, d);
  541     sb7(a, b, c, d, e, f, g, h);
  542     k_get(12, e, f, g, h);
  543     k_set(13, a, b, c, d);
  544     sb6(a, b, c, d, e, f, g, h);
  545     k_get(13, e, f, g, h);
  546     k_set(14, a, b, c, d);
  547     sb5(a, b, c, d, e, f, g, h);
  548     k_get(14, e, f, g, h);
  549     k_set(15, a, b, c, d);
  550     sb4(a, b, c, d, e, f, g, h);
  551     k_get(15, e, f, g, h);
  552     k_set(16, a, b, c, d);
  553     sb3(a, b, c, d, e, f, g, h);
  554     k_get(16, e, f, g, h);
  555     k_set(17, a, b, c, d);
  556     sb2(a, b, c, d, e, f, g, h);
  557     k_get(17, e, f, g, h);
  558     k_set(18, a, b, c, d);
  559     sb1(a, b, c, d, e, f, g, h);
  560     k_get(18, e, f, g, h);
  561     k_set(19, a, b, c, d);
  562     sb0(a, b, c, d, e, f, g, h);
  563     k_get(19, e, f, g, h);
  564     k_set(20, a, b, c, d);
  565     sb7(a, b, c, d, e, f, g, h);
  566     k_get(20, e, f, g, h);
  567     k_set(21, a, b, c, d);
  568     sb6(a, b, c, d, e, f, g, h);
  569     k_get(21, e, f, g, h);
  570     k_set(22, a, b, c, d);
  571     sb5(a, b, c, d, e, f, g, h);
  572     k_get(22, e, f, g, h);
  573     k_set(23, a, b, c, d);
  574     sb4(a, b, c, d, e, f, g, h);
  575     k_get(23, e, f, g, h);
  576     k_set(24, a, b, c, d);
  577     sb3(a, b, c, d, e, f, g, h);
  578     k_get(24, e, f, g, h);
  579     k_set(25, a, b, c, d);
  580     sb2(a, b, c, d, e, f, g, h);
  581     k_get(25, e, f, g, h);
  582     k_set(26, a, b, c, d);
  583     sb1(a, b, c, d, e, f, g, h);
  584     k_get(26, e, f, g, h);
  585     k_set(27, a, b, c, d);
  586     sb0(a, b, c, d, e, f, g, h);
  587     k_get(27, e, f, g, h);
  588     k_set(28, a, b, c, d);
  589     sb7(a, b, c, d, e, f, g, h);
  590     k_get(28, e, f, g, h);
  591     k_set(29, a, b, c, d);
  592     sb6(a, b, c, d, e, f, g, h);
  593     k_get(29, e, f, g, h);
  594     k_set(30, a, b, c, d);
  595     sb5(a, b, c, d, e, f, g, h);
  596     k_get(30, e, f, g, h);
  597     k_set(31, a, b, c, d);
  598     sb4(a, b, c, d, e, f, g, h);
  599     k_get(31, e, f, g, h);
  600     k_set(32, a, b, c, d);
  601     sb3(a, b, c, d, e, f, g, h);
  602     k_get(32, e, f, g, h);
  603 
  604     return 0;
  605 }
  606 
  607 /* encrypt a block of text  */
  608 
  609 WIN32DLL_DEFINE void _mcrypt_encrypt(SERPENT_KEY * spkey, word32 * in_blk)
  610 {
  611     word32 a, b, c, d, e, f, g, h;
  612     word32 t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14,
  613         t15, t16;
  614 
  615 #ifdef WORDS_BIGENDIAN
  616     a = byteswap32(in_blk[0]);
  617     b = byteswap32(in_blk[1]);
  618     c = byteswap32(in_blk[2]);
  619     d = byteswap32(in_blk[3]);
  620 #else
  621     a = in_blk[0];
  622     b = in_blk[1];
  623     c = in_blk[2];
  624     d = in_blk[3];
  625 #endif
  626 
  627     k_xor(0, a, b, c, d);
  628     sb0(a, b, c, d, e, f, g, h);
  629     rot(e, f, g, h);
  630     k_xor(1, e, f, g, h);
  631     sb1(e, f, g, h, a, b, c, d);
  632     rot(a, b, c, d);
  633     k_xor(2, a, b, c, d);
  634     sb2(a, b, c, d, e, f, g, h);
  635     rot(e, f, g, h);
  636     k_xor(3, e, f, g, h);
  637     sb3(e, f, g, h, a, b, c, d);
  638     rot(a, b, c, d);
  639     k_xor(4, a, b, c, d);
  640     sb4(a, b, c, d, e, f, g, h);
  641     rot(e, f, g, h);
  642     k_xor(5, e, f, g, h);
  643     sb5(e, f, g, h, a, b, c, d);
  644     rot(a, b, c, d);
  645     k_xor(6, a, b, c, d);
  646     sb6(a, b, c, d, e, f, g, h);
  647     rot(e, f, g, h);
  648     k_xor(7, e, f, g, h);
  649     sb7(e, f, g, h, a, b, c, d);
  650     rot(a, b, c, d);
  651     k_xor(8, a, b, c, d);
  652     sb0(a, b, c, d, e, f, g, h);
  653     rot(e, f, g, h);
  654     k_xor(9, e, f, g, h);
  655     sb1(e, f, g, h, a, b, c, d);
  656     rot(a, b, c, d);
  657     k_xor(10, a, b, c, d);
  658     sb2(a, b, c, d, e, f, g, h);
  659     rot(e, f, g, h);
  660     k_xor(11, e, f, g, h);
  661     sb3(e, f, g, h, a, b, c, d);
  662     rot(a, b, c, d);
  663     k_xor(12, a, b, c, d);
  664     sb4(a, b, c, d, e, f, g, h);
  665     rot(e, f, g, h);
  666     k_xor(13, e, f, g, h);
  667     sb5(e, f, g, h, a, b, c, d);
  668     rot(a, b, c, d);
  669     k_xor(14, a, b, c, d);
  670     sb6(a, b, c, d, e, f, g, h);
  671     rot(e, f, g, h);
  672     k_xor(15, e, f, g, h);
  673     sb7(e, f, g, h, a, b, c, d);
  674     rot(a, b, c, d);
  675     k_xor(16, a, b, c, d);
  676     sb0(a, b, c, d, e, f, g, h);
  677     rot(e, f, g, h);
  678     k_xor(17, e, f, g, h);
  679     sb1(e, f, g, h, a, b, c, d);
  680     rot(a, b, c, d);
  681     k_xor(18, a, b, c, d);
  682     sb2(a, b, c, d, e, f, g, h);
  683     rot(e, f, g, h);
  684     k_xor(19, e, f, g, h);
  685     sb3(e, f, g, h, a, b, c, d);
  686     rot(a, b, c, d);
  687     k_xor(20, a, b, c, d);
  688     sb4(a, b, c, d, e, f, g, h);
  689     rot(e, f, g, h);
  690     k_xor(21, e, f, g, h);
  691     sb5(e, f, g, h, a, b, c, d);
  692     rot(a, b, c, d);
  693     k_xor(22, a, b, c, d);
  694     sb6(a, b, c, d, e, f, g, h);
  695     rot(e, f, g, h);
  696     k_xor(23, e, f, g, h);
  697     sb7(e, f, g, h, a, b, c, d);
  698     rot(a, b, c, d);
  699     k_xor(24, a, b, c, d);
  700     sb0(a, b, c, d, e, f, g, h);
  701     rot(e, f, g, h);
  702     k_xor(25, e, f, g, h);
  703     sb1(e, f, g, h, a, b, c, d);
  704     rot(a, b, c, d);
  705     k_xor(26, a, b, c, d);
  706     sb2(a, b, c, d, e, f, g, h);
  707     rot(e, f, g, h);
  708     k_xor(27, e, f, g, h);
  709     sb3(e, f, g, h, a, b, c, d);
  710     rot(a, b, c, d);
  711     k_xor(28, a, b, c, d);
  712     sb4(a, b, c, d, e, f, g, h);
  713     rot(e, f, g, h);
  714     k_xor(29, e, f, g, h);
  715     sb5(e, f, g, h, a, b, c, d);
  716     rot(a, b, c, d);
  717     k_xor(30, a, b, c, d);
  718     sb6(a, b, c, d, e, f, g, h);
  719     rot(e, f, g, h);
  720     k_xor(31, e, f, g, h);
  721     sb7(e, f, g, h, a, b, c, d);
  722     k_xor(32, a, b, c, d);
  723 
  724 #ifdef WORDS_BIGENDIAN
  725     in_blk[0] = byteswap32(a);
  726     in_blk[1] = byteswap32(b);
  727     in_blk[2] = byteswap32(c);
  728     in_blk[3] = byteswap32(d);
  729 #else
  730     in_blk[0] = a;
  731     in_blk[1] = b;
  732     in_blk[2] = c;
  733     in_blk[3] = d;
  734 #endif
  735 }
  736 
  737 /* decrypt a block of text  */
  738 
  739 WIN32DLL_DEFINE void _mcrypt_decrypt(SERPENT_KEY * spkey, word32 * in_blk)
  740 {
  741     word32 a, b, c, d, e, f, g, h;
  742     word32 t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14,
  743         t15, t16;
  744 
  745 #ifdef WORDS_BIGENDIAN
  746     a = byteswap32(in_blk[0]);
  747     b = byteswap32(in_blk[1]);
  748     c = byteswap32(in_blk[2]);
  749     d = byteswap32(in_blk[3]);
  750 #else
  751     a = in_blk[0];
  752     b = in_blk[1];
  753     c = in_blk[2];
  754     d = in_blk[3];
  755 #endif
  756 
  757     k_xor(32, a, b, c, d);
  758     ib7(a, b, c, d, e, f, g, h);
  759     k_xor(31, e, f, g, h);
  760     irot(e, f, g, h);
  761     ib6(e, f, g, h, a, b, c, d);
  762     k_xor(30, a, b, c, d);
  763     irot(a, b, c, d);
  764     ib5(a, b, c, d, e, f, g, h);
  765     k_xor(29, e, f, g, h);
  766     irot(e, f, g, h);
  767     ib4(e, f, g, h, a, b, c, d);
  768     k_xor(28, a, b, c, d);
  769     irot(a, b, c, d);
  770     ib3(a, b, c, d, e, f, g, h);
  771     k_xor(27, e, f, g, h);
  772     irot(e, f, g, h);
  773     ib2(e, f, g, h, a, b, c, d);
  774     k_xor(26, a, b, c, d);
  775     irot(a, b, c, d);
  776     ib1(a, b, c, d, e, f, g, h);
  777     k_xor(25, e, f, g, h);
  778     irot(e, f, g, h);
  779     ib0(e, f, g, h, a, b, c, d);
  780     k_xor(24, a, b, c, d);
  781     irot(a, b, c, d);
  782     ib7(a, b, c, d, e, f, g, h);
  783     k_xor(23, e, f, g, h);
  784     irot(e, f, g, h);
  785     ib6(e, f, g, h, a, b, c, d);
  786     k_xor(22, a, b, c, d);
  787     irot(a, b, c, d);
  788     ib5(a, b, c, d, e, f, g, h);
  789     k_xor(21, e, f, g, h);
  790     irot(e, f, g, h);
  791     ib4(e, f, g, h, a, b, c, d);
  792     k_xor(20, a, b, c, d);
  793     irot(a, b, c, d);
  794     ib3(a, b, c, d, e, f, g, h);
  795     k_xor(19, e, f, g, h);
  796     irot(e, f, g, h);
  797     ib2(e, f, g, h, a, b, c, d);
  798     k_xor(18, a, b, c, d);
  799     irot(a, b, c, d);
  800     ib1(a, b, c, d, e, f, g, h);
  801     k_xor(17, e, f, g, h);
  802     irot(e, f, g, h);
  803     ib0(e, f, g, h, a, b, c, d);
  804     k_xor(16, a, b, c, d);
  805     irot(a, b, c, d);
  806     ib7(a, b, c, d, e, f, g, h);
  807     k_xor(15, e, f, g, h);
  808     irot(e, f, g, h);
  809     ib6(e, f, g, h, a, b, c, d);
  810     k_xor(14, a, b, c, d);
  811     irot(a, b, c, d);
  812     ib5(a, b, c, d, e, f, g, h);
  813     k_xor(13, e, f, g, h);
  814     irot(e, f, g, h);
  815     ib4(e, f, g, h, a, b, c, d);
  816     k_xor(12, a, b, c, d);
  817     irot(a, b, c, d);
  818     ib3(a, b, c, d, e, f, g, h);
  819     k_xor(11, e, f, g, h);
  820     irot(e, f, g, h);
  821     ib2(e, f, g, h, a, b, c, d);
  822     k_xor(10, a, b, c, d);
  823     irot(a, b, c, d);
  824     ib1(a, b, c, d, e, f, g, h);
  825     k_xor(9, e, f, g, h);
  826     irot(e, f, g, h);
  827     ib0(e, f, g, h, a, b, c, d);
  828     k_xor(8, a, b, c, d);
  829     irot(a, b, c, d);
  830     ib7(a, b, c, d, e, f, g, h);
  831     k_xor(7, e, f, g, h);
  832     irot(e, f, g, h);
  833     ib6(e, f, g, h, a, b, c, d);
  834     k_xor(6, a, b, c, d);
  835     irot(a, b, c, d);
  836     ib5(a, b, c, d, e, f, g, h);
  837     k_xor(5, e, f, g, h);
  838     irot(e, f, g, h);
  839     ib4(e, f, g, h, a, b, c, d);
  840     k_xor(4, a, b, c, d);
  841     irot(a, b, c, d);
  842     ib3(a, b, c, d, e, f, g, h);
  843     k_xor(3, e, f, g, h);
  844     irot(e, f, g, h);
  845     ib2(e, f, g, h, a, b, c, d);
  846     k_xor(2, a, b, c, d);
  847     irot(a, b, c, d);
  848     ib1(a, b, c, d, e, f, g, h);
  849     k_xor(1, e, f, g, h);
  850     irot(e, f, g, h);
  851     ib0(e, f, g, h, a, b, c, d);
  852     k_xor(0, a, b, c, d);
  853 
  854 #ifdef WORDS_BIGENDIAN
  855     in_blk[0] = byteswap32(a);
  856     in_blk[1] = byteswap32(b);
  857     in_blk[2] = byteswap32(c);
  858     in_blk[3] = byteswap32(d);
  859 #else
  860     in_blk[0] = a;
  861     in_blk[1] = b;
  862     in_blk[2] = c;
  863     in_blk[3] = d;
  864 #endif
  865 }
  866 
  867 
  868 WIN32DLL_DEFINE int _mcrypt_get_size()
  869 {
  870     return sizeof(SERPENT_KEY);
  871 }
  872 
  873 WIN32DLL_DEFINE int _mcrypt_get_block_size()
  874 {
  875     return 16;
  876 }
  877 WIN32DLL_DEFINE int _is_block_algorithm()
  878 {
  879     return 1;
  880 }
  881 WIN32DLL_DEFINE int _mcrypt_get_key_size()
  882 {
  883     return 32;
  884 }
  885 
  886 static const int key_sizes[] = { 16, 24, 32 };
  887 WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
  888 {
  889     *len = sizeof(key_sizes)/sizeof(int);
  890     return key_sizes;
  891 
  892 }
  893 WIN32DLL_DEFINE const char *_mcrypt_get_algorithms_name()
  894 {
  895 return "Serpent";
  896 }
  897 
  898 #define CIPHER "9a99455df5080bfccadf049b5aaf7d61"
  899 
  900 WIN32DLL_DEFINE int _mcrypt_self_test()
  901 {
  902     char *keyword;
  903     unsigned char plaintext[16];
  904     unsigned char ciphertext[16];
  905     int blocksize = _mcrypt_get_block_size(), j;
  906     void *key;
  907     unsigned char cipher_tmp[200];
  908 
  909     keyword = calloc(1, _mcrypt_get_key_size());
  910     if (keyword == NULL)
  911         return -1;
  912 
  913     for (j = 0; j < _mcrypt_get_key_size(); j++) {
  914         keyword[j] = ((j * 2 + 10) % 256);
  915     }
  916 
  917 
  918     for (j = 0; j < blocksize; j++) {
  919         plaintext[j] = j % 256;
  920     }
  921     key = malloc(_mcrypt_get_size());
  922     if (key == NULL)
  923         return -1;
  924 
  925     memcpy(ciphertext, plaintext, blocksize);
  926 
  927     _mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
  928     free(keyword);
  929 
  930     _mcrypt_encrypt(key, (void *) ciphertext);
  931 
  932     for (j = 0; j < blocksize; j++) {
  933         sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
  934             ciphertext[j]);
  935     }
  936 
  937     if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
  938         printf("failed compatibility\n");
  939         printf("Expected: %s\nGot: %s\n", CIPHER,
  940                (char *) cipher_tmp);
  941         free(key);
  942         return -1;
  943     }
  944     _mcrypt_decrypt(key, (void *) ciphertext);
  945     free(key);
  946 
  947     if (strcmp(ciphertext, plaintext) != 0) {
  948         printf("failed internally\n");
  949         return -1;
  950     }
  951 
  952     return 0;
  953 }
  954 
  955 WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
  956 {
  957     return 20010801;
  958 }
  959 
  960 #ifdef WIN32
  961 # ifdef USE_LTDL
  962 WIN32DLL_DEFINE int main (void)
  963 {
  964        /* empty main function to avoid linker error (see cygwin FAQ) */
  965 }
  966 # endif
  967 #endif