// File: /workspace/github_c_makefile_star2_O1/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 $0x1a8138, %rsp         # imm = 0x1A8138
movq %rsi, %r14
movq %rdi, 0x10(%rsp)
movw $0x1, 0x120(%rsp)
xorl %ebx, %ebx
leaq (%r14,%rbx), %rdi
callq 0x6b60
andl $0x1fff, %eax           # imm = 0x1FFF
movw %ax, 0x20(%rsp,%rbx)
addq $0x2, %rbx
cmpq $0x100, %rbx            # imm = 0x100
jne 0x5add
addq %rbx, %r14
leaq 0x4130(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x18c0
leaq 0x130(%rsp), %rdi
leaq 0x20(%rsp), %rsi
movq %r15, %rdx
callq 0x66f9
xorl %ebx, %ebx
movzwl 0x130(%rsp,%rbx,2), %edi
callq 0x56e3
movw %ax, 0x130(%rsp,%rbx,2)
incq %rbx
cmpq $0x2000, %rbx           # imm = 0x2000
jne 0x5b2a
leaq 0x8130(%rsp), %rbx
xorl %r14d, %r14d
movl $0x1a0000, %edx         # imm = 0x1A0000
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1070
movq %r14, (%rsp)
movq %rbx, 0x8(%rsp)
movq %rbx, %rax
xorl %edx, %edx
movzwl 0x13e(%rsp,%rdx,2), %esi
movzwl 0x13c(%rsp,%rdx,2), %edi
movzwl 0x13a(%rsp,%rdx,2), %r8d
movzwl 0x138(%rsp,%rdx,2), %r9d
movzwl 0x136(%rsp,%rdx,2), %r10d
movzwl 0x134(%rsp,%rdx,2), %r11d
movzwl 0x132(%rsp,%rdx,2), %ebp
movzwl 0x130(%rsp,%rdx,2), %r12d
movq %rax, %r13
xorl %ecx, %ecx
movl %esi, %ebx
shrl %cl, %ebx
andl $0x1, %ebx
xorl %r15d, %r15d
btl %ecx, %edi
setb %r15b
movl %r8d, %r14d
shrl %cl, %r14d
leal (%r15,%rbx,2), %ebx
andl $0x1, %r14d
addl %r14d, %r14d
leal (%r14,%rbx,4), %ebx
xorl %r14d, %r14d
btl %ecx, %r9d
setb %r14b
movl %r10d, %r15d
shrl %cl, %r15d
orl %ebx, %r14d
andl $0x1, %r15d
addl %r15d, %r15d
xorl %ebx, %ebx
btl %ecx, %r11d
setb %bl
leal (%r15,%r14,4), %r14d
movl %ebp, %r15d
shrl %cl, %r15d
orl %ebx, %r14d
andl $0x1, %r15d
addl %r15d, %r15d
xorl %ebx, %ebx
btl %ecx, %r12d
setb %bl
leal (%r15,%r14,4), %r14d
orl %ebx, %r14d
movb %r14b, (%r13)
incq %rcx
addq $0x400, %r13            # imm = 0x400
cmpq $0xd, %rcx
jne 0x5bbd
leaq 0x8(%rdx), %rcx
incq %rax
cmpq $0x1ff8, %rdx           # imm = 0x1FF8
movq %rcx, %rdx
jb 0x5b73
xorl %ebx, %ebx
movzwl 0x130(%rsp,%rbx,2), %edi
movzwl 0x4130(%rsp,%rbx,2), %esi
callq 0x4f64
movw %ax, 0x130(%rsp,%rbx,2)
incq %rbx
cmpq $0x2000, %rbx           # imm = 0x2000
jne 0x5c5c
movq (%rsp), %r14
incq %r14
movq 0x8(%rsp), %rbx
addq $0x3400, %rbx           # imm = 0x3400
cmpq $0x80, %r14
jne 0x5b65
leaq 0x8130(%rsp), %r14
leaq 0x8530(%rsp), %rdx
xorl %esi, %esi
xorl %ebx, %ebx
leaq (,%rsi,8), %r11
movq %r14, (%rsp)
movq %rdx, 0x8(%rsp)
xorl %ecx, %ecx
movq %rbx, 0x18(%rsp)
leaq (%rcx,%r11), %r13
cmpq $0x67e, %r13            # imm = 0x67E
ja 0x5d50
movq %r13, %rax
shlq $0xa, %rax
movl $0x1, %ebp
shll %cl, %ebp
leaq (%rsp,%rax), %r8
addq $0x8130, %r8            # imm = 0x8130
addq %rsi, %r8
movq %rdx, %r15
movq %rbx, %r10
movq %r10, %r12
incq %r10
movq %r10, %rax
shlq $0xa, %rax
addq %rsp, %rax
addq $0x8130, %rax           # imm = 0x8130
movb (%rsi,%rax), %al
xorb (%r8), %al
movzbl %al, %r9d
andl %ebp, %r9d
xorl %eax, %eax
testl %r9d, %r9d
movzbl (%r15,%rax), %edi
cmovel %r9d, %edi
xorb %dil, (%r14,%rax)
incq %rax
cmpq $0x400, %rax            # imm = 0x400
jne 0x5d25
addq $0x400, %r15            # imm = 0x400
cmpq $0x67d, %r12            # imm = 0x67D
jbe 0x5d00
movq %r13, %rax
shlq $0xa, %rax
addq %rsp, %rax
addq $0x8130, %rax           # imm = 0x8130
movzbl (%rsi,%rax), %eax
movl $0x1, %ebp
shll %cl, %ebp
btl %ecx, %eax
jae 0x5e51
leaq 0x8130(%rsp), %r8
xorl %r15d, %r15d
cmpq %r13, %r15
je 0x5db9
movq %r15, %rax
shlq $0xa, %rax
addq %rsp, %rax
addq $0x8130, %rax           # imm = 0x8130
movzbl (%rsi,%rax), %r9d
andl %ebp, %r9d
xorl %eax, %eax
testl %r9d, %r9d
movzbl (%r14,%rax), %edi
cmovel %r9d, %edi
xorb %dil, (%r8,%rax)
incq %rax
cmpq $0x400, %rax            # imm = 0x400
jne 0x5d9e
incq %r15
addq $0x400, %r8             # imm = 0x400
cmpq $0x680, %r15            # imm = 0x680
jne 0x5d7f
incq %rcx
incq %rbx
movl $0x400, %eax            # imm = 0x400
addq %rax, %rdx
addq %rax, %r14
cmpq $0x8, %rcx
jne 0x5cd1
incq %rsi
movq 0x18(%rsp), %rbx
addq $0x8, %rbx
movq 0x8(%rsp), %rdx
movl $0x2000, %eax           # imm = 0x2000
addq %rax, %rdx
movq (%rsp), %r14
addq %rax, %r14
cmpq $0xd0, %rsi
jne 0x5cb9
movl $0xd0, %ebx
movq 0x10(%rsp), %r14
leaq (%rsp,%rbx), %rsi
addq $0x8130, %rsi           # imm = 0x8130
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 0x5e1e
jmp 0x5e56
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x1a8138, %rsp         # imm = 0x1A8138
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq