md5.hxx

00001 // Copyright (C) 2004  EPITA Research and Development Laboratory
00002 //
00003 // This  file is  part of  the Olena  Library.  This  library  is free
00004 // software; you can redistribute it  and/or modify it under the terms
00005 // of the  GNU General  Public License version  2 as published  by the
00006 // Free Software Foundation.
00007 //
00008 // This library is distributed in the hope that it will be useful, but
00009 // WITHOUT  ANY  WARRANTY;  without   even  the  implied  warranty  of
00010 // MERCHANTABILITY or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU
00011 // General Public License for more details.
00012 //
00013 // You should have  received a copy of the  GNU General Public License
00014 // along with  this library; see the  file COPYING.  If  not, write to
00015 // the Free Software Foundation, 59  Temple Place - Suite 330, Boston,
00016 // MA 02111-1307, USA.
00017 //
00018 // As a  special exception, you  may use this  file as part of  a free
00019 // software library without restriction.  Specifically, if other files
00020 // instantiate templates  or use macros or inline  functions from this
00021 // file, or  you compile  this file  and link it  with other  files to
00022 // produce  an executable,  this file  does  not by  itself cause  the
00023 // resulting  executable  to be  covered  by  the  GNU General  Public
00024 // License.   This exception  does  not however  invalidate any  other
00025 // reasons why the executable file might be covered by the GNU General
00026 // Public License.
00027 
00028 #ifndef OLENA_OLN_UTILS_MD5_HXX
00029 # define OLENA_OLN_UTILS_MD5_HXX
00030 
00031 // Ctor.
00032 inline
00033 MD5::MD5(buffer b): buffer_(b),
00034                     X(16),
00035                     T(),
00036                     current_(0),
00037                     a(0x67452301),
00038                     b(0xefcdab89),
00039                     c(0x98badcfe),
00040                     d(0x10325476)
00041   //             a(0x01234567),
00042   //             b(0x89abcdef),
00043   //             c(0xfedcba98),
00044   //             d(0x76543210)
00045 {
00046   precondition(buffer_.is_append_padding());
00047   precondition(buffer_.is_append_length());
00048   T.reserve(64);
00049   T.push_back(0xd76aa478); /* 1 */
00050   T.push_back(0xe8c7b756); /* 2 */
00051   T.push_back(0x242070db); /* 3 */
00052   T.push_back(0xc1bdceee); /* 4 */
00053   T.push_back(0xf57c0faf); /* 5 */
00054   T.push_back(0x4787c62a); /* 6 */
00055   T.push_back(0xa8304613); /* 7 */
00056   T.push_back(0xfd469501); /* 8 */
00057   T.push_back(0x698098d8); /* 9 */
00058   T.push_back(0x8b44f7af); /* 10 */
00059   T.push_back(0xffff5bb1); /* 11 */
00060   T.push_back(0x895cd7be); /* 12 */
00061   T.push_back(0x6b901122); /* 13 */
00062   T.push_back(0xfd987193); /* 14 */
00063   T.push_back(0xa679438e); /* 15 */
00064   T.push_back(0x49b40821); /* 16 */
00065   T.push_back(0xf61e2562); /* 17 */
00066   T.push_back(0xc040b340); /* 18 */
00067   T.push_back(0x265e5a51); /* 19 */
00068   T.push_back(0xe9b6c7aa); /* 20 */
00069   T.push_back(0xd62f105d); /* 21 */
00070   T.push_back(0x2441453); /* 22 */
00071   T.push_back(0xd8a1e681); /* 23 */
00072   T.push_back(0xe7d3fbc8); /* 24 */
00073   T.push_back(0x21e1cde6); /* 25 */
00074   T.push_back(0xc33707d6); /* 26 */
00075   T.push_back(0xf4d50d87); /* 27 */
00076   T.push_back(0x455a14ed); /* 28 */
00077   T.push_back(0xa9e3e905); /* 29 */
00078   T.push_back(0xfcefa3f8); /* 30 */
00079   T.push_back(0x676f02d9); /* 31 */
00080   T.push_back(0x8d2a4c8a); /* 32 */
00081   T.push_back(0xfffa3942); /* 33 */
00082   T.push_back(0x8771f681); /* 34 */
00083   T.push_back(0x6d9d6122); /* 35 */
00084   T.push_back(0xfde5380c); /* 36 */
00085   T.push_back(0xa4beea44); /* 37 */
00086   T.push_back(0x4bdecfa9); /* 38 */
00087   T.push_back(0xf6bb4b60); /* 39 */
00088   T.push_back(0xbebfbc70); /* 40 */
00089   T.push_back(0x289b7ec6); /* 41 */
00090   T.push_back(0xeaa127fa); /* 42 */
00091   T.push_back(0xd4ef3085); /* 43 */
00092   T.push_back(0x4881d05); /* 44 */
00093   T.push_back(0xd9d4d039); /* 45 */
00094   T.push_back(0xe6db99e5); /* 46 */
00095   T.push_back(0x1fa27cf8); /* 47 */
00096   T.push_back(0xc4ac5665); /* 48 */
00097   T.push_back(0xf4292244); /* 49 */
00098   T.push_back(0x432aff97); /* 50 */
00099   T.push_back(0xab9423a7); /* 51 */
00100   T.push_back(0xfc93a039); /* 52 */
00101   T.push_back(0x655b59c3); /* 53 */
00102   T.push_back(0x8f0ccc92); /* 54 */
00103   T.push_back(0xffeff47d); /* 55 */
00104   T.push_back(0x85845dd1); /* 56 */
00105   T.push_back(0x6fa87e4f); /* 57 */
00106   T.push_back(0xfe2ce6e0); /* 58 */
00107   T.push_back(0xa3014314); /* 59 */
00108   T.push_back(0x4e0811a1); /* 60 */
00109   T.push_back(0xf7537e82); /* 61 */
00110   T.push_back(0xbd3af235); /* 62 */
00111   T.push_back(0x2ad7d2bb); /* 63 */
00112   T.push_back(0xeb86d391); /* 64 */
00113 };
00114 
00115 // sav() implementation.
00116 inline
00117 void MD5::sav()
00118 {
00119   for (unsigned i = 0; i < 16; ++i)
00120     X[i] = buffer_[current_ + i];
00121   current_ += 16;
00122   aa = a;
00123   bb = b;
00124   cc = c;
00125   dd = d;
00126 }
00127 
00128 // round1() implementation.
00129 inline
00130 void MD5::round1()
00131 {
00132   sub_step(F, a, b, c, d, 0, 7, 1);
00133   sub_step(F, d, a, b, c, 1, 12, 2);
00134   sub_step(F, c, d, a, b, 2, 17, 3);
00135   sub_step(F, b, c, d, a, 3, 22, 4);
00136   sub_step(F, a, b, c, d, 4, 7, 5);
00137   sub_step(F, d, a, b, c, 5, 12, 6);
00138   sub_step(F, c, d, a, b, 6, 17, 7);
00139   sub_step(F, b, c, d, a, 7, 22, 8);
00140   sub_step(F, a, b, c, d, 8, 7, 9);
00141   sub_step(F, d, a, b, c, 9, 12, 10);
00142   sub_step(F, c, d, a, b, 10, 17, 11);
00143   sub_step(F, b, c, d, a, 11, 22, 12);
00144   sub_step(F, a, b, c, d, 12, 7, 13);
00145   sub_step(F, d, a, b, c, 13, 12, 14);
00146   sub_step(F, c, d, a, b, 14, 17, 15);
00147   sub_step(F, b, c, d, a, 15, 22, 16);
00148 }
00149 
00150 // round2() implementation.
00151 inline
00152 void MD5::round2()
00153 {
00154   sub_step(G, a, b, c, d, 1, 5, 17);
00155   sub_step(G, d, a, b, c, 6, 9, 18);
00156   sub_step(G, c, d, a, b, 11, 14, 19);
00157   sub_step(G, b, c, d, a, 0, 20, 20);
00158   sub_step(G, a, b, c, d, 5, 5, 21);
00159   sub_step(G, d, a, b, c, 10, 9, 22);
00160   sub_step(G, c, d, a, b, 15, 14, 23);
00161   sub_step(G, b, c, d, a, 4, 20, 24);
00162   sub_step(G, a, b, c, d, 9, 5, 25);
00163   sub_step(G, d, a, b, c, 14, 9, 26);
00164   sub_step(G, c, d, a, b, 3, 14, 27);
00165   sub_step(G, b, c, d, a, 8, 20, 28);
00166   sub_step(G, a, b, c, d, 13, 5, 29);
00167   sub_step(G, d, a, b, c, 2, 9, 30);
00168   sub_step(G, c, d, a, b, 7, 14, 31);
00169   sub_step(G, b, c, d, a, 12, 20, 32);
00170 }
00171 
00172 // round3() implementation.
00173 inline
00174 void MD5::round3()
00175 {
00176   sub_step(H, a, b, c, d,  5,  4, 33);
00177   sub_step(H, d, a, b, c,  8, 11, 34);
00178   sub_step(H, c, d, a, b, 11, 16, 35);
00179   sub_step(H, b, c, d, a, 14, 23, 36);
00180   sub_step(H, a, b, c, d,  1,  4, 37);
00181   sub_step(H, d, a, b, c,  4, 11, 38);
00182   sub_step(H, c, d, a, b,  7, 16, 39);
00183   sub_step(H, b, c, d, a, 10, 23, 40);
00184   sub_step(H, a, b, c, d, 13,  4, 41);
00185   sub_step(H, d, a, b, c,  0, 11, 42);
00186   sub_step(H, c, d, a, b,  3, 16, 43);
00187   sub_step(H, b, c, d, a,  6, 23, 44);
00188   sub_step(H, a, b, c, d,  9,  4, 45);
00189   sub_step(H, d, a, b, c, 12, 11, 46);
00190   sub_step(H, c, d, a, b, 15, 16, 47);
00191   sub_step(H, b, c, d, a,  2, 23, 48);
00192 }
00193 
00194 // round 4() implementation.
00195 inline
00196 void MD5::round4()
00197 {
00198   sub_step(I, a, b, c, d,  0,  6, 49);
00199   sub_step(I, d, a, b, c,  7, 10, 50);
00200   sub_step(I, c, d, a, b, 14, 15, 51);
00201   sub_step(I, b, c, d, a,  5, 21, 52);
00202   sub_step(I, a, b, c, d, 12,  6, 53);
00203   sub_step(I, d, a, b, c,  3, 10, 54);
00204   sub_step(I, c, d, a, b, 10, 15, 55);
00205   sub_step(I, b, c, d, a,  1, 21, 56);
00206   sub_step(I, a, b, c, d,  8,  6, 57);
00207   sub_step(I, d, a, b, c, 15, 10, 58);
00208   sub_step(I, c, d, a, b,  6, 15, 59);
00209   sub_step(I, b, c, d, a, 13, 21, 60);
00210   sub_step(I, a, b, c, d,  4,  6, 61);
00211   sub_step(I, d, a, b, c, 11, 10, 62);
00212   sub_step(I, c, d, a, b,  2, 15, 63);
00213   sub_step(I, b, c, d, a,  9, 21, 64);
00214 }
00215 
00216 // step  implementation.
00217 inline
00218 void MD5::step()
00219 {
00220   sav();
00221   round1();
00222   round2();
00223   round3();
00224   round4();
00225   a += aa;
00226   b += bb;
00227   c += cc;
00228   d += dd;
00229 };
00230 
00231 // sub step implementation.
00232 template <class Fun>
00233 inline
00234 void MD5::sub_step(const Fun &fun,
00235                    storage_type &a,
00236                    const storage_type &b,
00237                    const storage_type &c,
00238                    const storage_type &d,
00239                    unsigned k,
00240                    unsigned s,
00241                    unsigned i)
00242 {
00243   a += fun(b, c, d) + (X[k] + T[i - 1]);
00244   a = a<<s | a>>(32-s);
00245   a += b;
00246   //a = b + ((a + fun(b, c, d) + X[k] + T[i - 1]) << s);
00247 }
00248 
00249 // gen_sub_key implementation.
00250 inline
00251 void MD5::gen_sub_key(std::vector<key::value_type> &v,
00252                       storage_type x,
00253                       unsigned base)
00254 {
00255   base *= sizeof(value_type);
00256 
00257   for (unsigned i = 0; i < sizeof(value_type); ++i)
00258     v[base + i] = (x & (0xFF << (i * 8))) >> (i * 8);
00259 }
00260 
00261 // gen_key implementation.
00262 
00263 inline
00264 key MD5::gen_key()
00265 {
00266   std::vector<key::value_type>  k;
00267 
00268   k.reserve(16);
00269   gen_sub_key(k, a, 0);
00270   gen_sub_key(k, b, 1);
00271   gen_sub_key(k, c, 2);
00272   gen_sub_key(k, d, 3);
00273   return key(k);
00274 }
00275 
00276 // execute implementation.
00277 inline
00278 key MD5::execute()
00279 {
00280   while (buffer_.size() > current_)
00281     step();
00282   return gen_key();
00283 }
00284 
00285 
00286 // md5 implementation.
00287 template <class I>
00288 inline
00289 key md5(const oln::abstract::non_vectorial_image<I> &im)
00290 {
00291   oln_iter_type(I)      p(im);
00292   buffer        b;
00293 
00294   for_all(p)
00295     b.add(im[p]);
00296   b.append_padding();
00297   b.append_length();
00298 
00299   oln::utils::MD5       md5(b);
00300   return md5.execute();
00301 }
00302 
00303 // md5 implementation.
00304 template <class I>
00305 inline
00306 key md5(const oln::abstract::vectorial_image<I> &im)
00307 {
00308   oln_iter_type(I)      p(im);
00309   buffer        b;
00310   //  unsigned nb =
00311 
00312   for_all(p)
00313     {
00314       for (unsigned i = 0; i < ntg_nb_comp(oln_value_type(I)); ++i)
00315         b.add(im[p][i]);
00316     }
00317   b.append_padding();
00318   b.append_length();
00319 
00320   oln::utils::MD5       md5(b);
00321   return md5.execute();
00322 }
00323 
00324 #endif // !OLENA_OLN_UTILS_MD5_HXX

Generated on Thu Apr 15 20:13:13 2004 for Olena by doxygen 1.3.6-20040222