bits 64
global _start

_start:
		push rbp
		push rsp
		push rbx
		push r12
		push r13
		push r14
		push r15

		push rax
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		push r9
		push r10
		push r11

		mov rdi, 1
		lea     rsi, [rel msg]
		mov rbx, rsi
		sub rbx, qword [rel text_section] ;text_section address because of this and that
		mov r8, qword [rel section_size] ;text_section size
		shr r8, 2
		inc r8
		mov r9, 0 ;increment register
		mov r10, 0 ;increment register
		xor r10, r10
		xor r13, r13
		mov r13d, dword [rel private_key]
		xor r12, r12
		mov r12d, dword [rel private_key + 4]
		;shr r12, 32
		push r13 ; push rsa.d
		push r12 ; push rsa.n
		jmp decrypt_loop

	; rbx is adress of text(encrypted) section
	; r8 is section size
	; r9 is index
	; rax is cypher that needs to be converted to message
	; dword [rsp + 16] is rsa.d
	; dword [rsp + 8] is rsa.n
	; qword [rsp] is cypher backup
	decrypt_once:
		mov r11, 0x100000000
	sq_mul_bit_index:
		shr r11, 1
		mov r12, r11
		and r12, qword [rsp + 16]
		jz sq_mul_bit_index
	sq_mul_loop:
		; check if pow is zero
		shr r11, 1
		cmp r11, 0
		je decrypt_loop2
		; square ...
		mul rax,
		; modulo n ...
		mov r13, qword [rsp + 8]
		xor rdx, rdx
		div r13
		mov rax, rdx
		; ... and multiply
		mov r12, r11
		and r12, qword [rsp + 16]
		cmp r12, 0
		je sq_mul_loop
		mov r13, qword [rsp]
		mul r13
		; modulo n ...
		mov r13, qword [rsp + 8]
		xor rdx, rdx
		div r13
		mov rax, rdx
		; end of loop
		jmp sq_mul_loop

	decrypt_loop:
		cmp r8, r10
		je end_decrypt
		xor rax, rax
		mov eax, dword [rbx + r9]
		push rax
		;push r10
		jmp decrypt_once
	decrypt_loop2:
		sub rax, 42 ; remove 42 of result (avoid 0 values)
		sub rax, r10 ; remove index of result (caesar like cypher so 0/42 values are differents)
		; unpadding and write back here
		mov dword [rbx + r9], 0
		mov r15, r10
		shr r15, 5
		shl r15, 2
		mov rcx, r10
		shl rcx, 59
		shr rcx, 59
		inc rcx
		shl rax, cl
		mov r14, r9
		sub r14, r15
		add [rbx + r14], eax
		shr rax, 32
		cmp r9, 0
		je first_block_skip
		add [rbx + r14 - 4], eax

	first_block_skip:
		; unpadding and write back here
		pop rax
		add r9, 4
		inc r10
		jmp decrypt_loop

	end_decrypt:
		mov rdx, 14
		mov rax, 1
		syscall

		pop r12 ; pop rsa.n
		pop r12 ; pop rsa.d

		pop r11
		pop r10
		pop r9
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rax

		pop r15
		pop r14
		pop r13
		pop r12
		pop rbx
		pop rsp
		pop rbp

        jmp 0xdadadada ; this needs to be just before that
		msg     db "....WOODY....",10 ; that needs to be just after this
		text_section      dq 0xbabababababababa
		section_size     dq 0xcacacacacacacaca
		private_key       dq 0xabcdefabcdefabcd