0,0 → 1,238 |
; Implementation of SHA-256 hash algorithm. |
; Written by diamond in 2007. |
|
iglobal |
align 4 |
sha256_start_digest: |
dd 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A |
dd 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 |
sha256_const: |
dd 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5 |
dd 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5 |
dd 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3 |
dd 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174 |
dd 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC |
dd 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA |
dd 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7 |
dd 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967 |
dd 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13 |
dd 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85 |
dd 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3 |
dd 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070 |
dd 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5 |
dd 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3 |
dd 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208 |
dd 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 |
endg |
|
uglobal |
align 4 |
sha256_buf rb 64 |
sha256_digest rd 8 |
sha256_count dd ? |
sha256_size dq ? |
endg |
|
sha256_init: |
mov edi, sha256_digest |
mov esi, sha256_start_digest |
push 8 |
pop ecx |
rep movsd |
xor eax, eax |
stosd ; 0 bytes in buffer |
stosd |
stosd ; 0 bytes processed |
ret |
|
; Core of SHA-256: transform 64-byte 'sha256_buf' to updated 'sha256_digest' |
sha256_transform: |
mov esi, sha256_buf |
mov edi, esi |
rept 16 |
{ |
lodsd |
bswap eax |
stosd |
} |
push ebp |
mov ebp, [esi+7*4] |
mov edi, [esi+6*4] |
push dword [esi+5*4] |
push dword [esi+4*4] |
push dword [esi+3*4] |
push dword [esi+2*4] |
push dword [esi+1*4] |
push dword [esi+0*4] |
xor ecx, ecx |
.loop: |
macro cmd1 cmd,a,b |
{ |
if (b and 7) = 7 |
cmd a, ebp |
else if (b and 7) = 6 |
cmd a, edi |
else |
cmd a, [esp+(b and 7)*4] |
end if |
} |
macro cmd2 cmd,a,b |
{ |
if (a and 7) = 7 |
cmd ebp, b |
else if (a and 7) = 6 |
cmd edi, b |
else |
cmd [esp+(a and 7)*4], b |
end if |
} |
rept 16 counter |
{ |
cmd1 mov, eax, (5-counter) |
ror eax, 6 |
mov edx, eax |
ror eax, 5 |
xor edx, eax |
ror eax, 14 |
xor edx, eax |
cmd1 mov, eax, (6-counter) |
cmd1 mov, esi, (7-counter) |
xor eax, esi |
cmd1 and, eax, (5-counter) |
xor eax, esi |
add edx, eax |
add edx, [sha256_const+ecx+(counter-1)*4] |
add edx, dword [sha256_buf+(counter-1)*4] |
test ecx, ecx |
jz @f |
mov eax, dword [sha256_buf+((counter-3) and 15)*4] |
mov esi, eax |
ror eax, 17 |
shr esi, 10 |
xor esi, eax |
ror eax, 2 |
xor esi, eax |
add esi, dword [sha256_buf+((counter-8) and 15)*4] |
mov eax, dword [sha256_buf+(counter and 15)*4] |
mov ebx, eax |
ror eax, 7 |
shr ebx, 3 |
xor ebx, eax |
ror eax, 11 |
xor ebx, eax |
add esi, ebx |
add dword [sha256_buf+(counter-1)*4], esi |
add edx, esi |
@@: |
cmd1 add, edx, (8-counter) |
cmd2 mov, (8-counter), edx |
cmd2 add, (4-counter), edx |
cmd1 mov, ebx, (1-counter) |
mov eax, ebx |
cmd1 mov, edx, (2-counter) |
mov esi, ebx |
ror eax, 2 |
or esi, edx |
and ebx, edx |
cmd1 and, esi, (3-counter) |
mov edx, eax |
or esi, ebx |
ror eax, 11 |
xor edx, eax |
ror eax, 9 |
xor edx, eax |
add esi, edx |
cmd2 add, (8-counter), esi |
} |
purge cmd1,cmd2 |
add cl, 64 |
jnz .loop |
mov esi, sha256_digest |
pop eax |
add [esi+0*4], eax |
pop eax |
add [esi+1*4], eax |
pop eax |
add [esi+2*4], eax |
pop eax |
add [esi+3*4], eax |
pop eax |
add [esi+4*4], eax |
pop eax |
add [esi+5*4], eax |
add [esi+6*4], edi |
add [esi+7*4], ebp |
pop ebp |
ret |
|
sha256_update.transform: |
push esi edx |
call sha256_transform |
pop edx esi |
mov [sha256_count], ecx |
|
sha256_update: |
; in: esi->data, edx=size |
mov eax, 64 |
sub eax, [sha256_count] |
sub eax, edx |
sbb ecx, ecx |
and ecx, eax |
add ecx, edx |
sub edx, ecx |
mov edi, sha256_buf |
add edi, [sha256_count] |
add [sha256_count], ecx |
add dword [sha256_size], ecx |
adc dword [sha256_size+4], 0 |
rep movsb |
cmp edi, sha256_buf+64 |
jz .transform |
.ret: |
ret |
|
sha256_final: |
; out: edi->digest |
push edi |
mov eax, [sha256_count] |
mov [sha256_buf+eax], 0x80 |
inc eax |
cmp al, 64-8 |
jbe @f |
lea edi, [sha256_buf+eax] |
push 64 |
pop ecx |
sub ecx, eax |
xor eax, eax |
rep stosb |
push edx |
call sha256_transform |
pop edx |
xor eax, eax |
@@: |
push 64-8 |
pop ecx |
sub ecx, eax |
lea edi, [sha256_buf+eax] |
xor eax, eax |
rep stosb |
mov eax, dword [sha256_size] |
mov edx, dword [sha256_size+4] |
shld edx, eax, 3 |
shl eax, 3 |
bswap edx |
bswap eax |
xchg eax, edx |
stosd |
xchg eax, edx |
stosd |
call sha256_transform |
mov esi, sha256_digest |
mov cl, 8 |
pop edi |
@@: |
lodsd |
bswap eax |
stosd |
loop @b |
ret |