SNAP Library 6.0, Developer Reference  2020-12-09 16:24:20
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
md5.cpp
Go to the documentation of this file.
1 // MD5
3 void TMd5::Init(){
4  DefP=false; // we just started!
5 
6  // Nothing counted, so count=0
7  count[0]=0;
8  count[1]=0;
9 
10  // Load magic initialization constants.
11  state[0]=0x67452301;
12  state[1]=0xefcdab89;
13  state[2]=0x98badcfe;
14  state[3]=0x10325476;
15 }
16 
17 // MD5 basic transformation. Transforms state based on block.
18 void TMd5::Transform(uint1 block[64]){
19  static const int S11=7;
20  static const int S12=12;
21  static const int S13=17;
22  static const int S14=22;
23  static const int S21=5;
24  static const int S22=9;
25  static const int S23=14;
26  static const int S24=20;
27  static const int S31=4;
28  static const int S32=11;
29  static const int S33=16;
30  static const int S34=23;
31  static const int S41=6;
32  static const int S42=10;
33  static const int S43=15;
34  static const int S44=21;
35 
36  uint4 a=state[0];
37  uint4 b=state[1];
38  uint4 c=state[2];
39  uint4 d=state[3];
40  uint4 x[16];
41 
42  Decode(x, block, 64);
43 
44  IAssert(!DefP); // not just a user error, since the method is private
45 
46  /* Round 1 */
47  FF(a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
48  FF(d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
49  FF(c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
50  FF(b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
51  FF(a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
52  FF(d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
53  FF(c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
54  FF(b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
55  FF(a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
56  FF(d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
57  FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
58  FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
59  FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
60  FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
61  FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
62  FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
63 
64  /* Round 2 */
65  GG(a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
66  GG(d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
67  GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
68  GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
69  GG(a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
70  GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
71  GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
72  GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
73  GG(a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
74  GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
75  GG(c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
76  GG(b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
77  GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
78  GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
79  GG(c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
80  GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
81 
82  /* Round 3 */
83  HH(a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
84  HH(d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
85  HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
86  HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
87  HH(a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
88  HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
89  HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
90  HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
91  HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
92  HH(d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
93  HH(c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
94  HH(b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
95  HH(a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
96  HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
97  HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
98  HH(b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
99 
100  /* Round 4 */
101  II(a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
102  II(d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
103  II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
104  II(b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
105  II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
106  II(d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
107  II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
108  II(b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
109  II(a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
110  II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
111  II(c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
112  II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
113  II(a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
114  II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
115  II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
116  II(b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
117 
118  state[0]+=a;
119  state[1]+=b;
120  state[2]+=c;
121  state[3]+=d;
122 
123  // Zeroize sensitive information.
124  MemSet((uint1*)x, 0, sizeof(x));
125 }
126 
127 // Encodes input (UINT4) into output (unsigned char). Assumes len is
128 // a multiple of 4.
129 void TMd5::Encode(uint1 *output, uint4 *input, uint4 len){
130  for (uint4 i=0, j=0; j<len; i++, j+=4){
131  output[j]=uint1(input[i] & 0xff);
132  output[j+1]=uint1((input[i]>>8) & 0xff);
133  output[j+2]=uint1((input[i]>>16) & 0xff);
134  output[j+3]=uint1((input[i]>>24) & 0xff);
135  }
136 }
137 
138 // Decodes input (unsigned char) into output (UINT4).
139 // Assumes len is a multiple of 4.
140 void TMd5::Decode(uint4* output, uint1* input, uint4 len){
141  for (uint4 i=0, j=0; j<len; i++, j+=4){
142  output[i]=
143  ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
144  (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
145  }
146 }
147 
148 void TMd5::Add(uchar* InBf, const int& InBfL){
149  IAssert(!DefP);
150  // compute number of bytes mod 64
151  uint4 BfX=uint((count[0]>>3) & 0x3F);
152 
153  // update number of bits
154  if ((count[0]+=((uint4)InBfL<<3))<((uint4)InBfL<<3)){
155  count[1]++;}
156  count[1]+=((uint4)InBfL>>29);
157 
158  uint4 BfSpace=64-BfX; // how much space is left in buffer
159 
160  // transform as many times as possible.
161  uint4 InX;
162  if (uint(InBfL)>=BfSpace) { // ie. we have enough to fill the buffer
163  // fill the rest of the buffer and transform
164  MemCpy(buffer+BfX, InBf, BfSpace);
165  Transform(buffer);
166  // now, transform each 64-byte piece of the InBf, bypassing the buffer
167  for (InX=BfSpace; InX+63<uint(InBfL); InX+=64){Transform(InBf+InX);}
168  BfX=0; // so we can buffer remaining
169  } else {
170  InX=0; // so we can buffer the whole InBf
171  }
172 
173  // and here we do the buffering:
174  MemCpy(buffer+BfX, InBf+InX, InBfL-InX);
175 }
176 
177 void TMd5::Add(const PSIn& SIn){
178  uchar Bf[1024];
179  while (SIn->Len()>0){
180  int BfL=1024;
181  if (SIn->Len()<BfL){BfL=SIn->Len();}
182  SIn->GetBf(Bf, BfL);
183  Add(Bf, BfL);
184  }
185 }
186 
187 void TMd5::Def(){
188  unsigned char bits[8];
189  static uint1 PADDING[64]={
190  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
191  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
192  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
193 
194  IAssert(!DefP);
195  Encode(bits, count, 8); // save number of bits
196 
197  // Pad out to 56 mod 64.
198  uint index=uint4((count[0] >> 3) & 0x3f);
199  uint padLen=(index<56) ? (56-index) : (120-index);
200  Add(PADDING, padLen);
201 
202  Add(bits, 8); // append length (before padding)
203  Encode(Sig, state, 16); // store state in digest
204  MemSet(buffer, 0, sizeof(*buffer)); // zeroize sensitive information
205  DefP=true;
206 }
207 
208 void TMd5::GetSigMem(TMem& Mem) const {
209  IAssert(DefP);
210  Mem.Gen(16);
211  for (int CdN=0; CdN<16; CdN++){Mem+=Sig[CdN];}
212 }
213 
215  IAssert(DefP);
216  TChA ChA(32);
217  for (int CdN=0; CdN<16; CdN++){
218  ChA+=TCh::GetHexCh(Sig[CdN]/16);
219  ChA+=TCh::GetHexCh(Sig[CdN]%16);
220  }
221  return ChA;
222 }
223 
224 bool TMd5::Check(){
225  return
226  (TMd5::GetMd5SigStr("")=="D41D8CD98F00B204E9800998ECF8427E")&&
227  (TMd5::GetMd5SigStr("a")=="0CC175B9C0F1B6A831C399E269772661")&&
228  (TMd5::GetMd5SigStr("abc")=="900150983CD24FB0D6963F7D28E17F72")&&
229  (TMd5::GetMd5SigStr("message digest")=="F96B697D7CB7938D525A2F31AAF161D0")&&
230  (TMd5::GetMd5SigStr("abcdefghijklmnopqrstuvwxyz")=="C3FCD3D76192E4007DFB496CCA67E13B")&&
231  (TMd5::GetMd5SigStr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")==
232  "D174AB98D277D9F5A5611C2C9F419D9F")&&
233  (TMd5::GetMd5SigStr("12345678901234567890123456789012345678901234567890123456789012345678901234567890")==
234  "57EDF4A22BE3C955AC49DA2E2107B67A");
235 }
236 
238 // MD5-Signature
239 TMd5Sig::TMd5Sig(const PSIn& SIn){
240  PMd5 Md5=TMd5::New(SIn);
241  memcpy(CdT, Md5->Sig, 16);
242 }
243 
244 TMd5Sig::TMd5Sig(const TStr& Str){
245  PMd5 Md5=TMd5::New(TStrIn::New(Str));
246  memcpy(CdT, Md5->Sig, 16);
247 }
248 
249 TMd5Sig::TMd5Sig(const TChA& ChA) {
250  TMd5 Md5; Md5.Add((uchar *) ChA.CStr(), ChA.Len()); Md5.Def();
251  memcpy(CdT, Md5.Sig, 16);
252 }
253 
254 TMd5Sig::TMd5Sig(const char* CStr) {
255  TMd5 Md5; Md5.Add((uchar *) CStr, (int) strlen(CStr)); Md5.Def();
256  memcpy(CdT, Md5.Sig, 16);
257 }
258 
259 TMd5Sig::TMd5Sig(const TMem& Mem){
260  PMd5 Md5=TMd5::New(TMemIn::New(Mem));
261  memcpy(CdT, Md5->Sig, 16);
262 }
263 
265  int HashCd=0;
266  memcpy(&HashCd, &CdT[0], 4);
267  HashCd=abs(HashCd);
268  return HashCd;
269 }
270 
272  int HashCd=0;
273  memcpy(&HashCd, &CdT[3], 4);
274  HashCd=abs(HashCd);
275  return HashCd;
276 }
277 
279  TChA ChA(32);
280  for (int CdN=0; CdN<16; CdN++){
281  ChA+=TCh::GetHexCh(CdT[CdN]/16);
282  ChA+=TCh::GetHexCh(CdT[CdN]%16);
283  }
284  return ChA;
285 }
286 
#define IAssert(Cond)
Definition: bd.h:262
uint4 count[2]
Definition: md5.h:14
TStr GetStr() const
Definition: md5.cpp:278
virtual int Len() const =0
void Gen(const int &_BfL)
Definition: dt.h:123
TB4Def::TB4 uint4
Definition: md5.h:8
static PSIn New(const TMem &Mem)
Definition: dt.h:165
static void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
Definition: md5.h:40
unsigned int uint
Definition: bd.h:11
static char GetHexCh(const int &Val)
Definition: dt.h:1077
static void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
Definition: md5.h:44
TMd5Sig()
Definition: md5.h:86
virtual int GetBf(const void *Bf, const TSize &BfL)=0
int Len() const
Definition: dt.h:259
uint1 CdT[16]
Definition: md5.h:84
void Add(uchar *InBf, const int &InBfL)
Definition: md5.cpp:148
Definition: md5.h:5
static PMd5 New()
Definition: md5.h:49
Definition: dt.h:77
uint1 buffer[64]
Definition: md5.h:15
uint4 state[4]
Definition: md5.h:13
char * CStr()
Definition: dt.h:255
static void Decode(uint4 *Dst, uint1 *Src, uint4 Len)
Definition: md5.cpp:140
static PSIn New(const TStr &Str)
Definition: dt.h:711
uint1 Sig[16]
Definition: md5.h:16
TB1Def::TB1 uint1
Definition: md5.h:10
void Transform(uint1 *buffer)
Definition: md5.cpp:18
unsigned char uchar
Definition: bd.h:10
void GetSigMem(TMem &Mem) const
Definition: md5.cpp:208
Definition: dt.h:201
Definition: dt.h:412
void Init()
Definition: md5.cpp:3
static void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
Definition: md5.h:38
static void MemCpy(uint1 *Dst, uint1 *Src, uint4 Len)
Definition: md5.h:24
static bool Check()
Definition: md5.cpp:224
TStr GetSigStr() const
Definition: md5.cpp:214
static void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
Definition: md5.h:42
void Def()
Definition: md5.cpp:187
static TStr GetMd5SigStr(const PSIn &SIn)
Definition: md5.h:66
int GetSecHashCd() const
Definition: md5.cpp:271
static void MemSet(uint1 *Start, uint1 Val, uint4 Len)
Definition: md5.h:26
static void Encode(uint1 *Dst, uint4 *Src, uint4 Len)
Definition: md5.cpp:129
bool DefP
Definition: md5.h:17
int GetPrimHashCd() const
Definition: md5.cpp:264