[BACK]Return to cast5.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / ox_ntl / crypt / cast5

File: [local] / OpenXM / src / ox_ntl / crypt / cast5 / cast5.c (download)

Revision 1.2, Mon Sep 20 00:10:24 2004 UTC (19 years, 9 months ago) by iwane
Branch: MAIN
CVS Tags: R_1_3_1-2, RELEASE_1_3_1_13b, RELEASE_1_2_3_12, RELEASE_1_2_3, KNOPPIX_2006, HEAD, DEB_REL_1_2_3-9
Changes since 1.1: +1 -3 lines

include <inttypes.h>

/* $OpenXM: OpenXM/src/ox_ntl/crypt/cast5/cast5.c,v 1.2 2004/09/20 00:10:24 iwane Exp $ */
/*
 * rfc 2144
 *  The CAST-128 Encryption Algorithm
 */

#include "cast5.h"
#include "cast5tbl.h"


#if HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */

#define leftrot32(x, n)      ((((uint32_t)x) << n) | ((uint32_t)x) >> (32 - n))

#ifdef WORDS_BIGENDIAN
#define ARY(x, i)  (((unsigned char *)(x))[i])
#else
#define ARY(x, i)  (((unsigned char *)(x))[(int)("\x03\x02\x01\x00\x07\x06\x05\x04\x0b\x0a\x09\x08\x0f\x0e\x0d\x0c"[i])])
#endif


/*
#define ARY(x, i)  (((unsigned char *)(x))[((((i) / 4) * 4) + (3 - (i) % 4))])
 * compute: 7.473
 *         15.100
 *         11.805
 *
#define ARY(x, i)  (((unsigned char *)(x))[(int)("\x03\x02\x01\x00\x07\x06\x05\x04\x0b\x0a\x09\x08\x0f\x0e\x0d\x0c"[i])])
 * char array: 7.044
 *            14.124
 *            11.366
 *
static const int _ar[] = {3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12};
#define ARY(x, i)  (((unsigned char *)(x))[_ar[i]])
 * int array: 8.679
 *           17.233
 *           12.705
 */



/*
 * length of key is 16 byte = 128 bit.
 */
