scire
Sadh's C++ Impromptu Routines Ensemble
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
md5.hpp
Go to the documentation of this file.
1 // scire/hash/md5
2 
3 // "RSA Data Security, Inc. MD5 Message-Digest Algorithm"
4 // Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved.
5 
6 // Adopted 2014, (C) by Khan 'Sadh' Mostafa (http://nafSadh.com/Khan)
7 // Distributed as part of 'scire' under the Boost Software License, Version 1.0.
8 // (See accompanying text at http://www.boost.org/LICENSE_1_0.txt)
9 
10 /**
11  @file: scire/hash/md5.hpp
12  @author: nafSadh
13  @brief: MD5
14  */
15 /*
16  scire MD5 implementation:
17  - MD5 : a class offering MD5 functionalities
18 
19  other required scire files:
20  scire/hash/hash_comn.hpp
21 
22  can be STANDALONE : Yes
23 
24  acknowledgement:
25  [1] RFC 1321, Rivest, http://tools.ietf.org/html/rfc1321
26  [2] quantq, https://github.com/quantq/md5
27  [3] Marshall Cline, http://www.parashift.com/c++-faq-lite/template-friends.html
28 
29  */
30 #ifndef SCIRE_hash_md5_HPP
31 #define SCIRE_hash_md5_HPP
32 
33 #include <iostream>
34 #include <iomanip>
35 #include <cstdint>
36 #include <cstring>
37 #include <string>
38 #include <sstream>
39 
40 #ifndef STANDALONE
41 #include "hash_comn.hpp"
42 #endif
43 
44 namespace scire
45 {
47 #define SCIRE_MD5_CLASS
48 
49 
50  /**
51  * MD5 Message-Digest Algorithm.
52  * scire adaptation of the MD5 algorithm, adopted from RFC 1321.
53  * http://tools.ietf.org/html/rfc1321
54  *
55  * This implemenation is templatic to facilitate machine portability. It takes
56  * four <type> parameters:
57  * - SzType : size type, integer; default: size_t
58  * - Ui32t : unsigned 32bit integer, default: uint32_t of <cstdint>
59  * - ByteT : unsigned byte (8bit int), default: uint8_t of <cstdint>
60  * - SByteT : signed byte (8bit int), default: int8_t of <cstdint>
61  *
62  * In most cases it will simply suffice to use MD5<>
63  *
64  * Example usage:
65  * @code
66  * MD5<> md5;
67  * md5.Update(message, msglen); //call Update once or as many times necessary
68  * md5.Final(); // digest is ready, any subsequent updates will be ignored
69  * md5.Digest(digest); // fill 'digest' byte array with digest values
70  * @endcode
71  * Client should create an MD5 object. The construcor calls Init inside it, so
72  * it is redundant to call Init() upor first use of the object. To compute MD5
73  * checksum of a buffer, call Update() once or several times with chunks of the
74  * message. A call to Final() indicated MD5 object that, message is complete.
75  * Then, MD5 object computes finalized the digest. Client can receive digest
76  * bytes by passing a byte array to fill digest values with it. Digest size is
77  * 16 byte. After a call to Final(), all subsequent Update() calls will be
78  * ignored. \n
79  * MD5 object can be reused by invoking Reset() and then using it in a similar
80  * fashion.
81  *
82  */
83  template<typename SzType = size_t, /* size type, integer */
84  typename Ui32t = uint32_t,/* std 32bit unsigned integer */
85  typename ByteT = uint8_t,/* byte type, 8bit unsigned integer */
86  typename SByteT = int8_t/* signed byte type */>
87  class MD5
89  : public IHashAlgo<SzType, Ui32t, ByteT, SByteT>
90 #endif
91  {
92  public:
93  // -- Informative CONSTANTS --//
94  enum Info {
95  DigestSize_bits = 128, /**< MD5 digest size in bits */
96  DigestSize_bytes = 16, /**< MD5 digest size in bytes */
97  DigestSize_words = 4, /**< MD5 digest size in words (32bit) */
98  BlockSize_bits = 512, /**< MD5 process message in chunks each of 512bit*/
99  BlockSize_bytes = 64, /**< block size in bytes */
100  BlockSize_words = 16, /**< block size in words (32bit) */
101  Rounds = 4 /**< MD5 has 4 rounds */
102  };
103  enum Magic {
104  MagicWordA = 0x01234567, /**< 0x01234567 */
105  MagicWordB = 0x89abcdef, /**< 0x89abcdef */
106  MagicWordC = 0xfedcba98, /**< 0xfedcba98 */
107  MagicWordD = 0X76543210 /**< 0X76543210 */
108  };
109 
110  /** allocate MD5 context and init */
111  MD5();
112 
113  /** Construct MD5 object with a string message. This will cause full stack
114  of the algorithm to execute. Hence, Initi(), Update() and Final() shall be
115  called within and the object is ready to yield digest. */
116  MD5(std::string message);
117  /** @copydoc MD5::MD5(std::string) */
118  MD5(char message[]);
119 
120  /* release MD5 resources */
121  //~MD5();
122 
123  // -- MD5 INTERFACE --// // adopted from Rivest's RFC
124  /**
125  * MD5 initialization.
126  * Begins an MD5 operation, writing a new context (i.e. init class object).
127  */
128  void Init();
129 
130  /**
131  * MD5 block update operation. Continues an MD5 message-digest
132  * operation, processing another message block, and updating the
133  * context.
134  * @param input an array of bytes
135  * @param lenght number of bytes in input chunk
136  */
137  bool Update(const ByteT* input, SzType lenght);
138  /** @copydoc MD5::Update */
139  bool Update(const SByteT* input, SzType lenght);
140 
141  /**
142  * MD5 finalization. Ends an MD5 message-digest operation, writing the
143  * the message digest and zeroizing the context.
144  */
145  void Final();
146 
147  /**
148  * get digest bytes in
149  * @return false if Final has yet not been called
150  * @param digest a 16 byte array to read digest values in
151  */
152  bool Digest(ByteT digest[DigestSize_bytes]) const;
153 
154  // -- ADOPTED FROM RFC 1321 -- //
155  private:
156  // -- MD5 context --//
157  /** state (ABCD) */
158  Ui32t state[DigestSize_words];
159  /** number of bits modulo 2^64 (lsb first) */
160  Ui32t count[2];
161  /** bytes that didn't fit in last 64B chunk */
162  ByteT buffer[BlockSize_bytes];
163  /** if Final called */
164  bool finalized;
165  ByteT digest[DigestSize_bytes];
166 
167  public:
168  // -- MD5 Added Interface -- // // alias and extra functionality
169 
170  /** fingerprint is the 128bit message-digest */
171  std::string Fingerprint() const;
172 
173  /** String representation of Four State Words (ABCD) */
174  std::string StatePhrase() const;
175 
176  /** string reprsentation | fingerpring on finalize, else status words */
177  std::string ToString() const;
178 
179  /** Reset object, similar to doing Init() */
180  void Reset()
181  {
182  Init();
183  }
184 
185  // -- Basic MD5 Functions -- //
186  protected:
187  /**
188  * F(X,Y,Z) = XY v not(X) Z
189  *
190  * from RFC 1321:\n
191  * In each bit position F acts as a conditional: if X then Y else Z.
192  * The function F could have been defined using + instead of v since XY
193  * and not(X)Z will never have 1's in the same bit position.) It is
194  * interesting to note that if the bits of X, Y, and Z are independent
195  * and unbiased, the each bit of F(X,Y,Z) will be independent and
196  * unbiased.
197  */
198  static Ui32t F(Ui32t x, Ui32t y, Ui32t z)
199  {
200  return (x&y) | ((~x)&z);
201  }
202  /**
203  * G(X,Y,Z) = XZ v Y not(Z)
204  *
205  * from RFC 1321:\n
206  * The functions G, H, and I are similar to the function F, in that they
207  * act in "bitwise parallel" to produce their output from the bits of X,
208  * Y, and Z, in such a manner that if the corresponding bits of X, Y,
209  * and Z are independent and unbiased, then each bit of G(X,Y,Z),
210  * H(X,Y,Z), and I(X,Y,Z) will be independent and unbiased. Note that
211  * the function H is the bit-wise "xor" or "parity" function of its
212  * inputs.
213  * @see MD5::F
214  */
215  static Ui32t G(Ui32t x, Ui32t y, Ui32t z)
216  {
217  return (x&z) | (y&(~z));
218  }
219  /** H(X,Y,Z) = X xor Y xor Z @see MD5::G */
220  static Ui32t H(Ui32t x, Ui32t y, Ui32t z)
221  {
222  return x ^ y ^ z;
223  }
224  /** I(X,Y,Z) = Y xor (X v not(Z)) @see MD5::G */
225  static Ui32t I(Ui32t x, Ui32t y, Ui32t z)
226  {
227  return y ^ (x | (~z));
228  }
229 
230  /** the phenomenal transform function */
231  void transform(const ByteT block[BlockSize_bytes]);
232 
233  private:
234  /** constants for MD5 algorithm */
235  enum {
236  /** status indices */
237  A = 0, B = 1, C = 2, D = 3,
238  /** Constants for transform routine */
239  S11 = 7, S21 = 5, S31 = 4, S41 = 6,
240  S12 = 12, S22 = 9, S32 = 11, S42 = 10,
241  S13 = 17, S23 = 14, S33 = 16, S43 = 15,
242  S14 = 22, S24 = 20, S34 = 23, S44 = 21,
243  };
244 
245  // -- MD5 UTILITY FUNCTIONS -- //
246 
247  /** rotates x left n bits.*/
248  static Ui32t rotateleft(Ui32t x, SzType n)
249  {
250  return (x << n) | (x >> (32 - n));
251  }
252 
253  /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
254  Rotation is separate from addition to prevent recomputation.
255  */
256  static void FF(Ui32t &a, Ui32t b, Ui32t c, Ui32t d,
257  Ui32t x, Ui32t s, Ui32t ac)
258  {
259  a = rotateleft(a + F(b, c, d) + x + ac, s) + b;
260  }
261 
262  static void GG(Ui32t &a, Ui32t b, Ui32t c, Ui32t d,
263  Ui32t x, Ui32t s, Ui32t ac)
264  {
265  a = rotateleft(a + G(b, c, d) + x + ac, s) + b;
266  }
267 
268  static void HH(Ui32t &a, Ui32t b, Ui32t c, Ui32t d,
269  Ui32t x, Ui32t s, Ui32t ac)
270  {
271  a = rotateleft(a + H(b, c, d) + x + ac, s) + b;
272  }
273 
274  static void II(Ui32t &a, Ui32t b, Ui32t c, Ui32t d,
275  Ui32t x, Ui32t s, Ui32t ac)
276  {
277  a = rotateleft(a + I(b, c, d) + x + ac, s) + b;
278  }
279 
280  /**
281  * decodes input (unsigned char) into output (Ui32t). Assumes len is a
282  * multiple of 4.
283  */
284  static void decode(Ui32t out[], const ByteT input[], SzType len)
285  {
286  for (unsigned int i = 0, j = 0; j < len; i++, j += 4)
287  out[i] = ((Ui32t)input[j]) | (((Ui32t)input[j + 1]) << 8) |
288  (((Ui32t)input[j + 2]) << 16) | (((Ui32t)input[j + 3]) << 24);
289  }
290 
291  /**
292  * encodes input (Ui32t) into output (unsigned char). Assumes len is
293  * a multiple of 4.
294  */
295  static void encode(ByteT out[], const Ui32t input[], SzType len)
296  {
297  for (SzType i = 0, j = 0; j < len; i++, j += 4) {
298  out[j] = input[i] & 0xff;
299  out[j + 1] = (input[i] >> 8) & 0xff;
300  out[j + 2] = (input[i] >> 16) & 0xff;
301  out[j + 3] = (input[i] >> 24) & 0xff;
302  }
303  }
304  };
305 
306  //-----------------------------//
307  // -- NON-MEMBER functions -- //
308  //---------------------------//
309  /**
310  * @relates MD5
311  * if MD5 finalized then output digest, else current state words to ostream
312  */
313  template<typename SzType, typename Ui32t, typename ByteT, typename SByteT>
314  std::ostream&
316  const MD5<SzType, Ui32t, ByteT, SByteT>& md5)
317  {
318  return out << md5.ToString();
319  }
320 
321 //------------------//
322 // -- MD5 CTORS -- //
323 //----------------//
324 
325  template<typename SzType, typename Ui32t, typename ByteT, typename SByteT>
326  MD5<SzType, Ui32t, ByteT, SByteT>::
327  MD5()
328  : finalized(false)
329  {
330  Init();
331  }
332 
333 
334  template<typename SzType, typename Ui32t, typename ByteT, typename SByteT>
335  MD5<SzType, Ui32t, ByteT, SByteT>::
336  MD5(char msg[])
337  : finalized(false)
338  {
339  Init();
340  Update(reinterpret_cast<const ByteT*>(msg), strlen(msg));
341  Final();
342  }
343 
344  template<typename SzType, typename Ui32t, typename ByteT, typename SByteT>
345  MD5<SzType, Ui32t, ByteT, SByteT>::
346  MD5(std::string msg)
347  : finalized(false)
348  {
349  Init();
350  Update(reinterpret_cast<const ByteT*>(msg.c_str()), msg.length());
351  Final();
352  }
353 
354  //-----------------------//
355  // -- MD5 Interfaces -- //
356  //---------------------//
357 
358  template<typename SzType, typename Ui32t, typename ByteT, typename SByteT>
359  std::string MD5<SzType, Ui32t, ByteT, SByteT>::
360  Fingerprint() const
361  {
363  for (SzType i = 0; i < 16; i++) {
364  strm << setfill('0') << setw(2) << hex << (unsigned int)digest[i];
365  }
366  return strm.str();
367  }
368 
369 
370  template<typename SzType, typename Ui32t, typename ByteT, typename SByteT>
371  std::string MD5<SzType, Ui32t, ByteT, SByteT>::
372  StatePhrase() const
373  {
375  strm << setfill('0') << setw(2) << hex
376  << "A:" << (unsigned int)state[A]
377  << " B:" << (unsigned int)state[B]
378  << " C:" << (unsigned int)state[C]
379  << " D:" << (unsigned int)state[D];
380 
381  return strm.str();
382  }
383  template<typename SzType, typename Ui32t, typename ByteT, typename SByteT>
384  std::string MD5<SzType, Ui32t, ByteT, SByteT>::
385  ToString() const
386  {
387  return (finalized) ? Fingerprint() : StatePhrase();
388  }
389 
390  //---------------------------//
391  // -- MD5 IMPLEMENTATION -- //
392  //-------------------------//
393 
394  template<typename SzType, typename Ui32t, typename ByteT, typename SByteT>
395  void MD5<SzType, Ui32t, ByteT, SByteT>::
397  {
398  // init consumed bitlen to zero
399  this->count[0] = this->count[1] = 0;
400  // init with magic numbers
401  this->state[0] = 0x67452301;
402  this->state[1] = 0xefcdab89;
403  this->state[2] = 0x98badcfe;
404  this->state[3] = 0x10325476;
405 
406  this->finalized = false;
407  }
408 
409 
410  template<typename SzType, typename Ui32t, typename ByteT, typename SByteT>
411  bool MD5<SzType, Ui32t, ByteT, SByteT>::
412  Digest(ByteT digest_[DigestSize_bytes]) const
413  {
414  if (!finalized) return false;
415 
416  for (int i = 0; i < DigestSize_bytes; i++) {
417  digest_[i] = this->digest[i];
418  }
419 
420  return true;
421  }
422 
423 
424  template<typename SzType, typename Ui32t, typename ByteT, typename SByteT>
425  bool MD5<SzType, Ui32t, ByteT, SByteT>::
426  Update(const SByteT * input, SzType length)
427  {
428  return Update((const unsigned char*)input, length);
429  }
430 
431 
432  template<typename SzType, typename Ui32t, typename ByteT, typename SByteT>
433  bool MD5<SzType, Ui32t, ByteT, SByteT>::
434  Update(const ByteT * input, SzType inputLen)
435  {
436  if (finalized) return false; // ignore all Update() after Final() is called
437 
438  // Compute number of bytes mod 64
439  SzType index = (unsigned int)((this->count[0] >> 3) & 0x3F);
440 
441  // Update number of bits
442  if ((this->count[0] += ((Ui32t)inputLen << 3)) < ((Ui32t)inputLen << 3)) {
443  this->count[1]++;
444  }//eventually
445  this->count[1] += ((Ui32t)inputLen >> 29);
446 
447  SzType partLen = 64 - index;
448  SzType i;
449  // Transform as many times as possible
450  if (inputLen >= partLen) {
452  transform(buffer);
453 
454  // transform each chunk of blocksize (64B)
455  for (i = partLen; i + 63 < inputLen; i += 64)
456  transform(&input[i]);
457  index = 0;
458  } else {
459  i = 0;
460  }
461 
462  //buffer remaining input for padding shall occur
463  memcpy(&buffer[index], &input[i], inputLen - i);
464 
465  return true;
466  }//end MD5::Update
467 
468 
469  template<typename SzType, typename Ui32t, typename ByteT, typename SByteT>
470  void MD5<SzType, Ui32t, ByteT, SByteT>::
472  {
473  static ByteT padding[64] = {
474  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
475  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
476  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
477  };
478 
479  if (!finalized) {
480  // Save number of bits
481  ByteT bits[8];
482  encode(bits, count, 8);
483 
484  // pad out to 56 mod 64.
485  SzType index = (Ui32t)((this->count[0] >> 3) & 0x3f);
486  SzType padLen = (index < 56) ? (56 - index) : (120 - index);
488 
489  // Append length (before padding)
490  Update(bits, 8);
491 
492  // Store state in digest
493  encode(digest, state, 16);
494 
495  // Zeroize sensitive information.
496  memset(buffer, 0, sizeof buffer);
497  memset(count, 0, sizeof count);
498 
499  finalized = true;
500  }
501  }
502 
503  // exact copy paste from Rivest's RFC
504  // yes bit 44's ac is indeed small
505  template<typename SzType, typename Ui32t, typename ByteT, typename SByteT>
506  void MD5<SzType, Ui32t, ByteT, SByteT>::
507  transform(const ByteT block[BlockSize_bytes])
508  {
509  // copy current status
510  Ui32t a = state[A], b = state[B], c = state[C], d = state[D];
511 
512  // convert input to 32bit uints
515 
516  /* Round 1 */
517  FF(a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
518  FF(d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
519  FF(c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
520  FF(b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
521  FF(a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
522  FF(d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
523  FF(c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
524  FF(b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
525  FF(a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
526  FF(d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
527  FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
528  FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
529  FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
530  FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
531  FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
532  FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
533 
534  /* Round 2 */
535  GG(a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
536  GG(d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
537  GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
538  GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
539  GG(a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
540  GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
541  GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
542  GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
543  GG(a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
544  GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
545  GG(c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
546  GG(b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
547  GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
548  GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
549  GG(c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
550  GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
551 
552  /* Round 3 */
553  HH(a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
554  HH(d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
555  HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
556  HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
557  HH(a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
558  HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
559  HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
560  HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
561  HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
562  HH(d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
563  HH(c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
564  HH(b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
565  HH(a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
566  HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
567  HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
568  HH(b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
569 
570  /* Round 4 */
571  II(a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
572  II(d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
573  II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
574  II(b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
575  II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
576  II(d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
577  II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
578  II(b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
579  II(a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
580  II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
581  II(c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
582  II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
583  II(a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
584  II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
585  II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
586  II(b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
587 
588  state[0] += a;
589  state[1] += b;
590  state[2] += c;
591  state[3] += d;
592 
593  // Zeroize sensitive information.
594  memset(x, 0, sizeof x);
595  }
596 #endif//SCIRE_MD5_CLASS
597 }//scire namespace
598 #endif//SCIRE_hash_md5_HPP
MD5 digest size in bits.
Definition: md5.hpp:95
std::ostream & operator<<(std::ostream &out, const MD5< SzType, Ui32t, ByteT, SByteT > &md5)
Definition: md5.hpp:315
0x89abcdef
Definition: md5.hpp:105
void Reset()
Reset object, similar to doing Init()
Definition: md5.hpp:180
block size in bytes
Definition: md5.hpp:99
0x01234567
Definition: md5.hpp:104
static Ui32t F(Ui32t x, Ui32t y, Ui32t z)
F(X,Y,Z) = XY v not(X) Z.
Definition: md5.hpp:198
MD5 digest size in words (32bit)
Definition: md5.hpp:97
Common interface for Hash Algorithms.
Definition: hash_comn.hpp:42
bool Update(const SByteT *input, SzType lenght)
MD5 block update operation.
Definition: md5.hpp:426
MD5 process message in chunks each of 512bit.
Definition: md5.hpp:98
bool Digest(ByteT digest[DigestSize_bytes]) const
get digest bytes in
Definition: md5.hpp:412
std::string ToString() const
string reprsentation | fingerpring on finalize, else status words
Definition: md5.hpp:385
static Ui32t G(Ui32t x, Ui32t y, Ui32t z)
G(X,Y,Z) = XZ v Y not(Z)
Definition: md5.hpp:215
MD5 Message-Digest Algorithm.
Definition: md5.hpp:87
scire/graph/gale_shapley.hpp
0X76543210
Definition: md5.hpp:107
0xfedcba98
Definition: md5.hpp:106
MD5 digest size in bytes.
Definition: md5.hpp:96
block size in words (32bit)
Definition: md5.hpp:100
MD5()
allocate MD5 context and init
Definition: md5.hpp:327
std::string StatePhrase() const
String representation of Four State Words (ABCD)
Definition: md5.hpp:372
MD5(std::string message)
Construct MD5 object with a string message.
Definition: md5.hpp:346
MD5 has 4 rounds.
Definition: md5.hpp:101
void transform(const ByteT block[BlockSize_bytes])
the phenomenal transform function
Definition: md5.hpp:507
static Ui32t I(Ui32t x, Ui32t y, Ui32t z)
I(X,Y,Z) = Y xor (X v not(Z))
Definition: md5.hpp:225
static Ui32t H(Ui32t x, Ui32t y, Ui32t z)
H(X,Y,Z) = X xor Y xor Z.
Definition: md5.hpp:220
void Init()
MD5 initialization.
Definition: md5.hpp:396
bool Update(const ByteT *input, SzType lenght)
MD5 block update operation.
Definition: md5.hpp:434
MD5(char message[])
Construct MD5 object with a string message.
Definition: md5.hpp:336
std::string Fingerprint() const
fingerprint is the 128bit message-digest
Definition: md5.hpp:360
void Final()
MD5 finalization.
Definition: md5.hpp:471