Ejemplo n.º 1
0
        /// <summary>
        /// Compute the result of the division of two polynomials over the field <c>GF(2^m)</c>
        /// </summary>
        ///
        /// <param name="A">he first polynomial</param>
        /// <param name="F">he second polynomial</param>
        ///
        /// <returns>Returns <c>int[][] {q,r}</c>, where <c>a = q*f+r</c> and <c>deg(r) &lt; deg(f)</c></returns>
        private static int[][] Divide(int[] A, int[] F, GF2mField GF2)
        {
            int df = ComputeDegree(F);
            int da = ComputeDegree(A) + 1;

            if (df == -1)
            {
                throw new ArithmeticException("Division by zero.");
            }

            int[][] result = new int[2][];
            result[0] = new int[1];
            result[1] = new int[da];
            int hc = HeadCoefficient(F);

            hc           = GF2.Inverse(hc);
            result[0][0] = 0;
            Array.Copy(A, 0, result[1], 0, result[1].Length);

            while (df <= ComputeDegree(result[1]))
            {
                int[] q;
                int[] coeff = new int[1];
                coeff[0] = GF2.Multiply(HeadCoefficient(result[1]), hc);
                q        = MultWithElement(F, coeff[0], GF2);
                int n = ComputeDegree(result[1]) - df;
                q         = MultWithMonomial(q, n);
                coeff     = MultWithMonomial(coeff, n);
                result[0] = Add(coeff, result[0], GF2);
                result[1] = Add(q, result[1], GF2);
            }

            return(result);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Reduce a polynomial modulo another polynomial
        /// </summary>
        ///
        /// <param name="A">The polynomial</param>
        /// <param name="F">The reduction polynomial</param>
        ///
        /// <returns>Returns <c>a mod f</c></returns>
        private static int[] Mod(int[] A, int[] F, GF2mField GF2)
        {
            int df = ComputeDegree(F);

            if (df == -1)
            {
                throw new ArithmeticException("Division by zero");
            }

            int[] result = new int[A.Length];
            int   hc     = HeadCoefficient(F);

            hc = GF2.Inverse(hc);
            Array.Copy(A, 0, result, 0, result.Length);
            while (df <= ComputeDegree(result))
            {
                int[] q;
                int   coeff = GF2.Multiply(HeadCoefficient(result), hc);
                q      = MultWithMonomial(F, ComputeDegree(result) - df);
                q      = MultWithElement(q, coeff, GF2);
                result = Add(q, result, GF2);
            }

            return(result);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Find an error vector <c>E</c> over <c>GF(2)</c> from an input syndrome <c>S</c> over <c>GF(2^M)</c>
        /// </summary>
        ///
        /// <param name="SyndVec">The syndrome</param>
        /// <param name="Field">The finite field</param>
        /// <param name="Gp">The irreducible Goppa polynomial</param>
        /// <param name="SqRootMatrix">The matrix for computing square roots in <c>(GF(2M))<sup>T</sup></c></param>
        ///
        /// <returns>The error vector</returns>
        public static GF2Vector SyndromeDecode(GF2Vector SyndVec, GF2mField Field, PolynomialGF2mSmallM Gp, PolynomialGF2mSmallM[] SqRootMatrix)
        {
            int n = 1 << Field.Degree;
            // the error vector
            GF2Vector errors = new GF2Vector(n);

            // if the syndrome vector is zero, the error vector is also zero
            if (!SyndVec.IsZero())
            {
                // convert syndrome vector to polynomial over GF(2^m)
                PolynomialGF2mSmallM syndrome = new PolynomialGF2mSmallM(SyndVec.ToExtensionFieldVector(Field));
                // compute T = syndrome^-1 mod gp
                PolynomialGF2mSmallM t = syndrome.ModInverse(Gp);
                // compute tau = sqRoot(T + X) mod gp
                PolynomialGF2mSmallM tau = t.AddMonomial(1);
                tau = tau.ModSquareRootMatrix(SqRootMatrix);
                // compute polynomials a and b satisfying a + b*tau = 0 mod gp
                PolynomialGF2mSmallM[] ab = tau.ModPolynomialToFracton(Gp);
                // compute the polynomial a^2 + X*b^2
                PolynomialGF2mSmallM a2        = ab[0].Multiply(ab[0]);
                PolynomialGF2mSmallM b2        = ab[1].Multiply(ab[1]);
                PolynomialGF2mSmallM xb2       = b2.MultWithMonomial(1);
                PolynomialGF2mSmallM a2plusXb2 = a2.Add(xb2);
                // normalize a^2 + X*b^2 to obtain the error locator polynomial
                int headCoeff            = a2plusXb2.Head;
                int invHeadCoeff         = Field.Inverse(headCoeff);
                PolynomialGF2mSmallM elp = a2plusXb2.MultWithElement(invHeadCoeff);

                // for all elements i of GF(2^m)
                for (int i = 0; i < n; i++)
                {
                    // evaluate the error locator polynomial at i
                    int z = elp.EvaluateAt(i);
                    // if polynomial evaluates to zero
                    if (z == 0)
                    {
                        // set the i-th coefficient of the error vector
                        errors.SetBit(i);
                    }
                }
            }

            return(errors);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Return the greatest common divisor of two polynomials over the field <c>GF(2^m)</c>
        /// </summary>
        ///
        /// <param name="F">The first polynomial</param>
        /// <param name="G">The second polynomial</param>
        ///
        /// <returns>Returns <c>Gcd(f, g)</c></returns>
        private static int[] Gcd(int[] F, int[] G, GF2mField GF2)
        {
            int[] a = F;
            int[] b = G;
            if (ComputeDegree(a) == -1)
            {
                return(b);
            }

            while (ComputeDegree(b) != -1)
            {
                int[] c = Mod(a, b, GF2);
                a = new int[b.Length];
                Array.Copy(b, 0, a, 0, a.Length);
                b = new int[c.Length];
                Array.Copy(c, 0, b, 0, b.Length);
            }
            int coeff = GF2.Inverse(HeadCoefficient(a));

            return(MultWithElement(a, coeff, GF2));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Compute the result of the division of two polynomials modulo a third polynomial over the field <c>GF(2^m)</c>
        /// </summary>
        ///
        /// <param name="A">The first polynomial</param>
        /// <param name="B">The second polynomial</param>
        /// <param name="G">The reduction polynomial</param>
        ///
        /// <returns>Returns <c>a * b^(-1) mod g</c></returns>
        private static int[] ModDiv(int[] A, int[] B, int[] G, GF2mField GF2)
        {
            int[]   r0 = NormalForm(G);
            int[]   r1 = Mod(B, G, GF2);
            int[]   s0 = { 0 };
            int[]   s1 = Mod(A, G, GF2);
            int[]   s2;
            int[][] q;

            while (ComputeDegree(r1) != -1)
            {
                q  = Divide(r0, r1, GF2);
                r0 = NormalForm(r1);
                r1 = NormalForm(q[1]);
                s2 = Add(s0, ModMultiply(q[0], s1, G, GF2), GF2);
                s0 = NormalForm(s1);
                s1 = NormalForm(s2);
            }
            int hc = HeadCoefficient(r0);

            s0 = MultWithElement(s0, GF2.Inverse(hc), GF2);

            return(s0);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Compute the matrix for computing square roots in this polynomial ring by inverting the squaring matrix
        /// </summary>
        private void ComputeSquareRootMatrix()
        {
            int numColumns = _poly.Degree;

            // clone squaring matrix
            PolynomialGF2mSmallM[] tmpMatrix = new PolynomialGF2mSmallM[numColumns];
            for (int i = numColumns - 1; i >= 0; i--)
            {
                tmpMatrix[i] = new PolynomialGF2mSmallM(_sqMatrix[i]);
            }

            // initialize square root matrix as unit matrix
            _sqRootMatrix = new PolynomialGF2mSmallM[numColumns];
            for (int i = numColumns - 1; i >= 0; i--)
            {
                _sqRootMatrix[i] = new PolynomialGF2mSmallM(_field, i);
            }

            // simultaneously compute Gaussian reduction of squaring matrix and unit matrix
            for (int i = 0; i < numColumns; i++)
            {
                // if diagonal element is zero
                if (tmpMatrix[i].GetCoefficient(i) == 0)
                {
                    bool foundNonZero = false;
                    // find a non-zero element in the same row
                    for (int j = i + 1; j < numColumns; j++)
                    {
                        if (tmpMatrix[j].GetCoefficient(i) != 0)
                        {
                            // found it, swap columns ...
                            foundNonZero = true;
                            SwapColumns(tmpMatrix, i, j);
                            SwapColumns(_sqRootMatrix, i, j);
                            // ... and quit searching
                            j = numColumns;
                            continue;
                        }
                    }
                    // if no non-zero element was found the matrix is not invertible
                    if (!foundNonZero)
                    {
                        throw new ArithmeticException("Squaring matrix is not invertible.");
                    }
                }

                // normalize i-th column
                int coef    = tmpMatrix[i].GetCoefficient(i);
                int invCoef = _field.Inverse(coef);
                tmpMatrix[i].MultThisWithElement(invCoef);
                _sqRootMatrix[i].MultThisWithElement(invCoef);

                if (ParallelUtils.IsParallel)
                {
                    // normalize all other columns
                    Parallel.For(0, numColumns, j =>
                    {
                        if (j != i)
                        {
                            int coefp = tmpMatrix[j].GetCoefficient(i);
                            if (coefp != 0)
                            {
                                PolynomialGF2mSmallM tmpSqColumn  = tmpMatrix[i].MultWithElement(coefp);
                                PolynomialGF2mSmallM tmpInvColumn = _sqRootMatrix[i].MultWithElement(coefp);
                                tmpMatrix[j].AddToThis(tmpSqColumn);
                                lock (_sqRootMatrix)
                                    _sqRootMatrix[j].AddToThis(tmpInvColumn);
                            }
                        }
                    });
                }
                else
                {
                    for (int j = 0; j < numColumns; j++)
                    {
                        if (j != i)
                        {
                            coef = tmpMatrix[j].GetCoefficient(i);
                            if (coef != 0)
                            {
                                PolynomialGF2mSmallM tmpSqColumn  = tmpMatrix[i].MultWithElement(coef);
                                PolynomialGF2mSmallM tmpInvColumn = _sqRootMatrix[i].MultWithElement(coef);
                                tmpMatrix[j].AddToThis(tmpSqColumn);
                                lock (_sqRootMatrix)
                                    _sqRootMatrix[j].AddToThis(tmpInvColumn);
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Construct the check matrix of a Goppa code in canonical form from the irreducible Goppa polynomial over the finite field <c>GF(2^m)</c>.
        /// </summary>
        ///
        /// <param name="Field">The finite field</param>
        /// <param name="Gp">The irreducible Goppa polynomial</param>
        ///
        /// <returns>The new GF2Matrix</returns>
        public static GF2Matrix CreateCanonicalCheckMatrix(GF2mField Field, PolynomialGF2mSmallM Gp)
        {
            int m = Field.Degree;
            int n = 1 << m;
            int t = Gp.Degree;

            // create matrix H over GF(2^m)
            int[][] hArray = ArrayUtils.CreateJagged <int[][]>(t, n);
            // create matrix YZ
            int[][] yz = ArrayUtils.CreateJagged <int[][]>(t, n);

            if (ParallelUtils.IsParallel)
            {
                Parallel.For(0, n, j =>
                             yz[0][j] = Field.Inverse(Gp.EvaluateAt(j)));
            }
            else
            {
                // here j is used as index and as element of field GF(2^m)
                for (int j = 0; j < n; j++)
                {
                    yz[0][j] = Field.Inverse(Gp.EvaluateAt(j));
                }
            }

            for (int i = 1; i < t; i++)
            {
                // here j is used as index and as element of field GF(2^m)
                if (ParallelUtils.IsParallel)
                {
                    Parallel.For(0, n, j =>
                    {
                        yz[i][j] = Field.Multiply(yz[i - 1][j], j);
                    });
                }
                else
                {
                    for (int j = 0; j < n; j++)
                    {
                        yz[i][j] = Field.Multiply(yz[i - 1][j], j);
                    }
                }
            }

            // create matrix H = XYZ
            for (int i = 0; i < t; i++)
            {
                if (ParallelUtils.IsParallel)
                {
                    Parallel.For(0, n, j =>
                    {
                        for (int k = 0; k <= i; k++)
                        {
                            hArray[i][j] = Field.Add(hArray[i][j], Field.Multiply(yz[k][j], Gp.GetCoefficient(t + k - i)));
                        }
                    });
                }
                else
                {
                    for (int j = 0; j < n; j++)
                    {
                        for (int k = 0; k <= i; k++)
                        {
                            hArray[i][j] = Field.Add(hArray[i][j], Field.Multiply(yz[k][j], Gp.GetCoefficient(t + k - i)));
                        }
                    }
                }
            }

            // convert to matrix over GF(2)
            int[][] result = ArrayUtils.CreateJagged <int[][]>(t * m, IntUtils.URShift((n + 31), 5));

            if (ParallelUtils.IsParallel)
            {
                for (int j = 0; j < n; j++)
                {
                    int q = IntUtils.URShift(j, 5);
                    int r = 1 << (j & 0x1f);
                    for (int i = 0; i < t; i++)
                    {
                        int e = hArray[i][j];
                        Parallel.For(0, m, u =>
                        {
                            int b = (IntUtils.URShift(e, u)) & 1;
                            if (b != 0)
                            {
                                int ind         = (i + 1) * m - u - 1;
                                result[ind][q] ^= r;
                            }
                        });
                    }
                }
            }
            else
            {
                for (int j = 0; j < n; j++)
                {
                    int q = IntUtils.URShift(j, 5);
                    int r = 1 << (j & 0x1f);
                    for (int i = 0; i < t; i++)
                    {
                        int e = hArray[i][j];
                        for (int u = 0; u < m; u++)
                        {
                            int b = (IntUtils.URShift(e, u)) & 1;
                            if (b != 0)
                            {
                                int ind = (i + 1) * m - u - 1;
                                result[ind][q] ^= r;
                            }
                        }
                    }
                }
            }

            return(new GF2Matrix(n, result));
        }
        /// <summary>
        /// Reduce a polynomial modulo another polynomial
        /// </summary>
        /// 
        /// <param name="A">The polynomial</param>
        /// <param name="F">The reduction polynomial</param>
        /// 
        /// <returns>Returns <c>a mod f</c></returns>
        private static int[] Mod(int[] A, int[] F, GF2mField GF2)
        {
            int df = ComputeDegree(F);
            if (df == -1)
                throw new ArithmeticException("Division by zero");

            int[] result = new int[A.Length];
            int hc = HeadCoefficient(F);
            hc = GF2.Inverse(hc);
            Array.Copy(A, 0, result, 0, result.Length);
            while (df <= ComputeDegree(result))
            {
                int[] q;
                int coeff = GF2.Multiply(HeadCoefficient(result), hc);
                q = MultWithMonomial(F, ComputeDegree(result) - df);
                q = MultWithElement(q, coeff, GF2);
                result = Add(q, result, GF2);
            }

            return result;
        }
        /// <summary>
        /// Compute the result of the division of two polynomials modulo a third polynomial over the field <c>GF(2^m)</c>
        /// </summary>
        /// 
        /// <param name="A">The first polynomial</param>
        /// <param name="B">The second polynomial</param>
        /// <param name="G">The reduction polynomial</param>
        /// 
        /// <returns>Returns <c>a * b^(-1) mod g</c></returns>
        private static int[] ModDiv(int[] A, int[] B, int[] G, GF2mField GF2)
        {
            int[] r0 = NormalForm(G);
            int[] r1 = Mod(B, G, GF2);
            int[] s0 = { 0 };
            int[] s1 = Mod(A, G, GF2);
            int[] s2;
            int[][] q;

            while (ComputeDegree(r1) != -1)
            {
                q = Divide(r0, r1, GF2);
                r0 = NormalForm(r1);
                r1 = NormalForm(q[1]);
                s2 = Add(s0, ModMultiply(q[0], s1, G, GF2), GF2);
                s0 = NormalForm(s1);
                s1 = NormalForm(s2);
            }
            int hc = HeadCoefficient(r0);
            s0 = MultWithElement(s0, GF2.Inverse(hc), GF2);

            return s0;
        }
        /// <summary>
        /// Return the greatest common divisor of two polynomials over the field <c>GF(2^m)</c>
        /// </summary>
        /// 
        /// <param name="F">The first polynomial</param>
        /// <param name="G">The second polynomial</param>
        /// 
        /// <returns>Returns <c>Gcd(f, g)</c></returns>
        private static int[] Gcd(int[] F, int[] G, GF2mField GF2)
        {
            int[] a = F;
            int[] b = G;
            if (ComputeDegree(a) == -1)
                return b;

            while (ComputeDegree(b) != -1)
            {
                int[] c = Mod(a, b, GF2);
                a = new int[b.Length];
                Array.Copy(b, 0, a, 0, a.Length);
                b = new int[c.Length];
                Array.Copy(c, 0, b, 0, b.Length);
            }
            int coeff = GF2.Inverse(HeadCoefficient(a));

            return MultWithElement(a, coeff, GF2);
        }
        /// <summary>
        /// Compute the result of the division of two polynomials over the field <c>GF(2^m)</c>
        /// </summary>
        /// 
        /// <param name="A">he first polynomial</param>
        /// <param name="F">he second polynomial</param>
        /// 
        /// <returns>Returns <c>int[][] {q,r}</c>, where <c>a = q*f+r</c> and <c>deg(r) &lt; deg(f)</c></returns>
        private static int[][] Divide(int[] A, int[] F, GF2mField GF2)
        {
            int df = ComputeDegree(F);
            int da = ComputeDegree(A) + 1;
            if (df == -1)
                throw new ArithmeticException("Division by zero.");

            int[][] result = new int[2][];
            result[0] = new int[1];
            result[1] = new int[da];
            int hc = HeadCoefficient(F);
            hc = GF2.Inverse(hc);
            result[0][0] = 0;
            Array.Copy(A, 0, result[1], 0, result[1].Length);

            while (df <= ComputeDegree(result[1]))
            {
                int[] q;
                int[] coeff = new int[1];
                coeff[0] = GF2.Multiply(HeadCoefficient(result[1]), hc);
                q = MultWithElement(F, coeff[0], GF2);
                int n = ComputeDegree(result[1]) - df;
                q = MultWithMonomial(q, n);
                coeff = MultWithMonomial(coeff, n);
                result[0] = Add(coeff, result[0], GF2);
                result[1] = Add(q, result[1], GF2);
            }

            return result;
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Construct the check matrix of a Goppa code in canonical form from the irreducible Goppa polynomial over the finite field <c>GF(2^m)</c>.
        /// </summary>
        /// 
        /// <param name="Field">The finite field</param>
        /// <param name="Gp">The irreducible Goppa polynomial</param>
        /// 
        /// <returns>The new GF2Matrix</returns>
        public static GF2Matrix CreateCanonicalCheckMatrix(GF2mField Field, PolynomialGF2mSmallM Gp)
        {
            int m = Field.Degree;
            int n = 1 << m;
            int t = Gp.Degree;
            // create matrix H over GF(2^m)
            int[][] hArray = ArrayUtils.CreateJagged<int[][]>(t, n);
            // create matrix YZ
            int[][] yz = ArrayUtils.CreateJagged<int[][]>(t, n);

            if (ParallelUtils.IsParallel)
            {
                Parallel.For(0, n, j =>
                    yz[0][j] = Field.Inverse(Gp.EvaluateAt(j)));
            }
            else
            {
                // here j is used as index and as element of field GF(2^m)
                for (int j = 0; j < n; j++)
                    yz[0][j] = Field.Inverse(Gp.EvaluateAt(j));
            }

            for (int i = 1; i < t; i++)
            {
                // here j is used as index and as element of field GF(2^m)
                if (ParallelUtils.IsParallel)
                {
                    Parallel.For(0, n, j =>
                    {
                        yz[i][j] = Field.Multiply(yz[i - 1][j], j);
                    });
                }
                else
                {
                    for (int j = 0; j < n; j++)
                        yz[i][j] = Field.Multiply(yz[i - 1][j], j);
                }
            }

            // create matrix H = XYZ
            for (int i = 0; i < t; i++)
            {
                if (ParallelUtils.IsParallel)
                {
                    Parallel.For(0, n, j =>
                    {
                        for (int k = 0; k <= i; k++)
                            hArray[i][j] = Field.Add(hArray[i][j], Field.Multiply(yz[k][j], Gp.GetCoefficient(t + k - i)));
                    });
                }
                else
                {
                    for (int j = 0; j < n; j++)
                    {
                        for (int k = 0; k <= i; k++)
                            hArray[i][j] = Field.Add(hArray[i][j], Field.Multiply(yz[k][j], Gp.GetCoefficient(t + k - i)));
                    }
                }
            }

            // convert to matrix over GF(2)
            int[][] result = ArrayUtils.CreateJagged<int[][]>(t * m, IntUtils.URShift((n + 31), 5));

            if (ParallelUtils.IsParallel)
            {
                for (int j = 0; j < n; j++)
                {
                    int q = IntUtils.URShift(j, 5);
                    int r = 1 << (j & 0x1f);
                    for (int i = 0; i < t; i++)
                    {
                        int e = hArray[i][j];
                        Parallel.For(0, m, u =>
                        {
                            int b = (IntUtils.URShift(e, u)) & 1;
                            if (b != 0)
                            {
                                int ind = (i + 1) * m - u - 1;
                                result[ind][q] ^= r;
                            }
                        });
                    }
                }
            }
            else
            {
                for (int j = 0; j < n; j++)
                {
                    int q = IntUtils.URShift(j, 5);
                    int r = 1 << (j & 0x1f);
                    for (int i = 0; i < t; i++)
                    {
                        int e = hArray[i][j];
                        for (int u = 0; u < m; u++)
                        {
                            int b = (IntUtils.URShift(e, u)) & 1;
                            if (b != 0)
                            {
                                int ind = (i + 1) * m - u - 1;
                                result[ind][q] ^= r;
                            }
                        }
                    }
                }
            }

            return new GF2Matrix(n, result);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Find an error vector <c>E</c> over <c>GF(2)</c> from an input syndrome <c>S</c> over <c>GF(2^M)</c>
        /// </summary>
        /// 
        /// <param name="SyndVec">The syndrome</param>
        /// <param name="Field">The finite field</param>
        /// <param name="Gp">The irreducible Goppa polynomial</param>
        /// <param name="SqRootMatrix">The matrix for computing square roots in <c>(GF(2M))<sup>T</sup></c></param>
        /// 
        /// <returns>The error vector</returns>
        public static GF2Vector SyndromeDecode(GF2Vector SyndVec, GF2mField Field, PolynomialGF2mSmallM Gp, PolynomialGF2mSmallM[] SqRootMatrix)
        {
            int n = 1 << Field.Degree;
            // the error vector
            GF2Vector errors = new GF2Vector(n);

            // if the syndrome vector is zero, the error vector is also zero
            if (!SyndVec.IsZero())
            {
                // convert syndrome vector to polynomial over GF(2^m)
                PolynomialGF2mSmallM syndrome = new PolynomialGF2mSmallM(SyndVec.ToExtensionFieldVector(Field));
                // compute T = syndrome^-1 mod gp
                PolynomialGF2mSmallM t = syndrome.ModInverse(Gp);
                // compute tau = sqRoot(T + X) mod gp
                PolynomialGF2mSmallM tau = t.AddMonomial(1);
                tau = tau.ModSquareRootMatrix(SqRootMatrix);
                // compute polynomials a and b satisfying a + b*tau = 0 mod gp
                PolynomialGF2mSmallM[] ab = tau.ModPolynomialToFracton(Gp);
                // compute the polynomial a^2 + X*b^2
                PolynomialGF2mSmallM a2 = ab[0].Multiply(ab[0]);
                PolynomialGF2mSmallM b2 = ab[1].Multiply(ab[1]);
                PolynomialGF2mSmallM xb2 = b2.MultWithMonomial(1);
                PolynomialGF2mSmallM a2plusXb2 = a2.Add(xb2);
                // normalize a^2 + X*b^2 to obtain the error locator polynomial
                int headCoeff = a2plusXb2.Head;
                int invHeadCoeff = Field.Inverse(headCoeff);
                PolynomialGF2mSmallM elp = a2plusXb2.MultWithElement(invHeadCoeff);

                // for all elements i of GF(2^m)
                for (int i = 0; i < n; i++)
                {
                    // evaluate the error locator polynomial at i
                    int z = elp.EvaluateAt(i);
                    // if polynomial evaluates to zero
                    if (z == 0)
                    {
                        // set the i-th coefficient of the error vector
                        errors.SetBit(i);
                    }
                }
            }

            return errors;
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Compute the inverse of this matrix
        /// </summary>
        ///
        /// <returns>Returns the inverse of this matrix (newly created)</returns>
        public override Matrix ComputeInverse()
        {
            if (RowCount != ColumnCount)
            {
                throw new ArithmeticException("GF2mMatrix: Matrix is not invertible!");
            }

            // clone this matrix
            int[][] tmpMatrix = ArrayUtils.CreateJagged <int[][]>(RowCount, RowCount);
            for (int i = RowCount - 1; i >= 0; i--)
            {
                tmpMatrix[i] = IntUtils.DeepCopy(MatrixN[i]);
            }

            // initialize inverse matrix as unit matrix
            int[][] invMatrix = ArrayUtils.CreateJagged <int[][]>(RowCount, RowCount);
            for (int i = RowCount - 1; i >= 0; i--)
            {
                invMatrix[i][i] = 1;
            }

            // simultaneously compute Gaussian reduction of tmpMatrix and unit
            // matrix
            for (int i = 0; i < RowCount; i++)
            {
                // if diagonal element is zero
                if (tmpMatrix[i][i] == 0)
                {
                    bool foundNonZero = false;
                    // find a non-zero element in the same column
                    for (int j = i + 1; j < RowCount; j++)
                    {
                        if (tmpMatrix[j][i] != 0)
                        {
                            // found it, swap rows ...
                            foundNonZero = true;
                            SwapColumns(tmpMatrix, i, j);
                            SwapColumns(invMatrix, i, j);
                            // ... and quit searching
                            j = RowCount;
                            continue;
                        }
                    }
                    // if no non-zero element was found the matrix is not invertible
                    if (!foundNonZero)
                    {
                        throw new ArithmeticException("GF2mMatrix: Matrix is not invertible!");
                    }
                }

                // normalize i-th row
                int coef    = tmpMatrix[i][i];
                int invCoef = FieldG.Inverse(coef);
                MultRowWithElementThis(tmpMatrix[i], invCoef);
                MultRowWithElementThis(invMatrix[i], invCoef);

                // normalize all other rows
                for (int j = 0; j < RowCount; j++)
                {
                    if (j != i)
                    {
                        coef = tmpMatrix[j][i];
                        if (coef != 0)
                        {
                            int[] tmpRow    = MultRowWithElement(tmpMatrix[i], coef);
                            int[] tmpInvRow = MultRowWithElement(invMatrix[i], coef);
                            AddToRow(tmpRow, tmpMatrix[j]);
                            AddToRow(tmpInvRow, invMatrix[j]);
                        }
                    }
                }
            }

            return(new GF2mMatrix(FieldG, invMatrix));
        }