Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Aлгоритм MD5 (хэш функция) 
:(
    Опции темы
chipset
Дата 7.4.2005, 22:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4071
Регистрация: 11.1.2003
Где: Seattle, US

Репутация: 27
Всего: 164



Автор: Chingachguk

Код

#ifndef _GLOBAL_H
#define _GLOBAL_H

typedef unsigned char UC;
typedef unsigned short UI;
typedef unsigned long UINT4;
typedef unsigned char *POINTER;

#endif //_GLOBAL_H

// MD5.H - header file for MD5C.C
// Copyright © 1991-2, RSA Data Security, Inc. Created 1991.
// All rights reserved.
// License to copy and use this software is granted provided that it
// is identified as the "RSA Data Security, Inc. MD5 Message-Digest
// Algorithm" in all material mentioning or referencing this software
// or this function.
// License is also granted to make and use derivative works provided
// that such works are identified as "derived from the RSA Data
// Security, Inc. MD5 Message-Digest Algorithm" in all material
// mentioning or referencing the derived work.
// RSA Data Security, Inc. makes no representations concerning either
// the merchantability of this software or the suitability of this
// software for any particular purpose. It is provided "as is"
// without express or implied warranty of any kind.
// These notices must be retained in any copies of any part of this
// documentation and/or software.

// MD5 context.
typedef struct
{
 UINT4 state[4];           // state (ABCD)
 UINT4 count[2];           // number of bits, modulo 2^64 (lsb first)
 UC buffer[64];            // input buffer
} MD5_CTX;

void MDInit   (MD5_CTX *);
void MDUpdate (MD5_CTX *, UC *, UI);
void MDFinal  (UC [16], MD5_CTX *);

// MDFILE.C - Реализация обработки файла по алгоритму шифрования MD5.
// Возвращаемое значение - строка шестнадцатиричных цифр, длиной 32 символа.  

#include <stdio.h>
#include <string.h>

#include "global.h"
#include "md5.h"

// Константы для MD5Transform.
#define S11      7
#define S12     12
#define S13     17
#define S14     22
#define S21      5
#define S22      9
#define S23     14
#define S24     20
#define S31      4
#define S32     11
#define S33     16
#define S34     23
#define S41      6
#define S42     10
#define S43     15
#define S44     21

// Прототипы.
static void MDTransform (UINT4 [4], UC [64]);
static void Encode      (UC *, UINT4 *, UI);
static void Decode      (UINT4 *, UC *, UI);

// -------------------------------------------------------------------------
static UC PADDING[64] = {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

// F, G, H и I - основные функции алгоритма MD5.
#define F(x, y, z) (((x) & (y)) | ((~x) & ( z)))
#define G(x, y, z) (((x) & (z)) | (( y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))

// ROTATE_LEFT - циклический сдвиг x влево на n бит.
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))

// FF, GG, HH, и II преобразования для округлений 1, 2, 3, и 4.
// Циклический сдвиг разделен со сложением во избежании перерасчета.
#define FF(a, b, c, d, x, s, ac) {\
 (a) += F ((b), ©, (d)) + (x) + (UINT4)(ac);\
 (a)  = ROTATE_LEFT ((a), (s));\
 (a) += (b);}

#define GG(a, b, c, d, x, s, ac) {\
 (a) += G ((b), ©, (d)) + (x) + (UINT4)(ac);\
 (a)  = ROTATE_LEFT ((a), (s));\
 (a) += (b);}

#define HH(a, b, c, d, x, s, ac) {\
 (a) += H ((b), ©, (d)) + (x) + (UINT4)(ac);\
 (a)  = ROTATE_LEFT ((a), (s));\
 (a) += (b);}

#define II(a, b, c, d, x, s, ac) {\
 (a) += I ((b), ©, (d)) + (x) + (UINT4)(ac);\
 (a) = ROTATE_LEFT ((a), (s));\
 (a) += (b);}

// -------------------------------------------------------------------------
// MD5 инициализация. Начало операции кодирования MD5, запись нового контекста.
void MDInit(MD5_CTX *context)
{
 context->count[0] = context->count[1] = 0;
 // Загрузка "магических" инициирующих констант .
 context->state[0] = 0x67452301;
 context->state[1] = 0xefcdab89;
 context->state[2] = 0x98badcfe;
 context->state[3] = 0x10325476;
}

