2010/2/24 16:34:25
IDEA加密算法中的用到一种2^16 + 1的模乘运算。
运算规则如下:
1. a , b分别为16位整数。
2. 如果a或b为0,则表示2^16.
3. 运算结果为a *b mod (2^16 + 1).
以上规则是我根据自己的理解描述的,如果大家小了解的更清除,可以参考专门介绍IDEA的文档。
这个运算涉及的模运算,模运算是比除法运算更耗时的一种运算。所以应该避免。
现在我们看怎么优化:
这里分两种情况(我们用M来代替2^16 + 1):
1. a. b都不为0
a * b mod M = c * 2^16 + d mod M = c * M - c + d mod M = d - c mod M = M + d - c mod M;
可见当 a, b都不为0时,模乘的结果是乘积的低位字与高位字的差, 如果结果为负值则应该加上M 后取低16位。
2. a. b中有一个为0, 这里假设a = 0;
a ^ b mod M = 2^16 * b mod M = M * b - b mod M = M - b mod M = 2^16 + 1 - b mod M
= 1 - b mod M
这样除法就从运算中彻底消失了。
这里要说的是这个原理并不是我的首创,该思想来源于molebox中的IDEA实现。
下面是molebox中IDEA的汇编实现. 里面多处重复了模乘代码,我把第一处用红 {MOD}标出来,大家可以参考。
0055E868 >/$ 55 push ebp ; zip restor 1
0055E869 |. 8BEC mov ebp, esp
0055E86B |. 83EC 48 sub esp, 48
0055E86E |. 53 push ebx
0055E86F |. 894D D0 mov dword ptr [ebp-30], ecx
0055E872 |. C745 FC 08000>mov dword ptr [ebp-4], 8
0055E879 |. 8B45 08 mov eax, dword ptr [ebp+8]
0055E87C |. 8945 E8 mov dword ptr [ebp-18], eax
0055E87F |. 8B45 E8 mov eax, dword ptr [ebp-18]
0055E882 |. 66:8B00 mov ax, word ptr [eax]
0055E885 |. 66:8945 E4 mov word ptr [ebp-1C], ax
0055E889 |. 8B45 E8 mov eax, dword ptr [ebp-18]
0055E88C |. 40 inc eax
0055E88D |. 40 inc eax
0055E88E |. 8945 E8 mov dword ptr [ebp-18], eax
0055E891 |. 8B45 E8 mov eax, dword ptr [ebp-18]
0055E894 |. 66:8B00 mov ax, word ptr [eax]
0055E897 |. 66:8945 E0 mov word ptr [ebp-20], ax
0055E89B |. 8B45 E8 mov eax, dword ptr [ebp-18]
0055E89E |. 40 inc eax
0055E89F |. 40 inc eax
0055E8A0 |. 8945 E8 mov dword ptr [ebp-18], eax
0055E8A3 |. 8B45 E8 mov eax, dword ptr [ebp-18]
0055E8A6 |. 66:8B00 mov ax, word ptr [eax]
0055E8A9 |. 66:8945 D8 mov word ptr [ebp-28], ax
0055E8AD |. 8B45 E8 mov eax, dword ptr [ebp-18]
0055E8B0 |. 40 inc eax
0055E8B1 |. 40 inc eax
0055E8B2 |. 8945 E8 mov dword ptr [ebp-18], eax
0055E8B5 |. 8B45 E8 mov eax, dword ptr [ebp-18]
0055E8B8 |. 66:8B00 mov ax, word ptr [eax]
0055E8BB |. 66:8945 D4 mov word ptr [ebp-2C], ax
0055E8BF |. 0FB745 E4 movzx eax, word ptr [ebp-1C]
0055E8C3 |. C1F8 08 sar eax, 8
0055E8C6 |. 0FB74D E4 movzx ecx, word ptr [ebp-1C]
0055E8CA |. C1E1 08 shl ecx, 8
0055E8CD |. 0BC1 or eax, ecx
0055E8CF |. 66:8945 E4 mov word ptr [ebp-1C], ax
0055E8D3 |. 0FB745 E0 movzx eax, word ptr [ebp-20]
0055E8D7 |. C1F8 08 sar eax, 8
0055E8DA |. 0FB74D E0 movzx ecx, word ptr [ebp-20]
0055E8DE |. C1E1 08 shl ecx, 8
0055E8E1 |. 0BC1 or eax, ecx
0055E8E3 |. 66:8945 E0 mov word ptr [ebp-20], ax
0055E8E7 |. 0FB745 D8 movzx eax, word ptr [ebp-28]
0055E8EB |. C1F8 08 sar eax, 8
0055E8EE |. 0FB74D D8 movzx ecx, word ptr [ebp-28]
0055E8F2 |. C1E1 08 shl ecx, 8
0055E8F5 |. 0BC1 or eax, ecx
0055E8F7 |. 66:8945 D8 mov word ptr [ebp-28], ax
0055E8FB |. 0FB745 D4 movzx eax, word ptr [ebp-2C]
0055E8FF |. C1F8 08 sar eax, 8
0055E902 |. 0FB74D D4 movzx ecx, word ptr [ebp-2C]
0055E906 |. C1E1 08 shl ecx, 8
0055E909 |. 0BC1 or eax, ecx
0055E90B |. 66:8945 D4 mov word ptr [ebp-2C], ax
0055E90F |> 8B45 10 /mov eax, dword ptr [ebp+10]
0055E912 |. 66:8B00 |mov ax, word ptr [eax]
0055E915 |. 66:8945 F0 |mov word ptr [ebp-10], ax
0055E919 |. 0FB745 F0 |movzx eax, word ptr [ebp-10]
0055E91D |. 8B4D 10 |mov ecx, dword ptr [ebp+10]
0055E920 |. 41 |inc ecx
0055E921 |. 41 |inc ecx
0055E922 |. 894D 10 |mov dword ptr [ebp+10], ecx
0055E925 |. 85C0 |test eax, eax
0055E927 |. 0F84 81000000 |je 0055E9AE
0055E92D |. 0FB745 E4 |movzx eax, word ptr [ebp-1C]
0055E931 |. 25 FFFF0000 |and eax, 0FFFF
0055E936 |. 66:8945 E4 |mov word ptr [ebp-1C], ax
0055E93A |. 0FB745 E4 |movzx eax, word ptr [ebp-1C]
0055E93E |. 85C0 |test eax, eax
0055E940 |. 74 4D |je short 0055E98F
0055E942 |. 0FB745 E4 |movzx eax, word ptr [ebp-1C]
0055E946 |. 0FB74D F0 |movzx ecx, word ptr [ebp-10]
0055E94A |. 0FAFC1 |imul eax, ecx
0055E94D |. 8945 DC |mov dword ptr [ebp-24], eax
0055E950 |. 8B45 DC |mov eax, dword ptr [ebp-24]
0055E953 |. 25 FFFF0000 |and eax, 0FFFF
0055E958 |. 66:8945 E4 |mov word ptr [ebp-1C], ax
0055E95C |. 8B45 DC |mov eax, dword ptr [ebp-24]
0055E95F |. C1E8 10 |shr eax, 10
0055E962 |. 66:8945 F0 |mov word ptr [ebp-10], ax
0055E966 |. 0FB745 E4 |movzx eax, word ptr [ebp-1C]
0055E96A |. 0FB74D F0 |movzx ecx, word ptr [ebp-10]
0055E96E |. 2BC1 |sub eax, ecx
0055E970 |. 0FB74D E4 |movzx ecx, word ptr [ebp-1C]
0055E974 |. 0FB755 F0 |movzx edx, word ptr [ebp-10]
0055E978 |. 33DB |xor ebx, ebx
0055E97A |. 3BCA |cmp ecx, edx
0055E97C |. 0F9CC3 |setl bl
0055E97F |. 03C3 |add eax, ebx
0055E981 |. 66:8945 E4 |mov word ptr [ebp-1C], ax
0055E985 |. 66:8B45 E4 |mov ax, word ptr [ebp-1C]
0055E989 |. 66:8945 CE |mov word ptr [ebp-32], ax
0055E98D |. EB 15 |jmp short 0055E9A4
0055E98F |> 0FB745 F0 |movzx eax, word ptr [ebp-10]
0055E993 |. 6A 01 |push 1
0055E995 |. 59 |pop ecx
0055E996 |. 2BC8 |sub ecx, eax
0055E998 |. 66:894D E4 |mov word ptr [ebp-1C], cx
0055E99C |. 66:8B45 E4 |mov ax, word ptr [ebp-1C]
0055E9A0 |. 66:8945 CE |mov word ptr [ebp-32], ax
0055E9A4 |> 66:8B45 CE |mov ax, word ptr [ebp-32]
0055E9A8 |. 66:8945 CC |mov word ptr [ebp-34], ax
0055E9AC |. EB 15 |jmp short 0055E9C3
0055E9AE |> 0FB745 E4 |movzx eax, word ptr [ebp-1C]
0055E9B2 |. 6A 01 |push 1
0055E9B4 |. 59 |pop ecx
0055E9B5 |. 2BC8 |sub ecx, eax
0055E9B7 |. 66:894D E4 |mov word ptr [ebp-1C], cx
0055E9BB |. 66:8B45 E4 |mov ax, word ptr [ebp-1C]
0055E9BF |. 66:8945 CC |mov word ptr [ebp-34], ax
.........
0055EE90 . C2 0C00 retn 0C
其实最重要的是,代码中完全没了了2^16+1的存在,可以骗过peid的识别加密算法插件。