// File: /workspace/github_cpp_makefile_star2_O2/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 $0x48, %rsp
movl %ecx, %ebx
movl %esi, %eax
testl %ecx, %ecx
setne %cl
testb $0xf, %bl
sete %sil
testb %sil, %cl
je 0x6617
cmpl %ebx, %eax
jge 0x6631
leaq 0x1df8(%rip), %rsi      # 0x83fe
xorl %edi, %edi
movl %eax, %edx
movl %ebx, %ecx
xorl %eax, %eax
callq 0x262c
pushq $-0x2
jmp 0x662b
leaq 0x1db7(%rip), %rsi      # 0x83d5
xorl %edi, %edi
movl %ebx, %edx
xorl %eax, %eax
callq 0x262c
pushq $-0x1
popq %rbx
jmp 0x675b
movq %r9, %r12
movq %r8, %r13
movq %rdi, %r14
movslq %ebx, %rax
movq %rdx, %rsi
movq %rax, %rdx
callq 0x2160
xorl %r15d, %r15d
xorl %edi, %edi
callq 0x21a0
movl %eax, %edi
callq 0x21d0
cmpq $0x10, %r15
je 0x6671
callq 0x2090
movb %al, (%r12,%r15)
movb %al, (%rsp,%r15)
incq %r15
jmp 0x6659
movq %rsp, %rax
movaps (%rax), %xmm0
leaq 0x30(%rsp), %rdi
movaps %xmm0, (%rdi)
movq %r13, %rsi
callq 0x6130
sarl $0x4, %ebx
xorl %ebp, %ebp
testl %ebx, %ebx
cmovlel %ebp, %ebx
movq %r14, %r15
cmpq %rbx, %rbp
je 0x66d5
movq %rsp, %rdi
callq 0x676c
movaps (%rsp), %xmm0
movaps %xmm0, 0x20(%rsp)
leaq 0x20(%rsp), %rdi
movq %r13, %rsi
callq 0x6130
xorl %eax, %eax
cmpq $0x10, %rax
je 0x66cc
movb 0x20(%rsp,%rax), %cl
xorb %cl, (%r15,%rax)
incq %rax
jmp 0x66b9
incq %rbp
addq $0x10, %r15
jmp 0x6694
leaq 0x30(%rsp), %rdi
callq 0x6541
movq %r12, %rdi
movq 0x80(%rsp), %r13
movq %r13, %rsi
callq 0x677d
xorl %r15d, %r15d
leaq 0x10(%rsp), %r12
cmpq %rbx, %r15
je 0x6732
movups (%r13), %xmm0
movaps %xmm0, 0x10(%rsp)
xorl %eax, %eax
cmpq $0x10, %rax
je 0x671e
movb (%r14,%rax), %cl
xorb %cl, 0x10(%rsp,%rax)
incq %rax
jmp 0x670b
movq %r12, %rdi
movq %r13, %rsi
callq 0x677d
incq %r15
addq $0x10, %r14
jmp 0x66fa
xorl %eax, %eax
cmpq $0x10, %rax
je 0x6748
movb 0x30(%rsp,%rax), %cl
xorb %cl, (%r13,%rax)
incq %rax
jmp 0x6734
leaq 0x1cff(%rip), %rsi      # 0x844e
xorl %ebx, %ebx
pushq $0x3
popq %rdi
xorl %eax, %eax
callq 0x262c
movl %ebx, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq