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

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

Diff for /ecrypt/trunk/submissions/hc-256/hc-256.c between version 148 and 149

version 148, Mon Jan 16 09:57:10 2006 UTC version 149, Mon Jan 16 09:57:47 2006 UTC
Line 1 
Line 1 
   
 #include "ecrypt-sync.h"  #include "ecrypt-sync.h"
   
 /* ===========================================================================  /* =====================================================================
    *     The following defines the keystream generation function
                  Added functions:    HC-256 Mandatory functions   *======================================================================*/
   
 ============================================================================== */  /*h1 function*/
   #define h1(ctx, x, y) {    \
 #define f1(x)    (ROTR32((x),7) ^ ROTR32((x),18) ^ ((x) >> 3))       u8 a,b,c,d;           \
 #define f2(x)    (ROTR32((x),17) ^ ROTR32((x),19) ^ ((x) >> 10))       a = (u8) (x);         \
        b = (u8) ((x) >> 8);  \
        c = (u8) ((x) >> 16); \
        d = (u8) ((x) >> 24); \
        (y) = (ctx->T[1024+a])+(ctx->T[1024+256+b])+(ctx->T[1024+512+c])+(ctx->T[1024+768+d]); \
   }
   
   /*h2 function*/
   #define h2(ctx, x, y) {    \
        u8 a,b,c,d;           \
        a = (u8) (x);         \
        b = (u8) ((x) >> 8);  \
        c = (u8) ((x) >> 16); \
        d = (u8) ((x) >> 24); \
        (y) = (ctx->T[a])+(ctx->T[256+b])+(ctx->T[512+c])+(ctx->T[768+d]); \
   }
   
   /*one step of HC-256, update P and generate 32 bits keystream*/
   #define step_P(ctx,u,v,a,b,c,d,m){    \
        u32 tem0,tem1,tem2,tem3;         \
        tem0 = ROTR32((ctx->T[(v)]),23);           \
        tem1 = ROTR32((ctx->X[(c)]),10);           \
        tem2 = ((ctx->T[(v)]) ^ (ctx->X[(c)])) & 0x3ff;      \
        (ctx->T[(u)]) += (ctx->X[(b)])+(tem0^tem1)+(ctx->T[1024+tem2]);  \
        (ctx->X[(a)]) = (ctx->T[(u)]);                       \
        h1((ctx),(ctx->X[(d)]),tem3);                \
        (m) = tem3 ^ (ctx->T[(u)]) ;              \
   }
   
   /*one step of HC-256, update Q and generate 32 bits keystream*/
   #define step_Q(ctx,u,v,a,b,c,d,m){    \
        u32 tem0,tem1,tem2,tem3;         \
        tem0 = ROTR32((ctx->T[(v)]),23);           \
        tem1 = ROTR32((ctx->Y[(c)]),10);           \
        tem2 = ((ctx->T[(v)]) ^ (ctx->Y[(c)])) & 0x3ff;      \
        (ctx->T[(u)]) += (ctx->Y[(b)])+(tem0^tem1)+(ctx->T[tem2]);  \
        (ctx->Y[(a)]) = (ctx->T[(u)]);                       \
        h2((ctx),(ctx->Y[(d)]),tem3);                    \
        (m) = tem3 ^ (ctx->T[(u)]) ;              \
   }
   
   /*16 steps of HC-256, generate 512 bits keystream*/
   void generate_keystream(ECRYPT_ctx* ctx, u32* keystream)
   {
      u32 cc,dd;
      cc = ctx->counter2048 & 0x3ff;
      dd = (cc+16)&0x3ff;
   
 u32 h1(ECRYPT_ctx* ctx, u32 u) {     if (ctx->counter2048 < 1024)
         u32 tem;     {
         unsigned char a,b,c,d;        ctx->counter2048 = (ctx->counter2048 + 16) & 0x7ff;
         a = (unsigned char) ((u));        step_P(ctx, cc+0, cc+1, 0, 6, 13,4, keystream[0]);
         b = (unsigned char) ((u) >> 8);        step_P(ctx, cc+1, cc+2, 1, 7, 14,5, keystream[1]);
         c = (unsigned char) ((u) >> 16);        step_P(ctx, cc+2, cc+3, 2, 8, 15,6, keystream[2]);
         d = (unsigned char) ((u) >> 24);        step_P(ctx, cc+3, cc+4, 3, 9, 0, 7, keystream[3]);
         tem = ctx->Q[a]+ctx->Q[256+b]+ctx->Q[512+c]+ctx->Q[768+d];        step_P(ctx, cc+4, cc+5, 4, 10,1, 8, keystream[4]);
         return (tem);        step_P(ctx, cc+5, cc+6, 5, 11,2, 9, keystream[5]);
         step_P(ctx, cc+6, cc+7, 6, 12,3, 10,keystream[6]);
         step_P(ctx, cc+7, cc+8, 7, 13,4, 11,keystream[7]);
         step_P(ctx, cc+8, cc+9, 8, 14,5, 12,keystream[8]);
         step_P(ctx, cc+9, cc+10,9, 15,6, 13,keystream[9]);
         step_P(ctx, cc+10,cc+11,10,0, 7, 14,keystream[10]);
         step_P(ctx, cc+11,cc+12,11,1, 8, 15,keystream[11]);
         step_P(ctx, cc+12,cc+13,12,2, 9, 0, keystream[12]);
         step_P(ctx, cc+13,cc+14,13,3, 10,1, keystream[13]);
         step_P(ctx, cc+14,cc+15,14,4, 11,2, keystream[14]);
         step_P(ctx, cc+15,dd+0, 15,5, 12,3, keystream[15]);
      }
      else
      {
             ctx->counter2048 = (ctx->counter2048 + 16) & 0x7ff;
         step_Q(ctx, 1024+cc+0, 1024+cc+1, 0, 6, 13,4, keystream[0]);
         step_Q(ctx, 1024+cc+1, 1024+cc+2, 1, 7, 14,5, keystream[1]);
         step_Q(ctx, 1024+cc+2, 1024+cc+3, 2, 8, 15,6, keystream[2]);
         step_Q(ctx, 1024+cc+3, 1024+cc+4, 3, 9, 0, 7, keystream[3]);
         step_Q(ctx, 1024+cc+4, 1024+cc+5, 4, 10,1, 8, keystream[4]);
         step_Q(ctx, 1024+cc+5, 1024+cc+6, 5, 11,2, 9, keystream[5]);
         step_Q(ctx, 1024+cc+6, 1024+cc+7, 6, 12,3, 10,keystream[6]);
         step_Q(ctx, 1024+cc+7, 1024+cc+8, 7, 13,4, 11,keystream[7]);
         step_Q(ctx, 1024+cc+8, 1024+cc+9, 8, 14,5, 12,keystream[8]);
         step_Q(ctx, 1024+cc+9, 1024+cc+10,9, 15,6, 13,keystream[9]);
         step_Q(ctx, 1024+cc+10,1024+cc+11,10,0, 7, 14,keystream[10]);
         step_Q(ctx, 1024+cc+11,1024+cc+12,11,1, 8, 15,keystream[11]);
         step_Q(ctx, 1024+cc+12,1024+cc+13,12,2, 9, 0, keystream[12]);
         step_Q(ctx, 1024+cc+13,1024+cc+14,13,3, 10,1, keystream[13]);
         step_Q(ctx, 1024+cc+14,1024+cc+15,14,4, 11,2, keystream[14]);
         step_Q(ctx, 1024+cc+15,1024+dd+0, 15,5, 12,3, keystream[15]);
      }
 }  }
   
   
   /*======================================================*/
   /*   The following defines the initialization functions */
   /*======================================================*/
   
 u32 h2(ECRYPT_ctx* ctx, u32 u) {  #define f1(x)  (ROTR32((x),7) ^ ROTR32((x),18) ^ ((x) >> 3))
         u32 tem;  #define f2(x)  (ROTR32((x),17) ^ ROTR32((x),19) ^ ((x) >> 10))
         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);  
 }  
   
   
   /*update table P*/
   #define update_P(ctx,u,v,a,b,c){      \
        u32 tem0,tem1,tem2;       \
        tem0 = ROTR32((ctx->T[(v)]),23);             \
        tem1 = ROTR32((ctx->X[(c)]),10);             \
        tem2 = ((ctx->T[(v)]) ^ (ctx->X[(c)])) & 0x3ff;      \
        (ctx->T[(u)]) += (ctx->X[(b)])+(tem0^tem1)+(ctx->T[1024+tem2]);  \
        (ctx->X[(a)]) = (ctx->T[(u)]);                       \
   }
   
   /*update table Q*/
   #define update_Q(ctx,u,v,a,b,c){      \
        u32 tem0,tem1,tem2;      \
        tem0 = ROTR32((ctx->T[(v)]),23);             \
        tem1 = ROTR32((ctx->Y[(c)]),10);             \
        tem2 = ((ctx->T[(v)]) ^ (ctx->Y[(c)])) & 0x3ff;      \
        (ctx->T[(u)]) += (ctx->Y[(b)])+(tem0^tem1)+(ctx->T[tem2]);  \
        (ctx->Y[(a)]) = (ctx->T[(u)]);                       \
   }
   
 u32 generate(ECRYPT_ctx* ctx) /*one step of the cipher*/  /*16 steps of HC-256, without generating keystream*/
   void setup_update(ECRYPT_ctx* ctx)  /*each time 16 steps*/
 {  {
                 u32 i,i3, i10, i12, i1023;     u32 cc,dd;
                 u32 output;     cc = ctx->counter2048 & 0x3ff;
      dd = (cc+16)&0x3ff;
                 i   = ctx->counter2048 & 0x3ff;  
                 i3  = (i - 3) & 0x3ff;  
                 i10 = (i - 10) & 0x3ff;  
                 i12 = (i - 12) & 0x3ff;  
                 i1023 = (i - 1023) & 0x3ff;  
   
                 if (ctx->counter2048 < 1024) {     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];        ctx->counter2048 = (ctx->counter2048 + 16) & 0x7ff;
         update_P(ctx, cc+0, cc+1, 0, 6, 13);
         update_P(ctx, cc+1, cc+2, 1, 7, 14);
         update_P(ctx, cc+2, cc+3, 2, 8, 15);
         update_P(ctx, cc+3, cc+4, 3, 9, 0);
         update_P(ctx, cc+4, cc+5, 4, 10,1);
         update_P(ctx, cc+5, cc+6, 5, 11,2);
         update_P(ctx, cc+6, cc+7, 6, 12,3);
         update_P(ctx, cc+7, cc+8, 7, 13,4);
         update_P(ctx, cc+8, cc+9, 8, 14,5);
         update_P(ctx, cc+9, cc+10,9, 15,6);
         update_P(ctx, cc+10,cc+11,10,0, 7);
         update_P(ctx, cc+11,cc+12,11,1, 8);
         update_P(ctx, cc+12,cc+13,12,2, 9);
         update_P(ctx, cc+13,cc+14,13,3, 10);
         update_P(ctx, cc+14,cc+15,14,4, 11);
         update_P(ctx, cc+15,dd+0, 15,5, 12);
                 }                  }
                 else {     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 + 16) & 0x7ff;
         update_Q(ctx, 1024+cc+0, 1024+cc+1, 0, 6, 13);
         update_Q(ctx, 1024+cc+1, 1024+cc+2, 1, 7, 14);
         update_Q(ctx, 1024+cc+2, 1024+cc+3, 2, 8, 15);
         update_Q(ctx, 1024+cc+3, 1024+cc+4, 3, 9, 0);
         update_Q(ctx, 1024+cc+4, 1024+cc+5, 4, 10,1);
         update_Q(ctx, 1024+cc+5, 1024+cc+6, 5, 11,2);
         update_Q(ctx, 1024+cc+6, 1024+cc+7, 6, 12,3);
         update_Q(ctx, 1024+cc+7, 1024+cc+8, 7, 13,4);
         update_Q(ctx, 1024+cc+8, 1024+cc+9, 8, 14,5);
         update_Q(ctx, 1024+cc+9, 1024+cc+10,9, 15,6);
         update_Q(ctx, 1024+cc+10,1024+cc+11,10,0, 7);
         update_Q(ctx, 1024+cc+11,1024+cc+12,11,1, 8);
         update_Q(ctx, 1024+cc+12,1024+cc+13,12,2, 9);
         update_Q(ctx, 1024+cc+13,1024+cc+14,13,3, 10);
         update_Q(ctx, 1024+cc+14,1024+cc+15,14,4, 11);
         update_Q(ctx, 1024+cc+15,1024+dd+0, 15,5, 12);
                 }                  }
                 ctx->counter2048 = (ctx->counter2048+1) & 0x7ff;  
                 return (output);  
 }  }
   
   
   
   
   
 void ECRYPT_init(void) {  void ECRYPT_init(void) {
 }  /* No operation performed */  }  /* No operation performed */
   
   
   /* for the 256-bit key:  key[0]...key[32]
   *  key[0] is the least significant byte of ctx->key[0] (K_0);
   *  key[3] is the most significant byte of ctx->key[0]  (K_0);
   *  ...
   *  key[28] is the least significant byte of ctx->key[8] (K_8)
   *  key[31] is the most significant byte of ctx->key[8]  (K_8)
   *
   *  for the 256-bit iv:  iv[0]...iv[32]
   *  iv[0] is the least significant byte of ctx->iv[0] (IV_0);
   *  iv[3] is the most significant byte of ctx->iv[0]  (IV_0);
   *  ...
   *  iv[28] is the least significant byte of ctx->iv[8] (IV_8)
   *  iv[31] is the most significant byte of ctx->iv[8]  (IV_8)
   */
   
 void ECRYPT_keysetup(  void ECRYPT_keysetup(
   ECRYPT_ctx* ctx,    ECRYPT_ctx* ctx,
   const u8* key,    const u8* key,
   u32 keysize,                /* Key size in bits. */    u32 keysize,                /* Key size in bits (128+128*i) */
   u32 ivsize)                 /* IV size in bits. */    u32 ivsize)                 /* IV size in bits  (128+128*i)*/
 {  {
   u32 i;    u32 i;
   
   ctx->keysize = keysize >> 3;    ctx->keysize = keysize;
   ctx->ivsize = ivsize >> 3;    ctx->ivsize = ivsize;
   
   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*/    /* Key size in bits (128+128*i) */
     for (i = 0; i < (keysize >> 5); i++) ctx->key[i] = U32TO32_LITTLE (((u32*)key)[i]);
   
     for ( ; i < 8 ; i++) ctx->key[i] = ctx->key[i-4];
   
   } /* initialize the key, save the iv size*/
   
   
 void ECRYPT_ivsetup(  void ECRYPT_ivsetup(ECRYPT_ctx* ctx, const u8* iv)
   ECRYPT_ctx* ctx,  
   const u8* iv)  
 {  {
     u32 W[2560],i;      u32 i;
   
     /* initialize the iv */      /* initialize the iv */
     for (i = 0; i < 8; i++) ctx->iv[i] = 0;      /* IV size in bits  (128+128*i)*/
     for (i = 0; (i < ctx->ivsize) & (i < 32); i++) {  
                 ctx->iv[i >> 2] =  ctx->iv[i >> 2] | iv[i];          for (i = 0; i < (ctx->ivsize >> 5); i++)  ctx->iv[i] = U32TO32_LITTLE(((u32*)iv)[i]);
                 ctx->iv[i >> 2] = ROTL32(ctx->iv[i >> 2],8);  
     }      for (; i < 8; i++) ctx->iv[i] = ctx->iv[i-4];
   
     /* setup the table P and Q */      /* expand the key and IV into the table T */
       /* (expand the key and IV into the table P and Q) */
   
         for (i = 0; i < 8;  i++) W[i] = ctx->key[i];          for (i = 0; i < 8;  i++)   ctx->T[i] = ctx->key[i];
         for (i = 8; i < 16; i++) W[i] = ctx->iv[i-8];          for (i = 8; i < 16; i++)   ctx->T[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 = 16; i < 528; i++)
                   ctx->T[i] = f2(ctx->T[i-2]) + ctx->T[i-7] + f1(ctx->T[i-15]) + ctx->T[i-16]+i;
   
         for (i = 0; i < 1024; i++)  ctx->P[i] = W[i+512];          for (i = 0; i < 16;  i++)  ctx->T[i] = ctx->T[512+i];
         for (i = 0; i < 1024; i++)  ctx->Q[i] = W[i+1536];  
   
           for (i = 16; i < 2048; i++)
                   ctx->T[i] = f2(ctx->T[i-2]) + ctx->T[i-7] + f1(ctx->T[i-15]) + ctx->T[i-16]+512+i;
   
       /* initialize counter2048, X and Y */
         ctx->counter2048 = 0;          ctx->counter2048 = 0;
           for (i = 0; i < 16; i++) ctx->X[i] = ctx->T[1008+i];
       for (i = 0; i < 16; i++) ctx->Y[i] = ctx->T[1024+1008+i];
   
       /* run the cipher 4096 steps before generating the output */        /* run the cipher 4096 steps before generating the output */
         for (i = 0; i < 4096; i++)  generate(ctx);          for (i = 0; i < 256; i++)  setup_update(ctx);
 }  }
   
   /*========================================================
    *  The following defines the encryption of data stream
    *  (same as the benchamrk implementation of SNOW-2.0)
    *========================================================
    */
   
 void ECRYPT_process_bytes(  void ECRYPT_process_bytes(
   int action,                 /* 0 = encrypt; 1 = decrypt; */    int action,                 /* 0 = encrypt; 1 = decrypt; */
Line 129 
Line 260 
   u8* output,    u8* output,
   u32 msglen)                /* Message length in bytes. */    u32 msglen)                /* Message length in bytes. */
 {  {
   u32 i, j, msglen32, keystreamword;    u32 i, keystream[16];
   
   msglen32 = msglen >> 2;    for ( ; msglen >= 64; msglen -= 64, input += 64, output += 64)
     {
             generate_keystream(ctx, keystream);
   
   for (i = 0; i < msglen32; i++) {        for (i = 0; i < 16; ++i)
       keystreamword = generate(ctx);                 /*generate a 32-bit word*/                ((u32*)output)[i] = ((u32*)input)[i] ^ U32TO32_LITTLE(keystream[i]);
       for (j = 0; j < 4; j++) {  
               *output = *input ^ keystreamword;       /*encrypt one byte*/  
           output += 1;  
           input +=1;  
                   keystreamword = keystreamword >> 8;  
           }  
   }    }
   
   if (msglen & 3)    if (msglen > 0)
     {      {
       keystreamword = generate(ctx);        generate_keystream(ctx, keystream);
       for (i = 0; i < (msglen & 3); i++) {  
         *output = *input ^ keystreamword;       /*encrypt one byte*/        for (i = 0; i < msglen; i ++)
         output += 1;                output[i] = input[i] ^ ((u8*)keystream)[i];
         input +=1;  
         keystreamword = keystreamword >> 8;  
       }  
     }      }
 }  }
   


Generate output suitable for use with a patch program
Legend:
Removed from v.148  
changed lines
  Added in v.149

eSTREAM Project

Powered by ViewCVS 1.0-dev
(Powered by Apache)

ViewCVS and CVS Help