www.pudn.com > IDEA1.rar > IDEA_TIME_TEST.C


/*                                                                     */ 
/* block cipher IDEA and sample data    for   A3 & A5 in GSM           */ 
/*                                             1993.8.14. BY HDK       */ 
/*                                                                     */ 
# include 
# include 
# include 
# include 
# include 
# include 
# define maxim 65537 
# define fuyi  65536 
# define one   65535 
# define round     8 
/*                                                                     */ 
void cip ( unsigned IN[5], unsigned OUT[5], unsigned Z[7][10] ); 
void key ( short unsigned uskey[9], unsigned Z[7][10] ); 
void de_key ( unsigned Z[7][10], unsigned DK[7][10] ); 
unsigned inv ( unsigned xin ); 
unsigned mul ( unsigned a, unsigned b); 
/*                                                                     */ 
/*        MAIN PROG.-SEG.                                              */ 
/*                                                                     */ 
main() 
{ 
  int i,j,k,x; 
  long int loop,n; 
  unsigned Z[7][10], DK[7][10], XX[5], TT[5], YY[5]; 
  short unsigned uskey[9]; 
  long int t1,t2; 
  long  s; 
  FILE *f; 
/*                                                                     */ 
/*         begin  running !                                            */ 
 
    for ( i =1; i<=8; i++ ) uskey[i]=i; 
    key(uskey,Z);           /*   generate encryption subkeys Z[i][r]   */ 
    printf("\n encryption keys    Z1     Z2     Z3     Z4     Z5     Z6 "); 
  for ( j =1; j<=9; j++ ) { printf("\n %3d-th round  ", j); 
      if (j==9) for (i=1;i<=4;i++ )    printf(" %6u",Z[i][j]); 
          else  for (i=1;i<=6;i++ )    printf(" %6u",Z[i][j]); 
                 } 
    de_key(Z,DK);            /*   compute decryption subkeys DK[i][r]  */ 
    printf("\n \n decryption keys   DK1    DK2    DK3    DK4    DK5    DK6 "); 
  for ( j =1; j<=9; j++ ) { printf("\n %3d-th round  ", j); 
      if (j==9) for (i=1;i<=4;i++ ) printf(" %6u",DK[i][j]); 
          else  for (i=1;i<=6;i++ ) printf(" %6u",DK[i][j]); 
                 } 
/*  give a plaintext                                                   */ 
    for (x=1; x<=4; x++) XX[x]=x-1; 
    printf("\n \n plaintext  X  %6u   %6u   %6u   %6u   \n", 
                 XX[1], XX[2], XX[3], XX[4]); 
    cip(XX,YY,Z);             /*     encipher XX to YY with key Z      */ 
    printf("\n \n ciphertext Y  %6u   %6u   %6u   %6u   \n", 
                  YY[1], YY[2], YY[3], YY[4]); 
    cip(YY,TT,DK);            /*     decipher YY to TT with key DK     */ 
    printf("\n \n result     T  %6u   %6u   %6u   %6u   \n", 
                 TT[1], TT[2], TT[3], TT[4]); 
    n=10000; 
    f=fopen("IDEA_RUN.REC","w"); 
    t1=time(&s); 
    printf("\n begin in %10u  seconds,",time(&s)); 
for (loop=1; loop<=n; loop++ ) 
    {  for (x=1; x<=4; x++) XX[x]=x-1; 
    cip(XX,YY,Z);             /*     encipher XX to YY with key Z      */ 
    }   t2=time(&s); 
    printf("   end in %10u seconds. \n ",time(&s)); 
printf("It spends %4d seconds",t2-t1); 
printf(" to run the IDEA %6u times ! \n",n); 
fprintf(f,"It spends %4d seconds",t2-t1); 
fprintf(f," to run the IDEA %6u times in  pc-X86  ! \n",n); 
  fclose(f); 
getche(); 
 
} 
/*       after delay , end the main prog.                              */ 
/*       after delay , end the main prog.                              */ 
/*       after delay , end the main prog.                              */ 
/*                                              1993.3.24.  by HDK     */ 
/*                                                                     */ 
/*                                                                     */ 
/*                                                                     */ 
/* (1) encryption algorithm                     passed !               */ 
/*                                                                     */ 
void cip ( unsigned IN[5], unsigned OUT[5], unsigned Z[7][10] ) 
{ 
      unsigned  int r, x1, x2, x3, x4, kk, t1, t2, a; 
/* 
 printf("   after                                                   "); 
 */ 
    x1=IN[1]; x2=IN[2]; x3=IN[3]; x4=IN[4]; 
    for (r=1; r<=8; r++)   /*  the round function  */ 
    { 
        /*   the group operation on 64-bits block  */ 
        x1 = mul(x1,Z[1][r]);        x4 = mul(x4,Z[4][r]); 
        x2 = (x2 + Z[2][r]) & one;     x3 = ( x3 + Z[3][r] ) & one; 
        /*   the function of the MA structure      */ 
        kk = mul( Z[5][r], (x1^x3) ); 
        t1 = mul( Z[6][r], ( kk + (x2^x4)) & one ); 
        t2 = ( kk + t1 ) & one; 
        /*   the involutary permutation PI         */ 
        x1 = x1^t1;    x4 = x4^t2; 
         a = x2^t2;    x2 = x3^t1;   x3 = a; 
/* 
printf("\n    %1u-th rnd  %6u  %6u  %6u  %6u  ",  r,  x1,  x2,  x3,  x4); 
*/     } 
        /*   the output transformation            */ 
    OUT[1] = mul (x1, Z[1][round+1] ); 
    OUT[4] = mul (x4, Z[4][round+1] ); 
    OUT[2] = (x3 + Z[2][round+1] ) & one; 
    OUT[3] = (x2 + Z[3][round+1] ) & one; 
} 
/*                                                                     */ 
/* (2)  the multiplication  using the Low-High algorithm               */ 
/*                                                         passed !    */ 
unsigned mul ( unsigned a, unsigned b) 
 
{       long int p; 
    long unsigned q; 
    if ( a==0 ) p = maxim-b; 
       else if ( b==0 )  p = maxim-a;  else 
  {   q=(unsigned long)a*(unsigned long)b; 
      p=(q & one) - (q>>16);  if (p<=0) p=p+maxim; 
    } 
    return ( unsigned ) ( p & one ); 
} 
/*  end the multiplication  using the Low-High algorithm               */ 
/*                                                                     */ 
/*                                                                     */ 
/* (3)  compute inverse of integer xin by Euclidean gcd algorithm      */ 
/*                                                       passed !      */ 
unsigned inv ( unsigned xin) 
{ 
    long  n1, n2, q, r, b1, b2, t; 
    if ( xin == 0 ) b2 = 0; 
    else { 
          n1=maxim; n2=xin; b2=1; b1=0; 
          do { r = (n1 % n2); q = (n1-r)/n2; 
           if ( r== 0) { if ( b2<0 ) b2 = maxim+b2; } 
            else { n1=n2; n2=r; t=b2; b2=b1-q*b2; b1=t; } 
          } while ( r !=0 ); 
           } 
    return ( unsigned) b2; 
} 
/*                                                                     */ 
/*  end compute inverse of integer xin by Euclidean gcd algorithm      */ 
/*                                                                     */ 
/*                                                                     */ 
/* (4)  genarate encryption subkeys Z's          passed !              */ 
/*                                                                     */ 
void key ( short unsigned uskey[9], unsigned Z[7][10] ) 
{ 
    short unsigned  S[54]; 
    int i,j,r; 
    for ( i =1; i<9; i++ ) S[i-1] = uskey[i]; 
     /*    shifts     */ 
    for ( i = 8; i<54; i++ ) 
     { 
        if ( (i+2)%8 == 0)      /* for S[14], S[22], ... */ 
            S[i] = ( S[i-7]<<9 )^( S[i-14]>>7 ) & one; 
        else if ( (i+1)%8 == 0)  /* for S[15], S[23], .. */ 
            S[i] = ( S[i-15]<<9 )^( S[i-14]>>7 ) & one; 
                 else               /* for other  S[i]       */ 
            S[i] = ( S[i-7]<<9 )^( S[i-6]>>7 ) & one; 
        } 
     /*  get subkeys    */ 
    for ( r=1; r<=round+1; r++ )  for ( j=1; j<7; j++ ) 
        Z[j][r] = S[ 6*(r-1) + j-1]; 
} 
/*                                                                     */ 
/* end  genarate encryption subkeys Z's                                */ 
/*                                                                     */ 
/*                                                                     */ 
/* (5)  compute  decryption  subkey  DK's         passed !             */ 
/*                                                                     */ 
void de_key ( unsigned Z[7][10], unsigned DK[7][10] ) 
{ 
    int j; 
    for ( j = 1; j<=round+1; j++ ) 
    {  DK[1][round-j+2] = inv (Z[1][j]); 
       DK[4][round-j+2] = inv (Z[4][j]); 
     if (j==1 || j==round+1 ) { 
       DK[2][round-j+2] = ( fuyi-Z[2][j] ) & one; 
       DK[3][round-j+2] = ( fuyi-Z[3][j] ) & one; 
        		   } 
      else { 
       DK[2][round-j+2] = ( fuyi-Z[3][j] ) & one; 
       DK[3][round-j+2] = ( fuyi-Z[2][j] ) & one; 
        		   } 
      } 
    for ( j=1; j<=round+1; j++ ) 
    { DK[5][round+1-j] = Z[5][j];  DK[6][round+1-j] = Z[6][j]; } 
} 
/*                                                                     */ 
/* end  compute  decryption  subkey  DK's                              */ 
/*                                                                     */ 
/*          END ALL PROGRAM IDEA BY LAI                  1993.3.24.    */ 
/*                                                         BY HDK      */