// File: /workspace/github_c_makefile_star2_O2/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, 0x18(%rsp)
movw $0x1, 0x120(%rsp)
xorl %ebx, %ebx
leaq (%r14,%rbx), %rsi
cmpq $0x100, %rbx            # imm = 0x100
je 0x56b6
movq %rsi, %rdi
callq 0x65c0
andl $0x1fff, %eax           # imm = 0x1FFF
movw %ax, 0x20(%rsp,%rbx)
addq $0x2, %rbx
jmp 0x5691
leaq 0x4130(%rsp), %r14
movq %r14, %rdi
callq 0x1889
leaq 0x130(%rsp), %rdi
leaq 0x20(%rsp), %rsi
movq %r14, %rdx
callq 0x6145
xorl %ebx, %ebx
cmpq $0x2000, %rbx           # imm = 0x2000
je 0x5700
movzwl 0x130(%rsp,%rbx,2), %edi
callq 0x5293
movw %ax, 0x130(%rsp,%rbx,2)
incq %rbx
jmp 0x56dd
leaq 0x8130(%rsp), %rax
xorl %ecx, %ecx
cmpq $0x680, %rcx            # imm = 0x680
je 0x5732
xorl %edx, %edx
cmpq $0x400, %rdx            # imm = 0x400
je 0x5727
movb $0x0, (%rax,%rdx)
incq %rdx
jmp 0x5715
incq %rcx
addq $0x400, %rax            # imm = 0x400
jmp 0x570a
leaq 0x8130(%rsp), %rax
xorl %ecx, %ecx
cmpq $0x80, %rcx
je 0x5892
movq %rcx, (%rsp)
movq %rax, 0x8(%rsp)
movq %rax, %r12
xorl %edx, %edx
cmpq $0x2000, %rdx           # imm = 0x2000
jae 0x584e
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), %ebx
movzwl 0x130(%rsp,%rdx,2), %ebp
movq %r12, 0x10(%rsp)
xorl %ecx, %ecx
cmpq $0xd, %rcx
je 0x583d
movl %esi, %r13d
shrl %cl, %r13d
andl $0x1, %r13d
xorl %r14d, %r14d
btl %ecx, %edi
setb %r14b
movl %r8d, %r15d
shrl %cl, %r15d
leal (%r14,%r13,2), %r14d
andl $0x1, %r15d
addl %r15d, %r15d
xorl %r13d, %r13d
btl %ecx, %r9d
setb %r13b
movl %r10d, %eax
shrl %cl, %eax
leal (%r15,%r14,4), %r14d
orl %r14d, %r13d
andl $0x1, %eax
addl %eax, %eax
xorl %r14d, %r14d
btl %ecx, %r11d
setb %r14b
movl %ebx, %r15d
shrl %cl, %r15d
leal (%rax,%r13,4), %eax
orl %r14d, %eax
andl $0x1, %r15d
addl %r15d, %r15d
xorl %r14d, %r14d
btl %ecx, %ebp
setb %r14b
leal (%r15,%rax,4), %eax
orl %r14d, %eax
movb %al, (%r12)
incq %rcx
addq $0x400, %r12            # imm = 0x400
jmp 0x57af
addq $0x8, %rdx
movq 0x10(%rsp), %r12
incq %r12
jmp 0x5757
xorl %ebx, %ebx
cmpq $0x2000, %rbx           # imm = 0x2000
je 0x587b
movzwl 0x130(%rsp,%rbx,2), %edi
movzwl 0x4130(%rsp,%rbx,2), %esi
callq 0x4ebc
movw %ax, 0x130(%rsp,%rbx,2)
incq %rbx
jmp 0x5850
movq (%rsp), %rcx
incq %rcx
movq 0x8(%rsp), %rax
addq $0x3400, %rax           # imm = 0x3400
jmp 0x573c
leaq 0x8130(%rsp), %r12
leaq 0x8530(%rsp), %rcx
xorl %edi, %edi
movl $0x400, %r10d           # imm = 0x400
xorl %r14d, %r14d
cmpq $0xd0, %rdi
je 0x5a0c
leaq (,%rdi,8), %r15
movq %r12, 0x8(%rsp)
movq %rcx, 0x10(%rsp)
movq %rcx, %rax
xorl %ecx, %ecx
movq %r14, (%rsp)
cmpq $0x8, %rcx
je 0x59d2
movq %rcx, %r8
orq %r15, %r8
movq %r8, %rdx
shlq $0xa, %rdx
pushq $0x1
popq %r9
shll %cl, %r9d
leaq (%rsp,%rdx), %rsi
addq $0x8130, %rsi           # imm = 0x8130
addq %rdi, %rsi
movq %rax, %r13
movq %r14, %rbp
movzbl (%rsi), %edx
cmpq $0x67e, %rbp            # imm = 0x67E
ja 0x595c
incq %rbp
movq %rbp, %r11
shlq $0xa, %r11
addq %rsp, %r11
addq $0x8130, %r11           # imm = 0x8130
xorb (%rdi,%r11), %dl
movzbl %dl, %r11d
andl %r9d, %r11d
xorl %edx, %edx
cmpq $0x400, %rdx            # imm = 0x400
je 0x5953
testl %r11d, %r11d
movzbl (%r13,%rdx), %ebx
cmovel %r11d, %ebx
xorb %bl, (%r12,%rdx)
incq %rdx
jmp 0x5934
addq $0x400, %r13            # imm = 0x400
jmp 0x5907
testl %edx, %r9d
je 0x59f7
leaq 0x8130(%rsp), %rsi
xorl %r13d, %r13d
cmpq $0x680, %r13            # imm = 0x680
je 0x59c1
cmpq %r8, %r13
jne 0x598a
incq %r13
addq $0x400, %rsi            # imm = 0x400
jmp 0x5970
movq %r13, %rdx
shlq $0xa, %rdx
addq %rsp, %rdx
addq $0x8130, %rdx           # imm = 0x8130
movzbl (%rdi,%rdx), %ebp
andl %r9d, %ebp
xorl %edx, %edx
cmpq $0x400, %rdx            # imm = 0x400
je 0x597e
testl %ebp, %ebp
movzbl (%r12,%rdx), %r11d
cmovel %ebp, %r11d
xorb %r11b, (%rsi,%rdx)
incq %rdx
jmp 0x59a4
incq %rcx
incq %r14
addq %r10, %rax
addq %r10, %r12
jmp 0x58d5
incq %rdi
movq (%rsp), %r14
addq $0x8, %r14
movq 0x10(%rsp), %rcx
movl $0x2000, %eax           # imm = 0x2000
addq %rax, %rcx
movq 0x8(%rsp), %r12
addq %rax, %r12
jmp 0x58ad
pushq $-0x1
popq %rax
addq $0x1a8138, %rsp         # imm = 0x1A8138
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0xd0, %ebx
cmpq $0x1a00d0, %rbx         # imm = 0x1A00D0
je 0x5a4c
leaq (%rsp,%rbx), %rsi
addq $0x8130, %rsi           # imm = 0x8130
movl $0x330, %edx            # imm = 0x330
movq 0x18(%rsp), %r14
movq %r14, %rdi
callq 0x10a0
addq $0x400, %rbx            # imm = 0x400
addq $0x330, %r14            # imm = 0x330
movq %r14, 0x18(%rsp)
jmp 0x5a11
xorl %eax, %eax
jmp 0x59fa