# Euclidean Algorithm in Polynomials $\Bbb Z_2[x]$

Express the greatest common divisor of the following pair of polynomials as a combination of polynomials: $f(x) = x^3 + x^2 +x +1$ and $g(x) = x^4 + x^2 + 1$.

I've been trying to understand this, but still can't get how I should do it in $\mathbb{Z}_2[x]$.

-
When dividing should I care about the coefficients or the exponents? – user40105 Sep 28 '12 at 4:11
The division algorithm is the same as always, except you perform coefficient arithmetic modulo $2$. For a convenient way to perform the extended Euclidean algorithm see here. – Bill Dubuque Sep 28 '12 at 4:19
So I used the Eucl. Algorithm with f(x)=x^3+x^2+x+1 and g(x)=x^4+x^2+1 as normally, and kept dividing until I got 3 in the remainder. So since 3 = 2 in Z2, I don't know what to do next. Stop dividing? – user40105 Sep 28 '12 at 4:32
$3=1$ in $\mathbb{Z}_2$. – Alexander Gruber Sep 28 '12 at 4:36
See the link I gave. You need to do the euclidean algorithm while simultaneously keeping track of each remainder as a linear combination of $f$ and $g$. – Bill Dubuque Sep 28 '12 at 4:36

There’s really nothing different from solving such problems in $\Bbb Z$.

Using the Euclidean algorithm in its most straightforward form, not trying to be mechanically efficient:

\begin{align*} x^4+x^2+1&=(x+1)(x^3+x^2+x+1)+x^2\\ x^3+x^2+x+1&=(x+1)x^2+(x+1)\\ x^2&=x(x+1)+x\\ x+1&=1\cdot x+\color{red}{1} \end{align*}

The gcd is in red. Working upwards, and taking advantage of the fact that subtraction in $\Bbb Z_2[x]$ is addition, we have

\begin{align*} 1&=1\cdot(x+1)+1\cdot x\\ &=1\cdot(x+1)+1\cdot\left(x^2+x(x+1)\right)\\ &=(x+1)(x+1)+1\cdot x^2\\ &=(x+1)\left(f(x)+(x+1)x^2\right)+1\cdot x^2\\ &=(x+1)f(x)+\left((x+1)^2+1\right)x^2\\ &=(x+1)f(x)+x^2\cdot x^2\\ &=(x+1)f(x)+x^2\Big(g(x)+(x+1)f(x)\Big)\\ &=\left(x+1+x^2(x+1)\right)f(x)+x^2 g(x)\\ &=(x+1)\left(x^2+1\right)f(x)+x^2 g(x)\\ &=(x+1)^3 f(x)+x^2 g(x)\;. \end{align*}

As Bill Dubuque points out, and as is illustrated for numerical problems in the Wikipedia article on the extended Euclidean algorithm, there are more efficient ways to carry out the computations, but this is perhaps the easiest way to see clearly exactly what is going on.

-

Here is the Code package polynomial;

class PolyFunction { private int degree; private int coeff[];

PolyFunction(int deg, int coef) {
this.coeff = new int [deg+1];
this.coeff[deg] = coef;
this.degree  = deg;
}
int getDegree() {
int d = 0;
for (int i = 0; i < coeff.length; i++)
if (coeff[i] != 0) d = i;
return d;
}
for (int i = 0; i <= getDegree(); i++) {
if (coeff[i] < 0)
}

}

PolyFunction fx = this;
PolyFunction fPlusG = new PolyFunction(Math.max(fx.degree, gx.degree),0);
for (int i = 0; i <= fx.degree; i++) {
fPlusG.coeff[i] += fx.coeff[i];
}
for (int i = 0; i <= gx.degree; i++) {
fPlusG.coeff[i] += gx.coeff[i];
}
return fPlusG;
}

PolyFunction minus(PolyFunction gx, int primeNumber) {
PolyFunction fx = this;
PolyFunction fMinusg = new PolyFunction(Math.max(fx.degree, gx.degree), 0);
for (int i = 0; i <= fx.degree; i++) {
fMinusg.coeff[i] += fx.coeff[i];
}
for (int i = 0; i <= gx.degree; i++) {
fMinusg.coeff[i] -= gx.coeff[i];
}
//fMinusg.degree = fMinusg.getDegree();
return fMinusg;
}

PolyFunction multiple(PolyFunction gx) {
PolyFunction fx = this;
PolyFunction fMulg = new PolyFunction(fx.degree + gx.degree, 0);
for (int i = 0; i <= fx.degree; i++)
for (int j = 0; j <= gx.degree; j++)
fMulg.coeff[i+j] += (fx.coeff[i] * gx.coeff[j]);

return fMulg;
}

PolyFunction[] PLDA(PolyFunction gx, int primeNumber) {
PolyFunction fx  = this;

PolyFunction []qr = new PolyFunction[2];
qr[1] = fx;
qr[0] = new PolyFunction(0,0);

int degofQ = fx.getDegree() - gx.getDegree() ;

if (degofQ == 0 && gx.getDegree() == 0) {
//System.out.println("deg is zero");
int temp [] = EEA(primeNumber, gx.coeff[0]);
int divResult = (qr[1].coeff[qr[1].getDegree()] * temp[1]);

if ( divResult < 0)
qr[0] = new PolyFunction((qr[1].getDegree()-gx.getDegree()), divResult);
qr[1] = new PolyFunction(0, 0);
return qr;
}

if (degofQ < 0) {

qr[1] = gx;
qr[0] = fx;
return qr;
}

while((qr[1].getDegree() >= gx.getDegree()) && (qr[1].getDegree()!=0 && qr[1].coeff[0]!=0)) {

int divResult = (qr[1].coeff[qr[1].getDegree()] * temp[1]);

if ( divResult < 0)
PolyFunction tx = new PolyFunction((qr[1].getDegree()-gx.getDegree()), divResult);

PolyFunction txgx = tx.multiple(gx);

}
return qr;
}

PolyFunction fx = this;
PolyFunction []qr = new PolyFunction[2];

if ((gx.getDegree() == 0) && gx.coeff[0] == 0) {

int divResult = (1 * temp[1]);
if ( divResult < 0)

qr[0] = new PolyFunction(0, divResult);
qr[1] = new PolyFunction(0, 0);
return qr;
}
else {
PolyFunction []R = new PolyFunction[2];
PolyFunction q = qr[0];
PolyFunction r = qr[1];

PolyFunction ux = R[1];

return new PolyFunction[]{ux,vx};
}
}

public int[] EEA(int a, int b){
if(b == 0){
return new int[]{1,0};
} else {
int q = a/b;
int r = a%b;
int[] R = EEA(b,r);
return new int[]{R[1], R[0]-q*R[1]};
}
}
public String toString() {
if (degree ==  0) return "" + coeff[0];
if (degree ==  1) return coeff[1] + "x + " + coeff[0];

String ret = coeff[getDegree()] + "x^" + getDegree();

for (int i = getDegree()-1; i >= 0; i--) {
if      (coeff[i] == 0) continue;
else if (coeff[i]  > 0) ret = ret + " + " + ( coeff[i]);
else if (coeff[i]  < 0) ret = ret + " - " + (-coeff[i]);
if      (i == 1) ret = ret + "x";
else if (i >  1) ret = ret + "x^" + i;
}
return ret;
}


}

public class GF2 { private PolyFunction fx; private PolyFunction gx; private PolyFunction mx; private int primeNumber;

GF2(String file) {
fx = gx = mx = null;
return;
System.out.println("mx is " + mx);
System.out.println("fx is " + fx);
System.out.println("gx is " + gx);
}
int mxDeg = 0, fxDeg = 0, gxDeg = 0;
try {
int counter = 1;
String data = null;

switch(counter) {
case 1:
break;
case 2:
mxDeg = Integer.parseInt(data);
break;
case 3:
String [] mxToken = data.split("\\s+");
PolyFunction []p = new PolyFunction[mxToken.length+1];
for(int i=0; i < mxToken.length; i++) {
p[i] = new PolyFunction(mxDeg-i, Integer.parseInt(mxToken[i]));
}
mx = p[0];
for(int i=1; i < mxToken.length; i++)
break;
case 4:
fxDeg = Integer.parseInt(data);;
break;
case 5:
String [] fxToken = data.split("\\s+");
PolyFunction []pf = new PolyFunction[fxToken.length+1];
for(int i=0; i < fxToken.length; i++) {
pf[i] = new PolyFunction(fxDeg-i, Integer.parseInt(fxToken[i]));
}
fx = pf[0];
for(int i=1; i < fxToken.length; i++)
break;
case 6:
gxDeg = Integer.parseInt(data);
case 7:
String [] gxToken = data.split("\\s+");
PolyFunction []pg = new PolyFunction[gxToken.length+1];
for(int i=0; i < gxToken.length; i++) {
pg[i] = new PolyFunction(gxDeg-i, Integer.parseInt(gxToken[i]));
}
gx = pg[0];
for(int i=1; i < gxToken.length; i++)
break;
}
counter++;
}
} catch (FileNotFoundException e) {
System.out.println("Input file is not able to open");
return -1;
} catch (IOException e) {
e.printStackTrace();
return -1;
}
return 0;
}
void dmas() {
System.out.println("Subtraction is : " + fx.minus(gx, primeNumber));
PolyFunction fMulg = fx.multiple(gx);
if (fMulg.getDegree() >= mx.getDegree()) {
}
System.out.println("Multiplication is : " + fMulg.toString());

fDivg = fx.multiple(fDivg);
if (fDivg.getDegree() >= mx.getDegree()) {
}

System.out.println("Division is : " + fDivg);

}
public static void main(String[] args) {
String file = "src\\polynomial\\myinput.txt";
GF2 obj = new GF2(file);
obj.dmas();
}


}

-