[svn] / ecrypt / trunk / submissions / grain / 128 / opt / grain-128.c  

svn: ecrypt/trunk/submissions/grain/128/opt/grain-128.c

File: [svn] / ecrypt / trunk / submissions / grain / 128 / opt / grain-128.c (download) (as text)
Revision: 173, Fri Jan 5 16:46:48 2007 UTC (6 years, 4 months ago) by cdecanni
File size: 6461 byte(s)
* imported implementation of Grain-v1 and Grain-128.
/*
 * OPTIMIZED IMPLEMENTATION OF STREAM CIPHER GRAIN-128
 *
 * Filename: grain-128.c
 *
 *
 * Synopsis:
 *  This file contains functions that implement the
 *  stream cipher Grain-128. It also implements functions
 *  specified by the ECRYPT API.
 *
 *
 */
#include "ecrypt-sync.h"

void ECRYPT_init(void)
{ }

void Reinit_After_NIter(ECRYPT_ctx* ctx)
{
  *(u64*)(ctx->lfsr)     = *(u64*)(ctx->lfsr+ctx->count-4);
  *(u64*)((ctx->lfsr)+2) = *(u64*)(ctx->lfsr+ctx->count-2);
  *(u64*)(ctx->nfsr)     = *(u64*)(ctx->nfsr+ctx->count-4);
  *(u64*)((ctx->nfsr)+2) = *(u64*)(ctx->nfsr+ctx->count-2);
  ctx->nptr=ctx->nfsr;
  ctx->lptr=ctx->lfsr;
  ctx->count=4;
}

#ifdef ECRYPT_BIG_ENDIAN

u32 GetWord(ECRYPT_ctx* ctx)
{ u8 *pn;
  u64 ln0=U64TO64_LITTLE(*(u64*)(ctx->lptr)),
    nn0=U64TO64_LITTLE(*(u64*)(ctx->nptr)),
    ln1=U64TO64_LITTLE(*(u64*)((ctx->lptr)+1)),
    nn1=U64TO64_LITTLE(*(u64*)((ctx->nptr)+1)),
    ln2=U64TO64_LITTLE(*(u64*)((ctx->lptr)+2)),
    nn2=U64TO64_LITTLE(*(u64*)((ctx->nptr)+2)),
    ln3=U64TO64_LITTLE(*(u64*)((ctx->lptr)+3)),
    nn3=U64TO64_LITTLE(*(u64*)((ctx->nptr)+3));
  ++(ctx->lptr);
  ++(ctx->nptr);
  pn = (u8*)(ctx->nptr);
  ctx->nfsr[ctx->count] = U32TO32_LITTLE( (u32) (nn0^nn3^ln0^(nn0>>26)^U64TO64_LITTLE(*(u64*)(pn+3))^(((nn0&nn1)^nn2)>>27)^
    (U64TO64_LITTLE(*(u64*)(pn+1)) & U64TO64_LITTLE(*(u64*)(pn+2)))^((nn0&nn2)>>3)^((nn1>>29)&(nn2>>1))^
    ((nn0>>17)&(nn0>>18))^((nn2>>4)&(nn2>>20))^((nn0>>11)&(nn0>>13))));
  ctx->lfsr[ctx->count] = U32TO32_LITTLE((u32)((ln0^ln3)^((ln1^ln2)>>6)^(ln0>>7)^(ln2>>17)));
  ln3=ln1>>13;
  nn3=ln0>>7;
  ln3&=ln2;
  nn3&=ln0;
  ++(ctx->count);
  ln3^=nn0;
  nn3^=nn1;
  return  U32TO32_LITTLE( (u32) (nn2^(nn0>>2)^(nn2>>9)^((nn0>>12)&(ln0>>8))^((nn2>>31)&(ln1>>10))^
    (nn3>>13)^(ln2>>29)^(ln3>>15)^(nn2>>25)^(nn1>>4)^((nn0>>12)&((nn2&ln2)>>31))));
}

void ECRYPT_keystream_bytes(
                            ECRYPT_ctx* ctx,
                            u8* keystream,
                            u32 msglen)
{
  u32 itr=msglen/4,i,j=0;
  u32 rem=msglen%4;
  u32 remWord;
  for (i=0;i<itr;++i)
    {   *(u32*)(keystream+j) = GetWord(ctx);
		j+=4;
		if ((ctx->count)>=1024) Reinit_After_NIter(ctx);
    }
  if (rem)
    {	remWord=GetWord(ctx);
		remWord=U32TO32_LITTLE(remWord);	
		for (i=0;i<rem;++i) *(keystream+j++) = (u8)(remWord>>(8*i));
    }
}
void ECRYPT_encrypt_bytes(
                          ECRYPT_ctx* ctx,
                          const u8* plaintext,
                          u8* ciphertext,
                          u32 msglen)
{
  u32 itr=msglen/4,i,j=0;
  u32 rem=msglen%4;
  u32 remWord;
  for (i=0;i<itr;++i)
    {   *(u32*)(ciphertext+j) = GetWord(ctx) ^ (*(u32*)(plaintext+j));
		j+=4;
		if ((ctx->count)>=1024) Reinit_After_NIter(ctx);
    }
  if (rem)
    {	remWord=GetWord(ctx);
		remWord=U32TO32_LITTLE(remWord);
		for (i=0;i<rem;++i)
		{	*(ciphertext+j) = ((u8)(remWord>>(8*i))) ^ *(plaintext+j);
			j++;
		}
    }
}
void ECRYPT_decrypt_bytes(
                          ECRYPT_ctx* ctx,
                          const u8* ciphertext,
                          u8* plaintext,
                          u32 msglen)
{
  u32 itr=msglen/4,i,j=0;
  u32 rem=msglen%4;
  u32 remWord;
  for (i=0;i<itr;++i)
    {	*(u32*)(plaintext+j) = GetWord(ctx) ^ (*(u32*)(ciphertext+j));
		j+=4;
		if ((ctx->count)>=1024) Reinit_After_NIter(ctx);
    }
  if (rem)
    {	remWord=GetWord(ctx);
		remWord=U32TO32_LITTLE(remWord);
		for (i=0;i<rem;++i)
		{	*(plaintext+j) = ((u8)(remWord>>(8*i))) ^ *(ciphertext+j);
			j++;
		}
    }
}

#else

u32 GetWord(ECRYPT_ctx* ctx)
{	
	u64 ln0=*(u64*)(ctx->lptr),
	  nn0=*(u64*)(ctx->nptr),
	  ln2=*(u64*)((ctx->lptr)+2),
	  nn2=*(u64*)((ctx->nptr)+2),
	  ln1=*(u64*)(++(ctx->lptr)),
	  nn1=*(u64*)(++(ctx->nptr)),
	  ln3=*(u64*)((ctx->lptr)+2),
	  nn3=*(u64*)((ctx->nptr)+2);
	u8 * pn = (u8*)(ctx->nptr);
    ctx->nfsr[ctx->count] = nn0^nn3^ln0^(nn0>>26)^(*(u64*)(pn+3))^(((nn0&nn1)^nn2)>>27)^
			    ((*(u64*)(pn+1)) & (*(u64*)(pn+2)))^((nn0&nn2)>>3)^((nn1>>29)&(nn2>>1))^
			    ((nn0>>17)&(nn0>>18))^((nn2>>4)&(nn2>>20))^((nn0>>11)&(nn0>>13));
	ctx->lfsr[ctx->count] = (ln0^ln3)^((ln1^ln2)>>6)^(ln0>>7)^(ln2>>17);
	ln3=ln1>>13;
	nn3=ln0>>7;
	ln3&=ln2;
    nn3&=ln0;
    ++(ctx->count);
	ln3^=nn0;
	nn3^=nn1;
	return  nn2^(nn0>>2)^(nn2>>9)^((nn0>>12)&(ln0>>8))^((nn2>>31)&(ln1>>10))^
	      (nn3>>13)^(ln2>>29)^(ln3>>15)^(nn2>>25)^(nn1>>4)^((nn0>>12)&((nn2&ln2)>>31));
}
void ECRYPT_keystream_bytes(
  ECRYPT_ctx* ctx, 
  u8* keystream, 
  u32 msglen)
{
	u32 itr=msglen/4,i,j=0;
	u32 rem=msglen%4;
	u32 remWord;
	for (i=0;i<itr;++i)
	{   *(u32*)(keystream+j) = GetWord(ctx);
		j+=4;
		if ((ctx->count)>=1024) Reinit_After_NIter(ctx);
	}
	if (rem)
	{  remWord=GetWord(ctx);
	   for (i=0;i<rem;++i) *(keystream+j++) = (u8)(remWord>>(8*i));
	}
}

void ECRYPT_encrypt_bytes(
  ECRYPT_ctx* ctx, 
  const u8* plaintext, 
  u8* ciphertext, 
  u32 msglen)
{
	u32 itr=msglen/4,i,j=0;
	u32 rem=msglen%4;
	u32 remWord;
	for (i=0;i<itr;++i)
	{   *(u32*)(ciphertext+j) = GetWord(ctx) ^ (*(u32*)(plaintext+j));
		j+=4;
		if ((ctx->count)>=1024) Reinit_After_NIter(ctx);
	}
	if (rem)
	{  remWord=GetWord(ctx);
	   for (i=0;i<rem;++i) 
	   { *(ciphertext+j) = ((u8)(remWord>>(8*i))) ^ *(plaintext+j);
	     j++;
	   }
	}
}

void ECRYPT_decrypt_bytes(
  ECRYPT_ctx* ctx, 
  const u8* ciphertext, 
  u8* plaintext, 
  u32 msglen)
{
	u32 itr=msglen/4,i,j=0;
	u32 rem=msglen%4;
	u32 remWord;
	for (i=0;i<itr;++i)
	{   *(u32*)(plaintext+j) = GetWord(ctx) ^ (*(u32*)(ciphertext+j));
		j+=4;
		if ((ctx->count)>=1024) Reinit_After_NIter(ctx);
	}
	if (rem)
	{  remWord=GetWord(ctx);
	   for (i=0;i<rem;++i) 
	   {  *(plaintext+j) = ((u8)(remWord>>(8*i))) ^ *(ciphertext+j);
	      j++;
	   }
	}
}

#endif

void ECRYPT_keysetup(
                     ECRYPT_ctx* ctx,
                     const u8* key,
                     u32 keysize,               
                     u32 ivsize) 
{
  ctx->key=key;
  ctx->keysize=keysize;
  ctx->ivsize=ivsize;
}

void ECRYPT_ivsetup(
                    ECRYPT_ctx* ctx,
                    const u8* iv)
{   int i;
 register u32 pad;
 *(u64*)(ctx->nfsr)     = *(u64*)(ctx->key);
 *(u64*)((ctx->nfsr)+2) = *(u64*)((ctx->key)+8);
 *(u64*)(ctx->lfsr)     = *(u64*)(iv);
 *(u32*)((ctx->lfsr)+2) = *(u32*)(iv+8);
 *(u32*)((ctx->lfsr)+3) =  (u32)0xFFFFFFFF;
 ctx->nptr=ctx->nfsr;
 ctx->lptr=ctx->lfsr;
 ctx->count=4;
 for(i=0; i<8; ++i)
   { pad=GetWord(ctx);
   ctx->nfsr[i+4]^=pad;
   ctx->lfsr[i+4]^=pad;
   }
}

eSTREAM Project

Powered by ViewCVS 1.0-dev
(Powered by Apache)

ViewCVS and CVS Help