void
cast128_keyset(const unsigned char *key, int len, cast128_key *ckey)
{
#define X(i) (ARY(&x, i))
#define Z(i) (ARY(&z, i))
	uint32_t x[4], z[4];
	int i;
	uint32_t K[32], *k;

	if (len > 16)
		len = 16;
	for (i = 0; i < len; i++) {
		X(i) = key[i];
	}

	for (; i < (int)sizeof(x); i++) {
		X(i) = 0;
	}

	k = K;

	for (i = 0; i < 2; i++) {
#define s5 __cast128_tbl_s5
#define s6 __cast128_tbl_s6
#define s7 __cast128_tbl_s7
#define s8 __cast128_tbl_s8
		z[0] = x[0] ^ s5[X(0xD)] ^ s6[X(0xF)] ^ s7[X(0xC)] ^ s8[X(0xE)] ^ s7[X(0x8)];
		z[1] = x[2] ^ s5[Z(0x0)] ^ s6[Z(0x2)] ^ s7[Z(0x1)] ^ s8[Z(0x3)] ^ s8[X(0xA)];
		z[2] = x[3] ^ s5[Z(0x7)] ^ s6[Z(0x6)] ^ s7[Z(0x5)] ^ s8[Z(0x4)] ^ s5[X(0x9)];
		z[3] = x[1] ^ s5[Z(0xA)] ^ s6[Z(0x9)] ^ s7[Z(0xB)] ^ s8[Z(0x8)] ^ s6[X(0xB)];

		k[ 0] = s5[Z(0x8)] ^ s6[Z(0x9)] ^ s7[Z(0x7)] ^ s8[Z(0x6)] ^ s5[Z(0x2)];
		k[ 1] = s5[Z(0xA)] ^ s6[Z(0xB)] ^ s7[Z(0x5)] ^ s8[Z(0x4)] ^ s6[Z(0x6)];
		k[ 2] = s5[Z(0xC)] ^ s6[Z(0xD)] ^ s7[Z(0x3)] ^ s8[Z(0x2)] ^ s7[Z(0x9)];
		k[ 3] = s5[Z(0xE)] ^ s6[Z(0xF)] ^ s7[Z(0x1)] ^ s8[Z(0x0)] ^ s8[Z(0xC)];
	
		x[0] = z[2] ^ s5[Z(0x5)] ^ s6[Z(0x7)] ^ s7[Z(0x4)] ^ s8[Z(0x6)] ^ s7[Z(0x0)];
		x[1] = z[0] ^ s5[X(0x0)] ^ s6[X(0x2)] ^ s7[X(0x1)] ^ s8[X(0x3)] ^ s8[Z(0x2)];
		x[2] = z[1] ^ s5[X(0x7)] ^ s6[X(0x6)] ^ s7[X(0x5)] ^ s8[X(0x4)] ^ s5[Z(0x1)];
		x[3] = z[3] ^ s5[X(0xA)] ^ s6[X(0x9)] ^ s7[X(0xB)] ^ s8[X(0x8)] ^ s6[Z(0x3)];
	
		k[ 4] = s5[X(0x3)] ^ s6[X(0x2)] ^ s7[X(0xC)] ^ s8[X(0xD)] ^ s5[X(0x8)];
		k[ 5] = s5[X(0x1)] ^ s6[X(0x0)] ^ s7[X(0xE)] ^ s8[X(0xF)] ^ s6[X(0xD)];
		k[ 6] = s5[X(0x7)] ^ s6[X(0x6)] ^ s7[X(0x8)] ^ s8[X(0x9)] ^ s7[X(0x3)];
		k[ 7] = s5[X(0x5)] ^ s6[X(0x4)] ^ s7[X(0xA)] ^ s8[X(0xB)] ^ s8[X(0x7)];
	
		z[0] = x[0] ^ s5[X(0xD)] ^ s6[X(0xF)] ^ s7[X(0xC)] ^ s8[X(0xE)] ^ s7[X(0x8)];
		z[1] = x[2] ^ s5[Z(0x0)] ^ s6[Z(0x2)] ^ s7[Z(0x1)] ^ s8[Z(0x3)] ^ s8[X(0xA)];
		z[2] = x[3] ^ s5[Z(0x7)] ^ s6[Z(0x6)] ^ s7[Z(0x5)] ^ s8[Z(0x4)] ^ s5[X(0x9)];
		z[3] = x[1] ^ s5[Z(0xA)] ^ s6[Z(0x9)] ^ s7[Z(0xB)] ^ s8[Z(0x8)] ^ s6[X(0xB)];
	
		k[ 8] = s5[Z(0x3)] ^ s6[Z(0x2)] ^ s7[Z(0xC)] ^ s8[Z(0xD)] ^ s5[Z(0x9)];
		k[ 9] = s5[Z(0x1)] ^ s6[Z(0x0)] ^ s7[Z(0xE)] ^ s8[Z(0xF)] ^ s6[Z(0xC)];
		k[10] = s5[Z(0x7)] ^ s6[Z(0x6)] ^ s7[Z(0x8)] ^ s8[Z(0x9)] ^ s7[Z(0x2)];
		k[11] = s5[Z(0x5)] ^ s6[Z(0x4)] ^ s7[Z(0xA)] ^ s8[Z(0xB)] ^ s8[Z(0x6)];
	
		x[0] = z[2] ^ s5[Z(0x5)] ^ s6[Z(0x7)] ^ s7[Z(0x4)] ^ s8[Z(0x6)] ^ s7[Z(0x0)];
		x[1] = z[0] ^ s5[X(0x0)] ^ s6[X(0x2)] ^ s7[X(0x1)] ^ s8[X(0x3)] ^ s8[Z(0x2)];
		x[2] = z[1] ^ s5[X(0x7)] ^ s6[X(0x6)] ^ s7[X(0x5)] ^ s8[X(0x4)] ^ s5[Z(0x1)];
		x[3] = z[3] ^ s5[X(0xA)] ^ s6[X(0x9)] ^ s7[X(0xB)] ^ s8[X(0x8)] ^ s6[Z(0x3)];
	
		k[12] = s5[X(0x8)] ^ s6[X(0x9)] ^ s7[X(0x7)] ^ s8[X(0x6)] ^ s5[X(0x3)];
		k[13] = s5[X(0xA)] ^ s6[X(0xB)] ^ s7[X(0x5)] ^ s8[X(0x4)] ^ s6[X(0x7)];
		k[14] = s5[X(0xC)] ^ s6[X(0xD)] ^ s7[X(0x3)] ^ s8[X(0x2)] ^ s7[X(0x8)];
		k[15] = s5[X(0xE)] ^ s6[X(0xF)] ^ s7[X(0x1)] ^ s8[X(0x0)] ^ s8[X(0xD)];
	
#undef s5
#undef s6
#undef s7
#undef s8
		k += 16;
	}

	for (i = 0; i < 16; i++) {
		ckey->km[i] = K[i];
		ckey->kr[i] = K[i + 16] & 0x1f;
	}
	ckey->len = len;
	if (len <= 10) /* < 80 bit */
		ckey->loop = 12;
	else
		ckey->loop = 16;

#undef X
#undef Z

}


