// File: /workspace/github_c_makefile_star2_O3/cbouilla[P]AES-attacks-finder/SysEqLin.c
// Function: ExtraireEX
int ExtraireEX(unsigned char ** __restrict dst, int * __restrict var, const int N, SysEqLin E) // Calcul E(X) (sous forme de matrice)
{

	const int nombre_ligne_big_matrix = E->a;
	const int nombre_colone_big_matrix = E->b + E->gen*N;
	unsigned char ** __restrict big_matrix=malloc(nombre_ligne_big_matrix*sizeof(unsigned char *));
	unsigned char * __restrict espace_big_matrix=malloc(nombre_colone_big_matrix*nombre_ligne_big_matrix*sizeof(unsigned char));

	int i;
	for (i = 0; i < nombre_ligne_big_matrix; i++) big_matrix[i]=espace_big_matrix + i*nombre_colone_big_matrix;
	for (i = 0; i < nombre_ligne_big_matrix; i++)
	{
		int j;
		for (j = 0; j < E->b; j++) big_matrix[i][j]=E->mat[i][j];
		for (j = E->b; j < nombre_colone_big_matrix; j++) big_matrix[i][j]=0;
	}
	for (i = 0; i < N; i++)
	{
		if (E->lignevar[var[i]]<E->a/E->gen)
		{
			int j;
			for (j = 0; j < E->gen; j++) big_matrix[E->gen*E->lignevar[var[i]]+j][E->b+E->gen*i+j]=1;
		}
	}
	
	int dim = 0;
	const int colonne_max_pour_pivot = E->b;
	int * __restrict place_pivot = malloc(min(colonne_max_pour_pivot,nombre_ligne_big_matrix)*sizeof(int));
	int pivot_c;
	for (pivot_c = 0; pivot_c < colonne_max_pour_pivot; pivot_c++)
	{
		int new_pivot_l;
		for (new_pivot_l = dim; new_pivot_l < nombre_ligne_big_matrix; new_pivot_l++)
		{
			if (big_matrix[new_pivot_l][pivot_c])
			{
				if (new_pivot_l!=dim)
				{
					unsigned char *tmp = big_matrix[dim];
					big_matrix[dim]=big_matrix[new_pivot_l];
					big_matrix[new_pivot_l]=tmp;
				}
				place_pivot[dim]=pivot_c;
				const unsigned char inv = Inverse(big_matrix[dim][pivot_c]);
				int colonne;
				for (colonne = pivot_c; colonne < nombre_colone_big_matrix; colonne++) big_matrix[dim][colonne]=Multiply(inv,big_matrix[dim][colonne]);
				int ligne;
				for (ligne = 0; ligne < dim; ligne++)
				{
					if (big_matrix[ligne][pivot_c])
					{
						for (colonne = pivot_c+1; colonne < nombre_colone_big_matrix; colonne++)
						{
							big_matrix[ligne][colonne]^=Multiply(big_matrix[ligne][pivot_c],big_matrix[dim][colonne]);
						}
						big_matrix[ligne][pivot_c]=0;
					}
				}
				for (ligne = new_pivot_l+1; ligne < nombre_ligne_big_matrix; ligne++)
				{
					if (big_matrix[ligne][pivot_c])
					{
						for (colonne = pivot_c+1; colonne < nombre_colone_big_matrix; colonne++)
						{
							big_matrix[ligne][colonne]^=Multiply(big_matrix[ligne][pivot_c],big_matrix[dim][colonne]);
						}
						big_matrix[ligne][pivot_c]=0;
					}
				}
				dim++;
				break;
			}
		}
	}
	
	const int dim_save = dim;
	for (pivot_c = colonne_max_pour_pivot; pivot_c < nombre_colone_big_matrix; pivot_c++)
	{
		int new_pivot_l;
		for (new_pivot_l = dim; new_pivot_l < nombre_ligne_big_matrix; new_pivot_l++)
		{
			if (big_matrix[new_pivot_l][pivot_c])
			{
				if (new_pivot_l!=dim)
				{
					unsigned char *tmp = big_matrix[dim];
					big_matrix[dim]=big_matrix[new_pivot_l];
					big_matrix[new_pivot_l]=tmp;
				}
				const unsigned char inv = Inverse(big_matrix[dim][pivot_c]);
				int colonne;
				for (colonne = pivot_c; colonne < nombre_colone_big_matrix; colonne++) big_matrix[dim][colonne]=Multiply(inv,big_matrix[dim][colonne]);
				int ligne;
				for (ligne = 0; ligne < dim; ligne++)
				{
					if (big_matrix[ligne][pivot_c])
					{
						for (colonne = pivot_c+1; colonne < nombre_colone_big_matrix; colonne++)
						{
							big_matrix[ligne][colonne]^=Multiply(big_matrix[ligne][pivot_c],big_matrix[dim][colonne]);
						}
						big_matrix[ligne][pivot_c]=0;
					}
				}
				for (ligne = new_pivot_l+1; ligne < nombre_ligne_big_matrix; ligne++)
				{
					if (big_matrix[ligne][pivot_c])
					{
						for (colonne = pivot_c+1; colonne < nombre_colone_big_matrix; colonne++)
						{
							big_matrix[ligne][colonne]^=Multiply(big_matrix[ligne][pivot_c],big_matrix[dim][colonne]);
						}
						big_matrix[ligne][pivot_c]=0;
					}
				}
				dim++;
				break;
			}
		}
	}

	const int nombre_de_lignes_max = VARIABLES*E->gen;
	int pos = 0;
	int ligne;	
	int colonne = colonne_max_pour_pivot;
	for (ligne = dim_save; ligne < dim; ligne++)
	{
		while (colonne<nombre_colone_big_matrix && big_matrix[ligne][colonne]==0)
		{
			unsigned char premier = 0;
			int j;
			for (j = 0; j < dim_save; j++)
			{
				if (big_matrix[j][colonne])
				{
					int k;
					if (premier) for (k = 0; k < nombre_de_lignes_max; k++) dst[k][pos]^=Multiply(big_matrix[j][colonne],E->mat[k][place_pivot[j]]);
					else
					{
						for (k = 0; k < nombre_de_lignes_max; k++) dst[k][pos]=Multiply(big_matrix[j][colonne],E->mat[k][place_pivot[j]]);
						premier=1;
					}			
				}
			}
			if (premier) pos++;
			colonne++;
		}
		colonne++;
	}

	for (i = colonne; i < nombre_colone_big_matrix; i++)
	{
		unsigned char premier = 0;
		int j;
		for (j = 0; j < dim_save; j++)
		{
			if (big_matrix[j][i])
			{
				int k;
				if (premier) for (k = 0; k < nombre_de_lignes_max; k++) dst[k][pos]^=Multiply(big_matrix[j][i],E->mat[k][place_pivot[j]]);
				else
				{
					for (k = 0; k < nombre_de_lignes_max; k++) dst[k][pos]=Multiply(big_matrix[j][i],E->mat[k][place_pivot[j]]);
					premier=1;
				}			
			}
		}
		if (premier) pos++;
	}

	free(place_pivot);
	free(big_matrix);
	free(espace_big_matrix);

	return pos;	

	/* A améliorer */
	#if 0
	int ligne=VARIABLES*E->gen;
	unsigned char **m=malloc(ligne*sizeof(unsigned char *));
	int b1=(N+VARIABLES)*E->gen-E->a, i;
	for (i = 0; i < ligne; i++)
	{
		m[i]=malloc(b1*sizeof(unsigned char));
		int j;
		for (j = 0; j < b1; j++) m[i][j]=0;
	}
	int col=0;
	for (i = 0; i < N; i++)
	{
		int j;
		for (j = 0; j < E->gen; j++) m[E->gen*E->lignevar[var[i]]+j][col++]=1;
	}
	for (i = E->a; i < VARIABLES*E->gen; i++) m[i][col++]=1;
	int b=Intersection(dst,E->mat,E->b,m,ligne,b1);
	for (i = 0; i < ligne; i++) free(m[i]);
	free(m);
	return b;
	#endif
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %rcx, %rbx
movq %rsi, %r12
movq %rdi, %r14
movslq 0x8(%rcx), %r13
movl 0x10(%rcx), %ebp
movl %edx, 0x30(%rsp)
imull %edx, %ebp
addl 0xc(%rcx), %ebp
leaq (,%r13,8), %rdi
callq 0x21d0
movq %rax, %r15
movl %ebp, %eax
imull %r13d, %eax
movslq %eax, %rdi
callq 0x21d0
movq %rax, 0x50(%rsp)
movslq %ebp, %rdx
testq %r13, %r13
movq %r15, 0x20(%rsp)
movq %rdx, 0x38(%rsp)
movl %ebp, 0xc(%rsp)
jle 0xb897
movq %r15, %rsi
xorl %eax, %eax
movq 0x50(%rsp), %rcx
movq %rcx, (%rsi,%rax,8)
incq %rax
addq %rdx, %rcx
cmpq %rax, %r13
jne 0xb830
testl %r13d, %r13d
jle 0xb897
xorl %r15d, %r15d
movl 0xc(%rbx), %edx
testl %edx, %edx
jle 0xb86d
movq (%rsi,%r15,8), %rax
xorl %ecx, %ecx
movq (%rbx), %rdx
movq (%rdx,%r15,8), %rdx
movb (%rdx,%rcx), %dl
movb %dl, (%rax,%rcx)
incq %rcx
movslq 0xc(%rbx), %rdx
cmpq %rdx, %rcx
jl 0xb854
cmpl %ebp, %edx
jge 0xb88f
movslq %edx, %rdi
addq (%rsi,%r15,8), %rdi
notl %edx
addl %ebp, %edx
incq %rdx
xorl %esi, %esi
callq 0x2120
movl 0xc(%rsp), %ebp
movq 0x20(%rsp), %rsi
incq %r15
cmpq %r13, %r15
jne 0xb847
movl 0x30(%rsp), %eax
testl %eax, %eax
jle 0xb8ff
movl %eax, %ecx
movl 0x10(%rbx), %edi
xorl %esi, %esi
movq 0x18(%rbx), %rax
movslq (%r12,%rsi,4), %r8
movl (%rax,%r8,4), %r9d
movl 0x8(%rbx), %eax
cltd
idivl %edi
cmpl %eax, %r9d
jge 0xb8f7
testl %edi, %edi
movq 0x20(%rsp), %r9
jle 0xb8f7
xorl %eax, %eax
movq 0x18(%rbx), %rdx
movslq (%rdx,%r8,4), %rdx
movslq %edi, %rdi
imulq %rdi, %rdx
addq %rax, %rdx
movq (%r9,%rdx,8), %rdx
imull %esi, %edi
addl 0xc(%rbx), %edi
addl %eax, %edi
movslq %edi, %rdi
movb $0x1, (%rdx,%rdi)
movl 0x10(%rbx), %edi
incq %rax
cmpl %edi, %eax
jl 0xb8c8
incq %rsi
cmpq %rcx, %rsi
jne 0xb8a6
movslq 0xc(%rbx), %r12
cmpl %r13d, %r12d
movl %r13d, %eax
cmovll %r12d, %eax
movslq %eax, %rdi
shlq $0x2, %rdi
callq 0x21d0
movq %rax, 0x30(%rsp)
testq %r12, %r12
movq %r13, 0x28(%rsp)
jle 0xbaca
movq 0x38(%rsp), %r10
leaq -0x1(%r10), %rax
movq %rax, (%rsp)
xorl %ebp, %ebp
xorl %eax, %eax
movq 0x20(%rsp), %r9
movl 0xc(%rsp), %r11d
cmpl %r13d, %eax
jge 0xbabc
movq %rax, %rsi
movslq %esi, %rax
leal 0x1(%rsi), %ecx
movq %rcx, 0x10(%rsp)
leaq (%r9,%rax,8), %rcx
movl %r13d, %edx
movq %rsi, 0x18(%rsp)
subl %esi, %edx
xorl %r13d, %r13d
movq (%rcx,%r13,8), %rsi
cmpb $0x0, (%rsi,%rbp)
jne 0xb990
incq %r13
cmpl %r13d, %edx
jne 0xb96f
movq 0x28(%rsp), %r13
movq 0x18(%rsp), %rax
jmp 0xbabc
testl %r13d, %r13d
je 0xb9a1
movq (%r9,%rax,8), %rdx
movq %rsi, (%r9,%rax,8)
movq %rdx, (%rcx,%r13,8)
movq 0x30(%rsp), %rcx
movl %ebp, (%rcx,%rax,4)
movq (%r9,%rax,8), %r15
movzbl (%r15,%rbp), %edi
callq 0x2534
movq 0x38(%rsp), %r10
cmpq %r10, %rbp
leaq 0xd64a(%rip), %r8       # 0x19010
jge 0xb9e9
movzbl %al, %eax
shll $0x8, %eax
movq %rbp, %rcx
movzbl (%r15,%rcx), %edx
leaq (%rax,%r8), %rsi
movb (%rdx,%rsi), %dl
movb %dl, (%r15,%rcx)
incq %rcx
cmpq %r10, %rcx
jl 0xb9d1
movq 0x18(%rsp), %rax
testl %eax, %eax
movq 0x20(%rsp), %r9
movl 0xc(%rsp), %r11d
jle 0xba50
movl %eax, %eax
movq %rax, 0x18(%rsp)
xorl %ecx, %ecx
movq (%r9,%rcx,8), %rdx
cmpb $0x0, (%rdx,%rbp)
je 0xba46
cmpq (%rsp), %rbp
movq %r8, %rax
jge 0xba3f
movq %rbp, %rsi
movzbl (%rdx,%rbp), %edi
movzbl 0x1(%r15,%rsi), %r8d
shll $0x8, %edi
addq %rax, %rdi
movb (%r8,%rdi), %dil
xorb %dil, 0x1(%rdx,%rsi)
incq %rsi
leal 0x1(%rsi), %edi
cmpl %edi, %r11d
jg 0xba1b
movb $0x0, (%rdx,%rbp)
movq %rax, %r8
incq %rcx
cmpq 0x18(%rsp), %rcx
jne 0xba05
movq 0x10(%rsp), %rcx
leal (%rcx,%r13), %eax
cmpl 0x28(%rsp), %eax
jge 0xbab5
movl %ecx, %eax
addq %r13, %rax
cltq
movq 0x28(%rsp), %r13
movq (%r9,%rax,8), %rcx
cmpb $0x0, (%rcx,%rbp)
je 0xbaa6
cmpq (%rsp), %rbp
jge 0xbaa2
movq %rbp, %rdx
movzbl (%rcx,%rbp), %esi
movzbl 0x1(%r15,%rdx), %edi
shll $0x8, %esi
addq %r8, %rsi
movb (%rdi,%rsi), %sil
xorb %sil, 0x1(%rcx,%rdx)
incq %rdx
leal 0x1(%rdx), %esi
cmpl %esi, %r11d
jg 0xba7e
movb $0x0, (%rcx,%rbp)
incq %rax
cmpq %r13, %rax
jl 0xba6b
movq 0x10(%rsp), %rax
jmp 0xbabc
movl %ecx, %eax
movq 0x28(%rsp), %r13
incq %rbp
cmpq %r12, %rbp
jne 0xb947
jmp 0xbadb
xorl %eax, %eax
movq 0x20(%rsp), %r9
movq 0x38(%rsp), %r10
movl 0xc(%rsp), %r11d
movl %eax, %r15d
cmpl %r11d, %r12d
movq %rax, 0x18(%rsp)
jge 0xbc7e
leaq -0x1(%r10), %rcx
movq %rcx, (%rsp)
movq %r12, %rdi
movl %eax, %r15d
movq %rdi, %r13
incq %rdi
movq 0x28(%rsp), %rdx
cmpl %edx, %r15d
jge 0xbc75
movslq %edi, %rax
movq %rax, 0x48(%rsp)
movslq %r15d, %rax
leal 0x1(%r15), %r8d
leaq (%r9,%rax,8), %rcx
subl %r15d, %edx
xorl %ebp, %ebp
movq (%rcx,%rbp,8), %rsi
cmpb $0x0, (%rsi,%r13)
jne 0xbb42
incq %rbp
cmpl %ebp, %edx
jne 0xbb26
movq 0x18(%rsp), %rax
jmp 0xbc75
movq %r15, 0x10(%rsp)
movq %rdi, 0x58(%rsp)
testl %ebp, %ebp
je 0xbb5c
movq (%r9,%rax,8), %rdx
movq %rsi, (%r9,%rax,8)
movq %rdx, (%rcx,%rbp,8)
movl %r8d, 0x44(%rsp)
movl %r8d, %ecx
addq %rbp, %rcx
movq %rcx, 0x60(%rsp)
movq (%r9,%rax,8), %r15
movzbl (%r15,%r13), %edi
callq 0x2534
movzbl %al, %eax
shll $0x8, %eax
movq %r13, %rcx
movq 0x38(%rsp), %r10
leaq 0xd481(%rip), %r8       # 0x19010
movzbl (%r15,%rcx), %edx
leaq (%rax,%r8), %rsi
movb (%rdx,%rsi), %dl
movb %dl, (%r15,%rcx)
incq %rcx
cmpq %r10, %rcx
jl 0xbb8f
movq 0x10(%rsp), %rax
testl %eax, %eax
movq 0x20(%rsp), %r9
movl 0xc(%rsp), %r11d
jle 0xbc0e
movl %eax, %eax
movq %rax, 0x10(%rsp)
xorl %ecx, %ecx
movq (%r9,%rcx,8), %rdx
cmpb $0x0, (%rdx,%r13)
je 0xbc04
cmpq (%rsp), %r13
movq %r8, %rax
jge 0xbbfc
movq 0x48(%rsp), %rsi
movzbl (%rdx,%r13), %edi
movzbl (%r15,%rsi), %r8d
shll $0x8, %edi
addq %rax, %rdi
movb (%r8,%rdi), %dil
xorb %dil, (%rdx,%rsi)
incq %rsi
cmpq %r10, %rsi
jl 0xbbdc
movb $0x0, (%rdx,%r13)
movq %rax, %r8
incq %rcx
cmpq 0x10(%rsp), %rcx
jne 0xbbc3
movl 0x44(%rsp), %eax
addl %eax, %ebp
cmpl 0x28(%rsp), %ebp
jge 0xbc68
movslq 0x60(%rsp), %rax
movq (%r9,%rax,8), %rcx
cmpb $0x0, (%rcx,%r13)
je 0xbc5a
cmpq (%rsp), %r13
jge 0xbc55
movq 0x48(%rsp), %rdx
movzbl (%rcx,%r13), %esi
movzbl (%r15,%rdx), %edi
shll $0x8, %esi
addq %r8, %rsi
movb (%rdi,%rsi), %sil
xorb %sil, (%rcx,%rdx)
incq %rdx
cmpq %r10, %rdx
jl 0xbc35
movb $0x0, (%rcx,%r13)
incq %rax
cmpq 0x28(%rsp), %rax
jl 0xbc1f
movl 0x44(%rsp), %eax
movl %eax, %r15d
movq 0x18(%rsp), %rax
movq 0x58(%rsp), %rdi
cmpl %edi, %r11d
jne 0xbafa
leaq 0x26633(%rip), %rcx     # 0x322b8
movq %rax, %rsi
movl 0x10(%rbx), %eax
imull (%rcx), %eax
movq $0x0, (%rsp)
movl %esi, %ecx
movl %eax, %edx
cmpl %r15d, %esi
jge 0xbdfc
movslq %esi, %rsi
movq %rsi, 0x10(%rsp)
movslq %r15d, %rsi
movq %rsi, 0x48(%rsp)
movq $0x0, (%rsp)
leaq 0xd34e(%rip), %r8       # 0x19010
cmpl %r11d, %r12d
jge 0xbde1
movq 0x10(%rsp), %rsi
movq (%r9,%rsi,8), %rsi
movq %rsi, 0x28(%rsp)
movslq %r12d, %r12
movq 0x28(%rsp), %rsi
cmpb $0x0, (%rsi,%r12)
jne 0xbde1
cmpl $0x0, 0x18(%rsp)
jle 0xbdc6
movslq (%rsp), %r10
xorl %r11d, %r11d
xorl %r15d, %r15d
movq (%r9,%r11,8), %r13
cmpb $0x0, (%r13,%r12)
je 0xbda5
testb %r15b, %r15b
je 0xbd5e
movb $0x1, %r15b
testl %eax, %eax
jle 0xbda5
movq 0x30(%rsp), %rsi
movslq (%rsi,%r11,4), %rdi
xorl %esi, %esi
movzbl (%r13,%r12), %r9d
movq (%rbx), %rbp
movq (%rbp,%rsi,8), %rbp
movzbl (%rbp,%rdi), %ebp
shll $0x8, %r9d
addq %r8, %r9
movb (%rbp,%r9), %r9b
movq (%r14,%rsi,8), %rbp
xorb %r9b, (%rbp,%r10)
incq %rsi
cmpq %rsi, %rdx
jne 0xbd2c
jmp 0xbda0
movb $0x1, %r15b
testl %eax, %eax
jle 0xbda5
movq 0x30(%rsp), %rsi
movslq (%rsi,%r11,4), %rdi
xorl %esi, %esi
movzbl (%r13,%r12), %r9d
movq (%rbx), %rbp
movq (%rbp,%rsi,8), %rbp
movzbl (%rbp,%rdi), %ebp
shll $0x8, %r9d
addq %r8, %r9
movb (%rbp,%r9), %r9b
movq (%r14,%rsi,8), %rbp
movb %r9b, (%rbp,%r10)
incq %rsi
cmpq %rsi, %rdx
jne 0xbd70
movq 0x20(%rsp), %r9
incq %r11
cmpq %rcx, %r11
jne 0xbd01
xorl %esi, %esi
testb %r15b, %r15b
setne %sil
movq 0x38(%rsp), %r10
movl 0xc(%rsp), %r11d
jmp 0xbdc8
xorl %esi, %esi
movq (%rsp), %rdi
addl %esi, %edi
movq %rdi, (%rsp)
incq %r12
cmpq %r10, %r12
jl 0xbcdc
movl %r11d, %r12d
incl %r12d
movq 0x10(%rsp), %rdi
incq %rdi
movq %rdi, 0x10(%rsp)
cmpq 0x48(%rsp), %rdi
jne 0xbcc2
cmpl %r11d, %r12d
jge 0xbf01
movslq %r12d, %rsi
leaq 0xd201(%rip), %rdi      # 0x19010
movl $0x0, %r8d
cmpl $0x0, 0x18(%rsp)
jle 0xbeea
movslq (%rsp), %r8
xorl %r9d, %r9d
xorl %r10d, %r10d
movq 0x20(%rsp), %r11
movq (%r11,%r9,8), %r11
cmpb $0x0, (%r11,%rsi)
je 0xbecf
testb %r10b, %r10b
je 0xbe8c
movb $0x1, %r10b
testl %eax, %eax
jle 0xbecf
movq 0x30(%rsp), %r15
movslq (%r15,%r9,4), %r15
xorl %r12d, %r12d
movzbl (%r11,%rsi), %r13d
movq (%rbx), %rbp
movq (%rbp,%r12,8), %rbp
movzbl (%rbp,%r15), %ebp
shll $0x8, %r13d
addq %rdi, %r13
movb (%rbp,%r13), %bpl
movq (%r14,%r12,8), %r13
xorb %bpl, (%r13,%r8)
incq %r12
cmpq %r12, %rdx
jne 0xbe5a
jmp 0xbecf
movb $0x1, %r10b
testl %eax, %eax
jle 0xbecf
movq 0x30(%rsp), %r15
movslq (%r15,%r9,4), %r15
xorl %r12d, %r12d
movzbl (%r11,%rsi), %r13d
movq (%rbx), %rbp
movq (%rbp,%r12,8), %rbp
movzbl (%rbp,%r15), %ebp
shll $0x8, %r13d
addq %rdi, %r13
movb (%rbp,%r13), %bpl
movq (%r14,%r12,8), %r13
movb %bpl, (%r13,%r8)
incq %r12
cmpq %r12, %rdx
jne 0xbe9f
incq %r9
cmpq %rcx, %r9
jne 0xbe2a
xorl %r8d, %r8d
testb %r10b, %r10b
setne %r8b
movq 0x38(%rsp), %r10
movq (%rsp), %r9
addl %r8d, %r9d
movq %r9, (%rsp)
incq %rsi
cmpq %r10, %rsi
jne 0xbe0f
movq 0x30(%rsp), %rdi
callq 0x2030
movq 0x20(%rsp), %rdi
callq 0x2030
movq 0x50(%rsp), %rdi
callq 0x2030
movq (%rsp), %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq