Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
111
Добавлен:
16.04.2013
Размер:
110.62 Кб
Скачать

ПРИЛОЖЕНИЕ 1 «Фрагмент кода системы Visual AES на языке C++ полной реализации алгоритма шифрования»

AES.H

#ifndef AES_H #define AES_H

#define ENCRYPT 0 #define DECRYPT 1

#include "StdAfx.h" #include "Resource.h" #include "winaesDlg.h"

/* rotates x one bit to the left */

#define ROTL(x) (((x)>>7)|((x)<<1))

/* Rotates 32-bit word left by 1, 2 or 3 byte */

#define ROTL8(x) (((x)<<8)|((x)>>24))

#define ROTL16(x) (((x)<<16)|((x)>>16))

#define ROTL24(x) (((x)<<24)|((x)>>8))

/* Function prototypes */

int KeyExpansion(CWinaesDlg* dlg, int nb,int nk, BYTE* key); void Encrypt(CWinaesDlg* dlg, BYTE* buff, BYTE* result); void InvDecrypt(CWinaesDlg* dlg, BYTE* buff, BYTE* result); void EquDecrypt(CWinaesDlg* dlg, BYTE* buff, BYTE* result);

int blockEncrypt(CWinaesDlg* dlg, BYTE *input, int inputLen, BYTE* result, int cipher_mode);

int blockDecrypt(CWinaesDlg* dlg, BYTE *input, int inputLen, BYTE* result, int decrypt_mode, int cipher_mode);

#endif

AES.CPP

#include <stdio.h> #include <stdlib.h> #include "Rijndael.h" #include "service.h"

#define BPOLY

(BYTE) 0x11b

 

#define MPOLY

(BYTE) 0x101

 

/* Fixed Data */

 

/* Inverse Coefficients */

BYTE

Co[4]={0x3,0x1,0x1,0x2};

BYTE InvCo[4]={0xB,0xD,0x9,0xE};

/* Inverse Coefficients */

/* Parameter-dependent data */

 

int N, Nk, Nb, Nr;

 

 

DWORD fkey[120];

// inverse key

DWORD ikey[120];

DWORD ekey[120];

// equivalent key

BYTE subbytes[256];

BYTE invsubbytes[256];

BYTE shfts[3][4];

static char strTmp[260], Tmp[260]; static DWORD s[8];

void ResetShifts()

{

for (int i=0; i<3; i++)

for (int j=0; j<4; j++)

if (i==2 && j==3) shfts[i][j]=4; else shfts[i][j]=j;

}

62

void shiftrow(BYTE* row, int n, int direct)

{

BYTE t; int j;

if (n)

{

for (int i=0; i<n; i++)

{

switch (direct)

{

case ENCRYPT: t=row[0];

for (j=1; j<Nb; j++) row[j-1]=row[j]; row[Nb-1]=t;

break;

case DECRYPT: t=row[Nb-1];

for (j = Nb-1; j>0; j--) row[j]=row[j-1]; row[0]=t;

break;

}

}

}

}

void ShifRows(BYTE* s, int direct)

{

BYTE temp[8]; int i, j;

for (i=0;i<4;i++)

{

for (j=0;j<Nb;j++) temp[j]=s[j*4+i];

shiftrow( temp, shfts[Nb/2-2][i], direct);

for (j=0;j<Nb;j++) s[j*4+i]=temp[j];

}

}

static DWORD pack(BYTE *b)

{ /* pack bytes into a 32-bit Word */

return ((DWORD)b[3]<<24)|((DWORD)b[2]<<16)|((DWORD)b[1]<<8)|(DWORD)b[0];

}

static void unpack(DWORD a,BYTE *b) { /* unpack bytes from a word */

b[0]=(BYTE)a;

b[1]=(BYTE)(a>>8);

b[2]=(BYTE)(a>>16);

b[3]=(BYTE)(a>>24);

}

static BYTE xtime(BYTE a, BYTE mod)

{

return ( ( a & 0x80) ? a<<1^mod : a<<1);

};

static BYTE add(BYTE a, BYTE b) {return a^b;}

/* multiply two elements of GF(2^m)

* needed for MixColumn and InvMixColumn */ static BYTE bmul(BYTE a,BYTE b, BYTE mod)

{

BYTE t,s, u;

u=b; t=a; s=0;

while (u)

{

if(u & 1) s^=t; u>>=1; t=xtime(t, mod);

63

}

return(s);

}

static BYTE square(BYTE a, BYTE mod)

{

return (bmul(a,a, mod));

}

static BYTE product(DWORD x,DWORD y, BYTE mod) { /* dot product of two 4-byte arrays */

BYTE xb[4],yb[4]; unpack(x,xb); unpack(y,yb);

return bmul(xb[0],yb[0], mod)^bmul(xb[1],yb[1], mod)^bmul(xb[2],yb[2], mod)^bmul(xb[3],yb[3], mod);

}

static BYTE finv(const BYTE x, BYTE mod)

{

BYTE result = x;

for (int i=1; i<7; i++) result = bmul(square(result , mod), x, mod); return square(result, mod);

}

/*

static BYTE ByteSubOLD(BYTE x)

{

DWORD w;

return ((w = (DWORD)finv((BYTE) x), w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(BYTE)(w^(w>>8))));

}

static BYTE InvByteSubOLD(BYTE x)

{

DWORD w;

return (finv((w = (DWORD)(BYTE) x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(BYTE)(w^(w>>8)))) );

}

*/

BYTE SBinvModulo;

BYTE SBmulModulo;

BYTE SBmulConst1;

BYTE SBmulConst2;

BYTE SBaddConst1;

BYTE SBaddConst2;

static BYTE ByteSubOLD(BYTE x)

{

BYTE result=x;

result = finv( result , SBinvModulo);

result = bmul( SBmulConst1, result, SBmulModulo); result = add( result, SBaddConst1);

return result;

}

static BYTE InvByteSubOLD(BYTE x)

{

BYTE result=x;

result = bmul( SBmulConst2, result, SBmulModulo); result = add(result, SBaddConst2);

result = finv( result, SBinvModulo); return result;

}

void FillTables(int mode)

{

for (int i=0; i<256; i++)

{

if (mode & 1) subbytes[i]= ByteSubOLD(i);

if (mode & 2) invsubbytes[i]= InvByteSubOLD(i);

}

}

void ResetTables()

64

{

SBinvModulo = BPOLY;

SBmulModulo = MPOLY; SBmulConst1 = 0x1f; SBmulConst2 = 0x4a; SBaddConst1 = 0x63; SBaddConst2 = 0x05;

FillTables(3);

}

static BYTE ByteSub(BYTE x)

{

return (subbytes[x]);

}

static BYTE InvByteSub(BYTE x)

{

return (invsubbytes[x]);

}

static DWORD SubDWord(DWORD a)

{

BYTE b[4]; unpack(a,b); b[0]=ByteSub(b[0]); b[1]=ByteSub(b[1]); b[2]=ByteSub(b[2]); b[3]=ByteSub(b[3]); return pack(b);

}

static void AddRoundKey(DWORD* s, DWORD* key, int nround)

{

for (int i=0; i<Nb; i++) s[i]^=key[Nb*nround + i];

}

void SubBytes(BYTE* s, int direct)

{

int j;

switch (direct)

{

case ENCRYPT:

for (j=0; j<Nb*4 ;j++) s[j]=ByteSub((BYTE)s[j]);

break; case DECRYPT:

for (j=0; j<Nb*4 ;j++) s[j]=InvByteSub((BYTE)s[j]);

break;

}

}

void MixCol(DWORD* s, int lenght,int direct) { /* matrix Multiplication */

DWORD m; BYTE b[4];

switch (direct)

{

case ENCRYPT: m=pack(Co); break;

case DECRYPT: m=pack(InvCo); break;

}

for (int i=0; i<lenght; i++)

{

b[3]=product(m, s[i], BPOLY); m=ROTL24(m);

b[2]=product(m, s[i], BPOLY); m=ROTL24(m);

65

b[1]=product(m, s[i], BPOLY); m=ROTL24(m);

b[0]=product(m, s[i], BPOLY); m=ROTL24(m);

s[i]=pack(b);

}

return;

}

void RecalcKeys(BYTE* key)

{

DWORD temp, rcon=1; int i, j;

N=Nb*(Nr+1);

for (i=0;i<Nk;i++)

{

fkey[i]=pack(&key[i*4]);

}

for(i = Nk; i < N; i++)

{

temp = fkey[i - 1];

if (i % Nk == 0)

{

temp = SubDWord(ROTL24(temp)) ^ rcon; rcon=(DWORD)xtime((BYTE)rcon, BPOLY );

}

else if ( (Nk > 6) && (i % Nk == 4) ) temp= SubDWord(temp);

fkey[i] = fkey[i - Nk] ^ temp;

}

for (i=0; i<N;i+=Nb)

{

for (j=0; j<Nb;j++) (ikey[i+j]= fkey[N-Nb-i+j], ekey[i+j]= fkey[N-Nb-i+j]);

if (i>= Nb && i<N-Nb)MixCol(&ekey[i], Nb, DECRYPT);

}

}

int KeyExpansion(CWinaesDlg* dlg, int nb,int nk, BYTE* key)

{

Nb=nb; Nk=nk;

(Nb>=Nk) ? Nr=6+Nb : Nr=6+Nk;

if(dlg->m_bRecalcKey) RecalcKeys(key);

return (Nr);

};

BOOL b_MixColumns;

BOOL b_AddRoundKey;

BOOL b_ShiftRows;

BOOL b_SubBytes;

void Encrypt(CWinaesDlg* dlg, BYTE* buff, BYTE* result)

{

int i,j;

for (i=j=0;i<Nb;i++,j+=4) s[i]=pack((BYTE *)&buff[j]);

i=0;

if (dlg->m_Start)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"enc[%02u].input %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

66

if (!b_AddRoundKey)

{

if (dlg->m_KSch)

{

CharStr2HexStr((BYTE*)&fkey[i*Nb], Tmp, Nb*4); sprintf(strTmp, "enc[%02u].k_sch %s", i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

AddRoundKey(s, fkey, 0);

}

for (i=1;i<Nr;i++)

{

if (dlg->m_Start)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"enc[%02u].start %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

if (!b_SubBytes)

{

SubBytes((BYTE*)s, ENCRYPT);

if (dlg->m_SBox)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"enc[%02u].s_box %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

}

if (!b_ShiftRows)

{

ShifRows((BYTE*)s, ENCRYPT);

if (dlg->m_SRow)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"enc[%02u].s_row %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

}

if (!b_MixColumns)

{

MixCol(s, Nb, ENCRYPT);

if (dlg->m_M_Col)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"enc[%02u].m_col %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

}

if (!b_AddRoundKey)

{

if (dlg->m_KSch)

{

CharStr2HexStr((BYTE*)&fkey[i*Nb], Tmp, Nb*4); sprintf(strTmp, "enc[%02u].k_sch %s", i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

AddRoundKey(s, fkey, i);

}

}

if (dlg->m_Start)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"enc[%02u].start %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

if (!b_SubBytes)

{

SubBytes((BYTE*)s, ENCRYPT);

67

if (dlg->m_SBox)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"enc[%02u].s_box %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

}

if (!b_ShiftRows)

{

ShifRows((BYTE*)s, ENCRYPT);

if (dlg->m_SRow)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"enc[%02u].s_row %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

}

if (!b_AddRoundKey)

{

if (dlg->m_KSch)

{

CharStr2HexStr((BYTE*)&fkey[i*Nb], Tmp, Nb*4); sprintf(strTmp, "enc[%02u].k_sch %s", i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

AddRoundKey(s, fkey, Nr);

}

if (dlg->m_Start)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"enc[%02u].final %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

for (i=j=0;i<Nb;i++,j+=4) unpack(s[i],(BYTE *)&result[j]);

return;

}

void InvDecrypt(CWinaesDlg* dlg, BYTE* buff, BYTE* result)

{

int i,j;

for (i=j=0;i<Nb;i++,j+=4) s[i]=pack((BYTE *)&buff[j]);

i=0;

if (dlg->m_Start)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"inv[%02u].input %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

if (!b_AddRoundKey)

{

if (dlg->m_KSch)

{

CharStr2HexStr((BYTE*)&ikey[i*Nb], Tmp, Nb*4); sprintf(strTmp,"inv[%02u].k_sch %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

AddRoundKey(s, ikey, 0);

}

for (i=1;i<Nr;i++)

{

if (dlg->m_Start)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"inv[%02u].start %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

68

}

if (!b_ShiftRows)

{

ShifRows((BYTE*)s, DECRYPT);

if (dlg->m_SRow)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"inv[%02u].s_row %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

}

if (!b_SubBytes)

{

SubBytes((BYTE*)s, DECRYPT);

if (dlg->m_SBox)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"inv[%02u].s_box %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

}

if (!b_AddRoundKey)

{

if (dlg->m_KSch)

{

CharStr2HexStr((BYTE*)&ikey[i*Nb], Tmp, Nb*4); sprintf(strTmp,"inv[%02u].k_sch %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

AddRoundKey(s, ikey, i);

if (dlg->m_KSch)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"inv[%02u].k_add %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

}

if (!b_MixColumns)

{

MixCol(s, Nb, DECRYPT);

if (dlg->m_M_Col)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"inv[%02u].m_col %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

}

}

if (!b_ShiftRows)

{

ShifRows((BYTE*)s, DECRYPT);

if (dlg->m_SRow)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"inv[%02u].s_row %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

}

if (!b_SubBytes)

{

SubBytes((BYTE*)s, DECRYPT);

if (dlg->m_SBox)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"inv[%02u].s_box %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

69

}

if (!b_AddRoundKey)

{

if (dlg->m_KSch)

{

CharStr2HexStr((BYTE*)&ikey[i*Nb], Tmp, Nb*4); sprintf(strTmp,"inv[%02u].k_sch %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

AddRoundKey(s, ikey, i);

}

if (dlg->m_Start)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"inv[%02u].final %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

for (i=j=0;i<Nb;i++,j+=4) unpack(s[i],(BYTE *)&result[j]);

return;

}

void EquDecrypt(CWinaesDlg* dlg, BYTE* buff, BYTE* result)

{

int i=0,j;

for ( i = j = 0; i < Nb; i++, j+=4) s[i]=pack((BYTE *)&buff[j]);

i=0;

if (dlg->m_Start)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"equ[%02u].input %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

if (!b_AddRoundKey)

{

if (dlg->m_KSch)

{

CharStr2HexStr((BYTE*)&ikey[i*Nb], Tmp, Nb*4); sprintf(strTmp,"equ[%02u].k_sch %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

AddRoundKey(s, ekey, 0);

}

for (i=1;i<Nr;i++)

{

if (dlg->m_Start)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"equ[%02u].start %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

if (!b_SubBytes)

{

SubBytes((BYTE*)s, DECRYPT);

if (dlg->m_SBox)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"equ[%02u].s_box %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

}

if (!b_ShiftRows)

{

ShifRows((BYTE*)s, DECRYPT);

if (dlg->m_SRow)

{

70

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"equ[%02u].s_row %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

}

if (!b_MixColumns)

{

MixCol(s, Nb, DECRYPT);

if (dlg->m_M_Col)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"equ[%02u].m_col %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

}

if (!b_AddRoundKey)

{

if (dlg->m_KSch)

{

CharStr2HexStr((BYTE*)&ikey[i*Nb], Tmp, Nb*4); sprintf(strTmp,"equ[%02u].k_sch %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

AddRoundKey(s, ekey, i);

if (dlg->m_KSch)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"equ[%02u].k_add %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

}

}

if (!b_SubBytes)

{

SubBytes((BYTE*)s, DECRYPT);

if (dlg->m_SBox)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"equ[%02u].s_box %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

}

if (!b_ShiftRows)

{

ShifRows((BYTE*)s, DECRYPT);

if (dlg->m_SRow)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"equ[%02u].s_row %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

}

if (!b_AddRoundKey)

{

if (dlg->m_KSch)

{

CharStr2HexStr((BYTE*)&ikey[i*Nb], Tmp, Nb*4); sprintf(strTmp,"equ[%02u].k_sch %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

AddRoundKey(s, ekey, i);

}

if (dlg->m_Start)

{

CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"equ[%02u].final %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);

}

71

Соседние файлы в папке Шифрование AES