📄 twofish.cpp
字号:
AS2( movd mm3, edi ) \
AS2( movd mm4, ebx ) \
AS2( movd mm5, esi ) \
AS2( movd mm6, ebp ) \
AS2( mov edi, DWORD PTR [ebp + 8] ) \
AS2( mov esi, DWORD PTR [ebp + 12] )
#define EPILOG() \
AS2( movd esp, mm6 ) \
AS2( movd esi, mm5 ) \
AS2( movd ebx, mm4 ) \
AS2( movd edi, mm3 ) \
AS1( emms ) \
asm(".att_syntax");
#else
#define AS1(x) __asm x
#define AS2(x, y) __asm x, y
#define PROLOG() \
AS1( push ebp ) \
AS2( mov ebp, esp ) \
AS2( movd mm3, edi ) \
AS2( movd mm4, ebx ) \
AS2( movd mm5, esi ) \
AS2( movd mm6, ebp ) \
AS2( mov edi, ecx ) \
AS2( mov esi, DWORD PTR [ebp + 8] )
/* ebp already set */
#define EPILOG() \
AS2( movd esi, mm5 ) \
AS2( movd ebx, mm4 ) \
AS2( movd edi, mm3 ) \
AS2( mov esp, ebp ) \
AS1( pop ebp ) \
AS1( emms ) \
AS1( ret 8 )
#endif
// x = esi, y = [esp], s_ = ebp
// edi always open for G1 and G2
// G1 also uses edx after save and restore
// G2 also uses eax after save and restore
// and ecx for tmp [esp] which Rounds also use
// and restore from mm7
// x = G1(a) bytes(0,1,2,3)
#define ASMG1(z, zl, zh) \
AS2( movd mm2, edx ) \
AS2( movzx edi, zl ) \
AS2( mov esi, DWORD PTR [ebp + edi*4] ) \
AS2( movzx edx, zh ) \
AS2( xor esi, DWORD PTR 1024[ebp + edx*4] ) \
\
AS2( mov edx, z ) \
AS2( shr edx, 16 ) \
AS2( movzx edi, dl ) \
AS2( xor esi, DWORD PTR 2048[ebp + edi*4] ) \
AS2( movzx edx, dh ) \
AS2( xor esi, DWORD PTR 3072[ebp + edx*4] ) \
AS2( movd edx, mm2 )
// y = G2(b) bytes(3,0,1,2) [ put y into ecx for Rounds ]
#define ASMG2(z, zl, zh) \
AS2( movd mm7, ecx ) \
AS2( movd mm2, eax ) \
AS2( mov edi, z ) \
AS2( shr edi, 24 ) \
AS2( mov ecx, DWORD PTR [ebp + edi*4] ) \
AS2( movzx eax, zl ) \
AS2( xor ecx, DWORD PTR 1024[ebp + eax*4] ) \
\
AS2( mov eax, z ) \
AS2( shr eax, 16 ) \
AS2( movzx edi, zh ) \
AS2( xor ecx, DWORD PTR 2048[ebp + edi*4] ) \
AS2( movzx eax, al ) \
AS2( xor ecx, DWORD PTR 3072[ebp + eax*4] ) \
AS2( movd eax, mm2 )
// encrypt Round (n),
// x = esi, k = ebp, edi open
// y is in ecx from G2, restore when done from mm7
// before C (which be same register!)
#define ASMENCROUND(N, A, A2, A3, B, B2, B3, C, D) \
/* setup s_ */ \
AS2( movd ebp, mm1 ) \
ASMG1(A, A2, A3) \
ASMG2(B, B2, B3) \
/* setup k */ \
AS2( movd ebp, mm0 ) \
/* x += y */ \
AS2( add esi, ecx ) \
AS2( add ebp, 32 ) \
/* y += x + k[2 * (n) + 1] */ \
AS2( add ecx, esi ) \
AS2( rol D, 1 ) \
AS2( add ecx, DWORD PTR [ebp + 8 * N + 4] ) \
/* (d) = rotlFixed(d, 1) ^ y */ \
AS2( xor D, ecx ) \
AS2( movd ecx, mm7 ) \
/* (c) ^= x + k[2 * (n)] */ \
AS2( mov edi, esi ) \
AS2( add edi, DWORD PTR [ebp + 8 * N] ) \
AS2( xor C, edi ) \
/* (c) = rotrFixed(c, 1) */ \
AS2( ror C, 1 )
// decrypt Round (n),
// x = esi, k = ebp, edi open
// y is in ecx from G2, restore ecx from mm7 when done
#define ASMDECROUND(N, A, A2, A3, B, B2, B3, C, D) \
/* setup s_ */ \
AS2( movd ebp, mm1 ) \
ASMG1(A, A2, A3) \
ASMG2(B, B2, B3) \
/* setup k */ \
AS2( movd ebp, mm0 ) \
/* x += y */ \
AS2( add esi, ecx ) \
AS2( add ebp, 32 ) \
/* y += x */ \
AS2( add ecx, esi ) \
/* (d) ^= y + k[2 * (n) + 1] */ \
AS2( mov edi, DWORD PTR [ebp + 8 * N + 4] ) \
AS2( add edi, ecx ) \
AS2( movd ecx, mm7 ) \
AS2( xor D, edi ) \
/* (d) = rotrFixed(d, 1) */ \
AS2( ror D, 1 ) \
/* (c) = rotlFixed(c, 1) */ \
AS2( rol C, 1 ) \
/* (c) ^= (x + k[2 * (n)]) */ \
AS2( mov edi, esi ) \
AS2( add edi, DWORD PTR [ebp + 8 * N] ) \
AS2( xor C, edi )
#ifdef _MSC_VER
__declspec(naked)
#endif
void Twofish::AsmEncrypt(const byte* inBlock, byte* outBlock) const
{
PROLOG()
#ifdef OLD_GCC_OFFSET
AS2( add edi, 60 ) // k_
#else
AS2( add edi, 56 ) // k_
#endif
AS2( mov ebp, edi )
AS2( mov eax, DWORD PTR [esi] ) // a
AS2( movd mm0, edi ) // store k_
AS2( mov ebx, DWORD PTR [esi + 4] ) // b
AS2( add ebp, 160 ) // s_[0]
AS2( mov ecx, DWORD PTR [esi + 8] ) // c
AS2( movd mm1, ebp ) // store s_
AS2( mov edx, DWORD PTR [esi + 12] ) // d
AS2( xor eax, DWORD PTR [edi] ) // k_[0]
AS2( xor ebx, DWORD PTR [edi + 4] ) // [1]
AS2( xor ecx, DWORD PTR [edi + 8] ) // [2]
AS2( xor edx, DWORD PTR [edi + 12] ) // [3]
ASMENCROUND( 0, eax, al, ah, ebx, bl, bh, ecx, edx)
ASMENCROUND( 1, ecx, cl, ch, edx, dl, dh, eax, ebx)
ASMENCROUND( 2, eax, al, ah, ebx, bl, bh, ecx, edx)
ASMENCROUND( 3, ecx, cl, ch, edx, dl, dh, eax, ebx)
ASMENCROUND( 4, eax, al, ah, ebx, bl, bh, ecx, edx)
ASMENCROUND( 5, ecx, cl, ch, edx, dl, dh, eax, ebx)
ASMENCROUND( 6, eax, al, ah, ebx, bl, bh, ecx, edx)
ASMENCROUND( 7, ecx, cl, ch, edx, dl, dh, eax, ebx)
ASMENCROUND( 8, eax, al, ah, ebx, bl, bh, ecx, edx)
ASMENCROUND( 9, ecx, cl, ch, edx, dl, dh, eax, ebx)
ASMENCROUND(10, eax, al, ah, ebx, bl, bh, ecx, edx)
ASMENCROUND(11, ecx, cl, ch, edx, dl, dh, eax, ebx)
ASMENCROUND(12, eax, al, ah, ebx, bl, bh, ecx, edx)
ASMENCROUND(13, ecx, cl, ch, edx, dl, dh, eax, ebx)
ASMENCROUND(14, eax, al, ah, ebx, bl, bh, ecx, edx)
ASMENCROUND(15, ecx, cl, ch, edx, dl, dh, eax, ebx)
AS2( movd ebp, mm6 )
AS2( movd esi, mm0 ) // k_
#ifdef __GNUC__
AS2( mov edi, [ebp + 16] ) // outBlock
#else
AS2( mov edi, [ebp + 12] ) // outBlock
#endif
AS2( xor ecx, DWORD PTR [esi + 16] ) // k_[4]
AS2( xor edx, DWORD PTR [esi + 20] ) // k_[5]
AS2( xor eax, DWORD PTR [esi + 24] ) // k_[6]
AS2( xor ebx, DWORD PTR [esi + 28] ) // k_[7]
AS2( mov [edi], ecx ) // write out
AS2( mov [edi + 4], edx ) // write out
AS2( mov [edi + 8], eax ) // write out
AS2( mov [edi + 12], ebx ) // write out
EPILOG()
}
#ifdef _MSC_VER
__declspec(naked)
#endif
void Twofish::AsmDecrypt(const byte* inBlock, byte* outBlock) const
{
PROLOG()
#ifdef OLD_GCC_OFFSET
AS2( add edi, 60 ) // k_
#else
AS2( add edi, 56 ) // k_
#endif
AS2( mov ebp, edi )
AS2( mov ecx, DWORD PTR [esi] ) // c
AS2( movd mm0, edi ) // store k_
AS2( mov edx, DWORD PTR [esi + 4] ) // d
AS2( add ebp, 160 ) // s_[0]
AS2( mov eax, DWORD PTR [esi + 8] ) // a
AS2( movd mm1, ebp ) // store s_
AS2( mov ebx, DWORD PTR [esi + 12] ) // b
AS2( xor ecx, DWORD PTR [edi + 16] ) // k_[4]
AS2( xor edx, DWORD PTR [edi + 20] ) // [5]
AS2( xor eax, DWORD PTR [edi + 24] ) // [6]
AS2( xor ebx, DWORD PTR [edi + 28] ) // [7]
ASMDECROUND(15, ecx, cl, ch, edx, dl, dh, eax, ebx)
ASMDECROUND(14, eax, al, ah, ebx, bl, bh, ecx, edx)
ASMDECROUND(13, ecx, cl, ch, edx, dl, dh, eax, ebx)
ASMDECROUND(12, eax, al, ah, ebx, bl, bh, ecx, edx)
ASMDECROUND(11, ecx, cl, ch, edx, dl, dh, eax, ebx)
ASMDECROUND(10, eax, al, ah, ebx, bl, bh, ecx, edx)
ASMDECROUND( 9, ecx, cl, ch, edx, dl, dh, eax, ebx)
ASMDECROUND( 8, eax, al, ah, ebx, bl, bh, ecx, edx)
ASMDECROUND( 7, ecx, cl, ch, edx, dl, dh, eax, ebx)
ASMDECROUND( 6, eax, al, ah, ebx, bl, bh, ecx, edx)
ASMDECROUND( 5, ecx, cl, ch, edx, dl, dh, eax, ebx)
ASMDECROUND( 4, eax, al, ah, ebx, bl, bh, ecx, edx)
ASMDECROUND( 3, ecx, cl, ch, edx, dl, dh, eax, ebx)
ASMDECROUND( 2, eax, al, ah, ebx, bl, bh, ecx, edx)
ASMDECROUND( 1, ecx, cl, ch, edx, dl, dh, eax, ebx)
ASMDECROUND( 0, eax, al, ah, ebx, bl, bh, ecx, edx)
AS2( movd ebp, mm6 )
AS2( movd esi, mm0 ) // k_
#ifdef __GNUC__
AS2( mov edi, [ebp + 16] ) // outBlock
#else
AS2( mov edi, [ebp + 12] ) // outBlock
#endif
AS2( xor eax, DWORD PTR [esi ] ) // k_[0]
AS2( xor ebx, DWORD PTR [esi + 4] ) // k_[1]
AS2( xor ecx, DWORD PTR [esi + 8] ) // k_[2]
AS2( xor edx, DWORD PTR [esi + 12] ) // k_[3]
AS2( mov [edi], eax ) // write out
AS2( mov [edi + 4], ebx ) // write out
AS2( mov [edi + 8], ecx ) // write out
AS2( mov [edi + 12], edx ) // write out
EPILOG()
}
#endif // defined(DO_TWOFISH_ASM)
} // namespace
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -