[svn] / ecrypt / trunk / submissions / hc-256 / hc-256.c  

svn: ecrypt/trunk/submissions/hc-256/hc-256.c

File: [svn] / ecrypt / trunk / submissions / hc-256 / hc-256.c (download) (as text)
Revision: 13, Sun Jun 26 20:58:23 2005 UTC (7 years, 10 months ago) by cdecanni
File size: 3887 byte(s)
* removed function definitions from `ecrypt-sync.h'.
* added an `if (msglen & 3)' to allow correct incremental encryption.

#include "ecrypt-sync.h"

/* ===========================================================================

                 Added functions:    HC-256 Mandatory functions 

============================================================================== */

#define f1(x)    (ROTR32((x),7) ^ ROTR32((x),18) ^ ((x) >> 3))
#define f2(x)    (ROTR32((x),17) ^ ROTR32((x),19) ^ ((x) >> 10))



u32 h1(ECRYPT_ctx* ctx, u32 u) {
	u32 tem; 			
	unsigned char a,b,c,d;			
	a = (unsigned char) ((u));		
	b = (unsigned char) ((u) >> 8);	
	c = (unsigned char) ((u) >> 16);	
	d = (unsigned char) ((u) >> 24);	
	tem = ctx->Q[a]+ctx->Q[256+b]+ctx->Q[512+c]+ctx->Q[768+d];
	return (tem);
}



u32 h2(ECRYPT_ctx* ctx, u32 u) {
	u32 tem; 			
	unsigned char a,b,c,d;			
	a = (unsigned char) ((u));		
	b = (unsigned char) ((u) >> 8);	
	c = (unsigned char) ((u) >> 16);	
	d = (unsigned char) ((u) >> 24);	
	tem = ctx->P[a]+ctx->P[256+b]+ctx->P[512+c]+ctx->P[768+d];
	return (tem);
}



u32 generate(ECRYPT_ctx* ctx) /*one step of the cipher*/
{
		u32 i,i3, i10, i12, i1023;
		u32 output;

		i   = ctx->counter2048 & 0x3ff;
		i3  = (i - 3) & 0x3ff;
		i10 = (i - 10) & 0x3ff;
		i12 = (i - 12) & 0x3ff;
		i1023 = (i - 1023) & 0x3ff;

		if (ctx->counter2048 < 1024) {
			ctx->P[i] = ctx->P[i] + ctx->P[i10] + (ROTR32(ctx->P[i3],10)^ROTR32(ctx->P[i1023],23))+ctx->Q[(ctx->P[i3]^ctx->P[i1023])&0x3ff];
			output = h1(ctx,ctx->P[i12]) ^ ctx->P[i];
		}
		else {                                   
			ctx->Q[i] = ctx->Q[i] + ctx->Q[i10] + (ROTR32(ctx->Q[i3],10)^ROTR32(ctx->Q[i1023],23))+ctx->P[(ctx->Q[i3]^ctx->Q[i1023])&0x3ff];
			output = h2(ctx, ctx->Q[i12]) ^ ctx->Q[i];
		}
		ctx->counter2048 = (ctx->counter2048+1) & 0x7ff;
		return (output);
}





void ECRYPT_init(void) {
}  /* No operation performed */


void ECRYPT_keysetup(
  ECRYPT_ctx* ctx, 
  const u8* key, 
  u32 keysize,                /* Key size in bits. */ 
  u32 ivsize)                 /* IV size in bits. */
{ 
  u32 i;  

  ctx->keysize = keysize >> 3;
  ctx->ivsize = ivsize >> 3;
  
  for (i = 0; i < 8; i++) ctx->key[i] = 0;
  for (i = 0; (i < ctx->keysize) & (i < 32); i++) {
	  	ctx->key[i >> 2] =  ctx->key[i >> 2] | key[i];
		ctx->key[i >> 2] = ROTL32(ctx->key[i >> 2],8);
  }
 
} /* initialize the key, save the iv size*/




void ECRYPT_ivsetup(
  ECRYPT_ctx* ctx, 
  const u8* iv)
{ 
    u32 W[2560],i;
  
    /* initialize the iv */
    for (i = 0; i < 8; i++) ctx->iv[i] = 0;
    for (i = 0; (i < ctx->ivsize) & (i < 32); i++) {
		ctx->iv[i >> 2] =  ctx->iv[i >> 2] | iv[i];
		ctx->iv[i >> 2] = ROTL32(ctx->iv[i >> 2],8);
    }
  
    /* setup the table P and Q */ 

	for (i = 0; i < 8;  i++) W[i] = ctx->key[i];
	for (i = 8; i < 16; i++) W[i] = ctx->iv[i-8];

	for (i = 16; i < 2560; i++) W[i] = f2(W[i-2]) + W[i-7] + f1(W[i-15]) + W[i-16]+i; 

	for (i = 0; i < 1024; i++)  ctx->P[i] = W[i+512];
	for (i = 0; i < 1024; i++)  ctx->Q[i] = W[i+1536];

	ctx->counter2048 = 0;
      
      /* run the cipher 4096 steps before generating the output */
	for (i = 0; i < 4096; i++)  generate(ctx);  
}



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, j, msglen32, keystreamword;

  msglen32 = msglen >> 2;

  for (i = 0; i < msglen32; i++) { 
      keystreamword = generate(ctx);                 /*generate a 32-bit word*/
      for (j = 0; j < 4; j++) {
	      *output = *input ^ keystreamword;       /*encrypt one byte*/
          output += 1; 
          input +=1;
		  keystreamword = keystreamword >> 8;
	  }
  }  

  if (msglen & 3)
    {
      keystreamword = generate(ctx);
      for (i = 0; i < (msglen & 3); i++) {
	*output = *input ^ keystreamword;       /*encrypt one byte*/
	output += 1; 
	input +=1;
	keystreamword = keystreamword >> 8;
      }
    }
}


eSTREAM Project

Powered by ViewCVS 1.0-dev
(Powered by Apache)

ViewCVS and CVS Help