Тема: [FASM] sha256
sha256. Не імплементація, а ріп, бо треба було швидко і чотко. Також для порівняння створено proc на CryptoApi
sha256.asm
use32
sha256:
push ebp
mov ebp, esp
and esp, 0FFFFFFF8h
sub esp, 70h
xor ecx, ecx
mov dword[esp + 50h], 6A09E667h
and dword[esp + 48h], ecx
and dword[esp + 4Ch], ecx
push esi
xor esi, esi
mov dword[esp + 44h], ecx
push edi
mov dword[esp + 5Ch], 0BB67AE85h
mov dword[esp + 60h], 3C6EF372h
mov dword[esp + 64h], 0A54FF53Ah
mov dword[esp + 68h], 510E527Fh
mov dword[esp + 6Ch], 9B05688Ch
mov dword[esp + 70h], 1F83D9ABh
mov dword[esp + 74h], 5BE0CD19h
cmp dword[ebp + 0Ch], ecx
jbe @04
mov edi, dword[ebp + 8h]
@02:
mov al, byte[edi + esi]
mov byte[ecx + esp + 8h], al
mov ecx, dword[esp + 48h]
inc ecx
mov dword[esp + 48h], ecx
cmp ecx, 40h
jne @03
lea edx, [esp + 8h]
mov ecx, edx
call @05
add dword[esp + 50h], 200h
adc dword[esp + 54h], 0h
xor ecx, ecx
mov dword[esp + 48h], ecx
@03:
inc esi
cmp esi, dword[ebp + 0Ch]
jb @02
@04:
mov edx, dword[ebp + 10h]
lea ecx, [esp + 8h]
call @11
pop edi
pop esi
mov esp, ebp
pop ebp
ret 0Ch
@05:
push ebp
mov ebp, esp
sub esp, 128h
push ebx
push esi
push edi
xor ebx, ebx
mov edi, ecx
mov dword[ebp - 20h], edi
mov esi, ebx
inc edx
@06:
movzx ecx, byte[edx - 1h]
movzx eax, byte[edx]
lea edx, [edx + 4h]
shl ecx, 8h
or ecx, eax
movzx eax, byte[edx - 3h]
shl ecx, 8h
or ecx, eax
movzx eax, byte[edx - 2h]
shl ecx, 8h
or ecx, eax
mov dword[esi * 4h + ebp - 128h], ecx
inc esi
cmp esi, 10h
jb @06
push 40h
pop eax
cmp esi, eax
jae @08
sub eax, esi
lea ebx, [esi * 4h + ebp - 130h]
mov dword[ebp - 4h], eax
mov edi, eax
@07:
mov ecx, dword[ebx]
mov esi, ecx
mov edx, dword[ebx - 34h]
lea ebx, [ebx + 4h]
mov eax, ecx
rol esi, 0Fh
rol eax, 0Dh
xor esi, eax
shr ecx, 0Ah
xor esi, ecx
mov eax, edx
mov ecx, edx
ror eax, 7h
rol ecx, 0Eh
xor ecx, eax
shr edx, 3h
xor ecx, edx
add esi, ecx
add esi, dword[ebx - 3Ch]
add esi, dword[ebx - 18h]
mov dword[ebx + 4h], esi
dec edi
jne @07
mov edi, dword[ebp - 20h]
xor ebx, ebx
@08:
mov eax, dword[edi + 50h]
mov edx, dword[edi + 64h]
mov dword[ebp - 24h], eax
mov dword[ebp - 28h], eax
mov eax, dword[edi + 54h]
mov dword[ebp - 14h], eax
mov eax, dword[edi + 58h]
mov dword[ebp - 10h], eax
mov eax, dword[edi + 5Ch]
mov dword[ebp - 18h], eax
mov eax, dword[edi + 60h]
mov ecx, eax
mov dword[ebp - 1Ch], eax
mov eax, dword[edi + 68h]
mov dword[ebp - 0Ch], eax
mov eax, dword[edi + 6Ch]
mov edi, dword[ebp - 24h]
mov dword[ebp - 8h], edx
mov dword[ebp - 4h], eax
jmp @10
@09:
mov edx, dword[ebp - 8h]
@10:
and edx, dword[ebp - 1Ch]
mov esi, ecx
mov eax, ecx
ror esi, 0Bh
rol eax, 7h
xor esi, eax
mov eax, ecx
ror eax, 6h
not ecx
and ecx, dword[ebp - 0Ch]
xor esi, eax
xor ecx, edx
mov eax, edi
rol eax, 0Ah
mov edx, edi
ror edx, 0Dh
add esi, ecx
; базонезалежність
; -------------------------------------------
; push eax
; call @f
;@@: pop eax
; sub eax, @b
; add esi, dword[eax + ebx + k]
; pop eax
add esi, dword[ebx + k]
; -------------------------------------------
xor edx, eax
add esi, dword[ebx + ebp - 128h]
mov eax, edi
add esi, dword[ebp - 4h]
add ebx, 4h
ror eax, 2h
xor edx, eax
mov eax, dword[ebp - 14h]
mov ecx, eax
and eax, edi
xor ecx, edi
and ecx, dword[ebp - 10h]
xor ecx, eax
mov eax, dword[ebp - 0Ch]
add edx, ecx
mov dword[ebp - 4h], eax
mov ecx, dword[ebp - 8h]
mov eax, dword[ebp - 1Ch]
mov dword[ebp - 0Ch], ecx
mov ecx, dword[ebp - 18h]
mov dword[ebp - 8h], eax
add ecx, esi
mov eax, dword[ebp - 10h]
mov dword[ebp - 18h], eax
mov eax, dword[ebp - 14h]
mov dword[ebp - 14h], edi
lea edi, [esi + edx]
mov dword[ebp - 1Ch], ecx
mov dword[ebp - 10h], eax
cmp ebx, 100h
jb @09
mov eax, dword[ebp - 28h]
mov edx, dword[ebp - 14h]
add eax, edi
mov edi, dword[ebp - 20h]
add dword[edi + 60h], ecx
add dword[edi + 54h], edx
mov ecx, dword[ebp - 8h]
add dword[edi + 64h], ecx
mov edx, dword[ebp - 10h]
add dword[edi + 58h], edx
mov ecx, dword[ebp - 0Ch]
add dword[edi + 68h], ecx
mov edx, dword[ebp - 18h]
add dword[edi + 5Ch], edx
mov ecx, dword[ebp - 4h]
add dword[edi + 6Ch], ecx
mov dword[edi + 50h], eax
pop edi
pop esi
pop ebx
leave
ret
@11:
push ebp
mov ebp, esp
push ecx
push ebx
push esi
mov esi, ecx
mov dword[ebp - 4h], edx
push edi
push 38h
xor edi, edi
mov ecx, dword[esi + 40h]
pop ebx
cmp ecx, ebx
mov byte[esi + ecx], 80h
inc ecx
jae @12
cmp ecx, ebx
jae @15
sub ebx, ecx
lea eax, [esi + ecx]
push ebx
push edi
push eax
jmp @14
@12:
push 40h
pop edx
cmp ecx, edx
jae @13
sub edx, ecx
lea eax, [esi + ecx]
push edx
push edi
push eax
call @20
add esp, 0Ch
@13:
mov edx, esi
mov ecx, esi
call @05
push ebx
push edi
push esi
@14:
call @20
add esp, 0Ch
@15:
mov eax, dword[esi + 40h]
shl eax, 3h
add dword[esi + 48h], eax
adc dword[esi + 4Ch], edi
mov al, byte[esi + 48h]
mov byte[esi + 3Fh], al
mov ecx, dword[esi + 48h]
mov eax, dword[esi + 4Ch]
shrd ecx, eax, 8h
mov byte[esi + 3Eh], cl
mov ecx, dword[esi + 48h]
shr eax, 8h
mov eax, dword[esi + 4Ch]
shrd ecx, eax, 10h
mov byte[esi + 3Dh], cl
mov ecx, dword[esi + 48h]
shr eax, 10h
mov eax, dword[esi + 4Ch]
shrd ecx, eax, 18h
mov byte[esi + 3Ch], cl
mov cl, 20h
mov edx, dword[esi + 4Ch]
shr eax, 18h
mov eax, dword[esi + 48h]
call @17
mov byte[esi + 3Bh], al
mov cl, 28h
mov eax, dword[esi + 48h]
mov edx, dword[esi + 4Ch]
call @17
mov byte[esi + 3Ah], al
mov edx, esi
mov al, byte[esi + 4Eh]
mov ecx, esi
mov byte[esi + 39h], al
mov al, byte[esi + 4Fh]
mov byte[esi + 38h], al
call @05
mov edx, dword[ebp - 4h]
@16:
push 3h
pop eax
sub eax, edi
mov ecx, eax
mov eax, dword[esi + 50h]
shl ecx, 3h
shr eax, cl
mov byte[edi + edx], al
mov eax, dword[esi + 54h]
shr eax, cl
mov byte[edi + edx + 4h], al
mov eax, dword[esi + 58h]
shr eax, cl
mov byte[edi + edx + 8h], al
mov eax, dword[esi + 5Ch]
shr eax, cl
mov byte[edi + edx + 0Ch], al
mov eax, dword[esi + 60h]
shr eax, cl
mov byte[edi + edx + 10h], al
mov eax, dword[esi + 64h]
shr eax, cl
mov byte[edi + edx + 14h], al
mov eax, dword[esi + 68h]
shr eax, cl
mov byte[edi + edx + 18h], al
mov eax, dword[esi + 6Ch]
shr eax, cl
mov byte[edi + edx + 1Ch], al
inc edi
cmp edi, 4h
jb @16
pop edi
pop esi
pop ebx
leave
ret
@17:
cmp cl, 40h
jae @19
cmp cl, 20h
jae @18
shrd eax, edx, cl
shr edx, cl
ret
@18:
mov eax, edx
xor edx, edx
and cl, 1Fh
shr eax, cl
ret
@19:
xor eax, eax
xor edx, edx
ret
@20:
push ebp
mov ebp, esp
push edi
mov ecx, dword[ebp + 0x10]
mov edi, dword[ebp + 0x08]
mov al, byte[ebp + 0x0C]
rep stosb
pop edi
leave
retn
k:
dd 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
dd 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
dd 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
dd 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
dd 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
dd 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
dd 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
dd 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
main.asm
format pe console
section '.code' import readable writeable executable
PROV_RSA_AES = 24
CALG_SHA_256 = 0x0000800C
CRYPT_VERIFYCONTEXT = 0xF0000000
HP_HASHVAL = 2
include 'win32ax.inc'
library msvcrt, 'msvcrt.dll',\
advapi32, 'advapi32.dll'
import msvcrt,\
printf, 'printf',\
getchar, 'getchar',\
memcmp, 'memcmp'
import advapi32,\
CryptAcquireContextA, 'CryptAcquireContextA',\
CryptCreateHash, 'CryptCreateHash',\
CryptHashData, 'CryptHashData',\
CryptGetHashParam, 'CryptGetHashParam',\
CryptDestroyHash, 'CryptDestroyHash',\
CryptReleaseContext, 'CryptReleaseContext',\
RtlGenRandom, 'SystemFunction036'
proc print, buf
locals
frmt db '%02X', 0
endl
mov esi, [buf]
xor ecx, ecx
@@: movzx eax, byte[esi]
push ecx
cinvoke printf, addr frmt, eax
pop ecx
inc ecx
inc esi
cmp ecx, 32
jne @b
cinvoke printf, next_line
ret
endp
proc rnd, buf
locals
pRandomBuffer rd 1
endl
mov edi, [buf]
xor ecx, ecx
@@: push ecx
invoke RtlGenRandom, addr pRandomBuffer, 4
cmp eax, 0
je .err
mov eax, [pRandomBuffer]
xor edx, edx
mov ecx, 255
div ecx
mov eax, edx
jmp .fin
.err:
xor eax, eax
dec eax
.fin:
mov byte[edi], al
pop ecx
inc edi
inc ecx
cmp ecx, 32
jl @b
ret
endp
include 'sha256.asm'
proc sha256_get_hash_api, txt, len, buf
locals
buf_api_size dd 32
hProv rd 1
hHash rd 1
endl
invoke CryptAcquireContextA, addr hProv, 0, 0, PROV_RSA_AES, CRYPT_VERIFYCONTEXT
cmp eax, 0
je .fin1
invoke CryptCreateHash, [hProv], CALG_SHA_256, 0, 0, addr hHash
cmp eax, 0
je .fin
invoke CryptHashData, [hHash], [txt], [len], 0
cmp eax, 0
je .fin
invoke CryptGetHashParam, [hHash], HP_HASHVAL, [buf], addr buf_api_size, 0
cmp eax, 0
je .fin
.fin:
invoke CryptDestroyHash, [hHash]
.fin1:
invoke CryptReleaseContext, [hProv], 0
ret
endp
entry $
xor ecx, ecx
@@: push ecx
stdcall rnd, buf_rnd
; ---------------------------------------------------------------------------------------------------
stdcall sha256_get_hash_api, buf_rnd, 32, buf_api
; stdcall print, buf_api
; ---------------------------------------------------------------------------------------------------
stdcall sha256, buf_rnd, 32, buf_shl
; stdcall print, buf_shl
; ---------------------------------------------------------------------------------------------------
cinvoke memcmp, buf_api, buf_shl, 32
cmp eax, 0
jne not_eq
cinvoke printf, equally
jmp fin
not_eq:
cinvoke printf, not_equal
cinvoke getchar
fin:
pop ecx
inc ecx
cmp ecx, 40
jl @b
cinvoke printf, finish
cinvoke getchar
xor eax, eax
ret
equally db 'memcmp: equally', 13, 10, 0
not_equal db 'memcmp: not equal', 13, 10, 0
finish db 13, 10, 'finish ok!', 13, 10, 0
next_line db 13, 10, 0
buf_rnd rb 32
buf_api rb 32
buf_shl rb 32