⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aestable.c

📁 AES加密算法 2000年10月
💻 C
📖 第 1 页 / 共 2 页
字号:
void Encrypt (uchar *in, uchar *expkey, uchar *out)
{
unsigned round, idx, j;
uchar state[Nb * 4];

	for( idx = 0; idx < Nb; idx++ ) {
		state[4*idx+0] = *in++;
		state[4*idx+1] = *in++;
		state[4*idx+2] = *in++;
		state[4*idx+3] = *in++;
	}

	AddRoundKey ((unsigned *)state, (unsigned *)expkey);

	for( round = 1; round < Nr + 1; round++ ) {
		if( round < Nr )
			MixSubColumns (state);
		else
			ShiftRows (state);

		AddRoundKey ((unsigned *)state, (unsigned *)expkey + round * Nb);
	}

	for( idx = 0; idx < Nb; idx++ ) {
		*out++ = state[4*idx+0];
		*out++ = state[4*idx+1];
		*out++ = state[4*idx+2];
		*out++ = state[4*idx+3];
	}
}

void Decrypt (uchar *in, uchar *expkey, uchar *out)
{
unsigned idx, round, j;
uchar state[Nb * 4];

	for( idx = 0; idx < Nb; idx++ ) {
		state[4*idx+0] = *in++;
		state[4*idx+1] = *in++;
		state[4*idx+2] = *in++;
		state[4*idx+3] = *in++;
	}

	AddRoundKey ((unsigned *)state, (unsigned *)expkey + Nr * Nb);
	round = Nr;

	InvShiftRows(state);

	while( round-- )
	{
		AddRoundKey ((unsigned *)state, (unsigned *)expkey + round * Nb);
		if( round )
			InvMixSubColumns (state);
	} 

	for( idx = 0; idx < Nb; idx++ ) {
		*out++ = state[4*idx+0];
		*out++ = state[4*idx+1];
		*out++ = state[4*idx+2];
		*out++ = state[4*idx+3];
	}
}

#include <stdio.h>
#include <fcntl.h>
extern int _setmode (int, int);

uchar in[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};

uchar key[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};

uchar out[16];

#ifndef unix
void rd_clock (__int64 *ans)
{
unsigned dwLow, dwHigh;

	__asm {
		rdtsc
		mov dwLow, eax
		mov dwHigh, edx
	}
	*ans = (__int64)dwHigh << 32 | (__int64)dwLow;
}
#else
typedef long long __int64;

void rd_clock (__int64 *ans)
{
unsigned long long dwBoth;

	__asm__ volatile(".byte 0x0f, 0x31" : "=A"(dwBoth)); 
	*ans = dwBoth;
}
#endif

void certify ()
{
uchar expkey[4 * Nb * (Nr + 1)];
unsigned idx, diff;
__int64 start, stop;

	ExpandKey (key, expkey);
	Encrypt (in, expkey, out);

	rd_clock(&start);

	Encrypt (in, expkey, out);

	rd_clock(&stop);
	diff = stop - start;
	printf ("encrypt time: %d, %d cycles per byte\n", diff, diff/16);

	for( idx = 0; idx < 16; idx++ )
		printf ("%.2x ", out[idx]);

	printf ("\n");
	Decrypt (out, expkey, in);
	rd_clock(&start);
	Decrypt (out, expkey, in);

	rd_clock(&stop);
	diff = stop - start;
	printf ("decrypt time: %d, %d cycles per byte\n", diff, diff/16);

	for( idx = 0; idx < 16; idx++ )
		printf ("%.2x ", in[idx]);

	printf ("\n");
}

void decrypt (char *mykey, char *name)
{
uchar expkey[4 * Nb * (Nr + 1)];
FILE *fd = fopen (name, "rb");
int ch, idx = 0;

	strncpy (key, mykey, sizeof(key));
	ExpandKey (key, expkey);

	while( ch = getc(fd), ch != EOF ) {
		in[idx++] = ch;
		if( idx % 16 )
			continue;

		Decrypt (in, expkey, out);

		for( idx = 0; idx < 16; idx++ )
			putchar (out[idx]);
		idx = 0;
	}
}

void encrypt (char *mykey, char *name)
{
uchar expkey[4 * Nb * (Nr + 1)];
FILE *fd = fopen (name, "rb");
int ch, idx = 0;

	strncpy (key, mykey, sizeof(key));
	ExpandKey (key, expkey);

	while( ch = getc(fd), ch != EOF ) {
		in[idx++] = ch;
		if( idx % 16 )
			continue;

		Encrypt (in, expkey, out);

		for( idx = 0; idx < 16; idx++ )
			putchar (out[idx]);
		idx = 0;
	}

	if( idx )
	  while( idx % 16 )
		in[idx++] = 0;
	else
	  return;

	Encrypt (in, expkey, out);

	for( idx = 0; idx < 16; idx++ )
		putchar (out[idx]);
}

