minor AES optimization

This commit is contained in:
Jack Andersen 2015-07-13 16:23:36 -10:00
parent 09e3d33ff2
commit 87306a18d8
1 changed files with 143 additions and 151 deletions

View File

@ -20,8 +20,6 @@ namespace Athena
#define ROTL16(x) (((x)<<16)|((x)>>16))
#define ROTL24(x) (((x)<<24)|((x)>>8))
/* Fixed Data */
static const uint8_t InCo[4] = {0xB, 0xD, 0x9, 0xE}; /* Inverse Coefficients */
static inline uint32_t pack(const uint8_t* b)
@ -51,9 +49,8 @@ static inline uint8_t xtime(uint8_t a)
return a;
}
class SoftwareAES : public IAES
static const struct SoftwareAESTables
{
protected:
uint8_t fbsub[256];
uint8_t rbsub[256];
uint8_t ptab[256], ltab[256];
@ -61,38 +58,14 @@ protected:
uint32_t rtable[256];
uint32_t rco[30];
/* Parameter-dependent data */
int Nk, Nb, Nr;
uint8_t fi[24], ri[24];
uint32_t fkey[120];
uint32_t rkey[120];
uint8_t bmul(uint8_t x, uint8_t y);
uint32_t SubByte(uint32_t a);
uint8_t product(uint32_t x, uint32_t y);
uint32_t InvMixCol(uint32_t x);
uint8_t ByteSub(uint8_t x);
void gentables(void);
void gkey(int nb, int nk, const uint8_t* key);
void _encrypt(uint8_t* buff);
void _decrypt(uint8_t* buff);
public:
void encrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len);
void decrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len);
void setKey(const uint8_t* key);
};
uint8_t SoftwareAES::bmul(uint8_t x, uint8_t y)
uint8_t bmul(uint8_t x, uint8_t y) const
{
/* x.y= AntiLog(Log(x) + Log(y)) */
if (x && y) return ptab[(ltab[x] + ltab[y]) % 255];
else return 0;
}
uint32_t SoftwareAES::SubByte(uint32_t a)
uint32_t SubByte(uint32_t a) const
{
uint8_t b[4];
unpack(a, b);
@ -103,7 +76,7 @@ uint32_t SoftwareAES::SubByte(uint32_t a)
return pack(b);
}
uint8_t SoftwareAES::product(uint32_t x, uint32_t y)
uint8_t product(uint32_t x, uint32_t y) const
{
/* dot product of two 4-byte arrays */
uint8_t xb[4], yb[4];
@ -112,7 +85,7 @@ uint8_t SoftwareAES::product(uint32_t x, uint32_t y)
return bmul(xb[0], yb[0])^bmul(xb[1], yb[1])^bmul(xb[2], yb[2])^bmul(xb[3], yb[3]);
}
uint32_t SoftwareAES::InvMixCol(uint32_t x)
uint32_t InvMixCol(uint32_t x) const
{
/* matrix Multiplication */
uint32_t y, m;
@ -130,7 +103,7 @@ uint32_t SoftwareAES::InvMixCol(uint32_t x)
return y;
}
uint8_t SoftwareAES::ByteSub(uint8_t x)
uint8_t ByteSub(uint8_t x) const
{
uint8_t y = ptab[255 - ltab[x]]; /* multiplicative inverse */
x = y;
@ -146,7 +119,7 @@ uint8_t SoftwareAES::ByteSub(uint8_t x)
return y;
}
void SoftwareAES::gentables(void)
SoftwareAESTables()
{
/* generate tables */
int i;
@ -202,6 +175,26 @@ void SoftwareAES::gentables(void)
rtable[i] = pack(b);
}
}
} AEStb;
class SoftwareAES : public IAES
{
protected:
/* Parameter-dependent data */
int Nk, Nb, Nr;
uint8_t fi[24], ri[24];
uint32_t fkey[120];
uint32_t rkey[120];
void gkey(int nb, int nk, const uint8_t* key);
void _encrypt(uint8_t* buff);
void _decrypt(uint8_t* buff);
public:
void encrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len);
void decrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len);
void setKey(const uint8_t* key);
};
void SoftwareAES::gkey(int nb, int nk, const uint8_t* key)
{
@ -247,7 +240,7 @@ void SoftwareAES::gkey(int nb, int nk, const uint8_t* key)
for (j = Nk, k = 0; j < N; j += Nk, k++)
{
fkey[j] = fkey[j - Nk] ^ SubByte(ROTL24(fkey[j - 1]))^rco[k];
fkey[j] = fkey[j - Nk] ^ AEStb.SubByte(ROTL24(fkey[j - 1]))^AEStb.rco[k];
if (Nk <= 6)
{
@ -259,7 +252,7 @@ void SoftwareAES::gkey(int nb, int nk, const uint8_t* key)
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]);
if ((j + 4) < N) fkey[j + 4] = fkey[j + 4 - Nk] ^ AEStb.SubByte(fkey[j + 3]);
for (i = 5; i < Nk && (i + j) < N; i++)
fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1];
@ -275,7 +268,7 @@ void SoftwareAES::gkey(int nb, int nk, const uint8_t* key)
{
k = N - Nb - i;
for (j = 0; j < Nb; j++) rkey[k + j] = InvMixCol(fkey[i + j]);
for (j = 0; j < Nb; j++) rkey[k + j] = AEStb.InvMixCol(fkey[i + j]);
}
for (j = N - Nb; j < N; j++) rkey[j - N + Nb] = fkey[j];
@ -313,10 +306,10 @@ void SoftwareAES::_encrypt(uint8_t* buff)
{
/* deal with each 32-bit element of the State */
/* This is the time-critical bit */
y[j] = fkey[k++] ^ ftable[(uint8_t)x[j]] ^
ROTL8(ftable[(uint8_t)(x[fi[m]] >> 8)])^
ROTL16(ftable[(uint8_t)(x[fi[m + 1]] >> 16)])^
ROTL24(ftable[(uint8_t)(x[fi[m + 2]] >> 24)]);
y[j] = fkey[k++] ^ AEStb.ftable[(uint8_t)x[j]] ^
ROTL8(AEStb.ftable[(uint8_t)(x[fi[m]] >> 8)])^
ROTL16(AEStb.ftable[(uint8_t)(x[fi[m + 1]] >> 16)])^
ROTL24(AEStb.ftable[(uint8_t)(x[fi[m + 2]] >> 24)]);
}
t = x;
@ -327,10 +320,10 @@ void SoftwareAES::_encrypt(uint8_t* buff)
/* Last Round - unroll if possible */
for (m = j = 0; j < Nb; j++, m += 3)
{
y[j] = fkey[k++] ^ (uint32_t)fbsub[(uint8_t)x[j]] ^
ROTL8((uint32_t)fbsub[(uint8_t)(x[fi[m]] >> 8)])^
ROTL16((uint32_t)fbsub[(uint8_t)(x[fi[m + 1]] >> 16)])^
ROTL24((uint32_t)fbsub[(uint8_t)(x[fi[m + 2]] >> 24)]);
y[j] = fkey[k++] ^ (uint32_t)AEStb.fbsub[(uint8_t)x[j]] ^
ROTL8((uint32_t)AEStb.fbsub[(uint8_t)(x[fi[m]] >> 8)])^
ROTL16((uint32_t)AEStb.fbsub[(uint8_t)(x[fi[m + 1]] >> 16)])^
ROTL24((uint32_t)AEStb.fbsub[(uint8_t)(x[fi[m + 2]] >> 24)]);
}
for (i = j = 0; i < Nb; i++, j += 4)
@ -368,10 +361,10 @@ void SoftwareAES::_decrypt(uint8_t* buff)
for (m = j = 0; j < Nb; j++, m += 3)
{
/* This is the time-critical bit */
y[j] = rkey[k++] ^ rtable[(uint8_t)x[j]] ^
ROTL8(rtable[(uint8_t)(x[ri[m]] >> 8)])^
ROTL16(rtable[(uint8_t)(x[ri[m + 1]] >> 16)])^
ROTL24(rtable[(uint8_t)(x[ri[m + 2]] >> 24)]);
y[j] = rkey[k++] ^ AEStb.rtable[(uint8_t)x[j]] ^
ROTL8(AEStb.rtable[(uint8_t)(x[ri[m]] >> 8)])^
ROTL16(AEStb.rtable[(uint8_t)(x[ri[m + 1]] >> 16)])^
ROTL24(AEStb.rtable[(uint8_t)(x[ri[m + 2]] >> 24)]);
}
t = x;
@ -382,10 +375,10 @@ void SoftwareAES::_decrypt(uint8_t* buff)
/* Last Round - unroll if possible */
for (m = j = 0; j < Nb; j++, m += 3)
{
y[j] = rkey[k++] ^ (uint32_t)rbsub[(uint8_t)x[j]] ^
ROTL8((uint32_t)rbsub[(uint8_t)(x[ri[m]] >> 8)])^
ROTL16((uint32_t)rbsub[(uint8_t)(x[ri[m + 1]] >> 16)])^
ROTL24((uint32_t)rbsub[(uint8_t)(x[ri[m + 2]] >> 24)]);
y[j] = rkey[k++] ^ (uint32_t)AEStb.rbsub[(uint8_t)x[j]] ^
ROTL8((uint32_t)AEStb.rbsub[(uint8_t)(x[ri[m]] >> 8)])^
ROTL16((uint32_t)AEStb.rbsub[(uint8_t)(x[ri[m + 1]] >> 16)])^
ROTL24((uint32_t)AEStb.rbsub[(uint8_t)(x[ri[m + 2]] >> 24)]);
}
for (i = j = 0; i < Nb; i++, j += 4)
@ -399,12 +392,11 @@ void SoftwareAES::_decrypt(uint8_t* buff)
void SoftwareAES::setKey(const uint8_t* key)
{
gentables();
gkey(4, 4, key);
}
// CBC mode decryption
void SoftwareAES::decrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len)
void SoftwareAES::decrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, size_t len)
{
uint8_t block[16];
const uint8_t* ctext_ptr;