📄 aes.cpp
字号:
#include "stdafx.h"
#include "aes.h"
static WORD digitValue[]=
{
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
0x0008, 0x0009, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
};
static unsigned char nextKeyScheduleDword[] =
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 0
};
static ULONG initialKeySchedule[] =
{
0xb7e15163, 0x5618cb1c, /* Pseudo-round #0 */
0xf45044d5, 0x9287be8e, /* Round #1 */
0x30bf3847, 0xcef6b200, /* Round #2 */
0x6d2e2bb9, 0x0b65a572, /* Round #3 */
0xa99d1f2b, 0x47d498e4, /* Round #4 */
0xe60c129d, 0x84438c56, /* Round #5 */
0x227b060f, 0xc0b27fc8, /* Round #6 */
0x5ee9f981, 0xfd21733a, /* Round #7 */
0x9b58ecf3, 0x399066ac, /* Round #8 */
0xd7c7e065, 0x75ff5a1e, /* Round #9 */
0x1436d3d7, 0xb26e4d90, /* Round #10 */
0x50a5c749, 0xeedd4102, /* Round #11 */
0x8d14babb, 0x2b4c3474, /* Round #12 */
0xc983ae2d, 0x67bb27e6, /* Round #13 */
0x05f2a19f, 0xa42a1b58, /* Round #14 */
0x42619511, 0xe0990eca, /* Round #15 */
0x7ed08883, 0x1d08023c, /* Round #16 */
0xbb3f7bf5, 0x5976f5ae, /* Round #17 */
0xf7ae6f67, 0x95e5e920, /* Round #18 */
0x341d62d9, 0xd254dc92, /* Round #19 */
0x708c564b, 0x0ec3d004, /* Round #20 */
0xacfb49bd, 0x4b32c376 /* Pseudo-round #21 */
};
CAES::CAES()
{
}
CAES::~CAES()
{
}
void CAES::Rc6ComputeKeySchedule(BYTE* key, int keyLengthInBytes,unsigned long* S)
{
unsigned long L[(255+4-1)/4];
unsigned int count;//int count;
unsigned long i,j;
unsigned long A,B;
unsigned long thirtytwo = 32;
UCHAR nextKeyDword[((255+4-1)/4)*4];
/* Compute number of dwords taken up by key */
unsigned long c = ((keyLengthInBytes+4-1) >> 2)
+((((unsigned long) keyLengthInBytes)-1) >> 31);
/* Set up table of indices of next element in original key array.
* We'll make use of the fact that Intels are little-endian. */
*((unsigned long*) &(nextKeyDword[0])) = 0x04030201;
*((unsigned long*) &(nextKeyDword[4])) = 0x08070605;
count = 4;
while ((count += 4) < c) {
*((unsigned long*) &(nextKeyDword[count])) =
(count*0x01010101UL)+0x04030201;
}
nextKeyDword[c-1] = 0;
/* Zero out last element of array of key dwords */
L[c-1] = 0;
/* Load all the key bytes into the array of key dwords. This method
* of performing this task requires a little-endian CPU. */
memcpy((void*) L, (void*) key, keyLengthInBytes);
/* Initialize key schedule array */
memcpy((void*) S, (void*) initialKeySchedule, 4*(2+2*ROUNDS+2));
count = ((c <= (2+2*ROUNDS+2)) ? (2+2*ROUNDS+2) : c);
A = B = i = j = 0;
/* Mix the key into the key schedule array */
do {
unsigned long sum;
S[i] += A+B;
A = S[i] = CONST_ROTL(S[i], 3);
i = nextKeyScheduleDword[i];
sum = A+B;
L[j] += sum;
B = L[j] = ROTL(L[j], sum);
j = nextKeyDword[j];
S[i] += A+B;
A = S[i] = CONST_ROTL(S[i], 3);
i = nextKeyScheduleDword[i];
sum = A+B;
L[j] += sum;
B = L[j] = ROTL(L[j], sum);
j = nextKeyDword[j];
S[i] += A+B;
A = S[i] = CONST_ROTL(S[i], 3);
i = nextKeyScheduleDword[i];
sum = A+B;
L[j] += sum;
B = L[j] = ROTL(L[j], sum);
j = nextKeyDword[j];
} while (--count > 0);
}
/*
* Rc6EncryptEcb() encrypts a specified number of blocks in ECB mode.
*/
void CAES::Rc6EncryptEcb(unsigned long* keySchedule, int numberOfBlocks,
unsigned long* plaintext, unsigned long* ciphertext)
{
unsigned long thirtytwo = 32;
unsigned long S[2+2*ROUNDS+2];
if (numberOfBlocks == 0)
return;
/* Let's put our key schedule conveniently in this stack frame */
memcpy((void*) S, (void*) keySchedule, 4*(2+2*ROUNDS+2));
do {
unsigned long A, B, C, D;
unsigned long t,u;
/* Perform pseudo-round #0 and round #1 */
B = plaintext[1]+S[0];
D = plaintext[3]+S[1];
t = (B+B+1)*B;
u = (D+D+1)*D;
t = CONST_ROTL(t, 5);
u = CONST_ROTL(u, 5);
A = plaintext[0] ^ t;
A = ROTL(A, u)+S[2];
C = plaintext[2] ^ u;
C = ROTL(C, t)+S[3];
/* Perform rounds #2-18 */
ENCRYPT_MIDDLE(S, A, B, C, D);
/* Perform round #19 */
ENCRYPT_ROUND(S, 38, C, D, A, B,t,u);
/* Perform round #20 and pseudo-round #21 */
t = (A+A+1)*A;
u = (C+C+1)*C;
t = CONST_ROTL(t, 5);
u = CONST_ROTL(u, 5);
D ^= t;
ciphertext[0] = A+S[42];
ciphertext[3] = ROTL(D, u)+S[40];
B ^= u;
ciphertext[2] = C+S[43];
ciphertext[1] = ROTL(B, t)+S[41];
/* Update text pointers */
plaintext += 4;
ciphertext += 4;
} while (--numberOfBlocks > 0);
}
/*
* Rc6EncryptCbc() encrypts a specified number of blocks in CBC mode.
* In the process, it alters the 16-byte value pointed to by ivBytes.
*/
void CAES::Rc6EncryptCbc(unsigned long* keySchedule, int numberOfBlocks,
unsigned long* ivDwords,
unsigned long* plaintext, unsigned long* ciphertext)
{
unsigned long thirtytwo = 32;
unsigned long IV[4];
unsigned long S[2+2*ROUNDS+2];
if (numberOfBlocks == 0)
return;
/* Let's put our IV and key schedule conveniently in this stack frame */
IV[0] = ivDwords[0];
IV[1] = ivDwords[1];
IV[2] = ivDwords[2];
IV[3] = ivDwords[3];
memcpy((void*) S, (void*) keySchedule, 4*(2+2*ROUNDS+2));
do
{
unsigned long A, B, C, D;
unsigned long t,u;
/* XOR in IV and perform pseudo-round #0 and round #1 */
B = (plaintext[1] ^ IV[1])+S[0];
D = (plaintext[3] ^ IV[3])+S[1];
t = (B+B+1)*B;
u = (D+D+1)*D;
t = CONST_ROTL(t, 5);
u = CONST_ROTL(u, 5);
A = (plaintext[0] ^ IV[0]) ^ t;
A = ROTL(A, u)+S[2];
C = (plaintext[2] ^ IV[2]) ^ u;
C = ROTL(C, t)+S[3];
/* Perform rounds #2-18 */
ENCRYPT_MIDDLE(S, A, B, C, D);
/* Perform round #19 */
ENCRYPT_ROUND(S, 38, C, D, A, B,t,u);
/* Perform round #20 and pseudo-round #17 and save IV */
t = (A+A+1)*A;
u = (C+C+1)*C;
t = CONST_ROTL(t, 5);
u = CONST_ROTL(u, 5);
D ^= t;
IV[0] = ciphertext[0] = A+S[42];
IV[3] = ciphertext[3] = ROTL(D, u)+S[40];
B ^= u;
IV[2] = ciphertext[2] = C+S[43];
IV[1] = ciphertext[1] = ROTL(B, t)+S[41];
/* Update text pointers */
plaintext += 4;
ciphertext += 4;
} while (--numberOfBlocks > 0);
/* Save IV for next call */
ivDwords[0] = IV[0];
ivDwords[1] = IV[1];
ivDwords[2] = IV[2];
ivDwords[3] = IV[3];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -