📄 aes_ref.c
字号:
state[(col + Shr[2]) % Ncol][2] = bval(t[col], 2);
state[(col + Shr[3]) % Ncol][3] = bval(t[col], 3);
}
}
// the MixColumns transformation performed on all columns of the state
void MixColumns(byte state[][4], word Ncol)
{ word col;
byte t, u;
for(col = 0; col < Ncol; ++col)
{ t = state[col][0];
u = state[col][0] ^ state[col][1] ^ state[col][2] ^ state[col][3];
state[col][0] ^= u ^ FFmulX(t ^ state[col][1]);
state[col][1] ^= u ^ FFmulX(state[col][1] ^ state[col][2]);
state[col][2] ^= u ^ FFmulX(state[col][2] ^ state[col][3]);
state[col][3] ^= u ^ FFmulX(state[col][3] ^ t);
}
}
// the inverse MixColumns transformation performed on all columns of the state
void InvMixColumns(byte state[][4], word Ncol)
{ word col;
byte t, u, v;
for(col = 0; col < Ncol; ++col)
{ t = state[col][0];
u = state[col][0] ^ state[col][1] ^ state[col][2] ^ state[col][3];
u ^= FFmulX(FFmulX(FFmulX(u)));
v = u ^ FFmulX(FFmulX(state[col][1] ^ state[col][3]));
u ^= FFmulX(FFmulX(state[col][0] ^ state[col][2]));
state[col][0] ^= u ^ FFmulX(t ^ state[col][1]);
state[col][1] ^= v ^ FFmulX(state[col][1] ^ state[col][2]);
state[col][2] ^= u ^ FFmulX(state[col][2] ^ state[col][3]);
state[col][3] ^= v ^ FFmulX(state[col][3] ^ t);
}
}
// XorRoundKey - add the round key to the state
void XorRoundKey(byte state[][4], const word rk[], const word Ncol)
{ word col, t;
for(col = 0; col < Ncol; ++col)
{ t = rk[col];
state[col][0] ^= bval(t,0);
state[col][1] ^= bval(t,1);
state[col][2] ^= bval(t,2);
state[col][3] ^= bval(t,3);
}
}
// input the state from the input byte array
void GetState(byte state[][4], const byte in[], const word Ncol)
{ word col, i;
for(col = 0, i = 0; col < Ncol; ++col)
{
state[col][0] = in[i++];
state[col][1] = in[i++];
state[col][2] = in[i++];
state[col][3] = in[i++];
}
}
// output the state to the output byte array
void PutState(const byte state[][4], byte out[], const word Ncol)
{ word col, i;
for(col = 0, i = 0; col < Ncol; ++col)
{
out[i++] = state[col][0];
out[i++] = state[col][1];
out[i++] = state[col][2];
out[i++] = state[col][3];
}
}
#if(0)
// code to test the generation of the key schedule from the top downwards
static word t_key[128];
void reverse(const word Ncol, const word Nrnd, const word Nkey, const byte e_key[])
{ word i;
i = Ncol * (Nrnd + 1);
while(i-- > Ncol * (Nrnd + 1) - Nkey)
{
t_key[i] = e_key[i];
}
i = Ncol * (Nrnd + 1);
while(i-- > Nkey)
{
word t = t_key[i - 1];
if(i % Nkey == 0)
{
t = SubWord(RotWord(t)) ^ bytes2word(rc_tab[i / Nkey - 1], 0, 0, 0);
}
else if(Nkey > 6 && i % Nkey == 4)
t = SubWord(t);
t_key[i - Nkey] = t_key[i] ^ t;
}
}
#endif
// Subroutne to set the block size (if variable)
#if defined(BLOCK_SIZE)
#define nc (Ncol)
#else
#define nc (cx->Ncol)
#endif
#if !defined(BLOCK_SIZE)
cf_dec c_name(set_blk)(const word n_bytes, c_name(aes) *cx)
{
if((n_bytes & 3) || n_bytes < 16 || n_bytes > 32)
{
return (n_bytes ? cx->mode &= ~0x07, aes_bad : (aes_ret)(nc << 2));
}
cx->mode = cx->mode & ~0x07 | 0x04;
nc = n_bytes >> 2;
return aes_good;
}
#endif
// Key Expansion - expand the key to form the key schedule from the
// user supplied key, where Nk is the key length in bits divided by
// 32 with a value of 4, 5, 6, 7 or 8
cf_dec c_name(set_key)(const byte key[], const word n_bytes, const enum aes_key f, c_name(aes) *cx)
{ word i;
byte rc;
const byte *p;
if((n_bytes & 3) || n_bytes < 16 || n_bytes > 32 || !(f & 1) && !(f & 2))
{
return (n_bytes ? cx->mode &= ~0x03, aes_bad : (aes_ret)(cx->Nkey << 2));
}
cx->mode = cx->mode & ~0x03 | (byte)f & 0x03;
cx->Nkey = n_bytes >> 2;
cx->Nrnd = Nr(cx->Nkey, nc);
i = 0; p = key;
while (i < cx->Nkey)
{
cx->e_key[i] = bytes2word(p[0], p[1], p[2], p[3]);
i = i + 1; p += Nrow;
}
i = cx->Nkey; rc = 1;
while(i < nc * (cx->Nrnd + 1))
{
word t = cx->e_key[i - 1];
if(i % cx->Nkey == 0)
{
t = SubWord(RotWord(t)) ^ bytes2word(rc, 0, 0, 0); rc = FFmulX(rc);
}
else if(cx->Nkey > 6 && i % cx->Nkey == 4)
t = SubWord(t);
cx->e_key[i] = cx->e_key[i - cx->Nkey] ^ t;
i = i + 1;
}
if(cx->mode != enc)
{
for(i = 0; i < (cx->Nrnd + 1) * nc; ++i)
cx->d_key[i] = cx->e_key[i];
for(i = 1; i < cx->Nrnd; ++i)
InvMixColumns((wa_ptr*)(cx->d_key + i * nc), nc);
}
// reverse(nc, Nrnd, Nkey, e_key);
return aes_good;
}
// The Forward Cipher
cf_dec c_name(encrypt)(const byte input[], byte output[], const c_name(aes) *cx)
{ byte state[Mcol][4];
word Shr[Nrow], rnd;
if(!(cx->mode & 0x01)) return aes_bad;
Shr[1] = 1;
Shr[2] = (nc == 8 ? 3 : 2);
Shr[3] = (nc > 6 ? 4 : 3);
GetState(state, input, nc);
XorRoundKey(state, cx->e_key, nc);
for(rnd = 1; rnd < cx->Nrnd; ++rnd)
{
SubBytes(state, nc);
ShiftRows(state, nc, Shr);
MixColumns(state, nc);
XorRoundKey(state, cx->e_key + rnd * nc, nc);
}
SubBytes(state, nc);
ShiftRows(state, nc, Shr);
XorRoundKey(state, cx->e_key + cx->Nrnd * nc, nc);
PutState(state, output, nc);
return aes_good;
}
// The Inverse Cipher (in normal and modified equivalent form)
cf_dec c_name(decrypt)(const byte input[], byte output[], const c_name(aes) *cx)
{ byte state[Mcol][4];
word Shr[Nrow], rnd;
if(!(cx->mode & 0x02)) return aes_bad;
Shr[1] = 1;
Shr[2] = (nc == 8 ? 3 : 2);
Shr[3] = (nc > 6 ? 4 : 3);
GetState(state, input, nc);
XorRoundKey(state, cx->e_key + cx->Nrnd * nc, nc);
for(rnd = cx->Nrnd - 1; rnd > 0; --rnd)
{
if(mod)
{
InvSubBytes(state, nc);
InvShiftRows(state, nc, Shr);
InvMixColumns(state, nc);
XorRoundKey(state, cx->d_key + rnd * nc, nc);
}
else
{
InvShiftRows(state, nc, Shr);
InvSubBytes(state, nc);
XorRoundKey(state, cx->e_key + rnd * nc, nc);
InvMixColumns(state, nc);
}
}
if(mod)
{
InvSubBytes(state, nc);
InvShiftRows(state, nc, Shr);
}
else
{
InvShiftRows(state, nc, Shr);
InvSubBytes(state, nc);
}
XorRoundKey(state, cx->e_key, nc);
PutState(state, output, nc);
return aes_good;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -