//解密运算,inputSize必须为128,192,256位 void Decrypt(RijndaelContextPtr context,void* input) { int round; //明文的最大长度 unsigned long state[8] = {0}; unsigned char* inputStringPtr = (unsigned char*)input; unsigned int nb = context->nb; state[0] = GETINT32(inputStringPtr,0,nb); state[1] = GETINT32(inputStringPtr,1,nb); state[2] = GETINT32(inputStringPtr,2,nb); state[3] = GETINT32(inputStringPtr,3,nb); if (nb >= (KeySize_192/4)) { state[4] = GETINT32(inputStringPtr,4,nb); state[5] = GETINT32(inputStringPtr,5,nb); } if (nb >= (KeySize_256/4)) { state[6] = GETINT32(inputStringPtr,6,nb); state[7] = GETINT32(inputStringPtr,7,nb); } InvAddRoundKey(context,context->nr,state); InvShiftRow(context,state); InvSubByte(context,state); for (round = (context->nr-1); round > 0; round--) { InvAddRoundKey(context,round,state); InvMixColumn(context,state); InvShiftRow(context,state); InvSubByte(context,state); } InvAddRoundKey(context,0,state); StateToChars((unsigned char*)input,state,context->nb); }
int rijndaelKeyEnctoDec (int keyBits, word8 W[MAXROUNDS+1][4][4]) { int r; for (r = 1; r < ROUNDS; r++) { InvMixColumn(W[r], 4); } return 0; }
int rijndaelDecryptRound (word8 a[4][MAXBC], int keyBits, int blockBits, word8 rk[MAXROUNDS+1][4][MAXBC], int rounds) /* Decrypt only a certain number of rounds. * Only used in the Intermediate Value Known Answer Test. * Operations rearranged such that the intermediate values * of decryption correspond with the intermediate values * of encryption. */ { int r, BC, ROUNDS; switch (blockBits) { case 128: BC = 4; break; case 192: BC = 6; break; case 256: BC = 8; break; default : return (-2); } switch (keyBits >= blockBits ? keyBits : blockBits) { case 128: ROUNDS = 10; break; case 192: ROUNDS = 12; break; case 256: ROUNDS = 14; break; default : return (-3); /* this cannot happen */ } /* make number of rounds sane */ if (rounds > ROUNDS) rounds = ROUNDS; /* First the special round: * without InvMixColumn * with extra KeyAddition */ KeyAddition(a,rk[ROUNDS],BC); Substitution(a,Si,BC); ShiftRow(a,1,BC); /* ROUNDS-1 ordinary rounds */ for(r = ROUNDS-1; r > rounds; r--) { KeyAddition(a,rk[r],BC); InvMixColumn(a,BC); Substitution(a,Si,BC); ShiftRow(a,1,BC); } if (rounds == 0) { /* End with the extra key addition */ KeyAddition(a,rk[0],BC); } return 0; }
int _rijndaelDecrypt (word8 a[4][MAXBC], int keyBits, int blockBits, word8 rk[MAXROUNDS+1][4][MAXBC]) { int r, BC, ROUNDS; switch (blockBits) { case 128: BC = 4; break; case 192: BC = 6; break; case 256: BC = 8; break; default : return (-2); } switch (keyBits >= blockBits ? keyBits : blockBits) { case 128: ROUNDS = 10; break; case 192: ROUNDS = 12; break; case 256: ROUNDS = 14; break; default : return (-3); /* this cannot happen */ } /* To decrypt: apply the inverse operations of the encrypt routine, * in opposite order * * (KeyAddition is an involution: it 's equal to its inverse) * (the inverse of Substitution with table S is Substitution with the inverse table of S) * (the inverse of Shiftrow is Shiftrow over a suitable distance) */ /* First the special round: * without InvMixColumn * with extra KeyAddition */ KeyAddition(a,rk[ROUNDS],BC); Substitution(a,Si,BC); ShiftRow(a,1,BC); /* ROUNDS-1 ordinary rounds */ for(r = ROUNDS-1; r > 0; r--) { KeyAddition(a,rk[r],BC); InvMixColumn(a,BC); Substitution(a,Si,BC); ShiftRow(a,1,BC); } /* End with the extra key addition */ KeyAddition(a,rk[0],BC); return 0; }
void InvCipher(WORD block[Nb], WORD key[Nb*(Nr+1)]) { for(int round=Nr-1; round>0; round--) { log_it("Round %d started with:\n", block); // InvShiftRows InvShiftRows(block); log_it("After InvShiftRows\n", block); // InvByteSub for(int i=0; i<Nb; i++) { BYTE* temp = (BYTE*)&block[i]; for (int j = 0; j < 4; j++) temp[j] = InvSubBytesTab[temp[j]]; block[i] = pack(temp); } log_it("After InvByteSub\n", block); // AddRoundKey AddRoundKey(block, &key[4*round]); log_it("After AddRoundKey\n", block); // InvMixColumn InvMixColumn(block); log_it("After InvMixColumn\n", block); } // InvShiftRows InvShiftRows(block); log_it("After InvShiftRows\n", block); // InvByteSub for(int i=0; i<Nb; i++) { BYTE* temp = (BYTE*)&block[i]; for (int j = 0; j < 4; j++) temp[j] = InvSubBytesTab[temp[j]]; block[i] = pack(temp); } log_it("After InvByteSub\n", block); // AddRoundKey AddRoundKey(block, &key[0]); log_it("After AddRoundKey\n", block); }
int rijndaelDecryptRound (word8 a[4][4], word8 rk[MAXROUNDS+1][4][4], int rounds) /* Decrypt only a certain number of rounds. * Only used in the Intermediate Value Known Answer Test. * Operations rearranged such that the intermediate values * of decryption correspond with the intermediate values * of encryption. */ { int r; /* make number of rounds sane */ if (rounds > ROUNDS) rounds = ROUNDS; /* First the special round: * without InvMixColumn * with extra KeyAddition */ KeyAddition(a,rk[ROUNDS],4); Substitution(a,Si,4); ShiftRow(a,1,4); /* ROUNDS-1 ordinary rounds */ for(r = ROUNDS-1; r > rounds; r--) { KeyAddition(a,rk[r],4); InvMixColumn(a,4); Substitution(a,Si,4); ShiftRow(a,1,4); } if (rounds == 0) { /* End with the extra key addition */ KeyAddition(a,rk[0],4); } return 0; }
char rijndaelDecrypt () { char r; /* To decrypt: apply the inverse operations of the encrypt routine, * in opposite order * * (KeyAddition is an involution: it 's equal to its inverse) * (the inverse of Substitution with table S is Substitution with the inverse table of S) * (the inverse of Shiftrow is Shiftrow over a suitable distance) */ /* First the special round: * without InvMixColumn * with extra KeyAddition */ KeyAddition ( ROUNDS ); SubstitutionSi(); ShiftRow1(); /* ROUNDS-1 ordinary rounds */ for ( r = ROUNDS - 1; r > 0; r-- ) { KeyAddition ( r ); InvMixColumn(); SubstitutionSi(); ShiftRow1(); } /* End with the extra key addition */ KeyAddition ( 0 ); return 0; }
/* // Expansion of key for Rijndael's Encryption */ void ExpandRijndaelKey(const Ipp8u* pKey, int NK, int NB, int NR, int nKeys, Ipp8u* pEncKeys, Ipp8u* pDecKeys) { Ipp32u* enc_keys = (Ipp32u*)pEncKeys; Ipp32u* dec_keys = (Ipp32u*)pDecKeys; /* convert security key to WORD and save into the enc_key array */ int n; for(n=0; n<NK; n++) enc_keys[n] = BYTES_TO_WORD(pKey[4*n+0], pKey[4*n+1], pKey[4*n+2], pKey[4*n+3]); /* 128-bits Key */ if(NK128 == NK) { const Ipp32u* rtbl = RconTbl; Ipp32u k0 = enc_keys[0]; Ipp32u k1 = enc_keys[1]; Ipp32u k2 = enc_keys[2]; Ipp32u k3 = enc_keys[3]; for(n=NK128; n<nKeys; n+=NK128) { /* key expansion: extract bytes, substitute via Sbox and rotate */ k0 ^= BYTES_TO_WORD( RijEncSbox[EBYTE(k3,1)], RijEncSbox[EBYTE(k3,2)], RijEncSbox[EBYTE(k3,3)], RijEncSbox[EBYTE(k3,0)] ) ^ *rtbl++; k1 ^= k0; k2 ^= k1; k3 ^= k2; /* add key expansion */ enc_keys[n ] = k0; enc_keys[n+1] = k1; enc_keys[n+2] = k2; enc_keys[n+3] = k3; } } /* 192-bits Key */ else if(NK192 == NK) { const Ipp32u* rtbl = RconTbl; Ipp32u k0 = enc_keys[0]; Ipp32u k1 = enc_keys[1]; Ipp32u k2 = enc_keys[2]; Ipp32u k3 = enc_keys[3]; Ipp32u k4 = enc_keys[4]; Ipp32u k5 = enc_keys[5]; for(n=NK192; n<nKeys; n+=NK192) { /* key expansion: extract bytes, substitute via Sbox and rorate */ k0 ^= BYTES_TO_WORD( RijEncSbox[EBYTE(k5,1)], RijEncSbox[EBYTE(k5,2)], RijEncSbox[EBYTE(k5,3)], RijEncSbox[EBYTE(k5,0)] ) ^ *rtbl++; k1 ^= k0; k2 ^= k1; k3 ^= k2; k4 ^= k3; k5 ^= k4; /* add key expansion */ enc_keys[n ] = k0; enc_keys[n+1] = k1; enc_keys[n+2] = k2; enc_keys[n+3] = k3; enc_keys[n+4] = k4; enc_keys[n+5] = k5; } } /* 256-bits Key */ else { const Ipp32u* rtbl = RconTbl; Ipp32u k0 = enc_keys[0]; Ipp32u k1 = enc_keys[1]; Ipp32u k2 = enc_keys[2]; Ipp32u k3 = enc_keys[3]; Ipp32u k4 = enc_keys[4]; Ipp32u k5 = enc_keys[5]; Ipp32u k6 = enc_keys[6]; Ipp32u k7 = enc_keys[7]; for(n=NK256; n<nKeys; n+=NK256) { /* key expansion: extract bytes, substitute via Sbox and rorate */ k0 ^= BYTES_TO_WORD( RijEncSbox[EBYTE(k7,1)], RijEncSbox[EBYTE(k7,2)], RijEncSbox[EBYTE(k7,3)], RijEncSbox[EBYTE(k7,0)] ) ^ *rtbl++; k1 ^= k0; k2 ^= k1; k3 ^= k2; k4 ^= BYTES_TO_WORD( RijEncSbox[EBYTE(k3,0)], RijEncSbox[EBYTE(k3,1)], RijEncSbox[EBYTE(k3,2)], RijEncSbox[EBYTE(k3,3)] ); k5 ^= k4; k6 ^= k5; k7 ^= k6; /* add key expansion */ enc_keys[n ] = k0; enc_keys[n+1] = k1; enc_keys[n+2] = k2; enc_keys[n+3] = k3; enc_keys[n+4] = k4; enc_keys[n+5] = k5; enc_keys[n+6] = k6; enc_keys[n+7] = k7; } } /* // Key Expansion for Decryption */ /* copy keys */ CopyBlock(enc_keys, dec_keys, sizeof(Ipp32u)*nKeys); /* update decryption keys */ for(n=NB; n<NR*NB; n++) dec_keys[n] = InvMixColumn(dec_keys[n], InvMixCol_Tbl); }