Logo Search packages:      
Sourcecode: cfs version File versions  Download package

mcgsbox.c

/*
 * The author of this software is Matt Blaze.
 *              Copyright (c) 1992, 1993, 1994 by AT&T.
 * Permission to use, copy, and modify this software without fee
 * is hereby granted, provided that this entire notice is included in
 * all copies of any software which is or includes a copy or
 * modification of this software and in all copies of the supporting
 * documentation for such software.
 *
 * This software is subject to United States export controls.
 *
 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
 */

/*
 * MacGuffin optimized table initialization and key setup
 *
 * 10/3/94 matt blaze
 */


#include "mcg.h"

/*
 * the 8 s-boxes, expanded to put the output bits in the right
 * places.  note that these are the des s-boxes (in left-right,
 * not cannonical, order), but with only the "outer" two output
 * bits.
 */
unsigned short sboxes[8][64] = {
/* 0 (S1) */
      {0x0002, 0x0000, 0x0000, 0x0003, 0x0003, 0x0001, 0x0001, 0x0000,
       0x0000, 0x0002, 0x0003, 0x0000, 0x0003, 0x0003, 0x0002, 0x0001,
       0x0001, 0x0002, 0x0002, 0x0000, 0x0000, 0x0002, 0x0002, 0x0003,
       0x0001, 0x0003, 0x0003, 0x0001, 0x0000, 0x0001, 0x0001, 0x0002,
       0x0000, 0x0003, 0x0001, 0x0002, 0x0002, 0x0002, 0x0002, 0x0000,
       0x0003, 0x0000, 0x0000, 0x0003, 0x0000, 0x0001, 0x0003, 0x0001,
       0x0003, 0x0001, 0x0002, 0x0003, 0x0003, 0x0001, 0x0001, 0x0002,
       0x0001, 0x0002, 0x0002, 0x0000, 0x0001, 0x0000, 0x0000, 0x0003},
/* 1 (S2) */
      {0x000c, 0x0004, 0x0004, 0x000c, 0x0008, 0x0000, 0x0008, 0x0004,
       0x0000, 0x000c, 0x000c, 0x0000, 0x0004, 0x0008, 0x0000, 0x0008,
       0x000c, 0x0008, 0x0004, 0x0000, 0x0000, 0x0004, 0x000c, 0x0008,
       0x0008, 0x0000, 0x0000, 0x000c, 0x0004, 0x000c, 0x0008, 0x0004,
       0x0000, 0x000c, 0x0008, 0x0008, 0x0004, 0x0008, 0x000c, 0x0004,
       0x0008, 0x0004, 0x0000, 0x000c, 0x000c, 0x0000, 0x0004, 0x0000,
       0x0004, 0x000c, 0x0008, 0x0000, 0x0008, 0x0004, 0x0000, 0x0008,
       0x000c, 0x0000, 0x0004, 0x0004, 0x0000, 0x0008, 0x000c, 0x000c},
/* 2 (S3) */
      {0x0020, 0x0030, 0x0000, 0x0010, 0x0030, 0x0000, 0x0020, 0x0030,
       0x0000, 0x0010, 0x0010, 0x0000, 0x0030, 0x0000, 0x0010, 0x0020,
       0x0010, 0x0000, 0x0030, 0x0020, 0x0020, 0x0010, 0x0010, 0x0020,
       0x0030, 0x0020, 0x0000, 0x0030, 0x0000, 0x0030, 0x0020, 0x0010,
       0x0030, 0x0010, 0x0000, 0x0020, 0x0000, 0x0030, 0x0030, 0x0000,
       0x0020, 0x0000, 0x0030, 0x0030, 0x0010, 0x0020, 0x0000, 0x0010,
       0x0030, 0x0000, 0x0010, 0x0030, 0x0000, 0x0020, 0x0020, 0x0010,
       0x0010, 0x0030, 0x0020, 0x0010, 0x0020, 0x0000, 0x0010, 0x0020},
/* 3 (S4) */
      {0x0040, 0x00c0, 0x00c0, 0x0080, 0x0080, 0x00c0, 0x0040, 0x0040,
       0x0000, 0x0000, 0x0000, 0x00c0, 0x00c0, 0x0000, 0x0080, 0x0040,
       0x0040, 0x0000, 0x0000, 0x0040, 0x0080, 0x0000, 0x0040, 0x0080,
       0x00c0, 0x0040, 0x0080, 0x0080, 0x0000, 0x0080, 0x00c0, 0x00c0,
       0x0080, 0x0040, 0x0000, 0x00c0, 0x00c0, 0x0000, 0x0000, 0x0000,
       0x0080, 0x0080, 0x00c0, 0x0040, 0x0040, 0x00c0, 0x00c0, 0x0080,
       0x00c0, 0x00c0, 0x0040, 0x0000, 0x0040, 0x0040, 0x0080, 0x00c0,
       0x0040, 0x0080, 0x0000, 0x0040, 0x0080, 0x0000, 0x0000, 0x0080},
/* 4 (S5) */
      {0x0000, 0x0200, 0x0200, 0x0300, 0x0000, 0x0000, 0x0100, 0x0200,
       0x0100, 0x0000, 0x0200, 0x0100, 0x0300, 0x0300, 0x0000, 0x0100,
       0x0200, 0x0100, 0x0100, 0x0000, 0x0100, 0x0300, 0x0300, 0x0200,
       0x0300, 0x0100, 0x0000, 0x0300, 0x0200, 0x0200, 0x0300, 0x0000,
       0x0000, 0x0300, 0x0000, 0x0200, 0x0100, 0x0200, 0x0300, 0x0100,
       0x0200, 0x0100, 0x0300, 0x0200, 0x0100, 0x0000, 0x0200, 0x0300,
       0x0300, 0x0000, 0x0300, 0x0300, 0x0200, 0x0000, 0x0100, 0x0300,
       0x0000, 0x0200, 0x0100, 0x0000, 0x0000, 0x0100, 0x0200, 0x0100},
/* 5 (S6) */
      {0x0800, 0x0800, 0x0400, 0x0c00, 0x0800, 0x0000, 0x0c00, 0x0000,
       0x0c00, 0x0400, 0x0000, 0x0800, 0x0000, 0x0c00, 0x0800, 0x0400,
       0x0000, 0x0000, 0x0c00, 0x0400, 0x0400, 0x0c00, 0x0000, 0x0800,
       0x0800, 0x0000, 0x0400, 0x0c00, 0x0400, 0x0400, 0x0c00, 0x0800,
       0x0c00, 0x0000, 0x0800, 0x0400, 0x0c00, 0x0000, 0x0400, 0x0800,
       0x0000, 0x0c00, 0x0800, 0x0400, 0x0800, 0x0c00, 0x0400, 0x0800,
       0x0400, 0x0c00, 0x0000, 0x0800, 0x0000, 0x0400, 0x0800, 0x0400,
       0x0400, 0x0000, 0x0c00, 0x0000, 0x0c00, 0x0800, 0x0000, 0x0c00},
/* 6 (S7) */
      {0x0000, 0x3000, 0x3000, 0x0000, 0x0000, 0x3000, 0x2000, 0x1000,
       0x3000, 0x0000, 0x0000, 0x3000, 0x2000, 0x1000, 0x3000, 0x2000,
       0x1000, 0x2000, 0x2000, 0x1000, 0x3000, 0x1000, 0x1000, 0x2000,
       0x1000, 0x0000, 0x2000, 0x3000, 0x0000, 0x2000, 0x1000, 0x0000,
       0x1000, 0x0000, 0x0000, 0x3000, 0x3000, 0x3000, 0x3000, 0x2000,
       0x2000, 0x1000, 0x1000, 0x0000, 0x1000, 0x2000, 0x2000, 0x1000,
       0x2000, 0x3000, 0x3000, 0x1000, 0x0000, 0x0000, 0x2000, 0x3000,
       0x0000, 0x2000, 0x1000, 0x0000, 0x3000, 0x1000, 0x0000, 0x2000},
/* 7 (S8) */
      {0xc000, 0x4000, 0x0000, 0xc000, 0x8000, 0xc000, 0x0000, 0x8000,
       0x0000, 0x8000, 0xc000, 0x4000, 0xc000, 0x4000, 0x4000, 0x0000,
       0x8000, 0x8000, 0xc000, 0x4000, 0x4000, 0x0000, 0x8000, 0xc000,
       0x4000, 0x0000, 0x0000, 0x8000, 0x8000, 0xc000, 0x4000, 0x0000,
       0x4000, 0x0000, 0xc000, 0x4000, 0x0000, 0x8000, 0x4000, 0x4000,
       0xc000, 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0xc000,
       0x0000, 0xc000, 0x0000, 0x8000, 0x8000, 0xc000, 0xc000, 0x0000,
       0xc000, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x8000, 0xc000}};

