AES-Example(64Bit) for AES supported CPUs

Bare metal programming in PureBasic, for experienced users
Helle
Enthusiast
Enthusiast
Posts: 178
Joined: Wed Apr 12, 2006 7:59 pm
Location: Germany
Contact:

AES-Example(64Bit) for AES supported CPUs

Post by Helle »

This is a test for CPUs with AES-support (Intel Sandy Bridge / AMD Bulldozer):
Purebasic-x64 needed.

Code: Select all

;AES-Test with AES-supported CPU. 64-Bit-Windows
;"Helle" Klaus Helbing, 14.12.2011, PB 4.60 (x64)
;Based on http://software.intel.com/file/24917
;Need FAsm 1.69.15 or later (http://flatassembler.net)
;No Unicode!
;For this test I use keys/IV without padding (allways 16/32 byte) - I think, this is for this test o.k. 
;Test-Results:
;AMD FX-8120 (3.1 GHz):
 ;AES-Test ECB_128:
  ;Time Encoding 67108864 Bytes : 47 ms   (PB : 405 ms)
  ;Time Decoding 67108864 Bytes : 47 ms   (PB : 437 ms)
  ;Check Plaintext - Decoding : Correspondency!
  ;Ckeck Encoding with PB : Correspondency!  
 ;AES-Test CBC_256: 
  ;Time Encoding 67108864 Bytes : 156 ms   (PB : 546 ms)
  ;Time Decoding 67108864 Bytes : 46 ms   (PB : 530 ms)
  ;Check Plaintext - Decoding : Correspondency!
  ;Check Encoding with PB : Correspondency!  
;Intel i7-2600 (3.4 GHz):
 ;AES-Test ECB_128:
  ;Time Encoding 268435456 Bytes : 93 ms   (PB : 1264 ms)
  ;Time Decoding 268435456 Bytes : 110 ms   (PB : 1232 ms)
  ;Check Plaintext - Decoding : Correspondency!
  ;Ckeck Encoding with PB : Correspondency!
 ;AES-Test CBC_256: 
  ;Time Encoding 268435456 Bytes : 531 ms   (PB : 1716 ms)
  ;Time Decoding 268435456 Bytes : 109 ms   (PB : 1607 ms)
  ;Check Plaintext - Decoding : Correspondency!
  ;Check Encoding with PB : Correspondency!

;------------------------------------------------------------------------------
;Test, if AES-CPU-Support
!mov eax,1h
!cpuid  
!test ecx,2000000h
!jnz @f  
MessageRequester("Sorry!", "No AES-CPU-Support!")  
End
!@@:  

*Key_Schedule_Encrypt = AllocateMemory(272)
Ali = 16 - *Key_Schedule_Encrypt % 16
*Key_Schedule_EncryptA16 = *Key_Schedule_Encrypt + Ali

*Key_Schedule_Decrypt = AllocateMemory(272)      
Ali = 16 - *Key_Schedule_Decrypt % 16
*Key_Schedule_DecryptA16 = *Key_Schedule_Decrypt + Ali

*XMM_Sicherung = AllocateMemory(160)      
Ali = 16 - *XMM_Sicherung % 16
XMM_SicherungA16 = *XMM_Sicherung + Ali

String$ = "Hello, this is a AES-Test for CPUs with AES-Support in PureBasic"
For i = 1 To 22                        ;Test-File 268.435.456 Bytes (256 MB)
  String$ + String$
Next 
StringLen = Len(String$)

*CipheredString   = AllocateMemory(StringLen + 1)  ;with Zero-Byte
*DecipheredString = AllocateMemory(StringLen + 1)  ;with Zero-Byte

;--------------------- Key_Expansion_Encrypt AES_128 ---------------------
Procedure Make_Roundkey_AES_128()
  !pshufd xmm2,xmm2,255
  !movdqa xmm3,xmm1
  !pslldq xmm3,4
  !pxor xmm1,xmm3
  !pslldq xmm3,4
  !pxor xmm1,xmm3
  !pslldq xmm3,4
  !pxor xmm1,xmm3  
  !pxor xmm1,xmm2  
  !add r11,16
  !movdqa [r11],xmm1
EndProcedure  

Procedure AES_128_Key_Expansion_Encrypt(Userkey, Key_Schedule_E)
  !mov r10,[p.v_Userkey]
  !mov r11,[p.v_Key_Schedule_E]

  !movdqu xmm1,[r10]
  !movdqa [r11],xmm1
  !aeskeygenassist xmm2,xmm1,1
  Make_Roundkey_AES_128()
  !aeskeygenassist xmm2,xmm1,2    
  Make_Roundkey_AES_128()  
  !aeskeygenassist xmm2,xmm1,4  
  Make_Roundkey_AES_128()
  !aeskeygenassist xmm2,xmm1,8  
  Make_Roundkey_AES_128()  
  !aeskeygenassist xmm2,xmm1,16  
  Make_Roundkey_AES_128()
  !aeskeygenassist xmm2,xmm1,32  
  Make_Roundkey_AES_128()  
  !aeskeygenassist xmm2,xmm1,64  
  Make_Roundkey_AES_128()
  !aeskeygenassist xmm2,xmm1,128  
  Make_Roundkey_AES_128()  
  !aeskeygenassist xmm2,xmm1,27  
  Make_Roundkey_AES_128()
  !aeskeygenassist xmm2,xmm1,54  
  Make_Roundkey_AES_128()  
EndProcedure 
;-------------------------------------------------------------------------

;--------------------- Key_Expansion_Encrypt AES_192 ---------------------
Procedure Make_Roundkey_AES_192_a()
  !pshufd xmm2,xmm2,85
  !movdqa xmm4,xmm1
  !pslldq xmm4,4
  !pxor xmm1,xmm4
  !pslldq xmm4,4
  !pxor xmm1,xmm4
  !pslldq xmm4,4
  !pxor xmm1,xmm4  
  !pxor xmm1,xmm2  
  !pshufd xmm2,xmm1,255
  !movdqa xmm4,xmm3
  !pslldq xmm4,4
  !pxor xmm3,xmm4  
  !pxor xmm3,xmm2 
  !add r11,16
  !shufpd xmm5,xmm1,0
  !movdqa [r11],xmm5
  !movdqa xmm6,xmm1
  !shufpd xmm6,xmm3,1
  !add r11,16
  !movdqa [r11],xmm6
EndProcedure

Procedure Make_Roundkey_AES_192_b()
  !pshufd xmm2,xmm2,85
  !movdqa xmm4,xmm1
  !pslldq xmm4,4
  !pxor xmm1,xmm4
  !pslldq xmm4,4
  !pxor xmm1,xmm4
  !pslldq xmm4,4
  !pxor xmm1,xmm4  
  !pxor xmm1,xmm2  
  !pshufd xmm2,xmm1,255
  !movdqa xmm4,xmm3
  !pslldq xmm4,4
  !pxor xmm3,xmm4  
  !pxor xmm3,xmm2 
  !add r11,16
  !movdqa [r11],xmm1
  !movdqa xmm5,xmm3
EndProcedure

Procedure AES_192_Key_Expansion_Encrypt(Userkey, Key_Schedule_E)
  !mov r10,[p.v_Userkey]
  !mov r11,[p.v_Key_Schedule_E]
  !movdqu xmm1,[r10]
  !movdqu xmm3,[r10+16]  
  !movdqa [r11],xmm1
  !movdqa xmm5,xmm3  
  !aeskeygenassist xmm2,xmm3,1  
  Make_Roundkey_AES_192_a()
  !aeskeygenassist xmm2,xmm3,2 
  Make_Roundkey_AES_192_b()
  !aeskeygenassist xmm2,xmm3,4  
  Make_Roundkey_AES_192_a()
  !aeskeygenassist xmm2,xmm3,8 
  Make_Roundkey_AES_192_b()
  !aeskeygenassist xmm2,xmm3,16 
  Make_Roundkey_AES_192_a()
  !aeskeygenassist xmm2,xmm3,32 
  Make_Roundkey_AES_192_b()
  !aeskeygenassist xmm2,xmm3,64 
  Make_Roundkey_AES_192_a()
  !aeskeygenassist xmm2,xmm3,128
  Make_Roundkey_AES_192_b()
  !movdqa [r11+16],xmm3
EndProcedure
;-------------------------------------------------------------------------

;--------------------- Key_Expansion_Encrypt AES_256 ---------------------
Procedure Make_Roundkey_AES_256_a()
  !pshufd xmm2,xmm2,255
  !movdqa xmm4,xmm1
  !pslldq xmm4,4
  !pxor xmm1,xmm4
  !pslldq xmm4,4
  !pxor xmm1,xmm4
  !pslldq xmm4,4
  !pxor xmm1,xmm4  
  !pxor xmm1,xmm2  
  !add r11,16
  !movdqa [r11],xmm1
EndProcedure

Procedure Make_Roundkey_AES_256_b()
  !pshufd xmm2,xmm2,170
  !movdqa xmm4,xmm3
  !pslldq xmm4,4
  !pxor xmm3,xmm4
  !pslldq xmm4,4
  !pxor xmm3,xmm4
  !pslldq xmm4,4
  !pxor xmm3,xmm4  
  !pxor xmm3,xmm2  
  !add r11,16
  !movdqa [r11],xmm3
EndProcedure

Procedure AES_256_Key_Expansion_Encrypt(Userkey, Key_Schedule_E)
  !mov r10,[p.v_Userkey]
  !mov r11,[p.v_Key_Schedule_E]
  !movdqu xmm1,[r10]
  !movdqu xmm3,[r10+16]  
  !movdqa [r11],xmm1
  !add r11,16
  !movdqa [r11],xmm3
  !aeskeygenassist xmm2,xmm3,1
  Make_Roundkey_AES_256_a()
  !aeskeygenassist xmm2,xmm1,0
  Make_Roundkey_AES_256_b()
  !aeskeygenassist xmm2,xmm3,2
  Make_Roundkey_AES_256_a()
  !aeskeygenassist xmm2,xmm1,0
  Make_Roundkey_AES_256_b()
  !aeskeygenassist xmm2,xmm3,4
  Make_Roundkey_AES_256_a()
  !aeskeygenassist xmm2,xmm1,0
  Make_Roundkey_AES_256_b()
  !aeskeygenassist xmm2,xmm3,8
  Make_Roundkey_AES_256_a()
  !aeskeygenassist xmm2,xmm1,0
  Make_Roundkey_AES_256_b()
  !aeskeygenassist xmm2,xmm3,16
  Make_Roundkey_AES_256_a()
  !aeskeygenassist xmm2,xmm1,0
  Make_Roundkey_AES_256_b()
  !aeskeygenassist xmm2,xmm3,32
  Make_Roundkey_AES_256_a()
  !aeskeygenassist xmm2,xmm1,0
  Make_Roundkey_AES_256_b()
  !aeskeygenassist xmm2,xmm3,64
  Make_Roundkey_AES_256_a()
EndProcedure
;-------------------------------------------------------------------------

Procedure AES_Key_Expansion_Decrypt(Key_Schedule_E, Key_Schedule_D, Rounds)
  !mov r10,[p.v_Key_Schedule_E]
  !mov r11,[p.v_Key_Schedule_D]
  !mov rdx,[p.v_Rounds]
  !mov rax,rdx
  !shl rax,4
  !mov rcx,rax
  !add rcx,r10
  !movdqa xmm0,[rcx] 
  !movdqa [r11],xmm0
  !sub rcx,208
  !aesimc xmm1,[rcx+192] 
  !aesimc xmm2,[rcx+176] 
  !aesimc xmm3,[rcx+160] 
  !aesimc xmm4,[rcx+144] 
  !movdqa [r11+16],xmm1
  !movdqa [r11+32],xmm2
  !movdqa [r11+48],xmm3
  !movdqa [r11+64],xmm4
  !aesimc xmm5,[rcx+128]
  !aesimc xmm6,[rcx+112]
  !aesimc xmm7,[rcx+96]
  !aesimc xmm8,[rcx+80]
  !movdqa [r11+80],xmm5
  !movdqa [r11+96],xmm6
  !movdqa [r11+112],xmm7
  !movdqa [r11+128],xmm8
  !aesimc xmm9,[rcx+64]
  !movdqa [r11+144],xmm9
  !cmp rdx,10  
  !jle END_DEC
  !aesimc xmm0,[rcx+48]  
  !aesimc xmm1,[rcx+32]
  !movdqa [r11+160],xmm0
  !movdqa [r11+176],xmm1
  !cmp rdx,12  
  !jle END_DEC
  !aesimc xmm0,[rcx+16] 
  !aesimc xmm1,[rcx]
  !movdqa [r11+192],xmm0
  !movdqa [r11+208],xmm1
!END_DEC:
  !movdqa xmm0,[r10]
  !add r11,rax
  !movdqa [r11],xmm0
EndProcedure

Procedure AES_ECB_Encrypt(Plain, Cipher, Length, Key_Schedule_E, Rounds)
  !mov rax,[v_XMM_SicherungA16]
  !movdqa [rax],xmm9
  !movdqa [rax+16],xmm10
  !movdqa [rax+32],xmm11
  !movdqa [rax+48],xmm12
  !mov r8,[p.v_Plain]
  !mov r9,[p.v_Cipher]
  !mov rdx,[p.v_Length]
  !mov rcx,[p.v_Key_Schedule_E]
  !mov r11,[p.v_Rounds]
  !mov r10,rdx
  !shr rdx,4
  !shl r10,60
  !jz E_NO_PARTS_4_ECB
  !add rdx,1
!E_NO_PARTS_4_ECB:
  !mov r10,rdx
  !shl r10,62
  !shr r10,62
  !shr rdx,2
  !jz E_REMAINDER_4_ECB
  !sub r9,64
!E_LOOP_4_ECB:
  !movdqu xmm1,[r8]
  !movdqu xmm2,[r8+16]  
  !movdqu xmm3,[r8+32]
  !movdqu xmm4,[r8+48]
  !movdqa xmm9,[rcx]
  !movdqa xmm10,[rcx+16]
  !movdqa xmm11,[rcx+32]
  !movdqa xmm12,[rcx+48]
  !pxor xmm1,xmm9
  !pxor xmm2,xmm9
  !pxor xmm3,xmm9
  !pxor xmm4,xmm9
  !aesenc xmm1,xmm10   
  !aesenc xmm2,xmm10
  !aesenc xmm3,xmm10
  !aesenc xmm4,xmm10
  !aesenc xmm1,xmm11
  !aesenc xmm2,xmm11
  !aesenc xmm3,xmm11
  !aesenc xmm4,xmm11
  !aesenc xmm1,xmm12
  !aesenc xmm2,xmm12
  !aesenc xmm3,xmm12
  !aesenc xmm4,xmm12
  !movdqa xmm9,[rcx+64]
  !movdqa xmm10,[rcx+80]
  !movdqa xmm11,[rcx+96]
  !movdqa xmm12,[rcx+112]
  !aesenc xmm1,xmm9
  !aesenc xmm2,xmm9
  !aesenc xmm3,xmm9
  !aesenc xmm4,xmm9
  !aesenc xmm1,xmm10
  !aesenc xmm2,xmm10
  !aesenc xmm3,xmm10
  !aesenc xmm4,xmm10
  !aesenc xmm1,xmm11
  !aesenc xmm2,xmm11
  !aesenc xmm3,xmm11
  !aesenc xmm4,xmm11
  !aesenc xmm1,xmm12
  !aesenc xmm2,xmm12
  !aesenc xmm3,xmm12
  !aesenc xmm4,xmm12
  !movdqa xmm9,[rcx+128]
  !movdqa xmm10,[rcx+144]
  !movdqa xmm11,[rcx+160]
  !aesenc xmm1,xmm9
  !aesenc xmm2,xmm9
  !aesenc xmm3,xmm9
  !aesenc xmm4,xmm9
  !aesenc xmm1,xmm10
  !aesenc xmm2,xmm10
  !aesenc xmm3,xmm10
  !aesenc xmm4,xmm10
  !cmp r11,12   
  !jb E_LAST_4_ECB
  !movdqa xmm9,[rcx+160]
  !movdqa xmm10,[rcx+176]
  !movdqa xmm11,[rcx+192]
  !aesenc xmm1,xmm9
  !aesenc xmm2,xmm9
  !aesenc xmm3,xmm9
  !aesenc xmm4,xmm9
  !aesenc xmm1,xmm10
  !aesenc xmm2,xmm10
  !aesenc xmm3,xmm10
  !aesenc xmm4,xmm10
  !cmp r11,14 
  !jb E_LAST_4_ECB
  !movdqa xmm9,[rcx+192]
  !movdqa xmm10,[rcx+208]
  !movdqa xmm11,[rcx+224]
  !aesenc xmm1,xmm9
  !aesenc xmm2,xmm9
  !aesenc xmm3,xmm9
  !aesenc xmm4,xmm9
  !aesenc xmm1,xmm10
  !aesenc xmm2,xmm10
  !aesenc xmm3,xmm10
  !aesenc xmm4,xmm10
!E_LAST_4_ECB:
  !add r8,64
  !add r9,64
  !dec rdx
  !aesenclast xmm1,xmm11
  !aesenclast xmm2,xmm11
  !aesenclast xmm3,xmm11
  !aesenclast xmm4,xmm11
  !movdqu [r9],xmm1
  !movdqu [r9+16],xmm2
  !movdqu [r9+32],xmm3
  !movdqu [r9+48],xmm4
  !jnz E_LOOP_4_ECB
  !add r9,64
!E_REMAINDER_4_ECB:
  !cmp r10,0
  !je E_END_4_ECB
!E_LOOP_4_2_ECB:
  !movdqu xmm1,[r8]
  !add r8,16
  !pxor xmm1,[rcx]
  !movdqu xmm2,[rcx+160]
  !aesenc xmm1,[rcx+16]
  !aesenc xmm1,[rcx+32]
  !aesenc xmm1,[rcx+48]
  !aesenc xmm1,[rcx+64]
  !aesenc xmm1,[rcx+80]
  !aesenc xmm1,[rcx+96]
  !aesenc xmm1,[rcx+112]
  !aesenc xmm1,[rcx+128]
  !aesenc xmm1,[rcx+144]
  !aesenclast xmm1,xmm2
  !movdqu [r9],xmm1
  !add r9,16
  !dec r10
  !jnz E_LOOP_4_2_ECB
!E_END_4_ECB:
  !mov rax,[v_XMM_SicherungA16]
  !movdqa xmm9,[rax]
  !movdqa xmm10,[rax+16]
  !movdqa xmm11,[rax+32]
  !movdqa xmm12,[rax+48]
EndProcedure

Procedure AES_CBC_Encrypt(Plain, Cipher, IVec, Length, Key_Schedule_E, Rounds)
  !mov r10,[p.v_Plain]
  !mov r11,[p.v_Cipher]
  !mov rdx,[p.v_IVec] 
  !mov rcx,[p.v_Length]
  !mov r8,[p.v_Key_Schedule_E]
  !mov r9,[p.v_Rounds]
  !mov rax,rcx
  !shr rcx,4
  !shl rax,60
  !jz E_NO_PARTS_CBC
  !add rcx,1
!E_NO_PARTS_CBC:
  !sub r11,16
  !movdqu xmm1,[rdx]
!E_LOOP_CBC:
  !pxor xmm1,[r10]
  !pxor xmm1,[r8]
  !add r10,16
  !add r11,16
  !aesenc xmm1,[r8+16]
  !aesenc xmm1,[r8+32]
  !aesenc xmm1,[r8+48]
  !aesenc xmm1,[r8+64]
  !aesenc xmm1,[r8+80]
  !aesenc xmm1,[r8+96]
  !aesenc xmm1,[r8+112]
  !aesenc xmm1,[r8+128]
  !aesenc xmm1,[r8+144]
  !movdqa xmm2,[r8+160]
  !cmp r9,12  
  !jb E_LAST_CBC
  !aesenc xmm1,[r8+160]
  !aesenc xmm1,[r8+176]
  !movdqa xmm2,[r8+192]
  !cmp r9,14  
  !jb E_LAST_CBC
  !aesenc xmm1,[r8+192]
  !aesenc xmm1,[r8+208]
  !movdqa xmm2,[r8+224]
!E_LAST_CBC:
  !dec rcx
  !aesenclast xmm1,xmm2
  !movdqu [r11],xmm1
  !jnz E_LOOP_CBC
EndProcedure

Procedure AES_ECB_Decrypt(Cipher, Decipher, Length, Key_Schedule_D, Rounds)
  !mov rax,[v_XMM_SicherungA16]
  !movdqa [rax],xmm9
  !movdqa [rax+16],xmm10
  !movdqa [rax+32],xmm11
  !movdqa [rax+48],xmm12

  !mov r8,[p.v_Cipher]
  !mov r9,[p.v_Decipher]
  !mov rdx,[p.v_Length]
  !mov rcx,[p.v_Key_Schedule_D]
  !mov r11,[p.v_Rounds]  

  !mov r10,rdx
  !shr rdx,4
  !shl r10,60
  !jz D_NO_PARTS_4_ECB
  !add rdx,1
!D_NO_PARTS_4_ECB:
  !mov r10,rdx
  !shl r10,62
  !shr r10,62
  !shr rdx,2
  !jz D_REMAINDER_4_ECB
  !sub r9,64
!D_LOOP_4_ECB:
  !movdqu xmm1,[r8]
  !movdqu xmm2,[r8+16]
  !movdqu xmm3,[r8+32]
  !movdqu xmm4,[r8+48]
  !movdqa xmm9,[rcx]
  !movdqa xmm10,[rcx+16]
  !movdqa xmm11,[rcx+32]
  !movdqa xmm12,[rcx+48]
  !pxor xmm1,xmm9
  !pxor xmm2,xmm9
  !pxor xmm3,xmm9
  !pxor xmm4,xmm9
  !aesdec xmm1,xmm10
  !aesdec xmm2,xmm10
  !aesdec xmm3,xmm10
  !aesdec xmm4,xmm10
  !aesdec xmm1,xmm11
  !aesdec xmm2,xmm11
  !aesdec xmm3,xmm11
  !aesdec xmm4,xmm11
  !aesdec xmm1,xmm12
  !aesdec xmm2,xmm12
  !aesdec xmm3,xmm12
  !aesdec xmm4,xmm12
  !movdqa xmm9,[rcx+64]
  !movdqa xmm10,[rcx+80]
  !movdqa xmm11,[rcx+96]
  !movdqa xmm12,[rcx+112]
  !aesdec xmm1,xmm9
  !aesdec xmm2,xmm9
  !aesdec xmm3,xmm9
  !aesdec xmm4,xmm9
  !aesdec xmm1,xmm10
  !aesdec xmm2,xmm10
  !aesdec xmm3,xmm10
  !aesdec xmm4,xmm10
  !aesdec xmm1,xmm11
  !aesdec xmm2,xmm11
  !aesdec xmm3,xmm11
  !aesdec xmm4,xmm11
  !aesdec xmm1,xmm12
  !aesdec xmm2,xmm12
  !aesdec xmm3,xmm12
  !aesdec xmm4,xmm12
  !movdqa xmm9,[rcx+128]
  !movdqa xmm10,[rcx+144]
  !movdqa xmm11,[rcx+160]
  !aesdec xmm1,xmm9
  !aesdec xmm2,xmm9
  !aesdec xmm3,xmm9
  !aesdec xmm4,xmm9
  !aesdec xmm1,xmm10
  !aesdec xmm2,xmm10
  !aesdec xmm3,xmm10
  !aesdec xmm4,xmm10
  !cmp r11,12
  !jb D_LAST_4_ECB
  !movdqa xmm9,[rcx+160]
  !movdqa xmm10,[rcx+176]
  !movdqa xmm11,[rcx+192]
  !aesdec xmm1,xmm9
  !aesdec xmm2,xmm9
  !aesdec xmm3,xmm9
  !aesdec xmm4,xmm9
  !aesdec xmm1,xmm10
  !aesdec xmm2,xmm10
  !aesdec xmm3,xmm10
  !aesdec xmm4,xmm10
  !cmp r11,14  
  !jb D_LAST_4_ECB
  !movdqa xmm9,[rcx+192]
  !movdqa xmm10,[rcx+208]
  !movdqa xmm11,[rcx+224]
  !aesdec xmm1,xmm9
  !aesdec xmm2,xmm9
  !aesdec xmm3,xmm9
  !aesdec xmm4,xmm9
  !aesdec xmm1,xmm10
  !aesdec xmm2,xmm10
  !aesdec xmm3,xmm10
  !aesdec xmm4,xmm10
!D_LAST_4_ECB:
  !add r8,64
  !add r9,64
  !aesdeclast xmm1,xmm11
  !aesdeclast xmm2,xmm11
  !aesdeclast xmm3,xmm11
  !aesdeclast xmm4,xmm11
  !movdqu [r9],xmm1
  !movdqu [r9+16],xmm2
  !movdqu [r9+32],xmm3
  !movdqu [r9+48],xmm4
  !dec rdx  
  !jnz D_LOOP_4_ECB
  !add r9,64
!D_REMAINDER_4_ECB:
  !cmp r10,0
  !je D_END_4_ECB
!D_LOOP_4_2_ECB:
  !movdqu xmm1,[r8]
  !add r8,16
  !pxor xmm1,[rcx]
  !movdqu xmm2,[rcx+160]
  !aesdec xmm1,[rcx+16]
  !aesdec xmm1,[rcx+32]
  !aesdec xmm1,[rcx+48]
  !aesdec xmm1,[rcx+64]
  !aesdec xmm1,[rcx+80]
  !aesdec xmm1,[rcx+96]
  !aesdec xmm1,[rcx+112]
  !aesdec xmm1,[rcx+128]
  !aesdec xmm1,[rcx+144]
  !aesdeclast xmm1,xmm2
  !movdqu [r9],xmm1
  !add r9,16
  !dec r10
  !jnz D_LOOP_4_2_ECB
!D_END_4_ECB:
  !movdqa xmm9,[rax]
  !movdqa xmm10,[rax+16]
  !movdqa xmm11,[rax+32]
  !movdqa xmm12,[rax+48]
EndProcedure

Procedure AES_CBC_Decrypt(Cipher, Decipher, IVec, Length, Key_Schedule_D, Rounds)
  !mov rax,[v_XMM_SicherungA16]
  !movdqa [rax],xmm6
  !movdqa [rax+16],xmm7
  !movdqa [rax+32],xmm8
  !movdqa [rax+48],xmm9
  !movdqa [rax+64],xmm10
  !movdqa [rax+80],xmm11
  !movdqa [rax+96],xmm12
  !movdqa [rax+112],xmm15
  !mov r10,[p.v_Cipher]
  !mov r11,[p.v_Decipher]
  !mov rdx,[p.v_IVec] 
  !mov rcx,[p.v_Length]
  !mov r8,[p.v_Key_Schedule_D]
  !mov r9,[p.v_Rounds]
  !mov rax,rcx
  !shr rcx,4
  !shl rax,60
  !jz D_NO_PARTS_4_CBC
  !add rcx,1
!D_NO_PARTS_4_CBC:
  !mov rax,rcx
  !shl rax,62
  !shr rax,62
  !shr rcx,2
  !movdqu xmm5,[rdx] 
  !jz D_REMAINDER_4_CBC
  !sub r11,64
!D_LOOP_4_CBC:
  !movdqu xmm1,[r10]
  !movdqu xmm2,[r10+16]
  !movdqu xmm3,[r10+32]
  !movdqu xmm4,[r10+48]
  !movdqa xmm6,xmm1
  !movdqa xmm7,xmm2
  !movdqa xmm8,xmm3
  !movdqa xmm15,xmm4
  !movdqa xmm9,[r8]
  !movdqa xmm10,[r8+16]
  !movdqa xmm11,[r8+32]
  !movdqa xmm12,[r8+48]
  !pxor xmm1,xmm9
  !pxor xmm2,xmm9
  !pxor xmm3,xmm9
  !pxor xmm4,xmm9
  !aesdec xmm1,xmm10
  !aesdec xmm2,xmm10
  !aesdec xmm3,xmm10
  !aesdec xmm4,xmm10
  !aesdec xmm1,xmm11
  !aesdec xmm2,xmm11
  !aesdec xmm3,xmm11
  !aesdec xmm4,xmm11
  !aesdec xmm1,xmm12
  !aesdec xmm2,xmm12
  !aesdec xmm3,xmm12
  !aesdec xmm4,xmm12
  !movdqa xmm9,[r8+64]
  !movdqa xmm10,[r8+80]
  !movdqa xmm11,[r8+96]
  !movdqa xmm12,[r8+112]
  !aesdec xmm1,xmm9
  !aesdec xmm2,xmm9
  !aesdec xmm3,xmm9
  !aesdec xmm4,xmm9
  !aesdec xmm1,xmm10
  !aesdec xmm2,xmm10
  !aesdec xmm3,xmm10
  !aesdec xmm4,xmm10
  !aesdec xmm1,xmm11
  !aesdec xmm2,xmm11
  !aesdec xmm3,xmm11
  !aesdec xmm4,xmm11
  !aesdec xmm1,xmm12
  !aesdec xmm2,xmm12
  !aesdec xmm3,xmm12
  !aesdec xmm4,xmm12
  !movdqa xmm9,[r8+128]
  !movdqa xmm10,[r8+144]
  !movdqa xmm11,[r8+160]
  !aesdec xmm1,xmm9
  !aesdec xmm2,xmm9
  !aesdec xmm3,xmm9
  !aesdec xmm4,xmm9
  !aesdec xmm1,xmm10
  !aesdec xmm2,xmm10
  !aesdec xmm3,xmm10
  !aesdec xmm4,xmm10
  !cmp r9,12  
  !jb D_LAST_4_CBC
  !movdqa xmm9,[r8+160]
  !movdqa xmm10,[r8+176]
  !movdqa xmm11,[r8+192]
  !aesdec xmm1,xmm9
  !aesdec xmm2,xmm9
  !aesdec xmm3,xmm9
  !aesdec xmm4,xmm9
  !aesdec xmm1,xmm10
  !aesdec xmm2,xmm10
  !aesdec xmm3,xmm10
  !aesdec xmm4,xmm10
  !cmp r9,14
  !jb D_LAST_4_CBC
  !movdqa xmm9,[r8+192]
  !movdqa xmm10,[r8+208]
  !movdqa xmm11,[r8+224]
  !aesdec xmm1,xmm9
  !aesdec xmm2,xmm9
  !aesdec xmm3,xmm9
  !aesdec xmm4,xmm9
  !aesdec xmm1,xmm10
  !aesdec xmm2,xmm10
  !aesdec xmm3,xmm10
  !aesdec xmm4,xmm10
!D_LAST_4_CBC:
  !add r10,64
  !add r11,64
  !aesdeclast xmm1,xmm11
  !aesdeclast xmm2,xmm11
  !aesdeclast xmm3,xmm11
  !aesdeclast xmm4,xmm11
  !pxor xmm1,xmm5
  !pxor xmm2,xmm6
  !pxor xmm3,xmm7
  !pxor xmm4,xmm8
  !movdqu [r11],xmm1
  !movdqu [r11+16],xmm2
  !movdqu [r11+32],xmm3
  !movdqu [r11+48],xmm4
  !movdqa xmm5,xmm15
  !dec rcx  
  !jnz D_LOOP_4_CBC
  !add r11,64
!D_REMAINDER_4_CBC:
  !cmp rax,0
  !je D_END_4_CBC
!D_LOOP_4_2_CBC:
  !movdqu xmm1,[r10]
  !movdqa xmm15,xmm1
  !add r10,16
  !pxor xmm1,[r8]
  !movdqu xmm2,[r8+160]
  !aesdec xmm1,[r8+16]
  !aesdec xmm1,[r8+32]
  !aesdec xmm1,[r8+48]
  !aesdec xmm1,[r8+64]
  !aesdec xmm1,[r8+80]
  !aesdec xmm1,[r8+96]
  !aesdec xmm1,[r8+112]
  !aesdec xmm1,[r8+128]
  !aesdec xmm1,[r8+144]
  !cmp r9,12  
  !jb D_LAST_4_2_CBC
  !movdqu xmm2,[r8+192]
  !aesdec xmm1,[r8+160]
  !aesdec xmm1,[r8+176]
  !cmp r9,14  
  !jb D_LAST_4_2_CBC
  !movdqu xmm2,[r8+224]
  !aesdec xmm1,[r8+192]
  !aesdec xmm1,[r8+208]
!D_LAST_4_2_CBC:
  !aesdeclast xmm1,xmm2
  !pxor xmm1,xmm5
  !movdqa xmm5,xmm15
  !movdqu [r11],xmm1
  !add r11,16
  !dec rax
  !jnz D_LOOP_4_2_CBC
!D_END_4_CBC:
  !mov rax,[v_XMM_SicherungA16]
  !movdqa xmm6,[rax]
  !movdqa xmm7,[rax+16]
  !movdqa xmm8,[rax+32]
  !movdqa xmm9,[rax+48]
  !movdqa xmm10,[rax+64]
  !movdqa xmm11,[rax+80]
  !movdqa xmm12,[rax+96]
  !movdqa xmm15,[rax+112]
EndProcedure

;---------------------------- Test AES_ECB_128 ---------------------------
TEA = ElapsedMilliseconds()
AES_128_Key_Expansion_Encrypt(?Key, *Key_Schedule_EncryptA16)
AES_ECB_Encrypt(@String$, *CipheredString, StringLen, *Key_Schedule_EncryptA16, 10)
E_Time_CPU = ElapsedMilliseconds() - TEA

TDA = ElapsedMilliseconds()
AES_Key_Expansion_Decrypt(*Key_Schedule_EncryptA16, *Key_Schedule_DecryptA16, 10)
AES_ECB_Decrypt(*CipheredString, *DecipheredString, StringLen, *Key_Schedule_DecryptA16, 10)
D_Time_CPU = ElapsedMilliseconds() - TDA

If CompareMemory(@String$, *DecipheredString, StringLen)
  Comp$ = "Correspondency!" 
 Else
  Comp$ = "No Correspondency!"
EndIf 

Titel$ = "AES-Test ECB_128"
Test_E$ = "Time Encoding " + Str(StringLen) + " Bytes : " + Str(E_Time_CPU) + " ms"
Test_D$ = "Time Decoding " + Str(StringLen) + " Bytes : " + Str(D_Time_CPU) + " ms"
Compare$ = "Check Plaintext - Decoding : " + Comp$
;          -------------- Encoding-Crosstest with PB --------------
*CipheredString_PB = AllocateMemory(StringLen + 1)
*DecipheredString_PB = AllocateMemory(StringLen + 1)

TEA = ElapsedMilliseconds()
AESEncoder(@String$, *CipheredString_PB, StringLen, ?Key, 128, 0, #PB_Cipher_ECB)
E_Time_PB = ElapsedMilliseconds() - TEA
Test_E$ + "   (PB : " + Str(E_Time_PB) + " ms)"

TDA = ElapsedMilliseconds()
AESDecoder(*CipheredString_PB, *DecipheredString_PB, StringLen, ?Key, 128, 0, #PB_Cipher_ECB)
D_Time_PB = ElapsedMilliseconds() - TDA
Test_D$ + "   (PB : " + Str(D_Time_PB) + " ms)"

If CompareMemory(*CipheredString, *CipheredString_PB, StringLen)
  PBComp$ = "Correspondency!" 
 Else
  PBComp$ = "No Correspondency!"
EndIf 
PB$ = "Ckeck Encoding with PB : " + PBComp$

MessageRequester(Titel$, Test_E$ + #LFCR$ + Test_D$ + #LFCR$ + Compare$ + #LFCR$ + PB$)
;-------------------------------------------------------------------------

;---------------------------- Test AES_CBC_256 ---------------------------
;Memory noch von oben
TEA = ElapsedMilliseconds()
AES_256_Key_Expansion_Encrypt(?Key, *Key_Schedule_EncryptA16)
AES_CBC_Encrypt(@String$, *CipheredString, ?InitializationVector, StringLen, *Key_Schedule_EncryptA16, 14)
E_Time_CPU = ElapsedMilliseconds() - TEA

TDA = ElapsedMilliseconds()
AES_Key_Expansion_Decrypt(*Key_Schedule_EncryptA16, *Key_Schedule_DecryptA16, 14)
AES_CBC_Decrypt(*CipheredString, *DecipheredString, ?InitializationVector, StringLen, *Key_Schedule_DecryptA16, 14)
D_Time_CPU = ElapsedMilliseconds() - TDA

If CompareMemory(@String$, *DecipheredString, StringLen)
  Comp$ = "Correspondency!" 
 Else
  Comp$ = "No Correspondency!"
EndIf 

Titel$ = "AES-Test CBC_256"
Test_E$ = "Time Encoding " + Str(StringLen) + " Bytes : " + Str(E_Time_CPU) + " ms"
Test_D$ = "Time Decoding " + Str(StringLen) + " Bytes : " + Str(D_Time_CPU) + " ms"
Compare$ = "Check Plaintext - Decoding : " + Comp$
;          -------------- Encoding-Quertest mit PB --------------
TEA = ElapsedMilliseconds()
AESEncoder(@String$, *CipheredString_PB, StringLen, ?Key, 256, ?InitializationVector, #PB_Cipher_CBC)
E_Time_PB = ElapsedMilliseconds() - TEA
Test_E$ + "   (PB : " + Str(E_Time_PB) + " ms)"

TDA = ElapsedMilliseconds()
AESDecoder(*CipheredString_PB, *DecipheredString_PB, StringLen, ?Key, 256, ?InitializationVector, #PB_Cipher_CBC)
D_Time_PB = ElapsedMilliseconds() - TDA
Test_D$ + "   (PB : " + Str(D_Time_PB) + " ms)"

If CompareMemory(*CipheredString, *CipheredString_PB, StringLen)
  PBComp$ = "Correspondency!" 
 Else
  PBComp$ = "No Correspondency!"
EndIf 
PB$ = "Check Encoding with PB : " + PBComp$

MessageRequester(Titel$, Test_E$ + #LFCR$ + Test_D$ + #LFCR$ + Compare$ + #LFCR$ + PB$)
;-------------------------------------------------------------------------
SetClipboardText(Test_E$ + #LFCR$ + Test_D$ + #LFCR$ + Compare$ + #LFCR$ + PB$)
End 

DataSection
  Key: 
    Data.c "K", "e", "y", "w", "o", "r", "d", " ", "P", "a", "r", "t", " ", "O", "n", "e"     ;16 bytes, what you will
    Data.c "K", "e", "y", "w", "o", "r", "d", " ", "P", "a", "r", "t", " ", "T", "w", "o"     ;16 bytes, what you will   
  InitializationVector:                ;16 Bytes !
    Data.c "V", "e", "c", "t", "o", "r", "f", "o", "r", "I", "n", "i", "t", "i", "a", "l"     ;16 bytes, what you will    
EndDataSection

Have fun!
Helle
Last edited by Helle on Wed Oct 03, 2012 9:48 am, edited 1 time in total.
User avatar
Rings
Moderator
Moderator
Posts: 1427
Joined: Sat Apr 26, 2003 1:11 am

Re: AES-Example(64Bit) for AES supported CPUs

Post by Rings »

topic/description changed , as it compiles only with a 64 Purebasic compiler
SPAMINATOR NR.1
xakep
User
User
Posts: 40
Joined: Fri Mar 25, 2016 2:02 pm
Location: Europe

Re: AES-Example(64Bit) for AES supported CPUs

Post by xakep »

Great work!

Maybe you also have an x86 version?
User avatar
Olliv
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Sep 22, 2009 10:41 pm

Re: AES-Example(64Bit) for AES supported CPUs

Post by Olliv »

Check if you have the hardwared statement :

Code: Select all

!mov eax,1h
!cpuid
!test ecx,2000000h
!jnz @f
MessageRequester("Sorry!", "No AES-CPU-Support!")
End
!@@:
Not sure that x86 supports it...
Post Reply