[svn] / ecrypt / trunk / submissions / polarbear / polar-bear.c  

svn: ecrypt/trunk/submissions/polarbear/polar-bear.c

File: [svn] / ecrypt / trunk / submissions / polarbear / polar-bear.c (download) (as text)
Revision: 54, Tue Aug 9 15:49:55 2005 UTC (7 years, 9 months ago) by cdecanni
File size: 13697 byte(s)
* included AES C-files in `polar-bear.c' in order to have a single object file.
* corrected non-ansi `//' comments.
* renamed `ECRYPTInit' to `ECRYPT_init'.
* removed unused variable `gi', `expKeyBytes' and `j'.
* removed dynamic memory allocation of ctx->ks.
* removed `aes.h' form `ecrypt-sync.h' in order to keep the namespace clean.
* made `ECRYPT_KEYSIZE(i)' API-compliant.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "ecrypt-sync.h"

/* "Polar Bear" stream cipher implementaion           */
/* This code is provided "as is" with no warranty or  */
/* support. Requires a (slightly modified) Rijndael   */
/* (see documentation and "readme.txt").              */


#include "aes.h"

#include "aestab.c"
#include "aeskey.c"
#include "aescrypt.c"


/* Define this flag to get debug printouts           */

#undef CIPHER_DEBUG

#ifndef ECRYPT_API 
#undef CIPHER_DEBUG
#endif

/* Multiplication in GF(2^16)						  */

#define GF216MUL(x,y) ALOG[(DLOG[(x)] + DLOG[(y)]) % 0xffff]


#define GF216MUL2(TL,TH,x) (TL[x & 0xff] ^ TH[x >> 8]) 


/* Multiplication in GF(2^16) by pre.computed DLOG	  */

#define GF216DMUL(d,x) ALOG[(DLOG[(x)] + d) % 0xffff]


/* Multiplies v(y), corresponding to a polynomial over GF(2^16),
   by y where GF(2^16) is defined by 
   y^16 = y^8 + y^7 + y^5 + 1 = 0x1a1 */

#define YTIMES(v) (((v & 0x7fff) << 1) ^ (((v & 0x8000) >> 15)*0x1a1))



/* Steps LFSR R0 once                                   */
/* Poly: 23787 x^7 + 35674 x^6 + 1                      */

#define STEP_R0 {\
	c =  R0[0];\
	R0[0] =  R0[1];\
	R0[1] =  R0[2];\
	R0[2] =  R0[3];\
	R0[3] =  R0[4];\
	R0[4] =  R0[5];\
	R0[5] =  R0[6];\
	R0[6] =  GF216MUL2(TL00,TH00,c) ^ GF216MUL2(TL01,TH01,R0[0]);\
	}
	



/* Steps LFSR R1 once                                   */
/* Poly: 11362 x^9 + 26778 x^4 + 1                      */

#define STEP_R1 {\
	c = R1[0];\
	R1[0] =  R1[1];\
	R1[1] =  R1[2];\
	R1[2] =  R1[3];\
	R1[3] =  R1[4];\
	R1[4] =  R1[5];\
	R1[5] =  R1[6];\
	R1[6] =  R1[7];\
	R1[7] =  R1[8];\
	R1[8] =  GF216MUL2(TL10,TH10,c) ^ GF216MUL2(TL11,TH11,R1[4]);\
	}
	



/* Init of S-box on each message                           */

#define InitD8(tab) memcpy(tab, T8_init, 256)


u16 T, ALOG[265536], DLOG[65536];

u16 TL00[256],TH00[256], TL01[256],TH01[256],
		TL10[256],TH10[256], TL11[256],TH11[256];

char init_done = 0;

/* S-box, taken from AES                                           */

static u8 T8_init[256] = {
   99, 124, 119, 123, 242, 107, 111, 197,  48,   1, 103,  43, 254, 215, 171, 118, 
  202, 130, 201, 125, 250,  89,  71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 
  183, 253, 147,  38,  54,  63, 247, 204,  52, 165, 229, 241, 113, 216,  49,  21, 
    4, 199,  35, 195,  24, 150,   5, 154,   7,  18, 128, 226, 235,  39, 178, 117, 
    9, 131,  44,  26,  27, 110,  90, 160,  82,  59, 214, 179,  41, 227,  47, 132, 
   83, 209,   0, 237,  32, 252, 177,  91, 106, 203, 190,  57,  74,  76,  88, 207, 
  208, 239, 170, 251,  67,  77,  51, 133,  69, 249,   2, 127,  80,  60, 159, 168, 
   81, 163,  64, 143, 146, 157,  56, 245, 188, 182, 218,  33,  16, 255, 243, 210, 
  205,  12,  19, 236,  95, 151,  68,  23, 196, 167, 126,  61, 100,  93,  25, 115, 
   96, 129,  79, 220,  34,  42, 144, 136,  70, 238, 184,  20, 222,  94,  11, 219, 
  224,  50,  58,  10,  73,   6,  36,  92, 194, 211, 172,  98, 145, 149, 228, 121, 
  231, 200,  55, 109, 141, 213,  78, 169, 108,  86, 244, 234, 101, 122, 174,   8, 
  186, 120,  37,  46,  28, 166, 180, 198, 232, 221, 116,  31,  75, 189, 139, 138, 
  112,  62, 181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 134, 193,  29, 158, 
  225, 248, 152,  17, 105, 217, 142, 148, 155,  30, 135, 233, 206,  85,  40, 223, 
  140, 161, 137,  13, 191, 230,  66, 104,  65, 153,  45,  15, 176,  84, 187,  22
};



/* Initiates tables for GF(2^16) arithmetic          */

void ECRYPT_init(void) {
	u16 g;
	int i;

#ifdef CIPHER_DEBUG
	fprintf(stderr,"Builiding tables...\n");
#endif

	if (!init_done) {
		
		for (i = 0; i <= 0xffff; i++)
			DLOG[i] = ALOG[i] = 0;

		g = 1;
		DLOG[g] = 0;
		ALOG[0] = 1;

		for (i = 1; i < 0xffff; i++) {
		  g = YTIMES(g); /* g = g*y; */
			if (DLOG[g] || ALOG[i])
				fprintf(stderr,"Table error, collision, i = %04x\n",i);
			DLOG[g] = i;
			ALOG[i] = g;
		}

		for (i = 1; i < 0xffff; i++) 
			if (!(DLOG[g] && ALOG[i]))
				fprintf(stderr,"Table error, empty\n");

		for (i = 0; i <= 0xff; i++) {
			g = (DLOG[i] + DLOG[23787]) % 0xffff;
			TL00[i] = ALOG[g];
			TH00[i] = ALOG[(g + 8) % 0xffff];

			g = (DLOG[i] + DLOG[35674]) % 0xffff;
			TL01[i] = ALOG[g];
			TH01[i] = ALOG[(g + 8) % 0xffff];

			g = (DLOG[i] + DLOG[11362]) % 0xffff;
			TL10[i] = ALOG[g];
			TH10[i] = ALOG[(g + 8) % 0xffff];

			g = (DLOG[i] + DLOG[26778]) % 0xffff;
			TL11[i] = ALOG[g];
			TH11[i] = ALOG[(g + 8) % 0xffff];
				
		}

/* Poly: 11362 x^9 + 26778 x^4 + 1                      */
/*
	g = 23787;
	gi = DLOG[g];
	fprintf(stderr,"%04x: log = %04x,\n",g,gi);
	g = 35674;
	gi = DLOG[g];
	fprintf(stderr,"%04x: log = %04x,\n",g,gi);
	g = 11362;
	gi = DLOG[g];
	fprintf(stderr,"%04x: log = %04x,\n",g,gi);
	g = 26778;
	gi = DLOG[g];
	fprintf(stderr,"%04x: log = %04x,\n",g,gi);
*/

		init_done = 1;
	}
	

}




/* Computes Polar Bear key schedule, done once per key      */
/* memory is alloacted and a pointer is returned        */

void ECRYPT_keysetup(
  ECRYPT_ctx* ctx, 
  const u8* key, 
  u32 keysize,                /* Key size in bits. */ 
  u32 ivsize)               /* IV size in bits. */ 
 {
	if (keysize != 128) {
		fprintf(stderr,"Key size not implemented\n");
		exit(1);
	}

	if (!init_done)
		ECRYPT_init();


#ifdef CIPHER_DEBUG
	fprintf(stderr,"input key (len = %d): ",keysize);
	for (j = 0; j < keysize/8; j++) 
		fprintf(stderr," %02x",key[j]);
	fprintf(stderr,"\n");
#endif

	ctx->ivsize = ivsize;
	aes_enc_key(key, keysize/8, &ctx->ks);

#ifdef CIPHER_DEBUG
	fprintf(stderr,"aes ctx:\n");
	fprintf(stderr,"n_rounds %d\n",ctx->ks->n_rnd);
	fprintf(stderr,"n_blk %d\n key schedule:\n",ctx->ks->n_blk);
	
	for (j = 0; j < (6*32)/4; j++) 
		fprintf(stderr," %04x",ctx->ks->k_sch[j]);
	fprintf(stderr,"\n");
	fgetc(stdin);
#endif

}



/* Init of Polar Bear on each new message/IV          */
/* the context, p, needs to have been allocated and the */
/* ks field of the context needs to point to the key    */
/* schedule before calling                              */

void ECRYPT_ivsetup(
  ECRYPT_ctx* ctx, 
  const u8* iv) {
	int j, n_iv;
	u16 IR[16], *R0 = ctx->R0, *R1 = ctx->R1;
	u8 pt[32], *ct;


	if (ctx->ivsize > 248) {
		fprintf(stderr,"Illegal IV size\n");
		exit(1);
	}
	else
		n_iv = ctx->ivsize/8;


#ifdef CIPHER_DEBUG
	fprintf(stderr,"IV (len = %d): ",ctx->ivsize);
	for (j = 0; j < n_iv; j++) 
		fprintf(stderr," %02x",iv[j]);
	fprintf(stderr,"\n");
#endif

	InitD8(ctx->D8);
	
	/* IV schedule */

	for (j = 0; j < n_iv; j++)
		pt[j] = iv[j];
	pt[n_iv] = 0x80;
	for (j = n_iv+1; j < 32; j++) 
		pt[j] = 0;
	
#ifdef CIPHER_DEBUG
	fprintf(stderr,"expanded IV:\n");
	for (j = 0; j < 32; j++) 
		fprintf(stderr," %02x",pt[j]);
	fprintf(stderr,"\n");
#endif

	ct = (u8 *) IR;

	aes_enc_blk(pt, ct, &ctx->ks);
	
	for (j = 0; j < 7; j++) {
		R0[j] = IR[j];
		R1[j] = IR[j + 7];
	}
	R1[7] = IR[14];
	R1[8] = IR[15];

#ifdef CIPHER_DEBUG
	fprintf(stderr,"R0 inital value (6..0): ");
	for (j = 6; j >= 0; j--) 
		fprintf(stderr," %04x",ctx->R0[j]);
	fprintf(stderr,"\n");
	fprintf(stderr,"R1 initial value (8..0): ");
	for (j = 8; j >= 0; j--) 
		fprintf(stderr," %04x",ctx->R1[j]);
	fprintf(stderr,"\n");
	fgetc(stdin);
#endif

	ctx->shift  = 0;


}


void ECRYPT_process_bytes(
  int action,                 /* 0 = encrypt; 1 = decrypt; */
  ECRYPT_ctx* ctx, 
  const u8* input, 
  u8* output, 
  u32 msglen)                /* Message length in bytes. */ 
  {
	u8 alpha0, alpha1, alpha2, alpha3;
	u8 beta00, beta01, beta02, beta03, beta10, beta11, beta12, beta13;
	u16	c, gamma0, gamma1;
	u16 *R0 = ctx->R0, *R1 = ctx->R1;
	u8 *D8 = ctx->D8;
	int j,i = 0;

	while (i < msglen) {

		STEP_R0;
		STEP_R0;
		STEP_R1;
		STEP_R1;

#ifdef CIPHER_DEBUG
		fprintf(stderr,"R0 stepped twice: ");
		for (j = 6; j >= 0; j--) 
			fprintf(stderr," %04x",ctx->R0[j]);
		fprintf(stderr,"\n");
		fprintf(stderr,"R1 stepped twice: ");
		for (j = 8; j >= 0; j--) 
			fprintf(stderr," %04x",ctx->R1[j]);
		fprintf(stderr,"\n");
#endif

		if (ctx->shift & 0x4000) {
			STEP_R0;

#ifdef CIPHER_DEBUG
			fprintf(stderr,"R0 stepped once more: ");
			for (j = 6; j >= 0; j--) 
				fprintf(stderr," %04x",ctx->R0[j]);
			fprintf(stderr,"\n");
#endif
		}

		if (ctx->shift & 0x8000) {
			STEP_R1;
	
#ifdef CIPHER_DEBUG
			fprintf(stderr,"R1 stepped once more: ");
			for (j = 8; j >= 0; j--) 
				fprintf(stderr," %04x",ctx->R1[j]);
			fprintf(stderr,"\n");
#endif
		}

		alpha3 = R0[5] & 0xff;
		alpha2 = R0[5] >> 8;
		alpha1 = R0[6] & 0xff;
		alpha0 = R0[6] >> 8;

		beta00 = D8[alpha0];
		beta01 = D8[alpha1];
		beta02 = D8[alpha2];
		beta03 = D8[alpha3];
#ifdef CIPHER_DEBUG
		fprintf(stderr,"alpha0 (0-3): %02x %02x %02x %02x \n",alpha0,alpha1,alpha2,alpha3);
		fprintf(stderr,"beta0  (0-3): %02x %02x %02x %02x \n",beta00,beta01,beta02,beta03);
#endif
		D8[alpha0] = beta02;
		D8[alpha1] = beta00;
		D8[alpha2] = beta03;
		D8[alpha3] = beta01;

		alpha3 = R1[7] & 0xff;
		alpha2 = R1[7] >> 8;
		alpha1 = R1[8] & 0xff;
		alpha0 = R1[8] >> 8;

		beta10 = D8[alpha0];
		beta11 = D8[alpha1];
		beta12 = D8[alpha2];
		beta13 = D8[alpha3];

#ifdef CIPHER_DEBUG
		fprintf(stderr,"alpha1 (0-3): %02x %02x %02x %02x \n",alpha0,alpha1,alpha2,alpha3);
		fprintf(stderr,"beta1  (0-3): %02x %02x %02x %02x \n",beta10,beta11,beta12,beta13);
#endif

		D8[alpha0] = beta12;
		D8[alpha1] = beta10;
		D8[alpha2] = beta13;
		D8[alpha3] = beta11;

		gamma0 = beta11 | (beta10 << 8);
		gamma1 = beta13 | (beta12 << 8);

#ifdef CIPHER_DEBUG	
		fprintf(stderr,"gamma0, gamma1: %04x %04x \n",gamma0,gamma1);
#endif
		
		ctx->shift = (gamma0 + ctx->shift) & 0xffff;

		R0[5] = (gamma1 + R0[5]) & 0xffff;

		j = msglen - i;

		if (j >= 4) {
			output[i]   = input[i]   ^ beta00 ^ beta10;
			output[i+1] = input[i+1] ^ beta01 ^ beta11;
			output[i+2] = input[i+2] ^ beta02 ^ beta12;
			output[i+3] = input[i+3] ^ beta03 ^ beta13;
		}
		else {
			output[i]   = input[i] ^ beta00 ^ beta10;
			if (j > 1)
				output[i+1] = input[i+1] ^ beta01 ^ beta11;
			if (j > 2)
				output[i+2] = input[i+2] ^ beta02 ^ beta12;
		}
		
#ifdef CIPHER_DEBUG

		fprintf(stderr,"new shift: %04x \n",ctx->shift);
		fprintf(stderr,"new R0[5]: %04x \n",ctx->R0[5]);

		fprintf(stderr,"plaintext: %02x",input[i]);
		if (j > 1)
			fprintf(stderr," %02x",input[i+1]);
		if (j > 2)
			fprintf(stderr," %02x",input[i+2]);
		if (j > 3)
			fprintf(stderr," %02x",input[i+3]);
        fprintf(stderr,"\n");


		fprintf(stderr,"ciphertext: %02x",output[i]);
		if (j > 1)
			fprintf(stderr," %02x",output[i+1]);
		if (j > 2)
			fprintf(stderr," %02x",output[i+2]);
		if (j > 3)
			fprintf(stderr," %02x",output[i+3]);
        fprintf(stderr,"\n");
		fgetc(stdin);
#endif

		i += 4;
	}

}
	
void ECRYPT_keystream_bytes(
  ECRYPT_ctx* ctx,
  u8* keystream,
  u32 length)  {
	u8 alpha0, alpha1, alpha2, alpha3;
	u8 beta00, beta01, beta02, beta03, beta10, beta11, beta12, beta13;
	u16	c, gamma0, gamma1;
	u16 *R0 = ctx->R0, *R1 = ctx->R1;
	u8 *D8 = ctx->D8;
	int j,i = 0;

	while (i < length) {

		STEP_R0;
		STEP_R0;
		STEP_R1;
		STEP_R1;

#ifdef CIPHER_DEBUG
		fprintf(stderr,"R0 stepped twice: ");
		for (j = 6; j >= 0; j--) 
			fprintf(stderr," %04x",ctx->R0[j]);
		fprintf(stderr,"\n");
		fprintf(stderr,"R1 stepped twice: ");
		for (j = 8; j >= 0; j--) 
			fprintf(stderr," %04x",ctx->R1[j]);
		fprintf(stderr,"\n");
#endif

		if (ctx->shift & 0x4000) {
			STEP_R0;

#ifdef CIPHER_DEBUG
			fprintf(stderr,"R0 stepped once more: ");
			for (j = 6; j >= 0; j--) 
				fprintf(stderr," %04x",ctx->R0[j]);
			fprintf(stderr,"\n");
#endif
		}

		if (ctx->shift & 0x8000) {
			STEP_R1;
	
#ifdef CIPHER_DEBUG
			fprintf(stderr,"R1 stepped once more: ");
			for (j = 8; j >= 0; j--) 
				fprintf(stderr," %04x",ctx->R1[j]);
			fprintf(stderr,"\n");
#endif
		}

		alpha3 = R0[5] & 0xff;
		alpha2 = R0[5] >> 8;
		alpha1 = R0[6] & 0xff;
		alpha0 = R0[6] >> 8;

		beta00 = D8[alpha0];
		beta01 = D8[alpha1];
		beta02 = D8[alpha2];
		beta03 = D8[alpha3];
#ifdef CIPHER_DEBUG
		fprintf(stderr,"alpha0 (0-3): %02x %02x %02x %02x \n",alpha0,alpha1,alpha2,alpha3);
		fprintf(stderr,"beta0  (0-3): %02x %02x %02x %02x \n",beta00,beta01,beta02,beta03);
#endif
		D8[alpha0] = beta02;
		D8[alpha1] = beta00;
		D8[alpha2] = beta03;
		D8[alpha3] = beta01;

		alpha3 = R1[7] & 0xff;
		alpha2 = R1[7] >> 8;
		alpha1 = R1[8] & 0xff;
		alpha0 = R1[8] >> 8;

		beta10 = D8[alpha0];
		beta11 = D8[alpha1];
		beta12 = D8[alpha2];
		beta13 = D8[alpha3];

#ifdef CIPHER_DEBUG
		fprintf(stderr,"alpha1 (0-3): %02x %02x %02x %02x \n",alpha0,alpha1,alpha2,alpha3);
		fprintf(stderr,"beta1  (0-3): %02x %02x %02x %02x \n",beta10,beta11,beta12,beta13);
#endif

		D8[alpha0] = beta12;
		D8[alpha1] = beta10;
		D8[alpha2] = beta13;
		D8[alpha3] = beta11;

		gamma0 = beta11 | (beta10 << 8);
		gamma1 = beta13 | (beta12 << 8);

#ifdef CIPHER_DEBUG	
		fprintf(stderr,"gamma0, gamma1: %04x %04x \n",gamma0,gamma1);
#endif
		
		ctx->shift = (gamma0 + ctx->shift) & 0xffff;

		R0[5] = (gamma1 + R0[5]) & 0xffff;

		j = length - i;

		if (j >= 4) {
			keystream[i]   = beta00 ^ beta10;
			keystream[i+1] = beta01 ^ beta11;
			keystream[i+2] = beta02 ^ beta12;
			keystream[i+3] = beta03 ^ beta13;
		}
		else {
			keystream[i]   = beta00 ^ beta10;
			if (j > 1)
				keystream[i+1] = beta01 ^ beta11;
			if (j > 2)
				keystream[i+2] = beta02 ^ beta12;
		}

#ifdef CIPHER_DEBUG

		fprintf(stderr,"new shift: %04x \n",ctx->shift);
		fprintf(stderr,"new R0[5]: %04x \n",ctx->R0[5]);

		fprintf(stderr,"keystream: %02x",keystream[i]);
		if (j > 1)
			fprintf(stderr," %02x",keystream[i+1]);
		if (j > 2)
			fprintf(stderr," %02x",keystream[i+2]);
		if (j > 3)
			fprintf(stderr," %02x",keystream[i+3]);
        fprintf(stderr,"\n");
		fgetc(stdin);
#endif

		i += 4;
	}

}

eSTREAM Project

Powered by ViewCVS 1.0-dev
(Powered by Apache)

ViewCVS and CVS Help