;
;------------------------------------------------------------------
;
; This code is form www.hendrikdettmer.de
;
; Copyright by 
;
;  Thomas Siebert		
;  Johannes Veerkamp
;& Hendrik Dettmer		(me@hendrikdettmer.de)
;
; Have fun!
; Questions? Just mail us!
;-------------------------------------------------------------------
;


.INCLUDE "m163def.inc"	;ATmega163 spezifische Konstanten einbinden
.include "defsdec.inc"

LDI R16, high(ramend)	;R16 ? Höherwertigen 8 Bit des SRAM Endes
LDI R17, low(ramend)	;R17 ? Niederwertigen 8 Bit des SRAM Endes
OUT SPH, R16			;Stack Pointer (high Byte) ? R16
OUT SPL, R17			;Stack Pointer (low Byte) ? R17


;set key
ldi r16,0
ldi r17,1
ldi r18,2
ldi r19,3
ldi r20,4
ldi r21,5
ldi r22,6
ldi r23,7
ldi r24,8


sts $0060,r16
sts $0061,r17
sts $0062,r16
sts $0063,r18
sts $0064,r16
sts $0065,r19
sts $0066,r16
sts $0067,r20
sts $0068,r16
sts $0069,r21
sts $006a,r16
sts $006b,r22
sts $006c,r16
sts $006d,r23
sts $006e,r16
sts $006f,r24

;set plaintext/ciphertext

ldi r16,$11
ldi r17,$FB
ldi r18,$ED
ldi r19,$2B
ldi r20,$01
ldi r21,$98
ldi r22,$6D
ldi r23,$E5

sts $0070,r16
sts $0071,r17
sts $0072,r18
sts $0073,r19
sts $0074,r20
sts $0075,r21
sts $0076,r22
sts $0077,r23

;set parameter pointers

ldi r24,$70     ;pointer 1 to plaintext
ldi r25,$00
ldi r22,$60     ;pointer 2 to key
ldi r23,$00
ldi r20,$78     ;pointer 3 to 104 free bytes in SRAM
ldi r21,$00



;.... hier kommt Euer Programm rein


;--------------------------------------------------------------
;                        [. Decryption .]
;--------------------------------------------------------------

	push texth
	push textl
	
	mov xh, keyh		;load key
	mov xl, keyl
	ld k1h, x+
	ld k1l, x+
	ld k2h, x+
	ld k2l, x+
	ld k3h, x+
	ld k3l, x+
	ld k4h, x+
	ld k4l, x+
	ld k5h, x+
	ld k5l, x+
	ld k6h, x+
	ld k6l, x+
	ld k7h, x+
	ld k7l, x+
	ld k8h, x+
	ld k8l, x+


	mov xh, texth		;load plaintext
	mov xl, textl
	ld p1h, x+
	ld p1l, x+
	ld p2h, x+
	ld p2l, x+
	ld p3h, x+
	ld p3l, x+
	ld p4h, x+
	ld p4l, x+

	clr r0
	clr r1
	inc r1


;--------------------------------------------------------------
;                               Round 1
;--------------------------------------------------------------

;/
;/ Key Shift
;/

	lsr k8l
	ror k1h
	ror k1l
	ror k2h
	ror k2l
	ror k3h
	ror k3l
	ror k4h
	ror k4l
	ror k5h
	ror k5l
	ror k6h
	ror k6l
	ror k7h
	ror k7l
	ror k8h
	brcc prekeysh1
	ori k8l, $80
prekeysh1:
	lsr k8l
	ror k1h
	ror k1l
	ror k2h
	ror k2l
	ror k3h
	ror k3l
	ror k4h
	ror k4l
	ror k5h
	ror k5l
	ror k6h
	ror k6l
	ror k7h
	ror k7l
	ror k8h
	brcc prekeysh2
	ori k8l, $80
prekeysh2:
	


;/
;/ p1 x k1 --> p1
;/

	push k1h_1
	push k1l_1
	push bh
	push bl

	cp k1h_1, r0
	cpc k1l_1, r0
	brne prekeynotzero_k1_1

	mov TMP2, p1l
	mov TMP3, p1h
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k1_1

prekeynotzero_k1_1:
	clr r1
	inc r1
	clr uh
	clr um
	mov ul, r1
	clr bh
	mov bl, r1
	clr vh
	clr vm
	clr vl

pre_abcompare_k1_1:
	cp k1l_1, bl
	cpc k1h_1, bh
	brne pre_weiter_k1_1
	rjmp eukfinished_k1_1
pre_weiter_k1_1:
	bst k1l_1, 0			;if (A even)
	brts pre_anoteven_k1_1

	lsr k1h_1				;	A <- A/2
	ror k1l_1

	bst ul, 0			;	if (U uneven)
	brtc pre_u1even_k1_1

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

pre_u1even_k1_1:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp pre_abcompare_k1_1


pre_anoteven_k1_1:
	sub bl, k1l_1					;	B <- (B-A)/2
	sbc bh, k1h_1
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh
	
	add vl, r1			;	cause (V<0)
	adc vm, r0				;		V <- V+(2^16)+1
	adc vh, r1

	bst vl, 0					;	if (V uneven)
	brtc pre_veven_k1_1

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

pre_veven_k1_1:
	lsr vh						;	V <- V/2
	ror vm
	ror vl


abcompare_k1_1:
	cp k1l_1, bl
	cpc k1h_1, bh
	brne weiter_k1_1
	rjmp eukfinished_k1_1
weiter_k1_1:
	bst k1l_1, 0			;if (A even)
	brts anoteven_k1_1

	lsr k1h_1				;	A <- A/2
	ror k1l_1

	bst ul, 0			;	if (U uneven)
	brtc u1even_k1_1

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

u1even_k1_1:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k1_1


anoteven_k1_1:
	bst bl, 0			;if (B even)
	brts bnoteven_k1_1

	lsr bh				;	B <- B/2
	ror bl

	bst vl, 0					;	if (V uneven)
	brtc v1even_k1_1

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

v1even_k1_1:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k1_1

bnoteven_k1_1:
	cp k1h_1, bh			;if (A>B)
	brlo alowerthanb_k1_1
	brne ahigherthanb_k1_1
	cp k1l_1, bl
	brlo alowerthanb_k1_1
ahigherthanb_k1_1:
	sub k1l_1, bl			;	A <- (A-B)/2			
	sbc k1h_1, bh
	lsr k1h_1
	ror k1l_1

	sub ul, vl			;	U <- U-V
	sbc um, vm
	sbc uh, vh

	brpl upositive_k1_1		;	if (U<0)
	
	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

upositive_k1_1:
	bst ul, 0			;	if (U uneven)
	brtc ueven_k1_1

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

ueven_k1_1:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k1_1	


alowerthanb_k1_1:					;else
	sub bl, k1l_1					;	B <- (B-A)/2
	sbc bh, k1h_1
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh

	brpl vpositive_k1_1			;	if (V<0)
	
	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

vpositive_k1_1:
	bst vl, 0					;	if (V uneven)
	brtc veven_k1_1

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

veven_k1_1:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k1_1	

eukfinished_k1_1:

	mul	p1h, um					; ah * bh
	movw	TMP5:TMP4, r1:r0
	brne	A_Notzero_k1_1		; Go on if mul nonzero

	mul	p1l, ul
	movw	TMP3:TMP2, r1:r0
	brne	B_Notzero_k1_1		; Go on if mul nonzero

	mul	p1h, ul					; ah * bl
	brne	C_Notzero_k1_1		; Go on if mul nonzero
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p1l					; bh * al
	brne	D_Notzero_k1_1

	mov TMP2, ul
	mov TMP3, um
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k1_1

A_Notzero_k1_1:
	mul	p1l, ul					; al * bl
	movw	TMP3:TMP2, r1:r0

B_Notzero_k1_1:
	mul	p1h, ul					; ah * bl
C_Notzero_k1_1:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p1l					; bh * al
D_Notzero_k1_1:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	sub TMP2, TMP4				;sub low16(result), high16(result)
	sbc TMP3, TMP5
	brsh mulmod216_end_k1_1		;if low16(result) <= high16(result)
	adiw TMP3:TMP2, 1			;    inc low16(result) 
mulmod216_end_k1_1:
	mov p1h, TMP3
	mov p1l, TMP2

	pop bl
	pop bh
	pop k1l_1
	pop k1h_1
	

;/	
;/ p2 + k2 --> p2
;/

	sub p2l, k2l_1
	sbc p2h, k2h_1


;/
;/ p3 + k3 --> p3
;/

	sub p3l, k3l_1
	sbc p3h, k3h_1

;/
;/ p4 x k4 --> p4
;/

	push k4h_1
	push k4l_1
	push bh
	push bl

	cp k4h_1, r0
	cpc k4l_1, r0
	brne prekeynotzero_k4_1

	mov TMP2, p4l
	mov TMP3, p4h
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k4_1

prekeynotzero_k4_1:
	clr r1
	inc r1
	clr uh
	clr um
	mov ul, r1
	clr bh
	mov bl, r1
	clr vh
	clr vm
	clr vl

pre_abcompare_k4_1:
	cp k4l_1, bl
	cpc k4h_1, bh
	brne pre_weiter_k4_1
	rjmp eukfinished_k4_1
pre_weiter_k4_1:
	bst k4l_1, 0			;if (A even)
	brts pre_anoteven_k4_1

	lsr k4h_1				;	A <- A/2
	ror k4l_1

	bst ul, 0			;	if (U uneven)
	brtc pre_u1even_k4_1

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

pre_u1even_k4_1:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp pre_abcompare_k4_1


pre_anoteven_k4_1:
	sub bl, k4l_1					;	B <- (B-A)/2
	sbc bh, k4h_1
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh
	
	add vl, r1			;	cause (V<0)
	adc vm, r0				;		V <- V+(2^16)+1
	adc vh, r1

	bst vl, 0					;	if (V uneven)
	brtc pre_veven_k4_1

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

pre_veven_k4_1:
	lsr vh						;	V <- V/2
	ror vm
	ror vl


abcompare_k4_1:
	cp k4l_1, bl
	cpc k4h_1, bh
	brne weiter_k4_1
	rjmp eukfinished_k4_1
weiter_k4_1:
	bst k4l_1, 0			;if (A even)
	brts anoteven_k4_1

	lsr k4h_1				;	A <- A/2
	ror k4l_1

	bst ul, 0			;	if (U uneven)
	brtc u1even_k4_1

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

u1even_k4_1:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k4_1


anoteven_k4_1:
	bst bl, 0			;if (B even)
	brts bnoteven_k4_1

	lsr bh				;	B <- B/2
	ror bl

	bst vl, 0					;	if (V uneven)
	brtc v1even_k4_1

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

v1even_k4_1:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k4_1

bnoteven_k4_1:
	cp k4h_1, bh			;if (A>B)
	brlo alowerthanb_k4_1
	brne ahigherthanb_k4_1
	cp k4l_1, bl
	brlo alowerthanb_k4_1
ahigherthanb_k4_1:
	sub k4l_1, bl			;	A <- (A-B)/2			
	sbc k4h_1, bh
	lsr k4h_1
	ror k4l_1

	sub ul, vl			;	U <- U-V
	sbc um, vm
	sbc uh, vh

	brpl upositive_k4_1		;	if (U<0)
	
	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

upositive_k4_1:
	bst ul, 0			;	if (U uneven)
	brtc ueven_k4_1

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

ueven_k4_1:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k4_1	


alowerthanb_k4_1:					;else
	sub bl, k4l_1					;	B <- (B-A)/2
	sbc bh, k4h_1
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh

	brpl vpositive_k4_1			;	if (V<0)
	
	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

vpositive_k4_1:
	bst vl, 0					;	if (V uneven)
	brtc veven_k4_1

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

veven_k4_1:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k4_1	

eukfinished_k4_1:

	mul	p4h, um					; ah * bh
	movw	TMP5:TMP4, r1:r0
	brne	A_Notzero_k4_1		; Go on if mul nonzero

	mul	p4l, ul
	movw	TMP3:TMP2, r1:r0
	brne	B_Notzero_k4_1		; Go on if mul nonzero

	mul	p4h, ul					; ah * bl
	brne	C_Notzero_k4_1		; Go on if mul nonzero
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p4l					; bh * al
	brne	D_Notzero_k4_1

	mov TMP2, ul
	mov TMP3, um
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k4_1

A_Notzero_k4_1:
	mul	p4l, ul					; al * bl
	movw	TMP3:TMP2, r1:r0

B_Notzero_k4_1:
	mul	p4h, ul					; ah * bl
C_Notzero_k4_1:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p4l					; bh * al
D_Notzero_k4_1:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	sub TMP2, TMP4				;sub low16(result), high16(result)
	sbc TMP3, TMP5
	brsh mulmod216_end_k4_1		;if low16(result) <= high16(result)
	adiw TMP3:TMP2, 1			;    inc low16(result) 
mulmod216_end_k4_1:
	mov p4h, TMP3
	mov p4l, TMP2

	pop bl
	pop bh
	pop k4l_1
	pop k4h_1

;/
;/ p1 XOR p3 --> i1
;/

	mov i1h, p1h
	mov i1l, p1l
	eor i1h, p3h
	eor i1l, p3l

;/
;/ Key Shift
;/

	lsr k8l
	ror k1h
	ror k1l
	ror k2h
	ror k2l
	ror k3h
	ror k3l
	ror k4h
	ror k4l
	ror k5h
	ror k5l
	ror k6h
	ror k6l
	ror k7h
	ror k7l
	ror k8h
	brcc keysh1
	ori k8l, $80
keysh1:


;/
;/ i1 x k5 --> i1
;/

	mul	i1h, k5h_1					; ah * bh
	movw	TMP3:TMP2, r1:r0
	brne	A_Notzero_k5_1		; Go on if mul nonzero

	mul	i1l, k5l_1
	movw	TMP1:TMP0, r1:r0
	brne	B_Notzero_k5_1		; Go on if mul nonzero

	mul	i1h, k5l_1					; ah * bl
	brne	C_Notzero_k5_1		; Go on if mul nonzero
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k5h_1, i1l					; bh * al
	brne	D_Notzero_k5_1

	add TMP0, k5l_1
	breq keyzerotest_k5_1
	add TMP1, k5h_1
	rjmp negresult_k5_1
keyzerotest_k5_1:
	add TMP1, k5h_1
	brne negresult_k5_1

	mov TMP0, i1l
	mov TMP1, i1h

negresult_k5_1:
	neg TMP0
	clr r0
	adc TMP1, r0
	neg TMP1
	adiw TMP1:TMP0, 1
	
	rjmp mulmod216_end_k5_1

A_Notzero_k5_1:
	mul	i1l, k5l_1					; al * bl
	movw	TMP1:TMP0, r1:r0

B_Notzero_k5_1:
	mul	i1h, k5l_1					; ah * bl
C_Notzero_k5_1:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k5h_1, i1l					; bh * al
D_Notzero_k5_1:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	sub TMP0, TMP2				;sub low16(result), high16(result)
	sbc TMP1, TMP3
	brsh mulmod216_end_k5_1		;if low16(result) <= high16(result)
	adiw TMP1:TMP0, 1			;    inc low16(result) 
mulmod216_end_k5_1:
	mov i1h, TMP1
	mov i1l, TMP0


;/
;/ p2 XOR p4 --> i2
;/

	mov i2h, p2h
	mov i2l, p2l
	eor i2h, p4h
	eor i2l, p4l

;/
;/ i2 + i1 --> i2
;/

	add i2l, i1l
	adc i2h, i1h

;/
;/ i2 x k6 --> i2
;/

	push i1h
	push i1l

	mov i1h, i2h
	mov i1l, i2l

	mul	i1h, k6h_1					; ah * bh
	movw	TMP3:TMP2, r1:r0
	brne	A_Notzero_k6_1		; Go on if mul nonzero

	mul	i1l, k6l_1
	movw	TMP1:TMP0, r1:r0
	brne	B_Notzero_k6_1		; Go on if mul nonzero

	mul	i1h, k6l_1					; ah * bl
	brne	C_Notzero_k6_1		; Go on if mul nonzero
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k6h_1, i1l					; bh * al
	brne	D_Notzero_k6_1

	add TMP0, k6l_1
	breq keyzerotest_k6_1
	add TMP1, k6h_1
	rjmp negresult_k6_1
keyzerotest_k6_1:
	add TMP1, k6h_1
	brne negresult_k6_1

	mov TMP0, i1l
	mov TMP1, i1h

negresult_k6_1:
	neg TMP0
	clr r0
	adc TMP1, r0
	neg TMP1
	adiw TMP1:TMP0, 1
	
	rjmp mulmod216_end_k6_1

A_Notzero_k6_1:
	mul	i1l, k6l_1					; al * bl
	movw	TMP1:TMP0, r1:r0

B_Notzero_k6_1:
	mul	i1h, k6l_1					; ah * bl
C_Notzero_k6_1:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k6h_1, i1l					; bh * al
D_Notzero_k6_1:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	sub TMP0, TMP2				;sub low16(result), high16(result)
	sbc TMP1, TMP3
	brsh mulmod216_end_k6_1		;if low16(result) <= high16(result)
	adiw TMP1:TMP0, 1			;    inc low16(result) 
mulmod216_end_k6_1:
	mov i2h, TMP1
	mov i2l, TMP0

	pop i1l
	pop i1h 

;/
;/ i1 + i2 --> i1
;/

	add i1l, i2l
	adc i1h, i2h

;/
;/ p1 XOR i2 --> p1
;/

	eor p1h, i2h
	eor p1l, i2l

;/
;/ p3 XOR i2 --> p3
;/

	eor p3h, i2h
	eor p3l, i2l

;/
;/ p2 XOR i1 --> p2
;/

	eor p2h, i1h
	eor p2l, i1l

;/
;/ p4 XOR i1 --> p4
;/

	eor p4h, i1h
	eor p4l, i1l


;--------------------------------------------------------------
;                               Round 2
;--------------------------------------------------------------


;/
;/ p1 x k1 --> p1
;/

	push k1h_2
	push k1l_2
	push bh
	push bl

	cp k1h_2, r0
	cpc k1l_2, r0
	brne prekeynotzero_k1_2

	mov TMP2, p1l
	mov TMP3, p1h
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k1_2

prekeynotzero_k1_2:
	clr r1
	inc r1
	clr uh
	clr um
	mov ul, r1
	clr bh
	mov bl, r1
	clr vh
	clr vm
	clr vl

pre_abcompare_k1_2:
	cp k1l_2, bl
	cpc k1h_2, bh
	brne pre_weiter_k1_2
	rjmp eukfinished_k1_2
pre_weiter_k1_2:
	bst k1l_2, 0			;if (A even)
	brts pre_anoteven_k1_2

	lsr k1h_2				;	A <- A/2
	ror k1l_2

	bst ul, 0			;	if (U uneven)
	brtc pre_u1even_k1_2

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

pre_u1even_k1_2:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp pre_abcompare_k1_2


pre_anoteven_k1_2:
	sub bl, k1l_2					;	B <- (B-A)/2
	sbc bh, k1h_2
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh
	
	add vl, r1			;	cause (V<0)
	adc vm, r0				;		V <- V+(2^16)+1
	adc vh, r1

	bst vl, 0					;	if (V uneven)
	brtc pre_veven_k1_2

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

pre_veven_k1_2:
	lsr vh						;	V <- V/2
	ror vm
	ror vl


abcompare_k1_2:
	cp k1l_2, bl
	cpc k1h_2, bh
	brne weiter_k1_2
	rjmp eukfinished_k1_2
weiter_k1_2:
	bst k1l_2, 0			;if (A even)
	brts anoteven_k1_2

	lsr k1h_2				;	A <- A/2
	ror k1l_2

	bst ul, 0			;	if (U uneven)
	brtc u1even_k1_2

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

u1even_k1_2:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k1_2


anoteven_k1_2:
	bst bl, 0			;if (B even)
	brts bnoteven_k1_2

	lsr bh				;	B <- B/2
	ror bl

	bst vl, 0					;	if (V uneven)
	brtc v1even_k1_2

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

v1even_k1_2:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k1_2

bnoteven_k1_2:
	cp k1h_2, bh			;if (A>B)
	brlo alowerthanb_k1_2
	brne ahigherthanb_k1_2
	cp k1l_2, bl
	brlo alowerthanb_k1_2
ahigherthanb_k1_2:
	sub k1l_2, bl			;	A <- (A-B)/2			
	sbc k1h_2, bh
	lsr k1h_2
	ror k1l_2

	sub ul, vl			;	U <- U-V
	sbc um, vm
	sbc uh, vh

	brpl upositive_k1_2		;	if (U<0)
	
	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

upositive_k1_2:
	bst ul, 0			;	if (U uneven)
	brtc ueven_k1_2

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

ueven_k1_2:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k1_2	


alowerthanb_k1_2:					;else
	sub bl, k1l_2					;	B <- (B-A)/2
	sbc bh, k1h_2
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh

	brpl vpositive_k1_2			;	if (V<0)
	
	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

vpositive_k1_2:
	bst vl, 0					;	if (V uneven)
	brtc veven_k1_2

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

veven_k1_2:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k1_2	

eukfinished_k1_2:

	mul	p1h, um					; ah * bh
	movw	TMP5:TMP4, r1:r0
	brne	A_Notzero_k1_2		; Go on if mul nonzero

	mul	p1l, ul
	movw	TMP3:TMP2, r1:r0
	brne	B_Notzero_k1_2		; Go on if mul nonzero

	mul	p1h, ul					; ah * bl
	brne	C_Notzero_k1_2		; Go on if mul nonzero
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p1l					; bh * al
	brne	D_Notzero_k1_2

	mov TMP2, ul
	mov TMP3, um
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k1_2

A_Notzero_k1_2:
	mul	p1l, ul					; al * bl
	movw	TMP3:TMP2, r1:r0

B_Notzero_k1_2:
	mul	p1h, ul					; ah * bl
C_Notzero_k1_2:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p1l					; bh * al
D_Notzero_k1_2:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	sub TMP2, TMP4				;sub low16(result), high16(result)
	sbc TMP3, TMP5
	brsh mulmod216_end_k1_2		;if low16(result) <= high16(result)
	adiw TMP3:TMP2, 1			;    inc low16(result) 
mulmod216_end_k1_2:
	mov p1h, TMP3
	mov p1l, TMP2

	pop bl
	pop bh
	pop k1l_2
	pop k1h_2
	
	
;/	
;/ p2 + k2 --> p2
;/

	sub p2l_g, k2l_2
	sbc p2h_g, k2h_2


;/
;/ p3 + k3 --> p3
;/

	sub p3l_g, k3l_2
	sbc p3h_g, k3h_2

;/
;/ p4 x k4 --> p4
;/

	push k4h_2
	push k4l_2
	push bh
	push bl

	cp k4h_2, r0
	cpc k4l_2, r0
	brne prekeynotzero_k4_2

	mov TMP2, p4l
	mov TMP3, p4h
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k4_2

prekeynotzero_k4_2:
	clr r1
	inc r1
	clr uh
	clr um
	mov ul, r1
	clr bh
	mov bl, r1
	clr vh
	clr vm
	clr vl

pre_abcompare_k4_2:
	cp k4l_2, bl
	cpc k4h_2, bh
	brne pre_weiter_k4_2
	rjmp eukfinished_k4_2
pre_weiter_k4_2:
	bst k4l_2, 0			;if (A even)
	brts pre_anoteven_k4_2

	lsr k4h_2				;	A <- A/2
	ror k4l_2

	bst ul, 0			;	if (U uneven)
	brtc pre_u1even_k4_2

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

pre_u1even_k4_2:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp pre_abcompare_k4_2


pre_anoteven_k4_2:
	sub bl, k4l_2					;	B <- (B-A)/2
	sbc bh, k4h_2
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh
	
	add vl, r1			;	cause (V<0)
	adc vm, r0				;		V <- V+(2^16)+1
	adc vh, r1

	bst vl, 0					;	if (V uneven)
	brtc pre_veven_k4_2

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

pre_veven_k4_2:
	lsr vh						;	V <- V/2
	ror vm
	ror vl


abcompare_k4_2:
	cp k4l_2, bl
	cpc k4h_2, bh
	brne weiter_k4_2
	rjmp eukfinished_k4_2
weiter_k4_2:
	bst k4l_2, 0			;if (A even)
	brts anoteven_k4_2

	lsr k4h_2				;	A <- A/2
	ror k4l_2

	bst ul, 0			;	if (U uneven)
	brtc u1even_k4_2

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

u1even_k4_2:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k4_2


anoteven_k4_2:
	bst bl, 0			;if (B even)
	brts bnoteven_k4_2

	lsr bh				;	B <- B/2
	ror bl

	bst vl, 0					;	if (V uneven)
	brtc v1even_k4_2

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

v1even_k4_2:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k4_2

bnoteven_k4_2:
	cp k4h_2, bh			;if (A>B)
	brlo alowerthanb_k4_2
	brne ahigherthanb_k4_2
	cp k4l_2, bl
	brlo alowerthanb_k4_2
ahigherthanb_k4_2:
	sub k4l_2, bl			;	A <- (A-B)/2			
	sbc k4h_2, bh
	lsr k4h_2
	ror k4l_2

	sub ul, vl			;	U <- U-V
	sbc um, vm
	sbc uh, vh

	brpl upositive_k4_2		;	if (U<0)
	
	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

upositive_k4_2:
	bst ul, 0			;	if (U uneven)
	brtc ueven_k4_2

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

ueven_k4_2:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k4_2	


alowerthanb_k4_2:					;else
	sub bl, k4l_2					;	B <- (B-A)/2
	sbc bh, k4h_2
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh

	brpl vpositive_k4_2			;	if (V<0)
	
	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

vpositive_k4_2:
	bst vl, 0					;	if (V uneven)
	brtc veven_k4_2

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

veven_k4_2:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k4_2	

eukfinished_k4_2:

	mul	p4h, um					; ah * bh
	movw	TMP5:TMP4, r1:r0
	brne	A_Notzero_k4_2		; Go on if mul nonzero

	mul	p4l, ul
	movw	TMP3:TMP2, r1:r0
	brne	B_Notzero_k4_2		; Go on if mul nonzero

	mul	p4h, ul					; ah * bl
	brne	C_Notzero_k4_2		; Go on if mul nonzero
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p4l					; bh * al
	brne	D_Notzero_k4_2

	mov TMP2, ul
	mov TMP3, um
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k4_2

A_Notzero_k4_2:
	mul	p4l, ul					; al * bl
	movw	TMP3:TMP2, r1:r0

B_Notzero_k4_2:
	mul	p4h, ul					; ah * bl
C_Notzero_k4_2:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p4l					; bh * al
D_Notzero_k4_2:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	sub TMP2, TMP4				;sub low16(result), high16(result)
	sbc TMP3, TMP5
	brsh mulmod216_end_k4_2		;if low16(result) <= high16(result)
	adiw TMP3:TMP2, 1			;    inc low16(result) 
mulmod216_end_k4_2:
	mov p4h, TMP3
	mov p4l, TMP2

	pop bl
	pop bh
	pop k4l_2
	pop k4h_2


;/
;/ p1 XOR p3 --> i1
;/

	mov i1h, p1h
	mov i1l, p1l
	eor i1h, p3h_g
	eor i1l, p3l_g

;/
;/ i1 x k5 --> i1
;/

	mul	i1h, k5h_2					; ah * bh
	movw	TMP3:TMP2, r1:r0
	brne	A_Notzero_k5_2		; Go on if mul nonzero

	mul	i1l, k5l_2
	movw	TMP1:TMP0, r1:r0
	brne	B_Notzero_k5_2		; Go on if mul nonzero

	mul	i1h, k5l_2					; ah * bl
	brne	C_Notzero_k5_2		; Go on if mul nonzero
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k5h_2, i1l					; bh * al
	brne	D_Notzero_k5_2

	add TMP0, k5l_2
	breq keyzerotest_k5_2
	add TMP1, k5h_2
	rjmp negresult_k5_2
keyzerotest_k5_2:
	add TMP1, k5h_2
	brne negresult_k5_2

	mov TMP0, i1l
	mov TMP1, i1h

negresult_k5_2:
	neg TMP0
	clr r0
	adc TMP1, r0
	neg TMP1
	adiw TMP1:TMP0, 1
	
	rjmp mulmod216_end_k5_2

A_Notzero_k5_2:
	mul	i1l, k5l_2					; al * bl
	movw	TMP1:TMP0, r1:r0

B_Notzero_k5_2:
	mul	i1h, k5l_2					; ah * bl
C_Notzero_k5_2:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k5h_2, i1l					; bh * al
D_Notzero_k5_2:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	sub TMP0, TMP2				;sub low16(result), high16(result)
	sbc TMP1, TMP3
	brsh mulmod216_end_k5_2		;if low16(result) <= high16(result)
	adiw TMP1:TMP0, 1			;    inc low16(result) 
mulmod216_end_k5_2:
	mov i1h, TMP1
	mov i1l, TMP0


;/
;/ p2 XOR p4 --> i2
;/

	mov i2h, p2h_g
	mov i2l, p2l_g
	eor i2h, p4h
	eor i2l, p4l

;/
;/ i2 + i1 --> i2
;/

	add i2l, i1l
	adc i2h, i1h

;/
;/ i2 x k6 --> i2
;/

	push i1h
	push i1l

	mov i1h, i2h
	mov i1l, i2l

	mul	i1h, k6h_2					; ah * bh
	movw	TMP3:TMP2, r1:r0
	brne	A_Notzero_k6_2		; Go on if mul nonzero

	mul	i1l, k6l_2
	movw	TMP1:TMP0, r1:r0
	brne	B_Notzero_k6_2		; Go on if mul nonzero

	mul	i1h, k6l_2					; ah * bl
	brne	C_Notzero_k6_2		; Go on if mul nonzero
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k6h_2, i1l					; bh * al
	brne	D_Notzero_k6_2

	add TMP0, k6l_2
	breq keyzerotest_k6_2
	add TMP1, k6h_2
	rjmp negresult_k6_2
keyzerotest_k6_2:
	add TMP1, k6h_2
	brne negresult_k6_2

	mov TMP0, i1l
	mov TMP1, i1h

negresult_k6_2:
	neg TMP0
	clr r0
	adc TMP1, r0
	neg TMP1
	adiw TMP1:TMP0, 1
	
	rjmp mulmod216_end_k6_2

A_Notzero_k6_2:
	mul	i1l, k6l_2					; al * bl
	movw	TMP1:TMP0, r1:r0

B_Notzero_k6_2:
	mul	i1h, k6l_2					; ah * bl
C_Notzero_k6_2:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k6h_2, i1l					; bh * al
D_Notzero_k6_2:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	sub TMP0, TMP2				;sub low16(result), high16(result)
	sbc TMP1, TMP3
	brsh mulmod216_end_k6_2		;if low16(result) <= high16(result)
	adiw TMP1:TMP0, 1			;    inc low16(result) 
mulmod216_end_k6_2:
	mov i2h, TMP1
	mov i2l, TMP0

	pop i1l
	pop i1h 

;/
;/ i1 + i2 --> i1
;/

	add i1l, i2l
	adc i1h, i2h

;/
;/ p1 XOR i2 --> p1
;/

	eor p1h, i2h
	eor p1l, i2l

;/
;/ p3 XOR i2 --> p3
;/

	eor p3h_g, i2h
	eor p3l_g, i2l

;/
;/ p2 XOR i1 --> p2
;/

	eor p2h_g, i1h
	eor p2l_g, i1l

;/
;/ p4 XOR i1 --> p4
;/

	eor p4h, i1h
	eor p4l, i1l


;--------------------------------------------------------------
;                               Round 3
;--------------------------------------------------------------

;/
;/ Key Shift
;/

	lsr k8l
	ror k1h
	ror k1l
	ror k2h
	ror k2l
	ror k3h
	ror k3l
	ror k4h
	ror k4l
	ror k5h
	ror k5l
	ror k6h
	ror k6l
	ror k7h
	ror k7l
	ror k8h
	brcc keysh2
	ori k8l, $80
keysh2:


;/
;/ p1 x k1 --> p1
;/

	push k1h_3
	push k1l_3
	push bh
	push bl

	cp k1h_3, r0
	cpc k1l_3, r0
	brne prekeynotzero_k1_3

	mov TMP2, p1l
	mov TMP3, p1h
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k1_3

prekeynotzero_k1_3:
	clr r1
	inc r1
	clr uh
	clr um
	mov ul, r1
	clr bh
	mov bl, r1
	clr vh
	clr vm
	clr vl

pre_abcompare_k1_3:
	cp k1l_3, bl
	cpc k1h_3, bh
	brne pre_weiter_k1_3
	rjmp eukfinished_k1_3
pre_weiter_k1_3:
	bst k1l_3, 0			;if (A even)
	brts pre_anoteven_k1_3

	lsr k1h_3				;	A <- A/2
	ror k1l_3

	bst ul, 0			;	if (U uneven)
	brtc pre_u1even_k1_3

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

pre_u1even_k1_3:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp pre_abcompare_k1_3


pre_anoteven_k1_3:
	sub bl, k1l_3					;	B <- (B-A)/2
	sbc bh, k1h_3
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh
	
	add vl, r1			;	cause (V<0)
	adc vm, r0				;		V <- V+(2^16)+1
	adc vh, r1

	bst vl, 0					;	if (V uneven)
	brtc pre_veven_k1_3

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

pre_veven_k1_3:
	lsr vh						;	V <- V/2
	ror vm
	ror vl


abcompare_k1_3:
	cp k1l_3, bl
	cpc k1h_3, bh
	brne weiter_k1_3
	rjmp eukfinished_k1_3
weiter_k1_3:
	bst k1l_3, 0			;if (A even)
	brts anoteven_k1_3

	lsr k1h_3				;	A <- A/2
	ror k1l_3

	bst ul, 0			;	if (U uneven)
	brtc u1even_k1_3

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

u1even_k1_3:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k1_3


anoteven_k1_3:
	bst bl, 0			;if (B even)
	brts bnoteven_k1_3

	lsr bh				;	B <- B/2
	ror bl

	bst vl, 0					;	if (V uneven)
	brtc v1even_k1_3

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

v1even_k1_3:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k1_3

bnoteven_k1_3:
	cp k1h_3, bh			;if (A>B)
	brlo alowerthanb_k1_3
	brne ahigherthanb_k1_3
	cp k1l_3, bl
	brlo alowerthanb_k1_3
ahigherthanb_k1_3:
	sub k1l_3, bl			;	A <- (A-B)/2			
	sbc k1h_3, bh
	lsr k1h_3
	ror k1l_3

	sub ul, vl			;	U <- U-V
	sbc um, vm
	sbc uh, vh

	brpl upositive_k1_3		;	if (U<0)
	
	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

upositive_k1_3:
	bst ul, 0			;	if (U uneven)
	brtc ueven_k1_3

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

ueven_k1_3:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k1_3	


alowerthanb_k1_3:					;else
	sub bl, k1l_3					;	B <- (B-A)/2
	sbc bh, k1h_3
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh

	brpl vpositive_k1_3			;	if (V<0)
	
	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

vpositive_k1_3:
	bst vl, 0					;	if (V uneven)
	brtc veven_k1_3

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

veven_k1_3:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k1_3	

eukfinished_k1_3:

	mul	p1h, um					; ah * bh
	movw	TMP5:TMP4, r1:r0
	brne	A_Notzero_k1_3		; Go on if mul nonzero

	mul	p1l, ul
	movw	TMP3:TMP2, r1:r0
	brne	B_Notzero_k1_3		; Go on if mul nonzero

	mul	p1h, ul					; ah * bl
	brne	C_Notzero_k1_3		; Go on if mul nonzero
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p1l					; bh * al
	brne	D_Notzero_k1_3

	mov TMP2, ul
	mov TMP3, um
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k1_3

A_Notzero_k1_3:
	mul	p1l, ul					; al * bl
	movw	TMP3:TMP2, r1:r0

B_Notzero_k1_3:
	mul	p1h, ul					; ah * bl
C_Notzero_k1_3:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p1l					; bh * al
D_Notzero_k1_3:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	sub TMP2, TMP4				;sub low16(result), high16(result)
	sbc TMP3, TMP5
	brsh mulmod216_end_k1_3		;if low16(result) <= high16(result)
	adiw TMP3:TMP2, 1			;    inc low16(result) 
mulmod216_end_k1_3:
	mov p1h, TMP3
	mov p1l, TMP2

	pop bl
	pop bh
	pop k1l_3
	pop k1h_3
	

;/	
;/ p2 + k2 --> p2
;/

	sub p2l, k2l_3
	sbc p2h, k2h_3


;/
;/ p3 + k3 --> p3
;/

	sub p3l, k3l_3
	sbc p3h, k3h_3

;/
;/ p4 x k4 --> p4
;/

	push k4h_3
	push k4l_3
	push bh
	push bl

	cp k4h_3, r0
	cpc k4l_3, r0
	brne prekeynotzero_k4_3

	mov TMP2, p4l
	mov TMP3, p4h
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k4_3

prekeynotzero_k4_3:
	clr r1
	inc r1
	clr uh
	clr um
	mov ul, r1
	clr bh
	mov bl, r1
	clr vh
	clr vm
	clr vl

pre_abcompare_k4_3:
	cp k4l_3, bl
	cpc k4h_3, bh
	brne pre_weiter_k4_3
	rjmp eukfinished_k4_3
pre_weiter_k4_3:
	bst k4l_3, 0			;if (A even)
	brts pre_anoteven_k4_3

	lsr k4h_3				;	A <- A/2
	ror k4l_3

	bst ul, 0			;	if (U uneven)
	brtc pre_u1even_k4_3

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

pre_u1even_k4_3:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp pre_abcompare_k4_3


pre_anoteven_k4_3:
	sub bl, k4l_3					;	B <- (B-A)/2
	sbc bh, k4h_3
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh
	
	add vl, r1			;	cause (V<0)
	adc vm, r0				;		V <- V+(2^16)+1
	adc vh, r1

	bst vl, 0					;	if (V uneven)
	brtc pre_veven_k4_3

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

pre_veven_k4_3:
	lsr vh						;	V <- V/2
	ror vm
	ror vl


abcompare_k4_3:
	cp k4l_3, bl
	cpc k4h_3, bh
	brne weiter_k4_3
	rjmp eukfinished_k4_3
weiter_k4_3:
	bst k4l_3, 0			;if (A even)
	brts anoteven_k4_3

	lsr k4h_3				;	A <- A/2
	ror k4l_3

	bst ul, 0			;	if (U uneven)
	brtc u1even_k4_3

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

u1even_k4_3:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k4_3


anoteven_k4_3:
	bst bl, 0			;if (B even)
	brts bnoteven_k4_3

	lsr bh				;	B <- B/2
	ror bl

	bst vl, 0					;	if (V uneven)
	brtc v1even_k4_3

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

v1even_k4_3:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k4_3

bnoteven_k4_3:
	cp k4h_3, bh			;if (A>B)
	brlo alowerthanb_k4_3
	brne ahigherthanb_k4_3
	cp k4l_3, bl
	brlo alowerthanb_k4_3
ahigherthanb_k4_3:
	sub k4l_3, bl			;	A <- (A-B)/2			
	sbc k4h_3, bh
	lsr k4h_3
	ror k4l_3

	sub ul, vl			;	U <- U-V
	sbc um, vm
	sbc uh, vh

	brpl upositive_k4_3		;	if (U<0)
	
	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

upositive_k4_3:
	bst ul, 0			;	if (U uneven)
	brtc ueven_k4_3

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

ueven_k4_3:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k4_3	


alowerthanb_k4_3:					;else
	sub bl, k4l_3					;	B <- (B-A)/2
	sbc bh, k4h_3
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh

	brpl vpositive_k4_3			;	if (V<0)
	
	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

vpositive_k4_3:
	bst vl, 0					;	if (V uneven)
	brtc veven_k4_3

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

veven_k4_3:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k4_3	

eukfinished_k4_3:

	mul	p4h, um					; ah * bh
	movw	TMP5:TMP4, r1:r0
	brne	A_Notzero_k4_3		; Go on if mul nonzero

	mul	p4l, ul
	movw	TMP3:TMP2, r1:r0
	brne	B_Notzero_k4_3		; Go on if mul nonzero

	mul	p4h, ul					; ah * bl
	brne	C_Notzero_k4_3		; Go on if mul nonzero
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p4l					; bh * al
	brne	D_Notzero_k4_3

	mov TMP2, ul
	mov TMP3, um
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k4_3

A_Notzero_k4_3:
	mul	p4l, ul					; al * bl
	movw	TMP3:TMP2, r1:r0

B_Notzero_k4_3:
	mul	p4h, ul					; ah * bl
C_Notzero_k4_3:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p4l					; bh * al
D_Notzero_k4_3:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	sub TMP2, TMP4				;sub low16(result), high16(result)
	sbc TMP3, TMP5
	brsh mulmod216_end_k4_3		;if low16(result) <= high16(result)
	adiw TMP3:TMP2, 1			;    inc low16(result) 
mulmod216_end_k4_3:
	mov p4h, TMP3
	mov p4l, TMP2

	pop bl
	pop bh
	pop k4l_3
	pop k4h_3


;/
;/ p1 XOR p3 --> i1
;/

	mov i1h, p1h
	mov i1l, p1l
	eor i1h, p3h
	eor i1l, p3l

;/
;/ i1 x k5 --> i1
;/

	mul	i1h, k5h_3					; ah * bh
	movw	TMP3:TMP2, r1:r0
	brne	A_Notzero_k5_3		; Go on if mul nonzero

	mul	i1l, k5l_3
	movw	TMP1:TMP0, r1:r0
	brne	B_Notzero_k5_3		; Go on if mul nonzero

	mul	i1h, k5l_3					; ah * bl
	brne	C_Notzero_k5_3		; Go on if mul nonzero
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k5h_3, i1l					; bh * al
	brne	D_Notzero_k5_3

	add TMP0, k5l_3
	breq keyzerotest_k5_3
	add TMP1, k5h_3
	rjmp negresult_k5_3
keyzerotest_k5_3:
	add TMP1, k5h_3
	brne negresult_k5_3

	mov TMP0, i1l
	mov TMP1, i1h

negresult_k5_3:
	neg TMP0
	clr r0
	adc TMP1, r0
	neg TMP1
	adiw TMP1:TMP0, 1
	
	rjmp mulmod216_end_k5_3

A_Notzero_k5_3:
	mul	i1l, k5l_3					; al * bl
	movw	TMP1:TMP0, r1:r0

B_Notzero_k5_3:
	mul	i1h, k5l_3					; ah * bl
C_Notzero_k5_3:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k5h_3, i1l					; bh * al
D_Notzero_k5_3:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	sub TMP0, TMP2				;sub low16(result), high16(result)
	sbc TMP1, TMP3
	brsh mulmod216_end_k5_3		;if low16(result) <= high16(result)
	adiw TMP1:TMP0, 1			;    inc low16(result) 
mulmod216_end_k5_3:
	mov i1h, TMP1
	mov i1l, TMP0


;/
;/ p2 XOR p4 --> i2
;/

	mov i2h, p2h
	mov i2l, p2l
	eor i2h, p4h
	eor i2l, p4l

;/
;/ i2 + i1 --> i2
;/

	add i2l, i1l
	adc i2h, i1h

;/
;/ i2 x k6 --> i2
;/

	push i1h
	push i1l

	mov i1h, i2h
	mov i1l, i2l

	mul	i1h, k6h_3					; ah * bh
	movw	TMP3:TMP2, r1:r0
	brne	A_Notzero_k6_3		; Go on if mul nonzero

	mul	i1l, k6l_3
	movw	TMP1:TMP0, r1:r0
	brne	B_Notzero_k6_3		; Go on if mul nonzero

	mul	i1h, k6l_3					; ah * bl
	brne	C_Notzero_k6_3		; Go on if mul nonzero
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k6h_3, i1l					; bh * al
	brne	D_Notzero_k6_3

	add TMP0, k6l_3
	breq keyzerotest_k6_3
	add TMP1, k6h_3
	rjmp negresult_k6_3
keyzerotest_k6_3:
	add TMP1, k6h_3
	brne negresult_k6_3

	mov TMP0, i1l
	mov TMP1, i1h

negresult_k6_3:
	neg TMP0
	clr r0
	adc TMP1, r0
	neg TMP1
	adiw TMP1:TMP0, 1
	
	rjmp mulmod216_end_k6_3

A_Notzero_k6_3:
	mul	i1l, k6l_3					; al * bl
	movw	TMP1:TMP0, r1:r0

B_Notzero_k6_3:
	mul	i1h, k6l_3					; ah * bl
C_Notzero_k6_3:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k6h_3, i1l					; bh * al
D_Notzero_k6_3:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	sub TMP0, TMP2				;sub low16(result), high16(result)
	sbc TMP1, TMP3
	brsh mulmod216_end_k6_3		;if low16(result) <= high16(result)
	adiw TMP1:TMP0, 1			;    inc low16(result)
mulmod216_end_k6_3:
	mov i2h, TMP1
	mov i2l, TMP0

	pop i1l
	pop i1h 

;/
;/ i1 + i2 --> i1
;/

	add i1l, i2l
	adc i1h, i2h

;/
;/ p1 XOR i2 --> p1
;/

	eor p1h, i2h
	eor p1l, i2l

;/
;/ p3 XOR i2 --> p3
;/

	eor p3h, i2h
	eor p3l, i2l

;/
;/ p2 XOR i1 --> p2
;/

	eor p2h, i1h
	eor p2l, i1l

;/
;/ p4 XOR i1 --> p4
;/

	eor p4h, i1h
	eor p4l, i1l


;--------------------------------------------------------------
;                               Round 4
;--------------------------------------------------------------


	
;/	
;/ p2 + k2 --> p2
;/

	sub p2l_g, k2l_4
	sbc p2h_g, k2h_4

;/
;/ p4 x k4 --> p4
;/

	push k4h_4
	push k4l_4
	push bh
	push bl

	cp k4h_4, r0
	cpc k4l_4, r0
	brne prekeynotzero_k4_4

	mov TMP2, p4l
	mov TMP3, p4h
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k4_4

prekeynotzero_k4_4:
	clr r1
	inc r1
	clr uh
	clr um
	mov ul, r1
	clr bh
	mov bl, r1
	clr vh
	clr vm
	clr vl

pre_abcompare_k4_4:
	cp k4l_4, bl
	cpc k4h_4, bh
	brne pre_weiter_k4_4
	rjmp eukfinished_k4_4
pre_weiter_k4_4:
	bst k4l_4, 0			;if (A even)
	brts pre_anoteven_k4_4

	lsr k4h_4				;	A <- A/2
	ror k4l_4

	bst ul, 0			;	if (U uneven)
	brtc pre_u1even_k4_4

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

pre_u1even_k4_4:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp pre_abcompare_k4_4


pre_anoteven_k4_4:
	sub bl, k4l_4					;	B <- (B-A)/2
	sbc bh, k4h_4
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh
	
	add vl, r1			;	cause (V<0)
	adc vm, r0				;		V <- V+(2^16)+1
	adc vh, r1

	bst vl, 0					;	if (V uneven)
	brtc pre_veven_k4_4

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

pre_veven_k4_4:
	lsr vh						;	V <- V/2
	ror vm
	ror vl


abcompare_k4_4:
	cp k4l_4, bl
	cpc k4h_4, bh
	brne weiter_k4_4
	rjmp eukfinished_k4_4
weiter_k4_4:
	bst k4l_4, 0			;if (A even)
	brts anoteven_k4_4

	lsr k4h_4				;	A <- A/2
	ror k4l_4

	bst ul, 0			;	if (U uneven)
	brtc u1even_k4_4

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

u1even_k4_4:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k4_4


anoteven_k4_4:
	bst bl, 0			;if (B even)
	brts bnoteven_k4_4

	lsr bh				;	B <- B/2
	ror bl

	bst vl, 0					;	if (V uneven)
	brtc v1even_k4_4

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

v1even_k4_4:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k4_4

bnoteven_k4_4:
	cp k4h_4, bh			;if (A>B)
	brlo alowerthanb_k4_4
	brne ahigherthanb_k4_4
	cp k4l_4, bl
	brlo alowerthanb_k4_4
ahigherthanb_k4_4:
	sub k4l_4, bl			;	A <- (A-B)/2			
	sbc k4h_4, bh
	lsr k4h_4
	ror k4l_4

	sub ul, vl			;	U <- U-V
	sbc um, vm
	sbc uh, vh

	brpl upositive_k4_4		;	if (U<0)
	
	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

upositive_k4_4:
	bst ul, 0			;	if (U uneven)
	brtc ueven_k4_4

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

ueven_k4_4:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k4_4	


alowerthanb_k4_4:					;else
	sub bl, k4l_4					;	B <- (B-A)/2
	sbc bh, k4h_4
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh

	brpl vpositive_k4_4			;	if (V<0)
	
	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

vpositive_k4_4:
	bst vl, 0					;	if (V uneven)
	brtc veven_k4_4

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

veven_k4_4:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k4_4	

eukfinished_k4_4:

	mul	p4h, um					; ah * bh
	movw	TMP5:TMP4, r1:r0
	brne	A_Notzero_k4_4		; Go on if mul nonzero

	mul	p4l, ul
	movw	TMP3:TMP2, r1:r0
	brne	B_Notzero_k4_4		; Go on if mul nonzero

	mul	p4h, ul					; ah * bl
	brne	C_Notzero_k4_4		; Go on if mul nonzero
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p4l					; bh * al
	brne	D_Notzero_k4_4

	mov TMP2, ul
	mov TMP3, um
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k4_4

A_Notzero_k4_4:
	mul	p4l, ul					; al * bl
	movw	TMP3:TMP2, r1:r0

B_Notzero_k4_4:
	mul	p4h, ul					; ah * bl
C_Notzero_k4_4:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p4l					; bh * al
D_Notzero_k4_4:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	sub TMP2, TMP4				;sub low16(result), high16(result)
	sbc TMP3, TMP5
	brsh mulmod216_end_k4_4		;if low16(result) <= high16(result)
	adiw TMP3:TMP2, 1			;    inc low16(result) 
mulmod216_end_k4_4:
	mov p4h, TMP3
	mov p4l, TMP2

	pop bl
	pop bh
	pop k4l_4
	pop k4h_4

;/
;/ Key Shift
;/

	lsr k8l
	ror k1h
	ror k1l
	ror k2h
	ror k2l
	ror k3h
	ror k3l
	ror k4h
	ror k4l
	ror k5h
	ror k5l
	ror k6h
	ror k6l
	ror k7h
	ror k7l
	ror k8h
	brcc keysh3
	ori k8l, $80
keysh3:


;/
;/ p3 + k3 --> p3
;/

	sub p3l_g, k3l_4
	sbc p3h_g, k3h_4


;/
;/ p1 x k1 --> p1
;/

	push k1h_4
	push k1l_4
	push bh
	push bl

	cp k1h_4, r0
	cpc k1l_4, r0
	brne prekeynotzero_k1_4

	mov TMP2, p1l
	mov TMP3, p1h
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k1_4

prekeynotzero_k1_4:
	clr r1
	inc r1
	clr uh
	clr um
	mov ul, r1
	clr bh
	mov bl, r1
	clr vh
	clr vm
	clr vl

pre_abcompare_k1_4:
	cp k1l_4, bl
	cpc k1h_4, bh
	brne pre_weiter_k1_4
	rjmp eukfinished_k1_4
pre_weiter_k1_4:
	bst k1l_4, 0			;if (A even)
	brts pre_anoteven_k1_4

	lsr k1h_4				;	A <- A/2
	ror k1l_4

	bst ul, 0			;	if (U uneven)
	brtc pre_u1even_k1_4

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

pre_u1even_k1_4:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp pre_abcompare_k1_4


pre_anoteven_k1_4:
	sub bl, k1l_4					;	B <- (B-A)/2
	sbc bh, k1h_4
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh
	
	add vl, r1			;	cause (V<0)
	adc vm, r0				;		V <- V+(2^16)+1
	adc vh, r1

	bst vl, 0					;	if (V uneven)
	brtc pre_veven_k1_4

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

pre_veven_k1_4:
	lsr vh						;	V <- V/2
	ror vm
	ror vl


abcompare_k1_4:
	cp k1l_4, bl
	cpc k1h_4, bh
	brne weiter_k1_4
	rjmp eukfinished_k1_4
weiter_k1_4:
	bst k1l_4, 0			;if (A even)
	brts anoteven_k1_4

	lsr k1h_4				;	A <- A/2
	ror k1l_4

	bst ul, 0			;	if (U uneven)
	brtc u1even_k1_4

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

u1even_k1_4:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k1_4


anoteven_k1_4:
	bst bl, 0			;if (B even)
	brts bnoteven_k1_4

	lsr bh				;	B <- B/2
	ror bl

	bst vl, 0					;	if (V uneven)
	brtc v1even_k1_4

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

v1even_k1_4:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k1_4

bnoteven_k1_4:
	cp k1h_4, bh			;if (A>B)
	brlo alowerthanb_k1_4
	brne ahigherthanb_k1_4
	cp k1l_4, bl
	brlo alowerthanb_k1_4
ahigherthanb_k1_4:
	sub k1l_4, bl			;	A <- (A-B)/2			
	sbc k1h_4, bh
	lsr k1h_4
	ror k1l_4

	sub ul, vl			;	U <- U-V
	sbc um, vm
	sbc uh, vh

	brpl upositive_k1_4		;	if (U<0)
	
	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

upositive_k1_4:
	bst ul, 0			;	if (U uneven)
	brtc ueven_k1_4

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

ueven_k1_4:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k1_4	


alowerthanb_k1_4:					;else
	sub bl, k1l_4					;	B <- (B-A)/2
	sbc bh, k1h_4
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh

	brpl vpositive_k1_4			;	if (V<0)
	
	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

vpositive_k1_4:
	bst vl, 0					;	if (V uneven)
	brtc veven_k1_4

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

veven_k1_4:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k1_4	

eukfinished_k1_4:

	mul	p1h, um					; ah * bh
	movw	TMP5:TMP4, r1:r0
	brne	A_Notzero_k1_4		; Go on if mul nonzero

	mul	p1l, ul
	movw	TMP3:TMP2, r1:r0
	brne	B_Notzero_k1_4		; Go on if mul nonzero

	mul	p1h, ul					; ah * bl
	brne	C_Notzero_k1_4		; Go on if mul nonzero
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p1l					; bh * al
	brne	D_Notzero_k1_4

	mov TMP2, ul
	mov TMP3, um
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k1_4

A_Notzero_k1_4:
	mul	p1l, ul					; al * bl
	movw	TMP3:TMP2, r1:r0

B_Notzero_k1_4:
	mul	p1h, ul					; ah * bl
C_Notzero_k1_4:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p1l					; bh * al
D_Notzero_k1_4:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	sub TMP2, TMP4				;sub low16(result), high16(result)
	sbc TMP3, TMP5
	brsh mulmod216_end_k1_4		;if low16(result) <= high16(result)
	adiw TMP3:TMP2, 1			;    inc low16(result) 
mulmod216_end_k1_4:
	mov p1h, TMP3
	mov p1l, TMP2

	pop bl
	pop bh
	pop k1l_4
	pop k1h_4
	

;/
;/ p1 XOR p3 --> i1
;/

	mov i1h, p1h
	mov i1l, p1l
	eor i1h, p3h_g
	eor i1l, p3l_g

;/
;/ i1 x k5 --> i1
;/

	mul	i1h, k5h_4					; ah * bh
	movw	TMP3:TMP2, r1:r0
	brne	A_Notzero_k5_4		; Go on if mul nonzero

	mul	i1l, k5l_4
	movw	TMP1:TMP0, r1:r0
	brne	B_Notzero_k5_4		; Go on if mul nonzero

	mul	i1h, k5l_4					; ah * bl
	brne	C_Notzero_k5_4		; Go on if mul nonzero
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k5h_4, i1l					; bh * al
	brne	D_Notzero_k5_4

	add TMP0, k5l_4
	breq keyzerotest_k5_4
	add TMP1, k5h_4
	rjmp negresult_k5_4
keyzerotest_k5_4:
	add TMP1, k5h_4
	brne negresult_k5_4

	mov TMP0, i1l
	mov TMP1, i1h

negresult_k5_4:
	neg TMP0
	clr r0
	adc TMP1, r0
	neg TMP1
	adiw TMP1:TMP0, 1
	
	rjmp mulmod216_end_k5_4

A_Notzero_k5_4:
	mul	i1l, k5l_4					; al * bl
	movw	TMP1:TMP0, r1:r0

B_Notzero_k5_4:
	mul	i1h, k5l_4					; ah * bl
C_Notzero_k5_4:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k5h_4, i1l					; bh * al
D_Notzero_k5_4:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	sub TMP0, TMP2				;sub low16(result), high16(result)
	sbc TMP1, TMP3
	brsh mulmod216_end_k5_4		;if low16(result) <= high16(result)
	adiw TMP1:TMP0, 1			;    inc low16(result) 
mulmod216_end_k5_4:
	mov i1h, TMP1
	mov i1l, TMP0


;/
;/ p2 XOR p4 --> i2
;/

	mov i2h, p2h_g
	mov i2l, p2l_g
	eor i2h, p4h
	eor i2l, p4l

;/
;/ i2 + i1 --> i2
;/

	add i2l, i1l
	adc i2h, i1h

;/
;/ i2 x k6 --> i2
;/

	push i1h
	push i1l

	mov i1h, i2h
	mov i1l, i2l

	mul	i1h, k6h_4					; ah * bh
	movw	TMP3:TMP2, r1:r0
	brne	A_Notzero_k6_4		; Go on if mul nonzero

	mul	i1l, k6l_4
	movw	TMP1:TMP0, r1:r0
	brne	B_Notzero_k6_4		; Go on if mul nonzero

	mul	i1h, k6l_4					; ah * bl
	brne	C_Notzero_k6_4		; Go on if mul nonzero
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k6h_4, i1l					; bh * al
	brne	D_Notzero_k6_4

	add TMP0, k6l_4
	breq keyzerotest_k6_4
	add TMP1, k6h_4
	rjmp negresult_k6_4
keyzerotest_k6_4:
	add TMP1, k6h_4
	brne negresult_k6_4

	mov TMP0, i1l
	mov TMP1, i1h

negresult_k6_4:
	neg TMP0
	clr r0
	adc TMP1, r0
	neg TMP1
	adiw TMP1:TMP0, 1
	
	rjmp mulmod216_end_k6_4

A_Notzero_k6_4:
	mul	i1l, k6l_4					; al * bl
	movw	TMP1:TMP0, r1:r0

B_Notzero_k6_4:
	mul	i1h, k6l_4					; ah * bl
C_Notzero_k6_4:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k6h_4, i1l					; bh * al
D_Notzero_k6_4:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	sub TMP0, TMP2				;sub low16(result), high16(result)
	sbc TMP1, TMP3
	brsh mulmod216_end_k6_4		;if low16(result) <= high16(result)
	adiw TMP1:TMP0, 1			;    inc low16(result) 
mulmod216_end_k6_4:
	mov i2h, TMP1
	mov i2l, TMP0

	pop i1l
	pop i1h 

;/
;/ i1 + i2 --> i1
;/

	add i1l, i2l
	adc i1h, i2h

;/
;/ p1 XOR i2 --> p1
;/

	eor p1h, i2h
	eor p1l, i2l

;/
;/ p3 XOR i2 --> p3
;/

	eor p3h_g, i2h
	eor p3l_g, i2l

;/
;/ p2 XOR i1 --> p2
;/

	eor p2h_g, i1h
	eor p2l_g, i1l

;/
;/ p4 XOR i1 --> p4
;/

	eor p4h, i1h
	eor p4l, i1l


;--------------------------------------------------------------
;                               Round 5
;--------------------------------------------------------------



;/
;/ p1 x k1 --> p1
;/

	push k1h_5
	push k1l_5
	push bh
	push bl

	cp k1h_5, r0
	cpc k1l_5, r0
	brne prekeynotzero_k1_5

	mov TMP2, p1l
	mov TMP3, p1h
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k1_5

prekeynotzero_k1_5:
	clr r1
	inc r1
	clr uh
	clr um
	mov ul, r1
	clr bh
	mov bl, r1
	clr vh
	clr vm
	clr vl

pre_abcompare_k1_5:
	cp k1l_5, bl
	cpc k1h_5, bh
	brne pre_weiter_k1_5
	rjmp eukfinished_k1_5
pre_weiter_k1_5:
	bst k1l_5, 0			;if (A even)
	brts pre_anoteven_k1_5

	lsr k1h_5				;	A <- A/2
	ror k1l_5

	bst ul, 0			;	if (U uneven)
	brtc pre_u1even_k1_5

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

pre_u1even_k1_5:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp pre_abcompare_k1_5


pre_anoteven_k1_5:
	sub bl, k1l_5					;	B <- (B-A)/2
	sbc bh, k1h_5
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh
	
	add vl, r1			;	cause (V<0)
	adc vm, r0				;		V <- V+(2^16)+1
	adc vh, r1

	bst vl, 0					;	if (V uneven)
	brtc pre_veven_k1_5

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

pre_veven_k1_5:
	lsr vh						;	V <- V/2
	ror vm
	ror vl


abcompare_k1_5:
	cp k1l_5, bl
	cpc k1h_5, bh
	brne weiter_k1_5
	rjmp eukfinished_k1_5
weiter_k1_5:
	bst k1l_5, 0			;if (A even)
	brts anoteven_k1_5

	lsr k1h_5				;	A <- A/2
	ror k1l_5

	bst ul, 0			;	if (U uneven)
	brtc u1even_k1_5

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

u1even_k1_5:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k1_5


anoteven_k1_5:
	bst bl, 0			;if (B even)
	brts bnoteven_k1_5

	lsr bh				;	B <- B/2
	ror bl

	bst vl, 0					;	if (V uneven)
	brtc v1even_k1_5

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

v1even_k1_5:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k1_5

bnoteven_k1_5:
	cp k1h_5, bh			;if (A>B)
	brlo alowerthanb_k1_5
	brne ahigherthanb_k1_5
	cp k1l_5, bl
	brlo alowerthanb_k1_5
ahigherthanb_k1_5:
	sub k1l_5, bl			;	A <- (A-B)/2			
	sbc k1h_5, bh
	lsr k1h_5
	ror k1l_5

	sub ul, vl			;	U <- U-V
	sbc um, vm
	sbc uh, vh

	brpl upositive_k1_5		;	if (U<0)
	
	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

upositive_k1_5:
	bst ul, 0			;	if (U uneven)
	brtc ueven_k1_5

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

ueven_k1_5:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k1_5	


alowerthanb_k1_5:					;else
	sub bl, k1l_5					;	B <- (B-A)/2
	sbc bh, k1h_5
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh

	brpl vpositive_k1_5			;	if (V<0)
	
	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

vpositive_k1_5:
	bst vl, 0					;	if (V uneven)
	brtc veven_k1_5

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

veven_k1_5:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k1_5	

eukfinished_k1_5:

	mul	p1h, um					; ah * bh
	movw	TMP5:TMP4, r1:r0
	brne	A_Notzero_k1_5		; Go on if mul nonzero

	mul	p1l, ul
	movw	TMP3:TMP2, r1:r0
	brne	B_Notzero_k1_5		; Go on if mul nonzero

	mul	p1h, ul					; ah * bl
	brne	C_Notzero_k1_5		; Go on if mul nonzero
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p1l					; bh * al
	brne	D_Notzero_k1_5

	mov TMP2, ul
	mov TMP3, um
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k1_5

A_Notzero_k1_5:
	mul	p1l, ul					; al * bl
	movw	TMP3:TMP2, r1:r0

B_Notzero_k1_5:
	mul	p1h, ul					; ah * bl
C_Notzero_k1_5:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p1l					; bh * al
D_Notzero_k1_5:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	sub TMP2, TMP4				;sub low16(result), high16(result)
	sbc TMP3, TMP5
	brsh mulmod216_end_k1_5		;if low16(result) <= high16(result)
	adiw TMP3:TMP2, 1			;    inc low16(result) 
mulmod216_end_k1_5:
	mov p1h, TMP3
	mov p1l, TMP2

	pop bl
	pop bh
	pop k1l_5
	pop k1h_5
	
	
;/	
;/ p2 + k2 --> p2
;/

	sub p2l, k2l_5
	sbc p2h, k2h_5


;/
;/ p3 + k3 --> p3
;/

	sub p3l, k3l_5
	sbc p3h, k3h_5


;/
;/ p4 x k4 --> p4
;/

	push k4h_5
	push k4l_5
	push bh
	push bl

	cp k4h_5, r0
	cpc k4l_5, r0
	brne prekeynotzero_k4_5

	mov TMP2, p4l
	mov TMP3, p4h
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k4_5

prekeynotzero_k4_5:
	clr r1
	inc r1
	clr uh
	clr um
	mov ul, r1
	clr bh
	mov bl, r1
	clr vh
	clr vm
	clr vl

pre_abcompare_k4_5:
	cp k4l_5, bl
	cpc k4h_5, bh
	brne pre_weiter_k4_5
	rjmp eukfinished_k4_5
pre_weiter_k4_5:
	bst k4l_5, 0			;if (A even)
	brts pre_anoteven_k4_5

	lsr k4h_5				;	A <- A/2
	ror k4l_5

	bst ul, 0			;	if (U uneven)
	brtc pre_u1even_k4_5

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

pre_u1even_k4_5:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp pre_abcompare_k4_5


pre_anoteven_k4_5:
	sub bl, k4l_5					;	B <- (B-A)/2
	sbc bh, k4h_5
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh
	
	add vl, r1			;	cause (V<0)
	adc vm, r0				;		V <- V+(2^16)+1
	adc vh, r1

	bst vl, 0					;	if (V uneven)
	brtc pre_veven_k4_5

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

pre_veven_k4_5:
	lsr vh						;	V <- V/2
	ror vm
	ror vl


abcompare_k4_5:
	cp k4l_5, bl
	cpc k4h_5, bh
	brne weiter_k4_5
	rjmp eukfinished_k4_5
weiter_k4_5:
	bst k4l_5, 0			;if (A even)
	brts anoteven_k4_5

	lsr k4h_5				;	A <- A/2
	ror k4l_5

	bst ul, 0			;	if (U uneven)
	brtc u1even_k4_5

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

u1even_k4_5:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k4_5


anoteven_k4_5:
	bst bl, 0			;if (B even)
	brts bnoteven_k4_5

	lsr bh				;	B <- B/2
	ror bl

	bst vl, 0					;	if (V uneven)
	brtc v1even_k4_5

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

v1even_k4_5:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k4_5

bnoteven_k4_5:
	cp k4h_5, bh			;if (A>B)
	brlo alowerthanb_k4_5
	brne ahigherthanb_k4_5
	cp k4l_5, bl
	brlo alowerthanb_k4_5
ahigherthanb_k4_5:
	sub k4l_5, bl			;	A <- (A-B)/2			
	sbc k4h_5, bh
	lsr k4h_5
	ror k4l_5

	sub ul, vl			;	U <- U-V
	sbc um, vm
	sbc uh, vh

	brpl upositive_k4_5		;	if (U<0)
	
	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

upositive_k4_5:
	bst ul, 0			;	if (U uneven)
	brtc ueven_k4_5

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

ueven_k4_5:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k4_5	


alowerthanb_k4_5:					;else
	sub bl, k4l_5					;	B <- (B-A)/2
	sbc bh, k4h_5
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh

	brpl vpositive_k4_5			;	if (V<0)
	
	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

vpositive_k4_5:
	bst vl, 0					;	if (V uneven)
	brtc veven_k4_5

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

veven_k4_5:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k4_5	

eukfinished_k4_5:

	mul	p4h, um					; ah * bh
	movw	TMP5:TMP4, r1:r0
	brne	A_Notzero_k4_5		; Go on if mul nonzero

	mul	p4l, ul
	movw	TMP3:TMP2, r1:r0
	brne	B_Notzero_k4_5		; Go on if mul nonzero

	mul	p4h, ul					; ah * bl
	brne	C_Notzero_k4_5		; Go on if mul nonzero
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p4l					; bh * al
	brne	D_Notzero_k4_5

	mov TMP2, ul
	mov TMP3, um
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k4_5

A_Notzero_k4_5:
	mul	p4l, ul					; al * bl
	movw	TMP3:TMP2, r1:r0

B_Notzero_k4_5:
	mul	p4h, ul					; ah * bl
C_Notzero_k4_5:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p4l					; bh * al
D_Notzero_k4_5:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	sub TMP2, TMP4				;sub low16(result), high16(result)
	sbc TMP3, TMP5
	brsh mulmod216_end_k4_5		;if low16(result) <= high16(result)
	adiw TMP3:TMP2, 1			;    inc low16(result) 
mulmod216_end_k4_5:
	mov p4h, TMP3
	mov p4l, TMP2

	pop bl
	pop bh
	pop k4l_5
	pop k4h_5


;/
;/ p1 XOR p3 --> i1
;/

	mov i1h, p1h
	mov i1l, p1l
	eor i1h, p3h
	eor i1l, p3l


;/
;/ Key Shift
;/

	lsr k8l
	ror k1h
	ror k1l
	ror k2h
	ror k2l
	ror k3h
	ror k3l
	ror k4h
	ror k4l
	ror k5h
	ror k5l
	ror k6h
	ror k6l
	ror k7h
	ror k7l
	ror k8h
	brcc keysh4
	ori k8l, $80
keysh4:


;/
;/ i1 x k5 --> i1
;/

	mul	i1h, k5h_5					; ah * bh
	movw	TMP3:TMP2, r1:r0
	brne	A_Notzero_k5_5		; Go on if mul nonzero

	mul	i1l, k5l_5
	movw	TMP1:TMP0, r1:r0
	brne	B_Notzero_k5_5		; Go on if mul nonzero

	mul	i1h, k5l_5					; ah * bl
	brne	C_Notzero_k5_5		; Go on if mul nonzero
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k5h_5, i1l					; bh * al
	brne	D_Notzero_k5_5

	add TMP0, k5l_5
	breq keyzerotest_k5_5
	add TMP1, k5h_5
	rjmp negresult_k5_5
keyzerotest_k5_5:
	add TMP1, k5h_5
	brne negresult_k5_5

	mov TMP0, i1l
	mov TMP1, i1h

negresult_k5_5:
	neg TMP0
	clr r0
	adc TMP1, r0
	neg TMP1
	adiw TMP1:TMP0, 1
	
	rjmp mulmod216_end_k5_5

A_Notzero_k5_5:
	mul	i1l, k5l_5					; al * bl
	movw	TMP1:TMP0, r1:r0

B_Notzero_k5_5:
	mul	i1h, k5l_5					; ah * bl
C_Notzero_k5_5:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k5h_5, i1l					; bh * al
D_Notzero_k5_5:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	sub TMP0, TMP2				;sub low16(result), high16(result)
	sbc TMP1, TMP3
	brsh mulmod216_end_k5_5		;if low16(result) <= high16(result)
	adiw TMP1:TMP0, 1			;    inc low16(result) 
mulmod216_end_k5_5:
	mov i1h, TMP1
	mov i1l, TMP0


;/
;/ p2 XOR p4 --> i2
;/

	mov i2h, p2h
	mov i2l, p2l
	eor i2h, p4h
	eor i2l, p4l

;/
;/ i2 + i1 --> i2
;/

	add i2l, i1l
	adc i2h, i1h

;/
;/ i2 x k6 --> i2
;/

	push i1h
	push i1l

	mov i1h, i2h
	mov i1l, i2l

	mul	i1h, k6h_5					; ah * bh
	movw	TMP3:TMP2, r1:r0
	brne	A_Notzero_k6_5		; Go on if mul nonzero

	mul	i1l, k6l_5
	movw	TMP1:TMP0, r1:r0
	brne	B_Notzero_k6_5		; Go on if mul nonzero

	mul	i1h, k6l_5					; ah * bl
	brne	C_Notzero_k6_5		; Go on if mul nonzero
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k6h_5, i1l					; bh * al
	brne	D_Notzero_k6_5

	add TMP0, k6l_5
	breq keyzerotest_k6_5
	add TMP1, k6h_5
	rjmp negresult_k6_5
keyzerotest_k6_5:
	add TMP1, k6h_5
	brne negresult_k6_5

	mov TMP0, i1l
	mov TMP1, i1h

negresult_k6_5:
	neg TMP0
	clr r0
	adc TMP1, r0
	neg TMP1
	adiw TMP1:TMP0, 1
	
	rjmp mulmod216_end_k6_5

A_Notzero_k6_5:
	mul	i1l, k6l_5					; al * bl
	movw	TMP1:TMP0, r1:r0

B_Notzero_k6_5:
	mul	i1h, k6l_5					; ah * bl
C_Notzero_k6_5:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k6h_5, i1l					; bh * al
D_Notzero_k6_5:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	sub TMP0, TMP2				;sub low16(result), high16(result)
	sbc TMP1, TMP3
	brsh mulmod216_end_k6_5		;if low16(result) <= high16(result)
	adiw TMP1:TMP0, 1			;    inc low16(result) 
mulmod216_end_k6_5:
	mov i2h, TMP1
	mov i2l, TMP0

	pop i1l
	pop i1h 

;/
;/ i1 + i2 --> i1
;/

	add i1l, i2l
	adc i1h, i2h

;/
;/ p1 XOR i2 --> p1
;/

	eor p1h, i2h
	eor p1l, i2l

;/
;/ p3 XOR i2 --> p3
;/

	eor p3h, i2h
	eor p3l, i2l

;/
;/ p2 XOR i1 --> p2
;/

	eor p2h, i1h
	eor p2l, i1l

;/
;/ p4 XOR i1 --> p4
;/

	eor p4h, i1h
	eor p4l, i1l


;--------------------------------------------------------------
;                               Round 6
;--------------------------------------------------------------


;/
;/ p1 x k1 --> p1
;/

	push k1h_6
	push k1l_6
	push bh
	push bl

	cp k1h_6, r0
	cpc k1l_6, r0
	brne prekeynotzero_k1_6

	mov TMP2, p1l
	mov TMP3, p1h
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k1_6

prekeynotzero_k1_6:
	clr r1
	inc r1
	clr uh
	clr um
	mov ul, r1
	clr bh
	mov bl, r1
	clr vh
	clr vm
	clr vl

pre_abcompare_k1_6:
	cp k1l_6, bl
	cpc k1h_6, bh
	brne pre_weiter_k1_6
	rjmp eukfinished_k1_6
pre_weiter_k1_6:
	bst k1l_6, 0			;if (A even)
	brts pre_anoteven_k1_6

	lsr k1h_6				;	A <- A/2
	ror k1l_6

	bst ul, 0			;	if (U uneven)
	brtc pre_u1even_k1_6

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

pre_u1even_k1_6:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp pre_abcompare_k1_6


pre_anoteven_k1_6:
	sub bl, k1l_6					;	B <- (B-A)/2
	sbc bh, k1h_6
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh
	
	add vl, r1			;	cause (V<0)
	adc vm, r0				;		V <- V+(2^16)+1
	adc vh, r1

	bst vl, 0					;	if (V uneven)
	brtc pre_veven_k1_6

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

pre_veven_k1_6:
	lsr vh						;	V <- V/2
	ror vm
	ror vl


abcompare_k1_6:
	cp k1l_6, bl
	cpc k1h_6, bh
	brne weiter_k1_6
	rjmp eukfinished_k1_6
weiter_k1_6:
	bst k1l_6, 0			;if (A even)
	brts anoteven_k1_6

	lsr k1h_6				;	A <- A/2
	ror k1l_6

	bst ul, 0			;	if (U uneven)
	brtc u1even_k1_6

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

u1even_k1_6:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k1_6


anoteven_k1_6:
	bst bl, 0			;if (B even)
	brts bnoteven_k1_6

	lsr bh				;	B <- B/2
	ror bl

	bst vl, 0					;	if (V uneven)
	brtc v1even_k1_6

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

v1even_k1_6:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k1_6

bnoteven_k1_6:
	cp k1h_6, bh			;if (A>B)
	brlo alowerthanb_k1_6
	brne ahigherthanb_k1_6
	cp k1l_6, bl
	brlo alowerthanb_k1_6
ahigherthanb_k1_6:
	sub k1l_6, bl			;	A <- (A-B)/2			
	sbc k1h_6, bh
	lsr k1h_6
	ror k1l_6

	sub ul, vl			;	U <- U-V
	sbc um, vm
	sbc uh, vh

	brpl upositive_k1_6		;	if (U<0)
	
	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

upositive_k1_6:
	bst ul, 0			;	if (U uneven)
	brtc ueven_k1_6

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

ueven_k1_6:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k1_6	


alowerthanb_k1_6:					;else
	sub bl, k1l_6					;	B <- (B-A)/2
	sbc bh, k1h_6
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh

	brpl vpositive_k1_6			;	if (V<0)
	
	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

vpositive_k1_6:
	bst vl, 0					;	if (V uneven)
	brtc veven_k1_6

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

veven_k1_6:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k1_6	

eukfinished_k1_6:

	mul	p1h, um					; ah * bh
	movw	TMP5:TMP4, r1:r0
	brne	A_Notzero_k1_6		; Go on if mul nonzero

	mul	p1l, ul
	movw	TMP3:TMP2, r1:r0
	brne	B_Notzero_k1_6		; Go on if mul nonzero

	mul	p1h, ul					; ah * bl
	brne	C_Notzero_k1_6		; Go on if mul nonzero
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p1l					; bh * al
	brne	D_Notzero_k1_6

	mov TMP2, ul
	mov TMP3, um
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k1_6

A_Notzero_k1_6:
	mul	p1l, ul					; al * bl
	movw	TMP3:TMP2, r1:r0

B_Notzero_k1_6:
	mul	p1h, ul					; ah * bl
C_Notzero_k1_6:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p1l					; bh * al
D_Notzero_k1_6:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	sub TMP2, TMP4				;sub low16(result), high16(result)
	sbc TMP3, TMP5
	brsh mulmod216_end_k1_6		;if low16(result) <= high16(result)
	adiw TMP3:TMP2, 1			;    inc low16(result) 
mulmod216_end_k1_6:
	mov p1h, TMP3
	mov p1l, TMP2

	pop bl
	pop bh
	pop k1l_6
	pop k1h_6
	
	
;/	
;/ p2 + k2 --> p2
;/

	sub p2l_g, k2l_6
	sbc p2h_g, k2h_6


;/
;/ p3 + k3 --> p3
;/

	sub p3l_g, k3l_6
	sbc p3h_g, k3h_6

;/
;/ p4 x k4 --> p4
;/

	push k4h_6
	push k4l_6
	push bh
	push bl

	cp k4h_6, r0
	cpc k4l_6, r0
	brne prekeynotzero_k4_6

	mov TMP2, p4l
	mov TMP3, p4h
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k4_6

prekeynotzero_k4_6:
	clr r1
	inc r1
	clr uh
	clr um
	mov ul, r1
	clr bh
	mov bl, r1
	clr vh
	clr vm
	clr vl

pre_abcompare_k4_6:
	cp k4l_6, bl
	cpc k4h_6, bh
	brne pre_weiter_k4_6
	rjmp eukfinished_k4_6
pre_weiter_k4_6:
	bst k4l_6, 0			;if (A even)
	brts pre_anoteven_k4_6

	lsr k4h_6				;	A <- A/2
	ror k4l_6

	bst ul, 0			;	if (U uneven)
	brtc pre_u1even_k4_6

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

pre_u1even_k4_6:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp pre_abcompare_k4_6


pre_anoteven_k4_6:
	sub bl, k4l_6					;	B <- (B-A)/2
	sbc bh, k4h_6
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh
	
	add vl, r1			;	cause (V<0)
	adc vm, r0				;		V <- V+(2^16)+1
	adc vh, r1

	bst vl, 0					;	if (V uneven)
	brtc pre_veven_k4_6

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

pre_veven_k4_6:
	lsr vh						;	V <- V/2
	ror vm
	ror vl


abcompare_k4_6:
	cp k4l_6, bl
	cpc k4h_6, bh
	brne weiter_k4_6
	rjmp eukfinished_k4_6
weiter_k4_6:
	bst k4l_6, 0			;if (A even)
	brts anoteven_k4_6

	lsr k4h_6				;	A <- A/2
	ror k4l_6

	bst ul, 0			;	if (U uneven)
	brtc u1even_k4_6

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

u1even_k4_6:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k4_6


anoteven_k4_6:
	bst bl, 0			;if (B even)
	brts bnoteven_k4_6

	lsr bh				;	B <- B/2
	ror bl

	bst vl, 0					;	if (V uneven)
	brtc v1even_k4_6

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

v1even_k4_6:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k4_6

bnoteven_k4_6:
	cp k4h_6, bh			;if (A>B)
	brlo alowerthanb_k4_6
	brne ahigherthanb_k4_6
	cp k4l_6, bl
	brlo alowerthanb_k4_6
ahigherthanb_k4_6:
	sub k4l_6, bl			;	A <- (A-B)/2			
	sbc k4h_6, bh
	lsr k4h_6
	ror k4l_6

	sub ul, vl			;	U <- U-V
	sbc um, vm
	sbc uh, vh

	brpl upositive_k4_6		;	if (U<0)
	
	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

upositive_k4_6:
	bst ul, 0			;	if (U uneven)
	brtc ueven_k4_6

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

ueven_k4_6:
	lsr uh										;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k4_6	


alowerthanb_k4_6:					;else
	sub bl, k4l_6					;	B <- (B-A)/2
	sbc bh, k4h_6
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh

	brpl vpositive_k4_6			;	if (V<0)
	
	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

vpositive_k4_6:
	bst vl, 0					;	if (V uneven)
	brtc veven_k4_6

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

veven_k4_6:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k4_6	

eukfinished_k4_6:

	mul	p4h, um					; ah * bh
	movw	TMP5:TMP4, r1:r0
	brne	A_Notzero_k4_6		; Go on if mul nonzero

	mul	p4l, ul
	movw	TMP3:TMP2, r1:r0
	brne	B_Notzero_k4_6		; Go on if mul nonzero

	mul	p4h, ul					; ah * bl
	brne	C_Notzero_k4_6		; Go on if mul nonzero
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p4l					; bh * al
	brne	D_Notzero_k4_6

	mov TMP2, ul
	mov TMP3, um
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k4_6

A_Notzero_k4_6:
	mul	p4l, ul					; al * bl
	movw	TMP3:TMP2, r1:r0

B_Notzero_k4_6:
	mul	p4h, ul					; ah * bl
C_Notzero_k4_6:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p4l					; bh * al
D_Notzero_k4_6:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	sub TMP2, TMP4				;sub low16(result), high16(result)
	sbc TMP3, TMP5
	brsh mulmod216_end_k4_6		;if low16(result) <= high16(result)
	adiw TMP3:TMP2, 1			;    inc low16(result) 
mulmod216_end_k4_6:
	mov p4h, TMP3
	mov p4l, TMP2

	pop bl
	pop bh
	pop k4l_6
	pop k4h_6


;/
;/ p1 XOR p3 --> i1
;/

	mov i1h, p1h
	mov i1l, p1l
	eor i1h, p3h_g
	eor i1l, p3l_g

;/
;/ i1 x k5 --> i1
;/

	mul	i1h, k5h_6					; ah * bh
	movw	TMP3:TMP2, r1:r0
	brne	A_Notzero_k5_6		; Go on if mul nonzero

	mul	i1l, k5l_6
	movw	TMP1:TMP0, r1:r0
	brne	B_Notzero_k5_6		; Go on if mul nonzero

	mul	i1h, k5l_6					; ah * bl
	brne	C_Notzero_k5_6		; Go on if mul nonzero
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k5h_6, i1l					; bh * al
	brne	D_Notzero_k5_6

	add TMP0, k5l_6
	breq keyzerotest_k5_6
	add TMP1, k5h_6
	rjmp negresult_k5_6
keyzerotest_k5_6:
	add TMP1, k5h_6
	brne negresult_k5_6

	mov TMP0, i1l
	mov TMP1, i1h

negresult_k5_6:
	neg TMP0
	clr r0
	adc TMP1, r0
	neg TMP1
	adiw TMP1:TMP0, 1
	
	rjmp mulmod216_end_k5_6

A_Notzero_k5_6:
	mul	i1l, k5l_6					; al * bl
	movw	TMP1:TMP0, r1:r0

B_Notzero_k5_6:
	mul	i1h, k5l_6					; ah * bl
C_Notzero_k5_6:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k5h_6, i1l					; bh * al
D_Notzero_k5_6:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	sub TMP0, TMP2				;sub low16(result), high16(result)
	sbc TMP1, TMP3
	brsh mulmod216_end_k5_6		;if low16(result) <= high16(result)
	adiw TMP1:TMP0, 1			;    inc low16(result) 
mulmod216_end_k5_6:
	mov i1h, TMP1
	mov i1l, TMP0


;/
;/ p2 XOR p4 --> i2
;/

	mov i2h, p2h_g
	mov i2l, p2l_g
	eor i2h, p4h
	eor i2l, p4l

;/
;/ i2 + i1 --> i2
;/

	add i2l, i1l
	adc i2h, i1h

;/
;/ i2 x k6 --> i2
;/

	push i1h
	push i1l

	mov i1h, i2h
	mov i1l, i2l

	mul	i1h, k6h_6					; ah * bh
	movw	TMP3:TMP2, r1:r0
	brne	A_Notzero_k6_6		; Go on if mul nonzero

	mul	i1l, k6l_6
	movw	TMP1:TMP0, r1:r0
	brne	B_Notzero_k6_6		; Go on if mul nonzero

	mul	i1h, k6l_6					; ah * bl
	brne	C_Notzero_k6_6		; Go on if mul nonzero
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k6h_6, i1l					; bh * al
	brne	D_Notzero_k6_6

	add TMP0, k6l_6
	breq keyzerotest_k6_6
	add TMP1, k6h_6
	rjmp negresult_k6_6
keyzerotest_k6_6:
	add TMP1, k6h_6
	brne negresult_k6_6

	mov TMP0, i1l
	mov TMP1, i1h

negresult_k6_6:
	neg TMP0
	clr r0
	adc TMP1, r0
	neg TMP1
	adiw TMP1:TMP0, 1
	
	rjmp mulmod216_end_k6_6

A_Notzero_k6_6:
	mul	i1l, k6l_6					; al * bl
	movw	TMP1:TMP0, r1:r0

B_Notzero_k6_6:
	mul	i1h, k6l_6					; ah * bl
C_Notzero_k6_6:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k6h_6, i1l					; bh * al
D_Notzero_k6_6:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	sub TMP0, TMP2				;sub low16(result), high16(result)
	sbc TMP1, TMP3
	brsh mulmod216_end_k6_6		;if low16(result) <= high16(result)
	adiw TMP1:TMP0, 1			;    inc low16(result) 
mulmod216_end_k6_6:
	mov i2h, TMP1
	mov i2l, TMP0

	pop i1l
	pop i1h 

;/
;/ i1 + i2 --> i1
;/

	add i1l, i2l
	adc i1h, i2h

;/
;/ p1 XOR i2 --> p1
;/

	eor p1h, i2h
	eor p1l, i2l

;/
;/ p3 XOR i2 --> p3
;/

	eor p3h_g, i2h
	eor p3l_g, i2l

;/
;/ p2 XOR i1 --> p2
;/

	eor p2h_g, i1h
	eor p2l_g, i1l

;/
;/ p4 XOR i1 --> p4
;/

	eor p4h, i1h
	eor p4l, i1l


;--------------------------------------------------------------
;                               Round 7
;--------------------------------------------------------------

;/
;/ Key Shift
;/

	lsr k8l
	ror k1h
	ror k1l
	ror k2h
	ror k2l
	ror k3h
	ror k3l
	ror k4h
	ror k4l
	ror k5h
	ror k5l
	ror k6h
	ror k6l
	ror k7h
	ror k7l
	ror k8h
	brcc keysh5
	ori k8l, $80
keysh5:

;/
;/ p1 x k1 --> p1
;/

	push k1h_7
	push k1l_7
	push bh
	push bl

	cp k1h_7, r0
	cpc k1l_7, r0
	brne prekeynotzero_k1_7

	mov TMP2, p1l
	mov TMP3, p1h
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k1_7

prekeynotzero_k1_7:
	clr r1
	inc r1
	clr uh
	clr um
	mov ul, r1
	clr bh
	mov bl, r1
	clr vh
	clr vm
	clr vl

pre_abcompare_k1_7:
	cp k1l_7, bl
	cpc k1h_7, bh
	brne pre_weiter_k1_7
	rjmp eukfinished_k1_7
pre_weiter_k1_7:
	bst k1l_7, 0			;if (A even)
	brts pre_anoteven_k1_7

	lsr k1h_7				;	A <- A/2
	ror k1l_7

	bst ul, 0			;	if (U uneven)
	brtc pre_u1even_k1_7

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

pre_u1even_k1_7:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp pre_abcompare_k1_7


pre_anoteven_k1_7:
	sub bl, k1l_7					;	B <- (B-A)/2
	sbc bh, k1h_7
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh
	
	add vl, r1			;	cause (V<0)
	adc vm, r0				;		V <- V+(2^16)+1
	adc vh, r1

	bst vl, 0					;	if (V uneven)
	brtc pre_veven_k1_7

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

pre_veven_k1_7:
	lsr vh						;	V <- V/2
	ror vm
	ror vl


abcompare_k1_7:
	cp k1l_7, bl
	cpc k1h_7, bh
	brne weiter_k1_7
	rjmp eukfinished_k1_7
weiter_k1_7:
	bst k1l_7, 0			;if (A even)
	brts anoteven_k1_7

	lsr k1h_7				;	A <- A/2
	ror k1l_7

	bst ul, 0			;	if (U uneven)
	brtc u1even_k1_7

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

u1even_k1_7:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k1_7


anoteven_k1_7:
	bst bl, 0			;if (B even)
	brts bnoteven_k1_7

	lsr bh				;	B <- B/2
	ror bl

	bst vl, 0					;	if (V uneven)
	brtc v1even_k1_7

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

v1even_k1_7:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k1_7

bnoteven_k1_7:
	cp k1h_7, bh			;if (A>B)
	brlo alowerthanb_k1_7
	brne ahigherthanb_k1_7
	cp k1l_7, bl
	brlo alowerthanb_k1_7
ahigherthanb_k1_7:
	sub k1l_7, bl			;	A <- (A-B)/2			
	sbc k1h_7, bh
	lsr k1h_7
	ror k1l_7

	sub ul, vl			;	U <- U-V
	sbc um, vm
	sbc uh, vh

	brpl upositive_k1_7		;	if (U<0)
	
	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

upositive_k1_7:
	bst ul, 0			;	if (U uneven)
	brtc ueven_k1_7

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

ueven_k1_7:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k1_7	


alowerthanb_k1_7:					;else
	sub bl, k1l_7					;	B <- (B-A)/2
	sbc bh, k1h_7
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh

	brpl vpositive_k1_7			;	if (V<0)
	
	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

vpositive_k1_7:
	bst vl, 0					;	if (V uneven)
	brtc veven_k1_7

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

veven_k1_7:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k1_7	

eukfinished_k1_7:

	mul	p1h, um					; ah * bh
	movw	TMP5:TMP4, r1:r0
	brne	A_Notzero_k1_7		; Go on if mul nonzero

	mul	p1l, ul
	movw	TMP3:TMP2, r1:r0
	brne	B_Notzero_k1_7		; Go on if mul nonzero

	mul	p1h, ul					; ah * bl
	brne	C_Notzero_k1_7		; Go on if mul nonzero
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p1l					; bh * al
	brne	D_Notzero_k1_7

	mov TMP2, ul
	mov TMP3, um
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k1_7

A_Notzero_k1_7:
	mul	p1l, ul					; al * bl
	movw	TMP3:TMP2, r1:r0

B_Notzero_k1_7:
	mul	p1h, ul					; ah * bl
C_Notzero_k1_7:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p1l					; bh * al
D_Notzero_k1_7:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	sub TMP2, TMP4				;sub low16(result), high16(result)
	sbc TMP3, TMP5
	brsh mulmod216_end_k1_7		;if low16(result) <= high16(result)
	adiw TMP3:TMP2, 1			;    inc low16(result) 
mulmod216_end_k1_7:
	mov p1h, TMP3
	mov p1l, TMP2

	pop bl
	pop bh
	pop k1l_7
	pop k1h_7
	
	
;/	
;/ p2 + k2 --> p2
;/

	sub p2l, k2l_7
	sbc p2h, k2h_7


;/
;/ p3 + k3 --> p3
;/

	sub p3l, k3l_7
	sbc p3h, k3h_7

;/
;/ p4 x k4 --> p4
;/

	push k4h_7
	push k4l_7
	push bh
	push bl

	cp k4h_7, r0
	cpc k4l_7, r0
	brne prekeynotzero_k4_7

	mov TMP2, p4l
	mov TMP3, p4h
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k4_7

prekeynotzero_k4_7:
	clr r1
	inc r1
	clr uh
	clr um
	mov ul, r1
	clr bh
	mov bl, r1
	clr vh
	clr vm
	clr vl

pre_abcompare_k4_7:
	cp k4l_7, bl
	cpc k4h_7, bh
	brne pre_weiter_k4_7
	rjmp eukfinished_k4_7
pre_weiter_k4_7:
	bst k4l_7, 0			;if (A even)
	brts pre_anoteven_k4_7

	lsr k4h_7				;	A <- A/2
	ror k4l_7

	bst ul, 0			;	if (U uneven)
	brtc pre_u1even_k4_7

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

pre_u1even_k4_7:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp pre_abcompare_k4_7


pre_anoteven_k4_7:
	sub bl, k4l_7					;	B <- (B-A)/2
	sbc bh, k4h_7
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh
	
	add vl, r1			;	cause (V<0)
	adc vm, r0				;		V <- V+(2^16)+1
	adc vh, r1

	bst vl, 0					;	if (V uneven)
	brtc pre_veven_k4_7

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

pre_veven_k4_7:
	lsr vh						;	V <- V/2
	ror vm
	ror vl


abcompare_k4_7:
	cp k4l_7, bl
	cpc k4h_7, bh
	brne weiter_k4_7
	rjmp eukfinished_k4_7
weiter_k4_7:
	bst k4l_7, 0			;if (A even)
	brts anoteven_k4_7

	lsr k4h_7				;	A <- A/2
	ror k4l_7

	bst ul, 0			;	if (U uneven)
	brtc u1even_k4_7

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

u1even_k4_7:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k4_7


anoteven_k4_7:
	bst bl, 0			;if (B even)
	brts bnoteven_k4_7

	lsr bh				;	B <- B/2
	ror bl

	bst vl, 0					;	if (V uneven)
	brtc v1even_k4_7

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

v1even_k4_7:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k4_7

bnoteven_k4_7:
	cp k4h_7, bh			;if (A>B)
	brlo alowerthanb_k4_7
	brne ahigherthanb_k4_7
	cp k4l_7, bl
	brlo alowerthanb_k4_7
ahigherthanb_k4_7:
	sub k4l_7, bl			;	A <- (A-B)/2			
	sbc k4h_7, bh
	lsr k4h_7
	ror k4l_7

	sub ul, vl			;	U <- U-V
	sbc um, vm
	sbc uh, vh

	brpl upositive_k4_7		;	if (U<0)
	
	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

upositive_k4_7:
	bst ul, 0			;	if (U uneven)
	brtc ueven_k4_7

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

ueven_k4_7:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k4_7	


alowerthanb_k4_7:					;else
	sub bl, k4l_7					;	B <- (B-A)/2
	sbc bh, k4h_7
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh

	brpl vpositive_k4_7			;	if (V<0)
	
	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

vpositive_k4_7:
	bst vl, 0					;	if (V uneven)
	brtc veven_k4_7

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

veven_k4_7:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k4_7	

eukfinished_k4_7:

	mul	p4h, um					; ah * bh
	movw	TMP5:TMP4, r1:r0
	brne	A_Notzero_k4_7		; Go on if mul nonzero

	mul	p4l, ul
	movw	TMP3:TMP2, r1:r0
	brne	B_Notzero_k4_7		; Go on if mul nonzero

	mul	p4h, ul					; ah * bl
	brne	C_Notzero_k4_7		; Go on if mul nonzero
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p4l					; bh * al
	brne	D_Notzero_k4_7

	mov TMP2, ul
	mov TMP3, um
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k4_7

A_Notzero_k4_7:
	mul	p4l, ul					; al * bl
	movw	TMP3:TMP2, r1:r0

B_Notzero_k4_7:
	mul	p4h, ul					; ah * bl
C_Notzero_k4_7:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p4l					; bh * al
D_Notzero_k4_7:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	sub TMP2, TMP4				;sub low16(result), high16(result)
	sbc TMP3, TMP5
	brsh mulmod216_end_k4_7		;if low16(result) <= high16(result)
	adiw TMP3:TMP2, 1			;    inc low16(result) 
mulmod216_end_k4_7:
	mov p4h, TMP3
	mov p4l, TMP2

	pop bl
	pop bh
	pop k4l_7
	pop k4h_7


;/
;/ p1 XOR p3 --> i1
;/

	mov i1h, p1h
	mov i1l, p1l
	eor i1h, p3h
	eor i1l, p3l

;/
;/ i1 x k5 --> i1
;/

	mul	i1h, k5h_7					; ah * bh
	movw	TMP3:TMP2, r1:r0
	brne	A_Notzero_k5_7		; Go on if mul nonzero

	mul	i1l, k5l_7
	movw	TMP1:TMP0, r1:r0
	brne	B_Notzero_k5_7		; Go on if mul nonzero

	mul	i1h, k5l_7					; ah * bl
	brne	C_Notzero_k5_7		; Go on if mul nonzero
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k5h_7, i1l					; bh * al
	brne	D_Notzero_k5_7

	add TMP0, k5l_7
	breq keyzerotest_k5_7
	add TMP1, k5h_7
	rjmp negresult_k5_7
keyzerotest_k5_7:
	add TMP1, k5h_7
	brne negresult_k5_7

	mov TMP0, i1l
	mov TMP1, i1h

negresult_k5_7:
	neg TMP0
	clr r0
	adc TMP1, r0
	neg TMP1
	adiw TMP1:TMP0, 1
	
	rjmp mulmod216_end_k5_7

A_Notzero_k5_7:
	mul	i1l, k5l_7					; al * bl
	movw	TMP1:TMP0, r1:r0

B_Notzero_k5_7:
	mul	i1h, k5l_7					; ah * bl
C_Notzero_k5_7:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k5h_7, i1l					; bh * al
D_Notzero_k5_7:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	sub TMP0, TMP2				;sub low16(result), high16(result)
	sbc TMP1, TMP3
	brsh mulmod216_end_k5_7		;if low16(result) <= high16(result)
	adiw TMP1:TMP0, 1			;    inc low16(result) 
mulmod216_end_k5_7:
	mov i1h, TMP1
	mov i1l, TMP0


;/
;/ p2 XOR p4 --> i2
;/

	mov i2h, p2h
	mov i2l, p2l
	eor i2h, p4h
	eor i2l, p4l

;/
;/ i2 + i1 --> i2
;/

	add i2l, i1l
	adc i2h, i1h

;/
;/ i2 x k6 --> i2
;/

	push i1h
	push i1l

	mov i1h, i2h
	mov i1l, i2l

	mul	i1h, k6h_7					; ah * bh
	movw	TMP3:TMP2, r1:r0
	brne	A_Notzero_k6_7		; Go on if mul nonzero

	mul	i1l, k6l_7
	movw	TMP1:TMP0, r1:r0
	brne	B_Notzero_k6_7		; Go on if mul nonzero

	mul	i1h, k6l_7					; ah * bl
	brne	C_Notzero_k6_7		; Go on if mul nonzero
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k6h_7, i1l					; bh * al
	brne	D_Notzero_k6_7

	add TMP0, k6l_7
	breq keyzerotest_k6_7
	add TMP1, k6h_7
	rjmp negresult_k6_7
keyzerotest_k6_7:
	add TMP1, k6h_7
	brne negresult_k6_7

	mov TMP0, i1l
	mov TMP1, i1h

negresult_k6_7:
	neg TMP0
	clr r0
	adc TMP1, r0
	neg TMP1
	adiw TMP1:TMP0, 1
	
	rjmp mulmod216_end_k6_7

A_Notzero_k6_7:
	mul	i1l, k6l_7					; al * bl
	movw	TMP1:TMP0, r1:r0

B_Notzero_k6_7:
	mul	i1h, k6l_7					; ah * bl
C_Notzero_k6_7:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k6h_7, i1l					; bh * al
D_Notzero_k6_7:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	sub TMP0, TMP2				;sub low16(result), high16(result)
	sbc TMP1, TMP3
	brsh mulmod216_end_k6_7		;if low16(result) <= high16(result)
	adiw TMP1:TMP0, 1			;    inc low16(result) 
mulmod216_end_k6_7:
	mov i2h, TMP1
	mov i2l, TMP0

	pop i1l
	pop i1h 

;/
;/ i1 + i2 --> i1
;/

	add i1l, i2l
	adc i1h, i2h

;/
;/ p1 XOR i2 --> p1
;/

	eor p1h, i2h
	eor p1l, i2l

;/
;/ p3 XOR i2 --> p3
;/

	eor p3h, i2h
	eor p3l, i2l

;/
;/ p2 XOR i1 --> p2
;/

	eor p2h, i1h
	eor p2l, i1l

;/
;/ p4 XOR i1 --> p4
;/

	eor p4h, i1h
	eor p4l, i1l


;--------------------------------------------------------------
;                               Round 8
;--------------------------------------------------------------


;/	
;/ p2 + k2 --> p2
;/

	sub p2l_g, k2l_8
	sbc p2h_g, k2h_8


;/
;/ p4 x k4 --> p4
;/

	push k4h_8
	push k4l_8
	push bh
	push bl

	cp k4h_8, r0
	cpc k4l_8, r0
	brne prekeynotzero_k4_8

	mov TMP2, p4l
	mov TMP3, p4h
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k4_8

prekeynotzero_k4_8:
	clr r1
	inc r1
	clr uh
	clr um
	mov ul, r1
	clr bh
	mov bl, r1
	clr vh
	clr vm
	clr vl

pre_abcompare_k4_8:
	cp k4l_8, bl
	cpc k4h_8, bh
	brne pre_weiter_k4_8
	rjmp eukfinished_k4_8
pre_weiter_k4_8:
	bst k4l_8, 0			;if (A even)
	brts pre_anoteven_k4_8

	lsr k4h_8				;	A <- A/2
	ror k4l_8

	bst ul, 0			;	if (U uneven)
	brtc pre_u1even_k4_8

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

pre_u1even_k4_8:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp pre_abcompare_k4_8


pre_anoteven_k4_8:
	sub bl, k4l_8					;	B <- (B-A)/2
	sbc bh, k4h_8
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh
	
	add vl, r1			;	cause (V<0)
	adc vm, r0				;		V <- V+(2^16)+1
	adc vh, r1

	bst vl, 0					;	if (V uneven)
	brtc pre_veven_k4_8

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

pre_veven_k4_8:
	lsr vh						;	V <- V/2
	ror vm
	ror vl


abcompare_k4_8:
	cp k4l_8, bl
	cpc k4h_8, bh
	brne weiter_k4_8
	rjmp eukfinished_k4_8
weiter_k4_8:
	bst k4l_8, 0			;if (A even)
	brts anoteven_k4_8

	lsr k4h_8				;	A <- A/2
	ror k4l_8

	bst ul, 0			;	if (U uneven)
	brtc u1even_k4_8

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

u1even_k4_8:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k4_8


anoteven_k4_8:
	bst bl, 0			;if (B even)
	brts bnoteven_k4_8

	lsr bh				;	B <- B/2
	ror bl

	bst vl, 0					;	if (V uneven)
	brtc v1even_k4_8

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

v1even_k4_8:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k4_8

bnoteven_k4_8:
	cp k4h_8, bh			;if (A>B)
	brlo alowerthanb_k4_8
	brne ahigherthanb_k4_8
	cp k4l_8, bl
	brlo alowerthanb_k4_8
ahigherthanb_k4_8:
	sub k4l_8, bl			;	A <- (A-B)/2			
	sbc k4h_8, bh
	lsr k4h_8
	ror k4l_8

	sub ul, vl			;	U <- U-V
	sbc um, vm
	sbc uh, vh

	brpl upositive_k4_8		;	if (U<0)
	
	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

upositive_k4_8:
	bst ul, 0			;	if (U uneven)
	brtc ueven_k4_8

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

ueven_k4_8:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k4_8	


alowerthanb_k4_8:				;else
	sub bl, k4l_8				;	B <- (B-A)/2
	sbc bh, k4h_8
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh

	brpl vpositive_k4_8			;	if (V<0)
	
	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

vpositive_k4_8:
	bst vl, 0					;	if (V uneven)
	brtc veven_k4_8

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

veven_k4_8:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k4_8	

eukfinished_k4_8:

	mul	p4h, um					; ah * bh
	movw	TMP5:TMP4, r1:r0
	brne	A_Notzero_k4_8		; Go on if mul nonzero

	mul	p4l, ul
	movw	TMP3:TMP2, r1:r0
	brne	B_Notzero_k4_8		; Go on if mul nonzero

	mul	p4h, ul					; ah * bl
	brne	C_Notzero_k4_8		; Go on if mul nonzero
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p4l					; bh * al
	brne	D_Notzero_k4_8

	mov TMP2, ul
	mov TMP3, um
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k4_8

A_Notzero_k4_8:
	mul	p4l, ul					; al * bl
	movw	TMP3:TMP2, r1:r0

B_Notzero_k4_8:
	mul	p4h, ul					; ah * bl
C_Notzero_k4_8:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p4l					; bh * al
D_Notzero_k4_8:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	sub TMP2, TMP4				;sub low16(result), high16(result)
	sbc TMP3, TMP5
	brsh mulmod216_end_k4_8		;if low16(result) <= high16(result)
	adiw TMP3:TMP2, 1			;    inc low16(result) 
mulmod216_end_k4_8:
	mov p4h, TMP3
	mov p4l, TMP2

	pop bl
	pop bh
	pop k4l_8
	pop k4h_8


;/
;/ Key Shift
;/

	lsr k8l
	ror k1h
	ror k1l
	ror k2h
	ror k2l
	ror k3h
	ror k3l
	ror k4h
	ror k4l
	ror k5h
	ror k5l
	ror k6h
	ror k6l
	ror k7h
	ror k7l
	ror k8h
	brcc keysh6
	ori k8l, $80
keysh6:


;/
;/ p1 x k1 --> p1
;/

	push k1h_8
	push k1l_8
	push bh
	push bl

	cp k1h_8, r0
	cpc k1l_8, r0
	brne prekeynotzero_k1_8

	mov TMP2, p1l
	mov TMP3, p1h
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k1_8

prekeynotzero_k1_8:
	clr r1
	inc r1
	clr uh
	clr um
	mov ul, r1
	clr bh
	mov bl, r1
	clr vh
	clr vm
	clr vl

pre_abcompare_k1_8:
	cp k1l_8, bl
	cpc k1h_8, bh
	brne pre_weiter_k1_8
	rjmp eukfinished_k1_8
pre_weiter_k1_8:
	bst k1l_8, 0			;if (A even)
	brts pre_anoteven_k1_8

	lsr k1h_8				;	A <- A/2
	ror k1l_8

	bst ul, 0			;	if (U uneven)
	brtc pre_u1even_k1_8

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

pre_u1even_k1_8:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp pre_abcompare_k1_8


pre_anoteven_k1_8:
	sub bl, k1l_8					;	B <- (B-A)/2
	sbc bh, k1h_8
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh
	
	add vl, r1			;	cause (V<0)
	adc vm, r0				;		V <- V+(2^16)+1
	adc vh, r1

	bst vl, 0					;	if (V uneven)
	brtc pre_veven_k1_8

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

pre_veven_k1_8:
	lsr vh						;	V <- V/2
	ror vm
	ror vl


abcompare_k1_8:
	cp k1l_8, bl
	cpc k1h_8, bh
	brne weiter_k1_8
	rjmp eukfinished_k1_8
weiter_k1_8:
	bst k1l_8, 0			;if (A even)
	brts anoteven_k1_8

	lsr k1h_8				;	A <- A/2
	ror k1l_8

	bst ul, 0			;	if (U uneven)
	brtc u1even_k1_8

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

u1even_k1_8:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k1_8


anoteven_k1_8:
	bst bl, 0			;if (B even)
	brts bnoteven_k1_8

	lsr bh				;	B <- B/2
	ror bl

	bst vl, 0					;	if (V uneven)
	brtc v1even_k1_8

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

v1even_k1_8:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k1_8

bnoteven_k1_8:
	cp k1h_8, bh			;if (A>B)
	brlo alowerthanb_k1_8
	brne ahigherthanb_k1_8
	cp k1l_8, bl
	brlo alowerthanb_k1_8
ahigherthanb_k1_8:
	sub k1l_8, bl			;	A <- (A-B)/2			
	sbc k1h_8, bh
	lsr k1h_8
	ror k1l_8

	sub ul, vl			;	U <- U-V
	sbc um, vm
	sbc uh, vh

	brpl upositive_k1_8		;	if (U<0)
	
	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

upositive_k1_8:
	bst ul, 0			;	if (U uneven)
	brtc ueven_k1_8

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

ueven_k1_8:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k1_8	


alowerthanb_k1_8:					;else
	sub bl, k1l_8					;	B <- (B-A)/2
	sbc bh, k1h_8
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh

	brpl vpositive_k1_8			;	if (V<0)
	
	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

vpositive_k1_8:
	bst vl, 0					;	if (V uneven)
	brtc veven_k1_8

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

veven_k1_8:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k1_8	

eukfinished_k1_8:

	mul	p1h, um					; ah * bh
	movw	TMP5:TMP4, r1:r0
	brne	A_Notzero_k1_8		; Go on if mul nonzero

	mul	p1l, ul
	movw	TMP3:TMP2, r1:r0
	brne	B_Notzero_k1_8		; Go on if mul nonzero

	mul	p1h, ul					; ah * bl
	brne	C_Notzero_k1_8		; Go on if mul nonzero
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p1l					; bh * al
	brne	D_Notzero_k1_8

	mov TMP2, ul
	mov TMP3, um
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k1_8

A_Notzero_k1_8:
	mul	p1l, ul					; al * bl
	movw	TMP3:TMP2, r1:r0

B_Notzero_k1_8:
	mul	p1h, ul					; ah * bl
C_Notzero_k1_8:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p1l					; bh * al
D_Notzero_k1_8:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	sub TMP2, TMP4				;sub low16(result), high16(result)
	sbc TMP3, TMP5
	brsh mulmod216_end_k1_8		;if low16(result) <= high16(result)
	adiw TMP3:TMP2, 1			;    inc low16(result) 
mulmod216_end_k1_8:
	mov p1h, TMP3
	mov p1l, TMP2

	pop bl
	pop bh
	pop k1l_8
	pop k1h_8


;/
;/ p3 + k3 --> p3
;/

	sub p3l_g, k3l_8
	sbc p3h_g, k3h_8


;/
;/ p1 XOR p3 --> i1
;/

	mov i1h, p1h
	mov i1l, p1l
	eor i1h, p3h_g
	eor i1l, p3l_g

;/
;/ i1 x k5 --> i1
;/

	mul	i1h, k5h_8					; ah * bh
	movw	TMP3:TMP2, r1:r0
	brne	A_Notzero_k5_8		; Go on if mul nonzero

	mul	i1l, k5l_8
	movw	TMP1:TMP0, r1:r0
	brne	B_Notzero_k5_8		; Go on if mul nonzero

	mul	i1h, k5l_8					; ah * bl
	brne	C_Notzero_k5_8		; Go on if mul nonzero
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k5h_8, i1l					; bh * al
	brne	D_Notzero_k5_8

	add TMP0, k5l_8
	breq keyzerotest_k5_8
	add TMP1, k5h_8
	rjmp negresult_k5_8
keyzerotest_k5_8:
	add TMP1, k5h_8
	brne negresult_k5_8

	mov TMP0, i1l
	mov TMP1, i1h

negresult_k5_8:
	neg TMP0
	clr r0
	adc TMP1, r0
	neg TMP1
	adiw TMP1:TMP0, 1
	
	rjmp mulmod216_end_k5_8

A_Notzero_k5_8:
	mul	i1l, k5l_8					; al * bl
	movw	TMP1:TMP0, r1:r0

B_Notzero_k5_8:
	mul	i1h, k5l_8					; ah * bl
C_Notzero_k5_8:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k5h_8, i1l					; bh * al
D_Notzero_k5_8:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	sub TMP0, TMP2				;sub low16(result), high16(result)
	sbc TMP1, TMP3
	brsh mulmod216_end_k5_8		;if low16(result) <= high16(result)
	adiw TMP1:TMP0, 1			;    inc low16(result) 
mulmod216_end_k5_8:
	mov i1h, TMP1
	mov i1l, TMP0


;/
;/ p2 XOR p4 --> i2
;/

	mov i2h, p2h_g
	mov i2l, p2l_g
	eor i2h, p4h
	eor i2l, p4l

;/
;/ i2 + i1 --> i2
;/

	add i2l, i1l
	adc i2h, i1h

;/
;/ i2 x k6 --> i2
;/

	push i1h
	push i1l

	mov i1h, i2h
	mov i1l, i2l

	mul	i1h, k6h_8					; ah * bh
	movw	TMP3:TMP2, r1:r0
	brne	A_Notzero_k6_8		; Go on if mul nonzero

	mul	i1l, k6l_8
	movw	TMP1:TMP0, r1:r0
	brne	B_Notzero_k6_8		; Go on if mul nonzero

	mul	i1h, k6l_8					; ah * bl
	brne	C_Notzero_k6_8		; Go on if mul nonzero
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k6h_8, i1l					; bh * al
	brne	D_Notzero_k6_8

	add TMP0, k6l_8
	breq keyzerotest_k6_8
	add TMP1, k6h_8
	rjmp negresult_k6_8
keyzerotest_k6_8:
	add TMP1, k6h_8
	brne negresult_k6_8

	mov TMP0, i1l
	mov TMP1, i1h

negresult_k6_8:
	neg TMP0
	clr r0
	adc TMP1, r0
	neg TMP1
	adiw TMP1:TMP0, 1
	
	rjmp mulmod216_end_k6_8

A_Notzero_k6_8:
	mul	i1l, k6l_8					; al * bl
	movw	TMP1:TMP0, r1:r0

B_Notzero_k6_8:
	mul	i1h, k6l_8					; ah * bl
C_Notzero_k6_8:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	mul	k6h_8, i1l					; bh * al
D_Notzero_k6_8:
	add	TMP1, r0
	adc	TMP2, r1
	clr r0
	adc	TMP3, r0

	sub TMP0, TMP2				;sub low16(result), high16(result)
	sbc TMP1, TMP3
	brsh mulmod216_end_k6_8		;if low16(result) <= high16(result)
	adiw TMP1:TMP0, 1			;    inc low16(result) 
mulmod216_end_k6_8:
	mov i2h, TMP1
	mov i2l, TMP0

	pop i1l
	pop i1h 

;/
;/ i1 + i2 --> i1
;/

	add i1l, i2l
	adc i1h, i2h

;/
;/ p1 XOR i2 --> p1
;/

	eor p1h, i2h
	eor p1l, i2l

;/
;/ p3 XOR i2 --> p3
;/

	eor p3h_g, i2h
	eor p3l_g, i2l

;/
;/ p2 XOR i1 --> p2
;/

	eor p2h_g, i1h
	eor p2l_g, i1l

;/
;/ p4 XOR i1 --> p4
;/

	eor p4h, i1h
	eor p4l, i1l


;--------------------------------------------------------------
;                               Round 9
;--------------------------------------------------------------



;/
;/ p1 x k1 --> p1
;/

	push bh
	push bl

	cp k1h_9, r0
	cpc k1l_9, r0
	brne prekeynotzero_k1_9

	mov TMP2, p1l
	mov TMP3, p1h
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k1_9

prekeynotzero_k1_9:
	clr r1
	inc r1
	clr uh
	clr um
	mov ul, r1
	clr bh
	mov bl, r1
	clr vh
	clr vm
	clr vl

pre_abcompare_k1_9:
	cp k1l_9, bl
	cpc k1h_9, bh
	brne pre_weiter_k1_9
	rjmp eukfinished_k1_9
pre_weiter_k1_9:
	bst k1l_9, 0			;if (A even)
	brts pre_anoteven_k1_9

	lsr k1h_9				;	A <- A/2
	ror k1l_9

	bst ul, 0			;	if (U uneven)
	brtc pre_u1even_k1_9

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

pre_u1even_k1_9:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp pre_abcompare_k1_9


pre_anoteven_k1_9:
	sub bl, k1l_9					;	B <- (B-A)/2
	sbc bh, k1h_9
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh
	
	add vl, r1			;	cause (V<0)
	adc vm, r0				;		V <- V+(2^16)+1
	adc vh, r1

	bst vl, 0					;	if (V uneven)
	brtc pre_veven_k1_9

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

pre_veven_k1_9:
	lsr vh						;	V <- V/2
	ror vm
	ror vl


abcompare_k1_9:
	cp k1l_9, bl
	cpc k1h_9, bh
	brne weiter_k1_9
	rjmp eukfinished_k1_9
weiter_k1_9:
	bst k1l_9, 0			;if (A even)
	brts anoteven_k1_9

	lsr k1h_9				;	A <- A/2
	ror k1l_9

	bst ul, 0			;	if (U uneven)
	brtc u1even_k1_9

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

u1even_k1_9:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k1_9


anoteven_k1_9:
	bst bl, 0			;if (B even)
	brts bnoteven_k1_9

	lsr bh				;	B <- B/2
	ror bl

	bst vl, 0					;	if (V uneven)
	brtc v1even_k1_9

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

v1even_k1_9:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k1_9

bnoteven_k1_9:
	cp k1h_9, bh			;if (A>B)
	brlo alowerthanb_k1_9
	brne ahigherthanb_k1_9
	cp k1l_9, bl
	brlo alowerthanb_k1_9
ahigherthanb_k1_9:
	sub k1l_9, bl			;	A <- (A-B)/2			
	sbc k1h_9, bh
	lsr k1h_9
	ror k1l_9

	sub ul, vl			;	U <- U-V
	sbc um, vm
	sbc uh, vh

	brpl upositive_k1_9		;	if (U<0)
	
	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

upositive_k1_9:
	bst ul, 0			;	if (U uneven)
	brtc ueven_k1_9

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

ueven_k1_9:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k1_9	


alowerthanb_k1_9:					;else
	sub bl, k1l_9					;	B <- (B-A)/2
	sbc bh, k1h_9
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh

	brpl vpositive_k1_9			;	if (V<0)
	
	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

vpositive_k1_9:
	bst vl, 0					;	if (V uneven)
	brtc veven_k1_9

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

veven_k1_9:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k1_9	

eukfinished_k1_9:

	mul	p1h, um					; ah * bh
	movw	TMP5:TMP4, r1:r0
	brne	A_Notzero_k1_9		; Go on if mul nonzero

	mul	p1l, ul
	movw	TMP3:TMP2, r1:r0
	brne	B_Notzero_k1_9		; Go on if mul nonzero

	mul	p1h, ul					; ah * bl
	brne	C_Notzero_k1_9		; Go on if mul nonzero
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p1l					; bh * al
	brne	D_Notzero_k1_9

	mov TMP2, ul
	mov TMP3, um
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k1_9

A_Notzero_k1_9:
	mul	p1l, ul					; al * bl
	movw	TMP3:TMP2, r1:r0

B_Notzero_k1_9:
	mul	p1h, ul					; ah * bl
C_Notzero_k1_9:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p1l					; bh * al
D_Notzero_k1_9:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	sub TMP2, TMP4				;sub low16(result), high16(result)
	sbc TMP3, TMP5
	brsh mulmod216_end_k1_9		;if low16(result) <= high16(result)
	adiw TMP3:TMP2, 1			;    inc low16(result) 
mulmod216_end_k1_9:
	mov p1h, TMP3
	mov p1l, TMP2

;/
;/ p2 + k2 --> p2
;/

	sub p2l_g, k2l_9
	sbc p2h_g, k2h_9


;/
;/ p4 x k4 --> p4
;/

	cp k4h_9, r0
	cpc k4l_9, r0
	brne prekeynotzero_k4_9

	mov TMP2, p4l
	mov TMP3, p4h
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k4_9

prekeynotzero_k4_9:
	clr r1
	inc r1
	clr uh
	clr um
	mov ul, r1
	clr bh
	mov bl, r1
	clr vh
	clr vm
	clr vl

pre_abcompare_k4_9:
	cp k4l_9, bl
	cpc k4h_9, bh
	brne pre_weiter_k4_9
	rjmp eukfinished_k4_9
pre_weiter_k4_9:
	bst k4l_9, 0			;if (A even)
	brts pre_anoteven_k4_9

	lsr k4h_9				;	A <- A/2
	ror k4l_9

	bst ul, 0			;	if (U uneven)
	brtc pre_u1even_k4_9

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

pre_u1even_k4_9:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp pre_abcompare_k4_9


pre_anoteven_k4_9:
	sub bl, k4l_9					;	B <- (B-A)/2
	sbc bh, k4h_9
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh
	
	add vl, r1			;	cause (V<0)
	adc vm, r0				;		V <- V+(2^16)+1
	adc vh, r1

	bst vl, 0					;	if (V uneven)
	brtc pre_veven_k4_9

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

pre_veven_k4_9:
	lsr vh						;	V <- V/2
	ror vm
	ror vl


abcompare_k4_9:
	cp k4l_9, bl
	cpc k4h_9, bh
	brne weiter_k4_9
	rjmp eukfinished_k4_9
weiter_k4_9:
	bst k4l_9, 0			;if (A even)
	brts anoteven_k4_9

	lsr k4h_9				;	A <- A/2
	ror k4l_9

	bst ul, 0			;	if (U uneven)
	brtc u1even_k4_9

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

u1even_k4_9:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k4_9


anoteven_k4_9:
	bst bl, 0			;if (B even)
	brts bnoteven_k4_9

	lsr bh				;	B <- B/2
	ror bl

	bst vl, 0					;	if (V uneven)
	brtc v1even_k4_9

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

v1even_k4_9:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k4_9

bnoteven_k4_9:
	cp k4h_9, bh			;if (A>B)
	brlo alowerthanb_k4_9
	brne ahigherthanb_k4_9
	cp k4l_9, bl
	brlo alowerthanb_k4_9
ahigherthanb_k4_9:
	sub k4l_9, bl			;	A <- (A-B)/2			
	sbc k4h_9, bh
	lsr k4h_9
	ror k4l_9

	sub ul, vl			;	U <- U-V
	sbc um, vm
	sbc uh, vh

	brpl upositive_k4_9		;	if (U<0)
	
	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

upositive_k4_9:
	bst ul, 0			;	if (U uneven)
	brtc ueven_k4_9

	adiw um:ul, 1			;		U <- (2^16)+1
	adc uh, r1

ueven_k4_9:
	lsr uh							;	U <- U/2
	ror um
	ror ul

	rjmp abcompare_k4_9	


alowerthanb_k4_9:					;else
	sub bl, k4l_9					;	B <- (B-A)/2
	sbc bh, k4h_9
	lsr bh
	ror bl

	sub vl, ul					;	V <- V-U
	sbc vm, um
	sbc vh, uh

	brpl vpositive_k4_9			;	if (V<0)
	
	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

vpositive_k4_9:
	bst vl, 0					;	if (V uneven)
	brtc veven_k4_9

	adiw vm:vl, 1				;		V <- V+(2^16)+1
	adc vh, r1

veven_k4_9:
	lsr vh						;	V <- V/2
	ror vm
	ror vl

	rjmp abcompare_k4_9	

eukfinished_k4_9:

	mul	p4h, um					; ah * bh
	movw	TMP5:TMP4, r1:r0
	brne	A_Notzero_k4_9		; Go on if mul nonzero

	mul	p4l, ul
	movw	TMP3:TMP2, r1:r0
	brne	B_Notzero_k4_9		; Go on if mul nonzero

	mul	p4h, ul					; ah * bl
	brne	C_Notzero_k4_9		; Go on if mul nonzero
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p4l					; bh * al
	brne	D_Notzero_k4_9

	mov TMP2, ul
	mov TMP3, um
	neg TMP2
	clr r0
	adc TMP3, r0
	neg TMP3
	adiw TMP3:TMP2, 1
	
	rjmp mulmod216_end_k4_9

A_Notzero_k4_9:
	mul	p4l, ul					; al * bl
	movw	TMP3:TMP2, r1:r0

B_Notzero_k4_9:
	mul	p4h, ul					; ah * bl
C_Notzero_k4_9:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	mul	um, p4l					; bh * al
D_Notzero_k4_9:
	add	TMP3, r0
	adc	TMP4, r1
	clr r0
	adc	TMP5, r0

	sub TMP2, TMP4				;sub low16(result), high16(result)
	sbc TMP3, TMP5
	brsh mulmod216_end_k4_9		;if low16(result) <= high16(result)
	adiw TMP3:TMP2, 1			;    inc low16(result) 
mulmod216_end_k4_9:
	mov p4h, TMP3
	mov p4l, TMP2

	pop bl
	pop bh

;/
;/ p3 + k3 --> p3
;/

	sub p3l_g, k3l_9
	sbc p3h_g, k3h_9

	pop xl
	pop xh

	st x+, p1h
	st x+, p1l
	st x+, p2h_g
	st x+, p2l_g
	st x+, p3h_g
	st x+, p3l_g
	st x+, p4h
	st x+, p4l

	ret

.exit
