SNAP Library 2.1, Developer Reference  2013-09-25 10:47:25
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
md5.cpp
Go to the documentation of this file.
00001 
00002 // MD5
00003 void TMd5::Init(){
00004   DefP=false; // we just started!
00005 
00006   // Nothing counted, so count=0
00007   count[0]=0;
00008   count[1]=0;
00009 
00010   // Load magic initialization constants.
00011   state[0]=0x67452301;
00012   state[1]=0xefcdab89;
00013   state[2]=0x98badcfe;
00014   state[3]=0x10325476;
00015 }
00016 
00017 // MD5 basic transformation. Transforms state based on block.
00018 void TMd5::Transform(uint1 block[64]){
00019   static const int S11=7;
00020   static const int S12=12;
00021   static const int S13=17;
00022   static const int S14=22;
00023   static const int S21=5;
00024   static const int S22=9;
00025   static const int S23=14;
00026   static const int S24=20;
00027   static const int S31=4;
00028   static const int S32=11;
00029   static const int S33=16;
00030   static const int S34=23;
00031   static const int S41=6;
00032   static const int S42=10;
00033   static const int S43=15;
00034   static const int S44=21;
00035 
00036   uint4 a=state[0];
00037   uint4 b=state[1];
00038   uint4 c=state[2];
00039   uint4 d=state[3];
00040   uint4 x[16];
00041 
00042   Decode(x, block, 64);
00043 
00044   IAssert(!DefP);  // not just a user error, since the method is private
00045 
00046   /* Round 1 */
00047   FF(a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
00048   FF(d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
00049   FF(c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
00050   FF(b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
00051   FF(a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
00052   FF(d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
00053   FF(c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
00054   FF(b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
00055   FF(a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
00056   FF(d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
00057   FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
00058   FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
00059   FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
00060   FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
00061   FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
00062   FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
00063 
00064  /* Round 2 */
00065   GG(a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
00066   GG(d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
00067   GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
00068   GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
00069   GG(a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
00070   GG(d, a, b, c, x[10], S22,  0x2441453); /* 22 */
00071   GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
00072   GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
00073   GG(a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
00074   GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
00075   GG(c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
00076   GG(b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
00077   GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
00078   GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
00079   GG(c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
00080   GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
00081 
00082   /* Round 3 */
00083   HH(a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
00084   HH(d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
00085   HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
00086   HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
00087   HH(a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
00088   HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
00089   HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
00090   HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
00091   HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
00092   HH(d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
00093   HH(c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
00094   HH(b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
00095   HH(a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
00096   HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
00097   HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
00098   HH(b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
00099 
00100   /* Round 4 */
00101   II(a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
00102   II(d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
00103   II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
00104   II(b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
00105   II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
00106   II(d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
00107   II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
00108   II(b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
00109   II(a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
00110   II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
00111   II(c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
00112   II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
00113   II(a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
00114   II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
00115   II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
00116   II(b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
00117 
00118   state[0]+=a;
00119   state[1]+=b;
00120   state[2]+=c;
00121   state[3]+=d;
00122 
00123   // Zeroize sensitive information.
00124   MemSet((uint1*)x, 0, sizeof(x));
00125 }
00126 
00127 // Encodes input (UINT4) into output (unsigned char). Assumes len is
00128 // a multiple of 4.
00129 void TMd5::Encode(uint1 *output, uint4 *input, uint4 len){
00130   for (uint4 i=0, j=0; j<len; i++, j+=4){
00131     output[j]=uint1(input[i] & 0xff);
00132     output[j+1]=uint1((input[i]>>8) & 0xff);
00133     output[j+2]=uint1((input[i]>>16) & 0xff);
00134     output[j+3]=uint1((input[i]>>24) & 0xff);
00135   }
00136 }
00137 
00138 // Decodes input (unsigned char) into output (UINT4).
00139 // Assumes len is a multiple of 4.
00140 void TMd5::Decode(uint4* output, uint1* input, uint4 len){
00141   for (uint4 i=0, j=0; j<len; i++, j+=4){
00142     output[i]=
00143      ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
00144      (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
00145   }
00146 }
00147 
00148 void TMd5::Add(uchar* InBf, const int& InBfL){
00149   IAssert(!DefP);
00150   // compute number of bytes mod 64
00151   uint4 BfX=uint((count[0]>>3) & 0x3F);
00152 
00153   // update number of bits
00154   if ((count[0]+=((uint4)InBfL<<3))<((uint4)InBfL<<3)){
00155     count[1]++;}
00156   count[1]+=((uint4)InBfL>>29);
00157 
00158   uint4 BfSpace=64-BfX; // how much space is left in buffer
00159 
00160   // transform as many times as possible.
00161   uint4 InX;
00162   if (uint(InBfL)>=BfSpace) { // ie. we have enough to fill the buffer
00163     // fill the rest of the buffer and transform
00164     MemCpy(buffer+BfX, InBf, BfSpace);
00165     Transform(buffer);
00166     // now, transform each 64-byte piece of the InBf, bypassing the buffer
00167     for (InX=BfSpace; InX+63<uint(InBfL); InX+=64){Transform(InBf+InX);}
00168     BfX=0; // so we can buffer remaining
00169   } else {
00170     InX=0; // so we can buffer the whole InBf
00171   }
00172 
00173   // and here we do the buffering:
00174   MemCpy(buffer+BfX, InBf+InX, InBfL-InX);
00175 }
00176 
00177 void TMd5::Add(const PSIn& SIn){
00178   uchar Bf[1024];
00179   while (SIn->Len()>0){
00180     int BfL=1024;
00181     if (SIn->Len()<BfL){BfL=SIn->Len();}
00182     SIn->GetBf(Bf, BfL);
00183     Add(Bf, BfL);
00184   }
00185 }
00186 
00187 void TMd5::Def(){
00188   unsigned char bits[8];
00189   static uint1 PADDING[64]={
00190     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00191     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00192     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
00193 
00194   IAssert(!DefP);
00195   Encode(bits, count, 8); // save number of bits
00196 
00197   // Pad out to 56 mod 64.
00198   uint index=uint4((count[0] >> 3) & 0x3f);
00199   uint padLen=(index<56) ? (56-index) : (120-index);
00200   Add(PADDING, padLen);
00201 
00202   Add(bits, 8); // append length (before padding)
00203   Encode(Sig, state, 16); // store state in digest
00204   MemSet(buffer, 0, sizeof(*buffer)); // zeroize sensitive information
00205   DefP=true;
00206 }
00207 
00208 void TMd5::GetSigMem(TMem& Mem) const {
00209   IAssert(DefP);
00210   Mem.Gen(16);
00211   for (int CdN=0; CdN<16; CdN++){Mem+=Sig[CdN];}
00212 }
00213 
00214 TStr TMd5::GetSigStr() const {
00215   IAssert(DefP);
00216   TChA ChA(32);
00217   for (int CdN=0; CdN<16; CdN++){
00218     ChA+=TCh::GetHexCh(Sig[CdN]/16);
00219     ChA+=TCh::GetHexCh(Sig[CdN]%16);
00220   }
00221   return ChA;
00222 }
00223 
00224 bool TMd5::Check(){
00225   return
00226    (TMd5::GetMd5SigStr("")=="D41D8CD98F00B204E9800998ECF8427E")&&
00227    (TMd5::GetMd5SigStr("a")=="0CC175B9C0F1B6A831C399E269772661")&&
00228    (TMd5::GetMd5SigStr("abc")=="900150983CD24FB0D6963F7D28E17F72")&&
00229    (TMd5::GetMd5SigStr("message digest")=="F96B697D7CB7938D525A2F31AAF161D0")&&
00230    (TMd5::GetMd5SigStr("abcdefghijklmnopqrstuvwxyz")=="C3FCD3D76192E4007DFB496CCA67E13B")&&
00231    (TMd5::GetMd5SigStr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")==
00232     "D174AB98D277D9F5A5611C2C9F419D9F")&&
00233    (TMd5::GetMd5SigStr("12345678901234567890123456789012345678901234567890123456789012345678901234567890")==
00234     "57EDF4A22BE3C955AC49DA2E2107B67A");
00235 }
00236 
00238 // MD5-Signature
00239 TMd5Sig::TMd5Sig(const PSIn& SIn){
00240   PMd5 Md5=TMd5::New(SIn);
00241   memcpy(CdT, Md5->Sig, 16);
00242 }
00243 
00244 TMd5Sig::TMd5Sig(const TStr& Str){
00245   PMd5 Md5=TMd5::New(TStrIn::New(Str));
00246   memcpy(CdT, Md5->Sig, 16);
00247 }
00248 
00249 TMd5Sig::TMd5Sig(const TChA& ChA) {
00250   TMd5 Md5;  Md5.Add((uchar *) ChA.CStr(), ChA.Len());  Md5.Def();
00251   memcpy(CdT, Md5.Sig, 16);
00252 }
00253 
00254 TMd5Sig::TMd5Sig(const char* CStr) {
00255   TMd5 Md5;  Md5.Add((uchar *) CStr, (int) strlen(CStr));  Md5.Def();
00256   memcpy(CdT, Md5.Sig, 16);
00257 }
00258 
00259 TMd5Sig::TMd5Sig(const TMem& Mem){
00260   PMd5 Md5=TMd5::New(TMemIn::New(Mem));
00261   memcpy(CdT, Md5->Sig, 16);
00262 }
00263 
00264 int TMd5Sig::GetPrimHashCd() const {
00265   int HashCd=0;
00266   memcpy(&HashCd, &CdT[0], 4);
00267   HashCd=abs(HashCd);
00268   return HashCd;
00269 }
00270 
00271 int TMd5Sig::GetSecHashCd() const {
00272   int HashCd=0;
00273   memcpy(&HashCd, &CdT[3], 4);
00274   HashCd=abs(HashCd);
00275   return HashCd;
00276 }
00277 
00278 TStr TMd5Sig::GetStr() const {
00279   TChA ChA(32);
00280   for (int CdN=0; CdN<16; CdN++){
00281     ChA+=TCh::GetHexCh(CdT[CdN]/16);
00282     ChA+=TCh::GetHexCh(CdT[CdN]%16);
00283   }
00284   return ChA;
00285 }
00286