#define I(i) (ARY(&j, i))

#define _CAST_TYPE(FUNC, OP1, OP2, OP3) \
static inline uint32_t                                                       \
FUNC(uint32_t d, uint32_t km, uint32_t kr)                                   \
{                                                                            \
	uint32_t j = leftrot32(km OP3 d, kr);                                   \
	return (((__cast128_tbl_s1[I(0)] OP1 __cast128_tbl_s2[I(1)]) OP2 __cast128_tbl_s3[I(2)]) OP3 __cast128_tbl_s4[I(3)]);        \
}

_CAST_TYPE(_type1, ^, -, +)
_CAST_TYPE(_type2, -, +, ^)
_CAST_TYPE(_type3, +, ^, -)

#undef I


void
cast128_enc_i(cast128_key *key,
    uint32_t ml, uint32_t mr, 
    uint32_t *el, uint32_t *er)
{
	int i;

	uint32_t l;
	uint32_t (*f[3])(uint32_t, uint32_t, uint32_t) = {_type1, _type2, _type3};

	for (i = 0; i < key->loop; i++) {
		l = mr;
		mr = ml ^ f[i % 3](mr, key->km[i], key->kr[i]);
		ml = l;
	}

	*er = ml;
	*el = mr;
}



void
cast128_enc_c(cast128_key *key,
    const unsigned char *msg, unsigned char *enc)
{
	uint32_t m[2], e[2];
	int i;

	for (i = 0; i < 8; i++) {
		ARY(m, i) = msg[i];
	}

	cast128_enc_i(key, m[0], m[1], &e[0], &e[1]);

	for (i = 0; i < 8; i++) {
		enc[i] = ARY(e, i);
	}
}



void
cast128_dec_i(cast128_key *key,
    uint32_t ml, uint32_t mr, 
    uint32_t *el, uint32_t *er)
{
	int i;

	uint32_t l;
	uint32_t (*f[3])(uint32_t, uint32_t, uint32_t) = {_type1, _type2, _type3};

	for (i = key->loop - 1; i >= 0; i--) {
		l = mr;
		mr = ml ^ f[i % 3](mr, key->km[i], key->kr[i]);
		ml = l;
	}

	*er = ml;
	*el = mr;
}


void
cast128_dec_c(cast128_key *key,
    const unsigned char *msg, unsigned char *enc)
{
	uint32_t m[2], e[2];
	int i;

	for (i = 0; i < 8; i++) {
		ARY(m, i) = msg[i];
	}

	cast128_dec_i(key, m[0], m[1], &e[0], &e[1]);

	for (i = 0; i < 8; i++) {
		enc[i] = ARY(e, i);
	}
}