// -------------------------------------------------------------------------
// MD5 операция модификации блока. Продолжает операцию кодирования MD5, 
// обрабатывает блок сообщения и модифицирует контекст.
void MDUpdate(MD5_CTX *context, UC *input, UI inputLen)
{
 UI i, index, partLen;

 // Подсчитываем число байт по модулю 64.
 index = (UI)((context->count[0] >> 3) & 0x3F);

 // Модифицируем число бит.
 if ((context->count[0] += ((UINT4)inputLen << 3))
      < ((UINT4)inputLen << 3))
    context->count[1]++;
 context->count[1] += ((UINT4)inputLen >> 29);

 partLen = 64 - index;

 // Выполняем преобразование столько раз, сколько возможно.
 if (inputLen >= partLen)
  {
    memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen);
 MDTransform (context->state, context->buffer);

    for (i = partLen; i + 63 < inputLen; i += 64)
       MDTransform(context->state, &input[i]);

    index = 0;
  }
 else
    i = 0;

 // Ввод остатка буфера
 memcpy((POINTER)&context->buffer[index], (POINTER)&input[i],inputLen-i);
}

// -------------------------------------------------------------------------
// MD5 завершение. Завершает операцию кодирования MD5, записывает цифровую 
// строку сообщения и обнуляет контекст.
void MDFinal(UC digest[16], MD5_CTX *context)
{
 UC bits[8];
 UI index, padLen;

 // Сохраняем число бит
 Encode(bits, context->count, 8);

 // Подбиваем до 56 по модулю 64
 index = (UI)((context->count[0] >> 3) & 0x3f);
 padLen = (index < 56) ? (56 - index) : (120 - index);
 MDUpdate(context, PADDING, padLen);

 // Добавляем длину (перед подбивкой)
 MDUpdate(context, bits, 8);

 // Сохраняем состояние в цифровой строке
 Encode(digest, context->state, 16);

 // Обнуляем чувствительную информацию
 memset((POINTER)context, 0, sizeof (*context));
}

// -------------------------------------------------------------------------
static void MDTransformF (UINT4 s[4], UINT4 x[16])
{
 FF(s[0], s[1], s[2], s[3], x[ 0], S11, 0xd76aa478);     //  1
 FF(s[3], s[0], s[1], s[2], x[ 1], S12, 0xe8c7b756);     //  2
 FF(s[2], s[3], s[0], s[1], x[ 2], S13, 0x242070db);     //  3
 FF(s[1], s[2], s[3], s[0], x[ 3], S14, 0xc1bdceee);     //  4
 FF(s[0], s[1], s[2], s[3], x[ 4], S11, 0xf57c0faf);     //  5
 FF(s[3], s[0], s[1], s[2], x[ 5], S12, 0x4787c62a);     //  6
 FF(s[2], s[3], s[0], s[1], x[ 6], S13, 0xa8304613);     //  7
 FF(s[1], s[2], s[3], s[0], x[ 7], S14, 0xfd469501);     //  8
 FF(s[0], s[1], s[2], s[3], x[ 8], S11, 0x698098d8);     //  9
 FF(s[3], s[0], s[1], s[2], x[ 9], S12, 0x8b44f7af);     // 10
 FF(s[2], s[3], s[0], s[1], x[10], S13, 0xffff5bb1);     // 11
 FF(s[1], s[2], s[3], s[0], x[11], S14, 0x895cd7be);     // 12
 FF(s[0], s[1], s[2], s[3], x[12], S11, 0x6b901122);     // 13
 FF(s[3], s[0], s[1], s[2], x[13], S12, 0xfd987193);     // 14
 FF(s[2], s[3], s[0], s[1], x[14], S13, 0xa679438e);     // 15
 FF(s[1], s[2], s[3], s[0], x[15], S14, 0x49b40821);     // 16
}

// -------------------------------------------------------------------------
static void MDTransformG (UINT4 s[4], UINT4 x[16])
{
 GG(s[0], s[1], s[2], s[3], x[ 1], S21, 0xf61e2562);     // 17
 GG(s[3], s[0], s[1], s[2], x[ 6], S22, 0xc040b340);     // 18
 GG(s[2], s[3], s[0], s[1], x[11], S23, 0x265e5a51);     // 19
 GG(s[1], s[2], s[3], s[0], x[ 0], S24, 0xe9b6c7aa);     // 20
 GG(s[0], s[1], s[2], s[3], x[ 5], S21, 0xd62f105d);     // 21
 GG(s[3], s[0], s[1], s[2], x[10], S22, 0x02441453);     // 22
 GG(s[2], s[3], s[0], s[1], x[15], S23, 0xd8a1e681);     // 23
 GG(s[1], s[2], s[3], s[0], x[ 4], S24, 0xe7d3fbc8);     // 24
 GG(s[0], s[1], s[2], s[3], x[ 9], S21, 0x21e1cde6);     // 25
 GG(s[3], s[0], s[1], s[2], x[14], S22, 0xc33707d6);     // 26
 GG(s[2], s[3], s[0], s[1], x[ 3], S23, 0xf4d50d87);     // 27
 GG(s[1], s[2], s[3], s[0], x[ 8], S24, 0x455a14ed);     // 28
 GG(s[0], s[1], s[2], s[3], x[13], S21, 0xa9e3e905);     // 29
 GG(s[3], s[0], s[1], s[2], x[ 2], S22, 0xfcefa3f8);     // 30
 GG(s[2], s[3], s[0], s[1], x[ 7], S23, 0x676f02d9);     // 31
 GG(s[1], s[2], s[3], s[0], x[12], S24, 0x8d2a4c8a);     // 32
}

// -------------------------------------------------------------------------
static void MDTransformH (UINT4 s[4], UINT4 x[16])
{
 HH(s[0], s[1], s[2], s[3], x[ 5], S31, 0xfffa3942);     // 33
 HH(s[3], s[0], s[1], s[2], x[ 8], S32, 0x8771f681);     // 34
 HH(s[2], s[3], s[0], s[1], x[11], S33, 0x6d9d6122);     // 35
 HH(s[1], s[2], s[3], s[0], x[14], S34, 0xfde5380c);     // 36
 HH(s[0], s[1], s[2], s[3], x[ 1], S31, 0xa4beea44);     // 37
 HH(s[3], s[0], s[1], s[2], x[ 4], S32, 0x4bdecfa9);     // 38
 HH(s[2], s[3], s[0], s[1], x[ 7], S33, 0xf6bb4b60);     // 39
 HH(s[1], s[2], s[3], s[0], x[10], S34, 0xbebfbc70);     // 40
 HH(s[0], s[1], s[2], s[3], x[13], S31, 0x289b7ec6);     // 41
 HH(s[3], s[0], s[1], s[2], x[ 0], S32, 0xeaa127fa);     // 42
 HH(s[2], s[3], s[0], s[1], x[ 3], S33, 0xd4ef3085);     // 43
 HH(s[1], s[2], s[3], s[0], x[ 6], S34, 0x04881d05);     // 44
 HH(s[0], s[1], s[2], s[3], x[ 9], S31, 0xd9d4d039);     // 45
 HH(s[3], s[0], s[1], s[2], x[12], S32, 0xe6db99e5);     // 46
 HH(s[2], s[3], s[0], s[1], x[15], S33, 0x1fa27cf8);     // 47
 HH(s[1], s[2], s[3], s[0], x[ 2], S34, 0xc4ac5665);     // 48
}

// -------------------------------------------------------------------------
static void MDTransformI (UINT4 s[4], UINT4 x[16])
{
 II(s[0], s[1], s[2], s[3], x[ 0], S41, 0xf4292244);     // 49
 II(s[3], s[0], s[1], s[2], x[ 7], S42, 0x432aff97);     // 50
 II(s[2], s[3], s[0], s[1], x[14], S43, 0xab9423a7);     // 51
 II(s[1], s[2], s[3], s[0], x[ 5], S44, 0xfc93a039);     // 52
 II(s[0], s[1], s[2], s[3], x[12], S41, 0x655b59c3);     // 53
 II(s[3], s[0], s[1], s[2], x[ 3], S42, 0x8f0ccc92);     // 54
 II(s[2], s[3], s[0], s[1], x[10], S43, 0xffeff47d);     // 55
 II(s[1], s[2], s[3], s[0], x[ 1], S44, 0x85845dd1);     // 56
 II(s[0], s[1], s[2], s[3], x[ 8], S41, 0x6fa87e4f);     // 57
 II(s[3], s[0], s[1], s[2], x[15], S42, 0xfe2ce6e0);     // 58
 II(s[2], s[3], s[0], s[1], x[ 6], S43, 0xa3014314);     // 59
 II(s[1], s[2], s[3], s[0], x[13], S44, 0x4e0811a1);     // 60
 II(s[0], s[1], s[2], s[3], x[ 4], S41, 0xf7537e82);     // 61
 II(s[3], s[0], s[1], s[2], x[11], S42, 0xbd3af235);     // 62
 II(s[2], s[3], s[0], s[1], x[ 2], S43, 0x2ad7d2bb);     // 63
 II(s[1], s[2], s[3], s[0], x[ 9], S44, 0xeb86d391);     // 64
}

