在VC6中用汇编实现MD5运算

来源:互联网 发布:大学生网络科 编辑:程序博客网 时间:2024/05/21 07:07

      很早时候就想写这个东东了。在网上下载了一个C语言的MD5代码,后来朋友又发给我一份用 mm0 mm1 等寄存器(64位)的汇编代码,两者都能完成MD5运算。

      MD5运算的结果是一个“摘要”,16B数据。输入可以是无穷的,但输出是有限的(16B)。可见它是一个不可逆算法(是有损变换)。

      网上有说MD5被破解了,不是很确切。下载了fastcoll程序代码,看了一下,它只是相当快地找到两个不一样的输入,而输出是一样的,这就是说它能快速实现了MD5碰撞。可惜程序并不能自己构造一个输入,使得输出的结果是事先指定好的,也就是说它不能找到一个指定的16B所对应的输入。

      所以,要是想到得一个输出所对应的输入,只有查表法和穷举法了。查表法要的是超大硬盘,穷举法要的是速度(可配合字典)。

      为了追求速度,会用到汇编程序实现MD5,因为MD5中的 FF GG HH II 变换用到的 & | ~ ^  + 还有循环移位等都很适合汇编指令。而用C程序写的MD5程序编译后,看它的汇编指令中有很多可优化的地方。

 

#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))             //  C语言实现的循环移位

编译后为

mov     eax, dword ptr [ebp-14]      // mov     eax, x
shl     eax, 0C                                  // eax << n
mov     ecx, dword ptr [ebp-14]      //  mov     ecx, x
shr     ecx, 14                                  //  ecx  >> 32- n
or      eax, ecx                                 //  eax  = eax | ecx
mov     dword ptr [ebp-14], eax      //  mov     x, eax

 

 

上面做了N步,其实就是一个循环移位,本来用一条指令就行了的    rol  eax, n

mov     eax, dword ptr [ebp-14]      // mov     eax, x
rol  eax, n                                        //  循环左移 n位
mov     dword ptr [ebp-14], eax      //  mov     x, eax

 

 

 

void CMD5::MD5Transform( uInt state[4], const uChar block[64] )   //  MD5变换函数(是MD5运算消耗时间最多的地方)
{
    uInt a, b, c, d, x[16];
    memcpy (x, block, 64);     // 把变换的数据复制到 x[16]中,再由x[16]去参加运算
    ... ...
}

 

看了MD5  F G H I变换  FF GG HH II变换,并没有改变 x[16]的值,所以复制数据是多余的,这一步可省去。

变换中用了uInt a, b, c, d,整个变换过程反反复复地读内存写内存,其实没必要。我用了 eax,ebx,ecx,edx 代替它们了。程序是C中加入汇编写成的。在变换函数中,还使用了 edi, esi, ebp 这样恰好够用。整个程序中没有用到mm0 mm1 等寄存器。

用汇编宏替换了原来的C语言宏:
#define F_asm(x, y, z)   #define G_asm(x, y, z)  ......
#define FF_asm(a, b, c, d, x, s, ac)    #define GG_asm(a, b, c, d, x, s, ac)    ......

 

 

 

MD5算法的输入单位是 bit,但在计算机中,我们传给MD5算法的都是 Byte,所以我把程序中相关bit的地方都作了修改,简化程序。

 

生成的是一个MD5_asm.dll,导出函数如下图:

 

比较一下MD5主要的变换过程,C版的和 MMX版的 都有1300多条汇编指令,但C版的内存读写(相对寄存器之间操作而言)多过MMX版。

而MD5_asm中的主要变换过程不到600行,并且所含内存读写指令相当少,运算速度可想而知。

 

MD5_asm.dll  和 .h .lib 部分代码 与测试程序代码 已上传,可于个人上传资源中找到。下载地址:

http://download.csdn.net/source/2453975

 

原创粉丝点击