// File: /workspace/github_c_makefile_star2_O0/cbouilla[P]AES-attacks-finder/Solver.c
// Function: EnleveFaussesEq
int EnleveFaussesEq(Solver *B1, int N1, SysEqLin E) // Prend en compte le fait que x = y soit equivalent à S(x) = S(y)
{
	/*
	 * Doit être lancé avec les solvers 1 issues de MakeSolver1.
     * Cela permet de savoir si oui ou non il y a une equation entre 2 variables.
     * Il ne reste donc plus qu'à déterminer si cette équation est x = y ou équivalent.
     * Si c'est le cas, on remplace toutes les occurences de y par x, sauf pour cette équation.
     */
	int trouve = 0; // indique si l'on trouve une équation d'égalité entre 2 variables
	
	int a=E->gen*VARIABLES; // nombre de lignes de E->mat
	
	unsigned char **m=malloc(a*sizeof(unsigned char *));

	int i;
	for (i = 0; i < a; i++)
	{
		m[i]=malloc((E->b+E->gen)*sizeof(unsigned char));
		int j;
		for (j = 0; j < E->b; j++) m[i][j]=E->mat[i][j];
		for (j = 0; j < E->gen; j++) m[i][j+E->b]=0;
	}
	
	int c=Dimension(m,a,E->b,1);
	
	int *X=malloc(VARIABLES*sizeof(int));
	
	for (i = 0; i < N1; i++)
	{
		int pos=0,j;
		/* Si une variable apparait "linéairement" c'est inutile */
		for (j = 0; j < B1[i]->Nvar; j++) if (!ApparaitLineairement(B1[i]->var[j],E)) X[pos++]=B1[i]->var[j];
		for (j = 0; j < pos; j++)
		{
			int k;
			for (k = j+1; k < pos; k++)
			{
				#if 1
				int l;
				for (l = 0; l < E->gen; l++)
				{
					m[E->gen*E->lignevar[X[j]]+l][E->b]=1;
					m[E->gen*E->lignevar[X[k]]+l][E->b]=1;
					int d=Dimension(m,a,E->b+1,1);
					m[E->gen*E->lignevar[X[j]]+l][E->b]=0;
					m[E->gen*E->lignevar[X[k]]+l][E->b]=0;
					if (d<c+1) break;				
				}
				if (l<E->gen)
				{
					int b=l;
					for (l = 0; l < E->gen; l++)
					{
						if (l!=b) // Permet de garder l'équation x = y ou S(x) = S(y)
						{
							int p;
							for (p = 0; p < E->b; p++)
							{
								if (m[E->gen*E->lignevar[X[k]]+l][p])
								{
									m[E->gen*E->lignevar[X[j]]+l][p]^=m[E->gen*E->lignevar[X[k]]+l][p];
									m[E->gen*E->lignevar[X[k]]+l][p]=0;
								}
							}
						}
					}
					trouve=1;
					c=Dimension(m,a,E->b,1);
					pos--;
					for (l = k; l < pos; l++) X[l]=X[l+1];
					k--;
				}
				#else // Ce serait mieux : on regarde si il exite une fonction f tel que f(x) = f(y), il faudrait vérifier si f est bijective.
				int l;
				for (l = 0; l < E->gen; l++)
				{
					m[E->gen*E->lignevar[X[j]]+l][E->b+l]=1;
					m[E->gen*E->lignevar[X[k]]+l][E->b+l]=1;			
				}
				int d=Dimension(m,a,E->b+E->gen,1);
				for (l = 0; l < E->gen; l++)
				{
					m[E->gen*E->lignevar[X[j]]+l][E->b+l]=0;
					m[E->gen*E->lignevar[X[k]]+l][E->b+l]=0;			
				}
				if (d<c+E->gen)
				{
					for (l = 0; l < E->gen; l++)
					{
						int p;
						for (p = 0; p < E->b; p++)
						{
							if (m[E->gen*E->lignevar[X[k]]+l][p])
							{
								m[E->gen*E->lignevar[X[j]]+l][p]^=m[E->gen*E->lignevar[X[k]]+l][p];
								m[E->gen*E->lignevar[X[k]]+l][p]=0;
							}
						}
					}
					trouve=1;
					c=Dimension(m,a,E->b,1);
					pos--;
					for (l = k; l < pos; l++) X[l]=X[l+1];
					k--;
				}
				#endif
				
			}
		}
	}
	free(X);
	
	int j=Base(E->mat,m,a,E->b);
	
	for (i = 0; i < a; i++) free(m[i]);
	free(m);

	if (!trouve && j==E->b) return 0; // Il n'y avait pas d'équations du type x = y ou S(x) = S(y)
	
	E->b=j;
	
	if (E->initialise)
	{
		for (i = 0; i < E->a/E->gen; i++)
		{
			freeMatriceCreuse(E->sousmat[E->varligne[i]]);
		}
		free(E->sousmat);
		E->initialise=0;
	}

	#if 0 // Activer si l'on supprime des variables
	int *dedans=malloc(VARIABLES*sizeof(int));
	for (i = 0; i < VARIABLES; i++)
	{
		for (j = 0; j < E->gen; j++)
		{
			int k=0;
			while (k<E->b && E->mat[E->lignevar[i]*E->gen+j][k]==0) k++;
			if (k<E->b) break;
		}
		if (j<E->gen) dedans[i]=1;
		else dedans[i]=0;
	}
	for (i = 0; i < VARIABLES; i++)
	{
		if (dedans[i]==0 && E->gen*E->lignevar[i]<E->a)
		{
			E->a=E->a-E->gen;
			int l;
			for (l = 0; l < E->gen; l++) echangeligne(E->gen*E->lignevar[i]+l,E->a+l,E->mat,E->gen*VARIABLES,E->b);
			j=E->varligne[E->a/E->gen];
			int k=E->lignevar[i];
			E->lignevar[i]=E->lignevar[j];
			E->lignevar[j]=k;
			E->varligne[E->a/E->gen]=i;
			E->varligne[k]=j;
		}
	}
	free(dedans);
	#endif
	return 1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
movq -0x20(%rbp), %rax
movl 0x10(%rax), %eax
leaq 0x2f8e0(%rip), %rcx     # 0x3d2c8
imull (%rcx), %eax
movl %eax, -0x28(%rbp)
movslq -0x28(%rbp), %rdi
shlq $0x3, %rdi
callq 0x21c0
movq %rax, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x28(%rbp), %eax
jge 0xdacd
movq -0x20(%rbp), %rax
movl 0xc(%rax), %eax
movq -0x20(%rbp), %rcx
addl 0x10(%rcx), %eax
movslq %eax, %rdi
shlq $0x0, %rdi
callq 0x21c0
movq %rax, %rdx
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movl $0x0, -0x38(%rbp)
movl -0x38(%rbp), %eax
movq -0x20(%rbp), %rcx
cmpl 0xc(%rcx), %eax
jge 0xda82
movq -0x20(%rbp), %rax
movq (%rax), %rax
movslq -0x34(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x38(%rbp), %rcx
movb (%rax,%rcx), %dl
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x38(%rbp), %rcx
movb %dl, (%rax,%rcx)
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0xda42
movl $0x0, -0x38(%rbp)
movl -0x38(%rbp), %eax
movq -0x20(%rbp), %rcx
cmpl 0x10(%rcx), %eax
jge 0xdabd
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movl -0x38(%rbp), %ecx
movq -0x20(%rbp), %rdx
addl 0xc(%rdx), %ecx
movslq %ecx, %rcx
movb $0x0, (%rax,%rcx)
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0xda89
jmp 0xdabf
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0xda06
movq -0x30(%rbp), %rdi
movl -0x28(%rbp), %esi
movq -0x20(%rbp), %rax
movl 0xc(%rax), %edx
movl $0x1, %ecx
callq 0x3b00
movl %eax, -0x3c(%rbp)
leaq 0x2f7d9(%rip), %rax     # 0x3d2c8
movslq (%rax), %rdi
shlq $0x2, %rdi
callq 0x21c0
movq %rax, -0x48(%rbp)
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0xded9
movl $0x0, -0x4c(%rbp)
movl $0x0, -0x50(%rbp)
movl -0x50(%rbp), %eax
movq -0x10(%rbp), %rcx
movslq -0x34(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
cmpl 0x8(%rcx), %eax
jge 0xdb90
movq -0x10(%rbp), %rax
movslq -0x34(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rax
movslq -0x50(%rbp), %rcx
movl (%rax,%rcx,4), %edi
movq -0x20(%rbp), %rsi
callq 0x12190
cmpl $0x0, %eax
jne 0xdb83
movq -0x10(%rbp), %rax
movslq -0x34(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rax
movslq -0x50(%rbp), %rcx
movl (%rax,%rcx,4), %edx
movq -0x48(%rbp), %rax
movl -0x4c(%rbp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, -0x4c(%rbp)
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
jmp 0xdb85
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0xdb20
movl $0x0, -0x50(%rbp)
movl -0x50(%rbp), %eax
cmpl -0x4c(%rbp), %eax
jge 0xdec9
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
movl -0x54(%rbp), %eax
cmpl -0x4c(%rbp), %eax
jge 0xdeb9
movl $0x0, -0x58(%rbp)
movl -0x58(%rbp), %eax
movq -0x20(%rbp), %rcx
cmpl 0x10(%rcx), %eax
jge 0xdcf0
movq -0x30(%rbp), %rax
movq -0x20(%rbp), %rcx
movl 0x10(%rcx), %ecx
movq -0x20(%rbp), %rdx
movq 0x18(%rdx), %rdx
movq -0x48(%rbp), %rsi
movslq -0x50(%rbp), %rdi
movslq (%rsi,%rdi,4), %rsi
imull (%rdx,%rsi,4), %ecx
addl -0x58(%rbp), %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movq -0x20(%rbp), %rcx
movslq 0xc(%rcx), %rcx
movb $0x1, (%rax,%rcx)
movq -0x30(%rbp), %rax
movq -0x20(%rbp), %rcx
movl 0x10(%rcx), %ecx
movq -0x20(%rbp), %rdx
movq 0x18(%rdx), %rdx
movq -0x48(%rbp), %rsi
movslq -0x54(%rbp), %rdi
movslq (%rsi,%rdi,4), %rsi
imull (%rdx,%rsi,4), %ecx
addl -0x58(%rbp), %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movq -0x20(%rbp), %rcx
movslq 0xc(%rcx), %rcx
movb $0x1, (%rax,%rcx)
movq -0x30(%rbp), %rdi
movl -0x28(%rbp), %esi
movq -0x20(%rbp), %rax
movl 0xc(%rax), %edx
addl $0x1, %edx
movl $0x1, %ecx
callq 0x3b00
movl %eax, -0x5c(%rbp)
movq -0x30(%rbp), %rax
movq -0x20(%rbp), %rcx
movl 0x10(%rcx), %ecx
movq -0x20(%rbp), %rdx
movq 0x18(%rdx), %rdx
movq -0x48(%rbp), %rsi
movslq -0x50(%rbp), %rdi
movslq (%rsi,%rdi,4), %rsi
imull (%rdx,%rsi,4), %ecx
addl -0x58(%rbp), %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movq -0x20(%rbp), %rcx
movslq 0xc(%rcx), %rcx
movb $0x0, (%rax,%rcx)
movq -0x30(%rbp), %rax
movq -0x20(%rbp), %rcx
movl 0x10(%rcx), %ecx
movq -0x20(%rbp), %rdx
movq 0x18(%rdx), %rdx
movq -0x48(%rbp), %rsi
movslq -0x54(%rbp), %rdi
movslq (%rsi,%rdi,4), %rsi
imull (%rdx,%rsi,4), %ecx
addl -0x58(%rbp), %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movq -0x20(%rbp), %rcx
movslq 0xc(%rcx), %rcx
movb $0x0, (%rax,%rcx)
movl -0x5c(%rbp), %eax
movl -0x3c(%rbp), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
jge 0xdce0
jmp 0xdcf0
jmp 0xdce2
movl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0xdbbf
movl -0x58(%rbp), %eax
movq -0x20(%rbp), %rcx
cmpl 0x10(%rcx), %eax
jge 0xdea9
movl -0x58(%rbp), %eax
movl %eax, -0x60(%rbp)
movl $0x0, -0x58(%rbp)
movl -0x58(%rbp), %eax
movq -0x20(%rbp), %rcx
cmpl 0x10(%rcx), %eax
jge 0xde41
movl -0x58(%rbp), %eax
cmpl -0x60(%rbp), %eax
je 0xde31
movl $0x0, -0x64(%rbp)
movl -0x64(%rbp), %eax
movq -0x20(%rbp), %rcx
cmpl 0xc(%rcx), %eax
jge 0xde2f
movq -0x30(%rbp), %rax
movq -0x20(%rbp), %rcx
movl 0x10(%rcx), %ecx
movq -0x20(%rbp), %rdx
movq 0x18(%rdx), %rdx
movq -0x48(%rbp), %rsi
movslq -0x54(%rbp), %rdi
movslq (%rsi,%rdi,4), %rsi
imull (%rdx,%rsi,4), %ecx
addl -0x58(%rbp), %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movslq -0x64(%rbp), %rcx
cmpb $0x0, (%rax,%rcx)
je 0xde1f
movq -0x30(%rbp), %rax
movq -0x20(%rbp), %rcx
movl 0x10(%rcx), %ecx
movq -0x20(%rbp), %rdx
movq 0x18(%rdx), %rdx
movq -0x48(%rbp), %rsi
movslq -0x54(%rbp), %rdi
movslq (%rsi,%rdi,4), %rsi
imull (%rdx,%rsi,4), %ecx
addl -0x58(%rbp), %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movslq -0x64(%rbp), %rcx
movzbl (%rax,%rcx), %esi
movq -0x30(%rbp), %rax
movq -0x20(%rbp), %rcx
movl 0x10(%rcx), %ecx
movq -0x20(%rbp), %rdx
movq 0x18(%rdx), %rdx
movq -0x48(%rbp), %rdi
movslq -0x50(%rbp), %r8
movslq (%rdi,%r8,4), %rdi
imull (%rdx,%rdi,4), %ecx
addl -0x58(%rbp), %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movslq -0x64(%rbp), %rcx
movzbl (%rax,%rcx), %edx
xorl %esi, %edx
movb %dl, (%rax,%rcx)
movq -0x30(%rbp), %rax
movq -0x20(%rbp), %rcx
movl 0x10(%rcx), %ecx
movq -0x20(%rbp), %rdx
movq 0x18(%rdx), %rdx
movq -0x48(%rbp), %rsi
movslq -0x54(%rbp), %rdi
movslq (%rsi,%rdi,4), %rsi
imull (%rdx,%rsi,4), %ecx
addl -0x58(%rbp), %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movslq -0x64(%rbp), %rcx
movb $0x0, (%rax,%rcx)
jmp 0xde21
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0xdd30
jmp 0xde31
jmp 0xde33
movl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0xdd0d
movl $0x1, -0x24(%rbp)
movq -0x30(%rbp), %rdi
movl -0x28(%rbp), %esi
movq -0x20(%rbp), %rax
movl 0xc(%rax), %edx
movl $0x1, %ecx
callq 0x3b00
movl %eax, -0x3c(%rbp)
movl -0x4c(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x4c(%rbp)
movl -0x54(%rbp), %eax
movl %eax, -0x58(%rbp)
movl -0x58(%rbp), %eax
cmpl -0x4c(%rbp), %eax
jge 0xdea0
movq -0x48(%rbp), %rax
movl -0x58(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %edx
movq -0x48(%rbp), %rax
movslq -0x58(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0xde72
movl -0x54(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0xdeab
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0xdbac
jmp 0xdebb
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0xdb97
jmp 0xdecb
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0xdb06
movq -0x48(%rbp), %rdi
callq 0x2030
movq -0x20(%rbp), %rax
movq (%rax), %rdi
movq -0x30(%rbp), %rsi
movl -0x28(%rbp), %edx
movq -0x20(%rbp), %rax
movl 0xc(%rax), %ecx
callq 0x3c10
movl %eax, -0x68(%rbp)
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x28(%rbp), %eax
jge 0xdf2a
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x2030
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0xdf06
movq -0x30(%rbp), %rdi
callq 0x2030
cmpl $0x0, -0x24(%rbp)
jne 0xdf51
movl -0x68(%rbp), %eax
movq -0x20(%rbp), %rcx
cmpl 0xc(%rcx), %eax
jne 0xdf51
movl $0x0, -0x4(%rbp)
jmp 0xdfd2
movl -0x68(%rbp), %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0xc(%rax)
movq -0x20(%rbp), %rax
cmpb $0x0, 0x28(%rax)
je 0xdfcb
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
movl %eax, -0x6c(%rbp)
movq -0x20(%rbp), %rax
movl 0x8(%rax), %eax
movq -0x20(%rbp), %rcx
cltd
idivl 0x10(%rcx)
movl %eax, %ecx
movl -0x6c(%rbp), %eax
cmpl %ecx, %eax
jge 0xdfb6
movq -0x20(%rbp), %rax
movq 0x30(%rax), %rax
movq -0x20(%rbp), %rcx
movq 0x20(%rcx), %rcx
movslq -0x34(%rbp), %rdx
movslq (%rcx,%rdx,4), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xe2f0
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0xdf6c
movq -0x20(%rbp), %rax
movq 0x30(%rax), %rdi
callq 0x2030
movq -0x20(%rbp), %rax
movb $0x0, 0x28(%rax)
movl $0x1, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x70, %rsp
popq %rbp
retq
nopl (%rax,%rax)