Commit de2361e72ec68f4ea98f6db2965794b0770a753f

Authored by dg
1 parent 180052a2

plop


git-svn-id: http://svn.net-core.org/repos/t-engine4@2143 51575b47-30f0-44d4-a5cc-537603b46e54
  1 +
  2 +/*
  3 + * Fast implementation of the DES, as described in the Federal Register,
  4 + * Vol. 40, No. 52, p. 12134, March 17, 1975.
  5 + *
  6 + * Stuart Levy, Minnesota Supercomputer Center, April 1988.
  7 + * Currently (2007) slevy@ncsa.uiuc.edu
  8 + * NCSA, University of Illinois Urbana-Champaign
  9 + *
  10 + * Calling sequence:
  11 + *
  12 + * typedef unsigned long keysched[32];
  13 + *
  14 + * fsetkey(key, keysched) / * Converts a DES key to a "key schedule" * /
  15 + * unsigned char key[8];
  16 + * keysched *ks;
  17 + *
  18 + * fencrypt(block, decrypt, keysched) / * En/decrypts one 64-bit block * /
  19 + * unsigned char block[8]; / * data, en/decrypted in place * /
  20 + * int decrypt; / * 0=>encrypt, 1=>decrypt * /
  21 + * keysched *ks; / * key schedule, as set by fsetkey * /
  22 + *
  23 + * Key and data block representation:
  24 + * The 56-bit key (bits 1..64 including "parity" bits 8, 16, 24, ..., 64)
  25 + * and the 64-bit data block (bits 1..64)
  26 + * are each stored in arrays of 8 bytes.
  27 + * Following the NBS numbering, the MSB has the bit number 1, so
  28 + * key[0] = 128*bit1 + 64*bit2 + ... + 1*bit8, ... through
  29 + * key[7] = 128*bit57 + 64*bit58 + ... + 1*bit64.
  30 + * In the key, "parity" bits are not checked; their values are ignored.
  31 + *
  32 +*/
  33 +
  34 +/*
  35 +===============================================================================
  36 +License
  37 +
  38 +des56.c is licensed under the terms of the MIT license reproduced below.
  39 +This means that des56.c is free software and can be used for both academic
  40 +and commercial purposes at absolutely no cost.
  41 +===============================================================================
  42 +Copyright (C) 1988 Stuart Levy
  43 +
  44 +Permission is hereby granted, free of charge, to any person obtaining a copy
  45 +of this software and associated documentation files (the "Software"), to deal
  46 +in the Software without restriction, including without limitation the rights
  47 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  48 +copies of the Software, and to permit persons to whom the Software is
  49 +furnished to do so, subject to the following conditions:
  50 +
  51 +The above copyright notice and this permission notice shall be included in
  52 +all copies or substantial portions of the Software.
  53 +
  54 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  55 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  56 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  57 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  58 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  59 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  60 +THE SOFTWARE.
  61 + */
  62 +
  63 +
  64 +#include "des56.h"
  65 +
  66 +
  67 +/*
  68 + * Key schedule generation.
  69 + * We begin by pointlessly permuting the 56 useful key bits into
  70 + * two groups of 28 bits called C and D.
  71 + * bK_C and bK_D are indexed by C and D bit numbers, respectively,
  72 + * and give the key bit number (1..64) which should initialize that C/D bit.
  73 + * This is the "permuted choice 1" table.
  74 + */
  75 +
  76 +static tiny bK_C[28] = {
  77 + 57, 49, 41, 33, 25, 17, 9,
  78 + 1, 58, 50, 42, 34, 26, 18,
  79 + 10, 2, 59, 51, 43, 35, 27,
  80 + 19, 11, 3, 60, 52, 44, 36,
  81 +};
  82 +static tiny bK_D[28] = {
  83 + 63, 55, 47, 39, 31, 23, 15,
  84 + 7, 62, 54, 46, 38, 30, 22,
  85 + 14, 6, 61, 53, 45, 37, 29,
  86 + 21, 13, 5, 28, 20, 12, 4,
  87 +};
  88 +
  89 +/*
  90 + * For speed, we invert these, building tables to map groups of
  91 + * key bits into the corresponding C and D bits.
  92 + * We represent C and D each as 28 contiguous bits right-justified in a
  93 + * word, padded on the left with zeros.
  94 + * If key byte `i' is said to contain bits Ki,0 (MSB) Ki,1 ... Ki,7 (LSB)
  95 + * then
  96 + * wC_K4[i][Ki,0 Ki,1 Ki,2 Ki,3] gives the C bits for Ki,0..3,
  97 + * wD_K4[i][Ki,0 Ki,1 Ki,2 Ki,3] the corresponding D bits,
  98 + * wC_K3[i][Ki,4 Ki,5 Ki,6] the C bits for Ki,4..6,
  99 + * and wD_K3[i][Ki,4 Ki,5 Ki,6] the D bits for Ki,4..6.
  100 + * Ki,7 is ignored since it is the nominal parity bit.
  101 + * We could just use a single table for [i][Ki,0 .. Ki,6] but that
  102 + * would take a lot of storage for such a rarely-used function.
  103 + */
  104 +
  105 +static word32 wC_K4[8][16], wC_K3[8][8];
  106 +static word32 wD_K4[8][16], wD_K3[8][8];
  107 +
  108 +/*
  109 + * Successive Ci and Di for the sixteen steps in the key schedule are
  110 + * created by independent 28-bit left circular shifts on C and D.
  111 + * The shift count varies with the step number.
  112 + */
  113 +static tiny preshift[16] = {
  114 + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
  115 +};
  116 +
  117 +/*
  118 + * Each step in the key schedule is generated by selecting 48 bits
  119 + * (8 groups of 6 bits) from the appropriately shifted Ci and Di.
  120 + * bCD_KS, indexed by the key schedule bit number, gives the bit number
  121 + * in CD (CD1 = MSB of C, CD28 = LSB of C, CD29 = MSB of D, CD56 = LSB of D)
  122 + * which determines that bit of the key schedule.
  123 + * Note that only C bits (1..28) appear in the first (upper) 24 bits of
  124 + * the key schedule, and D bits (29..56) in the second (lower) 24 bits.
  125 + * This is the "permuted-choice-2" table.
  126 + */
  127 +
  128 +static tiny bCD_KS[48] = {
  129 + 14, 17, 11, 24, 1, 5,
  130 + 3, 28, 15, 6, 21, 10,
  131 + 23, 19, 12, 4, 26, 8,
  132 + 16, 7, 27, 20, 13, 2,
  133 + 41, 52, 31, 37, 47, 55,
  134 + 30, 40, 51, 45, 33, 48,
  135 + 44, 49, 39, 56, 34, 53,
  136 + 46, 42, 50, 36, 29, 32,
  137 +};
  138 +
  139 +/*
  140 + * We invert bCD_KS into a pair of tables which map groups of 4
  141 + * C or D bits into corresponding key schedule bits.
  142 + * We represent each step of the key schedule as 8 groups of 8 bits,
  143 + * with the 6 real bits right-justified in each 8-bit group.
  144 + * hKS_C4[i][C4i+1 .. C4i+4] gives the bits in the high order (first four)
  145 + * key schedule "bytes" which correspond to C bits 4i+1 .. 4i+4.
  146 + * lKS_D4[i][D4i+1 .. D4i+4] gives the appropriate bits in the latter (last 4)
  147 + * key schedule bytes, from the corresponding D bits.
  148 + */
  149 +
  150 +static word32 hKS_C4[7][16];
  151 +static word32 lKS_D4[7][16];
  152 +
  153 +/*
  154 + * Encryption/decryption.
  155 + * Before beginning, and after ending, we perform another useless permutation
  156 + * on the bits in the data block.
  157 + *
  158 + * The initial permutation and its inverse, final permutation
  159 + * are too simple to need a table for. If we break the input I1 .. I64 into
  160 + * 8-bit chunks I0,0 I0,1 ... I0,7 I1,0 I1,1 ... I7,7
  161 + * then the initial permutation sets LR as follows:
  162 + * L = I7,1 I6,1 I5,1 ... I0,1 I7,3 I6,3 ... I0,3 I7,5 ... I0,5 I7,7 ... I0,7
  163 + * and
  164 + * R = I7,0 I6,0 I5,0 ... I0,0 I7,2 I6,2 ... I0,2 I7,4 ... I0,4 I7,6 ... I0,6
  165 + *
  166 + * If we number the bits in the final LR similarly,
  167 + * L = L0,0 L0,1 ... L3,7 R = R0,0 R0,1 ... R3,7
  168 + * then the output is
  169 + * O = R0,7 L0,7 R1,7 L1,7 ... R3,7 L3,7 R0,6 L0,6 ... L3,6 R0,5 ... R3,0 L3,0
  170 + *
  171 + * To speed I => LR shuffling we use an array of 32-bit values indexed by
  172 + * 8-bit input bytes.
  173 + * wL_I8[ 0 I0,1 0 I0,3 0 I0,5 0 I0,7 ] = the corresponding L bits.
  174 + * Other R and L bits are derived from wL_I8 by shifting.
  175 + *
  176 + * To speed LR => O shuffling, an array of 32-bit values indexed by 4-bit lumps:
  177 + * wO_L4[ L0,4 L0,5 L0,6 L0,7 ] = the corresponding high-order 32 O bits.
  178 + */
  179 +
  180 +static word32 wL_I8[0x55 + 1];
  181 +static word32 wO_L4[16];
  182 +
  183 +/*
  184 + * Core of encryption/decryption.
  185 + * In each key schedule stage, we:
  186 + * take 8 overlapping groups of 6 bits each from R
  187 + * (the NBS tabulates the bit selections in the E table,
  188 + * but it's so simple we just use shifting to get the right bits)
  189 + * XOR each group with the corresponding bits from the key schedule
  190 + * Use the resulting 6 bits as an index into the appropriate S table
  191 + * (there are 8 such tables, one per group of 6 bits)
  192 + * Each S entry yields 4 bits.
  193 + * The 8 groups of 4 bits are catenated into a 32-bit value.
  194 + * Those 32 bits are permuted according to the P table.
  195 + * Finally the permuted 32-bit value is XORed with L and becomes
  196 + * the R value for the next stage, while the previous R becomes the new L.
  197 + *
  198 + * Here, we merge the P permutation with the S tables by making the
  199 + * S entries be 32-bit masks, already suitably permuted.
  200 + * Also, the bits in each six-bit group must be permuted before use as
  201 + * an index into the NBS-tabulated S tables.
  202 + * We rearrange entries in wPS so that natural bit order can be used.
  203 + */
  204 +
  205 +static word32 wPS[8][64];
  206 +
  207 +static tiny P[32] = {
  208 + 16, 7, 20, 21,
  209 + 29, 12, 28, 17,
  210 + 1, 15, 23, 26,
  211 + 5, 18, 31, 10,
  212 + 2, 8, 24, 14,
  213 + 32, 27, 3, 9,
  214 + 19, 13, 30, 6,
  215 + 22, 11, 4, 25,
  216 +};
  217 +
  218 +static tiny S[8][64] = {
  219 + {
  220 + 14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
  221 + 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
  222 + 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
  223 + 15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
  224 + },
  225 +
  226 + {
  227 + 15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
  228 + 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
  229 + 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
  230 + 13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
  231 + },
  232 +
  233 + {
  234 + 10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
  235 + 13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
  236 + 13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
  237 + 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
  238 + },
  239 +
  240 + {
  241 + 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
  242 + 13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
  243 + 10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
  244 + 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
  245 + },
  246 +
  247 + {
  248 + 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
  249 + 14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
  250 + 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
  251 + 11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
  252 + },
  253 +
  254 + {
  255 + 12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
  256 + 10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
  257 + 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
  258 + 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
  259 + },
  260 +
  261 + {
  262 + 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
  263 + 13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
  264 + 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
  265 + 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
  266 + },
  267 +
  268 + {
  269 + 13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
  270 + 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
  271 + 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
  272 + 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
  273 + },
  274 +};
  275 +
  276 +static void buildtables( void )
  277 +{
  278 + register int i, j;
  279 + register word32 v;
  280 + word32 wC_K[64], wD_K[64];
  281 + word32 hKS_C[28], lKS_D[28];
  282 + int Smap[64];
  283 + word32 wP[32];
  284 +
  285 +#if USG
  286 +# define ZERO(array) memset((char *)(array), '\0', sizeof(array))
  287 +#else
  288 +# if BSD
  289 +# define ZERO(array) bzero((char *)(array), sizeof(array))
  290 +# else
  291 +# define ZERO(array) { register word32 *p = (word32 *)(array); \
  292 + i = sizeof(array) / sizeof(*p); \
  293 + do { *p++ = 0; } while(--i > 0); \
  294 + }
  295 +# endif
  296 +#endif
  297 +
  298 +
  299 + /* Invert permuted-choice-1 (key => C,D) */
  300 +
  301 + ZERO(wC_K);
  302 + ZERO(wD_K);
  303 + v = 1;
  304 + for(j = 28; --j >= 0; ) {
  305 + wC_K[ bK_C[j] - 1 ] = wD_K[ bK_D[j] - 1 ] = v;
  306 + v += v; /* (i.e. v <<= 1) */
  307 + }
  308 +
  309 + for(i = 0; i < 64; i++) {
  310 + int t = 8 >> (i & 3);
  311 + for(j = 0; j < 16; j++) {
  312 + if(j & t) {
  313 + wC_K4[i >> 3][j] |= wC_K[i];
  314 + wD_K4[i >> 3][j] |= wD_K[i];
  315 + if(j < 8) {
  316 + wC_K3[i >> 3][j] |= wC_K[i + 3];
  317 + wD_K3[i >> 3][j] |= wD_K[i + 3];
  318 + }
  319 + }
  320 + }
  321 + /* Generate the sequence 0,1,2,3, 8,9,10,11, ..., 56,57,58,59. */
  322 + if(t == 1) i += 4;
  323 + }
  324 +
  325 + /* Invert permuted-choice-2 */
  326 +
  327 + ZERO(hKS_C);
  328 + ZERO(lKS_D);
  329 + v = 1;
  330 + for(i = 24; (i -= 6) >= 0; ) {
  331 + j = i+5;
  332 + do {
  333 + hKS_C[ bCD_KS[j] - 1 ] = lKS_D[ bCD_KS[j+24] - 28 - 1 ] = v;
  334 + v += v; /* Like v <<= 1 but may be faster */
  335 + } while(--j >= i);
  336 + v <<= 2; /* Keep byte aligned */
  337 + }
  338 +
  339 + for(i = 0; i < 28; i++) {
  340 + v = 8 >> (i & 3);
  341 + for(j = 0; j < 16; j++) {
  342 + if(j & v) {
  343 + hKS_C4[i >> 2][j] |= hKS_C[i];
  344 + lKS_D4[i >> 2][j] |= lKS_D[i];
  345 + }
  346 + }
  347 + }
  348 +
  349 + /* Initial permutation */
  350 +
  351 + for(i = 0; i <= 0x55; i++) {
  352 + v = 0;
  353 + if(i & 64) v = (word32) 1 << 24;
  354 + if(i & 16) v |= (word32) 1 << 16;
  355 + if(i & 4) v |= (word32) 1 << 8;
  356 + if(i & 1) v |= 1;
  357 + wL_I8[i] = v;
  358 + }
  359 +
  360 + /* Final permutation */
  361 +
  362 + for(i = 0; i < 16; i++) {
  363 + v = 0;
  364 + if(i & 1) v = (word32) 1 << 24;
  365 + if(i & 2) v |= (word32) 1 << 16;
  366 + if(i & 4) v |= (word32) 1 << 8;
  367 + if(i & 8) v |= (word32) 1;
  368 + wO_L4[i] = v;
  369 + }
  370 +
  371 + /* Funny bit rearrangement on second index into S tables */
  372 +
  373 + for(i = 0; i < 64; i++) {
  374 + Smap[i] = (i & 0x20) | (i & 1) << 4 | (i & 0x1e) >> 1;
  375 + }
  376 +
  377 + /* Invert permutation P into mask indexed by R bit number */
  378 +
  379 + v = 1;
  380 + for(i = 32; --i >= 0; ) {
  381 + wP[ P[i] - 1 ] = v;
  382 + v += v;
  383 + }
  384 +
  385 + /* Build bit-mask versions of S tables, indexed in natural bit order */
  386 +
  387 + for(i = 0; i < 8; i++) {
  388 + for(j = 0; j < 64; j++) {
  389 + int k, t;
  390 +
  391 + t = S[i][ Smap[j] ];
  392 + for(k = 0; k < 4; k++) {
  393 + if(t & 8)
  394 + wPS[i][j] |= wP[4*i + k];
  395 + t += t;
  396 + }
  397 + }
  398 + }
  399 +}
  400 +
  401 +
  402 +void fsetkey(char key[8], keysched *ks)
  403 +{
  404 + register int i;
  405 + register word32 C, D;
  406 + static int built = 0;
  407 +
  408 + if(!built) {
  409 + buildtables();
  410 + built = 1;
  411 + }
  412 +
  413 + C = D = 0;
  414 + for(i = 0; i < 8; i++) {
  415 + register int v;
  416 +
  417 + v = key[i] >> 1; /* Discard "parity" bit */
  418 + C |= wC_K4[i][(v>>3) & 15] | wC_K3[i][v & 7];
  419 + D |= wD_K4[i][(v>>3) & 15] | wD_K3[i][v & 7];
  420 + }
  421 +
  422 + /*
  423 + * C and D now hold the suitably right-justified
  424 + * 28 permuted key bits each.
  425 + */
  426 + for(i = 0; i < 16; i++) {
  427 +#ifdef CRAY
  428 +#define choice2(x, v) x[6][v&15] | x[5][(v>>4)&15] | x[4][(v>>8)&15] | \
  429 + x[3][(v>>12)&15] | x[2][(v>>16)&15] | x[1][(v>>20)&15] | \
  430 + x[0][(v>>24)&15]
  431 +#else
  432 + register word32 *ap;
  433 +
  434 +# define choice2(x, v) ( \
  435 + ap = &(x)[0][0], \
  436 + ap[16*6 + (v&15)] | \
  437 + ap[16*5 + ((v>>4)&15)] | ap[16*4 + ((v>>8)&15)] | \
  438 + ap[16*3 + ((v>>12)&15)] | ap[16*2 + ((v>>16)&15)] | \
  439 + ap[16*1 + ((v>>20)&15)] | ap[16*0 + ((v>>24)&15)] )
  440 +#endif
  441 +
  442 +
  443 + /* 28-bit left circular shift */
  444 + C <<= preshift[i];
  445 + C = ((C >> 28) & 3) | (C & (((word32)1<<28) - 1));
  446 + ks->KS[i].h = choice2(hKS_C4, C);
  447 +
  448 + D <<= preshift[i];
  449 + D = ((D >> 28) & 3) | (D & (((word32)1<<28) - 1));
  450 + ks->KS[i].l = choice2(lKS_D4, D);
  451 + }
  452 +}
  453 +
  454 +void
  455 +fencrypt(char block[8], int decrypt, keysched *ks)
  456 +{
  457 + int i;
  458 + register word32 L, R;
  459 + register struct keystage *ksp;
  460 + register word32 *ap;
  461 +
  462 + /* Initial permutation */
  463 +
  464 + L = R = 0;
  465 + i = 7;
  466 + ap = wL_I8;
  467 + do {
  468 + register int v;
  469 +
  470 + v = block[i]; /* Could optimize according to ENDIAN */
  471 + L = ap[v & 0x55] | (L << 1);
  472 + R = ap[(v >> 1) & 0x55] | (R << 1);
  473 + } while(--i >= 0);
  474 +
  475 + if(decrypt) {
  476 + ksp = &ks->KS[15];
  477 + } else {
  478 + ksp = &ks->KS[0];
  479 + }
  480 +
  481 +#ifdef CRAY
  482 +# define PS(i,j) wPS[i][j]
  483 +#else
  484 +# define PS(i,j) ap[64*(i) + (j)]
  485 + ap = &wPS[0][0];
  486 +#endif
  487 +
  488 + i = 16;
  489 + do {
  490 + register word32 k, tR;
  491 +
  492 + tR = (R >> 15) | (R << 17);
  493 +
  494 + k = ksp->h;
  495 + L ^= PS(0, ((tR >> 12) ^ (k >> 24)) & 63)
  496 + | PS(1, ((tR >> 8) ^ (k >> 16)) & 63)
  497 + | PS(2, ((tR >> 4) ^ (k >> 8)) & 63)
  498 + | PS(3, (tR ^ k) & 63);
  499 +
  500 + k = ksp->l;
  501 + L ^= PS(4, ((R >> 11) ^ (k >> 24)) & 63)
  502 + | PS(5, ((R >> 7) ^ (k >> 16)) & 63)
  503 + | PS(6, ((R >> 3) ^ (k >> 8)) & 63)
  504 + | PS(7, ((tR >> 16) ^ k) & 63);
  505 +
  506 + tR = L;
  507 + L = R;
  508 + R = tR;
  509 +
  510 +
  511 + if(decrypt)
  512 + ksp--;
  513 + else
  514 + ksp++;
  515 + } while(--i > 0);
  516 + {
  517 + register word32 t;
  518 +
  519 +#ifdef CRAY
  520 +# define FP(k) (wO_L4[ (L >> (k)) & 15 ] << 1 | wO_L4[ (R >> (k)) & 15 ])
  521 +#else
  522 +# define FP(k) (ap[ (L >> (k)) & 15 ] << 1 | ap[ (R >> (k)) & 15 ])
  523 +
  524 + ap = wO_L4;
  525 +#endif
  526 +
  527 + t = FP(0) | (FP(8) | (FP(16) | (FP(24) << 2)) << 2) << 2;
  528 + R = FP(4) | (FP(12) | (FP(20) | (FP(28) << 2)) << 2) << 2;
  529 + L = t;
  530 + }
  531 + {
  532 + register word32 t;
  533 + register char *bp;
  534 +
  535 + bp = &block[7];
  536 + t = R;
  537 + *bp = t & 255;
  538 + *--bp = (t >>= 8) & 255;
  539 + *--bp = (t >>= 8) & 255;
  540 + *--bp = (t >> 8) & 255;
  541 + t = L;
  542 + *--bp = t & 255;
  543 + *--bp = (t >>= 8) & 255;
  544 + *--bp = (t >>= 8) & 255;
  545 + *--bp = (t >> 8) & 255;
  546 + }
  547 +}
  548 +
... ...
  1 +#ifndef DES56_H
  2 +#define DES56_H 1
  3 +/*
  4 + * Fast implementation of the DES, as described in the Federal Register,
  5 + * Vol. 40, No. 52, p. 12134, March 17, 1975.
  6 + *
  7 + * Stuart Levy, Minnesota Supercomputer Center, April 1988.
  8 + * Currently (2007) slevy@ncsa.uiuc.edu
  9 + * NCSA, University of Illinois Urbana-Champaign
  10 + *
  11 + * Calling sequence:
  12 + *
  13 + * typedef unsigned long keysched[32];
  14 + *
  15 + * fsetkey(key, keysched) / * Converts a DES key to a "key schedule" * /
  16 + * unsigned char key[8];
  17 + * keysched *ks;
  18 + *
  19 + * fencrypt(block, decrypt, keysched) / * En/decrypts one 64-bit block * /
  20 + * unsigned char block[8]; / * data, en/decrypted in place * /
  21 + * int decrypt; / * 0=>encrypt, 1=>decrypt * /
  22 + * keysched *ks; / * key schedule, as set by fsetkey * /
  23 + *
  24 + * Key and data block representation:
  25 + * The 56-bit key (bits 1..64 including "parity" bits 8, 16, 24, ..., 64)
  26 + * and the 64-bit data block (bits 1..64)
  27 + * are each stored in arrays of 8 bytes.
  28 + * Following the NBS numbering, the MSB has the bit number 1, so
  29 + * key[0] = 128*bit1 + 64*bit2 + ... + 1*bit8, ... through
  30 + * key[7] = 128*bit57 + 64*bit58 + ... + 1*bit64.
  31 + * In the key, "parity" bits are not checked; their values are ignored.
  32 + *
  33 +*/
  34 +
  35 +/*
  36 +===============================================================================
  37 +License
  38 +
  39 +des56.c is licensed under the terms of the MIT license reproduced below.
  40 +This means that des56.c is free software and can be used for both academic
  41 +and commercial purposes at absolutely no cost.
  42 +===============================================================================
  43 +Copyright (C) 1988 Stuart Levy
  44 +
  45 +Permission is hereby granted, free of charge, to any person obtaining a copy
  46 +of this software and associated documentation files (the "Software"), to deal
  47 +in the Software without restriction, including without limitation the rights
  48 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  49 +copies of the Software, and to permit persons to whom the Software is
  50 +furnished to do so, subject to the following conditions:
  51 +
  52 +The above copyright notice and this permission notice shall be included in
  53 +all copies or substantial portions of the Software.
  54 +
  55 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  56 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  57 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  58 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  59 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  60 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  61 +THE SOFTWARE.
  62 + */
  63 +
  64 +typedef unsigned long word32;
  65 +typedef unsigned char tiny;
  66 +
  67 +typedef struct keysched {
  68 + struct keystage {
  69 + word32 h, l;
  70 + } KS[16];
  71 +} keysched;
  72 +
  73 +extern void fsetkey(char key[8], keysched *ks);
  74 +
  75 +extern void fencrypt(char block[8], int decrypt, keysched *ks);
  76 +
  77 +#endif /*DES56_H*/
