added libtomcrypt-0.85

This commit is contained in:
Tom St Denis 2003-06-11 21:10:22 +00:00 committed by Steffen Jaeckel
parent d6071c6267
commit f5331baa9f
28 changed files with 7513 additions and 8092 deletions

783
aes.c
View File

@ -1,19 +1,19 @@
/* This is an independent implementation of the encryption algorithm: */
/* */
/* RIJNDAEL by Joan Daemen and Vincent Rijmen */
/* */
/* which is a candidate algorithm in the Advanced Encryption Standard */
/* programme of the US National Institute of Standards and Technology. */
/* */
/* Copyright in this implementation is held by Dr B R Gladman but I */
/* hereby give permission for its free direct or derivative use subject */
/* to acknowledgment of its origin and compliance with any conditions */
/* that the originators of the algorithm place on its exploitation. */
/* */
/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */
/* This code has been modified by Tom St Denis for libtomcrypt.a */
/* AES implementation by Tom St Denis
*
* Derived from the Public Domain source code by
---
* rijndael-alg-fst.c
*
* @version 3.0 (December 2000)
*
* Optimised ANSI C code for the Rijndael cipher (now AES)
*
* @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
* @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
* @author Paulo Barreto <paulo.barreto@terra.com.br>
---
*/
#include "mycrypt.h"
@ -45,285 +45,517 @@ const struct _cipher_descriptor aes_desc =
#include "aes_tab.c"
#define byte(x, y) (((x)>>(8*(y)))&255)
#define f_rn(bo, bi, n, k) \
bo[n] = ft_tab[0][byte(bi[n],0)] ^ \
ft_tab[1][byte(bi[(n + 1) & 3],1)] ^ \
ft_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
#define i_rn(bo, bi, n, k) \
bo[n] = it_tab[0][byte(bi[n],0)] ^ \
it_tab[1][byte(bi[(n + 3) & 3],1)] ^ \
it_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
#define ls_box(x) \
( fl_tab[0][byte(x, 0)] ^ \
fl_tab[1][byte(x, 1)] ^ \
fl_tab[2][byte(x, 2)] ^ \
fl_tab[3][byte(x, 3)] )
#define f_rl(bo, bi, n, k) \
bo[n] = fl_tab[0][byte(bi[n],0)] ^ \
fl_tab[1][byte(bi[(n + 1) & 3],1)] ^ \
fl_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
#define i_rl(bo, bi, n, k) \
bo[n] = il_tab[0][byte(bi[n],0)] ^ \
il_tab[1][byte(bi[(n + 3) & 3],1)] ^ \
il_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
#define star_x(x) (((x) & 0x7f7f7f7fUL) << 1) ^ ((((x) & 0x80808080UL) >> 7) * 0x1bUL)
#define imix_col(y,x) \
u = star_x(x); \
v = star_x(u); \
w = star_x(v); \
t = w ^ (x); \
(y) = u ^ v ^ w; \
(y) ^= ROR(u ^ t, 8) ^ \
ROR(v ^ t, 16) ^ \
ROR(t,24)
#ifdef CLEAN_STACK
static int _rijndael_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
#else
int rijndael_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
#endif
int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_key *skey)
{
unsigned long t, u, v, w, in_key[8];
int i, k_len;
/* check arguments */
_ARGCHK(key != NULL);
int i = 0, j;
unsigned long temp, *rk;
_ARGCHK(key != NULL);
_ARGCHK(skey != NULL);
if (numrounds == 0) {
numrounds = 10 + (2 * ((keylen/8)-2));
}
if (keylen != 16 && keylen != 24 && keylen != 32) {
return CRYPT_INVALID_KEYSIZE;
}
if (numrounds != (10 + (2 * ((keylen/8)-2)))) {
if (rounds != 0 && rounds != (10 + ((keylen/8)-2)*2)) {
return CRYPT_INVALID_ROUNDS;
}
k_len = keylen / 4;
for (i = 0; i < k_len; i++) {
LOAD32L(in_key[i], key+(4*i));
}
skey->rijndael.k_len = k_len;
skey->rijndael.eK[0] = in_key[0]; skey->rijndael.eK[1] = in_key[1];
skey->rijndael.eK[2] = in_key[2]; skey->rijndael.eK[3] = in_key[3];
switch(k_len) {
case 4: t = skey->rijndael.eK[3];
for(i = 0; i < 10; ++i) {
t = ls_box(ROR(t, 8)) ^ rco_tab[i];
t ^= skey->rijndael.eK[4 * i]; skey->rijndael.eK[4 * i + 4] = t;
t ^= skey->rijndael.eK[4 * i + 1]; skey->rijndael.eK[4 * i + 5] = t;
t ^= skey->rijndael.eK[4 * i + 2]; skey->rijndael.eK[4 * i + 6] = t;
t ^= skey->rijndael.eK[4 * i + 3]; skey->rijndael.eK[4 * i + 7] = t;
skey->rijndael.Nr = 10 + ((keylen/8)-2)*2;
/* setup the forward key */
rk = skey->rijndael.eK;
LOAD32H(rk[0], key );
LOAD32H(rk[1], key + 4);
LOAD32H(rk[2], key + 8);
LOAD32H(rk[3], key + 12);
if (keylen == 16) {
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) ^
rcon[i];
rk[5] = rk[1] ^ rk[4];
rk[6] = rk[2] ^ rk[5];
rk[7] = rk[3] ^ rk[6];
if (++i == 10) {
break;
}
break;
case 6: skey->rijndael.eK[4] = in_key[4];
t = skey->rijndael.eK[5] = in_key[5];
for(i = 0; i < 8; ++i) {
t = ls_box(ROR(t, 8)) ^ rco_tab[i];
t ^= skey->rijndael.eK[6 * i]; skey->rijndael.eK[6 * i + 6] = t;
t ^= skey->rijndael.eK[6 * i + 1]; skey->rijndael.eK[6 * i + 7] = t;
t ^= skey->rijndael.eK[6 * i + 2]; skey->rijndael.eK[6 * i + 8] = t;
t ^= skey->rijndael.eK[6 * i + 3]; skey->rijndael.eK[6 * i + 9] = t;
t ^= skey->rijndael.eK[6 * i + 4]; skey->rijndael.eK[6 * i + 10] = t;
t ^= skey->rijndael.eK[6 * i + 5]; skey->rijndael.eK[6 * i + 11] = t;
rk += 4;
}
} else if (keylen == 24) {
LOAD32H(rk[4], key + 16);
LOAD32H(rk[5], key + 20);
for (;;) {
temp = rk[ 5];
rk[ 6] = rk[ 0] ^
(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
(Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te4[(temp ) & 0xff] & 0x0000ff00) ^
(Te4[(temp >> 24) ] & 0x000000ff) ^
rcon[i];
rk[ 7] = rk[ 1] ^ rk[ 6];
rk[ 8] = rk[ 2] ^ rk[ 7];
rk[ 9] = rk[ 3] ^ rk[ 8];
if (++i == 8) {
break;
}
break;
case 8: skey->rijndael.eK[4] = in_key[4];
skey->rijndael.eK[5] = in_key[5];
skey->rijndael.eK[6] = in_key[6];
t = skey->rijndael.eK[7] = in_key[7];
for(i = 0; i < 7; ++i) {
t = ls_box(ROR(t, 8)) ^ rco_tab[i];
t ^= skey->rijndael.eK[8 * i]; skey->rijndael.eK[8 * i + 8] = t;
t ^= skey->rijndael.eK[8 * i + 1]; skey->rijndael.eK[8 * i + 9] = t;
t ^= skey->rijndael.eK[8 * i + 2]; skey->rijndael.eK[8 * i + 10] = t;
t ^= skey->rijndael.eK[8 * i + 3]; skey->rijndael.eK[8 * i + 11] = t;
t = skey->rijndael.eK[8 * i + 4] ^ ls_box(t); skey->rijndael.eK[8 * i + 12] = t;
t ^= skey->rijndael.eK[8 * i + 5]; skey->rijndael.eK[8 * i + 13] = t;
t ^= skey->rijndael.eK[8 * i + 6]; skey->rijndael.eK[8 * i + 14] = t;
t ^= skey->rijndael.eK[8 * i + 7]; skey->rijndael.eK[8 * i + 15] = t;
rk[10] = rk[ 4] ^ rk[ 9];
rk[11] = rk[ 5] ^ rk[10];
rk += 6;
}
} else if (keylen == 32) {
LOAD32H(rk[4], key + 16);
LOAD32H(rk[5], key + 20);
LOAD32H(rk[6], key + 24);
LOAD32H(rk[7], key + 28);
for (;;) {
temp = rk[ 7];
rk[ 8] = rk[ 0] ^
(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
(Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te4[(temp ) & 0xff] & 0x0000ff00) ^
(Te4[(temp >> 24) ] & 0x000000ff) ^
rcon[i];
rk[ 9] = rk[ 1] ^ rk[ 8];
rk[10] = rk[ 2] ^ rk[ 9];
rk[11] = rk[ 3] ^ rk[10];
if (++i == 7) {
break;
}
break;
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);
rk[13] = rk[ 5] ^ rk[12];
rk[14] = rk[ 6] ^ rk[13];
rk[15] = rk[ 7] ^ rk[14];
rk += 8;
}
}
skey->rijndael.dK[0] = skey->rijndael.eK[0];
skey->rijndael.dK[1] = skey->rijndael.eK[1];
skey->rijndael.dK[2] = skey->rijndael.eK[2];
skey->rijndael.dK[3] = skey->rijndael.eK[3];
for(i = 4; i < 4 * k_len + 24; ++i) {
imix_col(skey->rijndael.dK[i], skey->rijndael.eK[i]);
/* setup the inverse key now */
memcpy(skey->rijndael.dK, skey->rijndael.eK, sizeof(skey->rijndael.eK));
rk = skey->rijndael.dK;
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;
}
return CRYPT_OK;
};
#ifdef CLEAN_STACK
int rijndael_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
{
int x;
x = _rijndael_setup(key, keylen, numrounds, skey);
burn_stack(sizeof(unsigned long) * 12 + sizeof(int) * 2);
return x;
/* 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];
}
return CRYPT_OK;
}
#endif
/* encrypt a block of text */
#define f_nround(bo, bi, k) \
f_rn(bo, bi, 0, k); \
f_rn(bo, bi, 1, k); \
f_rn(bo, bi, 2, k); \
f_rn(bo, bi, 3, k); \
k += 4
#define f_lround(bo, bi, k) \
f_rl(bo, bi, 0, k); \
f_rl(bo, bi, 1, k); \
f_rl(bo, bi, 2, k); \
f_rl(bo, bi, 3, k)
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
static void _fnround(unsigned long *bo, unsigned long *bi, unsigned long *k)
{
f_nround(bo, bi, k);
}
static void _flround(unsigned long *bo, unsigned long *bi, unsigned long *k)
{
f_lround(bo, bi, k);
}
#undef f_nround
#define f_nround(bo, bi, k) { _fnround(bo, bi, k); k += 4; }
#undef f_lround
#define f_lround(bo, bi, k) _flround(bo, bi, k)
#endif
void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
unsigned long b0[4], b1[4], *kp;
int r;
#endif
_ARGCHK(pt != NULL);
_ARGCHK(ct != NULL);
_ARGCHK(skey != NULL);
LOAD32L(b0[0], &pt[0]); LOAD32L(b0[1], &pt[4]);
LOAD32L(b0[2], &pt[8]); LOAD32L(b0[3], &pt[12]);
b0[0] ^= skey->rijndael.eK[0]; b0[1] ^= skey->rijndael.eK[1];
b0[2] ^= skey->rijndael.eK[2]; b0[3] ^= skey->rijndael.eK[3];
kp = skey->rijndael.eK + 4;
if (skey->rijndael.k_len > 6) {
f_nround(b1, b0, kp); f_nround(b0, b1, kp);
f_nround(b1, b0, kp); f_nround(b0, b1, kp);
} else if (skey->rijndael.k_len > 4) {
f_nround(b1, b0, kp); f_nround(b0, b1, kp);
}
f_nround(b1, b0, kp); f_nround(b0, b1, kp);
f_nround(b1, b0, kp); f_nround(b0, b1, kp);
f_nround(b1, b0, kp); f_nround(b0, b1, kp);
f_nround(b1, b0, kp); f_nround(b0, b1, kp);
f_nround(b1, b0, kp); f_lround(b0, b1, kp);
STORE32L(b0[0], &ct[0]); STORE32L(b0[1], &ct[4]);
STORE32L(b0[2], &ct[8]); STORE32L(b0[3], &ct[12]);
#ifdef CLEAN_STACK
zeromem(b0, sizeof(b0));
zeromem(b1, sizeof(b1));
#endif
};
/* decrypt a block of text */
#define i_nround(bo, bi, k) \
i_rn(bo, bi, 0, k); \
i_rn(bo, bi, 1, k); \
i_rn(bo, bi, 2, k); \
i_rn(bo, bi, 3, k); \
k -= 4
#define i_lround(bo, bi, k) \
i_rl(bo, bi, 0, k); \
i_rl(bo, bi, 1, k); \
i_rl(bo, bi, 2, k); \
i_rl(bo, bi, 3, k)
#ifdef SMALL_CODE
Nr = skey->rijndael.Nr;
rk = skey->rijndael.eK;
/*
* map byte array block to cipher state
* and add initial round key:
*/
LOAD32H(s0, pt ); s0 ^= rk[0];
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:
*/
r = Nr >> 1;
for (;;) {
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];
static void _inround(unsigned long *bo, unsigned long *bi, unsigned long *k)
{
i_nround(bo, bi, k);
rk += 8;
if (--r == 0) {
break;
}
s0 =
Te0[(t0 >> 24) ] ^
Te1[(t1 >> 16) & 0xff] ^
Te2[(t2 >> 8) & 0xff] ^
Te3[(t3 ) & 0xff] ^
rk[0];
s1 =
Te0[(t1 >> 24) ] ^
Te1[(t2 >> 16) & 0xff] ^
Te2[(t3 >> 8) & 0xff] ^
Te3[(t0 ) & 0xff] ^
rk[1];
s2 =
Te0[(t2 >> 24) ] ^
Te1[(t3 >> 16) & 0xff] ^
Te2[(t0 >> 8) & 0xff] ^
Te3[(t1 ) & 0xff] ^
rk[2];
s3 =
Te0[(t3 >> 24) ] ^
Te1[(t0 >> 16) & 0xff] ^
Te2[(t1 >> 8) & 0xff] ^
Te3[(t2 ) & 0xff] ^
rk[3];
}
#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) ^
rk[0];
STORE32H(s0, ct);
s1 =
(Te4[(t1 >> 24) ] & 0xff000000) ^
(Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t0 ) & 0xff] & 0x000000ff) ^
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) ^
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) ^
rk[3];
STORE32H(s3, ct+12);
}
static void _ilround(unsigned long *bo, unsigned long *bi, unsigned long *k)
{
i_lround(bo, bi, k);
}
#undef i_nround
#define i_nround(bo, bi, k) { _inround(bo, bi, k); k -= 4; }
#undef i_lround
#define i_lround(bo, bi, k) _ilround(bo, bi, k)
#endif
void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
unsigned long b0[4], b1[4], *kp;
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 */
_ARGCHK(pt != NULL);
_ARGCHK(ct != NULL);
_ARGCHK(skey != NULL);
Nr = skey->rijndael.Nr;
rk = skey->rijndael.dK;
LOAD32L(b0[0], &ct[0]); LOAD32L(b0[1], &ct[4]);
LOAD32L(b0[2], &ct[8]); LOAD32L(b0[3], &ct[12]);
b0[0] ^= skey->rijndael.eK[4 * skey->rijndael.k_len + 24];
b0[1] ^= skey->rijndael.eK[4 * skey->rijndael.k_len + 25];
b0[2] ^= skey->rijndael.eK[4 * skey->rijndael.k_len + 26];
b0[3] ^= skey->rijndael.eK[4 * skey->rijndael.k_len + 27];
kp = skey->rijndael.dK + 4 * (skey->rijndael.k_len + 5);
if(skey->rijndael.k_len > 6) {
i_nround(b1, b0, kp); i_nround(b0, b1, kp);
i_nround(b1, b0, kp); i_nround(b0, b1, kp);
} else if(skey->rijndael.k_len > 4) {
i_nround(b1, b0, kp); i_nround(b0, b1, kp);
/*
* map byte array block to cipher state
* and add initial round key:
*/
LOAD32H(s0, ct ); s0 ^= rk[0];
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] ^
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];
i_nround(b1, b0, kp); i_nround(b0, b1, kp);
i_nround(b1, b0, kp); i_nround(b0, b1, kp);
i_nround(b1, b0, kp); i_nround(b0, b1, kp);
i_nround(b1, b0, kp); i_nround(b0, b1, kp);
i_nround(b1, b0, kp); i_lround(b0, b1, kp);
rk += 8;
if (--r == 0) {
break;
}
STORE32L(b0[0], &pt[0]); STORE32L(b0[1], &pt[4]);
STORE32L(b0[2], &pt[8]); STORE32L(b0[3], &pt[12]);
#ifdef CLEAN_STACK
zeromem(b0, sizeof(b0));
zeromem(b1, sizeof(b1));
#endif
};
s0 =
Td0[(t0 >> 24) ] ^
Td1[(t3 >> 16) & 0xff] ^
Td2[(t2 >> 8) & 0xff] ^
Td3[(t1 ) & 0xff] ^
rk[0];
s1 =
Td0[(t1 >> 24) ] ^
Td1[(t0 >> 16) & 0xff] ^
Td2[(t3 >> 8) & 0xff] ^
Td3[(t2 ) & 0xff] ^
rk[1];
s2 =
Td0[(t2 >> 24) ] ^
Td1[(t1 >> 16) & 0xff] ^
Td2[(t0 >> 8) & 0xff] ^
Td3[(t3 ) & 0xff] ^
rk[2];
s3 =
Td0[(t3 >> 24) ] ^
Td1[(t2 >> 16) & 0xff] ^
Td2[(t1 >> 8) & 0xff] ^
Td3[(t0 ) & 0xff] ^
rk[3];
}
#endif /* SMALL_CODE */
/*
* apply last round and
* map cipher state to byte array block:
*/
s0 =
(Td4[(t0 >> 24) ] & 0xff000000) ^
(Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t1 ) & 0xff] & 0x000000ff) ^
rk[0];
STORE32H(s0, pt);
s1 =
(Td4[(t1 >> 24) ] & 0xff000000) ^
(Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t2 ) & 0xff] & 0x000000ff) ^
rk[1];
STORE32H(s1, pt+4);
s2 =
(Td4[(t2 >> 24) ] & 0xff000000) ^
(Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t3 ) & 0xff] & 0x000000ff) ^
rk[2];
STORE32H(s2, pt+8);
s3 =
(Td4[(t3 >> 24) ] & 0xff000000) ^
(Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t0 ) & 0xff] & 0x000000ff) ^
rk[3];
STORE32H(s3, pt+12);
}
int rijndael_test(void)
{
@ -337,7 +569,7 @@ int rijndael_test(void)
} tests[] = {
{ 16,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
@ -369,14 +601,31 @@ int rijndael_test(void)
int i;
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
if ((errno = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
zeromem(&key, sizeof(key));
if ((errno = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
return errno;
}
rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key);
rijndael_ecb_decrypt(tmp[0], tmp[1], &key);
if (memcmp(tmp[0], tests[i].ct, 16) || memcmp(tmp[1], tests[i].pt, 16)) {
return CRYPT_FAIL_TESTVECTOR;
#if 0
printf("\n\nTest %d failed\n", i);
if (memcmp(tmp[0], tests[i].ct, 16)) {
printf("CT: ");
for (i = 0; i < 16; i++) {
printf("%02x ", tmp[0][i]);
}
printf("\n");
} else {
printf("PT: ");
for (i = 0; i < 16; i++) {
printf("%02x ", tmp[1][i]);
}
printf("\n");
}
#endif
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;

1523
aes_tab.c

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,8 @@
Jun 11th, 2003
v0.85 -- Swapped in a new AES routine
-- Removed Serpent
-- Added TDCAL policy document
Jun 1st, 2003
v0.84 -- Removed a 4KB buffer from rsa_decrypt_key that wasn't being used no more
-- Fixed another potential buffer problem. Not an overflow but could cause the

View File

@ -30,7 +30,6 @@
"RC2,Include RC2 block cipher,y",
"RC5,Include RC5 block cipher,y",
"RC6,Include RC6 block cipher,y",
"SERPENT,Include Serpent block cipher,y",
"SAFERP,Include Safer+ block cipher,y",
"SAFER,Include Safer-64 block ciphers,y",
"RIJNDAEL,Include Rijndael (AES) block cipher,y",
@ -145,7 +144,7 @@ for (@settings) {
# output objects
print OUT "\ndefault: library\n\n";
print OUT "OBJECTS = keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o serpent.o des.o safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o mpi.o prime.o twofish.o packet.o hmac.o strings.o\n\n";
print OUT "OBJECTS = keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o des.o safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o mpi.o prime.o twofish.o packet.o hmac.o strings.o \n\n";
# some depends
print OUT "rsa.o: rsa_sys.c\ndh.o: dh_sys.c\necc.o: ecc_sys.c\n\n";

View File

@ -384,9 +384,6 @@ const char *crypt_build_settings =
#if defined(RC6)
" RC6\n"
#endif
#if defined(SERPENT)
" Serpent\n"
#endif
#if defined(SAFERP)
" Safer+\n"
#endif

76
crypt.out Normal file
View File

@ -0,0 +1,76 @@
\BOOKMARK [0][-]{chapter.1}{Introduction}{}
\BOOKMARK [1][-]{section.1.1}{What is the LibTomCrypt?}{chapter.1}
\BOOKMARK [2][-]{subsection.1.1.1}{What the library IS for?}{section.1.1}
\BOOKMARK [2][-]{subsection.1.1.2}{What the library IS NOT for?}{section.1.1}
\BOOKMARK [1][-]{section.1.2}{Why did I write it?}{chapter.1}
\BOOKMARK [2][-]{subsection.1.2.1}{Modular}{section.1.2}
\BOOKMARK [1][-]{section.1.3}{License}{chapter.1}
\BOOKMARK [1][-]{section.1.4}{Patent Disclosure}{chapter.1}
\BOOKMARK [1][-]{section.1.5}{Building the library}{chapter.1}
\BOOKMARK [1][-]{section.1.6}{Building against the library}{chapter.1}
\BOOKMARK [1][-]{section.1.7}{Thanks}{chapter.1}
\BOOKMARK [0][-]{chapter.2}{The Application Programming Interface \(API\)}{}
\BOOKMARK [1][-]{section.2.1}{Introduction}{chapter.2}
\BOOKMARK [1][-]{section.2.2}{Macros}{chapter.2}
\BOOKMARK [1][-]{section.2.3}{Functions with Variable Length Output}{chapter.2}
\BOOKMARK [1][-]{section.2.4}{Functions that need a PRNG}{chapter.2}
\BOOKMARK [1][-]{section.2.5}{Functions that use Arrays of Octets}{chapter.2}
\BOOKMARK [0][-]{chapter.3}{Symmetric Block Ciphers}{}
\BOOKMARK [1][-]{section.3.1}{Core Functions}{chapter.3}
\BOOKMARK [1][-]{section.3.2}{Key Sizes and Number of Rounds}{chapter.3}
\BOOKMARK [1][-]{section.3.3}{The Cipher Descriptors}{chapter.3}
\BOOKMARK [2][-]{subsection.3.3.1}{Notes}{section.3.3}
\BOOKMARK [1][-]{section.3.4}{Symmetric Modes of Operations}{chapter.3}
\BOOKMARK [2][-]{subsection.3.4.1}{Background}{section.3.4}
\BOOKMARK [2][-]{subsection.3.4.2}{Choice of Mode}{section.3.4}
\BOOKMARK [2][-]{subsection.3.4.3}{Implementation}{section.3.4}
\BOOKMARK [0][-]{chapter.4}{One-Way Cryptographic Hash Functions}{}
\BOOKMARK [1][-]{section.4.1}{Core Functions}{chapter.4}
\BOOKMARK [1][-]{section.4.2}{Hash Descriptors}{chapter.4}
\BOOKMARK [2][-]{subsection.4.2.1}{Notice}{section.4.2}
\BOOKMARK [1][-]{section.4.3}{Hash based Message Authenication Codes}{chapter.4}
\BOOKMARK [0][-]{chapter.5}{Pseudo-Random Number Generators}{}
\BOOKMARK [1][-]{section.5.1}{Core Functions}{chapter.5}
\BOOKMARK [2][-]{subsection.5.1.1}{Remarks}{section.5.1}
\BOOKMARK [2][-]{subsection.5.1.2}{Example}{section.5.1}
\BOOKMARK [1][-]{section.5.2}{PRNG Descriptors}{chapter.5}
\BOOKMARK [1][-]{section.5.3}{The Secure RNG}{chapter.5}
\BOOKMARK [2][-]{subsection.5.3.1}{The Secure PRNG Interface}{section.5.3}
\BOOKMARK [0][-]{chapter.6}{RSA Routines}{}
\BOOKMARK [1][-]{section.6.1}{Background}{chapter.6}
\BOOKMARK [1][-]{section.6.2}{Core Functions}{chapter.6}
\BOOKMARK [1][-]{section.6.3}{Packet Routines}{chapter.6}
\BOOKMARK [1][-]{section.6.4}{Remarks}{chapter.6}
\BOOKMARK [0][-]{chapter.7}{Diffie-Hellman Key Exchange}{}
\BOOKMARK [1][-]{section.7.1}{Background}{chapter.7}
\BOOKMARK [1][-]{section.7.2}{Core Functions}{chapter.7}
\BOOKMARK [2][-]{subsection.7.2.1}{Remarks on Usage}{section.7.2}
\BOOKMARK [2][-]{subsection.7.2.2}{Remarks on The Snippet}{section.7.2}
\BOOKMARK [1][-]{section.7.3}{Other Diffie-Hellman Functions}{chapter.7}
\BOOKMARK [1][-]{section.7.4}{DH Packet}{chapter.7}
\BOOKMARK [0][-]{chapter.8}{Elliptic Curve Cryptography}{}
\BOOKMARK [1][-]{section.8.1}{Background}{chapter.8}
\BOOKMARK [1][-]{section.8.2}{Core Functions}{chapter.8}
\BOOKMARK [1][-]{section.8.3}{ECC Packet}{chapter.8}
\BOOKMARK [1][-]{section.8.4}{ECC Keysizes}{chapter.8}
\BOOKMARK [0][-]{chapter.9}{Public Keyrings}{}
\BOOKMARK [1][-]{section.9.1}{Introduction}{chapter.9}
\BOOKMARK [1][-]{section.9.2}{The Keyring API}{chapter.9}
\BOOKMARK [0][-]{chapter.10}{GF\(2w\) Math Routines}{}
\BOOKMARK [0][-]{chapter.11}{Miscellaneous}{}
\BOOKMARK [1][-]{section.11.1}{Base64 Encoding and Decoding}{chapter.11}
\BOOKMARK [1][-]{section.11.2}{The Multiple Precision Integer Library \(MPI\)}{chapter.11}
\BOOKMARK [2][-]{subsection.11.2.1}{Binary Forms of ``mp\137int'' Variables}{section.11.2}
\BOOKMARK [2][-]{subsection.11.2.2}{Primality Testing}{section.11.2}
\BOOKMARK [0][-]{chapter.12}{Programming Guidelines}{}
\BOOKMARK [1][-]{section.12.1}{Secure Pseudo Random Number Generators}{chapter.12}
\BOOKMARK [1][-]{section.12.2}{Preventing Trivial Errors}{chapter.12}
\BOOKMARK [1][-]{section.12.3}{Registering Your Algorithms}{chapter.12}
\BOOKMARK [1][-]{section.12.4}{Key Sizes}{chapter.12}
\BOOKMARK [2][-]{subsection.12.4.1}{Symmetric Ciphers}{section.12.4}
\BOOKMARK [2][-]{subsection.12.4.2}{Assymetric Ciphers}{section.12.4}
\BOOKMARK [1][-]{section.12.5}{Thread Safety}{chapter.12}
\BOOKMARK [0][-]{chapter.13}{Configuring the Library}{}
\BOOKMARK [1][-]{section.13.1}{Introduction}{chapter.13}
\BOOKMARK [1][-]{section.13.2}{mycrypt\137cfg.h}{chapter.13}
\BOOKMARK [1][-]{section.13.3}{The Configure Script}{chapter.13}

BIN
crypt.pdf

Binary file not shown.

View File

@ -1,4 +1,5 @@
\documentclass{book}
\usepackage{hyperref}
\usepackage{makeidx}
\usepackage{amssymb}
\usepackage{color}
@ -41,14 +42,12 @@
\def\C{{\mathbb C}}
\def\Q{{\mathbb Q}}
\newcommand{\url}[1]{\mbox{$<${#1}$>$}}
\newcommand{\emailaddr}[1]{\mbox{$<${#1}$>$}}
\def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}}
\def\gap{\vspace{0.5ex}}
\makeindex
\begin{document}
\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.84}
\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.85}
\author{Tom St Denis \\
Algonquin College \\
\\
@ -162,14 +161,11 @@ All of the source code except for the following files have been written by the a
under the TDCAL license:
\begin{enumerate}
\item aes.c
\item rc2.c
\item serpent.c
\item safer.c
\end{enumerate}
``aes.c'' and ``serpent.c'' were written by Brian Gladman (gladman@seven77.demon.co.uk). They are copyrighted works
but were both granted unrestricted usage in any project (commercial or otherwise). ``mpi.c'' was originally written
`mpi.c'' was originally written
by Michael Fromberger (sting@linguist.dartmouth.edu) but has since been replaced with my LibTomMath library.
``rc2.c'' is based on publicly available code that is not attributed to a person from the given source. ``safer.c''
was written by Richard De Moliner (demoliner@isi.ee.ethz.ch) and is public domain.
@ -512,7 +508,6 @@ As of this release the current cipher\_descriptors elements are
\hline Safer SK64 & safer\_sk64\_desc & 8 & 8 & 6 .. 13 \\
\hline Safer K128 & safer\_k128\_desc & 8 & 16 & 6 .. 13 \\
\hline Safer SK128 & safer\_sk128\_desc & 8 & 16 & 6 .. 13 \\
\hline Serpent & serpent\_desc & 16 & 16 .. 32 & 32 \\
\hline AES & aes\_desc & 16 & 16, 24, 32 & 10, 12, 14 \\
\hline Twofish & twofish\_desc & 16 & 16, 24, 32 & 16 \\
\hline DES & des\_desc & 8 & 7 & 16 \\

View File

@ -506,7 +506,6 @@ pad_test (void)
}
printf ("passed.\n");
}
void
rsa_test (void)
{
@ -658,9 +657,6 @@ rsa_test (void)
rsa_free (&key);
}
}
}
#else
void
@ -1296,6 +1292,9 @@ test_prime (void)
void
register_all_algs (void)
{
#ifdef RIJNDAEL
register_cipher (&aes_desc);
#endif
#ifdef BLOWFISH
register_cipher (&blowfish_desc);
#endif
@ -1311,12 +1310,6 @@ register_all_algs (void)
#ifdef SAFERP
register_cipher (&saferp_desc);
#endif
#ifdef SERPENT
register_cipher (&serpent_desc);
#endif
#ifdef RIJNDAEL
register_cipher (&aes_desc);
#endif
#ifdef TWOFISH
register_cipher (&twofish_desc);
#endif
@ -1375,6 +1368,7 @@ register_all_algs (void)
#endif
}
#ifdef KR
void
kr_display (pk_key * kr)
{
@ -1664,8 +1658,8 @@ kr_test (void)
}
kr_clear (&kr);
}
#endif
void
test_errs (void)
@ -1715,7 +1709,7 @@ main (void)
#endif
register_all_algs ();
if ((errnum = yarrow_start (&prng)) != CRYPT_OK) {
printf ("yarrow_start: %s\n", error_to_string (errnum));
}
@ -1746,7 +1740,9 @@ main (void)
rng_tests ();
//test_prime();
#ifdef KR
kr_test ();
#endif
rsa_test ();
pad_test ();
ecc_tests ();

View File

@ -4,19 +4,6 @@ Tom St Denis
The bulk of the code was written or donated under the TDCAL "Tom Doesn't Care About License" license. It entitles the developer to free-reign on
the use and distribution of derived works, commercial or otherwise. Certain files are taken from public domain packages.
AES.C
-----
Author: Dr Brian Gladman
Email : gladman@seven77.demon.co.uk
Disclaimer (verbatim)
----
/* Copyright in this implementation is held by Dr B R Gladman but I */
/* hereby give permission for its free direct or derivative use subject */
/* to acknowledgment of its origin and compliance with any conditions */
/* that the originators of the algorithm place on its exploitation. */
----
Status: Public Domain, modified [not original]
DES.C
-----
Author: Unknown, Submitted by Dobes Vandermeer
@ -63,18 +50,4 @@ Author: [copied verbatim]
----
Email: demoliner@isi.ee.ethz.ch
Disclaimer: Appears to be Public Domain [not quite sure]
Status: Public Domain, modified [not original]
SERPENT.C
---------
Author: Dr. Brian Gladman
Email : gladman@seven77.demon.co.uk
Disclaimer (verbatim)
----
/* Copyright in this implementation is held by Dr B R Gladman but I */
/* hereby give permission for its free direct or derivative use subject */
/* to acknowledgment of its origin and compliance with any conditions */
/* that the originators of the algorithm place on its exploitation. */
----
Status: Public Domain, modified [not original]
Status: Public Domain, modified [not original]

View File

@ -9,7 +9,7 @@
# a build. This is easy to remedy though, for those that have problems.
# The version
VERSION=0.84
VERSION=0.85
#ch1-01-1
# Compiler and Linker Names
@ -55,9 +55,9 @@ DATAPATH=/usr/share/doc/libtomcrypt/pdf
#List of objects to compile.
OBJECTS=keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o \
bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o \
md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o serpent.o des.o \
md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o des.o \
safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o \
mpi.o prime.o twofish.o packet.o hmac.o strings.o
mpi.o prime.o twofish.o packet.o hmac.o strings.o
TESTOBJECTS=demos/test.o
HASHOBJECTS=demos/hashsum.o

View File

@ -2,16 +2,17 @@
#
#Tom St Denis
CFLAGS = /I. /Ogiyb1s /Gs /DWIN32 /W3
# note optimizations are turned off because it causes a bug in aes.c that cannot be rectified [right away]
CFLAGS = /I. /Od /G3 /DWIN32 /W3
default: library
#List of objects to compile.
OBJECTS=keyring.obj gf.obj mem.obj sprng.obj ecc.obj base64.obj dh.obj rsa.obj \
bits.obj yarrow.obj cfb.obj ofb.obj ecb.obj ctr.obj cbc.obj hash.obj tiger.obj sha1.obj \
md5.obj md4.obj md2.obj sha256.obj sha512.obj xtea.obj aes.obj serpent.obj des.obj \
md5.obj md4.obj md2.obj sha256.obj sha512.obj xtea.obj aes.obj des.obj \
safer_tab.obj safer.obj safer+.obj rc4.obj rc2.obj rc6.obj rc5.obj cast5.obj noekeon.obj \
blowfish.obj crypt.obj mpi.obj prime.obj twofish.obj packet.obj hmac.obj strings.obj
blowfish.obj crypt.obj mpi.obj prime.obj twofish.obj packet.obj hmac.obj strings.obj
library: $(OBJECTS)
lib /out:tomcrypt.lib $(OBJECTS)

View File

@ -5,11 +5,11 @@
CC = gcc
AR = ar
LD = ld
CFLAGS += -O3 -Wall -Wsign-compare -W -Wno-unused -Werror -I./
CFLAGS += -Os -Wall -Wsign-compare -W -Wno-unused -Werror -I./
default: library
OBJECTS = keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o serpent.o des.o safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o ampi.o mpi.o prime.o twofish.o packet.o hmac.o strings.o
OBJECTS = keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o des.o safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o mpi.o prime.o twofish.o packet.o hmac.o strings.o
rsa.o: rsa_sys.c
dh.o: dh_sys.c

2
md4.c
View File

@ -29,7 +29,7 @@ const struct _hash_descriptor md4_desc =
#define S34 15
/* F, G and H are basic MD4 functions. */
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define F(x, y, z) (z ^ (x & (y ^ z)))
#define G(x, y, z) ((x & y) | (z & (x | y)))
#define H(x, y, z) ((x) ^ (y) ^ (z))

2
md5.c
View File

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

12367
mpi.c

File diff suppressed because it is too large Load Diff

View File

@ -16,8 +16,8 @@ extern "C" {
#endif
/* version */
#define CRYPT 0x0084
#define SCRYPT "0.84"
#define CRYPT 0x0085
#define SCRYPT "0.85"
/* max size of either a cipher/hash block or symmetric key [largest of the two] */
#define MAXBLOCKSIZE 128

View File

@ -30,15 +30,10 @@ struct saferp_key {
};
#endif
#ifdef SERPENT
struct serpent_key {
unsigned long K[132];
};
#endif
#ifdef RIJNDAEL
struct rijndael_key {
unsigned long eK[64], dK[64], k_len;
unsigned long eK[64], dK[64];
int Nr;
};
#endif
@ -96,7 +91,7 @@ struct cast5_key {
#ifdef NOEKEON
struct noekeon_key {
unsigned long K[4], dK[4];
unsigned long K[4], dK[4];
};
#endif
@ -126,9 +121,6 @@ typedef union Symmetric_key {
#ifdef SAFERP
struct saferp_key saferp;
#endif
#ifdef SERPENT
struct serpent_key serpent;
#endif
#ifdef RIJNDAEL
struct rijndael_key rijndael;
#endif
@ -251,23 +243,14 @@ extern int safer_128_keysize(int *desired_keysize);
extern const struct _cipher_descriptor safer_k64_desc, safer_k128_desc, safer_sk64_desc, safer_sk128_desc;
#endif
#ifdef SERPENT
extern int serpent_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
extern void serpent_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
extern void serpent_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
extern int serpent_test(void);
extern int serpent_keysize(int *desired_keysize);
extern const struct _cipher_descriptor serpent_desc;
#endif
#ifdef RIJNDAEL
/* make aes an alias */
#define aes_setup rijndael_setup
#define aes_ecb_encrypt rijndael_ecb_encrypt
#define aes_ecb_decrypt rijndael_ecb_decrypt
#define aes_test rijndael_test
#define aes_keysize rijndael_keysize
#define aes_setup rijndael_setup
#define aes_ecb_encrypt rijndael_ecb_encrypt
#define aes_ecb_decrypt rijndael_ecb_decrypt
#define aes_test rijndael_test
#define aes_keysize rijndael_keysize
extern int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
extern void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
@ -363,7 +346,7 @@ extern int ctr_start(int cipher, const unsigned char *IV, const unsigned char *k
extern int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr);
extern int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr);
#endif
extern int find_cipher(const char *name);
extern int find_cipher_any(const char *name, int blocklen, int keylen);
extern int find_cipher_id(unsigned char ID);

View File

@ -1,16 +1,14 @@
/* This header is meant to be included before mycrypt.h in projects where
* you don't want to throw all the defines in a makefile.
* you don't want to throw all the defines in a makefile.
*/
#ifndef MYCRYPT_CUSTOM_H_
#define MYCRYPT_CUSTOM_H_
#ifdef CRYPT
#error mycrypt_custom.h should be included before mycrypt.h
#error mycrypt_custom.h should be included before mycrypt.h
#endif
#define LTC_TEST
#define XMALLOC malloc
#define XREALLOC realloc
#define XCALLOC calloc
@ -18,11 +16,11 @@
#define XCLOCK clock
#define XCLOCKS_PER_SEC CLOCKS_PER_SEC
#define SMALL_CODE
#define LTC_TEST
#define BLOWFISH
#define RC2
#define RC5
#define RC6
#define SERPENT
#define SAFERP
#define SAFER
#define RIJNDAEL

View File

@ -183,4 +183,3 @@ extern int hmac_file(int hash, const char *fname, const unsigned char *key,
unsigned long keylen,
unsigned char *dst, unsigned long *dstlen);
#endif

View File

@ -45,7 +45,7 @@ loop:
dist += step; x = -1;
}
}
/* recalc the total distance from where we started */
total_dist += dist;

702
serpent.c
View File

@ -1,702 +0,0 @@
#include "mycrypt.h"
#ifdef SERPENT
const struct _cipher_descriptor serpent_desc =
{
"serpent",
5,
16, 32, 16, 32,
&serpent_setup,
&serpent_ecb_encrypt,
&serpent_ecb_decrypt,
&serpent_test,
&serpent_keysize
};
/* These defines are derived from Brian Gladman's work. Contact him at gladman@seven77.demon.co.uk
*
* Available on the web at http://fp.gladman.plus.com/cryptography_technology/aes/index.htm
*/
#define sb0(a,b,c,d,e,f,g,h) \
t1 = a ^ d; \
t2 = a & d; \
t3 = c ^ t1; \
t6 = b & t1; \
t4 = b ^ t3; \
t10 = ~t3; \
h = t2 ^ t4; \
t7 = a ^ t6; \
t14 = ~t7; \
t8 = c | t7; \
t11 = t3 ^ t7; \
g = t4 ^ t8; \
t12 = h & t11; \
f = t10 ^ t12; \
e = t12 ^ t14
/* 15 terms */
#define ib0(a,b,c,d,e,f,g,h) \
t1 = ~a; \
t2 = a ^ b; \
t3 = t1 | t2; \
t4 = d ^ t3; \
t7 = d & t2; \
t5 = c ^ t4; \
t8 = t1 ^ t7; \
g = t2 ^ t5; \
t11 = a & t4; \
t9 = g & t8; \
t14 = t5 ^ t8; \
f = t4 ^ t9; \
t12 = t5 | f; \
h = t11 ^ t12; \
e = h ^ t14
/* 14 terms! */
#define sb1(a,b,c,d,e,f,g,h) \
t1 = ~a; \
t2 = b ^ t1; \
t3 = a | t2; \
t4 = d | t2; \
t5 = c ^ t3; \
g = d ^ t5; \
t7 = b ^ t4; \
t8 = t2 ^ g; \
t9 = t5 & t7; \
h = t8 ^ t9; \
t11 = t5 ^ t7; \
f = h ^ t11; \
t13 = t8 & t11; \
e = t5 ^ t13
/* 17 terms */
#define ib1(a,b,c,d,e,f,g,h) \
t1 = a ^ d; \
t2 = a & b; \
t3 = b ^ c; \
t4 = a ^ t3; \
t5 = b | d; \
t7 = c | t1; \
h = t4 ^ t5; \
t8 = b ^ t7; \
t11 = ~t2; \
t9 = t4 & t8; \
f = t1 ^ t9; \
t13 = t9 ^ t11; \
t12 = h & f; \
g = t12 ^ t13; \
t15 = a & d; \
t16 = c ^ t13; \
e = t15 ^ t16
/* 16 terms */
#define sb2(a,b,c,d,e,f,g,h) \
t1 = ~a; \
t2 = b ^ d; \
t3 = c & t1; \
t13 = d | t1; \
e = t2 ^ t3; \
t5 = c ^ t1; \
t6 = c ^ e; \
t7 = b & t6; \
t10 = e | t5; \
h = t5 ^ t7; \
t9 = d | t7; \
t11 = t9 & t10; \
t14 = t2 ^ h; \
g = a ^ t11; \
t15 = g ^ t13; \
f = t14 ^ t15
/* 16 terms */
#define ib2(a,b,c,d,e,f,g,h) \
t1 = b ^ d; \
t2 = ~t1; \
t3 = a ^ c; \
t4 = c ^ t1; \
t7 = a | t2; \
t5 = b & t4; \
t8 = d ^ t7; \
t11 = ~t4; \
e = t3 ^ t5; \
t9 = t3 | t8; \
t14 = d & t11; \
h = t1 ^ t9; \
t12 = e | h; \
f = t11 ^ t12; \
t15 = t3 ^ t12; \
g = t14 ^ t15
/* 17 terms */
#define sb3(a,b,c,d,e,f,g,h) \
t1 = a ^ c; \
t2 = d ^ t1; \
t3 = a & t2; \
t4 = d ^ t3; \
t5 = b & t4; \
g = t2 ^ t5; \
t7 = a | g; \
t8 = b | d; \
t11 = a | d; \
t9 = t4 & t7; \
f = t8 ^ t9; \
t12 = b ^ t11; \
t13 = g ^ t9; \
t15 = t3 ^ t8; \
h = t12 ^ t13; \
t16 = c & t15; \
e = t12 ^ t16
/* 16 term solution that performs less well than 17 term one
in my environment (PPro/PII)
#define sb3(a,b,c,d,e,f,g,h) \
t1 = a ^ b; \
t2 = a & c; \
t3 = a | d; \
t4 = c ^ d; \
t5 = t1 & t3; \
t6 = t2 | t5; \
g = t4 ^ t6; \
t8 = b ^ t3; \
t9 = t6 ^ t8; \
t10 = t4 & t9; \
e = t1 ^ t10; \
t12 = g & e; \
f = t9 ^ t12; \
t14 = b | d; \
t15 = t4 ^ t12; \
h = t14 ^ t15
*/
/* 17 terms */
#define ib3(a,b,c,d,e,f,g,h) \
t1 = b ^ c; \
t2 = b | c; \
t3 = a ^ c; \
t7 = a ^ d; \
t4 = t2 ^ t3; \
t5 = d | t4; \
t9 = t2 ^ t7; \
e = t1 ^ t5; \
t8 = t1 | t5; \
t11 = a & t4; \
g = t8 ^ t9; \
t12 = e | t9; \
f = t11 ^ t12; \
t14 = a & g; \
t15 = t2 ^ t14; \
t16 = e & t15; \
h = t4 ^ t16
/* 15 terms */
#define sb4(a,b,c,d,e,f,g,h) \
t1 = a ^ d; \
t2 = d & t1; \
t3 = c ^ t2; \
t4 = b | t3; \
h = t1 ^ t4; \
t6 = ~b; \
t7 = t1 | t6; \
e = t3 ^ t7; \
t9 = a & e; \
t10 = t1 ^ t6; \
t11 = t4 & t10; \
g = t9 ^ t11; \
t13 = a ^ t3; \
t14 = t10 & g; \
f = t13 ^ t14
/* 17 terms */
#define ib4(a,b,c,d,e,f,g,h) \
t1 = c ^ d; \
t2 = c | d; \
t3 = b ^ t2; \
t4 = a & t3; \
f = t1 ^ t4; \
t6 = a ^ d; \
t7 = b | d; \
t8 = t6 & t7; \
h = t3 ^ t8; \
t10 = ~a; \
t11 = c ^ h; \
t12 = t10 | t11;\
e = t3 ^ t12; \
t14 = c | t4; \
t15 = t7 ^ t14; \
t16 = h | t10; \
g = t15 ^ t16
/* 16 terms */
#define sb5(a,b,c,d,e,f,g,h) \
t1 = ~a; \
t2 = a ^ b; \
t3 = a ^ d; \
t4 = c ^ t1; \
t5 = t2 | t3; \
e = t4 ^ t5; \
t7 = d & e; \
t8 = t2 ^ e; \
t10 = t1 | e; \
f = t7 ^ t8; \
t11 = t2 | t7; \
t12 = t3 ^ t10; \
t14 = b ^ t7; \
g = t11 ^ t12; \
t15 = f & t12; \
h = t14 ^ t15
/* 16 terms */
#define ib5(a,b,c,d,e,f,g,h) \
t1 = ~c; \
t2 = b & t1; \
t3 = d ^ t2; \
t4 = a & t3; \
t5 = b ^ t1; \
h = t4 ^ t5; \
t7 = b | h; \
t8 = a & t7; \
f = t3 ^ t8; \
t10 = a | d; \
t11 = t1 ^ t7; \
e = t10 ^ t11; \
t13 = a ^ c; \
t14 = b & t10; \
t15 = t4 | t13; \
g = t14 ^ t15
/* 15 terms */
#define sb6(a,b,c,d,e,f,g,h) \
t1 = ~a; \
t2 = a ^ d; \
t3 = b ^ t2; \
t4 = t1 | t2; \
t5 = c ^ t4; \
f = b ^ t5; \
t13 = ~t5; \
t7 = t2 | f; \
t8 = d ^ t7; \
t9 = t5 & t8; \
g = t3 ^ t9; \
t11 = t5 ^ t8; \
e = g ^ t11; \
t14 = t3 & t11; \
h = t13 ^ t14
/* 15 terms */
#define ib6(a,b,c,d,e,f,g,h) \
t1 = ~a; \
t2 = a ^ b; \
t3 = c ^ t2; \
t4 = c | t1; \
t5 = d ^ t4; \
t13 = d & t1; \
f = t3 ^ t5; \
t7 = t3 & t5; \
t8 = t2 ^ t7; \
t9 = b | t8; \
h = t5 ^ t9; \
t11 = b | h; \
e = t8 ^ t11; \
t14 = t3 ^ t11; \
g = t13 ^ t14
/* 17 terms */
#define sb7(a,b,c,d,e,f,g,h) \
t1 = ~c; \
t2 = b ^ c; \
t3 = b | t1; \
t4 = d ^ t3; \
t5 = a & t4; \
t7 = a ^ d; \
h = t2 ^ t5; \
t8 = b ^ t5; \
t9 = t2 | t8; \
t11 = d & t3; \
f = t7 ^ t9; \
t12 = t5 ^ f; \
t15 = t1 | t4; \
t13 = h & t12; \
g = t11 ^ t13; \
t16 = t12 ^ g; \
e = t15 ^ t16
/* 17 terms */
#define ib7(a,b,c,d,e,f,g,h) \
t1 = a & b; \
t2 = a | b; \
t3 = c | t1; \
t4 = d & t2; \
h = t3 ^ t4; \
t6 = ~d; \
t7 = b ^ t4; \
t8 = h ^ t6; \
t11 = c ^ t7; \
t9 = t7 | t8; \
f = a ^ t9; \
t12 = d | f; \
e = t11 ^ t12; \
t14 = a & h; \
t15 = t3 ^ f; \
t16 = e ^ t14; \
g = t15 ^ t16
#define k_xor(r,a,b,c,d) \
a ^= skey->serpent.K[4 * (r) + 0]; \
b ^= skey->serpent.K[4 * (r) + 1]; \
c ^= skey->serpent.K[4 * (r) + 2]; \
d ^= skey->serpent.K[4 * (r) + 3]
#define k_set(r,a,b,c,d) \
a = lkey[4 * (r) + 8]; \
b = lkey[4 * (r) + 9]; \
c = lkey[4 * (r) + 10]; \
d = lkey[4 * (r) + 11]
#define k_get(r,a,b,c,d) \
skey->serpent.K[4 * (r) + 0] = a; \
skey->serpent.K[4 * (r) + 1] = b; \
skey->serpent.K[4 * (r) + 2] = c; \
skey->serpent.K[4 * (r) + 3] = d
/* the linear transformation and its inverse */
#define rot(a,b,c,d) \
a = ROL(a, 13); \
c = ROL(c, 3); \
d ^= c ^ (a << 3); \
b ^= a ^ c; \
d = ROL(d, 7); \
b = ROL(b, 1); \
a ^= b ^ d; \
c ^= d ^ (b << 7); \
a = ROL(a, 5); \
c = ROL(c, 22)
#define irot(a,b,c,d) \
c = ROR(c, 22); \
a = ROR(a, 5); \
c ^= d ^ (b << 7); \
a ^= b ^ d; \
d = ROR(d, 7); \
b = ROR(b, 1); \
d ^= c ^ (a << 3); \
b ^= a ^ c; \
c = ROR(c, 3); \
a = ROR(a, 13)
#ifdef CLEAN_STACK
static int _serpent_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
#else
int serpent_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
#endif
{
unsigned long lkey[140], t, a, b, c, d, e, f, g, h, x;
unsigned long t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16;
unsigned char buf[32];
_ARGCHK(key != NULL);
_ARGCHK(skey != NULL);
/* check rounds */
if (num_rounds != 0 && num_rounds != 32) {
return CRYPT_INVALID_ROUNDS;
}
/* check keylen */
if (keylen < 16 || keylen > 32) {
return CRYPT_INVALID_KEYSIZE;
}
/* copy key and expand to 32bytes as required */
for (x = 0; x < (unsigned long)keylen; x++) {
buf[x] = key[x];
}
if (x < 32) {
buf[x++] = (unsigned char)0x01;
while (x < 32) {
buf[x++] = (unsigned char)0;
}
}
/* copy key into 32-bit words */
for (x = 0; x < 8; x++) {
LOAD32L(lkey[x], &buf[x*4]);
}
/* expand using the LFSR to 140 words */
for (x = 0; x < 132; x++) {
t = lkey[x] ^ lkey[x+3] ^ lkey[x+5] ^ lkey[x+7] ^ x ^ 0x9E3779B9UL;
lkey[x + 8] = ROL(t, 11);
}
/* perform the substituions */
for (x = 0; x < 32; ) {
k_set( x,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x;
k_set( x,a,b,c,d);sb2(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x;
k_set( x,a,b,c,d);sb1(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x;
k_set( x,a,b,c,d);sb0(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x;
k_set( x,a,b,c,d);sb7(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x;
k_set( x,a,b,c,d);sb6(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x;
k_set( x,a,b,c,d);sb5(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x;
k_set( x,a,b,c,d);sb4(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x;
}
k_set(32,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get(32,e,f,g,h);
return CRYPT_OK;
}
#ifdef CLEAN_STACK
int serpent_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
int x;
x = _serpent_setup(key, keylen, num_rounds, skey);
burn_stack(sizeof(unsigned long)*166 + sizeof(unsigned char)*32);
return x;
}
#endif
#ifdef CLEAN_STACK
static void _serpent_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else
void serpent_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif
{
unsigned long a,b,c,d,e,f,g,h;
unsigned long t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16;
_ARGCHK(pt != NULL);
_ARGCHK(ct != NULL);
_ARGCHK(skey != NULL);
LOAD32L(a, &pt[0]);LOAD32L(b, &pt[4]);LOAD32L(c, &pt[8]);LOAD32L(d, &pt[12]);
k_xor( 0,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor( 1,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor( 2,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor( 3,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor( 4,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor( 5,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor( 6,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor( 7,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor( 8,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor( 9,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(10,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(11,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(12,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(13,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(14,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(15,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(16,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(17,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(18,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(19,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(20,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(21,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(22,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(23,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(24,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(25,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(26,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(27,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(28,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(29,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(30,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(31,e,f,g,h); sb7(e,f,g,h,a,b,c,d); k_xor(32,a,b,c,d);
STORE32L(a, &ct[0]);STORE32L(b, &ct[4]);STORE32L(c, &ct[8]);STORE32L(d, &ct[12]);
}
#ifdef CLEAN_STACK
void serpent_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
_serpent_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(unsigned long)*24);
}
#endif
#ifdef CLEAN_STACK
static void _serpent_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else
void serpent_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif
{
unsigned long a,b,c,d,e,f,g,h;
unsigned long t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16;
_ARGCHK(pt != NULL);
_ARGCHK(ct != NULL);
_ARGCHK(skey != NULL);
LOAD32L(a, &ct[0]);LOAD32L(b, &ct[4]);LOAD32L(c, &ct[8]);LOAD32L(d, &ct[12]);
k_xor(32,a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(31,e,f,g,h);
irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(30,a,b,c,d);
irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(29,e,f,g,h);
irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(28,a,b,c,d);
irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(27,e,f,g,h);
irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(26,a,b,c,d);
irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor(25,e,f,g,h);
irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor(24,a,b,c,d);
irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(23,e,f,g,h);
irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(22,a,b,c,d);
irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(21,e,f,g,h);
irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(20,a,b,c,d);
irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(19,e,f,g,h);
irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(18,a,b,c,d);
irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor(17,e,f,g,h);
irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor(16,a,b,c,d);
irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(15,e,f,g,h);
irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(14,a,b,c,d);
irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(13,e,f,g,h);
irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(12,a,b,c,d);
irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(11,e,f,g,h);
irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(10,a,b,c,d);
irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor( 9,e,f,g,h);
irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor( 8,a,b,c,d);
irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor( 7,e,f,g,h);
irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor( 6,a,b,c,d);
irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor( 5,e,f,g,h);
irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor( 4,a,b,c,d);
irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor( 3,e,f,g,h);
irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor( 2,a,b,c,d);
irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor( 1,e,f,g,h);
irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor( 0,a,b,c,d);
STORE32L(a, &pt[0]);STORE32L(b, &pt[4]);STORE32L(c, &pt[8]);STORE32L(d, &pt[12]);
}
#ifdef CLEAN_STACK
void serpent_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
_serpent_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(unsigned long)*24);
}
#endif
int serpent_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
int keylen;
unsigned char key[32], pt[16], ct[16];
} tests[] = {
{
16,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xdd, 0xd2, 0x6b, 0x98, 0xa5, 0xff, 0xd8, 0x2c,
0x05, 0x34, 0x5a, 0x9d, 0xad, 0xbf, 0xaf, 0x49 }
},
{
16,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 },
{ 0x4a, 0xe9, 0xa2, 0x0b, 0x2b, 0x14, 0xa1, 0x02,
0x90, 0xcb, 0xb8, 0x20, 0xb7, 0xff, 0xb5, 0x10 }
},
{
24,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08 },
{ 0xe1, 0x1b, 0x01, 0x52, 0x4e, 0xa1, 0xf4, 0x65,
0xa2, 0xa2, 0x00, 0x43, 0xeb, 0x9f, 0x7e, 0x8a }
},
{
32,
{ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xe0, 0x88, 0x5d, 0x44, 0x60, 0x37, 0x34, 0x69,
0xd1, 0xfa, 0x6c, 0x36, 0xa6, 0xe1, 0xc5, 0x2f }
},
{
32,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x17, 0xc6, 0x25, 0x8e, 0x60, 0x09, 0xe2, 0x82,
0x66, 0x18, 0x69, 0xd5, 0x25, 0xf7, 0xd2, 0x04 }
},
{
32,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x9f, 0xe1, 0x43, 0x25, 0x0d, 0x00, 0xe2, 0x56,
0x96, 0xb0, 0x1e, 0x0a, 0x2e, 0xd0, 0x5d, 0xb3 }
}
};
unsigned char buf[2][16];
int x, err;
symmetric_key key;
for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
/* setup key */
if ((err = serpent_setup(tests[x].key, tests[x].keylen, 0, &key))!= CRYPT_OK) {
return err;
}
/* encrypt and decrypt */
serpent_ecb_encrypt(tests[x].pt, buf[0], &key);
serpent_ecb_decrypt(buf[0], buf[1], &key);
/* compare */
if (memcmp(buf[0], tests[x].ct, 16) != 0 || memcmp(buf[1], tests[x].pt, 16) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
int serpent_keysize(int *desired_keysize)
{
_ARGCHK(desired_keysize != NULL);
if (*desired_keysize < 16)
return CRYPT_INVALID_KEYSIZE;
if (*desired_keysize > 32)
*desired_keysize = 32;
return CRYPT_OK;
}
#endif

2
sha1.c
View File

@ -14,7 +14,7 @@ const struct _hash_descriptor sha1_desc =
&sha1_test
};
#define F0(x,y,z) ( (x&y) | ((~x)&z) )
#define F0(x,y,z) (z ^ (x & (y ^ z)))
#define F1(x,y,z) (x ^ y ^ z)
#define F2(x,y,z) ((x & y) | (z & (x | y)))
#define F3(x,y,z) (x ^ y ^ z)

View File

@ -32,7 +32,7 @@ static const unsigned long K[64] = {
};
/* Various logical functions */
#define Ch(x,y,z) ((x & y) | (~x & z))
#define Ch(x,y,z) (z ^ (x & (y ^ z)))
#define Maj(x,y,z) (((x | y) & z) | (x & y))
#define S(x, n) ROR((x),(n))
#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))

View File

@ -59,7 +59,7 @@ CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817)
};
/* Various logical functions */
#define Ch(x,y,z) ((x & y) | (~x & z))
#define Ch(x,y,z) (z ^ (x & (y ^ z)))
#define Maj(x,y,z) (((x | y) & z) | (x & y))
#define S(x, n) ROR64((x),(n))
#define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n))

BIN
tdcal.pdf Normal file

Binary file not shown.

View File

@ -397,9 +397,9 @@ static unsigned long g_func(unsigned long x, symmetric_key *key)
burn_stack(sizeof(unsigned char) * 4 + sizeof(unsigned long));
return y;
}
#endif
#endif /* CLEAN_STACK */
#endif
#endif /* TWOFISH_SMALL */
#ifdef CLEAN_STACK
static int _twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)

View File

@ -28,8 +28,6 @@ int yarrow_start(prng_state *prng)
prng->yarrow.cipher = register_cipher(&twofish_desc);
#elif defined(CAST5)
prng->yarrow.cipher = register_cipher(&cast5_desc);
#elif defined(SERPENT)
prng->yarrow.cipher = register_cipher(&serpent_desc);
#elif defined(SAFER)
prng->yarrow.cipher = register_cipher(&saferp_desc);
#elif defined(RC5)