// -------------------------------------------------------------------------
// MD5 основное преобразование. Преобразования структуры на базе блока.
static void MDTransform(UINT4 state[4], UC block[64])
{
 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
 
 Decode(x, block, 64);

 MDTransformF (state, x);
 MDTransformG (state, x);
 MDTransformH (state, x);
 MDTransformI (state, x);
 
 state[0] += a;
 state[1] += b;
 state[2] += c;
 state[3] += d;

 // Обнуляем чувствительную информацию
 memset((POINTER)x, 0, sizeof (x));
}

// -------------------------------------------------------------------------
// Кодируем вход (UINT4) в выход (UC). Добавляем длину, умноженную на 4.
static void Encode(UC *output, UINT4 *input, UI len)
{
 UI i, j;

 for (i = 0, j = 0; j < len; i++, j += 4)
  {
   output[ j ] = (UC)(input[i]         & 0xff);
   output[j+1] = (UC)((input[i] >>  8) & 0xff);
   output[j+2] = (UC)((input[i] >> 16) & 0xff);
   output[j+3] = (UC)((input[i] >> 24) & 0xff);
  }
}

// -------------------------------------------------------------------------
// Декодируем вход (UC), выход (UINT4). Добавляем длину, умноженную на 4.
static void Decode(UINT4 *output, UC *input, UI len)
{
 UI i, j;

 for (i = 0, j = 0; j < len; i++, j += 4)
   output[i] = ((UINT4)input[ j ])        | 
              (((UINT4)input[j+1]) <<  8) |
              (((UINT4)input[j+2]) << 16) | 
              (((UINT4)input[j+3]) << 24);
}

// -------------------------------------------------------------------------
// Формирование цифровой строки по файлу.
unsigned int MDFile(char *filename, char *res)
{
 FILE   *file;
 MD5_CTX context;
 int     len;
 UC      buffer[1024], digest[16];
 
 if ((file = fopen(filename, "rb")) == NULL)
    return(0);                      // Ошибка открытия файла
 else
{
    MDInit(&context);
    while ( (len= fread (buffer, 1, 1024, file)) )
       MDUpdate(&context, buffer, len);
    MDFinal(digest, &context);

    // Формируем возвращаемую строку
    for (len = 0; len < 16; len++)  
        sprintf(&res[len*2],"%02x",digest[len]);
    res[32] = '\0';
  }
 
 fclose(file);
 return(1);                         // Все в порядке
}

void main(int argc, char *argv[])
{
char MD5[200];

if ( argc == 1 )
{
printf("\n Error, no input file!!!");
return;
}
MDFile(argv[1], MD5);
printf("\nMD5 sign for file %s: %s", argv[1], MD5);
}

...
Ниже мой код получения MD5. Он оптимизирован по скорости (примерно ~1-20мкс/на 16 байт или меньше) на p120. Состоит из трех процедур:

- MD5Init (P309AD4D2)
- MD5Update (P309AD4FC)
- MD5Final (P309AD5A9)

Входными данными является некая последовательность байт, пусть это будет  StringForHash длиной sizeof StringForHash или какой-то еще.

Сначала ты должен инициализировать следующую струкутру:

Код

MD5_CTX db 68h dup(?)


процедурой MD5Init - всего лишь заполнение части ее (24 байта) "магическими"
числами:

Код

; Инициализировать контекст MD5  
mov  ecx,offset MD5_CTX
call P309AD4D2; MD5Init


Потом ты должен передавать второй процедуре блоки данных (байты входной строки):

Код

; Добавить информацию к контексту
push dword ptr [ebp+10h]; Длина буфера
mov  ecx,offset MD5_CTX; контекст MD5
mov  edx,[ebp+0Ch]; адрес буфера
call P309AD4FC; MD5Update


Добаялять ты можешь сразу все байты строки (как у меня) или побайтно (это связано с тем, сколько байт исходной строки ты можешь держать в памяти одновременно). Добавив все байты, ты формируешь сам MD5-хэш:
Код


; Получить хэш по контексту
mov  ecx,offset MD5_CTX; контекст MD5
call P309AD5A9     ; MD5Final

передавая лишь адрес структуры - контекста. После этого хэшем являются 16 байт в структуре:

mov  esi,offset MD5_CTX+58h; String with hash
mov  ecx,MD5HashSize

По смещению +58h от ее начала (или последние 16 байт). Например, вот что получится в следующем примере:

MD5("Test String") = bd08ba3c982eaad768602536fb8e1184.

EntryStrSize equ 512
MD5HashSize equ 16
...
StringForHash db EntryStrSize dup(?)
MD5Hash  db MD5HashSize dup(?)
.code
...
@@EntryStrDone:
; Формируем MD5-хэш !
push sizeof StringForHash; Длина строки для MD5 - можешь написать 10 - 10 байт и т.д.
push offset StringForHash; Адрес строки для MD5
push offset MD5Hash; Куда будет помещен хэш
call Get_MD5Hash
...

; Процедура получения MD5 хэша (16 байт)
; [ebp+8] - адрес приемника (16 байт)
; [ebp+0Ch] - адрес строки, от которой будет получен хэш
; [ebp+10h] - длина строки
Get_MD5Hash proc
.data
; Буфер для MD5
StrangeBuffer db 80h, 15 dup(0)
            db 16 dup(0)
            db 16 dup(0)
            db 16 dup(0)