/*
 * table s-box outputs, expanded for 16 bit input
 * this one table includes all 8 sboxes - just mask off
 * the output bits not in use
 */
unsigned short stable[SIZE];

/*
 * we can exploit two features of the s-box input and output
 * permutations - first, each s-box uses as input two different bits
 * from each of the three registers in the right side, and, second,
 * for each s-box there is another-sbox with no common input bits
 * between them.  therefore we can lookup two s-box outputs in one
 * probe of the table.  just mask off the approprate input bits
 * in the table below for each of the three registers and or
 * together for the table lookup index.
 *
 * These are also available in #defines, for better lookup 
 * speed in unrolled loops.
 */
unsigned short lookupmasks[4][3] = {
      /* a   ,   b   ,   c    */
      {0x0036, 0x06c0, 0x6900},     /* s1+s2 */
      {0x5048, 0x2106, 0x8411},     /* s3+s4 */
      {0x8601, 0x4828, 0x10c4},     /* s5+s7 */
      {0x2980, 0x9011, 0x022a}};    /* s6+s8 */

/*
 * this table contains the corresponding output masks for the table
 * lookup procedure mentioned above.
 *
 * similarly available in #defines.
 */
unsigned short outputmasks[4] = {
      0x000f,      /* s1+s2 */
      0x00f0,      /* s3+s4 */
      0x3300,      /* s5+s7 */
      0xcc00}; /* s6+s8 */



