⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mks_aes.cpp

📁 xtunnel nat/fw traversal source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*	File:       MKS_AES.cpp	Contains:   Mok-Kong Shen's byte-oriented AES implementation	            http://home.t-online.de/home/mok-kong.shen/#paper1	            "Several readers of sci.crypt have verified that the package runs correctly on big-endian machines as well"	Copyright:  (c) 2003 by Xten Networks, Inc., all rights reserved.*//* ----------------------------------------------------------//// An AES implementation for 32-bit platforms//// Release 1.4  //// Release date: 10th October 2003//// Consisting of a principal part (this file) and a (separate) // Supplement. //// Author: Mok-Kong Shen, Munich, Germany//// Last date of site modification: (currently empty)////// Design assumptions: Size of unsigned int 32 bits.//                     Size of unsigned char 8 bits.//                     Sequential processing model.//// See copyright notice further below.//// For application runs, include the package as header file// and invoke in the main program://// (a) one call of aessetup(keylength), where keylength is //     one of 128, 192 and 256.//// (b) after placing the user-given key in the byte-array //     ukey.b[16], one call of aeskeyschedule(encrypt) or //     aeskeyschedule(decrypt), depending on whether //     encryption or decryption is to be done.//// (c) one call of aesprocess() for processing each input //     block provided in the byte-array aesin.b[16] to result //     in the output block in the byte-array aesout.b[16].//// Redo (a), if a different keylength is to be used. Redo // (b), if one changes key or switches from encryption to // decryption (or vice versa).//// For a demonstration with the example vectors of FIPS-197,// Appendix C, and benchmarking of the individual functions// mentioned in (a), (b) and (c) above, include the package // as header file and invoke in a main program the function// call aesdemo(). Check carefully with FIPS-197 that the // results (ciphertexts and recovered plaintexts) are indeed // correct before any practical applications of the package.//// The Supplement is informative only and is intended for // rendering easier the understanding or checking of certain // functions and for benchmark comparisons with other AES // implementations.//// Release 1.4, as originally issued, is available at // http://home.t-online.de/home/mok-kong.shen.//------------------------------------------------------------- */#include <stdio.h> #include <stdlib.h> #include <time.h>#include "MKS_AES.h"/* moved to headertypedef unsigned char byte;typedef unsigned int word;*/typedef union { byte b[4];  word w;} UU;/* moved to headertypedef union { byte b[16];  byte bm[4][4];  word w[4];} BLOCK;*//* ----------------------------------------------------------// aesin and aesout are input/output of the function aesprocess.// These are to be considered by the user as byte-arrays, not as// arrays of unsigned int. Beware of confusion and potential// errors due to the endian-ness of hardware, resulting in// non-interoperability, when implementing CTR mode with integer// arithmetic operations without due consideration of the// effect of endian-ness.------------------------------------------------------------- */BLOCK aesin,aesout;const int Nb=4; int Nk,Nr,Nr4minus1;  int ekeywdim,ekeywdimminus1,roundpairs;int aessetupdone=0;/* ----------------------------------------------------------// ukey is the user-given key, ekey is the expanded key.// Maximum storage space is provided for ukey and ekey. Size of// ekey provides for a max. of 14 rounds. The actual size in // words is Nk for ukey and ekeywdim for ekey. See FIPS-197 and // the function aessetup. For ekey, for implementation reasons,// four additional words are provided but not actually used in // encryption/decrpyption processing, see the function // aeskeyschedule.------------------------------------------------------------- *//* moved to headertypedef union { byte b[32];  byte bm[8][4];  word w[8];} USERKEY;*/USERKEY ukey;typedef union { byte b[256];  byte bm[64][4];  word w[64];} EXPANDEDKEY;EXPANDEDKEY ekey;/* ----------------------------------------------------------// For elements of the array sbox, see FIPS-197. ------------------------------------------------------------- */byte sbox[256]={0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16 };byte invsbox[256];static byte gfmult(byte a, byte b){ byte r,t;  if (a < b) { t=b; b=a; a=t; }  r=0;  do   { if (b&0x01) r^=a;    if (a&0x80) a=(a<<1)^0x1b; else a<<=1;  } while (b>>=1);  return r;}typedef union { byte b[1024];  byte bm[256][4];  word w[256];} TABLE;/* ----------------------------------------------------------// The tables t's and v's are for encryption and decryption // respectively. (See the book of Daemen and Rijmen, pp.56-59,// for detailed explanation of the tables t's.)// The tables z's are similar to the v's but without the // involvement of substitution. The tables u's and w's are // similar to the tables t's and v's but use an identity // matrix. The table y is the identity of the byte extended // with three zero bytes. // We have introduced the additional tables u's, w's, y and // z's for enabling more efficient processing in the functions// asekeyschedule and aesprocess.------------------------------------------------------------- */TABLE t0,t1,t2,t3,u0,u1,u2,u3,v0,v1,v2,v3,w0,w1,w2,w3,y,      z0,z1,z2,z3;static void computetables(){ int i,j;  byte s,r;  for (i=0; i<256; i++) invsbox[sbox[i]]=i;  for (i=0; i<256; i++)   { s=sbox[i];    t0.bm[i][0]=gfmult(s,0x02); t0.bm[i][1]=t0.bm[i][2]=s;     t0.bm[i][3]=gfmult(s,0x03);    u0.bm[i][0]=s; u0.bm[i][1]=u0.bm[i][2]=u0.bm[i][3]=0;    y.bm[i][0]=i; y.bm[i][1]=y.bm[i][2]=y.bm[i][3]=0;    r=invsbox[i];    v0.bm[i][0]=gfmult(r,0x0e); v0.bm[i][1]=gfmult(r,0x09);    v0.bm[i][2]=gfmult(r,0x0d); v0.bm[i][3]=gfmult(r,0x0b);    z0.bm[i][0]=gfmult(i,0x0e); z0.bm[i][1]=gfmult(i,0x09);    z0.bm[i][2]=gfmult(i,0x0d); z0.bm[i][3]=gfmult(i,0x0b);    w0.bm[i][0]=r; w0.bm[i][1]=w0.bm[i][2]=w0.bm[i][3]=0;    for (j=0; j<4; j++)    { t1.bm[i][j]=t0.bm[i][(j+3)%4];      t2.bm[i][j]=t0.bm[i][(j+2)%4];      t3.bm[i][j]=t0.bm[i][(j+1)%4];      u1.bm[i][j]=u0.bm[i][(j+3)%4];       u2.bm[i][j]=u0.bm[i][(j+2)%4];      u3.bm[i][j]=u0.bm[i][(j+1)%4];      v1.bm[i][j]=v0.bm[i][(j+3)%4];       v2.bm[i][j]=v0.bm[i][(j+2)%4];      v3.bm[i][j]=v0.bm[i][(j+1)%4];      w1.bm[i][j]=w0.bm[i][(j+3)%4];       w2.bm[i][j]=w0.bm[i][(j+2)%4];      w3.bm[i][j]=w0.bm[i][(j+1)%4];      z1.bm[i][j]=z0.bm[i][(j+3)%4];       z2.bm[i][j]=z0.bm[i][(j+2)%4];      z3.bm[i][j]=z0.bm[i][(j+1)%4];    }  }}void aessetup(int keylength){   if (!aessetupdone)   { computetables(); aessetupdone=1;  }  switch(keylength)  { case 128: Nk=4; Nr=10; break;    case 192: Nk=6; Nr=12; break;    case 256: Nk=8; Nr=14; break;    default: printf("\nwrong keylength in aessetup call\n");               exit(1);  }  Nr4minus1=Nr*4-1;  ekeywdim=Nb*(Nr+1);  ekeywdimminus1=ekeywdim-1;  roundpairs=Nr/2;}const byte RC[12]={ 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,                    0x40, 0x80, 0x1b, 0x36, 0x6c };/* moved to headertypedef enum { encrypt, decrypt } PROCESS;*/PROCESS encdec;/* ----------------------------------------------------------// The function aeskeyschedule utilizes the tables u's and// the table y, the table z's and partial loop-unrolling to // do the same as the function aeskeyschedule_version1 in the // Supplement but more efficiently. See FIPS-197 and the function // computetables. For elements of the array RC (size provided for // max. of 14 rounds), see the book of Daemen and Rijmen, p.214. // Before calling aeskeyschedule, key of the user must be// available in the array ukey.b in the bytes from ukey.b[0] // to ukey.b[4*Nk-1].// It is assumed that aessetup has been called previously// with the correct keylength.------------------------------------------------------------- */void aeskeyschedule(PROCESS kind) { int i,ii;  word *wp;  byte *bp;  if (!aessetupdone)  { printf(      "\nerror: aessetup was not called. program aborted\n");     exit(1);   }  encdec=kind;  for (i=0; i < Nk; i++) ekey.w[i]=ukey.w[i];   ii=0;  wp=&ekey.w[Nk]; bp=(byte *) &ekey.w[Nk-1];  if (Nk==4)   for (i=0; i < 10; i++)  { wp[0]=wp[-4]^y.w[RC[++ii]]^          u0.w[bp[1]]^u1.w[bp[2]]^u2.w[bp[3]]^u3.w[bp[0]];    wp[1]=wp[-3]^wp[0];    wp[2]=wp[-2]^wp[1];    wp[3]=wp[-1]^wp[2];    wp+=4; bp+=16;  }                   else if (Nk==6)    for (i=0; i < 8; i++)  { wp[0]=wp[-6]^y.w[RC[++ii]]^          u0.w[bp[1]]^u1.w[bp[2]]^u2.w[bp[3]]^u3.w[bp[0]];    wp[1]=wp[-5]^wp[0];    wp[2]=wp[-4]^wp[1];    wp[3]=wp[-3]^wp[2];    wp[4]=wp[-2]^wp[3];    wp[5]=wp[-1]^wp[4];    wp+=6; bp+=24;  }  else  for (i=0; i < 7; i++)  { wp[0]=wp[-8]^y.w[RC[++ii]]^          u0.w[bp[1]]^u1.w[bp[2]]^u2.w[bp[3]]^u3.w[bp[0]];    wp[1]=wp[-7]^wp[0];    wp[2]=wp[-6]^wp[1];    wp[3]=wp[-5]^wp[2];    bp+=16;    wp[4]=wp[-4]^          u0.w[bp[0]]^u1.w[bp[1]]^u2.w[bp[2]]^u3.w[bp[3]];    wp[5]=wp[-3]^wp[4];    wp[6]=wp[-2]^wp[5];    wp[7]=wp[-1]^wp[6];    wp+=8; bp+=16;  }  if (encdec==decrypt)  {/* ----------------------------------------------------------// The first and the last round key are excluded from the// inverse mixcolumns transform. See the book of Daemen and // Rijmen, p.59.------------------------------------------------------------- */    bp=(byte *) &ekey.w[4];    for (ii=4; ii<=Nr4minus1; ii++)     { ekey.w[ii]=z0.w[bp[0]]^z1.w[bp[1]]^                 z2.w[bp[2]]^z3.w[bp[3]];      bp+=4;    }  }}/* ----------------------------------------------------------// Before calling aesprocess, input data must be available // in the array aesin.b (bytes aesin.b[0] to aesin.b[15]). // Output will be in the array aesout.b (bytes aesout.b[0] // to aesout.b[15]). It is assumed (not checked) that // aeskeyschedule has been called previously. The function // aesprocess employs partial loop-unrolling and two // alternating buffers temp0 and temp1 and also the tables u's // and w's to do the same as the function aesprocess_version1 // in the Supplement but more efficiently. The loops operate on // pairs of rounds. Note that, for implementation reasons, the // matrices involved are the transposes of the corresponding // ones in FIPS-197, hence the difference in indexing of their // elements. Note also that in AES Nr is always even and that // the final round is different, hence the last two rounds // are separated from the loop. For decryption, see the book// of Daemen and Rijmen, p.48-50.------------------------------------------------------------- */BLOCK temp0,temp1;void aesprocess()   { int grdp;  word *wp;  if (encdec==encrypt)  { wp=&ekey.w[0];    temp0.w[0]=(*wp++)^aesin.w[0];    temp0.w[1]=(*wp++)^aesin.w[1];    temp0.w[2]=(*wp++)^aesin.w[2];    temp0.w[3]=(*wp++)^aesin.w[3];    for (grdp=1; grdp < roundpairs; grdp++)    { temp1.w[0]=(*wp++)^                 t0.w[temp0.bm[0][0]]^t1.w[temp0.bm[1][1]]^                 t2.w[temp0.bm[2][2]]^t3.w[temp0.bm[3][3]];      temp1.w[1]=(*wp++)^                 t0.w[temp0.bm[1][0]]^t1.w[temp0.bm[2][1]]^                 t2.w[temp0.bm[3][2]]^t3.w[temp0.bm[0][3]];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -