239 lines
6.4 KiB
PHP
239 lines
6.4 KiB
PHP
|
; 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
|