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
|
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