メインページ | アルファベット順一覧 | 構成 | ファイル一覧 | 構成メンバ | ファイルメンバ | 関連ページ

dkcHC256.c

説明を見る。
00001 
00023 #include "dkcHC256.h"
00024 
00025 #include <stdlib.h>
00026 
00027 /*
00028 uint32 P[1024],Q[1024];
00029 uint32 X[16],Y[16];
00030 uint32 counter2048; // counter2048 = i mod 2048;
00031 */
00032 #ifndef _MSC_VER
00033 #define rotr(x,n)   (((x)>>(n))|((x)<<(32-(n))))
00034 #else
00035 #define rotr(x,n)   _lrotr(x,n)
00036 #endif
00037 
00038 
00039 static DKC_INLINE uint32 h1(uint32 *Q,uint32 x){
00040     DKC_4BYTE_UNION_LITTLE_ENDIAN_BASE a;
00041     a.dword = x;
00042     return Q[a.w.byte0] +
00043         Q[256+a.w.byte1] +
00044         Q[512+a.w.byte2] +
00045         Q[768+a.w.byte3];
00046 }
00047 
00048 static DKC_INLINE uint32 h2(uint32 *P,uint32 x){
00049     DKC_4BYTE_UNION_LITTLE_ENDIAN_BASE a;
00050     a.dword = x;
00051   return P[a.w.byte0] +
00052         P[256+a.w.byte1] +
00053         P[512+a.w.byte2] +
00054         P[768+a.w.byte3];
00055 }
00056 
00057 static DKC_INLINE uint32 g1(uint32 *Q,uint32 x,uint32 y){
00058     uint32 a,b,c;
00059     a = rotr((x),10);
00060     b = rotr((y),23);
00061     c = ((x)^(y))&0x3ff;
00062     return (a^b) + Q[c];
00063 }
00064 static DKC_INLINE uint32 g2(uint32 *P,uint32 x,uint32 y){
00065     uint32 a,b,c;
00066     a = rotr((x),10);
00067     b = rotr((y),23);
00068     c = ((x)^(y))&0x3ff;
00069     return (a^b) + P[c];
00070 }
00071 
00072 #define feedback_1(u,v,b,c) {        \
00073    uint32 tem0,tem1,tem2;          \
00074    tem0 = rotr((v),23);             \
00075    tem1 = rotr((c),10);            \
00076    tem2 = ((v) ^ (c)) & 0x3ff;     \
00077    (u) += (b)+(tem0^tem1)+Q[tem2]; \
00078 }       
00079 
00080 #define feedback_2(u,v,b,c) {        \
00081    uint32 tem0,tem1,tem2;          \
00082    tem0 = rotr((v),23);             \
00083    tem1 = rotr((c),10);            \
00084    tem2 = ((v) ^ (c)) & 0x3ff;     \
00085    (u) += (b)+(tem0^tem1)+P[tem2]; \
00086 }      
00087 static DKC_INLINE uint32 fb1(uint32 *Q,uint32 u,uint32 v,uint32 b,uint32 c){
00088      uint32 tem0,tem1,tem2;          
00089    tem0 = rotr((v),23);             
00090    tem1 = rotr((c),10);            
00091    tem2 = ((v) ^ (c)) & 0x3ff;    
00092    (u) += (b)+(tem0^tem1)+Q[tem2];
00093      return u;
00094 }
00095 static DKC_INLINE uint32 fb2(uint32 *P,uint32 u,uint32 v,uint32 b,uint32 c){
00096     uint32 tem0,tem1,tem2;          
00097     tem0 = rotr((v),23);             
00098     tem1 = rotr((c),10);               
00099     tem2 = ((v) ^ (c)) & 0x3ff;     
00100     (u) += (b)+(tem0^tem1)+P[tem2]; 
00101     return u;
00102 }
00103 static DKC_INLINE void fb1_(uint32 *Q,uint32 *u,uint32 v,uint32 b,uint32 c){
00104      uint32 tem0,tem1,tem2;          
00105    tem0 = rotr((v),23);             
00106    tem1 = rotr((c),10);            
00107    tem2 = ((v) ^ (c)) & 0x3ff;     
00108    (*u) += (b)+(tem0^tem1)+Q[tem2]; 
00109 }
00110 static DKC_INLINE void fb2_(uint32 *P,uint32 *u,uint32 v,uint32 b,uint32 c){
00111     uint32 tem0,tem1,tem2;          
00112     tem0 = rotr((v),23);             
00113     tem1 = rotr((c),10);               
00114     tem2 = ((v) ^ (c)) & 0x3ff;     
00115     (*u) += (b)+(tem0^tem1)+P[tem2]; 
00116 }
00117 #define f1(x)  (rotr((x),7) ^ rotr((x),18) ^ ((x) >> 3))
00118 #define f2(x)  (rotr((x),17) ^ rotr((x),19) ^ ((x) >> 10))
00119 #define f(a,b,c,d) (f2((a)) + b + f1((c)) + d) 
00120 
00121 void initialization(DKC_HC256 *p,uint32 key[], uint32 iv[]) 
00122 {
00123     uint32 i,j;
00124     uint32 *P = p->P;
00125     uint32 *Q = p->Q;
00126 
00127     //expand the key and iv into P and Q
00128     for (i = 0; i < 8; i++)     P[i] = key[i];
00129     for (i = 8; i < 16; i++)    P[i] = iv[i-8]; 
00130 
00131     for (i = 16; i < 528; i++)  
00132          P[i] = f(P[i-2],P[i-7],P[i-15],P[i-16])+i;
00133     for (i = 0; i < 16; i++)    
00134          P[i] = P[i+512];
00135     for (i = 16; i < 1024; i++) 
00136          P[i] = f(P[i-2],P[i-7],P[i-15],P[i-16])+512+i;
00137 
00138     for (i = 0;  i < 16;  i++)  
00139          Q[i] = P[1024-16+i];
00140     for (i = 16; i < 32;  i++)  
00141          Q[i] = f(Q[i-2],Q[i-7],Q[i-15],Q[i-16])+1520+i;
00142     for (i = 0;  i < 16;  i++)  
00143          Q[i] = Q[i+16];
00144     for (i = 16; i < 1024;i++)  
00145          Q[i] = f(Q[i-2],Q[i-7],Q[i-15],Q[i-16])+1536+i;
00146 
00147     //run the cipher 4096 steps without generating output   
00148     for (i = 0; i < 2; i++) {
00149 #if 1
00150         for (j = 0;  j < 10;   j++)  
00151              fb1_(Q,&P[j],P[j+1],P[(j-10)&0x3ff],P[(j-3)&0x3ff]);
00152         for (j = 10; j < 1023; j++)  
00153              fb1_(Q,&P[j],P[j+1],P[j-10],P[j-3]);
00154         fb1_(Q,&P[1023],P[0],P[1013],P[1020]);
00155         for (j = 0;  j < 10;   j++)  
00156              fb2_(P,&Q[j],Q[j+1],Q[(j-10)&0x3ff],Q[(j-3)&0x3ff]);
00157         for (j = 10; j < 1023; j++)  
00158              fb2_(P,&Q[j],Q[j+1],Q[j-10],Q[j-3]);
00159         fb2_(P,&Q[1023],Q[0],Q[1013],Q[1020]);  
00160         /*
00161         for (j = 0;  j < 10;   j++)  
00162              P[j] = fb1(P,P[j],P[j+1],P[(j-10)&0x3ff],P[(j-3)&0x3ff]);
00163         for (j = 10; j < 1023; j++)  
00164              P[j] = fb1(P,P[j],P[j+1],P[j-10],P[j-3]);
00165              P[1023] = fb1(P,P[1023],P[0],P[1013],P[1020]);
00166         for (j = 0;  j < 10;   j++)  
00167              Q[j] = fb2(Q,Q[j],Q[j+1],Q[(j-10)&0x3ff],Q[(j-3)&0x3ff]);
00168         for (j = 10; j < 1023; j++)  
00169              Q[j] =fb2(Q,Q[j],Q[j+1],Q[j-10],Q[j-3]);
00170              Q[1023] =fb2(Q,Q[1023],Q[0],Q[1013],Q[1020]);  
00171         */
00172 #else
00173         for (j = 0;  j < 10;   j++)  
00174             feedback_1(P[j],P[j+1],P[(j-10)&0x3ff],P[(j-3)&0x3ff]);
00175         for (j = 10; j < 1023; j++)  
00176             feedback_1(P[j],P[j+1],P[j-10],P[j-3]);
00177         feedback_1(P[1023],P[0],P[1013],P[1020]);
00178         for (j = 0;  j < 10;   j++)  
00179             feedback_2(Q[j],Q[j+1],Q[(j-10)&0x3ff],Q[(j-3)&0x3ff]);
00180         for (j = 10; j < 1023; j++)  
00181             feedback_2(Q[j],Q[j+1],Q[j-10],Q[j-3]);
00182         feedback_2(Q[1023],Q[0],Q[1013],Q[1020]); 
00183 #endif
00184     }
00185 
00186     //initialize counter2048, and tables X and Y 
00187     p->counter2048 = 0;
00188     for (i = 0; i < 16; i++) p->X[i] = P[1008+i];
00189     for (i = 0; i < 16; i++) p->Y[i] = Q[1008+i];
00190 }   
00191 
00192 DKC_INLINE DKC_HC256 *WINAPI dkcAllocHC256(BYTE *key,size_t size){
00193     DKC_HC256 *p;
00194     uint32 iv[8];
00195     if(size != sizeof(uint32) * 8){
00196         return NULL;
00197     }
00198     
00199     p = dkcAllocate(sizeof(DKC_HC256));
00200     if(NULL==p){
00201         return NULL;
00202     }
00203     DKUTIL_MEMZERO(iv,sizeof(iv));
00204     initialization(p,(uint32 *)key,iv);
00205     return p;
00206 }
00207 
00208 
00209 
00210 DKC_INLINE int WINAPI dkcFreeHC256(DKC_HC256 **p){
00211     return dkcFree(p);
00212 }
00213 
00214 
00215 
00216 DKC_INLINE uint32 dkcHC256Process(DKC_HC256 *p,uint32 u) 
00217 {
00218     unsigned long i,i3, i10, i12, i1023;
00219     unsigned long output;
00220 
00221     i   = p->counter2048 & 0x3ff;
00222     i3  = (i - 3) & 0x3ff;
00223     i10 = (i - 10) & 0x3ff;
00224     i12 = (i - 12) & 0x3ff;
00225     i1023 = (i - 1023) & 0x3ff;
00226 
00227     if (p->counter2048 < 1024) {
00228         p->P[i] = p->P[i] + p->P[i10] + g1(p->Q,p->P[i3],p->P[i1023]);
00229         output = h1(p->Q,p->P[i12]) ^ p->P[i];
00230     }
00231     else {
00232         p->Q[i] = p->Q[i] + p->Q[i10] + g2(p->P,p->Q[i3],p->Q[i1023]);
00233         output = h2(p->P,p->Q[i12]) ^ p->Q[i];
00234 
00235     }
00236     p->counter2048 = (p->counter2048+1) & 0x7ff;
00237     return (output);
00238 }
00239 
00240 
00241 static DKC_INLINE void step_A(DKC_HC256 *p,uint32 u,uint32 v,
00242                                                             uint32 a,uint32 b,uint32 c,uint32 d,uint32 *m)
00243 {
00244     uint32 tem0,tem1,tem2,tem3;
00245     tem0 = rotr((v),23);
00246     tem1 = rotr((c),10);
00247     tem2 = ((v) ^ (c)) & 0x3ff;
00248     (u) += (b)+(tem0^tem1) + p->Q[tem2];
00249     (a) = (u);
00250     tem3 = h1(p->P,d);
00251     //h1(p->Q,(d),tem3);                    
00252     (*m) ^= tem3 ^ (u) ;              
00253 }
00254 static DKC_INLINE step_B(DKC_HC256 *p,uint32 u,uint32 v,
00255                                                             uint32 a,uint32 b,uint32 c,uint32 d,uint32 *m){
00256     uint32 tem0,tem1,tem2,tem3;      
00257     tem0 = rotr((v),23);              
00258     tem1 = rotr((c),10);             
00259     tem2 = ((v) ^ (c)) & 0x3ff;      
00260     (u) += (b)+(tem0^tem1)+p->P[tem2];  
00261     (a) = (u);
00262     tem3 = h2(p->P,d);
00263     //h2(p->P,(d),tem3);                    
00264     (*m) ^= tem3 ^ (u) ;              
00265 }       
00266 
00267 
00268 static void encrypt(DKC_HC256 *p,uint32 data[])  //each time it encrypts 512-bit data
00269 {
00270     uint32 cc,dd,counter2048 = p->counter2048;
00271     uint32 *P = p->P,*Q = p->Q,*X =p->X, *Y = p->Y;
00272 
00273     cc = counter2048 & 0x3ff;
00274     dd = (cc+16) & 0x3ff;
00275 
00276     if (counter2048 < 1024) 
00277     {           
00278         counter2048 = (counter2048 + 16) & 0x7ff;
00279         step_A(p,P[cc+0], P[cc+1], X[0], X[6], X[13],X[4], &data[0]);
00280         step_A(p,P[cc+1], P[cc+2], X[1], X[7], X[14],X[5], &data[1]);
00281         step_A(p,P[cc+2], P[cc+3], X[2], X[8], X[15],X[6], &data[2]);
00282         step_A(p,P[cc+3], P[cc+4], X[3], X[9], X[0], X[7], &data[3]);
00283         step_A(p,P[cc+4], P[cc+5], X[4], X[10],X[1], X[8], &data[4]);
00284         step_A(p,P[cc+5], P[cc+6], X[5], X[11],X[2], X[9], &data[5]);
00285         step_A(p,P[cc+6], P[cc+7], X[6], X[12],X[3], X[10],&data[6]);
00286         step_A(p,P[cc+7], P[cc+8], X[7], X[13],X[4], X[11],&data[7]);
00287         step_A(p,P[cc+8], P[cc+9], X[8], X[14],X[5], X[12],&data[8]);
00288         step_A(p,P[cc+9], P[cc+10],X[9], X[15],X[6], X[13],&data[9]);
00289         step_A(p,P[cc+10],P[cc+11],X[10],X[0], X[7], X[14],&data[10]);
00290         step_A(p,P[cc+11],P[cc+12],X[11],X[1], X[8], X[15],&data[11]);
00291         step_A(p,P[cc+12],P[cc+13],X[12],X[2], X[9], X[0], &data[12]);
00292         step_A(p,P[cc+13],P[cc+14],X[13],X[3], X[10],X[1], &data[13]);
00293         step_A(p,P[cc+14],P[cc+15],X[14],X[4], X[11],X[2], &data[14]);
00294         step_A(p,P[cc+15],P[dd+0], X[15],X[5], X[12],X[3], &data[15]);
00295     }
00296     else                    
00297     {
00298         counter2048 = (counter2048 + 16) & 0x7ff;
00299         step_B(p,Q[cc+0], Q[cc+1], Y[0], Y[6], Y[13],Y[4], &data[0]);
00300         step_B(p,Q[cc+1], Q[cc+2], Y[1], Y[7], Y[14],Y[5], &data[1]);
00301         step_B(p,Q[cc+2], Q[cc+3], Y[2], Y[8], Y[15],Y[6], &data[2]);
00302         step_B(p,Q[cc+3], Q[cc+4], Y[3], Y[9], Y[0], Y[7], &data[3]);
00303         step_B(p,Q[cc+4], Q[cc+5], Y[4], Y[10],Y[1], Y[8], &data[4]);
00304         step_B(p,Q[cc+5], Q[cc+6], Y[5], Y[11],Y[2], Y[9], &data[5]);
00305         step_B(p,Q[cc+6], Q[cc+7], Y[6], Y[12],Y[3], Y[10],&data[6]);
00306         step_B(p,Q[cc+7], Q[cc+8], Y[7], Y[13],Y[4], Y[11],&data[7]);
00307         step_B(p,Q[cc+8], Q[cc+9], Y[8], Y[14],Y[5], Y[12],&data[8]);
00308         step_B(p,Q[cc+9], Q[cc+10],Y[9], Y[15],Y[6], Y[13],&data[9]);
00309         step_B(p,Q[cc+10],Q[cc+11],Y[10],Y[0], Y[7], Y[14],&data[10]);
00310         step_B(p,Q[cc+11],Q[cc+12],Y[11],Y[1], Y[8], Y[15],&data[11]);
00311         step_B(p,Q[cc+12],Q[cc+13],Y[12],Y[2], Y[9], Y[0], &data[12]);
00312         step_B(p,Q[cc+13],Q[cc+14],Y[13],Y[3], Y[10],Y[1], &data[13]);
00313         step_B(p,Q[cc+14],Q[cc+15],Y[14],Y[4], Y[11],Y[2], &data[14]);
00314         step_B(p,Q[cc+15],Q[dd+0], Y[15],Y[5], Y[12],Y[3], &data[15]);
00315     }
00316 
00317     p->counter2048 = counter2048;
00318 }
00319 
00320 DKC_INLINE int WINAPI dkcHC256EncryptBlock512NoDestDOE(DKC_HC256 *p,BYTE *dest,size_t size){
00321     dkcmNOT_ASSERT(NULL==p || NULL==dest);
00322     if(size != 512){
00323         return edk_ArgumentException;
00324     }
00325     encrypt(p,(uint32 *)dest);
00326     return edk_SUCCEEDED;
00327 }
00328 
00329 DKC_INLINE int WINAPI dkcHC256EncryptBlock512DOE(DKC_HC256 *p,BYTE *dest,size_t dsize,const BYTE *src,size_t ssize)
00330 {   
00331     dkcmNOT_ASSERT(NULL==p || NULL==dest || NULL==src);
00332     if(ssize != 512 || dsize < 512){
00333         return edk_ArgumentException;
00334     }
00335     memcpy(dest,src,ssize);
00336     return dkcHC256EncryptBlock512NoDestDOE(p,dest,ssize);
00337 }
00338 
00339 
00340 

dkutil_cに対してTue Feb 22 02:01:47 2005に生成されました。 doxygen 1.3.6