Guest User

Untitled

a guest
Nov 28th, 2021
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.76 KB | None | 0 0
  1. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  2. /* memcpy_test.c */
  3. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  4.  
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <time.h>
  8. #include <string.h>
  9. #include "md5.h"
  10. #include "tools.h"
  11.  
  12. #define BLOCK_SIZE (8LLU * 1024LLU * 1024LLU * 1024LLU)
  13.  
  14. static void test(const uint8_t *const data, const size_t size, uint8_t *const digest)
  15. {
  16.     md5_context_t ctx;
  17.     md5_init(&ctx);
  18.     md5_update(&ctx, data, size);
  19.     memcpy(digest, md5_finalize(&ctx), 16U);
  20. }
  21.  
  22. static void test2(const uint8_t *const data, const size_t size, uint8_t* const digest)
  23. {
  24.     const uint8_t* p;
  25.     uint64_t temp;
  26.     md5_context_t ctx;
  27.     const uint8_t* const end = data + size;
  28.     md5_init(&ctx);
  29.     for (p = data; p < end; p += sizeof(uint64_t))
  30.     {
  31.         memcpy(&temp, p, sizeof(uint64_t));
  32.         md5_update(&ctx, (const uint8_t*)&temp, sizeof(uint64_t));
  33.     }
  34.     memcpy(digest, md5_finalize(&ctx), 16U);
  35. }
  36.  
  37. int main()
  38. {
  39.     uint8_t *p;
  40.     uint8_t digest[16U];
  41.     size_t i = 0LLU;
  42.     clock_t clk_0, clk_1;
  43.     int repeat = 1;
  44.  
  45.     fputs("Allocating memory, please wait...\n", stderr);
  46.     uint8_t* const data = allocate_memory(BLOCK_SIZE);
  47.     if (!data)
  48.     {
  49.         fputs("Allocation failed!", stderr);
  50.         exit(-1);
  51.     }
  52.     fputs("Done.\n\n", stderr);
  53.  
  54.     fputs("Filling memory, please wait...\n", stderr);
  55.     srand(42U);
  56.     for (p = data; p < data + BLOCK_SIZE; p += sizeof(uint32_t))
  57.     {
  58.         *((uint32_t*)p) = (rand() & 0xFFF) | ((rand() & 0xFFF) << 12) | ((rand() & 0xFFF) << 24);
  59.         if (++i >= 9973U)
  60.         {
  61.             fprintf(stderr, "\r%.1f%%", 100.0 * (((double)(p - data)) / ((double)BLOCK_SIZE)));
  62.             i = 0U;
  63.         }
  64.     }
  65.     fputs("\r100.0%\n\n", stderr);
  66.  
  67. repeat:
  68.  
  69.     /* -------------------------- TEST #1 -------------------------- */
  70.  
  71.     fputs("Computing hash #1, please wait...\n", stderr);
  72.  
  73.     clk_0 = clock();
  74.     test(data, BLOCK_SIZE, digest);
  75.     clk_1 = clock();
  76.     fputs("Done.\n\n", stderr);
  77.  
  78.     for (i = 0U; i < 16U; i++)
  79.     {
  80.         fprintf(stderr, "%02X", digest[i]);
  81.     }
  82.  
  83.     fprintf(stderr, "\nTime #1: %lu\n\n", clk_1 - clk_0);
  84.  
  85.     /* -------------------------- TEST #2 -------------------------- */
  86.  
  87.     fputs("Computing hash #2, please wait...\n", stderr);
  88.  
  89.     clk_0 = clock();
  90.     test2(data, BLOCK_SIZE, digest);
  91.     clk_1 = clock();
  92.     fputs("Done.\n\n", stderr);
  93.  
  94.     for (i = 0U; i < 16U; i++)
  95.     {
  96.         fprintf(stderr, "%02X", digest[i]);
  97.     }
  98.  
  99.     fprintf(stderr, "\nTime #2: %lu\n\n", clk_1 - clk_0);
  100.  
  101.     /* -------------------------- FINISH -------------------------- */
  102.  
  103.     if (repeat > 0)
  104.     {
  105.         --repeat;
  106.         goto  repeat;
  107.     }
  108. }
  109.  
  110.  
  111. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  112. /* md5.h */
  113. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  114.  
  115. #ifndef MD5_H
  116. #define MD5_H
  117.  
  118. #include <stdint.h>
  119.  
  120. typedef struct
  121. {
  122.     uint64_t size;
  123.     uint32_t buffer[4U];
  124.     uint8_t input[64U];
  125.     uint8_t digest[16U];
  126. }
  127. md5_context_t;
  128.  
  129. void md5_init(md5_context_t *const ctx);
  130. void md5_update(md5_context_t *const ctx, const uint8_t *const input_buffer, const size_t input_len);
  131. const uint8_t* md5_finalize(md5_context_t *const ctx);
  132.  
  133. #endif
  134.  
  135.  
  136. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  137. /* md5.c */
  138. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  139.  
  140. #include "md5.h"
  141.  
  142. #define A 0x67452301
  143. #define B 0xefcdab89
  144. #define C 0x98badcfe
  145. #define D 0x10325476
  146.  
  147. #pragma warning(disable: 6386)
  148.  
  149. static uint32_t S[] =
  150. {
  151.     7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
  152.     5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20,
  153.     4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
  154.     6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
  155. };
  156.  
  157. static uint32_t K[] =
  158. {
  159.     0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
  160.     0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
  161.     0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
  162.     0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
  163.     0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
  164.     0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
  165.     0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
  166.     0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
  167.     0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
  168.     0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
  169.     0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
  170.     0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
  171.     0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
  172.     0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
  173.     0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
  174.     0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
  175. };
  176.  
  177. #define F(X, Y, Z) ((X & Y) | (~X & Z))
  178. #define G(X, Y, Z) ((X & Z) | (Y & ~Z))
  179. #define H(X, Y, Z) (X ^ Y ^ Z)
  180. #define I(X, Y, Z) (Y ^ (X | ~Z))
  181.  
  182. static uint8_t PADDING[] =
  183. {
  184.     0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  185.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  186.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  187.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  188.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  189.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  190.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  191.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  192. };
  193.  
  194. static uint32_t rotate_left(const uint32_t x, const uint32_t n)
  195. {
  196.     return (x << n) | (x >> (32 - n));
  197. }
  198.  
  199. static void md5_step(uint32_t *const buffer, const uint32_t *const input)
  200. {
  201.     uint32_t AA = buffer[0];
  202.     uint32_t BB = buffer[1];
  203.     uint32_t CC = buffer[2];
  204.     uint32_t DD = buffer[3];
  205.  
  206.     uint32_t E;
  207.     unsigned int j;
  208.  
  209.     for (unsigned int i = 0; i < 64; ++i) {
  210.         switch (i / 16) {
  211.         case 0:
  212.             E = F(BB, CC, DD);
  213.             j = i;
  214.             break;
  215.         case 1:
  216.             E = G(BB, CC, DD);
  217.             j = ((i * 5) + 1) % 16;
  218.             break;
  219.         case 2:
  220.             E = H(BB, CC, DD);
  221.             j = ((i * 3) + 5) % 16;
  222.             break;
  223.         default:
  224.             E = I(BB, CC, DD);
  225.             j = (i * 7) % 16;
  226.             break;
  227.         }
  228.  
  229.         uint32_t temp = DD;
  230.         DD = CC;
  231.         CC = BB;
  232.         BB = BB + rotate_left(AA + E + K[i] + input[j], S[i]);
  233.         AA = temp;
  234.     }
  235.  
  236.     buffer[0] += AA;
  237.     buffer[1] += BB;
  238.     buffer[2] += CC;
  239.     buffer[3] += DD;
  240. }
  241.  
  242. void md5_init(md5_context_t *const ctx)
  243. {
  244.     ctx->size      = (uint64_t)0;
  245.     ctx->buffer[0] = (uint32_t)A;
  246.     ctx->buffer[1] = (uint32_t)B;
  247.     ctx->buffer[2] = (uint32_t)C;
  248.     ctx->buffer[3] = (uint32_t)D;
  249. }
  250.  
  251. void md5_update(md5_context_t *const ctx, const uint8_t *const input_buffer, const size_t input_len)
  252. {
  253.     uint32_t input[16];
  254.     unsigned int offset = ctx->size % 64;
  255.     ctx->size += (uint64_t)input_len;
  256.  
  257.     for (size_t i = 0; i < input_len; ++i)
  258.     {
  259.         ctx->input[offset++] = (uint8_t)*(input_buffer + i);
  260.         if (offset % 64 == 0)
  261.         {
  262.             for (unsigned int j = 0; j < 16; ++j)
  263.             {
  264.                 input[j] =
  265.                     (uint32_t)(ctx->input[(j * 4) + 3]) << 24 |
  266.                     (uint32_t)(ctx->input[(j * 4) + 2]) << 16 |
  267.                     (uint32_t)(ctx->input[(j * 4) + 1]) <<  8 |
  268.                     (uint32_t)(ctx->input[(j * 4)]);
  269.             }
  270.             md5_step(ctx->buffer, input);
  271.             offset = 0;
  272.         }
  273.     }
  274. }
  275.  
  276. const uint8_t *md5_finalize(md5_context_t *const ctx)
  277. {
  278.     uint32_t input[16];
  279.     unsigned int offset = ctx->size % 64;
  280.     unsigned int padding_length = offset < 56 ? 56 - offset : (56 + 64) - offset;
  281.  
  282.     md5_update(ctx, PADDING, padding_length);
  283.     ctx->size -= (uint64_t)padding_length;
  284.  
  285.     for (unsigned int j = 0; j < 14; ++j)
  286.     {
  287.         input[j] =
  288.             (uint32_t)(ctx->input[(j * 4) + 3]) << 24 |
  289.             (uint32_t)(ctx->input[(j * 4) + 2]) << 16 |
  290.             (uint32_t)(ctx->input[(j * 4) + 1]) <<  8 |
  291.             (uint32_t)(ctx->input[(j * 4)]);
  292.     }
  293.     input[14] = (uint32_t)(ctx->size * 8);
  294.     input[15] = (uint32_t)((ctx->size * 8) >> 32);
  295.  
  296.     md5_step(ctx->buffer, input);
  297.  
  298.     for (unsigned int i = 0; i < 4; ++i)
  299.     {
  300.         ctx->digest[(i * 4) + 0] = (uint8_t)((ctx->buffer[i] & 0x000000FF));
  301.         ctx->digest[(i * 4) + 1] = (uint8_t)((ctx->buffer[i] & 0x0000FF00) >>  8);
  302.         ctx->digest[(i * 4) + 2] = (uint8_t)((ctx->buffer[i] & 0x00FF0000) >> 16);
  303.         ctx->digest[(i * 4) + 3] = (uint8_t)((ctx->buffer[i] & 0xFF000000) >> 24);
  304.     }
  305.  
  306.     return ctx->digest;
  307. }
  308.  
  309.  
  310. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  311. /* tools.h */
  312. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  313.  
  314. #ifndef TOOLS_H
  315. #define TOOLS_H
  316.  
  317. #include <stdint.h>
  318.  
  319. uint8_t* allocate_memory(const size_t size);
  320.  
  321. #endif
  322.  
  323.  
  324. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  325. /* tools.c */
  326. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  327.  
  328. #define WIN32_LEAN_AND_MEAN 1
  329.  
  330. #include "tools.h"
  331. #include <Windows.h>
  332.  
  333. static volatile SIZE_T allocated = 204800LLU;
  334.  
  335. uint8_t* allocate_memory(const size_t size)
  336. {
  337.     if (SetProcessWorkingSetSize(GetCurrentProcess(), allocated + size, allocated + size))
  338.     {
  339.         const PVOID memory = VirtualAllocEx(GetCurrentProcess(), NULL, size, 0x3000, 0x204);
  340.         if (memory)
  341.         {
  342.             if (VirtualLock(memory, size))
  343.             {
  344.                 allocated += size;
  345.                 return (uint8_t*) memory;
  346.             }
  347.             else
  348.             {
  349.                 VirtualFree(memory, 0U, MEM_RELEASE);
  350.             }
  351.  
  352.         }
  353.     }
  354.     return NULL;
  355. }
  356.  
Advertisement
Add Comment
Please, Sign In to add comment