/*
 * initialize the macguffin s-box tables.
 * this takes a while, but is only done once.
 */
mcg_init()
{
      unsigned int i,j,k;
      int b;
      /*
       * input permutation for the 8 s-boxes.
       * each row entry is a bit position from
       * one of the three right hand registers,
       * as follows:
       *   a,a,b,b,c,c
       */
      static int sbits[8][6] = {
            {2,5,6,9,11,13},
            {1,4,7,10,8,14},
            {3,6,8,13,0,15},
            {12,14,1,2,4,10},
            {0,10,3,14,6,12},
            {7,8,12,15,1,5},
            {9,15,5,11,2,7},
            {11,13,0,4,3,9}};

      /* fill the table */
      if ((stable[0]==0xc86e) && (stable[0xffff]==0xedaf))
            return 0;
      for (i=0; i<SIZE; i++) {
            stable[i]=0;
            for (j=0; j<8; j++)
                  stable[i] |=
                        sboxes[j][((i>>sbits[j][0])&1)
                                |(((i>>sbits[j][1])&1)<<1)
                                |(((i>>sbits[j][2])&1)<<2)
                                |(((i>>sbits[j][3])&1)<<3)
                                |(((i>>sbits[j][4])&1)<<4)
                                |(((i>>sbits[j][5])&1)<<5)];
            
      }
      return 1;
}

#ifdef SOLARIS2X
#define bcopy(s,d,l) memcpy(d,s,l)
#endif

mcg_keyset(key,ek)
     unsigned char *key;
     mcg_key *ek;
{
      int i,j;
      unsigned char k[2][8];

      mcg_init();
      bcopy(&key[0],k[0],8);
      bcopy(&key[8],k[1],8);
      for (i=0; i<KSIZE; i++)
            ek->val[i]=0;
      for (i=0; i<2; i++)
            for (j=0; j<32; j++) {
                  mcg_block_encrypt(k[i],ek);
                  ek->val[j*3] ^= k[i][0] | (k[i][1]<<8);
                  ek->val[j*3+1] ^= k[i][2] | (k[i][3]<<8);
                  ek->val[j*3+2] ^= k[i][4] | (k[i][5]<<8);
            }
}     

Generated by  Doxygen 1.6.0   Back to index