00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef OLENA_OLN_UTILS_MD5_HXX
00029 # define OLENA_OLN_UTILS_MD5_HXX
00030
00031
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
00042
00043
00044
00045 {
00046 precondition(buffer_.is_append_padding());
00047 precondition(buffer_.is_append_length());
00048 T.reserve(64);
00049 T.push_back(0xd76aa478);
00050 T.push_back(0xe8c7b756);
00051 T.push_back(0x242070db);
00052 T.push_back(0xc1bdceee);
00053 T.push_back(0xf57c0faf);
00054 T.push_back(0x4787c62a);
00055 T.push_back(0xa8304613);
00056 T.push_back(0xfd469501);
00057 T.push_back(0x698098d8);
00058 T.push_back(0x8b44f7af);
00059 T.push_back(0xffff5bb1);
00060 T.push_back(0x895cd7be);
00061 T.push_back(0x6b901122);
00062 T.push_back(0xfd987193);
00063 T.push_back(0xa679438e);
00064 T.push_back(0x49b40821);
00065 T.push_back(0xf61e2562);
00066 T.push_back(0xc040b340);
00067 T.push_back(0x265e5a51);
00068 T.push_back(0xe9b6c7aa);
00069 T.push_back(0xd62f105d);
00070 T.push_back(0x2441453);
00071 T.push_back(0xd8a1e681);
00072 T.push_back(0xe7d3fbc8);
00073 T.push_back(0x21e1cde6);
00074 T.push_back(0xc33707d6);
00075 T.push_back(0xf4d50d87);
00076 T.push_back(0x455a14ed);
00077 T.push_back(0xa9e3e905);
00078 T.push_back(0xfcefa3f8);
00079 T.push_back(0x676f02d9);
00080 T.push_back(0x8d2a4c8a);
00081 T.push_back(0xfffa3942);
00082 T.push_back(0x8771f681);
00083 T.push_back(0x6d9d6122);
00084 T.push_back(0xfde5380c);
00085 T.push_back(0xa4beea44);
00086 T.push_back(0x4bdecfa9);
00087 T.push_back(0xf6bb4b60);
00088 T.push_back(0xbebfbc70);
00089 T.push_back(0x289b7ec6);
00090 T.push_back(0xeaa127fa);
00091 T.push_back(0xd4ef3085);
00092 T.push_back(0x4881d05);
00093 T.push_back(0xd9d4d039);
00094 T.push_back(0xe6db99e5);
00095 T.push_back(0x1fa27cf8);
00096 T.push_back(0xc4ac5665);
00097 T.push_back(0xf4292244);
00098 T.push_back(0x432aff97);
00099 T.push_back(0xab9423a7);
00100 T.push_back(0xfc93a039);
00101 T.push_back(0x655b59c3);
00102 T.push_back(0x8f0ccc92);
00103 T.push_back(0xffeff47d);
00104 T.push_back(0x85845dd1);
00105 T.push_back(0x6fa87e4f);
00106 T.push_back(0xfe2ce6e0);
00107 T.push_back(0xa3014314);
00108 T.push_back(0x4e0811a1);
00109 T.push_back(0xf7537e82);
00110 T.push_back(0xbd3af235);
00111 T.push_back(0x2ad7d2bb);
00112 T.push_back(0xeb86d391);
00113 };
00114
00115
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
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
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
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
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
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
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
00247 }
00248
00249
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
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
00277 inline
00278 key MD5::execute()
00279 {
00280 while (buffer_.size() > current_)
00281 step();
00282 return gen_key();
00283 }
00284
00285
00286
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
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
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