// File: /workspace/github_cpp_makefile_star2_O3/renzibei[P]TSProxy/aes.cpp
// Function: encode(char*, int, char const*, int, char const (&) [16], char (&) [16], char (&) [16])
int encode(char *dst, int dst_size, const char *src, int src_size, const char (&key)[16], char (&random)[16], char (&mac)[16]) {
	if(src_size == 0 || src_size % 16 != 0) {
		// printf("data len should be 16*n");
		LogHelper::log(Error, "src len should be 16*n, but src_size: %d", src_size);
		return -1;
	}
	if (dst_size < src_size) {
		LogHelper::log(Error, "dst_size should be at least the same as src_size, but dst_size: %, src_size: %d", dst_size, src_size);
		return -2;
	}

	memcpy(dst, src, src_size);

	srand((unsigned int)time((time_t *)NULL));
	// 生成随机计数器初始值
	// char* copy = (char*) malloc((16) * sizeof(char));
	char copy[16];
	int i, j;
	for(i=0; i<16; i++){
		copy[i] = random[i] = (char)rand();
	}
	// 计算h
	// char* h = (char*) malloc((16) * sizeof(char));
	char h[16];
	// strCopy(h, copy);
	memcpy(h, copy, 16);
	aes(h, key);

	// 加密 len/16 组数据，得到密文
	char ctr[16];
	for(i=0; i< (src_size >> 4); i++){
		ctrAdd(copy);	// 计数器 +1
		// char* ctr = (char*) malloc((16) * sizeof(char));
		memcpy(ctr, copy, sizeof(ctr));
		// strCopy(ctr, copy);
		aes(ctr, key);
		// 对该组数据的16个字节分别进行异或操作
		for(j=0; j<16; j++){
			dst[(i << 4) + j] = dst[ (i << 4) + j] ^ ctr[j];
		}
	}

	// 计算 mac 值
	compute_hh((Uchar16 &)h);
	// 第一次GF乘法
	mult_h((Uchar16 &)random, (Uchar16 &)mac);
	// 对每组密文进行一次
	char lastResult[16];
	for(i=0; i< (src_size >> 4); i++){
		// char* lastResult = (char*) malloc((16) * sizeof(char));
		// strCopy(lastResult, mac);
		memcpy(lastResult, mac, sizeof(lastResult));
		// 对该组密文的16个字节分别进行异或操作
		for(j=0; j<16; j++){
			lastResult[j] = lastResult[j] ^ dst[ (i << 4) + j];
		}
		mult_h((Uchar16 &)lastResult, (Uchar16 &)mac);
	}
	// 与h进行异或操作
	for(j=0; j<16; j++){
		mac[j] = mac[j] ^ h[j];
	}
	// printf("finish encode\n");
	LogHelper::log(Debug, "finish encode");
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %ecx, %ebp
movl %esi, %eax
testl %ecx, %ecx
setne %cl
testb $0xf, %bpl
sete %sil
testb %sil, %cl
je 0x65ad
cmpl %ebp, %eax
jge 0x65c9
leaq 0x1e68(%rip), %rsi      # 0x83fe
xorl %edi, %edi
movl %eax, %edx
movl %ebp, %ecx
xorl %eax, %eax
callq 0x273c
movl $0xfffffffe, %ebx       # imm = 0xFFFFFFFE
jmp 0x671e
leaq 0x1e21(%rip), %rsi      # 0x83d5
xorl %edi, %edi
movl %ebp, %edx
xorl %eax, %eax
callq 0x273c
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
jmp 0x671e
movq %r9, %r15
movq %r8, %r12
movq %rdi, %r14
movq 0x90(%rsp), %r13
movslq %ebp, %rax
movq %rdx, %rsi
movq %rax, %rdx
callq 0x2150
xorl %ebx, %ebx
xorl %edi, %edi
callq 0x2190
movl %eax, %edi
callq 0x21c0
callq 0x2090
movb %al, (%r15,%rbx)
movb %al, 0x10(%rsp,%rbx)
incq %rbx
cmpq $0x10, %rbx
jne 0x65f8
movaps 0x10(%rsp), %xmm0
leaq 0x20(%rsp), %rdi
movaps %xmm0, (%rdi)
movq %r12, %rsi
callq 0x60a0
sarl $0x4, %ebp
testl %ebp, %ebp
jle 0x66e5
movl %ebp, 0xc(%rsp)
movl %ebp, %ebx
xorl %ebp, %ebp
leaq 0x40(%rsp), %r13
movl $0xf, %eax
movl %eax, %edx
movb 0x10(%rsp,%rdx), %cl
incb %cl
movb %cl, 0x10(%rsp,%rdx)
subl $0x1, %eax
jb 0x6655
testb %cl, %cl
je 0x6640
movaps 0x10(%rsp), %xmm0
movaps %xmm0, 0x40(%rsp)
movq %r13, %rdi
movq %r12, %rsi
callq 0x60a0
movq %rbp, %rax
shlq $0x4, %rax
movups (%r14,%rax), %xmm0
xorps 0x40(%rsp), %xmm0
movups %xmm0, (%r14,%rax)
incq %rbp
cmpq %rbx, %rbp
jne 0x663b
leaq 0x20(%rsp), %rdi
callq 0x64de
movq %r15, %rdi
movq 0x90(%rsp), %r13
movq %r13, %rsi
callq 0x672f
cmpl $0x0, 0xc(%rsp)
jle 0x66fa
shlq $0x4, %rbx
xorl %r12d, %r12d
leaq 0x30(%rsp), %r15
movups (%r13), %xmm0
movaps %xmm0, 0x30(%rsp)
movups (%r14,%r12), %xmm1
xorps %xmm0, %xmm1
movaps %xmm1, 0x30(%rsp)
movq %r15, %rdi
movq %r13, %rsi
callq 0x672f
addq $0x10, %r12
cmpq %r12, %rbx
jne 0x66b8
jmp 0x66fa
leaq 0x20(%rsp), %rdi
callq 0x64de
movq %r15, %rdi
movq %r13, %rsi
callq 0x672f
movups (%r13), %xmm0
xorps 0x20(%rsp), %xmm0
movups %xmm0, (%r13)
leaq 0x1d3e(%rip), %rsi      # 0x844e
xorl %ebx, %ebx
movl $0x3, %edi
xorl %eax, %eax
callq 0x273c
movl %ebx, %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq