// File: SamKG[P]Flush-Reload-Sidechannel/receiver.cpp
// Function: main
int main(int argc, char **argv)
{
	// Put your covert channel setup code here
	int fd = open("sender",O_RDONLY);
	char* mapped = (char*) mmap(NULL, 0x20000, PROT_READ, MAP_PRIVATE, fd, 0);
	// I think using uint64_t prevents prefetching
	int num_ptrs = 0;
	ADDR_PTR probe_ptrs[100];
	int mult = 15;
	probe_ptrs[num_ptrs++] = (uint64_t)(mapped + ADDR_0 + mult*CACHE_LINE_SIZE);
	probe_ptrs[num_ptrs++] = (uint64_t)(mapped + ADDR_1 + mult*CACHE_LINE_SIZE);
	probe_ptrs[num_ptrs++] = (uint64_t)(mapped + ADDR_2 + mult*CACHE_LINE_SIZE);
	probe_ptrs[num_ptrs++] = (uint64_t)(mapped + ADDR_3 + mult*CACHE_LINE_SIZE);
	probe_ptrs[num_ptrs++] = (uint64_t)(mapped + ADDR_4 + mult*CACHE_LINE_SIZE);
	probe_ptrs[num_ptrs++] = (uint64_t)(mapped + ADDR_5 + mult*CACHE_LINE_SIZE);
	probe_ptrs[num_ptrs++] = (uint64_t)(mapped + ADDR_6 + mult*CACHE_LINE_SIZE);
	probe_ptrs[num_ptrs++] = (uint64_t)(mapped + ADDR_7 + mult*CACHE_LINE_SIZE);
	probe_ptrs[num_ptrs++] = (uint64_t)(mapped + ADDR_8 + mult*CACHE_LINE_SIZE);
	printf("Please press enter.\n");

	char text_buf[2];
	fgets(text_buf, sizeof(text_buf), stdin);

	printf("Receiver now listening.\n");
	int hitcnt = 0;
	bool listening = true;
	int hits[100];
	while (listening) {
		//spy flushes
		for (int i = 0 ; i < 100 ; i++){
			hits[i] = 0;
		}
		//spy waits TIME_SLOT time
		for (int i = 0 ; i < SLOT_WINDOW_COUNT;  i++){
			for (int i = 0 ; i < num_ptrs ; i++){
				flush_one_block(probe_ptrs[i]);
			}
			CYCLES start_t = get_highres_time();
			while(get_highres_time() - start_t <= TIME_SLOT){
			}
			//spy reloads
			for (int i = 0 ; i < num_ptrs ; i++){
				CYCLES time = probe_one_block(probe_ptrs[i]);
				if ( time < TIME_CUTOFF){
					hits[i]++;
					//printf("HIT %d\t%d\t%d\n",i,hitcnt++,time);
				}
			}
		}
		
		if (hits[0] >= SLOT_HIT_CUTOFF){
			// 0 bit means we have a message!
			int bitstr = 0;
			for (int i = 1 ; i < num_ptrs ; i++){
				if (hits[i] >= SLOT_HIT_CUTOFF){
					//printf("HIT BIT %d\n",i);
					bitstr |= 1<<(i-1);	
				}
			}
			printf("%c",(char)bitstr);
			fflush(stdout);
		}

	}

	printf("Receiver finished.\n");

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x520, %rsp            # imm = 0x520
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq 0xe64(%rip), %rdi       # 0x2004
xorl %esi, %esi
movb $0x0, %al
callq 0x1040
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %r8d
xorl %eax, %eax
movl %eax, %r9d
movl $0x20000, %esi          # imm = 0x20000
movl $0x1, %edx
movl $0x2, %ecx
movq %r9, %rdi
callq 0x1070
movq %rax, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
movl $0xf, -0x354(%rbp)
movq -0x20(%rbp), %rcx
addq $0x1176, %rcx           # imm = 0x1176
movl -0x354(%rbp), %eax
shll $0x6, %eax
cltq
addq %rax, %rcx
movl -0x24(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x24(%rbp)
cltq
movq %rcx, -0x350(%rbp,%rax,8)
movq -0x20(%rbp), %rcx
addq $0x22fd, %rcx           # imm = 0x22FD
movl -0x354(%rbp), %eax
shll $0x6, %eax
cltq
addq %rax, %rcx
movl -0x24(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x24(%rbp)
cltq
movq %rcx, -0x350(%rbp,%rax,8)
movq -0x20(%rbp), %rcx
addq $0x3484, %rcx           # imm = 0x3484
movl -0x354(%rbp), %eax
shll $0x6, %eax
cltq
addq %rax, %rcx
movl -0x24(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x24(%rbp)
cltq
movq %rcx, -0x350(%rbp,%rax,8)
movq -0x20(%rbp), %rcx
addq $0x460b, %rcx           # imm = 0x460B
movl -0x354(%rbp), %eax
shll $0x6, %eax
cltq
addq %rax, %rcx
movl -0x24(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x24(%rbp)
cltq
movq %rcx, -0x350(%rbp,%rax,8)
movq -0x20(%rbp), %rcx
addq $0x5792, %rcx           # imm = 0x5792
movl -0x354(%rbp), %eax
shll $0x6, %eax
cltq
addq %rax, %rcx
movl -0x24(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x24(%rbp)
cltq
movq %rcx, -0x350(%rbp,%rax,8)
movq -0x20(%rbp), %rcx
addq $0x6919, %rcx           # imm = 0x6919
movl -0x354(%rbp), %eax
shll $0x6, %eax
cltq
addq %rax, %rcx
movl -0x24(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x24(%rbp)
cltq
movq %rcx, -0x350(%rbp,%rax,8)
movq -0x20(%rbp), %rcx
addq $0x7aa0, %rcx           # imm = 0x7AA0
movl -0x354(%rbp), %eax
shll $0x6, %eax
cltq
addq %rax, %rcx
movl -0x24(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x24(%rbp)
cltq
movq %rcx, -0x350(%rbp,%rax,8)
movq -0x20(%rbp), %rcx
addq $0x8c27, %rcx           # imm = 0x8C27
movl -0x354(%rbp), %eax
shll $0x6, %eax
cltq
addq %rax, %rcx
movl -0x24(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x24(%rbp)
cltq
movq %rcx, -0x350(%rbp,%rax,8)
movq -0x20(%rbp), %rcx
addq $0x9dae, %rcx           # imm = 0x9DAE
movl -0x354(%rbp), %eax
shll $0x6, %eax
cltq
addq %rax, %rcx
movl -0x24(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x24(%rbp)
cltq
movq %rcx, -0x350(%rbp,%rax,8)
leaq 0xc85(%rip), %rdi       # 0x200b
movb $0x0, %al
callq 0x1030
leaq -0x356(%rbp), %rdi
movq 0x2c45(%rip), %rax      # 0x3fe0
movq (%rax), %rdx
movl $0x2, %esi
callq 0x1060
leaq 0xc71(%rip), %rdi       # 0x2020
movb $0x0, %al
callq 0x1030
movl $0x0, -0x35c(%rbp)
movb $0x1, -0x35d(%rbp)
testb $0x1, -0x35d(%rbp)
je 0x1597
movl $0x0, -0x4f4(%rbp)
cmpl $0x64, -0x4f4(%rbp)
jge 0x140a
movslq -0x4f4(%rbp), %rax
movl $0x0, -0x4f0(%rbp,%rax,4)
movl -0x4f4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4f4(%rbp)
jmp 0x13de
movl $0x0, -0x4f8(%rbp)
cmpl $0xa, -0x4f8(%rbp)
jge 0x1500
movl $0x0, -0x4fc(%rbp)
movl -0x4fc(%rbp), %eax
cmpl -0x24(%rbp), %eax
jge 0x145b
movslq -0x4fc(%rbp), %rax
movq -0x350(%rbp,%rax,8), %rdi
callq 0x1680
movl -0x4fc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4fc(%rbp)
jmp 0x142b
callq 0x15e0
movq %rax, -0x508(%rbp)
callq 0x15e0
movq -0x508(%rbp), %rcx
subq %rcx, %rax
cmpq $0x9c4, %rax            # imm = 0x9C4
ja 0x1480
jmp 0x1467
movl $0x0, -0x50c(%rbp)
movl -0x50c(%rbp), %eax
cmpl -0x24(%rbp), %eax
jge 0x14ea
movslq -0x50c(%rbp), %rax
movq -0x350(%rbp,%rax,8), %rdi
callq 0x1610
movq %rax, -0x518(%rbp)
movq -0x518(%rbp), %rax
cmpq $0xc8, %rax
jae 0x14d7
movslq -0x50c(%rbp), %rax
movl -0x4f0(%rbp,%rax,4), %ecx
addl $0x1, %ecx
movl %ecx, -0x4f0(%rbp,%rax,4)
jmp 0x14d9
movl -0x50c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50c(%rbp)
jmp 0x148a
jmp 0x14ec
movl -0x4f8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4f8(%rbp)
jmp 0x1414
cmpl $0x2, -0x4f0(%rbp)
jl 0x1592
movl $0x0, -0x51c(%rbp)
movl $0x1, -0x520(%rbp)
movl -0x520(%rbp), %eax
cmpl -0x24(%rbp), %eax
jge 0x156c
movslq -0x520(%rbp), %rax
cmpl $0x2, -0x4f0(%rbp,%rax,4)
jl 0x1559
movl -0x520(%rbp), %ecx
subl $0x1, %ecx
movl $0x1, %eax
shll %cl, %eax
orl -0x51c(%rbp), %eax
movl %eax, -0x51c(%rbp)
jmp 0x155b
movl -0x520(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x520(%rbp)
jmp 0x1521
movl -0x51c(%rbp), %eax
movsbl %al, %esi
leaq 0xabd(%rip), %rdi       # 0x2039
movb $0x0, %al
callq 0x1030
movq 0x2a3e(%rip), %rax      # 0x3fc8
movq (%rax), %rdi
callq 0x1050
jmp 0x13c7
leaq 0xa9e(%rip), %rdi       # 0x203c
movb $0x0, %al
callq 0x1030
xorl %eax, %eax
addq $0x520, %rsp            # imm = 0x520
popq %rbp
retq