aaaaaa123456789 icon

SHA-1 implementation in gbz80

aaaaaa123456789 | PRO | 09/06/18 07:53:13 AM UTC | 0 ⭐ | 564 👁️ | Never ⏰ | []
text |

5.52 KB

|

None

|

0 👍

/

0 👎

offset: MACRO
	; I want to keep myself sane
	if _NARG > 1
		ld a, \2
	endc
	add a, LOW(\1)
	ld LOW(\1), a
	jr nc, .no_carry_\@
	inc HIGH(\1)
.no_carry_\@
ENDM
 CalculateSHA1:
	; in: hl: pointer to data, a: length (bytes)
	; out: hl = hl + 64 pointing to hash, all other regs clobbered, initial data buffer clobbered
	; returns carry iif a > 55 (since this would require implementing proper blocking)
	; prereq's: a <= 55, hl points to an 84-byte buffer initialized with the data
	cp 55
	ccf
	ret c
	push hl
 	; pad the block
	ld c, a
	offset hl
	ld a, $80
	ld [hli], a
	ld a, c
	sub 62
	ld b, a
	xor a
	jr .padding_loop_check
.padding_loop
	ld [hli], a
.padding_loop_check
	inc b
	jr nz, .padding_loop
	ld a, c
	add a, a
	add a, a
	add a, a
	ld b, a
	sbc a
	and 1
	ld [hli], a
	ld a, b
	ld [hli], a
 	; initialize the registers
	ld b, 20
	ld de, .initialization_data
.initialization_loop
	ld a, [de]
	inc de
	ld [hli], a
	dec b
	jr nz, .initialization_loop
	pop hl
 	; 80 iterations of operations
	xor a
.iteration_loop
	call .combine_states_and_constant
	push hl
	push af
	and $f
	add a, a
	add a, a
	offset hl
	call .add_word
	pop af
	pop hl
	push af
	call .update_states
	pop af
	cp $40
	call c, .update_buffer_word
	inc a
	cp $50
	jr c, .iteration_loop
 	; add the results to the initialization data
	offset hl, $40
	push hl
	xor a
.final_addition_loop
	push af
	call .load_word
	dec hl
	dec hl
	dec hl
	dec hl
	pop af
	push af
	push hl
	ld hl, .initialization_data
	add a, a
	add a, a
	offset hl
	call .add_word
	pop hl
	call .store_word
	pop af
	inc a
	cp 5
	jr c, .final_addition_loop
 	; and we're done!
	pop hl
	and a
	ret
 .load_word
	ld a, [hli]
	ld b, a
	ld a, [hli]
	ld c, a
	ld a, [hli]
	ld d, a
	ld a, [hli]
	ld e, a
	ret
 .store_word
	ld a, b
	ld [hli], a
	ld a, c
	ld [hli], a
	ld a, d
	ld [hli], a
	ld a, e
	ld [hli], a
	ret
 .and_word
	ld a, [hli]
	and b
	ld b, a
	ld a, [hli]
	and c
	ld c, a
	ld a, [hli]
	and d
	ld d, a
	ld a, [hli]
	and e
	ld e, a
	ret
 .or_word
	ld a, [hli]
	or b
	ld b, a
	ld a, [hli]
	or c
	ld c, a
	ld a, [hli]
	or d
	ld d, a
	ld a, [hli]
	or e
	ld e, a
	ret
 .rotate_word_left
	sla e
	rl d
	rl c
	rl b
	ret nc
	inc e
	ret
 .rotate_word_right
	srl b
	rr c
	rr d
	rr e
	ret nc
	set 7, b
	ret
 .combine_states_and_constant
	; must preserve a, hl
	push af
	push hl
	ld c, a
	offset hl, $44
	ld a, c
	call .initial_states_combination
	pop hl
	push hl
	offset hl, $50
	call .add_word
	pop hl
	push hl
	offset hl, $40
	add sp, -4
	push hl
	ld hl, sp + 2
	call .store_word
	pop hl
	call .load_word
	ld l, 5
.rotation_loop
	call .rotate_word_left
	dec l
	jr nz, .rotation_loop
	ld hl, sp + 0
	call .add_word
	add sp, 4
	pop hl
	pop af
	push af
	push hl
	call .add_iteration_constant
	pop hl
	pop af
	ret
 .initial_states_combination
	cp 20
	jr c, .selection_function
	cp 40
	jr c, .xor_function
	cp 60
	jr c, .majority_function
.xor_function
	call .load_word
	call .xor_word
.xor_word
	ld a, [hli]
	xor b
	ld b, a
	ld a, [hli]
	xor c
	ld c, a
	ld a, [hli]
	xor d
	ld d, a
	ld a, [hli]
	xor e
	ld e, a
	ret
 .majority_function
	add sp, -4
	call .load_word
	push hl
	push de
	push bc
	call .and_word
	push hl
	ld hl, sp + 8
	call .store_word
	pop hl
	pop bc
	pop de
	call .and_word
	ld hl, sp + 2
	call .or_word
	ld hl, sp + 2 ;faster than push/pop, and same size
	call .store_word
	pop hl
	call .load_word
	call .and_word
	ld hl, sp + 0
	call .or_word
	add sp, 4
	ret
 .selection_function
	add sp, -4
	call .load_word
	push de
	push bc
	call .and_word
	push hl
	ld hl, sp + 6
	call .store_word
	pop hl
	pop bc
	ld a, b
	cpl
	ld b, a
	ld a, c
	cpl
	ld c, a
	pop de
	ld a, d
	cpl
	ld d, a
	ld a, e
	cpl
	ld e, a
	call .and_word
	ld hl, sp + 0
	call .or_word
	add sp, 4
	ret
 .add_iteration_constant
	ld l, -1
.iteration_constant_loop
	inc l
	sub 20
	jr nc, .iteration_constant_loop
	ld a, l
	add a, a
	add a, a
	ld hl, .iteration_constants
	offset hl
.add_word
	inc hl
	inc hl
	inc hl
	ld a, [hld]
	add a, e
	ld e, a
	ld a, [hld]
	adc d
	ld d, a
	ld a, [hld]
	adc c
	ld c, a
	ld a, [hl]
	adc b
	ld b, a
	ret	
 .update_buffer_word
	; must preserve a, hl
	push af
	push hl
	sub 3
	and $f
	add a, a
	add a, a
	offset hl
	call .load_word
	pop hl
	pop af
	push af
	sub 8
	call .xor_word_by_offset
	pop af
	push af
	sub 14
	call .xor_word_by_offset
	pop af
	push af
	push hl
	and $f
	add a, a
	add a, a
	offset hl
	push hl
	call .xor_word
	call .rotate_word_left
	pop hl
	call .store_word
	pop hl
	pop af
	ret
 .xor_word_by_offset
	push hl
	and $f
	add a, a
	add a, a
	offset hl
	call .xor_word
	pop hl
	ret
 .update_states
	; must preserve hl
	push bc
	push de
	ld a, $4c
	call .shift_word_position
	ld a, $48
	call .shift_word_position
	push hl
	offset hl, $44
	call .load_word
	call .rotate_word_right
	call .rotate_word_right
	call .store_word
	pop hl
	ld a, $40
	call .shift_word_position
	pop de
	pop bc
	push hl
	offset hl, $40
	call .store_word
	pop hl
	ret
 .shift_word_position
	push hl
	offset hl
	call .load_word
	call .store_word
	pop hl
	ret
 .initialization_data
	db $67, $45, $23, $01
	db $ef, $cd, $ab, $89
	db $98, $ba, $dc, $fe
	db $10, $32, $54, $76
	db $c3, $d2, $e1, $f0
 .iteration_constants
	db $5a, $82, $79, $99
	db $6e, $d9, $eb, $a1
	db $8f, $1b, $bc, $dc
	db $ca, $62, $c1, $d6

Comments