« AES暗号 実装編? | トップページ | AES暗号をSSE命令で処理 »

2010/12/23

AES、暗号部だけSSE命令で書いてみる。

書いてみた。
復号は、これから。


;===============================================================|
;								|
;		AES for SSE (SIMD)				|
;								|
;				Programmed by			|
;					(S.W.)	( A.Watanabe )	|
;								|
;===============================================================|
;void	__fastcall	AES_SSE_Cipher(char Nr, unsigned char Ks);
;---------------------------------------------------------------|
;*Input								|
;	Nr	Round				(ecx)		|
;	Ks	Pointer of Key schedule		(edx)		|
;	xmm0	Plain text					|
;*Output							|
;	xmm0	Cipher text					|
;*Break								|
;	eax, ecx, edx						|
;	xmm1~7   (all SIMD Register)				|
;===============================================================|
;void	__fastcall	AES_SSE_InvCipher(char Nr, unsigned char Ks);
;---------------------------------------------------------------|
;*Input								|
;	Nr	Round				(ecx)		|
;	Ks	Pointer of Key schedule		(edx)		|
;	xmm0	Cipher text					|
;*Output							|
;	xmm0	Plain text					|
;*Break								|
;	eax, ecx, edx						|
;	xmm1~7   (all SIMD Register)				|
;===============================================================|

.586p
.xmm
.model flat, stdcall

;****************************************************************
;* proto type *
;****************************************************************
;●外部宣言
printf proto near C _Format:ptr byte, var:VARARG

;これは、C言語側にある。
RotWord proto near stdcall data:DWORD
SubWord proto near stdcall data:DWORD

;●プロトタイプ宣言
AES_SSE_mul proto near ;4.2 Multiplication

@AES_SSE_Cipher@8 proto near syscall Nr:BYTE,ptrKS:PTR DWORD ;5.1 Cipher (__fastcall)
AES_SSE_SubBytes proto near stdcall ;5.1.1 SubBytes
AES_SSE_ShiftRows proto near stdcall ;5.1.2 ShiftRows
AES_SSE_MixColumns proto near stdcall ;5.1.3 MixColumns
;AES_SSE_AddRoundKey proto near stdcall ;5.1.4 AddRoundKey

@AES_SSE_InvCipher@8 proto near syscall Nr:BYTE,ptrKS:PTR DWORD ;5.2 InvCipher (__fastcall)
;AES_SSE_InvShiftRows proto near stdcall ;5.2.1 InvShiftRows
;AES_SSE_InvSubBytes proto near stdcall ;5.2.2 InvSubBytes
;AES_SSE_InvMixColumns proto near stdcall ;5.2.3 InvMixColumns
;AES_SSE_InvAddRoundKey proto near stdcall ;5.2.4 InvAddRoundKey

;****************************************************************
;* define *
;****************************************************************
Nb equ 4
Nbb equ Nb * 4

;****************************************************************
;* variable *
;****************************************************************
;というか、メモリ上に作る定数。SSE 命令用。
.const
align(16)

AES_SSE_Mul_Mask1 db 0,255, 0,255, 0,255, 0,255, 0,255, 0,255, 0,255, 0,255
AES_SSE_Mul_Mask2 db 255, 0,255, 0, 255, 0,255, 0, 255, 0,255, 0, 255, 0,255, 0

AES_SSE_Mask0 db 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0
AES_SSE_Mask1 db 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0
AES_SSE_Mask2 db 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0
AES_SSE_Mask3 db 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255

AES_SSE_00FF dw 00FFh,00FFh,00FFh,00FFh, 00FFh,00FFh,00FFh,00FFh
AES_SSE_011B dw 011Bh,011Bh,011Bh,011Bh, 011Bh,011Bh,011Bh,011Bh


;===============================================================|
; fips-197 4.2 Multiplication |
;---------------------------------------------------------------|
; ●引数 |
; xmm0 計算前 (破壊せず) |
; al かける数 |
; ●引数 |
; xmm1 計算後 |
; ●使用するレジスタ xmm4~xmm7 |
; ecx 乗算用 |
; xmm1 計算結果(奇数Bytes) |
; xmm5 計算結果(偶数Bytes) |
; xmm4 加算値 |
; xmm6 加算値 |
; xmm7 比較用 |
;===============================================================|
.code
align(16)
AES_SSE_mul proc

movdqa xmm6, xmm0
pxor xmm1, xmm1
pand xmm6, XMMWORD PTR [AES_SSE_Mul_Mask1]
psrlw xmm6, 8

movdqa xmm4, xmm0
pxor xmm5, xmm5
pand xmm4, XMMWORD PTR [AES_SSE_Mul_Mask2]

xor ecx, ecx
mov cl, 80h

align(16)
.repeat
psllw xmm1, 1 ;result <<= 1;
movdqa xmm7, xmm1
pcmpgtw xmm7, XMMWORD PTR [AES_SSE_00FF]
pand xmm7, XMMWORD PTR [AES_SSE_011B]
pxor xmm1, xmm7 ;result ^= ((result & 0x100)? 0x11B : 0);

psllw xmm5, 1 ;result <<= 1;
movdqa xmm7, xmm5
pcmpgtw xmm7, XMMWORD PTR [AES_SSE_00FF]
pand xmm7, XMMWORD PTR [AES_SSE_011B]
pxor xmm5, xmm7 ;result ^= ((result & 0x100)? 0x11B : 0);
.if (al & cl)
pxor xmm1, xmm6
pxor xmm5, xmm4
.endif
shr cl, 1
.until (!cl)

psllw xmm1, 8
por xmm1, xmm5

ret

AES_SSE_mul endp
;===============================================================|
; fips-197 5.1 Cipher |
;---------------------------------------------------------------|
; ●引数 |
; xmm0 Plain Text |
; ecx Nr Round |
; edx ptrKS Pointer of Key stream |
; ●返値 |
; xmm0 Cipher Text |
;===============================================================|
.code
align(16)
@AES_SSE_Cipher@8 proc SYSCALL uses ebx edi esi

movzx edi, cl
mov esi, edx
xor ebx, ebx
shl edi, 4

;=======================
;◆Round (0)
;---------------
;AddRoundKey()
pxor xmm0, XMMWORD PTR [esi + ebx]
add ebx, 16

;=======================
;◆Round (1) ~ (Nr-1)
.repeat
invoke AES_SSE_SubBytes
invoke AES_SSE_ShiftRows
invoke AES_SSE_MixColumns
pxor xmm0, XMMWORD PTR [esi + ebx]
add ebx, 16
.until (edi <= ebx)

;=======================
;◆Last Round (Nr)
invoke AES_SSE_SubBytes
invoke AES_SSE_ShiftRows
pxor xmm0, XMMWORD PTR [esi + ebx]

ret
@AES_SSE_Cipher@8 endp
;===============================================================|
; fips-197 5.1.1 SubBytes |
;---------------------------------------------------------------|
; ●引数 |
; xmm0 input |
; ●返値 |
; xmm0 output |
;===============================================================|
align(16)
AES_SSE_SubBytes proc

push ebx

lea ebx, [esp - 16]
sub esp, 32
and ebx, -16 ;align(16)

movdqa XMMWORD PTR [ebx], xmm0

movdqa XMMWORD PTR [ebx], xmm0
invoke SubWord, DWORD PTR [ebx + 0]
mov DWORD PTR [ebx + 0], eax
invoke SubWord, DWORD PTR [ebx + 4]
mov DWORD PTR [ebx + 4], eax
invoke SubWord, DWORD PTR [ebx + 8]
mov DWORD PTR [ebx + 8], eax
invoke SubWord, DWORD PTR [ebx + 12]
mov DWORD PTR [ebx + 12], eax
movdqa xmm0, XMMWORD PTR [ebx]

add esp, 32

pop ebx
ret
AES_SSE_SubBytes endp
;===============================================================|
; fips-197 5.1.2 ShiftRows |
;---------------------------------------------------------------|
; ●引数 |
; xmm0 input |
; ●返値 |
; xmm0 output |
;===============================================================|
align(16)
AES_SSE_ShiftRows proc

pshufd xmm1, xmm0, 00111001b
pshufd xmm2, xmm0, 01001110b
pand xmm1, XMMWORD PTR [AES_SSE_Mask1]
pand xmm2, XMMWORD PTR [AES_SSE_Mask2]
pshufd xmm3, xmm0, 10010011b
pand xmm0, XMMWORD PTR [AES_SSE_Mask0]
pand xmm3, XMMWORD PTR [AES_SSE_Mask3]
por xmm2, xmm3
por xmm0, xmm1
por xmm0, xmm2

ret
AES_SSE_ShiftRows endp
;===============================================================|
; fips-197 5.1.3 MixColumns |
;---------------------------------------------------------------|
; ●引数 |
; xmm0 input |
; ●返値 |
; xmm0 output |
;===============================================================|
align(16)
AES_SSE_MixColumns proc

push ebx

lea ebx, [esp - 64]
sub esp, 80
and ebx, -16 ;align(16)

;---------------
;◆乗算
;◎これを作る。
; xmm4 = | 2S0 2S1 2S2 2S3 |
; xmm5 = | S3 S0 S1 S2 |
; xmm6 = | S2 S3 S0 S1 |
; xmm7 = | 3S1 3S2 3S3 3S0 |

mov al, 2
invoke AES_SSE_mul ;//クラスのメンバー関数なので、 関数規約=thiscall
movdqa xmm3, xmm1 ;//一時保存

mov al, 3
invoke AES_SSE_mul ;//クラスのメンバー関数なので、 関数規約=thiscall
movdqa xmm4, xmm3 ;//[0]

movdqa xmm2, xmm1
psrld xmm1, 8
pslld xmm2, 24
por xmm1, xmm2
movdqa xmm7, xmm1 ;//[3]

movdqa xmm1, xmm0
psrld xmm0, 16
pslld xmm1, 16
por xmm0, xmm1
movdqa xmm6, xmm0 ;//[2]

movdqa xmm1, xmm0
psrld xmm0, 8
pslld xmm1, 24
por xmm0, xmm1
movdqa xmm5, xmm0 ;//[1]


;//------------------
;//◆並べ替え
;//◎これを作る。
;// MixColumnsTbl[0] = | 2S0 S0 S0 3S0 |
;// MixColumnsTbl[1] = | 3S1 2S1 S1 S1 |
;// MixColumnsTbl[2] = | S2 3S2 2S2 S2 |
;// MixColumnsTbl[3] = | S3 S3 3S3 2S3 |

movdqa xmm2, xmm6
movdqa xmm3, xmm7
pand xmm2, XMMWORD PTR [AES_SSE_Mask2]
movdqa xmm0, xmm4
pand xmm3, XMMWORD PTR [AES_SSE_Mask3]
movdqa xmm1, xmm5
pand xmm0, XMMWORD PTR [AES_SSE_Mask0]
por xmm2, xmm3
pand xmm1, XMMWORD PTR [AES_SSE_Mask1]
por xmm0, xmm1
por xmm0, xmm2
movdqa XMMWORD PTR [ebx + 0], xmm0

movdqa xmm2, xmm6
movdqa xmm3, xmm7
pand xmm2, XMMWORD PTR [AES_SSE_Mask3]
movdqa xmm0, xmm4
pand xmm3, XMMWORD PTR [AES_SSE_Mask0]
movdqa xmm1, xmm5
pand xmm0, XMMWORD PTR [AES_SSE_Mask1]
por xmm2, xmm3
pand xmm1, XMMWORD PTR [AES_SSE_Mask2]
por xmm0, xmm1
por xmm0, xmm2
movdqa XMMWORD PTR [ebx + 16], xmm0

movdqa xmm2, xmm6
movdqa xmm3, xmm7
pand xmm2, XMMWORD PTR [AES_SSE_Mask0]
movdqa xmm0, xmm4
pand xmm3, XMMWORD PTR [AES_SSE_Mask1]
movdqa xmm1, xmm5
pand xmm0, XMMWORD PTR [AES_SSE_Mask2]
por xmm2, xmm3
pand xmm1, XMMWORD PTR [AES_SSE_Mask3]
por xmm0, xmm1
por xmm0, xmm2
movdqa XMMWORD PTR [ebx + 32], xmm0

movdqa xmm2, xmm6
movdqa xmm3, xmm7
pand xmm2, XMMWORD PTR [AES_SSE_Mask1]
movdqa xmm0, xmm4
pand xmm3, XMMWORD PTR [AES_SSE_Mask2]
movdqa xmm1, xmm5
pand xmm0, XMMWORD PTR [AES_SSE_Mask3]
por xmm2, xmm3
pand xmm1, XMMWORD PTR [AES_SSE_Mask0]
por xmm0, xmm1
por xmm0, xmm2
;// movdqa XMMWORD PTR [ebx + 48], xmm0

;//------------------
;//◆排他的論理和
;// MixColumnsTbl[0] ~ MixColumnsTbl[3] 全てXOR。
movdqa xmm1, XMMWORD PTR [ebx + 0]
movdqa xmm2, XMMWORD PTR [ebx + 16]
pxor xmm0, xmm1
movdqa xmm3, XMMWORD PTR [ebx + 32]
pxor xmm2, xmm3
pxor xmm0, xmm2

add esp, 80
pop ebx
ret
AES_SSE_MixColumns endp
;===============================================================|
; fips-197 5.1.4 AddRoundKey |
;---------------------------------------------------------------|
; ●引数 |
; xmm0 Plain Text |
; esi Pointer of Key schedule |
; ebx Round * 16 |
; ●返値 |
; xmm0 Cipher Text |
;===============================================================|
; align(16)
;AES_SSE_AddRoundKey proc
;
; pxor xmm0, XMMWORD PTR [esi + ebx]
;
; ret
;AES_SSE_AddRoundKey endp
;===============================================================|
; fips-197 5.2 InvCipher |
;---------------------------------------------------------------|
; ●引数 |
; xmm0 Cipher Text |
; ecx Nr Round |
; edx ptrKS Pointer of Key stream |
; ●返値 |
; xmm0 Plain Text |
;===============================================================|
.code
align(16)
@AES_SSE_InvCipher@8 proc SYSCALL uses ebx edi esi

movzx ebx, cl
shl ebx, 4
mov esi, edx

;=======================
;◆Round (Nr)
pxor xmm0, XMMWORD PTR [esi + ebx]
sub ebx, 16

;=======================
;◆Round (Nr-1) ~ (1)
.repeat
;invoke AES_SSE_InvShiftRows
;invoke AES_SSE_InvSubBytes
pxor xmm0, XMMWORD PTR [esi + ebx]
;invoke AES_SSE_InvMixColumns
sub ebx, 16
.until(!zero)

;=======================
;◆Round (0)
;invoke AES_SSE_InvShiftRows
;invoke AES_SSE_InvSubBytes
pxor xmm0, XMMWORD PTR [esi + ebx]

ret
@AES_SSE_InvCipher@8 endp
;****************************************************************
end


|

« AES暗号 実装編? | トップページ | AES暗号をSSE命令で処理 »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/36969/50374280

この記事へのトラックバック一覧です: AES、暗号部だけSSE命令で書いてみる。:

« AES暗号 実装編? | トップページ | AES暗号をSSE命令で処理 »