"Fossies" - the Fresh Open Source Software Archive

Member "darktable-2.6.3/src/external/rawspeed/src/utilities/rstest/md5.cpp" (19 Oct 2019, 7286 Bytes) of package /linux/misc/darktable-2.6.3.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "md5.cpp" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * MD5 hash in C and x86 assembly
    3  *
    4  * Copyright (c) 2016 Project Nayuki
    5  * https://www.nayuki.io/page/fast-md5-hash-implementation-in-x86-assembly
    6  *
    7  * (MIT License)
    8  * Permission is hereby granted, free of charge, to any person obtaining a copy
    9  * of
   10  * this software and associated documentation files (the "Software"), to deal in
   11  * the Software without restriction, including without limitation the rights to
   12  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
   13  * of
   14  * the Software, and to permit persons to whom the Software is furnished to do
   15  * so,
   16  * subject to the following conditions:
   17  * - The above copyright notice and this permission notice shall be included in
   18  *   all copies or substantial portions of the Software.
   19  * - The Software is provided "as is", without warranty of any kind, express or
   20  *   implied, including but not limited to the warranties of merchantability,
   21  *   fitness for a particular purpose and noninfringement. In no event shall the
   22  *   authors or copyright holders be liable for any claim, damages or other
   23  *   liability, whether in an action of contract, tort or otherwise, arising
   24  * from,
   25  *   out of or in connection with the Software or the use or other dealings in
   26  * the
   27  *   Software.
   28  */
   29 
   30 #include "md5.h"
   31 #include <cstdint> // for uint32_t, uint8_t, UINT32_C
   32 #include <cstdio>  // for printf, snprintf
   33 #include <cstring> // for memset, strlen, memcmp, memcpy
   34 #include <string>  // for string
   35 
   36 namespace rawspeed {
   37 
   38 namespace md5 {
   39 
   40 // hashes 64 bytes at once
   41 static void md5_compress(md5_state* state, const uint8_t* block);
   42 
   43 static void md5_compress(md5_state* state, const uint8_t* block) {
   44   std::array<uint32_t, 16> schedule = {{}};
   45 
   46   auto LOADSCHEDULE = [&block, &schedule](int i) {
   47     for (int k = 3; k >= 0; k--)
   48       schedule[i] |= uint32_t(block[4 * i + k]) << (8 * k);
   49   };
   50 
   51   for (int i = 0; i < 16; i++)
   52     LOADSCHEDULE(i);
   53 
   54   // Assumes that x is uint32_t and 0 < n < 32
   55   auto ROTL32 = [](uint32_t x, int n) __attribute__((pure)) {
   56     return (x << n) | (x >> (32 - n));
   57   };
   58 
   59   auto ROUND_TAIL = [ROTL32, &schedule](uint32_t& a, uint32_t b, uint32_t expr,
   60                                         uint32_t k, uint32_t s, uint32_t t) {
   61     a = uint32_t(0UL + a + expr + t + schedule[k]);
   62     (a) = uint32_t(0UL + b + ROTL32(a, s));
   63   };
   64 
   65   auto ROUND0 = [ROUND_TAIL](uint32_t& a, uint32_t b, uint32_t c, uint32_t d,
   66                              uint32_t k, uint32_t s, uint32_t t) {
   67     ROUND_TAIL(a, b, d ^ (b & (c ^ d)), k, s, t);
   68   };
   69 
   70   auto ROUND1 = [ROUND_TAIL](uint32_t& a, uint32_t b, uint32_t c, uint32_t d,
   71                              uint32_t k, uint32_t s, uint32_t t) {
   72     ROUND_TAIL(a, b, c ^ (d & (b ^ c)), k, s, t);
   73   };
   74 
   75   auto ROUND2 = [ROUND_TAIL](uint32_t& a, uint32_t b, uint32_t c, uint32_t d,
   76                              uint32_t k, uint32_t s, uint32_t t) {
   77     ROUND_TAIL(a, b, b ^ c ^ d, k, s, t);
   78   };
   79 
   80   auto ROUND3 = [ROUND_TAIL](uint32_t& a, uint32_t b, uint32_t c, uint32_t d,
   81                              uint32_t k, uint32_t s, uint32_t t) {
   82     ROUND_TAIL(a, b, c ^ (b | ~d), k, s, t);
   83   };
   84 
   85   uint32_t a = (*state)[0];
   86   uint32_t b = (*state)[1];
   87   uint32_t c = (*state)[2];
   88   uint32_t d = (*state)[3];
   89 
   90   ROUND0(a, b, c, d, 0, 7, 0xD76AA478);
   91   ROUND0(d, a, b, c, 1, 12, 0xE8C7B756);
   92   ROUND0(c, d, a, b, 2, 17, 0x242070DB);
   93   ROUND0(b, c, d, a, 3, 22, 0xC1BDCEEE);
   94   ROUND0(a, b, c, d, 4, 7, 0xF57C0FAF);
   95   ROUND0(d, a, b, c, 5, 12, 0x4787C62A);
   96   ROUND0(c, d, a, b, 6, 17, 0xA8304613);
   97   ROUND0(b, c, d, a, 7, 22, 0xFD469501);
   98   ROUND0(a, b, c, d, 8, 7, 0x698098D8);
   99   ROUND0(d, a, b, c, 9, 12, 0x8B44F7AF);
  100   ROUND0(c, d, a, b, 10, 17, 0xFFFF5BB1);
  101   ROUND0(b, c, d, a, 11, 22, 0x895CD7BE);
  102   ROUND0(a, b, c, d, 12, 7, 0x6B901122);
  103   ROUND0(d, a, b, c, 13, 12, 0xFD987193);
  104   ROUND0(c, d, a, b, 14, 17, 0xA679438E);
  105   ROUND0(b, c, d, a, 15, 22, 0x49B40821);
  106   ROUND1(a, b, c, d, 1, 5, 0xF61E2562);
  107   ROUND1(d, a, b, c, 6, 9, 0xC040B340);
  108   ROUND1(c, d, a, b, 11, 14, 0x265E5A51);
  109   ROUND1(b, c, d, a, 0, 20, 0xE9B6C7AA);
  110   ROUND1(a, b, c, d, 5, 5, 0xD62F105D);
  111   ROUND1(d, a, b, c, 10, 9, 0x02441453);
  112   ROUND1(c, d, a, b, 15, 14, 0xD8A1E681);
  113   ROUND1(b, c, d, a, 4, 20, 0xE7D3FBC8);
  114   ROUND1(a, b, c, d, 9, 5, 0x21E1CDE6);
  115   ROUND1(d, a, b, c, 14, 9, 0xC33707D6);
  116   ROUND1(c, d, a, b, 3, 14, 0xF4D50D87);
  117   ROUND1(b, c, d, a, 8, 20, 0x455A14ED);
  118   ROUND1(a, b, c, d, 13, 5, 0xA9E3E905);
  119   ROUND1(d, a, b, c, 2, 9, 0xFCEFA3F8);
  120   ROUND1(c, d, a, b, 7, 14, 0x676F02D9);
  121   ROUND1(b, c, d, a, 12, 20, 0x8D2A4C8A);
  122   ROUND2(a, b, c, d, 5, 4, 0xFFFA3942);
  123   ROUND2(d, a, b, c, 8, 11, 0x8771F681);
  124   ROUND2(c, d, a, b, 11, 16, 0x6D9D6122);
  125   ROUND2(b, c, d, a, 14, 23, 0xFDE5380C);
  126   ROUND2(a, b, c, d, 1, 4, 0xA4BEEA44);
  127   ROUND2(d, a, b, c, 4, 11, 0x4BDECFA9);
  128   ROUND2(c, d, a, b, 7, 16, 0xF6BB4B60);
  129   ROUND2(b, c, d, a, 10, 23, 0xBEBFBC70);
  130   ROUND2(a, b, c, d, 13, 4, 0x289B7EC6);
  131   ROUND2(d, a, b, c, 0, 11, 0xEAA127FA);
  132   ROUND2(c, d, a, b, 3, 16, 0xD4EF3085);
  133   ROUND2(b, c, d, a, 6, 23, 0x04881D05);
  134   ROUND2(a, b, c, d, 9, 4, 0xD9D4D039);
  135   ROUND2(d, a, b, c, 12, 11, 0xE6DB99E5);
  136   ROUND2(c, d, a, b, 15, 16, 0x1FA27CF8);
  137   ROUND2(b, c, d, a, 2, 23, 0xC4AC5665);
  138   ROUND3(a, b, c, d, 0, 6, 0xF4292244);
  139   ROUND3(d, a, b, c, 7, 10, 0x432AFF97);
  140   ROUND3(c, d, a, b, 14, 15, 0xAB9423A7);
  141   ROUND3(b, c, d, a, 5, 21, 0xFC93A039);
  142   ROUND3(a, b, c, d, 12, 6, 0x655B59C3);
  143   ROUND3(d, a, b, c, 3, 10, 0x8F0CCC92);
  144   ROUND3(c, d, a, b, 10, 15, 0xFFEFF47D);
  145   ROUND3(b, c, d, a, 1, 21, 0x85845DD1);
  146   ROUND3(a, b, c, d, 8, 6, 0x6FA87E4F);
  147   ROUND3(d, a, b, c, 15, 10, 0xFE2CE6E0);
  148   ROUND3(c, d, a, b, 6, 15, 0xA3014314);
  149   ROUND3(b, c, d, a, 13, 21, 0x4E0811A1);
  150   ROUND3(a, b, c, d, 4, 6, 0xF7537E82);
  151   ROUND3(d, a, b, c, 11, 10, 0xBD3AF235);
  152   ROUND3(c, d, a, b, 2, 15, 0x2AD7D2BB);
  153   ROUND3(b, c, d, a, 9, 21, 0xEB86D391);
  154 
  155   (*state)[0] = uint32_t(0UL + (*state)[0] + a);
  156   (*state)[1] = uint32_t(0UL + (*state)[1] + b);
  157   (*state)[2] = uint32_t(0UL + (*state)[2] + c);
  158   (*state)[3] = uint32_t(0UL + (*state)[3] + d);
  159 }
  160 
  161 /* Full message hasher */
  162 
  163 void md5_hash(const uint8_t* message, size_t len, md5_state* hash) {
  164   *hash = md5_init;
  165 
  166   size_t i;
  167   for (i = 0; len - i >= 64; i += 64)
  168     md5_compress(hash, &message[i]);
  169 
  170   std::array<uint8_t, 64> block;
  171   size_t rem = len - i;
  172   memcpy(block.data(), &message[i], rem);
  173 
  174   block[rem] = 0x80;
  175   rem++;
  176   if (64 - rem >= 8)
  177     memset(&block[rem], 0, 56 - rem);
  178   else {
  179     memset(&block[rem], 0, 64 - rem);
  180     md5_compress(hash, block.data());
  181     memset(block.data(), 0, 56);
  182   }
  183 
  184   block[64 - 8] = static_cast<uint8_t>((len & 0x1FU) << 3);
  185   len >>= 5;
  186   for (i = 1; i < 8; i++) {
  187     block[64 - 8 + i] = static_cast<uint8_t>(len);
  188     len >>= 8;
  189   }
  190   md5_compress(hash, block.data());
  191 }
  192 
  193 std::string hash_to_string(const md5_state& hash) {
  194   std::array<char, 2 * sizeof(hash) + 1> res;
  195   auto* h = reinterpret_cast<const uint8_t*>(&hash[0]);
  196   for (int i = 0; i < static_cast<int>(sizeof(hash)); ++i)
  197     snprintf(&res[2 * i], 3, "%02x", h[i]);
  198   res[32] = 0;
  199   return res.data();
  200 }
  201 
  202 std::string md5_hash(const uint8_t* message, size_t len) {
  203   md5_state hash;
  204   md5_hash(message, len, &hash);
  205   return hash_to_string(hash);
  206 }
  207 
  208 } // namespace md5
  209 
  210 } // namespace rawspeed