Пример #1
0
 private void MultRowWithElementThis(int[] Row, int Element)
 {
     for (int i = Row.Length - 1; i >= 0; i--)
     {
         Row[i] = FieldG.Multiply(Row[i], Element);
     }
 }
Пример #2
0
        /// <summary>
        /// Evaluate this polynomial <c>p</c> at a value <c>e</c> (in <c>GF(2^m)</c>) with the Horner scheme
        /// </summary>
        ///
        /// <param name="E">The element of the finite field GF(2^m)</param>
        ///
        /// <returns>Returns <c>this(e)</c></returns>
        public int EvaluateAt(int E)
        {
            int result = _coefficients[_degree];

            for (int i = _degree - 1; i >= 0; i--)
            {
                result = _field.Multiply(result, E) ^ _coefficients[i];
            }

            return(result);
        }
Пример #3
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);
        }
Пример #4
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);
        }
Пример #5
0
        /// <summary>
        /// Compute the product of a polynomial a with an element from the finite field <c>GF(2^m)</c>
        /// </summary>
        ///
        /// <param name="A">The polynomial</param>
        /// <param name="Element">An element of the finite field GF(2^m)</param>
        ///
        /// <returns>Return <c>a * element</c></returns>
        private static int[] MultWithElement(int[] A, int Element, GF2mField GF2)
        {
            int degree = ComputeDegree(A);

            if (degree == -1 || Element == 0)
            {
                return(new int[1]);
            }

            if (Element == 1)
            {
                return(IntUtils.DeepCopy(A));
            }

            int[] result = new int[degree + 1];
            for (int i = degree; i >= 0; i--)
            {
                result[i] = GF2.Multiply(A[i], Element);
            }

            return(result);
        }
Пример #6
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 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;
        }
        /// <summary>
        /// Compute the product of a polynomial a with an element from the finite field <c>GF(2^m)</c>
        /// </summary>
        /// 
        /// <param name="A">The polynomial</param>
        /// <param name="Element">An element of the finite field GF(2^m)</param>
        /// 
        /// <returns>Return <c>a * element</c></returns>
        private static int[] MultWithElement(int[] A, int Element, GF2mField GF2)
        {
            int degree = ComputeDegree(A);
            if (degree == -1 || Element == 0)
                return new int[1];

            if (Element == 1)
                return IntUtils.DeepCopy(A);

            int[] result = new int[degree + 1];
            for (int i = degree; i >= 0; i--)
                result[i] = GF2.Multiply(A[i], Element);

            return result;
        }
Пример #10
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);
        }