📄 rijndael.cpp
字号:
sm_U3[(tt >> 8) & 0xFF] ^
sm_U4[tt & 0xFF];
}
m_bKeyInit = true;
}
//Convenience method to encrypt exactly one block of plaintext, assuming
//Rijndael's default block size (128-bit).
// in - The plaintext
// result - The ciphertext generated from a plaintext using the key
void CRijndael::DefEncryptBlock(char const* in, char* result)
{
if(false==m_bKeyInit)
throw exception(sm_szErrorMsg1);
int* Ker = m_Ke[0];
int t0 = ((unsigned char)*(in++) << 24);
t0 |= ((unsigned char)*(in++) << 16);
t0 |= ((unsigned char)*(in++) << 8);
(t0 |= (unsigned char)*(in++)) ^= Ker[0];
int t1 = ((unsigned char)*(in++) << 24);
t1 |= ((unsigned char)*(in++) << 16);
t1 |= ((unsigned char)*(in++) << 8);
(t1 |= (unsigned char)*(in++)) ^= Ker[1];
int t2 = ((unsigned char)*(in++) << 24);
t2 |= ((unsigned char)*(in++) << 16);
t2 |= ((unsigned char)*(in++) << 8);
(t2 |= (unsigned char)*(in++)) ^= Ker[2];
int t3 = ((unsigned char)*(in++) << 24);
t3 |= ((unsigned char)*(in++) << 16);
t3 |= ((unsigned char)*(in++) << 8);
(t3 |= (unsigned char)*(in++)) ^= Ker[3];
int a0, a1, a2, a3;
//Apply Round Transforms
for (int r = 1; r < m_iROUNDS; r++)
{
Ker = m_Ke[r];
a0 = (sm_T1[(t0 >> 24) & 0xFF] ^
sm_T2[(t1 >> 16) & 0xFF] ^
sm_T3[(t2 >> 8) & 0xFF] ^
sm_T4[t3 & 0xFF]) ^ Ker[0];
a1 = (sm_T1[(t1 >> 24) & 0xFF] ^
sm_T2[(t2 >> 16) & 0xFF] ^
sm_T3[(t3 >> 8) & 0xFF] ^
sm_T4[t0 & 0xFF]) ^ Ker[1];
a2 = (sm_T1[(t2 >> 24) & 0xFF] ^
sm_T2[(t3 >> 16) & 0xFF] ^
sm_T3[(t0 >> 8) & 0xFF] ^
sm_T4[t1 & 0xFF]) ^ Ker[2];
a3 = (sm_T1[(t3 >> 24) & 0xFF] ^
sm_T2[(t0 >> 16) & 0xFF] ^
sm_T3[(t1 >> 8) & 0xFF] ^
sm_T4[t2 & 0xFF]) ^ Ker[3];
t0 = a0;
t1 = a1;
t2 = a2;
t3 = a3;
}
//Last Round is special
Ker = m_Ke[m_iROUNDS];
int tt = Ker[0];
result[0] = sm_S[(t0 >> 24) & 0xFF] ^ (tt >> 24);
result[1] = sm_S[(t1 >> 16) & 0xFF] ^ (tt >> 16);
result[2] = sm_S[(t2 >> 8) & 0xFF] ^ (tt >> 8);
result[3] = sm_S[t3 & 0xFF] ^ tt;
tt = Ker[1];
result[4] = sm_S[(t1 >> 24) & 0xFF] ^ (tt >> 24);
result[5] = sm_S[(t2 >> 16) & 0xFF] ^ (tt >> 16);
result[6] = sm_S[(t3 >> 8) & 0xFF] ^ (tt >> 8);
result[7] = sm_S[t0 & 0xFF] ^ tt;
tt = Ker[2];
result[8] = sm_S[(t2 >> 24) & 0xFF] ^ (tt >> 24);
result[9] = sm_S[(t3 >> 16) & 0xFF] ^ (tt >> 16);
result[10] = sm_S[(t0 >> 8) & 0xFF] ^ (tt >> 8);
result[11] = sm_S[t1 & 0xFF] ^ tt;
tt = Ker[3];
result[12] = sm_S[(t3 >> 24) & 0xFF] ^ (tt >> 24);
result[13] = sm_S[(t0 >> 16) & 0xFF] ^ (tt >> 16);
result[14] = sm_S[(t1 >> 8) & 0xFF] ^ (tt >> 8);
result[15] = sm_S[t2 & 0xFF] ^ tt;
}
//Convenience method to decrypt exactly one block of plaintext, assuming
//Rijndael's default block size (128-bit).
// in - The ciphertext.
// result - The plaintext generated from a ciphertext using the session key.
void CRijndael::DefDecryptBlock(char const* in, char* result)
{
if(false==m_bKeyInit)
throw exception(sm_szErrorMsg1);
int* Kdr = m_Kd[0];
int t0 = ((unsigned char)*(in++) << 24);
t0 = t0 | ((unsigned char)*(in++) << 16);
t0 |= ((unsigned char)*(in++) << 8);
(t0 |= (unsigned char)*(in++)) ^= Kdr[0];
int t1 = ((unsigned char)*(in++) << 24);
t1 |= ((unsigned char)*(in++) << 16);
t1 |= ((unsigned char)*(in++) << 8);
(t1 |= (unsigned char)*(in++)) ^= Kdr[1];
int t2 = ((unsigned char)*(in++) << 24);
t2 |= ((unsigned char)*(in++) << 16);
t2 |= ((unsigned char)*(in++) << 8);
(t2 |= (unsigned char)*(in++)) ^= Kdr[2];
int t3 = ((unsigned char)*(in++) << 24);
t3 |= ((unsigned char)*(in++) << 16);
t3 |= ((unsigned char)*(in++) << 8);
(t3 |= (unsigned char)*(in++)) ^= Kdr[3];
int a0, a1, a2, a3;
for(int r = 1; r < m_iROUNDS; r++) // apply round transforms
{
Kdr = m_Kd[r];
a0 = (sm_T5[(t0 >> 24) & 0xFF] ^
sm_T6[(t3 >> 16) & 0xFF] ^
sm_T7[(t2 >> 8) & 0xFF] ^
sm_T8[ t1 & 0xFF] ) ^ Kdr[0];
a1 = (sm_T5[(t1 >> 24) & 0xFF] ^
sm_T6[(t0 >> 16) & 0xFF] ^
sm_T7[(t3 >> 8) & 0xFF] ^
sm_T8[ t2 & 0xFF] ) ^ Kdr[1];
a2 = (sm_T5[(t2 >> 24) & 0xFF] ^
sm_T6[(t1 >> 16) & 0xFF] ^
sm_T7[(t0 >> 8) & 0xFF] ^
sm_T8[ t3 & 0xFF] ) ^ Kdr[2];
a3 = (sm_T5[(t3 >> 24) & 0xFF] ^
sm_T6[(t2 >> 16) & 0xFF] ^
sm_T7[(t1 >> 8) & 0xFF] ^
sm_T8[ t0 & 0xFF] ) ^ Kdr[3];
t0 = a0;
t1 = a1;
t2 = a2;
t3 = a3;
}
//Last Round is special
Kdr = m_Kd[m_iROUNDS];
int tt = Kdr[0];
result[ 0] = sm_Si[(t0 >> 24) & 0xFF] ^ (tt >> 24);
result[ 1] = sm_Si[(t3 >> 16) & 0xFF] ^ (tt >> 16);
result[ 2] = sm_Si[(t2 >> 8) & 0xFF] ^ (tt >> 8);
result[ 3] = sm_Si[ t1 & 0xFF] ^ tt;
tt = Kdr[1];
result[ 4] = sm_Si[(t1 >> 24) & 0xFF] ^ (tt >> 24);
result[ 5] = sm_Si[(t0 >> 16) & 0xFF] ^ (tt >> 16);
result[ 6] = sm_Si[(t3 >> 8) & 0xFF] ^ (tt >> 8);
result[ 7] = sm_Si[ t2 & 0xFF] ^ tt;
tt = Kdr[2];
result[ 8] = sm_Si[(t2 >> 24) & 0xFF] ^ (tt >> 24);
result[ 9] = sm_Si[(t1 >> 16) & 0xFF] ^ (tt >> 16);
result[10] = sm_Si[(t0 >> 8) & 0xFF] ^ (tt >> 8);
result[11] = sm_Si[ t3 & 0xFF] ^ tt;
tt = Kdr[3];
result[12] = sm_Si[(t3 >> 24) & 0xFF] ^ (tt >> 24);
result[13] = sm_Si[(t2 >> 16) & 0xFF] ^ (tt >> 16);
result[14] = sm_Si[(t1 >> 8) & 0xFF] ^ (tt >> 8);
result[15] = sm_Si[ t0 & 0xFF] ^ tt;
}
//Encrypt exactly one block of plaintext.
// in - The plaintext.
// result - The ciphertext generated from a plaintext using the key.
void CRijndael::EncryptBlock(char const* in, char* result)
{
if(false==m_bKeyInit)
throw exception(sm_szErrorMsg1);
if(DEFAULT_BLOCK_SIZE == m_blockSize)
{
DefEncryptBlock(in, result);
return;
}
int BC = m_blockSize / 4;
int SC = (BC == 4) ? 0 : (BC == 6 ? 1 : 2);
int s1 = sm_shifts[SC][1][0];
int s2 = sm_shifts[SC][2][0];
int s3 = sm_shifts[SC][3][0];
//Temporary Work Arrays
int i;
int tt;
int* pi = t;
for(i=0; i<BC; i++)
{
*pi = ((unsigned char)*(in++) << 24);
*pi |= ((unsigned char)*(in++) << 16);
*pi |= ((unsigned char)*(in++) << 8);
(*(pi++) |= (unsigned char)*(in++)) ^= m_Ke[0][i];
}
//Apply Round Transforms
for(int r=1; r<m_iROUNDS; r++)
{
for(i=0; i<BC; i++)
a[i] = (sm_T1[(t[i] >> 24) & 0xFF] ^
sm_T2[(t[(i + s1) % BC] >> 16) & 0xFF] ^
sm_T3[(t[(i + s2) % BC] >> 8) & 0xFF] ^
sm_T4[ t[(i + s3) % BC] & 0xFF] ) ^ m_Ke[r][i];
memcpy(t, a, 4*BC);
}
int j;
//Last Round is Special
for(i=0,j=0; i<BC; i++)
{
tt = m_Ke[m_iROUNDS][i];
result[j++] = sm_S[(t[i] >> 24) & 0xFF] ^ (tt >> 24);
result[j++] = sm_S[(t[(i + s1) % BC] >> 16) & 0xFF] ^ (tt >> 16);
result[j++] = sm_S[(t[(i + s2) % BC] >> 8) & 0xFF] ^ (tt >> 8);
result[j++] = sm_S[ t[(i + s3) % BC] & 0xFF] ^ tt;
}
}
//Decrypt exactly one block of ciphertext.
// in - The ciphertext.
// result - The plaintext generated from a ciphertext using the session key.
void CRijndael::DecryptBlock(char const* in, char* result)
{
if(false==m_bKeyInit)
throw exception(sm_szErrorMsg1);
if(DEFAULT_BLOCK_SIZE == m_blockSize)
{
DefDecryptBlock(in, result);
return;
}
int BC = m_blockSize / 4;
int SC = BC == 4 ? 0 : (BC == 6 ? 1 : 2);
int s1 = sm_shifts[SC][1][1];
int s2 = sm_shifts[SC][2][1];
int s3 = sm_shifts[SC][3][1];
//Temporary Work Arrays
int i;
int tt;
int* pi = t;
for(i=0; i<BC; i++)
{
*pi = ((unsigned char)*(in++) << 24);
*pi |= ((unsigned char)*(in++) << 16);
*pi |= ((unsigned char)*(in++) << 8);
(*(pi++) |= (unsigned char)*(in++)) ^= m_Kd[0][i];
}
//Apply Round Transforms
for(int r=1; r<m_iROUNDS; r++)
{
for(i=0; i<BC; i++)
a[i] = (sm_T5[(t[i] >> 24) & 0xFF] ^
sm_T6[(t[(i + s1) % BC] >> 16) & 0xFF] ^
sm_T7[(t[(i + s2) % BC] >> 8) & 0xFF] ^
sm_T8[ t[(i + s3) % BC] & 0xFF]) ^ m_Kd[r][i];
memcpy(t, a, 4*BC);
}
int j;
//Last Round is Special
for(i=0,j=0; i<BC; i++)
{
tt = m_Kd[m_iROUNDS][i];
result[j++] = sm_Si[(t[i] >> 24) & 0xFF] ^ (tt >> 24);
result[j++] = sm_Si[(t[(i + s1) % BC] >> 16) & 0xFF] ^ (tt >> 16);
result[j++] = sm_Si[(t[(i + s2) % BC] >> 8) & 0xFF] ^ (tt >> 8);
result[j++] = sm_Si[ t[(i + s3) % BC] & 0xFF] ^ tt;
}
}
void CRijndael::Encrypt(char const* in, char* result, size_t n, int iMode)
{
if(false==m_bKeyInit)
throw exception(sm_szErrorMsg1);
//n should be > 0 and multiple of m_blockSize
if(0==n || n%m_blockSize!=0)
throw exception(sm_szErrorMsg2);
int i;
char const* pin;
char* presult;
if(CBC == iMode) //CBC mode, using the Chain
{
for(i=0,pin=in,presult=result; i<n/m_blockSize; i++)
{
Xor(m_chain, pin);
EncryptBlock(m_chain, presult);
memcpy(m_chain, presult, m_blockSize);
pin += m_blockSize;
presult += m_blockSize;
}
}
else if(CFB == iMode) //CFB mode, using the Chain
{
for(i=0,pin=in,presult=result; i<n/m_blockSize; i++)
{
EncryptBlock(m_chain, presult);
Xor(presult, pin);
memcpy(m_chain, presult, m_blockSize);
pin += m_blockSize;
presult += m_blockSize;
}
}
else //ECB mode, not using the Chain
{
for(i=0,pin=in,presult=result; i<n/m_blockSize; i++)
{
EncryptBlock(pin, presult);
pin += m_blockSize;
presult += m_blockSize;
}
}
}
void CRijndael::Decrypt(char const* in, char* result, size_t n, int iMode)
{
if(false==m_bKeyInit)
throw exception(sm_szErrorMsg1);
//n should be > 0 and multiple of m_blockSize
if(0==n || n%m_blockSize!=0)
throw exception(sm_szErrorMsg2);
int i;
char const* pin;
char* presult;
if(CBC == iMode) //CBC mode, using the Chain
{
for(i=0,pin=in,presult=result; i<n/m_blockSize; i++)
{
DecryptBlock(pin, presult);
Xor(presult, m_chain);
memcpy(m_chain, pin, m_blockSize);
pin += m_blockSize;
presult += m_blockSize;
}
}
else if(CFB == iMode) //CFB mode, using the Chain, not using Decrypt()
{
for(i=0,pin=in,presult=result; i<n/m_blockSize; i++)
{
EncryptBlock(m_chain, presult);
//memcpy(presult, pin, m_blockSize);
Xor(presult, pin);
memcpy(m_chain, pin, m_blockSize);
pin += m_blockSize;
presult += m_blockSize;
}
}
else //ECB mode, not using the Chain
{
for(i=0,pin=in,presult=result; i<n/m_blockSize; i++)
{
DecryptBlock(pin, presult);
pin += m_blockSize;
presult += m_blockSize;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -