static u32 InvMixCol(u32 x) { /* matrix Multiplication */ u32 y,m; u8 b[4]; m=pack(InCo); b[3]=product(m,x); m=ROTL24(m); b[2]=product(m,x); m=ROTL24(m); b[1]=product(m,x); m=ROTL24(m); b[0]=product(m,x); y=pack(b); return y; }
/*列混合的逆变换*/ static WORD InvMixCol(WORD x) { /* matrix Multiplication */ WORD y,m; BYTE b[4]; m=pack(InCo); b[3]=product(m,x); m=ROTL24(m); b[2]=product(m,x); m=ROTL24(m); b[1]=product(m,x); m=ROTL24(m); b[0]=product(m,x); y=pack(b); return y; }
//============================================================================== void KeyExpansion(uint8_t *key , uint8_t direct) //Функция расширения ключа { uint32_t fkey[N]; //Вспомогательный массив uint32_t temp,rcon=1; //Промежуточные переменные uint8_t i,j; //Счетчики 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 = (uint32_t)xtime((uint8_t )rcon , BPOLY); } fkey[i] = fkey[i-Nk] ^ temp; } for(i=0; i<N;i +=Nb) //Заполнение выходного массива { for(j=0; j<Nb; j++) { if(direct==ENCRYPT) rkey[i+j] = fkey[i+j] ; //Заполнение при шифровке else if(direct==DECRYPT) rkey[i+j] = fkey[N-Nb-i+j] ; //Заполнение при дешифровке } } }
BOOL aes_init(aes* a,int mode,int nk,char *key,char *iv) { /* Key=nk bytes */ /* currently NB,nk = 16, 24 or 32 */ /* Key Scheduler. Create expanded encryption key */ int i,j,k,N,nr; WORD CipherKey[8]; nk/=4; if (nk!=4 && nk!=6 && nk!=8) return FALSE; /* nr is number of rounds */ nr=6+nk; a->Nk=nk; a->Nr=nr; aes_reset(a,mode,iv); N=NB*(nr+1); for (i=j=0; i<nk; i++,j+=4) { CipherKey[i]=pack((BYTE *)&key[j]); } for (i=0; i<nk; i++) a->fkey[i]=CipherKey[i]; for (j=nk,k=0; j<N; j+=nk,k++) { a->fkey[j]=a->fkey[j-nk]^SubByte(ROTL24(a->fkey[j-1]))^rco[k]; if (nk<=6) { for (i=1; i<nk && (i+j)<N; i++) a->fkey[i+j]=a->fkey[i+j-nk]^a->fkey[i+j-1]; } else { for (i=1; i<4 && (i+j)<N; i++) a->fkey[i+j]=a->fkey[i+j-nk]^a->fkey[i+j-1]; if ((j+4)<N) a->fkey[j+4]=a->fkey[j+4-nk]^SubByte(a->fkey[j+3]); for (i=5; i<nk && (i+j)<N; i++) a->fkey[i+j]=a->fkey[i+j-nk]^a->fkey[i+j-1]; } } /* now for the expanded decrypt key in reverse order */ for (j=0; j<NB; j++) a->rkey[j+N-NB]=a->fkey[j]; for (i=NB; i<N-NB; i+=NB) { k=N-NB-i; for (j=0; j<NB; j++) a->rkey[k+j]=InvMixCol(a->fkey[i+j]); } for (j=N-NB; j<N; j++) a->rkey[j-N+NB]=a->fkey[j]; return TRUE; }
//============================================================================== void MixColums(uint32_t *s, uint8_t lenght, uint8_t direct) //Фукция перемешивания данных в колонке { uint32_t m; uint8_t b[4]; uint8_t cnt; //Счетчик switch(direct) { case ENCRYPT: { m = Co; break; } case DECRYPT: { m = InvCo; break; } } for(cnt=0; cnt<lenght; cnt++) { b[3] = product(m, s[cnt], BPOLY); m = ROTL24(m); b[2] = product(m, s[cnt], BPOLY); m = ROTL24(m); b[1] = product(m, s[cnt], BPOLY); m = ROTL24(m); b[0] = product(m, s[cnt], BPOLY); m = ROTL24(m); s[cnt] = pack(b); } }
/* Initialise cipher */ int MCL_AES_init(mcl_aes* a,int mode,int nk,char *key,char *iv) { /* Key length Nk=16, 24 or 32 bytes */ /* Key Scheduler. Create expanded encryption key */ int i,j,k,N,nr; unsign32 CipherKey[8]; nk/=4; if (nk!=4 && nk!=6 && nk!=8) return 0; nr=6+nk; a->Nk=nk; a->Nr=nr; MCL_AES_reset(a,mode,iv); N=NB*(nr+1); for (i=j=0;i<nk;i++,j+=4) { CipherKey[i]=pack((uchar *)&key[j]); } for (i=0;i<nk;i++) a->fkey[i]=CipherKey[i]; for (j=nk,k=0;j<N;j+=nk,k++) { a->fkey[j]=a->fkey[j-nk]^SubByte(ROTL24(a->fkey[j-1]))^rco[k]; if (nk<=6) { for (i=1;i<nk && (i+j)<N;i++) a->fkey[i+j]=a->fkey[i+j-nk]^a->fkey[i+j-1]; } else { for (i=1;i<4 && (i+j)<N;i++) a->fkey[i+j]=a->fkey[i+j-nk]^a->fkey[i+j-1]; if ((j+4)<N) a->fkey[j+4]=a->fkey[j+4-nk]^SubByte(a->fkey[j+3]); for (i=5;i<nk && (i+j)<N;i++) a->fkey[i+j]=a->fkey[i+j-nk]^a->fkey[i+j-1]; } } /* now for the expanded decrypt key in reverse order */ for (j=0;j<NB;j++) a->rkey[j+N-NB]=a->fkey[j]; for (i=NB;i<N-NB;i+=NB) { k=N-NB-i; for (j=0;j<NB;j++) a->rkey[k+j]=InvMixCol(a->fkey[i+j]); } for (j=N-NB;j<N;j++) a->rkey[j-N+NB]=a->fkey[j]; return 1; }
void KeyExpansion(WORD key[Nk], WORD ExKey[Nb*(Nr+1)]) { for(int i=0; i<Nk; i++) ExKey[i] = key[i]; BYTE xi = 0x01; WORD temp; for(int i=Nk; i<Nb*(Nr+1); i++) { temp = ExKey[i-1]; if (i % Nk == 0) { WORD w = xi; w = ROTL24(xi); temp = SubWord(ROTL8(temp)) ^ w; xi = xtime(xi); } //else // temp = SubWord(temp); ExKey[i] = ExKey[i-Nk] ^ temp; } }
/* Initialise cipher */ void AES_init(aes* a,int mode,char *key,char *iv) { /* Key=16 bytes */ /* Key Scheduler. Create expanded encryption key */ int i,j,k,N,nk; unsign32 CipherKey[4]; nk=4; AES_reset(a,mode,iv); N=NB*(ROUNDS+1); for (i=j=0;i<nk;i++,j+=4) { CipherKey[i]=pack((uchar *)&key[j]); } for (i=0;i<nk;i++) a->fkey[i]=CipherKey[i]; for (j=nk,k=0;j<N;j+=nk,k++) { a->fkey[j]=a->fkey[j-nk]^SubByte(ROTL24(a->fkey[j-1]))^rco[k]; for (i=1;i<nk && (i+j)<N;i++) a->fkey[i+j]=a->fkey[i+j-nk]^a->fkey[i+j-1]; } /* now for the expanded decrypt key in reverse order */ for (j=0;j<NB;j++) a->rkey[j+N-NB]=a->fkey[j]; for (i=NB;i<N-NB;i+=NB) { k=N-NB-i; for (j=0;j<NB;j++) a->rkey[k+j]=InvMixCol(a->fkey[i+j]); } for (j=N-NB;j<N;j++) a->rkey[j-N+NB]=a->fkey[j]; }
void InvShiftRows(WORD in[Nb]) { ROTL8(in[1]); ROTL16(in[2]); ROTL24(in[3]); }
void gkey(int nb,int nk,char *key) { /* blocksize=32*nb bits. Key=32*nk bits */ /* currently nb,bk = 4, 6 or 8 */ /* key comes as 4*Nk bytes */ /* Key Scheduler. Create expanded encryption key */ int i,j,k,m,N; int C1,C2,C3; u32 CipherKey[8]; Nb=nb; Nk=nk; /* Nr is number of rounds */ if (Nb>=Nk) Nr=6+Nb; else Nr=6+Nk; C1=1; if (Nb<8) { C2=2; C3=3; } else { C2=3; C3=4; } /* pre-calculate forward and reverse increments */ for (m=j=0;j<nb;j++,m+=3) { fi[m]=(j+C1)%nb; fi[m+1]=(j+C2)%nb; fi[m+2]=(j+C3)%nb; ri[m]=(nb+j-C1)%nb; ri[m+1]=(nb+j-C2)%nb; ri[m+2]=(nb+j-C3)%nb; } N=Nb*(Nr+1); for (i=j=0;i<Nk;i++,j+=4) { CipherKey[i]=pack((u8 *)&key[j]); } for (i=0;i<Nk;i++) fkey[i]=CipherKey[i]; for (j=Nk,k=0;j<N;j+=Nk,k++) { fkey[j]=fkey[j-Nk]^SubByte(ROTL24(fkey[j-1]))^rco[k]; if (Nk<=6) { for (i=1;i<Nk && (i+j)<N;i++) fkey[i+j]=fkey[i+j-Nk]^fkey[i+j-1]; } else { for (i=1;i<4 &&(i+j)<N;i++) fkey[i+j]=fkey[i+j-Nk]^fkey[i+j-1]; if ((j+4)<N) fkey[j+4]=fkey[j+4-Nk]^SubByte(fkey[j+3]); for (i=5;i<Nk && (i+j)<N;i++) fkey[i+j]=fkey[i+j-Nk]^fkey[i+j-1]; } } /* now for the expanded decrypt key in reverse order */ for (j=0;j<Nb;j++) rkey[j+N-Nb]=fkey[j]; for (i=Nb;i<N-Nb;i+=Nb) { k=N-Nb-i; for (j=0;j<Nb;j++) rkey[k+j]=InvMixCol(fkey[i+j]); } for (j=N-Nb;j<N;j++) rkey[j-N+Nb]=fkey[j]; }
/*获得密钥*/ void gkey(int nb,int nk,char *key) { int i,j,k,m,N; int C1,C2,C3; WORD CipherKey[8]; Nb=nb; Nk=nk; /* Nr is number of rounds Nr是加密的轮数*/ if (Nb>=Nk) Nr=6+Nb; else Nr=6+Nk; C1=1; if (Nb<8) { C2=2; C3=3; } else { C2=3; C3=4; } for (m=j=0;j<nb;j++,m+=3) { fi[m]=(j+C1)%nb; fi[m+1]=(j+C2)%nb; fi[m+2]=(j+C3)%nb; ri[m]=(nb+j-C1)%nb; ri[m+1]=(nb+j-C2)%nb; ri[m+2]=(nb+j-C3)%nb; } N=Nb*(Nr+1); for (i=j=0;i<Nk;i++,j+=4) { CipherKey[i]=pack((BYTE *)&key[j]); } for (i=0;i<Nk;i++) fkey[i]=CipherKey[i]; for (j=Nk,k=0;j<N;j+=Nk,k++) { fkey[j]=fkey[j-Nk]^SubByte(ROTL24(fkey[j-1]))^rco[k]; if (Nk<=6) { for (i=1;i<Nk && (i+j)<N;i++) fkey[i+j]=fkey[i+j-Nk]^fkey[i+j-1]; } else { for (i=1;i<4 &&(i+j)<N;i++) fkey[i+j]=fkey[i+j-Nk]^fkey[i+j-1]; if ((j+4)<N) fkey[j+4]=fkey[j+4-Nk]^SubByte(fkey[j+3]); for (i=5;i<Nk && (i+j)<N;i++) fkey[i+j]=fkey[i+j-Nk]^fkey[i+j-1]; } } for (j=0;j<Nb;j++) rkey[j+N-Nb]=fkey[j]; for (i=Nb;i<N-Nb;i+=Nb) { k=N-Nb-i; for (j=0;j<Nb;j++) rkey[k+j]=InvMixCol(fkey[i+j]); } for (j=N-Nb;j<N;j++) rkey[j-N+Nb]=fkey[j]; }