.data?
MD5_CTX db 68h dup(?)
.code
push ebp
mov  ebp,esp
; Инициализировать контекст MD5  
mov  ecx,offset MD5_CTX
call P309AD4D2; MD5Init
; Добавить информацию к контексту
cmp  dword ptr [ebp+10h],0; Длина буфера
jz   @@EmptyMD5Str
push dword ptr [ebp+10h]; Длина буфера
mov  ecx,offset MD5_CTX; контекст MD5
mov  edx,[ebp+0Ch]; адрес буфера
call P309AD4FC; MD5Update
@@EmptyMD5Str:
; Получить хэш по контексту
mov  ecx,offset MD5_CTX; контекст MD5
call P309AD5A9     ; MD5Final
; Передать хеш из 16 байт обратно
mov  edi,[ebp+8]; Result string
mov  esi,offset MD5_CTX+58h; String with hash
mov  ecx,MD5HashSize
rep  movsb
pop  ebp
ret  3*4
Get_MD5Hash endp
;***************************************************************************************
; Подпрограмма MD5Init( MD5_CTX - контекст MD5 ) - инициализация контекста MD5
P309AD4D2 proc; Инициализация 24 байт ? по ECX. ECX=0062B9DC...
mov dword ptr [ecx],00000000h; count[1]:=0;
mov dword ptr [ecx+04h],00000000h; count[2]:=0;
mov dword ptr [ecx+08h],67452301h; state[1]:=MagValue1
mov dword ptr [ecx+0Ch],0EFCDAB89h; state[2]:=MagValue2
mov dword ptr [ecx+10h],98BADCFEh; state[3]:=MagValue3
mov dword ptr [ecx+14h],10325476h; state[4]:=MagValue4
ret
P309AD4D2 endp
; Конец подпрограммы 309AD4D2
;***************************************************************************************
; Подпрограмма MD5Update( MD5_CTX - контекст MD5, буфер, длина буфера )
; MD5_CTX - контекст MD5 - в ECX (его адрес)
; буфер - в EDX (его адрес)
; длина буфера - в стеке (первое слово за адресом возврата)
P309AD4FC proc; Что-то делаем с 24 байтами по ECX
push ebp
mov  ebp,esp
push edi
mov  esi,ecx     ; Адрес переданного по ECX контекста
mov  ebp,[ebp+8h]; Длина буффера, переданного нам > EBP
mov  eax,ebp
mov  ebx,edx     ; адрес буффера -> EBX
mov  edx,[esi]     ; 4 байта из переданного в ECX контекста
mov  ecx,edx     ; Положить их в ecx
lea  eax,[edx+eax*8] ; Длина массива * 8 + dd из контекста
and  ecx,01F8h     ; Первые 4 байта из контекста and 01F8h
shr  ecx,3; разделить их на 8
cmp  eax,edx     ; Сравнить: (Длина массива * 8 + dd из контекста) и (dd из контекста)
jae  L309AD522     ; Вышли за пределы ?
inc  dword ptr [esi+04]; Увеличить следующий dd из контекста
L309AD522:
mov  [esi],eax     ; в контекст положить вычисленный eax
mov  eax,ebp    ; Длина буффера, переданного нам > EAX
shr  eax,1Dh     ; Оставить 31,30 и 29 биты ? - 00,00,..
add  [esi+04],eax; Добавить к следующему dd контекста
dec  ebp             ; Уменьшить длину буффера, переданного нам
js   L309AD59F     ; Равна 0 ? -> На выход
L309AD53A:
mov  al,[ebx]     ; Взять байт переданного буффера
inc  ebx             ; Указать на следующий байт
mov  [ecx+esi+18h],al; Положить его в [4 байта из переданного в ((ECX and 01F8h) shr 3 +
; + адрес переданного массива в 24 байта + следующие в нем 24 байта)
inc  ecx     ; Прирастить разделенный на 8 первый элемент массива
cmp  ecx,40h     ; Он вдруг стал 64 ?
jnz  L309AD593     ; Да, да ...
lea  edx,[esi+18h]
lea  ecx,[esi+08h]
call P309AD671     ; МАКРОСЫ
xor  ecx,ecx
L309AD593:
dec  ebp             ; Длина буффера, переданного нам
jns  L309AD53A
L309AD59F:
pop  edi
pop  ebp
ret  4
P309AD4FC endp
; Конец подпрограммы 309AD4FC
;***************************************************************************************
; Подпрограмма 309AD5A9
; Пока кандидат на MD5Final (MD5_CTX - контекст, digest - наполняемый буфер 10h)
; ECX - адрес контекста MD5 ?
P309AD5A9 proc; ECX=адрес контекста
push edi
mov  eax,[ecx+4]; Взять второе слово контекста
mov  esi,ecx     ; Адрес контекста
mov  [esi+18h+3Ch],eax; <- второе слово контекста
mov  ecx,[esi]     ; Первое слово контекста
mov  [esi+18h+38h],ecx; <- Первое слово контекста
and  ecx,1F8h     ; с 1-м словом
shr  ecx,3; /8
mov  eax,38h
cmp  ecx,eax
jl   L309AD5D5
mov  eax,78h
L309AD5D5:
sub  eax,ecx
mov  edx,offset StrangeBuffer
push eax
mov  ecx,esi     ; Адрес буфера
call P309AD4FC     ; MD5Update
lea  edx,[esi+18h]
add  esi,8h
mov  ecx,esi
call P309AD671     ; Макроподстановки MD5
lea  edi,[esi+50h]
movsd
movsd
movsd
movsd
pop  edi
ret
P309AD5A9 endp
;***
; Подпрограмма 309AD671 - Макроподстановки MD5
; edx - адрес массива x[16] из long-ов
; ecx - адрес массива s[4] из long-ов ?!
;// Константы для MD5Transform.
S11 equ 7
S12 equ 12
S13 equ 17
S14 equ 22
S21 equ 5
S22 equ 9
S23 equ 14
S24 equ 20
S31 equ 4
S32 equ 11
S33 equ 16
S34 equ 23
S41 equ 6
S42 equ 10
S43 equ 15
S44 equ 21
s0 equ eax ; Элемент s[0]
s1 equ ebx ; Элемент s[1]
s2 equ esi ; Элемент s[2]
s3 equ ebp ; Элемент s[3]
x0 equ dword ptr [edi]   ; Элемент x[0]
x1 equ dword ptr [edi+4] ; Элемент x[1]
x2 equ dword ptr [edi+8] ; Элемент x[2]
x3 equ dword ptr [edi+0Ch]; Элемент x[3]
x4 equ dword ptr [edi+10h]; Элемент x[4]
x5 equ dword ptr [edi+14h]; Элемент x[5]
x6 equ dword ptr [edi+18h]; Элемент x[6]
x7 equ dword ptr [edi+1Ch]; Элемент x[7]
x8 equ dword ptr [edi+20h]; Элемент x[8]
x9 equ dword ptr [edi+24h]; Элемент x[9]
x10 equ dword ptr [edi+28h]; Элемент x[10]
x11 equ dword ptr [edi+2Ch]; Элемент x[11]
x12 equ dword ptr [edi+30h]; Элемент x[12]
x13 equ dword ptr [edi+34h]; Элемент x[13]
x14 equ dword ptr [edi+38h]; Элемент x[14]
x15 equ dword ptr [edi+3Ch]; Элемент x[15]
PFF macro  _a,_b,_c,_d,_x,_s,_ac
lea  ecx,[_a+_ac]
mov  _a,_b
and  _a,_c
add  ecx,_x
mov  edx,_b
not  edx
and  edx,_d
or   _a,edx
add  _a,ecx
rol  _a,_s
add  _a,_b
endm
PGG macro  _a,_b,_c,_d,_x,_s,_ac
mov  ecx,_c
mov  edx,_d
not  edx
and  ecx,edx
mov  edx,_b
and  edx,_d
or   edx,ecx
lea  _a,[_a+edx+_ac]
add  _a,_x
rol  _a,_s
add  _a,_b
endm
PHH macro  _a,_b,_c,_d,_x,_s,_ac
mov  ecx,_b
xor  ecx,_c
xor  ecx,_d  
lea  _a,[_a+ecx+_ac]
add  _a,_x
rol  _a,_s
add  _a,_b
endm
PII macro  _a,_b,_c,_d,_x,_s,_ac
mov  ecx,_b
mov  edx,_d
not  edx
or   ecx,edx
mov  edx,_c
xor  edx,ecx
lea  _a,[_a+edx+_ac]
add  _a,_x
rol  _a,_s
add  _a,_b
endm
P309AD671 proc
  pushad
  mov  edi,edx
  mov  s0,[ecx]      ; s[0]
  mov  s1,[ecx+4]    ; s[1]
  mov  s2,[ecx+8]    ; s[2]
  mov  s3,[ecx+0Ch]  ; s[3]
  push ecx
;static void MDTransformF (UINT4 s[4, UINT4 x16])
  PFF s0,s1,s2,s3,x0,S11,0d76aa478h; //  1
  PFF s3,s0,s1,s2,x1,S12,0e8c7b756h; //  2
  PFF s2,s3,s0,s1,x2,S13,0242070dbh; //  3
  PFF s1,s2,s3,s0,x3,S14,0c1bdceeeh; //  4
  PFF s0,s1,s2,s3,x4,S11,0f57c0fafh; //  5
  PFF s3,s0,s1,s2,x5,S12,04787c62ah; //  6
  PFF s2,s3,s0,s1,x6,S13,0a8304613h; //  7
  PFF s1,s2,s3,s0,x7,S14,0fd469501h; //  8
  PFF s0,s1,s2,s3,x8,S11,0698098d8h; //  9
  PFF s3,s0,s1,s2,x9,S12,08b44f7afh; // 10
  PFF s2,s3,s0,s1,x10,S13,0ffff5bb1h; // 11
  PFF s1,s2,s3,s0,x11,S14,0895cd7beh; // 12
  PFF s0,s1,s2,s3,x12,S11,06b901122h; // 13
  PFF s3,s0,s1,s2,x13,S12,0fd987193h; // 14
  PFF s2,s3,s0,s1,x14,S13,0a679438eh; // 15
  PFF s1,s2,s3,s0,x15,S14,049b40821h; // 16
; static void MDTransformG (UINT4 s[4, UINT4 x16])
  PGG s0,s1,s2,s3,x1,S21, 0f61e2562h; // 17
  PGG s3,s0,s1,s2,x6,S22, 0c040b340h; // 18
  PGG s2,s3,s0,s1,x11,S23,0265e5a51h; // 19
  PGG s1,s2,s3,s0,x0,S24, 0e9b6c7aah; // 20
  PGG s0,s1,s2,s3,x5,S21, 0d62f105dh; // 21
  PGG s3,s0,s1,s2,x10,S22,002441453h; // 22
  PGG s2,s3,s0,s1,x15,S23,0d8a1e681h; // 23
  PGG s1,s2,s3,s0,x4,S24, 0e7d3fbc8h; // 24
  PGG s0,s1,s2,s3,x9,S21, 021e1cde6h; // 25
  PGG s3,s0,s1,s2,x14,S22,0c33707d6h; // 26
  PGG s2,s3,s0,s1,x3,S23, 0f4d50d87h; // 27
  PGG s1,s2,s3,s0,x8,S24, 0455a14edh; // 28
  PGG s0,s1,s2,s3,x13,S21,0a9e3e905h; // 29
  PGG s3,s0,s1,s2,x2,S22, 0fcefa3f8h; // 30
  PGG s2,s3,s0,s1,x7,S23, 0676f02d9h; // 31
  PGG s1,s2,s3,s0,x12,S24,08d2a4c8ah; // 32
; static void MDTransformH (UINT4 s[4, UINT4 x16])
  PHH s0,s1,s2,s3,x5,S31, 0fffa3942h; // 33
  PHH s3,s0,s1,s2,x8,S32, 08771f681h; // 34
  PHH s2,s3,s0,s1,x11,S33,06d9d6122h; // 35
  PHH s1,s2,s3,s0,x14,S34,0fde5380ch; // 36
  PHH s0,s1,s2,s3,x1,S31, 0a4beea44h; // 37
  PHH s3,s0,s1,s2,x4,S32, 04bdecfa9h; // 38
  PHH s2,s3,s0,s1,x7,S33, 0f6bb4b60h; // 39
  PHH s1,s2,s3,s0,x10,S34,0bebfbc70h; // 40
  PHH s0,s1,s2,s3,x13,S31,0289b7ec6h; // 41
  PHH s3,s0,s1,s2,x0,S32, 0eaa127fah; // 42
  PHH s2,s3,s0,s1,x3,S33, 0d4ef3085h; // 43
  PHH s1,s2,s3,s0,x6,S34, 004881d05h; // 44
  PHH s0,s1,s2,s3,x9,S31, 0d9d4d039h; // 45
  PHH s3,s0,s1,s2,x12,S32,0e6db99e5h; // 46
  PHH s2,s3,s0,s1,x15,S33,01fa27cf8h; // 47
  PHH s1,s2,s3,s0,x2,S34, 0c4ac5665h; // 48
; static void MDTransformI (UINT4 s[4, UINT4 x16])
  PII s0,s1,s2,s3,x0,S41, 0f4292244h; // 49
  PII s3,s0,s1,s2,x7,S42, 0432aff97h; // 50
  PII s2,s3,s0,s1,x14,S43,0ab9423a7h; // 51
  PII s1,s2,s3,s0,x5,S44, 0fc93a039h; // 52
  PII s0,s1,s2,s3,x12,S41,0655b59c3h; // 53
  PII s3,s0,s1,s2,x3,S42, 08f0ccc92h; // 54
  PII s2,s3,s0,s1,x10,S43,0ffeff47dh; // 55
  PII s1,s2,s3,s0,x1,S44, 085845dd1h; // 56
  PII s0,s1,s2,s3,x8,S41, 06fa87e4fh; // 57
  PII s3,s0,s1,s2,x15,S42,0fe2ce6e0h; // 58
  PII s2,s3,s0,s1,x6,S43, 0a3014314h; // 59
  PII s1,s2,s3,s0,x13,S44,04e0811a1h; // 60
  PII s0,s1,s2,s3,x4,S41, 0f7537e82h; // 61
  PII s3,s0,s1,s2,x11,S42,0bd3af235h; // 62
  PII s2,s3,s0,s1,x2,S43, 02ad7d2bbh; // 63
  PII s1,s2,s3,s0,x9,S44, 0eb86d391h; // 64
; Добавить результат к первичным значениям !!!
  pop ecx
  add [ecx],s0      ; s[0]
  add [ecx+4],s1    ; s[1]
  add [ecx+8],s2    ; s[2]
  add [ecx+0Ch],s3  ; s[3]
  popad
  ret
P309AD671 endp



--------------------
Цитата(Jimi Hendrix)
Well, I stand up next to a mountain
And I chop it down with the edge of my hand
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0931 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.