added libtomcrypt-0.87

This commit is contained in:
Tom St Denis 2003-06-19 15:23:20 +00:00 committed by Steffen Jaeckel
parent f9afcba638
commit e309942b29
19 changed files with 1697 additions and 1198 deletions

486
aes.c
View File

@ -48,7 +48,7 @@ const struct _cipher_descriptor aes_desc =
int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_key *skey)
{
int i = 0, j;
unsigned long temp, *rk;
unsigned long temp, *rk, *rrk;
_ARGCHK(key != NULL);
_ARGCHK(skey != NULL);
@ -70,13 +70,14 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
LOAD32H(rk[2], key + 8);
LOAD32H(rk[3], key + 12);
if (keylen == 16) {
j = 44;
for (;;) {
temp = rk[3];
rk[4] = rk[0] ^
(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
(Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te4[(temp ) & 0xff] & 0x0000ff00) ^
(Te4[(temp >> 24) ] & 0x000000ff) ^
(Te4_3[byte(temp, 2)]) ^
(Te4_2[byte(temp, 1)]) ^
(Te4_1[byte(temp, 0)]) ^
(Te4_0[byte(temp, 3)]) ^
rcon[i];
rk[5] = rk[1] ^ rk[4];
rk[6] = rk[2] ^ rk[5];
@ -87,6 +88,7 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
rk += 4;
}
} else if (keylen == 24) {
j = 52;
LOAD32H(rk[4], key + 16);
LOAD32H(rk[5], key + 20);
for (;;) {
@ -96,10 +98,10 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
temp = rk[5];
#endif
rk[ 6] = rk[ 0] ^
(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
(Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te4[(temp ) & 0xff] & 0x0000ff00) ^
(Te4[(temp >> 24) ] & 0x000000ff) ^
(Te4_3[byte(temp, 2)]) ^
(Te4_2[byte(temp, 1)]) ^
(Te4_1[byte(temp, 0)]) ^
(Te4_0[byte(temp, 3)]) ^
rcon[i];
rk[ 7] = rk[ 1] ^ rk[ 6];
rk[ 8] = rk[ 2] ^ rk[ 7];
@ -112,6 +114,7 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
rk += 6;
}
} else if (keylen == 32) {
j = 60;
LOAD32H(rk[4], key + 16);
LOAD32H(rk[5], key + 20);
LOAD32H(rk[6], key + 24);
@ -123,10 +126,10 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
temp = rk[7];
#endif
rk[ 8] = rk[ 0] ^
(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
(Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te4[(temp ) & 0xff] & 0x0000ff00) ^
(Te4[(temp >> 24) ] & 0x000000ff) ^
(Te4_3[byte(temp, 2)]) ^
(Te4_2[byte(temp, 1)]) ^
(Te4_1[byte(temp, 0)]) ^
(Te4_0[byte(temp, 3)]) ^
rcon[i];
rk[ 9] = rk[ 1] ^ rk[ 8];
rk[10] = rk[ 2] ^ rk[ 9];
@ -136,64 +139,105 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
}
temp = rk[11];
rk[12] = rk[ 4] ^
(Te4[(temp >> 24) ] & 0xff000000) ^
(Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(temp ) & 0xff] & 0x000000ff);
(Te4_3[byte(temp, 3)]) ^
(Te4_2[byte(temp, 2)]) ^
(Te4_1[byte(temp, 1)]) ^
(Te4_0[byte(temp, 0)]);
rk[13] = rk[ 5] ^ rk[12];
rk[14] = rk[ 6] ^ rk[13];
rk[15] = rk[ 7] ^ rk[14];
rk += 8;
}
} else {
/* this can't happen */
j = 4;
}
/* setup the inverse key now */
memcpy(skey->rijndael.dK, skey->rijndael.eK, sizeof(skey->rijndael.eK));
rk = skey->rijndael.dK;
rk = skey->rijndael.dK;
rrk = skey->rijndael.eK + j - 4;
for (i = 0, j = 4*skey->rijndael.Nr; i < j; i += 4, j -= 4) {
temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
}
/* apply the inverse MixColumn transform to all round keys but the first and the last: */
for (i = 1; i < skey->rijndael.Nr; i++) {
rk += 4;
rk[0] =
Td0[Te4[(rk[0] >> 24) ] & 0xff] ^
Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(rk[0] ) & 0xff] & 0xff];
rk[1] =
Td0[Te4[(rk[1] >> 24) ] & 0xff] ^
Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(rk[1] ) & 0xff] & 0xff];
rk[2] =
Td0[Te4[(rk[2] >> 24) ] & 0xff] ^
Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(rk[2] ) & 0xff] & 0xff];
rk[3] =
Td0[Te4[(rk[3] >> 24) ] & 0xff] ^
Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(rk[3] ) & 0xff] & 0xff];
}
/* copy first */
*rk++ = *rrk++;
*rk++ = *rrk++;
*rk++ = *rrk++;
*rk = *rrk;
rk -= 3; rrk -= 3;
for (i = 1; i < skey->rijndael.Nr; i++) {
rrk -= 4;
rk += 4;
#ifdef SMALL_CODE
temp = rrk[0];
rk[0] =
Td0[255 & Te4[byte(temp, 3)]] ^
Td1[255 & Te4[byte(temp, 2)]] ^
Td2[255 & Te4[byte(temp, 1)]] ^
Td3[255 & Te4[byte(temp, 0)]];
temp = rrk[1];
rk[1] =
Td0[255 & Te4[byte(temp, 3)]] ^
Td1[255 & Te4[byte(temp, 2)]] ^
Td2[255 & Te4[byte(temp, 1)]] ^
Td3[255 & Te4[byte(temp, 0)]];
temp = rrk[2];
rk[2] =
Td0[255 & Te4[byte(temp, 3)]] ^
Td1[255 & Te4[byte(temp, 2)]] ^
Td2[255 & Te4[byte(temp, 1)]] ^
Td3[255 & Te4[byte(temp, 0)]];
temp = rrk[3];
rk[3] =
Td0[255 & Te4[byte(temp, 3)]] ^
Td1[255 & Te4[byte(temp, 2)]] ^
Td2[255 & Te4[byte(temp, 1)]] ^
Td3[255 & Te4[byte(temp, 0)]];
#else
temp = rrk[0];
rk[0] =
Tks0[byte(temp, 3)] ^
Tks1[byte(temp, 2)] ^
Tks2[byte(temp, 1)] ^
Tks3[byte(temp, 0)];
temp = rrk[1];
rk[1] =
Tks0[byte(temp, 3)] ^
Tks1[byte(temp, 2)] ^
Tks2[byte(temp, 1)] ^
Tks3[byte(temp, 0)];
temp = rrk[2];
rk[2] =
Tks0[byte(temp, 3)] ^
Tks1[byte(temp, 2)] ^
Tks2[byte(temp, 1)] ^
Tks3[byte(temp, 0)];
temp = rrk[3];
rk[3] =
Tks0[byte(temp, 3)] ^
Tks1[byte(temp, 2)] ^
Tks2[byte(temp, 1)] ^
Tks3[byte(temp, 0)];
#endif
}
/* copy last */
rrk -= 4;
rk += 4;
*rk++ = *rrk++;
*rk++ = *rrk++;
*rk++ = *rrk++;
*rk = *rrk;
return CRYPT_OK;
}
void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
unsigned long s0, s1, s2, s3, t0, t1, t2, t3, *rk;
int Nr;
#ifdef SMALL_CODE
int r;
#endif
int Nr, r;
_ARGCHK(pt != NULL);
_ARGCHK(ct != NULL);
_ARGCHK(skey != NULL);
@ -209,78 +253,7 @@ void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
LOAD32H(s1, pt + 4); s1 ^= rk[1];
LOAD32H(s2, pt + 8); s2 ^= rk[2];
LOAD32H(s3, pt + 12); s3 ^= rk[3];
#ifndef SMALL_CODE
/* round 1: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
/* round 2: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
/* round 3: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
/* round 4: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
/* round 5: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
/* round 6: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
/* round 7: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
/* round 8: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
/* round 9: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
if (Nr > 10) {
/* round 10: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
/* round 11: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
if (Nr > 12) {
/* round 12: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
/* round 13: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
}
}
rk += Nr << 2;
#else /* SMALL_CODE */
/*
* Nr - 1 full rounds:
*/
@ -288,36 +261,36 @@ void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
for (;;) {
/* Both of these blocks are equivalent except the top is more friendlier for x86 processors */
#if 1
#if defined(__GNUC__)
t0 = rk[4]; t1 = rk[5]; t2 = rk[6]; t3 = rk[7];
t1 ^= Te3[(s0 ) & 0xFF]; t2 ^= Te2[(s0 >> 8) & 0xFF]; t3 ^= Te1[(s0 >> 16) & 0xFF]; t0 ^= Te0[(s0 >> 24)];
t2 ^= Te3[(s1 ) & 0xFF]; t3 ^= Te2[(s1 >> 8) & 0xFF]; t0 ^= Te1[(s1 >> 16) & 0xFF]; t1 ^= Te0[(s1 >> 24)];
t3 ^= Te3[(s2 ) & 0xFF]; t0 ^= Te2[(s2 >> 8) & 0xFF]; t1 ^= Te1[(s2 >> 16) & 0xFF]; t2 ^= Te0[(s2 >> 24)];
t0 ^= Te3[(s3 ) & 0xFF]; t1 ^= Te2[(s3 >> 8) & 0xFF]; t2 ^= Te1[(s3 >> 16) & 0xFF]; t3 ^= Te0[(s3 >> 24)];
t1 ^= Te3[byte(s0, 0)]; t2 ^= Te2[byte(s0, 1)]; t3 ^= Te1[byte(s0, 2)]; t0 ^= Te0[byte(s0, 3)];
t2 ^= Te3[byte(s1, 0)]; t3 ^= Te2[byte(s1, 1)]; t0 ^= Te1[byte(s1, 2)]; t1 ^= Te0[byte(s1, 3)];
t3 ^= Te3[byte(s2, 0)]; t0 ^= Te2[byte(s2, 1)]; t1 ^= Te1[byte(s2, 2)]; t2 ^= Te0[byte(s2, 3)];
t0 ^= Te3[byte(s3, 0)]; t1 ^= Te2[byte(s3, 1)]; t2 ^= Te1[byte(s3, 2)]; t3 ^= Te0[byte(s3, 3)];
#else
t0 =
Te0[(s0 >> 24) ] ^
Te1[(s1 >> 16) & 0xff] ^
Te2[(s2 >> 8) & 0xff] ^
Te3[(s3 ) & 0xff] ^
Te0[byte(s0, 3)] ^
Te1[byte(s1, 2)] ^
Te2[byte(s2, 1)] ^
Te3[byte(s3, 0)] ^
rk[4];
t1 =
Te0[(s1 >> 24) ] ^
Te1[(s2 >> 16) & 0xff] ^
Te2[(s3 >> 8) & 0xff] ^
Te3[(s0 ) & 0xff] ^
Te0[byte(s1, 3)] ^
Te1[byte(s2, 2)] ^
Te2[byte(s3, 1)] ^
Te3[byte(s0, 0)] ^
rk[5];
t2 =
Te0[(s2 >> 24) ] ^
Te1[(s3 >> 16) & 0xff] ^
Te2[(s0 >> 8) & 0xff] ^
Te3[(s1 ) & 0xff] ^
Te0[byte(s2, 3)] ^
Te1[byte(s3, 2)] ^
Te2[byte(s0, 1)] ^
Te3[byte(s1, 0)] ^
rk[6];
t3 =
Te0[(s3 >> 24) ] ^
Te1[(s0 >> 16) & 0xff] ^
Te2[(s1 >> 8) & 0xff] ^
Te3[(s2 ) & 0xff] ^
Te0[byte(s3, 3)] ^
Te1[byte(s0, 2)] ^
Te2[byte(s1, 1)] ^
Te3[byte(s2, 0)] ^
rk[7];
#endif
@ -329,78 +302,74 @@ void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
/* this second half optimization actually makes it slower on the Athlon, use with caution. */
#if 0
s1 = rk[1]; s2 = rk[2]; s3 = rk[3]; s0 = rk[0];
s1 ^= Te3[(t0 ) & 0xFF]; s2 ^= Te2[(t0 >> 8) & 0xFF]; s3 ^= Te1[(t0 >> 16) & 0xFF]; s0 ^= Te0[(t0 >> 24)];
s2 ^= Te3[(t1 ) & 0xFF]; s3 ^= Te2[(t1 >> 8) & 0xFF]; s0 ^= Te1[(t1 >> 16) & 0xFF]; s1 ^= Te0[(t1 >> 24)];
s3 ^= Te3[(t2 ) & 0xFF]; s0 ^= Te2[(t2 >> 8) & 0xFF]; s1 ^= Te1[(t2 >> 16) & 0xFF]; s2 ^= Te0[(t2 >> 24)];
s0 ^= Te3[(t3 ) & 0xFF]; s1 ^= Te2[(t3 >> 8) & 0xFF]; s2 ^= Te1[(t3 >> 16) & 0xFF]; s3 ^= Te0[(t3 >> 24)];
s1 ^= Te3[byte(t0, 0)]; s2 ^= Te2[byte(t0, 1)]; s3 ^= Te1[byte(t0, 2)]; s0 ^= Te0[byte(t0, 3)];
s2 ^= Te3[byte(t1, 0)]; s3 ^= Te2[byte(t1, 1)]; s0 ^= Te1[byte(t1, 2)]; s1 ^= Te0[byte(t1, 3)];
s3 ^= Te3[byte(t2, 0)]; s0 ^= Te2[byte(t2, 1)]; s1 ^= Te1[byte(t2, 2)]; s2 ^= Te0[byte(t2, 3)];
s0 ^= Te3[byte(t3, 0)]; s1 ^= Te2[byte(t3, 1)]; s2 ^= Te1[byte(t3, 2)]; s3 ^= Te0[byte(t3, 3)];
#else
s0 =
Te0[(t0 >> 24) ] ^
Te1[(t1 >> 16) & 0xff] ^
Te2[(t2 >> 8) & 0xff] ^
Te3[(t3 ) & 0xff] ^
Te0[byte(t0, 3)] ^
Te1[byte(t1, 2)] ^
Te2[byte(t2, 1)] ^
Te3[byte(t3, 0)] ^
rk[0];
s1 =
Te0[(t1 >> 24) ] ^
Te1[(t2 >> 16) & 0xff] ^
Te2[(t3 >> 8) & 0xff] ^
Te3[(t0 ) & 0xff] ^
Te0[byte(t1, 3)] ^
Te1[byte(t2, 2)] ^
Te2[byte(t3, 1)] ^
Te3[byte(t0, 0)] ^
rk[1];
s2 =
Te0[(t2 >> 24) ] ^
Te1[(t3 >> 16) & 0xff] ^
Te2[(t0 >> 8) & 0xff] ^
Te3[(t1 ) & 0xff] ^
Te0[byte(t2, 3)] ^
Te1[byte(t3, 2)] ^
Te2[byte(t0, 1)] ^
Te3[byte(t1, 0)] ^
rk[2];
s3 =
Te0[(t3 >> 24) ] ^
Te1[(t0 >> 16) & 0xff] ^
Te2[(t1 >> 8) & 0xff] ^
Te3[(t2 ) & 0xff] ^
Te0[byte(t3, 3)] ^
Te1[byte(t0, 2)] ^
Te2[byte(t1, 1)] ^
Te3[byte(t2, 0)] ^
rk[3];
#endif
}
#endif /* SMALL_CODE */
/*
* apply last round and
* map cipher state to byte array block:
*/
s0 =
(Te4[(t0 >> 24) ] & 0xff000000) ^
(Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t3 ) & 0xff] & 0x000000ff) ^
(Te4_3[(t0 >> 24) ]) ^
(Te4_2[(t1 >> 16) & 0xff]) ^
(Te4_1[(t2 >> 8) & 0xff]) ^
(Te4_0[(t3 ) & 0xff]) ^
rk[0];
STORE32H(s0, ct);
s1 =
(Te4[(t1 >> 24) ] & 0xff000000) ^
(Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t0 ) & 0xff] & 0x000000ff) ^
(Te4_3[(t1 >> 24) ]) ^
(Te4_2[(t2 >> 16) & 0xff]) ^
(Te4_1[(t3 >> 8) & 0xff]) ^
(Te4_0[(t0 ) & 0xff]) ^
rk[1];
STORE32H(s1, ct+4);
s2 =
(Te4[(t2 >> 24) ] & 0xff000000) ^
(Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t1 ) & 0xff] & 0x000000ff) ^
(Te4_3[(t2 >> 24) ]) ^
(Te4_2[(t3 >> 16) & 0xff]) ^
(Te4_1[(t0 >> 8) & 0xff]) ^
(Te4_0[(t1 ) & 0xff]) ^
rk[2];
STORE32H(s2, ct+8);
s3 =
(Te4[(t3 >> 24) ] & 0xff000000) ^
(Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t2 ) & 0xff] & 0x000000ff) ^
(Te4_3[(t3 >> 24) ]) ^
(Te4_2[(t0 >> 16) & 0xff]) ^
(Te4_1[(t1 >> 8) & 0xff]) ^
(Te4_0[(t2 ) & 0xff]) ^
rk[3];
STORE32H(s3, ct+12);
}
void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) {
unsigned long s0, s1, s2, s3, t0, t1, t2, t3, *rk;
int Nr;
#ifdef SMALL_CODE
int r;
#endif /* SMALL_CODE */
int Nr, r;
_ARGCHK(pt != NULL);
_ARGCHK(ct != NULL);
@ -417,106 +386,36 @@ void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
LOAD32H(s1, ct + 4); s1 ^= rk[1];
LOAD32H(s2, ct + 8); s2 ^= rk[2];
LOAD32H(s3, ct + 12); s3 ^= rk[3];
#ifndef SMALL_CODE
/* round 1: */
t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
/* round 2: */
s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
/* round 3: */
t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
/* round 4: */
s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
/* round 5: */
t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
/* round 6: */
s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
/* round 7: */
t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
/* round 8: */
s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
/* round 9: */
t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
if (Nr > 10) {
/* round 10: */
s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
/* round 11: */
t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
if (Nr > 12) {
/* round 12: */
s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
/* round 13: */
t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
}
}
rk += Nr << 2;
#else /* SMALL_CODE */
/*
* Nr - 1 full rounds:
*/
r = Nr >> 1;
for (;;) {
t0 =
Td0[(s0 >> 24) ] ^
Td1[(s3 >> 16) & 0xff] ^
Td2[(s2 >> 8) & 0xff] ^
Td3[(s1 ) & 0xff] ^
Td0[byte(s0, 3)] ^
Td1[byte(s3, 2)] ^
Td2[byte(s2, 1)] ^
Td3[byte(s1, 0)] ^
rk[4];
t1 =
Td0[(s1 >> 24) ] ^
Td1[(s0 >> 16) & 0xff] ^
Td2[(s3 >> 8) & 0xff] ^
Td3[(s2 ) & 0xff] ^
Td0[byte(s1, 3)] ^
Td1[byte(s0, 2)] ^
Td2[byte(s3, 1)] ^
Td3[byte(s2, 0)] ^
rk[5];
t2 =
Td0[(s2 >> 24) ] ^
Td1[(s1 >> 16) & 0xff] ^
Td2[(s0 >> 8) & 0xff] ^
Td3[(s3 ) & 0xff] ^
Td0[byte(s2, 3)] ^
Td1[byte(s1, 2)] ^
Td2[byte(s0, 1)] ^
Td3[byte(s3, 0)] ^
rk[6];
t3 =
Td0[(s3 >> 24) ] ^
Td1[(s2 >> 16) & 0xff] ^
Td2[(s1 >> 8) & 0xff] ^
Td3[(s0 ) & 0xff] ^
Td0[byte(s3, 3)] ^
Td1[byte(s2, 2)] ^
Td2[byte(s1, 1)] ^
Td3[byte(s0, 0)] ^
rk[7];
rk += 8;
@ -524,32 +423,33 @@ void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
break;
}
s0 =
Td0[(t0 >> 24) ] ^
Td1[(t3 >> 16) & 0xff] ^
Td2[(t2 >> 8) & 0xff] ^
Td3[(t1 ) & 0xff] ^
Td0[byte(t0, 3)] ^
Td1[byte(t3, 2)] ^
Td2[byte(t2, 1)] ^
Td3[byte(t1, 0)] ^
rk[0];
s1 =
Td0[(t1 >> 24) ] ^
Td1[(t0 >> 16) & 0xff] ^
Td2[(t3 >> 8) & 0xff] ^
Td3[(t2 ) & 0xff] ^
Td0[byte(t1, 3)] ^
Td1[byte(t0, 2)] ^
Td2[byte(t3, 1)] ^
Td3[byte(t2, 0)] ^
rk[1];
s2 =
Td0[(t2 >> 24) ] ^
Td1[(t1 >> 16) & 0xff] ^
Td2[(t0 >> 8) & 0xff] ^
Td3[(t3 ) & 0xff] ^
Td0[byte(t2, 3)] ^
Td1[byte(t1, 2)] ^
Td2[byte(t0, 1)] ^
Td3[byte(t3, 0)] ^
rk[2];
s3 =
Td0[(t3 >> 24) ] ^
Td1[(t2 >> 16) & 0xff] ^
Td2[(t1 >> 8) & 0xff] ^
Td3[(t0 ) & 0xff] ^
Td0[byte(t3, 3)] ^
Td1[byte(t2, 2)] ^
Td2[byte(t1, 1)] ^
Td3[byte(t0, 0)] ^
rk[3];
}
#endif /* SMALL_CODE */
/*
* apply last round and
* map cipher state to byte array block:

1581
aes_tab.c

File diff suppressed because it is too large Load Diff

View File

@ -347,7 +347,14 @@ int blowfish_setup(const unsigned char *key, int keylen, int num_rounds,
return CRYPT_OK;
}
#define F(x) ((((key->blowfish.S[0][((x)>>24)&255] + key->blowfish.S[1][((x)>>16)&255]) ^ key->blowfish.S[2][((x)>>8)&255]) + key->blowfish.S[3][((x)>>0)&255]))
#if defined(__GNUC__)
#define S1 key->blowfish.S[0]
#define S2 key->blowfish.S[1]
#define S3 key->blowfish.S[2]
#define S4 key->blowfish.S[3]
#endif
#define F(x) ((S1[byte(x,3)] + S2[byte(x,2)]) ^ S3[byte(x,1)]) + S4[byte(x,0)]
#ifdef CLEAN_STACK
static void _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
@ -357,10 +364,20 @@ void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
{
unsigned long L, R;
int r;
#if !defined(TWOFISH_SMALL) && !defined(__GNUC__)
unsigned long *S1, *S2, *S3, *S4;
#endif
_ARGCHK(pt != NULL);
_ARGCHK(ct != NULL);
_ARGCHK(key != NULL);
_ARGCHK(pt != NULL);
_ARGCHK(ct != NULL);
_ARGCHK(key != NULL);
#if !defined(TWOFISH_SMALL) && !defined(__GNUC__)
S1 = key->blowfish.S[0];
S2 = key->blowfish.S[1];
S3 = key->blowfish.S[2];
S4 = key->blowfish.S[3];
#endif
/* load it */
LOAD32H(L, &pt[0]);
@ -399,10 +416,20 @@ void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
{
unsigned long L, R;
int r;
_ARGCHK(pt != NULL);
_ARGCHK(ct != NULL);
_ARGCHK(key != NULL);
#if !defined(TWOFISH_SMALL) && !defined(__GNUC__)
unsigned long *S1, *S2, *S3, *S4;
#endif
_ARGCHK(pt != NULL);
_ARGCHK(ct != NULL);
_ARGCHK(key != NULL);
#if !defined(TWOFISH_SMALL) && !defined(__GNUC__)
S1 = key->blowfish.S[0];
S2 = key->blowfish.S[1];
S3 = key->blowfish.S[2];
S4 = key->blowfish.S[3];
#endif
/* load it */
LOAD32H(R, &ct[0]);

18
cast5.c
View File

@ -458,28 +458,34 @@ int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_
return CRYPT_OK;
}
static unsigned long FI(unsigned long R, unsigned long Km, unsigned long Kr)
#ifdef _MSC_VER
#define INLINE __inline
#else
#define INLINE
#endif
INLINE static unsigned long FI(unsigned long R, unsigned long Km, unsigned long Kr)
{
unsigned long I;
I = (Km + R);
I = ROL(I, Kr);
return ((S1[(I>>24)&255] ^ S2[(I>>16)&255]) - S3[(I>>8)&255]) + S4[I&255];
return ((S1[byte(I, 3)] ^ S2[byte(I,2)]) - S3[byte(I,1)]) + S4[byte(I,0)];
}
static unsigned long FII(unsigned long R, unsigned long Km, unsigned long Kr)
INLINE static unsigned long FII(unsigned long R, unsigned long Km, unsigned long Kr)
{
unsigned long I;
I = (Km ^ R);
I = ROL(I, Kr);
return ((S1[(I>>24)&255] - S2[(I>>16)&255]) + S3[(I>>8)&255]) ^ S4[I&255];
return ((S1[byte(I, 3)] - S2[byte(I,2)]) + S3[byte(I,1)]) ^ S4[byte(I,0)];
}
static unsigned long FIII(unsigned long R, unsigned long Km, unsigned long Kr)
INLINE static unsigned long FIII(unsigned long R, unsigned long Km, unsigned long Kr)
{
unsigned long I;
I = (Km - R);
I = ROL(I, Kr);
return ((S1[(I>>24)&255] + S2[(I>>16)&255]) ^ S3[(I>>8)&255]) - S4[I&255];
return ((S1[byte(I, 3)] + S2[byte(I,2)]) ^ S3[byte(I,1)]) - S4[byte(I,0)];
}
void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)

View File

@ -1,3 +1,8 @@
Jun 19th, 2003
v0.87 -- Many MSVC optimizations to the code base
-- Improved the AES and Twofish key schedule [faster, more constant time]
-- Tons of optimizations here and there.
Jun 15th, 2003
v0.86 -- Fixed up AES to workaround MSVC optimizer bug
-- Merged in fresh LTM base [based on v0.20] so there are no warnings with MSVC

View File

@ -21,7 +21,7 @@
);
@opts = (
"SMALL_CODE,Use small code where possible (slower code),y",
"SMALL_CODE,Use small code where possible (slower code),n",
"NO_FILE,Avoid file I/O calls,n",
"CLEAN_STACK,Clean the stack within functions,n",
"LTC_TEST,Include Test Vector Routines,y",
@ -36,7 +36,7 @@
"XTEA,Include XTEA block cipher,y",
"TWOFISH,Include Twofish block cipher,y",
"TWOFISH_SMALL,Include Use a low ram variant of Twofish,n",
"TWOFISH_TABLES,Include Use precomputed tables to speed up the low-ram variant,n",
"TWOFISH_TABLES,Include Use precomputed tables to speed up the low-ram variant,y",
"DES,Include DES and 3DES block ciphers,y",
"CAST5,Include CAST5 (aka CAST-128) block cipher,y",
"NOEKEON,Include Noekeon block cipher,y",

BIN
crypt.pdf

Binary file not shown.

View File

@ -47,7 +47,7 @@
\def\gap{\vspace{0.5ex}}
\makeindex
\begin{document}
\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.86}
\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.87}
\author{Tom St Denis \\
Algonquin College \\
\\

View File

@ -1,7 +1,69 @@
#include <mycrypt.h>
extern void t_start(void);
extern ulong64 t_read(void);
#define KTIMES 25
#define TIMES 10000
/* RDTSC from Scott Duplichan */
static ulong64 rdtsc (void)
{
#if defined __GNUC__
#ifdef i386
ulong64 a;
asm volatile("rdtsc ":"=A" (a));
return a;
#else /* gcc-IA64 version */
unsigned long result;
__asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory");
while (__builtin_expect ((int) result == -1, 0))
__asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory");
return result;
#endif
// Microsoft and Intel Windows compilers
#elif defined _M_IX86
__asm rdtsc
#elif defined _M_AMD64
return __rdtsc ();
#elif defined _M_IA64
#if defined __INTEL_COMPILER
#include <ia64intrin.h>
#endif
return __getReg (3116);
#else
#error need rdtsc function for this build
#endif
}
ulong64 timer, skew = 0;
void t_start(void)
{
timer = rdtsc();
}
ulong64 t_read(void)
{
return rdtsc() - timer;
}
void init_timer(void)
{
ulong64 c1, c2, t1, t2, t3;
unsigned long y1;
c1 = c2 = (ulong64)-1;
for (y1 = 0; y1 < TIMES*100; y1++) {
t_start();
t1 = t_read();
t3 = t_read();
t2 = t_read() - t1;
c1 = (c1 > t1) ? t1 : c1;
c2 = (c2 > t2) ? t2 : c2;
}
skew = c2 - c1;
printf("Clock Skew: %lu\n", (unsigned long)skew);
}
void reg_algs(void)
{
@ -73,12 +135,50 @@ void reg_algs(void)
}
#define TIMES 20
int time_keysched(void)
{
unsigned long x, i, y1;
ulong64 t1, c1;
symmetric_key skey;
int kl;
int (*func) (const unsigned char *, int , int , symmetric_key *);
unsigned char key[256][MAXBLOCKSIZE];
printf ("\n\nKey Schedule Time Trials for the Symmetric Ciphers:\n(Times are cycles per key)\n");
for (x = 0; cipher_descriptor[x].name != NULL; x++) {
#define DO1(k) func(k, kl, 0, &skey);
func = cipher_descriptor[x].setup;
kl = cipher_descriptor[x].min_key_length;
c1 = (ulong64)-1;
for (y1 = 0; y1 < KTIMES; y1++) {
for (i = 0; i < 256; i++) {
rng_get_bytes(key[i], kl, NULL);
}
t_start();
for (i = 0; i < 256; i++) {
DO1(key[i]);
}
t1 = t_read() >> 8;
if (t1 < c1) { if (y1 > 0) --y1; }
c1 = (t1 > c1) ? c1 : t1;
}
t1 = c1 - skew;
printf
("%-20s: Schedule at %6lu\n", cipher_descriptor[x].name, (unsigned long)t1);
#undef DO1
}
return 0;
}
int time_cipher(void)
{
unsigned long x, y1;
ulong64 t1, t2;
ulong64 t1, t2, c1, c2, a1, a2;
symmetric_key skey;
void (*func) (const unsigned char *, unsigned char *, symmetric_key *);
unsigned char key[MAXBLOCKSIZE], pt[MAXBLOCKSIZE];
@ -91,43 +191,41 @@ int time_cipher(void)
#define DO1 func(pt,pt,&skey);
#define DO2 DO1 DO1
#define DO4 DO2 DO2
#define DO8 DO4 DO4
#define DO16 DO8 DO8
#define DO32 DO16 DO16
#define DO64 DO32 DO32
#define DO128 DO64 DO64
#define DO256 DO128 DO128
func = cipher_descriptor[x].ecb_encrypt;
y1 = 1<<TIMES;
t_start();
do {
DO256;
} while ((y1 -= 256) > 0);
t1 = t_read();
c1 = c2 = (ulong64)-1;
for (y1 = 0; y1 < TIMES; y1++) {
t_start();
DO1;
t1 = t_read();
DO2;
t2 = t_read();
t2 -= t1;
c1 = (t1 > c1 ? c1 : t1);
c2 = (t2 > c2 ? c2 : t2);
}
a1 = c2 - c1 - skew;
func = cipher_descriptor[x].ecb_decrypt;
y1 = 1<<TIMES;
t_start();
do {
DO256;
} while ((y1 -= 256) > 0);
t2 = t_read();
t1 = ((t1 * CONST64(1000)) >> TIMES) / ((ulong64)cipher_descriptor[x].block_length);
t2 = ((t2 * CONST64(1000)) >> TIMES) / ((ulong64)cipher_descriptor[x].block_length);
c1 = c2 = (ulong64)-1;
for (y1 = 0; y1 < TIMES; y1++) {
t_start();
DO1;
t1 = t_read();
DO2;
t2 = t_read();
t2 -= t1;
c1 = (t1 > c1 ? c1 : t1);
c2 = (t2 > c2 ? c2 : t2);
}
a2 = c2 - c1 - skew;
printf
("%-20s: Encrypt at %5.3f, Decrypt at %5.3f\n", cipher_descriptor[x].name, t1/1000.0, t2/1000.0);
("%-20s: Encrypt at %7.3f, Decrypt at %7.3f\n", cipher_descriptor[x].name, a1/(double)cipher_descriptor[x].block_length, a2/(double)cipher_descriptor[x].block_length);
#undef DO256
#undef DO128
#undef DO64
#undef DO32
#undef DO16
#undef DO8
#undef DO4
#undef DO2
#undef DO1
}
@ -138,47 +236,38 @@ int time_cipher(void)
int time_hash(void)
{
unsigned long x, y1, len;
ulong64 t1;
ulong64 t1, t2, c1, c2;
hash_state md;
void (*func)(hash_state *, const unsigned char *, unsigned long);
unsigned char pt[MAXBLOCKSIZE];
printf ("HASH Time Trials for:\n");
printf ("\n\nHASH Time Trials for:\n");
for (x = 0; hash_descriptor[x].name != NULL; x++) {
hash_descriptor[x].init(&md);
#define DO1 func(&md,pt,len);
#define DO2 DO1 DO1
#define DO4 DO2 DO2
#define DO8 DO4 DO4
#define DO16 DO8 DO8
#define DO32 DO16 DO16
#define DO64 DO32 DO32
#define DO128 DO64 DO64
#define DO256 DO128 DO128
func = hash_descriptor[x].process;
len = hash_descriptor[x].blocksize;
y1 = 1<<TIMES;
t_start();
do {
DO256;
} while ((y1 -= 256) > 0);
t1 = t_read();
t1 = ((t1 * CONST64(1000)) >> TIMES) / ((ulong64)hash_descriptor[x].blocksize);
c1 = c2 = (ulong64)-1;
for (y1 = 0; y1 < TIMES; y1++) {
t_start();
DO1;
t1 = t_read();
DO2;
t2 = t_read() - t1;
c1 = (t1 > c1) ? c1 : t1;
c2 = (t2 > c2) ? c2 : t2;
}
t1 = c2 - c1 - skew;
t1 = ((t1 * CONST64(1000))) / ((ulong64)hash_descriptor[x].blocksize);
printf
("%-20s: Process at %5.3f\n", hash_descriptor[x].name, t1 / 1000.0);
("%-20s: Process at %9.3f\n", hash_descriptor[x].name, t1 / 1000.0);
#undef DO256
#undef DO128
#undef DO64
#undef DO32
#undef DO16
#undef DO8
#undef DO4
#undef DO2
#undef DO1
}
@ -192,8 +281,10 @@ int main(void)
printf("Timings for ciphers and hashes. Times are listed as cycles per byte processed.\n\n");
time_hash();
// init_timer();
time_keysched();
time_cipher();
time_hash();
return EXIT_SUCCESS;
}

View File

@ -9,7 +9,7 @@
# a build. This is easy to remedy though, for those that have problems.
# The version
VERSION=0.86
VERSION=0.87
#ch1-01-1
# Compiler and Linker Names
@ -91,7 +91,7 @@ dh.o: dh.c dh_sys.c
aes.o: aes.c aes_tab.c
sha512.o: sha512.c sha384.c
#These are objects that are known to build with -fomit-frame-pointer successfully
#These are objects that are known to build with -fomit-frame-pointer successfully [RISK!]
aes.o: aes.c
$(CC) $(CFLAGS) $(EXT_CFLAGS) -c aes.c
@ -150,13 +150,7 @@ small: library $(SMALLOBJECTS)
$(CC) $(SMALLOBJECTS) $(LIBNAME) -o $(SMALL) $(WARN)
x86_prof: library $(PROFS)
nasm -f coff demos/timer.asm
$(CC) demos/x86_prof.o demos/timer.o $(LIBNAME) -o $(PROF)
#for linux
x86_profl: library $(PROFS)
nasm -f elf -DUSE_ELF demos/timer.asm
$(CC) demos/x86_prof.o demos/timer.o $(LIBNAME) -o $(PROF)
$(CC) demos/x86_prof.o $(LIBNAME) -o $(PROF)
#This rule installs the library and the header files. This must be run
#as root in order to have a high enough permission to write to the correct

View File

@ -24,5 +24,4 @@ test: library test.obj
cl test.obj tomcrypt.lib advapi32.lib
x86_prof: demos/x86_prof.c library
nasm -f win32 demos/timer.asm
cl $(CFLAGS) demos/x86_prof.c demos/timer.obj tomcrypt.lib advapi32.lib
cl $(CFLAGS) demos/x86_prof.c tomcrypt.lib advapi32.lib

2
md5.c
View File

@ -15,7 +15,7 @@ const struct _hash_descriptor md5_desc =
};
#define F(x,y,z) (z ^ (x & (y ^ z)))
#define G(x,y,z) ((x&z)|(y&(~z)))
#define G(x,y,z) (y ^ (z & (y ^ x)))
#define H(x,y,z) (x^y^z)
#define I(x,y,z) (y^(x|(~z)))

View File

@ -15,7 +15,8 @@
#define XFREE free
#define XCLOCK clock
#define XCLOCKS_PER_SEC CLOCKS_PER_SEC
#define SMALL_CODE
#define TWOFISH_TABLES
//#define SMALL_CODE
#define LTC_TEST
#define BLOWFISH
#define RC2

View File

@ -183,9 +183,20 @@ extern char *crypt_error;
#define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \
((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) )
#ifdef _MSC_VER
# include <stdlib.h>
# pragma intrinsic(_lrotr,_lrotl)
# define ROR(x,n) _lrotr(x,n)
# define ROL(x,n) _lrotl(x,n)
#else
#define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
#define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
#endif
#define ROL64(x, y) \
( (((x)<<((ulong64)(y)&63)) | \
(((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
@ -198,3 +209,10 @@ extern char *crypt_error;
#undef MIN
#define MAX(x, y) ( ((x)>(y))?(x):(y) )
#define MIN(x, y) ( ((x)<(y))?(x):(y) )
/* extract a byte portably */
#if (CHAR_BIT == 8)
#define byte(x, n) ((unsigned char)((x) >> (8 * (n))))
#else
#define byte(x, n) (((x) >> (8 * (n))) & 255)
#endif

View File

@ -23,7 +23,12 @@ static const unsigned long RC[] = {
0x000000d4UL
};
static const unsigned long zero[] = { 0, 0, 0, 0 };
#define kTHETA(a, b, c, d) \
temp = a^c; temp = temp ^ ROL(temp, 8) ^ ROR(temp, 8); \
b ^= temp; d ^= temp; \
temp = b^d; temp = temp ^ ROL(temp, 8) ^ ROR(temp, 8); \
a ^= temp; c ^= temp;
#define THETA(k, a, b, c, d) \
temp = a^c; temp = temp ^ ROL(temp, 8) ^ ROR(temp, 8); \
@ -72,7 +77,7 @@ int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetri
LOAD32L(skey->noekeon.dK[2],&key[8]);
LOAD32L(skey->noekeon.dK[3],&key[12]);
THETA(zero, skey->noekeon.dK[0], skey->noekeon.dK[1], skey->noekeon.dK[2], skey->noekeon.dK[3]);
kTHETA(skey->noekeon.dK[0], skey->noekeon.dK[1], skey->noekeon.dK[2], skey->noekeon.dK[3]);
return CRYPT_OK;
}
@ -100,9 +105,11 @@ void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
GAMMA(a,b,c,d); \
PI2(a,b,c,d);
for (r = 0; r < 16; r += 2) {
for (r = 0; r < 16; r += 4) {
ROUND(0);
ROUND(1);
ROUND(2);
ROUND(3);
}
#undef ROUND

43
rc5.c
View File

@ -92,7 +92,7 @@ static void _rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetr
void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
#endif
{
unsigned long A, B;
unsigned long A, B, *K;
int r;
_ARGCHK(key != NULL);
_ARGCHK(pt != NULL);
@ -102,9 +102,22 @@ void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *
LOAD32L(B, &pt[4]);
A += key->rc5.K[0];
B += key->rc5.K[1];
for (r = 0; r < key->rc5.rounds; r++) {
A = ROL(A ^ B, B) + key->rc5.K[r+r+2];
B = ROL(B ^ A, A) + key->rc5.K[r+r+3];
K = key->rc5.K + 2;
if ((key->rc5.rounds & 1) == 0) {
for (r = 0; r < key->rc5.rounds; r += 2) {
A = ROL(A ^ B, B) + K[0];
B = ROL(B ^ A, A) + K[1];
A = ROL(A ^ B, B) + K[2];
B = ROL(B ^ A, A) + K[3];
K += 4;
}
} else {
for (r = 0; r < key->rc5.rounds; r++) {
A = ROL(A ^ B, B) + K[0];
B = ROL(B ^ A, A) + K[1];
K += 2;
}
}
STORE32L(A, &ct[0]);
STORE32L(B, &ct[4]);
@ -124,7 +137,7 @@ static void _rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetr
void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
#endif
{
unsigned long A, B;
unsigned long A, B, *K;
int r;
_ARGCHK(key != NULL);
_ARGCHK(pt != NULL);
@ -132,9 +145,23 @@ void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *
LOAD32L(A, &ct[0]);
LOAD32L(B, &ct[4]);
for (r = key->rc5.rounds - 1; r >= 0; r--) {
B = ROR(B - key->rc5.K[r+r+3], A) ^ A;
A = ROR(A - key->rc5.K[r+r+2], B) ^ B;
K = key->rc5.K + (key->rc5.rounds << 1);
if ((key->rc5.rounds & 1) == 0) {
K -= 2;
for (r = key->rc5.rounds - 1; r >= 0; r -= 2) {
B = ROR(B - K[3], A) ^ A;
A = ROR(A - K[2], B) ^ B;
B = ROR(B - K[1], A) ^ A;
A = ROR(A - K[0], B) ^ B;
K -= 4;
}
} else {
for (r = key->rc5.rounds - 1; r >= 0; r--) {
B = ROR(B - K[1], A) ^ A;
A = ROR(A - K[0], B) ^ B;
K -= 2;
}
}
A -= key->rc5.K[0];
B -= key->rc5.K[1];

50
rc6.c
View File

@ -89,22 +89,33 @@ static void _rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetr
void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
#endif
{
unsigned long a,b,c,d,t,u;
unsigned long a,b,c,d,t,u, *K;
int r;
_ARGCHK(key != NULL);
_ARGCHK(pt != NULL);
_ARGCHK(ct != NULL);
LOAD32L(a,&pt[0]);LOAD32L(b,&pt[4]);LOAD32L(c,&pt[8]);LOAD32L(d,&pt[12]);
b += key->rc6.K[0];
d += key->rc6.K[1];
for (r = 0; r < 20; r++) {
t = (b * (b + b + 1)); t = ROL(t, 5);
u = (d * (d + d + 1)); u = ROL(u, 5);
a = ROL(a^t,u) + key->rc6.K[r+r+2];
c = ROL(c^u,t) + key->rc6.K[r+r+3];
t = a; a = b; b = c; c = d; d = t;
#define RND(a,b,c,d) \
t = (b * (b + b + 1)); t = ROL(t, 5); \
u = (d * (d + d + 1)); u = ROL(u, 5); \
a = ROL(a^t,u) + K[0]; \
c = ROL(c^u,t) + K[1]; K += 2;
K = key->rc6.K + 2;
for (r = 0; r < 20; r += 4) {
RND(a,b,c,d);
RND(b,c,d,a);
RND(c,d,a,b);
RND(d,a,b,c);
}
#undef RND
a += key->rc6.K[42];
c += key->rc6.K[43];
STORE32L(a,&ct[0]);STORE32L(b,&ct[4]);STORE32L(c,&ct[8]);STORE32L(d,&ct[12]);
@ -124,7 +135,7 @@ static void _rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetr
void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
#endif
{
unsigned long a,b,c,d,t,u;
unsigned long a,b,c,d,t,u, *K;
int r;
_ARGCHK(key != NULL);
@ -134,13 +145,24 @@ void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *
LOAD32L(a,&ct[0]);LOAD32L(b,&ct[4]);LOAD32L(c,&ct[8]);LOAD32L(d,&ct[12]);
a -= key->rc6.K[42];
c -= key->rc6.K[43];
for (r = 19; r >= 0; r--) {
t = d; d = c; c = b; b = a; a = t;
t = (b * (b + b + 1)); t = ROL(t, 5);
u = (d * (d + d + 1)); u = ROL(u, 5);
c = ROR(c - key->rc6.K[r+r+3], t) ^ u;
a = ROR(a - key->rc6.K[r+r+2], u) ^ t;
#define RND(a,b,c,d) \
t = (b * (b + b + 1)); t = ROL(t, 5); \
u = (d * (d + d + 1)); u = ROL(u, 5); \
c = ROR(c - K[1], t) ^ u; \
a = ROR(a - K[0], u) ^ t; K -= 2;
K = key->rc6.K + 40;
for (r = 0; r < 20; r += 4) {
RND(d,a,b,c);
RND(c,d,a,b);
RND(b,c,d,a);
RND(a,b,c,d);
}
#undef RND
b -= key->rc6.K[0];
d -= key->rc6.K[1];
STORE32L(a,&pt[0]);STORE32L(b,&pt[4]);STORE32L(c,&pt[8]);STORE32L(d,&pt[12]);

23
tiger.c
View File

@ -533,17 +533,28 @@ static const ulong64 table[4*256] = {
CONST64(0xCD56D9430EA8280E) /* 1020 */, CONST64(0xC12591D7535F5065) /* 1021 */,
CONST64(0xC83223F1720AEF96) /* 1022 */, CONST64(0xC3A0396F7363A51F) /* 1023 */};
#ifdef _MSC_VER
#define INLINE __inline
#else
#define INLINE
#endif
/* one round of the hash function */
static void round(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 x, ulong64 mul)
INLINE static void round(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 x, int mul)
{
*c ^= x;
*a -= t1[(*c)&255] ^ t2[((*c)>>16)&255] ^ t3[((*c)>>32)&255] ^ t4[((*c)>>48)&255];
*b += t4[((*c)>>8)&255] ^ t3[((*c)>>24)&255] ^ t2[((*c)>>40)&255] ^ t1[((*c)>>56)&255];
*b *= mul;
ulong64 tmp;
tmp = (*c ^= x);
*a -= t1[byte(tmp, 0)] ^ t2[byte(tmp, 2)] ^ t3[byte(tmp, 4)] ^ t4[byte(tmp, 6)];
tmp = (*b += t4[byte(tmp, 1)] ^ t3[byte(tmp, 3)] ^ t2[byte(tmp,5)] ^ t1[byte(tmp,7)]);
switch (mul) {
case 5: *b = (tmp << 2) + tmp; break;
case 7: *b = (tmp << 3) - tmp; break;
case 9: *b = (tmp << 3) + tmp; break;
}
}
/* one complete pass */
static void pass(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 *x, ulong64 mul)
static void pass(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 *x, int mul)
{
round(a,b,c,x[0],mul);
round(b,c,a,x[1],mul);

376
twofish.c
View File

@ -101,61 +101,143 @@ static const unsigned char SBOX[2][256] = {
0x86, 0x56, 0x55, 0x09, 0xbe, 0x91}
};
static const unsigned char GF_EF[256] = {
0x00, 0xef, 0xb7, 0x58, 0x07, 0xe8, 0xb0, 0x5f, 0x0e, 0xe1,
0xb9, 0x56, 0x09, 0xe6, 0xbe, 0x51, 0x1c, 0xf3, 0xab, 0x44,
0x1b, 0xf4, 0xac, 0x43, 0x12, 0xfd, 0xa5, 0x4a, 0x15, 0xfa,
0xa2, 0x4d, 0x38, 0xd7, 0x8f, 0x60, 0x3f, 0xd0, 0x88, 0x67,
0x36, 0xd9, 0x81, 0x6e, 0x31, 0xde, 0x86, 0x69, 0x24, 0xcb,
0x93, 0x7c, 0x23, 0xcc, 0x94, 0x7b, 0x2a, 0xc5, 0x9d, 0x72,
0x2d, 0xc2, 0x9a, 0x75, 0x70, 0x9f, 0xc7, 0x28, 0x77, 0x98,
0xc0, 0x2f, 0x7e, 0x91, 0xc9, 0x26, 0x79, 0x96, 0xce, 0x21,
0x6c, 0x83, 0xdb, 0x34, 0x6b, 0x84, 0xdc, 0x33, 0x62, 0x8d,
0xd5, 0x3a, 0x65, 0x8a, 0xd2, 0x3d, 0x48, 0xa7, 0xff, 0x10,
0x4f, 0xa0, 0xf8, 0x17, 0x46, 0xa9, 0xf1, 0x1e, 0x41, 0xae,
0xf6, 0x19, 0x54, 0xbb, 0xe3, 0x0c, 0x53, 0xbc, 0xe4, 0x0b,
0x5a, 0xb5, 0xed, 0x02, 0x5d, 0xb2, 0xea, 0x05, 0xe0, 0x0f,
0x57, 0xb8, 0xe7, 0x08, 0x50, 0xbf, 0xee, 0x01, 0x59, 0xb6,
0xe9, 0x06, 0x5e, 0xb1, 0xfc, 0x13, 0x4b, 0xa4, 0xfb, 0x14,
0x4c, 0xa3, 0xf2, 0x1d, 0x45, 0xaa, 0xf5, 0x1a, 0x42, 0xad,
0xd8, 0x37, 0x6f, 0x80, 0xdf, 0x30, 0x68, 0x87, 0xd6, 0x39,
0x61, 0x8e, 0xd1, 0x3e, 0x66, 0x89, 0xc4, 0x2b, 0x73, 0x9c,
0xc3, 0x2c, 0x74, 0x9b, 0xca, 0x25, 0x7d, 0x92, 0xcd, 0x22,
0x7a, 0x95, 0x90, 0x7f, 0x27, 0xc8, 0x97, 0x78, 0x20, 0xcf,
0x9e, 0x71, 0x29, 0xc6, 0x99, 0x76, 0x2e, 0xc1, 0x8c, 0x63,
0x3b, 0xd4, 0x8b, 0x64, 0x3c, 0xd3, 0x82, 0x6d, 0x35, 0xda,
0x85, 0x6a, 0x32, 0xdd, 0xa8, 0x47, 0x1f, 0xf0, 0xaf, 0x40,
0x18, 0xf7, 0xa6, 0x49, 0x11, 0xfe, 0xa1, 0x4e, 0x16, 0xf9,
0xb4, 0x5b, 0x03, 0xec, 0xb3, 0x5c, 0x04, 0xeb, 0xba, 0x55,
0x0d, 0xe2, 0xbd, 0x52, 0x0a, 0xe5};
static const unsigned char GF_5B[256] = {
0x00, 0x5b, 0xb6, 0xed, 0x05, 0x5e, 0xb3, 0xe8, 0x0a, 0x51,
0xbc, 0xe7, 0x0f, 0x54, 0xb9, 0xe2, 0x14, 0x4f, 0xa2, 0xf9,
0x11, 0x4a, 0xa7, 0xfc, 0x1e, 0x45, 0xa8, 0xf3, 0x1b, 0x40,
0xad, 0xf6, 0x28, 0x73, 0x9e, 0xc5, 0x2d, 0x76, 0x9b, 0xc0,
0x22, 0x79, 0x94, 0xcf, 0x27, 0x7c, 0x91, 0xca, 0x3c, 0x67,
0x8a, 0xd1, 0x39, 0x62, 0x8f, 0xd4, 0x36, 0x6d, 0x80, 0xdb,
0x33, 0x68, 0x85, 0xde, 0x50, 0x0b, 0xe6, 0xbd, 0x55, 0x0e,
0xe3, 0xb8, 0x5a, 0x01, 0xec, 0xb7, 0x5f, 0x04, 0xe9, 0xb2,
0x44, 0x1f, 0xf2, 0xa9, 0x41, 0x1a, 0xf7, 0xac, 0x4e, 0x15,
0xf8, 0xa3, 0x4b, 0x10, 0xfd, 0xa6, 0x78, 0x23, 0xce, 0x95,
0x7d, 0x26, 0xcb, 0x90, 0x72, 0x29, 0xc4, 0x9f, 0x77, 0x2c,
0xc1, 0x9a, 0x6c, 0x37, 0xda, 0x81, 0x69, 0x32, 0xdf, 0x84,
0x66, 0x3d, 0xd0, 0x8b, 0x63, 0x38, 0xd5, 0x8e, 0xa0, 0xfb,
0x16, 0x4d, 0xa5, 0xfe, 0x13, 0x48, 0xaa, 0xf1, 0x1c, 0x47,
0xaf, 0xf4, 0x19, 0x42, 0xb4, 0xef, 0x02, 0x59, 0xb1, 0xea,
0x07, 0x5c, 0xbe, 0xe5, 0x08, 0x53, 0xbb, 0xe0, 0x0d, 0x56,
0x88, 0xd3, 0x3e, 0x65, 0x8d, 0xd6, 0x3b, 0x60, 0x82, 0xd9,
0x34, 0x6f, 0x87, 0xdc, 0x31, 0x6a, 0x9c, 0xc7, 0x2a, 0x71,
0x99, 0xc2, 0x2f, 0x74, 0x96, 0xcd, 0x20, 0x7b, 0x93, 0xc8,
0x25, 0x7e, 0xf0, 0xab, 0x46, 0x1d, 0xf5, 0xae, 0x43, 0x18,
0xfa, 0xa1, 0x4c, 0x17, 0xff, 0xa4, 0x49, 0x12, 0xe4, 0xbf,
0x52, 0x09, 0xe1, 0xba, 0x57, 0x0c, 0xee, 0xb5, 0x58, 0x03,
0xeb, 0xb0, 0x5d, 0x06, 0xd8, 0x83, 0x6e, 0x35, 0xdd, 0x86,
0x6b, 0x30, 0xd2, 0x89, 0x64, 0x3f, 0xd7, 0x8c, 0x61, 0x3a,
0xcc, 0x97, 0x7a, 0x21, 0xc9, 0x92, 0x7f, 0x24, 0xc6, 0x9d,
0x70, 0x2b, 0xc3, 0x98, 0x75, 0x2e};
static const unsigned long mds_tab[4][256] = {
{
0x00000000UL, 0xefef5b01UL, 0xb7b7b602UL, 0x5858ed03UL, 0x07070504UL, 0xe8e85e05UL, 0xb0b0b306UL, 0x5f5fe807UL,
0x0e0e0a08UL, 0xe1e15109UL, 0xb9b9bc0aUL, 0x5656e70bUL, 0x09090f0cUL, 0xe6e6540dUL, 0xbebeb90eUL, 0x5151e20fUL,
0x1c1c1410UL, 0xf3f34f11UL, 0xababa212UL, 0x4444f913UL, 0x1b1b1114UL, 0xf4f44a15UL, 0xacaca716UL, 0x4343fc17UL,
0x12121e18UL, 0xfdfd4519UL, 0xa5a5a81aUL, 0x4a4af31bUL, 0x15151b1cUL, 0xfafa401dUL, 0xa2a2ad1eUL, 0x4d4df61fUL,
0x38382820UL, 0xd7d77321UL, 0x8f8f9e22UL, 0x6060c523UL, 0x3f3f2d24UL, 0xd0d07625UL, 0x88889b26UL, 0x6767c027UL,
0x36362228UL, 0xd9d97929UL, 0x8181942aUL, 0x6e6ecf2bUL, 0x3131272cUL, 0xdede7c2dUL, 0x8686912eUL, 0x6969ca2fUL,
0x24243c30UL, 0xcbcb6731UL, 0x93938a32UL, 0x7c7cd133UL, 0x23233934UL, 0xcccc6235UL, 0x94948f36UL, 0x7b7bd437UL,
0x2a2a3638UL, 0xc5c56d39UL, 0x9d9d803aUL, 0x7272db3bUL, 0x2d2d333cUL, 0xc2c2683dUL, 0x9a9a853eUL, 0x7575de3fUL,
0x70705040UL, 0x9f9f0b41UL, 0xc7c7e642UL, 0x2828bd43UL, 0x77775544UL, 0x98980e45UL, 0xc0c0e346UL, 0x2f2fb847UL,
0x7e7e5a48UL, 0x91910149UL, 0xc9c9ec4aUL, 0x2626b74bUL, 0x79795f4cUL, 0x9696044dUL, 0xcecee94eUL, 0x2121b24fUL,
0x6c6c4450UL, 0x83831f51UL, 0xdbdbf252UL, 0x3434a953UL, 0x6b6b4154UL, 0x84841a55UL, 0xdcdcf756UL, 0x3333ac57UL,
0x62624e58UL, 0x8d8d1559UL, 0xd5d5f85aUL, 0x3a3aa35bUL, 0x65654b5cUL, 0x8a8a105dUL, 0xd2d2fd5eUL, 0x3d3da65fUL,
0x48487860UL, 0xa7a72361UL, 0xffffce62UL, 0x10109563UL, 0x4f4f7d64UL, 0xa0a02665UL, 0xf8f8cb66UL, 0x17179067UL,
0x46467268UL, 0xa9a92969UL, 0xf1f1c46aUL, 0x1e1e9f6bUL, 0x4141776cUL, 0xaeae2c6dUL, 0xf6f6c16eUL, 0x19199a6fUL,
0x54546c70UL, 0xbbbb3771UL, 0xe3e3da72UL, 0x0c0c8173UL, 0x53536974UL, 0xbcbc3275UL, 0xe4e4df76UL, 0x0b0b8477UL,
0x5a5a6678UL, 0xb5b53d79UL, 0xededd07aUL, 0x02028b7bUL, 0x5d5d637cUL, 0xb2b2387dUL, 0xeaead57eUL, 0x05058e7fUL,
0xe0e0a080UL, 0x0f0ffb81UL, 0x57571682UL, 0xb8b84d83UL, 0xe7e7a584UL, 0x0808fe85UL, 0x50501386UL, 0xbfbf4887UL,
0xeeeeaa88UL, 0x0101f189UL, 0x59591c8aUL, 0xb6b6478bUL, 0xe9e9af8cUL, 0x0606f48dUL, 0x5e5e198eUL, 0xb1b1428fUL,
0xfcfcb490UL, 0x1313ef91UL, 0x4b4b0292UL, 0xa4a45993UL, 0xfbfbb194UL, 0x1414ea95UL, 0x4c4c0796UL, 0xa3a35c97UL,
0xf2f2be98UL, 0x1d1de599UL, 0x4545089aUL, 0xaaaa539bUL, 0xf5f5bb9cUL, 0x1a1ae09dUL, 0x42420d9eUL, 0xadad569fUL,
0xd8d888a0UL, 0x3737d3a1UL, 0x6f6f3ea2UL, 0x808065a3UL, 0xdfdf8da4UL, 0x3030d6a5UL, 0x68683ba6UL, 0x878760a7UL,
0xd6d682a8UL, 0x3939d9a9UL, 0x616134aaUL, 0x8e8e6fabUL, 0xd1d187acUL, 0x3e3edcadUL, 0x666631aeUL, 0x89896aafUL,
0xc4c49cb0UL, 0x2b2bc7b1UL, 0x73732ab2UL, 0x9c9c71b3UL, 0xc3c399b4UL, 0x2c2cc2b5UL, 0x74742fb6UL, 0x9b9b74b7UL,
0xcaca96b8UL, 0x2525cdb9UL, 0x7d7d20baUL, 0x92927bbbUL, 0xcdcd93bcUL, 0x2222c8bdUL, 0x7a7a25beUL, 0x95957ebfUL,
0x9090f0c0UL, 0x7f7fabc1UL, 0x272746c2UL, 0xc8c81dc3UL, 0x9797f5c4UL, 0x7878aec5UL, 0x202043c6UL, 0xcfcf18c7UL,
0x9e9efac8UL, 0x7171a1c9UL, 0x29294ccaUL, 0xc6c617cbUL, 0x9999ffccUL, 0x7676a4cdUL, 0x2e2e49ceUL, 0xc1c112cfUL,
0x8c8ce4d0UL, 0x6363bfd1UL, 0x3b3b52d2UL, 0xd4d409d3UL, 0x8b8be1d4UL, 0x6464bad5UL, 0x3c3c57d6UL, 0xd3d30cd7UL,
0x8282eed8UL, 0x6d6db5d9UL, 0x353558daUL, 0xdada03dbUL, 0x8585ebdcUL, 0x6a6ab0ddUL, 0x32325ddeUL, 0xdddd06dfUL,
0xa8a8d8e0UL, 0x474783e1UL, 0x1f1f6ee2UL, 0xf0f035e3UL, 0xafafdde4UL, 0x404086e5UL, 0x18186be6UL, 0xf7f730e7UL,
0xa6a6d2e8UL, 0x494989e9UL, 0x111164eaUL, 0xfefe3febUL, 0xa1a1d7ecUL, 0x4e4e8cedUL, 0x161661eeUL, 0xf9f93aefUL,
0xb4b4ccf0UL, 0x5b5b97f1UL, 0x03037af2UL, 0xecec21f3UL, 0xb3b3c9f4UL, 0x5c5c92f5UL, 0x04047ff6UL, 0xebeb24f7UL,
0xbabac6f8UL, 0x55559df9UL, 0x0d0d70faUL, 0xe2e22bfbUL, 0xbdbdc3fcUL, 0x525298fdUL, 0x0a0a75feUL, 0xe5e52effUL
},
{
0x00000000UL, 0x015befefUL, 0x02b6b7b7UL, 0x03ed5858UL, 0x04050707UL, 0x055ee8e8UL, 0x06b3b0b0UL, 0x07e85f5fUL,
0x080a0e0eUL, 0x0951e1e1UL, 0x0abcb9b9UL, 0x0be75656UL, 0x0c0f0909UL, 0x0d54e6e6UL, 0x0eb9bebeUL, 0x0fe25151UL,
0x10141c1cUL, 0x114ff3f3UL, 0x12a2ababUL, 0x13f94444UL, 0x14111b1bUL, 0x154af4f4UL, 0x16a7acacUL, 0x17fc4343UL,
0x181e1212UL, 0x1945fdfdUL, 0x1aa8a5a5UL, 0x1bf34a4aUL, 0x1c1b1515UL, 0x1d40fafaUL, 0x1eada2a2UL, 0x1ff64d4dUL,
0x20283838UL, 0x2173d7d7UL, 0x229e8f8fUL, 0x23c56060UL, 0x242d3f3fUL, 0x2576d0d0UL, 0x269b8888UL, 0x27c06767UL,
0x28223636UL, 0x2979d9d9UL, 0x2a948181UL, 0x2bcf6e6eUL, 0x2c273131UL, 0x2d7cdedeUL, 0x2e918686UL, 0x2fca6969UL,
0x303c2424UL, 0x3167cbcbUL, 0x328a9393UL, 0x33d17c7cUL, 0x34392323UL, 0x3562ccccUL, 0x368f9494UL, 0x37d47b7bUL,
0x38362a2aUL, 0x396dc5c5UL, 0x3a809d9dUL, 0x3bdb7272UL, 0x3c332d2dUL, 0x3d68c2c2UL, 0x3e859a9aUL, 0x3fde7575UL,
0x40507070UL, 0x410b9f9fUL, 0x42e6c7c7UL, 0x43bd2828UL, 0x44557777UL, 0x450e9898UL, 0x46e3c0c0UL, 0x47b82f2fUL,
0x485a7e7eUL, 0x49019191UL, 0x4aecc9c9UL, 0x4bb72626UL, 0x4c5f7979UL, 0x4d049696UL, 0x4ee9ceceUL, 0x4fb22121UL,
0x50446c6cUL, 0x511f8383UL, 0x52f2dbdbUL, 0x53a93434UL, 0x54416b6bUL, 0x551a8484UL, 0x56f7dcdcUL, 0x57ac3333UL,
0x584e6262UL, 0x59158d8dUL, 0x5af8d5d5UL, 0x5ba33a3aUL, 0x5c4b6565UL, 0x5d108a8aUL, 0x5efdd2d2UL, 0x5fa63d3dUL,
0x60784848UL, 0x6123a7a7UL, 0x62ceffffUL, 0x63951010UL, 0x647d4f4fUL, 0x6526a0a0UL, 0x66cbf8f8UL, 0x67901717UL,
0x68724646UL, 0x6929a9a9UL, 0x6ac4f1f1UL, 0x6b9f1e1eUL, 0x6c774141UL, 0x6d2caeaeUL, 0x6ec1f6f6UL, 0x6f9a1919UL,
0x706c5454UL, 0x7137bbbbUL, 0x72dae3e3UL, 0x73810c0cUL, 0x74695353UL, 0x7532bcbcUL, 0x76dfe4e4UL, 0x77840b0bUL,
0x78665a5aUL, 0x793db5b5UL, 0x7ad0ededUL, 0x7b8b0202UL, 0x7c635d5dUL, 0x7d38b2b2UL, 0x7ed5eaeaUL, 0x7f8e0505UL,
0x80a0e0e0UL, 0x81fb0f0fUL, 0x82165757UL, 0x834db8b8UL, 0x84a5e7e7UL, 0x85fe0808UL, 0x86135050UL, 0x8748bfbfUL,
0x88aaeeeeUL, 0x89f10101UL, 0x8a1c5959UL, 0x8b47b6b6UL, 0x8cafe9e9UL, 0x8df40606UL, 0x8e195e5eUL, 0x8f42b1b1UL,
0x90b4fcfcUL, 0x91ef1313UL, 0x92024b4bUL, 0x9359a4a4UL, 0x94b1fbfbUL, 0x95ea1414UL, 0x96074c4cUL, 0x975ca3a3UL,
0x98bef2f2UL, 0x99e51d1dUL, 0x9a084545UL, 0x9b53aaaaUL, 0x9cbbf5f5UL, 0x9de01a1aUL, 0x9e0d4242UL, 0x9f56adadUL,
0xa088d8d8UL, 0xa1d33737UL, 0xa23e6f6fUL, 0xa3658080UL, 0xa48ddfdfUL, 0xa5d63030UL, 0xa63b6868UL, 0xa7608787UL,
0xa882d6d6UL, 0xa9d93939UL, 0xaa346161UL, 0xab6f8e8eUL, 0xac87d1d1UL, 0xaddc3e3eUL, 0xae316666UL, 0xaf6a8989UL,
0xb09cc4c4UL, 0xb1c72b2bUL, 0xb22a7373UL, 0xb3719c9cUL, 0xb499c3c3UL, 0xb5c22c2cUL, 0xb62f7474UL, 0xb7749b9bUL,
0xb896cacaUL, 0xb9cd2525UL, 0xba207d7dUL, 0xbb7b9292UL, 0xbc93cdcdUL, 0xbdc82222UL, 0xbe257a7aUL, 0xbf7e9595UL,
0xc0f09090UL, 0xc1ab7f7fUL, 0xc2462727UL, 0xc31dc8c8UL, 0xc4f59797UL, 0xc5ae7878UL, 0xc6432020UL, 0xc718cfcfUL,
0xc8fa9e9eUL, 0xc9a17171UL, 0xca4c2929UL, 0xcb17c6c6UL, 0xccff9999UL, 0xcda47676UL, 0xce492e2eUL, 0xcf12c1c1UL,
0xd0e48c8cUL, 0xd1bf6363UL, 0xd2523b3bUL, 0xd309d4d4UL, 0xd4e18b8bUL, 0xd5ba6464UL, 0xd6573c3cUL, 0xd70cd3d3UL,
0xd8ee8282UL, 0xd9b56d6dUL, 0xda583535UL, 0xdb03dadaUL, 0xdceb8585UL, 0xddb06a6aUL, 0xde5d3232UL, 0xdf06ddddUL,
0xe0d8a8a8UL, 0xe1834747UL, 0xe26e1f1fUL, 0xe335f0f0UL, 0xe4ddafafUL, 0xe5864040UL, 0xe66b1818UL, 0xe730f7f7UL,
0xe8d2a6a6UL, 0xe9894949UL, 0xea641111UL, 0xeb3ffefeUL, 0xecd7a1a1UL, 0xed8c4e4eUL, 0xee611616UL, 0xef3af9f9UL,
0xf0ccb4b4UL, 0xf1975b5bUL, 0xf27a0303UL, 0xf321ececUL, 0xf4c9b3b3UL, 0xf5925c5cUL, 0xf67f0404UL, 0xf724ebebUL,
0xf8c6babaUL, 0xf99d5555UL, 0xfa700d0dUL, 0xfb2be2e2UL, 0xfcc3bdbdUL, 0xfd985252UL, 0xfe750a0aUL, 0xff2ee5e5UL
},
{
0x00000000UL, 0xef01ef5bUL, 0xb702b7b6UL, 0x580358edUL, 0x07040705UL, 0xe805e85eUL, 0xb006b0b3UL, 0x5f075fe8UL,
0x0e080e0aUL, 0xe109e151UL, 0xb90ab9bcUL, 0x560b56e7UL, 0x090c090fUL, 0xe60de654UL, 0xbe0ebeb9UL, 0x510f51e2UL,
0x1c101c14UL, 0xf311f34fUL, 0xab12aba2UL, 0x441344f9UL, 0x1b141b11UL, 0xf415f44aUL, 0xac16aca7UL, 0x431743fcUL,
0x1218121eUL, 0xfd19fd45UL, 0xa51aa5a8UL, 0x4a1b4af3UL, 0x151c151bUL, 0xfa1dfa40UL, 0xa21ea2adUL, 0x4d1f4df6UL,
0x38203828UL, 0xd721d773UL, 0x8f228f9eUL, 0x602360c5UL, 0x3f243f2dUL, 0xd025d076UL, 0x8826889bUL, 0x672767c0UL,
0x36283622UL, 0xd929d979UL, 0x812a8194UL, 0x6e2b6ecfUL, 0x312c3127UL, 0xde2dde7cUL, 0x862e8691UL, 0x692f69caUL,
0x2430243cUL, 0xcb31cb67UL, 0x9332938aUL, 0x7c337cd1UL, 0x23342339UL, 0xcc35cc62UL, 0x9436948fUL, 0x7b377bd4UL,
0x2a382a36UL, 0xc539c56dUL, 0x9d3a9d80UL, 0x723b72dbUL, 0x2d3c2d33UL, 0xc23dc268UL, 0x9a3e9a85UL, 0x753f75deUL,
0x70407050UL, 0x9f419f0bUL, 0xc742c7e6UL, 0x284328bdUL, 0x77447755UL, 0x9845980eUL, 0xc046c0e3UL, 0x2f472fb8UL,
0x7e487e5aUL, 0x91499101UL, 0xc94ac9ecUL, 0x264b26b7UL, 0x794c795fUL, 0x964d9604UL, 0xce4ecee9UL, 0x214f21b2UL,
0x6c506c44UL, 0x8351831fUL, 0xdb52dbf2UL, 0x345334a9UL, 0x6b546b41UL, 0x8455841aUL, 0xdc56dcf7UL, 0x335733acUL,
0x6258624eUL, 0x8d598d15UL, 0xd55ad5f8UL, 0x3a5b3aa3UL, 0x655c654bUL, 0x8a5d8a10UL, 0xd25ed2fdUL, 0x3d5f3da6UL,
0x48604878UL, 0xa761a723UL, 0xff62ffceUL, 0x10631095UL, 0x4f644f7dUL, 0xa065a026UL, 0xf866f8cbUL, 0x17671790UL,
0x46684672UL, 0xa969a929UL, 0xf16af1c4UL, 0x1e6b1e9fUL, 0x416c4177UL, 0xae6dae2cUL, 0xf66ef6c1UL, 0x196f199aUL,
0x5470546cUL, 0xbb71bb37UL, 0xe372e3daUL, 0x0c730c81UL, 0x53745369UL, 0xbc75bc32UL, 0xe476e4dfUL, 0x0b770b84UL,
0x5a785a66UL, 0xb579b53dUL, 0xed7aedd0UL, 0x027b028bUL, 0x5d7c5d63UL, 0xb27db238UL, 0xea7eead5UL, 0x057f058eUL,
0xe080e0a0UL, 0x0f810ffbUL, 0x57825716UL, 0xb883b84dUL, 0xe784e7a5UL, 0x088508feUL, 0x50865013UL, 0xbf87bf48UL,
0xee88eeaaUL, 0x018901f1UL, 0x598a591cUL, 0xb68bb647UL, 0xe98ce9afUL, 0x068d06f4UL, 0x5e8e5e19UL, 0xb18fb142UL,
0xfc90fcb4UL, 0x139113efUL, 0x4b924b02UL, 0xa493a459UL, 0xfb94fbb1UL, 0x149514eaUL, 0x4c964c07UL, 0xa397a35cUL,
0xf298f2beUL, 0x1d991de5UL, 0x459a4508UL, 0xaa9baa53UL, 0xf59cf5bbUL, 0x1a9d1ae0UL, 0x429e420dUL, 0xad9fad56UL,
0xd8a0d888UL, 0x37a137d3UL, 0x6fa26f3eUL, 0x80a38065UL, 0xdfa4df8dUL, 0x30a530d6UL, 0x68a6683bUL, 0x87a78760UL,
0xd6a8d682UL, 0x39a939d9UL, 0x61aa6134UL, 0x8eab8e6fUL, 0xd1acd187UL, 0x3ead3edcUL, 0x66ae6631UL, 0x89af896aUL,
0xc4b0c49cUL, 0x2bb12bc7UL, 0x73b2732aUL, 0x9cb39c71UL, 0xc3b4c399UL, 0x2cb52cc2UL, 0x74b6742fUL, 0x9bb79b74UL,
0xcab8ca96UL, 0x25b925cdUL, 0x7dba7d20UL, 0x92bb927bUL, 0xcdbccd93UL, 0x22bd22c8UL, 0x7abe7a25UL, 0x95bf957eUL,
0x90c090f0UL, 0x7fc17fabUL, 0x27c22746UL, 0xc8c3c81dUL, 0x97c497f5UL, 0x78c578aeUL, 0x20c62043UL, 0xcfc7cf18UL,
0x9ec89efaUL, 0x71c971a1UL, 0x29ca294cUL, 0xc6cbc617UL, 0x99cc99ffUL, 0x76cd76a4UL, 0x2ece2e49UL, 0xc1cfc112UL,
0x8cd08ce4UL, 0x63d163bfUL, 0x3bd23b52UL, 0xd4d3d409UL, 0x8bd48be1UL, 0x64d564baUL, 0x3cd63c57UL, 0xd3d7d30cUL,
0x82d882eeUL, 0x6dd96db5UL, 0x35da3558UL, 0xdadbda03UL, 0x85dc85ebUL, 0x6add6ab0UL, 0x32de325dUL, 0xdddfdd06UL,
0xa8e0a8d8UL, 0x47e14783UL, 0x1fe21f6eUL, 0xf0e3f035UL, 0xafe4afddUL, 0x40e54086UL, 0x18e6186bUL, 0xf7e7f730UL,
0xa6e8a6d2UL, 0x49e94989UL, 0x11ea1164UL, 0xfeebfe3fUL, 0xa1eca1d7UL, 0x4eed4e8cUL, 0x16ee1661UL, 0xf9eff93aUL,
0xb4f0b4ccUL, 0x5bf15b97UL, 0x03f2037aUL, 0xecf3ec21UL, 0xb3f4b3c9UL, 0x5cf55c92UL, 0x04f6047fUL, 0xebf7eb24UL,
0xbaf8bac6UL, 0x55f9559dUL, 0x0dfa0d70UL, 0xe2fbe22bUL, 0xbdfcbdc3UL, 0x52fd5298UL, 0x0afe0a75UL, 0xe5ffe52eUL
},
{
0x00000000UL, 0x5bef015bUL, 0xb6b702b6UL, 0xed5803edUL, 0x05070405UL, 0x5ee8055eUL, 0xb3b006b3UL, 0xe85f07e8UL,
0x0a0e080aUL, 0x51e10951UL, 0xbcb90abcUL, 0xe7560be7UL, 0x0f090c0fUL, 0x54e60d54UL, 0xb9be0eb9UL, 0xe2510fe2UL,
0x141c1014UL, 0x4ff3114fUL, 0xa2ab12a2UL, 0xf94413f9UL, 0x111b1411UL, 0x4af4154aUL, 0xa7ac16a7UL, 0xfc4317fcUL,
0x1e12181eUL, 0x45fd1945UL, 0xa8a51aa8UL, 0xf34a1bf3UL, 0x1b151c1bUL, 0x40fa1d40UL, 0xada21eadUL, 0xf64d1ff6UL,
0x28382028UL, 0x73d72173UL, 0x9e8f229eUL, 0xc56023c5UL, 0x2d3f242dUL, 0x76d02576UL, 0x9b88269bUL, 0xc06727c0UL,
0x22362822UL, 0x79d92979UL, 0x94812a94UL, 0xcf6e2bcfUL, 0x27312c27UL, 0x7cde2d7cUL, 0x91862e91UL, 0xca692fcaUL,
0x3c24303cUL, 0x67cb3167UL, 0x8a93328aUL, 0xd17c33d1UL, 0x39233439UL, 0x62cc3562UL, 0x8f94368fUL, 0xd47b37d4UL,
0x362a3836UL, 0x6dc5396dUL, 0x809d3a80UL, 0xdb723bdbUL, 0x332d3c33UL, 0x68c23d68UL, 0x859a3e85UL, 0xde753fdeUL,
0x50704050UL, 0x0b9f410bUL, 0xe6c742e6UL, 0xbd2843bdUL, 0x55774455UL, 0x0e98450eUL, 0xe3c046e3UL, 0xb82f47b8UL,
0x5a7e485aUL, 0x01914901UL, 0xecc94aecUL, 0xb7264bb7UL, 0x5f794c5fUL, 0x04964d04UL, 0xe9ce4ee9UL, 0xb2214fb2UL,
0x446c5044UL, 0x1f83511fUL, 0xf2db52f2UL, 0xa93453a9UL, 0x416b5441UL, 0x1a84551aUL, 0xf7dc56f7UL, 0xac3357acUL,
0x4e62584eUL, 0x158d5915UL, 0xf8d55af8UL, 0xa33a5ba3UL, 0x4b655c4bUL, 0x108a5d10UL, 0xfdd25efdUL, 0xa63d5fa6UL,
0x78486078UL, 0x23a76123UL, 0xceff62ceUL, 0x95106395UL, 0x7d4f647dUL, 0x26a06526UL, 0xcbf866cbUL, 0x90176790UL,
0x72466872UL, 0x29a96929UL, 0xc4f16ac4UL, 0x9f1e6b9fUL, 0x77416c77UL, 0x2cae6d2cUL, 0xc1f66ec1UL, 0x9a196f9aUL,
0x6c54706cUL, 0x37bb7137UL, 0xdae372daUL, 0x810c7381UL, 0x69537469UL, 0x32bc7532UL, 0xdfe476dfUL, 0x840b7784UL,
0x665a7866UL, 0x3db5793dUL, 0xd0ed7ad0UL, 0x8b027b8bUL, 0x635d7c63UL, 0x38b27d38UL, 0xd5ea7ed5UL, 0x8e057f8eUL,
0xa0e080a0UL, 0xfb0f81fbUL, 0x16578216UL, 0x4db8834dUL, 0xa5e784a5UL, 0xfe0885feUL, 0x13508613UL, 0x48bf8748UL,
0xaaee88aaUL, 0xf10189f1UL, 0x1c598a1cUL, 0x47b68b47UL, 0xafe98cafUL, 0xf4068df4UL, 0x195e8e19UL, 0x42b18f42UL,
0xb4fc90b4UL, 0xef1391efUL, 0x024b9202UL, 0x59a49359UL, 0xb1fb94b1UL, 0xea1495eaUL, 0x074c9607UL, 0x5ca3975cUL,
0xbef298beUL, 0xe51d99e5UL, 0x08459a08UL, 0x53aa9b53UL, 0xbbf59cbbUL, 0xe01a9de0UL, 0x0d429e0dUL, 0x56ad9f56UL,
0x88d8a088UL, 0xd337a1d3UL, 0x3e6fa23eUL, 0x6580a365UL, 0x8ddfa48dUL, 0xd630a5d6UL, 0x3b68a63bUL, 0x6087a760UL,
0x82d6a882UL, 0xd939a9d9UL, 0x3461aa34UL, 0x6f8eab6fUL, 0x87d1ac87UL, 0xdc3eaddcUL, 0x3166ae31UL, 0x6a89af6aUL,
0x9cc4b09cUL, 0xc72bb1c7UL, 0x2a73b22aUL, 0x719cb371UL, 0x99c3b499UL, 0xc22cb5c2UL, 0x2f74b62fUL, 0x749bb774UL,
0x96cab896UL, 0xcd25b9cdUL, 0x207dba20UL, 0x7b92bb7bUL, 0x93cdbc93UL, 0xc822bdc8UL, 0x257abe25UL, 0x7e95bf7eUL,
0xf090c0f0UL, 0xab7fc1abUL, 0x4627c246UL, 0x1dc8c31dUL, 0xf597c4f5UL, 0xae78c5aeUL, 0x4320c643UL, 0x18cfc718UL,
0xfa9ec8faUL, 0xa171c9a1UL, 0x4c29ca4cUL, 0x17c6cb17UL, 0xff99ccffUL, 0xa476cda4UL, 0x492ece49UL, 0x12c1cf12UL,
0xe48cd0e4UL, 0xbf63d1bfUL, 0x523bd252UL, 0x09d4d309UL, 0xe18bd4e1UL, 0xba64d5baUL, 0x573cd657UL, 0x0cd3d70cUL,
0xee82d8eeUL, 0xb56dd9b5UL, 0x5835da58UL, 0x03dadb03UL, 0xeb85dcebUL, 0xb06addb0UL, 0x5d32de5dUL, 0x06dddf06UL,
0xd8a8e0d8UL, 0x8347e183UL, 0x6e1fe26eUL, 0x35f0e335UL, 0xddafe4ddUL, 0x8640e586UL, 0x6b18e66bUL, 0x30f7e730UL,
0xd2a6e8d2UL, 0x8949e989UL, 0x6411ea64UL, 0x3ffeeb3fUL, 0xd7a1ecd7UL, 0x8c4eed8cUL, 0x6116ee61UL, 0x3af9ef3aUL,
0xccb4f0ccUL, 0x975bf197UL, 0x7a03f27aUL, 0x21ecf321UL, 0xc9b3f4c9UL, 0x925cf592UL, 0x7f04f67fUL, 0x24ebf724UL,
0xc6baf8c6UL, 0x9d55f99dUL, 0x700dfa70UL, 0x2be2fb2bUL, 0xc3bdfcc3UL, 0x9852fd98UL, 0x750afe75UL, 0x2ee5ff2eUL
}};
#define sbox(i, x) ((unsigned long)SBOX[i][(x)&255])
@ -232,69 +314,34 @@ static unsigned long sbox(int i, unsigned long x)
/* computes ab mod p */
static unsigned long gf_mult(unsigned long a, unsigned long b, unsigned long p)
{
unsigned long result = 0;
while (a > 0) {
if ((a & 1) == 1)
result ^= b;
a >>= 1;
b <<= 1;
if ((b & 0x100) == 0x100)
b ^= p;
}
return result & 255;
}
unsigned long result = 0, B[2], P[2];
P[1] = p;
B[1] = b;
P[0] = B[0] = 0;
/* unrolled branchless GF multiplier */
result ^= B[a&1]; a >>= 1; B[1] <<= 1; B[1] ^= P[B[1]>>8];
result ^= B[a&1]; a >>= 1; B[1] <<= 1; B[1] ^= P[B[1]>>8];
result ^= B[a&1]; a >>= 1; B[1] <<= 1; B[1] ^= P[B[1]>>8];
result ^= B[a&1]; a >>= 1; B[1] <<= 1; B[1] ^= P[B[1]>>8];
result ^= B[a&1]; a >>= 1; B[1] <<= 1; B[1] ^= P[B[1]>>8];
result ^= B[a&1]; a >>= 1; B[1] <<= 1; B[1] ^= P[B[1]>>8];
result ^= B[a&1]; a >>= 1; B[1] <<= 1; B[1] ^= P[B[1]>>8];
result ^= B[a&1];
/* Computes [y0 y1 y2 y3] = MDS . [x0 x1 x2 x3] */
static void mds_mult(const unsigned char *in, unsigned char *out)
{
int x, y;
unsigned char tmp[4];
for (x = 0; x < 4; x++) {
tmp[x] = (unsigned char)0;
for (y = 0; y < 4; y++)
tmp[x] ^= gf_mult(in[y], MDS[x][y], MDS_POLY);
}
for (x = 0; x < 4; x++)
out[x] = tmp[x];
zeromem(tmp, 4);
}
/* computes [y0 y1 y2 y3] = RS . [x0 x1 x2 x3 x4 x5 x6 x7] */
static void rs_mult(const unsigned char *in, unsigned char *out)
{
int x, y;
unsigned char tmp[4];
for (x = 0; x < 4; x++) {
tmp[x] = 0;
for (y = 0; y < 8; y++)
tmp[x] ^= gf_mult(in[y], RS[x][y], RS_POLY);
}
for (x = 0; x < 4; x++)
out[x] = tmp[x];
zeromem(tmp, 4);
return result;
}
/* computes [y0 y1 y2 y3] = MDS . [x0] */
#ifndef TWOFISH_TABLES
static unsigned long mds_column_mult(unsigned char in, int col)
{
return
(gf_mult(in, MDS[0][col], MDS_POLY) << 0) |
(gf_mult(in, MDS[1][col], MDS_POLY) << 8) |
(gf_mult(in, MDS[2][col], MDS_POLY) << 16) |
(gf_mult(in, MDS[3][col], MDS_POLY) << 24);
}
#else
static unsigned long mds_column_mult(unsigned char in, int col)
{
unsigned long x01, x5B, xEF;
x01 = in;
x5B = GF_5B[in];
xEF = GF_EF[in];
x5B = gf_mult(in, 0x5B, MDS_POLY);
xEF = gf_mult(in, 0xEF, MDS_POLY);
switch (col) {
case 0:
@ -321,14 +368,40 @@ static unsigned long mds_column_mult(unsigned char in, int col)
/* avoid warnings, we'd never get here normally but just to calm compiler warnings... */
return 0;
}
#endif
#else /* TWOFISH_TABLES */
#define mds_column_mult(x, i) mds_tab[i][x]
#endif /* TWOFISH_TABLES */
/* Computes [y0 y1 y2 y3] = MDS . [x0 x1 x2 x3] */
static void mds_mult(const unsigned char *in, unsigned char *out)
{
int x;
unsigned long tmp;
for (tmp = x = 0; x < 4; x++) {
tmp ^= mds_column_mult(in[x], x);
}
STORE32L(tmp, out);
}
/* computes [y0 y1 y2 y3] = RS . [x0 x1 x2 x3 x4 x5 x6 x7] */
static void rs_mult(const unsigned char *in, unsigned char *out)
{
int x, y;
for (x = 0; x < 4; x++) {
out[x] = 0;
for (y = 0; y < 8; y++)
out[x] ^= gf_mult(in[y], RS[x][y], RS_POLY);
}
}
/* computes h(x) */
static void h_func(const unsigned char *in, unsigned char *out, unsigned char *M, int k, int offset)
{
int x;
unsigned char y[4];
for (x = 0; x < 4; x++)
y[x] = in[x];
@ -354,14 +427,24 @@ static void h_func(const unsigned char *in, unsigned char *out, unsigned char *M
#ifndef TWOFISH_SMALL
#define g_func(x,dum) (key->twofish.S[0][((x)>>0)&255] ^ key->twofish.S[1][((x)>>8)&255] ^ key->twofish.S[2][((x)>>16)&255] ^ key->twofish.S[3][((x)>>24)&255])
/* for GCC we don't use pointer aliases */
#if defined(__GNUC__)
#define S1 key->twofish.S[0]
#define S2 key->twofish.S[1]
#define S3 key->twofish.S[2]
#define S4 key->twofish.S[3]
#endif
/* the G function */
#define g_func(x, dum) (S1[byte(x,0)] ^ S2[byte(x,1)] ^ S3[byte(x,2)] ^ S4[byte(x,3)])
#define g1_func(x, dum) (S2[byte(x,0)] ^ S3[byte(x,1)] ^ S4[byte(x,2)] ^ S1[byte(x,3)])
#else
#ifdef CLEAN_STACK
static unsigned long _g_func(unsigned long x, symmetric_key *key)
#else
unsigned long g_func(unsigned long x, symmetric_key *key)
static unsigned long g_func(unsigned long x, symmetric_key *key)
#endif
{
unsigned char g, i, y, z;
@ -389,6 +472,8 @@ unsigned long g_func(unsigned long x, symmetric_key *key)
return res;
}
#define g1_func(x, key) g_func(ROL(x, 8), key)
#ifdef CLEAN_STACK
static unsigned long g_func(unsigned long x, symmetric_key *key)
{
@ -487,8 +572,7 @@ int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetri
/* do key mixing+sbox until z==5 */
while (z != 5) {
g = g ^ S[4*i++ + y];
g = sbox((int)qord[y][z++], g);
g = sbox((int)qord[y][z++], g ^ S[4*i++ + y]);
}
/* multiply g by a column of the MDS */
@ -520,10 +604,20 @@ void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
{
unsigned long a,b,c,d,ta,tb,tc,td,t1,t2, *k;
int r;
#if !defined(TWOFISH_SMALL) && !defined(__GNUC__)
unsigned long *S1, *S2, *S3, *S4;
#endif
_ARGCHK(pt != NULL);
_ARGCHK(ct != NULL);
_ARGCHK(key != NULL);
#if !defined(TWOFISH_SMALL) && !defined(__GNUC__)
S1 = key->twofish.S[0];
S2 = key->twofish.S[1];
S3 = key->twofish.S[2];
S4 = key->twofish.S[3];
#endif
LOAD32L(a,&pt[0]); LOAD32L(b,&pt[4]);
LOAD32L(c,&pt[8]); LOAD32L(d,&pt[12]);
@ -535,20 +629,16 @@ void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
k = key->twofish.K + 8;
for (r = 0; r < 16; r += 2) {
t1 = g_func(a, key);
t2 = g_func(ROL(b, 8), key);
t2 += (t1 += t2);
t1 += *k++;
t2 += *k++;
c ^= t1; c = ROR(c, 1);
d = ROL(d, 1) ^ t2;
t2 = g1_func(b, key);
c = ROR(c ^ (t1 + t2 + k[0]), 1);
d = ROL(d, 1) ^ (t2 + t2 + t1 + k[1]);
k += 2;
t1 = g_func(c, key);
t2 = g_func(ROL(d, 8), key);
t2 += (t1 += t2);
t1 += *k++;
t2 += *k++;
a ^= t1; a = ROR(a, 1);
b = ROL(b, 1) ^ t2;
t2 = g1_func(d, key);
a = ROR(a ^ (t1 + t2 + k[0]), 1);
b = ROL(b, 1) ^ (t2 + t2 + t1 + k[1]);
k += 2;
}
/* output with "undo last swap" */
@ -578,10 +668,20 @@ void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k
{
unsigned long a,b,c,d,ta,tb,tc,td,t1,t2, *k;
int r;
#if !defined(TWOFISH_SMALL) && !defined(__GNUC__)
unsigned long *S1, *S2, *S3, *S4;
#endif
_ARGCHK(pt != NULL);
_ARGCHK(ct != NULL);
_ARGCHK(key != NULL);
#if !defined(TWOFISH_SMALL) && !defined(__GNUC__)
S1 = key->twofish.S[0];
S2 = key->twofish.S[1];
S3 = key->twofish.S[2];
S4 = key->twofish.S[3];
#endif
/* load input */
LOAD32L(ta,&ct[0]); LOAD32L(tb,&ct[4]);
@ -593,23 +693,19 @@ void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k
c = ta ^ key->twofish.K[4];
d = tb ^ key->twofish.K[5];
k = key->twofish.K + 39;
k = key->twofish.K + 38;
for (r = 14; r >= 0; r -= 2) {
t1 = g_func(c, key);
t2 = g_func(ROL(d, 8), key);
t2 += (t1 += t2);
t2 += *k--;
t1 += *k--;
a = ROL(a, 1) ^ t1;
b = b ^ t2; b = ROR(b, 1);
t2 = g1_func(d, key);
a = ROL(a, 1) ^ (t1 + t2 + k[0]);
b = ROR(b ^ (t2 + t2 + t1 + k[1]), 1);
k -= 2;
t1 = g_func(a, key);
t2 = g_func(ROL(b, 8), key);
t2 += (t1 += t2);
t2 += *k--;
t1 += *k--;
c = ROL(c, 1) ^ t1;
d = d ^ t2; d = ROR(d, 1);
t2 = g1_func(b, key);
c = ROL(c, 1) ^ (t1 + t2 + k[0]);
d = ROR(d ^ (t2 + t2 + t1 + k[1]), 1);
k -= 2;
}
/* pre-white */