;SHA1

;message digest size : 160 bits

;       push    offset ptrData                  ;The address of the data to be hashed 
;       push    nSize                           ;The number of bytes of data to be hashed
;       push    offset ptrBuffer                ;The pointer to the buffer to receive message digest (20 bytes)
;       call    SHA1

;WiteG//xtreeme

macro Trans_0	argument_1 , argument_2, argument_3, argument_4, argument_5, memory_ptr {

	mov	esp, argument_1
	mov	edi, dword [esi]
	rol	esp , 5
	bswap	edi
	add	argument_5, esp
	mov	memory_ptr, edi
	mov	esp, argument_3
	add	esi, 4
	xor	esp, argument_4
	add	argument_5, edi
	and	esp, argument_2
	xor	esp, argument_4
	ror	argument_2, 2
	lea	argument_5, [argument_5+esp+05A827999h]
}

macro Trans_1	argument_1 , argument_2, argument_3, argument_4, argument_5, memory_ptr_1, memory_ptr_2, memory_ptr_3, memory_ptr_4 {
	mov	esp, argument_1
	mov	edi, memory_ptr_1
	rol	esp , 5
	xor	edi, memory_ptr_2
	add	argument_5, esp
	xor	edi, memory_ptr_3
	mov	esp, argument_3
	xor	edi, memory_ptr_4
	xor	esp, argument_4
	rol	edi, 1
	and	esp, argument_2
	mov	memory_ptr_4, edi
	xor	esp, argument_4
	add	argument_5, edi
	ror	argument_2, 2
	lea	argument_5, [argument_5+esp+05A827999h]
}

macro Trans_2	argument_1 , argument_2, argument_3, argument_4, argument_5, memory_ptr_1, memory_ptr_2, memory_ptr_3, memory_ptr_4 {

	mov	esp, argument_1
	mov	edi, memory_ptr_1
	rol	esp , 5
	xor	edi, memory_ptr_2
	add	argument_5, esp
	xor	edi, memory_ptr_3
	mov	esp, argument_2
	xor	edi, memory_ptr_4
	xor	esp, argument_3
	rol	edi, 1
	xor	esp, argument_4
	mov	memory_ptr_4, edi
	add	argument_5, esp
	ror	argument_2, 2
	lea	argument_5, [argument_5+edi+06ED9EBA1h]
}

macro Trans_3	argument_1 , argument_2, argument_3, argument_4, argument_5, memory_ptr_1, memory_ptr_2, memory_ptr_3, memory_ptr_4 {

	mov	esp, argument_1
	mov	edi, memory_ptr_1
	rol	esp , 5
	xor	edi, memory_ptr_2
	add	argument_5, esp
	xor	edi, memory_ptr_3
	mov	esp, argument_2
	xor	edi, memory_ptr_4
	or	esp, argument_3
	rol	edi, 1
	and	esp, argument_4
	mov	memory_ptr_4, edi
	add	argument_5  , edi
	mov	edi, argument_2
	and	edi, argument_3
	or	edi, esp
	ror	argument_2, 2
	lea	argument_5, [argument_5+edi+08F1BBCDCh]
}

macro Trans_4	argument_1 , argument_2, argument_3, argument_4, argument_5, memory_ptr_1, memory_ptr_2, memory_ptr_3, memory_ptr_4 {

	mov	esp, argument_1
	mov	edi, memory_ptr_1
	rol	esp , 5
	xor	edi, memory_ptr_2
	add	argument_5, esp
	xor	edi, memory_ptr_3
	mov	esp, argument_2
	xor	edi, memory_ptr_4
	xor	esp, argument_3
	rol	edi, 1
	xor	esp, argument_4
	mov	memory_ptr_4, edi
	add	argument_5  , esp
	ror	argument_2, 2
	lea	argument_5, [argument_5+edi+0CA62C1D6h]
}

_temp_buffer	db 128 dup(?)
old_esp 	dd ?
_hash_0 	dd ?
_hash_1 	dd ?
_hash_2 	dd ?
_hash_3 	dd ?
_hash_4 	dd ?
_hash_5 	dd ?
_hash_6 	dd ?
_hash_7 	dd ?
_hash_8 	dd ?
_hash_9 	dd ?
_hash_0_temp	dd ?
_hash_1_temp	dd ?
_hash_2_temp	dd ?
_hash_3_temp	dd ?
_hash_4_temp	dd ?
_hash_5_temp	dd ?
_hash_6_temp	dd ?
_hash_7_temp	dd ?
_hash_8_temp	dd ?
_hash_9_temp	dd ?
_size		dd ?
_count		dd ?
_flag		dd ?

proc SHA1
	pushad
	mov	[old_esp], esp
	cld
	mov	ecx, [esp+ 28h] ; dlugosc danych do hashowania w bajtach        _size
	mov	esi, [esp+ 2Ch] ; offset danych do hashowania                   _addr_INPUT
	mov	dword [_size] , ecx
	or	dword [_flag] , -1		; umowna flaga...
	mov	dword [_count], ecx

	mov	dword [_hash_0] , 067452301h
	mov	dword [_hash_1] , 0EFCDAB89h
	mov	dword [_hash_2] , 098BADCFEh
	mov	dword [_hash_3] , 010325476h
	mov	dword [_hash_4] , 0C3D2E1F0h

@@SHA1_Loop:
	cmp	dword [_count] , 64
	jb	@@SHA1_LIPOF

	mov	eax, dword [_hash_0]
	mov	ebx, dword [_hash_1]
	mov	ecx, dword [_hash_2]
	mov	edx, dword [_hash_3]
	mov	ebp, dword [_hash_4]

	Trans_0 eax,ebx,ecx,edx,ebp,dword [_temp_buffer+4*0]
	Trans_0 ebp,eax,ebx,ecx,edx,dword [_temp_buffer+4*1]
	Trans_0 edx,ebp,eax,ebx,ecx,dword [_temp_buffer+4*2]
	Trans_0 ecx,edx,ebp,eax,ebx,dword [_temp_buffer+4*3]
	Trans_0 ebx,ecx,edx,ebp,eax,dword [_temp_buffer+4*4]
	Trans_0 eax,ebx,ecx,edx,ebp,dword [_temp_buffer+4*5]
	Trans_0 ebp,eax,ebx,ecx,edx,dword [_temp_buffer+4*6]
	Trans_0 edx,ebp,eax,ebx,ecx,dword [_temp_buffer+4*7]
	Trans_0 ecx,edx,ebp,eax,ebx,dword [_temp_buffer+4*8]
	Trans_0 ebx,ecx,edx,ebp,eax,dword [_temp_buffer+4*9]
	Trans_0 eax,ebx,ecx,edx,ebp,dword [_temp_buffer+4*10]
	Trans_0 ebp,eax,ebx,ecx,edx,dword [_temp_buffer+4*11]
	Trans_0 edx,ebp,eax,ebx,ecx,dword [_temp_buffer+4*12]
	Trans_0 ecx,edx,ebp,eax,ebx,dword [_temp_buffer+4*13]
	Trans_0 ebx,ecx,edx,ebp,eax,dword [_temp_buffer+4*14]
	Trans_0 eax,ebx,ecx,edx,ebp,dword [_temp_buffer+4*15]
	Trans_1 ebp,eax,ebx,ecx,edx,dword [_temp_buffer+4*13],dword [_temp_buffer+4*8] ,dword [_temp_buffer+4*2] ,dword [_temp_buffer+4*0]
	Trans_1 edx,ebp,eax,ebx,ecx,dword [_temp_buffer+4*14],dword [_temp_buffer+4*9] ,dword [_temp_buffer+4*3] ,dword [_temp_buffer+4*1]
	Trans_1 ecx,edx,ebp,eax,ebx,dword [_temp_buffer+4*15],dword [_temp_buffer+4*10],dword [_temp_buffer+4*4] ,dword [_temp_buffer+4*2]
	Trans_1 ebx,ecx,edx,ebp,eax,dword [_temp_buffer+4*0] ,dword [_temp_buffer+4*11],dword [_temp_buffer+4*5] ,dword [_temp_buffer+4*3]
	Trans_2 eax,ebx,ecx,edx,ebp,dword [_temp_buffer+4*1] ,dword [_temp_buffer+4*12],dword [_temp_buffer+4*6] ,dword [_temp_buffer+4*4]
	Trans_2 ebp,eax,ebx,ecx,edx,dword [_temp_buffer+4*2] ,dword [_temp_buffer+4*13],dword [_temp_buffer+4*7] ,dword [_temp_buffer+4*5]
	Trans_2 edx,ebp,eax,ebx,ecx,dword [_temp_buffer+4*3] ,dword [_temp_buffer+4*14],dword [_temp_buffer+4*8] ,dword [_temp_buffer+4*6]
	Trans_2 ecx,edx,ebp,eax,ebx,dword [_temp_buffer+4*4] ,dword [_temp_buffer+4*15],dword [_temp_buffer+4*9] ,dword [_temp_buffer+4*7]
	Trans_2 ebx,ecx,edx,ebp,eax,dword [_temp_buffer+4*5] ,dword [_temp_buffer+4*0] ,dword [_temp_buffer+4*10],dword [_temp_buffer+4*8]
	Trans_2 eax,ebx,ecx,edx,ebp,dword [_temp_buffer+4*6] ,dword [_temp_buffer+4*1] ,dword [_temp_buffer+4*11],dword [_temp_buffer+4*9]
	Trans_2 ebp,eax,ebx,ecx,edx,dword [_temp_buffer+4*7] ,dword [_temp_buffer+4*2] ,dword [_temp_buffer+4*12],dword [_temp_buffer+4*10]
	Trans_2 edx,ebp,eax,ebx,ecx,dword [_temp_buffer+4*8] ,dword [_temp_buffer+4*3] ,dword [_temp_buffer+4*13],dword [_temp_buffer+4*11]
	Trans_2 ecx,edx,ebp,eax,ebx,dword [_temp_buffer+4*9] ,dword [_temp_buffer+4*4] ,dword [_temp_buffer+4*14],dword [_temp_buffer+4*12]
	Trans_2 ebx,ecx,edx,ebp,eax,dword [_temp_buffer+4*10],dword [_temp_buffer+4*5] ,dword [_temp_buffer+4*15],dword [_temp_buffer+4*13]
	Trans_2 eax,ebx,ecx,edx,ebp,dword [_temp_buffer+4*11],dword [_temp_buffer+4*6] ,dword [_temp_buffer+4*0] ,dword [_temp_buffer+4*14]
	Trans_2 ebp,eax,ebx,ecx,edx,dword [_temp_buffer+4*12],dword [_temp_buffer+4*7] ,dword [_temp_buffer+4*1] ,dword [_temp_buffer+4*15]
	Trans_2 edx,ebp,eax,ebx,ecx,dword [_temp_buffer+4*13],dword [_temp_buffer+4*8] ,dword [_temp_buffer+4*2] ,dword [_temp_buffer+4*0]
	Trans_2 ecx,edx,ebp,eax,ebx,dword [_temp_buffer+4*14],dword [_temp_buffer+4*9] ,dword [_temp_buffer+4*3] ,dword [_temp_buffer+4*1]
	Trans_2 ebx,ecx,edx,ebp,eax,dword [_temp_buffer+4*15],dword [_temp_buffer+4*10],dword [_temp_buffer+4*4] ,dword [_temp_buffer+4*2]
	Trans_2 eax,ebx,ecx,edx,ebp,dword [_temp_buffer+4*0] ,dword [_temp_buffer+4*11],dword [_temp_buffer+4*5] ,dword [_temp_buffer+4*3]
	Trans_2 ebp,eax,ebx,ecx,edx,dword [_temp_buffer+4*1] ,dword [_temp_buffer+4*12],dword [_temp_buffer+4*6] ,dword [_temp_buffer+4*4]
	Trans_2 edx,ebp,eax,ebx,ecx,dword [_temp_buffer+4*2] ,dword [_temp_buffer+4*13],dword [_temp_buffer+4*7] ,dword [_temp_buffer+4*5]
	Trans_2 ecx,edx,ebp,eax,ebx,dword [_temp_buffer+4*3] ,dword [_temp_buffer+4*14],dword [_temp_buffer+4*8] ,dword [_temp_buffer+4*6]
	Trans_2 ebx,ecx,edx,ebp,eax,dword [_temp_buffer+4*4] ,dword [_temp_buffer+4*15],dword [_temp_buffer+4*9] ,dword [_temp_buffer+4*7]
	Trans_3 eax,ebx,ecx,edx,ebp,dword [_temp_buffer+4*5] ,dword [_temp_buffer+4*0] ,dword [_temp_buffer+4*10],dword [_temp_buffer+4*8]
	Trans_3 ebp,eax,ebx,ecx,edx,dword [_temp_buffer+4*6] ,dword [_temp_buffer+4*1] ,dword [_temp_buffer+4*11],dword [_temp_buffer+4*9]
	Trans_3 edx,ebp,eax,ebx,ecx,dword [_temp_buffer+4*7] ,dword [_temp_buffer+4*2] ,dword [_temp_buffer+4*12],dword [_temp_buffer+4*10]
	Trans_3 ecx,edx,ebp,eax,ebx,dword [_temp_buffer+4*8] ,dword [_temp_buffer+4*3] ,dword [_temp_buffer+4*13],dword [_temp_buffer+4*11]
	Trans_3 ebx,ecx,edx,ebp,eax,dword [_temp_buffer+4*9] ,dword [_temp_buffer+4*4] ,dword [_temp_buffer+4*14],dword [_temp_buffer+4*12]
	Trans_3 eax,ebx,ecx,edx,ebp,dword [_temp_buffer+4*10],dword [_temp_buffer+4*5] ,dword [_temp_buffer+4*15],dword [_temp_buffer+4*13]
	Trans_3 ebp,eax,ebx,ecx,edx,dword [_temp_buffer+4*11],dword [_temp_buffer+4*6] ,dword [_temp_buffer+4*0] ,dword [_temp_buffer+4*14]
	Trans_3 edx,ebp,eax,ebx,ecx,dword [_temp_buffer+4*12],dword [_temp_buffer+4*7] ,dword [_temp_buffer+4*1] ,dword [_temp_buffer+4*15]
	Trans_3 ecx,edx,ebp,eax,ebx,dword [_temp_buffer+4*13],dword [_temp_buffer+4*8] ,dword [_temp_buffer+4*2] ,dword [_temp_buffer+4*0]
	Trans_3 ebx,ecx,edx,ebp,eax,dword [_temp_buffer+4*14],dword [_temp_buffer+4*9] ,dword [_temp_buffer+4*3] ,dword [_temp_buffer+4*1]
	Trans_3 eax,ebx,ecx,edx,ebp,dword [_temp_buffer+4*15],dword [_temp_buffer+4*10],dword [_temp_buffer+4*4] ,dword [_temp_buffer+4*2]
	Trans_3 ebp,eax,ebx,ecx,edx,dword [_temp_buffer+4*0] ,dword [_temp_buffer+4*11],dword [_temp_buffer+4*5] ,dword [_temp_buffer+4*3]
	Trans_3 edx,ebp,eax,ebx,ecx,dword [_temp_buffer+4*1] ,dword [_temp_buffer+4*12],dword [_temp_buffer+4*6] ,dword [_temp_buffer+4*4]
	Trans_3 ecx,edx,ebp,eax,ebx,dword [_temp_buffer+4*2] ,dword [_temp_buffer+4*13],dword [_temp_buffer+4*7] ,dword [_temp_buffer+4*5]
	Trans_3 ebx,ecx,edx,ebp,eax,dword [_temp_buffer+4*3] ,dword [_temp_buffer+4*14],dword [_temp_buffer+4*8] ,dword [_temp_buffer+4*6]
	Trans_3 eax,ebx,ecx,edx,ebp,dword [_temp_buffer+4*4] ,dword [_temp_buffer+4*15],dword [_temp_buffer+4*9] ,dword [_temp_buffer+4*7]
	Trans_3 ebp,eax,ebx,ecx,edx,dword [_temp_buffer+4*5] ,dword [_temp_buffer+4*0] ,dword [_temp_buffer+4*10],dword [_temp_buffer+4*8]
	Trans_3 edx,ebp,eax,ebx,ecx,dword [_temp_buffer+4*6] ,dword [_temp_buffer+4*1] ,dword [_temp_buffer+4*11],dword [_temp_buffer+4*9]
	Trans_3 ecx,edx,ebp,eax,ebx,dword [_temp_buffer+4*7] ,dword [_temp_buffer+4*2] ,dword [_temp_buffer+4*12],dword [_temp_buffer+4*10]
	Trans_3 ebx,ecx,edx,ebp,eax,dword [_temp_buffer+4*8] ,dword [_temp_buffer+4*3] ,dword [_temp_buffer+4*13],dword [_temp_buffer+4*11]
	Trans_4 eax,ebx,ecx,edx,ebp,dword [_temp_buffer+4*9] ,dword [_temp_buffer+4*4] ,dword [_temp_buffer+4*14],dword [_temp_buffer+4*12]
	Trans_4 ebp,eax,ebx,ecx,edx,dword [_temp_buffer+4*10],dword [_temp_buffer+4*5] ,dword [_temp_buffer+4*15],dword [_temp_buffer+4*13]
	Trans_4 edx,ebp,eax,ebx,ecx,dword [_temp_buffer+4*11],dword [_temp_buffer+4*6] ,dword [_temp_buffer+4*0] ,dword [_temp_buffer+4*14]
	Trans_4 ecx,edx,ebp,eax,ebx,dword [_temp_buffer+4*12],dword [_temp_buffer+4*7] ,dword [_temp_buffer+4*1] ,dword [_temp_buffer+4*15]
	Trans_4 ebx,ecx,edx,ebp,eax,dword [_temp_buffer+4*13],dword [_temp_buffer+4*8] ,dword [_temp_buffer+4*2] ,dword [_temp_buffer+4*0]
	Trans_4 eax,ebx,ecx,edx,ebp,dword [_temp_buffer+4*14],dword [_temp_buffer+4*9] ,dword [_temp_buffer+4*3] ,dword [_temp_buffer+4*1]
	Trans_4 ebp,eax,ebx,ecx,edx,dword [_temp_buffer+4*15],dword [_temp_buffer+4*10],dword [_temp_buffer+4*4] ,dword [_temp_buffer+4*2]
	Trans_4 edx,ebp,eax,ebx,ecx,dword [_temp_buffer+4*0] ,dword [_temp_buffer+4*11],dword [_temp_buffer+4*5] ,dword [_temp_buffer+4*3]
	Trans_4 ecx,edx,ebp,eax,ebx,dword [_temp_buffer+4*1] ,dword [_temp_buffer+4*12],dword [_temp_buffer+4*6] ,dword [_temp_buffer+4*4]
	Trans_4 ebx,ecx,edx,ebp,eax,dword [_temp_buffer+4*2] ,dword [_temp_buffer+4*13],dword [_temp_buffer+4*7] ,dword [_temp_buffer+4*5]
	Trans_4 eax,ebx,ecx,edx,ebp,dword [_temp_buffer+4*3] ,dword [_temp_buffer+4*14],dword [_temp_buffer+4*8] ,dword [_temp_buffer+4*6]
	Trans_4 ebp,eax,ebx,ecx,edx,dword [_temp_buffer+4*4] ,dword [_temp_buffer+4*15],dword [_temp_buffer+4*9] ,dword [_temp_buffer+4*7]
	Trans_4 edx,ebp,eax,ebx,ecx,dword [_temp_buffer+4*5] ,dword [_temp_buffer+4*0] ,dword [_temp_buffer+4*10],dword [_temp_buffer+4*8]
	Trans_4 ecx,edx,ebp,eax,ebx,dword [_temp_buffer+4*6] ,dword [_temp_buffer+4*1] ,dword [_temp_buffer+4*11],dword [_temp_buffer+4*9]
	Trans_4 ebx,ecx,edx,ebp,eax,dword [_temp_buffer+4*7] ,dword [_temp_buffer+4*2] ,dword [_temp_buffer+4*12],dword [_temp_buffer+4*10]
	Trans_4 eax,ebx,ecx,edx,ebp,dword [_temp_buffer+4*8] ,dword [_temp_buffer+4*3] ,dword [_temp_buffer+4*13],dword [_temp_buffer+4*11]
	Trans_4 ebp,eax,ebx,ecx,edx,dword [_temp_buffer+4*9] ,dword [_temp_buffer+4*4] ,dword [_temp_buffer+4*14],dword [_temp_buffer+4*12]
	Trans_4 edx,ebp,eax,ebx,ecx,dword [_temp_buffer+4*10],dword [_temp_buffer+4*5] ,dword [_temp_buffer+4*15],dword [_temp_buffer+4*13]
	Trans_4 ecx,edx,ebp,eax,ebx,dword [_temp_buffer+4*11],dword [_temp_buffer+4*6] ,dword [_temp_buffer+4*0] ,dword [_temp_buffer+4*14]
	Trans_4 ebx,ecx,edx,ebp,eax,dword [_temp_buffer+4*12],dword [_temp_buffer+4*7] ,dword [_temp_buffer+4*1] ,dword [_temp_buffer+4*15]

	add	dword [_hash_0], eax
	add	dword [_hash_1], ebx
	add	dword [_hash_2], ecx
	add	dword [_hash_3], edx
	add	dword [_hash_4], ebp

	sub	dword [_count], 64
	jmp	@@SHA1_Loop

@@SHA1_LIPOF:
	cmp	dword [_flag], 0
	jz	@@SHA1_Finishing
	mov	esp, old_esp
	call	BI_Padding
	jmp	@@SHA1_Loop

@@SHA1_Finishing:
	mov	esp, old_esp
	mov	edi, [esp+ 24h] 	; offset bufora dla wyniku _addr_OUTPUT
	mov	esi, offset _hash_0

	mov	ecx, 5
@@:
	mov	eax, dword [esi+4*ecx-4]
	bswap	eax
	mov	dword [edi+4*ecx-4], eax
	dec	ecx
	jnz	@B

	mov	ecx, 56
	xor	eax, eax
	mov	edi, offset _temp_buffer
	rep	stosd

	popad
	ret	0Ch
endp

proc BI_Padding

	mov	ecx, dword [_count]
	mov	dword [_flag] , 0
	mov	dword [_count], 64
	mov	eax, ecx
	mov	edi, offset _temp_buffer

	test	eax, eax
	jz	@@only_null
	
	rep	movsb

@@only_null:
	mov	ecx, eax
	mov	byte ptr [edi], 80h
	sub	ecx, 55
	inc	edi
	neg	ecx
	jz	@@save_size_in_pad
	jns	@@zero_mem

	add	dword [_count], 64
	add	ecx, 64 	;padding rozciagnij tez na nastepne 64 bajty !

@@zero_mem:
	xor	al, al
	rep	stosb

@@save_size_in_pad:
	xor	edx, edx
	mov	eax, dword [_size]
	mul	dword [const_8]
	bswap	eax
	bswap	edx
	mov	dword [edi], edx
	mov	dword [edi+4], eax
	mov	esi, offset _temp_buffer
	ret
	
const_8 dd	8
endp