... ...
  1 +#include <stdlib.h>
  2 +#include <string.h>
  3 +
  4 +#include "des56.h"
  5 +
  6 +#include "lua.h"
  7 +#include "lauxlib.h"
  8 +
  9 +#include "ldes56.h"
  10 +
  11 +static int des56_decrypt( lua_State *L )
  12 +{
  13 + char* decypheredText;
  14 + keysched KS;
  15 + int rel_index, abs_index;
  16 + size_t cypherlen;
  17 + const char *cypheredText =
  18 + luaL_checklstring( L, 1, &cypherlen );
  19 + const char *key = luaL_optstring( L, 2, NULL );
  20 + int padinfo;
  21 +
  22 + padinfo = cypheredText[cypherlen-1];
  23 + cypherlen--;
  24 +
  25 + /* Aloca array */
  26 + decypheredText =
  27 + (char *) malloc( (cypherlen+1) * sizeof(char));
  28 + if(decypheredText == NULL) {
  29 + lua_pushstring(L, "Error decrypting file. Not enough memory.");
  30 + lua_error(L);
  31 + }
  32 +
  33 + /* Inicia decifragem */
  34 + if (key && strlen(key) >= 8)
  35 + {
  36 + char k[8];
  37 + int i;
  38 +
  39 + for (i=0; i<8; i++)
  40 + k[i] = (unsigned char)key[i];
  41 + fsetkey(k, &KS);
  42 + } else {
  43 + lua_pushstring(L, "Error decrypting file. Invalid key.");
  44 + lua_error(L);
  45 + }
  46 +
  47 + rel_index = 0;
  48 + abs_index = 0;
  49 +
  50 + while (abs_index < (int) cypherlen)
  51 + {
  52 + decypheredText[abs_index] = cypheredText[abs_index];
  53 + abs_index++;
  54 + rel_index++;
  55 + if( rel_index == 8 )
  56 + {
  57 + rel_index = 0;
  58 + fencrypt(&(decypheredText[abs_index - 8]), 1, &KS);
  59 + }
  60 + }
  61 + decypheredText[abs_index] = 0;
  62 +
  63 + lua_pushlstring(L, decypheredText, (abs_index-padinfo));
  64 + free( decypheredText );
  65 + return 1;
  66 +}
  67 +
  68 +static int des56_crypt( lua_State *L )
  69 +{
  70 + char *cypheredText;
  71 + keysched KS;
  72 + int rel_index, pad, abs_index;
  73 + size_t plainlen;
  74 + const char *plainText = luaL_checklstring( L, 1, &plainlen );
  75 + const char *key = luaL_optstring( L, 2, NULL );
  76 +
  77 + cypheredText = (char *) malloc( (plainlen+8) * sizeof(char));
  78 + if(cypheredText == NULL) {
  79 + lua_pushstring(L, "Error encrypting file. Not enough memory.");
  80 + lua_error(L);
  81 + }
  82 +
  83 + if (key && strlen(key) >= 8)
  84 + {
  85 + char k[8];
  86 + int i;
  87 +
  88 + for (i=0; i<8; i++)
  89 + k[i] = (unsigned char)key[i];
  90 + fsetkey(k, &KS);
  91 + } else {
  92 + lua_pushstring(L, "Error encrypting file. Invalid key.");
  93 + lua_error(L);
  94 + }
  95 +
  96 + rel_index = 0;
  97 + abs_index = 0;
  98 + while (abs_index < (int) plainlen) {
  99 + cypheredText[abs_index] = plainText[abs_index];
  100 + abs_index++;
  101 + rel_index++;
  102 + if( rel_index == 8 ) {
  103 + rel_index = 0;
  104 + fencrypt(&(cypheredText[abs_index - 8]), 0, &KS);
  105 + }
  106 + }
  107 +
  108 + pad = 0;
  109 + if(rel_index != 0) { /* Pads remaining bytes with zeroes */
  110 + while(rel_index < 8)
  111 + {
  112 + pad++;
  113 + cypheredText[abs_index++] = 0;
  114 + rel_index++;
  115 + }
  116 + fencrypt(&(cypheredText[abs_index - 8]), 0, &KS);
  117 + }
  118 + cypheredText[abs_index] = pad;
  119 +
  120 + lua_pushlstring( L, cypheredText, abs_index+1 );
  121 + free( cypheredText );
  122 + return 1;
  123 +}
  124 +
  125 +/*
  126 +** Assumes the table is on top of the stack.
  127 +*/
  128 +static void set_info (lua_State *L) {
  129 + lua_pushliteral (L, "_COPYRIGHT");
  130 + lua_pushliteral (L, "Copyright (C) 2007 PUC-Rio");
  131 + lua_settable (L, -3);
  132 + lua_pushliteral (L, "_DESCRIPTION");
  133 + lua_pushliteral (L, "DES 56 cryptographic facilities for Lua");
  134 + lua_settable (L, -3);
  135 + lua_pushliteral (L, "_VERSION");
  136 + lua_pushliteral (L, "DES56 1.1.2");
  137 + lua_settable (L, -3);
  138 +}
  139 +
  140 +static const struct luaL_reg des56lib[] = {
  141 + {"crypt", des56_crypt},
  142 + {"decrypt", des56_decrypt},
  143 + {NULL, NULL},
  144 +};
  145 +
  146 +int luaopen_des56 (lua_State *L) {
  147 + luaL_openlib (L, "des56", des56lib, 0);
  148 + set_info (L);
  149 + return 1;
  150 +}
  151 +
  152 +
... ...
  1 +int luaopen_des56 (lua_State *L);
... ...
  1 +/**
  2 +* $Id: md5.c,v 1.2 2008/03/24 20:59:12 mascarenhas Exp $
  3 +* Hash function MD5
  4 +* @author Marcela Ozorio Suarez, Roberto I.
  5 +*/
  6 +
  7 +
  8 +#include <string.h>
  9 +
  10 +#include "md5.h"
  11 +
  12 +
  13 +#define WORD 32
  14 +#define MASK 0xFFFFFFFF
  15 +#if __STDC_VERSION__ >= 199901L
  16 +#include <stdint.h>
  17 +typedef uint32_t WORD32;
  18 +#else
  19 +typedef unsigned int WORD32;
  20 +#endif
  21 +
  22 +
  23 +/**
  24 +* md5 hash function.
  25 +* @param message: aribtary string.
  26 +* @param len: message length.
  27 +* @param output: buffer to receive the hash value. Its size must be
  28 +* (at least) HASHSIZE.
  29 +*/
  30 +void md5 (const char *message, long len, char *output);
  31 +
  32 +
  33 +
  34 +/*
  35 +** Realiza a rotacao no sentido horario dos bits da variavel 'D' do tipo WORD32.
  36 +** Os bits sao deslocados de 'num' posicoes
  37 +*/
  38 +#define rotate(D, num) (D<<num) | (D>>(WORD-num))
  39 +
  40 +/*Macros que definem operacoes relizadas pelo algoritmo md5 */
  41 +#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
  42 +#define G(x, y, z) (((x) & (z)) | ((y) & (~(z))))
  43 +#define H(x, y, z) ((x) ^ (y) ^ (z))
  44 +#define I(x, y, z) ((y) ^ ((x) | (~(z))))
  45 +
  46 +
  47 +/*vetor de numeros utilizados pelo algoritmo md5 para embaralhar bits */
  48 +static const WORD32 T[64]={
  49 + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
  50 + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
  51 + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
  52 + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
  53 + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
  54 + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
  55 + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
  56 + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
  57 + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
  58 + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
  59 + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
  60 + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
  61 + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
  62 + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
  63 + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
  64 + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
  65 +};
  66 +
  67 +
  68 +static void word32tobytes (const WORD32 *input, char *output) {
  69 + int j = 0;
  70 + while (j<4*4) {
  71 + WORD32 v = *input++;
  72 + output[j++] = (char)(v & 0xff); v >>= 8;
  73 + output[j++] = (char)(v & 0xff); v >>= 8;
  74 + output[j++] = (char)(v & 0xff); v >>= 8;
  75 + output[j++] = (char)(v & 0xff);
  76 + }
  77 +}
  78 +
  79 +
  80 +static void inic_digest(WORD32 *d) {
  81 + d[0] = 0x67452301;
  82 + d[1] = 0xEFCDAB89;
  83 + d[2] = 0x98BADCFE;
  84 + d[3] = 0x10325476;
  85 +}
  86 +
  87 +
  88 +/*funcao que implemeta os quatro passos principais do algoritmo MD5 */
  89 +static void digest(const WORD32 *m, WORD32 *d) {
  90 + int j;
  91 + /*MD5 PASSO1 */
  92 + for (j=0; j<4*4; j+=4) {
  93 + d[0] = d[0]+ F(d[1], d[2], d[3])+ m[j] + T[j]; d[0]=rotate(d[0], 7);
  94 + d[0]+=d[1];
  95 + d[3] = d[3]+ F(d[0], d[1], d[2])+ m[(j)+1] + T[j+1]; d[3]=rotate(d[3], 12);
  96 + d[3]+=d[0];
  97 + d[2] = d[2]+ F(d[3], d[0], d[1])+ m[(j)+2] + T[j+2]; d[2]=rotate(d[2], 17);
  98 + d[2]+=d[3];
  99 + d[1] = d[1]+ F(d[2], d[3], d[0])+ m[(j)+3] + T[j+3]; d[1]=rotate(d[1], 22);
  100 + d[1]+=d[2];
  101 + }
  102 + /*MD5 PASSO2 */
  103 + for (j=0; j<4*4; j+=4) {
  104 + d[0] = d[0]+ G(d[1], d[2], d[3])+ m[(5*j+1)&0x0f] + T[(j-1)+17];
  105 + d[0] = rotate(d[0],5);
  106 + d[0]+=d[1];
  107 + d[3] = d[3]+ G(d[0], d[1], d[2])+ m[((5*(j+1)+1)&0x0f)] + T[(j+0)+17];
  108 + d[3] = rotate(d[3], 9);
  109 + d[3]+=d[0];
  110 + d[2] = d[2]+ G(d[3], d[0], d[1])+ m[((5*(j+2)+1)&0x0f)] + T[(j+1)+17];
  111 + d[2] = rotate(d[2], 14);
  112 + d[2]+=d[3];
  113 + d[1] = d[1]+ G(d[2], d[3], d[0])+ m[((5*(j+3)+1)&0x0f)] + T[(j+2)+17];
  114 + d[1] = rotate(d[1], 20);
  115 + d[1]+=d[2];
  116 + }
  117 + /*MD5 PASSO3 */
  118 + for (j=0; j<4*4; j+=4) {
  119 + d[0] = d[0]+ H(d[1], d[2], d[3])+ m[(3*j+5)&0x0f] + T[(j-1)+33];
  120 + d[0] = rotate(d[0], 4);
  121 + d[0]+=d[1];
  122 + d[3] = d[3]+ H(d[0], d[1], d[2])+ m[(3*(j+1)+5)&0x0f] + T[(j+0)+33];
  123 + d[3] = rotate(d[3], 11);
  124 + d[3]+=d[0];
  125 + d[2] = d[2]+ H(d[3], d[0], d[1])+ m[(3*(j+2)+5)&0x0f] + T[(j+1)+33];
  126 + d[2] = rotate(d[2], 16);
  127 + d[2]+=d[3];
  128 + d[1] = d[1]+ H(d[2], d[3], d[0])+ m[(3*(j+3)+5)&0x0f] + T[(j+2)+33];
  129 + d[1] = rotate(d[1], 23);
  130 + d[1]+=d[2];
  131 + }
  132 + /*MD5 PASSO4 */
  133 + for (j=0; j<4*4; j+=4) {
  134 + d[0] = d[0]+ I(d[1], d[2], d[3])+ m[(7*j)&0x0f] + T[(j-1)+49];
  135 + d[0] = rotate(d[0], 6);
  136 + d[0]+=d[1];
  137 + d[3] = d[3]+ I(d[0], d[1], d[2])+ m[(7*(j+1))&0x0f] + T[(j+0)+49];
  138 + d[3] = rotate(d[3], 10);
  139 + d[3]+=d[0];
  140 + d[2] = d[2]+ I(d[3], d[0], d[1])+ m[(7*(j+2))&0x0f] + T[(j+1)+49];
  141 + d[2] = rotate(d[2], 15);
  142 + d[2]+=d[3];
  143 + d[1] = d[1]+ I(d[2], d[3], d[0])+ m[(7*(j+3))&0x0f] + T[(j+2)+49];
  144 + d[1] = rotate(d[1], 21);
  145 + d[1]+=d[2];
  146 + }
  147 +}
  148 +
  149 +
  150 +static void bytestoword32 (WORD32 *x, const char *pt) {
  151 + int i;
  152 + for (i=0; i<16; i++) {
  153 + int j=i*4;
  154 + x[i] = (((WORD32)(unsigned char)pt[j+3] << 8 |
  155 + (WORD32)(unsigned char)pt[j+2]) << 8 |
  156 + (WORD32)(unsigned char)pt[j+1]) << 8 |
  157 + (WORD32)(unsigned char)pt[j];
  158 + }
  159 +
  160 +}
  161 +
  162 +
  163 +static void put_length(WORD32 *x, long len) {
  164 + /* in bits! */
  165 + x[14] = (WORD32)((len<<3) & MASK);
  166 + x[15] = (WORD32)(len>>(32-3) & 0x7);
  167 +}
  168 +
  169 +
  170 +/*
  171 +** returned status:
  172 +* 0 - normal message (full 64 bytes)
  173 +* 1 - enough room for 0x80, but not for message length (two 4-byte words)
  174 +* 2 - enough room for 0x80 plus message length (at least 9 bytes free)
  175 +*/
  176 +static int converte (WORD32 *x, const char *pt, int num, int old_status) {
  177 + int new_status = 0;
  178 + char buff[64];
  179 + if (num<64) {
  180 + memcpy(buff, pt, num); /* to avoid changing original string */
  181 + memset(buff+num, 0, 64-num);
  182 + if (old_status == 0)
  183 + buff[num] = '\200';
  184 + new_status = 1;
  185 + pt = buff;
  186 + }
  187 + bytestoword32(x, pt);
  188 + if (num <= (64 - 9))
  189 + new_status = 2;
  190 + return new_status;
  191 +}
  192 +
  193 +
  194 +
  195 +void md5 (const char *message, long len, char *output) {
  196 + WORD32 d[4];
  197 + int status = 0;
  198 + long i = 0;
  199 + inic_digest(d);
  200 + while (status != 2) {
  201 + WORD32 d_old[4];
  202 + WORD32 wbuff[16];
  203 + int numbytes = (len-i >= 64) ? 64 : len-i;
  204 + /*salva os valores do vetor digest*/
  205 + d_old[0]=d[0]; d_old[1]=d[1]; d_old[2]=d[2]; d_old[3]=d[3];
  206 + status = converte(wbuff, message+i, numbytes, status);
  207 + if (status == 2) put_length(wbuff, len);
  208 + digest(wbuff, d);
  209 + d[0]+=d_old[0]; d[1]+=d_old[1]; d[2]+=d_old[2]; d[3]+=d_old[3];
  210 + i += numbytes;
  211 + }
  212 + word32tobytes(d, output);
  213 +}
  214 +
... ...
  1 +/**
  2 +* $Id: md5.h,v 1.2 2006/03/03 15:04:49 tomas Exp $
  3 +* Cryptographic module for Lua.
  4 +* @author Roberto Ierusalimschy
  5 +*/
  6 +
  7 +
  8 +#ifndef md5_h
  9 +#define md5_h
  10 +
  11 +#include <lua.h>
  12 +
  13 +
  14 +#define HASHSIZE 16
  15 +
  16 +void md5 (const char *message, long len, char *output);
  17 +int luaopen_md5_core (lua_State *L);
  18 +
  19 +
  20 +#endif
... ...
  1 +/**
  2 +* $Id: md5lib.c,v 1.10 2008/05/12 20:51:27 carregal Exp $
  3 +* Cryptographic and Hash functions for Lua
  4 +* @author Roberto Ierusalimschy
  5 +*/
  6 +
  7 +
  8 +#include <stdlib.h>
  9 +#include <string.h>
  10 +#include <time.h>
  11 +
  12 +#include <lua.h>
  13 +#include <lauxlib.h>
  14 +
  15 +#if ! defined (LUA_VERSION_NUM) || LUA_VERSION_NUM < 501
  16 +#include "compat-5.1.h"
  17 +#endif
  18 +
  19 +#include "md5.h"
  20 +
  21 +
  22 +/**
  23 +* Hash function. Returns a hash for a given string.
  24 +* @param message: arbitrary binary string.
  25 +* @return A 128-bit hash string.
  26 +*/
  27 +static int lmd5 (lua_State *L) {
  28 + char buff[16];
  29 + size_t l;
  30 + const char *message = luaL_checklstring(L, 1, &l);
  31 + md5(message, l, buff);
  32 + lua_pushlstring(L, buff, 16L);
  33 + return 1;
  34 +}
  35 +
  36 +
  37 +/**
  38 +* X-Or. Does a bit-a-bit exclusive-or of two strings.
  39 +* @param s1: arbitrary binary string.
  40 +* @param s2: arbitrary binary string with same length as s1.
  41 +* @return a binary string with same length as s1 and s2,
  42 +* where each bit is the exclusive-or of the corresponding bits in s1-s2.
  43 +*/
  44 +static int ex_or (lua_State *L) {
  45 + size_t l1, l2;
  46 + const char *s1 = luaL_checklstring(L, 1, &l1);
  47 + const char *s2 = luaL_checklstring(L, 2, &l2);
  48 + luaL_Buffer b;
  49 + luaL_argcheck( L, l1 == l2, 2, "lengths must be equal" );
  50 + luaL_buffinit(L, &b);
  51 + while (l1--) luaL_putchar(&b, (*s1++)^(*s2++));
  52 + luaL_pushresult(&b);
  53 + return 1;
  54 +}
  55 +
  56 +
  57 +static void checkseed (lua_State *L) {
  58 + if (lua_isnone(L, 3)) { /* no seed? */
  59 + time_t tm = time(NULL); /* for `random' seed */
  60 + lua_pushlstring(L, (char *)&tm, sizeof(tm));
  61 + }
  62 +}
  63 +
  64 +
  65 +#define MAXKEY 256
  66 +#define BLOCKSIZE 16
  67 +
  68 +
  69 +
  70 +static int initblock (lua_State *L, const char *seed, int lseed, char *block) {
  71 + size_t lkey;
  72 + const char *key = luaL_checklstring(L, 2, &lkey);
  73 + if (lkey > MAXKEY)
  74 + luaL_error(L, "key too long (> %d)", MAXKEY);
  75 + memset(block, 0, BLOCKSIZE);
  76 + memcpy(block, seed, lseed);
  77 + memcpy(block+BLOCKSIZE, key, lkey);
  78 + return (int)lkey+BLOCKSIZE;
  79 +}
  80 +
  81 +
  82 +static void codestream (lua_State *L, const char *msg, size_t lmsg,
  83 + char *block, int lblock) {
  84 + luaL_Buffer b;
  85 + luaL_buffinit(L, &b);
  86 + while (lmsg > 0) {
  87 + char code[BLOCKSIZE];
  88 + int i;
  89 + md5(block, lblock, code);
  90 + for (i=0; i<BLOCKSIZE && lmsg > 0; i++, lmsg--)
  91 + code[i] ^= *msg++;
  92 + luaL_addlstring(&b, code, i);
  93 + memcpy(block, code, i); /* update seed */
  94 + }
  95 + luaL_pushresult(&b);
  96 +}
  97 +
  98 +
  99 +static void decodestream (lua_State *L, const char *cypher, size_t lcypher,
  100 + char *block, int lblock) {
  101 + luaL_Buffer b;
  102 + luaL_buffinit(L, &b);
  103 + while (lcypher > 0) {
  104 + char code[BLOCKSIZE];
  105 + int i;
  106 + md5(block, lblock, code); /* update seed */
  107 + for (i=0; i<BLOCKSIZE && lcypher > 0; i++, lcypher--)
  108 + code[i] ^= *cypher++;
  109 + luaL_addlstring(&b, code, i);
  110 + memcpy(block, cypher-i, i);
  111 + }
  112 + luaL_pushresult(&b);
  113 +}
  114 +
  115 +
  116 +/**
  117 +* Encrypts a string. Uses the hash function md5 in CFB (Cipher-feedback
  118 +* mode).
  119 +* @param message: arbitrary binary string to be encrypted.
  120 +* @param key: arbitrary binary string to be used as a key.
  121 +* @param [seed]: optional arbitrary binary string to be used as a seed.
  122 +* if no seed is provided, the function uses the result of
  123 +* <code>time()</code> as a seed.
  124 +* @return The cyphertext (as a binary string).
  125 +*/
  126 +static int crypt (lua_State *L) {
  127 + size_t lmsg;
  128 + const char *msg = luaL_checklstring(L, 1, &lmsg);
  129 + size_t lseed;
  130 + const char *seed;
  131 + int lblock;
  132 + char block[BLOCKSIZE+MAXKEY];
  133 + checkseed(L);
  134 + seed = luaL_checklstring(L, 3, &lseed);
  135 + if (lseed > BLOCKSIZE)
  136 + luaL_error(L, "seed too long (> %d)", BLOCKSIZE);
  137 + /* put seed and seed length at the beginning of result */
  138 + block[0] = (char)lseed;
  139 + memcpy(block+1, seed, lseed);
  140 + lua_pushlstring(L, block, lseed+1); /* to concat with result */
  141 + lblock = initblock(L, seed, lseed, block);
  142 + codestream(L, msg, lmsg, block, lblock);
  143 + lua_concat(L, 2);
  144 + return 1;
  145 +}
  146 +
  147 +
  148 +/**
  149 +* Decrypts a string. For any message, key, and seed, we have that
  150 +* <code>decrypt(crypt(msg, key, seed), key) == msg</code>.
  151 +* @param cyphertext: message to be decrypted (this must be the result of
  152 + a previous call to <code>crypt</code>.
  153 +* @param key: arbitrary binary string to be used as a key.
  154 +* @return The plaintext.
  155 +*/
  156 +static int decrypt (lua_State *L) {
  157 + size_t lcyphertext;
  158 + const char *cyphertext = luaL_checklstring(L, 1, &lcyphertext);
  159 + size_t lseed = cyphertext[0];
  160 + const char *seed = cyphertext+1;
  161 + int lblock;
  162 + char block[BLOCKSIZE+MAXKEY];
  163 + luaL_argcheck(L, lcyphertext >= lseed+1 && lseed <= BLOCKSIZE, 1,
  164 + "invalid cyphered string");
  165 + cyphertext += lseed+1;
  166 + lcyphertext -= lseed+1;
  167 + lblock = initblock(L, seed, lseed, block);
  168 + decodestream(L, cyphertext, lcyphertext, block, lblock);
  169 + return 1;
  170 +}
  171 +
  172 +
  173 +/*
  174 +** Assumes the table is on top of the stack.
  175 +*/
  176 +static void set_info (lua_State *L) {
  177 + lua_pushliteral (L, "_COPYRIGHT");
  178 + lua_pushliteral (L, "Copyright (C) 2003 PUC-Rio");
  179 + lua_settable (L, -3);
  180 + lua_pushliteral (L, "_DESCRIPTION");
  181 + lua_pushliteral (L, "Basic cryptographic facilities");
  182 + lua_settable (L, -3);
  183 + lua_pushliteral (L, "_VERSION");
  184 + lua_pushliteral (L, "MD5 1.1.2");
  185 + lua_settable (L, -3);
  186 +}
  187 +
  188 +
  189 +static struct luaL_reg md5lib[] = {
  190 + {"sum", lmd5},
  191 + {"exor", ex_or},
  192 + {"crypt", crypt},
  193 + {"decrypt", decrypt},
  194 + {NULL, NULL}
  195 +};
  196 +
  197 +
  198 +int luaopen_md5_core (lua_State *L) {
  199 + luaL_openlib(L, "md5.core", md5lib, 0);
  200 + set_info (L);
  201 + return 1;
  202 +}
  203 +
... ...