uchar expkey[4 * Nb * (Nr + 1)];
void mrandom (int, char *);
unsigned xrandom (void);

int aescycles ()
{
__int64 start, end;
int t;

	do {
		rd_clock(&start);
		Encrypt (in, expkey, out);
		rd_clock (&end);
		t = end - start;
	} while( t<= 0 || t>= 4000);
	return t;
}

int bestx (int b, int loops)
{
int bestx = 0, bestxt = 0;
int x, xt, i, j;

	for( x = 0; x < 256; x++ ) {
		xt = 0;
		for( i = 0; i < loops; i++ ) {
			for( j = 0; j < 16; j++ )
				in[j] = xrandom() >> 16;
			in[b] = x;
			xt += aescycles(); xt += aescycles(); xt += aescycles();
			xt += aescycles(); xt += aescycles();
		}
		if( xt > bestxt )
			bestx = x, bestxt = xt;
	}
	return bestx;
}

void bernstein (char *seed)
{
int loops, b, j, k;

	mrandom (strlen(seed), seed);

	for( loops = 4; loops <= 65536; loops *= 16) {
		for( b = 0; b < 16; b++ ) {
			printf ("%.2d, %.5d loops:", b, loops);
			for( k = 0; k < 10; k++ ) {
				for( j = 0; j < 16; j++ )
					key[j] = xrandom() >> 16;
				ExpandKey (key, expkey);
				printf (" %.2x", bestx (b, loops) ^ key[b]);
				fflush (stdout);
			}
			printf ("\n");
		}
	}
}

void tables()
{
int i;

	for( i = 0; i < 256; i++)
	{
		printf("0x%.2x, ", Sbox[i] ^ Xtime2[Sbox[i]]);
		if( !((i+1) % 16) )
			printf("\n");
	}

	printf("\n");

	for( i = 0; i < 256; i++)
	{
		printf("0x%.2x, ", Xtime2[Sbox[i]]);
		if ( !((i+1) % 16) )
			printf("\n");
	}
}

int main (int argc, char *argv[])
{
#ifndef unix
	_setmode (_fileno(stdout), _O_BINARY);
#endif

	switch( argv[1][0] ) {
	case 'c': certify(); break;
	case 'e': encrypt(argv[2], argv[3]); break;
	case 'd': decrypt(argv[2], argv[3]); break;
	case 'b': bernstein(argv[2]);	break;
	case 't': tables(); break;
	}
}

/*
 * The package generates far better random numbers than a linear
 * congruential generator.  The random number generation technique
 * is a linear feedback shift register approach.  In this approach,
 * the least significant bit of all the numbers in the RandTbl table
 * will act as a linear feedback shift register, and will have period
 * of approximately 2^96 - 1.
 *
 */

#define RAND_order (7 * sizeof(unsigned))
#define RAND_size (96 * sizeof(unsigned))

uchar RandTbl[RAND_size + RAND_order];
int RandHead = 0;

/*
 * random: 	x**96 + x**7 + x**6 + x**4 + x**3 + x**2 + 1
 *
 * The basic operation is to add to the number at the head index
 * the XOR sum of the lower order terms in the polynomial.
 * Then the index is advanced to the next location cyclically
 * in the table.  The value returned is the sum generated.
 *
 */

unsigned xrandom ()
{
register unsigned fact;

	if( (RandHead -= sizeof(unsigned)) < 0 ) {
		RandHead = RAND_size - sizeof(unsigned);
		memcpy (RandTbl + RAND_size, RandTbl, RAND_order);
	}

	fact = *(unsigned *)(RandTbl + RandHead + 7 * sizeof(unsigned));
	fact ^= *(unsigned *)(RandTbl + RandHead + 6 * sizeof(unsigned));
	fact ^= *(unsigned *)(RandTbl + RandHead + 4 * sizeof(unsigned));
	fact ^= *(unsigned *)(RandTbl + RandHead + 3 * sizeof(unsigned));
	fact ^= *(unsigned *)(RandTbl + RandHead + 2 * sizeof(unsigned));
	return *(unsigned *)(RandTbl + RandHead) += fact;
}

/*
 * mrandom:
 * 		Initialize the random number generator based on the given seed.
 *
 */

void mrandom (int len, char *ptr)
{
unsigned short rand = *ptr;
int idx, bit = len * 4;

	memset (RandTbl, 0, sizeof(RandTbl));
	RandHead = 0;

	while( rand *= 20077, rand += 11, bit-- )
		if( ptr[bit >> 2] & (1 << (bit & 3)) )
			for (idx = 0; idx < 5; idx++) {
				rand *= 20077, rand += 11;
				RandTbl[rand % 96 << 2] ^= 1;
			}

	for( idx = 0; idx < 96 * 63; idx++ )
		xrandom ();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -