[svn] / ecrypt / trunk / submissions / f-fcsr / f-fcsr-8 / f-fcsr-8.c  

svn: ecrypt/trunk/submissions/f-fcsr/f-fcsr-8/f-fcsr-8.c

File: [svn] / ecrypt / trunk / submissions / f-fcsr / f-fcsr-8 / f-fcsr-8.c (download) (as text)
Revision: 1, Sun Jun 26 18:46:26 2005 UTC (7 years, 10 months ago) by cdecanni
File size: 9850 byte(s)
* imported original ECRYPT submissions after first automatic cleanup.
    /*
     * F-FCSR-8 reference implementation.
     *
     * (c) 2005 FCSR project. This software is provided 'as-is', without
     * any express or implied warranty. In no event will the authors be held
     * liable for any damages arising from the use of this software.
     *
     * Permission is granted to anyone to use this software for any purpose,
     * including commercial applications, and to alter it and redistribute it
     * freely, subject to no restriction.
     *
     * Technical remarks and questions can be addressed to
     * <cedric.lauradoux@inria.fr>
     */
#define FFCSR8_EVALUATE

#include "ffcsr8-sync.h"
#ifdef FFCSR8_EVALUATE
#include <time.h>
#endif



void ECRYPT_keysetup(
  ECRYPT_ctx* ctx, 
  const u8* key, 
  u32 keyse,                /* Key se in bits. */ 
  u32 ivse)                 /* IV se in bits. */ 
{
	u32 i;

	
	ctx->carry[0] = 0;
	ctx->carry[1] = 0;
	ctx->carry[2] = 0;
	ctx->carry[3] = 0;
	
	ctx->state[3] = key[3] | key[2]<<8 | key[1]<<16 | key[0]<<24;
	ctx->state[2] = key[7] | key[6]<<8 | key[5]<<16 | key[4]<<24;
	ctx->state[1] = key[11] | key[10]<<8 | key[9]<<16 | key[8]<<24;
	ctx->state[0] = key[15] | key[14]<<8 | key[13]<<16 | key[12]<<24;
	
	
	while( goodfilter(ctx) != 1 )
	{
		ctx->carry[0] = 0;
		ctx->carry[1] = 0;
		ctx->carry[2] = 0;
		ctx->carry[3] = 0;

		ECRYPT_clock(ctx);
		ECRYPT_clock(ctx);
		ECRYPT_clock(ctx);
		ECRYPT_clock(ctx);
		ECRYPT_clock(ctx);
		ECRYPT_clock(ctx);
	}
		
	ctx->filter[0]=ctx->state[0];
	ctx->filter[1]=ctx->state[1];
	ctx->filter[2]=ctx->state[2];
	ctx->filter[3]=ctx->state[3];
		
	ctx->carry[0] = 0;
	ctx->carry[1] = 0;
	ctx->carry[2] = 0;
	ctx->carry[3] = 0;
	
	
	for(i=0;i<128;i++)
	{
		ECRYPT_clock(ctx);
	}
	
	init[0]=ctx->state[0];
	init[1]=ctx->state[1];
	init[2]=ctx->state[2];
	init[3]=ctx->state[3];
}

void ECRYPT_ivsetup(
  ECRYPT_ctx* ctx, 
  const u8* iv)
{
	u32 i=0,tmp;
	ctx->carry[0] = 0;
	ctx->carry[1] = 0;
	ctx->carry[2] = 0;
	ctx->carry[3] = 0;
	
	insertIV(ctx,&iv[0]);	
	
	ctx->state[0]=init[0];
	ctx->state[1]=init[1];
	ctx->state[2]=init[2];
	ctx->state[3]=init[3];
	
	for( i=0; i<64 ; i++)
		{
			ECRYPT_clock(ctx);
		}
		
	ctx->carry[0] = 0;
	ctx->carry[1] = 0;
	ctx->carry[2] = 0;
	ctx->carry[3] = 0;
	insertIV(ctx,&iv[8]);
	
	for( i=0; i<64 ; i++)
		{
			ECRYPT_clock(ctx);
		}
	ctx->state[0]=init[0];
	ctx->state[1]=init[1];
	ctx->state[2]=init[2];
	ctx->state[3]=init[3];
}

void ECRYPT_process_bytes(
  int action,                 /* 0 = encrypt; 1 = decrypt; */
  ECRYPT_ctx* ctx, 
  const u8* input, 
  u8* output, 
  u32 msglen)                /* Message length in bytes. */ 
{
	u32 i;
	for( i=0 ; i< msglen ; i++)
	{
		ECRYPT_clock(ctx);
		output[i] = input[i] ^ ECRYPT_filter(ctx);
	}
}


/* Update the shift register and the carry register of the FCSR */
void ECRYPT_clock(
  ECRYPT_ctx* ctx 
)
{
	u32 feedback;
	u32 buffer[4];
	
	/* expand the feedback bit */
	
	feedback = ((int) (ctx->state[0] << (MAXSHIFT))) >> (MAXSHIFT); 
	/* shift the state */
	
	ctx->state[0] = ctx->state[0] >> 1;
	ctx->state[0] |= (ctx->state[1] & 0x00000001 ) << (MAXSHIFT);

	ctx->state[1] = ctx->state[1] >> 1;
	ctx->state[1] |= (ctx->state[2] & 0x01 ) << (MAXSHIFT);
	
	ctx->state[2] = ctx->state[2] >> 1;
	ctx->state[2] |= (ctx->state[3] & 0x01 ) << (MAXSHIFT);

	ctx->state[3] >>=1;
	/* update the register */
	
	buffer[0] = ctx->state[0] ^ ctx->carry[0]; 
	buffer[1] = ctx->state[1] ^ ctx->carry[1];
	buffer[2] = ctx->state[2] ^ ctx->carry[2];
	buffer[3] = ctx->state[3] ^ ctx->carry[3];
	
	ctx->carry[0] &= ctx->state[0];
	ctx->carry[1] &= ctx->state[1];
	ctx->carry[2] &= ctx->state[2];
	ctx->carry[3] &= ctx->state[3];

	ctx->carry[0] ^= buffer[0] & (feedback &d0);
	ctx->carry[1] ^= buffer[1] & (feedback &d1);
	ctx->carry[2] ^= buffer[2] & (feedback &d2);
	ctx->carry[3] ^= buffer[3] & (feedback &d3);

	buffer[0] ^= feedback & d0;
	buffer[1] ^= feedback & d1;
	buffer[2] ^= feedback & d2;
	buffer[3] ^= feedback & d3;
	
	ctx->state[0] = buffer[0];
	ctx->state[1] = buffer[1];
	ctx->state[2] = buffer[2];
	ctx->state[3] = buffer[3];
}

/* Produce one byte of keystream from the internal state of the register */
u8 ECRYPT_filter(
  ECRYPT_ctx* ctx 
)
{
	u32 buffer[4];
	
	
	buffer[0] = ctx->filter[0] & ctx->state[0];
	buffer[1] = ctx->filter[1] & ctx->state[1];
	buffer[2] = ctx->filter[2] & ctx->state[2];
	buffer[3] = ctx->filter[3] & ctx->state[3];
	
	buffer[0] ^= buffer[1];
	buffer[2] ^= buffer[3];
	
	buffer[0] ^= buffer[2];
	buffer[0] ^= ( buffer[0] >> 16 );
	buffer[0] ^= ( buffer[0] >> 8);
	return (u8)buffer[0];
}

/* compute the hamming of 32 bits word */
/* this method is efficient for low hamming weight word */
u32 hammingWeight (
u32 n
) 
{
	u32 count=0 ;
    while (n)
    {
        count++ ;
        n &= (n - 1) ;     
    }
    return count ;
}


/* each subFilter of the filter must have a hamming weight > LIMIT_WEIGHT */
u8 goodfilter (
ECRYPT_ctx *ctx
)
{
  u32 i,j;
  u32 weight;
  u32 tmp, mask;
  
  for ( i=0; i < 8 ; i++ )  
  {
	mask = 0x01010101 << i;
	tmp = (ctx->state[0] & mask)>>i ;
	tmp ^= ((ctx->state[1] & mask) >>i)<<1;
	tmp ^= ((ctx->state[2] & mask) >>i)<<2;
	tmp ^= ((ctx->state[3] & mask) >>i)<<3;
		
	weight=hammingWeight(tmp);
	if(weight<LIMIT_WEIGHT){return 0;}
  }
  return 1;
}

void insertIV(
ECRYPT_ctx *ctx, 
const u8*iv
)
{
	u32 i,tmp;
	
	tmp=iv[7];
	for( i=0; i<8;i++)
	{
		ctx->carry[0] |= (tmp & 0x00000001) << (ivD0Load[i]); 
		tmp = tmp>>1;
	}
		
	tmp=iv[6];
	for( i=8; i<14 ;i++)
	{
		ctx->carry[0] |= (tmp & 0x00000001) << ivD0Load[i]; 
		tmp = tmp>>1;
	}	
		
	/* inject the next 16 bit of IV in the carry */
	for( i=0; i<2;i++)
	{
		ctx->carry[1] |= (tmp & 0x00000001) << ivD1Load[i]; 
		tmp = tmp>>1;
	}
	
	tmp=iv[5];
	for( i=2; i<10;i++)
	{
		ctx->carry[1] |= (tmp & 0x00000001) << ivD1Load[i]; 
		tmp = tmp>>1;
	}
	
	tmp=iv[4];
	for( i=10; i<16;i++)
	{
		ctx->carry[1] |= (tmp & 0x00000001) << ivD1Load[i]; 
		tmp = tmp>>1;
	}
	/* inject the next 21 bit of IV in the carry */
	ctx->carry[2] |= (tmp & 0x00000001) << ivD2Load[0];
	tmp = tmp>>1;
	ctx->carry[2] |= (tmp & 0x00000001) << ivD2Load[1];
	
	tmp=iv[3];
	for( i=2; i<10;i++)
	{
		ctx->carry[2] |= (tmp & 0x00000001) << ivD2Load[i]; 
		tmp = tmp>>1;
	}
	tmp=iv[2];
	for( i=10; i<18;i++)
	{
		ctx->carry[2] |= (tmp & 0x00000001) << ivD2Load[i]; 
		tmp = tmp>>1;
	}
	tmp=iv[1];
	for( i=18; i<21;i++)
	{
		ctx->carry[2] |= (tmp & 0x00000001) << ivD2Load[i]; 
		tmp = tmp>>1;
	}
	
	/* inject the last 17 bit of IV in the carry */
	for(i=0;i<5;i++)
	{
		ctx->carry[3] |= (tmp & 0x00000001) << ivD3Load[i];
		tmp = tmp>>1;
	}
	tmp=iv[0];
	for( i=5; i<13;i++)
	{
		ctx->carry[3] |= (tmp & 0x00000001) << ivD3Load[i]; 
		tmp = tmp>>1;
	}
}


#ifdef FFCSR8_EVALUATE
#define MB 1048576
#define NUM_MB 100
int main()
{
	u32 nbByte,i,j;
	clock_t orig, end;
	double time;
	ECRYPT_ctx ctx;
	
	/* key for test vector */
	u8 testKEY[16] = { 0x00, 0x88 , 0x63 , 0x9d, 0x6b , 0xf8 , 0x47 , 0xed , 0x59 , 0xc6 , 0x21 , 0x79 , 0x5d , 0x33 , 0x63 , 0xf1 };
	u8 testIV[16] = { 0x00 , 0x11 , 0x22 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xAA , 0xBB , 0xCC , 0xDD , 0xEE , 0xFF};
	u8 encipheredText[9]={ 0x50 , 0xf8 , 0xec , 0xde , 0xfa , 0x3c , 0x15 , 0xe1 , 0xc0 };
	u8 output[9];
	u8 text[9]={'S','O','S','E','M','A','N','U','K'};
	u8 data=0;
	/* iv for vector test */
	
	printf("\t TEST VECTOR\n");
	
	printf("KEY 0x");
	for(i=0;i<16;i++)
	{
		printf("%x",testKEY[i]);
	}
	printf("\n");
	
	printf("IV 0x");
	for(i=0;i<16;i++)
	{
		printf("%x",testIV[i]);
	}
	printf("\n");
	
	printf("Plain Text: ");
	for(i=0;i<9;i++)
	{
		printf("%c",text[i]);
	}
	printf("\n");
	
	
	ECRYPT_keysetup( &ctx , testKEY , ECRYPT_MAXKEYSIZE , ECRYPT_MAXIVSIZE);
	printf("Key loaded\n");
	printf("Filter is: \n%x %x %x %x\n",ctx.filter[0],ctx.filter[1],ctx.filter[2],ctx.filter[3]);
	ECRYPT_ivsetup( &ctx , testIV );
	printf("IV loaded\n");
	ECRYPT_process_bytes( 0, &ctx , text , output , 9); 
	printf("Enciphered Text: 0x");
	for(i=0;i<9;i++)
	{
		if(encipheredText[i] != output[i])
		{
			printf("ERROR\n");
			exit(EXIT_FAILURE);
		}
		else
		{
			printf("%x",output[i]);
		}
	}
	printf("\n");
	
	ECRYPT_keysetup( &ctx , testKEY , ECRYPT_MAXKEYSIZE , ECRYPT_MAXIVSIZE);
	ECRYPT_ivsetup( &ctx , testIV );
	ECRYPT_process_bytes( 1, &ctx , output , output, 9); 
	
	printf("Deciphered Text: ");
	for(i=0;i<9;i++)
	{
		printf("%c",output[i]);
	}
	printf("\n");
	
	printf("SPEED TEST\n");
	ECRYPT_keysetup( &ctx , testKEY , ECRYPT_MAXKEYSIZE , ECRYPT_MAXIVSIZE);
	ECRYPT_ivsetup( &ctx , testIV );
	
	
	orig = clock();
	for(i=0;i<(NUM_MB);i++)
	{
		for( j=0 ; j<MB ; j++)
		{
			ECRYPT_clock(&ctx);
			data ^= ECRYPT_filter(&ctx); 
		}
	}
	end = clock();
	
	time = (double)end / CLOCKS_PER_SEC - (double)orig / CLOCKS_PER_SEC;
	if (time <= 1.0) {
		printf("Time resolution too big !\n");
	} else {
		printf("elapsed time: %.4f seconds\n", time);
		printf("byte per second: %.0f\n", (double)(MB*NUM_MB) / time);
	}
	
	orig = clock();
	for(i=0;i<NUM_MB;i++)
	{
		for( j=0 ; j<(MB/256) ; j++)
		{
			ECRYPT_ivsetup( &ctx , testIV );
		}
	}
	end = clock();
	
	time = (double)end / CLOCKS_PER_SEC - (double)orig / CLOCKS_PER_SEC;
	if (time <= 1.0) {
		printf("Time resolution too big !\n");
	} else {
		printf("elapsed time: %.4f seconds\n", time);
		printf("IV reload per second: %.0f\n", (double)(MB*NUM_MB) / (256*time));
	}
		
	orig = clock();
	for(i=0;i<(NUM_MB);i++)
	{
		for( j=0 ; j<(MB/1024) ; j++)
		{
			ECRYPT_keysetup( &ctx , testKEY , ECRYPT_MAXKEYSIZE , ECRYPT_MAXIVSIZE);
		}
	}
	end = clock();
	
	time = (double)end / CLOCKS_PER_SEC - (double)orig / CLOCKS_PER_SEC;
	if (time <= 1.0) {
		printf("Time resolution too big !\n");
	} else {
		printf("elapsed time: %.4f seconds\n", time);
		printf("Load KEY per second: %.0f\n", (double)(MB*NUM_MB) / (time*1024));
	}
	printf("data = 0x%x\n", data);
	return 0;
}
#endif






eSTREAM Project

Powered by ViewCVS 1.0-dev
(Powered by Apache)

ViewCVS and CVS Help