/// <summary> /// Square this polynomial using a squaring matrix /// </summary> /// /// <param name="M">The squaring matrix</param> /// /// <returns>Returns <c>this^2</c> modulo the reduction polynomial implicitly given via the squaring matrix</returns> public PolynomialGF2mSmallM ModSquareMatrix(PolynomialGF2mSmallM[] M) { int length = M.Length; int[] resultCoeff = new int[length]; int[] thisSquare = new int[length]; // square each entry of this polynomial for (int i = 0; i < _coefficients.Length; i++) { thisSquare[i] = _field.Multiply(_coefficients[i], _coefficients[i]); } // do matrix-vector multiplication for (int i = 0; i < length; i++) { // compute scalar product of i-th row and coefficient vector for (int j = 0; j < length; j++) { if (i >= M[j]._coefficients.Length) { continue; } int scalarTerm = _field.Multiply(M[j]._coefficients[i], thisSquare[j]); resultCoeff[i] = _field.Add(resultCoeff[i], scalarTerm); } } return(new PolynomialGF2mSmallM(_field, resultCoeff)); }
private void AddToRow(int[] FromRow, int[] ToRow) { for (int i = ToRow.Length - 1; i >= 0; i--) { ToRow[i] = FieldG.Add(FromRow[i], ToRow[i]); } }
/// <summary> /// Compute the sum of two polynomials a and b over the finite field <c>GF(2^m)</c> /// </summary> /// /// <param name="A">The first polynomial</param> /// <param name="B">The second polynomial</param> /// /// <returns>Return a + b</returns> private static int[] Add(int[] A, int[] B, GF2mField GF2) { int[] result, addend; if (A.Length < B.Length) { result = new int[B.Length]; Array.Copy(B, 0, result, 0, B.Length); addend = A; } else { result = new int[A.Length]; Array.Copy(A, 0, result, 0, A.Length); addend = B; } for (int i = addend.Length - 1; i >= 0; i--) { result[i] = GF2.Add(result[i], addend[i]); } return(result); }
/// <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> /// Compute the sum of two polynomials a and b over the finite field <c>GF(2^m)</c> /// </summary> /// /// <param name="A">The first polynomial</param> /// <param name="B">The second polynomial</param> /// /// <returns>Return a + b</returns> private static int[] Add(int[] A, int[] B, GF2mField GF2) { int[] result, addend; if (A.Length < B.Length) { result = new int[B.Length]; Array.Copy(B, 0, result, 0, B.Length); addend = A; } else { result = new int[A.Length]; Array.Copy(A, 0, result, 0, A.Length); addend = B; } for (int i = addend.Length - 1; i >= 0; i--) result[i] = GF2.Add(result[i], addend[i]); return result; }
/// <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); }