// File: /workspace/github_c_makefile_star2_O3/janmojzis[P]mcencrypt/pk_gen.c
// Function: pk_gen
int pk_gen(unsigned char * pk, unsigned char * sk)
{
	int i, j, k;
	int row, c;

	unsigned char mat[ GFBITS * SYS_T ][ SYS_N/8 ];
	unsigned char mask;
	unsigned char b;

	gf g[ SYS_T+1 ];
	gf L[ SYS_N ];
	gf inv[ SYS_N ];

	/* // */

	g[ SYS_T ] = 1;

	for (i = 0; i < SYS_T; i++) { g[i] = load2(sk); g[i] &= GFMASK; sk += 2; }

	support_gen(L, sk);

	root(inv, g, L);
		
	for (i = 0; i < SYS_N; i++)
		inv[i] = gf_inv(inv[i]);

	/* // */

	for (i = 0; i < PK_NROWS; i++)
	for (j = 0; j < SYS_N/8; j++)
		mat[i][j] = 0;

	for (i = 0; i < SYS_T; i++)
	{
		for (j = 0; j < SYS_N; j+=8)
		for (k = 0; k < GFBITS;  k++)
		{
			b  = (inv[j+7] >> k) & 1; b <<= 1;
			b |= (inv[j+6] >> k) & 1; b <<= 1;
			b |= (inv[j+5] >> k) & 1; b <<= 1;
			b |= (inv[j+4] >> k) & 1; b <<= 1;
			b |= (inv[j+3] >> k) & 1; b <<= 1;
			b |= (inv[j+2] >> k) & 1; b <<= 1;
			b |= (inv[j+1] >> k) & 1; b <<= 1;
			b |= (inv[j+0] >> k) & 1;

			mat[ i*GFBITS + k ][ j/8 ] = b;
		}

		for (j = 0; j < SYS_N; j++)
			inv[j] = gf_mul(inv[j], L[j]);

	}

	/* // */

	for (i = 0; i < (GFBITS * SYS_T + 7) / 8; i++)
	for (j = 0; j < 8; j++)
	{
		row = i*8 + j;			

		if (row >= GFBITS * SYS_T)
			break;

		for (k = row + 1; k < GFBITS * SYS_T; k++)
		{
			mask = mat[ row ][ i ] ^ mat[ k ][ i ];
			mask >>= j;
			mask &= 1;
			mask = -mask;

			for (c = 0; c < SYS_N/8; c++)
				mat[ row ][ c ] ^= mat[ k ][ c ] & mask;
		}

		if ( ((mat[ row ][ i ] >> j) & 1) == 0 ) /* // return if not systematic */
		{
			return -1;
		}

		for (k = 0; k < GFBITS * SYS_T; k++)
		{
			if (k != row)
			{
				mask = mat[ k ][ i ] >> j;
				mask &= 1;
				mask = -mask;

				for (c = 0; c < SYS_N/8; c++)
					mat[ k ][ c ] ^= mat[ row ][ c ] & mask;
			}
		}
	}

	for (i = 0; i < PK_NROWS; i++)
		memcpy(pk + i*PK_ROW_BYTES, mat[i] + PK_NROWS/8, PK_ROW_BYTES);

	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1a8158, %rsp         # imm = 0x1A8158
movq %rsi, %r14
movq %rdi, %r15
movw $0x1, 0x140(%rsp)
xorl %ebx, %ebx
leaq (%r14,%rbx), %rdi
callq 0x6f28
andl $0x1fff, %eax           # imm = 0x1FFF
movw %ax, 0x40(%rsp,%rbx)
addq $0x2, %rbx
cmpq $0x100, %rbx            # imm = 0x100
jne 0x5ed7
movq %r15, 0x20(%rsp)
addq %rbx, %r14
leaq 0x4150(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x1896
leaq 0x150(%rsp), %rdi
leaq 0x40(%rsp), %rsi
movq %r15, %rdx
callq 0x6ac1
xorl %ebx, %ebx
movzwl 0x150(%rsp,%rbx,2), %edi
callq 0x59f8
movw %ax, 0x150(%rsp,%rbx,2)
incq %rbx
cmpq $0x2000, %rbx           # imm = 0x2000
jne 0x5f29
leaq 0x8150(%rsp), %rdi
xorl %ebx, %ebx
movl $0x1a0000, %edx         # imm = 0x1A0000
xorl %esi, %esi
callq 0x1070
leaq 0x8550(%rsp), %rdx
movdqa 0x2170(%rip), %xmm3     # 0x80e0
movdqa 0x2198(%rip), %xmm4     # 0x8110
movdqa 0x2eb0(%rip), %xmm5     # 0x8e30
pshufd $0xf5, %xmm5, %xmm6     # xmm6 = xmm5[1,1,3,3]
movdqa 0x2163(%rip), %xmm7     # 0x80f0
movdqa %xmm6, 0x30(%rsp)
movq %rbx, 0x8(%rsp)
movq %rdx, 0x28(%rsp)
xorl %eax, %eax
movzwl 0x15e(%rsp,%rax,2), %edi
movzwl 0x15c(%rsp,%rax,2), %r8d
movzwl 0x15a(%rsp,%rax,2), %r9d
movzwl 0x158(%rsp,%rax,2), %r10d
movzwl 0x156(%rsp,%rax,2), %r11d
movzwl 0x154(%rsp,%rax,2), %ebp
movzwl 0x152(%rsp,%rax,2), %r13d
movq %rax, 0x10(%rsp)
movzwl 0x150(%rsp,%rax,2), %ebx
movq %rdx, 0x18(%rsp)
xorl %eax, %eax
movdqa %xmm3, %xmm0
movdqa %xmm0, %xmm1
pxor %xmm4, %xmm1
movdqa %xmm5, %xmm2
pcmpgtd %xmm1, %xmm2
pshufd $0xf5, %xmm1, %xmm1     # xmm1 = xmm1[1,1,3,3]
pcmpeqd %xmm6, %xmm1
pand %xmm2, %xmm1
movd %xmm1, %ecx
testb $0x1, %cl
je 0x6093
movl %edi, %r15d
movl %eax, %ecx
shrl %cl, %r15d
movl %r9d, %r14d
shrl %cl, %r14d
xorl %ecx, %ecx
btl %eax, %r8d
setb %cl
andl $0x1, %r15d
leal (%rcx,%r15,2), %r15d
andl $0x1, %r14d
addl %r14d, %r14d
movl %r11d, %r12d
movl %eax, %ecx
shrl %cl, %r12d
xorl %ecx, %ecx
btl %eax, %r10d
setb %cl
leal (%r14,%r15,4), %r14d
orl %ecx, %r14d
andl $0x1, %r12d
addl %r12d, %r12d
movl %r13d, %r15d
movl %eax, %ecx
shrl %cl, %r15d
xorl %ecx, %ecx
btl %eax, %ebp
setb %cl
leal (%r12,%r14,4), %r14d
orl %ecx, %r14d
andl $0x1, %r15d
addl %r15d, %r15d
xorl %ecx, %ecx
btl %eax, %ebx
setb %cl
leal (%r15,%r14,4), %r14d
orl %ecx, %r14d
movb %r14b, -0x400(%rdx)
pextrw $0x4, %xmm1, %ecx
testb $0x1, %cl
je 0x6115
leal 0x1(%rax), %ecx
movl %edi, %r14d
shrl %cl, %r14d
movl %r9d, %r15d
shrl %cl, %r15d
movzbl %cl, %ecx
xorl %r12d, %r12d
btl %ecx, %r8d
setb %r12b
andl $0x1, %r14d
leal (%r12,%r14,2), %r14d
andl $0x1, %r15d
addl %r15d, %r15d
movl %r11d, %r12d
shrl %cl, %r12d
xorl %esi, %esi
btl %ecx, %r10d
setb %sil
leal (%r15,%r14,4), %r14d
orl %esi, %r14d
andl $0x1, %r12d
addl %r12d, %r12d
movl %r13d, %esi
shrl %cl, %esi
xorl %r15d, %r15d
btl %ecx, %ebp
setb %r15b
leal (%r12,%r14,4), %r14d
orl %r15d, %r14d
andl $0x1, %esi
addl %esi, %esi
xorl %r15d, %r15d
btl %ecx, %ebx
setb %r15b
leal (%rsi,%r14,4), %ecx
orl %r15d, %ecx
movb %cl, (%rdx)
addq $0x2, %rax
paddq %xmm7, %xmm0
addq $0x800, %rdx            # imm = 0x800
cmpq $0xe, %rax
jne 0x5ff4
movq 0x10(%rsp), %rcx
leaq 0x8(%rcx), %rax
movq 0x18(%rsp), %rdx
incq %rdx
cmpq $0x1ff8, %rcx           # imm = 0x1FF8
jb 0x5f9f
xorl %ebx, %ebx
movzwl 0x150(%rsp,%rbx,2), %edi
movzwl 0x4150(%rsp,%rbx,2), %esi
callq 0x52b4
movw %ax, 0x150(%rsp,%rbx,2)
incq %rbx
cmpq $0x2000, %rbx           # imm = 0x2000
jne 0x614e
movq 0x8(%rsp), %rbx
incq %rbx
movq 0x28(%rsp), %rdx
addq $0x3400, %rdx           # imm = 0x3400
cmpq $0x80, %rbx
movdqa 0x1f46(%rip), %xmm3     # 0x80e0
movdqa 0x1f6e(%rip), %xmm4     # 0x8110
movdqa 0x2c86(%rip), %xmm5     # 0x8e30
movdqa 0x30(%rsp), %xmm6
movdqa 0x1f38(%rip), %xmm7     # 0x80f0
jne 0x5f93
leaq 0x8550(%rsp), %rbx
xorl %edx, %edx
movl $0x400, %esi            # imm = 0x400
leaq 0x8150(%rsp), %r11
xorl %r9d, %r9d
leaq (,%rdx,8), %r10
movq %r11, 0x10(%rsp)
movq %rbx, 0x18(%rsp)
xorl %ecx, %ecx
movq %r9, 0x8(%rsp)
leaq (%rcx,%r10), %r15
cmpq $0x67f, %r15            # imm = 0x67F
jae 0x6285
movq %r15, %rax
shlq $0xa, %rax
movl $0x1, %ebp
shll %cl, %ebp
leaq (%rsp,%rax), %r12
addq $0x8150, %r12           # imm = 0x8150
addq %rdx, %r12
movq %rbx, %r13
movq %r9, %r14
leaq 0x1(%r14), %rax
movq %rax, %rdi
shlq $0xa, %rdi
addq %rsp, %rdi
addq $0x8150, %rdi           # imm = 0x8150
movb (%rdx,%rdi), %dil
xorb (%r12), %dil
movzbl %dil, %r8d
xorl %edi, %edi
pxor %xmm0, %xmm0
testl %r8d, %ebp
je 0x6257
movdqa (%r13,%rdi), %xmm0
pxor (%r11,%rdi), %xmm0
movdqa %xmm0, (%r11,%rdi)
addq $0x10, %rdi
cmpq $0x400, %rdi            # imm = 0x400
jne 0x6247
addq $0x400, %r13            # imm = 0x400
cmpq $0x67e, %r14            # imm = 0x67E
movq %rax, %r14
jb 0x6224
jmp 0x628c
movl $0x1, %ebp
shll %cl, %ebp
movq %r15, %rax
shlq $0xa, %rax
addq %rsp, %rax
addq $0x8150, %rax           # imm = 0x8150
movzbl (%rdx,%rax), %eax
testl %eax, %ebp
je 0x637f
leaq 0x8150(%rsp), %r12
xorl %r14d, %r14d
cmpq %r15, %r14
je 0x62eb
movq %r14, %rax
shlq $0xa, %rax
addq %rsp, %rax
addq $0x8150, %rax           # imm = 0x8150
movzbl (%rdx,%rax), %eax
andl %ebp, %eax
xorl %edi, %edi
testl %eax, %eax
movzbl (%r11,%rdi), %r8d
cmovel %eax, %r8d
xorb %r8b, (%r12,%rdi)
incq %rdi
cmpq $0x400, %rdi            # imm = 0x400
jne 0x62d0
incq %r14
addq $0x400, %r12            # imm = 0x400
cmpq $0x680, %r14            # imm = 0x680
jne 0x62b3
incq %rcx
incq %r9
addq %rsi, %rbx
addq %rsi, %r11
cmpq $0x8, %rcx
jne 0x61f1
incq %rdx
movq 0x8(%rsp), %r9
addq $0x8, %r9
movq 0x18(%rsp), %rbx
movl $0x2000, %eax           # imm = 0x2000
addq %rax, %rbx
movq 0x10(%rsp), %r11
addq %rax, %r11
cmpq $0xd0, %rdx
jne 0x61d8
movl $0xd0, %ebx
movq 0x20(%rsp), %r14
leaq (%rsp,%rbx), %rsi
addq $0x8150, %rsi           # imm = 0x8150
movl $0x330, %edx            # imm = 0x330
movq %r14, %rdi
callq 0x10a0
addq $0x330, %r14            # imm = 0x330
addq $0x400, %rbx            # imm = 0x400
xorl %eax, %eax
cmpq $0x1a00d0, %rbx         # imm = 0x1A00D0
jne 0x634c
jmp 0x6384
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x1a8158, %rsp         # imm = 0x1A8158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop